@@ -59,6 +59,7 @@ struct uart_struct_t {
5959 bool _inverted ; // UART inverted signal
6060 uint8_t _rxfifo_full_thrhd ; // UART RX FIFO full threshold
6161 int8_t _uart_clock_source ; // UART Clock Source used when it is started using uartBegin()
62+ uint32_t inv_mask ; // UART inverse mask used to maintain related pin state
6263};
6364
6465#if CONFIG_DISABLE_HAL_LOCKS
@@ -67,21 +68,21 @@ struct uart_struct_t {
6768#define UART_MUTEX_UNLOCK ()
6869
6970static uart_t _uart_bus_array [] = {
70- {0 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 },
71+ {0 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 , 0 },
7172#if SOC_UART_NUM > 1
72- {1 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 },
73+ {1 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 , 0 },
7374#endif
7475#if SOC_UART_NUM > 2
75- {2 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 },
76+ {2 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 , 0 },
7677#endif
7778#if SOC_UART_NUM > 3
78- {3 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 },
79+ {3 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 , 0 },
7980#endif
8081#if SOC_UART_NUM > 4
81- {4 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 },
82+ {4 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 , 0 },
8283#endif
8384#if SOC_UART_NUM > 5
84- {5 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 },
85+ {5 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 , 0 },
8586#endif
8687};
8788
@@ -96,21 +97,21 @@ static uart_t _uart_bus_array[] = {
9697 xSemaphoreGive(uart->lock)
9798
9899static uart_t _uart_bus_array [] = {
99- {NULL , 0 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 },
100+ {NULL , 0 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 , 0 },
100101#if SOC_UART_NUM > 1
101- {NULL , 1 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 },
102+ {NULL , 1 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 , 0 },
102103#endif
103104#if SOC_UART_NUM > 2
104- {NULL , 2 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 },
105+ {NULL , 2 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 , 0 },
105106#endif
106107#if SOC_UART_NUM > 3
107- {NULL , 3 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 },
108+ {NULL , 3 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 , 0 },
108109#endif
109110#if SOC_UART_NUM > 4
110- {NULL , 4 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 },
111+ {NULL , 4 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 , 0 },
111112#endif
112113#if SOC_UART_NUM > 5
113- {NULL , 5 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 },
114+ {NULL , 5 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 , -1 , 0 },
114115#endif
115116};
116117
@@ -712,9 +713,15 @@ uart_t *uartBegin(
712713 if (inverted ) {
713714 // invert signal for both Rx and Tx
714715 retCode &= ESP_OK == uart_set_line_inverse (uart_nr , UART_SIGNAL_TXD_INV | UART_SIGNAL_RXD_INV );
716+ if (retCode ) {
717+ inv_mask |= UART_SIGNAL_TXD_INV | UART_SIGNAL_RXD_INV ;
718+ }
715719 } else {
716720 // disable invert signal for both Rx and Tx
717721 retCode &= ESP_OK == uart_set_line_inverse (uart_nr , UART_SIGNAL_INV_DISABLE );
722+ if (retCode ) {
723+ inv_mask &= ~(UART_SIGNAL_TXD_INV | UART_SIGNAL_RXD_INV );
724+ }
718725 }
719726 }
720727 // if all fine, set internal parameters
@@ -823,62 +830,49 @@ void uartEnd(uint8_t uart_num) {
823830 UART_MUTEX_UNLOCK ();
824831}
825832
826- void uartSetRxInvert (uart_t * uart , bool invert ) {
833+ // Helper generic function that takes a uart_sigenl_inv_t mask to be properly applied to the designated uart pin
834+ // invMask can be UART_SIGNAL_RXD_INV, UART_SIGNAL_TXD_INV, UART_SIGNAL_RTS_INV, UART_SIGNAL_CTS_INV
835+ // returns the operation success status
836+ bool _uartPinSignalInversion (uart_t * uart , uint32_t invMask , bool inverted ) {
827837 if (uart == NULL ) {
828838 return ;
829839 }
830- // POTENTIAL ISSUE :: original code only set/reset rxd_inv bit
831- // IDF or LL set/reset the whole inv_mask!
832- // if (invert)
833- // ESP_ERROR_CHECK(uart_set_line_inverse(uart->num, UART_SIGNAL_RXD_INV));
834- // else
835- // ESP_ERROR_CHECK(uart_set_line_inverse(uart->num, UART_SIGNAL_INV_DISABLE));
836- // this implementation is better over IDF API because it only affects RXD
837- uart_dev_t * hw = UART_LL_GET_HW (uart -> num );
838-
839- #if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4
840- if (invert ) {
841- hw -> conf0_sync .rxd_inv = 1 ;
842- } else {
843- hw -> conf0_sync .rxd_inv = 0 ;
844- }
845- #else
846- // this is supported in ESP32, ESP32-S2 and ESP32-C3
847- if (invert ) {
848- hw -> conf0 .rxd_inv = 1 ;
840+ bool retCode = true;
841+ uint32_t _inv_mask = inv_mask ;
842+ if (inverted ) {
843+ _inv_mask |= invMask ;
844+ retCode = ESP_OK == uart_set_line_inverse (uart -> num , _inv_mask );
845+ if (retCode ) {
846+ inv_mask = _inv_mask ;
847+ } else {
848+ retCode = false;
849+ }
849850 } else {
850- hw -> conf0 .rxd_inv = 0 ;
851+ _inv_mask &= ~invMask ;
852+ retCode = ESP_OK == uart_set_line_inverse (uart -> num , _inv_mask );
853+ if (retCode ) {
854+ inv_mask = _inv_mask ;
855+ } else {
856+ retCode = false;
857+ }
851858 }
852- #endif
859+ return retCode ;
853860}
854861
855- void uartSetTxInvert (uart_t * uart , bool invert ) {
856- if (uart == NULL ) {
857- return ;
858- }
859- // POTENTIAL ISSUE :: original code only set/reset txd_inv bit
860- // IDF or LL set/reset the whole inv_mask!
861- // if (invert)
862- // ESP_ERROR_CHECK(uart_set_line_inverse(uart->num, UART_SIGNAL_TXD_INV));
863- // else
864- // ESP_ERROR_CHECK(uart_set_line_inverse(uart->num, UART_SIGNAL_INV_DISABLE));
865- // this implementation is better over IDF API because it only affects TXD
866- uart_dev_t * hw = UART_LL_GET_HW (uart -> num );
862+ bool uartSetRxInvert (uart_t * uart , bool invert ) {
863+ return _uartPinSignalInversion (uart , UART_SIGNAL_RXD_INV , invert );
864+ }
867865
868- #if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4
869- if (invert ) {
870- hw -> conf0_sync .txd_inv = 1 ;
871- } else {
872- hw -> conf0_sync .txd_inv = 0 ;
873- }
874- #else
875- // this is supported in ESP32, ESP32-S2 and ESP32-C3
876- if (invert ) {
877- hw -> conf0 .txd_inv = 1 ;
878- } else {
879- hw -> conf0 .txd_inv = 0 ;
880- }
881- #endif
866+ bool uartSetTxInvert (uart_t * uart , bool invert ) {
867+ return _uartPinSignalInversion (uart , UART_SIGNAL_RXD_INV , invert );
868+ }
869+
870+ bool uartSetCtsInvert (uart_t * uart , bool invert ) {
871+ return _uartPinSignalInversion (uart , UART_SIGNAL_CTS_INV , invert );
872+ }
873+
874+ bool uartSetRtsInvert (uart_t * uart , bool invert ) {
875+ return _uartPinSignalInversion (uart , UART_SIGNAL_RTS_INV , invert );
882876}
883877
884878uint32_t uartAvailable (uart_t * uart ) {
0 commit comments