Skip to content

Bus_SPI: zero-initialize spi_bus_config_t instead of memset(~0u) - #281

Merged
lovyan03 merged 2 commits into
m5stack:developfrom
ainyan03:spi_buscfg_zero_init
Sep 10, 2026
Merged

Bus_SPI: zero-initialize spi_bus_config_t instead of memset(~0u)#281
lovyan03 merged 2 commits into
m5stack:developfrom
ainyan03:spi_buscfg_zero_init

Conversation

@ainyan03

Copy link
Copy Markdown
Contributor

Follow-up to #280 (stacked on it; the first commit here is that PR's commit). Please merge #280 first, or merge this one alone since it contains both.

#280 patched the one field that ESP-IDF v6.1 added. This replaces the underlying memset(&buscfg, ~0u, ...) in spi::init() so the same class of problem cannot come back with the next field ESP-IDF adds:

  • memset(~0u) seeded every *_io_num with -1 in one stroke, but also left every non-pin field at 0xFFFFFFFF, which is exactly what broke on v6.1 (dma_burst_size).
  • ESP-IDF's own examples aggregate-initialize spi_bus_config_t (unspecified members become 0). Following that convention, the struct is now zero-initialized and only the unused pin fields are set to -1 explicitly (quadwp/quadhd always; data4..7 under a v4.4+ guard, where they exist), because 0 would denote GPIO0.
  • With this, every non-pin field present in IDF 3.2 through 6.1 receives a valid value: dma_burst_size = 0 is the driver default on v6.1, and data_io_default_level = 0 is the same Low level that was assigned explicitly before. The v6.1-specific assignment from Bus_SPI: initialize spi_bus_config_t::dma_burst_size for ESP-IDF 6.1 #280 is therefore removed again, and initQuad() (already a designated initializer) and init() now follow the same pattern.
  • Version guards keep the nested #if defined (ESP_IDF_VERSION_VAL) / #if (ESP_IDF_VERSION >= ...) form so toolchains without esp_idf_version.h still preprocess.

Verification

  • A/B on hardware with ESP-IDF v6.1 (tag): StickS3 and CoreS3 (ESP32-S3), ToughC5 (ESP32-C5), Tab5 (ESP32-P4) all initialise and draw normally with this branch (they boot-loop on develop). Smoke test on ESP32 (Core BASIC, no GDMA) with ESP-IDF v6.0: initialises and draws normally.
  • Builds: ESP-IDF v6.1 (S3 / C5 / P4), ESP-IDF v6.0 (ESP32), Arduino-ESP32 2.0.3 and 2.0.17 (IDF 4.4, the data4..7 guard boundary), Arduino-ESP32 3.x (IDF 5.5).
  • CI on the fork: all build workflows green.

ESP-IDF 6.1 added dma_burst_size to spi_bus_config_t. The memset(~0u) that
seeds the *_io_num fields with -1 leaves it at 0xFFFFFFFF, which the GDMA
driver rejects on chips with an adjustable burst size (ESP32-S3, C5, C61,
P4). spi_bus_initialize() then panics in its error path and the board
boot-loops in init(). Set it to 0 (driver default) on 6.1 and later.

Reproduced and verified on ESP32-S3 with ESP-IDF v6.1.
memset(~0u) seeded the *_io_num fields with -1 in one stroke but also
left every non-pin field at 0xFFFFFFFF, which is what broke on ESP-IDF
v6.1 (dma_burst_size). Follow the aggregate-initializer convention used
by ESP-IDF itself instead: zero-initialize the struct, then set only the
unused pin fields to -1 (quadwp/quadhd always, data4..7 on v4.4 and later
where they exist), because 0 would denote GPIO0.

With this, every non-pin field present in IDF 3.2 through 6.1 receives a
valid value: dma_burst_size = 0 is the driver default on v6.1, and
data_io_default_level = 0 is the same Low level that was assigned
explicitly before. The v6.1-specific dma_burst_size assignment is
therefore no longer needed.

Verified A/B on ESP32-S3 (StickS3, CoreS3), ESP32-C5 and ESP32-P4 with
ESP-IDF v6.1; builds on ESP-IDF v6.0 (ESP32), Arduino-ESP32 2.0.3 / 2.0.17
(IDF 4.4) and 3.x (IDF 5.5).
@lovyan03
lovyan03 merged commit ac0dab5 into m5stack:develop Sep 10, 2026
27 checks passed
@ainyan03
ainyan03 deleted the spi_buscfg_zero_init branch September 10, 2026 12:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants