commit
171efd55e0
2
.gitmodules
vendored
2
.gitmodules
vendored
@ -152,7 +152,7 @@
|
||||
url = https://github.com/adafruit/Adafruit_CircuitPython_RFM69.git
|
||||
[submodule "ports/esp32s2/esp-idf"]
|
||||
path = ports/esp32s2/esp-idf
|
||||
url = https://github.com/jepler/esp-idf.git
|
||||
url = https://github.com/adafruit/esp-idf.git
|
||||
[submodule "ports/esp32s2/certificates/nina-fw"]
|
||||
path = ports/esp32s2/certificates/nina-fw
|
||||
url = https://github.com/adafruit/nina-fw.git
|
||||
|
@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2020-12-23 16:41-0500\n"
|
||||
"POT-Creation-Date: 2020-12-23 23:04-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"
|
||||
@ -20,7 +20,13 @@ msgstr ""
|
||||
#: main.c
|
||||
msgid ""
|
||||
"\n"
|
||||
"Code done running. Waiting for reload.\n"
|
||||
"Code done running.\n"
|
||||
msgstr ""
|
||||
|
||||
#: main.c
|
||||
msgid ""
|
||||
"\n"
|
||||
"Code stopped by auto-reload.\n"
|
||||
msgstr ""
|
||||
|
||||
#: supervisor/shared/safe_mode.c
|
||||
@ -534,6 +540,18 @@ msgstr ""
|
||||
msgid "Call super().__init__() before accessing native object."
|
||||
msgstr ""
|
||||
|
||||
#: ports/esp32s2/common-hal/alarm/pin/PinAlarm.c
|
||||
msgid "Can only alarm on RTC IO from deep sleep."
|
||||
msgstr ""
|
||||
|
||||
#: ports/esp32s2/common-hal/alarm/pin/PinAlarm.c
|
||||
msgid "Can only alarm on one low pin while others alarm high from deep sleep."
|
||||
msgstr ""
|
||||
|
||||
#: ports/esp32s2/common-hal/alarm/pin/PinAlarm.c
|
||||
msgid "Can only alarm on two low pins from deep sleep."
|
||||
msgstr ""
|
||||
|
||||
#: ports/nrf/common-hal/_bleio/Characteristic.c
|
||||
msgid "Can't set CCCD on local Characteristic"
|
||||
msgstr ""
|
||||
@ -566,6 +584,10 @@ msgstr ""
|
||||
msgid "Cannot output both channels on the same pin"
|
||||
msgstr ""
|
||||
|
||||
#: ports/esp32s2/common-hal/alarm/pin/PinAlarm.c
|
||||
msgid "Cannot pull on input-only pin."
|
||||
msgstr ""
|
||||
|
||||
#: shared-module/bitbangio/SPI.c
|
||||
msgid "Cannot read without MISO pin."
|
||||
msgstr ""
|
||||
@ -609,6 +631,10 @@ msgstr ""
|
||||
msgid "Cannot vary frequency on a timer that is already in use"
|
||||
msgstr ""
|
||||
|
||||
#: ports/esp32s2/common-hal/alarm/pin/PinAlarm.c
|
||||
msgid "Cannot wake on pin edge. Only level."
|
||||
msgstr ""
|
||||
|
||||
#: shared-module/bitbangio/SPI.c
|
||||
msgid "Cannot write without MOSI pin."
|
||||
msgstr ""
|
||||
@ -1458,7 +1484,7 @@ msgid ""
|
||||
"%d bpp given"
|
||||
msgstr ""
|
||||
|
||||
#: ports/esp32s2/common-hal/alarm/__init__.c
|
||||
#: ports/esp32s2/common-hal/alarm/time/TimeAlarm.c
|
||||
msgid "Only one alarm.time alarm can be set."
|
||||
msgstr ""
|
||||
|
||||
@ -1520,10 +1546,6 @@ msgstr ""
|
||||
msgid "Pin number already reserved by EXTI"
|
||||
msgstr ""
|
||||
|
||||
#: ports/esp32s2/common-hal/alarm/__init__.c
|
||||
msgid "PinAlarm not yet implemented"
|
||||
msgstr ""
|
||||
|
||||
#: shared-bindings/rgbmatrix/RGBMatrix.c
|
||||
#, c-format
|
||||
msgid ""
|
||||
@ -1564,7 +1586,7 @@ msgid "Press any key to enter the REPL. Use CTRL-D to reload.\n"
|
||||
msgstr ""
|
||||
|
||||
#: main.c
|
||||
msgid "Pretending to deep sleep until alarm, any key or file write.\n"
|
||||
msgid "Pretending to deep sleep until alarm, CTRL-C or file write.\n"
|
||||
msgstr ""
|
||||
|
||||
#: shared-bindings/digitalio/DigitalInOut.c
|
||||
|
27
main.c
27
main.c
@ -260,10 +260,10 @@ STATIC void print_code_py_status_message(safe_mode_t safe_mode) {
|
||||
STATIC bool run_code_py(safe_mode_t safe_mode) {
|
||||
bool serial_connected_at_start = serial_connected();
|
||||
#if CIRCUITPY_AUTORELOAD_DELAY_MS > 0
|
||||
if (serial_connected_at_start) {
|
||||
serial_write("\n");
|
||||
print_code_py_status_message(safe_mode);
|
||||
}
|
||||
serial_write("\n");
|
||||
print_code_py_status_message(safe_mode);
|
||||
print_safe_mode_message(safe_mode);
|
||||
serial_write("\n");
|
||||
#endif
|
||||
|
||||
pyexec_result_t result;
|
||||
@ -307,16 +307,17 @@ STATIC bool run_code_py(safe_mode_t safe_mode) {
|
||||
if (result.return_code & PYEXEC_FORCED_EXIT) {
|
||||
return reload_requested;
|
||||
}
|
||||
|
||||
if (reload_requested && result.return_code == PYEXEC_EXCEPTION) {
|
||||
serial_write_compressed(translate("\nCode stopped by auto-reload.\n"));
|
||||
} else {
|
||||
serial_write_compressed(translate("\nCode done running.\n"));
|
||||
}
|
||||
}
|
||||
|
||||
// Program has finished running.
|
||||
|
||||
// Display a different completion message if the user has no USB attached (cannot save files)
|
||||
if (!serial_connected_at_start) {
|
||||
serial_write_compressed(translate("\nCode done running. Waiting for reload.\n"));
|
||||
}
|
||||
|
||||
bool serial_connected_before_animation = false;
|
||||
bool serial_connected_before_animation = serial_connected();
|
||||
#if CIRCUITPY_DISPLAYIO
|
||||
bool refreshed_epaper_display = false;
|
||||
#endif
|
||||
@ -409,7 +410,7 @@ STATIC bool run_code_py(safe_mode_t safe_mode) {
|
||||
alarm_enter_deep_sleep();
|
||||
// Does not return.
|
||||
} else {
|
||||
serial_write_compressed(translate("Pretending to deep sleep until alarm, any key or file write.\n"));
|
||||
serial_write_compressed(translate("Pretending to deep sleep until alarm, CTRL-C or file write.\n"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -615,6 +616,10 @@ void gc_collect(void) {
|
||||
|
||||
background_callback_gc_collect();
|
||||
|
||||
#if CIRCUITPY_ALARM
|
||||
common_hal_alarm_gc_collect();
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_DISPLAYIO
|
||||
displayio_gc_collect();
|
||||
#endif
|
||||
|
@ -145,7 +145,6 @@ LDFLAGS += -L$(BUILD)/esp-idf/esp-idf/esp32s2 \
|
||||
-Tesp32s2.peripherals.ld \
|
||||
-Lesp-idf/components/esp_rom/esp32s2/ld \
|
||||
-Tesp32s2.rom.ld \
|
||||
-Tesp32s2.rom.api.ld \
|
||||
-Tesp32s2.rom.libgcc.ld \
|
||||
-Tesp32s2.rom.newlib-data.ld \
|
||||
-Tesp32s2.rom.newlib-funcs.ld \
|
||||
@ -278,7 +277,7 @@ menuconfig: $(BUILD)/esp-idf/config
|
||||
# qstr builds include headers so we need to make sure they are up to date
|
||||
$(HEADER_BUILD)/qstr.split: | $(BUILD)/esp-idf/config/sdkconfig.h
|
||||
|
||||
ESP_IDF_COMPONENTS_LINK = freertos log hal esp_system esp_adc_cal esp32s2 bootloader_support pthread esp_timer vfs spi_flash app_update esp_common esp32s2 heap newlib driver xtensa soc esp_ringbuf esp_wifi esp_event wpa_supplicant mbedtls efuse nvs_flash esp_netif lwip esp_rom esp-tls
|
||||
ESP_IDF_COMPONENTS_LINK = freertos log esp_system esp_adc_cal esp32s2 bootloader_support pthread esp_timer vfs spi_flash app_update esp_common esp32s2 heap newlib driver xtensa soc esp_ringbuf esp_wifi esp_event wpa_supplicant mbedtls efuse nvs_flash esp_netif lwip esp-tls
|
||||
|
||||
ESP_IDF_COMPONENTS_INCLUDE = driver freertos log soc
|
||||
|
||||
@ -290,11 +289,11 @@ ESP_IDF_WIFI_COMPONENTS_EXPANDED = $(foreach component, $(ESP_IDF_WIFI_COMPONENT
|
||||
MBEDTLS_COMPONENTS_LINK = crypto tls x509
|
||||
MBEDTLS_COMPONENTS_LINK_EXPANDED = $(foreach component, $(MBEDTLS_COMPONENTS_LINK), $(BUILD)/esp-idf/esp-idf/mbedtls/mbedtls/library/libmbed$(component).a)
|
||||
|
||||
BINARY_BLOBS = esp-idf/components/xtensa/esp32s2/libxt_hal.a
|
||||
BINARY_BLOBS = esp-idf/components/xtensa/esp32s2/libhal.a
|
||||
BINARY_WIFI_BLOBS = libcoexist.a libcore.a libespnow.a libmesh.a libnet80211.a libpp.a librtc.a libsmartconfig.a libphy.a
|
||||
BINARY_BLOBS += $(addprefix esp-idf/components/esp_wifi/lib/esp32s2/, $(BINARY_WIFI_BLOBS))
|
||||
|
||||
ESP_IDF_COMPONENTS_EXPANDED += $(BUILD)/esp-idf/esp-idf/soc/soc/esp32s2/libsoc_esp32s2.a esp-idf/components/xtensa/esp32s2/libxt_hal.a
|
||||
ESP_IDF_COMPONENTS_EXPANDED += $(BUILD)/esp-idf/esp-idf/soc/soc/esp32s2/libsoc_esp32s2.a
|
||||
ESP_AUTOGEN_LD = $(BUILD)/esp-idf/esp-idf/esp32s2/esp32s2_out.ld $(BUILD)/esp-idf/esp-idf/esp32s2/ld/esp32s2.project.ld
|
||||
|
||||
FLASH_FLAGS = --flash_mode $(CIRCUITPY_ESP_FLASH_MODE) --flash_freq $(CIRCUITPY_ESP_FLASH_FREQ) --flash_size $(CIRCUITPY_ESP_FLASH_SIZE)
|
||||
@ -310,7 +309,6 @@ esp-idf-stamp: $(BUILD)/esp-idf/config/sdkconfig.h
|
||||
esp-idf/esp32s2/ld/esp32s2.project.ld \
|
||||
esp-idf/esp_event/libesp_event.a \
|
||||
esp-idf/esp_netif/libesp_netif.a \
|
||||
esp-idf/esp_rom/libesp_rom.a \
|
||||
esp-idf/esp_system/libesp_system.a \
|
||||
esp-idf/esp_wifi/libesp_wifi.a \
|
||||
esp-idf/lwip/liblwip.a \
|
||||
|
@ -25,10 +25,12 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "py/gc.h"
|
||||
#include "py/obj.h"
|
||||
#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/SleepMemory.h"
|
||||
#include "shared-bindings/alarm/time/TimeAlarm.h"
|
||||
@ -38,10 +40,11 @@
|
||||
#include "supervisor/port.h"
|
||||
#include "supervisor/shared/workflow.h"
|
||||
|
||||
#include "common-hal/alarm/__init__.h"
|
||||
|
||||
#include "esp_sleep.h"
|
||||
|
||||
#include "components/soc/soc/esp32s2/include/soc/rtc_cntl_reg.h"
|
||||
#include "components/driver/include/driver/uart.h"
|
||||
|
||||
// Singleton instance of SleepMemory.
|
||||
const alarm_sleep_memory_obj_t alarm_sleep_memory_obj = {
|
||||
.base = {
|
||||
@ -49,9 +52,9 @@ const alarm_sleep_memory_obj_t alarm_sleep_memory_obj = {
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
void alarm_reset(void) {
|
||||
alarm_time_timealarm_reset();
|
||||
alarm_pin_pinalarm_reset();
|
||||
alarm_sleep_memory_reset();
|
||||
esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_ALL);
|
||||
}
|
||||
@ -60,6 +63,9 @@ STATIC esp_sleep_wakeup_cause_t _get_wakeup_cause(void) {
|
||||
if (alarm_time_timealarm_woke_us_up()) {
|
||||
return ESP_SLEEP_WAKEUP_TIMER;
|
||||
}
|
||||
if (alarm_pin_pinalarm_woke_us_up()) {
|
||||
return ESP_SLEEP_WAKEUP_GPIO;
|
||||
}
|
||||
|
||||
return esp_sleep_get_wakeup_cause();
|
||||
}
|
||||
@ -69,14 +75,16 @@ bool alarm_woken_from_sleep(void) {
|
||||
}
|
||||
|
||||
STATIC mp_obj_t _get_wake_alarm(size_t n_alarms, const mp_obj_t *alarms) {
|
||||
switch (_get_wakeup_cause()) {
|
||||
esp_sleep_wakeup_cause_t cause = _get_wakeup_cause();
|
||||
switch (cause) {
|
||||
case ESP_SLEEP_WAKEUP_TIMER: {
|
||||
return alarm_time_timealarm_get_wakeup_alarm(n_alarms, alarms);
|
||||
}
|
||||
|
||||
case ESP_SLEEP_WAKEUP_EXT0: {
|
||||
// TODO: implement pin alarm wake.
|
||||
break;
|
||||
case ESP_SLEEP_WAKEUP_GPIO:
|
||||
case ESP_SLEEP_WAKEUP_EXT0:
|
||||
case ESP_SLEEP_WAKEUP_EXT1: {
|
||||
return alarm_pin_pinalarm_get_wakeup_alarm(n_alarms, alarms);
|
||||
}
|
||||
|
||||
case ESP_SLEEP_WAKEUP_TOUCHPAD:
|
||||
@ -98,24 +106,8 @@ mp_obj_t common_hal_alarm_get_wake_alarm(void) {
|
||||
|
||||
// Set up light sleep or deep sleep alarms.
|
||||
STATIC void _setup_sleep_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms) {
|
||||
bool time_alarm_set = false;
|
||||
alarm_time_time_alarm_obj_t *time_alarm = MP_OBJ_NULL;
|
||||
|
||||
for (size_t i = 0; i < n_alarms; i++) {
|
||||
if (MP_OBJ_IS_TYPE(alarms[i], &alarm_pin_pin_alarm_type)) {
|
||||
mp_raise_NotImplementedError(translate("PinAlarm not yet implemented"));
|
||||
} else if (MP_OBJ_IS_TYPE(alarms[i], &alarm_time_time_alarm_type)) {
|
||||
if (time_alarm_set) {
|
||||
mp_raise_ValueError(translate("Only one alarm.time alarm can be set."));
|
||||
}
|
||||
time_alarm = MP_OBJ_TO_PTR(alarms[i]);
|
||||
time_alarm_set = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (time_alarm_set) {
|
||||
alarm_time_timealarm_set_alarm(time_alarm);
|
||||
}
|
||||
alarm_pin_pinalarm_set_alarms(deep_sleep, n_alarms, alarms);
|
||||
alarm_time_timealarm_set_alarms(deep_sleep, n_alarms, alarms);
|
||||
}
|
||||
|
||||
STATIC void _idle_until_alarm(void) {
|
||||
@ -131,21 +123,16 @@ STATIC void _idle_until_alarm(void) {
|
||||
}
|
||||
}
|
||||
|
||||
// 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) && !supervisor_workflow_active();
|
||||
}
|
||||
|
||||
mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj_t *alarms) {
|
||||
_setup_sleep_alarms(false, n_alarms, alarms);
|
||||
|
||||
// Light sleep can break some functionality so only do it when possible. Otherwise we idle.
|
||||
if (_light_sleep_ok()) {
|
||||
esp_light_sleep_start();
|
||||
} else {
|
||||
_idle_until_alarm();
|
||||
// We cannot esp_light_sleep_start() here because it shuts down all non-RTC peripherals.
|
||||
_idle_until_alarm();
|
||||
|
||||
if (mp_hal_is_interrupted()) {
|
||||
return mp_const_none; // Shouldn't be given to python code because exception handling should kick in.
|
||||
}
|
||||
|
||||
mp_obj_t wake_alarm = _get_wake_alarm(n_alarms, alarms);
|
||||
alarm_reset();
|
||||
return wake_alarm;
|
||||
@ -156,7 +143,12 @@ void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *ala
|
||||
}
|
||||
|
||||
void NORETURN alarm_enter_deep_sleep(void) {
|
||||
alarm_pin_pinalarm_prepare_for_deep_sleep();
|
||||
// The ESP-IDF caches the deep sleep settings and applies them before sleep.
|
||||
// We don't need to worry about resetting them in the interim.
|
||||
esp_deep_sleep_start();
|
||||
}
|
||||
|
||||
void common_hal_alarm_gc_collect(void) {
|
||||
gc_collect_ptr(alarm_get_wake_alarm());
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2020 Dan Halbert 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
|
||||
@ -24,30 +25,283 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "esp_sleep.h"
|
||||
#include "py/runtime.h"
|
||||
|
||||
#include "shared-bindings/alarm/pin/PinAlarm.h"
|
||||
#include "shared-bindings/microcontroller/__init__.h"
|
||||
#include "shared-bindings/microcontroller/Pin.h"
|
||||
#include "supervisor/esp_port.h"
|
||||
|
||||
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) {
|
||||
#include "components/driver/include/driver/rtc_io.h"
|
||||
#include "components/esp32s2/include/esp_sleep.h"
|
||||
#include "components/freertos/include/freertos/FreeRTOS.h"
|
||||
#include "components/soc/src/esp32s2/include/hal/gpio_ll.h"
|
||||
#include "components/xtensa/include/esp_debug_helpers.h"
|
||||
|
||||
void common_hal_alarm_pin_pinalarm_construct(alarm_pin_pinalarm_obj_t *self, mcu_pin_obj_t *pin, bool value, bool edge, bool pull) {
|
||||
if (edge) {
|
||||
mp_raise_ValueError(translate("Cannot wake on pin edge. Only level."));
|
||||
}
|
||||
|
||||
if (pull && !GPIO_IS_VALID_OUTPUT_GPIO(pin->number)) {
|
||||
mp_raise_ValueError(translate("Cannot pull on input-only pin."));
|
||||
}
|
||||
self->pin = pin;
|
||||
self->value = value;
|
||||
self->edge = edge;
|
||||
self->pull = pull;
|
||||
}
|
||||
|
||||
mcu_pin_obj_t *common_hal_alarm_pin_pin_alarm_get_pin(alarm_pin_pin_alarm_obj_t *self) {
|
||||
mcu_pin_obj_t *common_hal_alarm_pin_pinalarm_get_pin(alarm_pin_pinalarm_obj_t *self) {
|
||||
return self->pin;
|
||||
}
|
||||
|
||||
bool common_hal_alarm_pin_pin_alarm_get_value(alarm_pin_pin_alarm_obj_t *self) {
|
||||
bool common_hal_alarm_pin_pinalarm_get_value(alarm_pin_pinalarm_obj_t *self) {
|
||||
return self->value;
|
||||
}
|
||||
|
||||
bool common_hal_alarm_pin_pin_alarm_get_edge(alarm_pin_pin_alarm_obj_t *self) {
|
||||
return self->edge;
|
||||
bool common_hal_alarm_pin_pinalarm_get_edge(alarm_pin_pinalarm_obj_t *self) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool common_hal_alarm_pin_pin_alarm_get_pull(alarm_pin_pin_alarm_obj_t *self) {
|
||||
bool common_hal_alarm_pin_pinalarm_get_pull(alarm_pin_pinalarm_obj_t *self) {
|
||||
return self->pull;
|
||||
}
|
||||
|
||||
gpio_isr_handle_t gpio_interrupt_handle;
|
||||
// Low and high are relative to pin number. 32+ is high. <32 is low.
|
||||
static volatile uint32_t pin_31_0_status = 0;
|
||||
static volatile uint32_t pin_63_32_status = 0;
|
||||
void gpio_interrupt(void *arg) {
|
||||
(void) arg;
|
||||
|
||||
gpio_ll_get_intr_status(&GPIO, xPortGetCoreID(), (uint32_t*) &pin_31_0_status);
|
||||
gpio_ll_clear_intr_status(&GPIO, pin_31_0_status);
|
||||
gpio_ll_get_intr_status_high(&GPIO, xPortGetCoreID(), (uint32_t*) &pin_63_32_status);
|
||||
gpio_ll_clear_intr_status_high(&GPIO, pin_63_32_status);
|
||||
|
||||
// disable the interrupts that fired, maybe all of them
|
||||
for (size_t i = 0; i < 32; i++) {
|
||||
uint32_t mask = 1 << i;
|
||||
if ((pin_31_0_status & mask) != 0) {
|
||||
gpio_ll_intr_disable(&GPIO, i);
|
||||
}
|
||||
if ((pin_63_32_status & mask) != 0) {
|
||||
gpio_ll_intr_disable(&GPIO, 32 + i);
|
||||
}
|
||||
}
|
||||
BaseType_t high_task_wakeup;
|
||||
vTaskNotifyGiveFromISR(circuitpython_task, &high_task_wakeup);
|
||||
if (high_task_wakeup) {
|
||||
portYIELD_FROM_ISR();
|
||||
}
|
||||
}
|
||||
|
||||
bool alarm_pin_pinalarm_woke_us_up(void) {
|
||||
return pin_31_0_status != 0 || pin_63_32_status != 0;
|
||||
}
|
||||
|
||||
mp_obj_t alarm_pin_pinalarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *alarms) {
|
||||
// First, check to see if we match any given alarms.
|
||||
uint64_t pin_status = ((uint64_t) pin_63_32_status) << 32 | pin_31_0_status;
|
||||
for (size_t i = 0; i < n_alarms; i++) {
|
||||
if (!MP_OBJ_IS_TYPE(alarms[i], &alarm_pin_pinalarm_type)) {
|
||||
continue;
|
||||
}
|
||||
alarm_pin_pinalarm_obj_t *alarm = MP_OBJ_TO_PTR(alarms[i]);
|
||||
if ((pin_status & (1ull << alarm->pin->number)) != 0) {
|
||||
return alarms[i];
|
||||
}
|
||||
}
|
||||
esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause();
|
||||
size_t pin_number = 64;
|
||||
if (cause == ESP_SLEEP_WAKEUP_EXT0) {
|
||||
pin_number = REG_GET_FIELD(RTC_IO_EXT_WAKEUP0_REG, RTC_IO_EXT_WAKEUP0_SEL);
|
||||
} else {
|
||||
if (cause == ESP_SLEEP_WAKEUP_EXT1) {
|
||||
pin_status = esp_sleep_get_ext1_wakeup_status();
|
||||
}
|
||||
// If the cause is GPIO, we've already snagged pin_status in the interrupt.
|
||||
// We'll only get here if we pretended to deep sleep. Light sleep will
|
||||
// pass in existing objects.
|
||||
for (size_t i = 0; i < 64; i++) {
|
||||
if ((pin_status & (1ull << i)) != 0) {
|
||||
pin_number = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
alarm_pin_pinalarm_obj_t *alarm = m_new_obj(alarm_pin_pinalarm_obj_t);
|
||||
alarm->base.type = &alarm_pin_pinalarm_type;
|
||||
alarm->pin = NULL;
|
||||
// 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 == pin_number) {
|
||||
alarm->pin = mcu_pin_globals.map.table[i].value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return alarm;
|
||||
}
|
||||
|
||||
// These must be static because we need to configure pulls later, right before
|
||||
// deep sleep.
|
||||
static uint64_t high_alarms = 0;
|
||||
static uint64_t low_alarms = 0;
|
||||
static uint64_t pull_pins = 0;
|
||||
|
||||
void alarm_pin_pinalarm_reset(void) {
|
||||
if (gpio_interrupt_handle != NULL) {
|
||||
esp_intr_free(gpio_interrupt_handle);
|
||||
gpio_interrupt_handle = NULL;
|
||||
}
|
||||
for (size_t i = 0; i < 64; i++) {
|
||||
uint64_t mask = 1ull << i;
|
||||
bool high = (high_alarms & mask) != 0;
|
||||
bool low = (low_alarms & mask) != 0;
|
||||
if (!(high || low)) {
|
||||
continue;
|
||||
}
|
||||
reset_pin_number(i);
|
||||
}
|
||||
high_alarms = 0;
|
||||
low_alarms = 0;
|
||||
pull_pins = 0;
|
||||
pin_63_32_status = 0;
|
||||
pin_31_0_status = 0;
|
||||
}
|
||||
|
||||
void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms) {
|
||||
// Bitmask of wake up settings.
|
||||
size_t high_count = 0;
|
||||
size_t low_count = 0;
|
||||
|
||||
for (size_t i = 0; i < n_alarms; i++) {
|
||||
// TODO: Check for ULP or touch alarms because they can't coexist with GPIO alarms.
|
||||
if (!MP_OBJ_IS_TYPE(alarms[i], &alarm_pin_pinalarm_type)) {
|
||||
continue;
|
||||
}
|
||||
alarm_pin_pinalarm_obj_t *alarm = MP_OBJ_TO_PTR(alarms[i]);
|
||||
|
||||
gpio_num_t pin_number = alarm->pin->number;
|
||||
if (alarm->value) {
|
||||
high_alarms |= 1ull << pin_number;
|
||||
high_count++;
|
||||
} else {
|
||||
low_alarms |= 1ull << pin_number;
|
||||
low_count++;
|
||||
}
|
||||
if (alarm->pull) {
|
||||
pull_pins |= 1ull << pin_number;
|
||||
}
|
||||
}
|
||||
if (high_count == 0 && low_count == 0) {
|
||||
return;
|
||||
}
|
||||
if (deep_sleep && low_count > 2 && high_count == 0) {
|
||||
mp_raise_ValueError(translate("Can only alarm on two low pins from deep sleep."));
|
||||
}
|
||||
if (deep_sleep && low_count > 1 && high_count > 0) {
|
||||
mp_raise_ValueError(translate("Can only alarm on one low pin while others alarm high from deep sleep."));
|
||||
}
|
||||
// Only use ext0 and ext1 during deep sleep.
|
||||
if (deep_sleep) {
|
||||
if (high_count > 0) {
|
||||
if (esp_sleep_enable_ext1_wakeup(high_alarms, ESP_EXT1_WAKEUP_ANY_HIGH) != ESP_OK) {
|
||||
mp_raise_ValueError(translate("Can only alarm on RTC IO from deep sleep."));
|
||||
}
|
||||
}
|
||||
size_t low_pins[2];
|
||||
size_t j = 0;
|
||||
for (size_t i = 0; i < 64; i++) {
|
||||
uint64_t mask = 1ull << i;
|
||||
if ((low_alarms & mask) != 0) {
|
||||
low_pins[j++] = i;
|
||||
}
|
||||
if (j == 2) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (low_count > 1) {
|
||||
if (esp_sleep_enable_ext1_wakeup(1ull << low_pins[1], ESP_EXT1_WAKEUP_ALL_LOW) != ESP_OK) {
|
||||
mp_raise_ValueError(translate("Can only alarm on RTC IO from deep sleep."));
|
||||
}
|
||||
}
|
||||
if (low_count > 0) {
|
||||
if (esp_sleep_enable_ext0_wakeup(low_pins[0], 0) != ESP_OK) {
|
||||
mp_raise_ValueError(translate("Can only alarm on RTC IO from deep sleep."));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Enable GPIO wake up if we're sleeping.
|
||||
esp_sleep_enable_gpio_wakeup();
|
||||
}
|
||||
// Set GPIO interrupts so they wake us from light sleep or from idle via the
|
||||
// interrupt handler above.
|
||||
pin_31_0_status = 0;
|
||||
pin_63_32_status = 0;
|
||||
if (gpio_isr_register(gpio_interrupt, NULL, 0, &gpio_interrupt_handle) != ESP_OK) {
|
||||
mp_raise_ValueError(translate("Can only alarm on RTC IO from deep sleep."));
|
||||
}
|
||||
for (size_t i = 0; i < 64; i++) {
|
||||
uint64_t mask = 1ull << i;
|
||||
bool high = (high_alarms & mask) != 0;
|
||||
bool low = (low_alarms & mask) != 0;
|
||||
bool pull = (pull_pins & mask) != 0;
|
||||
if (!(high || low)) {
|
||||
continue;
|
||||
}
|
||||
if (rtc_gpio_is_valid_gpio(i)) {
|
||||
rtc_gpio_deinit(i);
|
||||
}
|
||||
gpio_int_type_t interrupt_mode = GPIO_INTR_DISABLE;
|
||||
gpio_pull_mode_t pull_mode = GPIO_FLOATING;
|
||||
if (high) {
|
||||
interrupt_mode = GPIO_INTR_HIGH_LEVEL;
|
||||
pull_mode = GPIO_PULLDOWN_ONLY;
|
||||
}
|
||||
if (low) {
|
||||
interrupt_mode = GPIO_INTR_LOW_LEVEL;
|
||||
pull_mode = GPIO_PULLUP_ONLY;
|
||||
}
|
||||
gpio_set_direction(i, GPIO_MODE_DEF_INPUT);
|
||||
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[i], PIN_FUNC_GPIO);
|
||||
if (pull) {
|
||||
gpio_set_pull_mode(i, pull_mode);
|
||||
size_t j = 0;
|
||||
while (gpio_get_level(i) == false) {
|
||||
j++;
|
||||
}
|
||||
}
|
||||
never_reset_pin_number(i);
|
||||
// Sets interrupt type and wakeup bits.
|
||||
gpio_wakeup_enable(i, interrupt_mode);
|
||||
gpio_intr_enable(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void alarm_pin_pinalarm_prepare_for_deep_sleep(void) {
|
||||
if (pull_pins == 0) {
|
||||
return;
|
||||
}
|
||||
for (size_t i = 0; i < 64; i++) {
|
||||
uint64_t mask = 1ull << i;
|
||||
bool pull = (pull_pins & mask) != 0;
|
||||
if (!pull) {
|
||||
continue;
|
||||
}
|
||||
bool high = (high_alarms & mask) != 0;
|
||||
bool low = (low_alarms & mask) != 0;
|
||||
// The pull direction is opposite from alarm value.
|
||||
if (high) {
|
||||
rtc_gpio_pullup_dis(i);
|
||||
rtc_gpio_pulldown_en(i);
|
||||
}
|
||||
if (low) {
|
||||
rtc_gpio_pullup_en(i);
|
||||
rtc_gpio_pulldown_dis(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,11 @@ typedef struct {
|
||||
mp_obj_base_t base;
|
||||
mcu_pin_obj_t *pin;
|
||||
bool value;
|
||||
bool all_same_value;
|
||||
bool edge;
|
||||
bool pull;
|
||||
} alarm_pin_pin_alarm_obj_t;
|
||||
} alarm_pin_pinalarm_obj_t;
|
||||
|
||||
void alarm_pin_pinalarm_reset(void);
|
||||
void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms);
|
||||
void alarm_pin_pinalarm_prepare_for_deep_sleep(void);
|
||||
mp_obj_t alarm_pin_pinalarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *alarms);
|
||||
bool alarm_pin_pinalarm_woke_us_up(void);
|
||||
|
@ -34,23 +34,23 @@
|
||||
#include "shared-bindings/alarm/time/TimeAlarm.h"
|
||||
#include "shared-bindings/time/__init__.h"
|
||||
|
||||
void common_hal_alarm_time_time_alarm_construct(alarm_time_time_alarm_obj_t *self, mp_float_t monotonic_time) {
|
||||
void common_hal_alarm_time_timealarm_construct(alarm_time_timealarm_obj_t *self, mp_float_t monotonic_time) {
|
||||
self->monotonic_time = monotonic_time;
|
||||
}
|
||||
|
||||
mp_float_t common_hal_alarm_time_time_alarm_get_monotonic_time(alarm_time_time_alarm_obj_t *self) {
|
||||
mp_float_t common_hal_alarm_time_timealarm_get_monotonic_time(alarm_time_timealarm_obj_t *self) {
|
||||
return self->monotonic_time;
|
||||
}
|
||||
|
||||
mp_obj_t alarm_time_timealarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *alarms) {
|
||||
// First, check to see if we match
|
||||
for (size_t i = 0; i < n_alarms; i++) {
|
||||
if (MP_OBJ_IS_TYPE(alarms[i], &alarm_time_time_alarm_type)) {
|
||||
if (MP_OBJ_IS_TYPE(alarms[i], &alarm_time_timealarm_type)) {
|
||||
return alarms[i];
|
||||
}
|
||||
}
|
||||
alarm_time_time_alarm_obj_t *timer = m_new_obj(alarm_time_time_alarm_obj_t);
|
||||
timer->base.type = &alarm_time_time_alarm_type;
|
||||
alarm_time_timealarm_obj_t *timer = m_new_obj(alarm_time_timealarm_obj_t);
|
||||
timer->base.type = &alarm_time_timealarm_type;
|
||||
// TODO: Set monotonic_time based on the RTC state.
|
||||
timer->monotonic_time = 0.0f;
|
||||
return timer;
|
||||
@ -63,9 +63,7 @@ STATIC bool woke_up = false;
|
||||
void timer_callback(void *arg) {
|
||||
(void) arg;
|
||||
woke_up = true;
|
||||
if (sleeping_circuitpython_task) {
|
||||
xTaskNotifyGive(sleeping_circuitpython_task);
|
||||
}
|
||||
xTaskNotifyGive(circuitpython_task);
|
||||
}
|
||||
|
||||
bool alarm_time_timealarm_woke_us_up(void) {
|
||||
@ -79,7 +77,24 @@ void alarm_time_timealarm_reset(void) {
|
||||
woke_up = false;
|
||||
}
|
||||
|
||||
void alarm_time_timealarm_set_alarm(alarm_time_time_alarm_obj_t *self) {
|
||||
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;
|
||||
|
||||
for (size_t i = 0; i < n_alarms; i++) {
|
||||
if (!MP_OBJ_IS_TYPE(alarms[i], &alarm_time_timealarm_type)) {
|
||||
continue;
|
||||
}
|
||||
if (timealarm_set) {
|
||||
mp_raise_ValueError(translate("Only one alarm.time alarm can be set."));
|
||||
}
|
||||
timealarm = MP_OBJ_TO_PTR(alarms[i]);
|
||||
timealarm_set = true;
|
||||
}
|
||||
if (!timealarm_set) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (pretend_sleep_timer != NULL) {
|
||||
esp_timer_stop(pretend_sleep_timer);
|
||||
} else {
|
||||
@ -94,7 +109,7 @@ void alarm_time_timealarm_set_alarm(alarm_time_time_alarm_obj_t *self) {
|
||||
|
||||
// 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, self->monotonic_time - now_secs);
|
||||
mp_float_t wakeup_in_secs = MAX(0.0f, timealarm->monotonic_time - now_secs);
|
||||
const uint64_t sleep_for_us = (uint64_t) (wakeup_in_secs * 1000000);
|
||||
esp_sleep_enable_timer_wakeup(sleep_for_us);
|
||||
|
||||
|
@ -30,11 +30,11 @@
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
mp_float_t monotonic_time; // values compatible with time.monotonic_time()
|
||||
} alarm_time_time_alarm_obj_t;
|
||||
} alarm_time_timealarm_obj_t;
|
||||
|
||||
// Find the alarm object that caused us to wake up or create an equivalent one.
|
||||
mp_obj_t alarm_time_timealarm_get_wakeup_alarm(size_t n_alarms, const mp_obj_t *alarms);
|
||||
// Check for the wake up alarm from pretend deep sleep.
|
||||
bool alarm_time_timealarm_woke_us_up(void);
|
||||
void alarm_time_timealarm_set_alarm(alarm_time_time_alarm_obj_t *self);
|
||||
void alarm_time_timealarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_obj_t *alarms);
|
||||
void alarm_time_timealarm_reset(void);
|
||||
|
@ -29,7 +29,7 @@
|
||||
|
||||
#include "common-hal/microcontroller/Pin.h"
|
||||
|
||||
#include "components/hal/include/hal/adc_types.h"
|
||||
#include "components/soc/include/hal/adc_types.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "py/obj.h"
|
||||
|
@ -29,7 +29,7 @@
|
||||
|
||||
#include "common-hal/microcontroller/Pin.h"
|
||||
|
||||
#include "components/hal/include/hal/i2c_types.h"
|
||||
#include "components/soc/include/hal/i2c_types.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "py/obj.h"
|
||||
|
@ -273,7 +273,7 @@ bool common_hal_busio_spi_configure(busio_spi_obj_t *self,
|
||||
self->bits = bits;
|
||||
self->target_frequency = baudrate;
|
||||
self->hal_context.timing_conf = &self->timing_conf;
|
||||
esp_err_t result = spi_hal_cal_clock_conf(&self->hal_context,
|
||||
esp_err_t result = spi_hal_get_clock_conf(&self->hal_context,
|
||||
self->target_frequency,
|
||||
128 /* duty_cycle */,
|
||||
self->connected_through_gpio,
|
||||
@ -366,7 +366,8 @@ bool common_hal_busio_spi_transfer(busio_spi_obj_t *self, const uint8_t *data_ou
|
||||
burst_length = sizeof(hal->hw->data_buf);
|
||||
// When switching to non-DMA, we need to make sure DMA is off. Otherwise,
|
||||
// the S2 will transmit zeroes instead of our data.
|
||||
spi_ll_txdma_disable(hal->hw);
|
||||
hal->hw->dma_out_link.dma_tx_ena = 0;
|
||||
hal->hw->dma_out_link.stop = 1;
|
||||
}
|
||||
|
||||
// This rounds up.
|
||||
|
@ -30,8 +30,8 @@
|
||||
#include "common-hal/microcontroller/Pin.h"
|
||||
|
||||
#include "components/driver/include/driver/spi_common_internal.h"
|
||||
#include "components/hal/include/hal/spi_hal.h"
|
||||
#include "components/hal/include/hal/spi_types.h"
|
||||
#include "components/soc/include/hal/spi_hal.h"
|
||||
#include "components/soc/include/hal/spi_types.h"
|
||||
#include "py/obj.h"
|
||||
|
||||
typedef struct {
|
||||
|
@ -29,7 +29,7 @@
|
||||
|
||||
#include "common-hal/microcontroller/Pin.h"
|
||||
|
||||
#include "components/hal/include/hal/uart_types.h"
|
||||
#include "components/soc/include/hal/uart_types.h"
|
||||
#include "py/obj.h"
|
||||
|
||||
typedef struct {
|
||||
|
@ -30,7 +30,7 @@
|
||||
|
||||
#include "components/driver/include/driver/gpio.h"
|
||||
|
||||
#include "components/hal/include/hal/gpio_hal.h"
|
||||
#include "components/soc/include/hal/gpio_hal.h"
|
||||
|
||||
void common_hal_digitalio_digitalinout_never_reset(
|
||||
digitalio_digitalinout_obj_t *self) {
|
||||
|
@ -100,7 +100,7 @@ void common_hal_dualbank_flash(const void *buf, const size_t len, const size_t o
|
||||
}
|
||||
}
|
||||
|
||||
err = esp_ota_begin(update_partition, OTA_WITH_SEQUENTIAL_WRITES, &update_handle);
|
||||
err = esp_ota_begin(update_partition, OTA_SIZE_UNKNOWN, &update_handle);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "esp_ota_begin failed (%s)", esp_err_to_name(err));
|
||||
task_fatal_error();
|
||||
|
@ -32,7 +32,7 @@
|
||||
#include "py/mphal.h"
|
||||
|
||||
#include "components/driver/include/driver/gpio.h"
|
||||
#include "components/hal/include/hal/gpio_hal.h"
|
||||
#include "components/soc/include/hal/gpio_hal.h"
|
||||
|
||||
#ifdef MICROPY_HW_NEOPIXEL
|
||||
bool neopixel_in_use;
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit d06744f5efc382c61cbad8758107cec308feef09
|
||||
Subproject commit ebe7784258d8c10e9cc334ccc00c3fd270746c8b
|
@ -35,9 +35,9 @@
|
||||
#include "esp32s2_peripherals_config.h"
|
||||
#include "esp-idf/config/sdkconfig.h"
|
||||
|
||||
#include "components/hal/include/hal/gpio_types.h"
|
||||
#include "components/hal/include/hal/adc_types.h"
|
||||
#include "components/hal/include/hal/touch_sensor_types.h"
|
||||
#include "components/soc/include/hal/gpio_types.h"
|
||||
#include "components/soc/include/hal/adc_types.h"
|
||||
#include "components/soc/include/hal/touch_sensor_types.h"
|
||||
|
||||
typedef struct {
|
||||
PIN_PREFIX_FIELDS
|
||||
|
@ -30,6 +30,6 @@
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
extern TaskHandle_t sleeping_circuitpython_task;
|
||||
extern TaskHandle_t circuitpython_task;
|
||||
|
||||
#endif // MICROPY_INCLUDED_ESP32S2_SUPERVISOR_PORT_H
|
||||
|
@ -55,7 +55,7 @@
|
||||
#include "peripherals/rmt.h"
|
||||
#include "peripherals/pcnt.h"
|
||||
#include "peripherals/timer.h"
|
||||
#include "components/esp_rom/include/esp_rom_uart.h"
|
||||
#include "components/esp_rom/include/esp32s2/rom/ets_sys.h"
|
||||
#include "components/heap/include/esp_heap_caps.h"
|
||||
#include "components/xtensa/include/esp_debug_helpers.h"
|
||||
#include "components/soc/soc/esp32s2/include/soc/cache_memory.h"
|
||||
@ -67,13 +67,22 @@ uint32_t* heap;
|
||||
uint32_t heap_size;
|
||||
|
||||
STATIC esp_timer_handle_t _tick_timer;
|
||||
STATIC esp_timer_handle_t _sleep_timer;
|
||||
|
||||
TaskHandle_t circuitpython_task = NULL;
|
||||
|
||||
extern void esp_restart(void) NORETURN;
|
||||
|
||||
void tick_timer_cb(void* arg) {
|
||||
supervisor_tick();
|
||||
|
||||
// CircuitPython's VM is run in a separate FreeRTOS task from timer callbacks. So, we have to
|
||||
// notify the main task every time in case it's waiting for us.
|
||||
xTaskNotifyGive(circuitpython_task);
|
||||
}
|
||||
|
||||
void sleep_timer_cb(void* arg);
|
||||
|
||||
safe_mode_t port_init(void) {
|
||||
esp_timer_create_args_t args;
|
||||
args.callback = &tick_timer_cb;
|
||||
@ -82,9 +91,17 @@ safe_mode_t port_init(void) {
|
||||
args.name = "CircuitPython Tick";
|
||||
esp_timer_create(&args, &_tick_timer);
|
||||
|
||||
#ifdef DEBUG
|
||||
args.callback = &sleep_timer_cb;
|
||||
args.arg = NULL;
|
||||
args.dispatch_method = ESP_TIMER_TASK;
|
||||
args.name = "CircuitPython Sleep";
|
||||
esp_timer_create(&args, &_sleep_timer);
|
||||
|
||||
circuitpython_task = xTaskGetCurrentTaskHandle();
|
||||
|
||||
// Send the ROM output out of the UART. This includes early logs.
|
||||
esp_rom_install_channel_putc(1, esp_rom_uart_putc);
|
||||
#ifdef DEBUG
|
||||
ets_install_uart_printf();
|
||||
#endif
|
||||
|
||||
heap = NULL;
|
||||
@ -104,11 +121,15 @@ safe_mode_t port_init(void) {
|
||||
}
|
||||
|
||||
esp_reset_reason_t reason = esp_reset_reason();
|
||||
if (reason == ESP_RST_BROWNOUT) {
|
||||
return BROWNOUT;
|
||||
}
|
||||
if (reason == ESP_RST_PANIC) {
|
||||
return HARD_CRASH;
|
||||
switch (reason) {
|
||||
case ESP_RST_BROWNOUT:
|
||||
return BROWNOUT;
|
||||
case ESP_RST_PANIC:
|
||||
case ESP_RST_INT_WDT:
|
||||
case ESP_RST_WDT:
|
||||
return HARD_CRASH;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return NO_SAFE_MODE;
|
||||
@ -252,32 +273,24 @@ void port_enable_tick(void) {
|
||||
// Disable 1/1024 second tick.
|
||||
void port_disable_tick(void) {
|
||||
esp_timer_stop(_tick_timer);
|
||||
|
||||
// CircuitPython's VM is run in a separate FreeRTOS task from TinyUSB.
|
||||
// Tick disable can happen via auto-reload so poke the main task here.
|
||||
if (sleeping_circuitpython_task != NULL) {
|
||||
xTaskNotifyGive(sleeping_circuitpython_task);
|
||||
}
|
||||
}
|
||||
|
||||
TickType_t sleep_time_duration;
|
||||
void sleep_timer_cb(void* arg) {
|
||||
xTaskNotifyGive(circuitpython_task);
|
||||
}
|
||||
|
||||
void port_interrupt_after_ticks(uint32_t ticks) {
|
||||
sleep_time_duration = (ticks * 100)/1024;
|
||||
uint64_t timeout_us = ticks * 1000000ull / 1024;
|
||||
if (esp_timer_start_once(_sleep_timer, timeout_us) != ESP_OK) {
|
||||
esp_timer_stop(_sleep_timer);
|
||||
esp_timer_start_once(_sleep_timer, timeout_us);
|
||||
}
|
||||
}
|
||||
|
||||
// On the ESP we use FreeRTOS notifications instead of interrupts so this is a
|
||||
// bit of a misnomer.
|
||||
void port_idle_until_interrupt(void) {
|
||||
uint32_t notify_value = 0;
|
||||
|
||||
if (sleep_time_duration == 0) {
|
||||
return;
|
||||
}
|
||||
sleeping_circuitpython_task = xTaskGetCurrentTaskHandle();
|
||||
xTaskNotifyWait(0x01, 0x01, ¬ify_value, sleep_time_duration );
|
||||
sleeping_circuitpython_task = NULL;
|
||||
if (notify_value == 1) {
|
||||
mp_handle_pending();
|
||||
}
|
||||
xTaskNotifyWait(0x01, 0x01, NULL, portMAX_DELAY);
|
||||
}
|
||||
|
||||
// Wrap main in app_main that the IDF expects.
|
||||
|
@ -26,6 +26,7 @@
|
||||
*/
|
||||
|
||||
#include "supervisor/usb.h"
|
||||
#include "supervisor/esp_port.h"
|
||||
#include "lib/utils/interrupt_char.h"
|
||||
#include "lib/mp-readline/readline.h"
|
||||
|
||||
@ -33,8 +34,7 @@
|
||||
#include "components/driver/include/driver/periph_ctrl.h"
|
||||
#include "components/driver/include/driver/gpio.h"
|
||||
#include "components/esp_rom/include/esp32s2/rom/gpio.h"
|
||||
#include "components/esp_rom/include/esp_rom_gpio.h"
|
||||
#include "components/hal/esp32s2/include/hal/gpio_ll.h"
|
||||
#include "components/soc/src/esp32s2/include/hal/gpio_ll.h"
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
@ -52,8 +52,6 @@
|
||||
StackType_t usb_device_stack[USBD_STACK_SIZE];
|
||||
StaticTask_t usb_device_taskdef;
|
||||
|
||||
TaskHandle_t sleeping_circuitpython_task = NULL;
|
||||
|
||||
// USB Device Driver task
|
||||
// This top level thread process all usb events and invoke callbacks
|
||||
void usb_device_task(void* param)
|
||||
@ -78,23 +76,20 @@ static void configure_pins (usb_hal_context_t *usb)
|
||||
* Introduce additional parameters in usb_hal_context_t when adding support
|
||||
* for USB Host.
|
||||
*/
|
||||
for ( const usb_iopin_dsc_t *iopin = usb_periph_iopins; iopin->pin != -1; ++iopin ) {
|
||||
if ( (usb->use_external_phy) || (iopin->ext_phy_only == 0) ) {
|
||||
esp_rom_gpio_pad_select_gpio(iopin->pin);
|
||||
if ( iopin->is_output ) {
|
||||
esp_rom_gpio_connect_out_signal(iopin->pin, iopin->func, false, false);
|
||||
for (const usb_iopin_dsc_t* iopin = usb_periph_iopins; iopin->pin != -1; ++iopin) {
|
||||
if ((usb->use_external_phy) || (iopin->ext_phy_only == 0)) {
|
||||
gpio_pad_select_gpio(iopin->pin);
|
||||
if (iopin->is_output) {
|
||||
gpio_matrix_out(iopin->pin, iopin->func, false, false);
|
||||
} else {
|
||||
gpio_matrix_in(iopin->pin, iopin->func, false);
|
||||
gpio_pad_input_enable(iopin->pin);
|
||||
}
|
||||
else {
|
||||
esp_rom_gpio_connect_in_signal(iopin->pin, iopin->func, false);
|
||||
if ( (iopin->pin != GPIO_FUNC_IN_LOW) && (iopin->pin != GPIO_FUNC_IN_HIGH) ) {
|
||||
gpio_ll_input_enable(&GPIO, iopin->pin);
|
||||
}
|
||||
}
|
||||
esp_rom_gpio_pad_unhold(iopin->pin);
|
||||
gpio_pad_unhold(iopin->pin);
|
||||
}
|
||||
}
|
||||
if ( !usb->use_external_phy ) {
|
||||
gpio_set_drive_capability(USBPHY_DM_NUM, GPIO_DRIVE_CAP_3);
|
||||
if (!usb->use_external_phy) {
|
||||
gpio_set_drive_capability(USBPHY_DP_NUM, GPIO_DRIVE_CAP_3);
|
||||
gpio_set_drive_capability(USBPHY_DP_NUM, GPIO_DRIVE_CAP_3);
|
||||
}
|
||||
}
|
||||
@ -131,8 +126,6 @@ void tud_cdc_rx_wanted_cb(uint8_t itf, char wanted_char)
|
||||
mp_keyboard_interrupt();
|
||||
// CircuitPython's VM is run in a separate FreeRTOS task from TinyUSB.
|
||||
// So, we must notify the other task when a CTRL-C is received.
|
||||
if (sleeping_circuitpython_task != NULL) {
|
||||
xTaskNotifyGive(sleeping_circuitpython_task);
|
||||
}
|
||||
xTaskNotifyGive(circuitpython_task);
|
||||
}
|
||||
}
|
||||
|
@ -24,12 +24,14 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#include <unistd.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef CHAR_CTRL_C
|
||||
#define CHAR_CTRL_C (3)
|
||||
#endif
|
||||
|
||||
void mp_hal_set_interrupt_char(char c);
|
||||
bool mp_hal_is_interrupted(void);
|
||||
|
||||
void mp_hal_stdio_mode_raw(void);
|
||||
void mp_hal_stdio_mode_orig(void);
|
||||
|
@ -81,6 +81,10 @@ void mp_hal_set_interrupt_char(char c) {
|
||||
}
|
||||
}
|
||||
|
||||
bool mp_hal_is_interrupted(void) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#if MICROPY_USE_READLINE == 1
|
||||
|
||||
#include <termios.h>
|
||||
|
8
py/obj.c
8
py/obj.c
@ -29,6 +29,7 @@
|
||||
#include <stdarg.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "lib/utils/interrupt_char.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/objtype.h"
|
||||
#include "py/objint.h"
|
||||
@ -67,7 +68,12 @@ void mp_obj_print_helper(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t
|
||||
#ifdef RUN_BACKGROUND_TASKS
|
||||
RUN_BACKGROUND_TASKS;
|
||||
#endif
|
||||
mp_handle_pending();
|
||||
#if MICROPY_KBD_EXCEPTION
|
||||
// Stop printing if we've been interrupted.
|
||||
if (mp_hal_is_interrupted()) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef NDEBUG
|
||||
if (o_in == MP_OBJ_NULL) {
|
||||
|
2
py/vm.c
2
py/vm.c
@ -1015,7 +1015,7 @@ unwind_jump:;
|
||||
}
|
||||
#endif
|
||||
SET_TOP(mp_call_method_n_kw(unum & 0xff, (unum >> 8) & 0xff, sp));
|
||||
DISPATCH();
|
||||
DISPATCH_WITH_PEND_EXC_CHECK();
|
||||
}
|
||||
|
||||
ENTRY(MP_BC_CALL_METHOD_VAR_KW): {
|
||||
|
@ -71,8 +71,8 @@
|
||||
|
||||
void validate_objs_are_alarms(size_t n_args, const mp_obj_t *objs) {
|
||||
for (size_t i = 0; i < n_args; i++) {
|
||||
if (MP_OBJ_IS_TYPE(objs[i], &alarm_pin_pin_alarm_type) ||
|
||||
MP_OBJ_IS_TYPE(objs[i], &alarm_time_time_alarm_type)) {
|
||||
if (MP_OBJ_IS_TYPE(objs[i], &alarm_pin_pinalarm_type) ||
|
||||
MP_OBJ_IS_TYPE(objs[i], &alarm_time_timealarm_type)) {
|
||||
continue;
|
||||
}
|
||||
mp_raise_TypeError_varg(translate("Expected an alarm"));
|
||||
@ -159,7 +159,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(alarm_exit_and_deep_sleep_until_alarms_obj,
|
||||
STATIC const mp_map_elem_t alarm_pin_globals_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_pin) },
|
||||
|
||||
{ MP_ROM_QSTR(MP_QSTR_PinAlarm), MP_OBJ_FROM_PTR(&alarm_pin_pin_alarm_type) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_PinAlarm), MP_OBJ_FROM_PTR(&alarm_pin_pinalarm_type) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(alarm_pin_globals, alarm_pin_globals_table);
|
||||
@ -172,7 +172,7 @@ STATIC const mp_obj_module_t alarm_pin_module = {
|
||||
STATIC const mp_map_elem_t alarm_time_globals_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_time) },
|
||||
|
||||
{ MP_ROM_QSTR(MP_QSTR_TimeAlarm), MP_OBJ_FROM_PTR(&alarm_time_time_alarm_type) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_TimeAlarm), MP_OBJ_FROM_PTR(&alarm_time_timealarm_type) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(alarm_time_globals, alarm_time_globals_table);
|
||||
@ -201,6 +201,17 @@ STATIC mp_map_elem_t alarm_module_globals_table[] = {
|
||||
};
|
||||
STATIC MP_DEFINE_MUTABLE_DICT(alarm_module_globals, alarm_module_globals_table);
|
||||
|
||||
// Fetch value from module dict.
|
||||
mp_obj_t alarm_get_wake_alarm(void) {
|
||||
mp_map_elem_t *elem =
|
||||
mp_map_lookup(&alarm_module_globals.map, MP_ROM_QSTR(MP_QSTR_wake_alarm), MP_MAP_LOOKUP);
|
||||
if (elem) {
|
||||
return elem->value;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
STATIC void alarm_set_wake_alarm(mp_obj_t alarm) {
|
||||
// Equivalent of:
|
||||
// alarm.wake_alarm = alarm
|
||||
|
@ -43,6 +43,10 @@ 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);
|
||||
|
||||
// Fetches value from module dict.
|
||||
extern mp_obj_t alarm_get_wake_alarm(void);
|
||||
|
||||
extern void common_hal_alarm_gc_collect(void);
|
||||
extern mp_obj_t common_hal_alarm_get_wake_alarm(void);
|
||||
|
||||
// Used by wake-up code.
|
||||
@ -52,4 +56,5 @@ 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);
|
||||
|
||||
|
||||
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_ALARM___INIT___H
|
||||
|
@ -60,9 +60,9 @@
|
||||
//| """
|
||||
//| ...
|
||||
//|
|
||||
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;
|
||||
STATIC mp_obj_t alarm_pin_pinalarm_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_pinalarm_obj_t *self = m_new_obj(alarm_pin_pinalarm_obj_t);
|
||||
self->base.type = &alarm_pin_pinalarm_type;
|
||||
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 },
|
||||
@ -75,7 +75,7 @@ STATIC mp_obj_t alarm_pin_pin_alarm_make_new(const mp_obj_type_t *type, mp_uint_
|
||||
|
||||
mcu_pin_obj_t *pin = validate_obj_is_free_pin(args[ARG_pin].u_obj);
|
||||
|
||||
common_hal_alarm_pin_pin_alarm_construct(self,
|
||||
common_hal_alarm_pin_pinalarm_construct(self,
|
||||
pin,
|
||||
args[ARG_value].u_bool,
|
||||
args[ARG_edge].u_bool,
|
||||
@ -87,15 +87,19 @@ STATIC mp_obj_t alarm_pin_pin_alarm_make_new(const mp_obj_type_t *type, mp_uint_
|
||||
//| pin: microcontroller.Pin
|
||||
//| """The trigger pin."""
|
||||
//|
|
||||
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_pin(self);
|
||||
STATIC mp_obj_t alarm_pin_pinalarm_obj_get_pin(mp_obj_t self_in) {
|
||||
alarm_pin_pinalarm_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
mcu_pin_obj_t* pin = common_hal_alarm_pin_pinalarm_get_pin(self);
|
||||
if (pin == NULL) {
|
||||
return mp_const_none;
|
||||
}
|
||||
return MP_OBJ_FROM_PTR(pin);
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(alarm_pin_pin_alarm_get_pin_obj, alarm_pin_pin_alarm_obj_get_pin);
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(alarm_pin_pinalarm_get_pin_obj, alarm_pin_pinalarm_obj_get_pin);
|
||||
|
||||
const mp_obj_property_t alarm_pin_pin_alarm_pin_obj = {
|
||||
const mp_obj_property_t alarm_pin_pinalarm_pin_obj = {
|
||||
.base.type = &mp_type_property,
|
||||
.proxy = {(mp_obj_t)&alarm_pin_pin_alarm_get_pin_obj,
|
||||
.proxy = {(mp_obj_t)&alarm_pin_pinalarm_get_pin_obj,
|
||||
(mp_obj_t)&mp_const_none_obj,
|
||||
(mp_obj_t)&mp_const_none_obj},
|
||||
};
|
||||
@ -103,29 +107,29 @@ const mp_obj_property_t alarm_pin_pin_alarm_pin_obj = {
|
||||
//| value: bool
|
||||
//| """The value on which to trigger."""
|
||||
//|
|
||||
STATIC mp_obj_t alarm_pin_pin_alarm_obj_get_value(mp_obj_t self_in) {
|
||||
alarm_pin_pin_alarm_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
return mp_obj_new_bool(common_hal_alarm_pin_pin_alarm_get_value(self));
|
||||
STATIC mp_obj_t alarm_pin_pinalarm_obj_get_value(mp_obj_t self_in) {
|
||||
alarm_pin_pinalarm_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
return mp_obj_new_bool(common_hal_alarm_pin_pinalarm_get_value(self));
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(alarm_pin_pin_alarm_get_value_obj, alarm_pin_pin_alarm_obj_get_value);
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(alarm_pin_pinalarm_get_value_obj, alarm_pin_pinalarm_obj_get_value);
|
||||
|
||||
const mp_obj_property_t alarm_pin_pin_alarm_value_obj = {
|
||||
const mp_obj_property_t alarm_pin_pinalarm_value_obj = {
|
||||
.base.type = &mp_type_property,
|
||||
.proxy = {(mp_obj_t)&alarm_pin_pin_alarm_get_value_obj,
|
||||
.proxy = {(mp_obj_t)&alarm_pin_pinalarm_get_value_obj,
|
||||
(mp_obj_t)&mp_const_none_obj,
|
||||
(mp_obj_t)&mp_const_none_obj},
|
||||
};
|
||||
|
||||
STATIC const mp_rom_map_elem_t alarm_pin_pin_alarm_locals_dict_table[] = {
|
||||
{ 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) },
|
||||
STATIC const mp_rom_map_elem_t alarm_pin_pinalarm_locals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_pin), MP_ROM_PTR(&alarm_pin_pinalarm_pin_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_value), MP_ROM_PTR(&alarm_pin_pinalarm_value_obj) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(alarm_pin_pin_alarm_locals_dict, alarm_pin_pin_alarm_locals_dict_table);
|
||||
STATIC MP_DEFINE_CONST_DICT(alarm_pin_pinalarm_locals_dict, alarm_pin_pinalarm_locals_dict_table);
|
||||
|
||||
const mp_obj_type_t alarm_pin_pin_alarm_type = {
|
||||
const mp_obj_type_t alarm_pin_pinalarm_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_PinAlarm,
|
||||
.make_new = alarm_pin_pin_alarm_make_new,
|
||||
.locals_dict = (mp_obj_t)&alarm_pin_pin_alarm_locals_dict,
|
||||
.make_new = alarm_pin_pinalarm_make_new,
|
||||
.locals_dict = (mp_obj_t)&alarm_pin_pinalarm_locals_dict,
|
||||
};
|
||||
|
@ -24,20 +24,20 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_PIN_PIN_ALARM_H
|
||||
#define MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_PIN_PIN_ALARM_H
|
||||
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_PIN_PINALARM_H
|
||||
#define MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_PIN_PINALARM_H
|
||||
|
||||
#include "py/obj.h"
|
||||
#include "py/objtuple.h"
|
||||
#include "common-hal/microcontroller/Pin.h"
|
||||
#include "common-hal/alarm/pin/PinAlarm.h"
|
||||
|
||||
extern const mp_obj_type_t alarm_pin_pin_alarm_type;
|
||||
extern const mp_obj_type_t alarm_pin_pinalarm_type;
|
||||
|
||||
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);
|
||||
void common_hal_alarm_pin_pinalarm_construct(alarm_pin_pinalarm_obj_t *self, mcu_pin_obj_t *pin, bool value, bool edge, bool pull);
|
||||
extern mcu_pin_obj_t *common_hal_alarm_pin_pinalarm_get_pin(alarm_pin_pinalarm_obj_t *self);
|
||||
extern bool common_hal_alarm_pin_pinalarm_get_value(alarm_pin_pinalarm_obj_t *self);
|
||||
extern bool common_hal_alarm_pin_pinalarm_get_edge(alarm_pin_pinalarm_obj_t *self);
|
||||
extern bool common_hal_alarm_pin_pinalarm_get_pull(alarm_pin_pinalarm_obj_t *self);
|
||||
|
||||
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_PIN_PIN_ALARM_H
|
||||
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_PIN_PINALARM_H
|
||||
|
@ -56,10 +56,10 @@ mp_obj_t MP_WEAK rtc_get_time_source_time(void) {
|
||||
//| """
|
||||
//| ...
|
||||
//|
|
||||
STATIC mp_obj_t alarm_time_time_alarm_make_new(const mp_obj_type_t *type,
|
||||
STATIC mp_obj_t alarm_time_timealarm_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_time_time_alarm_obj_t *self = m_new_obj(alarm_time_time_alarm_obj_t);
|
||||
self->base.type = &alarm_time_time_alarm_type;
|
||||
alarm_time_timealarm_obj_t *self = m_new_obj(alarm_time_timealarm_obj_t);
|
||||
self->base.type = &alarm_time_timealarm_type;
|
||||
|
||||
enum { ARG_monotonic_time, ARG_epoch_time };
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
@ -105,7 +105,7 @@ STATIC mp_obj_t alarm_time_time_alarm_make_new(const mp_obj_type_t *type,
|
||||
mp_raise_ValueError(translate("Time is in the past."));
|
||||
}
|
||||
|
||||
common_hal_alarm_time_time_alarm_construct(self, monotonic_time);
|
||||
common_hal_alarm_time_timealarm_construct(self, monotonic_time);
|
||||
|
||||
return MP_OBJ_FROM_PTR(self);
|
||||
}
|
||||
@ -116,28 +116,28 @@ STATIC mp_obj_t alarm_time_time_alarm_make_new(const mp_obj_type_t *type,
|
||||
//| by this property only as a `time.monotonic()` time.
|
||||
//| """
|
||||
//|
|
||||
STATIC mp_obj_t alarm_time_time_alarm_obj_get_monotonic_time(mp_obj_t self_in) {
|
||||
alarm_time_time_alarm_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
return mp_obj_new_float(common_hal_alarm_time_time_alarm_get_monotonic_time(self));
|
||||
STATIC mp_obj_t alarm_time_timealarm_obj_get_monotonic_time(mp_obj_t self_in) {
|
||||
alarm_time_timealarm_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
return mp_obj_new_float(common_hal_alarm_time_timealarm_get_monotonic_time(self));
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(alarm_time_time_alarm_get_monotonic_time_obj, alarm_time_time_alarm_obj_get_monotonic_time);
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(alarm_time_timealarm_get_monotonic_time_obj, alarm_time_timealarm_obj_get_monotonic_time);
|
||||
|
||||
const mp_obj_property_t alarm_time_time_alarm_monotonic_time_obj = {
|
||||
const mp_obj_property_t alarm_time_timealarm_monotonic_time_obj = {
|
||||
.base.type = &mp_type_property,
|
||||
.proxy = {(mp_obj_t)&alarm_time_time_alarm_get_monotonic_time_obj,
|
||||
.proxy = {(mp_obj_t)&alarm_time_timealarm_get_monotonic_time_obj,
|
||||
(mp_obj_t)&mp_const_none_obj,
|
||||
(mp_obj_t)&mp_const_none_obj},
|
||||
};
|
||||
|
||||
STATIC const mp_rom_map_elem_t alarm_time_time_alarm_locals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_monotonic_time), MP_ROM_PTR(&alarm_time_time_alarm_monotonic_time_obj) },
|
||||
STATIC const mp_rom_map_elem_t alarm_time_timealarm_locals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_monotonic_time), MP_ROM_PTR(&alarm_time_timealarm_monotonic_time_obj) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(alarm_time_time_alarm_locals_dict, alarm_time_time_alarm_locals_dict_table);
|
||||
STATIC MP_DEFINE_CONST_DICT(alarm_time_timealarm_locals_dict, alarm_time_timealarm_locals_dict_table);
|
||||
|
||||
const mp_obj_type_t alarm_time_time_alarm_type = {
|
||||
const mp_obj_type_t alarm_time_timealarm_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_TimeAlarm,
|
||||
.make_new = alarm_time_time_alarm_make_new,
|
||||
.locals_dict = (mp_obj_t)&alarm_time_time_alarm_locals_dict,
|
||||
.make_new = alarm_time_timealarm_make_new,
|
||||
.locals_dict = (mp_obj_t)&alarm_time_timealarm_locals_dict,
|
||||
};
|
||||
|
@ -24,16 +24,16 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_TIME_MONOTONIC_TIME_ALARM_H
|
||||
#define MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_TIME_MONOTINIC_TIME_ALARM_H
|
||||
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_TIME_TIMEALARM_H
|
||||
#define MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_TIME_TIMEALARM_H
|
||||
|
||||
#include "py/obj.h"
|
||||
|
||||
#include "common-hal/alarm/time/TimeAlarm.h"
|
||||
|
||||
extern const mp_obj_type_t alarm_time_time_alarm_type;
|
||||
extern const mp_obj_type_t alarm_time_timealarm_type;
|
||||
|
||||
extern void common_hal_alarm_time_time_alarm_construct(alarm_time_time_alarm_obj_t *self, mp_float_t monotonic_time);
|
||||
extern mp_float_t common_hal_alarm_time_time_alarm_get_monotonic_time(alarm_time_time_alarm_obj_t *self);
|
||||
extern void common_hal_alarm_time_timealarm_construct(alarm_time_timealarm_obj_t *self, mp_float_t monotonic_time);
|
||||
extern mp_float_t common_hal_alarm_time_timealarm_get_monotonic_time(alarm_time_timealarm_obj_t *self);
|
||||
|
||||
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_TIME_MONOTONIC_TIME_ALARM_H
|
||||
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_ALARM_TIME_TIMEALARM_H
|
||||
|
@ -26,6 +26,7 @@
|
||||
|
||||
#include "supervisor/shared/tick.h"
|
||||
|
||||
#include "lib/utils/interrupt_char.h"
|
||||
#include "py/mpstate.h"
|
||||
#include "py/runtime.h"
|
||||
#include "supervisor/linker.h"
|
||||
@ -145,10 +146,11 @@ void mp_hal_delay_ms(mp_uint_t delay) {
|
||||
delay = delay * 1024 / 1000;
|
||||
uint64_t end_tick = start_tick + delay;
|
||||
int64_t remaining = delay;
|
||||
while (remaining > 0) {
|
||||
|
||||
// Loop until we've waited long enough or we've been CTRL-Ced by autoreload
|
||||
// or the user.
|
||||
while (remaining > 0 && !mp_hal_is_interrupted()) {
|
||||
RUN_BACKGROUND_TASKS;
|
||||
// Check to see if we've been CTRL-Ced by autoreload or the user.
|
||||
mp_handle_pending();
|
||||
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.
|
||||
|
Loading…
Reference in New Issue
Block a user