running the same sketch on the T4.x with & without an RA8875 display attached

kd5rxt-mark

Well-known member
I am working on my TeensyCANmonitor, which has most recently been discussed <here>. To make using it more convenient (as discussed in that other thread, everything was previously controlled from the serial console, strictly as a command-line menu-driven interface), I have added an RA8875 7" display from buydisplay.com that I have successfully used on other projects. When the display is attached, all is working fine as expected.


Environment:
Code:
//  Arduino IDE Configuration (last built with Arduino 1.8.19 + Teensyduino 1.58b2):
//     Tools/Board:           "Teensy 4.0"
//     Tools/USB Type:        "Serial"
//     Tools/CPU Speed:       "600MHz"
//     Tools/Optimize:        "Faster"
//     Tools/Keyboard Layout: "US English"
//     Tools/Port:            "COMx Serial (Teensy 4.0)"


Technical background: I would like to use the same source sketch & be able to use my TeensyCANmonitor either with or without the display attached (i.e. either using the display for control/status, or using the original serial console only operation). My first attempt (simply don't enable the TFT interrupt and/or don't call tft.begin()) causes a crash report to be generated, which indicates that a bad interrupt was detected.

Code:
=============================================
       Teensy CAN bus monitor utility
     version 2.0 dated 10/08/2022 @2120
designed & written by Mark J Culross (KD5RXT)
=============================================


CrashReport:
  A problem occurred at (system time) 1:12:47
  Code was executing from address 0x13E0C
  CFSR: 82
	(DACCVIOL) Data Access Violation
	(MMARVALID) Accessed Address: 0x13 (nullptr)
	  Check code at 0x13E0C - very likely a bug!
	  Run "addr2line -e mysketch.ino.elf 0x13E0C" for filename & line number.
  Temperature inside the chip was 53.90 °C
  Startup CPU clock speed is 600MHz
  Reboot was caused by auto reboot after fault or bad interrupt detected


Technical question: is it possible to leave all of the RA8875 TFT implementation in place, but somehow not initialize it (to run using only the serial console, with the display not attached) ?? if so, what calls (related to the TFT) should I eliminate and/or change ??

Thanks in advance for any advice and/or suggestions . . .

Mark J Culross
KD5RXT

Libraries included:

Code:
#include <FlexCAN_T4.h>
#include <EEPROM.h>
#include <isotp.h>

isotp<RX_BANKS_16, 512> isotp1; /* 16 slots for multi-ID support, at 512bytes buffer each payload rebuild */
FlexCAN_T4<CAN1, RX_SIZE_256, TX_SIZE_16> Can1;

#include <SPI.h>    // to avoid unnecessary compile errors, this *must* appear in the list of includes *before* RA8875
#include <RA8875.h>

// when used w/ Audio Adapter, must use an alternate CS pin for the display
const int RA8875_CHIP_SELECT     =  38;       // Teensy 38 (A14) -to- RA8875 05
const int RA8875_RESET           =   3;       // Teensy 03 (D03) -to -RA8875 11
const int RA8875_MISO            =  39;       // Teensy 39 (A15) -to- RA8875 06
const int RA8875_MOSI            =  26;       // Teensy 26 (A12) -to- RA8875 07
const int RA8875_SCLK            =  27;       // Teensy 27 (A13) -to- RA8875 08
const int RA8875_TS_INT          =   2;       // Teensy 02 (D02) -to- RA8875 33

const int RA8875_MAX_TOUCH_LIMIT =   1;

RA8875 tft = RA8875(RA8875_CHIP_SELECT, RA8875_RESET, RA8875_MOSI, RA8875_SCLK, RA8875_MISO);

// custom RA8875 TFT colors (5-bit RED, 6-bit GREEN, 5-bit BLUE)
#define RA8875_SHADOWGREY  0x8414      // SHADOWGREY: 0x8414 = 10000 100000 10100       LIGHTGREY: 0xC618 = 11000 110000 11000  
#define RA8875_ORANGE      0xFB00


//#define DEBUG_EEPROM_WRITE              // uncomment to show specifics of EEPROM writes
//#define DEBUG_EEPROM_READ               // uncomment to show specifics of EEPROM reads
//#define DISABLE_EEPROM_READ_SETTINGS    // uncomment to not read settings from EEPROM (to simply use program defaults for all settings)
//#define DISABLE_EEPROM_WRITE_SETTINGS   // uncomment to not write settings to EEPROM
//#define DEBUG_TOUCHSCREEN               // uncomment to print touchscreen coordinates & touch state
//#define FAKE_STATUS_UPDATES             // uncomment to generate fake updates to the status area


//
// The following pins are used in this (Audio) portion of the Teensy 4.x PolySynth project:
//
// PIN D0       = (not used)
// PIN D1       = (not used)
// PIN D2       = RA8875 Touchscreen INT
// PIN D3       = RA8875 Touchscreen RESET
// PIN D4       = (not used)
// PIN D5       = (not used)
// PIN D6       = (not used)
// PIN D7       = (not used)
// PIN D8       = (not used)
// PIN D9       = (not used)
// PIN D10      = (not used)
// PIN D11      = (not used)
// PIN D12      = (not used)
// PIN D13      = (onboard LED)
// PIN D14/A0   = (not used)
// PIN D15/A1   = (not used)
// PIN D16/A2   = (not used)
// PIN D17/A3   = (not used)
// PIN D18/A4   = (not used)
// PIN D19/A5   = (not used)
// PIN D20/A6   = (not used)
// PIN D21/A7   = K-line for 5 baud init (to base of 2N2222A NPN transistor)
// PIN D22/A8   = CAN1 TX (to CTX on SN65HVD230 breakout board)
// PIN D23/A9   = CAN1 RX (to CRX on SN65HVD230 breakout board)
// PIN D24/A10  = (not used)
// PIN D25/A11  = (not used)
// PIN D26/A12  = RA8875 Touchscreen MOSI (MOSI1)
// PIN D27/A13  = RA8875 Touchscreen SCLK (SCK1)
// PIN D28      = (not used)
// PIN D29      = (not used)
// PIN D30      = (not used)
// PIN D31      = (not used)
// PIN D32      = (not used)
// PIN D33      = (not used)
// PIN D34      = (not used)
// PIN D35      = (not used)
// PIN D36      = (not used)
// PIN D37      = (not used)
// PIN D38/A14  = RA8875 Touchscreen CS (CS1)
// PIN D39/A15  = RA8875 Touchscreen MISO (MISO1)
// PIN D40/A16  = (not used)
// PIN D41/A17  = (not used)


setup():

Code:
// one-time setup
void setup(void)
{
   unsigned long check_time;

   check_time = millis();
   while (!Serial && ((millis() - check_time) <= 3000));

   Serial.println("=============================================");
   Serial.print("       ");
   Serial.println(TITLE);
   Serial.print("     ");
   Serial.println(VERSION);
   Serial.println(AUTHOR);
   Serial.println("=============================================");
   Serial.println("");
   Serial.println("");

   if (CrashReport) {
      Serial.print(CrashReport);
   }

   pinMode(RA8875_CHIP_SELECT, OUTPUT);
   digitalWrite(RA8875_CHIP_SELECT, HIGH);

   pinMode(RA8875_RESET, OUTPUT);
   digitalWrite(RA8875_RESET, LOW);

   check_time = millis();
   while ((millis() - check_time) <= 100);

   digitalWrite(RA8875_RESET, HIGH);

   check_time = millis();
   while ((millis() - check_time) <= 2000);

   tft.begin(RA8875_800x480);

   tft.DMA_enable();

   tft.setRotation(2);

   tft.clearScreen();

   tft.brightness(128);

#ifdef USE_RA8875_TOUCH
   tft.useINT(RA8875_TS_INT);   // use generic int helper for Internal Resistive Touch
   tft.touchBegin();   //enable touch support for RA8875
#else
   tft.useCapINT(RA8875_TS_INT);   // use the FT5206 chip interrupt
#endif

   tft.setTouchLimit(RA8875_MAX_TOUCH_LIMIT);

#ifdef USE_RA8875_TOUCH
   tft.enableISR(true);
#else
   tft.enableCapISR(true);   // capacitive touch screen interrupt it's armed
#endif

   tft.writeTo(L1);//write to layer 1
   tft.layerEffect(OR);//apply OR between layer 1 and 2

   check_splash_time = millis();

   draw_screen();

   while ((millis() - check_splash_time) < CHECK_SPLASH_MILLIS)
   {
   }

   config_mode = CONFIG_MODE_INIT_SCREEN;

   draw_screen();

   // try to read the settings from EEPROM for this index
   if (!read_settings())
   {
      // if the setting in EEPROM for this index are invalid, then set to default values & save
      CAN_baudrate_index = CAN_baudrate_size - 1;
      CAN_baudrate_fixed = false;

      save_settings();
   }

   Serial.println("");
   Serial.print("EEPROM USED: ");
   Serial.println(EEPROM_INDEX_VALUE_COUNT);
   Serial.print("EEPROM MAX ALLOWED: ");
   Serial.println(MAX_T4X_EEPROM_SIZE_ALLOWED);
   Serial.println("");

   status_add("EEPROM USED: ");
   status_append(String(EEPROM_INDEX_VALUE_COUNT));
   status_add("EEPROM MAX ALLOWED: ");
   status_append(String(MAX_T4X_EEPROM_SIZE_ALLOWED));

   Can1.begin();
   Can1.setBaudRate(CAN_baudrate_list[CAN_baudrate_index]);
   Can1.setMaxMB(16);
   Can1.enableFIFO();
   Can1.enableFIFOInterrupt();
   Can1.onReceive(can_sniff_RX);
   
   isotp1.begin();
   isotp1.setWriteBus(&Can1); /* we write to this bus */
   isotp1.onReceive(can_sniff_RX_isotp); /* set callback */
   
   report_current_baudrate();

   for (int i = 0; i < 256; i++)
   {
      supported_PIDs_for_service_01[i] = false;
   }

   for (int i = 0; i < 33; i++)
   {
      supported_PIDs_for_service_09[i] = false;
   }

   CAN_baud_change_timer = millis();

   pinMode(KLINE_PIN, OUTPUT);
   digitalWrite(KLINE_PIN, KLINE_HIGH);

   LED_timer = millis();
} // setup()
 
Sorry, I don't know enough of RA8875 to know best way to know how to recover when not there.

I would probably start off with something like: If you have an unused pin, wire it high or low and detect it, to control if you should initialize any of the RA8875 code.

The ftf.begin() returns void, so can not detect with it. Not sure if it will produce an error, So would probably experiment and see tft.errorCode() returns something useful.

After tft.begin(), not sure if calling tft.errorCode() would return anything.

But problems with this would be if SPI pins are floating, not sure if things will return at all, or if so, probably garbage?

I know not much help
 
Sorry, I don't know enough of RA8875 to know best way to know how to recover when not there.

I would probably start off with something like: If you have an unused pin, wire it high or low and detect it, to control if you should initialize any of the RA8875 code.

The ftf.begin() returns void, so can not detect with it. Not sure if it will produce an error, So would probably experiment and see tft.errorCode() returns something useful.

After tft.begin(), not sure if calling tft.errorCode() would return anything.

But problems with this would be if SPI pins are floating, not sure if things will return at all, or if so, probably garbage?

I know not much help

Kurt:

Thanks for the suggestion. On a related note, I've seen the recommendation in other threads for running addr2line & feed it with the location given in the crash report to find the offending line. For my Windows Arduino/TD environment, where would I look to find the addr2line utility ??

Thanks for your help !!

Mark J Culross
KD5RXT
 
It depends.

What are you running? That is IDE1 or 2? Which version of Teensyduino?

For example for IDE2 I have: "C:\Users\kurte\AppData\Local\Arduino15\packages\teensy\tools\teensy-compile\11.3.1-beta1\arm\bin\arm-none-eabi-addr2line.exe"
Under my install for 1.8.19: "C:\arduino-1.8.19\hardware\tools\arm\bin\arm-none-eabi-addr2line.exe"

Note: I am running beta versions, and the addr2line appears to be busted. The older versions don't like the new files, and the newer version does not give the right stuff...

However with the beta builds, we are now building the list file, which is in the directory where the .hex file is, and the listing does show you the right stuff.
 
It depends.

What are you running? That is IDE1 or 2? Which version of Teensyduino?

For example for IDE2 I have: "C:\Users\kurte\AppData\Local\Arduino15\packages\teensy\tools\teensy-compile\11.3.1-beta1\arm\bin\arm-none-eabi-addr2line.exe"
Under my install for 1.8.19: "C:\arduino-1.8.19\hardware\tools\arm\bin\arm-none-eabi-addr2line.exe"

Note: I am running beta versions, and the addr2line appears to be busted. The older versions don't like the new files, and the newer version does not give the right stuff...

However with the beta builds, we are now building the list file, which is in the directory where the .hex file is, and the listing does show you the right stuff.

From my first post:

Environment:

Code:
//  Arduino IDE Configuration (last built with Arduino 1.8.19 + Teensyduino 1.58b2):
//     Tools/Board:           "Teensy 4.0"
//     Tools/USB Type:        "Serial"
//     Tools/CPU Speed:       "600MHz"
//     Tools/Optimize:        "Faster"
//     Tools/Keyboard Layout: "US English"
//     Tools/Port:            "COMx Serial (Teensy 4.0)"

Thanks for the confirmation of the 1.8.19 location when using the original IDE. I had previously tried to run C:\arduino-1.8.19\hardware\tools\arm\bin\arm-none-eabi-addr2line.exe. Unfortunately, it tells me that the "-e" option is not understood . . . this is really what prompted my question of the correct location. So, I'll continue to dig . . .

Thanks again,

Mark J Culross
KD5RXT
 
Your running b2 so look for the list (edit after Spell check) file
 
Last edited:
Kurt:

Thanks !!

And, I ended up using a somewhat brute-force solution to my original question: I created a "#define NO_DISPLAY_ATTACHED" directive & simply surrounded all of the TFT-specific stuff with "ifndef NO_DISPLAY_ATTACHED" / "#endif" . . . ugly, but functional, & it wasn't nearly as challenging as I initially thought it might be !!

Thanks again,

Mark J Culross
KD5RXT
 
Back
Top