From ebc36a3519ce8633ead394b0f15cb90780d6e397 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20H=C3=B6pfinger?= Date: Tue, 23 Aug 2022 14:41:36 +0200 Subject: [PATCH 1/5] fix(esp_modem): Extend pppos example project config --- .../pppos_client/main/Kconfig.projbuild | 24 +++++++++++++++- .../pppos_client/main/pppos_client_main.c | 28 ++++++++++++++++++- 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/components/esp_modem/examples/pppos_client/main/Kconfig.projbuild b/components/esp_modem/examples/pppos_client/main/Kconfig.projbuild index 2da54ba01..4a0e0dbd5 100644 --- a/components/esp_modem/examples/pppos_client/main/Kconfig.projbuild +++ b/components/esp_modem/examples/pppos_client/main/Kconfig.projbuild @@ -29,10 +29,18 @@ menu "Example Configuration" bool "BG96" help Quectel BG96 is a series of LTE Cat M1/Cat NB1/EGPRS module. + config EXAMPLE_MODEM_DEVICE_SIM7000 + bool "SIM7000" + help + SIM7000 is a Multi-Band LTE-FDD and GSM/GPRS/EDGE module. + config EXAMPLE_MODEM_DEVICE_SIM7070 + bool "SIM7070" + help + SIM7070 is Multi-Band CAT M and NB IoT module. config EXAMPLE_MODEM_DEVICE_SIM7600 bool "SIM7600" help - SIM7600 is Multi-Band LTE-TDD/LTE-FDD/HSPA+ and GSM/GPRS/EDGE module + SIM7600 is a Multi-Band LTE-TDD/LTE-FDD/HSPA+ and GSM/GPRS/EDGE module. endchoice config EXAMPLE_MODEM_PPP_APN @@ -88,6 +96,20 @@ menu "Example Configuration" help Pin to unlock the SIM + 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 config EXAMPLE_MODEM_UART_TX_PIN diff --git a/components/esp_modem/examples/pppos_client/main/pppos_client_main.c b/components/esp_modem/examples/pppos_client/main/pppos_client_main.c index a7dac04a6..81e6cf2bc 100644 --- a/components/esp_modem/examples/pppos_client/main/pppos_client_main.c +++ b/components/esp_modem/examples/pppos_client/main/pppos_client_main.c @@ -21,6 +21,15 @@ #include "esp_log.h" #include "sdkconfig.h" + +#if defined(CONFIG_EXAMPLE_FLOW_CONTROL_NONE) +#define EXAMPLE_FLOW_CONTROL ESP_MODEM_FLOW_CONTROL_NONE +#elif defined(CONFIG_EXAMPLE_FLOW_CONTROL_SW) +#define EXAMPLE_FLOW_CONTROL ESP_MODEM_FLOW_CONTROL_SW +#elif defined(CONFIG_EXAMPLE_FLOW_CONTROL_HW) +#define EXAMPLE_FLOW_CONTROL ESP_MODEM_FLOW_CONTROL_HW +#endif + #define BROKER_URL "mqtt://mqtt.eclipseprojects.io" static const char *TAG = "pppos_example"; @@ -161,6 +170,7 @@ void app_main(void) dte_config.uart_config.rx_io_num = CONFIG_EXAMPLE_MODEM_UART_RX_PIN; dte_config.uart_config.rts_io_num = CONFIG_EXAMPLE_MODEM_UART_RTS_PIN; dte_config.uart_config.cts_io_num = CONFIG_EXAMPLE_MODEM_UART_CTS_PIN; + dte_config.uart_config.flow_control = EXAMPLE_FLOW_CONTROL; dte_config.uart_config.rx_buffer_size = CONFIG_EXAMPLE_MODEM_UART_RX_BUFFER_SIZE; dte_config.uart_config.tx_buffer_size = CONFIG_EXAMPLE_MODEM_UART_TX_BUFFER_SIZE; dte_config.uart_config.event_queue_size = CONFIG_EXAMPLE_MODEM_UART_EVENT_QUEUE_SIZE; @@ -174,6 +184,12 @@ void app_main(void) #elif CONFIG_EXAMPLE_MODEM_DEVICE_SIM800 == 1 ESP_LOGI(TAG, "Initializing esp_modem for the SIM800 module..."); esp_modem_dce_t *dce = esp_modem_new_dev(ESP_MODEM_DCE_SIM800, &dte_config, &dce_config, esp_netif); +#elif CONFIG_EXAMPLE_MODEM_DEVICE_SIM7000 == 1 + ESP_LOGI(TAG, "Initializing esp_modem for the SIM7000 module..."); + esp_modem_dce_t *dce = esp_modem_new_dev(ESP_MODEM_DCE_SIM7000, &dte_config, &dce_config, esp_netif); +#elif CONFIG_EXAMPLE_MODEM_DEVICE_SIM7070 == 1 + ESP_LOGI(TAG, "Initializing esp_modem for the SIM7070 module..."); + esp_modem_dce_t *dce = esp_modem_new_dev(ESP_MODEM_DCE_SIM7070, &dte_config, &dce_config, esp_netif); #elif CONFIG_EXAMPLE_MODEM_DEVICE_SIM7600 == 1 ESP_LOGI(TAG, "Initializing esp_modem for the SIM7600 module..."); esp_modem_dce_t *dce = esp_modem_new_dev(ESP_MODEM_DCE_SIM7600, &dte_config, &dce_config, esp_netif); @@ -199,6 +215,16 @@ void app_main(void) xEventGroupClearBits(event_group, CONNECT_BIT | GOT_DATA_BIT | USB_DISCONNECTED_BIT); /* Run the modem demo app */ + + if (dte_config.uart_config.flow_control == ESP_MODEM_FLOW_CONTROL_HW) { + esp_err_t err = esp_modem_set_flow_control(dce, 2, 2); //2/2 means HW Flow Control. + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to set the set_flow_control mode"); + return; + } + ESP_LOGI(TAG, "set_flow_control OK"); + } + #if CONFIG_EXAMPLE_NEED_SIM_PIN == 1 // check if PIN needed bool pin_ok = false; @@ -214,7 +240,7 @@ void app_main(void) int rssi, ber; esp_err_t err = esp_modem_get_signal_quality(dce, &rssi, &ber); if (err != ESP_OK) { - ESP_LOGE(TAG, "esp_modem_get_signal_quality failed with %d", err); + ESP_LOGE(TAG, "esp_modem_get_signal_quality failed with %d %s", err, esp_err_to_name(err)); return; } ESP_LOGI(TAG, "Signal quality: rssi=%d, ber=%d", rssi, ber); From 71a2388acb51e7820fb4d03c942610e6c23ba7ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20H=C3=B6pfinger?= Date: Tue, 4 Oct 2022 10:21:38 +0200 Subject: [PATCH 2/5] fix(esp_modem): Examples to configure MQTT Broker --- .../examples/simple_cmux_client/main/Kconfig.projbuild | 6 ++++++ .../simple_cmux_client/main/simple_cmux_client_main.cpp | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/components/esp_modem/examples/simple_cmux_client/main/Kconfig.projbuild b/components/esp_modem/examples/simple_cmux_client/main/Kconfig.projbuild index 16c0da168..7c6d91752 100644 --- a/components/esp_modem/examples/simple_cmux_client/main/Kconfig.projbuild +++ b/components/esp_modem/examples/simple_cmux_client/main/Kconfig.projbuild @@ -119,4 +119,10 @@ menu "Example Configuration" help Close the multiplexed mode at the end of the example and rollback to command mode. + config BROKER_URI + string "Broker URL" + default "mqtt://test.mosquitto.org" + help + URL of an mqtt broker which this example connects to. + endmenu diff --git a/components/esp_modem/examples/simple_cmux_client/main/simple_cmux_client_main.cpp b/components/esp_modem/examples/simple_cmux_client/main/simple_cmux_client_main.cpp index 0f3f4b760..d54fdeb03 100644 --- a/components/esp_modem/examples/simple_cmux_client/main/simple_cmux_client_main.cpp +++ b/components/esp_modem/examples/simple_cmux_client/main/simple_cmux_client_main.cpp @@ -34,7 +34,7 @@ #define EXAMPLE_FLOW_CONTROL ESP_MODEM_FLOW_CONTROL_HW #endif -#define BROKER_URL "mqtt://mqtt.eclipseprojects.io" +#define BROKER_URL CONFIG_BROKER_URI using namespace esp_modem; From 652314e73d72f72b982d0b63d1f6748585c7bc91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20H=C3=B6pfinger?= Date: Tue, 23 Aug 2022 14:13:10 +0200 Subject: [PATCH 3/5] fix(esp_modem) Add example that reads GNSS info --- .../components/SIM7070_gnss/CMakeLists.txt | 9 + .../components/SIM7070_gnss/SIM7070_gnss.cpp | 340 ++++++++++++++++++ .../components/SIM7070_gnss/SIM7070_gnss.hpp | 57 +++ .../components/SIM7070_gnss/nmea_parser.h | 137 +++++++ .../simple_cmux_client/main/Kconfig.projbuild | 4 + .../main/simple_cmux_client_main.cpp | 56 ++- .../simple_cmux_client/sdkconfig.defaults | 2 +- .../include/cxx_include/command_library.hpp | 27 ++ .../src/esp_modem_command_library.cpp | 14 +- 9 files changed, 634 insertions(+), 12 deletions(-) create mode 100644 components/esp_modem/examples/simple_cmux_client/components/SIM7070_gnss/CMakeLists.txt create mode 100644 components/esp_modem/examples/simple_cmux_client/components/SIM7070_gnss/SIM7070_gnss.cpp create mode 100644 components/esp_modem/examples/simple_cmux_client/components/SIM7070_gnss/SIM7070_gnss.hpp create mode 100644 components/esp_modem/examples/simple_cmux_client/components/SIM7070_gnss/nmea_parser.h create mode 100644 components/esp_modem/include/cxx_include/command_library.hpp diff --git a/components/esp_modem/examples/simple_cmux_client/components/SIM7070_gnss/CMakeLists.txt b/components/esp_modem/examples/simple_cmux_client/components/SIM7070_gnss/CMakeLists.txt new file mode 100644 index 000000000..86e1fa24a --- /dev/null +++ b/components/esp_modem/examples/simple_cmux_client/components/SIM7070_gnss/CMakeLists.txt @@ -0,0 +1,9 @@ +idf_component_register(SRCS "SIM7070_gnss.cpp" + INCLUDE_DIRS "." + PRIV_REQUIRES esp_modem) + +set_target_properties(${COMPONENT_LIB} PROPERTIES + CXX_STANDARD 17 + CXX_STANDARD_REQUIRED ON + CXX_EXTENSIONS ON +) diff --git a/components/esp_modem/examples/simple_cmux_client/components/SIM7070_gnss/SIM7070_gnss.cpp b/components/esp_modem/examples/simple_cmux_client/components/SIM7070_gnss/SIM7070_gnss.cpp new file mode 100644 index 000000000..cafe1c2bb --- /dev/null +++ b/components/esp_modem/examples/simple_cmux_client/components/SIM7070_gnss/SIM7070_gnss.cpp @@ -0,0 +1,340 @@ +/* + * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +// +// Created on: 23.08.2022 +// Author: franz + + +#include +#include +#include +#include +#include +#include +#include +#include "sdkconfig.h" +#include "esp_event.h" +#include "cxx_include/esp_modem_dte.hpp" +#include "cxx_include/esp_modem_dce.hpp" +#include "esp_modem_config.h" +#include "cxx_include/esp_modem_api.hpp" +#include "cxx_include/command_library.hpp" +#include "esp_log.h" +#include "SIM7070_gnss.hpp" + + +const static char *const TAG = "SIM7070_gnss"; + + +class LocalFactory: public esp_modem::dce_factory::Factory { +public: + static std::unique_ptr create(const esp_modem::dce_config *config, std::shared_ptr dte, esp_netif_t *netif) + { + return esp_modem::dce_factory::Factory::build_generic_DCE>(config, dte, netif); + } + +}; +/** + * @brief Helper create method which employs the DCE factory for creating DCE objects templated by a custom module + * @return unique pointer of the resultant DCE + */ +std::unique_ptr create_SIM7070_GNSS_dce(const esp_modem::dce_config *config, + std::shared_ptr dte, + esp_netif_t *netif) +{ + return LocalFactory::create(config, std::move(dte), netif); +} + +esp_modem::command_result get_gnss_information_sim70xx_lib(esp_modem::CommandableIf *t, gps_t &gps) +{ + + ESP_LOGV(TAG, "%s", __func__ ); + std::string_view out; + auto ret = esp_modem::dce_commands::generic_get_string(t, "AT+CGNSINF\r", out); + if (ret != esp_modem::command_result::OK) { + return ret; + } + + + + constexpr std::string_view pattern = "+CGNSINF: "; + if (out.find(pattern) == std::string_view::npos) { + return esp_modem::command_result::FAIL; + } + /** + * Parsing +CGNSINF: + * , + * , + * , + * , + * , + * , + * , + * , + * , + * , + * , + * , + * , + * , + * , + * , + * , + * + */ + out = out.substr(pattern.size()); + int pos = 0; + if ((pos = out.find(',')) == std::string::npos) { + return esp_modem::command_result::FAIL; + } + //GNSS run status + int GNSS_run_status; + if (std::from_chars(out.data(), out.data() + pos, GNSS_run_status).ec == std::errc::invalid_argument) { + return esp_modem::command_result::FAIL; + } + gps.run = (gps_run_t)GNSS_run_status; + out = out.substr(pos + 1); + if ((pos = out.find(',')) == std::string::npos) { + return esp_modem::command_result::FAIL; + } + //Fix status + { + std::string_view fix_status = out.substr(0, pos); + if (fix_status.length() > 1) { + int Fix_status; + if (std::from_chars(out.data(), out.data() + pos, Fix_status).ec == std::errc::invalid_argument) { + return esp_modem::command_result::FAIL; + } + gps.fix = (gps_fix_t)Fix_status; + } else { + gps.fix = GPS_FIX_INVALID; + } + } //clean up Fix status + out = out.substr(pos + 1); + if ((pos = out.find(',')) == std::string::npos) { + return esp_modem::command_result::FAIL; + } + //UTC date & Time + { + std::string_view UTC_date_and_Time = out.substr(0, pos); + if (UTC_date_and_Time.length() > 1) { + if (std::from_chars(out.data() + 0, out.data() + 4, gps.date.year).ec == std::errc::invalid_argument) { + return esp_modem::command_result::FAIL; + } + if (std::from_chars(out.data() + 4, out.data() + 6, gps.date.month).ec == std::errc::invalid_argument) { + return esp_modem::command_result::FAIL; + } + if (std::from_chars(out.data() + 6, out.data() + 8, gps.date.day).ec == std::errc::invalid_argument) { + return esp_modem::command_result::FAIL; + } + if (std::from_chars(out.data() + 8, out.data() + 10, gps.tim.hour).ec == std::errc::invalid_argument) { + return esp_modem::command_result::FAIL; + } + if (std::from_chars(out.data() + 10, out.data() + 12, gps.tim.minute).ec == std::errc::invalid_argument) { + return esp_modem::command_result::FAIL; + } + if (std::from_chars(out.data() + 12, out.data() + 14, gps.tim.second).ec == std::errc::invalid_argument) { + return esp_modem::command_result::FAIL; + } + if (std::from_chars(out.data() + 15, out.data() + 18, gps.tim.thousand).ec == std::errc::invalid_argument) { + return esp_modem::command_result::FAIL; + } + } else { + gps.date.year = 0; + gps.date.month = 0; + gps.date.day = 0; + gps.tim.hour = 0; + gps.tim.minute = 0; + gps.tim.second = 0; + gps.tim.thousand = 0; + } + + } //clean up UTC date & Time + out = out.substr(pos + 1); + if ((pos = out.find(',')) == std::string::npos) { + return esp_modem::command_result::FAIL; + } + //Latitude + { + std::string_view Latitude = out.substr(0, pos); + if (Latitude.length() > 1) { + gps.latitude = std::stof(std::string(out.substr(0, pos))); + } else { + gps.latitude = 0; + } + } //clean up Latitude + out = out.substr(pos + 1); + if ((pos = out.find(',')) == std::string::npos) { + return esp_modem::command_result::FAIL; + } + //Longitude + { + std::string_view Longitude = out.substr(0, pos); + if (Longitude.length() > 1) { + gps.longitude = std::stof(std::string(out.substr(0, pos))); + } else { + gps.longitude = 0; + } + } //clean up Longitude + out = out.substr(pos + 1); + if ((pos = out.find(',')) == std::string::npos) { + return esp_modem::command_result::FAIL; + } + //Altitude + { + std::string_view Altitude = out.substr(0, pos); + if (Altitude.length() > 1) { + gps.altitude = std::stof(std::string(out.substr(0, pos))); + } else { + gps.altitude = 0; + } + } //clean up Altitude + out = out.substr(pos + 1); + if ((pos = out.find(',')) == std::string::npos) { + return esp_modem::command_result::FAIL; + } + //Speed Over Ground Km/hour + { + std::string_view gps_speed = out.substr(0, pos); + if (gps_speed.length() > 1) { + gps.speed = std::stof(std::string(gps_speed)); + } else { + gps.speed = 0; + } + } //clean up gps_speed + out = out.substr(pos + 1); + if ((pos = out.find(',')) == std::string::npos) { + return esp_modem::command_result::FAIL; + } + //Course Over Ground degrees + { + std::string_view gps_cog = out.substr(0, pos); + if (gps_cog.length() > 1) { + gps.cog = std::stof(std::string(gps_cog)); + } else { + gps.cog = 0; + } + } //clean up gps_cog + out = out.substr(pos + 1); + if ((pos = out.find(',')) == std::string::npos) { + return esp_modem::command_result::FAIL; + } + // Fix Mode + { + std::string_view FixModesubstr = out.substr(0, pos); + if (FixModesubstr.length() > 1) { + int Fix_Mode; + if (std::from_chars(out.data(), out.data() + pos, Fix_Mode).ec == std::errc::invalid_argument) { + return esp_modem::command_result::FAIL; + } + gps.fix_mode = (gps_fix_mode_t)Fix_Mode; + } else { + gps.fix_mode = GPS_MODE_INVALID; + } + } //clean up Fix Mode + out = out.substr(pos + 1); + if ((pos = out.find(',')) == std::string::npos) { + return esp_modem::command_result::FAIL; + } + out = out.substr(pos + 1); + if ((pos = out.find(',')) == std::string::npos) { + return esp_modem::command_result::FAIL; + } + //HDOP + { + std::string_view HDOP = out.substr(0, pos); + if (HDOP.length() > 1) { + gps.dop_h = std::stof(std::string(HDOP)); + } else { + gps.dop_h = 0; + } + } //clean up HDOP + out = out.substr(pos + 1); + if ((pos = out.find(',')) == std::string::npos) { + return esp_modem::command_result::FAIL; + } + //PDOP + { + std::string_view PDOP = out.substr(0, pos); + if (PDOP.length() > 1) { + gps.dop_p = std::stof(std::string(PDOP)); + } else { + gps.dop_p = 0; + } + } //clean up PDOP + out = out.substr(pos + 1); + if ((pos = out.find(',')) == std::string::npos) { + return esp_modem::command_result::FAIL; + } + //VDOP + { + std::string_view VDOP = out.substr(0, pos); + if (VDOP.length() > 1) { + gps.dop_v = std::stof(std::string(VDOP)); + } else { + gps.dop_v = 0; + } + } //clean up VDOP + out = out.substr(pos + 1); + if ((pos = out.find(',')) == std::string::npos) { + return esp_modem::command_result::FAIL; + } + out = out.substr(pos + 1); + if ((pos = out.find(',')) == std::string::npos) { + return esp_modem::command_result::FAIL; + } + //sats_in_view + { + std::string_view sats_in_view = out.substr(0, pos); + if (sats_in_view.length() > 1) { + if (std::from_chars(out.data(), out.data() + pos, gps.sats_in_view).ec == std::errc::invalid_argument) { + return esp_modem::command_result::FAIL; + } + } else { + gps.sats_in_view = 0; + } + } //clean up sats_in_view + + out = out.substr(pos + 1); + if ((pos = out.find(',')) == std::string::npos) { + return esp_modem::command_result::FAIL; + } + out = out.substr(pos + 1); + if ((pos = out.find(',')) == std::string::npos) { + return esp_modem::command_result::FAIL; + } + //HPA + { + std::string_view HPA = out.substr(0, pos); + if (HPA.length() > 1) { + gps.hpa = std::stof(std::string(HPA)); + } else { + gps.hpa = 0; + } + } //clean up HPA + out = out.substr(pos + 1); + //VPA + { + std::string_view VPA = out.substr(0, pos); + if (VPA.length() > 1) { + gps.vpa = std::stof(std::string(VPA)); + } else { + gps.vpa = 0; + } + } //clean up VPA + + return esp_modem::command_result::OK; +} + +esp_modem::command_result SIM7070_gnss::get_gnss_information_sim70xx(gps_t &gps) +{ + return get_gnss_information_sim70xx_lib(dte.get(), gps); +} + +esp_modem::command_result DCE_gnss::get_gnss_information_sim70xx(gps_t &gps) +{ + return device->get_gnss_information_sim70xx(gps); +} diff --git a/components/esp_modem/examples/simple_cmux_client/components/SIM7070_gnss/SIM7070_gnss.hpp b/components/esp_modem/examples/simple_cmux_client/components/SIM7070_gnss/SIM7070_gnss.hpp new file mode 100644 index 000000000..10650867e --- /dev/null +++ b/components/esp_modem/examples/simple_cmux_client/components/SIM7070_gnss/SIM7070_gnss.hpp @@ -0,0 +1,57 @@ +/* + * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +// +// Created on: 23.08.2022 +// Author: franz + + +#pragma once + + +#include "cxx_include/esp_modem_dce_factory.hpp" +#include "cxx_include/esp_modem_dce_module.hpp" +#include "nmea_parser.h" + +/** + * @brief Definition of a custom modem which inherits from the GenericModule, uses all its methods + * and could override any of them. Here, for demonstration purposes only, we redefine just `get_module_name()` + */ +class SIM7070_gnss: public esp_modem::SIM7070 { + using SIM7070::SIM7070; +public: + esp_modem::command_result get_gnss_information_sim70xx(gps_t &gps); +}; + +class DCE_gnss : public esp_modem::DCE_T { +public: + + using DCE_T::DCE_T; +#define ESP_MODEM_DECLARE_DCE_COMMAND(name, return_type, num, ...) \ + template \ + esp_modem::return_type name(Agrs&&... args) \ + { \ + return device->name(std::forward(args)...); \ + } + + DECLARE_ALL_COMMAND_APIS(forwards name(...) + { + device->name(...); + } ) + +#undef ESP_MODEM_DECLARE_DCE_COMMAND + + esp_modem::command_result get_gnss_information_sim70xx(gps_t &gps); + +}; + + +/** + * @brief Helper create method which employs the DCE factory for creating DCE objects templated by a custom module + * @return unique pointer of the resultant DCE + */ +std::unique_ptr create_SIM7070_GNSS_dce(const esp_modem::dce_config *config, + std::shared_ptr dte, + esp_netif_t *netif); diff --git a/components/esp_modem/examples/simple_cmux_client/components/SIM7070_gnss/nmea_parser.h b/components/esp_modem/examples/simple_cmux_client/components/SIM7070_gnss/nmea_parser.h new file mode 100644 index 000000000..4f6fcebf9 --- /dev/null +++ b/components/esp_modem/examples/simple_cmux_client/components/SIM7070_gnss/nmea_parser.h @@ -0,0 +1,137 @@ +/* + * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + * + * Origin: https://github.com/espressif/esp-idf/blob/master/examples/peripherals/uart/nmea0183_parser/main/nmea_parser.h + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + + +#define GPS_MAX_SATELLITES_IN_USE (12) +#define GPS_MAX_SATELLITES_IN_VIEW (16) + + + +/** + * @brief GPS fix type + * + */ +typedef enum { + GPS_FIX_INVALID, /*!< Not fixed */ + GPS_FIX_GPS, /*!< GPS */ + GPS_FIX_DGPS, /*!< Differential GPS */ +} gps_fix_t; + +/** + * @brief GPS run type + * + */ +typedef enum { + GPS_RUN_INVALID, /*!< Not fixed */ + GPS_RUN_GPS, /*!< GPS */ +} gps_run_t; + +/** + * @brief GPS fix mode + * + */ +typedef enum { + GPS_MODE_INVALID, /*!< Not fixed */ + GPS_MODE_2D, /*!< 2D GPS */ + GPS_MODE_3D /*!< 3D GPS */ +} gps_fix_mode_t; + +/** + * @brief GPS satellite information + * + */ +typedef struct { + uint8_t num; /*!< Satellite number */ + uint8_t elevation; /*!< Satellite elevation */ + uint16_t azimuth; /*!< Satellite azimuth */ + uint8_t snr; /*!< Satellite signal noise ratio */ +} gps_satellite_t; + +/** + * @brief GPS time + * + */ +typedef struct { + uint8_t hour; /*!< Hour */ + uint8_t minute; /*!< Minute */ + uint8_t second; /*!< Second */ + uint16_t thousand; /*!< Thousand */ +} gps_time_t; + +/** + * @brief GPS date + * + */ +typedef struct { + uint8_t day; /*!< Day (start from 1) */ + uint8_t month; /*!< Month (start from 1) */ + uint16_t year; /*!< Year (start from 2000) */ +} gps_date_t; + +/** + * @brief NMEA Statement + * + */ +typedef enum { + STATEMENT_UNKNOWN = 0, /*!< Unknown statement */ + STATEMENT_GGA, /*!< GGA */ + STATEMENT_GSA, /*!< GSA */ + STATEMENT_RMC, /*!< RMC */ + STATEMENT_GSV, /*!< GSV */ + STATEMENT_GLL, /*!< GLL */ + STATEMENT_VTG /*!< VTG */ +} nmea_statement_t; + +/** + * @brief GPS object + * + */ +struct gps_s { + float latitude; /*!< Latitude (degrees) */ + float longitude; /*!< Longitude (degrees) */ + float altitude; /*!< Altitude (meters) */ + gps_run_t run; /*!< run status */ + gps_fix_t fix; /*!< Fix status */ + uint8_t sats_in_use; /*!< Number of satellites in use */ + gps_time_t tim; /*!< time in UTC */ + gps_fix_mode_t fix_mode; /*!< Fix mode */ + float dop_h; /*!< Horizontal dilution of precision */ + float dop_p; /*!< Position dilution of precision */ + float dop_v; /*!< Vertical dilution of precision */ + uint8_t sats_in_view; /*!< Number of satellites in view */ + gps_date_t date; /*!< Fix date */ + float speed; /*!< Ground speed, unit: m/s */ + float cog; /*!< Course over ground */ + float hpa; /*!< Horizontal Position Accuracy */ + float vpa; /*!< Vertical Position Accuracy */ +}; + +typedef struct gps_s gps_t; +typedef struct gps_s esp_modem_gps_s_t; + + + + +/** + * @brief NMEA Parser Event ID + * + */ +typedef enum { + GPS_UPDATE, /*!< GPS information has been updated */ + GPS_UNKNOWN /*!< Unknown statements detected */ +} nmea_event_id_t; + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_modem/examples/simple_cmux_client/main/Kconfig.projbuild b/components/esp_modem/examples/simple_cmux_client/main/Kconfig.projbuild index 7c6d91752..bf733a9ee 100644 --- a/components/esp_modem/examples/simple_cmux_client/main/Kconfig.projbuild +++ b/components/esp_modem/examples/simple_cmux_client/main/Kconfig.projbuild @@ -22,6 +22,10 @@ menu "Example Configuration" bool "SIM7070" help SIM7070 is Multi-Band CAT M and NB IoT module. + config EXAMPLE_MODEM_DEVICE_SIM7070_GNSS + bool "SIM7070_GNSS" + help + SIM7070 is Multi-Band CAT M and NB IoT module with Support for GNSS Location API config EXAMPLE_MODEM_DEVICE_SIM7600 bool "SIM7600" help diff --git a/components/esp_modem/examples/simple_cmux_client/main/simple_cmux_client_main.cpp b/components/esp_modem/examples/simple_cmux_client/main/simple_cmux_client_main.cpp index d54fdeb03..dadbcc6cc 100644 --- a/components/esp_modem/examples/simple_cmux_client/main/simple_cmux_client_main.cpp +++ b/components/esp_modem/examples/simple_cmux_client/main/simple_cmux_client_main.cpp @@ -25,6 +25,7 @@ #include "esp_vfs_dev.h" // For optional VFS support #include "esp_https_ota.h" // For potential OTA configuration #include "vfs_resource/vfs_create.hpp" +#include "SIM7070_gnss.hpp" #if defined(CONFIG_EXAMPLE_FLOW_CONTROL_NONE) #define EXAMPLE_FLOW_CONTROL ESP_MODEM_FLOW_CONTROL_NONE @@ -87,15 +88,17 @@ extern "C" void app_main(void) assert(esp_netif); #if CONFIG_EXAMPLE_MODEM_DEVICE_BG96 == 1 - std::unique_ptr dce = create_BG96_dce(&dce_config, dte, esp_netif); + auto dce = create_BG96_dce(&dce_config, dte, esp_netif); #elif CONFIG_EXAMPLE_MODEM_DEVICE_SIM800 == 1 - std::unique_ptr dce = create_SIM800_dce(&dce_config, dte, esp_netif); + auto dce = create_SIM800_dce(&dce_config, dte, esp_netif); #elif CONFIG_EXAMPLE_MODEM_DEVICE_SIM7000 == 1 - std::unique_ptr dce = create_SIM7000_dce(&dce_config, dte, esp_netif); + auto dce = create_SIM7000_dce(&dce_config, dte, esp_netif); #elif CONFIG_EXAMPLE_MODEM_DEVICE_SIM7070 == 1 - std::unique_ptr dce = create_SIM7070_dce(&dce_config, dte, esp_netif); + auto dce = create_SIM7070_dce(&dce_config, dte, esp_netif); +#elif CONFIG_EXAMPLE_MODEM_DEVICE_SIM7070_GNSS == 1 + auto dce = create_SIM7070_GNSS_dce(&dce_config, dte, esp_netif); #elif CONFIG_EXAMPLE_MODEM_DEVICE_SIM7600 == 1 - std::unique_ptr dce = create_SIM7600_dce(&dce_config, dte, esp_netif); + auto dce = create_SIM7600_dce(&dce_config, dte, esp_netif); #else #error "Unsupported device" #endif @@ -135,6 +138,12 @@ extern "C" void app_main(void) } std::cout << "Operator name:" << str << std::endl; +#if CONFIG_EXAMPLE_MODEM_DEVICE_SIM7070_GNSS == 1 + if (dce->set_gnss_power_mode(1) == esp_modem::command_result::OK) { + std::cout << "Modem set_gnss_power_mode: OK" << std::endl; + } +#endif + /* Try to connect to the network and publish an mqtt topic */ ESPEventHandlerSync event_handler(loop); event_handler.listen_to(ESPEvent(IP_EVENT, ESPEventID(ESP_EVENT_ANY_ID))); @@ -184,6 +193,43 @@ extern "C" void app_main(void) std::cout << "Modem IMSI number:" << str << std::endl; } + +#if CONFIG_EXAMPLE_MODEM_DEVICE_SIM7070_GNSS == 1 + gps_t gps; + + for (int i = 0; i < 200; ++i) { + if (dce->get_gnss_information_sim70xx(gps) == esp_modem::command_result::OK) { + ESP_LOGI(TAG, "gps.run %i", + gps.run); + ESP_LOGI(TAG, "gps.fix %i", + gps.fix); + ESP_LOGI(TAG, "gps.date.year %i gps.date.month %i gps.date.day %i", + gps.date.year, gps.date.month, gps.date.day); + ESP_LOGI(TAG, "gps.tim.hour %i gps.tim.minute %i gps.tim.second %i gps.tim.thousand %i", + gps.tim.hour, gps.tim.minute, gps.tim.second, gps.tim.thousand); + ESP_LOGI(TAG, "gps.latitude %f gps.longitude %f ", + gps.latitude, gps.longitude ); + ESP_LOGI(TAG, "gps.altitude %f", + gps.altitude); + ESP_LOGI(TAG, "gps.speed %f", + gps.speed); + ESP_LOGI(TAG, "gps.cog %f", + gps.cog); + ESP_LOGI(TAG, "gps.fix_mode %i", + gps.fix_mode); + ESP_LOGI(TAG, "gps.dop_h %f gps.dop_p %f gps.dop_v %f ", + gps.dop_h, gps.dop_p, gps.dop_v ); + ESP_LOGI(TAG, "gps.sats_in_view %i", + gps.sats_in_view); + ESP_LOGI(TAG, "gps.hpa %f gps.vpa %f", + gps.hpa, gps.vpa); + } + vTaskDelay(pdMS_TO_TICKS(1000)); //Wait + + } +#endif // CONFIG_EXAMPLE_MODEM_DEVICE_SIM7070_GNSS + + #if CONFIG_EXAMPLE_PERFORM_OTA == 1 esp_http_client_config_t config = { }; config.skip_cert_common_name_check = true; diff --git a/components/esp_modem/examples/simple_cmux_client/sdkconfig.defaults b/components/esp_modem/examples/simple_cmux_client/sdkconfig.defaults index 8f54fe475..dab94ca82 100644 --- a/components/esp_modem/examples/simple_cmux_client/sdkconfig.defaults +++ b/components/esp_modem/examples/simple_cmux_client/sdkconfig.defaults @@ -9,4 +9,4 @@ CONFIG_PARTITION_TABLE_TWO_OTA=y CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF=y CONFIG_NEWLIB_STDIN_LINE_ENDING_LF=y -CONFIG_MAIN_TASK_STACK_SIZE=8192 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=8192 diff --git a/components/esp_modem/include/cxx_include/command_library.hpp b/components/esp_modem/include/cxx_include/command_library.hpp new file mode 100644 index 000000000..c2c00ee69 --- /dev/null +++ b/components/esp_modem/include/cxx_include/command_library.hpp @@ -0,0 +1,27 @@ +/* + * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once +namespace esp_modem::dce_commands { +command_result generic_command(CommandableIf *t, const std::string &command, + const std::list &pass_phrase, + const std::list &fail_phrase, + uint32_t timeout_ms); + + +command_result generic_command(CommandableIf *t, const std::string &command, + const std::string &pass_phrase, + const std::string &fail_phrase, uint32_t timeout_ms); + +command_result generic_get_string(CommandableIf *t, const std::string &command, std::string_view &output, uint32_t timeout_ms = 500); + +command_result generic_get_string(CommandableIf *t, const std::string &command, std::string &output, uint32_t timeout_ms = 500); + +command_result generic_command_common(CommandableIf *t, const std::string &command, uint32_t timeout = 500); + + + +} // esp_modem::dce_commands diff --git a/components/esp_modem/src/esp_modem_command_library.cpp b/components/esp_modem/src/esp_modem_command_library.cpp index 18d74532f..5b320a054 100644 --- a/components/esp_modem/src/esp_modem_command_library.cpp +++ b/components/esp_modem/src/esp_modem_command_library.cpp @@ -10,6 +10,8 @@ #include "cxx_include/esp_modem_dte.hpp" #include "cxx_include/esp_modem_dce_module.hpp" #include "cxx_include/esp_modem_command_library.hpp" +#include "cxx_include/command_library.hpp" + namespace esp_modem::dce_commands { @@ -40,9 +42,9 @@ command_result generic_command(CommandableIf *t, const std::string &command, } -static inline command_result generic_command(CommandableIf *t, const std::string &command, - const std::string &pass_phrase, - const std::string &fail_phrase, uint32_t timeout_ms) +command_result generic_command(CommandableIf *t, const std::string &command, + const std::string &pass_phrase, + const std::string &fail_phrase, uint32_t timeout_ms) { ESP_LOGV(TAG, "%s", __func__ ); const auto pass = std::list({pass_phrase}); @@ -50,7 +52,7 @@ static inline command_result generic_command(CommandableIf *t, const std::string return generic_command(t, command, pass, fail, timeout_ms); } -static inline command_result generic_get_string(CommandableIf *t, const std::string &command, std::string_view &output, uint32_t timeout_ms = 500) +command_result generic_get_string(CommandableIf *t, const std::string &command, std::string_view &output, uint32_t timeout_ms) { ESP_LOGV(TAG, "%s", __func__ ); return t->command(command, [&](uint8_t *data, size_t len) { @@ -77,7 +79,7 @@ static inline command_result generic_get_string(CommandableIf *t, const std::str }, timeout_ms); } -static inline command_result generic_get_string(CommandableIf *t, const std::string &command, std::string &output, uint32_t timeout_ms = 500) +command_result generic_get_string(CommandableIf *t, const std::string &command, std::string &output, uint32_t timeout_ms) { ESP_LOGV(TAG, "%s", __func__ ); std::string_view out; @@ -89,7 +91,7 @@ static inline command_result generic_get_string(CommandableIf *t, const std::str } -static inline command_result generic_command_common(CommandableIf *t, const std::string &command, uint32_t timeout = 500) +command_result generic_command_common(CommandableIf *t, const std::string &command, uint32_t timeout) { ESP_LOGV(TAG, "%s", __func__ ); return generic_command(t, command, "OK", "ERROR", timeout); From 65c0e0e195c2fa5bb93e8f7220faaeedffbaa782 Mon Sep 17 00:00:00 2001 From: David Cermak Date: Tue, 18 Oct 2022 16:57:42 +0200 Subject: [PATCH 4/5] fix(esp_modem): Cleanup custom lib-commands and factory --- .../pppos_client/main/Kconfig.projbuild | 29 ++++++------ .../pppos_client/main/pppos_client_main.c | 22 ++++----- .../components/SIM7070_gnss/SIM7070_gnss.cpp | 41 ++++++++--------- .../components/SIM7070_gnss/SIM7070_gnss.hpp | 16 ++++--- .../components/SIM7070_gnss/nmea_parser.h | 8 +--- .../main/simple_cmux_client_main.cpp | 2 +- .../include/cxx_include/command_library.hpp | 27 ----------- .../esp_modem_command_library_utils.hpp | 45 +++++++++++++++++++ .../src/esp_modem_command_library.cpp | 17 ++++--- 9 files changed, 113 insertions(+), 94 deletions(-) delete mode 100644 components/esp_modem/include/cxx_include/command_library.hpp create mode 100644 components/esp_modem/include/cxx_include/esp_modem_command_library_utils.hpp diff --git a/components/esp_modem/examples/pppos_client/main/Kconfig.projbuild b/components/esp_modem/examples/pppos_client/main/Kconfig.projbuild index 4a0e0dbd5..65243a0b5 100644 --- a/components/esp_modem/examples/pppos_client/main/Kconfig.projbuild +++ b/components/esp_modem/examples/pppos_client/main/Kconfig.projbuild @@ -96,20 +96,6 @@ menu "Example Configuration" help Pin to unlock the SIM - 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 config EXAMPLE_MODEM_UART_TX_PIN @@ -181,6 +167,21 @@ menu "Example Configuration" default 1024 help Buffer size of UART RX buffer. + + 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 + endmenu endmenu diff --git a/components/esp_modem/examples/pppos_client/main/pppos_client_main.c b/components/esp_modem/examples/pppos_client/main/pppos_client_main.c index 81e6cf2bc..99f669efe 100644 --- a/components/esp_modem/examples/pppos_client/main/pppos_client_main.c +++ b/components/esp_modem/examples/pppos_client/main/pppos_client_main.c @@ -197,6 +197,15 @@ void app_main(void) ESP_LOGI(TAG, "Initializing esp_modem for a generic module..."); esp_modem_dce_t *dce = esp_modem_new(&dte_config, &dce_config, esp_netif); #endif + assert(dce); + if (dte_config.uart_config.flow_control == ESP_MODEM_FLOW_CONTROL_HW) { + esp_err_t err = esp_modem_set_flow_control(dce, 2, 2); //2/2 means HW Flow Control. + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to set the set_flow_control mode"); + return; + } + ESP_LOGI(TAG, "HW set_flow_control OK"); + } #elif defined(CONFIG_EXAMPLE_SERIAL_CONFIG_USB) while (1) { @@ -205,26 +214,17 @@ void app_main(void) const esp_modem_dte_config_t dte_usb_config = ESP_MODEM_DTE_DEFAULT_USB_CONFIG(usb_config); ESP_LOGI(TAG, "Waiting for USB device connection..."); esp_modem_dce_t *dce = esp_modem_new_dev_usb(ESP_MODEM_DCE_BG96, &dte_usb_config, &dce_config, esp_netif); + assert(dce); esp_modem_set_error_cb(dce, usb_terminal_error_handler); vTaskDelay(pdMS_TO_TICKS(1000)); // Although the DTE should be ready after USB enumeration, sometimes it fails to respond without this delay #else #error Invalid serial connection to modem. #endif - assert(dce); + xEventGroupClearBits(event_group, CONNECT_BIT | GOT_DATA_BIT | USB_DISCONNECTED_BIT); /* Run the modem demo app */ - - if (dte_config.uart_config.flow_control == ESP_MODEM_FLOW_CONTROL_HW) { - esp_err_t err = esp_modem_set_flow_control(dce, 2, 2); //2/2 means HW Flow Control. - if (err != ESP_OK) { - ESP_LOGE(TAG, "Failed to set the set_flow_control mode"); - return; - } - ESP_LOGI(TAG, "set_flow_control OK"); - } - #if CONFIG_EXAMPLE_NEED_SIM_PIN == 1 // check if PIN needed bool pin_ok = false; diff --git a/components/esp_modem/examples/simple_cmux_client/components/SIM7070_gnss/SIM7070_gnss.cpp b/components/esp_modem/examples/simple_cmux_client/components/SIM7070_gnss/SIM7070_gnss.cpp index cafe1c2bb..b60f01b96 100644 --- a/components/esp_modem/examples/simple_cmux_client/components/SIM7070_gnss/SIM7070_gnss.cpp +++ b/components/esp_modem/examples/simple_cmux_client/components/SIM7070_gnss/SIM7070_gnss.cpp @@ -7,36 +7,37 @@ // Created on: 23.08.2022 // Author: franz - -#include -#include -#include #include -#include #include #include #include "sdkconfig.h" -#include "esp_event.h" #include "cxx_include/esp_modem_dte.hpp" #include "cxx_include/esp_modem_dce.hpp" #include "esp_modem_config.h" #include "cxx_include/esp_modem_api.hpp" -#include "cxx_include/command_library.hpp" +#include "cxx_include/esp_modem_command_library_utils.hpp" #include "esp_log.h" #include "SIM7070_gnss.hpp" - -const static char *const TAG = "SIM7070_gnss"; +constexpr auto const TAG = "SIM7070_gnss"; -class LocalFactory: public esp_modem::dce_factory::Factory { +namespace gnss_factory { +using namespace esp_modem; +using namespace dce_factory; + +class LocalFactory: public Factory { + using DCE_gnss_ret = std::unique_ptr; // this custom Factory manufactures only unique_ptr's public: - static std::unique_ptr create(const esp_modem::dce_config *config, std::shared_ptr dte, esp_netif_t *netif) + static DCE_gnss_ret create(const dce_config *config, std::shared_ptr dte, esp_netif_t *netif) { - return esp_modem::dce_factory::Factory::build_generic_DCE>(config, dte, netif); + return Factory::build_generic_DCE + (config, std::move(dte), netif); } - }; + +} // namespace gnss_factory + /** * @brief Helper create method which employs the DCE factory for creating DCE objects templated by a custom module * @return unique pointer of the resultant DCE @@ -45,19 +46,19 @@ std::unique_ptr create_SIM7070_GNSS_dce(const esp_modem::dce_config *c std::shared_ptr dte, esp_netif_t *netif) { - return LocalFactory::create(config, std::move(dte), netif); + return gnss_factory::LocalFactory::create(config, std::move(dte), netif); } -esp_modem::command_result get_gnss_information_sim70xx_lib(esp_modem::CommandableIf *t, gps_t &gps) +esp_modem::command_result get_gnss_information_sim70xx_lib(esp_modem::CommandableIf *t, esp_modem_gps_t &gps) { ESP_LOGV(TAG, "%s", __func__ ); - std::string_view out; - auto ret = esp_modem::dce_commands::generic_get_string(t, "AT+CGNSINF\r", out); + std::string str_out; + auto ret = esp_modem::dce_commands::generic_get_string(t, "AT+CGNSINF\r", str_out); if (ret != esp_modem::command_result::OK) { return ret; } - + std::string_view out(str_out); constexpr std::string_view pattern = "+CGNSINF: "; @@ -329,12 +330,12 @@ esp_modem::command_result get_gnss_information_sim70xx_lib(esp_modem::Commandabl return esp_modem::command_result::OK; } -esp_modem::command_result SIM7070_gnss::get_gnss_information_sim70xx(gps_t &gps) +esp_modem::command_result SIM7070_gnss::get_gnss_information_sim70xx(esp_modem_gps_t &gps) { return get_gnss_information_sim70xx_lib(dte.get(), gps); } -esp_modem::command_result DCE_gnss::get_gnss_information_sim70xx(gps_t &gps) +esp_modem::command_result DCE_gnss::get_gnss_information_sim70xx(esp_modem_gps_t &gps) { return device->get_gnss_information_sim70xx(gps); } diff --git a/components/esp_modem/examples/simple_cmux_client/components/SIM7070_gnss/SIM7070_gnss.hpp b/components/esp_modem/examples/simple_cmux_client/components/SIM7070_gnss/SIM7070_gnss.hpp index 10650867e..8ca99dc0d 100644 --- a/components/esp_modem/examples/simple_cmux_client/components/SIM7070_gnss/SIM7070_gnss.hpp +++ b/components/esp_modem/examples/simple_cmux_client/components/SIM7070_gnss/SIM7070_gnss.hpp @@ -16,15 +16,19 @@ #include "nmea_parser.h" /** - * @brief Definition of a custom modem which inherits from the GenericModule, uses all its methods - * and could override any of them. Here, for demonstration purposes only, we redefine just `get_module_name()` + * @brief Definition of a custom SIM7070 class with GNSS capabilities. + * This inherits from the official esp-modem's SIM7070 device which contains all common library methods. + * On top of that, the SIM7070_gnss adds reading GNSS information, which is implemented in a private component. */ class SIM7070_gnss: public esp_modem::SIM7070 { using SIM7070::SIM7070; public: - esp_modem::command_result get_gnss_information_sim70xx(gps_t &gps); + esp_modem::command_result get_gnss_information_sim70xx(esp_modem_gps_t &gps); }; +/** + * @brief DCE for the SIM7070_gnss. Here we've got to forward the general commands, aa well as the GNSS one. + */ class DCE_gnss : public esp_modem::DCE_T { public: @@ -43,14 +47,14 @@ public: #undef ESP_MODEM_DECLARE_DCE_COMMAND - esp_modem::command_result get_gnss_information_sim70xx(gps_t &gps); + esp_modem::command_result get_gnss_information_sim70xx(esp_modem_gps_t &gps); }; /** - * @brief Helper create method which employs the DCE factory for creating DCE objects templated by a custom module - * @return unique pointer of the resultant DCE + * @brief Helper create method which employs the customized DCE factory for building DCE_gnss objects + * @return unique pointer of the specific DCE */ std::unique_ptr create_SIM7070_GNSS_dce(const esp_modem::dce_config *config, std::shared_ptr dte, diff --git a/components/esp_modem/examples/simple_cmux_client/components/SIM7070_gnss/nmea_parser.h b/components/esp_modem/examples/simple_cmux_client/components/SIM7070_gnss/nmea_parser.h index 4f6fcebf9..a0c59a714 100644 --- a/components/esp_modem/examples/simple_cmux_client/components/SIM7070_gnss/nmea_parser.h +++ b/components/esp_modem/examples/simple_cmux_client/components/SIM7070_gnss/nmea_parser.h @@ -97,7 +97,7 @@ typedef enum { * @brief GPS object * */ -struct gps_s { +struct esp_modem_gps { float latitude; /*!< Latitude (degrees) */ float longitude; /*!< Longitude (degrees) */ float altitude; /*!< Altitude (meters) */ @@ -117,11 +117,7 @@ struct gps_s { float vpa; /*!< Vertical Position Accuracy */ }; -typedef struct gps_s gps_t; -typedef struct gps_s esp_modem_gps_s_t; - - - +typedef struct esp_modem_gps esp_modem_gps_t; /** * @brief NMEA Parser Event ID diff --git a/components/esp_modem/examples/simple_cmux_client/main/simple_cmux_client_main.cpp b/components/esp_modem/examples/simple_cmux_client/main/simple_cmux_client_main.cpp index dadbcc6cc..df9229547 100644 --- a/components/esp_modem/examples/simple_cmux_client/main/simple_cmux_client_main.cpp +++ b/components/esp_modem/examples/simple_cmux_client/main/simple_cmux_client_main.cpp @@ -195,7 +195,7 @@ extern "C" void app_main(void) #if CONFIG_EXAMPLE_MODEM_DEVICE_SIM7070_GNSS == 1 - gps_t gps; + esp_modem_gps_t gps; for (int i = 0; i < 200; ++i) { if (dce->get_gnss_information_sim70xx(gps) == esp_modem::command_result::OK) { diff --git a/components/esp_modem/include/cxx_include/command_library.hpp b/components/esp_modem/include/cxx_include/command_library.hpp deleted file mode 100644 index c2c00ee69..000000000 --- a/components/esp_modem/include/cxx_include/command_library.hpp +++ /dev/null @@ -1,27 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#pragma once -namespace esp_modem::dce_commands { -command_result generic_command(CommandableIf *t, const std::string &command, - const std::list &pass_phrase, - const std::list &fail_phrase, - uint32_t timeout_ms); - - -command_result generic_command(CommandableIf *t, const std::string &command, - const std::string &pass_phrase, - const std::string &fail_phrase, uint32_t timeout_ms); - -command_result generic_get_string(CommandableIf *t, const std::string &command, std::string_view &output, uint32_t timeout_ms = 500); - -command_result generic_get_string(CommandableIf *t, const std::string &command, std::string &output, uint32_t timeout_ms = 500); - -command_result generic_command_common(CommandableIf *t, const std::string &command, uint32_t timeout = 500); - - - -} // esp_modem::dce_commands diff --git a/components/esp_modem/include/cxx_include/esp_modem_command_library_utils.hpp b/components/esp_modem/include/cxx_include/esp_modem_command_library_utils.hpp new file mode 100644 index 000000000..b47c150d8 --- /dev/null +++ b/components/esp_modem/include/cxx_include/esp_modem_command_library_utils.hpp @@ -0,0 +1,45 @@ +/* + * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +namespace esp_modem::dce_commands { + +/** + * @brief Generic command that passes on supplied pass_phrase, and fails on fail_phrase + * @param t Any "Command-able" class that implements "command()" method + * @param command Command to issue + * @param pass_phrase Pattern to find in replies to complete the command successfully + * @param fail_phrase If this pattern found the command fails immediately + * @param timeout_ms Command timeout in ms + * @return Generic command return type (OK, FAIL, TIMEOUT) + */ +command_result generic_command(CommandableIf *t, const std::string &command, + const std::string &pass_phrase, + const std::string &fail_phrase, uint32_t timeout_ms); + +/** + * @brief Utility command to send command and return reply (after DCE says OK) + * @param t Anything that is "command-able" + * @param command Command to issue + * @param output String to return + * @param timeout_ms + * @param timeout_ms Command timeout in ms + * @return Generic command return type (OK, FAIL, TIMEOUT) + */ +command_result generic_get_string(CommandableIf *t, const std::string &command, std::string &output, uint32_t timeout_ms = 500); + +/** + * @brief Generic command that passes on "OK" and fails on "ERROR" + * @param t Anything that is "command-able" + * @param command Command to issue + * @param timeout + * @param timeout_ms Command timeout in ms + * @return Generic command return type (OK, FAIL, TIMEOUT) + */ +command_result generic_command_common(CommandableIf *t, const std::string &command, uint32_t timeout_ms = 500); + +} // esp_modem::dce_commands diff --git a/components/esp_modem/src/esp_modem_command_library.cpp b/components/esp_modem/src/esp_modem_command_library.cpp index 5b320a054..2a638e982 100644 --- a/components/esp_modem/src/esp_modem_command_library.cpp +++ b/components/esp_modem/src/esp_modem_command_library.cpp @@ -10,17 +10,16 @@ #include "cxx_include/esp_modem_dte.hpp" #include "cxx_include/esp_modem_dce_module.hpp" #include "cxx_include/esp_modem_command_library.hpp" -#include "cxx_include/command_library.hpp" - +#include "cxx_include/esp_modem_command_library_utils.hpp" namespace esp_modem::dce_commands { static const char *TAG = "command_lib"; -command_result generic_command(CommandableIf *t, const std::string &command, - const std::list &pass_phrase, - const std::list &fail_phrase, - uint32_t timeout_ms) +static command_result generic_command(CommandableIf *t, const std::string &command, + const std::list &pass_phrase, + const std::list &fail_phrase, + uint32_t timeout_ms) { ESP_LOGD(TAG, "%s command %s\n", __func__, command.c_str()); return t->command(command, [&](uint8_t *data, size_t len) { @@ -52,7 +51,7 @@ command_result generic_command(CommandableIf *t, const std::string &command, return generic_command(t, command, pass, fail, timeout_ms); } -command_result generic_get_string(CommandableIf *t, const std::string &command, std::string_view &output, uint32_t timeout_ms) +static command_result generic_get_string(CommandableIf *t, const std::string &command, std::string_view &output, uint32_t timeout_ms = 500) { ESP_LOGV(TAG, "%s", __func__ ); return t->command(command, [&](uint8_t *data, size_t len) { @@ -91,10 +90,10 @@ command_result generic_get_string(CommandableIf *t, const std::string &command, } -command_result generic_command_common(CommandableIf *t, const std::string &command, uint32_t timeout) +command_result generic_command_common(CommandableIf *t, const std::string &command, uint32_t timeout_ms) { ESP_LOGV(TAG, "%s", __func__ ); - return generic_command(t, command, "OK", "ERROR", timeout); + return generic_command(t, command, "OK", "ERROR", timeout_ms); } command_result sync(CommandableIf *t) From f1ae14f263927016a1453099d599c05c3518106d Mon Sep 17 00:00:00 2001 From: David Cermak Date: Thu, 20 Oct 2022 15:56:20 +0200 Subject: [PATCH 5/5] update(esp_modem): Bump component version --- components/esp_modem/idf_component.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp_modem/idf_component.yml b/components/esp_modem/idf_component.yml index ae17e474f..ef5bbe906 100644 --- a/components/esp_modem/idf_component.yml +++ b/components/esp_modem/idf_component.yml @@ -1,4 +1,4 @@ -version: "0.1.24" +version: "0.1.25" description: esp modem url: https://github.com/espressif/esp-protocols/tree/master/components/esp_modem dependencies: