11 years, 8 months ago.

SDcard + TFT display

Hello guys,

I'm trying to get a SDcard and a TFT display to work on a single SPI controller.

For the SDcard I'm using SDFileSystem (https://mbed.org/cookbook/SD-Card-File-System) en for the display I'm using Peter Drescher's Library (http://mbed.org/cookbook/SPI-driven-QVGA-TFT).

The thing I run into is that when I try to combine both, something goes wrong. Both individual are no problem and work perfectly. But when I combine them, it won't write text to the SD card. But it still is able to create the "mydir" folder and the file "sdtext.txt" on the card, but after that the program just stops. The file is empty.

In the TFT library I have disabled the use of DMA, but this doesn't help. The SPI frequency for the display is set at 48MHz (the SD card uses 100Hz). The initialise function of the SD card (re)sets the frequency of the SPI to 100Hz (this is called when creating the directory) so it can't be a SPI frequency problem?

Maybe someone knows where this goes wrong?

The main code I currently use:

main.cpp

#include "mbed.h"
#include "rtos.h"

//SD Card
#include "SDFileSystem.h"

//TFT
#include "SPI_TFT.h"
#include "Arial12x12.h"
#include "Arial24x23.h"
#include "Arial28x28.h"
#include "font_big.h"

// The SDCard connection: SPI pin 5-7 + CS p29
SDFileSystem sd(p5, p6, p7, p29, "sd");  

//The TFT connection: SPI pin 5-7 + CS p8 (Reset P0_19)
SPI_TFT TFT(p5, p6, p7, p8, P0_19,"TFT");  
  
void spi_thread(void const *args) {
    
    //TFT.claim(stdout);                         // send stdout to the TFT display
    TFT.background(Black);                       // set background to black
    TFT.foreground(White);                       // set chars to white
    TFT.cls();                                   // clear the screen
    TFT.set_font((unsigned char*) Arial28x28);   // select the font
    TFT.set_orientation(3);
    
    //Put something on the display    
    TFT.locate(10,20);
    TFT.printf("LN2 Level:\r\n");
    TFT.locate(10,60);
    TFT.printf("Temp. A:\r\n");
    TFT.locate(10,100);
    TFT.printf("Temp. B:\r\n");
    
    //Output on UART0
    printf("Hello World!\n");   

    //Create map
    mkdir("/sd/mydir", 0777);

    //Write to SD card (append)
    FILE *fp = fopen("/sd/mydir/sdtest.txt", "a");
    if(fp == NULL) {
        error("Could not open file for write\n");
    }
    fprintf(fp, "Hello fun SD Card World!");
    fclose(fp); 

    //Output on UART0
    printf("Goodbye World!\n");
    
    while (true)
    {
        
    }
}
 
int main(){
    
    Thread thread(spi_thread);
    
    while (true)
    {

    }
}

1 Answer

11 years, 8 months ago.

Hi, my lib is using DMA and direct access to the spi register to speed up. If you want to share the SPI you have to switch to the slower version without optimation. To do open the SPI_TFT.cpp and comment out the two lines at the top

#define USE_DMA we use dma to speed up

#define NO_MBED_LIB we write direct to the SPI register to speed up

The lib will use the original mbed lib to access the spi.

Accepted Answer

Awsome! I just had to out comment NO_MBED_LIB. Thank you!

posted by David Vaessen 27 Mar 2013

I wondered why that was the case, and I saw with NO_MBED_LIB it doesnt use any mbed lib function for SPI (okay okay, I could have gotten that from the name) when for example clearing the screen, also not for the initial command write. So the other SPI objects dont know they lost ownership of the peripheral.

And when you comment that out you will lose alot of speed writing to the display. As ugly fix where you dont have to edit the library it should work if you define another SPI object (doesnt even need to be on the same pins), and after writing something to the display tell that extra SPI object to set the SPI frequency on a random value. Then the SPI object in the SD card library knows it lost ownership of the SPI bus and will put in its own settings again.

posted by Erik - 27 Mar 2013

I've just tried what you said, making a "dummy" SPI object. And after writing to the display it sets the SPI freq. Then the program tries to write something to the SD card and this does not work, the program just stops. It seems to initialise the card but when trying to create a folder or file it stops.

The TFT library does something which is not reset when the SDcard takes over, and then it just fails.

posted by David Vaessen 28 Mar 2013

Try to slow down the SPI speed of the tft lib by changing the _spi.frequency statement in SPI_TFT.cpp. If both run with 1Mhz you can place a _spi.frequency(48000000); before and _spi.frequency(1000000); after all calls to the TFT lib.

posted by Peter Drescher 30 Mar 2013