Using ILI9341_t3.h, tft.begin() causes reboot using Teensyduino 1.59.0 but works fine under 1.58.2.

jsnow

Member
I ran into an issue the other day when I finally gave in to the Arduino IDE asking if I wanted to update to the latest version. Recompiling the project I'm working on under Arduino 2.32, the Teensy to gets stuck in a reboot loop by apparently crashing when initializing the screen with a call to tft.begin().

I tried going back to Arduino 2.0.4, but the same problem persisted.

I tried installing Arduino 2.1.0 on a different computer and installing a slightly older version of Teensyduino (1.58.2), and that works fine -- no reboots.

Then I went back to the first computer and downgraded Teensyduino to 1.58.2 (Using Arduino 2.0.4) from 1.59.0, and that also works fine. So it seems like there was some sort of breaking change between 1.58.2 and 1.59.0.

Did something change in the ILI9341_t3.h library? Or something else that affects screen initialization?

A reproducer:

#define hwversion 3 #include <ILI9341_t3.h> #include <font_Arial.h> #include <font_ArialBold.h> /* Pins */ #define screenDCPin 9 #define sdiPin 11 #define sdoPin 12 #define sckPin 13 #define backlightPin 19 #define screenCSPin 255 /* Serial */ void serialSetup() { Serial.begin(115200); } /* Screen */ #define TFT_DC screenDCPin #define TFT_CS screenCSPin #define TFT_RST 255 // 255 = unused, connect to 3.3V #define TFT_MOSI sdiPin #define TFT_SCLK sckPin #define TFT_MISO sdoPin ILI9341_t3 tft = ILI9341_t3(TFT_CS, TFT_DC, TFT_RST, TFT_MOSI, TFT_SCLK, TFT_MISO); uint32_t brightness = 127; void screenSetup() { Serial.println("in screenSetup"); pinMode(backlightPin, OUTPUT); analogWriteFrequency(backlightPin, 3611*2); /* default is 3.611 kHz */ analogWrite(backlightPin, brightness); Serial.println("about to call tft.begin, &tft = " + String((uint32_t)&tft)); delayMicroseconds(100000); tft.begin(); Serial.println("got past tft.begin"); delayMicroseconds(100000); tft.setRotation(1); tft.setClock(100000000); tft.fillScreen(ILI9341_BLACK); Serial.println("was able to set rotation/clock and fill black"); //renderScreen(); uint8_t x = tft.readcommand8(ILI9341_RDMODE); Serial.print("Display Power Mode: 0x"); Serial.println(x, HEX); x = tft.readcommand8(ILI9341_RDMADCTL); Serial.print("MADCTL Mode: 0x"); Serial.println(x, HEX); x = tft.readcommand8(ILI9341_RDPIXFMT); Serial.print("Pixel Format: 0x"); Serial.println(x, HEX); x = tft.readcommand8(ILI9341_RDIMGFMT); Serial.print("Image Format: 0x"); Serial.println(x, HEX); x = tft.readcommand8(ILI9341_RDSELFDIAG); Serial.print("Self Diagnostic: 0x"); Serial.println(x, HEX); Serial.println("5"); } /* Setup, Main Loop */ void setup() { serialSetup(); Serial.println("initializing screen..."); screenSetup(); Serial.println("end setup"); } uint32_t usecs = 0; uint32_t prevUsecs = 0; uint32_t prevTimestamp = 0; uint32_t screenRedrawAge = 1000000; uint32_t maxRedrawAge = 10000; void loop() { Serial.println("main loop: if we got here, it's working"); delayMicroseconds(1000); }
 
It runs on mine, using recent nightly build and current Teensyduino...
Using library ILI9341_t3 at version 1.0 in folder: C:\Users\kurte\AppData\Local\Arduino15\packages\teensy\hardware\avr\1.59.0\libraries\ILI9341_t3

However I edited to my boards CS, DC, Reset pins.
Not sure with your setup where CS=255 works. Do you have CS pin wired to gnd?
 
Yeah, CS is grounded.

I didn't notice any compiler warnings. Is there a way to crank up the verbosity in the Arduino IDE?
 
I ran several tests just now. The display is not reliable without CS (shorting it to GND). I did get it to work a few times if another program has previously used the same display by driving CS. But I couldn't get the display to ever work from cold powerup with CS shorted to GND.

I ran your program with the CS pin set to 10, and a couple lines added to print "Hello World" in Arial font, and the delay in loop increased so the messages don't scroll away. It printed this:

Code:
initializing screen...
in screenSetup
about to call tft.begin, &tft = 536883460
got past tft.begin
was able to set rotation/clock and fill black
Display Power Mode: 0x9C
MADCTL Mode: 0x28
Pixel Format: 0x5
Image Format: 0x0
Self Diagnostic: 0x0
5
end setup
main loop: if we got here, it's working
main loop: if we got here, it's working
main loop: if we got here, it's working
main loop: if we got here, it's working
main loop: if we got here, it's working
main loop: if we got here, it's working
main loop: if we got here, it's working
main loop: if we got here, it's working

Here is the hardware on my workbench, with CS connected to pin 10.

1712876718167.png



And for completeness, here is the exact code I ran. Should look familiar, just a couple minor changes (mainly use of pin 10 for CS)

Code:
#define hwversion 3
#include <ILI9341_t3.h>
#include <font_Arial.h>
#include <font_ArialBold.h>
/* Pins */
#define screenDCPin 9
#define sdiPin 11
#define sdoPin 12
#define sckPin 13
#define backlightPin 19
#define screenCSPin 10 //255
/* Serial */
void serialSetup() {
  Serial.begin(115200);
}
/* Screen */
#define TFT_DC      screenDCPin
#define TFT_CS      screenCSPin
#define TFT_RST     255  // 255 = unused, connect to 3.3V
#define TFT_MOSI    sdiPin
#define TFT_SCLK    sckPin
#define TFT_MISO    sdoPin
ILI9341_t3 tft = ILI9341_t3(TFT_CS, TFT_DC, TFT_RST, TFT_MOSI, TFT_SCLK, TFT_MISO);
uint32_t brightness = 127;
void screenSetup() {
  Serial.println("in screenSetup");
  pinMode(backlightPin, OUTPUT);
  analogWriteFrequency(backlightPin, 3611*2); /* default is 3.611 kHz */
  analogWrite(backlightPin, brightness);
  Serial.println("about to call tft.begin, &tft = " + String((uint32_t)&tft));
  delayMicroseconds(100000);
  tft.begin();
  Serial.println("got past tft.begin");
  delayMicroseconds(100000);
  tft.setRotation(1);
  tft.setClock(100000000);
  tft.fillScreen(ILI9341_BLACK);
  Serial.println("was able to set rotation/clock and fill black");
  //renderScreen();
  uint8_t x = tft.readcommand8(ILI9341_RDMODE);
  Serial.print("Display Power Mode: 0x"); Serial.println(x, HEX);
  x = tft.readcommand8(ILI9341_RDMADCTL);
  Serial.print("MADCTL Mode: 0x"); Serial.println(x, HEX);
  x = tft.readcommand8(ILI9341_RDPIXFMT);
  Serial.print("Pixel Format: 0x"); Serial.println(x, HEX);
  x = tft.readcommand8(ILI9341_RDIMGFMT);
  Serial.print("Image Format: 0x"); Serial.println(x, HEX);
  x = tft.readcommand8(ILI9341_RDSELFDIAG);
  Serial.print("Self Diagnostic: 0x"); Serial.println(x, HEX); 
  Serial.println("5");
}

/* Setup, Main Loop */
void setup() {
  serialSetup();
  Serial.println("initializing screen...");
  screenSetup();
  Serial.println("end setup");
  tft.setFont(Arial_32_Bold);
  tft.setCursor(10, 10);
  tft.print("Hello World");
}
uint32_t usecs = 0;
uint32_t prevUsecs = 0;
uint32_t prevTimestamp = 0;
uint32_t screenRedrawAge = 1000000;
uint32_t maxRedrawAge = 10000;
void loop() {
  Serial.println("main loop: if we got here, it's working");
  delayMicroseconds(10000000);
}
 
Yeah, CS is grounded.

I didn't notice any compiler warnings. Is there a way to crank up the verbosity in the Arduino IDE?
Change in CS pin is interesting with changes in TeensyDuino version - but CS usage is normally a live pin.

As for Verbosity, the Preferences page in IDE ( Ctrl+, ) has a checkbox for Verbose compile output and all build info then appears in console.
 
I tried recompiling everything in verbose mode -- no warnings.

I tried switching back to Arduino 2.3.2. Just like with 2.0.4, I get reboot loops with Teensyduino 1.59.0, everything is fine with 1.58.2.

I ran several tests just now. The display is not reliable without CS (shorting it to GND). I did get it to work a few times if another program has previously used the same display by driving CS. But I couldn't get the display to ever work from cold powerup with CS shorted to GND.
That's weird that you've never gotten the screen to come up with CS grounded. I've been using it like that for months on multiple boards/screens, with no problems at all other than this reboot loop.

I'm using the 2.8" version of the screen from the pjrc.com store.

This is the schematic: https://github.com/jimsnow/microtonal-controller/blob/main/doc/keyboard-ji7l-pcb-rev3.pdf

I verified 0 resistance with my ohmmeter between the screen CS pin and Teensy GND pin.
 
It looks like the problem is specific to setting the CS pin to 255. If I set it to pin 10 it works normally. (Pin 36 works too, and that doesn't conflict with what I'm already using pin 10 for.)

The md5sum of all the ILI9341_t3 source code files is the same from 1.58.2 to 1.59.0, so apparently there's a change somewhere else. Maybe the SPI library used to treat 255 as a "fake" pin, and now it doesn't? Or maybe using 255 was always undefined behavior, and it just happened to work by accident in previous releases?

I think my problem is solved for now anyways.
 
Back
Top