Serial class implementation in Teensy 4

wygonski

Member
I am porting a logging application from Teensy 3.5 to Teensy 4.1, and I have a question concering the implementation of the Serial class in the Teensy core in 4.1 that affects the behavior of my app.

The application timestamps the receipt of a header character on a serial port to record the time of receipt of incoming packets of serial data.

In Teensy 3.5 I accomplished this by adding code to the serial interrupt handler to capture micros() value when the header character is read from the UART data register and put into the Rx circular buffer.
Then in the background I invoke HardwareSerial::read() to acquire the received data bytes from the Rx circular buffer, and when the header character is read I already have the timestamp which is logged with the data.

In porting the application to Teensy 4.1, I discovered that the core implementation of HardwareSerial::read not only retrieves bytes from the Rx circular buffer, but also reads from the LPUART fifo, same as what the IRQ handler does.

Code:
int HardwareSerial::read(void)
{
	uint32_t head, tail;
	int c;

	head = rx_buffer_head_;
	tail = rx_buffer_tail_;
	if (head == tail) {
		__disable_irq();
		head = rx_buffer_head_;  // reread head to make sure no ISR happened
		if (head == tail) {
			// Still empty Now check for stuff in FIFO Queue.
			c = -1;	// assume nothing to return
			if (port->WATER & 0x7000000) {
				c = port->DATA & 0x3ff;		// Use only up to 10 bits of data
			}
			__enable_irq();
			return c;
		}
		__enable_irq();

	}
	(code continues...)
This implementation of the read() method seems to be a departure from the well-understood pattern where incoming bytes are buffered by the IRQ handler and then read() is invoked to get the bytes from the buffer. So I thought I would ask about it just in case I was missing something. Is there something about the Teensy 4.1 chip that requires this change?
 
Back
Top