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.74k stars 1.07k forks source link

PlatformIO TFT_eSPI+SD slot. Problem duplicate func #1509

Closed serpetti closed 2 years ago

serpetti commented 2 years ago

Hi, I've just started to develop with ILI9341 and TFT_eSPI lib. Everything work perfectly, even the touchscreen. I've also added LVGL framework and is perfect (thanks Bodmer, great job). But I've a worrying behaviour when I try to add SD library. When I execute the method SD.begin(...) I get this error: [E][esp32-hal-cpu.c:93] addApbChangeCallback(): duplicate func=400D5FC8 arg=3FFBDCD8

I think it's due to multiple instantiations of SPI object, but is there a solution?

Thanks in advance

justp7 commented 2 years ago

Have you changed CS IO?I tried SD card and TFT working at the same time and it worked.

serpetti commented 2 years ago

Hi, thank you for your answer. Yes, I've changed CS for SD (pin 2). The truth is that everything seems work, at least for the test code. The only thing that worry me is the error "[E][esp32-hal-cpu.c:93] addApbChangeCallback(): duplicate func...". I don't know if it can cause leaks or insability. My code is:

...
lv_init();
if (!SD.begin(2))
{
    Serial.println("Card Mount Failed");
    return;
}    
tft.begin();        /* TFT init */
tft.setRotation(1); /* Landscape orientation, flipped */
uint16_t calData[5] = {379, 3486, 264, 3405, 7};
tft.setTouch(calData);
...

Regards

Bodmer commented 2 years ago

I suspect this occurs because the SD and TFT are on different pins so a single SPI hardware port cannot connected to both.

By default most libraries use the FPSI port.

If you add this line to your TFT_eSPI setup file then the library will use a different SPI port:

define USE_HSPI_PORT

serpetti commented 2 years ago

Hi, and thank you for your answer. At the moment I'm using VSPI port for TFT and HSPI for Touch screen (see attached document pag. 9) and I tried to use the SD device with default SD.h setup, changing only SD_CS. But everything seems work perfectly, I've only the error: [E][esp32-hal-cpu.c:93] addApbChangeCallback(): duplicate func=400D5FC8 arg=3FFBDCD8 I've tested touch, tft, sd and everything works fine, but I suspect that this error could create leaks or instability.

include

include

include

include

TFT_eSPI tft = TFT_eSPI();

void setup() { Serial.begin(115200);

// Set all chip selects high to avoid bus contention during initialisation of each peripheral digitalWrite(22, HIGH); // Touch controller chip select (if used) digitalWrite(5, HIGH); // TFT screen chip select digitalWrite( 2, HIGH); // SD card chips select,

tft.begin();

if (!SD.begin(2)) { Serial.println("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"); }

uint64_t cardSize = SD.cardSize() / (1024 * 1024); Serial.printf("SD Card Size: %lluMB\n", cardSize);

Serial.println("initialisation done."); }

//#################################################################################################### // Main loop //#################################################################################################### void loop() {

}

At the row if (!SD.begin(2)) { I've the error above. Any solution? Thanks again f

Il giorno lun 27 dic 2021 alle ore 17:24 Bodmer @.***> ha scritto:

I suspect this occurs because the SD and TFT are on different pins so a single SPI hardware port cannot connected to both.

By default most libraries use the FPSI port.

If you add this line to your TFT_eSPI setup file then the library will use a different SPI port:

define USE_HSPI_PORT

— Reply to this email directly, view it on GitHub https://github.com/Bodmer/TFT_eSPI/issues/1509#issuecomment-1001643471, or unsubscribe https://github.com/notifications/unsubscribe-auth/ASFYKH5E6B5KNQE3P7XMHY3UTCHMRANCNFSM5K2FCRWA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you authored the thread.Message ID: @.***>

Bodmer commented 2 years ago

If you are using the built in TFT_eSPI touch support then the TFT and touch interfaces must be on the same SPI port. The SD can be on a different port.

bhupiister commented 2 years ago

@Bodmer I am using M5Stack Core2 and it uses this library. I am facing issues with god knows what. I am using SD card and TFT_eSPI on same bus. SD card initializes properly and so does the display. But sometimes i face issues sometimes while accessing SD card, and i get an error [ 88619][E][sd_diskio.cpp:126] sdSelectCard(): Select Failed

I read your suggestion of flag USE_HSPI_PORT using HSPIbut then it does not load the screen. I have read somewhere that it is because of ILI9341using half duplex mode and causing error to SD card as they are on the same SPI bus.

SD card initializing script SD.begin(SS_PIN, SPI, 40000000);

Please help if you can on this issue, ill really appreciate any kind of help.

Bodmer commented 2 years ago

I rarely use and SD card, preferring to use LittleFS and do not have a setup to test at the moment.

I never got the SD card SPI to run at 40MHz, the best I got without errors was 10MHz. Have you tried a lower SPI clock speed?

Bodmer commented 2 years ago

According to this discussion the highest speed supported is 26MHz: https://www.esp32.com/viewtopic.php?t=12634

bhupiister commented 2 years ago

@Bodmer It seems that the issue was with the SD card library, probably the new version. It does not release resource at the end of SPI transaction. After porting from SD to SdFat, issue was resolved, as it has option of running sd card on shared SPI bus while initialising. Surprisingly, it was fast too. By the way you are right about the max frequency, it runs comfortably on 10Mhz.

Bodmer commented 2 years ago

Thanks for letting me know. Hope your project proceeds smoothly now.

MHYCWasTaken commented 1 year ago

Hi,
I got simillar problem, I am using a touch screen(ILI9341), the screen and touch worked well
But SD.begin() gives me

[   402][E][esp32-hal-cpu.c:110] addApbChangeCallback(): duplicate func=0x400d8098 arg=0x3ffbdc60
[  1916][E][sd_diskio.cpp:126] sdSelectCard(): Select Failed
[  2416][E][sd_diskio.cpp:126] sdSelectCard(): Select Failed
[  2416][E][sd_diskio.cpp:802] sdcard_mount(): f_mount failed: (3) The physical drive cannot work
[  2948][E][sd_diskio.cpp:126] sdSelectCard(): Select Failed

And SD.open() gives me

[  2948][E][vfs_api.cpp:24] open(): File system is not mounted

My code is like:

#include <arduino.h>
#include <SPI.h>
#include <TFT_eSPI.h>
#include <SD.h>
TFT_eSPI tft = TFT_eSPI();
...
void init() {
  ...
  tft.init();
  pinMode(12, OUTPUT);
  SD.begin(12, SPI, 1000000);
  File f = SD.open("test.txt", FILE_WRITE);
  ...
}
...

I didn't do SPI.begin(), so im kinda sure SD and TFT are using a same SPI object (that tft.init() created)
But when I add SPI.begin(18, 19, 23); between tft.init() and SD.init() (There should be 4 args, the last arg is ss, but i dont know what ssis , is it same as cs? if it is, should i use SD's cs or TFT's cs or TOUCH's cs?) SPI.begin() gives me

[   402][E][esp32-hal-cpu.c:110] addApbChangeCallback(): duplicate func=0x400d80a8 arg=0x3ffbdc60

SD.begin() gives me

[   720][E][sd_diskio.cpp:199] sdCommand(): Card Failed! cmd: 0x37
[   720][E][sd_diskio.cpp:199] sdCommand(): Card Failed! cmd: 0x29
[   727][E][sd_diskio.cpp:802] sdcard_mount(): f_mount failed: (3) The physical drive cannot work

And SD.open() give the same error

[   959][E][vfs_api.cpp:24] open(): File system is not mounted

Then, I put SPI.begin() line in front of tft.begin(), The error is as same as that when i didn't add SPI.begin()
(So i guess tft.begin() overwrites SPI object?)

My wire connection is like

TOUCH_MISO & SD_MISO ---> 19
TFT_MOSI & TOUCH_MOSI & SD_MOSI ---> 23 
TFT_SCLK & TOUCH_SLCK & SD_SLCK ---> 18
TFT_CS ---> 15
TOUCH_CS ---> 21
SD_CS ---> 12

My SD card is 32gb, but i have just make a partition with 1.5gb size and FAT16, the left space has no partition
I have no idea im using which of FSPI, VSPI or HSPI, i have no code setting them


(sorry my english is a little poor) (and im basiclly new to hardware stuff)