diff options
| author | Scott Shawcroft <scott@adafruit.com> | 2020-12-14 17:40:02 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-12-14 17:40:02 -0800 |
| commit | d07629665903c3e4e19a80cbbc4a8ccbd54493de (patch) | |
| tree | 910d34b157c5abe5dc2b5f4dd29fa5451fb28480 | |
| parent | d6ee17c6fd36cb5589d487d3f3d257a53bc805e3 (diff) | |
| parent | e0bb4a808ae1efb30076b4d0dd0991239e361f62 (diff) | |
Merge pull request #3816 from dhalbert/sleepmemory
alarm.sleep_memory + alarm.wake_alarm
| -rw-r--r-- | locale/circuitpython.pot | 17 | ||||
| -rwxr-xr-x | main.c | 12 | ||||
| -rw-r--r-- | ports/esp32s2/common-hal/alarm/SleepMemory.c | 66 | ||||
| -rw-r--r-- | ports/esp32s2/common-hal/alarm/SleepMemory.h | 53 | ||||
| -rw-r--r-- | ports/esp32s2/common-hal/alarm/__init__.c | 16 | ||||
| -rw-r--r-- | ports/esp32s2/common-hal/alarm/__init__.h | 6 | ||||
| -rw-r--r-- | ports/esp32s2/common-hal/alarm/time/TimeAlarm.c | 1 | ||||
| -rw-r--r-- | py/circuitpy_defns.mk | 1 | ||||
| -rw-r--r-- | shared-bindings/alarm/SleepMemory.c | 159 | ||||
| -rw-r--r-- | shared-bindings/alarm/SleepMemory.h | 40 | ||||
| -rw-r--r-- | shared-bindings/alarm/__init__.c | 17 | ||||
| -rw-r--r-- | shared-bindings/alarm/__init__.h | 5 |
12 files changed, 376 insertions, 17 deletions
diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 11ca8c814..93c8edc44 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-12-08 09:56-0800\n" +"POT-Creation-Date: 2020-12-14 11:48-0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -388,7 +388,7 @@ msgstr "" msgid "Array must contain halfwords (type 'H')" msgstr "" -#: shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c msgid "Array values should be single bytes." msgstr "" @@ -522,7 +522,7 @@ msgstr "" msgid "Byte buffer must be 16 bytes." msgstr "" -#: shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c msgid "Bytes must be between 0 and 255." msgstr "" @@ -1696,7 +1696,7 @@ msgstr "" msgid "Size not supported" msgstr "" -#: shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c msgid "Slice and value different lengths." msgstr "" @@ -1911,6 +1911,10 @@ msgstr "" msgid "Unable to write to nvm." msgstr "" +#: shared-bindings/alarm/SleepMemory.c +msgid "Unable to write to sleep_memory." +msgstr "" + #: ports/nrf/common-hal/_bleio/UUID.c msgid "Unexpected nrfx uuid type" msgstr "" @@ -2117,7 +2121,8 @@ msgstr "" msgid "array and index length must be equal" msgstr "" -#: py/objarray.c shared-bindings/nvm/ByteArray.c +#: py/objarray.c shared-bindings/alarm/SleepMemory.c +#: shared-bindings/nvm/ByteArray.c msgid "array/bytes required on right side" msgstr "" @@ -3215,7 +3220,7 @@ msgid "only sample_rate=16000 is supported" msgstr "" #: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c -#: shared-bindings/nvm/ByteArray.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/nvm/ByteArray.c msgid "only slices with step=1 (aka None) are supported" msgstr "" @@ -112,9 +112,6 @@ STATIC void start_mp(supervisor_allocation* heap) { reset_status_led(); autoreload_stop(); supervisor_workflow_reset(); -#if CIRCUITPY_ALARM - alarm_reset(); -#endif // Stack limit should be less than real stack size, so we have a chance // to recover from limit hit. (Limit is measured in bytes.) @@ -158,6 +155,13 @@ STATIC void start_mp(supervisor_allocation* heap) { mp_obj_list_init(mp_sys_argv, 0); + #if CIRCUITPY_ALARM + // Record which alarm woke us up, if any. An object may be created so the heap must be functional. + alarm_save_wakeup_alarm(); + // Reset alarm module only after we retrieved the wakeup alarm. + alarm_reset(); + #endif + #if CIRCUITPY_NETWORK network_module_init(); #endif @@ -285,6 +289,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode) { filesystem_flush(); supervisor_allocation* heap = allocate_remaining_memory(); start_mp(heap); + found_main = maybe_run_list(supported_filenames, &result); #if CIRCUITPY_FULL_BUILD if (!found_main){ @@ -354,7 +359,6 @@ STATIC bool run_code_py(safe_mode_t safe_mode) { serial_write_compressed(translate("Woken up by alarm.\n")); board_init(); supervisor_set_run_reason(RUN_REASON_STARTUP); - // TODO: Reset any volatile memory the user may have access to. return true; } #endif diff --git a/ports/esp32s2/common-hal/alarm/SleepMemory.c b/ports/esp32s2/common-hal/alarm/SleepMemory.c new file mode 100644 index 000000000..38e3de2b6 --- /dev/null +++ b/ports/esp32s2/common-hal/alarm/SleepMemory.c @@ -0,0 +1,66 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 microDev + * Copyright (c) 2020 Dan Halbert for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include <string.h> + +#include "py/runtime.h" +#include "common-hal/alarm/SleepMemory.h" + +#include "esp_log.h" +#include "esp_sleep.h" + +// Data storage for singleton instance of SleepMemory. +// Might be RTC_SLOW_MEM or RTC_FAST_MEM, depending on setting of CONFIG_ESP32S2_RTCDATA_IN_FAST_MEM. +static RTC_DATA_ATTR uint8_t _sleep_mem[SLEEP_MEMORY_LENGTH]; + +void alarm_sleep_memory_reset(void) { + // ESP-IDF build system takes care of doing esp_sleep_pd_config() or the equivalentwith + // the correct settings, depending on which RTC mem we are using. + // https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/api-reference/system/sleep_modes.html#power-down-of-rtc-peripherals-and-memories +} + +uint32_t common_hal_alarm_sleep_memory_get_length(alarm_sleep_memory_obj_t *self) { + return sizeof(_sleep_mem); +} + +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)) { + return false; + } + + memcpy((uint8_t *) (_sleep_mem + 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)) { + return; + } + memcpy(values, (uint8_t *) (_sleep_mem + start_index), len); +} diff --git a/ports/esp32s2/common-hal/alarm/SleepMemory.h b/ports/esp32s2/common-hal/alarm/SleepMemory.h new file mode 100644 index 000000000..bf6713ab8 --- /dev/null +++ b/ports/esp32s2/common-hal/alarm/SleepMemory.h @@ -0,0 +1,53 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Dan Halbert for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_ESP32S2_COMMON_HAL_ALARM_SLEEPMEMORY_H +#define MICROPY_INCLUDED_ESP32S2_COMMON_HAL_ALARM_SLEEPMEMORY_H + +#include "py/obj.h" + +// There are several places we could store persistent data for SleepMemory: +// +// RTC registers: There are a few 32-bit registers maintained during deep sleep. +// We are already using one for saving sleep information during deep sleep. +// +// RTC Fast Memory: 8kB, also used for deep-sleep power-on stub. +// RTC Slow Memory: 8kB, also used for the ULP (tiny co-processor available during sleep). +// +// The ESP-IDF build system takes care of the power management of these regions. +// RTC_DATA_ATTR will allocate storage in RTC_SLOW_MEM unless CONFIG_ESP32S2_RTCDATA_IN_FAST_MEM +// is set. Any memory not allocated by us can be used by the ESP-IDF for heap or other purposes. + +// Use half of RTC_SLOW_MEM or RTC_FAST_MEM. +#define SLEEP_MEMORY_LENGTH (4096) + +typedef struct { + mp_obj_base_t base; +} alarm_sleep_memory_obj_t; + +extern void alarm_sleep_memory_reset(void); + +#endif // MICROPY_INCLUDED_ESP32S2_COMMON_HAL_ALARM_SLEEPMEMORY_H diff --git a/ports/esp32s2/common-hal/alarm/__init__.c b/ports/esp32s2/common-hal/alarm/__init__.c index 529179200..fae921db0 100644 --- a/ports/esp32s2/common-hal/alarm/__init__.c +++ b/ports/esp32s2/common-hal/alarm/__init__.c @@ -1,10 +1,10 @@ - /* +/* * This file is part of the MicroPython project, http://micropython.org/ * * The MIT License (MIT) * - * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries - * Copyright (c) 2019 Lucian Copeland for Adafruit Industries + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * Copyright (c) 2020 Dan Halbert for Adafruit Industries * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -30,6 +30,7 @@ #include "py/runtime.h" #include "shared-bindings/alarm/pin/PinAlarm.h" +#include "shared-bindings/alarm/SleepMemory.h" #include "shared-bindings/alarm/time/TimeAlarm.h" #include "shared-bindings/microcontroller/__init__.h" #include "shared-bindings/wifi/__init__.h" @@ -41,8 +42,17 @@ #include "esp_sleep.h" +// Singleton instance of SleepMemory. +const alarm_sleep_memory_obj_t alarm_sleep_memory_obj = { + .base = { + .type = &alarm_sleep_memory_type, + }, +}; + + void alarm_reset(void) { alarm_time_timealarm_reset(); + alarm_sleep_memory_reset(); esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_ALL); } diff --git a/ports/esp32s2/common-hal/alarm/__init__.h b/ports/esp32s2/common-hal/alarm/__init__.h index 5678a0e7f..0823ff842 100644 --- a/ports/esp32s2/common-hal/alarm/__init__.h +++ b/ports/esp32s2/common-hal/alarm/__init__.h @@ -27,6 +27,10 @@ #ifndef MICROPY_INCLUDED_ESP32S2_COMMON_HAL_ALARM__INIT__H #define MICROPY_INCLUDED_ESP32S2_COMMON_HAL_ALARM__INIT__H -void alarm_reset(void); +#include "common-hal/alarm/SleepMemory.h" + +const alarm_sleep_memory_obj_t alarm_sleep_memory_obj; + +extern void alarm_reset(void); #endif // MICROPY_INCLUDED_ESP32S2_COMMON_HAL_ALARM__INIT__H diff --git a/ports/esp32s2/common-hal/alarm/time/TimeAlarm.c b/ports/esp32s2/common-hal/alarm/time/TimeAlarm.c index d5e896c01..4d0bba238 100644 --- a/ports/esp32s2/common-hal/alarm/time/TimeAlarm.c +++ b/ports/esp32s2/common-hal/alarm/time/TimeAlarm.c @@ -52,6 +52,7 @@ mp_obj_t alarm_time_timealarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t * alarm_time_time_alarm_obj_t *timer = m_new_obj(alarm_time_time_alarm_obj_t); timer->base.type = &alarm_time_time_alarm_type; // TODO: Set monotonic_time based on the RTC state. + timer->monotonic_time = 0.0f; return timer; } diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index e9253682e..1eafce259 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -304,6 +304,7 @@ SRC_COMMON_HAL_ALL = \ _bleio/__init__.c \ _pew/PewPew.c \ _pew/__init__.c \ + alarm/SleepMemory.c \ alarm/__init__.c \ alarm/pin/PinAlarm.c \ alarm/time/TimeAlarm.c \ diff --git a/shared-bindings/alarm/SleepMemory.c b/shared-bindings/alarm/SleepMemory.c new file mode 100644 index 000000000..bec0b7665 --- /dev/null +++ b/shared-bindings/alarm/SleepMemory.c @@ -0,0 +1,159 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * Copyright (c) 2020 Dan Halbert for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/binary.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "py/runtime0.h" + +#include "shared-bindings/alarm/SleepMemory.h" +#include "supervisor/shared/translate.h" + +//| class SleepMemory: +//| """Store raw bytes in RAM that persists during deep sleep. +//| The class acts as a ``bytearray``. +//| If power is lost, the memory contents are lost. +//| +//| Note that this class can't be imported and used directly. The sole +//| instance of :class:`SleepMemory` is available at +//| :attr:`alarm.sleep_memory`. +//| +//| Usage:: +//| +//| import alarm +//| alarm.sleep_memory[0] = True +//| alarm.sleep_memory[1] = 12 +//| """ + +//| def __init__(self) -> None: +//| """Not used. Access the sole instance through `alarm.sleep_memory`.""" +//| ... +//| + +STATIC const mp_rom_map_elem_t alarm_sleep_memory_locals_dict_table[] = { +}; + +STATIC MP_DEFINE_CONST_DICT(alarm_sleep_memory_locals_dict, alarm_sleep_memory_locals_dict_table); + +//| @overload +//| def __getitem__(self, index: slice) -> bytearray: ... +//| @overload +//| def __getitem__(self, index: int) -> int: +//| """Returns the value at the given index.""" +//| ... +//| +//| @overload +//| def __setitem__(self, index: slice, value: ReadableBuffer) -> None: ... +//| @overload +//| def __setitem__(self, index: int, value: int) -> None: +//| """Set the value at the given index.""" +//| ... +//| +STATIC mp_obj_t alarm_sleep_memory_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value) { + if (value == MP_OBJ_NULL) { + // delete item + // slice deletion + return MP_OBJ_NULL; // op not supported + } else { + alarm_sleep_memory_obj_t *self = MP_OBJ_TO_PTR(self_in); + if (0) { +#if MICROPY_PY_BUILTINS_SLICE + } else if (MP_OBJ_IS_TYPE(index_in, &mp_type_slice)) { + mp_bound_slice_t slice; + if (!mp_seq_get_fast_slice_indexes(common_hal_alarm_sleep_memory_get_length(self), index_in, &slice)) { + mp_raise_NotImplementedError(translate("only slices with step=1 (aka None) are supported")); + } + if (value != MP_OBJ_SENTINEL) { + #if MICROPY_PY_ARRAY_SLICE_ASSIGN + // Assign + size_t src_len = slice.stop - slice.start; + uint8_t* src_items; + if (MP_OBJ_IS_TYPE(value, &mp_type_array) || + MP_OBJ_IS_TYPE(value, &mp_type_bytearray) || + MP_OBJ_IS_TYPE(value, &mp_type_memoryview) || + MP_OBJ_IS_TYPE(value, &mp_type_bytes)) { + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(value, &bufinfo, MP_BUFFER_READ); + if (bufinfo.len != src_len) { + mp_raise_ValueError(translate("Slice and value different lengths.")); + } + src_len = bufinfo.len; + src_items = bufinfo.buf; + if (1 != mp_binary_get_size('@', bufinfo.typecode, NULL)) { + mp_raise_ValueError(translate("Array values should be single bytes.")); + } + } else { + mp_raise_NotImplementedError(translate("array/bytes required on right side")); + } + + if (!common_hal_alarm_sleep_memory_set_bytes(self, slice.start, src_items, src_len)) { + mp_raise_RuntimeError(translate("Unable to write to sleep_memory.")); + } + return mp_const_none; + #else + return MP_OBJ_NULL; // op not supported + #endif + } else { + // Read slice. + size_t len = slice.stop - slice.start; + uint8_t *items = m_new(uint8_t, len); + common_hal_alarm_sleep_memory_get_bytes(self, slice.start, items, len); + return mp_obj_new_bytearray_by_ref(len, items); + } +#endif + } else { + // Single index rather than slice. + size_t index = mp_get_index(self->base.type, common_hal_alarm_sleep_memory_get_length(self), + index_in, false); + if (value == MP_OBJ_SENTINEL) { + // load + uint8_t value_out; + common_hal_alarm_sleep_memory_get_bytes(self, index, &value_out, 1); + return MP_OBJ_NEW_SMALL_INT(value_out); + } else { + // store + mp_int_t byte_value = mp_obj_get_int(value); + if (byte_value > 0xff || byte_value < 0) { + mp_raise_ValueError(translate("Bytes must be between 0 and 255.")); + } + uint8_t short_value = byte_value; + if (!common_hal_alarm_sleep_memory_set_bytes(self, index, &short_value, 1)) { + mp_raise_RuntimeError(translate("Unable to write to sleep_memory.")); + } + return mp_const_none; + } + } + } +} + +const mp_obj_type_t alarm_sleep_memory_type = { + { &mp_type_type }, + .name = MP_QSTR_SleepMemory, + .subscr = alarm_sleep_memory_subscr, + .print = NULL, + .locals_dict = (mp_obj_t)&alarm_sleep_memory_locals_dict, +}; diff --git a/shared-bindings/alarm/SleepMemory.h b/shared-bindings/alarm/SleepMemory.h new file mode 100644 index 000000000..e7a56521b --- /dev/null +++ b/shared-bindings/alarm/SleepMemory.h @@ -0,0 +1,40 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_SLEEPMEMORY_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_SLEEPMEMORY_H + +#include "common-hal/alarm/SleepMemory.h" + +extern const mp_obj_type_t alarm_sleep_memory_type; + +uint32_t common_hal_alarm_sleep_memory_get_length(alarm_sleep_memory_obj_t *self); + +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); +void common_hal_alarm_sleep_memory_get_bytes(alarm_sleep_memory_obj_t *self, uint32_t start_index, uint8_t* values, uint32_t len); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_SLEEPMEMORY_H diff --git a/shared-bindings/alarm/__init__.c b/shared-bindings/alarm/__init__.c index 5420b8404..700fe020e 100644 --- a/shared-bindings/alarm/__init__.c +++ b/shared-bindings/alarm/__init__.c @@ -29,6 +29,7 @@ #include "py/runtime.h" #include "shared-bindings/alarm/__init__.h" +#include "shared-bindings/alarm/SleepMemory.h" #include "shared-bindings/alarm/pin/PinAlarm.h" #include "shared-bindings/alarm/time/TimeAlarm.h" #include "shared-bindings/supervisor/Runtime.h" @@ -57,7 +58,11 @@ //| maintaining the connection takes priority and power consumption may not be reduced. //| """ +//| sleep_memory: SleepMemory +//| """Memory that persists during deep sleep. +//| This object is the sole instance of `alarm.SleepMemory`.""" //| + //| wake_alarm: Alarm //| """The most recently triggered alarm. If CircuitPython was sleeping, the alarm the woke it from sleep.""" //| @@ -177,6 +182,7 @@ STATIC const mp_obj_module_t alarm_time_module = { .globals = (mp_obj_dict_t*)&alarm_time_globals, }; +// The module table is mutable because .wake_alarm is a mutable attribute. STATIC mp_map_elem_t alarm_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_alarm) }, @@ -188,12 +194,14 @@ STATIC mp_map_elem_t alarm_module_globals_table[] = { MP_OBJ_FROM_PTR(&alarm_exit_and_deep_sleep_until_alarms_obj) }, { MP_ROM_QSTR(MP_QSTR_pin), MP_OBJ_FROM_PTR(&alarm_pin_module) }, - { MP_ROM_QSTR(MP_QSTR_time), MP_OBJ_FROM_PTR(&alarm_time_module) } + { MP_ROM_QSTR(MP_QSTR_time), MP_OBJ_FROM_PTR(&alarm_time_module) }, + { MP_ROM_QSTR(MP_QSTR_SleepMemory), MP_OBJ_FROM_PTR(&alarm_sleep_memory_type) }, + { MP_ROM_QSTR(MP_QSTR_sleep_memory), MP_OBJ_FROM_PTR(&alarm_sleep_memory_obj) }, }; STATIC MP_DEFINE_MUTABLE_DICT(alarm_module_globals, alarm_module_globals_table); -void common_hal_alarm_set_wake_alarm(mp_obj_t alarm) { +STATIC void alarm_set_wake_alarm(mp_obj_t alarm) { // Equivalent of: // alarm.wake_alarm = alarm mp_map_elem_t *elem = @@ -203,6 +211,11 @@ void common_hal_alarm_set_wake_alarm(mp_obj_t alarm) { } } +// Initialize .wake_alarm value. +void alarm_save_wakeup_alarm(void) { + alarm_set_wake_alarm(common_hal_alarm_get_wake_alarm()); +} + const mp_obj_module_t alarm_module = { .base = { &mp_type_module }, .globals = (mp_obj_dict_t*)&alarm_module_globals, diff --git a/shared-bindings/alarm/__init__.h b/shared-bindings/alarm/__init__.h index 5a8c613d9..8c4b6cad9 100644 --- a/shared-bindings/alarm/__init__.h +++ b/shared-bindings/alarm/__init__.h @@ -43,8 +43,11 @@ extern void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj // Deep sleep is entered outside of the VM so we omit the `common_hal_` prefix. extern NORETURN void alarm_enter_deep_sleep(void); +extern mp_obj_t common_hal_alarm_get_wake_alarm(void); + // Used by wake-up code. -extern void common_hal_alarm_set_wake_alarm(mp_obj_t alarm); +void alarm_save_wakeup_alarm(void); + // True if an alarm is alerting. This is most useful for pretend deep sleep. extern bool alarm_woken_from_sleep(void); |
