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)) {
|
if (! _rtc_maketime(&datetime_tm, &t_hwrtc_origin, RTC_FULL_LEAP_YEAR_SUPPORT)) {
|
||||||
return 0;
|
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;
|
S_RTC_TIME_DATA_T hwrtc_datetime_2K_present;
|
||||||
|
RTC_WaitAccessEnable();
|
||||||
RTC_GetDateAndTime(&hwrtc_datetime_2K_present);
|
RTC_GetDateAndTime(&hwrtc_datetime_2K_present);
|
||||||
/* Convert date time from H/W RTC to struct TM */
|
/* Convert date time from H/W RTC to struct TM */
|
||||||
rtc_convert_datetime_hwrtc_to_tm(&datetime_tm, &hwrtc_datetime_2K_present);
|
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;
|
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);
|
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. */
|
/* 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);
|
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)) {
|
if (! _rtc_maketime(&datetime_tm, &t_hwrtc_origin, RTC_FULL_LEAP_YEAR_SUPPORT)) {
|
||||||
return 0;
|
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;
|
S_RTC_TIME_DATA_T hwrtc_datetime_2K_present;
|
||||||
|
RTC_WaitAccessEnable();
|
||||||
RTC_GetDateAndTime(&hwrtc_datetime_2K_present);
|
RTC_GetDateAndTime(&hwrtc_datetime_2K_present);
|
||||||
/* Convert date time from H/W RTC to struct TM */
|
/* Convert date time from H/W RTC to struct TM */
|
||||||
rtc_convert_datetime_hwrtc_to_tm(&datetime_tm, &hwrtc_datetime_2K_present);
|
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;
|
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);
|
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. */
|
/* 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);
|
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);
|
#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_Open(S_RTC_TIME_DATA_T *sPt);
|
||||||
void RTC_Close(void);
|
void RTC_Close(void);
|
||||||
|
@ -217,6 +237,7 @@ void RTC_32KCalibration(int32_t i32FrequencyX100);
|
||||||
void RTC_SetTickPeriod(uint32_t u32TickSelection);
|
void RTC_SetTickPeriod(uint32_t u32TickSelection);
|
||||||
void RTC_EnableInt(uint32_t u32IntFlagMask);
|
void RTC_EnableInt(uint32_t u32IntFlagMask);
|
||||||
void RTC_DisableInt(uint32_t u32IntFlagMask);
|
void RTC_DisableInt(uint32_t u32IntFlagMask);
|
||||||
|
void RTC_EnableSpareAccess(void);
|
||||||
uint32_t RTC_GetDayOfWeek(void);
|
uint32_t RTC_GetDayOfWeek(void);
|
||||||
void RTC_DisableTamperDetection(void);
|
void RTC_DisableTamperDetection(void);
|
||||||
void RTC_EnableTamperDetection(uint32_t u32PinCondition);
|
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)) {
|
if (! _rtc_maketime(&datetime_tm, &t_hwrtc_origin, RTC_FULL_LEAP_YEAR_SUPPORT)) {
|
||||||
return 0;
|
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;
|
S_RTC_TIME_DATA_T hwrtc_datetime_2K_present;
|
||||||
|
RTC_WaitAccessEnable();
|
||||||
RTC_GetDateAndTime(&hwrtc_datetime_2K_present);
|
RTC_GetDateAndTime(&hwrtc_datetime_2K_present);
|
||||||
/* Convert date time from H/W RTC to struct TM */
|
/* Convert date time from H/W RTC to struct TM */
|
||||||
rtc_convert_datetime_hwrtc_to_tm(&datetime_tm, &hwrtc_datetime_2K_present);
|
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;
|
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);
|
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. */
|
/* 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);
|
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)
|
#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_Open(S_RTC_TIME_DATA_T *sPt);
|
||||||
void RTC_Close(void);
|
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)) {
|
if (! _rtc_maketime(&datetime_tm, &t_hwrtc_origin, RTC_FULL_LEAP_YEAR_SUPPORT)) {
|
||||||
return 0;
|
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;
|
S_RTC_TIME_DATA_T hwrtc_datetime_2K_present;
|
||||||
|
RTC_WaitAccessEnable();
|
||||||
RTC_GetDateAndTime(&hwrtc_datetime_2K_present);
|
RTC_GetDateAndTime(&hwrtc_datetime_2K_present);
|
||||||
/* Convert date time from H/W RTC to struct TM */
|
/* Convert date time from H/W RTC to struct TM */
|
||||||
rtc_convert_datetime_hwrtc_to_tm(&datetime_tm, &hwrtc_datetime_2K_present);
|
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;
|
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);
|
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. */
|
/* 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);
|
wait_us((NU_US_PER_SEC / NU_RTCCLK_PER_SEC) * 3);
|
||||||
|
|
Loading…
Reference in New Issue