@@ -60,6 +60,7 @@ struct uart_struct_t {
6060 bool _inverted ; // UART inverted signal
6161 uint8_t _rxfifo_full_thrhd ; // UART RX FIFO full threshold
6262 int8_t _uart_clock_source ; // UART Clock Source that should be used if user defines an specific one with setClockSource()
63+ uint32_t inv_mask ; // UART inverse mask used to maintain related pin state
6364};
6465
6566#if CONFIG_DISABLE_HAL_LOCKS
@@ -68,21 +69,21 @@ struct uart_struct_t {
6869#define UART_MUTEX_UNLOCK ()
6970
7071static uart_t _uart_bus_array [] = {
71- {0 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 },
72+ {0 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 , 0 },
7273#if SOC_UART_NUM > 1
73- {1 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 },
74+ {1 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 , 0 },
7475#endif
7576#if SOC_UART_NUM > 2
76- {2 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 },
77+ {2 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 , 0 },
7778#endif
7879#if SOC_UART_NUM > 3
79- {3 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 },
80+ {3 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 , 0 },
8081#endif
8182#if SOC_UART_NUM > 4
82- {4 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 },
83+ {4 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 , 0 },
8384#endif
8485#if SOC_UART_NUM > 5
85- {5 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 },
86+ {5 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 , 0 },
8687#endif
8788};
8889
@@ -97,21 +98,21 @@ static uart_t _uart_bus_array[] = {
9798 xSemaphoreGive(uart->lock)
9899
99100static uart_t _uart_bus_array [] = {
100- {NULL , 0 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 },
101+ {NULL , 0 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 , 0 },
101102#if SOC_UART_NUM > 1
102- {NULL , 1 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 },
103+ {NULL , 1 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 , 0 },
103104#endif
104105#if SOC_UART_NUM > 2
105- {NULL , 2 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 },
106+ {NULL , 2 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 , 0 },
106107#endif
107108#if SOC_UART_NUM > 3
108- {NULL , 3 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 },
109+ {NULL , 3 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 , 0 },
109110#endif
110111#if SOC_UART_NUM > 4
111- {NULL , 4 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 },
112+ {NULL , 4 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 , 0 },
112113#endif
113114#if SOC_UART_NUM > 5
114- {NULL , 5 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 },
115+ {NULL , 5 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 , 0 },
115116#endif
116117};
117118
@@ -873,10 +874,20 @@ uart_t *uartBegin(
873874 if (retCode ) {
874875 if (inverted ) {
875876 // invert signal for both Rx and Tx
876- retCode &= ESP_OK == uart_set_line_inverse (uart_nr , UART_SIGNAL_TXD_INV | UART_SIGNAL_RXD_INV );
877+ uint32_t _inv_mask = uart -> inv_mask ;
878+ _inv_mask |= UART_SIGNAL_TXD_INV | UART_SIGNAL_RXD_INV ;
879+ retCode &= ESP_OK == uart_set_line_inverse (uart_nr , _inv_mask );
880+ if (retCode ) {
881+ uart -> inv_mask = _inv_mask ;
882+ log_v ("UART%d: RX and TX signals are set to be inverted." , uart_nr );
883+ }
877884 } else {
878885 // disable invert signal for both Rx and Tx
879886 retCode &= ESP_OK == uart_set_line_inverse (uart_nr , UART_SIGNAL_INV_DISABLE );
887+ if (retCode ) {
888+ uart -> inv_mask = UART_SIGNAL_INV_DISABLE ;
889+ log_v ("UART%d: RX and TX signals are set not inverted." , uart_nr );
890+ }
880891 }
881892 }
882893 // if all fine, set internal parameters
@@ -978,28 +989,58 @@ void uartEnd(uint8_t uart_num) {
978989 UART_MUTEX_UNLOCK ();
979990}
980991
981- void uartSetRxInvert (uart_t * uart , bool invert ) {
992+ // Helper generic function that takes a uart_signal_inv_t mask to be properly applied to the designated uart pin
993+ // invMask can be UART_SIGNAL_RXD_INV, UART_SIGNAL_TXD_INV, UART_SIGNAL_RTS_INV, UART_SIGNAL_CTS_INV
994+ // returns the operation success status
995+ bool uartPinSignalInversion (uart_t * uart , uint32_t invMask , bool inverted ) {
982996 if (uart == NULL ) {
983- return ;
997+ return false ;
984998 }
985- #if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5
986- // POTENTIAL ISSUE :: original code only set/reset rxd_inv bit
987- // IDF or LL set/reset the whole inv_mask!
988- // if (invert)
989- // ESP_ERROR_CHECK(uart_set_line_inverse(uart->num, UART_SIGNAL_RXD_INV));
990- // else
991- // ESP_ERROR_CHECK(uart_set_line_inverse(uart->num, UART_SIGNAL_INV_DISABLE));
992- log_e ("uartSetRxInvert is not supported in ESP32C6, ESP32H2 and ESP32P4" );
993- #else
994- // this implementation is better over IDF API because it only affects RXD
995- // this is supported in ESP32, ESP32-S2 and ESP32-C3
996- uart_dev_t * hw = UART_LL_GET_HW (uart -> num );
997- if (invert ) {
998- hw -> conf0 .rxd_inv = 1 ;
999+ UART_MUTEX_LOCK ();
1000+ uint32_t _inv_mask = uart -> inv_mask ;
1001+ if (inverted ) {
1002+ _inv_mask |= invMask ;
9991003 } else {
1000- hw -> conf0 . rxd_inv = 0 ;
1004+ _inv_mask &= ~ invMask ;
10011005 }
1002- #endif
1006+ bool retCode = ESP_OK == uart_set_line_inverse (uart -> num , _inv_mask );
1007+ if (retCode ) {
1008+ uart -> inv_mask = _inv_mask ;
1009+ }
1010+ UART_MUTEX_UNLOCK ();
1011+ return retCode ;
1012+ }
1013+
1014+ bool uartSetRxInvert (uart_t * uart , bool invert ) {
1015+ if (uartPinSignalInversion (uart , UART_SIGNAL_RXD_INV , invert )) {
1016+ log_v ("UART%d: RX signal inversion %s" , uart -> num , invert ? "enabled" : "disabled" );
1017+ return true;
1018+ }
1019+ return false;
1020+ }
1021+
1022+ bool uartSetTxInvert (uart_t * uart , bool invert ) {
1023+ if (uartPinSignalInversion (uart , UART_SIGNAL_TXD_INV , invert )) {
1024+ log_v ("UART%d: TX signal inversion %s" , uart -> num , invert ? "enabled" : "disabled" );
1025+ return true;
1026+ }
1027+ return false;
1028+ }
1029+
1030+ bool uartSetCtsInvert (uart_t * uart , bool invert ) {
1031+ if (uartPinSignalInversion (uart , UART_SIGNAL_CTS_INV , invert )) {
1032+ log_v ("UART%d: CTS signal inversion %s" , uart -> num , invert ? "enabled" : "disabled" );
1033+ return true;
1034+ }
1035+ return false;
1036+ }
1037+
1038+ bool uartSetRtsInvert (uart_t * uart , bool invert ) {
1039+ if (uartPinSignalInversion (uart , UART_SIGNAL_RTS_INV , invert )) {
1040+ log_v ("UART%d: RTS signal inversion %s" , uart -> num , invert ? "enabled" : "disabled" );
1041+ return true;
1042+ }
1043+ return false;
10031044}
10041045
10051046uint32_t uartAvailable (uart_t * uart ) {
0 commit comments