Description
Board
custom PCB
Device Description
ESP32-S3 FN8 with three SPI devices:
ICM 20948 9-axis IMU
MS5611-01BA03 barometric pressure sensor
192x64 monochrome LCD
Hardware Configuration
ESP32-S3 FN8 with three SPI devices connected to default VSPI (FSPI) pins (MOSI, MISO, CLK) and separate chip select pins.
Version
latest master (checkout manually)
IDE Name
Arduino IDE 2.3.2
Operating System
Windows 10
Flash frequency
QIO 80Mhz
PSRAM enabled
no
Upload speed
921600
Description
In ESP32 version 2.0.14, I was able to initialize each SPI device separately with its own SPIClass, even though they're all pointing to the same bus (VSPI in this case). This allows for unique settings (such as chip select pin) per spi device / class. In setup(), each device's class would then need a call to SPIClass->begin().
In version 3.0.2, it seems repeat calls to spi->begin() for the same spi bus creates a conflict or failure, such that the code hangs (with no error thrown) when performing a call to spi->transfer().
A simplified version of the code is below, which works on 2.0.14 and DOES NOT work on 3.0.2. The specific conflict I believe is the second call to spi->begin for the second device. If this line (imu_vspi->begin(...);) is commented out, the code compiles and runs without hanging (even though the SPI communication isn't as expected since the second device is now not set up properly).
There are ways to work around this if I was only using exclusively my own code, but some popular libraries (for example I'm using u8g2 for the LCD) internally handle their own SPI device setup. This makes it nearly impossible to avoid repeat calls to spi->begin on the same bus. (in other words, I can set up a single SPIClass to manage my other devices, or I can initialize the u8g2 library, but not both).
Is there a better way to approach multiple SPI devices on the same bus? I'd love to learn I'm just doing something wrong... I'm happy to take advice on alternative approaches. But this approach worked great in V2.x, so I'm surprised to see it failing here in v3.x when there were no listed breaking changes in the SPI API's (as far as I saw).
Sketch
#include <SPI.h>
#define SPI_SS_IMU 10
#define SPI_MOSI 11
#define SPI_CLK 12
#define SPI_MISO 13
#define SPI_SS_BARO 18
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
#define VSPI FSPI
#endif
static const int spiClk = 1000000; // 1 MHz
//uninitialised pointers to SPI objects
SPIClass * baro_vspi = NULL;
SPIClass * imu_vspi = NULL;
void setup() {
delay(1000);
Serial.begin(115200);
delay(1000);
Serial.println("Starting Setup");
baro_vspi = new SPIClass(VSPI);
baro_vspi->begin(SPI_CLK, SPI_MISO, SPI_MOSI, SPI_SS_BARO);
pinMode(baro_vspi->pinSS(), OUTPUT);
digitalWrite(baro_vspi->pinSS(), HIGH);
imu_vspi = new SPIClass(VSPI);
imu_vspi->begin(SPI_CLK, SPI_MISO, SPI_MOSI, SPI_SS_IMU); // comment this line out to make it "work"
pinMode(imu_vspi->pinSS(), OUTPUT);
digitalWrite(imu_vspi->pinSS(), HIGH);
}
void loop() {
spi_Command(baro_vspi, 0b01010101); // junk data to illustrate usage
delay(100);
spi_Command(imu_vspi, 0b01010101); // junk data to illustrate usage
delay(100);
}
void spi_Command(SPIClass *spi, byte data) {
spi->beginTransaction(SPISettings(spiClk, MSBFIRST, SPI_MODE0));
digitalWrite(spi->pinSS(), LOW);
spi->transfer(data); // code hangs here, doesn't return
digitalWrite(spi->pinSS(), HIGH);
spi->endTransaction();
}
Debug Message
no visible errors. As mentioned above, the code just hangs on the third to last line (it never returns from spi->transfer).
Other Steps to Reproduce
As mentioned, this has worked correctly on 2.0.14. I am able to initialize 3 separate SPIClasses, all pointing to VSPI, and each with their own spi->begin() call, and also initialize a fourth u8g2 library spi object.... and SPI transfers worked flawlessly among all of them.
Now in v3.0.2, I only seem to be able to make a single spi->begin call, which thus enables only one SPIClass, not multiple.
I have checked existing issues, online documentation and the Troubleshooting Guide
- I confirm I have checked existing issues, online documentation and Troubleshooting guide.