Skip to content

Commit 119082f

Browse files
authored
feat(uart): Refactor UART signal inversion handling
Refactor UART inversion functions to use a helper for signal inversion. Update UART bus array structure to include inversion mask.
1 parent 948c485 commit 119082f

File tree

1 file changed

+54
-60
lines changed

1 file changed

+54
-60
lines changed

cores/esp32/esp32-hal-uart.c

Lines changed: 54 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -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

6970
static 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

9899
static 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

884878
uint32_t uartAvailable(uart_t *uart) {

0 commit comments

Comments
 (0)