diff --git a/cpu/arm7_common/arm7_init.c b/cpu/arm7_common/arm7_init.c index 75cb2d45cf..f9619eae9d 100644 --- a/cpu/arm7_common/arm7_init.c +++ b/cpu/arm7_common/arm7_init.c @@ -88,7 +88,7 @@ static inline void _init_data(void) #ifdef CPU_HAS_BACKUP_RAM /* only initialize battery backup on cold boot */ - if (cpu_woke_from_backup()) { + if (cpu_backup_ram_is_initialized()) { return; } diff --git a/cpu/lpc2387/cpu.c b/cpu/lpc2387/cpu.c index 1f5cc7a3fc..15b93af1e3 100644 --- a/cpu/lpc2387/cpu.c +++ b/cpu/lpc2387/cpu.c @@ -139,12 +139,19 @@ void cpu_init(void) /* RSIR will only have POR bit set even when waking up from Deep Power Down * Use signature in battery RAM to discriminate between Deep Power Down and POR */ -bool cpu_woke_from_backup(void) +bool cpu_backup_ram_is_initialized(void) { static char signature[] __attribute__((section(".backup.data"))) = { 'R', 'I', 'O', 'T' }; + /* Only in case when a reset occurs and the POR = 0, the BODR bit + * indicates if the V_DD (3V3) voltage was below 2.6 V or not. + */ + if ((RSIR & (RSIR_BODR | RSIR_POR)) == (RSIR_BODR | RSIR_POR)) { + RSIR |= RSIR_BODR; + } + /* external reset */ if (RSIR & RSIR_EXTR) { return false; @@ -166,6 +173,11 @@ bool cpu_woke_from_backup(void) return false; } + /* When we wake from Deep Sleep only POR is set, just like in the real + * POR case. Clear the bit to create a new, distinct state. + */ + RSIR |= RSIR_POR; + return true; } diff --git a/cpu/lpc2387/include/cpu.h b/cpu/lpc2387/include/cpu.h index ecc188e823..c7dd8a3fc3 100644 --- a/cpu/lpc2387/include/cpu.h +++ b/cpu/lpc2387/include/cpu.h @@ -60,7 +60,14 @@ static inline void cpu_print_last_instruction(void) /** * @brief Returns true if the CPU woke from Deep Sleep */ -bool cpu_woke_from_backup(void); +static inline bool cpu_woke_from_backup(void) { + return RSIR == 0; +} + +/** + * @brief Returns true if the backup RAM has been initialized + */ +bool cpu_backup_ram_is_initialized(void); /** * @brief The CPU has RAM that is retained in the deepest sleep mode. diff --git a/cpu/lpc2387/periph/rtc.c b/cpu/lpc2387/periph/rtc.c index e17f24291c..5518c1da73 100644 --- a/cpu/lpc2387/periph/rtc.c +++ b/cpu/lpc2387/periph/rtc.c @@ -40,9 +40,6 @@ static rtc_alarm_cb_t _cb; /* Argument to alarm callback */ static void *_cb_arg; -/* internal function to set time based on time_t */ -static void _rtc_set(time_t time); - void RTC_IRQHandler(void) __attribute__((interrupt("IRQ"))); void rtc_init(void) @@ -56,10 +53,12 @@ void rtc_init(void) RTC_CCR = CCR_CLKSRC; /* Clock from external 32 kHz Osc. */ - /* initialize clock with valid unix compatible values - * If RTC_YEAR contains an value larger unix time_t we must reset. */ - if (RTC_YEAR > 2037) { - _rtc_set(0); + /* Initialize clock to a a sane and predictable default + * after cold boot or external reset. + */ + if ((RSIR == RSIR_POR) || (RSIR == (RSIR_POR | RSIR_EXTR))) { + struct tm localt = { .tm_year = 70 }; + rtc_set_time(&localt); } rtc_poweron(); @@ -201,10 +200,3 @@ void RTC_IRQHandler(void) VICVectAddr = 0; /* Acknowledge Interrupt */ } - -static void _rtc_set(time_t time) -{ - struct tm *localt; - localt = localtime(&time); /* convert seconds to broken-down time */ - rtc_set_time(localt); -}