123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263 |
- #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<CRY32_16_CYCLE_16MHZ_CYCLE_MIN)
- ? rtc_cnt_track : cnt_track;
-
- rtcCtl.lastTicks = tick;
- rtcCtl.prevUpdateBase += temp;
- rtcCtl.prevUpdateTicks = 0;
- }
- RTC_TIMEBASE = rtcCtl.prevUpdateBase+rtcCtl.prevUpdateTicks;
- }
- else
- {
- if(tick < rtcCtl.prevUpdateTicks)
- {
- if( ((uint32_t)(tick-rtcCtl.prevUpdateTicks)) < RTC_COUNT_OF_12HOUR_1MIN )
- {
- rtcCtl.prevUpdateBase += RTC_CNT_RANGE;
- }
- }
- rtcCtl.prevUpdateTicks = tick;
- RTC_TIMEBASE = rtcCtl.prevUpdateBase;
- }
- // LOG("track:%x\r\n", rtc_cnt_track);
- // LOG("base:%x%08x\r\n", (uint32)((uint64_t)rtcCtl.prevUpdateBase>>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<CRY32_16_CYCLE_16MHZ_CYCLE_MIN)
- ? STD_RC32_16_CYCLE_16MHZ_CYCLE : rtc_cnt_track;
- 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;
- }
-
- JUMP_FUNCTION(RTC_IRQ_HANDLER) = (uint32_t)&HalRtcIRQHandler;
- *(volatile uint32_t *) 0x4000f024 |= BIT(16)|BIT(21);
- NVIC_SetPriority((IRQn_Type)RTC_IRQn, IRQ_PRIO_HAL);
- NVIC_EnableIRQ((IRQn_Type)RTC_IRQn);
-
- hal_pwrmgr_register(MOD_RTC, NULL, HalRtcWakeupHandler);
- }
|