From 3fab9f8b1b8e86d0c9224ea4c79b4ba35da6ade1 Mon Sep 17 00:00:00 2001 From: jun2sak Date: Sun, 7 Mar 2021 01:09:54 +0900 Subject: [PATCH] new wait-until-alarm design, don't use System OFF. --- main.c | 1 + ports/nrf/common-hal/alarm/SleepMemory.c | 26 +-- ports/nrf/common-hal/alarm/SleepMemory.h | 1 + ports/nrf/common-hal/alarm/__init__.c | 184 +++++++++++++++++--- ports/nrf/common-hal/alarm/__init__.h | 9 + ports/nrf/common-hal/alarm/pin/PinAlarm.c | 14 +- ports/nrf/common-hal/alarm/time/TimeAlarm.c | 36 ++-- ports/nrf/common-hal/alarm/time/TimeAlarm.h | 6 + ports/nrf/supervisor/debug_uart.c | 32 +++- ports/nrf/supervisor/port.c | 32 +++- 10 files changed, 274 insertions(+), 67 deletions(-) diff --git a/main.c b/main.c index e6e5a6d2a8..0f7ca8860e 100755 --- a/main.c +++ b/main.c @@ -435,6 +435,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode) { #else port_idle_until_interrupt(); #endif + return false; // to go REPL } } } diff --git a/ports/nrf/common-hal/alarm/SleepMemory.c b/ports/nrf/common-hal/alarm/SleepMemory.c index 49eb0b2594..367f305972 100644 --- a/ports/nrf/common-hal/alarm/SleepMemory.c +++ b/ports/nrf/common-hal/alarm/SleepMemory.c @@ -27,6 +27,7 @@ #include #include "py/runtime.h" +#include "common-hal/alarm/__init__.h" #include "common-hal/alarm/SleepMemory.h" #include "nrf_power.h" @@ -35,14 +36,15 @@ extern void dbg_dump_RAMreg(void); #include "supervisor/serial.h" // dbg_printf() #endif -#define RTC_DATA_ATTR __attribute__((section(".uninitialized"))) -static RTC_DATA_ATTR uint8_t _sleep_mem[SLEEP_MEMORY_LENGTH]; -static RTC_DATA_ATTR uint32_t _sleep_mem_magicnum; +__attribute__((section(".uninitialized"))) static uint8_t _sleepmem[SLEEP_MEMORY_LENGTH]; +__attribute__((section(".uninitialized"))) uint8_t sleepmem_wakeup_event; +__attribute__((section(".uninitialized"))) uint8_t sleepmem_wakeup_pin; +__attribute__((section(".uninitialized"))) static uint32_t _sleepmem_magicnum; #define SLEEP_MEMORY_DATA_GUARD 0xad0000af #define SLEEP_MEMORY_DATA_GUARD_MASK 0xff0000ff static int is_sleep_memory_valid(void) { - if ((_sleep_mem_magicnum & SLEEP_MEMORY_DATA_GUARD_MASK) + if ((_sleepmem_magicnum & SLEEP_MEMORY_DATA_GUARD_MASK) == SLEEP_MEMORY_DATA_GUARD) { return 1; } @@ -75,14 +77,16 @@ void set_memory_retention(void) { } static void initialize_sleep_memory(void) { - memset((uint8_t *)_sleep_mem, 0, SLEEP_MEMORY_LENGTH); + memset((uint8_t *)_sleepmem, 0, SLEEP_MEMORY_LENGTH); + sleepmem_wakeup_event = 0; + sleepmem_wakeup_pin = 0; set_memory_retention(); #ifdef NRF_DEBUG_PRINT //dbg_dump_RAMreg(); #endif - _sleep_mem_magicnum = SLEEP_MEMORY_DATA_GUARD; + _sleepmem_magicnum = SLEEP_MEMORY_DATA_GUARD; } void alarm_sleep_memory_reset(void) { @@ -95,21 +99,21 @@ void alarm_sleep_memory_reset(void) { } uint32_t common_hal_alarm_sleep_memory_get_length(alarm_sleep_memory_obj_t *self) { - return sizeof(_sleep_mem); + return sizeof(_sleepmem); } bool common_hal_alarm_sleep_memory_set_bytes(alarm_sleep_memory_obj_t *self, uint32_t start_index, const uint8_t* values, uint32_t len) { - if (start_index + len > sizeof(_sleep_mem)) { + if (start_index + len > sizeof(_sleepmem)) { return false; } - memcpy((uint8_t *) (_sleep_mem + start_index), values, len); + memcpy((uint8_t *) (_sleepmem + start_index), values, len); return true; } void common_hal_alarm_sleep_memory_get_bytes(alarm_sleep_memory_obj_t *self, uint32_t start_index, uint8_t* values, uint32_t len) { - if (start_index + len > sizeof(_sleep_mem)) { + if (start_index + len > sizeof(_sleepmem)) { return; } - memcpy(values, (uint8_t *) (_sleep_mem + start_index), len); + memcpy(values, (uint8_t *) (_sleepmem + start_index), len); } diff --git a/ports/nrf/common-hal/alarm/SleepMemory.h b/ports/nrf/common-hal/alarm/SleepMemory.h index 24fe0065d0..11cc4a8fb9 100644 --- a/ports/nrf/common-hal/alarm/SleepMemory.h +++ b/ports/nrf/common-hal/alarm/SleepMemory.h @@ -35,6 +35,7 @@ typedef struct { mp_obj_base_t base; } alarm_sleep_memory_obj_t; +extern void set_memory_retention(void); extern void alarm_sleep_memory_reset(void); #endif // MICROPY_INCLUDED_NRF_COMMON_HAL_ALARM_SLEEPMEMORY_H diff --git a/ports/nrf/common-hal/alarm/__init__.c b/ports/nrf/common-hal/alarm/__init__.c index f54b54a3f9..12bb2a40c4 100644 --- a/ports/nrf/common-hal/alarm/__init__.c +++ b/ports/nrf/common-hal/alarm/__init__.c @@ -37,10 +37,13 @@ #include "shared-bindings/alarm/pin/PinAlarm.h" #include "shared-bindings/alarm/time/TimeAlarm.h" #include "shared-bindings/alarm/touch/TouchAlarm.h" +#include "shared-bindings/time/__init__.h" #include "supervisor/port.h" +#include "supervisor/serial.h" // serial_connected() #ifdef NRF_DEBUG_PRINT #include "supervisor/serial.h" // dbg_printf() +extern int dbg_check_RTCprescaler(void); #endif #include "nrf.h" @@ -113,6 +116,23 @@ bool alarm_woken_from_sleep(void) { || cause == NRF_SLEEP_WAKEUP_TOUCHPAD); } +nrf_sleep_source_t alarm_woken_from_sleep_2(void) { + nrf_sleep_source_t cause = _get_wakeup_cause(); +#ifdef NRF_DEBUG_PRINT + if (cause != NRF_SLEEP_WAKEUP_UNDEFINED) { + //print_wakeup_cause(cause); + } +#endif + if (cause == NRF_SLEEP_WAKEUP_GPIO || + cause == NRF_SLEEP_WAKEUP_TIMER || + cause == NRF_SLEEP_WAKEUP_TOUCHPAD) { + return cause; + } + else { + return NRF_SLEEP_WAKEUP_UNDEFINED; + } +} + STATIC mp_obj_t _get_wake_alarm(size_t n_alarms, const mp_obj_t *alarms) { nrf_sleep_source_t cause = _get_wakeup_cause(); #ifdef NRF_DEBUG_PRINT @@ -146,19 +166,74 @@ STATIC void _setup_sleep_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t alarm_touch_touchalarm_set_alarm(deep_sleep, n_alarms, alarms); } -STATIC void _idle_until_alarm(void) { +nrf_sleep_source_t system_on_idle_until_alarm(int64_t timediff_ms, uint32_t prescaler) { + bool have_timeout = false; + uint64_t start_tick = 0, end_tick = 0; + + if (timediff_ms != -1) { + have_timeout = true; +#if 0 + int64_t now = common_hal_time_monotonic_ms(); + dbg_printf("now_ms=%ld timediff_ms=%ld\r\n", (long)now, (long)timediff_ms); +#endif + if (timediff_ms < 0) timediff_ms = 0; + int64_t tickdiff; + if (prescaler == 0) { + // 1 tick = 1/1024 sec = 1000/1024 ms + // -> 1 ms = 1024/1000 ticks + tickdiff = (mp_uint_t)(timediff_ms * 1024 / 1000); // ms -> ticks + } + else { + // 1 tick = prescaler/1024 sec = prescaler*1000/1024 ms + // -> 1ms = 1024/(1000*prescaler) ticks + tickdiff = (mp_uint_t)(timediff_ms * 1024 / (1000 * prescaler)); + } + start_tick = port_get_raw_ticks(NULL); + end_tick = start_tick + tickdiff; + } +#if 0 + dbg_printf("start_tick=%ld end_tick=%ld have_timeout=%c\r\n", (long)start_tick, (long)end_tick, have_timeout ? 'T' : 'F'); +#endif + + int64_t remaining; + nrf_sleep_source_t wakeup_cause = NRF_SLEEP_WAKEUP_UNDEFINED; + sleepmem_wakeup_event = SLEEPMEM_WAKEUP_BY_NONE; + sleepmem_wakeup_pin = WAKEUP_PIN_UNDEF; + #ifdef NRF_DEBUG_PRINT int ct = 40; + char reason = '?'; +#define WAKEUP_REASON(x) reason = (x) +#else +#define WAKEUP_REASON(x) #endif - reset_reason_saved = 0; - // Poll for alarms. - while (!mp_hal_is_interrupted()) { - RUN_BACKGROUND_TASKS; - // Allow ctrl-C interrupt. - if (alarm_woken_from_sleep()) { - alarm_save_wake_alarm(); - return; + + while(1) { + if (mp_hal_is_interrupted()) { + WAKEUP_REASON('I'); + break; } + if (serial_connected() && serial_bytes_available()) { + WAKEUP_REASON('S'); + break; + } + RUN_BACKGROUND_TASKS; + wakeup_cause = alarm_woken_from_sleep_2(); + if (wakeup_cause != NRF_SLEEP_WAKEUP_UNDEFINED) { + WAKEUP_REASON('0'+wakeup_cause); + break; + } + if (have_timeout) { + remaining = end_tick - port_get_raw_ticks(NULL); + // We break a bit early so we don't risk setting the alarm before the time when we call + // sleep. + if (remaining < 1) { + WAKEUP_REASON('t'); + break; + } + port_interrupt_after_ticks(remaining); + } + // Idle until an interrupt happens. port_idle_until_interrupt(); #ifdef NRF_DEBUG_PRINT if (ct > 0) { @@ -166,17 +241,39 @@ STATIC void _idle_until_alarm(void) { --ct; } #endif + if (have_timeout) { + remaining = end_tick - port_get_raw_ticks(NULL); + if (remaining <= 0) { + wakeup_cause = NRF_SLEEP_WAKEUP_TIMER; + sleepmem_wakeup_event = SLEEPMEM_WAKEUP_BY_TIMER; + WAKEUP_REASON('T'); + break; + } + } } +#ifdef NRF_DEBUG_PRINT + dbg_printf("%c\r\n", reason); +#endif + return wakeup_cause; } mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms) { mp_obj_t r_obj = mp_const_none; + alarm_time_timealarm_clear_wakeup_time(); _setup_sleep_alarms(false, n_alarms, alarms); + #ifdef NRF_DEBUG_PRINT - dbg_printf("\r\nsleep..."); + dbg_printf("\r\nlight sleep..."); #endif - _idle_until_alarm(); + int64_t timediff_ms = alarm_time_timealarm_get_wakeup_timediff_ms(); + nrf_sleep_source_t cause = system_on_idle_until_alarm(timediff_ms, 0); + (void)cause; + +#ifdef NRF_DEBUG_PRINT + //dbg_printf("wakeup! "); + print_wakeup_cause(cause); +#endif if (mp_hal_is_interrupted()) { #ifdef NRF_DEBUG_PRINT @@ -192,29 +289,47 @@ mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj } void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *alarms) { + alarm_time_timealarm_clear_wakeup_time(); _setup_sleep_alarms(true, n_alarms, alarms); } -extern void set_memory_retention(void); +#if defined(MICROPY_QSPI_CS) +extern void qspi_disable(void); +#endif + +#define PRESCALER_VALUE_IN_DEEP_SLEEP (1024) +extern void _debug_uart_init(void); +extern void _debug_uart_uninit(void); void NORETURN alarm_enter_deep_sleep(void) { alarm_pin_pinalarm_prepare_for_deep_sleep(); - alarm_touch_touchalarm_prepare_for_deep_sleep(); + alarm_time_timealarm_prepare_for_deep_sleep(); - uint8_t sd_enabled; - sd_softdevice_is_enabled(&sd_enabled); - - set_memory_retention(); +#if defined(MICROPY_QSPI_CS) + qspi_disable(); +#endif #ifdef NRF_DEBUG_PRINT - dbg_printf("go system off.. %d\r\n", sd_enabled); + dbg_printf("\r\ndeep sleep..."); #endif - if (sd_enabled) { - sd_power_system_off(); - } - else { - NRF_POWER->SYSTEMOFF = 1; - } + int64_t timediff_ms = alarm_time_timealarm_get_wakeup_timediff_ms(); + tick_set_prescaler(PRESCALER_VALUE_IN_DEEP_SLEEP -1); +#ifdef NRF_DEBUG_PRINT + dbg_dump_RTCreg(); //XXX + dbg_check_RTCprescaler(); //XXX +#endif + nrf_sleep_source_t cause; + cause = system_on_idle_until_alarm(timediff_ms, + PRESCALER_VALUE_IN_DEEP_SLEEP); + (void)cause; + +#ifdef NRF_DEBUG_PRINT + dbg_printf("wakeup! "); + print_wakeup_cause(cause); + dbg_printf("RESET...\r\n\r\n"); +#endif + + reset_cpu(); // should not reach here.. while(1) ; @@ -222,12 +337,23 @@ void NORETURN alarm_enter_deep_sleep(void) { void alarm_pretending_deep_sleep(void) { alarm_pin_pinalarm_prepare_for_deep_sleep(); - alarm_touch_touchalarm_prepare_for_deep_sleep(); + alarm_time_timealarm_prepare_for_deep_sleep(); - port_idle_until_interrupt(); - if (alarm_woken_from_sleep()) { - alarm_reset(); - } +#ifdef NRF_DEBUG_PRINT + dbg_printf("\r\npretending to deep sleep..."); +#endif + + int64_t timediff_ms = alarm_time_timealarm_get_wakeup_timediff_ms(); + nrf_sleep_source_t cause = system_on_idle_until_alarm(timediff_ms, 0); + (void)cause; + +#ifdef NRF_DEBUG_PRINT + dbg_printf("wakeup! "); + print_wakeup_cause(cause); + dbg_printf("continue..\r\n"); +#endif + + alarm_reset(); } void common_hal_alarm_gc_collect(void) { diff --git a/ports/nrf/common-hal/alarm/__init__.h b/ports/nrf/common-hal/alarm/__init__.h index 6fa07bcd29..7df3aaf4c3 100644 --- a/ports/nrf/common-hal/alarm/__init__.h +++ b/ports/nrf/common-hal/alarm/__init__.h @@ -41,6 +41,15 @@ typedef enum { extern const alarm_sleep_memory_obj_t alarm_sleep_memory_obj; +enum { + SLEEPMEM_WAKEUP_BY_NONE = 0, + SLEEPMEM_WAKEUP_BY_PIN = 1, + SLEEPMEM_WAKEUP_BY_TIMER = 2, +}; +#define WAKEUP_PIN_UNDEF 0xFF +extern uint8_t sleepmem_wakeup_event; +extern uint8_t sleepmem_wakeup_pin; + extern void alarm_reset(void); #endif // MICROPY_INCLUDED_NRF_COMMON_HAL_ALARM__INIT__H diff --git a/ports/nrf/common-hal/alarm/pin/PinAlarm.c b/ports/nrf/common-hal/alarm/pin/PinAlarm.c index 47d7ce8360..1f00dc0c33 100644 --- a/ports/nrf/common-hal/alarm/pin/PinAlarm.c +++ b/ports/nrf/common-hal/alarm/pin/PinAlarm.c @@ -32,6 +32,7 @@ #include "shared-bindings/alarm/pin/PinAlarm.h" #include "shared-bindings/microcontroller/__init__.h" #include "shared-bindings/microcontroller/Pin.h" +#include "common-hal/alarm/__init__.h" #include "nrfx.h" #include "nrf_gpio.h" @@ -43,8 +44,6 @@ #define WPIN_UNUSED 0xFF volatile char _pinhandler_gpiote_count; -volatile nrfx_gpiote_pin_t _pinhandler_ev_pin; -#define MYGPIOTE_EV_PIN_UNDEF 0xFF static bool pins_configured = false; extern uint32_t reset_reason_saved; @@ -81,11 +80,13 @@ bool common_hal_alarm_pin_pinalarm_get_pull(alarm_pin_pinalarm_obj_t *self) { static void pinalarm_gpiote_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) { ++_pinhandler_gpiote_count; - _pinhandler_ev_pin = pin; + sleepmem_wakeup_event = SLEEPMEM_WAKEUP_BY_PIN; + sleepmem_wakeup_pin = pin & 0xFF; } bool alarm_pin_pinalarm_woke_us_up(void) { - return (_pinhandler_gpiote_count > 0 && _pinhandler_ev_pin != MYGPIOTE_EV_PIN_UNDEF); + return (sleepmem_wakeup_event == SLEEPMEM_WAKEUP_BY_PIN && + sleepmem_wakeup_pin != WAKEUP_PIN_UNDEF); } mp_obj_t alarm_pin_pinalarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *alarms) { @@ -95,7 +96,7 @@ mp_obj_t alarm_pin_pinalarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *al continue; } alarm_pin_pinalarm_obj_t *alarm = MP_OBJ_TO_PTR(alarms[i]); - if (alarm->pin->number == _pinhandler_ev_pin) { + if (alarm->pin->number == sleepmem_wakeup_pin) { return alarms[i]; } } @@ -105,7 +106,7 @@ mp_obj_t alarm_pin_pinalarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *al // Map the pin number back to a pin object. for (size_t i = 0; i < mcu_pin_globals.map.used; i++) { const mcu_pin_obj_t* pin_obj = MP_OBJ_TO_PTR(mcu_pin_globals.map.table[i].value); - if ((size_t) pin_obj->number == _pinhandler_ev_pin) { + if ((size_t) pin_obj->number == sleepmem_wakeup_pin) { alarm->pin = mcu_pin_globals.map.table[i].value; break; } @@ -147,7 +148,6 @@ static void configure_pins_for_sleep(void) { (void)err; // to suppress unused warning _pinhandler_gpiote_count = 0; - _pinhandler_ev_pin = MYGPIOTE_EV_PIN_UNDEF; nrfx_gpiote_in_config_t cfg = { .sense = NRF_GPIOTE_POLARITY_TOGGLE, diff --git a/ports/nrf/common-hal/alarm/time/TimeAlarm.c b/ports/nrf/common-hal/alarm/time/TimeAlarm.c index e9c536414b..c4b06982bf 100644 --- a/ports/nrf/common-hal/alarm/time/TimeAlarm.c +++ b/ports/nrf/common-hal/alarm/time/TimeAlarm.c @@ -30,6 +30,7 @@ //#include "supervisor/esp_port.h" #include +#include "common-hal/alarm/__init__.h" #include "shared-bindings/alarm/time/TimeAlarm.h" #include "shared-bindings/time/__init__.h" @@ -56,17 +57,31 @@ mp_obj_t alarm_time_timealarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t * } bool alarm_time_timealarm_woke_us_up(void) { - return rtc_woke_up_counter; + return sleepmem_wakeup_event == SLEEPMEM_WAKEUP_BY_TIMER; +} + +int64_t wakeup_time_saved =0; + +int64_t alarm_time_timealarm_get_wakeup_timediff_ms(void) { + if (wakeup_time_saved == 0) { + return -1; + } + return wakeup_time_saved - common_hal_time_monotonic_ms(); +} + +void alarm_time_timealarm_clear_wakeup_time(void) { + wakeup_time_saved = 0; } void alarm_time_timealarm_reset(void) { port_disable_interrupt_after_ticks_ch(1); - rtc_woke_up_counter = 0; + wakeup_time_saved = 0; } void alarm_time_timealarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms) { bool timealarm_set = false; alarm_time_timealarm_obj_t *timealarm = MP_OBJ_NULL; + wakeup_time_saved = 0; for (size_t i = 0; i < n_alarms; i++) { if (!MP_OBJ_IS_TYPE(alarms[i], &alarm_time_timealarm_type)) { @@ -82,17 +97,8 @@ void alarm_time_timealarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_ return; } - // Compute how long to actually sleep, considering the time now. - mp_float_t now_secs = uint64_to_float(common_hal_time_monotonic_ms()) / 1000.0f; - mp_float_t wakeup_in_secs = MAX(0.0f, timealarm->monotonic_time - now_secs); - int wsecs = (int)(wakeup_in_secs); - // timealarm is implemented by RTC, which is a 24bit counter - // running at 32768Hz. So, 2^24 / 32768 = 512sec is an upper limit. - if (wsecs >= 512) { - mp_raise_ValueError(translate("Alarm time must be < 512 seconds.")); - } - - uint32_t wakeup_in_ticks = (uint32_t)(wakeup_in_secs * 1024.0f); - port_interrupt_after_ticks_ch(1, wakeup_in_ticks); - rtc_woke_up_counter = 0; + wakeup_time_saved = (int64_t)(timealarm->monotonic_time * 1000.0f); +} + +void alarm_time_timealarm_prepare_for_deep_sleep(void) { } diff --git a/ports/nrf/common-hal/alarm/time/TimeAlarm.h b/ports/nrf/common-hal/alarm/time/TimeAlarm.h index 14a2ff80cf..a824c52535 100644 --- a/ports/nrf/common-hal/alarm/time/TimeAlarm.h +++ b/ports/nrf/common-hal/alarm/time/TimeAlarm.h @@ -42,3 +42,9 @@ mp_obj_t alarm_time_timealarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t * bool alarm_time_timealarm_woke_us_up(void); void alarm_time_timealarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms); void alarm_time_timealarm_reset(void); + +extern void alarm_time_timealarm_prepare_for_deep_sleep(void); +extern int64_t alarm_time_timealarm_get_wakeup_timediff_ms(void); +extern void alarm_time_timealarm_clear_wakeup_time(void); +extern void dbg_dump_RTCreg(void); +extern void tick_set_prescaler(uint32_t prescaler_val); diff --git a/ports/nrf/supervisor/debug_uart.c b/ports/nrf/supervisor/debug_uart.c index dda03a00af..f920cdae32 100644 --- a/ports/nrf/supervisor/debug_uart.c +++ b/ports/nrf/supervisor/debug_uart.c @@ -21,9 +21,9 @@ #include "nrfx_rtc.h" #include "supervisor/serial.h" // dbg_printf() #include "shared-bindings/microcontroller/Processor.h" +#include "common-hal/alarm/__init__.h" extern const nrfx_rtc_t rtc_instance; // port.c -extern volatile int rtc_woke_up_counter; // port.c extern uint32_t reset_reason_saved; const nrfx_uarte_t _dbg_uart_inst = NRFX_UARTE_INSTANCE(1); @@ -31,6 +31,16 @@ static int _dbg_uart_initialized = 0; #define DBG_PBUF_LEN 80 static char _dbg_pbuf[DBG_PBUF_LEN+1]; +void _debug_uart_uninit(void) { + nrf_gpio_cfg(DEBUG_UART_TXPIN, + NRF_GPIO_PIN_DIR_INPUT, + NRF_GPIO_PIN_INPUT_DISCONNECT, + NRF_GPIO_PIN_NOPULL, + NRF_GPIO_PIN_S0S1, + NRF_GPIO_PIN_NOSENSE); + nrfx_uarte_uninit(&_dbg_uart_inst); +} + void _debug_uart_init(void) { //if (_dbg_uart_initialized) return; nrfx_uarte_config_t config = { @@ -55,6 +65,16 @@ void _debug_uart_init(void) { NRF_GPIO_PIN_H0H1, // orig=S0S1 NRF_GPIO_PIN_NOSENSE); _dbg_uart_initialized = 1; +#if 1 //XXX + #define DBGPIN 6+32 + nrf_gpio_cfg(DBGPIN, + NRF_GPIO_PIN_DIR_OUTPUT, + NRF_GPIO_PIN_INPUT_DISCONNECT, + NRF_GPIO_PIN_NOPULL, + NRF_GPIO_PIN_H0H1, + NRF_GPIO_PIN_NOSENSE); + nrf_gpio_pin_write(DBGPIN, 1); +#endif return; } @@ -97,7 +117,15 @@ void dbg_dump_RTCreg(void) { dbg_printf("EVTENSET=%08X\r\n", (int)r->EVTENSET); dbg_printf("EVENTS_COMPARE[0..3]=%X,%X,%X,%X ", (int)r->EVENTS_COMPARE[0], (int)r->EVENTS_COMPARE[1], (int)r->EVENTS_COMPARE[2], (int)r->EVENTS_COMPARE[3]); dbg_printf("CC[0..3]=%08X,%08X,%08X,%08X\r\n", (int)r->CC[0], (int)r->CC[1], (int)r->CC[2], (int)r->CC[3]); - dbg_printf("woke_up=%d\r\n", rtc_woke_up_counter); +} + +int dbg_check_RTCprescaler(void) { + NRF_RTC_Type *r = rtc_instance.p_reg; + if ((int)r->PRESCALER == 0) { + dbg_printf("****** PRESCALER == 0\r\n"); + return -1; + } + return 0; } void dbg_dump_RAMreg(void) { diff --git a/ports/nrf/supervisor/port.c b/ports/nrf/supervisor/port.c index 5908683008..d5efa92b46 100644 --- a/ports/nrf/supervisor/port.c +++ b/ports/nrf/supervisor/port.c @@ -51,6 +51,7 @@ #include "common-hal/rtc/RTC.h" #include "common-hal/neopixel_write/__init__.h" #include "common-hal/watchdog/WatchDogTimer.h" +#include "common-hal/alarm/__init__.h" #include "shared-bindings/microcontroller/__init__.h" #include "shared-bindings/rtc/__init__.h" @@ -75,13 +76,13 @@ static void power_warning_handler(void) { #ifdef NRF_DEBUG_PRINT extern void _debug_uart_init(void); +#define DBGPIN 6+32 //XXX P1_06 = TP1 #endif uint32_t reset_reason_saved = 0; const nrfx_rtc_t rtc_instance = NRFX_RTC_INSTANCE(2); -volatile int rtc_woke_up_counter = 0; -const nrfx_rtc_config_t rtc_config = { +nrfx_rtc_config_t rtc_config = { .prescaler = RTC_FREQ_TO_PRESCALER(0x8000), .reliable = 0, .tick_latency = 0, @@ -97,6 +98,11 @@ static volatile struct { } overflow_tracker __attribute__((section(".uninitialized"))); void rtc_handler(nrfx_rtc_int_type_t int_type) { +#ifdef NRF_DEBUG_PRINT + if (int_type == NRFX_RTC_INT_TICK) { + nrf_gpio_pin_toggle(DBGPIN); //XXX + } +#endif if (int_type == NRFX_RTC_INT_OVERFLOW) { // Our RTC is 24 bits and we're clocking it at 32.768khz which is 32 (2 ** 5) subticks per // tick. @@ -108,7 +114,7 @@ void rtc_handler(nrfx_rtc_int_type_t int_type) { nrfx_rtc_cc_set(&rtc_instance, 0, 0, false); } else if (int_type == NRFX_RTC_INT_COMPARE1) { // used in light sleep - ++rtc_woke_up_counter; + sleepmem_wakeup_event = SLEEPMEM_WAKEUP_BY_TIMER; nrfx_rtc_cc_set(&rtc_instance, 1, 0, false); } } @@ -134,6 +140,22 @@ void tick_init(void) { } } +void tick_uninit(void) { + nrfx_rtc_counter_clear(&rtc_instance); + nrfx_rtc_disable(&rtc_instance); + nrfx_rtc_uninit(&rtc_instance); +} + +void tick_set_prescaler(uint32_t prescaler_val) { + tick_uninit(); + // update of prescaler value sometimes fails if we skip this delay.. + NRFX_DELAY_US(1000); + uint16_t prescaler_saved = rtc_config.prescaler; + rtc_config.prescaler = prescaler_val; + tick_init(); + rtc_config.prescaler = prescaler_saved; +} + safe_mode_t port_init(void) { nrf_peripherals_clocks_init(); @@ -166,6 +188,10 @@ safe_mode_t port_init(void) { reset_reason_saved = NRF_POWER->RESETREAS; // clear all RESET reason bits NRF_POWER->RESETREAS = reset_reason_saved; + // clear wakeup event/pin when reset by reset-pin + if (reset_reason_saved & NRF_POWER_RESETREAS_RESETPIN_MASK) { + sleepmem_wakeup_event = SLEEPMEM_WAKEUP_BY_NONE; + } // If the board was reset by the WatchDogTimer, we may // need to boot into safe mode. Reset the RESETREAS bit