📄 rtclk.c
字号:
#include <vxWorks.h>
#include <stdio.h>
#include <types/vxTypes.h>
#include <semLib.h>
#include <intLib.h>
#include <taskLib.h>
#include <tickLib.h>
#include "i2c.h"
#include "rtClk.h"
#include "private/timerLibP.h"
static SEM_ID rtcSemM;
extern int i2c_read(unsigned char chip, unsigned int addr, int alen, unsigned char *buffer, int len);
extern int i2c_write(unsigned char chip, unsigned int addr, int alen, unsigned char *buffer, int len);
IMPORT int sysClkRateGet (void);IMPORT STATUS sysClkRateSet (int ticksPerSecond);IMPORT void i2c_init(int, int);
/*******************************************************************************
* bcd2Dec
*/
UINT8 bcd2Dec (UINT8 x)
{
return ((x & 0xF0) >> 4) * 10 + (x & 0x0F);
}
/*******************************************************************************
* dec2Bcd
*/
UINT8 dec2Bcd (UINT8 x)
{
UINT8 t1, t2;
t1 = x / 10;
t2 = x % 10;
t1 = t1 << 4;
return (t1 + t2);
}
/*******************************************************************************
* date2Tm
*/
STATUS date2Tm (char *c, struct tm *tm)
{
sysTodGet (tm);
if (sscanf (c, "%4d-%2d-%2d-%2d", &tm->tm_year, &tm->tm_mon, &tm->tm_mday, &tm->tm_wday) != 4)
return ERROR;
if ((tm->tm_year < 2000) ||
(tm->tm_mon < 1) || (tm->tm_mon > 12) ||
(tm->tm_mday < 1) || (tm->tm_mday > 31) ||
(tm->tm_wday < 0) || (tm->tm_wday > 6))
return ERROR;
tm->tm_year -= OS_BASE_YEAR;
tm->tm_mon -= 1;
return OK;
}
/*******************************************************************************
* time2Tm
*/
STATUS time2Tm (char *c, struct tm *tm)
{
sysTodGet (tm);
if (sscanf(c, "%2d-%2d-%2d", &tm->tm_hour, &tm->tm_min, &tm->tm_sec) != 3)
return ERROR;
if ((tm->tm_hour < 0) || (tm->tm_hour > 23) ||
(tm->tm_min < 0) || (tm->tm_min > 59) ||
(tm->tm_sec < 0) || (tm->tm_sec > 59))
return ERROR;
else
return OK;
}
/*****************************************************************************
* MPC5200 RTC time Get
*/
STATUS getM5200RtcTime(struct tm *tm)
{
UINT32 reg_time;
UINT32 reg_date;
semTake (rtcSemM, WAIT_FOREVER);
reg_time = * MPC5200_RTC_TIME_GET;
reg_date = * MPC5200_RTC_DATE_GET;
tm->tm_year = (reg_date & 0xfff) - OS_BASE_YEAR;
tm->tm_mday = (reg_date & 0x001f0000) >> 16;
tm->tm_wday = ((reg_date & 0x00E00000) >> 21) % 7;
tm->tm_mon = ((reg_date & 0x0f000000) >> 24) - 1;
tm->tm_sec = reg_time & 0x3f;
tm->tm_min = (reg_time & 0x3f00) >> 8;
tm->tm_hour = (reg_time & 0x001f0000) >> 16;
semGive (rtcSemM);
return OK;
}
/*******************************************************************************
* GetDs1307RtcTime
*/
STATUS GetDs1307RtcTime (struct tm *tm)
{
unsigned char *buf;
int status;
semTake (rtcSemM, WAIT_FOREVER);
status = i2c_read(DS1307Z_ADR, 0x00, 1, buf, 7);
tm->tm_sec = buf[0] & 0x7f;
tm->tm_min = buf[1] & 0x7f;
tm->tm_hour = buf[2] & 0x3f;
tm->tm_wday = buf[3] & 0x07 ;
tm->tm_mday = buf[4] & 0x3f;
tm->tm_mon = buf[5] & 0x1f;
tm->tm_year = buf[6];
/* Convert from BCD to decimal */
tm->tm_sec = bcd2Dec(tm->tm_sec);
tm->tm_min = bcd2Dec(tm->tm_min);
tm->tm_hour = bcd2Dec(tm->tm_hour);
tm->tm_wday = bcd2Dec(tm->tm_wday) % 7;
tm->tm_mday = bcd2Dec(tm->tm_mday);
tm->tm_year = bcd2Dec(tm->tm_year);
tm->tm_year += 100;
tm->tm_mon = bcd2Dec(tm->tm_mon) - 1;
semGive (rtcSemM);
return OK;
}
/*****************************************************************************
* MPC5200 RTC time Set
*/
STATUS SetM5200RtcTime (struct tm *tm)
{
UINT32 time_set;
UINT32 date_set;
UINT32 year_set;
int weekday;
semTake (rtcSemM, WAIT_FOREVER);
if(tm->tm_wday == 0)
weekday = 7;
else
weekday = tm->tm_wday;
time_set = (tm->tm_sec & 0x3f) + ((tm->tm_min & 0x3f) << 8) + ((tm->tm_hour & 0x1f) << 16);
date_set = (tm->tm_mday & 0x3f) + ((weekday & 0x07) << 8) + (((tm->tm_mon + 1) & 0x1f) << 16);
year_set = (tm->tm_year + OS_BASE_YEAR) & 0xfff;
* RTC_NYS = year_set;
* RTC_DS = (date_set | MPC5200_RTC_DATE_PAUSE) & (~MPC5200_RTC_DATE_SET);
* RTC_DS = (date_set | MPC5200_RTC_DATE_PAUSE) | MPC5200_RTC_DATE_SET;
* RTC_DS = (date_set | MPC5200_RTC_DATE_PAUSE) & (~MPC5200_RTC_DATE_SET);
* RTC_DS = (date_set & (~MPC5200_RTC_DATE_PAUSE)) & (~MPC5200_RTC_DATE_SET);
* RTC_TS = (time_set | MPC5200_RTC_TIME_PAUSE) & (~MPC5200_RTC_TIME_SET);
* RTC_TS = (time_set | MPC5200_RTC_TIME_PAUSE) | MPC5200_RTC_TIME_SET;
* RTC_TS = (time_set | MPC5200_RTC_TIME_PAUSE) & (~MPC5200_RTC_TIME_SET);
* RTC_TS = (time_set & (~MPC5200_RTC_TIME_PAUSE)) & (~MPC5200_RTC_TIME_SET);
semGive (rtcSemM);
return (OK);
}
/*******************************************************************************
* SetDs1307RtcTime
*/
STATUS SetDs1307RtcTime (struct tm *tm)
{
int year, mon,weekday;
unsigned char val;
year = tm->tm_year;
mon = dec2Bcd(tm->tm_mon + 1);
year = year - 100;
year = dec2Bcd(year);
if(tm->tm_wday == 0)
weekday = 7;
else
weekday = dec2Bcd( tm->tm_wday);
semTake (rtcSemM, WAIT_FOREVER);
val = year;
i2c_write(DS1307Z_ADR, 0x06, 1, &val, 1);
val = mon;
i2c_write(DS1307Z_ADR, 0x05, 1, &val, 1);
val = dec2Bcd(tm->tm_mday);
i2c_write(DS1307Z_ADR, 0x04, 1, &val, 1);
val = weekday;
i2c_write(DS1307Z_ADR, 0x03, 1, &val, 1);
val = dec2Bcd(tm->tm_hour);
i2c_write(DS1307Z_ADR, 0x02, 1, &val, 1);
val = dec2Bcd(tm->tm_min);
i2c_write(DS1307Z_ADR, 0x01, 1, &val, 1);
val = dec2Bcd(tm->tm_sec);
i2c_write(DS1307Z_ADR, 0x00, 1, &val, 1);
semGive (rtcSemM);
return (OK);
}
/*******************************************************************************
* sysRtcInit
*/
STATUS sysRtcInit (void)
{
static int rtcInitFlag = 0;
struct tm tm;
unsigned char init_z;
unsigned char val;
int status;
if (rtcInitFlag == 1)
return ERROR;
rtcInitFlag = 1;
i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
rtcSemM = semMCreate (SEM_Q_FIFO);
if (!rtcSemM)
{
logMsg ("rtcSemM create fail\n",1,2,3,4,5,6);
taskSuspend(0);
return ERROR;
}
logMsg ("real time clock begins initializing.....\n",1,2,3,4,5,6);
/* if real time clock not initialized, init it */
status = i2c_read(DS1307Z_ADR, 0x00, 1, &init_z, 1);
if (init_z & 0x80)
{
val = 0x80;
i2c_write(DS1307Z_ADR, 0x00, 1, &val, 1);
val = 0;
i2c_write(DS1307Z_ADR, 0x00, 1, &val, 1);
val = 0x93; /* enable oscillator output, 32.768kHz */
i2c_write(DS1307Z_ADR, 0x07, 1, &val, 1);
tm.tm_mday = 1;
tm.tm_mon = 1;
tm.tm_wday = 1;
tm.tm_year = 2003 - OS_BASE_YEAR;
tm.tm_sec = 0;
tm.tm_min = 0;
tm.tm_hour = 0;
SetDs1307RtcTime (&tm);
}
GetDs1307RtcTime (&tm);
SetM5200RtcTime(&tm);
SetSoftwareTime(&tm);
logMsg (" real time clock initialized is OK.....\n",1,2,3,4,5,6);
return OK;
}
/*******************************************************************************
* sysTodGet
*/
STATUS sysTodGet (struct tm *tm)
{
time_t time_in_sec;
time (&time_in_sec);
return (localtime_r (&time_in_sec, tm));
}
/*******************************************************************************
* sysTickGet
*/
int sysTickGet (void)
{
return tickGet() % 100;
}
/*******************************************************************************
* sysTodSet
*/
STATUS sysTodSet (struct tm *tm)
{
SetDs1307RtcTime(tm);
SetM5200RtcTime(tm);
SetSoftwareTime(tm);
return OK;
}
/*******************************************************************************
* showCurrentTime
*/
void showCurrentTime (void) { struct tm t; sysTodGet(&t); logMsg ("Current DATE: %04d-%02d-%02d-W%01d\n", t.tm_year + OS_BASE_YEAR,
t.tm_mon + 1,
t.tm_mday,
t.tm_wday,
5,6);
logMsg ("Current Time: %02d:%02d:%02d\n",
t.tm_hour,
t.tm_min,
t.tm_sec,
4,5,6);
}
/*****************************************************************************
* MPC5200 RTC time Show
*/
void showM5200RtcTime(void)
{
struct tm t;
getM5200RtcTime(&t);
logMsg ("Current M5200 DATE: %04d-%02d-%02d-W%01d\n",
t.tm_year + OS_BASE_YEAR,
t.tm_mon + 1,
t.tm_mday,
t.tm_wday,
5,6);
logMsg ("Current M5200 Time: %02d:%02d:%02d\n",
t.tm_hour,
t.tm_min,
t.tm_sec,
4,5,6);
}
/*******************************************************************************
* showRtcTime
*/
void showDs1307RtcTime (void)
{
struct tm t;
GetDs1307RtcTime(&t);
logMsg ("Current rtc DATE: %04d-%02d-%02d-W%01d\n",
t.tm_year + OS_BASE_YEAR,
t.tm_mon + 1,
t.tm_mday,
t.tm_wday,
5,6);
logMsg ("Current rtc Time: %02d:%02d:%02d\n",
t.tm_hour,
t.tm_min,
t.tm_sec,
4,5,6); }
/*******************************************************************************
* setCurrentTime
*/
STATUS setCurrentTime
(
int year,
int mon,
int day,
int weekday,
int hour,
int min,
int sec
) { struct tm t; STATUS status;
if ((year > 2999) || (year < OS_BASE_YEAR) || (mon > 12) || (mon < 1) || (day > 31) || (day < 1) ||
(weekday < 0) || (weekday > 6) || (hour > 23) || (hour < 0) || (min > 59) || (min < 0) || (sec > 59) || (sec < 0) ) { logMsg ("Invalid date-time!\n",1,2,3,4,5,6); return ERROR; } t.tm_year = year - OS_BASE_YEAR; t.tm_mon = mon - 1; t.tm_mday = day;
t.tm_wday = weekday; t.tm_hour = hour; t.tm_min = min; t.tm_sec = sec; status = SetM5200RtcTime(&t); status = SetDs1307RtcTime(&t);
if (status == OK)
{
GetDs1307RtcTime (&t);
SetSoftwareTime (&t);
}
return (status); }
/*******************************************************************************
* SetSoftwareTime
*/
void SetSoftwareTime (struct tm * ptm)
{
struct timespec tv;
time_t t;
ptm->tm_wday = 0;
ptm->tm_yday = 0;
ptm->tm_isdst = 0;
t = mktime(ptm);
tv.tv_sec = t;
tv.tv_nsec = 0;
if (clock_settime(CLOCK_REALTIME, &tv) == ERROR)
{
logMsg ("clock_settime err\n",1,2,3,4,5,6);
}
}
/*******************************************************************************
* GetSoftwareTime
*
* Not used.
*/
struct tm * GetSoftwareTime (void)
{
struct tm * t;
time_t time_in_sec;
/* Note localtime() is not reentrant */
time (&time_in_sec);
t = localtime (&time_in_sec);
return t;
}
/*******************************************************************************
* ResetSoftwareTime
*/
void ResetSoftwareTime (void)
{
struct tm t;
sysClkRateSet (100);
/* _clockRealtime.hz = sysClkRateGet(); 60hz=16666666.7nsec */
/* _clockRealtime.resolution = BILLION / _clockRealtime.hz; */
GetDs1307RtcTime(&t);
SetSoftwareTime(&t);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -