diff --git a/components/esp_modem/.gitignore b/components/esp_modem/.gitignore index 5aa50beb2..01f34e62e 100644 --- a/components/esp_modem/.gitignore +++ b/components/esp_modem/.gitignore @@ -90,4 +90,7 @@ build dependencies.lock # ignore generated docs -docs/html \ No newline at end of file +docs/html + +# esp-idf managed components +**/managed_components/** \ No newline at end of file diff --git a/components/esp_modem/examples/modem_console/CMakeLists.txt b/components/esp_modem/examples/modem_console/CMakeLists.txt index 73765204f..12e4daf0a 100644 --- a/components/esp_modem/examples/modem_console/CMakeLists.txt +++ b/components/esp_modem/examples/modem_console/CMakeLists.txt @@ -2,15 +2,5 @@ # in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.5) -set(EXTRA_COMPONENT_DIRS "../..") - -include($ENV{IDF_PATH}/tools/cmake/version.cmake) - -if("${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}" VERSION_GREATER_EQUAL "4.4") -if(("${IDF_TARGET}" STREQUAL "esp32s2") OR ("${IDF_TARGET}" STREQUAL "esp32s3")) - list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/examples/peripherals/usb/host/cdc/common") -endif() -endif() - include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(modem-console) diff --git a/components/esp_modem/examples/modem_console/README.md b/components/esp_modem/examples/modem_console/README.md index 890ebe049..c76e82b75 100644 --- a/components/esp_modem/examples/modem_console/README.md +++ b/components/esp_modem/examples/modem_console/README.md @@ -20,7 +20,11 @@ For USB enabled targets (ESP32-S2 and ESP32-S3), it is possible to connect to th 1. In menuconfig, navigate to `Example Configuration->Type of serial connection to the modem` and choose `USB`. 2. Connect the modem USB signals to pin 19 (DATA-) and 20 (DATA+) on your ESP chip. -USB example uses Quactel BG96 modem device. +USB example uses Quactel BG96 modem device. BG96 needs a positive pulse on its PWK pin to boot-up. + +This example supports USB modem hot-plugging and reconnection. There is one limitation coming from esp_console component: +When esp_console REPL is being destroyed (after USB mode disconnection or after `exit` command), it will block on UART read. +You must send a character to it (via idf.py monitor), so it unblocks and properly exits. ### Supported IDF versions diff --git a/components/esp_modem/examples/modem_console/components/esp_modem_usb_dte/CMakeLists.txt b/components/esp_modem/examples/modem_console/components/esp_modem_usb_dte/CMakeLists.txt deleted file mode 100644 index dbec05b31..000000000 --- a/components/esp_modem/examples/modem_console/components/esp_modem_usb_dte/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -include($ENV{IDF_PATH}/tools/cmake/version.cmake) -idf_build_get_property(target IDF_TARGET) - -# USB is supported on S2 and S3 targets and IDF version >= 4.4 -if("${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}" VERSION_GREATER_EQUAL "4.4") -if(("${target}" STREQUAL "esp32s2") OR ("${target}" STREQUAL "esp32s3")) - -idf_component_register(SRCS "esp_modem_usb.cpp" "esp_modem_usb_api_target.cpp" - REQUIRES cdc_acm_host esp_modem - REQUIRED_IDF_TARGETS esp32s2 esp32s3 - PRIV_INCLUDE_DIRS "private_include" - INCLUDE_DIRS "include") - -set_target_properties(${COMPONENT_LIB} PROPERTIES - CXX_STANDARD 17 -) - -endif() -endif() \ No newline at end of file diff --git a/components/esp_modem/examples/modem_console/components/esp_modem_usb_dte/esp_modem_usb.cpp b/components/esp_modem/examples/modem_console/components/esp_modem_usb_dte/esp_modem_usb.cpp deleted file mode 100644 index fd7f99763..000000000 --- a/components/esp_modem/examples/modem_console/components/esp_modem_usb_dte/esp_modem_usb.cpp +++ /dev/null @@ -1,191 +0,0 @@ -// Copyright 2021 Espressif Systems (Shanghai) CO LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/semphr.h" -#include "esp_log.h" -#include "esp_modem_config.h" -#include "esp_modem_usb_config.h" -#include "cxx_include/esp_modem_dte.hpp" -#include "usb/usb_host.h" -#include "usb/cdc_acm_host.h" -#include "sdkconfig.h" -#include "usb_terminal.hpp" - -static const char *TAG = "usb_terminal"; - -/** - * @brief USB Host task - * - * This task is created only if install_usb_host is set to true in DTE configuration. - * In case the user doesn't want in install USB Host driver here, he must install it before creating UsbTerminal object. - * - * @param arg Unused - */ -void usb_host_task(void *arg) -{ - while (1) { - // Start handling system events - uint32_t event_flags; - usb_host_lib_handle_events(portMAX_DELAY, &event_flags); - if (event_flags & USB_HOST_LIB_EVENT_FLAGS_NO_CLIENTS) { - ESP_LOGD(TAG, "No more clients: clean up\n"); - usb_host_device_free_all(); - } - if (event_flags & USB_HOST_LIB_EVENT_FLAGS_ALL_FREE) { - ESP_LOGD(TAG, "All free: uninstall USB lib\n"); - break; - } - } - - // Clean up USB Host - vTaskDelay(10); // Short delay to allow clients clean-up - usb_host_lib_handle_events(0, NULL); // Make sure there are now pending events - usb_host_uninstall(); - vTaskDelete(NULL); -} - -namespace esp_modem { -class UsbTerminal : public Terminal, private CdcAcmDevice { -public: - explicit UsbTerminal(const esp_modem_dte_config *config) - { - const struct esp_modem_usb_term_config* usb_config = (struct esp_modem_usb_term_config*)(config->extension_config); - - // Install USB Host driver - if (usb_config->install_usb_host) { - const usb_host_config_t host_config = { - .skip_phy_setup = false, - .intr_flags = ESP_INTR_FLAG_LEVEL1, - }; - ESP_MODEM_THROW_IF_ERROR(usb_host_install(&host_config), "USB Host install failed"); - ESP_LOGD(TAG, "USB Host installed"); - ESP_MODEM_THROW_IF_FALSE(pdTRUE == xTaskCreatePinnedToCore(usb_host_task, "usb_host", 4096, NULL, config->task_priority + 1, NULL, usb_config->xCoreID), "USB host task failed"); - } - - // Install CDC-ACM driver - const cdc_acm_host_driver_config_t esp_modem_cdc_acm_driver_config = { - .driver_task_stack_size = config->task_stack_size, - .driver_task_priority = config->task_priority, - .xCoreID = (BaseType_t)usb_config->xCoreID - }; - - // Silently continue of error: CDC-ACM driver might be already installed - cdc_acm_host_install(&esp_modem_cdc_acm_driver_config); - - // Open CDC-ACM device - const cdc_acm_host_device_config_t esp_modem_cdc_acm_device_config = { - .connection_timeout_ms = usb_config->timeout_ms, - .out_buffer_size = config->dte_buffer_size, - .event_cb = handle_notif, - .data_cb = handle_rx, - .user_arg = this - }; - - if (usb_config->cdc_compliant) { - ESP_MODEM_THROW_IF_ERROR(this->CdcAcmDevice::open(usb_config->vid, usb_config->pid, - usb_config->interface_idx, &esp_modem_cdc_acm_device_config), - "USB Device open failed"); - } else { - ESP_MODEM_THROW_IF_ERROR(this->CdcAcmDevice::open_vendor_specific(usb_config->vid, usb_config->pid, - usb_config->interface_idx, &esp_modem_cdc_acm_device_config), - "USB Device open failed"); - } - }; - - ~UsbTerminal() - { - this->CdcAcmDevice::close(); - }; - - void start() override - { - return; - } - - void stop() override - { - return; - } - - int write(uint8_t *data, size_t len) override - { - ESP_LOG_BUFFER_HEXDUMP(TAG, data, len, ESP_LOG_DEBUG); - if (this->CdcAcmDevice::tx_blocking(data, len) != ESP_OK) { - return -1; - } - return len; - } - - int read(uint8_t *data, size_t len) override - { - // This function should never be called. UsbTerminal provides data through Terminal::on_read callback - ESP_LOGW(TAG, "Unexpected call to UsbTerminal::read function"); - return -1; - } - -private: - UsbTerminal() = delete; - UsbTerminal(const UsbTerminal ©) = delete; - UsbTerminal &operator=(const UsbTerminal ©) = delete; - bool operator== (const UsbTerminal ¶m) const = delete; - bool operator!= (const UsbTerminal ¶m) const = delete; - - static void handle_rx(uint8_t *data, size_t data_len, void *user_arg) - { - ESP_LOG_BUFFER_HEXDUMP(TAG, data, data_len, ESP_LOG_DEBUG); - UsbTerminal *this_terminal = static_cast(user_arg); - if (data_len > 0 && this_terminal->on_read) { - this_terminal->on_read(data, data_len); - } else { - ESP_LOGD(TAG, "Unhandled RX data"); - } - } - - static void handle_notif(cdc_acm_dev_hdl_t cdc_hdl, const cdc_acm_host_dev_event_data_t *event, void *user_ctx) - { - UsbTerminal *this_terminal = static_cast(user_ctx); - - switch (event->type) { - // Notifications like Ring, Rx Carrier indication or Network connection indication are not relevant for USB terminal - case CDC_ACM_HOST_NETWORK_CONNECTION: - case CDC_ACM_HOST_SERIAL_STATE: - break; - case CDC_ACM_HOST_DEVICE_DISCONNECTED: - ESP_LOGW(TAG, "USB terminal disconnected"); - cdc_acm_host_close(cdc_hdl); - if (this_terminal->on_error) { - this_terminal->on_error(terminal_error::UNEXPECTED_CONTROL_FLOW); - } - break; - case CDC_ACM_HOST_ERROR: - ESP_LOGE(TAG, "Unexpected CDC-ACM error: %d.", event->data.error); - if (this_terminal->on_error) { - this_terminal->on_error(terminal_error::UNEXPECTED_CONTROL_FLOW); - } - break; - default: - abort(); - } - }; -}; - -std::unique_ptr create_usb_terminal(const esp_modem_dte_config *config) -{ - TRY_CATCH_RET_NULL( - return std::make_unique(config); - ) -} -} // namespace esp_modem diff --git a/components/esp_modem/examples/modem_console/components/esp_modem_usb_dte/esp_modem_usb_api_target.cpp b/components/esp_modem/examples/modem_console/components/esp_modem_usb_dte/esp_modem_usb_api_target.cpp deleted file mode 100644 index 024269db7..000000000 --- a/components/esp_modem/examples/modem_console/components/esp_modem_usb_dte/esp_modem_usb_api_target.cpp +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2021-2022 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - - -#include "usb_terminal.hpp" -#include "cxx_include/esp_modem_api.hpp" -#include "cxx_include/esp_modem_netif.hpp" - -#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS -static const char *TAG = "modem_usb_api_target"; -#endif - -namespace esp_modem { -std::shared_ptr create_usb_dte(const dte_config *config) -{ - TRY_CATCH_RET_NULL( - auto term = create_usb_terminal(config); - return std::make_shared(config, std::move(term)); - ) -} -} diff --git a/components/esp_modem/examples/modem_console/components/esp_modem_usb_dte/include/cxx_include/esp_modem_usb_api.hpp b/components/esp_modem/examples/modem_console/components/esp_modem_usb_dte/include/cxx_include/esp_modem_usb_api.hpp deleted file mode 100644 index d7e24114e..000000000 --- a/components/esp_modem/examples/modem_console/components/esp_modem_usb_dte/include/cxx_include/esp_modem_usb_api.hpp +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2021-2022 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#pragma once -#include "cxx_include/esp_modem_dce.hpp" -#include "cxx_include/esp_modem_dce_module.hpp" - -namespace esp_modem { -/** - * @brief Create USB DTE - * - * @param config DTE configuration - * @return shared ptr to DTE on success - * nullptr on failure (either due to insufficient memory or wrong dte configuration) - * if exceptions are disabled the API abort()'s on error - */ -std::shared_ptr create_usb_dte(const dte_config *config); -} diff --git a/components/esp_modem/examples/modem_console/components/esp_modem_usb_dte/include/esp_modem_usb_config.h b/components/esp_modem/examples/modem_console/components/esp_modem_usb_dte/include/esp_modem_usb_config.h deleted file mode 100644 index b28e07ef3..000000000 --- a/components/esp_modem/examples/modem_console/components/esp_modem_usb_dte/include/esp_modem_usb_config.h +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright 2021-2022 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#pragma once -#include -#include - -/** - * @brief USB configuration structure - * @see USB host CDC-ACM driver documentation for details about interfaces settings - */ -struct esp_modem_usb_term_config { - uint16_t vid; /*!< Vendor ID of the USB device */ - uint16_t pid; /*!< Product ID of the USB device */ - int interface_idx; /*!< USB Interface index that will be used */ - uint32_t timeout_ms; /*!< Time for a USB modem to connect to USB host. 0 means wait forever. */ - int xCoreID; /*!< Core affinity of created tasks: CDC-ACM driver task and optional USB Host task */ - bool cdc_compliant; /*!< Treat the USB device as CDC-compliant. Read CDC-ACM driver documentation for more details */ - bool install_usb_host; /*!< Flag whether USB Host driver should be installed */ -}; - -/** - * @brief ESP Mode USB DTE Default Configuration - * - * @param[in] _usb_config esp_modem_usb_term_config configuration structure. Can be obtained by ESP_MODEM_DEFAULT_USB_CONFIG - * - */ -#define ESP_MODEM_DTE_DEFAULT_USB_CONFIG(_usb_config) \ - { \ - .dte_buffer_size = 512, \ - .task_stack_size = 4096, \ - .task_priority = 5, \ - .extension_config = &_usb_config \ - } - -/** - * @brief ESP Modem USB Default Configuration - * - * @param[in] _vid USB Vendor ID - * @param[in] _pid USB Product ID - * @see USB host CDC-ACM driver documentation for details about interfaces settings - */ -#define ESP_MODEM_DEFAULT_USB_CONFIG(_vid, _pid) \ - { \ - .vid = _vid, \ - .pid = _pid, \ - .interface_idx = 0, \ - .timeout_ms = 0, \ - .xCoreID = 0, \ - .cdc_compliant = false, \ - .install_usb_host = true \ - } diff --git a/components/esp_modem/examples/modem_console/components/esp_modem_usb_dte/private_include/usb_terminal.hpp b/components/esp_modem/examples/modem_console/components/esp_modem_usb_dte/private_include/usb_terminal.hpp deleted file mode 100644 index 68c70ff9d..000000000 --- a/components/esp_modem/examples/modem_console/components/esp_modem_usb_dte/private_include/usb_terminal.hpp +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2021 Espressif Systems (Shanghai) CO LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#pragma once -#include "cxx_include/esp_modem_dte.hpp" -#include "sdkconfig.h" -#include "esp_log.h" - -struct esp_modem_dte_config; - -// Copy-pasted from esp_modem/private_include/exception_stub.hpp -#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS -#define TRY_CATCH_OR_DO(block, action) \ - try { block \ - } catch (std::bad_alloc& e) { \ - ESP_LOGE(TAG, "Out of memory"); \ - action; \ - } catch (::esp_modem::esp_err_exception& e) { \ - esp_err_t err = e.get_err_t(); \ - ESP_LOGE(TAG, "%s: Exception caught with ESP err_code=%d", __func__, err); \ - ESP_LOGE(TAG, "%s", e.what()); \ - action; \ - } - -#define TRY_CATCH_RET_NULL(block) TRY_CATCH_OR_DO(block, return nullptr) -#else - -#define TRY_CATCH_OR_DO(block, action) \ - block - -#define TRY_CATCH_RET_NULL(block) \ - block - -#endif - -namespace esp_modem { - -std::unique_ptr create_usb_terminal(const esp_modem_dte_config *config); - -} // namespace esp_modem diff --git a/components/esp_modem/examples/modem_console/main/CMakeLists.txt b/components/esp_modem/examples/modem_console/main/CMakeLists.txt index d30fd66a1..9fe560cf0 100644 --- a/components/esp_modem/examples/modem_console/main/CMakeLists.txt +++ b/components/esp_modem/examples/modem_console/main/CMakeLists.txt @@ -2,6 +2,6 @@ idf_component_register(SRCS "modem_console_main.cpp" "console_helper.cpp" "httpget_handle.c" "ping_handle.c" - REQUIRES console esp_http_client nvs_flash esp_modem esp_modem_usb_dte + REQUIRES console esp_http_client nvs_flash INCLUDE_DIRS ".") target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format") diff --git a/components/esp_modem/examples/modem_console/main/Kconfig.projbuild b/components/esp_modem/examples/modem_console/main/Kconfig.projbuild index 4be838bde..70ad5996b 100644 --- a/components/esp_modem/examples/modem_console/main/Kconfig.projbuild +++ b/components/esp_modem/examples/modem_console/main/Kconfig.projbuild @@ -16,6 +16,7 @@ menu "Example Configuration" endchoice choice EXAMPLE_MODEM_DEVICE + depends on EXAMPLE_SERIAL_CONFIG_UART prompt "Choose supported modem device (DCE)" default EXAMPLE_MODEM_DEVICE_BG96 help @@ -74,21 +75,23 @@ menu "Example Configuration" help Set to true for the PPP client to skip authentication - choice EXAMPLE_FLOW_CONTROL - bool "Set preferred modem control flow" - default EXAMPLE_FLOW_CONTROL_NONE - help - Set the modem's preferred control flow - - config EXAMPLE_FLOW_CONTROL_NONE - bool "No control flow" - config EXAMPLE_FLOW_CONTROL_SW - bool "SW control flow" - config EXAMPLE_FLOW_CONTROL_HW - bool "HW control flow" - endchoice - menu "UART Configuration" + depends on EXAMPLE_SERIAL_CONFIG_UART + + choice EXAMPLE_FLOW_CONTROL + bool "Set preferred modem control flow" + default EXAMPLE_FLOW_CONTROL_NONE + help + Set the modem's preferred control flow + + config EXAMPLE_FLOW_CONTROL_NONE + bool "No control flow" + config EXAMPLE_FLOW_CONTROL_SW + bool "SW control flow" + config EXAMPLE_FLOW_CONTROL_HW + bool "HW control flow" + endchoice + config EXAMPLE_MODEM_UART_TX_PIN int "TXD Pin Number" default 25 diff --git a/components/esp_modem/examples/modem_console/main/idf_component.yml b/components/esp_modem/examples/modem_console/main/idf_component.yml new file mode 100644 index 000000000..ffcae2a6b --- /dev/null +++ b/components/esp_modem/examples/modem_console/main/idf_component.yml @@ -0,0 +1,12 @@ +## IDF Component Manager Manifest File +dependencies: + ## Required IDF version + idf: ">=4.1.0" + espressif/esp_modem: + version: "^0.1.20" + override_path: "../../../" + espressif/esp_modem_usb_dte: + version: "^1.0.0" + rules: + - if: "idf_version >=4.4" + - if: "target in [esp32s2, esp32s3]" \ No newline at end of file diff --git a/components/esp_modem/examples/modem_console/main/modem_console_main.cpp b/components/esp_modem/examples/modem_console/main/modem_console_main.cpp index 1d976b963..3c375d65f 100644 --- a/components/esp_modem/examples/modem_console/main/modem_console_main.cpp +++ b/components/esp_modem/examples/modem_console/main/modem_console_main.cpp @@ -18,7 +18,7 @@ #include "cxx_include/esp_modem_dte.hpp" #include "esp_modem_config.h" #include "cxx_include/esp_modem_api.hpp" -#if defined(CONFIG_USB_OTG_SUPPORTED) +#if defined(CONFIG_EXAMPLE_SERIAL_CONFIG_USB) #include "esp_modem_usb_config.h" #include "cxx_include/esp_modem_usb_api.hpp" #endif @@ -56,6 +56,7 @@ static const char *TAG = "modem_console"; static esp_console_repl_t *s_repl = nullptr; using namespace esp_modem; +static SignalGroup exit_signal; extern "C" void app_main(void) @@ -111,13 +112,19 @@ extern "C" void app_main(void) #elif defined(CONFIG_EXAMPLE_SERIAL_CONFIG_USB) - struct esp_modem_usb_term_config usb_config = ESP_MODEM_DEFAULT_USB_CONFIG(0x2C7C, 0x0296); // VID and PID of BG96 modem - // BG96 modem implements Vendor Specific class, that is CDC-ACM like. Interface for AT commands has index no. 2. - usb_config.interface_idx = 2; - esp_modem_dte_config_t dte_config = ESP_MODEM_DTE_DEFAULT_USB_CONFIG(usb_config); - ESP_LOGI(TAG, "Waiting for USB device connection..."); - auto dte = create_usb_dte(&dte_config); - std::unique_ptr dce = create_BG96_dce(&dce_config, dte, esp_netif); + while (1) { + exit_signal.clear(1); + struct esp_modem_usb_term_config usb_config = ESP_MODEM_DEFAULT_USB_CONFIG(0x2C7C, 0x0296, 2); // VID, PID and interface num of BG96 modem + const esp_modem_dte_config_t dte_config = ESP_MODEM_DTE_DEFAULT_USB_CONFIG(usb_config); + ESP_LOGI(TAG, "Waiting for USB device connection..."); + auto dte = create_usb_dte(&dte_config); + dte->set_error_cb([&](terminal_error err) { + ESP_LOGI(TAG, "error handler %d", err); + if (err == terminal_error::DEVICE_GONE) { + exit_signal.set(1); + } + }); + std::unique_ptr dce = create_BG96_dce(&dce_config, dte, esp_netif); #else #error Invalid serial connection to modem. @@ -277,16 +284,19 @@ extern "C" void app_main(void) return 0; }); - SignalGroup exit_signal; const ConsoleCommand ExitConsole("exit", "exit the console application", no_args, [&](ConsoleCommand * c) { ESP_LOGI(TAG, "Exiting..."); exit_signal.set(1); - s_repl->del(s_repl); return 0; }); // start console REPL ESP_ERROR_CHECK(esp_console_start_repl(s_repl)); // wait for exit exit_signal.wait_any(1, UINT32_MAX); + s_repl->del(s_repl); ESP_LOGI(TAG, "Exiting...%d", esp_get_free_heap_size()); +#if defined(CONFIG_EXAMPLE_SERIAL_CONFIG_USB) + // USB example runs in a loop to demonstrate hot-plugging and sudden disconnection features. + } // while (1) +#endif }