Paul Williamson
Member
Teensy 3.5, Teensyduino 1.48
I need to change the baud rate of a hardware UART on the fly under user control. The obvious sequence is Serial1.end(); Serial1.begin(newbaud);. This does indeed change the baud rate but it apparently leaves the receive FIFO in a weird state. It sorts itself out after a few dozen characters, but until then the characters are scrambled up and mixed with characters that arrived before the baud rate change. This is not timing dependent.
A workaround is to call Serial1.clear() after Serial1.begin(). I believe the active ingredient here is the UART_CFIFO_RXFLUSH command, though I have not tested that. This is not ideal, since clear() is not part of the official documented Arduino API for serial ports.
I suggest the FIFO flush, if not the entire contents of serial_clear(), be added to the code in serial_begin(), so this workaround will not be necessary.
I created a simple demo sketch to reproduce the problem:
I need to change the baud rate of a hardware UART on the fly under user control. The obvious sequence is Serial1.end(); Serial1.begin(newbaud);. This does indeed change the baud rate but it apparently leaves the receive FIFO in a weird state. It sorts itself out after a few dozen characters, but until then the characters are scrambled up and mixed with characters that arrived before the baud rate change. This is not timing dependent.
A workaround is to call Serial1.clear() after Serial1.begin(). I believe the active ingredient here is the UART_CFIFO_RXFLUSH command, though I have not tested that. This is not ideal, since clear() is not part of the official documented Arduino API for serial ports.
I suggest the FIFO flush, if not the entire contents of serial_clear(), be added to the code in serial_begin(), so this workaround will not be necessary.
I created a simple demo sketch to reproduce the problem:
Code:
// This is intended to be a minimal demo of a problem in the Teensy3 hardware serial driver.
//
// Symptom: if we call Serial1.end() and then Serial1.begin(), as we might do to change the
// baud rate, the characters received on Serial1 after the transition are scrambled up.
// Sometime they include repeats of characters received before the transition, and
// sometimes the characters are just out of order. This continues for some number of
// received characters before sorting itself out.
//
// Program description: Passes through received characters from Serial1 to USB Serial.
// A received character on USB Serial (e.g., a blank line from
// the Send line in the Arduino IDE) triggers Serial1.end()
// followed by Serial1.begin().
//
// Procedure: Connect a terminal emulator to Serial1 (pins 0 and 1) and run the
// program. Open the serial monitor. Type "1234567890" on the terminal,
// and see it echoed on the serial monitor. Click Send on the serial
// monitor. Now type "abcdefghij" on the terminal.
//
// Should see: 1234567890abcdefghij
// Actually see: 1234567890xxxxxxxxxx (where xxx is something wrong)
//
void setup() {
Serial.begin(9600);
Serial1.begin(9600);
}
void loop() {
if (Serial.available()) { // If anything comes in Serial (USB),
Serial.read(); // discard
Serial1.end();
Serial1.begin(9600);
// Serial1.clear(); // this workaround avoids the problem!
}
if (Serial1.available()) { // If anything comes in Serial1 (pins 0 & 1)
Serial.write(Serial1.read()); // read it and send it out Serial (USB)
}
}