14
14
15
15
#include "esp32-hal-uart.h"
16
16
17
+ #define SOC_UART_SUPPORTED 1
17
18
#if SOC_UART_SUPPORTED
18
19
#include "esp32-hal.h"
19
20
#include "esp32-hal-periman.h"
33
34
#include "hal/gpio_hal.h"
34
35
#include "esp_rom_gpio.h"
35
36
36
- static int s_uart_debug_nr = 0 ;
37
+ static int s_uart_debug_nr = 0 ; // UART number for debug output
37
38
38
39
struct uart_struct_t {
39
40
40
41
#if !CONFIG_DISABLE_HAL_LOCKS
41
- SemaphoreHandle_t lock ;
42
+ SemaphoreHandle_t lock ; // UART lock
42
43
#endif
43
44
44
- uint8_t num ;
45
- bool has_peek ;
46
- uint8_t peek_byte ;
47
- QueueHandle_t uart_event_queue ; // export it by some uartGetEventQueue() function
48
- int8_t _rxPin , _txPin , _ctsPin , _rtsPin ; // UART GPIOs
45
+ uint8_t num ; // UART number for IDF driver API
46
+ bool has_peek ; // flag to indicate that there is a peek byte pending to be read
47
+ uint8_t peek_byte ; // peek byte that has been read but not consumed
48
+ QueueHandle_t uart_event_queue ; // export it by some uartGetEventQueue() function
49
+ // configuration data:: Arduino API tipical data
50
+ int8_t _rxPin , _txPin , _ctsPin , _rtsPin ; // UART GPIOs
51
+ uint32_t _baudrate , _config ; // UART baudrate and config
52
+ // UART ESP32 specific data
53
+ uint16_t _rx_buffer_size , _tx_buffer_size ; // UART RX and TX buffer sizes
54
+ bool _inverted ; // UART inverted signal
55
+ uint8_t _rxfifo_full_thrhd ; // UART RX FIFO full threshold
49
56
};
50
57
51
58
#if CONFIG_DISABLE_HAL_LOCKS
@@ -54,12 +61,12 @@ struct uart_struct_t {
54
61
#define UART_MUTEX_UNLOCK ()
55
62
56
63
static uart_t _uart_bus_array [] = {
57
- {0 , false, 0 , NULL , -1 , -1 , -1 , -1 },
64
+ {0 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 },
58
65
#if SOC_UART_NUM > 1
59
- {1 , false, 0 , NULL , -1 , -1 , -1 , -1 },
66
+ {1 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 },
60
67
#endif
61
68
#if SOC_UART_NUM > 2
62
- {2 , false, 0 , NULL , -1 , -1 , -1 , -1 },
69
+ {2 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 },
63
70
#endif
64
71
};
65
72
@@ -69,12 +76,12 @@ static uart_t _uart_bus_array[] = {
69
76
#define UART_MUTEX_UNLOCK () if(uart->lock != NULL) xSemaphoreGive(uart->lock)
70
77
71
78
static uart_t _uart_bus_array [] = {
72
- {NULL , 0 , false, 0 , NULL , -1 , -1 , -1 , -1 },
79
+ {NULL , 0 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 },
73
80
#if SOC_UART_NUM > 1
74
- {NULL , 1 , false, 0 , NULL , -1 , -1 , -1 , -1 },
81
+ {NULL , 1 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 },
75
82
#endif
76
83
#if SOC_UART_NUM > 2
77
- {NULL , 2 , false, 0 , NULL , -1 , -1 , -1 , -1 },
84
+ {NULL , 2 , false, 0 , NULL , -1 , -1 , -1 , -1 , 0 , 0 , 0 , 0 , false, 0 },
78
85
#endif
79
86
};
80
87
@@ -97,7 +104,12 @@ static bool _uartDetachPins(uint8_t uart_num, int8_t rxPin, int8_t txPin, int8_t
97
104
// detaches pins and sets Peripheral Manager and UART information
98
105
if (rxPin >= 0 && uart -> _rxPin == rxPin && perimanGetPinBusType (rxPin ) == ESP32_BUS_TYPE_UART_RX ) {
99
106
gpio_hal_iomux_func_sel (GPIO_PIN_MUX_REG [rxPin ], PIN_FUNC_GPIO );
100
- esp_rom_gpio_connect_in_signal (GPIO_FUNC_IN_LOW , UART_PERIPH_SIGNAL (uart_num , SOC_UART_RX_PIN_IDX ), false);
107
+ // avoids cause BREAK in the UART line
108
+ if (uart -> _inverted ) {
109
+ esp_rom_gpio_connect_in_signal (GPIO_FUNC_IN_LOW , UART_PERIPH_SIGNAL (uart_num , SOC_UART_RX_PIN_IDX ), false);
110
+ } else {
111
+ esp_rom_gpio_connect_in_signal (GPIO_FUNC_IN_HIGH , UART_PERIPH_SIGNAL (uart_num , SOC_UART_RX_PIN_IDX ), false);
112
+ }
101
113
uart -> _rxPin = -1 ; // -1 means unassigned/detached
102
114
if (!perimanClearPinBus (rxPin )) {
103
115
retCode = false;
@@ -355,28 +367,121 @@ bool uartSetHwFlowCtrlMode(uart_t *uart, uart_hw_flowcontrol_t mode, uint8_t thr
355
367
return retCode ;
356
368
}
357
369
358
- uart_t * uartBegin (uint8_t uart_nr , uint32_t baudrate , uint32_t config , int8_t rxPin , int8_t txPin , uint16_t rx_buffer_size , uint16_t tx_buffer_size , bool inverted , uint8_t rxfifo_full_thrhd )
370
+ // This helper function will return true if a new IDF UART driver needs to be restarted and false if the current one can continue its execution
371
+ bool _testUartBegin (uint8_t uart_nr , uint32_t baudrate , uint32_t config , int8_t rxPin , int8_t txPin , uint16_t rx_buffer_size , uint16_t tx_buffer_size , bool inverted , uint8_t rxfifo_full_thrhd )
359
372
{
360
373
if (uart_nr >= SOC_UART_NUM ) {
361
- return NULL ;
374
+ return false; // no new driver has to be installed
362
375
}
363
376
uart_t * uart = & _uart_bus_array [uart_nr ];
364
-
377
+ // verify if is necessary to restart the UART driver
365
378
if (uart_is_driver_installed (uart_nr )) {
366
- uartEnd (uart_nr );
379
+ // some parameters can't be changed unless we end the UART driver
380
+ if ( uart -> _rx_buffer_size != rx_buffer_size || uart -> _tx_buffer_size != tx_buffer_size || uart -> _inverted != inverted || uart -> _rxfifo_full_thrhd != rxfifo_full_thrhd ) {
381
+ return true; // the current IDF UART driver must be terminated and a new driver shall be installed
382
+ } else {
383
+ return false; // The current IDF UART driver can continue its execution
384
+ }
385
+ } else {
386
+ return true; // no IDF UART driver is running and a new driver shall be installed
367
387
}
388
+ }
389
+
390
+ uart_t * uartBegin (uint8_t uart_nr , uint32_t baudrate , uint32_t config , int8_t rxPin , int8_t txPin , uint16_t rx_buffer_size , uint16_t tx_buffer_size , bool inverted , uint8_t rxfifo_full_thrhd )
391
+ {
392
+ if (uart_nr >= SOC_UART_NUM ) {
393
+ log_e ("UART number is invalid, please use number from 0 to %u" , SOC_UART_NUM - 1 );
394
+ return NULL ; // no new driver was installed
395
+ }
396
+ uart_t * uart = & _uart_bus_array [uart_nr ];
397
+ log_v ("UART%d baud(%ld) Mode(%x) rxPin(%d) txPin(%d)" , uart_nr , baudrate , config , rxPin , txPin );
368
398
369
399
#if !CONFIG_DISABLE_HAL_LOCKS
370
400
if (uart -> lock == NULL ) {
371
401
uart -> lock = xSemaphoreCreateMutex ();
372
402
if (uart -> lock == NULL ) {
373
403
log_e ("HAL LOCK error." );
374
- return NULL ;
404
+ return NULL ; // no new driver was installed
375
405
}
376
406
}
377
407
#endif
378
- UART_MUTEX_LOCK ();
379
408
409
+ if (uart_is_driver_installed (uart_nr )) {
410
+ log_v ("UART%d Driver already installed." , uart_nr );
411
+ // some parameters can't be changed unless we end the UART driver
412
+ if ( uart -> _rx_buffer_size != rx_buffer_size || uart -> _tx_buffer_size != tx_buffer_size || uart -> _inverted != inverted || uart -> _rxfifo_full_thrhd != rxfifo_full_thrhd ) {
413
+ log_v ("UART%d changing buffer sizes or inverted signal or rxfifo_full_thrhd. IDF driver will be restarted" , uart_nr );
414
+ uartEnd (uart_nr );
415
+ } else {
416
+ bool retCode = true;
417
+ UART_MUTEX_LOCK ();
418
+ //User may just want to change some parameters, such as baudrate, data length, parity, stop bits or pins
419
+ if (uart -> _baudrate != baudrate ) {
420
+ if (ESP_OK != uart_set_baudrate (uart_nr , baudrate )) {
421
+ log_e ("UART%d changing baudrate failed." , uart_nr );
422
+ retCode = false;
423
+ } else {
424
+ log_v ("UART%d changed baudrate to %d" , uart_nr , baudrate );
425
+ uart -> _baudrate = baudrate ;
426
+ }
427
+ }
428
+ uart_word_length_t data_bits = (config & 0xc ) >> 2 ;
429
+ uart_parity_t parity = config & 0x3 ;
430
+ uart_stop_bits_t stop_bits = (config & 0x30 ) >> 4 ;
431
+ if (retCode && (uart -> _config & 0xc ) >> 2 != data_bits ) {
432
+ if (ESP_OK != uart_set_word_length (uart_nr , data_bits )) {
433
+ log_e ("UART%d changing data length failed." , uart_nr );
434
+ retCode = false;
435
+ } else {
436
+ log_v ("UART%d changed data length to %d" , uart_nr , data_bits + 5 );
437
+ }
438
+ }
439
+ if (retCode && (uart -> _config & 0x3 ) != parity ) {
440
+ if (ESP_OK != uart_set_parity (uart_nr , parity )) {
441
+ log_e ("UART%d changing parity failed." , uart_nr );
442
+ retCode = false;
443
+ } else {
444
+ log_v ("UART%d changed parity to %s" , uart_nr , parity == 0 ? "NONE" : parity == 2 ? "EVEN" : "ODD" );
445
+ }
446
+ }
447
+ if (retCode && (uart -> _config & 0xc30 ) >> 4 != stop_bits ) {
448
+ if (ESP_OK != uart_set_stop_bits (uart_nr , stop_bits )) {
449
+ log_e ("UART%d changing stop bits failed." , uart_nr );
450
+ retCode = false;
451
+ } else {
452
+ log_v ("UART%d changed stop bits to %d" , uart_nr , stop_bits == 3 ? 2 : 1 );
453
+ }
454
+ }
455
+ if (retCode ) uart -> _config = config ;
456
+ if (retCode && rxPin > 0 && uart -> _rxPin != rxPin ) {
457
+ retCode &= _uartDetachPins (uart_nr , uart -> _rxPin , UART_PIN_NO_CHANGE , UART_PIN_NO_CHANGE , UART_PIN_NO_CHANGE );
458
+ retCode &= _uartAttachPins (uart_nr , rxPin , UART_PIN_NO_CHANGE , UART_PIN_NO_CHANGE , UART_PIN_NO_CHANGE );
459
+ if (!retCode ) {
460
+ log_e ("UART%d changing RX pin failed." , uart_nr );
461
+ } else {
462
+ log_v ("UART%d changed RX pin to %d" , uart_nr , rxPin );
463
+ }
464
+ }
465
+ if (retCode && txPin > 0 && uart -> _txPin != txPin ) {
466
+ retCode &= _uartDetachPins (uart_nr , UART_PIN_NO_CHANGE , uart -> _txPin , UART_PIN_NO_CHANGE , UART_PIN_NO_CHANGE );
467
+ retCode &= _uartAttachPins (uart_nr , UART_PIN_NO_CHANGE , txPin , UART_PIN_NO_CHANGE , UART_PIN_NO_CHANGE );
468
+ if (!retCode ) {
469
+ log_e ("UART%d changing TX pin failed." , uart_nr );
470
+ } else {
471
+ log_v ("UART%d changed TX pin to %d" , uart_nr , txPin );
472
+ }
473
+ }
474
+ UART_MUTEX_UNLOCK ();
475
+ if (retCode ) {
476
+ // UART driver was already working, just return the uart_t structure, syaing that no new driver was installed
477
+ return uart ;
478
+ }
479
+ // if we reach this point, it means that we need to restart the UART driver
480
+ uartEnd (uart_nr );
481
+ }
482
+ } else {
483
+ log_v ("UART%d not installed. Starting installation" , uart_nr );
484
+ }
380
485
uart_config_t uart_config ;
381
486
uart_config .data_bits = (config & 0xc ) >> 2 ;
382
487
uart_config .parity = (config & 0x3 );
@@ -386,7 +491,10 @@ uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rx
386
491
uart_config .baud_rate = baudrate ;
387
492
// CLK_APB for ESP32|S2|S3|C3 -- CLK_PLL_F40M for C2 -- CLK_PLL_F48M for H2 -- CLK_PLL_F80M for C6
388
493
uart_config .source_clk = UART_SCLK_DEFAULT ;
494
+
495
+ UART_MUTEX_LOCK ();
389
496
bool retCode = ESP_OK == uart_driver_install (uart_nr , rx_buffer_size , tx_buffer_size , 20 , & (uart -> uart_event_queue ), 0 );
497
+
390
498
if (retCode ) retCode &= ESP_OK == uart_param_config (uart_nr , & uart_config );
391
499
392
500
// Is it right or the idea is to swap rx and tx pins?
@@ -395,19 +503,31 @@ uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rx
395
503
retCode &= ESP_OK == uart_set_line_inverse (uart_nr , UART_SIGNAL_TXD_INV | UART_SIGNAL_RXD_INV );
396
504
}
397
505
506
+ if (retCode ) {
507
+ uart -> _baudrate = baudrate ;
508
+ uart -> _config = config ;
509
+ uart -> _inverted = inverted ;
510
+ uart -> _rxfifo_full_thrhd = rxfifo_full_thrhd ;
511
+ uart -> _rx_buffer_size = rx_buffer_size ;
512
+ uart -> _tx_buffer_size = tx_buffer_size ;
513
+ uart -> _ctsPin = -1 ;
514
+ uart -> _rtsPin = -1 ;
515
+ uart -> has_peek = false;
516
+ uart -> peek_byte = 0 ;
517
+ }
398
518
UART_MUTEX_UNLOCK ();
519
+
399
520
// uartSetPins detaches previous pins if new ones are used over a previous begin()
400
521
if (retCode ) retCode &= uartSetPins (uart_nr , rxPin , txPin , UART_PIN_NO_CHANGE , UART_PIN_NO_CHANGE );
401
-
402
- if (retCode ) uartFlush (uart );
403
- else {
522
+ if (!retCode ) {
404
523
uartEnd (uart_nr );
405
524
uart = NULL ;
406
525
log_e ("UART%d initialization error." , uart -> num );
526
+ } else {
527
+ uartFlush (uart );
528
+ log_v ("UART%d initialization done." , uart -> num );
407
529
}
408
-
409
- log_v ("UART%d baud(%ld) Mode(%x) rxPin(%d) txPin(%d)" , uart_nr , baudrate , config , rxPin , txPin );
410
- return uart ;
530
+ return uart ; // a new driver was installed
411
531
}
412
532
413
533
// This function code is under testing - for now just keep it here
@@ -1025,3 +1145,4 @@ int uart_send_msg_with_break(uint8_t uartNum, uint8_t *msg, size_t msgSize)
1025
1145
}
1026
1146
1027
1147
#endif /* SOC_UART_SUPPORTED */
1148
+
0 commit comments