Skip to content

Commit c1b212f

Browse files
committed
Merge branch 'release/v3.3.x' of https://github.com/espressif/arduino-esp32 into idf-release/v5.5
2 parents 23e2d95 + febca6b commit c1b212f

File tree

2 files changed

+128
-7
lines changed

2 files changed

+128
-7
lines changed

cores/esp32/esp32-hal-uart.c

Lines changed: 126 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,125 @@ static bool _uartDetachBus_RTS(void *busptr) {
307307
return _uartDetachPins(bus->num, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, bus->_rtsPin);
308308
}
309309

310+
static bool _uartTrySetIomuxPin(uart_port_t uart_num, int io_num, uint32_t idx) {
311+
// Store a pointer to the default pin, to optimize access to its fields.
312+
const uart_periph_sig_t *upin = &uart_periph_signal[uart_num].pins[idx];
313+
314+
// In theory, if default_gpio is -1, iomux_func should also be -1, but let's be safe and test both.
315+
if (upin->iomux_func == -1 || upin->default_gpio == -1 || upin->default_gpio != io_num) {
316+
return false;
317+
}
318+
319+
// Assign the correct function to the GPIO.
320+
assert(upin->iomux_func != -1);
321+
if (uart_num < SOC_UART_HP_NUM) {
322+
gpio_iomux_out(io_num, upin->iomux_func, false);
323+
// If the pin is input, we also have to redirect the signal, in order to bypass the GPIO matrix.
324+
if (upin->input) {
325+
gpio_iomux_in(io_num, upin->signal);
326+
}
327+
}
328+
#if (SOC_UART_LP_NUM >= 1) && (SOC_RTCIO_PIN_COUNT >= 1)
329+
else {
330+
if (upin->input) {
331+
rtc_gpio_set_direction(io_num, RTC_GPIO_MODE_INPUT_ONLY);
332+
} else {
333+
rtc_gpio_set_direction(io_num, RTC_GPIO_MODE_OUTPUT_ONLY);
334+
}
335+
rtc_gpio_init(io_num);
336+
rtc_gpio_iomux_func_sel(io_num, upin->iomux_func);
337+
}
338+
#endif
339+
return true;
340+
}
341+
342+
static esp_err_t _uartInternalSetPin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int rts_io_num, int cts_io_num) {
343+
// Since an IO cannot route peripheral signals via IOMUX and GPIO matrix at the same time,
344+
// if tx and rx share the same IO, both signals need to be routed to IOs through GPIO matrix
345+
bool tx_rx_same_io = (tx_io_num == rx_io_num);
346+
347+
// In the following statements, if the io_num is negative, no need to configure anything.
348+
if (tx_io_num >= 0) {
349+
#if CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND || CONFIG_PM_SLP_DISABLE_GPIO
350+
// In such case, IOs are going to switch to sleep configuration (isolate) when entering sleep for power saving reason
351+
// But TX IO in isolate state could write garbled data to the other end
352+
// Therefore, we should disable the switch of the TX pin to sleep configuration
353+
gpio_sleep_sel_dis(tx_io_num);
354+
#endif
355+
if (tx_rx_same_io || !_uartTrySetIomuxPin(uart_num, tx_io_num, SOC_UART_TX_PIN_IDX)) {
356+
if (uart_num < SOC_UART_HP_NUM) {
357+
gpio_func_sel(tx_io_num, PIN_FUNC_GPIO);
358+
esp_rom_gpio_connect_out_signal(tx_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_TX_PIN_IDX), 0, 0);
359+
// output enable is set inside esp_rom_gpio_connect_out_signal func after the signal is connected
360+
// (output enabled too early may cause unnecessary level change at the pad)
361+
}
362+
#if SOC_LP_GPIO_MATRIX_SUPPORTED
363+
else {
364+
rtc_gpio_init(tx_io_num); // set as a LP_GPIO pin
365+
lp_gpio_connect_out_signal(tx_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_TX_PIN_IDX), 0, 0);
366+
// output enable is set inside lp_gpio_connect_out_signal func after the signal is connected
367+
}
368+
#endif
369+
}
370+
}
371+
372+
if (rx_io_num >= 0) {
373+
#if CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND || CONFIG_PM_SLP_DISABLE_GPIO
374+
// In such case, IOs are going to switch to sleep configuration (isolate) when entering sleep for power saving reason
375+
// But RX IO in isolate state could receive garbled data into FIFO, which is not desired
376+
// Therefore, we should disable the switch of the RX pin to sleep configuration
377+
gpio_sleep_sel_dis(rx_io_num);
378+
#endif
379+
if (tx_rx_same_io || !_uartTrySetIomuxPin(uart_num, rx_io_num, SOC_UART_RX_PIN_IDX)) {
380+
if (uart_num < SOC_UART_HP_NUM) {
381+
gpio_input_enable(rx_io_num);
382+
esp_rom_gpio_connect_in_signal(rx_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_RX_PIN_IDX), 0);
383+
}
384+
#if SOC_LP_GPIO_MATRIX_SUPPORTED
385+
else {
386+
rtc_gpio_mode_t mode = (tx_rx_same_io ? RTC_GPIO_MODE_INPUT_OUTPUT : RTC_GPIO_MODE_INPUT_ONLY);
387+
rtc_gpio_set_direction(rx_io_num, mode);
388+
if (!tx_rx_same_io) { // set the same pin again as a LP_GPIO will overwrite connected out_signal, not desired, so skip
389+
rtc_gpio_init(rx_io_num); // set as a LP_GPIO pin
390+
}
391+
lp_gpio_connect_in_signal(rx_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_RX_PIN_IDX), 0);
392+
}
393+
#endif
394+
}
395+
}
396+
397+
if (rts_io_num >= 0 && !_uartTrySetIomuxPin(uart_num, rts_io_num, SOC_UART_RTS_PIN_IDX)) {
398+
if (uart_num < SOC_UART_HP_NUM) {
399+
gpio_func_sel(rts_io_num, PIN_FUNC_GPIO);
400+
esp_rom_gpio_connect_out_signal(rts_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_RTS_PIN_IDX), 0, 0);
401+
// output enable is set inside esp_rom_gpio_connect_out_signal func after the signal is connected
402+
}
403+
#if SOC_LP_GPIO_MATRIX_SUPPORTED
404+
else {
405+
rtc_gpio_init(rts_io_num); // set as a LP_GPIO pin
406+
lp_gpio_connect_out_signal(rts_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_RTS_PIN_IDX), 0, 0);
407+
// output enable is set inside lp_gpio_connect_out_signal func after the signal is connected
408+
}
409+
#endif
410+
}
411+
412+
if (cts_io_num >= 0 && !_uartTrySetIomuxPin(uart_num, cts_io_num, SOC_UART_CTS_PIN_IDX)) {
413+
if (uart_num < SOC_UART_HP_NUM) {
414+
gpio_pullup_en(cts_io_num);
415+
gpio_input_enable(cts_io_num);
416+
esp_rom_gpio_connect_in_signal(cts_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_CTS_PIN_IDX), 0);
417+
}
418+
#if SOC_LP_GPIO_MATRIX_SUPPORTED
419+
else {
420+
rtc_gpio_set_direction(cts_io_num, RTC_GPIO_MODE_INPUT_ONLY);
421+
rtc_gpio_init(cts_io_num); // set as a LP_GPIO pin
422+
lp_gpio_connect_in_signal(cts_io_num, UART_PERIPH_SIGNAL(uart_num, SOC_UART_CTS_PIN_IDX), 0);
423+
}
424+
#endif
425+
}
426+
return ESP_OK;
427+
}
428+
310429
// Attach function for UART
311430
// connects the IO Pad, set Paripheral Manager and internal UART structure data
312431
static bool _uartAttachPins(uint8_t uart_num, int8_t rxPin, int8_t txPin, int8_t ctsPin, int8_t rtsPin) {
@@ -319,7 +438,7 @@ static bool _uartAttachPins(uint8_t uart_num, int8_t rxPin, int8_t txPin, int8_t
319438
//log_v("attaching UART%d pins: prev,new RX(%d,%d) TX(%d,%d) CTS(%d,%d) RTS(%d,%d)", uart_num,
320439
// uart->_rxPin, rxPin, uart->_txPin, txPin, uart->_ctsPin, ctsPin, uart->_rtsPin, rtsPin); vTaskDelay(10);
321440

322-
// IDF uart_set_pin() checks if the pin is used within LP UART and if it is a valid RTC IO pin
441+
// IDF _uartInternalSetPin() checks if the pin is used within LP UART and if it is a valid RTC IO pin
323442
// No need for Arduino Layer to check it again
324443
bool retCode = true;
325444
if (rxPin >= 0) {
@@ -328,7 +447,7 @@ static bool _uartAttachPins(uint8_t uart_num, int8_t rxPin, int8_t txPin, int8_t
328447
perimanClearPinBus(rxPin);
329448
}
330449
// connect RX Pad
331-
bool ret = ESP_OK == uart_set_pin(uart->num, UART_PIN_NO_CHANGE, rxPin, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
450+
bool ret = ESP_OK == _uartInternalSetPin(uart->num, UART_PIN_NO_CHANGE, rxPin, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
332451
#if SOC_UART_LP_NUM >= 1
333452
if (ret && uart_num >= SOC_UART_HP_NUM) { // it is a LP UART NUM
334453
ret &= lp_uart_config_io(uart->num, rxPin, RTC_GPIO_MODE_INPUT_ONLY, SOC_UART_RX_PIN_IDX);
@@ -351,7 +470,7 @@ static bool _uartAttachPins(uint8_t uart_num, int8_t rxPin, int8_t txPin, int8_t
351470
perimanClearPinBus(txPin);
352471
}
353472
// connect TX Pad
354-
bool ret = ESP_OK == uart_set_pin(uart->num, txPin, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
473+
bool ret = ESP_OK == _uartInternalSetPin(uart->num, txPin, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
355474
#if SOC_UART_LP_NUM >= 1
356475
if (ret && uart_num >= SOC_UART_HP_NUM) { // it is a LP UART NUM
357476
ret &= lp_uart_config_io(uart->num, txPin, RTC_GPIO_MODE_OUTPUT_ONLY, SOC_UART_TX_PIN_IDX);
@@ -374,7 +493,7 @@ static bool _uartAttachPins(uint8_t uart_num, int8_t rxPin, int8_t txPin, int8_t
374493
perimanClearPinBus(ctsPin);
375494
}
376495
// connect CTS Pad
377-
bool ret = ESP_OK == uart_set_pin(uart->num, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, ctsPin);
496+
bool ret = ESP_OK == _uartInternalSetPin(uart->num, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, ctsPin);
378497
#if SOC_UART_LP_NUM >= 1
379498
if (ret && uart_num >= SOC_UART_HP_NUM) { // it is a LP UART NUM
380499
ret &= lp_uart_config_io(uart->num, ctsPin, RTC_GPIO_MODE_INPUT_ONLY, SOC_UART_CTS_PIN_IDX);
@@ -397,7 +516,7 @@ static bool _uartAttachPins(uint8_t uart_num, int8_t rxPin, int8_t txPin, int8_t
397516
perimanClearPinBus(rtsPin);
398517
}
399518
// connect RTS Pad
400-
bool ret = ESP_OK == uart_set_pin(uart->num, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, rtsPin, UART_PIN_NO_CHANGE);
519+
bool ret = ESP_OK == _uartInternalSetPin(uart->num, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, rtsPin, UART_PIN_NO_CHANGE);
401520
#if SOC_UART_LP_NUM >= 1
402521
if (ret && uart_num >= SOC_UART_HP_NUM) { // it is a LP UART NUM
403522
ret &= lp_uart_config_io(uart->num, rtsPin, RTC_GPIO_MODE_OUTPUT_ONLY, SOC_UART_RTS_PIN_IDX);
@@ -1414,11 +1533,13 @@ void uart_internal_loopback(uint8_t uartNum, int8_t rxPin) {
14141533
log_e("UART%d is not supported for loopback or RX pin %d is invalid.", uartNum, rxPin);
14151534
return;
14161535
}
1536+
#if 0 // leave this code here for future reference and need
14171537
// forces rxPin to use GPIO Matrix and setup the pin to receive UART TX Signal - IDF 5.4.1 Change with uart_release_pin()
14181538
gpio_func_sel((gpio_num_t)rxPin, PIN_FUNC_GPIO);
14191539
gpio_pullup_en((gpio_num_t)rxPin);
14201540
gpio_input_enable((gpio_num_t)rxPin);
14211541
esp_rom_gpio_connect_in_signal(rxPin, uart_periph_signal[uartNum].pins[SOC_UART_RX_PIN_IDX].signal, false);
1542+
#endif
14221543
esp_rom_gpio_connect_out_signal(rxPin, uart_periph_signal[uartNum].pins[SOC_UART_TX_PIN_IDX].signal, false, false);
14231544
}
14241545

idf_component.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,11 +107,11 @@ dependencies:
107107
rules:
108108
- if: "target in [esp32s3]"
109109
espressif/esp_hosted:
110-
version: "^2.0.0"
110+
version: "^2.0.12"
111111
rules:
112112
- if: "target == esp32p4"
113113
espressif/esp_wifi_remote:
114-
version: "~0.9.2"
114+
version: "^0.13.0"
115115
rules:
116116
- if: "target == esp32p4"
117117
espressif/libsodium:

0 commit comments

Comments
 (0)