⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtclk.c

📁 MPC5200 BSP 支持ATA,USB, I2C,扩展网口
💻 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 + -