Skip to content

Commit 3a60776

Browse files
ndoofpistm
authored andcommitted
feat(uart): support UART Tx, Rx and data invert function
This enables UART Tx, Rx and data invert function on STM32 families that support it. In order to enable Tx, Rx and/or data invert, call respectively: ```c++ Serial1.setTxInvert(); Serial1.setRxInvert(); Serial1.setDataInvert(); ``` Fixes: #1160 #2669 See also: #1418 Signed-off-by: Andrew Yong <[email protected]>
1 parent 646bec6 commit 3a60776

File tree

5 files changed

+55
-7
lines changed

5 files changed

+55
-7
lines changed

cores/arduino/HardwareSerial.cpp

+16-1
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,7 @@ void HardwareSerial::begin(unsigned long baud, byte config)
446446
break;
447447
}
448448

449-
uart_init(&_serial, (uint32_t)baud, databits, parity, stopbits);
449+
uart_init(&_serial, (uint32_t)baud, databits, parity, stopbits, _rx_invert, _tx_invert, _data_invert);
450450
enableHalfDuplexRx();
451451
uart_attach_rx_callback(&_serial, _rx_complete_irq);
452452
}
@@ -668,4 +668,19 @@ void HardwareSerial::enableHalfDuplexRx(void)
668668
}
669669
}
670670

671+
void HardwareSerial::setRxInvert(void)
672+
{
673+
_rx_invert = true;
674+
}
675+
676+
void HardwareSerial::setTxInvert(void)
677+
{
678+
_tx_invert = true;
679+
}
680+
681+
void HardwareSerial::setDataInvert(void)
682+
{
683+
_data_invert = true;
684+
}
685+
671686
#endif // HAL_UART_MODULE_ENABLED && !HAL_UART_MODULE_ONLY

cores/arduino/HardwareSerial.h

+9
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,9 @@ class HardwareSerial : public Stream {
9595
protected:
9696
// Has any byte been written to the UART since begin()
9797
bool _written;
98+
bool _rx_invert;
99+
bool _tx_invert;
100+
bool _data_invert;
98101

99102
// Don't put any members after these buffers, since only the first
100103
// 32 bytes of this struct can be accessed quickly using the ldd
@@ -165,6 +168,12 @@ class HardwareSerial : public Stream {
165168
bool isHalfDuplex(void) const;
166169
void enableHalfDuplexRx(void);
167170

171+
// Enable HW Rx/Tx/data inversion
172+
// This needs to be done before the call to begin()
173+
void setRxInvert(void);
174+
void setTxInvert(void);
175+
void setDataInvert(void);
176+
168177
friend class STM32LowPower;
169178

170179
// Interrupt handlers

keywords.txt

+3
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,9 @@ HALF_DUPLEX_ENABLED LITERAL1
274274
setHalfDuplex KEYWORD2
275275
isHalfDuplex KEYWORD2
276276
enableHalfDuplexRx KEYWORD2
277+
setRxInvert KEYWORD2
278+
setTxInvert KEYWORD2
279+
setDataInvert KEYWORD2
277280
Serial4 KEYWORD1
278281
Serial5 KEYWORD1
279282
Serial6 KEYWORD1

libraries/SrcWrapper/inc/uart.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#define __UART_H
3939

4040
/* Includes ------------------------------------------------------------------*/
41+
#include <stdbool.h>
4142
#include "stm32_def.h"
4243
#include "PinNames.h"
4344

@@ -254,7 +255,7 @@ struct serial_s {
254255

255256
/* Exported macro ------------------------------------------------------------*/
256257
/* Exported functions ------------------------------------------------------- */
257-
void uart_init(serial_t *obj, uint32_t baudrate, uint32_t databits, uint32_t parity, uint32_t stopbits);
258+
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);
258259
void uart_deinit(serial_t *obj);
259260
#if defined(HAL_PWR_MODULE_ENABLED) && (defined(UART_IT_WUF) || defined(LPUART1_BASE))
260261
void uart_config_lowpower(serial_t *obj);

libraries/SrcWrapper/src/stm32/uart.c

+25-5
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ serial_t *get_serial_obj(UART_HandleTypeDef *huart)
115115
* @param obj : pointer to serial_t structure
116116
* @retval None
117117
*/
118-
void uart_init(serial_t *obj, uint32_t baudrate, uint32_t databits, uint32_t parity, uint32_t stopbits)
118+
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)
119119
{
120120
if (obj == NULL) {
121121
return;
@@ -407,11 +407,31 @@ void uart_init(serial_t *obj, uint32_t baudrate, uint32_t databits, uint32_t par
407407
huart->Init.Mode = UART_MODE_TX_RX;
408408
huart->Init.HwFlowCtl = flow_control;
409409
huart->Init.OverSampling = UART_OVERSAMPLING_16;
410+
#if defined(UART_ADVFEATURE_NO_INIT)
411+
// Default value
412+
huart->AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
410413
#if defined(UART_ADVFEATURE_SWAP_INIT)
411-
huart->AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_SWAP_INIT;
414+
huart->AdvancedInit.AdvFeatureInit |= UART_ADVFEATURE_SWAP_INIT;
412415
huart->AdvancedInit.Swap = pin_swap;
413-
#elif defined(UART_ADVFEATURE_NO_INIT)
414-
huart->AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
416+
#endif
417+
#if defined(UART_ADVFEATURE_RXINVERT_INIT)
418+
if (rx_invert) {
419+
huart->AdvancedInit.AdvFeatureInit |= UART_ADVFEATURE_RXINVERT_INIT;
420+
huart->AdvancedInit.RxPinLevelInvert = UART_ADVFEATURE_RXINV_ENABLE;
421+
}
422+
#endif
423+
#if defined(UART_ADVFEATURE_TXINVERT_INIT)
424+
if (tx_invert) {
425+
huart->AdvancedInit.AdvFeatureInit |= UART_ADVFEATURE_TXINVERT_INIT;
426+
huart->AdvancedInit.TxPinLevelInvert = UART_ADVFEATURE_TXINV_ENABLE;
427+
}
428+
#endif
429+
#if defined(UART_ADVFEATURE_DATAINVERT_INIT)
430+
if (data_invert) {
431+
huart->AdvancedInit.AdvFeatureInit |= UART_ADVFEATURE_DATAINVERT_INIT;
432+
huart->AdvancedInit.DataInvert = UART_ADVFEATURE_DATAINV_ENABLE;
433+
}
434+
#endif
415435
#endif
416436
#ifdef UART_ONE_BIT_SAMPLE_DISABLE
417437
huart->Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
@@ -812,7 +832,7 @@ void uart_debug_init(void)
812832
serial_debug.pin_tx = pinmap_pin(DEBUG_UART, PinMap_UART_TX);
813833
#endif
814834
/* serial_debug.pin_rx set by default to NC to configure in half duplex mode */
815-
uart_init(&serial_debug, DEBUG_UART_BAUDRATE, UART_WORDLENGTH_8B, UART_PARITY_NONE, UART_STOPBITS_1);
835+
uart_init(&serial_debug, DEBUG_UART_BAUDRATE, UART_WORDLENGTH_8B, UART_PARITY_NONE, UART_STOPBITS_1, false, false, false);
816836
}
817837
}
818838

0 commit comments

Comments
 (0)