Re-enable bootloader interrupts after a hard fault [Teensy 4.1]

Shutdown seems right.

Only comments:
> IDE SerMon sometimes fails to connect on Teensy restart
> TyCommander dumps the device display after some short number of minutes when the device goes 'missing'

So restarting right away and displaying the text and having the Crash cleared may leave an unattended device with no record of the event if SerMon fails to connect or isn't discovered before the missing goes away.

Again no perfect answer? If the device is unpowered/restarted the Crash info is lost ... if the user returned puzzled and does some restart process involving power down/up.

Also if device restarted and no Serial.print(CrashReport); is issued - how does the Teensy know to print and shutdown and not just restart running back into the same issue? ... see last lines of post #87 ...

In terms of the panic temp I just put a PR (https://github.com/PaulStoffregen/cores/pull/573) for the changes.

Think that may be why you may want to print it to a SDCard of other device as @KurtE mentioned.

Here is what it looks like now:
Code:
D:\Users\Merli\Documents\Arduino\CrashRepot_example\CrashRepot_example.ino Jun 22 2021 22:03:24
 millis() now 710
CrashReport ... Hello World
  Fault occurred at: 22:04:26
  Temperature at time of fault: 55.7 degC
  length: 11
  IPSR: 50
  MMFAR: 0
  BFAR: 0
  return address: 2A0
  XPSR: 61010000
  crc: 76D08747
Reboot was caused by temperature sensor
Panic Temp Exceeded Shutting Down
Can be caused by Overclocking w/o Heatsink or other unknown reason
 
post #101 - new page a refresh hides ... was on github ...

Indeed on entry to setup the user can stream the data anywhere as I, then Paul, noted on prior page.

As long as the user knows they have a valid stream before sending they'll see the one shot of info easily with Serial.print(CrashReport);


Only other cool thing on startup.c restart would be pushing 'crash struct' to EEPROM when the system is stable to make it survive power outage.
 
I have tried this out.
It is irritating that the reboot happens after 8 seconds after the crash. Is this planned and if so for what reason?
I had understood that the message is shown 8 seconds. I must have misunderstood that. Instead, the user has to program that.

Somehow I find this the wrong way.
The tool is only used when there is an error.
It should be enough to add the include (even that shouldn't be needed...) Why do you have to program more (which can cause additional error sources) - output of the error, wait loops, etc.?
As a user who has never done this before, you have to get used to it. And as usual, this leads to a long search in the forum, because there is no documentation. Isn't that a bit suboptimal?

It's very unusual. An error report should work without having to progtam additional code and having to read a documentation. It simply should be there. Always. Without any additional line.
Alll other systems do it this way. At least the ones I know about.
 
Can't you simply add a switch " CrashReport on/off" to the Arduino-Menü? It should use a default which prints to USB Serial. In a way that a user don't has to modify the program.
And it should be enabled by default.
 
Last edited:
What happens if the crash happens before setup()?
This can happen with classes. Or if you programm things for the audio library. If the init of audio crashes, it will be before setup(). How do you print the crashreport, then?
Is there a way?
 
Does not work:

Code:
#include "crashreport.h"

class crashme {public:crashme(){*(uint32_t *)0 = 0;}};
crashme foo;

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWriteFast(LED_BUILTIN, HIGH);
  delay(1000);
  Serial.print(CrashReport);
}

void loop() {}

Now, imagine "crashme" is hidden deep in a library.

Edit:
A useful crashreport should be printed in this case, too:
Code:
class crashme {public:crashme(){*(uint32_t *)0 = 0;}};
crashme foo;
void setup() {}
void loop() {}
 
Last edited:
Are these 'warnings' from local CORES copy - or as others see it?
Code:
T:\arduino-1.8.15\hardware\teensy\avr\cores\teensy4\CrashReport.cpp: In member function 'virtual size_t CrashReportClass::printTo(Print&) const':
T:\arduino-1.8.15\hardware\teensy\avr\cores\teensy4\CrashReport.cpp:173:9: warning: passing 'const CrashReportClass' as 'this' argument discards qualifiers [-fpermissive]
   clear();
         ^
In file included from T:\arduino-1.8.15\hardware\teensy\avr\cores\teensy4/WProgram.h:68:0,
                 from t:\temp\arduino_build_CrashReport.ino\pch\Arduino.h:6:
T:\arduino-1.8.15\hardware\teensy\avr\cores\teensy4/CrashReport.h:9:7: note:   in call to 'void CrashReportClass::clear()'
  void clear();
       ^


I agree on the 8 secs delay before restart - as noted ... not sure what it accomplishes - except to allow time to flush last debug print that may point to the error ... 1 second? It may allow Temp to drop if that was the fault - but record and shutdown seems safer?

What happens if the crash happens before setup()?
This can happen with classes. Or if you programm things for the audio library. If the init of audio crashes, it will be before setup(). How do you print the crashreport, then?
Is there a way?

If the crash happens before setup - it will be logged - just have to keep Teensy powered and upload and run a bare bones Serial : BlinkWithCrashReport.
> yeah that's not trivial or obvious - but as long as unit stays powered the first sketch to get to setup and run CrashReport will show error.

Edit to setup isn't that hard and allows directed output to SD, FLASH, Serial?#, a Display unit (?) - menu item wouldn't afford that - and gets tricky assuming Serial? Would take a Startup.c call out to a preSetup() func that is hardcoded to print Serial?

It definitely needs a good example or two to show 'stream setup/test to work) to see and cut/paste from. : SD card, timeout, Press any key ....


It is good and stable as it works - and should help for most of the times it actually Crashes
 
I hope a connected flamethrower or 100KW electrc motor on your motorcycle will be switched off during these 8 seconds..

Editing setup does not work as I showed in the example above. It just does not work. Teensy crashes before setup. There is nothing you can do.


Edit:
If no print is possible, it should at least reset ASAP to avoid dangerous situations.
Edit2:
If an immediate reset is not possible, it might even be better to dispense with the crashreport altogether. Simply to give the responsibility back to the user.
 
Last edited:
I hope a connected flamethrower or 100KW electrc motor on your motorcycle will be switched off during these 8 seconds..

Editing setup does not work as I showed in the example above. It just does not work. Teensy crashes before setup. There is nothing you can do.


Edit:
If no print is possible, it should at least reset ASAP to avoid dangerous situations.
Edit2:
If an immediate reset is not possible, it might even be better to dispense with the crashreport altogether. Simply to give the responsibility back to the user.

@defragster - @Frank B

Going to focus on only the Panic Temperature for now, whether to reboot or shutdown. For the crashreport I opted to shutdown on panic as we have it now since it seemed the most logical thing otherwise you are going to keep getting into a reboot loop of various lengths depending on how fast the temp rises again on reboot.

But lets be honest in a critical application, or a real world application, I wouldn't be relying on the Panic temp tripping!!!! I would be either writing my own temperature monitoring function or looking at the High Temp flag being tripped to start taking action (or even lowering the high temp setting) like shutting down that flame thrower or shutting down that 100Kw electric motor or maybe for the motorcycle case give a 10 second warning of shutting down or throttling back the clock. That's just my 2 cents on the shutting down after a panic alarm is hit. Tim - I hope this answers your questions you posed in the PR comments as well.
 
defragster said:
Are these 'warnings' from local CORES copy - or as others see it?
Code:
T:\arduino-1.8.15\hardware\teensy\avr\cores\teensy4\CrashReport.cpp: In member function 'virtual size_t CrashReportClass::printTo(Print&) const':
T:\arduino-1.8.15\hardware\teensy\avr\cores\teensy4\CrashReport.cpp:173:9: warning: passing 'const CrashReportClass' as 'this' argument discards qualifiers [-fpermissive]
clear();
^
In file included from T:\arduino-1.8.15\hardware\teensy\avr\cores\teensy4/WProgram.h:68:0,
from t:\temp\arduino_build_CrashReport.ino\pch\Arduino.h:6:
T:\arduino-1.8.15\hardware\teensy\avr\cores\teensy4/CrashReport.h:9:7: note: in call to 'void CrashReportClass::clear()'
void clear();
^
Yes I am seeing the same warnings.
 
@defragster
Just updated your test sketch to add in the /t and also outputting to an SD Card if using the builtin sd card on a T4.1 as a test - yes it does work.
Code:
// Found a couple of Faults to force here :: https://interrupt.memfault.com/blog/cortex-m-fault-debug
int illegal_instruction_execution(void) {
  int (*bad_instruction)(void) = (void *)0xE0000000;
  return bad_instruction();
}

#include <SD.h>
#include <SPI.h>

void setup() {
  pinMode( LED_BUILTIN, OUTPUT );
  digitalWrite( LED_BUILTIN, 1 );
  Serial.begin(115200);
  while (!Serial && millis() < 4000 );
  Serial.println("\n" __FILE__ " " __DATE__ " " __TIME__);
  Serial.printf(" millis() now %u\n", millis() );
  if ( CrashReport ) {
    if (SD.begin(BUILTIN_SDCARD)) {
      File dataFile = SD.open("crashlog.txt", FILE_WRITE); // FILE_WRITE append if file already exists
      if (dataFile) {
        dataFile.print(CrashReport);
        dataFile.close();
      }
    } else {
      Serial.print(CrashReport);
    }
    Serial.print("\n\tRECOVERED from Crash !");
  }

  delay ( 100 );
  digitalWrite( LED_BUILTIN, 0 );
  delay ( 1000 );
  digitalWrite( LED_BUILTIN, 1 );
}

void loop() {
  if ( Serial.available()) {
    char cc = Serial.read();
    digitalWrite( LED_BUILTIN, 0 );
    Serial.println("\nIt's your fault!\n");
    delay ( 50 );
    if ( cc == '0' ) {
      illegal_instruction_execution();
    }
    else if ( cc == '1' ) { // Bad Address Read
      uint32_t ff = *(volatile uint32_t *)0xbadcafe;
      Serial.print(ff);
    }
    else if ( cc == '2' ) { // Coprocessor Fault - turn off FPU
      __asm volatile(
        "ldr r0, =0xE000ED88 \n"
        "mov r1, #0 \n"
        "str r1, [r0] \n"
        "dsb \n"
        "vmov r0, s0 \n"
      );
    }
    else if ( cc == '3' ) { // bad_addr_double_word_write
      volatile uint64_t *buf = (volatile uint64_t *)0x30000000;
      *buf = 0x1122334455667788;
    }
    else if ( cc == '4' ) { // Divide by Zero (not enabled?)
      cc = cc - '4';
      cc /= cc;
    }
    else if ( cc == '5' ) { // Fault using device not enabled : UART
      LPUART3_CTRL = 0; // did not enable the clock for this
    }
    else if ( cc == '6' ) {
    }
    else if ( cc == 't' ) {
      Serial.printf( "\tdeg  C=%f\t F_CPU=%u\n" , tempmonGetTemp(), F_CPU_ACTUAL );
      while ( Serial.available()) Serial.read();
    }
    else { // default fault on Serial with no other fault ... from 'Enter'
      uint32_t *y = 0; y[0] = 5;
    }
  }
  delay ( 3 );
  digitalWrite( LED_BUILTIN, 0 );
  delay ( 40 );
  digitalWrite( LED_BUILTIN, 1 );
}
 
Last edited by a moderator:
Morning All: Looks like everyone has been busy! Sorry I have been distracted.

I synced up Core... I now have Mikes Example here... And thought I would fill in a test '5'

With accessing a hardware register without enable the addresses. That is I added:
Code:
      LPUART3_CTRL = 0; // did not enable the clock for this
I did get a fault, actually I think I got 3 faults:
That is I entered a 5...
But the text input includes CR and LF, which then fault again with access of 0...

Will try again, This time with no line ending... So shows NULL ptr error will play some more
 
@mjs513 - good point about self handling of Pre-Panic to prevent CrashFault behavior on Temp issues

Morning All: Looks like everyone has been busy! Sorry I have been distracted.

I synced up Core... I now have Mikes Example here... And thought I would fill in a test '5'

With accessing a hardware register without enable the addresses. That is I added:
Code:
      LPUART3_CTRL = 0; // did not enable the clock for this
I did get a fault, actually I think I got 3 faults:
That is I entered a 5...
But the text input includes CR and LF, which then fault again with access of 0...

Will try again, This time with no line ending... So shows NULL ptr error will play some more

Thanks for the '5'==UART Fault KurtE - I had that here somewhere but didn't look at the right spot.

If it shows "It's your fault!" more than once before restating - it is not Faulting on any preceding entries.

Only the captured 'chars' will stop it from the else case - and that will always fault when it gets there.
 
I have good news and bad news: Here is an updated version of the Mike's sketch:
Code:
// Found a couple of Faults to force here :: https://interrupt.memfault.com/blog/cortex-m-fault-debug
int illegal_instruction_execution(void) {
  int (*bad_instruction)(void) = (void *)0xE0000000;
  return bad_instruction();
}

#include <SD.h>
#include <SPI.h>

void setup() {
  pinMode( LED_BUILTIN, OUTPUT );
  digitalWrite( LED_BUILTIN, 1 );
  Serial.begin(115200);
  while (!Serial && millis() < 4000 );
  Serial.println("\n" __FILE__ " " __DATE__ " " __TIME__);
  Serial.printf(" millis() now %u\n", millis() );
  if ( CrashReport ) {
    if (SD.begin(BUILTIN_SDCARD)) {
      File dataFile = SD.open("crashlog.txt", FILE_WRITE); // FILE_WRITE append if file already exists
      if (dataFile) {
        dataFile.print(CrashReport);
        dataFile.close();
      }
    } else {
      Serial.print(CrashReport);
    }
    Serial.print("\n\tRECOVERED from Crash !");
  }

  delay ( 100 );
  digitalWrite( LED_BUILTIN, 0 );
  delay ( 1000 );
  digitalWrite( LED_BUILTIN, 1 );
}

void loop() {
  if ( Serial.available()) {
    char cc = Serial.read();
    digitalWrite( LED_BUILTIN, 0 );
    Serial.println("\nIt's your fault!\n");
    delay ( 50 );
    if ( cc == '0' ) {
      illegal_instruction_execution();
    }
    else if ( cc == '1' ) { // Bad Address Read
      uint32_t ff = *(volatile uint32_t *)0xbadcafe;
      Serial.print(ff);
    }
    else if ( cc == '2' ) { // Coprocessor Fault - turn off FPU
      __asm volatile(
        "ldr r0, =0xE000ED88 \n"
        "mov r1, #0 \n"
        "str r1, [r0] \n"
        "dsb \n"
        "vmov r0, s0 \n"
      );
    }
    else if ( cc == '3' ) { // bad_addr_double_word_write
      volatile uint64_t *buf = (volatile uint64_t *)0x30000000;
      *buf = 0x1122334455667788;
    }
    else if ( cc == '4' ) { // Divide by Zero (not enabled?)
      cc = cc - '4';
      cc /= cc;
    }
    else if ( cc == '5' ) {
      Serial.println("Try FlexIO"); Serial.flush();
      // CCM_CCGR5 |= CCM_CCGR5_FLEXIO1(CCM_CCGR_ON);
      IMXRT_FLEXIO_t *p = &IMXRT_FLEXIO1_S;
      Serial.printf("%x\n", (uint32_t)p); Serial.flush();
      Serial.printf("VERID:%x PARAM:%x CTRL:%x PIN: %x\n", p->VERID, p->PARAM, p->CTRL, p->PIN); Serial.flush();
      Serial.printf("SHIFTSTAT:%x SHIFTERR=%x TIMSTAT=%x\n", p->SHIFTSTAT, p->SHIFTERR, p->TIMSTAT); Serial.flush();
      Serial.printf("SHIFTSIEN:%x SHIFTEIEN=%x TIMIEN=%x\n", p->SHIFTSIEN, p->SHIFTEIEN, p->TIMIEN); Serial.flush();
      Serial.printf("SHIFTSDEN:%x SHIFTSTATE=%x\n", p->SHIFTSDEN, p->SHIFTSTATE); Serial.flush();
      Serial.printf("SHIFTCTL:%x %x %x %x\n", p->SHIFTCTL[0], p->SHIFTCTL[1], p->SHIFTCTL[2], p->SHIFTCTL[3]); Serial.flush();
      Serial.printf("SHIFTCFG:%x %x %x %x\n", p->SHIFTCFG[0], p->SHIFTCFG[1], p->SHIFTCFG[2], p->SHIFTCFG[3]); Serial.flush();
      Serial.printf("TIMCTL:%x %x %x %x\n", p->TIMCTL[0], p->TIMCTL[1], p->TIMCTL[2], p->TIMCTL[3]); Serial.flush();
      Serial.printf("TIMCFG:%x %x %x %x\n", p->TIMCFG[0], p->TIMCFG[1], p->TIMCFG[2], p->TIMCFG[3]); Serial.flush();
      Serial.printf("TIMCMP:%x %x %x %x\n", p->TIMCMP[0], p->TIMCMP[1], p->TIMCMP[2], p->TIMCMP[3]); Serial.flush();
      Serial.println("made it through");
    }
    else if ( cc == '6' ) {
    }
    else if ( cc == 't' ) {
      Serial.printf( "\tdeg  C=%f\t F_CPU=%u\n" , tempmonGetTemp(), F_CPU_ACTUAL );
      while ( Serial.available()) Serial.read();
    }
    else { // default fault on Serial with no other fault ... from 'Enter'
      uint32_t *y = 0; y[0] = 5;
    }
  }
  delay ( 3 );
  digitalWrite( LED_BUILTIN, 0 );
  delay ( 40 );
  digitalWrite( LED_BUILTIN, 1 );
}
So I try to print out the FlexIO1 registers. If I uncomment the CcM_ line it runs without faulting...

The good news is with it commented out, it faults... The bad news is it stays faulted!
Code:
C:\Users\kurte\Documents\Arduino\Teensy Tests\Test_CrashReport\Test_CrashReport.ino Jun 23 2021 09:08:20
 millis() now 496

It's your fault!

Try FlexIO
401ac000
 
@Kurt - I pasted your UART fault into p#111 code of Mike and uploaded here - it is NOT faulting on that - then it re-loops for next char and faults on the else "uint32_t *y = 0; y[0] = 5;" on the Enter/CR.

Not finding where I sampled that fault before - but somehow it is bypassing the Crash Detect - or not faulting ???
 
@Kurt - I pasted your UART fault into p#111 code of Mike and uploaded here - it is NOT faulting on that - then it re-loops for next char and faults on the else "uint32_t *y = 0; y[0] = 5;" on the Enter/CR.

Not finding where I sampled that fault before - but somehow it is bypassing the Crash Detect - or not faulting ???

Yep the 112 post did not fault... it was faulting on next characters... But the 114 is hard faulting and not recovering.
 
Yep the 112 post did not fault... it was faulting on next characters... But the 114 is hard faulting and not recovering.

p#112 should fault though ?

Indeed #114 just goes away as shown. Fault not trapped. Or trapped but cascading with USB output? Maybe enable the LED on on fault detect ?

I have to get back to my lingering task ...
 
Yep - what is unclear so far is what interrupt does access to registers whose CCM_CC... is disabled?

Maybe one of the first 16? My guess they are the same as in the ARM M3/M4 book...
(Reset, NMI, Hard Fault, Mem Manage, Bus, Usage, SVC, Debug Monitor, PendSV, SIStICK) with holes....

Not sure which one (if any)...
So far found we set
_VectorsRam[15] = systick_isr;
_VectorsRam[14] = pendablesrvreq_isr;
 
Confirmed I am seeing exactly the same thing and it seems tohang the sketch.

On "if ( Serial.available()) {" the LED goes OFF and a short delay ( 50 );

In void unused_interrupt_vector(void) added :: digitalWrite( LED_BUILTIN, 1 );
> This doesn't light pin #13 ??? turn the pin on ? :: GPIO7_GDIR |= (1 << 3);

And not seeing that - so it is not making it to the _isr() with '5' Flexio Crash
> And the T_4.1 is non USB responsive.
> Not TyComm 'Missing' - but not responsive to upload/reset
 
The "Serial.println("\nIt's your fault!\n");" should be moved to each case as appropriate with a note on the fault triggered ... or not.

i.e. it should not show for 't' and that would make clear the expectation.

First pass quick and dirty didn't do that.

Gotta run ... I have a task I'm avoiding as it sukz ... hours yesterday downloading and updating SQL MGMT and Srv on a new computer for somebody ... finally done but then exhausted when I got the user SQL app downloaded ... have to get it working ...
 
On "if ( Serial.available()) {" the LED goes OFF and a short delay ( 50 );

In void unused_interrupt_vector(void) added :: digitalWrite( LED_BUILTIN, 1 );
> This doesn't light pin #13 ??? turn the pin on ? :: GPIO7_GDIR |= (1 << 3);

And not seeing that - so it is not making it to the _isr() with '5' Flexio Crash
> And the T_4.1 is non USB responsive.
> Not TyComm 'Missing' - but not responsive to upload/reset

Have funny feeling its not getting called or hanging before it gets to execute the ISR? No idea to be honest! Maybe its a fault that doesn't get recognized its a fault?
 
Sounds good, but did verify I believe that all of the interrupts in the low range have the same address beyond it... Except the Systick ones... So assuming this is setup properly.
t's your fault!

Print out top of Vector table
0:6731
1:6731
2:6731
3:6731
4:6731
5:6731
6:6731
7:6731
8:6731
9:6731
10:6731
11:6731
12:6731
13:6731
14:8051
15:8055
16:6731
17:6731
18:6731
19:6731
20:6731
21:6731
22:6731
23:6731
24:6731
25:6731
26:6731
27:6731
28:6731
29:6731
30:6731
31:6731
Try FlexIO
401ac000


SO not sure what this means...

Edit: again I am not sure what happens when you access these registers? Does it generate a fault? If so which one? And does this fault need to be enabled?
 
Last edited:
@KurtE

Out of curiosity I went ahead and incorporated @Frank B 's fault handler code in IDE 1.8.14 with TD 1.54beta8. And tried the same sketch with your flexIO forced error. Guess what.

The exact same thing happened.
Code:
[B]It's your fault!
[/B]
Try FlexIO
401ac000
At this point it just hangs again. So something else funny is going on!!!

EDIT: Seems to be hanging/failing before it hits the fault handler?
 
Wondering about the conglomeration of those commands perhaps hiding where the issue is ...
Looks like this is the culprit?
Code:
        case 2:
          Serial.printf("VERID:%x PARAM:%x CTRL:%x PIN: %x\n", p->VERID, p->PARAM, p->CTRL, p->PIN);
Comment that print and it advance to case 3 for the same end ...

Modified '5' to :
Code:
    else if ( cc == '5' ) { // Fault using device not enabled
      Serial.println("Try FlexIO"); Serial.flush();
      // CCM_CCGR5 |= CCM_CCGR5_FLEXIO1(CCM_CCGR_ON);
      int cnt = 0;
      IMXRT_FLEXIO_t *p = &IMXRT_FLEXIO1_S;
      while ( cnt < 12 ) {
        switch ( cnt ) {
        case 0:
          break;
        case 1:
          Serial.printf("%x\n", (uint32_t)p);
          break;
        case 2:
          Serial.printf("VERID:%x PARAM:%x CTRL:%x PIN: %x\n", p->VERID, p->PARAM, p->CTRL, p->PIN);
          break;
        case 3:
          Serial.printf("SHIFTSTAT:%x SHIFTERR=%x TIMSTAT=%x\n", p->SHIFTSTAT, p->SHIFTERR, p->TIMSTAT);
          break;
        case 4:
          Serial.printf("SHIFTSIEN:%x SHIFTEIEN=%x TIMIEN=%x\n", p->SHIFTSIEN, p->SHIFTEIEN, p->TIMIEN);
          break;
        case 5:
          Serial.printf("SHIFTSDEN:%x SHIFTSTATE=%x\n", p->SHIFTSDEN, p->SHIFTSTATE);
          break;
        case 6:
          Serial.printf("SHIFTCTL:%x %x %x %x\n", p->SHIFTCTL[0], p->SHIFTCTL[1], p->SHIFTCTL[2], p->SHIFTCTL[3]);
          break;
        case 7:
          Serial.printf("SHIFTCFG:%x %x %x %x\n", p->SHIFTCFG[0], p->SHIFTCFG[1], p->SHIFTCFG[2], p->SHIFTCFG[3]);
          break;
        case 8:
          Serial.printf("TIMCTL:%x %x %x %x\n", p->TIMCTL[0], p->TIMCTL[1], p->TIMCTL[2], p->TIMCTL[3]);
          break;
        case 9:
          Serial.printf("TIMCFG:%x %x %x %x\n", p->TIMCFG[0], p->TIMCFG[1], p->TIMCFG[2], p->TIMCFG[3]);
          break;
        case 10:
          Serial.printf("TIMCMP:%x %x %x %x\n", p->TIMCMP[0], p->TIMCMP[1], p->TIMCMP[2], p->TIMCMP[3]);
          break;
        case 11:
          Serial.println("made it through");
          break;
        }
        Serial.println( cnt++ );
        Serial.flush();
        delay(10);
      }
    }

Then on running it just hangs after:
Code:
T:\tCode\FAULT_HANDLER\CrashReport\CrashReport.ino Jun 23 2021 11:10:24
 millis() now 1191

It's your fault!

Try FlexIO
0
401ac000
1
 
Back
Top