Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit2905b3f

Browse files
authored
Merge branch 'espressif:master' into master
2 parentsa61e15d +9d84c78 commit2905b3f

File tree

1 file changed

+137
-40
lines changed

1 file changed

+137
-40
lines changed

‎cores/esp32/esp32-hal-uart.c‎

Lines changed: 137 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,11 @@
3232
#include"driver/gpio.h"
3333
#include"hal/gpio_hal.h"
3434
#include"esp_rom_gpio.h"
35+
#include"esp_private/gpio.h"
3536

3637
#include"driver/rtc_io.h"
3738
#include"driver/lp_io.h"
38-
#include"soc/uart_periph.h"
39+
#include"soc/uart_pins.h"
3940
#include"esp_private/uart_share_hw_ctrl.h"
4041

4142
staticints_uart_debug_nr=0;// UART number for debug output
@@ -294,6 +295,125 @@ static bool _uartDetachBus_RTS(void *busptr) {
294295
return_uartDetachPins(bus->num,UART_PIN_NO_CHANGE,UART_PIN_NO_CHANGE,UART_PIN_NO_CHANGE,bus->_rtsPin);
295296
}
296297

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

309-
// IDFuart_set_pin() checks if the pin is used within LP UART and if it is a valid RTC IO pin
429+
// IDF_uartInternalSetPin() checks if the pin is used within LP UART and if it is a valid RTC IO pin
310430
// No need for Arduino Layer to check it again
311431
boolretCode= true;
312432
if (rxPin >=0) {
@@ -315,7 +435,7 @@ static bool _uartAttachPins(uint8_t uart_num, int8_t rxPin, int8_t txPin, int8_t
315435
perimanClearPinBus(rxPin);
316436
}
317437
// connect RX Pad
318-
boolret=ESP_OK==uart_set_pin(uart->num,UART_PIN_NO_CHANGE,rxPin,UART_PIN_NO_CHANGE,UART_PIN_NO_CHANGE);
438+
boolret=ESP_OK==_uartInternalSetPin(uart->num,UART_PIN_NO_CHANGE,rxPin,UART_PIN_NO_CHANGE,UART_PIN_NO_CHANGE);
319439
#ifSOC_UART_LP_NUM >=1
320440
if (ret&&uart_num >=SOC_UART_HP_NUM) {// it is a LP UART NUM
321441
ret &=lp_uart_config_io(uart->num,rxPin,RTC_GPIO_MODE_INPUT_ONLY,SOC_UART_RX_PIN_IDX);
@@ -338,7 +458,7 @@ static bool _uartAttachPins(uint8_t uart_num, int8_t rxPin, int8_t txPin, int8_t
338458
perimanClearPinBus(txPin);
339459
}
340460
// connect TX Pad
341-
boolret=ESP_OK==uart_set_pin(uart->num,txPin,UART_PIN_NO_CHANGE,UART_PIN_NO_CHANGE,UART_PIN_NO_CHANGE);
461+
boolret=ESP_OK==_uartInternalSetPin(uart->num,txPin,UART_PIN_NO_CHANGE,UART_PIN_NO_CHANGE,UART_PIN_NO_CHANGE);
342462
#ifSOC_UART_LP_NUM >=1
343463
if (ret&&uart_num >=SOC_UART_HP_NUM) {// it is a LP UART NUM
344464
ret &=lp_uart_config_io(uart->num,txPin,RTC_GPIO_MODE_OUTPUT_ONLY,SOC_UART_TX_PIN_IDX);
@@ -361,7 +481,7 @@ static bool _uartAttachPins(uint8_t uart_num, int8_t rxPin, int8_t txPin, int8_t
361481
perimanClearPinBus(ctsPin);
362482
}
363483
// connect CTS Pad
364-
boolret=ESP_OK==uart_set_pin(uart->num,UART_PIN_NO_CHANGE,UART_PIN_NO_CHANGE,UART_PIN_NO_CHANGE,ctsPin);
484+
boolret=ESP_OK==_uartInternalSetPin(uart->num,UART_PIN_NO_CHANGE,UART_PIN_NO_CHANGE,UART_PIN_NO_CHANGE,ctsPin);
365485
#ifSOC_UART_LP_NUM >=1
366486
if (ret&&uart_num >=SOC_UART_HP_NUM) {// it is a LP UART NUM
367487
ret &=lp_uart_config_io(uart->num,ctsPin,RTC_GPIO_MODE_INPUT_ONLY,SOC_UART_CTS_PIN_IDX);
@@ -384,7 +504,7 @@ static bool _uartAttachPins(uint8_t uart_num, int8_t rxPin, int8_t txPin, int8_t
384504
perimanClearPinBus(rtsPin);
385505
}
386506
// connect RTS Pad
387-
boolret=ESP_OK==uart_set_pin(uart->num,UART_PIN_NO_CHANGE,UART_PIN_NO_CHANGE,rtsPin,UART_PIN_NO_CHANGE);
507+
boolret=ESP_OK==_uartInternalSetPin(uart->num,UART_PIN_NO_CHANGE,UART_PIN_NO_CHANGE,rtsPin,UART_PIN_NO_CHANGE);
388508
#ifSOC_UART_LP_NUM >=1
389509
if (ret&&uart_num >=SOC_UART_HP_NUM) {// it is a LP UART NUM
390510
ret &=lp_uart_config_io(uart->num,rtsPin,RTC_GPIO_MODE_OUTPUT_ONLY,SOC_UART_RTS_PIN_IDX);
@@ -1383,39 +1503,9 @@ unsigned long uartDetectBaudrate(uart_t *uart) {
13831503
}
13841504

13851505
/*
1386-
These functions are for testing purpose only and can be used in Arduino Sketches
1387-
Those are used in the UART examples
1388-
*/
1389-
1390-
/*
1391-
This is intended to make an internal loopback connection using IOMUX
1392-
The function uart_internal_loopback() shall be used right after Arduino Serial.begin(...)
1393-
This code "replaces" the physical wiring for connecting TX <--> RX in a loopback
1394-
*/
1395-
1396-
// gets the right TX or RX SIGNAL, based on the UART number from gpio_sig_map.h
1397-
#ifdefCONFIG_IDF_TARGET_ESP32P4
1398-
#defineUART_TX_SIGNAL(uartNumber) \
1399-
(uartNumber == UART_NUM_0 \
1400-
? UART0_TXD_PAD_OUT_IDX \
1401-
: (uartNumber == UART_NUM_1 \
1402-
? UART1_TXD_PAD_OUT_IDX \
1403-
: (uartNumber == UART_NUM_2 ? UART2_TXD_PAD_OUT_IDX : (uartNumber == UART_NUM_3 ? UART3_TXD_PAD_OUT_IDX : UART4_TXD_PAD_OUT_IDX))))
1404-
#defineUART_RX_SIGNAL(uartNumber) \
1405-
(uartNumber == UART_NUM_0 \
1406-
? UART0_RXD_PAD_IN_IDX \
1407-
: (uartNumber == UART_NUM_1 \
1408-
? UART1_RXD_PAD_IN_IDX \
1409-
: (uartNumber == UART_NUM_2 ? UART2_RXD_PAD_IN_IDX : (uartNumber == UART_NUM_3 ? UART3_RXD_PAD_IN_IDX : UART4_RXD_PAD_IN_IDX))))
1410-
#else
1411-
#ifSOC_UART_HP_NUM>2
1412-
#defineUART_TX_SIGNAL(uartNumber) (uartNumber == UART_NUM_0 ? U0TXD_OUT_IDX : (uartNumber == UART_NUM_1 ? U1TXD_OUT_IDX : U2TXD_OUT_IDX))
1413-
#defineUART_RX_SIGNAL(uartNumber) (uartNumber == UART_NUM_0 ? U0RXD_IN_IDX : (uartNumber == UART_NUM_1 ? U1RXD_IN_IDX : U2RXD_IN_IDX))
1414-
#else
1415-
#defineUART_TX_SIGNAL(uartNumber) (uartNumber == UART_NUM_0 ? U0TXD_OUT_IDX : U1TXD_OUT_IDX)
1416-
#defineUART_RX_SIGNAL(uartNumber) (uartNumber == UART_NUM_0 ? U0RXD_IN_IDX : U1RXD_IN_IDX)
1417-
#endif
1418-
#endif// ifdef CONFIG_IDF_TARGET_ESP32P4
1506+
* These functions are for testing purposes only and can be used in Arduino Sketches.
1507+
* They are utilized in the UART examples and CI.
1508+
*/
14191509

14201510
/*
14211511
This function internally binds defined UARTs TX signal with defined RX pin of any UART (same or different).
@@ -1427,7 +1517,14 @@ void uart_internal_loopback(uint8_t uartNum, int8_t rxPin) {
14271517
log_e("UART%d is not supported for loopback or RX pin %d is invalid.",uartNum,rxPin);
14281518
return;
14291519
}
1430-
esp_rom_gpio_connect_out_signal(rxPin,UART_TX_SIGNAL(uartNum), false, false);
1520+
#if0// leave this code here for future reference and need
1521+
// forces rxPin to use GPIO Matrix and setup the pin to receive UART TX Signal - IDF 5.4.1 Change with uart_release_pin()
1522+
gpio_func_sel((gpio_num_t)rxPin,PIN_FUNC_GPIO);
1523+
gpio_pullup_en((gpio_num_t)rxPin);
1524+
gpio_input_enable((gpio_num_t)rxPin);
1525+
esp_rom_gpio_connect_in_signal(rxPin,uart_periph_signal[uartNum].pins[SOC_UART_RX_PIN_IDX].signal, false);
1526+
#endif
1527+
esp_rom_gpio_connect_out_signal(rxPin,uart_periph_signal[uartNum].pins[SOC_UART_TX_PIN_IDX].signal, false, false);
14311528
}
14321529

14331530
/*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp