diff --git a/cores/arduino/HardwareSerial.cpp b/cores/arduino/HardwareSerial.cpp index 1c89de7f61..11cf90a7b1 100644 --- a/cores/arduino/HardwareSerial.cpp +++ b/cores/arduino/HardwareSerial.cpp @@ -446,7 +446,7 @@ void HardwareSerial::begin(unsigned long baud, byte config) break; } - uart_init(&_serial, (uint32_t)baud, databits, parity, stopbits); + uart_init(&_serial, (uint32_t)baud, databits, parity, stopbits, _rx_invert, _tx_invert, _data_invert); enableHalfDuplexRx(); uart_attach_rx_callback(&_serial, _rx_complete_irq); } @@ -668,4 +668,19 @@ void HardwareSerial::enableHalfDuplexRx(void) } } +void HardwareSerial::setRxInvert(void) +{ + _rx_invert = true; +} + +void HardwareSerial::setTxInvert(void) +{ + _tx_invert = true; +} + +void HardwareSerial::setDataInvert(void) +{ + _data_invert = true; +} + #endif // HAL_UART_MODULE_ENABLED && !HAL_UART_MODULE_ONLY diff --git a/cores/arduino/HardwareSerial.h b/cores/arduino/HardwareSerial.h index f8a2884de0..3ed29a873d 100644 --- a/cores/arduino/HardwareSerial.h +++ b/cores/arduino/HardwareSerial.h @@ -95,6 +95,9 @@ class HardwareSerial : public Stream { protected: // Has any byte been written to the UART since begin() bool _written; + bool _rx_invert; + bool _tx_invert; + bool _data_invert; // Don't put any members after these buffers, since only the first // 32 bytes of this struct can be accessed quickly using the ldd @@ -165,6 +168,12 @@ class HardwareSerial : public Stream { bool isHalfDuplex(void) const; void enableHalfDuplexRx(void); + // Enable HW Rx/Tx/data inversion + // This needs to be done before the call to begin() + void setRxInvert(void); + void setTxInvert(void); + void setDataInvert(void); + friend class STM32LowPower; // Interrupt handlers diff --git a/keywords.txt b/keywords.txt index a4a284e59a..5ddcab36dd 100644 --- a/keywords.txt +++ b/keywords.txt @@ -274,6 +274,9 @@ HALF_DUPLEX_ENABLED LITERAL1 setHalfDuplex KEYWORD2 isHalfDuplex KEYWORD2 enableHalfDuplexRx KEYWORD2 +setRxInvert KEYWORD2 +setTxInvert KEYWORD2 +setDataInvert KEYWORD2 Serial4 KEYWORD1 Serial5 KEYWORD1 Serial6 KEYWORD1 diff --git a/libraries/SrcWrapper/inc/uart.h b/libraries/SrcWrapper/inc/uart.h index a6c41390e7..7f99d498e7 100644 --- a/libraries/SrcWrapper/inc/uart.h +++ b/libraries/SrcWrapper/inc/uart.h @@ -38,6 +38,7 @@ #define __UART_H /* Includes ------------------------------------------------------------------*/ +#include #include "stm32_def.h" #include "PinNames.h" @@ -254,7 +255,7 @@ struct serial_s { /* Exported macro ------------------------------------------------------------*/ /* Exported functions ------------------------------------------------------- */ -void uart_init(serial_t *obj, uint32_t baudrate, uint32_t databits, uint32_t parity, uint32_t stopbits); +void uart_init(serial_t *obj, uint32_t baudrate, uint32_t databits, uint32_t parity, uint32_t stopbits, bool rx_invert, bool tx_invert, bool data_invert); void uart_deinit(serial_t *obj); #if defined(HAL_PWR_MODULE_ENABLED) && (defined(UART_IT_WUF) || defined(LPUART1_BASE)) void uart_config_lowpower(serial_t *obj); diff --git a/libraries/SrcWrapper/src/stm32/uart.c b/libraries/SrcWrapper/src/stm32/uart.c index 04ccb2c820..4aaa3f0e2e 100644 --- a/libraries/SrcWrapper/src/stm32/uart.c +++ b/libraries/SrcWrapper/src/stm32/uart.c @@ -115,7 +115,7 @@ serial_t *get_serial_obj(UART_HandleTypeDef *huart) * @param obj : pointer to serial_t structure * @retval None */ -void uart_init(serial_t *obj, uint32_t baudrate, uint32_t databits, uint32_t parity, uint32_t stopbits) +void uart_init(serial_t *obj, uint32_t baudrate, uint32_t databits, uint32_t parity, uint32_t stopbits, bool rx_invert, bool tx_invert, bool data_invert) { if (obj == NULL) { return; @@ -407,11 +407,31 @@ void uart_init(serial_t *obj, uint32_t baudrate, uint32_t databits, uint32_t par huart->Init.Mode = UART_MODE_TX_RX; huart->Init.HwFlowCtl = flow_control; huart->Init.OverSampling = UART_OVERSAMPLING_16; +#if defined(UART_ADVFEATURE_NO_INIT) + // Default value + huart->AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; #if defined(UART_ADVFEATURE_SWAP_INIT) - huart->AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_SWAP_INIT; + huart->AdvancedInit.AdvFeatureInit |= UART_ADVFEATURE_SWAP_INIT; huart->AdvancedInit.Swap = pin_swap; -#elif defined(UART_ADVFEATURE_NO_INIT) - huart->AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; +#endif +#if defined(UART_ADVFEATURE_RXINVERT_INIT) + if (rx_invert) { + huart->AdvancedInit.AdvFeatureInit |= UART_ADVFEATURE_RXINVERT_INIT; + huart->AdvancedInit.RxPinLevelInvert = UART_ADVFEATURE_RXINV_ENABLE; + } +#endif +#if defined(UART_ADVFEATURE_TXINVERT_INIT) + if (tx_invert) { + huart->AdvancedInit.AdvFeatureInit |= UART_ADVFEATURE_TXINVERT_INIT; + huart->AdvancedInit.TxPinLevelInvert = UART_ADVFEATURE_TXINV_ENABLE; + } +#endif +#if defined(UART_ADVFEATURE_DATAINVERT_INIT) + if (data_invert) { + huart->AdvancedInit.AdvFeatureInit |= UART_ADVFEATURE_DATAINVERT_INIT; + huart->AdvancedInit.DataInvert = UART_ADVFEATURE_DATAINV_ENABLE; + } +#endif #endif #ifdef UART_ONE_BIT_SAMPLE_DISABLE huart->Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE; @@ -812,7 +832,7 @@ void uart_debug_init(void) serial_debug.pin_tx = pinmap_pin(DEBUG_UART, PinMap_UART_TX); #endif /* serial_debug.pin_rx set by default to NC to configure in half duplex mode */ - uart_init(&serial_debug, DEBUG_UART_BAUDRATE, UART_WORDLENGTH_8B, UART_PARITY_NONE, UART_STOPBITS_1); + uart_init(&serial_debug, DEBUG_UART_BAUDRATE, UART_WORDLENGTH_8B, UART_PARITY_NONE, UART_STOPBITS_1, false, false, false); } }