diff --git a/teensy3/serial1.c b/teensy3/serial1.c index 9262c342e..3747d4377 100644 --- a/teensy3/serial1.c +++ b/teensy3/serial1.c @@ -114,6 +114,9 @@ static uint8_t tx_pin_num = 1; static uint8_t half_duplex_mode = 0; #endif +// 7-bit mode support +static uint8_t data_mask = 0xff; // Use all bits by default + // UART0 and UART1 are clocked by F_CPU, UART2 is clocked by F_BUS // UART0 has 8 byte fifo, UART1 and UART2 have 1 byte buffer @@ -202,6 +205,14 @@ void serial_format(uint32_t format) c = UART0_C3 & ~0x10; if (format & 0x20) c |= 0x10; // tx invert UART0_C3 = c; + + // 7-bit support + if ((format & 0x0E) == 0x02) { + data_mask = 0x7f; // Use only 7 bits of data + } else { + data_mask = 0xff; // Use all bits + } + #ifdef SERIAL_9BIT_SUPPORT c = UART0_C4 & 0x1F; if (format & 0x08) c |= 0x20; // 9 bit mode with parity (requires 10 bits) @@ -628,7 +639,7 @@ void uart0_status_isr(void) if (use9Bits && (UART0_C3 & 0x80)) { n = UART0_D | 0x100; } else { - n = UART0_D; + n = UART0_D & data_mask; } newhead = head + 1; if (newhead >= rx_buffer_total_size_) newhead = 0; @@ -674,7 +685,7 @@ void uart0_status_isr(void) if (use9Bits && (UART0_C3 & 0x80)) { n = UART0_D | 0x100; } else { - n = UART0_D; + n = UART0_D & data_mask; } head = rx_buffer_head + 1; if (head >= rx_buffer_total_size_) head = 0; diff --git a/teensy3/serial1_doughboy.txt b/teensy3/serial1_doughboy.txt index 3eeda9bc7..d95bece66 100644 --- a/teensy3/serial1_doughboy.txt +++ b/teensy3/serial1_doughboy.txt @@ -89,6 +89,9 @@ static volatile uint8_t rx_buffer_head = 0; static volatile uint8_t rx_buffer_tail = 0; #endif +// 7-bit mode support +static uint8_t data_mask = 0xff; // Use all bits by default + // UART0 and UART1 are clocked by F_CPU, UART2 is clocked by F_BUS // UART0 has 8 byte fifo, UART1 and UART2 have 1 byte buffer @@ -140,6 +143,14 @@ void serial_format(uint32_t format) c = UART0_C3 & ~0x10; if (format & 0x20) c |= 0x10; // tx invert UART0_C3 = c; + + // 7-bit support + if ((format & 0x0E) == 0x02) { + data_mask = 0x7f; // Use only 7 bits of data + } else { + data_mask = 0xff; // Use all bits + } + #ifdef SERIAL_9BIT_SUPPORT c = UART0_C4 & 0x1F; if (format & 0x08) c |= 0x20; // 9 bit mode with parity (requires 10 bits) @@ -404,7 +415,7 @@ void uart0_status_isr(void) if (use9Bits && (UART0_C3 & 0x80)) { n = UART0_D | 0x100; } else { - n = UART0_D; + n = UART0_D & data_mask; } head = newhead; rx_buffer[head] = n; @@ -442,7 +453,11 @@ void uart0_status_isr(void) } } n = UART0_D; - if (use9Bits && (UART0_C3 & 0x80)) n |= 0x100; + if (use9Bits && (UART0_C3 & 0x80)) { + n |= 0x100; + } else { + n &= data_mask; + } rx_buffer[head] = n; rx_buffer_head = head; break; diff --git a/teensy3/serial2.c b/teensy3/serial2.c index 15109a729..4ffc673ba 100644 --- a/teensy3/serial2.c +++ b/teensy3/serial2.c @@ -115,6 +115,9 @@ static uint8_t tx_pin_num = 10; static uint8_t half_duplex_mode = 0; #endif +// 7-bit mode support +static uint8_t data_mask = 0xff; // Use all bits by default + // UART0 and UART1 are clocked by F_CPU, UART2 is clocked by F_BUS // UART0 has 8 byte fifo, UART1 and UART2 have 1 byte buffer @@ -201,6 +204,14 @@ void serial2_format(uint32_t format) c = UART1_C3 & ~0x10; if (format & 0x20) c |= 0x10; // tx invert UART1_C3 = c; + + // 7-bit support + if ((format & 0x0E) == 0x02) { + data_mask = 0x7f; // Use only 7 bits of data + } else { + data_mask = 0xff; // Use all bits + } + #if defined(SERIAL_9BIT_SUPPORT) && !defined(KINETISL) c = UART1_C4 & 0x1F; if (format & 0x08) c |= 0x20; // 9 bit mode with parity (requires 10 bits) @@ -613,7 +624,7 @@ void uart1_status_isr(void) if (use9Bits && (UART1_C3 & 0x80)) { n = UART1_D | 0x100; } else { - n = UART1_D; + n = UART1_D & data_mask; } newhead = head + 1; if (newhead >= rx_buffer_total_size_) newhead = 0; @@ -659,7 +670,7 @@ void uart1_status_isr(void) if (use9Bits && (UART1_C3 & 0x80)) { n = UART1_D | 0x100; } else { - n = UART1_D; + n = UART1_D & data_mask; } head = rx_buffer_head + 1; if (head >= rx_buffer_total_size_) head = 0; diff --git a/teensy3/serial3.c b/teensy3/serial3.c index 94442a6b5..8f5cbfd01 100644 --- a/teensy3/serial3.c +++ b/teensy3/serial3.c @@ -117,6 +117,9 @@ static uint8_t tx_pin_num = 8; static uint8_t half_duplex_mode = 0; #endif +// 7-bit mode support +static uint8_t data_mask = 0xff; // Use all bits by default + // UART0 and UART1 are clocked by F_CPU, UART2 is clocked by F_BUS // UART0 has 8 byte fifo, UART1 and UART2 have 1 byte buffer @@ -184,6 +187,14 @@ void serial3_format(uint32_t format) c = UART2_C3 & ~0x10; if (format & 0x20) c |= 0x10; // tx invert UART2_C3 = c; + + // 7-bit support + if ((format & 0x0E) == 0x02) { + data_mask = 0x7f; // Use only 7 bits of data + } else { + data_mask = 0xff; // Use all bits + } + #if defined(SERIAL_9BIT_SUPPORT) && !defined(KINETISL) c = UART2_C4 & 0x1F; if (format & 0x08) c |= 0x20; // 9 bit mode with parity (requires 10 bits) @@ -492,7 +503,7 @@ void uart2_status_isr(void) if (use9Bits && (UART2_C3 & 0x80)) { n = UART2_D | 0x100; } else { - n = UART2_D; + n = UART2_D & data_mask; } head = rx_buffer_head + 1; if (head >= rx_buffer_total_size_) head = 0; diff --git a/teensy3/serial4.c b/teensy3/serial4.c index 0869fcf22..bd898b586 100644 --- a/teensy3/serial4.c +++ b/teensy3/serial4.c @@ -102,6 +102,9 @@ static volatile uint8_t rx_buffer_tail = 0; static uint8_t rx_pin_num = 31; static uint8_t tx_pin_num = 32; +// 7-bit mode support +static uint8_t data_mask = 0xff; // Use all bits by default + // UART0 and UART1 are clocked by F_CPU, UART2 is clocked by F_BUS // UART0 has 8 byte fifo, UART1 and UART2 have 1 byte buffer @@ -157,6 +160,14 @@ void serial4_format(uint32_t format) c = UART3_C3 & ~0x10; if (format & 0x20) c |= 0x10; // tx invert UART3_C3 = c; + + // 7-bit support + if ((format & 0x0E) == 0x02) { + data_mask = 0x7f; // Use only 7 bits of data + } else { + data_mask = 0xff; // Use all bits + } + #ifdef SERIAL_9BIT_SUPPORT c = UART3_C4 & 0x1F; if (format & 0x08) c |= 0x20; // 9 bit mode with parity (requires 10 bits) @@ -412,7 +423,7 @@ void uart3_status_isr(void) if (use9Bits && (UART3_C3 & 0x80)) { n = UART3_D | 0x100; } else { - n = UART3_D; + n = UART3_D & data_mask; } head = rx_buffer_head + 1; if (head >= rx_buffer_total_size_) head = 0; diff --git a/teensy3/serial5.c b/teensy3/serial5.c index 9037ec600..3a90abc30 100644 --- a/teensy3/serial5.c +++ b/teensy3/serial5.c @@ -102,6 +102,9 @@ static volatile uint8_t rx_buffer_tail = 0; static uint8_t tx_pin_num = 33; +// 7-bit mode support +static uint8_t data_mask = 0xff; // Use all bits by default + // UART0 and UART1 are clocked by F_CPU, UART2 is clocked by F_BUS // UART0 has 8 byte fifo, UART1 and UART2 have 1 byte buffer @@ -151,6 +154,14 @@ void serial5_format(uint32_t format) c = UART4_C3 & ~0x10; if (format & 0x20) c |= 0x10; // tx invert UART4_C3 = c; + + // 7-bit support + if ((format & 0x0E) == 0x02) { + data_mask = 0x7f; // Use only 7 bits of data + } else { + data_mask = 0xff; // Use all bits + } + #ifdef SERIAL_9BIT_SUPPORT c = UART4_C4 & 0x1F; if (format & 0x08) c |= 0x20; // 9 bit mode with parity (requires 10 bits) @@ -383,7 +394,7 @@ void uart4_status_isr(void) if (use9Bits && (UART4_C3 & 0x80)) { n = UART4_D | 0x100; } else { - n = UART4_D; + n = UART4_D & data_mask; } head = rx_buffer_head + 1; if (head >= rx_buffer_total_size_) head = 0; diff --git a/teensy3/serial6.c b/teensy3/serial6.c index 22eebab36..d9ceaeac8 100644 --- a/teensy3/serial6.c +++ b/teensy3/serial6.c @@ -102,6 +102,9 @@ static volatile uint8_t rx_buffer_tail = 0; static uint8_t tx_pin_num = 48; +// 7-bit mode support +static uint8_t data_mask = 0xff; // Use all bits by default + // UART0 and UART1 are clocked by F_CPU, UART2 is clocked by F_BUS // UART0 has 8 byte fifo, UART1 and UART2 have 1 byte buffer @@ -151,6 +154,14 @@ void serial6_format(uint32_t format) c = UART5_C3 & ~0x10; if (format & 0x20) c |= 0x10; // tx invert UART5_C3 = c; + + // 7-bit support + if ((format & 0x0E) == 0x02) { + data_mask = 0x7f; // Use only 7 bits of data + } else { + data_mask = 0xff; // Use all bits + } + #ifdef SERIAL_9BIT_SUPPORT c = UART5_C4 & 0x1F; if (format & 0x08) c |= 0x20; // 9 bit mode with parity (requires 10 bits) @@ -382,7 +393,7 @@ void uart5_status_isr(void) if (use9Bits && (UART5_C3 & 0x80)) { n = UART5_D | 0x100; } else { - n = UART5_D; + n = UART5_D & data_mask; } head = rx_buffer_head + 1; if (head >= rx_buffer_total_size_) head = 0; diff --git a/teensy3/serial6_lpuart.c b/teensy3/serial6_lpuart.c index efbf030f0..06c23048b 100644 --- a/teensy3/serial6_lpuart.c +++ b/teensy3/serial6_lpuart.c @@ -110,6 +110,9 @@ static volatile uint8_t rx_buffer_tail = 0; static uint8_t tx_pin_num = 48; +// 7-bit mode support +static uint32_t data_mask = 0x3ff; // Use only the 10 data bits by default + void serial6_begin(uint32_t desiredBaudRate) { @@ -224,7 +227,14 @@ void serial6_format(uint32_t format) // Bit 3 10 bit - Will assume that begin already cleared it. if (format & 0x08) LPUART0_BAUD |= LPUART_BAUD_M10; - + + // 7-bit support + if ((format & 0x0E) == 0x02) { + data_mask = 0x7f; // Use only 7 bits of data + } else { + data_mask = 0x3ff; // Use only the 10 data bits + } + // Bit 4 RXINVERT c = LPUART0_STAT & ~LPUART_STAT_RXINV; if (format & 0x10) c |= LPUART_STAT_RXINV; // rx invert @@ -456,9 +466,9 @@ void lpuart0_status_isr(void) // if (use9Bits && (UART5_C3 & 0x80)) { // n = UART5_D | 0x100; // } else { -// n = UART5_D; +// n = UART5_D & data_mask; // } - n = LPUART0_DATA & 0x3ff; // use only the 10 data bits + n = LPUART0_DATA & data_mask; head = rx_buffer_head + 1; if (head >= rx_buffer_total_size_) head = 0; if (head != rx_buffer_tail) { diff --git a/teensy4/HardwareSerial.cpp b/teensy4/HardwareSerial.cpp index 3fc9c26d9..5c936ed4d 100644 --- a/teensy4/HardwareSerial.cpp +++ b/teensy4/HardwareSerial.cpp @@ -208,6 +208,13 @@ void HardwareSerial::begin(uint32_t baud, uint16_t format) if (format & 0x04) ctrl |= LPUART_CTRL_M; // 9 bits (might include parity) if ((format & 0x0F) == 0x04) ctrl |= LPUART_CTRL_R9T8; // 8N2 is 9 bit with 9th bit always 1 + // 7-bit support + if ((format & 0x0E) == 0x02) { + data_mask_ = 0x7f; // Use only 7 bits of data + } else { + data_mask_ = 0x3ff; // Use only up to 10 bits of data + } + // Bit 5 TXINVERT if (format & 0x20) ctrl |= LPUART_CTRL_TXINV; // tx invert @@ -483,7 +490,7 @@ int HardwareSerial::peek(void) // Still empty Now check for stuff in FIFO Queue. int c = -1; // assume nothing to return if (port->WATER & 0x7000000) { - c = port->DATA & 0x3ff; // Use only up to 10 bits of data + c = port->DATA & data_mask_; // But we don't want to throw it away... // since queue is empty, just going to reset to front of queue... rx_buffer_head_ = 1; @@ -518,7 +525,7 @@ int HardwareSerial::read(void) // 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 + c = port->DATA & data_mask_; } __enable_irq(); return c; @@ -621,7 +628,7 @@ void HardwareSerial::IRQHandler() head = rx_buffer_head_; tail = rx_buffer_tail_; do { - n = port->DATA & 0x3ff; // Use only up to 10 bits of data + n = port->DATA & data_mask_; newhead = head + 1; if (newhead >= rx_buffer_total_size_) newhead = 0; diff --git a/teensy4/HardwareSerial.h b/teensy4/HardwareSerial.h index b4f2d0015..5148c1f69 100644 --- a/teensy4/HardwareSerial.h +++ b/teensy4/HardwareSerial.h @@ -287,6 +287,9 @@ class HardwareSerial : public Stream uint8_t tx_pin_index_ = 0x0; uint8_t half_duplex_mode_ = 0; // are we in half duplex mode? + // 7-bit mode support + int data_mask_ = 0x3ff; // Use only up to 10 bits of data by default + volatile BUFTYPE *tx_buffer_; volatile BUFTYPE *rx_buffer_; volatile BUFTYPE *rx_buffer_storage_ = nullptr;