Teensy hangs, while changing the baud rate for UARTs.

khtos

Active member
Hello, community!
I was working on a program for Teensy 4.1 and I met a strange behavior of the controller when working with UART. In my program, I need to process data from two UART channels and change the baud rates of these two channels “on the fly” depending on the user's actions. In one moment I noticed that I can change the baud rate in the channels only 6 times, when I try to do this for the seventh time, the Teensy hangs forever. The program stops working, and the USB channel to the terminal also falls off, and the only way to return the teensy to a working state is to reset the power or upload firmware to it by pressing a button on the teensy board.
Further investigation showed, that I can call these strings only 6 times in total before the Teensy hangs
Code:
Serial1.end ();
Serial1.begin (baud);
regardless of which channel they are called for and regardless of whether the baud rate actually changes or remains constant. For example, if I change the baud rate 3 times for Serial1 and then 3 times for Serial2, then the next attempt to change the baud rate for any of the channels leads to the hanging of Teensy 4. I tried this for Teense4.0 and for teensy4.1, their behavior is the same.
Finally, I found that the program only hangs if I declare
Code:
void serialEvent1 (void) {}
and/or
Code:
void serialEvent2 (void){}
even if they are empty!
If there is no declaration serialEventX() in the program I can change the baud rate for UARTs with no limitations.
So, can anybody explain what is it, and what should I do to force the program to work correctly?

Here is a program that demonstrates this behavior:
Code:
// the setup function runs once when you press reset or power the board
uint8_t  Key1 = 0;
uint8_t  OldKey1 = 0;

void setup() {
	Serial.begin(115200);
	while (Serial) { ; }
    	
	Serial2.begin(115200);

	pinMode(0, INPUT_PULLUP);            // hardware button
	pinMode(13, OUTPUT);
}

// the loop function runs over and over again until power down or reset
void loop() {
	static uint8_t Counter = 0;
//--------
	Key1 = digitalReadFast(0);						// read the hardware button and call Serial2.end();  Serial2.begin(115200); on each pressing
	if ((Key1 == 0) && (OldKey1 == 1)) {				// 
		Serial2.end();
		Counter++; 
		Serial.println(Counter);
		Serial2.begin(115200);
	}
	OldKey1 = Key1;
//--------
	delay(10);
	if ((millis() % 320) < 160) { digitalWriteFast(13, 0); }   // blink with led to see if the program works or not
	else                        { digitalWriteFast(13, 1); }
}


void serialEvent2(void)                          // if I comment out this declaration the program starts to work correctly
{
}
 
What version of TeensyDuino is in use? 1.55 or prior?

@KurtE: It may be something in the 'cleanup' done to prevent yield() callout to unneeded 'event' code?
 
1. I use teensyduino 1.53 and Microsoft Visual Studio Professional 2019 Version 16.6.3 with Arduino IDE for Visual Studio by Visual Micro-19.0
2. In the original version of the code, serialEvent was not empty, there was a processing of the received data. The given program is a minimal program that demonstrates the described behavior on my hardware.
 
There was a problem found in baud rate change and fixed IIRC since TD 1.53 - please update to TD 1.55 and test
 
Thanks for the advice! I have updated teensyduino to 1.55 and it looks like the UART is working fine ...
but, unfortunately, the main software stopped working altogether. Now it hangs somewhere when initializing an external FLASH, soldered on the board :( :confused: :mad:
 
I'm not so sure about my bug. This function calls in setup:
Code:
void InitExtFlash(void)
{
    eRAM.begin();
    Serial.println("eram begin done");
    eRAM.fs_mount();
    Serial.println("fs mount done");
  
    memset(FileBuf, 0, sizeof(FileBuf)); //emtpy buffer
    Serial.println("Read file:");
    eRAM.f_readFile("FlashVars", FileBuf, sizeof(FileBuf) / sizeof(char), SPIFFS_RDONLY);
    Serial.println(FileBuf);
}
and this is the text, I saw in the terminal:
Code:
Port open
Status 1:11101111
Status 2:11101111
Status 1:10000
Status 2:10010
Status 1:10000
Status 2:10010
eram begin done
Port open
Status 1:11101111
Status 2:11101111
Status 1:10000
Status 2:10010
Status 1:10000
Status 2:10010
eram begin done
so eRAM.begin(); is executed, but during eRAM.fs_mount(); something goes wrong, teensy hangs and reboot after about 8 seconds.
Maybe something is wrong with libraries? :confused: because on teenstduino 1.53 there was no problem with FLASH, just with UART
 
Your saying flash but your code uses ram? We'll never know with that short extract if code which does not run when we try to confirm that..
 
That 8 seconds delay is something FAULTING the processor.

Add this to setup and watch the Serial Montor:
Code:
  Serial.begin(115200);
  while (!Serial && millis() < 2500 );
  if ( CrashReport) Serial.print( CrashReport);
 
I commented out everything from my program and left just this:

Code:
void setup() { 
    Serial.begin(115200);
    while (!Serial && millis() < 2500);
    if (CrashReport) Serial.print(CrashReport);

    Serial.printf("Delay 0.5 sec.");
    delay(500);
    InitExtFlash();
    Serial.printf("Ext flash inited");
    delay(100);


}
uint8_t Cnt;
void loop() {
    Serial.println(Cnt);
    Cnt++;
    delay(50);
}

now I see in the terminal this text:
Code:
Port open
CrashReport:
  A problem occurred at (system time) 23:5:35
  Code was executing from address 0x4B9E
  CFSR: 82
	(DACCVIOL) Data Access Violation
	(MMARVALID) Accessed Address: 0x710000FE
  Temperature inside the chip was 38.76 °C
  Startup CPU clock speed is 600MHz
  Reboot was caused by auto reboot after fault or bad interrupt detected
Delay 0.5 sec.Status 1:11101111
Status 2:11101111
Status 1:10000
Status 2:10010
Status 1:10000
Status 2:10010
eram begin done
Port open
CrashReport:
  A problem occurred at (system time) 23:5:45
  Code was executing from address 0x4B9E
  CFSR: 82
	(DACCVIOL) Data Access Violation
	(MMARVALID) Accessed Address: 0x710000FE
  Temperature inside the chip was 38.76 °C
  Startup CPU clock speed is 600MHz
  Reboot was caused by auto reboot after fault or bad interrupt detected
Delay 0.5 sec.Status 1:11101111
Status 2:11101111
Status 1:10000
Status 2:10010
Status 1:10000
Status 2:10010
eram begin done
Do you know if there were any changes in the libraries for working with external FLASH?
I think I need to update libraries, but I'm going to do it tomorrow because now it's almost midnight!
 
Yup, code in msg #10 is bogus.

screenshot.png


Code:
	(MMARVALID) Accessed Address: 0x710000FE

An address beginning with 0x71 (probably) we're dealing custom code or extremely old flash chip code (obviously in the missing function, not what we were given in msg #10) which access the chip memory mapped, with than through the IP command interface as we now do with LittleFS.
 
Thank you for your help!
Could you please give me a link to a page with the right libraries for the Winbond 25Q128JVSQ FLASH memory which is soldered to the teensy 4.1 board?
I used # SPIFFS (SPI Flash File System) **V0.3.7** https://github.com/pellepl/spiffs/, which works well before updating to teensyduino 1.55, but now something gets broken :(
 
SPIFFS isn't directly supported on Teensy for a couple of revisions of TD - or by its maker or others when last checked ...

FLASH DISK is in use with LittleFS installed with TeensyDuino.

Looked like an image was being copied? LittleFS doesn't have that direct support ... at least not noted that anyone did it yet. >> Though I did write a sample file/folder copy to/from SD drive.

See this or other example in same library: {local install}\hardware\teensy\avr\libraries\LittleFS\examples\Integrity\QSPI\QSPI.ino
 
Could you please give me a link to a page with the right libraries for the Winbond 25Q128JVSQ FLASH memory which is soldered to the teensy 4.1 board?

In Arduino, click File > Examples > LittleFS > Simple_Datalogger > LittleFS_QSPI_Simple_Datalogger

When you look at the code, check for these lines:

Code:
//LittleFS_QSPIFlash myfs;  // Used to create FS on QSPI NOR flash chips located on the bottom of the T4.1 such as the W25Q16JV*IQ/W25Q16FV,  for the full list of supported NOR flash see https://github.com/PaulStoffregen/LittleFS#nor-flash
LittleFS_QPINAND myfs;  // Used to create FS on QSPI NAND flash chips located on the bottom of the T4.1 such as the W25N01G. for the full list of supported NAND flash see  https://github.com/PaulStoffregen/LittleFS#nand-flash

You're using a NOR flash chip, so edit the code to use the NOR flash class.

More detailed documentation here:

https://github.com/PaulStoffregen/LittleFS/blob/main/README.md
 
Unfortunately, something is still wrong.
I installed last version of Arduino 1.8.16 and tennsyduino 1.55 and tried both examples, that you suggest
File > Examples > LittleFS > Simple_Datalogger > LittleFS_QSPI_Simple_Datalogger
And {local install}\hardware\teensy\avr\libraries\LittleFS\ex amples\Integrity\QSPI\QSPI.ino
Unfortunately, the both stop working in the same way with message in terminal:
Code:
E:\Test\Little_FS_test\Little_FS_test\Little_FS_test.ino Oct 28 2021 11:44:22
Initializing LittleFS ...QSPI flash begin
Flash ID: FF FF FF
Error starting QSPI FLASH
(I opened commented Serial.print() in the method begin() of LittleFS_QSPIFlash)
Firstly, I thought, that FLASH IC was damaged for some reason, but after returning to Arduino 1.8.12 and teensyduino 1.53 my old program which uses SPIFFS libraries (https://github.com/pellepl/spiffs) for accessing FLASH can read and write to FLASH without any issues. So, I assumed that IC is not damaged. Maybe LittleFS libraries don't like file system, which exists in the FLASH, or FLASH IC is configured in a wrong way, after using SPIFFS functions, or something else? For now, I left TD1.53 in order to continue my soft and ordered a completely new IC 25Q128JVSQ and new teensy 4.1, to make further experiments on a separate board. They must come in a day or two, and I'll check examples with new hardware.

P.S. if somebody needs a code of the example, here it is:
Code:
/*
  LittleFS  datalogger

 This example shows how to log data from three analog sensors
 to an storage device such as a FLASH.

 This example code is in the public domain.
 */
#include <LittleFS.h>

// LittleFS supports creating file systems (FS) in multiple memory types.  Depending on the 
// memory type you want to use you would uncomment one of the following constructors

LittleFS_QSPIFlash myfs;  // Used to create FS on QSPI NOR flash chips located on the bottom of the T4.1 such as the W25Q16JV*IQ/W25Q16FV,  for the full list of supported NOR flash see https://github.com/PaulStoffregen/LittleFS#nor-flash
//LittleFS_QPINAND myfs;  // Used to create FS on QSPI NAND flash chips located on the bottom of the T4.1 such as the W25N01G. for the full list of supported NAND flash see  https://github.com/PaulStoffregen/LittleFS#nand-flash

File dataFile;  // Specifes that dataFile is of File type

int record_count = 0;
bool write_data = false;

void setup()
{

  // Open serial communications and wait for port to open:
    Serial.begin(115200);
    while (!Serial) {
      // wait for serial port to connect.
    }
    Serial.println("\n" __FILE__ " " __DATE__ " " __TIME__);

    Serial.print("Initializing LittleFS ...");

    // see if the Flash is present and can be initialized:
    //myfs.lowLevelFormat();
    if (!myfs.begin()) {
        Serial.printf("Error starting %s\n", "QSPI FLASH");
        while (1) {
          // Error, so don't do anything more - stay stuck here
        }
    }
    Serial.println("LittleFS initialized.");

    menu();

}

void loop()
{
    if (Serial.available()) {
        char rr;
        rr = Serial.read();
        switch (rr) {
            case 'l': listFiles(); break;
            case 'e': eraseFiles(); break;
            case 's':
            {
                Serial.println("\nLogging Data!!!");
                write_data = true;   // sets flag to continue to write data until new command is received
                // opens a file or creates a file if not present,  FILE_WRITE will append data to
                // to the file created.
                dataFile = myfs.open("datalog.txt", FILE_WRITE);
                logData();
            }
            break;
            case 'x': stopLogging(); break;
            case 'd': dumpLog(); break;
            case '\r':
            case '\n':
            case 'h': menu(); break;
        }
        while (Serial.read() != -1); // remove rest of characters.
    }

    if (write_data) logData();
}

void logData()
{
    // make a string for assembling the data to log:
    String dataString = "";

    // read three sensors and append to the string:
    for (int analogPin = 0; analogPin < 3; analogPin++) {
        int sensor = analogRead(analogPin);
        dataString += String(sensor);
        if (analogPin < 2) {
            dataString += ",";
        }
    }

    // if the file is available, write to it:
    if (dataFile) {
        dataFile.println(dataString);
        // print to the serial port too:
        Serial.println(dataString);
        record_count += 1;
    }
    else {
   // if the file isn't open, pop up an error:
        Serial.println("error opening datalog.txt");
    }
    delay(100); // run at a reasonable not-too-fast speed for testing
}

void stopLogging()
{
    Serial.println("\nStopped Logging Data!!!");
    write_data = false;
    // Closes the data file.
    dataFile.close();
    Serial.printf("Records written = %d\n", record_count);
}


void dumpLog()
{
    Serial.println("\nDumping Log!!!");
    // open the file.
    dataFile = myfs.open("datalog.txt");

    // if the file is available, write to it:
    if (dataFile) {
        while (dataFile.available()) {
            Serial.write(dataFile.read());
        }
        dataFile.close();
    }
    // if the file isn't open, pop up an error:
    else {
        Serial.println("error opening datalog.txt");
    }
}

void menu()
{
    Serial.println();
    Serial.println("Menu Options:");
    Serial.println("\tl - List files on disk");
    Serial.println("\te - Erase files on disk");
    Serial.println("\ts - Start Logging data (Restarting logger will append records to existing log)");
    Serial.println("\tx - Stop Logging data");
    Serial.println("\td - Dump Log");
    Serial.println("\th - Menu");
    Serial.println();
}

void listFiles()
{
    Serial.print("\n Space Used = ");
    Serial.println(myfs.usedSize());
    Serial.print("Filesystem Size = ");
    Serial.println(myfs.totalSize());

    printDirectory(myfs);
}

void eraseFiles()
{
    myfs.quickFormat();  // performs a quick format of the created di
    Serial.println("\nFiles erased !");
}

void printDirectory(FS& fs) {
    Serial.println("Directory\n---------");
    printDirectory(fs.open("/"), 0);
    Serial.println();
}

void printDirectory(File dir, int numSpaces) {
    while (true) {
        File entry = dir.openNextFile();
        if (!entry) {
          //Serial.println("** no more files **");
            break;
        }
        printSpaces(numSpaces);
        Serial.print(entry.name());
        if (entry.isDirectory()) {
            Serial.println("/");
            printDirectory(entry, numSpaces + 2);
        }
        else {
       // files have sizes, directories do not
            printSpaces(36 - numSpaces - strlen(entry.name()));
            Serial.print("  ");
            Serial.println(entry.size(), DEC);
        }
        entry.close();
    }
}

void printSpaces(int num) {
    for (int i = 0; i < num; i++) {
        Serial.print(" ");
    }
}
 
Does it truly retain the previously written data when you power cycle? Or in other words, as you sure you're not just accessing the ARM CPU's cache?

Yes, I add one string to the log file in FLASH on each power on. And, when I print the whole file, I see all log for about a month (~600 strings).
Also, I use second teensy 4.1, which communicates with a display, and there are more than 200 pictures stored in the flash, I can see them too.
 
I believe I have same chip on multiple different test boards. And they are working fine.

For example on this board setup:
screenshot2.jpg

I am using one of these:
screenshot.jpg

I am running right now on beyond latest released with MTP test program and it is showing up as a valid storage (QSPI)
screenshot3.jpg

When I have had problems in past, I would often go back with soldering iron and touch up each pad to make sure has good connection.
 
I am running right now on beyond latest released...
I believe that W25Q128JVS can work with teensy. I see it now, it works, but with a third-party old library. Moreover, I hope, it can work with built-in LittleFS libraries, that's why I bought a new memory chip and a new teensy. I want to be able to do a clean experiment with new memory and controller not wired into the system. And I am glad to hear a person who works with this IC. And I'd like you to believe me, that soldering is ok, and it is checked more than once.
So, I have one question for you: do you really use the built-in LittleFS library, which is come with Teensyduino1.55? My doubts are based on the fact that this library appeared there quite recently, but you already have many different devices working with this memory
 
I believe that W25Q128JVS can work with teensy. I see it now, it works, but with a third-party old library. Moreover, I hope, it can work with built-in LittleFS libraries, that's why I bought a new memory chip and a new teensy. I want to be able to do a clean experiment with new memory and controller not wired into the system. And I am glad to hear a person who works with this IC. And I'd like you to believe me, that soldering is ok, and it is checked more than once.
So, I have one question for you: do you really use the built-in LittleFS library, which is come with Teensyduino1.55? My doubts are based on the fact that this library appeared there quite recently, but you already have many different devices working with this memory
There are many of us who have and are playing with these chips: Just do a search on forum for W25q128 and you will find many:

example: https://forum.pjrc.com/threads/63878-W25Q256-breakout-for-Teensy-4-1?p=256267&viewfull=1#post256267

But again it may depend on your exact chip... That is, if you look at the source code you will see in littleFS...
For know chips:
Code:
} known_chips[] = {
	...
	{{0xEF, 0x40, 0x18}, 24, 256, 4096, 16777216, 3000, 400000}, // Winbond W25Q128JV*IQ/W25Q128FV
	...
	{{0xEF, 0x70, 0x18}, 24, 256, 4096, 16777216, 3000, 400000}, // Winbond W25Q128JV*IM (DTR)
...

So again it may depend...

Maybe try to show closeup picture of your board with the chip soldered in.

EDIT: forgot to mention, the code that I showed running is littlefs...
 
LittleFS was tested to work with some/all of the supported chips for TD 1.55 - I just rebuilt again for that p#14 sketch with this NOR chip on IDE 1.86 with fresh TD 1.55 install

The github.com/PaulStoffregen/LittleFS lists this similar part number : W25Q128JV*IQ/W25Q128FV 128Mb

So if all pins soldered, unbridged and cleaned of any interfering flux residue, it should work if the chip works.

PSRAM's a couple of times needed reflow and cleanup to work fully. Some would connect and run a minimal test, but fail LittleFS or other until reflowed/cleaned.

Just 12 days ago a NOR flash was working then not working - then:
Code:
Resoldered the faulty board with NOR flash.

My theory is that when I took it out of the cold cellar, it warmed up and the chip lost contact.
I have re-soldered - works now.
 
You will laugh to tears, but I found the reason why the examples from the libraries installed with Tinsiduino 1.55 did not work! The teensy in my breadboard is powered by an external power supply. Accordingly, I did not reset the power after flashing the teensy with the code from the example! Apparently, the SPIFFS library is changing something in the flash memory settings (for example, the addressing) after which LittleFS did not see the memory. But if you reset the power afterward, the example sketch starts working!

Thanks, everyone for the help! This is one of the best support I've met!

P.S. As for the topic message in this thread, since I returned to Tinsiduino1.53 today, I had to get around the problem. I removed all declaration void serialEventX (void) from the program and transferred the processing of receiving data into UART interrupts. After that, changing the baud rate stopped hanging the program.
 
Apparently, the SPIFFS library is changing something in the flash memory settings (for example, the addressing) after which LittleFS did not see the memory. But if you reset the power afterward, the example sketch starts working!

Glad it's working.

I tried to look into what's getting changed in the flash chip, but I can't find that code in the SPIFFS library. Maybe there's another library or other code outside SPIFFS which is providing the low level hardware abstraction for accessing the flash memory on Teensy 4.1?
 
Back
Top