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-2432S028 - Can't use SD card after initializing the UI #143

Open
AllanOricil opened this issue Mar 12, 2024 · 29 comments
Open

ESP32-2432S028 - Can't use SD card after initializing the UI #143

AllanOricil opened this issue Mar 12, 2024 · 29 comments
Assignees
Labels
bug Something isn't working

Comments

@AllanOricil
Copy link

AllanOricil commented Mar 12, 2024

@rzeldent

I isolated the problem to the UI initialization. If I remove it from my code entirely, I no longe have any issues reading/writing/append to files from the SD Card. Bellow you can see a simple evidence of the issue.

image

According to chat gpt, the issue might be related to the way the SPI is configured to the LCT, Toutch and SD card. There might exist a problem that does not let the 3 work together. Is there a way to bypass it?

Could you maybe create a lock/unlock for the display when the SD card wants to use the SPI?

@AllanOricil
Copy link
Author

AllanOricil commented Mar 12, 2024

I further isolated the issue to smartdisplay_init(). After calling it, I can no longer use the sd card

image

@rzeldent
Copy link
Owner

Hi Allan,

I think it is caused by the SPI bus using the same SPI bus as the SD card.

In the file esp32-2432S028R.json you can trt to change the SPI host to : "'-D ILI9341_SPI_HOST=SPI2_HOST'"

Choices are:

SPI1_HOST=0,    ///< SPI1
SPI2_HOST=1,    ///< SPI2

#if SOC_SPI_PERIPH_NUM > 2
SPI3_HOST=2, ///< SPI3

Or change the SPI HOST for the SD card....

@AllanOricil
Copy link
Author

AllanOricil commented Mar 12, 2024

ILI9341_SPI_HOST

@rzeldent
I'm using esp32-2432S028Rv3.json and there is no -D ILI9341_SPI_HOST=SPI2_HOST in extra_flags.

Besides that, inpecting esp32-2432S028R.json I saw that it has is already using SPI2_HOST

"'-D ILI9341_SPI_HOST=SPI2_HOST'",

v2 and v3 use this other one

"'-D ST7789_SPI_HOST=SPI2_HOST'",

Is this ST7789_SPI_HOST equivalent to ILI9341_SPI_HOST? Should I change it SPI1_HOST?

@rzeldent
Copy link
Owner

Yes, then try the "'-D ST7789_SPI_HOST=SPI2_HOST'" flag!

@AllanOricil
Copy link
Author

AllanOricil commented Mar 12, 2024

@rzeldent
Copy link
Owner

Yes, that is how it is now. But try to change this to SPI1_HOST or even SPI3_HOST....
The CS Card can also work in 2 modes, SPI or a 4 bits protocol. https://esp32.com/viewtopic.php?t=110

@AllanOricil
Copy link
Author

AllanOricil commented Mar 12, 2024

None worked.

I changed -D ST7789_SPI_HOST=SPI2_HOST to -D ST7789_SPI_HOST=SPI3_HOST at ~/.platformio/platforms/espressif32/boards/esp32-2432S028Rv3.json, full clean, build, upload and monitor and got the same result

I changed -D ST7789_SPI_HOST=SPI2_HOST to -D ST7789_SPI_HOST=SPI1_HOST at ~/.platformio/platforms/espressif32/boards/esp32-2432S028Rv3.json, then did a full clean, build, upload and monitor and got the same result

@AllanOricil
Copy link
Author

I also noticed that SPI3_HOST is already being used by the XPT2046 in all revisions of esp32-2432S028R.json

"'-D XPT2046_SPI_HOST=SPI3_HOST'",

@AllanOricil
Copy link
Author

AllanOricil commented Mar 12, 2024

I just tried to free the SPI2_HOST and SPI3_HOST to let the sd card use them, and got the same result. Maybe I did it wrong?

// all the following operations work
create_dir(SD, "/test3");
write_file(SD, "/test3/test.txt", "bla");
read_file(SD, "/test3/test.txt");

// SETUP UI
smartdisplay_init();
  
pinMode(TF_CS, OUTPUT);
pinMode(ST7789_SPI_CONFIG_CS_GPIO_NUM, OUTPUT);

digitalWrite(TF_CS, LOW); //enable SD card => option as it was already HIGH in the setup
digitalWrite(ST7789_SPI_CONFIG_CS_GPIO_NUM, HIGH); // disable toutch or the screen, you can change to the toutch pin here

// THIS FAILS even when disabling touch or lcd CS_GPIO pins
read_file(SD, "/test3/test.txt");

@AllanOricil
Copy link
Author

AllanOricil commented Mar 12, 2024

@rzeldent
I changed both lcd and touch to use SPI2_HOST and then set the sd card to use SPI3_HOST and it worked. In the board esp32-2432S028Rv3.json I added the following changes:

"'-D ST7789_SPI_HOST=SPI2_HOST'",
"'-D XPT2046_SPI_HOST=SPI2_HOST'",
"'-D TF_SPI_HOST=SPI3_HOST'",

It was the only thing I could do to make it work. I also tried changing both to SPI3_HOST, and le tthe SD card using SPI2_HOST, but this setup did not work. However, I can no longer use the touch, and I need it. So, I think you have to create some sort of multiplexing to allow both touch and screen share the same SPI host. At least, that was what chat gpt told me. Is he right?

Here is the evidence that proves I can now read from the SD card after calling smartdisplay_init. However, I got an error, possibly related to the touch sensor, and I can no longer use the touch feature.

image

@AllanOricil
Copy link
Author

AllanOricil commented Mar 12, 2024

I have also tried this combination, and my code breaks at runtime. Apparently, SPI1_HOST can only be used to flash.

"'-D ST7789_SPI_HOST=SPI2_HOST'",
"'-D XPT2046_SPI_HOST=SPI1_HOST'",
"'-D TF_SPI_HOST=SPI3_HOST'",

This means that in order to use the SD card, it will be necessary to have it sharing the same SPI_HOST with another peripheral. And, based on my tests, I believe the touch is the best option. However, it will be necessary to implement some sort of multipler. Is this possible?

@AllanOricil
Copy link
Author

I also tried this chatgpt suggestion. Put both touch and SD card on the same SPI3_HOST, then used the following code when trying to interact with the sd card. And again, it did not work.

digitalWrite(XPT2046_SPI_CONFIG_CS_GPIO_NUM, HIGH); // Deselect touch sensor 
mySPI.beginTransaction(SPISettings(SPI_CLOCK_DIV2, MSBFIRST, SPI_MODE0));
digitalWrite(TF_CS, LOW); // Select SD card
read_file(SD, "/test3/test.txt");
// Further file operations
digitalWrite(TF_CS, HIGH); // Deselect SD card
mySPI.endTransaction();
digitalWrite(XPT2046_SPI_CONFIG_CS_GPIO_NUM, LOW);

@AllanOricil
Copy link
Author

@rzeldent
Im blocked until this issue could be resolved. I tried everything I could have asked to chatgpt. I ran out of questions D:

@AllanOricil
Copy link
Author

According to chat gpt I have no option. This board was created without support for using SD card while touch and lcd are using the available spi buses. If you find a solution @rzeldent I would appreciate. I don't believe chat gpt is fully right.

@AllanOricil
Copy link
Author

AllanOricil commented Mar 12, 2024

Or could you make your lib handle both touch and screen on the same spi bus? I read that it is possible to have multiple peripherals on the same SPI bus.

https://learn.sparkfun.com/tutorials/serial-peripheral-interface-spi/all

@AllanOricil
Copy link
Author

@rzeldent
This video shows an implementation which uses a SPI Semaphore to control which peripherals can use the the spi bus. Maybe you can do the same for your lib, and expose this as a global spi semaphore which people can use to register their peripherals with ease.

https://m.youtube.com/watch?v=8BU07bUQKvg

@AllanOricil
Copy link
Author

@AllanOricil
Copy link
Author

AllanOricil commented Mar 12, 2024

This did not work as well. Both LCD and SD on the same SPI bus (SPI2_HOST).

image

The screen freezes, and the sd card cant find the file (the file exists, and it is closed!!!)

image

@rzeldent
Copy link
Owner

Hi Allan,

The TFT_CS and ST7789_SPI_CONFIG_CS_GPIO_NUM should indeed do the multiplexing. CS stands for Chip Select.

Did you call the SD.begin(cspin) with the cspin specified? This should be handled automatically....

@AllanOricil
Copy link
Author

AllanOricil commented Mar 12, 2024

@rzeldent I did. Look at the last picture.

Could you write a minimal example demonstrating that it endeed works? I could not make one.
Then you can share here with everyone.

@AllanOricil
Copy link
Author

Look, it does not work. This function called add_new_secret is called whenever a mqtt message is received.

image

Obs: disregard the name of the function.
Obs: I'm just trying to read the file in that function because I did it without a problem in the setup, before calling before calling smartdisplay_init()

@rzeldent
Copy link
Owner

Cograts! https://hackaday.com/2024/03/07/an-esp32-multifactor-totp-generator/

@AllanOricil
Copy link
Author

AllanOricil commented Mar 13, 2024

@rzeldent I think the solution would be to use this TFT_eTouch and TFT_eSPI, according to this forum. It seems these libraries allow both Touch and LCD to work on the same SPI bus.

image

With your library, I tried setting both touch and lcd to SPI2_HOST, and let the sd card alone in SPI3_HOST, but it did not work. I also did the opposite, and put both in SPI3_HOST, and left the SD card on SPI2_HOST, and again no success. In both cases the LCD works, and the touch is disabled. As an evidence that both LCD and Touch are on the same SPI bus, see the picture shown below

image

Still, I don't know why the SD Card isn't working anywhere after calling smartdisplay_init(). This is how I'm configuring the SD card to run exclusively on SPI3_HOST

SPIClass custom_spi = SPIClass(VSPI); // using SPI3_HOST exclusively for the SD card

void init_sd_card_reader(){
  custom_spi.begin(TF_SPI_SCLK, TF_SPI_MISO, TF_SPI_MOSI, TF_CS); // 18, 19, 23, 5 respectively

  if(!SD.begin(TF_CS, custom_spi, 80000000)){
    Serial.println("sd card mount failed");
    return;
  }
  uint8_t cardType = SD.cardType();
  if (cardType == CARD_NONE) {
    Serial.println("No SD card attached");
    return;
  }

  Serial.print("SD Card Type: ");
  if (cardType == CARD_MMC) {
      Serial.println("MMC");
  } else if (cardType == CARD_SD) {
      Serial.println("SDSC");
  } else if (cardType == CARD_SDHC) {
      Serial.println("SDHC");
  } else {
      Serial.println("UNKNOWN");
  }

  Serial.printf("SD Card Size: %lluMB\n", SD.cardSize() / (1024 * 1024));
  Serial.printf("Total space: %lluMB\n", SD.totalBytes() / (1024 * 1024));
  Serial.printf("Used space: %lluMB\n", SD.usedBytes() / (1024 * 1024));
}

Inside the setup, before calling smartdisplay_init(), I can read/append/write to files without a problem. I'm also sure to close the file with file.close() after reading it, so that I can later reopen it without a problem. But whenever I try doing it after calling smartdisplay_init(), the same problem happens. Even when using a exclusive SPI bus for the SD card.

This is my board config for the experiment described above

{
  "build": {
    "arduino": {
      "ldscript": "esp32_out.ld"
    },
    "core": "esp32",
    "extra_flags": [
      "'-D ARDUINO_ESP32_DEV'",
      "'-D ESP32_2432S028Rv3'",
      "'-D LCD_WIDTH=240'",
      "'-D LCD_HEIGHT=320'",
      "'-D LVGL_BUFFER_PIXELS=(LCD_WIDTH*LCD_HEIGHT/4)'",
      "'-D LVGL_BUFFER_MALLOC_FLAGS=(MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT)'",
      "'-D GPIO_BCKL=21'",
      "'-D LCD_ST7789_SPI'",
      "'-D ST7789_SPI_HOST=SPI2_HOST'",
      "'-D ST7789_SPI_DMA_CHANNEL=SPI_DMA_CH_AUTO'",
      "'-D ST7789_SPI_BUS_MOSI_IO_NUM=13'",
      "'-D ST7789_SPI_BUS_MISO_IO_NUM=GPIO_NUM_NC'",
      "'-D ST7789_SPI_BUS_SCLK_IO_NUM=14'",
      "'-D ST7789_SPI_BUS_QUADWP_IO_NUM=GPIO_NUM_NC'",
      "'-D ST7789_SPI_BUS_QUADHD_IO_NUM=GPIO_NUM_NC'",
      "'-D ST7789_SPI_BUS_MAX_TRANSFER_SZ=0'",
      "'-D ST7789_SPI_BUS_FLAGS=0'",
      "'-D ST7789_SPI_BUS_INTR_FLAGS=0'",
      "'-D ST7789_SPI_CONFIG_CS_GPIO_NUM=15'",
      "'-D ST7789_SPI_CONFIG_DC_GPIO_NUM=2'",
      "'-D ST7789_SPI_CONFIG_SPI_MODE=SPI_MODE3'",
      "'-D ST7789_SPI_CONFIG_PCLK_HZ=24000000'",
      "'-D ST7789_SPI_CONFIG_TRANS_QUEUE_DEPTH=10'",
      "'-D ST7789_SPI_CONFIG_LCD_CMD_BITS=8'",
      "'-D ST7789_SPI_CONFIG_LCD_PARAM_BITS=8'",
      "'-D ST7789_SPI_CONFIG_FLAGS_DC_AS_CMD_PHASE=false'",
      "'-D ST7789_SPI_CONFIG_FLAGS_DC_LOW_ON_DATA=false'",
      "'-D ST7789_SPI_CONFIG_FLAGS_OCTAL_MODE=false'",
      "'-D ST7789_SPI_CONFIG_FLAGS_LSB_FIRST=false'",
      "'-D ST7789_DEV_CONFIG_RESET_GPIO_NUM=GPIO_NUM_NC'",
      "'-D ST7789_DEV_CONFIG_COLOR_SPACE=ESP_LCD_COLOR_SPACE_RGB'",
      "'-D ST7789_DEV_CONFIG_BITS_PER_PIXEL=16'",
      "'-D ST7789_DEV_CONFIG_FLAGS_RESET_ACTIVE_HIGH=false'",
      "'-D ST7789_DEV_CONFIG_VENDOR_CONFIG=NULL'",
      "'-D LCD_SWAP_XY=false'",
      "'-D LCD_MIRROR_X=false'",
      "'-D LCD_MIRROR_Y=false'",
      "'-D BOARD_HAS_TOUCH'",
      "'-D TOUCH_XPT2046_SPI'",
      "'-D XPT2046_SPI_HOST=SPI2_HOST'",
      "'-D XPT2046_SPI_DMA_CHANNEL=SPI_DMA_CH_AUTO'",      
      "'-D XPT2046_SPI_BUS_MOSI_IO_NUM=32'",
      "'-D XPT2046_SPI_BUS_MISO_IO_NUM=39'",
      "'-D XPT2046_SPI_BUS_SCLK_IO_NUM=25'",
      "'-D XPT2046_SPI_BUS_QUADWP_IO_NUM=GPIO_NUM_NC'",
      "'-D XPT2046_SPI_BUS_QUADHD_IO_NUM=GPIO_NUM_NC'",
      "'-D XPT2046_SPI_CONFIG_CS_GPIO_NUM=33'",
      "'-D XPT2046_SPI_CONFIG_DC_GPIO_NUM=GPIO_NUM_NC'",
      "'-D XPT2046_SPI_CONFIG_SPI_MODE=SPI_MODE0'",
      "'-D XPT2046_SPI_CONFIG_PCLK_HZ=2000000'",
      "'-D XPT2046_SPI_CONFIG_TRANS_QUEUE_DEPTH=3'",
      "'-D XPT2046_SPI_CONFIG_LCD_CMD_BITS=8'",
      "'-D XPT2046_SPI_CONFIG_LCD_PARAM_BITS=8'",
      "'-D XPT2046_SPI_CONFIG_FLAGS_DC_AS_CMD_PHASE=false'",
      "'-D XPT2046_SPI_CONFIG_FLAGS_DC_LOW_ON_DATA=false'",
      "'-D XPT2046_SPI_CONFIG_FLAGS_OCTAL_MODE=false'",
      "'-D XPT2046_SPI_CONFIG_FLAGS_LSB_FIRST=false'",
      "'-D XPT2046_TOUCH_CONFIG_X_MAX=LCD_WIDTH'",
      "'-D XPT2046_TOUCH_CONFIG_Y_MAX=LCD_HEIGHT'",
      "'-D XPT2046_TOUCH_CONFIG_RST_GPIO_NUM=GPIO_NUM_NC'",
      "'-D XPT2046_TOUCH_CONFIG_INT_GPIO_NUM=36'",
      "'-D XPT2046_TOUCH_CONFIG_LEVELS_RESET=0'",
      "'-D XPT2046_TOUCH_CONFIG_LEVELS_INTERRUPT=0'",
      "'-D TOUCH_SWAP_XY=false'",
      "'-D TOUCH_SWAP_X=true'",
      "'-D TOUCH_SWAP_Y=false'",
      "'-D BOARD_HAS_TF'",
      "'-D TF_SPI_HOST=SPI3_HOST'",
      "'-D TF_CS=5'",
      "'-D TF_SPI_MOSI=23'",
      "'-D TF_SPI_SCLK=18'",
      "'-D TF_SPI_MISO=19'",
      "'-D BOARD_HAS_RGB_LED'",
      "'-D RGB_LED_R=4'",
      "'-D RGB_LED_G=16'",
      "'-D RGB_LED_B=17'",
      "'-D BOARD_HAS_CDS'",
      "'-D CDS=34'",
      "'-D BOARD_HAS_SPEAK'",
      "'-D SPEAK=26'"
    ],
    "f_cpu": "240000000L",
    "f_flash": "40000000L",
    "flash_mode": "dio",
    "mcu": "esp32",
    "variant": "esp32"
  },
  "connectivity": [
    "wifi",
    "bluetooth",
    "ethernet",
    "can"
  ],
  "debug": {
    "openocd_board": "esp-wroom-32.cfg"
  },
  "frameworks": [
    "arduino",
    "espidf"
  ],
  "name": "esp32-2432S028Rv3",
  "upload": {
    "flash_size": "4MB",
    "maximum_ram_size": 327680,
    "maximum_size": 4194304,
    "require_upload_port": true,
    "speed": 460800
  },
  "url": "https://www.aliexpress.com/item/1005004502250619.html",
  "vendor": "Sunton"
}

@AllanOricil
Copy link
Author

AllanOricil commented Mar 13, 2024

@rzeldent finally managed to make the SD card work after smartdisplay_init(). However the touch is no longer working. I think it is because the touch and lcd are sharing the same SPI bus, but your library wasn't made for that.

https://github.com/AllanOricil/esp32-mfa-totp-generator/blob/36ef7bac4e55dc0919e2a6bd2e6332146d0eea06/src/main.cpp#L43-L75

Now, I can receive messages from my server using mqtt, and the folder is created
image

UPDATE:

I added all the other operations just to be sure that they work

image

@rzeldent
Copy link
Owner

Hi Allan,

That's a pity touch is not working anymore. Now no time to look into that. However, maybe defining an esp32-2432S028N (No touch) might be something to prevent interference with touch,,,

@AllanOricil
Copy link
Author

esp32-2432S028N

@rzeldent no problem. But I need the touch to work. I want to use all 3 peripherals. Would your suggestion enable it? Could you explain it in more details? Thank you

@AllanOricil
Copy link
Author

@rzeldent I will put my project to rest for now. Once you you have time to fix this, I will go back to it. I don't have enough knowledge of microcontrolers like you, so it would take me ages to fix it by myself. Thank you anyway. Hope you find time soon!

@rzeldent rzeldent self-assigned this Mar 17, 2024
@rzeldent rzeldent added the bug Something isn't working label Mar 17, 2024
@AllanOricil
Copy link
Author

AllanOricil commented Mar 20, 2024

For those with the same issue, these repositories have a solution:

Solution Summary: use a bitbang implementation for the touch sensor instead of a hardware spi bus

https://github.com/AllanOricil/esp32-lvgl-lcd-touch-sd-card
obs: main branch uses lvgl 7
obs: lvgl-8 branch used lvgl 8

https://github.com/AllanOricil/esp32-mfa-totp-generator
obs: is using lvgl 8

@rzeldent you could add the same lib to your lib as a dependency, and create a feature flag such as "XPT2046_DONT_USE_SPI_BUS=1"

@plueschpruem
Copy link

@rzeldent finally managed to make the SD card work after smartdisplay_init(). However the touch is no longer working. I think it is because the touch and lcd are sharing the same SPI bus, but your library wasn't made for that.

Well, it works ONCE.
I can init smartdisplay and read a file in loop() – but only once and then it gives errors again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

When branches are created from issues, their pull requests are automatically linked.

3 participants