Fix ee02 button-wakeup build: ext1 fallback for ESP32-S3
Firmware build check / build-check (push) Successful in 2m44s
Firmware build check / build-check (push) Successful in 2m44s
esp_sleep_enable_gpio_wakeup_on_hp_periph_powerdown() only exists on
ESP32-C6 (SOC_GPIO_SUPPORT_HP_PERIPH_PD_SLEEP_WAKEUP), so the ee02
(ESP32-S3) build failed with implicit-declaration errors in
{back,next,combo}_button.c once the epd13in3e driver's #error stopped
masking it.
Each button file now branches on that capability macro: the C6 path
(devkit/xiao) is untouched, and ESP32-S3 uses
esp_sleep_enable_ext1_wakeup_io() instead. The earlier ext1 attempt was
rejected on C6 hardware because its pull resistor didn't hold across
RTC_PERIPH power-down -- tracing the same path in ESP-IDF source shows
gpio_config()'s pull_up_en already delegates to rtc_gpio_pullup_en()
for RTC-capable pins on every non-original-ESP32 target, so the pull-up
should already survive the same power-down on S3. The _io() variant is
additive, so the three button files don't need cross-file mask
coordination. Also widens the button GPIO Kconfig range for
IDF_TARGET_ESP32S3 (0-21, matching its RTC-IO set) instead of the
C6-shaped 0-7.
Verified: ee02, devkit, and xiao all build clean end-to-end locally
(native ESP-IDF v6.0, no Docker in this sandbox). NOT verified: whether
this actually avoids the spurious-instant-wakeup bug on real EE02
hardware -- that failure mode was only ever confirmed empirically, not
root-caused in a way a compile can check. continue-on-error stays on
in CI's ee02 build step until that's confirmed.
This commit is contained in:
+49
-29
@@ -163,7 +163,7 @@ an ESP32-S3) existed and "xiao" alone stopped disambiguating hardware.
|
||||
The server keeps accepting the old bare names indefinitely, since
|
||||
already-flashed devices can't be retroactively renamed.
|
||||
|
||||
## 13.3" Spectra 6 panel on Seeed's EE02 board (panel driver ported; board still doesn't build end-to-end)
|
||||
## 13.3" Spectra 6 panel on Seeed's EE02 board (panel driver ported, `ee02` builds end-to-end; unverified on real hardware)
|
||||
|
||||
A second panel size is supported server-side (the web UI shows a
|
||||
read-only "Panel: 13.3\" Spectra 6" once a frame's device reports
|
||||
@@ -183,25 +183,38 @@ correction that came with it: the panel's SPI wire raster is a *native
|
||||
doesn't just rotate the image, it shreds it (1600x1200 and 1200x1600
|
||||
don't share a row stride).
|
||||
|
||||
**A full `ee02` build still fails**, but for an unrelated, pre-existing
|
||||
reason now that the panel driver's own `#error` no longer stops the
|
||||
build early: `firmware/main/{back,next,combo}_button.c` call
|
||||
`esp_sleep_enable_gpio_wakeup_on_hp_periph_powerdown()`, an ESP32-C6-only
|
||||
deep-sleep GPIO-wakeup API (gated by `SOC_GPIO_SUPPORT_HP_PERIPH_PD_SLEEP_WAKEUP`,
|
||||
which ESP32-S3's `soc_caps.h` doesn't define) with no ESP32-S3 fallback
|
||||
path. This was always broken for `ee02`, just masked behind the panel
|
||||
driver's own compile failure -- see the note two paragraphs up about the
|
||||
button GPIO range not yet being verified against the ESP32-S3, which was
|
||||
already flagging this same gap before it had an actual compile error
|
||||
attached to it. ESP32-S3 does support GPIO deep-sleep wakeup via
|
||||
`esp_sleep_enable_ext1_wakeup()`/`esp_sleep_get_ext1_wakeup_status()`
|
||||
(and so, notably, does ESP32-C6 -- `SOC_PM_SUPPORT_EXT1_WAKEUP` is set on
|
||||
both chips), but EXT1 wakeup takes one combined GPIO mask/mode across all
|
||||
three button files' independent calls rather than each button
|
||||
registering its own -- porting to it is a real (if likely small)
|
||||
cross-board refactor, not a mechanical swap, and hasn't been done. CI's
|
||||
`firmware-build-check.yml`/`firmware-release-build.yml` `continue-on-error`
|
||||
on this board's step stays in place until it is.
|
||||
**A full `ee02` build now succeeds** (verified locally with a native,
|
||||
non-Docker ESP-IDF v6.0 install -- see
|
||||
`.claude/skills/build-firmware/SKILL.md`); `firmware/main/{back,next,combo}_button.c`
|
||||
used to call `esp_sleep_enable_gpio_wakeup_on_hp_periph_powerdown()`, an
|
||||
ESP32-C6-only deep-sleep GPIO-wakeup API (gated by
|
||||
`SOC_GPIO_SUPPORT_HP_PERIPH_PD_SLEEP_WAKEUP`, which ESP32-S3's
|
||||
`soc_caps.h` doesn't define) with no ESP32-S3 fallback path. Each of the
|
||||
three button files now branches on that same capability macro: the
|
||||
ESP32-C6 path (devkit/xiao) is untouched, and a new ESP32-S3 path uses
|
||||
`esp_sleep_enable_ext1_wakeup_io()` (not the non-`_io()`
|
||||
`esp_sleep_enable_ext1_wakeup()`, which resets any previously-registered
|
||||
mask -- the `_io()` variant is additive, confirmed by reading
|
||||
`esp_hw_support/sleep_modes.c`, so the three button files can each keep
|
||||
registering their own GPIO independently, no combined-mask coordination
|
||||
needed) plus `esp_sleep_get_ext1_wakeup_status()` for the wake-cause
|
||||
check. The original C6 EXT1 attempt was rejected on hardware because
|
||||
its pull resistor didn't hold across the RTC_PERIPH power-down (see
|
||||
`firmware/main/next_button.c`'s `next_button_init()` comment) -- tracing
|
||||
the same code path for ESP32-S3 shows `gpio_config()`'s `pull_up_en`
|
||||
(already used by all three button files) delegates to
|
||||
`rtc_gpio_pullup_en()` for RTC-capable pins on every non-original-ESP32
|
||||
target (confirmed in `esp_driver_gpio/gpio.c`: `GPIO_RTCIO_ARE_INDEPENDENT`
|
||||
is 1 for both C6 and S3, meaning the digital and RTC pull registers are
|
||||
independent hardware and `gpio_config()` already sets the RTC one), so
|
||||
the pull-up should already survive the same power-down on ESP32-S3
|
||||
without any extra `rtc_gpio_*` calls. That reasoning is verified against
|
||||
IDF source, **not against real EE02 hardware** -- a clean compile
|
||||
confirms the code builds and links, not that it's actually
|
||||
spurious-wakeup-free on a real board. CI's
|
||||
`firmware-build-check.yml`/`firmware-release-build.yml`
|
||||
`continue-on-error` on this board's step is intentionally still in place
|
||||
until that hardware verification happens.
|
||||
|
||||
Confirmed so far:
|
||||
|
||||
@@ -235,11 +248,16 @@ Confirmed so far:
|
||||
| Panel power-enable | 43 | `EPD_PIN_POWER_EN` |
|
||||
|
||||
User buttons are reportedly at GPIO 2/3/5, but which physical button
|
||||
maps to which logical role (next/back/menu) isn't confirmed, and the
|
||||
maps to which logical role (next/back/menu) still isn't confirmed. The
|
||||
firmware's button Kconfig options (`FRAME_NEXT_BUTTON_GPIO` etc.,
|
||||
`firmware/main/Kconfig.projbuild`) still range-limit to GPIO 0-7 --
|
||||
the ESP32-C6's deep-sleep-wakeup-capable set (see the build-blocker
|
||||
note above). SPI clock is reportedly reliable only up to 2MHz on this
|
||||
`firmware/main/Kconfig.projbuild`) now range to GPIO -1 to 21 under
|
||||
`IDF_TARGET_ESP32S3` (the ESP32-S3's own ext1-wakeup-capable RTC-IO
|
||||
range) instead of the ESP32-C6-shaped -1 to 7, so GPIO 2/3/5 fit
|
||||
regardless -- but `firmware/sdkconfig.ee02` still deliberately doesn't
|
||||
override the defaults inherited from the C6 boards (GPIO 2/0/1) until
|
||||
the role mapping above is confirmed.
|
||||
|
||||
SPI clock is reportedly reliable only up to 2MHz on this
|
||||
panel/board per the community ESPHome integration (vs. epd7in3e's 4MHz
|
||||
default) -- see `firmware/sdkconfig.ee02`. Waveshare's own
|
||||
ESP32-S3-ePaper-13.3E6 example defaults to 10MHz, but that's a
|
||||
@@ -247,8 +265,10 @@ Confirmed so far:
|
||||
hardware exists, not a reason to bump the current conservative default
|
||||
blind.
|
||||
|
||||
Once the button-wakeup gap above is fixed, remaining unknowns before
|
||||
trusting this on real hardware: the wiring table (community-sourced, not
|
||||
official), and `PANEL_WIRE_TRANSPOSE`'s rotation *direction*
|
||||
(`ROTATE_90` vs `ROTATE_270` -- a physical-assembly fact no vendor driver
|
||||
encodes, see that dict's own comment in `image_pipeline.py`).
|
||||
Remaining unknowns before trusting this on real hardware: whether the
|
||||
ESP32-S3 button-wakeup path above actually avoids a spurious-instant-wakeup
|
||||
on a real board (not just compiles), the button-to-role mapping, the
|
||||
wiring table (community-sourced, not official), and
|
||||
`PANEL_WIRE_TRANSPOSE`'s rotation *direction* (`ROTATE_90` vs
|
||||
`ROTATE_270` -- a physical-assembly fact no vendor driver encodes, see
|
||||
that dict's own comment in `image_pipeline.py`).
|
||||
|
||||
+24
-22
@@ -2,9 +2,9 @@
|
||||
|
||||
ESP-IDF firmware for the ESP32-C6 (devkit/xiao boards, 7.3" panel) or
|
||||
ESP32-S3 (ee02 board, 13.3" panel -- see
|
||||
[Building for Seeed's EE02](#building-for-seeeds-ee02-esp32-s3--133-panel-driver-ported-board-still-doesnt-build-end-to-end)
|
||||
below; the panel driver itself works now, but the board doesn't build
|
||||
end-to-end yet for an unrelated reason). On first boot it provisions itself over
|
||||
[Building for Seeed's EE02](#building-for-seeeds-ee02-esp32-s3--133-panel-driver-ported-ee02-builds-end-to-end-unverified-on-real-hardware)
|
||||
below; it builds end-to-end now, but is still unverified on real EE02
|
||||
hardware). On first boot it provisions itself over
|
||||
a WiFi captive portal; after that it wakes on a timer, fetches an
|
||||
already-processed frame from the [server](../server/), streams it straight
|
||||
to the panel over SPI, and goes back to deep sleep.
|
||||
@@ -52,7 +52,7 @@ never clobbers the other:
|
||||
(`./build_for_board.sh devkit ...` does the same for the dev board --
|
||||
equivalent to a plain `idf.py`, just consistent with the XIAO invocation.)
|
||||
|
||||
### Building for Seeed's EE02 (ESP32-S3 + 13.3" panel, driver ported; board still doesn't build end-to-end)
|
||||
### Building for Seeed's EE02 (ESP32-S3 + 13.3" panel, driver ported; `ee02` builds end-to-end, unverified on real hardware)
|
||||
|
||||
EE02 is a different chip (ESP32-S3, not C6), so it needs `set-target
|
||||
esp32s3` instead of `esp32c6`, and its own partition table/flash-size
|
||||
@@ -64,25 +64,27 @@ Kconfig sized for its 16MB flash
|
||||
./build_for_board.sh ee02 build
|
||||
```
|
||||
|
||||
**This still fails to compile, but no longer because of the panel
|
||||
driver.** `firmware/components/epd13in3e`'s panel init/LUT/refresh
|
||||
register sequence is now a real, vendor-confirmed port (see that
|
||||
component's own top comment and
|
||||
[`docs/hardware.md`](../docs/hardware.md#133-spectra-6-panel-on-seeeds-ee02-board-panel-driver-ported-board-still-doesnt-build-end-to-end)
|
||||
**This now compiles and links clean end-to-end**, verified locally with
|
||||
a native, non-Docker ESP-IDF v6.0 install (see
|
||||
`.claude/skills/build-firmware/SKILL.md`).
|
||||
`firmware/components/epd13in3e`'s panel init/LUT/refresh register
|
||||
sequence is a real, vendor-confirmed port (see that component's own top
|
||||
comment and
|
||||
[`docs/hardware.md`](../docs/hardware.md#133-spectra-6-panel-on-seeeds-ee02-board-panel-driver-ported-ee02-builds-end-to-end-unverified-on-real-hardware)
|
||||
for the vendor sources and the load-bearing native-raster-orientation
|
||||
correction that came with it) -- it compiles clean on its own. The build
|
||||
now fails one step later, in `main/{back,next,combo}_button.c`: they call
|
||||
an ESP32-C6-only deep-sleep GPIO-wakeup API with no ESP32-S3 fallback, a
|
||||
pre-existing gap that the panel driver's old `#error` simply stopped the
|
||||
build before reaching. See `docs/hardware.md`'s same section for what a
|
||||
real fix looks like (not a mechanical swap -- ESP32-S3's equivalent API
|
||||
takes one combined mask across all three button files' independent
|
||||
calls). Everything else around the panel driver (target selection,
|
||||
Kconfig, partition table, sdkconfig layering, `main/CMakeLists.txt`'s
|
||||
component selection) is in place and exercised by CI
|
||||
(`.gitea/workflows/firmware-build-check.yml`/`firmware-release-build.yml`,
|
||||
both with `continue-on-error` on this board's step until a full build is
|
||||
actually green).
|
||||
correction that came with it). `main/{back,next,combo}_button.c` used to
|
||||
call an ESP32-C6-only deep-sleep GPIO-wakeup API with no ESP32-S3
|
||||
fallback; each now branches on `SOC_GPIO_SUPPORT_HP_PERIPH_PD_SLEEP_WAKEUP`
|
||||
to keep the ESP32-C6 path (devkit/xiao) untouched while using
|
||||
`esp_sleep_enable_ext1_wakeup_io()` on ESP32-S3 -- see `docs/hardware.md`'s
|
||||
same section for why the additive `_io()` variant needs no combined-mask
|
||||
coordination across the three button files, and why the pull-resistor
|
||||
concern that ruled out EXT1 wakeup on ESP32-C6 doesn't apply the same
|
||||
way here. That reasoning is confirmed against ESP-IDF source, **not
|
||||
against real EE02 hardware** -- CI's
|
||||
(`.gitea/workflows/firmware-build-check.yml`/`firmware-release-build.yml`)
|
||||
`continue-on-error` on this board's step is intentionally still in place
|
||||
until it is.
|
||||
|
||||
## Configuration (`idf.py menuconfig`)
|
||||
|
||||
|
||||
@@ -142,6 +142,7 @@ menu "ESPresso Frame Configuration"
|
||||
config FRAME_NEXT_BUTTON_GPIO
|
||||
int "Next-photo button GPIO (-1 to disable)"
|
||||
default 2
|
||||
range -1 21 if IDF_TARGET_ESP32S3
|
||||
range -1 7
|
||||
help
|
||||
Button wired between this GPIO and GND (active-low, internal
|
||||
@@ -149,14 +150,17 @@ menu "ESPresso Frame Configuration"
|
||||
Pressing it wakes the device (if asleep), forces the server to
|
||||
advance to the next photo immediately (POST /frame/advance)
|
||||
regardless of the configured refresh interval, and displays
|
||||
it. Must be GPIO 0-7 -- the only pins the ESP32-C6 can use as
|
||||
a deep-sleep GPIO wakeup source, which is what lets a press
|
||||
wake the device promptly instead of only being noticed during
|
||||
its brief awake windows. Set to -1 to disable the feature.
|
||||
it. Must be a deep-sleep-wakeup-capable GPIO: 0-7 on the
|
||||
ESP32-C6, 0-21 on the ESP32-S3 (RTC-IO pins reachable by
|
||||
esp_sleep_enable_ext1_wakeup_io()) -- required so a press
|
||||
wakes the device promptly instead of only being noticed
|
||||
during its brief awake windows. Set to -1 to disable the
|
||||
feature.
|
||||
|
||||
config FRAME_BACK_BUTTON_GPIO
|
||||
int "Back-photo button GPIO (-1 to disable)"
|
||||
default 0
|
||||
range -1 21 if IDF_TARGET_ESP32S3
|
||||
range -1 7
|
||||
help
|
||||
Button wired between this GPIO and GND (active-low, internal
|
||||
@@ -165,13 +169,14 @@ menu "ESPresso Frame Configuration"
|
||||
to return to the previously-current photo immediately
|
||||
(POST /frame/back), and displays it. Pressing next
|
||||
afterwards returns to where you were before pressing back.
|
||||
Must be GPIO 0-7 for the same deep-sleep-wakeup reason as
|
||||
Must be a deep-sleep-wakeup-capable GPIO, same range as
|
||||
FRAME_NEXT_BUTTON_GPIO above; defaults to a different pin
|
||||
than the other buttons. Set to -1 to disable the feature.
|
||||
|
||||
config FRAME_COMBO_BUTTON_GPIO
|
||||
int "Menu/reset button GPIO (-1 to disable)"
|
||||
default 1
|
||||
range -1 21 if IDF_TARGET_ESP32S3
|
||||
range -1 7
|
||||
help
|
||||
Button wired between this GPIO and GND (active-low, internal
|
||||
@@ -182,8 +187,8 @@ menu "ESPresso Frame Configuration"
|
||||
then releasing shows the management menu; holding it all the
|
||||
way to FRAME_COMBO_FACTORY_RESET_HOLD_MS clears the stored
|
||||
config and restarts into provisioning, regardless of whether
|
||||
it's released yet. Must be GPIO 0-7 for the same deep-sleep-
|
||||
wakeup reason as FRAME_NEXT_BUTTON_GPIO above; defaults to
|
||||
it's released yet. Must be a deep-sleep-wakeup-capable GPIO,
|
||||
same range as FRAME_NEXT_BUTTON_GPIO above; defaults to
|
||||
a different pin than the other buttons. Set to -1 to
|
||||
disable the feature entirely (also disables the management
|
||||
menu, both reset tiers, and factory-reset-via-button --
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "driver/gpio.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_sleep.h"
|
||||
#include "soc/soc_caps.h"
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
@@ -35,10 +36,17 @@ void back_button_init(void)
|
||||
};
|
||||
gpio_config(&io_conf);
|
||||
|
||||
#if SOC_GPIO_SUPPORT_HP_PERIPH_PD_SLEEP_WAKEUP
|
||||
/* See next_button.c for why this API (not ext1) -- it manages the
|
||||
* pull resistor across the sleep transition itself, so the pin
|
||||
* doesn't float and wake the device spuriously. */
|
||||
esp_sleep_enable_gpio_wakeup_on_hp_periph_powerdown(1ULL << BACK_BUTTON_GPIO, ESP_GPIO_WAKEUP_GPIO_LOW);
|
||||
#else
|
||||
/* See next_button.c for why ext1 is safe here on targets without the
|
||||
* API above (e.g. ESP32-S3), and why _io() needs no cross-file mask
|
||||
* coordination. */
|
||||
ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup_io(1ULL << BACK_BUTTON_GPIO, ESP_EXT1_WAKEUP_ANY_LOW));
|
||||
#endif
|
||||
}
|
||||
|
||||
back_button_result_t back_button_check(void)
|
||||
@@ -49,7 +57,11 @@ back_button_result_t back_button_check(void)
|
||||
* status register is latched at the moment of waking and isn't
|
||||
* cleared until the next sleep entry, so it reliably reflects a tap
|
||||
* regardless of how quickly it was released. */
|
||||
#if SOC_GPIO_SUPPORT_HP_PERIPH_PD_SLEEP_WAKEUP
|
||||
bool caused_wake = esp_sleep_get_gpio_wakeup_status() & (1ULL << BACK_BUTTON_GPIO);
|
||||
#else
|
||||
bool caused_wake = esp_sleep_get_ext1_wakeup_status() & (1ULL << BACK_BUTTON_GPIO);
|
||||
#endif
|
||||
|
||||
if (!caused_wake) {
|
||||
/* Not a GPIO-wakeup-from-this-pin boot (normal timer wake, or a
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "driver/gpio.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_sleep.h"
|
||||
#include "soc/soc_caps.h"
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
@@ -31,10 +32,17 @@ void combo_button_init(void)
|
||||
};
|
||||
gpio_config(&io_conf);
|
||||
|
||||
#if SOC_GPIO_SUPPORT_HP_PERIPH_PD_SLEEP_WAKEUP
|
||||
/* See next_button.c for why this API (not ext1) -- it manages the
|
||||
* pull resistor across the sleep transition itself, so the pin
|
||||
* doesn't float and wake the device spuriously. */
|
||||
esp_sleep_enable_gpio_wakeup_on_hp_periph_powerdown(1ULL << COMBO_BUTTON_GPIO, ESP_GPIO_WAKEUP_GPIO_LOW);
|
||||
#else
|
||||
/* See next_button.c for why ext1 is safe here on targets without the
|
||||
* API above (e.g. ESP32-S3), and why _io() needs no cross-file mask
|
||||
* coordination. */
|
||||
ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup_io(1ULL << COMBO_BUTTON_GPIO, ESP_EXT1_WAKEUP_ANY_LOW));
|
||||
#endif
|
||||
}
|
||||
|
||||
bool combo_button_check(void)
|
||||
@@ -48,7 +56,11 @@ bool combo_button_check(void)
|
||||
* caused the wake even if it's since been released -- in which case
|
||||
* the poll loop below simply measures 0ms held, correctly resolving
|
||||
* to a quick press rather than "not pressed at all." */
|
||||
#if SOC_GPIO_SUPPORT_HP_PERIPH_PD_SLEEP_WAKEUP
|
||||
bool caused_wake = esp_sleep_get_gpio_wakeup_status() & (1ULL << COMBO_BUTTON_GPIO);
|
||||
#else
|
||||
bool caused_wake = esp_sleep_get_ext1_wakeup_status() & (1ULL << COMBO_BUTTON_GPIO);
|
||||
#endif
|
||||
if (!caused_wake && gpio_get_level(COMBO_BUTTON_GPIO) != 0) {
|
||||
return false; /* not pressed, and didn't cause this wake either */
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "driver/gpio.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_sleep.h"
|
||||
#include "soc/soc_caps.h"
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
@@ -36,13 +37,44 @@ void next_button_init(void)
|
||||
};
|
||||
gpio_config(&io_conf);
|
||||
|
||||
/* Not esp_sleep_enable_ext1_wakeup_io(): its internal pull resistors
|
||||
* don't hold once the RTC_PERIPH domain powers down for deep sleep, so
|
||||
* the pin floats and reads spuriously low, waking the device instantly
|
||||
* on every sleep entry (confirmed on hardware). This GPIO-wakeup
|
||||
* variant manages the pull resistor itself across the sleep
|
||||
* transition. */
|
||||
#if SOC_GPIO_SUPPORT_HP_PERIPH_PD_SLEEP_WAKEUP
|
||||
/* Not esp_sleep_enable_ext1_wakeup_io() on its own: on a target
|
||||
* without RTC-independent digital pull registers, ext1's internal
|
||||
* pull resistors don't hold once the RTC_PERIPH domain powers down
|
||||
* for deep sleep, so the pin floats and reads spuriously low, waking
|
||||
* the device instantly on every sleep entry (confirmed on hardware,
|
||||
* ESP32-C6). This GPIO-wakeup variant manages the pull resistor
|
||||
* itself across the sleep transition, sidestepping the issue
|
||||
* entirely -- but it only exists on chips with this capability
|
||||
* (currently just ESP32-C6; see the #else below for other targets,
|
||||
* e.g. ESP32-S3). */
|
||||
esp_sleep_enable_gpio_wakeup_on_hp_periph_powerdown(1ULL << NEXT_BUTTON_GPIO, ESP_GPIO_WAKEUP_GPIO_LOW);
|
||||
#else
|
||||
/* No HP-periph-powerdown wakeup API here (e.g. ESP32-S3) -- fall
|
||||
* back to ext1, but NOT naively: on every non-original-ESP32 target
|
||||
* (ESP32-S3 included), gpio_pullup_en() -- which the gpio_config()
|
||||
* call above invokes via pull_up_en -- delegates to
|
||||
* rtc_gpio_pullup_en() for RTC-capable pins (confirmed in
|
||||
* esp_driver_gpio's gpio.c: GPIO_RTCIO_ARE_INDEPENDENT is 1 for
|
||||
* every target except the original ESP32, meaning digital and RTC
|
||||
* pull registers are independent hardware and gpio_config() already
|
||||
* routes the pull-up through the RTC pad's own register for these
|
||||
* pins, not just the digital one). That's exactly what was missing
|
||||
* in the ext1 attempt that failed on hardware above -- so on this
|
||||
* target the pull-up already survives the RTC_PERIPH power-down
|
||||
* ext1 wakeup requires, without needing a separate rtc_gpio_*_en()
|
||||
* call here. _io() (not the bare esp_sleep_enable_ext1_wakeup(),
|
||||
* which resets any previously-configured mask) is additive across
|
||||
* this file's, back_button.c's, and combo_button.c's independent
|
||||
* init calls -- confirmed in esp_hw_support's sleep_modes.c -- so no
|
||||
* shared-mask coordination between the three button files is
|
||||
* needed. Still unconfirmed on real EE02 hardware: this avoids the
|
||||
* *documented* failure mode of the earlier ext1 attempt, but that
|
||||
* attempt was never root-caused beyond "confirmed spurious wakeup on
|
||||
* hardware" -- treat this as untested until it's actually run on an
|
||||
* EE02 board. */
|
||||
ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup_io(1ULL << NEXT_BUTTON_GPIO, ESP_EXT1_WAKEUP_ANY_LOW));
|
||||
#endif
|
||||
}
|
||||
|
||||
next_button_result_t next_button_check(void)
|
||||
@@ -53,7 +85,11 @@ next_button_result_t next_button_check(void)
|
||||
* status register is latched at the moment of waking and isn't
|
||||
* cleared until the next sleep entry, so it reliably reflects a tap
|
||||
* regardless of how quickly it was released. */
|
||||
#if SOC_GPIO_SUPPORT_HP_PERIPH_PD_SLEEP_WAKEUP
|
||||
bool caused_wake = esp_sleep_get_gpio_wakeup_status() & (1ULL << NEXT_BUTTON_GPIO);
|
||||
#else
|
||||
bool caused_wake = esp_sleep_get_ext1_wakeup_status() & (1ULL << NEXT_BUTTON_GPIO);
|
||||
#endif
|
||||
|
||||
if (!caused_wake) {
|
||||
/* Not a GPIO-wakeup-from-this-pin boot (normal timer wake, or a
|
||||
|
||||
+14
-9
@@ -34,12 +34,17 @@ CONFIG_PARTITION_TABLE_FILENAME="partitions_ee02.csv"
|
||||
# Deliberately NOT overriding FRAME_NEXT_BUTTON_GPIO/FRAME_BACK_BUTTON_
|
||||
# GPIO/FRAME_COMBO_BUTTON_GPIO/FRAME_BATTERY_ADC_GPIO here, even though
|
||||
# the same community source that gave the epd13in3e pinout also reports
|
||||
# EE02 has 3 user buttons at GPIO2/3/5: (1) which physical button maps to
|
||||
# which logical role (next/back/combo) isn't confirmed, and (2) more
|
||||
# importantly, those Kconfig options' `range -1 7`/`range -1 6`
|
||||
# constraints (main/Kconfig.projbuild) are hardcoded to the ESP32-C6's
|
||||
# deep-sleep-wakeup-capable GPIO set -- NOT verified against which pins
|
||||
# can actually wake the ESP32-S3 from deep sleep, which is a different
|
||||
# set on a different chip. Confirm both before wiring this up; widen/
|
||||
# adjust those Kconfig ranges if the real wakeup-capable pins for
|
||||
# whichever GPIOs EE02's buttons land on fall outside them.
|
||||
# EE02 has 3 user buttons at GPIO2/3/5: which physical button maps to
|
||||
# which logical role (next/back/combo) still isn't confirmed. The
|
||||
# button GPIOs' `range -1 7` constraint (main/Kconfig.projbuild) -- which
|
||||
# used to be hardcoded to the ESP32-C6's deep-sleep-wakeup-capable GPIO
|
||||
# set -- now widens to `range -1 21` under IDF_TARGET_ESP32S3 (the
|
||||
# ESP32-S3's own ext1-wakeup-capable RTC-IO range), so GPIO2/3/5 fit
|
||||
# either way and nothing here needs adjusting on that front. What's
|
||||
# still unconfirmed: (1) the button-to-role mapping above, and (2)
|
||||
# whether the S3 button-wakeup path itself (ext1 + RTC pull-up, see
|
||||
# main/next_button.c) actually avoids the spurious-instant-wakeup bug
|
||||
# that ruled out ext1 on the ESP32-C6 -- that needs real EE02 hardware,
|
||||
# not just a clean compile. FRAME_BATTERY_ADC_GPIO's `range -1 6` is a
|
||||
# separate, still-unwidened concern -- it's the ESP32-C6's ADC-capable
|
||||
# pin set, not a deep-sleep-wakeup range, and out of scope here.
|
||||
|
||||
Reference in New Issue
Block a user