Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 9 of 9

Thread: main loop freezes, interval timer keeps running

  1. #1
    Junior Member
    Join Date
    Dec 2020
    Posts
    7

    main loop freezes, interval timer keeps running

    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 by daverlee; 04-17-2021 at 06:04 PM.

  2. #2
    Member
    Join Date
    Oct 2019
    Location
    Germany Maintal
    Posts
    24
    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

  3. #3
    Junior Member
    Join Date
    Dec 2020
    Posts
    7
    good idea. I tried commenting out all the print statements in the timer but it still freezes

  4. #4
    Member
    Join Date
    Oct 2019
    Location
    Germany Maintal
    Posts
    24
    Do you have more longer things in all your ISRs ?

  5. #5
    Member
    Join Date
    Oct 2019
    Location
    Germany Maintal
    Posts
    24
    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.

  6. #6
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    13,923
    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");

  7. #7
    Junior Member
    Join Date
    Dec 2020
    Posts
    7
    what does asm("dsb":::"memory"); do?

  8. #8
    Junior Member
    Join Date
    Dec 2020
    Posts
    7
    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 by daverlee; 04-18-2021 at 10:44 PM.

  9. #9
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    13,923
    Quote Originally Posted by daverlee View Post
    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.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •