espressif / arduino-esp32

Arduino core for the ESP32
GNU Lesser General Public License v2.1
13.58k stars 7.4k forks source link

SPI buses on ESP32-S2 are mislabeled in arduino-esp32 #10079

Open egnor opened 3 months ago

egnor commented 3 months ago

Board: (any) Device Description: ESP32-S2 Hardware Configuration: (any configuration that uses SPI) Version: latest master (checkout manually) IDE Name: (any) Operating System: (any) Flash frequency: (any) PSRAM enabled: (any) Upload speed: (any)

Description

At the hardware level, the ESP32-S2 has four SPI buses: SPI0, SPI1, SPI2, SPI3. SPI0 and SPI1 are (mostly) reserved for flash I/O, SPI2 and SPI3 are available for user use.

In arduino-esp32, ESP32-S2 SPI buses are labeled as follows:

#elif CONFIG_IDF_TARGET_ESP32S2
#define FSPI 1  //SPI 1 bus. ESP32S2: for external memory only (can use the same data lines but different SS)
#define HSPI 2  //SPI 2 bus. ESP32S2: external memory or device  - it can be matrixed to any pins
#define SPI2 2  // Another name for ESP32S2 SPI 2
#define SPI3 3  //SPI 3 bus. ESP32S2: device only - it can be matrixed to any pins
...

These constants are used as indexes into _spi_bus_array[] in the HAL:

#if CONFIG_IDF_TARGET_ESP32S2
  {(volatile spi_dev_t *)(DR_REG_SPI1_BASE), NULL, 0, -1, -1, -1, -1},
  {(volatile spi_dev_t *)(DR_REG_SPI2_BASE), NULL, 1, -1, -1, -1, -1},
  {(volatile spi_dev_t *)(DR_REG_SPI3_BASE), NULL, 2, -1, -1, -1, -1}
...

So this means that

Basically everything is off by one. The default is to use FSPI:

#if CONFIG_IDF_TARGET_ESP32
SPIClass SPI(VSPI);
#else
SPIClass SPI(FSPI);
#endif

So that will actually work, but the situation is confusing and mislabeled, particularly if anyone tries to use the SPI2 or SPI3 constants. (And why aren't the numeric values lined up with ESP data sheets anyway? (Also this whole FSPI/HSPI/VSPI nonsense is just silly.))

I have checked existing issues, online documentation and the Troubleshooting Guide

egnor commented 3 months ago

(I'd be happy to submit a PR to fix the comments, if that would make sense. Changing the constants, even the SPI2 and SPI3 ones, might break existing code. I could also propose adding new constants and/or objects to make things clearer.)