main loop freezes, interval timer keeps running

Status
Not open for further replies.

daverlee

Member
currently trying to debug my program on a teensy 4.1. Occasionally the main loop will freeze but my interval timer will continue running, so my guess is something is caught in a wait loop.
I'm also running the audio library, radiohead rf69, and the ST7789 tft library with frame buffer. My guess is it might be either the tft.waitUpdateAsyncComplete() call or possibly something in the radiohead library. My interval timer is reading an IR receiver every 100 microseconds and printing to serial when an incoming IR message is complete.

I don't have a clear question, just fishing for debugging ideas
is there a way to access the program counter? can I reset it to point to loop() if it gets stuck somewhere?
 
Last edited:
Serial printing in the 100us Timer Interrupt will block the loop.
Put your data in a buffer(volatile) and give a flag to loop for printing the buffer.

OpaLothar
 
Print in ISR only for testing if the program comes to this place, only one character with highes baudrate possible.

ISR every 100usec not longer than 10 -20 usec max!

Never delay() in ISR.
 
Indeed - when an _isr() takes too long it effectively never exits before re-entering and loop() never gets cycles.

Without sketch code, there is nothing else running in CORE code that would block loop().

Perhaps put this at the end of the _isr() - it may be doubling? : asm("dsb":::"memory");
 
I think I found a solution. From RadioHead's online documentation:

"The RH_RF69 driver uses interrupts to react to events in the RF69 module, such as the reception of a new packet, or the completion of transmission of a packet. The RH_RF69 driver interrupt service routine reads status from and writes data to the the RF69 module via the SPI interface. It is very important therefore, that if you are using the RH_RF69 driver with another SPI based deviced, that you disable interrupts while you transfer data to and from that other device. Use cli() to disable interrupts and sei() to reenable them."

I thought I was in the clear because my tft was using a different spi bus than my radio, but just to experiment I disabled interrupts around all of my tft spi writes and that seemed to stabilize things.

I also added in the asm call, but so far haven't hit that part of the code yet.

posted-too-soon-edit: it still freezes if I make tft writes too frequently even with noInterrupts/interrupts, but it still seems much more stable
 
Last edited:
what does asm("dsb":::"memory"); do?

A quick search on dsb - like done to find the syntax - might yield more details ... here's a distilled recall from better notes posted elsewhere ...

Makes sure the handled interrupt indication propagates as handled on that slower bus to the higher speed processor bus so the processor doesn't immediately call back because the interrupt hasn't been marked as cleared/handled. Generally it works except on _isr()'s that are super short perhaps.

Worst case is a simple timer interrupt that just counts the event and exits - can end up double counting.
 
Status
Not open for further replies.
Back
Top