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

Thread: Bugs in custom audio library objects make Teensy unflashable

  1. #1
    Junior Member
    Join Date
    Oct 2020
    Location
    Melbourne, Australia
    Posts
    12

    Bugs in custom audio library objects make Teensy unflashable

    I've been working on some new effect objects using the Teensy Audio Library and have run into an annoying problem. Sometimes, if I've made a mistake in my code somewhere, it causes the Teensy to become completely unflashable.

    Here's a firmware to illustrate my point:

    Code:
    #include <Audio.h> // Teensy audio library
    #include "AudioStream.h"
    const bool DEBUG = true; // Debugging over serial
    
    class AudioEffectCrashTeensy : public AudioStream
    {
    public:
      AudioEffectCrashTeensy() : AudioStream(0, NULL) {}
      
      virtual void update(void) {
          audio_block_t *block;
    
          block = receiveReadOnly();
          if (!block) return;
    
          transmit(block);
          release(block);
        }
    private:
      audio_block_t *inputQueueArray[1];
    };
    
    // Initialise audio objects
    AudioSynthWaveform  waveform1;
    AudioEffectCrashTeensy effect1;
    AudioOutputI2S  i2s1;
    AudioConnection patchCord4(waveform1, effect1);
    AudioConnection patchCord2(effect1, 0, i2s1, 0);
    AudioConnection patchCord3(effect1, 0, i2s1, 1);
    
    void setup() {
      if (DEBUG){
        Serial.begin(9600);
        while (!Serial);
        Serial.println("Debug enabled. If overwriting bad firmware, do it now.\n10 seconds until main loop begins...");
        delay(1000);
        for (int i=9; i>0; i--){
          Serial.println(i);
          delay(1000);
        }
        Serial.println("Audio on.");
      }
    
      AudioMemory(10);
      waveform1.frequency(440);
      waveform1.amplitude(1.0);
      waveform1.begin(WAVEFORM_TRIANGLE);
    }
    
    void loop() {
      AudioNoInterrupts();
      AudioInterrupts();
    }
    This contains a mistake: the constructor should be
    Code:
    AudioStream(1, inputQueueArray)
    The result is if this code is allowed to enter the main loop() function, it completely freezes up the Teensy to the point where it no longer accepts commands over serial and cannot be flashed. The only way to fix it is to do a factory reset by holding down the button for 15 seconds. This is an un-workable solution for me as my teensies are hidden inside a case with a fair bit of disassembly required to get to the button.

    Merely trying not to make any mistakes in my code is also not a workable solution. Mistakes are a normal part of development! What I really need is a way to be able to test my code without fear of accidentally placing the Teensy in an unflashable state.

    As a work-around, I've placed a 10 second delay in the setup() function, which gives me time to flash the Teensy after resetting power in the case that I make a mistake in my audio library development. However, that's not ideal either.

    Any suggestions? Is this a bug in the audio core? Could it be made more resilient?

    The other thing I'm wondering is what affect (if any) AudioNoInterrupts() vs AudioInterrupts() would have on this problem.

  2. #2
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    15,264
    Teensy in use not indicated? Assuming a 4.x but 3.5 and 3.6 also have the factory Restore

    It should come back to programmable with just a Button press {perhaps a power Off/On} - not needing Restore ... unless it is somehow trashing something deep that the restore fixes.

    Yes, that still requires the button ... If this is just a development issue just wire out the Program Pin to a button.

    Though it could somehow be using the OFF function which is stored until given a hardware ON Signal, or all power fades - including vBat if connected?

    Ideally it is Faulting with a NULL pointer reference or something ... and if the fault was trapped generally it can stop there in a loop and USB can still function to allow Auto programming.

    CORES has code that can lead to showing something - but that is diff between 4.x and 3.x ...

  3. #3
    Junior Member
    Join Date
    Oct 2020
    Location
    Melbourne, Australia
    Posts
    12
    Quote Originally Posted by defragster View Post
    Teensy in use not indicated?
    It's a 4.1 :-)

    Quote Originally Posted by defragster View Post
    It should come back to programmable with just a Button press {perhaps a power Off/On} - not needing Restore ... unless it is somehow trashing something deep that the restore fixes.
    Yes, that still requires the button ...
    Bang on! The button is completely inaccessible for my application, and the device also needs to be user programmable. So either way, I need a reliable way to prevent the USB from locking up.

    Quote Originally Posted by defragster View Post
    or all power fades - including vBat if connected?
    Resetting power doesn't help unfortunately.

    Quote Originally Posted by defragster View Post
    Ideally it is Faulting with a NULL pointer reference or something ... and if the fault was trapped generally it can stop there in a loop and USB can still function to allow Auto programming.
    This sounds like it might be helpful... could you explain further?

    Thanks.
    J

  4. #4
    Senior Member manicksan's Avatar
    Join Date
    Jun 2020
    Location
    Sweden
    Posts
    316
    Do you know that the prog is accessible on the middle pins
    then you can connect a external button for the programming.

    the button should be connected between prog and gnd.

    https://www.pjrc.com/store/teensy41.html
    and
    https://www.pjrc.com/teensy/schematic.html

  5. #5
    Senior Member
    Join Date
    May 2015
    Location
    USA
    Posts
    1,084
    > a 10 second delay in the setup() function, which gives me time to flash the Teensy ... not ideal

    Maybe you could write some code that only does this delay if the previous run of the program was unsuccessful. For example (pseudo code):

    Code:
    setup() {
       if (eeprom_delay == 1) 
          delay(10000)   or more
    
       eeprom_delay = 1;
    }
    
    loop() {
       if (eeprom_delay == 1 && program running properly for > 10 seconds) 
          eeprom_delay = 0
    }

  6. #6
    Senior Member Blackaddr's Avatar
    Join Date
    Mar 2017
    Location
    Canada
    Posts
    328
    As someone else mentioned, the program button is also available on header pins on the T4.1. I would highly recommend bringing this signal out to an enclosure mounted button. A small tactile switch like the kind use to reset your router with a paperclip is common on devices that should not be opened.

    However, you can also help mitigate the problem by using the watchdog. Look for WDT_T4 library. If something crashes, at least the board will auto-reboot. If whatever is causing the crash happens immediately after reboot, you are back to having to press the enclosure mounted button.

    I would not recommend putting yourself in a situation where a crash results in having to open the enclosure because you didn't bring out the program button.

  7. #7
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    25,214
    The latest betas have a fault handler which tries to keep USB responsive after a memory fault and automatically reboots after 8 seconds.

    If anyone following this thread wants to give it a try, here's is the most recent.

    https://forum.pjrc.com/threads/67612...o-1-54-Beta-12

    No software can cover 100% of all cases where things go wrong (the reason a physical button exists on every Teensy), but hopefully this new software improves many of them.

  8. #8
    Junior Member
    Join Date
    Oct 2020
    Location
    Melbourne, Australia
    Posts
    12
    This is great Paul, thank you!
    And in response to Blackaddr, you are definitely right. Having user access to the program button is a very good idea.

Posting Permissions

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