Skip to content

Uart detach 2.0.13 #8629

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Sep 13, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 42 additions & 24 deletions cores/esp32/HardwareSerial.cpp
Original file line number Diff line number Diff line change
@@ -133,7 +133,7 @@ void serialEventRun(void)
#define HSERIAL_MUTEX_UNLOCK()
#endif

HardwareSerial::HardwareSerial(int uart_nr) :
HardwareSerial::HardwareSerial(uint8_t uart_nr) :
_uart_nr(uart_nr),
_uart(NULL),
_rxBufferSize(256),
@@ -147,8 +147,6 @@ _eventTask(NULL)
#if !CONFIG_DISABLE_HAL_LOCKS
,_lock(NULL)
#endif
,_rxPin(-1)
,_txPin(-1)
,_ctsPin(-1)
,_rtsPin(-1)
{
@@ -161,6 +159,14 @@ _eventTask(NULL)
}
}
#endif
// sets UART0 (default console) RX/TX pins as already configured in boot
if (uart_nr == 0) {
_rxPin = SOC_RX0;
_txPin = SOC_TX0;
} else {
_rxPin = -1;
_txPin = -1;
}
}

HardwareSerial::~HardwareSerial()
@@ -330,7 +336,7 @@ void HardwareSerial::_uartEventTask(void *args)

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)
{
if(0 > _uart_nr || _uart_nr >= SOC_UART_NUM) {
if(_uart_nr >= SOC_UART_NUM) {
log_e("Serial number is invalid, please use numers from 0 to %u", SOC_UART_NUM - 1);
return;
}
@@ -348,23 +354,26 @@ void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, in
switch (_uart_nr) {
case UART_NUM_0:
if (rxPin < 0 && txPin < 0) {
rxPin = SOC_RX0;
txPin = SOC_TX0;
// do not change RX0/TX0 if it has already been set before
rxPin = _rxPin < 0 ? SOC_RX0 : _rxPin;
txPin = _txPin < 0 ? SOC_TX0 : _txPin;
}
break;
#if SOC_UART_NUM > 1 // may save some flash bytes...
case UART_NUM_1:
if (rxPin < 0 && txPin < 0) {
rxPin = RX1;
txPin = TX1;
// do not change RX1/TX1 if it has already been set before
rxPin = _rxPin < 0 ? RX1 : _rxPin;
txPin = _txPin < 0 ? TX1 : _txPin;
}
break;
#endif
#if SOC_UART_NUM > 2 // may save some flash bytes...
case UART_NUM_2:
if (rxPin < 0 && txPin < 0) {
rxPin = RX2;
txPin = TX2;
// do not change RX2/TX2 if it has already been set before
rxPin = _rxPin < 0 ? RX2 : _rxPin;
txPin = _txPin < 0 ? TX2 : _txPin;
}
break;
#endif
@@ -424,9 +433,17 @@ void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, in
uartSetRxFIFOFull(_uart, fifoFull);
_rxFIFOFull = fifoFull;
}

_rxPin = rxPin;
_txPin = txPin;
// detach previous attached RX/TX pins when it has changed
if (_uart != NULL) {
if (rxPin >= 0 && rxPin != _rxPin) {
uartDetachPins(_uart_nr, _rxPin, -1, -1, -1);
_rxPin = rxPin;
}
if (txPin >= 0 && txPin != _txPin) {
uartDetachPins(_uart_nr, -1, _txPin, -1, -1);
_txPin = txPin;
}
}

HSERIAL_MUTEX_UNLOCK();
}
@@ -449,7 +466,7 @@ void HardwareSerial::end(bool fullyTerminate)

_rxFIFOFull = 0;

uartDetachPins(_uart, _rxPin, _txPin, _ctsPin, _rtsPin);
uartDetachPins(_uart_nr, _rxPin, _txPin, _ctsPin, _rtsPin);
_rxPin = _txPin = _ctsPin = _rtsPin = -1;

}
@@ -554,24 +571,25 @@ void HardwareSerial::setRxInvert(bool invert)
// negative Pin value will keep it unmodified
bool HardwareSerial::setPins(int8_t rxPin, int8_t txPin, int8_t ctsPin, int8_t rtsPin)
{
if(_uart == NULL) {
log_e("setPins() shall be called after begin() - nothing done\n");
return false;
}

// map logical pins to GPIO numbers
rxPin = digitalPinToGPIONumber(rxPin);
txPin = digitalPinToGPIONumber(txPin);
ctsPin = digitalPinToGPIONumber(ctsPin);
rtsPin = digitalPinToGPIONumber(rtsPin);

// uartSetPins() checks if pins are valid for each function and for the SoC
bool retCode = uartSetPins(_uart, rxPin, txPin, ctsPin, rtsPin);
bool retCode = uartSetPins(_uart_nr, rxPin, txPin, ctsPin, rtsPin);
if (retCode) {
_txPin = _txPin >= 0 ? txPin : _txPin;
_rxPin = _rxPin >= 0 ? rxPin : _rxPin;
_rtsPin = _rtsPin >= 0 ? rtsPin : _rtsPin;
_ctsPin = _ctsPin >= 0 ? ctsPin : _ctsPin;
// detach previous attached UART pins if not set as same as before
if (_rxPin >= 0 && rxPin >= 0 &&_rxPin != rxPin) uartDetachPins(_uart_nr, _rxPin, -1, -1, -1);
if (_txPin >= 0 && txPin >= 0 && _txPin != txPin) uartDetachPins(_uart_nr, -1, _txPin, -1, -1);
if (_ctsPin >= 0 && ctsPin >= 0 && _ctsPin != ctsPin) uartDetachPins(_uart_nr, -1, -1, _ctsPin, -1);
if (_rtsPin >= 0 && rtsPin >= 0 &&_rtsPin != rtsPin) uartDetachPins(_uart_nr, -1, -1, -1, _rtsPin);
// set new pins for a future end() or a setPins()
_txPin = txPin >= 0 ? txPin : _txPin;
_rxPin = rxPin >= 0 ? rxPin : _rxPin;
_rtsPin = rtsPin >= 0 ? rtsPin : _rtsPin;
_ctsPin = ctsPin >= 0 ? ctsPin : _ctsPin;
} else {
log_e("Error when setting Serial port Pins. Invalid Pin.\n");
}
4 changes: 2 additions & 2 deletions cores/esp32/HardwareSerial.h
Original file line number Diff line number Diff line change
@@ -71,7 +71,7 @@ typedef std::function<void(hardwareSerial_error_t)> OnReceiveErrorCb;
class HardwareSerial: public Stream
{
public:
HardwareSerial(int uart_nr);
HardwareSerial(uint8_t uart_nr);
~HardwareSerial();

// 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)
@@ -170,7 +170,7 @@ class HardwareSerial: public Stream
size_t setTxBufferSize(size_t new_size);

protected:
int _uart_nr;
uint8_t _uart_nr;
uart_t* _uart;
size_t _rxBufferSize;
size_t _txBufferSize;
23 changes: 11 additions & 12 deletions cores/esp32/esp32-hal-uart.c
Original file line number Diff line number Diff line change
@@ -79,21 +79,21 @@ static uart_t _uart_bus_array[] = {
// be seen in the previous pins and new pins as well.
// Valid pin UART_PIN_NO_CHANGE is defined to (-1)
// Negative Pin Number will keep it unmodified, thus this function can detach individual pins
void uartDetachPins(uart_t* uart, int8_t rxPin, int8_t txPin, int8_t ctsPin, int8_t rtsPin)
void uartDetachPins(uint8_t uart_num, int8_t rxPin, int8_t txPin, int8_t ctsPin, int8_t rtsPin)
{
if(uart == NULL) {
if(uart_num >= SOC_UART_NUM) {
log_e("Serial number is invalid, please use numers from 0 to %u", SOC_UART_NUM - 1);
return;
}

UART_MUTEX_LOCK();
if (txPin >= 0) {
gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[txPin], PIN_FUNC_GPIO);
esp_rom_gpio_connect_out_signal(txPin, SIG_GPIO_OUT_IDX, false, false);
}

if (rxPin >= 0) {
gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[rxPin], PIN_FUNC_GPIO);
esp_rom_gpio_connect_in_signal(GPIO_FUNC_IN_LOW, UART_PERIPH_SIGNAL(uart->num, SOC_UART_RX_PIN_IDX), false);
esp_rom_gpio_connect_in_signal(GPIO_FUNC_IN_LOW, UART_PERIPH_SIGNAL(uart_num, SOC_UART_RX_PIN_IDX), false);
}

if (rtsPin >= 0) {
@@ -103,9 +103,8 @@ void uartDetachPins(uart_t* uart, int8_t rxPin, int8_t txPin, int8_t ctsPin, int

if (ctsPin >= 0) {
gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[ctsPin], PIN_FUNC_GPIO);
esp_rom_gpio_connect_in_signal(GPIO_FUNC_IN_LOW, UART_PERIPH_SIGNAL(uart->num, SOC_UART_CTS_PIN_IDX), false);
esp_rom_gpio_connect_in_signal(GPIO_FUNC_IN_LOW, UART_PERIPH_SIGNAL(uart_num, SOC_UART_CTS_PIN_IDX), false);
}
UART_MUTEX_UNLOCK();
}

// solves issue https://github.com/espressif/arduino-esp32/issues/6032
@@ -147,15 +146,15 @@ bool uartIsDriverInstalled(uart_t* uart)

// Valid pin UART_PIN_NO_CHANGE is defined to (-1)
// Negative Pin Number will keep it unmodified, thus this function can set individual pins
bool uartSetPins(uart_t* uart, int8_t rxPin, int8_t txPin, int8_t ctsPin, int8_t rtsPin)
bool uartSetPins(uint8_t uart_num, int8_t rxPin, int8_t txPin, int8_t ctsPin, int8_t rtsPin)
{
if(uart == NULL) {
return false;
if(uart_num >= SOC_UART_NUM) {
log_e("Serial number is invalid, please use numers from 0 to %u", SOC_UART_NUM - 1);
return;
}
UART_MUTEX_LOCK();

// IDF uart_set_pin() will issue necessary Error Message and take care of all GPIO Number validation.
bool retCode = uart_set_pin(uart->num, txPin, rxPin, rtsPin, ctsPin) == ESP_OK;
UART_MUTEX_UNLOCK();
bool retCode = uart_set_pin(uart_num, txPin, rxPin, rtsPin, ctsPin) == ESP_OK;
return retCode;
}

4 changes: 2 additions & 2 deletions cores/esp32/esp32-hal-uart.h
Original file line number Diff line number Diff line change
@@ -131,8 +131,8 @@ int uartGetDebug();
bool uartIsDriverInstalled(uart_t* uart);

// Negative Pin Number will keep it unmodified, thus this function can set/reset individual pins
bool uartSetPins(uart_t* uart, int8_t rxPin, int8_t txPin, int8_t ctsPin, int8_t rtsPin);
void uartDetachPins(uart_t* uart, int8_t rxPin, int8_t txPin, int8_t ctsPin, int8_t rtsPin);
bool uartSetPins(uint8_t uart_num, int8_t rxPin, int8_t txPin, int8_t ctsPin, int8_t rtsPin);
void uartDetachPins(uint8_t uart_num, int8_t rxPin, int8_t txPin, int8_t ctsPin, int8_t rtsPin);

// Enables or disables HW Flow Control function -- needs also to set CTS and/or RTS pins
bool uartSetHwFlowCtrlMode(uart_t *uart, uint8_t mode, uint8_t threshold);