@@ -307,6 +307,125 @@ static bool _uartDetachBus_RTS(void *busptr) {
307
307
return _uartDetachPins (bus -> num , UART_PIN_NO_CHANGE , UART_PIN_NO_CHANGE , UART_PIN_NO_CHANGE , bus -> _rtsPin );
308
308
}
309
309
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
+
310
429
// Attach function for UART
311
430
// connects the IO Pad, set Paripheral Manager and internal UART structure data
312
431
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
319
438
//log_v("attaching UART%d pins: prev,new RX(%d,%d) TX(%d,%d) CTS(%d,%d) RTS(%d,%d)", uart_num,
320
439
// uart->_rxPin, rxPin, uart->_txPin, txPin, uart->_ctsPin, ctsPin, uart->_rtsPin, rtsPin); vTaskDelay(10);
321
440
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
323
442
// No need for Arduino Layer to check it again
324
443
bool retCode = true;
325
444
if (rxPin >= 0 ) {
@@ -328,7 +447,7 @@ static bool _uartAttachPins(uint8_t uart_num, int8_t rxPin, int8_t txPin, int8_t
328
447
perimanClearPinBus (rxPin );
329
448
}
330
449
// 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 );
332
451
#if SOC_UART_LP_NUM >= 1
333
452
if (ret && uart_num >= SOC_UART_HP_NUM ) { // it is a LP UART NUM
334
453
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
351
470
perimanClearPinBus (txPin );
352
471
}
353
472
// 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 );
355
474
#if SOC_UART_LP_NUM >= 1
356
475
if (ret && uart_num >= SOC_UART_HP_NUM ) { // it is a LP UART NUM
357
476
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
374
493
perimanClearPinBus (ctsPin );
375
494
}
376
495
// 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 );
378
497
#if SOC_UART_LP_NUM >= 1
379
498
if (ret && uart_num >= SOC_UART_HP_NUM ) { // it is a LP UART NUM
380
499
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
397
516
perimanClearPinBus (rtsPin );
398
517
}
399
518
// 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 );
401
520
#if SOC_UART_LP_NUM >= 1
402
521
if (ret && uart_num >= SOC_UART_HP_NUM ) { // it is a LP UART NUM
403
522
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) {
1414
1533
log_e ("UART%d is not supported for loopback or RX pin %d is invalid." , uartNum , rxPin );
1415
1534
return ;
1416
1535
}
1536
+ #if 0 // leave this code here for future reference and need
1417
1537
// forces rxPin to use GPIO Matrix and setup the pin to receive UART TX Signal - IDF 5.4.1 Change with uart_release_pin()
1418
1538
gpio_func_sel ((gpio_num_t )rxPin , PIN_FUNC_GPIO );
1419
1539
gpio_pullup_en ((gpio_num_t )rxPin );
1420
1540
gpio_input_enable ((gpio_num_t )rxPin );
1421
1541
esp_rom_gpio_connect_in_signal (rxPin , uart_periph_signal [uartNum ].pins [SOC_UART_RX_PIN_IDX ].signal , false);
1542
+ #endif
1422
1543
esp_rom_gpio_connect_out_signal (rxPin , uart_periph_signal [uartNum ].pins [SOC_UART_TX_PIN_IDX ].signal , false, false);
1423
1544
}
1424
1545
0 commit comments