Skip to content

Commit 6b1933b

Browse files
authored
3.0.0 - UART Peripheral Manager + Detach UART pins on begin()/setPins() (espressif#8719)
* detach UART pins * fixes uartEnd() call
1 parent 9e52647 commit 6b1933b

6 files changed

+269
-138
lines changed

cores/esp32/HardwareSerial.cpp

+28-23
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ void serialEventRun(void)
149149
#define HSERIAL_MUTEX_UNLOCK()
150150
#endif
151151

152-
HardwareSerial::HardwareSerial(int uart_nr) :
152+
HardwareSerial::HardwareSerial(uint8_t uart_nr) :
153153
_uart_nr(uart_nr),
154154
_uart(NULL),
155155
_rxBufferSize(256),
@@ -173,6 +173,12 @@ _eventTask(NULL)
173173
}
174174
}
175175
#endif
176+
// sets UART0 (default console) RX/TX pins as already configured in boot
177+
if (uart_nr == 0) {
178+
setPins(SOC_RX0, SOC_TX0);
179+
}
180+
// set deinit function in the Peripheral Manager
181+
uart_init_PeriMan();
176182
}
177183

178184
HardwareSerial::~HardwareSerial()
@@ -342,8 +348,8 @@ void HardwareSerial::_uartEventTask(void *args)
342348

343349
void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, int8_t txPin, bool invert, unsigned long timeout_ms, uint8_t rxfifo_full_thrhd)
344350
{
345-
if(0 > _uart_nr || _uart_nr >= SOC_UART_NUM) {
346-
log_e("Serial number is invalid, please use numers from 0 to %u", SOC_UART_NUM - 1);
351+
if(_uart_nr >= SOC_UART_NUM) {
352+
log_e("Serial number is invalid, please use a number from 0 to %u", SOC_UART_NUM - 1);
347353
return;
348354
}
349355

@@ -357,26 +363,32 @@ void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, in
357363
HSERIAL_MUTEX_LOCK();
358364
// First Time or after end() --> set default Pins
359365
if (!uartIsDriverInstalled(_uart)) {
366+
// get previously used RX/TX pins, if any.
367+
int8_t _rxPin = uart_get_RxPin(_uart_nr);
368+
int8_t _txPin = uart_get_TxPin(_uart_nr);
360369
switch (_uart_nr) {
361370
case UART_NUM_0:
362371
if (rxPin < 0 && txPin < 0) {
363-
rxPin = SOC_RX0;
364-
txPin = SOC_TX0;
372+
// do not change RX0/TX0 if it has already been set before
373+
rxPin = _rxPin < 0 ? SOC_RX0 : _rxPin;
374+
txPin = _txPin < 0 ? SOC_TX0 : _txPin;
365375
}
366376
break;
367377
#if SOC_UART_NUM > 1 // may save some flash bytes...
368378
case UART_NUM_1:
369379
if (rxPin < 0 && txPin < 0) {
370-
rxPin = RX1;
371-
txPin = TX1;
380+
// do not change RX1/TX1 if it has already been set before
381+
rxPin = _rxPin < 0 ? RX1 : _rxPin;
382+
txPin = _txPin < 0 ? TX1 : _txPin;
372383
}
373384
break;
374385
#endif
375386
#if SOC_UART_NUM > 2 // may save some flash bytes...
376387
case UART_NUM_2:
377388
if (rxPin < 0 && txPin < 0) {
378-
rxPin = RX2;
379-
txPin = TX2;
389+
// do not change RX2/TX2 if it has already been set before
390+
rxPin = _rxPin < 0 ? RX2 : _rxPin;
391+
txPin = _txPin < 0 ? TX2 : _txPin;
380392
}
381393
break;
382394
#endif
@@ -390,6 +402,7 @@ void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, in
390402
}
391403

392404
// IDF UART driver keeps Pin setting on restarting. Negative Pin number will keep it unmodified.
405+
// it will detach previous UART attached pins
393406
_uart = uartBegin(_uart_nr, baud ? baud : 9600, config, rxPin, txPin, _rxBufferSize, _txBufferSize, invert, rxfifo_full_thrhd);
394407
if (!baud) {
395408
// using baud rate as zero, forces it to try to detect the current baud rate in place
@@ -452,13 +465,13 @@ void HardwareSerial::end(bool fullyTerminate)
452465
uartSetDebug(0);
453466
}
454467
_rxFIFOFull = 0;
455-
uartEnd(_uart); // fully detach all pins and delete the UART driver
468+
uartEnd(_uart_nr); // fully detach all pins and delete the UART driver
456469
} else {
457470
// do not invalidate callbacks, detach pins, invalidate DBG output
458471
uart_driver_delete(_uart_nr);
459472
}
460473

461-
uartEnd(_uart);
474+
uartEnd(_uart_nr);
462475
_uart = 0;
463476
_destroyEventTask();
464477
}
@@ -540,8 +553,8 @@ size_t HardwareSerial::write(const uint8_t *buffer, size_t size)
540553
uartWriteBuf(_uart, buffer, size);
541554
return size;
542555
}
543-
uint32_t HardwareSerial::baudRate()
544556

557+
uint32_t HardwareSerial::baudRate()
545558
{
546559
return uartGetBaudRate(_uart);
547560
}
@@ -556,19 +569,11 @@ void HardwareSerial::setRxInvert(bool invert)
556569
}
557570

558571
// negative Pin value will keep it unmodified
572+
// can be called after or before begin()
559573
bool HardwareSerial::setPins(int8_t rxPin, int8_t txPin, int8_t ctsPin, int8_t rtsPin)
560574
{
561-
if(_uart == NULL) {
562-
log_e("setPins() shall be called after begin() - nothing done\n");
563-
return false;
564-
}
565-
566-
// uartSetPins() checks if pins are valid for each function and for the SoC
567-
if (uartSetPins(_uart, rxPin, txPin, ctsPin, rtsPin)) {
568-
return true;
569-
} else {
570-
return false;
571-
}
575+
// uartSetPins() checks if pins are valid and, if necessary, detaches the previous ones
576+
return uartSetPins(_uart_nr, rxPin, txPin, ctsPin, rtsPin);
572577
}
573578

574579
// Enables or disables Hardware Flow Control using RTS and/or CTS pins (must use setAllPins() before)

cores/esp32/HardwareSerial.h

+9-3
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ typedef std::function<void(hardwareSerial_error_t)> OnReceiveErrorCb;
7171
class HardwareSerial: public Stream
7272
{
7373
public:
74-
HardwareSerial(int uart_nr);
74+
HardwareSerial(uint8_t uart_nr);
7575
~HardwareSerial();
7676

7777
// setRxTimeout sets the timeout after which onReceive callback will be called (after receiving data, it waits for this time of UART rx inactivity to call the callback fnc)
@@ -106,6 +106,11 @@ class HardwareSerial: public Stream
106106
// eventQueueReset clears all events in the queue (the events that trigger onReceive and onReceiveError) - maybe usefull in some use cases
107107
void eventQueueReset();
108108

109+
// When pins are changed, it will detach the previous ones
110+
// if pin is negative, it won't be set/changed and will be kept as is
111+
// timeout_ms is used in baudrate detection (ESP32, ESP32S2 only)
112+
// invert will invert RX/TX polarity
113+
// rxfifo_full_thrhd if the UART Flow Control Threshold in the UART FIFO (max 127)
109114
void begin(unsigned long baud, uint32_t config=SERIAL_8N1, int8_t rxPin=-1, int8_t txPin=-1, bool invert=false, unsigned long timeout_ms = 20000UL, uint8_t rxfifo_full_thrhd = 112);
110115
void end(bool fullyTerminate = true);
111116
void updateBaudRate(unsigned long baud);
@@ -160,7 +165,8 @@ class HardwareSerial: public Stream
160165
void setRxInvert(bool);
161166

162167
// Negative Pin Number will keep it unmodified, thus this function can set individual pins
163-
// SetPins shall be called after Serial begin()
168+
// setPins() can be called after or before begin()
169+
// When pins are changed, it will detach the previous ones
164170
bool setPins(int8_t rxPin, int8_t txPin, int8_t ctsPin = -1, int8_t rtsPin = -1);
165171
// Enables or disables Hardware Flow Control using RTS and/or CTS pins (must use setAllPins() before)
166172
bool setHwFlowCtrlMode(uint8_t mode = HW_FLOWCTRL_CTS_RTS, uint8_t threshold = 64); // 64 is half FIFO Length
@@ -170,7 +176,7 @@ class HardwareSerial: public Stream
170176
size_t setTxBufferSize(size_t new_size);
171177

172178
protected:
173-
int _uart_nr;
179+
uint8_t _uart_nr;
174180
uart_t* _uart;
175181
size_t _rxBufferSize;
176182
size_t _txBufferSize;

cores/esp32/chip-debug-report.cpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,10 @@ static void printPerimanInfo(void){
253253
chip_report_printf(" %17u : ", i);
254254
switch(type){
255255
case ESP32_BUS_TYPE_GPIO: chip_report_printf("GPIO\n"); break;
256-
case ESP32_BUS_TYPE_UART: chip_report_printf("UART\n"); break;
256+
case ESP32_BUS_TYPE_UART_RX: chip_report_printf("UART_RX\n"); break;
257+
case ESP32_BUS_TYPE_UART_TX: chip_report_printf("UART_TX\n"); break;
258+
case ESP32_BUS_TYPE_UART_CTS: chip_report_printf("UART_CTS\n"); break;
259+
case ESP32_BUS_TYPE_UART_RTS: chip_report_printf("UART_RTS\n"); break;
257260
#if SOC_SDM_SUPPORTED
258261
case ESP32_BUS_TYPE_SIGMADELTA: chip_report_printf("SIGMADELTA\n"); break;
259262
#endif

cores/esp32/esp32-hal-periman.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@ extern "C"
1717
typedef enum {
1818
ESP32_BUS_TYPE_INIT, // IO has not been attached to a bus yet
1919
ESP32_BUS_TYPE_GPIO, // IO is used as GPIO
20-
ESP32_BUS_TYPE_UART, // IO is used as UART pin
20+
ESP32_BUS_TYPE_UART_RX, // IO is used as UART RX pin
21+
ESP32_BUS_TYPE_UART_TX, // IO is used as UART TX pin
22+
ESP32_BUS_TYPE_UART_CTS, // IO is used as UART CTS pin
23+
ESP32_BUS_TYPE_UART_RTS, // IO is used as UART RTS pin
2124
#if SOC_SDM_SUPPORTED
2225
ESP32_BUS_TYPE_SIGMADELTA, // IO is used as SigmeDelta output
2326
#endif

0 commit comments

Comments
 (0)