Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ESP32-S3 “SPIClass spi(HSPI)” but with pin definitions? #9588

Closed
1 task done
Rob58329 opened this issue May 3, 2024 · 2 comments
Closed
1 task done

ESP32-S3 “SPIClass spi(HSPI)” but with pin definitions? #9588

Rob58329 opened this issue May 3, 2024 · 2 comments
Labels
Status: Awaiting triage Issue is waiting for triage

Comments

@Rob58329
Copy link
Contributor

Rob58329 commented May 3, 2024

Board

"NodeMCU-32s" & "Firebeetle2 ESP32-3"

Device Description

Board connected to "Adafruit_ST7796S_kbv" tft (although not really relevant) using the HSPI .

Hardware Configuration

#define SD_CS 15
#define TFT_CS 33
#define TFT_DC 17
#define SPI_MISO 12 // default pin
#define SPI_MOSI 13 // default pin
#define SPI_CLK 14 // default pin
#define TFT_RST -1

Version

latest master (checkout manually)

IDE Name

Arduino IDE v1.8.19

Operating System

Windows 10

Flash frequency

n/a

PSRAM enabled

no

Upload speed

n/a

Description

The 1st below sketch works fine, but only with the default HSPI pin definitions.

#if CONFIG_IDF_TARGET_ESP32S3
    #define SD_CS    9 
    #define TFT_CS   18 
    #define TFT_DC   3 
    #define SPI_MOSI 15
    #define SPI_MISO 16
    #define SPI_CLK  17
    #define TFT_RST -1
#else
  #define SD_CS    15
  #define TFT_CS   33 
  #define TFT_DC   17 
  #define SPI_MISO 12 // default pin
  #define SPI_MOSI 13 // default pin
  #define SPI_CLK  14 // default pin
  #define TFT_RST -1
#endif
#define use_TFT true

#include <SPI.h>
#include <Adafruit_GFX.h>  // https://github.com/adafruit/Adafruit-GFX-Library 
#include <Adafruit_ST7796S_kbv.h> // https://github.com/prenticedavid/Adafruit_ST7796S_kbv1 

SPIClass MySPI(HSPI); // Declare an HSPI bus object (to use or BOTH TFT and SD-card)
Adafruit_ST7796S_kbv tft=Adafruit_ST7796S_kbv(&MySPI, TFT_DC, TFT_CS, TFT_RST);

#if (use_TFT)
  #define SerialD tft
#else
 #define SerialD Serial
#endif

void setup() {
  SerialD.begin();
  #if (use_TFT)
    tft.setRotation(3);
    tft.setTextSize(1); 
    tft.fillScreen(ST7796S_BLACK); tft.setCursor(0,0);
    tft.setTextColor(ST7796S_WHITE);
  #endif
} 

void loop() {
  SerialD.println("Loop");
  delay(1000);
}

The 2nd below sketch with new HSPI pin definitions compiles OK, but crashes at the line “SerialD.begin();” [aka tft.begin()]

#define SD_CS    15
#define TFT_CS   33 
#define TFT_DC   17 
#define SPI_MISO 12 // default pin
#define SPI_MOSI 13 // default pin
#define SPI_CLK  14 // default pin
#define TFT_RST -1

#define use_TFT true

#include <SPI.h>
#include <Adafruit_GFX.h>  // https://github.com/adafruit/Adafruit-GFX-Library 
#include <Adafruit_ST7796S_kbv.h> // https://github.com/prenticedavid/Adafruit_ST7796S_kbv1 

SPIClass *spi = NULL;
Adafruit_ST7796S_kbv tft=Adafruit_ST7796S_kbv(spi, TFT_DC, TFT_CS, TFT_RST);

#if (use_TFT)
  #define SerialD tft
#else
 #define SerialD Serial
#endif

void setup() {
  #if (use_TFT)
    spi = new SPIClass(HSPI);
    spi->begin(SPI_CLK, SPI_MISO, SPI_MOSI, TFT_CS);
  #endif
  SerialD.begin(); // crashes here
  #if (use_TFT)
    tft.setRotation(3);
    tft.setTextSize(1); 
    tft.fillScreen(ST7796S_BLACK); tft.setCursor(0,0);
    tft.setTextColor(ST7796S_WHITE);
  #endif
} 

void loop() {
  SerialD.println("Loop");
  delay(1000);
}

Is there any way to change the used HSPI pins outside of “setup()” and “loop()” so my above “#define SerialD tft” will work with “SerialD.print” etc?

Edit2:
@lbernstone - many thanks for below info! Interestingly the default "SPI" object "SPI.begin();" appears to use the pre-defined (SCK,MOSI, MISO,SS) variables, which on my board (nodeMCU-32S) are GPIO 18,23,19 & 5 which I understand to be the VSPI interface. But this still works fine.

The 3rd below sketch DOES work, and it a little more complex than sketch 1 above, but not too bad!

#define SD_CS    15
#define TFT_CS   33 
#define TFT_DC   17 
#define SPI_MISO 12 // default pin but can be changed
#define SPI_MOSI 13 // default pin but can be changed
#define SPI_CLK  14 // default pin but can be changed
#define TFT_RST -1

#define use_TFT true

#include <SPI.h>
#include <Adafruit_GFX.h>  // https://github.com/adafruit/Adafruit-GFX-Library 
#include <Adafruit_ST7796S_kbv.h> // https://github.com/prenticedavid/Adafruit_ST7796S_kbv1 

Adafruit_ST7796S_kbv *tft= NULL; 

#if (use_TFT)
  #define SerialD (*tft) // synonym for ->
#else
 #define SerialD Serial
#endif

void setup() {
  Serial.begin(115200);
  #if (use_TFT)
    // SPIClass *spi = new SPIClass(HSPI);  // not required as we can use the already existing "SPI"
    SPI.begin(SPI_CLK, SPI_MISO, SPI_MOSI, TFT_CS); // NB. SPI appears to use VSPI not HSPI, but this is ok.
    tft = new Adafruit_ST7796S_kbv(&SPI, TFT_DC, TFT_CS, TFT_RST); 
  #endif
  SerialD.begin(); 
  #if (use_TFT)
    tft->setRotation(3);
    tft->setTextSize(1); 
    tft->fillScreen(ST7796S_BLACK); tft->setCursor(0,0);
    tft->setTextColor(ST7796S_WHITE);
  #endif
} 

void loop() {
  SerialD.println("Loop");
  delay(1000);
}

Edit 3: re. ESP32-S3

Note that the ESP32-S3 has 2 available/user SPI controllers named:

  • SPIClass(HSPI); or SPIClass(1); = GP-SPI2 (or perhaps GP-SPI3)
  • SPIClass(FSPI); or SPIClass(0); = GP-SPI3 (or perhaps GP-SPI2)
    (each has slightly different capabilities).

Also note that although both above SPI controllers can be routed to any GPIO, for the fastest performance you can only use GPIOs 0-21 & 26-48 (which use the IO MUX to connect to the pins). Other pins use the GPIO MATRIX to connect to the pins and is slower.

Finally note that the SPI/TFT/SD (Arduino-ID) spi-frequency settings seem to work a bit differently on the ESP32-S3 (github.com/espressif/arduino-esp32 as at 16Jan24) compared with the ESP32-original. Specifically on the ESP32-original the following code works:

SPIClass *myspi = NULL;
Adafruit_ST7796S_kbv *tft = NULL;
myspi = new SPIClass(HSPI);
myspi->begin(SPI_CLK, SPI_MISO, SPI_MOSI, TFT_CS);
tft = new Adafruit_ST7796S_kbv(myspi, TFT_DC, TFT_CS, TFT_RST);
tft->begin();
boolean sd_OK = SD.begin(SD_CS, *myspi);

BUT on the ESP32-S3 the SD card gives the error message “sdCommand(): no token received” (I think because the SPI has ignored the default 10MHz setting for the SD card and is still using the default 40MHz setting of the TFT.)

To fix you need to specifically set the spi-frequency to the SD-cards default 10MHz frequency by changing the last couple of lines as follows:

#define SPI_freq 10000000 // 10MHz
tft->begin(SPI_freq);
boolean sd_OK =  SD.begin(SD_CS, MY_SPI, SPI_freq);

Sketch

See above

Debug Message

Sketch 2 crashes at the "SerialD.begin();"

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

  • I confirm I have checked existing issues, online documentation and Troubleshooting guide.
@Rob58329 Rob58329 added the Status: Awaiting triage Issue is waiting for triage label May 3, 2024
@lbernstone
Copy link
Contributor

lbernstone commented May 3, 2024

HSPI is the default, and there is already an object (SPI) defined on that bus.

#include <SPI.h>
...
   SPI.begin(SPI_CLK, SPI_MISO, SPI_MOSI, TFT_CS);

If you want to use VSPI, you can do so like:

#include <SPI.h>
SPIClass vspi(1);
...
   vspi.begin(SPI_CLK, SPI_MISO, SPI_MOSI, TFT_CS);

@Rob58329 Rob58329 closed this as completed May 4, 2024
@lbernstone
Copy link
Contributor

Edit2: @lbernstone - many thanks for below info! Interestingly the default "SPI" object "SPI.begin();" appears to use the pre-defined (SCK,MOSI, MISO,SS) variables, which on my board (nodeMCU-32S) are GPIO 18,23,19 & 5 which I understand to be the VSPI interface. But this still works fine.

In arduino-esp32 context, SPI names are just names- HSPI evaluates to bus 2, and should be the horizontal pins (2,4,12,15), but that's just not how they are defined in the variants file. Since it is all muxed through the gpio matrix, that doesn't really matter (although a bit confusing). Espressif has gotten away from the H/V naming, since it doesn't really apply to the other variants, but it is kinda stuck in arduino to maintain backwards compatibility. If you are going to define your own objects, I'd stick to using the numbers

@Rob58329 Rob58329 changed the title ESP32 “SPIClass spi(HSPI)” but with pin definitions? ESP32-S3 “SPIClass spi(HSPI)” but with pin definitions? May 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Awaiting triage Issue is waiting for triage
Projects
None yet
Development

No branches or pull requests

2 participants