#include "cst92f2x.h" #include "rtc.h" #include "pwrmgr.h" #include "uart.h" #include "OSAL_Clock.h" #include "clock.h" #include "log.h" #include "global_config.h" #include "jump_function.h" #define UTC_START_TIME 946656000 //2000.1.1 0:0:0 #define UPDATA_TICK 300000000 //updata interval tick(unit:s)(300s) #define RTC_COUNT_OF_5MIN 9830400 //32768*5*60 #define RTC_COUNT_OF_12HOUR 1415577600 //32768*12*60*60 #define RTC_COUNT_OF_12HOUR_1MIN 1417543680 //32768*(13*60+1)*60 12HOUR+1MIN /** * @struct RtcCtl_t * @brief RTC control information */ typedef struct { uint64_t prevUpdateBase; uint32_t prevUpdateTicks; uint32_t lastTicks; }RtcCtl_t; static RtcCtl_t rtcCtl; static uint32_t tick_unit = 0; static uint32_t rtc_cnt_track=0; uint32_t get_rtc_counter(void) { uint32_t cnt0,cnt1; while(1) { cnt0 =((*(volatile unsigned int *)0x4000f028) & 0xFFFFFFFF); cnt1 =((*(volatile unsigned int *)0x4000f028) & 0xFFFFFFFF); if(cnt1==cnt0) break; } return cnt1; } /** * @fn static void HalRtcUpdate(void) * @brief Update RTC time. this function or HalRtcGetTime(UTCTimeStruct *getTime) function should be called periodically, the periodic time < 512s, recommend 60s * @param none. * @return none */ static void HalRtcUpdate(void) { uint32_t tick; uint32_t delta_time; uint32_t temp; uint32_t cnt_track; tick = get_rtc_counter(); if(pGlobal_config[LL_SWITCH] & RC32_TRACKINK_ALLOW) { delta_time = tick - rtcCtl.lastTicks; temp = ((((delta_time &0xffff0000)>>16)*rtc_cnt_track)<<8) +(((delta_time &0xffff)*rtc_cnt_track)>>8); rtcCtl.prevUpdateTicks = temp; if(temp > UPDATA_TICK)//5min { cnt_track = *(volatile uint32_t *)0x4000f064 & 0x1ffff; rtc_cnt_track = (cnt_track>CRY32_16_CYCLE_16MHZ_CYCLE_MAX || cnt_track>32), ((uint32)rtcCtl.prevUpdateBase&0xFFFFFFFF)); // LOG("tick:%x,last:%x\r\n", tick, rtcCtl.lastTicks); // LOG("prev:%x\r\n", rtcCtl.prevUpdateTicks); // LOG("%d\r\n", tick); } /** * @fn void HalRtcGetTime(UTCTimeStruct *getTime) * @brief Get RTC time. this function or HalRtcUpdate(void) function should be called periodically, the periodic time < 512s, recommend 60s * @param getTime: current time output value. * @return none */ void HalRtcGetTime(UTCTimeStruct *getTime) { uint64_t tickSum; uint32_t time; HalRtcUpdate(); tickSum = rtcCtl.prevUpdateTicks + rtcCtl.prevUpdateBase; time = tickSum/tick_unit; osal_ConvertUTCTime(getTime, time); } /** * @fn void HalRtcSetTime(UTCTimeStruct *setTime) * @brief Set RTC time. * @param setTime: time set value. * @return none */ void HalRtcSetTime(UTCTimeStruct *setTime) { rtcCtl.prevUpdateBase = (uint64_t)osal_ConvertUTCSecs(setTime)*tick_unit; if(pGlobal_config[LL_SWITCH] & RC32_TRACKINK_ALLOW) { rtcCtl.prevUpdateTicks = 0; rtcCtl.lastTicks = get_rtc_counter(); } else { rtcCtl.prevUpdateTicks = get_rtc_counter(); } rtcCtl.prevUpdateBase -= rtcCtl.prevUpdateTicks; REG_RTC_CC2 = 0xAA55AA; RTC_TIMEBASE = rtcCtl.prevUpdateBase; } /** * @fn UTCTime HalRtcGet_Utc(void) * @brief Get RTC time. this function or HalRtcUpdate(void) function should be called periodically, the periodic time < 512s, recommend 60s * @param getTime: current time output value. * @return none */ UTCTime HalRtcGet_Utc(void) { uint64_t tickSum; uint32_t time; HalRtcUpdate(); tickSum = rtcCtl.prevUpdateTicks + rtcCtl.prevUpdateBase; time = tickSum/tick_unit+UTC_START_TIME; return time; } /** * @fn void HalRtcSet_Utc(UTCTime utc) * @brief Set RTC time. * @param setTime: time set value. * @return none */ void HalRtcSet_Utc(UTCTime utc) { rtcCtl.prevUpdateBase = (uint64_t)(utc-UTC_START_TIME)*tick_unit; if(pGlobal_config[LL_SWITCH] & RC32_TRACKINK_ALLOW) { rtcCtl.prevUpdateTicks = 0; rtcCtl.lastTicks = get_rtc_counter(); } else { rtcCtl.prevUpdateTicks = get_rtc_counter(); } rtcCtl.prevUpdateBase -= rtcCtl.prevUpdateTicks; REG_RTC_CC2 = 0xAA55AA; RTC_TIMEBASE = rtcCtl.prevUpdateBase; } void __attribute__((used)) HalRtcIRQHandler(void) { if(pGlobal_config[LL_SWITCH] & RC32_TRACKINK_ALLOW) { *(volatile uint32_t *) 0x4000f030 = (get_rtc_counter() + RTC_COUNT_OF_5MIN)&0xFFFFFFFF; } else { *(volatile uint32_t *) 0x4000f030 = (get_rtc_counter() + RTC_COUNT_OF_12HOUR)&0xFFFFFFFF; } HalRtcUpdate(); } void HalRtcWakeupHandler(void) { NVIC_EnableIRQ((IRQn_Type)RTC_IRQn); HalRtcUpdate(); } /** * @fn void HalRtcInit(void) * @brief RTC Init. * @param none. * @return none. */ void HalRtcInit(void) { uint32_t rtcValue; UTCTimeStruct setTime; if(pGlobal_config[LL_SWITCH] & RC32_TRACKINK_ALLOW) { tick_unit = US_OF_S; } else { tick_unit = RTC_CLK_FREQ; } rtcValue = REG_RTC_CC2 & 0xffffff; LOG("rtcValue:%04x\r\n",rtcValue); if(rtcValue != 0xAA55AA)//RTC don't be initized, init RTC { //set time:2019.1.1 00:00:00 setTime.year = 2019; setTime.month = 0; setTime.day = 0; setTime.hour = 0; setTime.minutes = 0; setTime.seconds = 0; HalRtcSetTime(&setTime); LOG("InitTime:%d/%d/%d %d:%d:%d\r\n", setTime.year,setTime.month+1,setTime.day+1,setTime.hour,setTime.minutes,setTime.seconds); } else//system reset { rtcCtl.lastTicks = get_rtc_counter(); rtcCtl.prevUpdateTicks = get_rtc_counter(); rtcCtl.prevUpdateBase = RTC_TIMEBASE; HalRtcGetTime(&setTime); LOG("recover:%d/%d/%d %d:%d:%d\r\n", setTime.year,setTime.month+1,setTime.day+1,setTime.hour,setTime.minutes,setTime.seconds); } rtc_cnt_track = *(volatile uint32_t *)0x4000f064 & 0x1ffff; rtc_cnt_track = (rtc_cnt_track>CRY32_16_CYCLE_16MHZ_CYCLE_MAX || rtc_cnt_track