Do the ILI9341 and SD libraries play nice together on the T4?

Status
Not open for further replies.

RetroD

Member
I'm working on displaying the files from an SD card on the ILI9341 LCD I bought from Adafruit (https://learn.adafruit.com/adafruit-2-dot-8-color-tft-touchscreen-breakout-v2/overview ) It has a built in microSD card reader on the back.

The SD card and LCD work just fine independently of each other, but as soon as I add SD.begin() after tft.begin() the LCD doesn't update. I'm suspecting it has something to do with either one of the libraries not properly setting the CS pin high, or that the SD library configures the SPI bus differently than the TFT library.

My wiring configuration is:

Code:
TEENSY | TFT | SD
Pin 8  |  x  | CS
Pin 9  |  DC |  x
Pin 10 |  CS |  x

Pin 11 | MOSI   \
Pin 12 | MISO   >- Wired to both TFT and SD
Pin 13 | SCK    /

My code is as follows:

Code:
#include <SD.h>
#include <SPI.h>
#include "ILI9341_t3.h"

#define TFT_DC 9
#define TFT_CS 10
#define SD_CS 8

File sdFile;
ILI9341_t3 tft = ILI9341_t3(TFT_CS, TFT_DC);

void setup() {
  pinMode(SD_CS, INPUT_PULLUP);
  delay(200);
  pinMode(TFT_CS, INPUT_PULLUP);
  delay(200);
  
  Serial.begin(9600);
  while(!Serial){}
  
  if(!SD.begin(SD_CS)){
    Serial.println("Card failed or isn't present");
    return;
  }
  tft.begin();
  tft.fillScreen(ILI9341_BLACK);
  tft.setTextSize(1);
  tft.setTextColor(ILI9341_WHITE);
  tft.setCursor(0,0);
  tft.println(F("This doesn't print!"));
}

void loop() {
 
}

Thank you for you help in advance.
 
You might try adding 2.2K pull-up resistors between each of the two CS pins. A pull-up resistor is connected in parallel between the pin and 3.3v. This comes from this page of how to make better SPI buses:

However, it looks like the SD library doesn't support beginTransaction or endTransaction which are important for sharing the SPI bus. There is a t3 version that does. You might try switching to use:
  • #include <SD_t3.h>
 
Quote from ILI9341 page here (with link to the mentioned HW mod thread): https://www.pjrc.com/store/display_ili9341_touch.html

"We do not recommend using the SD card socket on this display. It does not work, but this hardware modification may be able to get it working."

The ILI9341 module sold by PJRC differs from the one sold by Adafruit.

The SD card and LCD share a SPI bus on the module sold by Adafruit. I have gotten the two to work independently of each other, just not together in the same program.

You might try adding 2.2K pull-up resistors between each of the two CS pins. A pull-up resistor is connected in parallel between the pin and 3.3v. This comes from this page of how to make better SPI buses:

However, it looks like the SD library doesn't support beginTransaction or endTransaction which are important for sharing the SPI bus. There is a t3 version that does. You might try switching to use:
  • #include <SD_t3.h>

I will add some pull up resistors. I was looking at the source code of the two libraries and they seem to rewrite the pinMode from having a pullup on them.

Will the SD_t3 library work with the T4?
 
Adding the pull up resistors did not fix the problem where the LCD and SD card couldn't work at the same time, but it did fix another problem.

I was having to unplug and re-plug in my SD card every time I uploaded new code, and now things work automatically.

I'm about to try the SD_t3 library.
 
After looking at the source code, there doesn't appear to be support for the T4 in the SD_t3. Real bummer.

Might have to find a way to break out the bottom SPI connections into a separate board to use both devices.

Either that or spend a long time writing a new SD_T4 library that supports beginTransaction and endTransaction.
 
Well you might try calling beginTransaction and endTransaction in your code to manually switch between the two.

There are two separate SPI ports underneath the Teensy 4.0. For accessing a SD card, using the 8 pins at the front of the Teensy is the way to go. You use BUILTIN_SDCARD for the CS pin. It also is much faster, as it gets data via 4 pins in parallel. The downside is the pads are 1mm apart, so it needs much more careful soldering.

There is another SPI port that you need to wire 2 pads (for pins 26 and 27), and use pins 0 and 1. These pads are the standard 0.1" (2.54mm) spacing, so you could just solder the two wires. I've done that in the past, and I've had it come off 2 times.

Before getting to the various boards to bring out the pins, I was thinking of soldering a 2x5 surface mount header to bring out the pins with less possibility of tearing off:

There are various boards to access the bottom pins. If you can do a small amount of surface mount soldering there is the board by 'trainer4edu' (FRDM4236) that breaks out both sets of pads, and also allows you to solder a micro-SD card reader onto the PCB, so it gives a Teensy 3.6 form factor:

Another approach is to solder an 8 pin FFC connector underneath the Teensy, and then use a FFC cable to bring out the SD card pins. Paul used this during the beta test, and created a shield for it. While he isn't selling the shield, you can download the gerber files and make your own version:

There will be a follow-on for the Teensy 4.0 that uses the same processor, but it has a larger board, and it should bring out the SD card directly. I don't know what the timetable is for this, but it likely will be a few months until it is available on a retail basis.
 
I don't know whether the SD and ILI9341_t3 libraries play together nicely on the T4, but the SdFat and ILI9341_t3 libraries do. You can either make a minor tweak to one file in the SdFat library to get it to talk to the uSD on the T4's SPI lines, or use the beta version of the SdFat library that has the T4 support built in.

Code:
SdFat/src/SpiDriver/SdSpiTeensy3.cpp
***************
*** 23,31 ****
   * DEALINGS IN THE SOFTWARE.
   */
  #include "SdSpiDriver.h"
! #if defined(__arm__) && defined(CORE_TEENSY)
  // SPI definitions
  #include "kinetis.h"
  
  //------------------------------------------------------------------------------
  void SdSpiAltDriver::activate() {
--- 23,33 ----
   * DEALINGS IN THE SOFTWARE.
   */
  #include "SdSpiDriver.h"
! #if defined(__arm__) && defined(CORE_TEENSY) && !defined(__IMXRT1062__)
  // SPI definitions
  #include "kinetis.h"
+ #endif
+ #if defined(__arm__) && defined(CORE_TEENSY)
  
  //------------------------------------------------------------------------------
  void SdSpiAltDriver::activate() {

You can see in the picture below that on the right there's a 320x240 LCD display that uses an ILI9341 controller, and a separate uSD just above the T4. The previous iteration of hardware used one of Adafruit's ST7735 based 160x128 displays, and on that one I used the uSD connector built in to the display. Both configurations worked fine.

ILI9341 and uSD.jpg
 
Status
Not open for further replies.
Back
Top