Author Topic: Oak TFT / SD example fatal exception with fix  (Read 5071 times)

cpetito

  • Newbie
  • *
  • Posts: 22
Oak TFT / SD example fatal exception with fix
« on: March 12, 2016, 09:01:42 am »
Here's how to generate a continuous fatal error exception with a suggested fix.

The setup is an OAK with 0.9.5 firmware with the Oak TFT LCD Shield.  The SD card is wired to the appropriate SPI pins and SD_CS is on Pin 2.

The sketch is "digistump\hardware\oak\0.9.5\libraries\Adafruit_ILI9341\examples\spitftbitmap\spitftbitmap.ino" and the file purple.bmp from "https://learn.adafruit.com/assets/13448" is copied to the SD card and renamed.

First the following changes are required to make the original sample work:

Code: [Select]
// OAK TFT LCD Shield:
#define TFT_DC 1
#define TFT_CS 6
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);

#define SD_CS 2 // the pin I used

// the following function prototypes are needed to keep the Arduino IDE happy
void bmpDraw(char *filename, uint8_t x, uint16_t y);
uint16_t read16(File &f);
uint32_t read32(File &f);


The example displays the image and is done.  This version runs without issue.

However the following will cause a problem.

Code: [Select]
void setup(void) {
  Serial.begin(115200);

  tft.begin();
  tft.fillScreen(ILI9341_BLUE);

  Serial.print("Initializing SD card...");
  if (!SD.begin(SD_CS)) {
    Serial.println("failed!");
  }
  Serial.println("OK!");

  bmpDraw("purple.bmp", 0, 0);
}

void loop() {
  // the following three lines are added to give this example some activity
  tft.fillScreen(ILI9341_BLUE);
  bmpDraw("purple.bmp", 0, 0);
  delay(500);
}

With this version, the first image in setup displays as expected, but the image in loop is only partially drawn and the following is captured via the serial monitor:

Quote
ets Jan  8 2013,rst cause:2, boot mode:(3,0)

load 0x40100000, len 3632, room 16
tail 0
chksum 0xc0
load 0x3ffe8000, len 352, room 8
tail 8
chksum 0x82
csum 0x82

OakBoot v1 - N,BP,4

Initializing SD card...OK!

Loading image 'purple.bmp'
File size: 230456
Image Offset: 54
Header size: 40
Bit Depth: 24
Image size: 240x320
Loaded in 1713 ms

Loading image 'purple.bmp'
File size: 230456
Image Offset: 54
Header size: 40
Bit Depth: 24
Image size: 240x320

Soft WDT reset

ctx: cont
sp: 3fff29e0 end: 3fff2cb0 offset: 01b0

>>>stack>>>
3fff2b90:  000000f0 3fff1848 3fff18a4 402092d7 
3fff2ba0:  04c4b400 00000001 0000012e 4020a650 
3fff2bb0:  3f010000 ef000000 3fff1c38 40208fde 
3fff2bc0:  000000f0 0000003c 00000078 0000003b 
3fff2bd0:  000000f0 00000027 00000085 40207e59 
3fff2be0:  e99760f6 34cb914b 7d3bca7b c97d36c7 
3fff2bf0:  5ef57b34 af8efc8f ffceb9ff 74ffa27a 
3fff2c00:  af92ffa0 f8af94fe a1fdac86 ba97ffc0 
3fff2c10:  fab185fe 57fa9957 a56afe9b 3ffe85f8 
3fff2c20:  00000000 000003e8 1f001f00 70727570 
3fff2c30:  622e656c 0000706d 00000200 3fff5800 
3fff2c40:  0001c7d6 000000a2 0001b9c6 000002d0 
3fff2c50:  00000140 00000001 00001ce1 00000140 
3fff2c60:  00000001 00000003 3fff1c38 3fff1c7c 
3fff2c70:  3fffdc20 00000000 3fff1c75 3fff1c7c 
3fff2c80:  3fffdc20 00000000 3fff1c75 4020802c 
3fff2c90:  00000000 00000000 3fff1c75 4020b9a2 
3fff2ca0:  00000000 00000000 3fff1c90 40100114 
<<<stack<<<

 ets Jan  8 2013,rst cause:2, boot mode:(3,0)

load 0x40100000, len 3632, room 16
tail 0
chksum 0xc0
load 0x3ffe8000, len 352, room 8
tail 8
chksum 0x82
csum 0x82

OakBoot v1 - W,BU,0

Fatal exception (0):
epc1=0x40225980, epc2=0x00000000, epc3=0x00000000, excvaddr=0x00000000, depc=0x00000000
Fatal exception (0):
epc1=0x40225980, epc2=0x00000000, epc3=0x00000000, excvaddr=0x00000000, depc=0x00000000
Fatal exception (0):
epc1=0x40225980, epc2=0x00000000, epc3=0x00000000, excvaddr=0x00000000, depc=0x00000000
... ad nauseam ...

It appears that the Watch Dog TImer has not been satisfied by the long loading of two images.  And then there is no recovery after the reboot.

Fortunately the Pin 1 Safe Mode recovers as expected to the triple blink, ready for download state.

Adding the following line to the bmpDraw function, the example does not have the fatal exception problem.

Code: [Select]
            tft.pushColor(tft.color565(r,g,b));
          } // end pixel
          yield();  // in case this is a large file to process
        } // end scanline

As always all comments, corrections, suggestions, improvements are welcomed.
Carl

postuma

  • Jr. Member
  • **
  • Posts: 64
Re: Oak TFT / SD example fatal exception with fix
« Reply #1 on: April 01, 2016, 06:21:34 pm »
Useful! Thank you.

One question: you mention the example at digistump\hardware\oak\0.9.5\libraries\Adafruit_ILI9341\examples\spitftbitmap\spitftbitmap.ino. Where did you find these? They're certainly not part of my Arduino IDE install ...

cpetito

  • Newbie
  • *
  • Posts: 22
Re: Oak TFT / SD example fatal exception with fix
« Reply #2 on: April 01, 2016, 06:33:14 pm »
It's part of the OAK package library, which is located on my Windows machine here:

C:\Users\cpetito\AppData\Local\Arduino15\packages\digistump\hardware\oak\1.0.0\libraries\Adafruit_ILI9341\examples\spitftbitmap

exeng

  • Sr. Member
  • ****
  • Posts: 454
Re: Oak TFT / SD example fatal exception with fix
« Reply #3 on: April 03, 2016, 09:26:55 pm »
@cpetito, First, Thank you for posting this. Without it I would have been struggling to get the TFT LCD shield to work.

Now a question... why did you use pin 2 for SD_CS? I think I may have a suspicion as to why but wondered why you didn't use pin 4 or pin 10 as pin 4 is the default for the shield and pin 10 the alternate.

So here is my guess, pin 4 conflicts with serial output which this Adafruit example makes use of (more on that later). I couldn't get pin 4 to work and so I tried pin 2 for SD_CS and bingo worked like a charm. So then I speculated the that serial output was the conflict and removed all the serial.Print code. Still didn't work. So I tried pin 10. Still didn't work. So being the exeng bulldog that I am, I set off to debug the example. Now here is where I would have a serious discussion with whomever wrote the original example (I know it wasn't you)... It seems that there are file reads imbedded in the serial.Print lines of code that if removed cause the file reads to be out of sequence. Very bad practice IMHO.
I'm done for the evening but from what I'm seeing debug wise, the serial.Print()s can't simply be removed as the code is currently written.
I verified this by using pin 10 and restoring the serial.Print()s that have imbedded file reads in them. The example worked.

Here are the offending examples...
Code: [Select]
Serial.print(F("File size: ")); Serial.println(read32(bmpFile));
Serial.print(F("Header size: ")); Serial.println(read32(bmpFile));

Tomorrow, I will rewrite these sections and try using pin 4 (default) for SD_CS. I will report my results.

cpetito

  • Newbie
  • *
  • Posts: 22
Re: Oak TFT / SD example fatal exception with fix
« Reply #4 on: April 04, 2016, 08:48:06 am »
@exeng As to why I used Pin 2 for SD_CS, I wish I could reference a brilliant analysis on my part, but the reality is, I don't remember.

And now a question to you, what shield are you using?  The  Oak TFT shield requires the addition of wiring to use the SD card so the SD_CS is pretty much open to any available pin.  I did not feel compelled to use either 4 or 10. 

You are correct about not using pin 4 (or 3) because I do use the serial port for debugging and flashing purposes.

In reviewing the OAK pin-outs, Pin 5 would seem a better choice since Pin 2 is the I2C SCL pin and the free other pins (1, 10, A0) also have possible future special attributes.   

Now I will forever wander the Earth wondering why Pin 2... 

Good luck with your project!

exeng

  • Sr. Member
  • ****
  • Posts: 454
Re: Oak TFT / SD example fatal exception with fix
« Reply #5 on: April 04, 2016, 09:20:42 am »
@cpetito, I'm using the Oak TFT Color LCD Shield http://digistump.com/products/161. When assembling it, I did not solder the TFT board to the shield. Instead I soldered male headers on both the TFT 9 pin section and on the 4 pin SD card section. On the TFT board I solder a 4 pin male header on the SD card pins. I use jumper wires to make the connections. In addition, I have one Oak that I use for development and debug that has through headers on the 9 pin sections so that I can insert it into a breadboard and still have access to the female headers and additional breadboard holes. With this combo and jumper wires connecting the TFT board I can get to pretty much any pin I need to.
 

exeng

  • Sr. Member
  • ****
  • Posts: 454
Re: Oak TFT / SD example fatal exception with fix
« Reply #6 on: April 04, 2016, 02:40:31 pm »
Well now I'm totally confused... What was failing last night is now working. That is, I can get the Adafruit ILI9341 spitftbitmap example to work with cpetito's yield() addition and use pin 4 for SD_CS with the original serial prints still in the code. You won't get any of the serial.Print output but the example works.

So, if using the Oak TFT shield pin 4 default for SD_CS, it's probably best to remove or make conditional all the serial output since pin 4 is TX and modify the serial.Print()s that have embedded file reads so that the reads are done outside the serial.Print to preserve the file read sequence if the serial output is removed. Just seems like good practice.

If you want serial output, then you can do the cut and jump on the shield to move SD_CS to pin 10. Any other pin for SD_CS will require direct wiring.

So here are the additions / changes I will make to my version...
Code: [Select]
add...
  uint32_t bmpFileSize;           // Added to original example in bmpDraw()
  uint32_t bmpHeaderSize;         // Added to original example in bmpDraw()

replace...
  Serial.print(F("File size: ")); Serial.println(read32(bmpFile));
with...
   bmpFileSize = read32(bmpFile);
   Serial.print(F("File size: ")); Serial.println(bmpFileSize, DEC);

replace...
   Serial.print(F("Header size: ")); Serial.println(read32(bmpFile));
with...
   bmpHeaderSize = read32(bmpFile);
   Serial.print(F("Header size: ")); Serial.println(bmpHeaderSize, DEC);

defragster

  • Sr. Member
  • ****
  • Posts: 467
Re: Oak TFT / SD example fatal exception with fix
« Reply #7 on: April 12, 2016, 04:23:37 pm »
I keep seeing cool Connectivity methods in various threads.  Starting one thread to track them might work but could get polluted quickly - it could become a WIKI section.  It occurred to me putting a unique string once per Thread where stuff works could at least allow a forum Search to work.
TFT_ILI9341::OAK_CONNECT