lovyan03 / LovyanGFX

SPI LCD graphics library for ESP32 (ESP-IDF/ArduinoESP32) / ESP8266 (ArduinoESP8266) / SAMD51(Seeed ArduinoSAMD51)
Other
1.03k stars 189 forks source link

How to add SD SPI storage with LovyanGFX in ESP-IDF? #248

Closed sukesh-ak closed 1 year ago

sukesh-ak commented 1 year ago

I have display working well and now I am looking to integrate SD SPI for storage with it.

Do you have a sample of how to use the SPI bus shared with display & sd card in ESP-IDF?

I understand we need to use spi_bus_add_device but not sure how to get the handle while using LovyanGFX. And also how it works sharing the bus for both display & sd card.

Something similar to this https://github.com/loboris/ESP32_NEW_SPI_MASTER_EXAMPLE

Thanks in advance.

lovyan03 commented 1 year ago

Hello @sukesh-ak Here is a sample code I have created in the past, is this useful for you ?

https://gist.github.com/lovyan03/7a5a9b66130e81e1cb84776b5346e0fe

sukesh-ak commented 1 year ago

Hello @sukesh-ak Here is a sample code I have created in the past, is this useful for you ?

https://gist.github.com/lovyan03/7a5a9b66130e81e1cb84776b5346e0fe

Thank you for the response. Will test and get back.

sukesh-ak commented 1 year ago

@lovyan03 If I add the code you shared the SD card works and display also works. But the screen gets shifted towards right. Photo attached.

Screen works well if I comment out the SD card portion.

Hardware: Unexpected Maker FeatherS3 + LovyanGFX + LVGL + Adafruit 2.4" TFT Featherwing.

photo_2022-06-21_14-04-46

lovyan03 commented 1 year ago

@sukesh-ak Exclusion control may not be in place. Perhaps SD access is being performed with LCD CS asserted. I need to check your configuration and code, so please create the smallest code that reproduces the Issue and show it to me.

sukesh-ak commented 1 year ago

@sukesh-ak Exclusion control may not be in place. Perhaps SD access is being performed with LCD CS asserted. I need to check your configuration and code, so please create the smallest code that reproduces the Issue and show it to me.

ok will share a simpler code sample soon.

Exclusion control may not be in place.

What is this?

lovyan03 commented 1 year ago

Exclusion control may not be in place.

What is this?

Sorry. I use a translation tool because I cannot use English. I means that access control is required to prevent SD and LCD accesses from occurring simultaneously.

sukesh-ak commented 1 year ago

No worries.

Here is the simple sample. https://github.com/sukesh-ak/FeatherS3-LovyanGFX-SDSPI-LVGL

sukesh-ak commented 1 year ago

Working without SD SPI

photo_2022-06-21_19-05-47

After enabling SD SPI

photo_2022-06-21_19-05-41

geiseri commented 1 year ago

https://github.com/sukesh-ak/FeatherS3-LovyanGFX-SDSPI-LVGL/blob/master/main/storage_helper.hpp#L17 line might be the issue. It will use the default settings for the host as https://github.com/espressif/esp-idf/blob/release/v4.4/components/driver/include/driver/sdspi_host.h#L38 so some of those values may conflict. I am going to be fighting this on in a day or two because I am waiting for hardware.

geiseri commented 1 year ago

@sukesh-ak stupid question. Does order matter if you swap the init of the display and the sdcard?

sukesh-ak commented 1 year ago

@sukesh-ak stupid question. Does order matter if you swap the init of the display and the sdcard?

It won't work since we are setting up SPI bus inside LovyanGFX display setup. And then reusing it for SD SPI.

@lovyan03 & @geiseri I have made some progress and now looks like a timing issue. Link to updated code line number.

https://github.com/sukesh-ak/FeatherS3-LovyanGFX-SDSPI-LVGL/blob/6e532e26cc1fc5f9c5a6b84267cfd7ffdda6a0f5/main/main.cpp#L29

I added 2 timers.

1st timer (initialze SD SPI), if its lower than 1s value, it fails otherwise it works. That confirms its something to do with timing.

Will update once I get more clarity.

sukesh-ak commented 1 year ago

@lovyan03 & @geiseri Ok found the fix.

Call lv_timer_handler() atleast once before initializing SDSPI on the same shared SPI bus for screen refresh. Otherwise screen gets a glitch.

I will document in the repo README as well in sometime.

Code with explanation here https://github.com/sukesh-ak/FeatherS3-LovyanGFX-SDSPI-LVGL/blob/00d2d45454d417ba2b6a470a6441e31a3505af78/main/main.cpp#L73

sukesh-ak commented 1 year ago

After more testing I can't say its a fix like mentioned above. It defenitely looks like a timing issue though.

geiseri commented 1 year ago

It must be a side-effect of both init methods reconfiguring the bus. The spi calls are supposed to be okay if you don't access the same device from two tasks. esp_vfs_fat_sdspi_mount does a lot of stuff under the hood. It might be better to find a way to configure the SPI from only one place. The goal being to prevent spi_bus_add_device from running twice.

sukesh-ak commented 1 year ago

It must be a side-effect of both init methods reconfiguring the bus. The spi calls are supposed to be okay if you don't access the same device from two tasks. esp_vfs_fat_sdspi_mount does a lot of stuff under the hood. It might be better to find a way to configure the SPI from only one place. The goal being to prevent spi_bus_add_device from running twice.

Its actually not related to SPI directly I believe. I need to find time to remove lvgl out of the equation and see if I can still repro.

lovyan03 commented 1 year ago

@sukesh-ak @geiseri I may have found the cause. The current process is deasserting CS after releasing the bus when it finishes communicating with the LCD.

https://github.com/lovyan03/LovyanGFX/blob/develop/src/lgfx/v1/panel/Panel_LCD.cpp#L79-L80

/// in ` Panel_LCD::end_transaction() `

    _bus->endTransaction();
    cs_control(true);

This implementation can cause problems if the task handling the SD is waiting for the bus to be released. Communication with the SD will start the moment the bus is released, and data will probably flow before LCD_CS is deasserted

Try rewriting it as follows and see if it improves the situation

   _bus->wait();
   cs_control(true);
   _bus->endTransaction();
sukesh-ak commented 1 year ago

Changes as suggested.

    // before
    _bus->endTransaction();
    cs_control(true);
    // after
   _bus->wait();
   cs_control(true);
   _bus->endTransaction();
sukesh-ak commented 1 year ago

Sorry you can ignore the report about crash. But after the suggested changes still no difference.

geiseri commented 1 year ago

My board arrives today so I can confirm. I was under the impression though that the IDF supported multiple writers to the SPI if they were not the same slave. Or do I misunderstand the process of transactions on the bus? @lovyan03 ?

lovyan03 commented 1 year ago

@geiseri Yes, it should work fine inherently. At least, @sukesh-ak 's sample code works without any problems with M5Stack. it may be a problem specific to ESP32S3, but I do not have the feather-ESP32S3 board. I plan to make an environment that can be verified using other DevKits.

sukesh-ak commented 1 year ago

@lovyan03 Then I will test with ESP32 and revert tomorrow. I do have Adafruit Huzzah32 as well.

lovyan03 commented 1 year ago

@sukesh-ak @geiseri Thank you for your patience. I have confirmed and fixed the data corruption during DMA transfer on the ESP32S3. Please try and see if this fix in the develop branch solves the problem.

sukesh-ak commented 1 year ago

@sukesh-ak @geiseri Thank you for your patience. I have confirmed and fixed the data corruption during DMA transfer on the ESP32S3. Please try and see if this fix in the develop branch solves the problem.

Thank you for your time. Good news. Looks like the issue is fixed.

Please leave this issue open for the weekend till I get time to test in the larger project and revert.

geiseri commented 1 year ago

@lovyan03 I got my board and the display is working perfectly, but the SD card is all sorts of confused. If I run the example at https://github.com/espressif/esp-idf/blob/master/examples/storage/sd_card/sdspi/main/sd_card_example_main.c on the board it responds as expected. I looked at the traces, and the sdcard configures and even returns the information about the card. I can even see lseek and some other operations. Then as soon as I start writing it goes off into the weeds. The display still responds but it is much slower. I have a feeling that I need to do the following: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/sdspi_share.html. It is just not clear how to "mix" that setup. Your lgfx::v1::spi::init looks like it is supposed to do that. From your example I was not clear how-to set up the other spi device setup the way it wants to be. sdspi looks like it's a complete shitshow without extensive tweaking. It would be good to know how to do that tweaking in the context of you spi control.

lovyan03 commented 1 year ago

@geiseri I cannot read complex English correctly. Please show me the code you have tried.

sukesh-ak commented 1 year ago

@geiseri what hardware are you using?

sukesh-ak commented 1 year ago

@lovyan03 Is the fix now on main branch?

sukesh-ak commented 1 year ago

@geiseri My updated sample is here. Change pins as per your requirements

https://github.com/sukesh-ak/LVGL8x-SDSPI-Template

sukesh-ak commented 1 year ago

You can create a new config file for your hardware in header as done here

https://github.com/sukesh-ak/LVGL8x-SDSPI-Template/blob/e8f4d3a45c632e251d03b011e3e002c483b8be53/main/main.cpp#L19

lovyan03 commented 1 year ago

@sukesh-ak Currently, bug fixes are only applied to the develop branch. The main branch still contains bugs, but will be updated at the time of release. I hope to release an updated version in the next few days.

sukesh-ak commented 1 year ago

@lovyan03 The bug is not completely fixed Its missing top line when SDSPI is enabled

Updated sample is here with 3 different display/board support enabled using a header file

https://github.com/sukesh-ak/LVGL8x-SDSPI-Template

With SDSPI photo_2022-07-02_18-05-45

Without SDSPI photo_2022-07-02_18-05-52

lovyan03 commented 1 year ago

@sukesh-ak Hmmm… I will examine the cause of the glitch again. Just to confirm, I have updated the develop branch once recently. Are you using the latest one?

sukesh-ak commented 1 year ago

@sukesh-ak Hmmm… I will examine the cause of the glitch again. Just to confirm, I have updated the develop branch once recently. Are you using the latest one?

Looks like the updated develop branch fixed the issue.

lovyan03 commented 1 year ago

@sukesh-ak I am sorry… I am not confident in my English translation. Did you solve the problem with the first part of the image not displaying correctly? Are you still experiencing problems?

sukesh-ak commented 1 year ago

Updated develop branch fixes the issue. So its resolved.

lovyan03 commented 1 year ago

@sukesh-ak I appreciate your report ! Please let me know if you find any new problems.

sukesh-ak commented 1 year ago

@lovyan03 when are you planning to release new version with fixes?

My sample is complete and available here with multiple Controller and display combinations https://github.com/sukesh-ak/LVGL8x-SDSPI-Template

lovyan03 commented 1 year ago

@sukesh-ak thanks ! There was one more feature I wanted to add, so I was going to wait until it was completed, but it may take some time, so let's release the current version for now.

sukesh-ak commented 1 year ago

Closing since the shared SPI issue was fixed.