|
42 | 42 | static int s_uart_debug_nr = 0; // UART number for debug output |
43 | 43 | #define REF_TICK_BAUDRATE_LIMIT 250000 // this is maximum UART badrate using REF_TICK as clock |
44 | 44 |
|
| 45 | +/* C prototype for the notifier implemented in HardwareSerial.cpp */ |
| 46 | +extern void hal_uart_notify_pins_detached(int uart_num); |
| 47 | + |
45 | 48 | struct uart_struct_t { |
46 | 49 |
|
47 | 50 | #if !CONFIG_DISABLE_HAL_LOCKS |
@@ -282,29 +285,67 @@ static bool _uartDetachPins(uint8_t uart_num, int8_t rxPin, int8_t txPin, int8_t |
282 | 285 | // Peripheral Manager detach callback for each specific UART PIN |
283 | 286 | static bool _uartDetachBus_RX(void *busptr) { |
284 | 287 | // sanity check - it should never happen |
285 | | - assert(busptr && "_uartDetachBus_RX bus NULL pointer."); |
| 288 | + if (busptr == NULL) { |
| 289 | + log_e("_uartDetachBus_RX: busptr is NULL"); |
| 290 | + return false; |
| 291 | + } |
286 | 292 | uart_t *bus = (uart_t *)busptr; |
| 293 | + if (bus->_rxPin < 0) { |
| 294 | + log_d("_uartDetachBus_RX: RX pin already detached for UART%d", bus->num); |
| 295 | + return true; |
| 296 | + } |
| 297 | + if (bus->_txPin < 0) { // both rx and tx pins are detached, terminate the uart driver |
| 298 | + log_d("_uartDetachBus_RX: both RX and TX pins detached for UART%d, terminating driver", bus->num); |
| 299 | + hal_uart_notify_pins_detached(bus->num); |
| 300 | + return true; |
| 301 | + } |
287 | 302 | return _uartDetachPins(bus->num, bus->_rxPin, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); |
288 | 303 | } |
289 | 304 |
|
290 | 305 | static bool _uartDetachBus_TX(void *busptr) { |
291 | 306 | // sanity check - it should never happen |
292 | | - assert(busptr && "_uartDetachBus_TX bus NULL pointer."); |
| 307 | + if (busptr == NULL) { |
| 308 | + log_e("_uartDetachBus_TX: busptr is NULL"); |
| 309 | + return false; |
| 310 | + } |
293 | 311 | uart_t *bus = (uart_t *)busptr; |
| 312 | + if (bus->_txPin < 0) { |
| 313 | + log_d("_uartDetachBus_TX: TX pin already detached for UART%d", bus->num); |
| 314 | + return true; |
| 315 | + } |
| 316 | + if (bus->_rxPin < 0) { // both rx and tx pins are detached, terminate the uart driver |
| 317 | + log_d("_uartDetachBus_TX: both RX and TX pins detached for UART%d, terminating driver", bus->num); |
| 318 | + hal_uart_notify_pins_detached(bus->num); |
| 319 | + return true; |
| 320 | + } |
294 | 321 | return _uartDetachPins(bus->num, UART_PIN_NO_CHANGE, bus->_txPin, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); |
295 | 322 | } |
296 | 323 |
|
297 | 324 | static bool _uartDetachBus_CTS(void *busptr) { |
298 | 325 | // sanity check - it should never happen |
299 | | - assert(busptr && "_uartDetachBus_CTS bus NULL pointer."); |
| 326 | + if (busptr == NULL) { |
| 327 | + log_e("_uartDetachBus_CTS: busptr is NULL"); |
| 328 | + return false; |
| 329 | + } |
300 | 330 | uart_t *bus = (uart_t *)busptr; |
| 331 | + if (bus->_ctsPin < 0) { |
| 332 | + log_d("_uartDetachBus_CTS: CTS pin already detached for UART%d", bus->num); |
| 333 | + return true; |
| 334 | + } |
301 | 335 | return _uartDetachPins(bus->num, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, bus->_ctsPin, UART_PIN_NO_CHANGE); |
302 | 336 | } |
303 | 337 |
|
304 | 338 | static bool _uartDetachBus_RTS(void *busptr) { |
305 | 339 | // sanity check - it should never happen |
306 | | - assert(busptr && "_uartDetachBus_RTS bus NULL pointer."); |
| 340 | + if (busptr == NULL) { |
| 341 | + log_e("_uartDetachBus_RTS: busptr is NULL"); |
| 342 | + return false; |
| 343 | + } |
307 | 344 | uart_t *bus = (uart_t *)busptr; |
| 345 | + if (bus->_rtsPin < 0) { |
| 346 | + log_d("_uartDetachBus_RTS: RTS pin already detached for UART%d", bus->num); |
| 347 | + return true; |
| 348 | + } |
308 | 349 | return _uartDetachPins(bus->num, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, bus->_rtsPin); |
309 | 350 | } |
310 | 351 |
|
@@ -629,6 +670,16 @@ bool uartSetPins(uint8_t uart_num, int8_t rxPin, int8_t txPin, int8_t ctsPin, in |
629 | 670 | //log_v("setting UART%d pins: prev->new RX(%d->%d) TX(%d->%d) CTS(%d->%d) RTS(%d->%d)", uart_num, |
630 | 671 | // uart->_rxPin, rxPin, uart->_txPin, txPin, uart->_ctsPin, ctsPin, uart->_rtsPin, rtsPin); vTaskDelay(10); |
631 | 672 |
|
| 673 | + // mute bus detaching callbacks to avoid terminating the UART driver when both RX and TX pins are detached |
| 674 | + peripheral_bus_deinit_cb_t rxDeinit = perimanGetBusDeinit(ESP32_BUS_TYPE_UART_RX); |
| 675 | + peripheral_bus_deinit_cb_t txDeinit = perimanGetBusDeinit(ESP32_BUS_TYPE_UART_TX); |
| 676 | + peripheral_bus_deinit_cb_t ctsDeinit = perimanGetBusDeinit(ESP32_BUS_TYPE_UART_CTS); |
| 677 | + peripheral_bus_deinit_cb_t rtsDeinit = perimanGetBusDeinit(ESP32_BUS_TYPE_UART_RTS); |
| 678 | + perimanClearBusDeinit(ESP32_BUS_TYPE_UART_RX); |
| 679 | + perimanClearBusDeinit(ESP32_BUS_TYPE_UART_TX); |
| 680 | + perimanClearBusDeinit(ESP32_BUS_TYPE_UART_CTS); |
| 681 | + perimanClearBusDeinit(ESP32_BUS_TYPE_UART_RTS); |
| 682 | + |
632 | 683 | // First step: detaches all previous UART pins |
633 | 684 | bool rxPinChanged = rxPin >= 0 && rxPin != uart->_rxPin; |
634 | 685 | if (rxPinChanged) { |
@@ -660,6 +711,21 @@ bool uartSetPins(uint8_t uart_num, int8_t rxPin, int8_t txPin, int8_t ctsPin, in |
660 | 711 | if (rtsPinChanged) { |
661 | 712 | retCode &= _uartAttachPins(uart->num, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, rtsPin); |
662 | 713 | } |
| 714 | + |
| 715 | + // restore bus detaching callbacks |
| 716 | + if (rxDeinit != NULL) { |
| 717 | + perimanSetBusDeinit(ESP32_BUS_TYPE_UART_RX, rxDeinit); |
| 718 | + } |
| 719 | + if (txDeinit != NULL) { |
| 720 | + perimanSetBusDeinit(ESP32_BUS_TYPE_UART_TX, txDeinit); |
| 721 | + } |
| 722 | + if (ctsDeinit != NULL) { |
| 723 | + perimanSetBusDeinit(ESP32_BUS_TYPE_UART_CTS, ctsDeinit); |
| 724 | + } |
| 725 | + if (rtsDeinit != NULL) { |
| 726 | + perimanSetBusDeinit(ESP32_BUS_TYPE_UART_RTS, rtsDeinit); |
| 727 | + } |
| 728 | + |
663 | 729 | UART_MUTEX_UNLOCK(); |
664 | 730 |
|
665 | 731 | if (!retCode) { |
@@ -986,6 +1052,9 @@ void uartEnd(uint8_t uart_num) { |
986 | 1052 | if (uart_is_driver_installed(uart_num)) { |
987 | 1053 | uart_driver_delete(uart_num); |
988 | 1054 | } |
| 1055 | + if (uartGetDebug() == uart_num) { |
| 1056 | + uartSetDebug(0); |
| 1057 | + } |
989 | 1058 | UART_MUTEX_UNLOCK(); |
990 | 1059 | } |
991 | 1060 |
|
|
0 commit comments