📄 m41t11rtc.c
字号:
/* m41t11RTC.c - RTC m41t11 real time clock driver */
/* Copyright 2003-2004, Flexcomm Technology (Shenzhen) Limited.*/
/* Copyright 1984-1994, Wind River Systems, Inc. */
/*
modification history
--------------------
040316 james create ,referenced to driver/rtc/n8571RTC.c
*/
/*
DESCRIPTION
This is the driver for the on board real time clock.
USER CALLABLE ROUTINES
Most of the routines in this driver are accessible only through the I/O
system. Two routines, however, must be called directly, rtcDrv to
initialize the driver, and rtcDevCreate to create the device.
INSTALLING THE DRIVER
Before using the driver, it must be initialized by calling the routine:
.CS
rtcDrv ()
.CE
This routine should be called exactly once, before any ioctls or
DevCreates. Normally, it is called from usrRoot.
CREATING YOUR DEVICE
Before the real time clock device can be used, it has to be created.
This is done with the rtcDevCreate call:
.CS
STATUS rtcDevCreate ()
.CE
The default name for this device is "/rtc".
RTC DATE AND TIME
This driver maintains the date and time in an internal structure.
There are two routines provided to set the date and the time:
.CS
rtcDateSet (1992, 1, 13, 1); set date to Jan-13-1992, Mon
.CS
.CE
rtcTimeSet (14, 30, 22); set time to 14:30:22
.CE
To set the time, 24 hour notation is required.
To read the date and the time the following two routines
have to be called:
.CS
rtcDateGet (); print current date
.CS
.Ce
rtcTimeGet (); print current time
.CE
RTC 12/24 HOUR MODE
To toggle between the 12 and 24 hour mode, an additional call is
installed:
.CS
rtcModeSet (mode); set the mode
.CE
where mode has to be 12 or 24.
DOS DATE AND TIME
To support date and time of local DOS files, a date/time hook
routine is provided. After installing the RTC driver and
creating the RTC device with the calls described above, this routine
has to be installed with the call:
.CS
dosFsDateTimeInstall (rtcHook);
.CE
*/
/* includes */
#include "vxWorks.h"
#include "stdio.h"
#include "types.h"
#include "iosLib.h"
#include "errnoLib.h"
#include "dosFsLib.h"
#include "time.h"
#include "ctype.h"
/*###########################################*/
/*###########################################*/
/*I2C driver*/
/*#define I2C_STATUS_ADR 0x38420000
#define I2C_SDA_ADR 0x38428000
#define I2C_SCL_ADR 0x38430000
#define I2C_SDA_OUTPUT { *(unsigned char*) I2C_STATUS_ADR=3;}
#define I2C_SDA_INPUT { *(unsigned char*) I2C_STATUS_ADR=2;}
#define I2C_SCL_POLLDOWN { *(unsigned char*) I2C_SCL_ADR=0;}
#define I2C_SCL_POLLUP { *(unsigned char*) I2C_SCL_ADR=1;}
#define I2C_SDA_POLLDOWN { *(unsigned char* )I2C_SDA_ADR=0;}
#define I2C_SDA_POLLUP { *(unsigned char* )I2C_SDA_ADR=1;}
#define DP8571_ADRS 0x10000000*/
#define GPIO_OUTPUT_ENABLE_REGISTER 0xc8004004
#define GPIO_OUTPUT_DATA_REGISTER 0xc8004000
#define GPIO_INPUT_STATUS_REGISTER 0xc8004008
#define I2C_SDA 7
#define I2C_SCL 6
#define I2C_SDA_OUTPUT *(unsigned int *)GPIO_OUTPUT_ENABLE_REGISTER &= ~(1<<I2C_SDA)
#define I2C_SDA_INPUT *(unsigned int *)GPIO_OUTPUT_ENABLE_REGISTER |= (1<<I2C_SDA)
#define I2C_SDA_POLLUP *(unsigned int *)GPIO_OUTPUT_DATA_REGISTER |= (1<<I2C_SDA)
#define I2C_SDA_POLLDOWN *(unsigned int *)GPIO_OUTPUT_DATA_REGISTER &= ~(1<<I2C_SDA)
#define I2C_SCL_OUTPUT *(unsigned int *)GPIO_OUTPUT_ENABLE_REGISTER &= ~(1<<I2C_SCL)
#define I2C_SCL_POLLUP *(unsigned int *)GPIO_OUTPUT_DATA_REGISTER |= (1<<I2C_SCL)
#define I2C_SCL_POLLDOWN *(unsigned int *)GPIO_OUTPUT_DATA_REGISTER &= ~(1<<I2C_SCL)
int iixx,iiixxx;
#define RTC_Delay(t) { for(iixx = 0; \
iixx < t; \
iixx ++) \
iiixxx = iixx*iixx;\
}
#define RTC_TIMEOUT 100000
#define RTC_DELAY_CNT 400
#define I2C_SDA_GET (((* (unsigned int *)GPIO_INPUT_STATUS_REGISTER)>>I2C_SDA) & 1)
STATUS I2C_Start()
{
I2C_SCL_OUTPUT;
I2C_SDA_OUTPUT;
I2C_SCL_POLLUP;
RTC_Delay(RTC_DELAY_CNT);
I2C_SDA_POLLDOWN;
RTC_Delay(RTC_DELAY_CNT);
I2C_SCL_POLLDOWN;
RTC_Delay(RTC_DELAY_CNT);
return OK;
}
STATUS I2C_Stop()
{
I2C_SDA_POLLDOWN;
I2C_SDA_OUTPUT;
I2C_SCL_POLLUP;
RTC_Delay(RTC_DELAY_CNT);
I2C_SDA_POLLUP;
RTC_Delay(RTC_DELAY_CNT);
return OK;
}
STATUS I2C_ACK_check()
{
int i=0;
I2C_SDA_INPUT ;
I2C_SCL_POLLUP;
RTC_Delay(RTC_DELAY_CNT);
while(I2C_SDA_GET != 0)
{
i ++ ;
if(i > RTC_TIMEOUT )
{
printf("\r\nACK check ERROR,%d\n",i);
RTC_Delay(RTC_DELAY_CNT);
return ERROR;
}
}
RTC_Delay(RTC_DELAY_CNT);
I2C_SCL_POLLDOWN;
I2C_SDA_POLLUP;
RTC_Delay(RTC_DELAY_CNT);
return OK;
}
STATUS I2C_Write_ACK()
{
I2C_SCL_POLLDOWN;
RTC_Delay(RTC_DELAY_CNT);
I2C_SDA_POLLDOWN ;
I2C_SDA_OUTPUT ;
RTC_Delay(RTC_DELAY_CNT);
I2C_SCL_POLLUP;
RTC_Delay(RTC_DELAY_CNT);
I2C_SCL_POLLDOWN;
RTC_Delay(RTC_DELAY_CNT);
return OK;
}
STATUS I2C_Write(unsigned char data)
{
int i;
unsigned char tmpp;
I2C_SDA_OUTPUT;
for(i=0;i<8;i++)
{
tmpp = data << i ;
if(tmpp&0x80)
{
I2C_SDA_POLLUP;
}
else
{
I2C_SDA_POLLDOWN;
}
RTC_Delay(RTC_DELAY_CNT);
I2C_SCL_POLLUP;
RTC_Delay(RTC_DELAY_CNT);
I2C_SCL_POLLDOWN;
RTC_Delay(RTC_DELAY_CNT);
}
}
STATUS I2C_Read(unsigned char *data)
{
int i;
unsigned int tmpp;
tmpp = 0;
I2C_SDA_INPUT;
RTC_Delay(RTC_DELAY_CNT);
for(i=0;i<8;i++)
{
I2C_SCL_POLLDOWN;
RTC_Delay(RTC_DELAY_CNT);
I2C_SCL_POLLUP;
tmpp |= (I2C_SDA_GET<<(7-i));
RTC_Delay(RTC_DELAY_CNT);
}
I2C_Write_ACK();
*data = tmpp;
}
void I2C_Init()
{
I2C_Stop();
}
STATUS m41t11_Read(unsigned char adr,unsigned char *dataOut)
{
STATUS sta =ERROR;
I2C_Start();
I2C_Write(0xd0);
if( I2C_ACK_check() == ERROR ) goto m41t11_ReadStop;
I2C_Write(adr);
if( I2C_ACK_check() == ERROR ) goto m41t11_ReadStop;;
I2C_Start();
I2C_Write(0xd1);
if( I2C_ACK_check() == ERROR ) goto m41t11_ReadStop;
I2C_Read(dataOut);
sta = OK ;
m41t11_ReadStop:
I2C_Stop();
return sta;
}
STATUS m41t11_Write(unsigned char adr,unsigned char data)
{
STATUS sta =ERROR;
I2C_Start();
I2C_Write(0xd0);
if( I2C_ACK_check() == ERROR ) goto m41t11_WriteStop;
I2C_Write(adr);
if( I2C_ACK_check() == ERROR ) goto m41t11_WriteStop;
I2C_Write(data);
if( I2C_ACK_check() == ERROR ) goto m41t11_WriteStop;
sta = OK ;
m41t11_WriteStop:
I2C_Stop();
return sta;
}
unsigned char I2C_Read_Test(unsigned char pos)
{
unsigned char temp;
m41t11_Read(pos, &temp) ;
return temp;
}
void I2C_Write_Test(unsigned char temp)
{
m41t11_Write(1, temp) ;
}
I2C_test()
{
unsigned char adr,data;
/*configure the test output*/
adr = 7;
data= 0x40;
m41t11_Write(adr,data);
adr = 7;
data= 0x00;
m41t11_Write(adr,data);
}
/*############################################*/
/*############################################*/
/*############################################*/
/* typedefs */
typedef struct /* RTC_DEV */
{
DEV_HDR ioDev;
BOOL created;
} RTC_DEV;
typedef struct /* rtc date and time structure */
{
int rtcYear;
int rtcLeapYearDist;
int rtcMonth;
int rtcDayOfYear;
int rtcDayOfMonth;
int rtcDayOfWeek;
int rtcHour;
int rtcMinute;
int rtcSecond;
} RTC_DATE_TIME;
/* defines */
#define RTC_DEVICE "/rtc"
#define SET_DATE 100
#define GET_DATE 101
#define SET_TIME 102
#define GET_TIME 103
#define MODE_12HOUR 104
#define MODE_24HOUR 105
#define I2C_RESET 106
#define CENTURY 1970
#define rtc_Year rtcDateTime.rtcYear
#define rtc_LeapYearDist rtcDateTime.rtcLeapYearDist
#define rtc_Month rtcDateTime.rtcMonth
#define rtc_DayOfYear rtcDateTime.rtcDayOfYear
#define rtc_DayOfMonth rtcDateTime.rtcDayOfMonth
#define rtc_DayOfWeek rtcDateTime.rtcDayOfWeek
#define rtc_Hour rtcDateTime.rtcHour
#define rtc_Minute rtcDateTime.rtcMinute
#define rtc_Second rtcDateTime.rtcSecond
/* locals */
RTC_DEV rtcDv = /* device descriptor */
{
{{NULL}},
FALSE
};
char *monthTable [12] =
{
"JAN", "FEB", "MAR", "APR", "MAY", "JUN",
"JUL", "AUG", "SEP", "OCT", "NOV", "DEC"
};
char *dayTable [7] =
{
"Sunday", "Monday", "Tuesday",
"Wednesday", "Thursday", "Friday", "Saturday"
};
int rtcDrvNum = 0; /* driver number assigned to this driver */
int mode = 12;
RTC_DATE_TIME rtcDateTime;
/* forward declarations */
int rtcOpen (RTC_DEV *pRtcDv);
int rtcClose (RTC_DEV *pRtcDv);
STATUS rtcIoctl (RTC_DEV *pRtcDv, int request, BOOL print);
int toBCD (int intValue);
int fromBCD (int bcdValue);
void rtcSpIoctl (int request, BOOL print);
int dayOfYear (int month, int day);
/*******************************************************************************
*
* rtcDrv - adding the driver to the driver system
*
* This routine must be called in supervisor state.
*
* RETURNS: OK or ERROR
*/
STATUS rtcDrv (void)
{
if (rtcDrvNum > 0)
return (OK);
rtcDrvNum = iosDrvInstall (rtcOpen, (FUNCPTR) NULL, rtcOpen,
rtcClose, (FUNCPTR) NULL, (FUNCPTR) NULL,
rtcIoctl);
return (rtcDrvNum == ERROR ? ERROR : OK);
}
/*******************************************************************************
*
* rtcDevCreate - create a device for the real time clock
*
* RETURN: OK or ERROR, if already created.
*/
STATUS rtcDevCreate (void)
{
/* test if driver already installed */
if (rtcDrvNum <= 0)
{
(void) errnoSet (S_ioLib_NO_DRIVER);
return (ERROR);
}
/* if there is a device already created, don't do it */
if (rtcDv.created)
return (ERROR);
/* initialize clock to 24 hour mode */
mode = 24;
/*
* mark the device as having been created
* and add it to the I/O system
*/
rtcDv.created = TRUE;
return (iosDevAdd ((DEV_HDR *) &rtcDv, RTC_DEVICE, rtcDrvNum));
}
/*******************************************************************************
*
* rtcOpen - open file to RTC
*/
int rtcOpen
(
RTC_DEV *pRtcDv
)
{
return ((int) pRtcDv);
}
/*******************************************************************************
*
* rtcClose - close file to RTC
*/
int rtcClose
(
RTC_DEV *pRtcDv
)
{
return (OK);
}
/*******************************************************************************
*
* rtcHook - date/time hook routine to set DOS file date and time
*
* NOMANUAL
*/
void rtcHook
(
DOS_DATE_TIME *pDateTime
)
{
/* update local date and time structure */
rtcSpIoctl (GET_DATE, FALSE);
rtcSpIoctl (GET_TIME, FALSE);
/* pass values to DOS date and time structure */
pDateTime->dosdt_year = CENTURY + rtc_Year; /* current year */
pDateTime->dosdt_month = rtc_Month; /* current month */
pDateTime->dosdt_day = rtc_DayOfMonth; /* current day */
pDateTime->dosdt_hour = rtc_Hour; /* current hour */
pDateTime->dosdt_minute = rtc_Minute; /* current minute */
pDateTime->dosdt_second = rtc_Second; /* current second */
}
/*******************************************************************************
*
* rtcDateSet - set the date
*
* RETURNS: N/A.
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -