Bodmer / TFT_eSPI

Arduino and PlatformIO IDE compatible TFT library optimised for the Raspberry Pi Pico (RP2040), STM32, ESP8266 and ESP32 that supports different driver chips
Other
3.8k stars 1.09k forks source link

ESP32S3 + SD Card + ST7789 don't work #3403

Open sarvasvkulpati opened 4 months ago

sarvasvkulpati commented 4 months ago

I'm using an ESP32S3 Xiao Sense along with an ST7789. For some reason, I can't get the board to access both the LCD and the SD card at the same time. I'm using an arduino, latest version of the library, version 3.0.0+ of the esp32 library.

I'm assuming it's an SPI issue. This link states that I can access the SD using pin 21. Is there a way to do both?

The code below was my latest try, trying to use VSPI for the SD, while HSPi is bing used for the display. Attached also is my setup file

  #include <ESP_I2S.h>
#include "FS.h"
#include <SPI.h>
#include <SD.h>
#include <TB_TFT_eSPI.h>

#define SD_CS_PIN 21
#define VSPI_MOSI 11
#define VSPI_MISO 13
#define VSPI_SCK  12
#define RECORD_TIME 20
#define WAV_FILE_NAME "arduino_rec"
#define SAMPLE_RATE 16000U
#define SAMPLE_BITS 16
#define WAV_HEADER_SIZE 44
#define VOLUME_GAIN 2

TFT_eSPI tft = TFT_eSPI();
SPIClass spiSD(VSPI);
const int buff_size = 1024;
char buffer[buff_size];
I2SClass I2S;

void setup() {
  Serial.begin(115200);
  while (!Serial) delay(10);

  Serial.println("Initializing...");

  initDisplay();
  initSDCard();
  initI2S();

  Serial.println("Setup complete, attempting recording");
  tft.println("Recording...");

  record_wav();

  Serial.println("Finished recording");
  tft.println("Recording done");
}

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

void initDisplay() {
  Serial.println("Initializing display...");
  tft.init();
  tft.setRotation(1);
  tft.fillScreen(TFT_BLACK);
  tft.setTextColor(TFT_WHITE, TFT_BLACK);
  tft.setTextSize(2);
  tft.setCursor(0, 0);
  tft.print("Display init");
  Serial.println("Display initialized");
}

void initSDCard() {
  Serial.println("Initializing SD card...");
  spiSD.begin(VSPI_SCK, VSPI_MISO, VSPI_MOSI, SD_CS_PIN);
//  if (!SD.begin(SD_CS_PIN)) {
//    Serial.println("SD Card initialization failed!");
//    tft.print(" SD fail");
//  } else {
//    Serial.println("SD Card initialized successfully.");
//    tft.print(" SD OK");
//  }
  Serial.println("next line after init");
}

void initI2S() {
  Serial.println("Initializing I2S...");
  I2S.setPinsPdmRx(42, 41);
  if (!I2S.begin(I2S_MODE_PDM_RX, 16000, I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_MONO)) {
    Serial.println("Failed to initialize I2S!");
    tft.println("I2S fail");
  } else {
    Serial.println("I2S initialized");
    tft.println("I2S OK");
  }
}

void record_wav() {
  uint32_t record_size = (SAMPLE_RATE * SAMPLE_BITS / 8) * RECORD_TIME;
  uint8_t *rec_buffer = NULL;

  Serial.printf("Ready to start recording ...\n");
  File file = SD.open("/"WAV_FILE_NAME".wav", FILE_WRITE);
  tft.println(file);

  uint8_t wav_header[WAV_HEADER_SIZE];
  generate_wav_header(wav_header, record_size, SAMPLE_RATE);
  file.write(wav_header, WAV_HEADER_SIZE);

  rec_buffer = (uint8_t *)ps_malloc(record_size);
  if (rec_buffer == NULL) {
    Serial.printf("malloc failed!\n");
    while(1);
  }
  Serial.printf("Buffer: %d bytes\n", ESP.getPsramSize() - ESP.getFreePsram());

  size_t bytes_read = 0;
  int available, read;

  while (bytes_read < record_size) {
    available = I2S.available();
    if (available > 0) {
      if (available > buff_size) available = buff_size;
      read = I2S.readBytes(buffer, available);

      if (read > 0) {
        memcpy(rec_buffer + bytes_read, buffer, read);
        bytes_read += read;

        if (bytes_read % (record_size / 10) == 0) {
          Serial.printf("Progress: %d%%\n", (bytes_read * 100) / record_size);
        }
      }
    }
  }

  if (bytes_read == 0) {
    Serial.printf("Record Failed!\n");
  } else {
    Serial.printf("Recorded %d bytes\n", bytes_read);
  }

  for (uint32_t i = 0; i < bytes_read; i += 2) {
    (*(int16_t *)(rec_buffer+i)) *= VOLUME_GAIN;
  }

  Serial.printf("Writing to the file ...\n");
  if (file.write(rec_buffer, bytes_read) != bytes_read)
    Serial.printf("Write file Failed!\n");

  free(rec_buffer);
  file.close();
  I2S.end();
  Serial.printf("The recording is over.\n");
}

void generate_wav_header(uint8_t *wav_header, uint32_t wav_size, uint32_t sample_rate) {
  uint32_t file_size = wav_size + WAV_HEADER_SIZE - 8;
  uint32_t byte_rate = SAMPLE_RATE * SAMPLE_BITS / 8;
  const uint8_t set_wav_header[] = {
    'R', 'I', 'F', 'F',
    file_size, file_size >> 8, file_size >> 16, file_size >> 24,
    'W', 'A', 'V', 'E',
    'f', 'm', 't', ' ',
    0x10, 0x00, 0x00, 0x00,
    0x01, 0x00,
    0x01, 0x00,
    sample_rate, sample_rate >> 8, sample_rate >> 16, sample_rate >> 24,
    byte_rate, byte_rate >> 8, byte_rate >> 16, byte_rate >> 24,
    0x02, 0x00,
    0x10, 0x00,
    'd', 'a', 't', 'a',
    wav_size, wav_size >> 8, wav_size >> 16, wav_size >> 24,
  };
  memcpy(wav_header, set_wav_header, sizeof(set_wav_header));
}
#define ST7789_DRIVER      // Full configuration option, define additional parameters below for this display

#define TFT_BL   4           // LED back-light control pin
#define TFT_BACKLIGHT_ON HIGH  // Level to turn ON back-light (HIGH or LOW)

#define TFT_MOSI 9 //10
#define TFT_SCLK 7 //8
#define TFT_CS   2//3  // Chip select control pin
#define TFT_DC   3 //4  // Data Command control pin
#define TFT_RST   4//5  // Reset pin (could connect to RST pin)

#define LOAD_GLCD   // Font 1. Original Adafruit 8 pixel font needs ~1820 bytes in FLASH
#define LOAD_FONT2  // Font 2. Small 16 pixel high font, needs ~3534 bytes in FLASH, 96 characters
#define LOAD_FONT4  // Font 4. Medium 26 pixel high font, needs ~5848 bytes in FLASH, 96 characters
#define LOAD_FONT6  // Font 6. Large 48 pixel font, needs ~2666 bytes in FLASH, only characters 1234567890:-.apm
#define LOAD_FONT7  // Font 7. 7 segment 48 pixel font, needs ~2438 bytes in FLASH, only characters 1234567890:-.
#define LOAD_FONT8  // Font 8. Large 75 pixel font needs ~3256 bytes in FLASH, only characters 1234567890:-.
//#define LOAD_FONT8N // Font 8. Alternative to Font 8 above, slightly narrower, so 3 digits fit a 160 pixel TFT
#define LOAD_GFXFF  // FreeFonts. Include access to the 48 Adafruit_GFX free fonts FF1 to FF48 and custom 
#define SMOOTH_FONT

#define SPI_FREQUENCY     12500000 // this worked without SD

#define SPI_READ_FREQUENCY  20000000

#define SPI_TOUCH_FREQUENCY  2500000
JimDrewGH commented 4 months ago

I'm using an ESP32S3 Xiao Sense along with an ST7789. For some reason, I can't get the board to access both the LCD and the SD card at the same time. I'm using an arduino, latest version of the library, version 3.0.0+ of the esp32 library.

You might try downgrading to v2.0.14 of the ESP32 core. There is a known problem with v2.0.15 and later working with ESP32-S2/S3/C3/H6 versions.

TheWolf95 commented 3 months ago

I see that in the User_Setup.h that you pasted you didn't uncomment #define USE_HSPI_PORT. It may be that you forgot to paste it, but if not try it and give it a go