Visitar URL original
esp32: add ESP32-S31 SoC support by cumin777 · Pull Request #19726 · micropython/micropython · GitHub
Skip to content

esp32: add ESP32-S31 SoC support - #19726

Open
cumin777 wants to merge 8 commits into
micropython:masterfrom
cumin777:s31-pr2-soc
Open

cumin777 wants to merge 8 commits into
micropython:masterfrom
cumin777:s31-pr2-soc

Conversation

@cumin777

Copy link
Copy Markdown
Contributor

Summary

Adds ESP32-S31 support to the esp32 port. Requires ESP-IDF v6.1+ (the first IDF release with S31 headers). Depends on #19725 -- this branch contains that commit stack.

Large parts of the SoC bring-up are reused from #19421 (thanks to its author); this PR keeps only the generic SoC support, reworked per the review feedback there, and splits the IDF v6 compatibility layer into #19725.

  • New board ESP32_GENERIC_S31 (WROOM-3 style module, 16MiB flash): native USB CDC/MSC console on the OTG HS port with UART0 REPL as secondary; USB-Serial-JTAG console is mutually exclusive with native USB (same default as GENERIC_S3). partitions-16MiBplus.csv, sdkconfig.s31, mpconfigboard_esp32s31_common.cmake.
  • SoC tables: GPIO 0-61 (29/41 not bonded), ADC1 = GPIO42-49 / ADC2 = GPIO50-57 (S31 has no ADC calibration scheme: read_uv() raises NotImplementedError), touch v3 channels 0-13 = GPIO6-19, timer groups, PCNT x4, LDO, rv32imc+zcmp.
  • USB high speed: CFG_TUSB_RHPORT0_MODE = DEVICE|HIGH_SPEED via the UTMI PHY (usb_new_phy(USB_PHY_TARGET_UTMI)); HS-only SoC with the PHY on port 0 (unlike P4's port 1).
  • tinyusb source switch (main/idf_component.yml): from the micropython/tinyusb-espressif fork to registry espressif/tinyusb 0.19.0~3 for all targets. The fork has no S31 DWC2 support and a manifest cannot select different sources per target; the registry release also carries the DWC2 OUT-EP ZLP fix (ESP32-S3 bulk transfer issues #3154 hathach/tinyusb#3293) that the fork existed to provide.
  • CI: esp32_build_s31 on the v6.1 leg only (S31 does not exist in IDF 5.x).

Known scope limits (intended follow-ups): S31 has an EMAC but the external-PHY driver paths in network_lan.c remain ESP32/P4-only, so network.LAN compiles without external PHY drivers on S31; a SPIRAM_OCT variant (16MiB octal PSRAM on WROOM-3) is not included yet.

Testing

Built with IDF v6.1.0 and verified on an ESP32-S31-Function-CoreBoard-1 (WROOM-3, 16MiB flash + 16MiB octal PSRAM):

  • USB CDC REPL on the OTG port: enumerates and runs, survives resets and serial re-open cycles; drops and re-enumerates across machine.lightsleep(), as on other native-USB targets.
  • Peripheral smoke suite 16/16: sys/machine info, heap/GC, flash partition + VFS, GPIO + Boot button, WS2812 via machine.bitstream (RMT and bit-bang paths), ADC (read_u16; read_uv raises as expected), touch, Timer, PCNT (construct/value/deinit), I2C scan, SPI, RTC, WiFi scan, BLE init, lightsleep.
  • IDF v6.1 matrix for all other targets still green; IDF v5.5.5 regression in esp32: add ESP-IDF v6 build compatibility #19725.

Trade-offs and Alternatives

  • Switching all targets from the tinyusb fork to the registry component is deliberate: the fork has no S31 DWC2 port, and the component manager's manifest cannot select different sources (git vs registry) per target -- matches entries require semver versions. The registry release contains the DWC2 ZLP fix the fork was created for, so no functionality is lost on existing targets.
  • Native-USB console and USB-Serial-JTAG console are mutually exclusive (single OTG peripheral); the board default follows GENERIC_S3.

Generative AI

I used generative AI tools when creating this PR, but a human has checked the code and is responsible for the code and the description above.

@github-actions

github-actions Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

Code size report:

Reference:  extmod: Remove support for mbedTLS <3.0. [19e685e]
Comparison: esp32: Regenerate component lockfiles after the esp_hosted re-pin. [merge of b4e7797]
  mpy-cross:    +0 +0.000% 
   bare-arm:    +0 +0.000% 
minimal x86:    +0 +0.000% 
   unix x64:    +0 +0.000% standard
      stm32:    +0 +0.000% PYBV10
      esp32:  +172 +0.010% ESP32_GENERIC[incl +28(data) -8(bss)]
     mimxrt:    +0 +0.000% TEENSY40
        rp2:    +0 +0.000% RPI_PICO_W
       samd:    +0 +0.000% ADAFRUIT_ITSYBITSY_M4_EXPRESS
  qemu rv32:    +0 +0.000% VIRT_RV32

@codecov

codecov Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.59%. Comparing base (19e685e) to head (b4e7797).

Additional details and impacted files
@@            Coverage Diff             @@
##           master   #19726      +/-   ##
==========================================
+ Coverage   98.55%   98.59%   +0.03%     
==========================================
  Files         182      182              
  Lines       23342    23342              
  Branches        5        5              
==========================================
+ Hits        23005    23013       +8     
+ Misses        336      328       -8     
  Partials        1        1              
Flag Coverage Δ
unix-coverage-32bit 98.59% <ø> (+0.03%) ⬆️
unix-coverage-64bit 98.52% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

cumin777 and others added 8 commits September 30, 2026 14:54
Support building the esp32 port against both ESP-IDF v5.3-v5.5 and v6.x,
keeping 5.x builds and lockfiles byte-compatible:

- extmod: guard mbedtls 3 vs 4 differences by MBEDTLS_VERSION_MAJOR
  (entropy/ctr_drbg removal, PSA-RNG cookie_setup and pk_parse_key
  signatures, PSA-Crypto hashlib, private-tree AES header for cryptolib)
- esp32: esp_flash_t is opaque in v6 (query size into a local)
- esp32: periph headers moved soc/ -> hal/ (uart, ledc, touch channel);
  guard ledc_periph_signal layout change in v6.1
- esp32: esp_interface_t/ESP_IF_* removed from esp_wifi (recreate);
  WPA3_EXT_PSK auth constants removed (guard with #ifdef)
- esp32: esp_wifi_config_espnow_rate() removed (per-peer rate config)
- esp32: deep-sleep GPIO wakeup API renamed in v6
- esp32: ADC_ATTEN_DB_11 renamed ADC_ATTEN_DB_12; SOC_I2S_NUM and
  SOC_PCNT_UNITS_PER_GROUP removed from soc_caps (recreate)
- esp32: rewrite esp32_pcnt.c onto the pulse_cnt driver API (the legacy
  driver/pcnt.h is gone in v6; watch points map 1:1 onto the legacy
  five-event model)
- esp32: version-gate IDF components removed/added in v6 (newlib, usb,
  mbedtls_errors, esp_hal_timg, esp_driver_*)
- esp32: internal-MAC Ethernet PHY drivers moved to the component
  registry in v6; add them to the manifest gated on
  'idf_version >= 6.0 && target in [esp32, esp32p4]' so 5.x lockfiles
  resolve without them (verified: 5.5.5 regen changes only
  manifest_hash lines plus pre-existing registry drift)
- berkeley-db: provide legacy sys/cdefs.h macros (__P, __BEGIN_DECLS,
  __END_DECLS) when the toolchain lacks them (IDF v6 newlib)
- ci: add a v6.1 leg to the esp32 workflow matrix (lockfiles are only
  enforced on the newest 5.x, matching the existing mechanism)

Co-Authored-By: Claude <noreply@anthropic.com>

Signed-off-by: cumin <13809292481@163.com>
- SOC_TIMER_GROUP_TOTAL_TIMERS was removed from soc_caps.h in v6 (like
  SOC_I2S_NUM/SOC_PCNT_UNITS_PER_GROUP); recreate it per target
- WIFI_AUTH_MAX grew to 18 in v6 (WPA3_EXT_PSK slots became placeholders,
  WPA_ENTERPRISE added); add the v6 branch of the sync static_assert

Co-Authored-By: Claude <noreply@anthropic.com>

Signed-off-by: cumin <13809292481@163.com>
The component_hash of a git-sourced managed component is
platform-dependent: the tinyusb fork hash computed on Windows differs
from the one computed on Linux (which is what upstream CI uses), so the
Windows-regenerated lockfiles failed hash verification on Linux with
"downloaded component is corrupted". Regenerate the three lockfiles
that contain the git-sourced tinyusb component under Linux so the
hashes match upstream again.

Co-Authored-By: Claude <noreply@anthropic.com>

Signed-off-by: cumin <13809292481@163.com>
esp_wifi_remote 0.15.2 does not build against IDF v6.1 (the v6.1 support
sources only exist in 1.6.0+), so select the component versions per IDF
version using matches: 2.7.0/0.15.2 below v6 (unchanged pins, 5.x
lockfiles resolve identically) and 2.12.8/1.6.0 on v6+.

Also fix network_lan.c for IDF v6: rmii clock_gpio became a plain int
(the emac_rmii_clock_gpio_t enum was removed), and regenerate the
lockfiles (manifest hash changed).

Co-Authored-By: Claude <noreply@anthropic.com>

Signed-off-by: cumin <13809292481@163.com>
- machine_rtc.c: gate RTC_NOINIT_ATTR on SOC_RTC_MEM_SUPPORTED, with a
  DRAM_ATTR fallback for chips without RTC slow memory (eg ESP32-C2),
  which static-assert on RTC_NOINIT_ATTR from IDF v6.
- ESP32_GENERIC D2WD variant: also disable MICROPY_PY_BLUETOOTH to keep
  the firmware within the 2MiB flash layout, as the mbedtls 4 / PSA
  stack in IDF v6 increases binary size past the smallest app partition.
- machine_sdcard.c: collapse a now-redundant per-target host_id #if.
- modmachine.c: fix code formatting.

Signed-off-by: cumin <13809292481@163.com>
- Replace the hardcoded PCNT unit/channel, I2S controller and GPTimer
  counts with IDF macros, aliased with fallbacks covering the v5
  soc_caps.h names, the v6.0/6.1 *_ll.h names and the v6.2+ _SOC_CAPS_*
  rename. Revert the PCNT channel action types to mp_uint_t with an
  upper-bound check only, and reword the file header comment.
- Name the IDF v6 deep-sleep GPIO wakeup function via a GPIO_WAKEUP_FUNC
  alias macro, and drop the rmii.clock_gpio casts entirely (an uncast
  int assignment is valid on v5 as well).
- Deduplicate the mbedtls 4.x hashlib implementation: sha256/sha1/md5
  share the PSA make_new/update/digest, with the algorithm derived from
  the object's type. extmod comments now mention only mbedTLS versions.
- Pin esp_hosted 2.12.8 and esp_wifi_remote 1.6.0 unconditionally,
  verified to build against IDF v5.5.5 for ESP32_GENERIC_P4, and
  regenerate the lockfiles for the updated manifest.

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: cumin <13809292481@163.com>
Add the ESP32-S31 (dual-core RV32, Wi-Fi 6 + BLE, octal PSRAM) target
with an ESP32_GENERIC_S31 board for modules such as the
ESP32-S31-WROOM-1-N16R16V (16 MiB flash, octal PSRAM):

- boards/ESP32_GENERIC_S31: module-neutral board definition (native
  USB via the high-speed UTMI PHY on RHPORT0, UART REPL, BLE, Wi-Fi
  CSI); requires ESP-IDF v6.1 or later
- boards/sdkconfig.s31 + partitions-16MiBplus.csv: chip layer with
  16 MiB flash and auto-extending vfs partition
- machine_pin: GPIO0-61 enable table (GPIO29/41 not bonded)
- machine_adc: ADC1 GPIO42-49 / ADC2 GPIO50-57; no calibration scheme
  exists for S31 in IDF yet (adc read_uv raises NotImplementedError)
- machine_touchpad: S31 GPIO6-19 channel table (touch v3, like P4)
- esp32_ldo: take the LDO channel count from SOC_GP_LDO_NUM_UNITS
- mpconfigport: rv32imc+zcmp emitter, USB high-speed on RHPORT0
- tinyusb: switch from the micropython/tinyusb-espressif fork to the
  registry 0.19.0~3 component for all tinyusb targets -- the fork has
  no esp32s31 support and the manifest schema cannot select different
  sources per target; the registry build carries the DWC2 OUT EP ZLP
  fix (hathach/tinyusb#3293) the fork existed to provide
- ci: build ESP32_GENERIC_S31 on the ESP-IDF v6.1 leg

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: cumin <13809292481@163.com>
Update every target's lockfile for the combined manifest: the
unconditional esp_hosted 2.12.8 / esp_wifi_remote 1.6.0 pins from the
rebased base plus the registry tinyusb switch, with the S31 lockfile
regenerated on IDF v6.1 and the rest on v5.5.5.

Signed-off-by: cumin <13809292481@163.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants