From 019c989e24938d22eeb08235375c53a97c35303c Mon Sep 17 00:00:00 2001 From: ccli8 Date: Wed, 10 May 2017 09:23:01 +0800 Subject: [PATCH] Fix RTC time doesn't continue across reset cycle --- targets/TARGET_NUVOTON/TARGET_M451/rtc_api.c | 24 +++++++++++-------- .../TARGET_NUVOTON/TARGET_NUC472/rtc_api.c | 24 +++++++++++-------- 2 files changed, 28 insertions(+), 20 deletions(-) diff --git a/targets/TARGET_NUVOTON/TARGET_M451/rtc_api.c b/targets/TARGET_NUVOTON/TARGET_M451/rtc_api.c index 906604c1a8..292adcf893 100644 --- a/targets/TARGET_NUVOTON/TARGET_M451/rtc_api.c +++ b/targets/TARGET_NUVOTON/TARGET_M451/rtc_api.c @@ -26,31 +26,33 @@ #define YEAR0 1900 //#define EPOCH_YR 1970 -static int rtc_inited = 0; static const struct nu_modinit_s rtc_modinit = {RTC_0, RTC_MODULE, 0, 0, 0, RTC_IRQn, NULL}; void rtc_init(void) { - if (rtc_inited) { + if (rtc_isenabled()) { return; } - rtc_inited = 1; - - // Enable IP clock - CLK_EnableModuleClock(rtc_modinit.clkidx); RTC_Open(NULL); } void rtc_free(void) { - // FIXME + // N/A } int rtc_isenabled(void) { - return rtc_inited; + // NOTE: To access (RTC) registers, clock must be enabled first. + if (! (CLK->APBCLK0 & CLK_APBCLK0_RTCCKEN_Msk)) { + // Enable IP clock + CLK_EnableModuleClock(rtc_modinit.clkidx); + } + + // NOTE: Check RTC Init Active flag to support crossing reset cycle. + return !! (RTC->INIT & RTC_INIT_ACTIVE_Msk); } /* @@ -68,7 +70,9 @@ int rtc_isenabled(void) time_t rtc_read(void) { - if (! rtc_inited) { + // NOTE: After boot, RTC time registers are not synced immediately, about 1 sec latency. + // RTC time got (through RTC_GetDateAndTime()) in this sec would be last-synced and incorrect. + if (! rtc_isenabled()) { rtc_init(); } @@ -94,7 +98,7 @@ time_t rtc_read(void) void rtc_write(time_t t) { - if (! rtc_inited) { + if (! rtc_isenabled()) { rtc_init(); } diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/rtc_api.c b/targets/TARGET_NUVOTON/TARGET_NUC472/rtc_api.c index 906604c1a8..cf7dfbf2d2 100644 --- a/targets/TARGET_NUVOTON/TARGET_NUC472/rtc_api.c +++ b/targets/TARGET_NUVOTON/TARGET_NUC472/rtc_api.c @@ -26,31 +26,33 @@ #define YEAR0 1900 //#define EPOCH_YR 1970 -static int rtc_inited = 0; static const struct nu_modinit_s rtc_modinit = {RTC_0, RTC_MODULE, 0, 0, 0, RTC_IRQn, NULL}; void rtc_init(void) { - if (rtc_inited) { + if (rtc_isenabled()) { return; } - rtc_inited = 1; - - // Enable IP clock - CLK_EnableModuleClock(rtc_modinit.clkidx); RTC_Open(NULL); } void rtc_free(void) { - // FIXME + // N/A } int rtc_isenabled(void) { - return rtc_inited; + // NOTE: To access (RTC) registers, clock must be enabled first. + if (! (CLK->APBCLK0 & CLK_APBCLK0_RTCCKEN_Msk)) { + // Enable IP clock + CLK_EnableModuleClock(rtc_modinit.clkidx); + } + + // NOTE: Check RTC Init Active flag to support crossing reset cycle. + return !! (RTC->INIT & RTC_INIT_INIT_Active_Msk); } /* @@ -68,7 +70,9 @@ int rtc_isenabled(void) time_t rtc_read(void) { - if (! rtc_inited) { + // NOTE: After boot, RTC time registers are not synced immediately, about 1 sec latency. + // RTC time got (through RTC_GetDateAndTime()) in this sec would be last-synced and incorrect. + if (! rtc_isenabled()) { rtc_init(); } @@ -94,7 +98,7 @@ time_t rtc_read(void) void rtc_write(time_t t) { - if (! rtc_inited) { + if (! rtc_isenabled()) { rtc_init(); }