address review comments
This commit is contained in:
parent
28d9e9186e
commit
8b7c23c1ee
@ -101,7 +101,7 @@ STATIC int parse_compile_execute(const void *source, mp_parse_input_kind_t input
|
||||
#endif
|
||||
}
|
||||
|
||||
// If the code was loaded from a file its likely to be running for a while so we'll long
|
||||
// If the code was loaded from a file it's likely to be running for a while so we'll long
|
||||
// live it and collect any garbage before running.
|
||||
if (input_kind == MP_PARSE_FILE_INPUT) {
|
||||
module_fun = make_obj_long_lived(module_fun, 6);
|
||||
@ -132,6 +132,10 @@ STATIC int parse_compile_execute(const void *source, mp_parse_input_kind_t input
|
||||
if (mp_obj_is_subclass_fast(mp_obj_get_type((mp_obj_t)nlr.ret_val), &mp_type_SystemExit)) {
|
||||
// at the moment, the value of SystemExit is unused
|
||||
ret = pyexec_system_exit;
|
||||
#if CIRCUITPY_ALARM
|
||||
} else if (mp_obj_is_subclass_fast(mp_obj_get_type((mp_obj_t)nlr.ret_val), &mp_type_DeepSleepRequest)) {
|
||||
ret = PYEXEC_DEEP_SLEEP;
|
||||
#endif
|
||||
} else {
|
||||
if ((mp_obj_t) nlr.ret_val != MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_reload_exception))) {
|
||||
mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val);
|
||||
|
@ -49,6 +49,7 @@ extern int pyexec_system_exit;
|
||||
#define PYEXEC_FORCED_EXIT (0x100)
|
||||
#define PYEXEC_SWITCH_MODE (0x200)
|
||||
#define PYEXEC_EXCEPTION (0x400)
|
||||
#define PYEXEC_DEEP_SLEEP (0x800)
|
||||
|
||||
int pyexec_raw_repl(void);
|
||||
int pyexec_friendly_repl(void);
|
||||
|
10
main.c
10
main.c
@ -291,11 +291,21 @@ STATIC bool run_code_py(safe_mode_t safe_mode) {
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// TODO: on deep sleep, make sure display is refreshed before sleeping (for e-ink).
|
||||
|
||||
cleanup_after_vm(heap);
|
||||
|
||||
if (result.return_code & PYEXEC_FORCED_EXIT) {
|
||||
return reload_requested;
|
||||
}
|
||||
|
||||
#if CIRCUITPY_ALARM
|
||||
if (result.return_code & PYEXEC_DEEP_SLEEP) {
|
||||
common_hal_alarm_enter_deep_sleep();
|
||||
// Does not return.
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Program has finished running.
|
||||
|
@ -352,5 +352,5 @@ void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) {
|
||||
}
|
||||
|
||||
mcu_reset_reason_t common_hal_mcu_processor_get_reset_reason(void) {
|
||||
return RESET_REASON_POWER_ON;
|
||||
return RESET_REASON_UNKNOWN;
|
||||
}
|
||||
|
@ -50,5 +50,5 @@ void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) {
|
||||
}
|
||||
|
||||
mcu_reset_reason_t common_hal_mcu_processor_get_reset_reason(void) {
|
||||
return RESET_REASON_POWER_ON;
|
||||
return RESET_REASON_UNKNOWN;
|
||||
}
|
||||
|
@ -29,15 +29,16 @@
|
||||
#include "py/objtuple.h"
|
||||
#include "py/runtime.h"
|
||||
|
||||
#include "shared-bindings/alarm/__init__.h"
|
||||
#include "shared-bindings/alarm/pin/PinAlarm.h"
|
||||
#include "shared-bindings/alarm/time/TimeAlarm.h"
|
||||
#include "shared-bindings/microcontroller/__init__.h"
|
||||
#include "shared-bindings/time/__init__.h"
|
||||
#include "shared-bindings/wifi/__init__.h"
|
||||
|
||||
#include "common-hal/alarm/__init__.h"
|
||||
|
||||
#include "esp_log.h"
|
||||
#include "esp_sleep.h"
|
||||
#include "esp_wifi.h"
|
||||
|
||||
STATIC mp_obj_tuple_t *_deep_sleep_alarms;
|
||||
|
||||
@ -101,7 +102,7 @@ STATIC void setup_sleep_alarms(size_t n_alarms, const mp_obj_t *alarms) {
|
||||
mp_float_t now_secs = uint64_to_float(common_hal_time_monotonic_ms()) / 1000.0f;
|
||||
mp_float_t wakeup_in_secs = MAX(0.0f, time_alarm->monotonic_time - now_secs);
|
||||
const uint64_t sleep_for_us = (uint64_t) (wakeup_in_secs * 1000000);
|
||||
ESP_LOGI("ALARM", "Sleep for us: %lld", sleep_for_us);
|
||||
ESP_LOGI("ALARM", "will sleep for us: %lld", sleep_for_us);
|
||||
esp_sleep_enable_timer_wakeup(sleep_for_us);
|
||||
}
|
||||
}
|
||||
@ -157,25 +158,41 @@ mp_obj_t common_hal_alarm_wait_until_alarms(size_t n_alarms, const mp_obj_t *ala
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
mp_obj_t common_hal_alarm_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms) {
|
||||
// Is it safe to do a light sleep? Check whether WiFi is on or there are
|
||||
// other ongoing tasks that should not be shut down.
|
||||
static bool light_sleep_ok(void) {
|
||||
return !common_hal_wifi_radio_get_enabled(&common_hal_wifi_radio_obj);
|
||||
}
|
||||
|
||||
mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms) {
|
||||
if (n_alarms == 0) {
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
setup_sleep_alarms(n_alarms, alarms);
|
||||
|
||||
// Shut down wifi cleanly.
|
||||
esp_wifi_stop();
|
||||
ESP_LOGI("ALARM", "start light sleep");
|
||||
esp_light_sleep_start();
|
||||
return common_hal_alarm_get_wake_alarm();
|
||||
if (light_sleep_ok()) {
|
||||
ESP_LOGI("ALARM", "start light sleep");
|
||||
setup_sleep_alarms(n_alarms, alarms);
|
||||
esp_light_sleep_start();
|
||||
return common_hal_alarm_get_wake_alarm();
|
||||
} else {
|
||||
// Don't do an ESP32 light sleep.
|
||||
return common_hal_alarm_wait_until_alarms(n_alarms, alarms);
|
||||
}
|
||||
}
|
||||
|
||||
void common_hal_alarm_exit_and_deep_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms) {
|
||||
setup_sleep_alarms(n_alarms, alarms);
|
||||
|
||||
// Shut down wifi cleanly.
|
||||
esp_wifi_stop();
|
||||
// Raise an exception, which will be processed in main.c.
|
||||
mp_raise_arg1(&mp_type_DeepSleepRequest, NULL);
|
||||
}
|
||||
|
||||
void common_hal_alarm_prepare_for_deep_sleep(void) {
|
||||
// Turn off WiFi and anything else that should be shut down cleanly.
|
||||
common_hal_wifi_radio_set_enabled(&common_hal_wifi_radio_obj, false);
|
||||
}
|
||||
|
||||
void NORETURN common_hal_alarm_enter_deep_sleep(void) {
|
||||
ESP_LOGI("ALARM", "start deep sleep");
|
||||
esp_deep_sleep_start();
|
||||
}
|
||||
|
@ -29,26 +29,21 @@
|
||||
#include "shared-bindings/alarm/pin/PinAlarm.h"
|
||||
#include "shared-bindings/microcontroller/Pin.h"
|
||||
|
||||
void common_hal_alarm_pin_pin_alarm_construct(alarm_pin_pin_alarm_obj_t *self, const mp_obj_t pins[], size_t num_pins, bool value, bool all_same_value, bool edge, bool pull) {
|
||||
self->pins = mp_obj_new_tuple(num_pins, pins);
|
||||
void common_hal_alarm_pin_pin_alarm_construct(alarm_pin_pin_alarm_obj_t *self, mcu_pin_obj_t *pin, bool value, bool edge, bool pull) {
|
||||
self->pin = pin;
|
||||
self->value = value;
|
||||
self->all_same_value = all_same_value;
|
||||
self->edge = edge;
|
||||
self->pull = pull;
|
||||
}
|
||||
|
||||
mp_obj_tuple_t *common_hal_alarm_pin_pin_alarm_get_pins(alarm_pin_pin_alarm_obj_t *self) {
|
||||
return self->pins;
|
||||
mcu_pin_obj_t *common_hal_alarm_pin_pin_alarm_get_pin(alarm_pin_pin_alarm_obj_t *self) {
|
||||
return self->pin;
|
||||
}
|
||||
|
||||
bool common_hal_alarm_pin_pin_alarm_get_value(alarm_pin_pin_alarm_obj_t *self) {
|
||||
return self->value;
|
||||
}
|
||||
|
||||
bool common_hal_alarm_pin_pin_alarm_get_all_same_value(alarm_pin_pin_alarm_obj_t *self) {
|
||||
return self->all_same_value;
|
||||
}
|
||||
|
||||
bool common_hal_alarm_pin_pin_alarm_get_edge(alarm_pin_pin_alarm_obj_t *self) {
|
||||
return self->edge;
|
||||
}
|
||||
|
@ -29,7 +29,7 @@
|
||||
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
mp_obj_tuple_t *pins;
|
||||
mcu_pin_obj_t *pin;
|
||||
bool value;
|
||||
bool all_same_value;
|
||||
bool edge;
|
||||
|
@ -66,5 +66,5 @@ void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) {
|
||||
}
|
||||
|
||||
mcu_reset_reason_t common_hal_mcu_processor_get_reset_reason(void) {
|
||||
return RESET_REASON_POWER_ON;
|
||||
return RESET_REASON_UNKNOWN;
|
||||
}
|
||||
|
@ -73,5 +73,5 @@ void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) {
|
||||
}
|
||||
|
||||
mcu_reset_reason_t common_hal_mcu_processor_get_reset_reason(void) {
|
||||
return RESET_REASON_POWER_ON;
|
||||
return RESET_REASON_UNKNOWN;
|
||||
}
|
||||
|
@ -123,5 +123,5 @@ void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) {
|
||||
}
|
||||
|
||||
mcu_reset_reason_t common_hal_mcu_processor_get_reset_reason(void) {
|
||||
return RESET_REASON_POWER_ON;
|
||||
return RESET_REASON_UNKNOWN;
|
||||
}
|
||||
|
@ -143,5 +143,5 @@ void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) {
|
||||
}
|
||||
|
||||
mcu_reset_reason_t common_hal_mcu_processor_get_reset_reason(void) {
|
||||
return RESET_REASON_POWER_ON;
|
||||
return RESET_REASON_UNKNOWN;
|
||||
}
|
||||
|
4
py/obj.h
4
py/obj.h
@ -640,6 +640,10 @@ extern const mp_obj_type_t mp_type_UnicodeError;
|
||||
extern const mp_obj_type_t mp_type_ValueError;
|
||||
extern const mp_obj_type_t mp_type_ViperTypeError;
|
||||
extern const mp_obj_type_t mp_type_ZeroDivisionError;
|
||||
#if CIRCUITPY_ALARM
|
||||
extern const mp_obj_type_t mp_type_DeepSleepRequest;
|
||||
#endif
|
||||
|
||||
|
||||
// Constant objects, globally accessible
|
||||
// The macros are for convenience only
|
||||
|
@ -318,6 +318,9 @@ MP_DEFINE_EXCEPTION(Exception, BaseException)
|
||||
#if MICROPY_PY_BUILTINS_STR_UNICODE
|
||||
MP_DEFINE_EXCEPTION(UnicodeError, ValueError)
|
||||
//TODO: Implement more UnicodeError subclasses which take arguments
|
||||
#endif
|
||||
#if CIRCUITPY_ALARM
|
||||
MP_DEFINE_EXCEPTION(DeepSleepRequest, BaseException)
|
||||
#endif
|
||||
MP_DEFINE_EXCEPTION(MpyError, ValueError)
|
||||
/*
|
||||
|
22
py/reload.c
22
py/reload.c
@ -1,6 +1,22 @@
|
||||
//
|
||||
// Created by Roy Hooper on 2018-05-14.
|
||||
//
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2018 by Roy Hooper
|
||||
* 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 "reload.h"
|
||||
#include "py/mpstate.h"
|
||||
|
22
py/reload.h
22
py/reload.h
@ -1,6 +1,22 @@
|
||||
//
|
||||
// Created by Roy Hooper on 2018-05-14.
|
||||
//
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2018 by Roy Hooper
|
||||
* 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 CIRCUITPYTHON_RELOAD_H
|
||||
#define CIRCUITPYTHON_RELOAD_H
|
||||
|
@ -43,19 +43,21 @@
|
||||
//|
|
||||
//| Provides alarms that trigger based on time intervals or on external events, such as pin
|
||||
//| changes.
|
||||
//| The program can simply wait for these alarms, or go into a sleep state and
|
||||
//| and be awoken when they trigger.
|
||||
//| The program can simply wait for these alarms, or go to sleep and be awoken when they trigger.
|
||||
//|
|
||||
//| There are two supported levels of sleep: light sleep and deep sleep.
|
||||
//|
|
||||
//| Light sleep leaves the CPU and RAM powered so the program can resume after sleeping.
|
||||
//|
|
||||
//| *However, note that on some platforms, light sleep will shut down some communications, including
|
||||
//| WiFi and/or Bluetooth.*
|
||||
//| Light sleep keeps sufficient state so the program can resume after sleeping.
|
||||
//| It does not shut down WiFi, BLE, or other communications, or ongoing activities such
|
||||
//| as audio playback. It reduces power consumption to the extent possible that leaves
|
||||
//| these continuing activities running. In some cases there may be no decrease in power consumption.
|
||||
//|
|
||||
//| Deep sleep shuts down power to nearly all of the microcontroller including the CPU and RAM. This can save
|
||||
//| a more significant amount of power, but CircuitPython must restart ``code.py`` from the beginning when
|
||||
//| awakened.
|
||||
//|
|
||||
//| For both light sleep and deep sleep, if CircuitPython is connected to a host computer,
|
||||
//| maintaining the connection takes priority and power consumption may not be reduced.
|
||||
//| """
|
||||
|
||||
//|
|
||||
@ -75,45 +77,39 @@ void validate_objs_are_alarms(size_t n_args, const mp_obj_t *objs) {
|
||||
}
|
||||
}
|
||||
|
||||
//| def wait_until_alarms(*alarms: Alarm) -> Alarm:
|
||||
//| """Wait for one of the alarms to trigger. The triggering alarm is returned.
|
||||
//| is returned, and is also available as `alarm.wake_alarm`. Nothing is shut down
|
||||
//| or interrupted. Power consumption will be reduced if possible.
|
||||
//|
|
||||
//| If no alarms are specified, return immediately.
|
||||
//| """
|
||||
//| ...
|
||||
//|
|
||||
STATIC mp_obj_t alarm_wait_until_alarms(size_t n_args, const mp_obj_t *args) {
|
||||
validate_objs_are_alarms(n_args, args);
|
||||
common_hal_alarm_wait_until_alarms(n_args, args);
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(alarm_wait_until_alarms_obj, 1, MP_OBJ_FUN_ARGS_MAX, alarm_wait_until_alarms);
|
||||
|
||||
//| def sleep_until_alarms(*alarms: Alarm) -> Alarm:
|
||||
//| def light_sleep_until_alarms(*alarms: Alarm) -> Alarm:
|
||||
//| """Go into a light sleep until awakened one of the alarms. The alarm causing the wake-up
|
||||
//| is returned, and is also available as `alarm.wake_alarm`.
|
||||
//|
|
||||
//| Some functionality may be shut down during sleep. On ESP32-S2, WiFi is turned off,
|
||||
//| and existing connections are broken.
|
||||
//|
|
||||
//| If no alarms are specified, return immediately.
|
||||
//|
|
||||
//| **If CircuitPython is connected to a host computer,** `alarm.sleep_until_alarms()`
|
||||
//| **does not go into light sleep.**
|
||||
//| Instead, light sleep is simulated by doing `alarm.wait_until_alarms()`,
|
||||
//| **If CircuitPython is connected to a host computer, the connection will be maintained,
|
||||
//| and the microcontroller may not actually go into a light sleep.**
|
||||
//| This allows the user to interrupt an existing program with ctrl-C,
|
||||
//| and to edit the files in CIRCUITPY, which would not be possible in true light sleep
|
||||
//| and to edit the files in CIRCUITPY, which would not be possible in true light sleep.
|
||||
//| Thus, to use light sleep and save significant power,
|
||||
// it may be necessary to disconnect from the host.
|
||||
//| """
|
||||
//| ...
|
||||
//|
|
||||
STATIC mp_obj_t alarm_sleep_until_alarms(size_t n_args, const mp_obj_t *args) {
|
||||
STATIC mp_obj_t alarm_light_sleep_until_alarms(size_t n_args, const mp_obj_t *args) {
|
||||
validate_objs_are_alarms(n_args, args);
|
||||
common_hal_alarm_sleep_until_alarms(n_args, args);
|
||||
|
||||
// See if we are connected to a host.
|
||||
// Make sure we have been awake long enough for USB to connect (enumeration delay).
|
||||
int64_t connecting_delay_msec = CIRCUITPY_USB_CONNECTED_SLEEP_DELAY * 1024 - supervisor_ticks_ms64();
|
||||
if (connecting_delay_msec > 0) {
|
||||
common_hal_time_delay_ms(connecting_delay_msec * 1000 / 1024);
|
||||
}
|
||||
|
||||
if (supervisor_workflow_active()) {
|
||||
common_hal_alarm_wait_until_alarms(n_args, args);
|
||||
} else {
|
||||
common_hal_alarm_light_sleep_until_alarms(n_args, args);
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(alarm_sleep_until_alarms_obj, 1, MP_OBJ_FUN_ARGS_MAX, alarm_sleep_until_alarms);
|
||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(alarm_light_sleep_until_alarms_obj, 1, MP_OBJ_FUN_ARGS_MAX, alarm_light_sleep_until_alarms);
|
||||
|
||||
//| def exit_and_deep_sleep_until_alarms(*alarms: Alarm) -> None:
|
||||
//| """Exit the program and go into a deep sleep, until awakened by one of the alarms.
|
||||
@ -130,11 +126,10 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(alarm_sleep_until_alarms_obj, 1, MP_OBJ_FUN_
|
||||
//| If no alarms are specified, the microcontroller will deep sleep until reset.
|
||||
//|
|
||||
//| **If CircuitPython is connected to a host computer, `alarm.exit_and_deep_sleep_until_alarms()`
|
||||
//| does not go into deep sleep.**
|
||||
//| Instead, deep sleep is simulated by first doing `alarm.wait_until_alarms()`,
|
||||
//| and then, when an alarm triggers, by restarting CircuitPython.
|
||||
//| then the connection will be maintained, and the system will not go into deep sleep.**
|
||||
//| This allows the user to interrupt an existing program with ctrl-C,
|
||||
//| and to edit the files in CIRCUITPY, which would not be possible in true deep sleep.
|
||||
//| Thus, to use deep sleep and save significant power, you will need to disconnect from the host.
|
||||
//|
|
||||
//| Here is skeletal example that deep-sleeps and restarts every 60 seconds:
|
||||
//|
|
||||
@ -156,6 +151,10 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(alarm_sleep_until_alarms_obj, 1, MP_OBJ_FUN_
|
||||
STATIC mp_obj_t alarm_exit_and_deep_sleep_until_alarms(size_t n_args, const mp_obj_t *args) {
|
||||
validate_objs_are_alarms(n_args, args);
|
||||
|
||||
// Shut down WiFi, etc.
|
||||
common_hal_alarm_prepare_for_deep_sleep();
|
||||
|
||||
// See if we are connected to a host.
|
||||
// Make sure we have been awake long enough for USB to connect (enumeration delay).
|
||||
int64_t connecting_delay_msec = CIRCUITPY_USB_CONNECTED_SLEEP_DELAY * 1024 - supervisor_ticks_ms64();
|
||||
if (connecting_delay_msec > 0) {
|
||||
@ -163,6 +162,7 @@ STATIC mp_obj_t alarm_exit_and_deep_sleep_until_alarms(size_t n_args, const mp_o
|
||||
}
|
||||
|
||||
if (supervisor_workflow_active()) {
|
||||
// Simulate deep sleep by waiting for an alarm and then restarting when done.
|
||||
common_hal_alarm_wait_until_alarms(n_args, args);
|
||||
reload_requested = true;
|
||||
supervisor_set_run_reason(RUN_REASON_STARTUP);
|
||||
@ -175,9 +175,6 @@ STATIC mp_obj_t alarm_exit_and_deep_sleep_until_alarms(size_t n_args, const mp_o
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(alarm_exit_and_deep_sleep_until_alarms_obj, 1, MP_OBJ_FUN_ARGS_MAX, alarm_exit_and_deep_sleep_until_alarms);
|
||||
|
||||
//| """The `alarm.pin` module contains alarm attributes and classes related to pins.
|
||||
//| """
|
||||
//|
|
||||
STATIC const mp_map_elem_t alarm_pin_globals_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_pin) },
|
||||
|
||||
@ -191,9 +188,6 @@ STATIC const mp_obj_module_t alarm_pin_module = {
|
||||
.globals = (mp_obj_dict_t*)&alarm_pin_globals,
|
||||
};
|
||||
|
||||
//| """The `alarm.time` module contains alarm attributes and classes related to time-keeping.
|
||||
//| """
|
||||
//|
|
||||
STATIC const mp_map_elem_t alarm_time_globals_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_time) },
|
||||
|
||||
@ -213,7 +207,7 @@ STATIC mp_map_elem_t alarm_module_globals_table[] = {
|
||||
// wake_alarm is a mutable attribute.
|
||||
{ MP_ROM_QSTR(MP_QSTR_wake_alarm), mp_const_none },
|
||||
|
||||
{ MP_ROM_QSTR(MP_QSTR_sleep_until_alarms), MP_OBJ_FROM_PTR(&alarm_sleep_until_alarms_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_light_sleep_until_alarms), MP_OBJ_FROM_PTR(&alarm_light_sleep_until_alarms_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_exit_and_deep_sleep_until_alarms),
|
||||
MP_OBJ_FROM_PTR(&alarm_exit_and_deep_sleep_until_alarms_obj) },
|
||||
|
||||
|
@ -32,8 +32,10 @@
|
||||
#include "common-hal/alarm/__init__.h"
|
||||
|
||||
extern mp_obj_t common_hal_alarm_wait_until_alarms(size_t n_alarms, const mp_obj_t *alarms);
|
||||
extern mp_obj_t common_hal_alarm_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms);
|
||||
extern mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms);
|
||||
extern void common_hal_alarm_exit_and_deep_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms);
|
||||
extern void common_hal_alarm_prepare_for_deep_sleep(void);
|
||||
extern NORETURN void common_hal_alarm_enter_deep_sleep(void);
|
||||
|
||||
// Used by wake-up code.
|
||||
extern void common_hal_alarm_set_wake_alarm(mp_obj_t alarm);
|
||||
|
@ -38,18 +38,16 @@
|
||||
//| class PinAlarm:
|
||||
//| """Trigger an alarm when a pin changes state."""
|
||||
//|
|
||||
//| def __init__(self, *pins: microcontroller.Pin, value: bool, all_same_value: bool = False, edge: bool = False, pull: bool = False) -> None:
|
||||
//| def __init__(self, pin: microcontroller.Pin, value: bool, edge: bool = False, pull: bool = False) -> None:
|
||||
//| """Create an alarm triggered by a `microcontroller.Pin` level. The alarm is not active
|
||||
//| until it is passed to an `alarm`-enabling function, such as `alarm.sleep_until_alarms()` or
|
||||
//| `alarm.exit_and_deep_sleep_until_alarms()`.
|
||||
//|
|
||||
//| :param microcontroller.Pin \*pins: The pins to monitor. On some ports, the choice of pins
|
||||
//| :param microcontroller.Pin pin: The pin to monitor. On some ports, the choice of pin
|
||||
//| may be limited due to hardware restrictions, particularly for deep-sleep alarms.
|
||||
//| :param bool value: When active, trigger when the pin value is high (``True``) or low (``False``).
|
||||
//| On some ports, multiple `PinAlarm` objects may need to have coordinated values
|
||||
//| for deep-sleep alarms.
|
||||
//| :param bool all_same_value: If ``True``, all pins listed must be at ``value`` to trigger the alarm.
|
||||
//| If ``False``, any one of the pins going to ``value`` will trigger the alarm.
|
||||
//| :param bool edge: If ``True``, trigger only when there is a transition to the specified
|
||||
//| value of ``value``. If ``True``, if the alarm becomes active when the pin value already
|
||||
//| matches ``value``, the alarm is not triggered: the pin must transition from ``not value``
|
||||
@ -65,47 +63,44 @@
|
||||
STATIC mp_obj_t alarm_pin_pin_alarm_make_new(const mp_obj_type_t *type, mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
alarm_pin_pin_alarm_obj_t *self = m_new_obj(alarm_pin_pin_alarm_obj_t);
|
||||
self->base.type = &alarm_pin_pin_alarm_type;
|
||||
enum { ARG_value, ARG_all_same_value, ARG_edge, ARG_pull };
|
||||
enum { ARG_pin, ARG_value, ARG_edge, ARG_pull };
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_pin, MP_ARG_REQUIRED | MP_ARG_OBJ },
|
||||
{ MP_QSTR_value, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_BOOL },
|
||||
{ MP_QSTR_all_same_value, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
|
||||
{ MP_QSTR_edge, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
|
||||
{ MP_QSTR_pull, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
|
||||
};
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all(0, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
||||
for (size_t i = 0; i < n_args; i ++) {
|
||||
validate_obj_is_free_pin(pos_args[i]);
|
||||
}
|
||||
mcu_pin_obj_t *pin = validate_obj_is_free_pin(args[ARG_pin].u_obj);
|
||||
|
||||
common_hal_alarm_pin_pin_alarm_construct(
|
||||
self, pos_args, n_args,
|
||||
common_hal_alarm_pin_pin_alarm_construct(self,
|
||||
pin,
|
||||
args[ARG_value].u_bool,
|
||||
args[ARG_all_same_value].u_bool,
|
||||
args[ARG_edge].u_bool,
|
||||
args[ARG_pull].u_bool);
|
||||
|
||||
return MP_OBJ_FROM_PTR(self);
|
||||
}
|
||||
|
||||
//| pins: Tuple[microcontroller.Pin]
|
||||
//| """The trigger pins."""
|
||||
//| pin: microcontroller.Pin
|
||||
//| """The trigger pin."""
|
||||
//|
|
||||
STATIC mp_obj_t alarm_pin_pin_alarm_obj_get_pins(mp_obj_t self_in) {
|
||||
STATIC mp_obj_t alarm_pin_pin_alarm_obj_get_pin(mp_obj_t self_in) {
|
||||
alarm_pin_pin_alarm_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
return common_hal_alarm_pin_pin_alarm_get_pins(self);
|
||||
return common_hal_alarm_pin_pin_alarm_get_pin(self);
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(alarm_pin_pin_alarm_get_pins_obj, alarm_pin_pin_alarm_obj_get_pins);
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(alarm_pin_pin_alarm_get_pin_obj, alarm_pin_pin_alarm_obj_get_pin);
|
||||
|
||||
const mp_obj_property_t alarm_pin_pin_alarm_pins_obj = {
|
||||
const mp_obj_property_t alarm_pin_pin_alarm_pin_obj = {
|
||||
.base.type = &mp_type_property,
|
||||
.proxy = {(mp_obj_t)&alarm_pin_pin_alarm_get_pins_obj,
|
||||
.proxy = {(mp_obj_t)&alarm_pin_pin_alarm_get_pin_obj,
|
||||
(mp_obj_t)&mp_const_none_obj,
|
||||
(mp_obj_t)&mp_const_none_obj},
|
||||
};
|
||||
|
||||
//| value: Tuple[microcontroller.Pin]
|
||||
//| value: bool
|
||||
//| """The value on which to trigger."""
|
||||
//|
|
||||
STATIC mp_obj_t alarm_pin_pin_alarm_obj_get_value(mp_obj_t self_in) {
|
||||
@ -122,7 +117,7 @@ const mp_obj_property_t alarm_pin_pin_alarm_value_obj = {
|
||||
};
|
||||
|
||||
STATIC const mp_rom_map_elem_t alarm_pin_pin_alarm_locals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_pins), MP_ROM_PTR(&alarm_pin_pin_alarm_pins_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_pin), MP_ROM_PTR(&alarm_pin_pin_alarm_pin_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_value), MP_ROM_PTR(&alarm_pin_pin_alarm_value_obj) },
|
||||
};
|
||||
|
||||
|
@ -34,8 +34,8 @@
|
||||
|
||||
extern const mp_obj_type_t alarm_pin_pin_alarm_type;
|
||||
|
||||
void common_hal_alarm_pin_pin_alarm_construct(alarm_pin_pin_alarm_obj_t *self, const mp_obj_t pins[], size_t num_pins, bool value, bool all_same_value, bool edge, bool pull);
|
||||
extern mp_obj_tuple_t *common_hal_alarm_pin_pin_alarm_get_pins(alarm_pin_pin_alarm_obj_t *self);
|
||||
void common_hal_alarm_pin_pin_alarm_construct(alarm_pin_pin_alarm_obj_t *self, mcu_pin_obj_t *pin, bool value, bool edge, bool pull);
|
||||
extern mcu_pin_obj_t *common_hal_alarm_pin_pin_alarm_get_pin(alarm_pin_pin_alarm_obj_t *self);
|
||||
extern bool common_hal_alarm_pin_pin_alarm_get_value(alarm_pin_pin_alarm_obj_t *self);
|
||||
extern bool common_hal_alarm_pin_pin_alarm_get_edge(alarm_pin_pin_alarm_obj_t *self);
|
||||
extern bool common_hal_alarm_pin_pin_alarm_get_pull(alarm_pin_pin_alarm_obj_t *self);
|
||||
|
Loading…
Reference in New Issue
Block a user