mirror of https://github.com/ARMmbed/mbed-os.git
[Nuvoton] Fix RTC cannot cross reset cycle
parent
ee7efb556d
commit
6065e3a943
|
@ -136,9 +136,18 @@ time_t rtc_read(void)
|
|||
if (! _rtc_maketime(&datetime_tm, &t_hwrtc_origin, RTC_FULL_LEAP_YEAR_SUPPORT)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Load t_write from RTC spare register to cross reset cycle */
|
||||
RTC_WaitAccessEnable();
|
||||
RTC_EnableSpareAccess();
|
||||
RTC_WaitAccessEnable();
|
||||
t_write = RTC_READ_SPARE_REGISTER(0);
|
||||
RTC_WaitAccessEnable();
|
||||
while (! (RTC->SPRCTL & RTC_SPRCTL_SPRRWRDY_Msk));
|
||||
}
|
||||
|
||||
S_RTC_TIME_DATA_T hwrtc_datetime_2K_present;
|
||||
RTC_WaitAccessEnable();
|
||||
RTC_GetDateAndTime(&hwrtc_datetime_2K_present);
|
||||
/* Convert date time from H/W RTC to struct TM */
|
||||
rtc_convert_datetime_hwrtc_to_tm(&datetime_tm, &hwrtc_datetime_2K_present);
|
||||
|
@ -161,6 +170,15 @@ void rtc_write(time_t t)
|
|||
|
||||
t_write = t;
|
||||
|
||||
/* Store t_write to RTC spare register to cross reset cycle */
|
||||
RTC_WaitAccessEnable();
|
||||
RTC_EnableSpareAccess();
|
||||
RTC_WaitAccessEnable();
|
||||
RTC_WRITE_SPARE_REGISTER(0, t_write);
|
||||
RTC_WaitAccessEnable();
|
||||
while (! (RTC->SPRCTL & RTC_SPRCTL_SPRRWRDY_Msk));
|
||||
|
||||
RTC_WaitAccessEnable();
|
||||
RTC_SetDateAndTime((S_RTC_TIME_DATA_T *) &DATETIME_HWRTC_ORIGIN);
|
||||
/* NOTE: When engine is clocked by low power clock source (LXT/LIRC), we need to wait for 3 engine clocks. */
|
||||
wait_us((NU_US_PER_SEC / NU_RTCCLK_PER_SEC) * 3);
|
||||
|
|
|
@ -138,9 +138,16 @@ time_t rtc_read(void)
|
|||
if (! _rtc_maketime(&datetime_tm, &t_hwrtc_origin, RTC_FULL_LEAP_YEAR_SUPPORT)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Load t_write from RTC spare register to cross reset cycle */
|
||||
RTC_WaitAccessEnable();
|
||||
RTC_EnableSpareAccess();
|
||||
RTC_WaitAccessEnable();
|
||||
t_write = RTC_READ_SPARE_REGISTER(0);
|
||||
}
|
||||
|
||||
S_RTC_TIME_DATA_T hwrtc_datetime_2K_present;
|
||||
RTC_WaitAccessEnable();
|
||||
RTC_GetDateAndTime(&hwrtc_datetime_2K_present);
|
||||
/* Convert date time from H/W RTC to struct TM */
|
||||
rtc_convert_datetime_hwrtc_to_tm(&datetime_tm, &hwrtc_datetime_2K_present);
|
||||
|
@ -163,6 +170,13 @@ void rtc_write(time_t t)
|
|||
|
||||
t_write = t;
|
||||
|
||||
/* Store t_write to RTC spare register to cross reset cycle */
|
||||
RTC_WaitAccessEnable();
|
||||
RTC_EnableSpareAccess();
|
||||
RTC_WaitAccessEnable();
|
||||
RTC_WRITE_SPARE_REGISTER(0, t_write);
|
||||
|
||||
RTC_WaitAccessEnable();
|
||||
RTC_SetDateAndTime((S_RTC_TIME_DATA_T *) &DATETIME_HWRTC_ORIGIN);
|
||||
/* NOTE: When engine is clocked by low power clock source (LXT/LIRC), we need to wait for 3 engine clocks. */
|
||||
wait_us((NU_US_PER_SEC / NU_RTCCLK_PER_SEC) * 3);
|
||||
|
|
|
@ -210,6 +210,26 @@ typedef struct {
|
|||
*/
|
||||
#define RTC_DISABLE_TICK_WAKEUP() (RTC->TTR &= ~RTC_TTR_TWKE_Msk);
|
||||
|
||||
/* Declare these inline functions here to avoid MISRA C 2004 rule 8.1 error */
|
||||
static __INLINE void RTC_WaitAccessEnable(void);
|
||||
|
||||
/**
|
||||
* @brief Wait RTC Access Enable
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
* @details This function is used to enable the maximum RTC read/write accessible time.
|
||||
*/
|
||||
static __INLINE void RTC_WaitAccessEnable(void)
|
||||
{
|
||||
/* NOTE: When RTC->AER is written with RTC_WRITE_KEY frequently, we may lock in the loop here.
|
||||
* A workaround is to re-initialize RTC->INIR without checking RTC->INIR[ACTIVE] flag. */
|
||||
RTC->INIR = RTC_INIT_KEY;
|
||||
RTC->AER = RTC_WRITE_KEY;
|
||||
while(!(RTC->AER & RTC_AER_ENF_Msk)) RTC->AER = RTC_WRITE_KEY;
|
||||
}
|
||||
|
||||
void RTC_Open(S_RTC_TIME_DATA_T *sPt);
|
||||
void RTC_Close(void);
|
||||
|
@ -217,6 +237,7 @@ void RTC_32KCalibration(int32_t i32FrequencyX100);
|
|||
void RTC_SetTickPeriod(uint32_t u32TickSelection);
|
||||
void RTC_EnableInt(uint32_t u32IntFlagMask);
|
||||
void RTC_DisableInt(uint32_t u32IntFlagMask);
|
||||
void RTC_EnableSpareAccess(void);
|
||||
uint32_t RTC_GetDayOfWeek(void);
|
||||
void RTC_DisableTamperDetection(void);
|
||||
void RTC_EnableTamperDetection(uint32_t u32PinCondition);
|
||||
|
|
|
@ -136,9 +136,16 @@ time_t rtc_read(void)
|
|||
if (! _rtc_maketime(&datetime_tm, &t_hwrtc_origin, RTC_FULL_LEAP_YEAR_SUPPORT)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Load t_write from RTC spare register to cross reset cycle */
|
||||
RTC_WaitAccessEnable();
|
||||
t_write = RTC_READ_SPARE_REGISTER(0);
|
||||
RTC_WaitAccessEnable();
|
||||
while (! (RTC->SPRCTL & RTC_SPRCTL_SPRRDY_Msk));
|
||||
}
|
||||
|
||||
S_RTC_TIME_DATA_T hwrtc_datetime_2K_present;
|
||||
RTC_WaitAccessEnable();
|
||||
RTC_GetDateAndTime(&hwrtc_datetime_2K_present);
|
||||
/* Convert date time from H/W RTC to struct TM */
|
||||
rtc_convert_datetime_hwrtc_to_tm(&datetime_tm, &hwrtc_datetime_2K_present);
|
||||
|
@ -161,6 +168,13 @@ void rtc_write(time_t t)
|
|||
|
||||
t_write = t;
|
||||
|
||||
/* Store t_write to RTC spare register to cross reset cycle */
|
||||
RTC_WaitAccessEnable();
|
||||
RTC_WRITE_SPARE_REGISTER(0, t_write);
|
||||
RTC_WaitAccessEnable();
|
||||
while (! (RTC->SPRCTL & RTC_SPRCTL_SPRRDY_Msk));
|
||||
|
||||
RTC_WaitAccessEnable();
|
||||
RTC_SetDateAndTime((S_RTC_TIME_DATA_T *) &DATETIME_HWRTC_ORIGIN);
|
||||
/* NOTE: When engine is clocked by low power clock source (LXT/LIRC), we need to wait for 3 engine clocks. */
|
||||
wait_us((NU_US_PER_SEC / NU_RTCCLK_PER_SEC) * 3);
|
||||
|
|
|
@ -191,7 +191,23 @@ typedef struct {
|
|||
*/
|
||||
#define RTC_GET_TAMPER_FLAG(u32PinNum) ( (RTC->TAMPSTS & (1 << u32PinNum)) >> u32PinNum)
|
||||
|
||||
/* Declare these inline functions here to avoid MISRA C 2004 rule 8.1 error */
|
||||
static __INLINE void RTC_WaitAccessEnable(void);
|
||||
|
||||
/**
|
||||
* @brief Wait RTC Access Enable
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
* @details This function is used to enable the maximum RTC read/write accessible time.
|
||||
*/
|
||||
static __INLINE void RTC_WaitAccessEnable(void)
|
||||
{
|
||||
RTC->RWEN = RTC_WRITE_KEY;
|
||||
while(!(RTC->RWEN & RTC_RWEN_RWENF_Msk));
|
||||
}
|
||||
|
||||
void RTC_Open(S_RTC_TIME_DATA_T *sPt);
|
||||
void RTC_Close(void);
|
||||
|
|
|
@ -136,9 +136,18 @@ time_t rtc_read(void)
|
|||
if (! _rtc_maketime(&datetime_tm, &t_hwrtc_origin, RTC_FULL_LEAP_YEAR_SUPPORT)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Load t_write from RTC spare register to cross reset cycle */
|
||||
RTC_WaitAccessEnable();
|
||||
RTC_EnableSpareAccess();
|
||||
RTC_WaitAccessEnable();
|
||||
t_write = RTC_READ_SPARE_REGISTER(0);
|
||||
RTC_WaitAccessEnable();
|
||||
while (! (RTC->SPRCTL & RTC_SPRCTL_SPRRWRDY_Msk));
|
||||
}
|
||||
|
||||
S_RTC_TIME_DATA_T hwrtc_datetime_2K_present;
|
||||
RTC_WaitAccessEnable();
|
||||
RTC_GetDateAndTime(&hwrtc_datetime_2K_present);
|
||||
/* Convert date time from H/W RTC to struct TM */
|
||||
rtc_convert_datetime_hwrtc_to_tm(&datetime_tm, &hwrtc_datetime_2K_present);
|
||||
|
@ -161,6 +170,15 @@ void rtc_write(time_t t)
|
|||
|
||||
t_write = t;
|
||||
|
||||
/* Store t_write to RTC spare register to cross reset cycle */
|
||||
RTC_WaitAccessEnable();
|
||||
RTC_EnableSpareAccess();
|
||||
RTC_WaitAccessEnable();
|
||||
RTC_WRITE_SPARE_REGISTER(0, t_write);
|
||||
RTC_WaitAccessEnable();
|
||||
while (! (RTC->SPRCTL & RTC_SPRCTL_SPRRWRDY_Msk));
|
||||
|
||||
RTC_WaitAccessEnable();
|
||||
RTC_SetDateAndTime((S_RTC_TIME_DATA_T *) &DATETIME_HWRTC_ORIGIN);
|
||||
/* NOTE: When engine is clocked by low power clock source (LXT/LIRC), we need to wait for 3 engine clocks. */
|
||||
wait_us((NU_US_PER_SEC / NU_RTCCLK_PER_SEC) * 3);
|
||||
|
|
Loading…
Reference in New Issue