Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DRAFT: Use automatic light sleep for ESP32 alarm sleep #9559

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 30 additions & 1 deletion ports/espressif/common-hal/alarm/__init__.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@
// SPDX-FileCopyrightText: Copyright (c) 2020 Dan Halbert for Adafruit Industries
//
// SPDX-License-Identifier: MIT

#include <stdio.h>
#include "py/gc.h"
#include "py/obj.h"
#include "py/objtuple.h"
#include "py/runtime.h"
#include "py/mpprint.h"

#include "shared-bindings/alarm/__init__.h"
#include "shared-bindings/alarm/SleepMemory.h"
Expand All @@ -27,8 +28,10 @@

#include "supervisor/port.h"
#include "supervisor/shared/workflow.h"
#include "supervisor/shared/serial.h"

#include "esp_sleep.h"
#include "esp_pm.h"

#include "driver/gpio.h"
#include "driver/uart.h"
Expand Down Expand Up @@ -139,6 +142,27 @@ mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj

mp_obj_t wake_alarm = mp_const_none;

bool use_real_sleep = !serial_connected();


#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
esp_pm_config_t old_pm;
esp_pm_get_configuration(&old_pm);

esp_pm_config_t pm;
esp_pm_get_configuration(&pm);

pm.max_freq_mhz = 240;
pm.min_freq_mhz = 80;

if (use_real_sleep) {
pm.light_sleep_enable = true;
}

ESP_ERROR_CHECK_WITHOUT_ABORT(esp_pm_configure(&pm));
#endif


// We cannot esp_light_sleep_start() here because it shuts down all non-RTC peripherals.
while (!mp_hal_is_interrupted()) {
RUN_BACKGROUND_TASKS;
Expand Down Expand Up @@ -176,6 +200,11 @@ mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj
port_idle_until_interrupt();
}

#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
esp_pm_configure(&old_pm);
#endif


if (mp_hal_is_interrupted()) {
return mp_const_none; // Shouldn't be given to python code because exception handling should kick in.
}
Expand Down
4 changes: 3 additions & 1 deletion ports/espressif/common-hal/busio/UART.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "py/stream.h"
#include "supervisor/port.h"
#include "supervisor/shared/tick.h"
#include "esp_sleep.h"

static uint8_t never_reset_uart_mask = 0;

Expand Down Expand Up @@ -215,7 +216,8 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
if (uart_param_config(self->uart_num, &uart_config) != ESP_OK) {
mp_raise_RuntimeError(MP_ERROR_TEXT("UART init"));
}

uart_set_wakeup_threshold(self->uart_num, 1);
esp_sleep_enable_uart_wakeup(self->uart_num);
self->tx_pin = NULL;
self->rx_pin = NULL;
self->rts_pin = NULL;
Expand Down
3 changes: 2 additions & 1 deletion ports/espressif/esp-idf-config/sdkconfig.defaults
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ CONFIG_GPTIMER_ISR_IRAM_SAFE=y
# Power Management
#
CONFIG_PM_ENABLE=y # required for CIRCUITPY_SETTABLE_PROCESSOR_FREQUENCY

CONFIG_PM_PROFILING=y
#
# ESP System Settings
#
Expand All @@ -56,6 +56,7 @@ CONFIG_ESP_MAIN_TASK_STACK_SIZE=16384
# Kernel
#
CONFIG_FREERTOS_HZ=1000
CONFIG_FREERTOS_USE_TICKLESS_IDLE=y
# end of Kernel

#
Expand Down
1 change: 1 addition & 0 deletions ports/espressif/supervisor/port.c
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ safe_mode_t port_init(void) {
args.arg = NULL;
args.dispatch_method = ESP_TIMER_TASK;
args.name = "CircuitPython Tick";
args.skip_unhandled_events = true;
esp_timer_create(&args, &_tick_timer);

args.callback = &sleep_timer_cb;
Expand Down
10 changes: 9 additions & 1 deletion supervisor/shared/serial.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "supervisor/shared/cpu.h"
#include "supervisor/shared/display.h"
#include "shared-bindings/terminalio/Terminal.h"
#include "supervisor/port.h"
#include "supervisor/shared/serial.h"
#include "shared-bindings/microcontroller/Pin.h"

Expand Down Expand Up @@ -46,6 +47,10 @@ byte console_uart_rx_buf[64];
#endif
#endif

#if CIRCUITPY_CONSOLE_UART
static uint64_t _console_uart_rx_timestamp = 0;
#endif

#if CIRCUITPY_USB_DEVICE || CIRCUITPY_CONSOLE_UART
// Flag to note whether this is the first write after connection.
// Delay slightly on the first write to allow time for the host to set up things,
Expand Down Expand Up @@ -175,7 +180,9 @@ bool serial_connected(void) {
#endif

#if CIRCUITPY_CONSOLE_UART
return true;
if (_console_uart_rx_timestamp && (_console_uart_rx_timestamp + (60 * 1024 * 5) > port_get_raw_ticks(NULL))) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please breakout the 60 * 1024 * 5 into a macro that is documented with what it means.

return true;
}
#endif

#if CIRCUITPY_SERIAL_BLE
Expand Down Expand Up @@ -232,6 +239,7 @@ char serial_read(void) {
int uart_errcode;
char text;
common_hal_busio_uart_read(&console_uart, (uint8_t *)&text, 1, &uart_errcode);
_console_uart_rx_timestamp = port_get_raw_ticks(NULL);
return text;
}
#endif
Expand Down