Two SPIs parallel on ESP32-S3

I have a Lilygo T-Display-S3 AMOLED and want to use the Quad-SPI to control the AMOLED display and another SPI to do a distance measurement with a Decawave DW1000 module.

I have the code for the display with LVGL working without the DW1000.
The DW1000 also works when I don't use the display.
As soon as I try to run both the SPI connection to the DW1000 breaks down.

I assume that there are some resource conflicts but I can't find a good source of information what SPI module is connected to which pins. And the SPIs are also named different in several libaries. I found defines of "FSPI" and "HSPI" but also "SPI1_HOST" and "SPI2_HOST".

The PINs I use are:

+------------+-----------+-------------+------------+
| Signalname | Pin Flash | Pin Display | Pin DW1000 |
+------------+-----------+-------------+------------+
| CS         | SPICS1    | GPIO6       | GPIO10     |
| CLK        | SHICLK    | SPILCK_P    | GPIO12     |
| MOSI/Data0 | SPIQ      | GPIO18      | GPIO11     |
| MISO/Data1 | SPID      | GPIO7       | GPIO13     |
| Data2      | SPIWP     | SPICLK_N    | -          |
| Data3      | SHIPD     | GPIO5       | -          |
+------------+-----------+-------------+------------+

The library for the DW1000 I use is:

and I pass a SPIClass(FSPI) to its init function.

For the Display I used the official Lilygo LVGL example from here:

but I changed the code to use a SPIClass(HSPI) object instead of the normal SPI to do its stuff like .begin(). I'm not sure where this normal SPI object is even defined and what module it defaults to. In the display driver (rm67162.cpp) are two lines that don't use the SPIClass object but expect a spi_host_device_t type:

ret = spi_bus_initialize((spi_host_device_t)HSPI, &buscfg, SPI_DMA_CH_AUTO);
ESP_ERROR_CHECK(ret);
ret = spi_bus_add_device((spi_host_device_t)HSPI, &devcfg, &spi);
ESP_ERROR_CHECK(ret);

I just casted the HSPI to spi_host_device_t type.

As I said both snippets run fine independent of each other but the DW1000 fails as soon as spi_bus_initialize() or spi_bus_add_device() are called. If I delay the initialization of the DW1000 the display shows garbage and the module still does not work.

Can someone help me untangle this SPI chaos?

I'm having the same issue (albeit in a SD to GIF project).

I'll share what I've found so far, maybe if we combine our half-working projects we get 1 working :zany_face:

From the datasheet (table 2-4):
So SPI2/SPI3 are the ones you should use (SPI0/SPI1 is used for internal).
SPI3 is also called HSPI and SPI2 is also called FSPI (VSPI on non ESP32S3).

HSPI hardware pins "should be" GPIO35-39.
FSPI hardware pins should be GPIO10-13.

If i'm not mistaken then the default SPI bus is created through the SPI library in the ESP32 core folder. SPI.cpp learns me that default is VSPI/FSPI:

if(sck == -1 && miso == -1 && mosi == -1 && ss == -1) {
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
        _sck = (_spi_num == FSPI) ? SCK : -1;
        _miso = (_spi_num == FSPI) ? MISO : -1;
        _mosi = (_spi_num == FSPI) ? MOSI : -1;
        _ss = (_spi_num == FSPI) ? SS : -1;
#elif CONFIG_IDF_TARGET_ESP32C3
        _sck = SCK;
        _miso = MISO;
        _mosi = MOSI;
        _ss = SS;
#else
        _sck = (_spi_num == VSPI) ? SCK : 14;
        _miso = (_spi_num == VSPI) ? MISO : 12;
        _mosi = (_spi_num == VSPI) ? MOSI : 13;
        _ss = (_spi_num == VSPI) ? SS : 15;
#endif
    } else {
        _sck = sck;
        _miso = miso;
        _mosi = mosi;
        _ss = ss;
    }

In esp32-hal-spi.c you find the default pins that SPI.h is referring to.
You'll also find that HSPI does not have default pins (contrary to what table 2-4 says).
For example sck:

#elif CONFIG_IDF_TARGET_ESP32S3
        if(spi->num == FSPI) {
            sck = 12;
        } else {
            log_e("HSPI Does not have default pins on ESP32S3!");
            return;
        }

Right now I'm trying to set up a new SPIclass and insert that in the functions for SD & TFT without success (I know, you're not using those, but the principal could be useful to know)

My sketch is made from 2 example files put together: SPI>"SPI_multiple_buses" & GFX for arduino>"imgViewer":

#include <SPI.h>
#include <Arduino_GFX_Library.h>
#include <SD.h>
#include "GifClass.h"
// Define ALTERNATE_PINS to use non-standard GPIO pins for SPI bus

static GifClass gifClass;

  #define VSPI_MISO   13
  #define VSPI_MOSI   11
  #define VSPI_SCLK   12
  #define VSPI_SS     10

//for TFT
  #define HSPI_MISO   37
  #define HSPI_MOSI   35
  #define HSPI_SCLK   36
  #define HSPI_SS     39
  #define TFT_DC      40
  #define TFT_RST     41

Arduino_DataBus *bus = new Arduino_ESP32SPI(TFT_DC /*DC*/, HSPI_SS /*CS*/, HSPI_SCLK /*CLK*/, HSPI_MOSI /*MOSI*/, HSPI_MISO /*MISO*/, HSPI /*SPIClass*/, false /*Shared*/);

Arduino_GFX *gfx = new Arduino_ST7789(bus, DF_GFX_RST, 3 /* rotation */, false /* IPS */);

void setup() {
Serial.begin(115200);
Serial.println("Dual SPI & Arduino_GFX");
/* Back to Multiple bus example file */
  //initialise two instances of the SPIClass attached to VSPI and HSPI respectively
  vspi = new SPIClass(VSPI);
  hspi = new SPIClass(HSPI);

  vspi->begin(VSPI_SCLK, VSPI_MISO, VSPI_MOSI, VSPI_SS); //SCLK, MISO, MOSI, SS
  hspi->begin(HSPI_SCLK, HSPI_MISO, HSPI_MOSI, HSPI_SS); //SCLK, MISO, MOSI, SS
  
 /* DEBUG to serial monitor what currently used pins are */ 
Serial.println("HSPI MISO, MOSI, SCLK, SS");
Serial.println(HSPI_MISO);
Serial.println(HSPI_MOSI);
Serial.println(HSPI_SCLK);
Serial.println(HSPI_SS);

Serial.println("VSPI MISO, MOSI, SCLK, SS");
Serial.println(VSPI_MISO);
Serial.println(VSPI_MOSI);
Serial.println(VSPI_SCLK);
Serial.println(VSPI_SS);

/* Out of the GFX for arduino example file */
  if (!gfx->begin())
  {
    Serial.println("gfx->begin() failed!");
  }
  gfx->fillScreen(RGB565_BLACK);

  pinMode(vspi->pinSS(), OUTPUT); //VSPI SS
  pinMode(hspi->pinSS(), OUTPUT); //HSPI SS

    if (!SD.begin(VSPI_SS, FSPI))
  {
    Serial.println(F("ERROR: File System Mount Failed!"));
    gfx->println(F("ERROR: File System Mount Failed!"));
  }

}

void loop() {}

With alot of error codes about the bus function and SD begin function (FSPI is defined as "0" in the esp32-hal-spi.h file, and SD.begin does not recognise it as a SPIclass).
Maybe you can adapt the same strategy with more succes.