Fix for 9-bit serial receive bug

tigercat

Member
The V1.20 Teensyduino 9-bit serial support incorrectly implements 9-bit receive, resulting in the 9'th bit being randomly dropped. This is because, per the datasheet, the UART_C3 register must be read before UART_D for it to be valid. So the order of these lines of code in serial1.c, serial2.c, and serial3.c should be reversed:
Code:
n = UART1_D;
if (use9Bits && (UART1_C3 & 0x80)) n |= 0x100;
As in this code (this example is from Serial2.c):
Code:
if (use9Bits && (UART1_C3 & 0x80)) n = 0x100; else n=0;
n += UART1_D;
 
I've been having loads of fun with various MCUs and PC software that doesn't work correctly for ISO7816 smartCart serial which is 8 data bits + 9th even parity and with or without an externally clocked UART whose divisor shall be 1/372.

This is some of ISO's finest committee work.

PS: ISO says the smartCard reset can be either true low or true high - deduce it from the ill-defined pulse width.
 
Sorry, I have no 9 bit devices.
I have several ISO smartCard readers - but they're 8 data bits + 1 parity bit + 1.5 stop bits - per ISO, so the parity bit is checked and discarded in the USART.
 
Hi,

I checked it today and it was ok for Serial1 with 9o1.
But I think here is still a bug in Serial3

line 165 ff

if (++tail >= TX_BUFFER_SIZE) tail = 0;
UART2_D = tx_buffer[tail];
tx_buffer_tail = tail;

I think there is the 9bit part missing.

regards

gecko
 
Hi,

the bug found his way back into Teensyduino 1.34 and 1.35.

Serial1 and Serial2 don't read the bit 9 to the Buffer.

serial1.c line 554 ff

#else
if (UART0_S1 & UART_S1_RDRF)
{
if (use9Bits && (UART0_C3 & 0x80)) n = 0x100; // gk
n |= UART0_D; // gk
head = rx_buffer_head + 1;
if (head >= SERIAL1_RX_BUFFER_SIZE) head = 0;
if (head != rx_buffer_tail) {
rx_buffer[head] = n;
rx_buffer_head = head;
}
}

regards

gecko
 
Back
Top