From 8f0dfc733ecfca30bd9572de06e97c92dda44d70 Mon Sep 17 00:00:00 2001 From: Balazs Racz Date: Sat, 6 May 2023 22:46:00 +0200 Subject: [PATCH 1/3] Adds 9bit reception capability to the CC32xxUart. --- include/freertos/tc_ioctl.h | 3 +++ src/freertos_drivers/ti/CC32xxUart.cxx | 36 +++++++++++++++++++++++--- src/freertos_drivers/ti/CC32xxUart.hxx | 1 + 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/include/freertos/tc_ioctl.h b/include/freertos/tc_ioctl.h index b7ab168ef..64bc2152b 100644 --- a/include/freertos/tc_ioctl.h +++ b/include/freertos/tc_ioctl.h @@ -46,11 +46,14 @@ #define TCPAREVEN IO(TERMIOS_IOC_MAGIC, 0xF2) #define TCPARONE IO(TERMIOS_IOC_MAGIC, 0xF3) #define TCPARZERO IO(TERMIOS_IOC_MAGIC, 0xF4) +/// Use 9-bit reception mode +#define TCNINEBITRX IO(TERMIOS_IOC_MAGIC, 0xF5) /// One stop bit #define TCSTOPONE IO(TERMIOS_IOC_MAGIC, 0xF8) /// Two stop bits #define TCSTOPTWO IO(TERMIOS_IOC_MAGIC, 0xF9) + /// Argument is a Notifiable* pointer. This notifiable will be invoked when all /// bytes have completed transferring and the transmit engine is idle. #define TCDRAINNOTIFY IOW(TERMIOS_IOC_MAGIC, 0xE0, 4) diff --git a/src/freertos_drivers/ti/CC32xxUart.cxx b/src/freertos_drivers/ti/CC32xxUart.cxx index 1c72cd2ea..353e29591 100644 --- a/src/freertos_drivers/ti/CC32xxUart.cxx +++ b/src/freertos_drivers/ti/CC32xxUart.cxx @@ -74,6 +74,7 @@ CC32xxUart::CC32xxUart(const char *name, unsigned long base, uint32_t interrupt, , baud_(baud) , txPending_(false) , hwFIFO_(hw_fifo) + , nineBit_(false) { static_assert( UART_CONFIG_PAR_NONE == 0, "driverlib changed against our assumptions"); @@ -169,6 +170,13 @@ int CC32xxUart::ioctl(File *file, unsigned long int key, unsigned long data) mode_ |= UART_CONFIG_PAR_ONE; MAP_UARTParityModeSet(base_, UART_CONFIG_PAR_ONE); break; + case TCNINEBITRX: + nineBit_ = data != 0; + if (!nineBit_) + { + break; + } + // fall through case TCPARZERO: mode_ &= ~UART_CONFIG_PAR_MASK; mode_ |= UART_CONFIG_PAR_ZERO; @@ -287,14 +295,34 @@ void CC32xxUart::interrupt_handler() while (MAP_UARTCharsAvail(base_)) { long data = MAP_UARTCharGetNonBlocking(base_); - if (data >= 0 && data <= 0xff) + if (nineBit_) { - unsigned char c = data; - if (rxBuf->put(&c, 1) == 0) + if (rxBuf->space() < 2) { ++overrunCount; } - rxBuf->signal_condition_from_isr(); + else + { + // parity error bit is moved to the ninth bit, then two bytes + // are written to the buffer. + long bit9 = (data & 0x200) >> 1; + data &= 0xff; + data |= bit9; + rxBuf->put((uint8_t *)&data, 2); + rxBuf->signal_condition_from_isr(); + } + } + else + { + if (data >= 0 && data <= 0xff) + { + unsigned char c = data; + if (rxBuf->put(&c, 1) == 0) + { + ++overrunCount; + } + rxBuf->signal_condition_from_isr(); + } } } /* transmit a character if we have pending tx data */ diff --git a/src/freertos_drivers/ti/CC32xxUart.hxx b/src/freertos_drivers/ti/CC32xxUart.hxx index 663d36be9..9bf6e78c6 100644 --- a/src/freertos_drivers/ti/CC32xxUart.hxx +++ b/src/freertos_drivers/ti/CC32xxUart.hxx @@ -123,6 +123,7 @@ private: uint32_t baud_ : 24; /**< desired baud rate */ uint8_t txPending_; /**< transmission currently pending */ uint8_t hwFIFO_; /**< true if hardware fifo is to be enabled, else false */ + uint8_t nineBit_; /**< true if using 9-bit reception */ /** Default constructor. */ From dbca9175bcefd809382889f1472e724dbcbd1303 Mon Sep 17 00:00:00 2001 From: Balazs Racz Date: Sat, 6 May 2023 23:34:21 +0200 Subject: [PATCH 2/3] Adds 9bit to the tiva UART as well. --- src/freertos_drivers/ti/TivaDev.hxx | 1 + src/freertos_drivers/ti/TivaUart.cxx | 38 ++++++++++++++++++++++++---- 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/src/freertos_drivers/ti/TivaDev.hxx b/src/freertos_drivers/ti/TivaDev.hxx index b36d8023a..080a89840 100644 --- a/src/freertos_drivers/ti/TivaDev.hxx +++ b/src/freertos_drivers/ti/TivaDev.hxx @@ -229,6 +229,7 @@ private: uint8_t hwFIFO_; /**< enable HW FIFO */ uint8_t uartMode_; /**< uart config (mode) flags */ uint8_t txPending_; /**< transmission currently pending */ + uint8_t nineBit_; /**< true if using 9-bit reception */ /** Default constructor. */ diff --git a/src/freertos_drivers/ti/TivaUart.cxx b/src/freertos_drivers/ti/TivaUart.cxx index 384dd17d4..8733123f4 100644 --- a/src/freertos_drivers/ti/TivaUart.cxx +++ b/src/freertos_drivers/ti/TivaUart.cxx @@ -71,6 +71,7 @@ TivaUart::TivaUart(const char *name, unsigned long base, uint32_t interrupt, , hwFIFO_(hw_fifo) , uartMode_(mode) , txPending_(false) + , nineBit_(false) { static_assert( UART_CONFIG_PAR_NONE == 0, "driverlib changed against our assumptions"); @@ -218,14 +219,34 @@ void TivaUart::interrupt_handler() while (MAP_UARTCharsAvail(base_)) { long data = MAP_UARTCharGetNonBlocking(base_); - if (data >= 0 && data <= 0xff) + if (nineBit_) { - unsigned char c = data; - if (rxBuf->put(&c, 1) == 0) + if (rxBuf->space() < 2) { - overrunCount++; + ++overrunCount; + } + else + { + // parity error bit is moved to the ninth bit, then two bytes + // are written to the buffer. + long bit9 = (data & 0x200) >> 1; + data &= 0xff; + data |= bit9; + rxBuf->put((uint8_t *)&data, 2); + rxBuf->signal_condition_from_isr(); + } + } + else + { + if (data >= 0 && data <= 0xff) + { + unsigned char c = data; + if (rxBuf->put(&c, 1) == 0) + { + overrunCount++; + } + rxBuf->signal_condition_from_isr(); } - rxBuf->signal_condition_from_isr(); } } /* transmit a character if we have pending tx data */ @@ -302,6 +323,13 @@ int TivaUart::ioctl(File *file, unsigned long int key, unsigned long data) uartMode_ |= UART_CONFIG_PAR_ONE; MAP_UARTParityModeSet(base_, UART_CONFIG_PAR_ONE); break; + case TCNINEBITRX: + nineBit_ = data != 0; + if (!nineBit_) + { + break; + } + // fall through case TCPARZERO: uartMode_ &= ~UART_CONFIG_PAR_MASK; uartMode_ |= UART_CONFIG_PAR_ZERO; From e4c9d9588b1f8de78196e30874db413cdaaa8ab4 Mon Sep 17 00:00:00 2001 From: Balazs Racz Date: Sat, 8 Jul 2023 14:38:07 +0200 Subject: [PATCH 3/3] Fix comments. --- include/freertos/tc_ioctl.h | 1 - src/freertos_drivers/ti/CC32xxUart.cxx | 13 +++++++------ src/freertos_drivers/ti/TivaUart.cxx | 13 +++++++------ 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/include/freertos/tc_ioctl.h b/include/freertos/tc_ioctl.h index 64bc2152b..258d6fe03 100644 --- a/include/freertos/tc_ioctl.h +++ b/include/freertos/tc_ioctl.h @@ -53,7 +53,6 @@ /// Two stop bits #define TCSTOPTWO IO(TERMIOS_IOC_MAGIC, 0xF9) - /// Argument is a Notifiable* pointer. This notifiable will be invoked when all /// bytes have completed transferring and the transmit engine is idle. #define TCDRAINNOTIFY IOW(TERMIOS_IOC_MAGIC, 0xE0, 4) diff --git a/src/freertos_drivers/ti/CC32xxUart.cxx b/src/freertos_drivers/ti/CC32xxUart.cxx index 4d22e5020..04abfcd22 100644 --- a/src/freertos_drivers/ti/CC32xxUart.cxx +++ b/src/freertos_drivers/ti/CC32xxUart.cxx @@ -314,15 +314,16 @@ void CC32xxUart::interrupt_handler() rxBuf->signal_condition_from_isr(); } } - else + else if (data >= 0 && data <= 0xff) { - if (data >= 0 && data <= 0xff) + if (rxBuf->space() < 1) + { + ++overrunCount; + } + else { unsigned char c = data; - if (rxBuf->put(&c, 1) == 0) - { - ++overrunCount; - } + rxBuf->put(&c, 1); rxBuf->signal_condition_from_isr(); } } diff --git a/src/freertos_drivers/ti/TivaUart.cxx b/src/freertos_drivers/ti/TivaUart.cxx index 8733123f4..597e51b3f 100644 --- a/src/freertos_drivers/ti/TivaUart.cxx +++ b/src/freertos_drivers/ti/TivaUart.cxx @@ -236,15 +236,16 @@ void TivaUart::interrupt_handler() rxBuf->signal_condition_from_isr(); } } - else + else if (data >= 0 && data <= 0xff) { - if (data >= 0 && data <= 0xff) + if (rxBuf->space() < 1) + { + ++overrunCount; + } + else { unsigned char c = data; - if (rxBuf->put(&c, 1) == 0) - { - overrunCount++; - } + rxBuf->put(&c, 1); rxBuf->signal_condition_from_isr(); } }