address review comments

This commit is contained in:
Dan Halbert 2020-12-01 20:01:14 -05:00
parent 28d9e9186e
commit 8b7c23c1ee
20 changed files with 160 additions and 103 deletions

View File

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

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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)
/*

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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