diff --git a/cores/esp32/esp32-hal-periman.c b/cores/esp32/esp32-hal-periman.c index 2ba8ffde5f7..bec88b0fdeb 100644 --- a/cores/esp32/esp32-hal-periman.c +++ b/cores/esp32/esp32-hal-periman.c @@ -236,11 +236,30 @@ bool perimanSetBusDeinit(peripheral_bus_type_t type, peripheral_bus_deinit_cb_t return true; } +// This no-op callback is used by perimanClearBusDeinit() to effectively disable bus deinit functionality +// without setting the callback to NULL, which would cause errors in perimanSetPinBus() at line 146. +static bool empty_bus_deinit_cb(void *bus) { + return true; +} + +bool perimanClearBusDeinit(peripheral_bus_type_t type) { + if (type >= ESP32_BUS_TYPE_MAX || type == ESP32_BUS_TYPE_INIT) { + log_e("Invalid type: %s (%u)", perimanGetTypeName(type), (unsigned int)type); + return false; + } + deinit_functions[type] = empty_bus_deinit_cb; + log_v("Deinit function for type %s (%u) cleared", perimanGetTypeName(type), (unsigned int)type); + return true; +} + peripheral_bus_deinit_cb_t perimanGetBusDeinit(peripheral_bus_type_t type) { if (type >= ESP32_BUS_TYPE_MAX || type == ESP32_BUS_TYPE_INIT) { log_e("Invalid type: %s (%u)", perimanGetTypeName(type), (unsigned int)type); return NULL; } + if (deinit_functions[type] == empty_bus_deinit_cb) { + return NULL; + } return deinit_functions[type]; } diff --git a/cores/esp32/esp32-hal-periman.h b/cores/esp32/esp32-hal-periman.h index 08b8c791ea7..12563718e19 100644 --- a/cores/esp32/esp32-hal-periman.h +++ b/cores/esp32/esp32-hal-periman.h @@ -134,6 +134,9 @@ int8_t perimanGetPinBusChannel(uint8_t pin); // Sets the peripheral destructor callback. Used to destroy bus when pin is assigned another function bool perimanSetBusDeinit(peripheral_bus_type_t type, peripheral_bus_deinit_cb_t cb); +// Clears the peripheral destructor callback +bool perimanClearBusDeinit(peripheral_bus_type_t type); + // Get the peripheral destructor callback. It allows changing/restoring the peripheral pin function detaching, if necessary // returns NULL if none is set peripheral_bus_deinit_cb_t perimanGetBusDeinit(peripheral_bus_type_t type); diff --git a/libraries/PPP/src/PPP.cpp b/libraries/PPP/src/PPP.cpp index 5e713bc84b0..76c5fad0d78 100644 --- a/libraries/PPP/src/PPP.cpp +++ b/libraries/PPP/src/PPP.cpp @@ -394,6 +394,11 @@ void PPPClass::end(void) { Network.postEvent(&arduino_event); } + if (_dce != NULL) { + esp_modem_destroy(_dce); + _dce = NULL; + } + destroyNetif(); if (_ppp_ev_instance != NULL) { @@ -406,10 +411,10 @@ void PPPClass::end(void) { Network.removeEvent(_ppp_event_handle); _ppp_event_handle = 0; - if (_dce != NULL) { - esp_modem_destroy(_dce); - _dce = NULL; - } + perimanClearBusDeinit(ESP32_BUS_TYPE_PPP_TX); + perimanClearBusDeinit(ESP32_BUS_TYPE_PPP_RX); + perimanClearBusDeinit(ESP32_BUS_TYPE_PPP_RTS); + perimanClearBusDeinit(ESP32_BUS_TYPE_PPP_CTS); int8_t pin = -1; if (_pin_tx != -1) { @@ -438,6 +443,11 @@ void PPPClass::end(void) { perimanClearPinBus(pin); } + perimanSetBusDeinit(ESP32_BUS_TYPE_PPP_TX, PPPClass::pppDetachBus); + perimanSetBusDeinit(ESP32_BUS_TYPE_PPP_RX, PPPClass::pppDetachBus); + perimanSetBusDeinit(ESP32_BUS_TYPE_PPP_RTS, PPPClass::pppDetachBus); + perimanSetBusDeinit(ESP32_BUS_TYPE_PPP_CTS, PPPClass::pppDetachBus); + _mode = ESP_MODEM_MODE_COMMAND; }