Merge pull request #7031 from OpenNuvoton/nuvoton_5.9_rtc

Nuvoton: Adhere to reworked RTC spec to release with Mbed OS 5.9
pull/7075/head
Cruz Monrreal 2018-05-31 10:12:50 -05:00 committed by GitHub
commit dbc42f696a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 110 additions and 8 deletions

View File

@ -100,7 +100,7 @@ void rtc_init(void)
void rtc_free(void)
{
// N/A
CLK_DisableModuleClock(rtc_modinit.clkidx);
}
int rtc_isenabled(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);

View File

@ -100,7 +100,7 @@ void rtc_init(void)
void rtc_free(void)
{
// N/A
CLK_DisableModuleClock(rtc_modinit.clkidx);
}
int rtc_isenabled(void)
@ -114,6 +114,7 @@ int rtc_isenabled(void)
// NOTE: Check RTC Init Active flag to support crossing reset cycle.
return !! (RTC->INIT & RTC_INIT_ACTIVE_Msk);
}
time_t rtc_read(void)
{
/* NOTE: After boot, RTC time registers are not synced immediately, about 1 sec latency.
@ -137,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);
@ -162,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);

View File

@ -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);

View File

@ -100,7 +100,7 @@ void rtc_init(void)
void rtc_free(void)
{
// N/A
CLK_DisableModuleClock(rtc_modinit.clkidx);
}
int rtc_isenabled(void)
@ -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);

View File

@ -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);

View File

@ -100,7 +100,7 @@ void rtc_init(void)
void rtc_free(void)
{
// N/A
CLK_DisableModuleClock(rtc_modinit.clkidx);
}
int rtc_isenabled(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);

View File

@ -3796,7 +3796,7 @@
},
"inherits": ["Target"],
"macros_add": ["MBEDTLS_CONFIG_HW_SUPPORT"],
"device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "STDIO_MESSAGES", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "TRNG", "CAN", "FLASH", "EMAC"],
"device_has": ["RTC", "ANALOGIN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "STDIO_MESSAGES", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "TRNG", "CAN", "FLASH", "EMAC"],
"features": ["LWIP"],
"release_versions": ["5"],
"device_name": "NUC472HI8AE",
@ -3868,7 +3868,7 @@
},
"inherits": ["Target"],
"progen": {"target": "numaker-pfm-m453"},
"device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "STDIO_MESSAGES", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "CAN", "FLASH"],
"device_has": ["RTC", "ANALOGIN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "STDIO_MESSAGES", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "CAN", "FLASH"],
"release_versions": ["2", "5"],
"device_name": "M453VG6AE",
"bootloader_supported": true
@ -3899,7 +3899,7 @@
},
"inherits": ["Target"],
"macros": ["CMSIS_VECTAB_VIRTUAL", "CMSIS_VECTAB_VIRTUAL_HEADER_FILE=\"cmsis_nvic.h\"","MBED_FAULT_HANDLER_DISABLED"],
"device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "STDIO_MESSAGES", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH"],
"device_has": ["RTC", "ANALOGIN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "STDIO_MESSAGES", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH"],
"release_versions": ["5"],
"device_name": "NANO130KE3BN"
},
@ -4067,7 +4067,7 @@
},
"inherits": ["Target"],
"macros_add": ["MBEDTLS_CONFIG_HW_SUPPORT"],
"device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "STDIO_MESSAGES", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "TRNG", "FLASH", "CAN", "EMAC"],
"device_has": ["RTC", "ANALOGIN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "STDIO_MESSAGES", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "TRNG", "FLASH", "CAN", "EMAC"],
"features": ["LWIP"],
"release_versions": ["5"],
"device_name": "M487JIDAE",