Skip to content

Commit dbc42f6

Browse files
author
Cruz Monrreal
authored
Merge pull request #7031 from OpenNuvoton/nuvoton_5.9_rtc
Nuvoton: Adhere to reworked RTC spec to release with Mbed OS 5.9
2 parents 26b5f97 + 6065e3a commit dbc42f6

File tree

7 files changed

+110
-8
lines changed

7 files changed

+110
-8
lines changed

targets/TARGET_NUVOTON/TARGET_M451/rtc_api.c

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ void rtc_init(void)
100100

101101
void rtc_free(void)
102102
{
103-
// N/A
103+
CLK_DisableModuleClock(rtc_modinit.clkidx);
104104
}
105105

106106
int rtc_isenabled(void)
@@ -136,9 +136,18 @@ time_t rtc_read(void)
136136
if (! _rtc_maketime(&datetime_tm, &t_hwrtc_origin, RTC_FULL_LEAP_YEAR_SUPPORT)) {
137137
return 0;
138138
}
139+
140+
/* Load t_write from RTC spare register to cross reset cycle */
141+
RTC_WaitAccessEnable();
142+
RTC_EnableSpareAccess();
143+
RTC_WaitAccessEnable();
144+
t_write = RTC_READ_SPARE_REGISTER(0);
145+
RTC_WaitAccessEnable();
146+
while (! (RTC->SPRCTL & RTC_SPRCTL_SPRRWRDY_Msk));
139147
}
140148

141149
S_RTC_TIME_DATA_T hwrtc_datetime_2K_present;
150+
RTC_WaitAccessEnable();
142151
RTC_GetDateAndTime(&hwrtc_datetime_2K_present);
143152
/* Convert date time from H/W RTC to struct TM */
144153
rtc_convert_datetime_hwrtc_to_tm(&datetime_tm, &hwrtc_datetime_2K_present);
@@ -161,6 +170,15 @@ void rtc_write(time_t t)
161170

162171
t_write = t;
163172

173+
/* Store t_write to RTC spare register to cross reset cycle */
174+
RTC_WaitAccessEnable();
175+
RTC_EnableSpareAccess();
176+
RTC_WaitAccessEnable();
177+
RTC_WRITE_SPARE_REGISTER(0, t_write);
178+
RTC_WaitAccessEnable();
179+
while (! (RTC->SPRCTL & RTC_SPRCTL_SPRRWRDY_Msk));
180+
181+
RTC_WaitAccessEnable();
164182
RTC_SetDateAndTime((S_RTC_TIME_DATA_T *) &DATETIME_HWRTC_ORIGIN);
165183
/* NOTE: When engine is clocked by low power clock source (LXT/LIRC), we need to wait for 3 engine clocks. */
166184
wait_us((NU_US_PER_SEC / NU_RTCCLK_PER_SEC) * 3);

targets/TARGET_NUVOTON/TARGET_M480/rtc_api.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ void rtc_init(void)
100100

101101
void rtc_free(void)
102102
{
103-
// N/A
103+
CLK_DisableModuleClock(rtc_modinit.clkidx);
104104
}
105105

106106
int rtc_isenabled(void)
@@ -114,6 +114,7 @@ int rtc_isenabled(void)
114114
// NOTE: Check RTC Init Active flag to support crossing reset cycle.
115115
return !! (RTC->INIT & RTC_INIT_ACTIVE_Msk);
116116
}
117+
117118
time_t rtc_read(void)
118119
{
119120
/* NOTE: After boot, RTC time registers are not synced immediately, about 1 sec latency.
@@ -137,9 +138,16 @@ time_t rtc_read(void)
137138
if (! _rtc_maketime(&datetime_tm, &t_hwrtc_origin, RTC_FULL_LEAP_YEAR_SUPPORT)) {
138139
return 0;
139140
}
141+
142+
/* Load t_write from RTC spare register to cross reset cycle */
143+
RTC_WaitAccessEnable();
144+
RTC_EnableSpareAccess();
145+
RTC_WaitAccessEnable();
146+
t_write = RTC_READ_SPARE_REGISTER(0);
140147
}
141148

142149
S_RTC_TIME_DATA_T hwrtc_datetime_2K_present;
150+
RTC_WaitAccessEnable();
143151
RTC_GetDateAndTime(&hwrtc_datetime_2K_present);
144152
/* Convert date time from H/W RTC to struct TM */
145153
rtc_convert_datetime_hwrtc_to_tm(&datetime_tm, &hwrtc_datetime_2K_present);
@@ -162,6 +170,13 @@ void rtc_write(time_t t)
162170

163171
t_write = t;
164172

173+
/* Store t_write to RTC spare register to cross reset cycle */
174+
RTC_WaitAccessEnable();
175+
RTC_EnableSpareAccess();
176+
RTC_WaitAccessEnable();
177+
RTC_WRITE_SPARE_REGISTER(0, t_write);
178+
179+
RTC_WaitAccessEnable();
165180
RTC_SetDateAndTime((S_RTC_TIME_DATA_T *) &DATETIME_HWRTC_ORIGIN);
166181
/* NOTE: When engine is clocked by low power clock source (LXT/LIRC), we need to wait for 3 engine clocks. */
167182
wait_us((NU_US_PER_SEC / NU_RTCCLK_PER_SEC) * 3);

targets/TARGET_NUVOTON/TARGET_NANO100/device/StdDriver/nano100_rtc.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,13 +210,34 @@ typedef struct {
210210
*/
211211
#define RTC_DISABLE_TICK_WAKEUP() (RTC->TTR &= ~RTC_TTR_TWKE_Msk);
212212

213+
/* Declare these inline functions here to avoid MISRA C 2004 rule 8.1 error */
214+
static __INLINE void RTC_WaitAccessEnable(void);
215+
216+
/**
217+
* @brief Wait RTC Access Enable
218+
*
219+
* @param None
220+
*
221+
* @return None
222+
*
223+
* @details This function is used to enable the maximum RTC read/write accessible time.
224+
*/
225+
static __INLINE void RTC_WaitAccessEnable(void)
226+
{
227+
/* NOTE: When RTC->AER is written with RTC_WRITE_KEY frequently, we may lock in the loop here.
228+
* A workaround is to re-initialize RTC->INIR without checking RTC->INIR[ACTIVE] flag. */
229+
RTC->INIR = RTC_INIT_KEY;
230+
RTC->AER = RTC_WRITE_KEY;
231+
while(!(RTC->AER & RTC_AER_ENF_Msk)) RTC->AER = RTC_WRITE_KEY;
232+
}
213233

214234
void RTC_Open(S_RTC_TIME_DATA_T *sPt);
215235
void RTC_Close(void);
216236
void RTC_32KCalibration(int32_t i32FrequencyX100);
217237
void RTC_SetTickPeriod(uint32_t u32TickSelection);
218238
void RTC_EnableInt(uint32_t u32IntFlagMask);
219239
void RTC_DisableInt(uint32_t u32IntFlagMask);
240+
void RTC_EnableSpareAccess(void);
220241
uint32_t RTC_GetDayOfWeek(void);
221242
void RTC_DisableTamperDetection(void);
222243
void RTC_EnableTamperDetection(uint32_t u32PinCondition);

targets/TARGET_NUVOTON/TARGET_NANO100/rtc_api.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ void rtc_init(void)
100100

101101
void rtc_free(void)
102102
{
103-
// N/A
103+
CLK_DisableModuleClock(rtc_modinit.clkidx);
104104
}
105105

106106
int rtc_isenabled(void)
@@ -136,9 +136,16 @@ time_t rtc_read(void)
136136
if (! _rtc_maketime(&datetime_tm, &t_hwrtc_origin, RTC_FULL_LEAP_YEAR_SUPPORT)) {
137137
return 0;
138138
}
139+
140+
/* Load t_write from RTC spare register to cross reset cycle */
141+
RTC_WaitAccessEnable();
142+
t_write = RTC_READ_SPARE_REGISTER(0);
143+
RTC_WaitAccessEnable();
144+
while (! (RTC->SPRCTL & RTC_SPRCTL_SPRRDY_Msk));
139145
}
140146

141147
S_RTC_TIME_DATA_T hwrtc_datetime_2K_present;
148+
RTC_WaitAccessEnable();
142149
RTC_GetDateAndTime(&hwrtc_datetime_2K_present);
143150
/* Convert date time from H/W RTC to struct TM */
144151
rtc_convert_datetime_hwrtc_to_tm(&datetime_tm, &hwrtc_datetime_2K_present);
@@ -161,6 +168,13 @@ void rtc_write(time_t t)
161168

162169
t_write = t;
163170

171+
/* Store t_write to RTC spare register to cross reset cycle */
172+
RTC_WaitAccessEnable();
173+
RTC_WRITE_SPARE_REGISTER(0, t_write);
174+
RTC_WaitAccessEnable();
175+
while (! (RTC->SPRCTL & RTC_SPRCTL_SPRRDY_Msk));
176+
177+
RTC_WaitAccessEnable();
164178
RTC_SetDateAndTime((S_RTC_TIME_DATA_T *) &DATETIME_HWRTC_ORIGIN);
165179
/* NOTE: When engine is clocked by low power clock source (LXT/LIRC), we need to wait for 3 engine clocks. */
166180
wait_us((NU_US_PER_SEC / NU_RTCCLK_PER_SEC) * 3);

targets/TARGET_NUVOTON/TARGET_NUC472/device/StdDriver/nuc472_rtc.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,23 @@ typedef struct {
191191
*/
192192
#define RTC_GET_TAMPER_FLAG(u32PinNum) ( (RTC->TAMPSTS & (1 << u32PinNum)) >> u32PinNum)
193193

194+
/* Declare these inline functions here to avoid MISRA C 2004 rule 8.1 error */
195+
static __INLINE void RTC_WaitAccessEnable(void);
194196

197+
/**
198+
* @brief Wait RTC Access Enable
199+
*
200+
* @param None
201+
*
202+
* @return None
203+
*
204+
* @details This function is used to enable the maximum RTC read/write accessible time.
205+
*/
206+
static __INLINE void RTC_WaitAccessEnable(void)
207+
{
208+
RTC->RWEN = RTC_WRITE_KEY;
209+
while(!(RTC->RWEN & RTC_RWEN_RWENF_Msk));
210+
}
195211

196212
void RTC_Open(S_RTC_TIME_DATA_T *sPt);
197213
void RTC_Close(void);

targets/TARGET_NUVOTON/TARGET_NUC472/rtc_api.c

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ void rtc_init(void)
100100

101101
void rtc_free(void)
102102
{
103-
// N/A
103+
CLK_DisableModuleClock(rtc_modinit.clkidx);
104104
}
105105

106106
int rtc_isenabled(void)
@@ -136,9 +136,18 @@ time_t rtc_read(void)
136136
if (! _rtc_maketime(&datetime_tm, &t_hwrtc_origin, RTC_FULL_LEAP_YEAR_SUPPORT)) {
137137
return 0;
138138
}
139+
140+
/* Load t_write from RTC spare register to cross reset cycle */
141+
RTC_WaitAccessEnable();
142+
RTC_EnableSpareAccess();
143+
RTC_WaitAccessEnable();
144+
t_write = RTC_READ_SPARE_REGISTER(0);
145+
RTC_WaitAccessEnable();
146+
while (! (RTC->SPRCTL & RTC_SPRCTL_SPRRWRDY_Msk));
139147
}
140148

141149
S_RTC_TIME_DATA_T hwrtc_datetime_2K_present;
150+
RTC_WaitAccessEnable();
142151
RTC_GetDateAndTime(&hwrtc_datetime_2K_present);
143152
/* Convert date time from H/W RTC to struct TM */
144153
rtc_convert_datetime_hwrtc_to_tm(&datetime_tm, &hwrtc_datetime_2K_present);
@@ -161,6 +170,15 @@ void rtc_write(time_t t)
161170

162171
t_write = t;
163172

173+
/* Store t_write to RTC spare register to cross reset cycle */
174+
RTC_WaitAccessEnable();
175+
RTC_EnableSpareAccess();
176+
RTC_WaitAccessEnable();
177+
RTC_WRITE_SPARE_REGISTER(0, t_write);
178+
RTC_WaitAccessEnable();
179+
while (! (RTC->SPRCTL & RTC_SPRCTL_SPRRWRDY_Msk));
180+
181+
RTC_WaitAccessEnable();
164182
RTC_SetDateAndTime((S_RTC_TIME_DATA_T *) &DATETIME_HWRTC_ORIGIN);
165183
/* NOTE: When engine is clocked by low power clock source (LXT/LIRC), we need to wait for 3 engine clocks. */
166184
wait_us((NU_US_PER_SEC / NU_RTCCLK_PER_SEC) * 3);

targets/targets.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3796,7 +3796,7 @@
37963796
},
37973797
"inherits": ["Target"],
37983798
"macros_add": ["MBEDTLS_CONFIG_HW_SUPPORT"],
3799-
"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"],
3799+
"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"],
38003800
"features": ["LWIP"],
38013801
"release_versions": ["5"],
38023802
"device_name": "NUC472HI8AE",
@@ -3868,7 +3868,7 @@
38683868
},
38693869
"inherits": ["Target"],
38703870
"progen": {"target": "numaker-pfm-m453"},
3871-
"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"],
3871+
"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"],
38723872
"release_versions": ["2", "5"],
38733873
"device_name": "M453VG6AE",
38743874
"bootloader_supported": true
@@ -3899,7 +3899,7 @@
38993899
},
39003900
"inherits": ["Target"],
39013901
"macros": ["CMSIS_VECTAB_VIRTUAL", "CMSIS_VECTAB_VIRTUAL_HEADER_FILE=\"cmsis_nvic.h\"","MBED_FAULT_HANDLER_DISABLED"],
3902-
"device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "STDIO_MESSAGES", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH"],
3902+
"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"],
39033903
"release_versions": ["5"],
39043904
"device_name": "NANO130KE3BN"
39053905
},
@@ -4067,7 +4067,7 @@
40674067
},
40684068
"inherits": ["Target"],
40694069
"macros_add": ["MBEDTLS_CONFIG_HW_SUPPORT"],
4070-
"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"],
4070+
"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"],
40714071
"features": ["LWIP"],
40724072
"release_versions": ["5"],
40734073
"device_name": "M487JIDAE",

0 commit comments

Comments
 (0)