new wait-until-alarm design, don't use System OFF.

This commit is contained in:
jun2sak 2021-03-07 01:09:54 +09:00
parent 7bb789625e
commit 3fab9f8b1b
10 changed files with 274 additions and 67 deletions

1
main.c
View File

@ -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
}
}
}

View File

@ -27,6 +27,7 @@
#include <string.h>
#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);
}

View File

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

View File

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

View File

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

View File

@ -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,

View File

@ -30,6 +30,7 @@
//#include "supervisor/esp_port.h"
#include <stdio.h>
#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) {
}

View File

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

View File

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

View File

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