ESP32 Mulitple SPI devices: conflict with spi->begin() in Arduino on board manager v3.0.x

oxothnk423
Posts: 1
Joined: Tue Jun 25, 2024 7:18 pm

ESP32 Mulitple SPI devices: conflict with spi->begin() in Arduino on board manager v3.0.x

Postby oxothnk423 » Tue Jun 25, 2024 7:35 pm

Hi, hopefully this is the right place to post and ask for help.

I've been successfully using ESP32-S3 with Arduino board manager V2.0.x to support multiple SPI devices on the same VSPI bus.

Now, with migration to board manager v3.0.x, it seems there is a conflict when calling SPI->begin() more than once.

I have been implementing each SPI device with its own SPIClass, though they all point to the same VSPI bus. (simplified code below).
  1. #include <SPI.h>
  2.  
  3. #define SPI_SS_IMU       10
  4. #define SPI_MOSI         11
  5. #define SPI_CLK          12
  6. #define SPI_MISO         13  
  7. #define SPI_SS_BARO      18
  8.  
  9.  
  10. #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
  11. #define VSPI FSPI
  12. #endif
  13.  
  14. static const int spiClk = 1000000;  // 1 MHz
  15.  
  16. //uninitialised pointers to SPI objects
  17. SPIClass * baro_vspi = NULL;
  18. SPIClass * imu_vspi = NULL;
  19.  
  20. void setup() {
  21.   delay(1000);
  22.   Serial.begin(115200);
  23.   delay(1000);
  24.   Serial.println("Starting Setup");
  25.  
  26.   baro_vspi = new SPIClass(VSPI);
  27.   baro_vspi->begin(SPI_CLK, SPI_MISO, SPI_MOSI, SPI_SS_BARO);
  28.   pinMode(baro_vspi->pinSS(), OUTPUT);
  29.   digitalWrite(baro_vspi->pinSS(), HIGH);
  30.  
  31.   imu_vspi = new SPIClass(VSPI);
  32.   imu_vspi->begin(SPI_CLK, SPI_MISO, SPI_MOSI, SPI_SS_IMU);   // comment this line out to make it "work"
  33.   pinMode(imu_vspi->pinSS(), OUTPUT);
  34.   digitalWrite(imu_vspi->pinSS(), HIGH);
  35. }
  36.  
  37. void loop() {
  38.   spi_Command(baro_vspi, 0b01010101);  // junk data to illustrate usage
  39.   delay(100);
  40.   spi_Command(imu_vspi, 0b01010101);  // junk data to illustrate usage
  41.   delay(100);
  42. }
  43.  
  44. void spi_Command(SPIClass *spi, byte data) {
  45.  
  46.   spi->beginTransaction(SPISettings(spiClk, MSBFIRST, SPI_MODE0));    
  47.   digitalWrite(spi->pinSS(), LOW);                                    
  48.   spi->transfer(data);                // code hangs here, doesn't return
  49.   digitalWrite(spi->pinSS(), HIGH);                                    
  50.   spi->endTransaction();                                                
  51. }
This works on v2.0.x, but DOES NOT work on v3.0.x. Using V3.0.x, once spi->transfer() is called, the code hangs. If you remove one of the spi->begin() lines (line 27 or 32), then it "works", but of course then the chip select pin isn't initialized properly for that spi class / device.

This wouldn't be the end of the world...I have adjusted the code to use only a single SPI class and just manage all the chip selects manually, rather than referencing SPIClass->pin_SS().

But I'm at an impasse now because I also use the u8g2 display library, which itself sets up an SPI object for the display. Once u8g2.begin() is called, the code hangs. I presume behind the scenes, the u8g2 library is initializing the display and starting an SPI transfer, which is where the example code gets stuck too.

Does anyone know what changed between v2 and v3? And is there a better way to handle SPI devices now that you seem to not be able to call spi->begin() more than once for the same bus?

Thanks for the help!

(link to related post in Arduino forum, if helpful)
https://forum.arduino.cc/t/multiple-spi ... /1275440/3

Who is online

Users browsing this forum: No registered users and 70 guests