From 2240c57dffe55a8a748fd36689468dc2c47767df Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 21 Feb 2025 15:26:53 +0530 Subject: [PATCH] First Commit --- .clang-format | 9 + .clangd | 3 + .cproject | 18 + .gdbinit | 5 + .gitignore | 53 +- .project | 20 + .settings/org.eclipse.cdt.core.prefs | 6 + .settings/org.eclipse.core.resources.prefs | 2 + CMakeLists.txt | 9 + LICENSE | 5 + README.md | 11 +- main/.cproject | 16 + main/.project | 20 + main/CMakeLists.txt | 16 + main/Kconfig.projbuild | 14 + main/adc_ifx.c | 187 ++ main/adc_ifx.h | 18 + main/comms.c | 2125 +++++++++++++ main/comms.h | 283 ++ main/data_processing.c | 2603 ++++++++++++++++ main/data_processing.h | 298 ++ main/hmi.c | 656 +++++ main/hmi.h | 35 + main/i2c_sensors.c | 1729 +++++++++++ main/i2c_sensors.h | 281 ++ main/main.c | 48 + main/main.h | 33 + main/modem.c | 3109 ++++++++++++++++++++ main/modem.h | 181 ++ main/nvm.c | 1117 +++++++ main/nvm.h | 74 + main/ota.c | 424 +++ main/ota.h | 32 + main/port.c | 254 ++ main/port.h | 52 + main/rtc.c | 224 ++ main/rtc.h | 78 + main/uart_ifx.c | 270 ++ main/uart_ifx.h | 26 + main/ulp/sensors_registers.h | 321 ++ main/ulp/ulp_main.c | 730 +++++ main/wifi_Client.c | 643 ++++ main/wifi_Client.h | 50 + main/wifi_Init.c | 671 +++++ main/wifi_Init.h | 64 + main/wifi_OTA.c | 283 ++ main/wifi_OTA.h | 22 + main/wifi_webServer.c | 1645 +++++++++++ main/wifi_webServer.h | 30 + partitions.csv | 7 + release.bat | 14 + sdkconfig | 2022 +++++++++++++ sdkconfig.old | 2022 +++++++++++++ 53 files changed, 22862 insertions(+), 6 deletions(-) create mode 100644 .clang-format create mode 100644 .clangd create mode 100644 .cproject create mode 100644 .gdbinit create mode 100644 .project create mode 100644 .settings/org.eclipse.cdt.core.prefs create mode 100644 .settings/org.eclipse.core.resources.prefs create mode 100644 CMakeLists.txt create mode 100644 LICENSE create mode 100644 main/.cproject create mode 100644 main/.project create mode 100644 main/CMakeLists.txt create mode 100644 main/Kconfig.projbuild create mode 100644 main/adc_ifx.c create mode 100644 main/adc_ifx.h create mode 100644 main/comms.c create mode 100644 main/comms.h create mode 100644 main/data_processing.c create mode 100644 main/data_processing.h create mode 100644 main/hmi.c create mode 100644 main/hmi.h create mode 100644 main/i2c_sensors.c create mode 100644 main/i2c_sensors.h create mode 100644 main/main.c create mode 100644 main/main.h create mode 100644 main/modem.c create mode 100644 main/modem.h create mode 100644 main/nvm.c create mode 100644 main/nvm.h create mode 100644 main/ota.c create mode 100644 main/ota.h create mode 100644 main/port.c create mode 100644 main/port.h create mode 100644 main/rtc.c create mode 100644 main/rtc.h create mode 100644 main/uart_ifx.c create mode 100644 main/uart_ifx.h create mode 100644 main/ulp/sensors_registers.h create mode 100644 main/ulp/ulp_main.c create mode 100644 main/wifi_Client.c create mode 100644 main/wifi_Client.h create mode 100644 main/wifi_Init.c create mode 100644 main/wifi_Init.h create mode 100644 main/wifi_OTA.c create mode 100644 main/wifi_OTA.h create mode 100644 main/wifi_webServer.c create mode 100644 main/wifi_webServer.h create mode 100644 partitions.csv create mode 100644 release.bat create mode 100644 sdkconfig create mode 100644 sdkconfig.old diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..0c7b3aa --- /dev/null +++ b/.clang-format @@ -0,0 +1,9 @@ +# We'll use defaults from the LLVM style, but with some modifications so that it's close to the CDT K&R style. +BasedOnStyle: LLVM +UseTab: Always +IndentWidth: 4 +TabWidth: 4 +PackConstructorInitializers: NextLineOnly +BreakConstructorInitializers: AfterColon +IndentAccessModifiers: false +AccessModifierOffset: -4 diff --git a/.clangd b/.clangd new file mode 100644 index 0000000..22e5ea0 --- /dev/null +++ b/.clangd @@ -0,0 +1,3 @@ +CompileFlags: + CompilationDatabase: build + Remove: [-m*, -f*] diff --git a/.cproject b/.cproject new file mode 100644 index 0000000..bd5834b --- /dev/null +++ b/.cproject @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.gdbinit b/.gdbinit new file mode 100644 index 0000000..c8cc1a2 --- /dev/null +++ b/.gdbinit @@ -0,0 +1,5 @@ +target remote :3333 +mon reset halt +flushregs +thb app_main +c \ No newline at end of file diff --git a/.gitignore b/.gitignore index ead248a..f034a07 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,51 @@ -# ---> esp-idf -# gitignore template for esp-idf, the official development framework for ESP32 -# https://github.com/espressif/esp-idf +# These are some examples of commonly ignored file patterns. +# You should customize this list as applicable to your project. +# Learn more about .gitignore: +# https://www.atlassian.com/git/tutorials/saving-changes/gitignore +# Node artifact files +node_modules/ +dist/ build/ -sdkconfig -sdkconfig.old + +# Compiled Java class files +*.class + +# Compiled Python bytecode +*.py[cod] + +# Log files +*.log + +# Package files +*.jar + +# Maven +target/ +dist/ + +# JetBrains IDE +.idea/ + +# Unit test reports +TEST*.xml + +# Generated by MacOS +.DS_Store + +# Generated by Windows +Thumbs.db + +# Applications +*.app +*.exe +*.war + +# Large media files +*.mp4 +*.tiff +*.avi +*.flv +*.mov +*.wmv diff --git a/.project b/.project new file mode 100644 index 0000000..73a9216 --- /dev/null +++ b/.project @@ -0,0 +1,20 @@ + + + tempstick_cellular_esp32 + + + + + + org.eclipse.cdt.core.cBuilder + clean,full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.core.ccnature + com.espressif.idf.core.idfNature + + diff --git a/.settings/org.eclipse.cdt.core.prefs b/.settings/org.eclipse.cdt.core.prefs new file mode 100644 index 0000000..c8ec5df --- /dev/null +++ b/.settings/org.eclipse.cdt.core.prefs @@ -0,0 +1,6 @@ +doxygen/doxygen_new_line_after_brief=true +doxygen/doxygen_use_brief_tag=false +doxygen/doxygen_use_javadoc_tags=true +doxygen/doxygen_use_pre_tag=false +doxygen/doxygen_use_structural_commands=false +eclipse.preferences.version=1 diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..99f26c0 --- /dev/null +++ b/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..1e448a3 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,9 @@ +# The following lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.5) + +set(PROJECT_VER "2013") +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +get_filename_component(ProjectId ${CMAKE_CURRENT_LIST_DIR} NAME) +string(REPLACE " " "_" ProjectId ${ProjectId}) +project(${ProjectId}) diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..17fb21c --- /dev/null +++ b/LICENSE @@ -0,0 +1,5 @@ +Code in this repository is in the Public Domain (or CC0 licensed, at your option.) + +Unless required by applicable law or agreed to in writing, this +software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +CONDITIONS OF ANY KIND, either express or implied. diff --git a/README.md b/README.md index f5a64dc..27ddf0d 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,11 @@ -# Remote_Wifi_Switch +ESP-IDF template app +==================== +This is a template application to be used with [Espressif IoT Development Framework](https://github.com/espressif/esp-idf). + +Please check [ESP-IDF docs](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for getting started instructions. + +*Code in this repository is in the Public Domain (or CC0 licensed, at your option.) +Unless required by applicable law or agreed to in writing, this +software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +CONDITIONS OF ANY KIND, either express or implied.* diff --git a/main/.cproject b/main/.cproject new file mode 100644 index 0000000..078131e --- /dev/null +++ b/main/.cproject @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/main/.project b/main/.project new file mode 100644 index 0000000..7e65a99 --- /dev/null +++ b/main/.project @@ -0,0 +1,20 @@ + + + main + + + + + + org.eclipse.cdt.core.cBuilder + clean,full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.core.ccnature + org.eclipse.cdt.cmake.core.cmakeNature + + diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt new file mode 100644 index 0000000..92c3982 --- /dev/null +++ b/main/CMakeLists.txt @@ -0,0 +1,16 @@ +# See the build system documentation in IDF programming guide +# for more information about component CMakeLists.txt files. + +idf_component_register( + SRCS main.c uart_ifx.c port.c adc_ifx.c modem.c comms.c rtc.c i2c_sensors.c data_processing.c ota.c hmi.c wifi_Init.c wifi_Client.c wifi_OTA.c wifi_webServer.c nvm.c# list the source files of this component + INCLUDE_DIRS # optional, add here public include directories + PRIV_INCLUDE_DIRS # optional, add here private include directories + REQUIRES driver esp_adc nvs_flash app_update esp_timer esp_event esp-tls esp_http_client esp_https_server ulp soc esp_wifi lwip # optional, list the component requirements + PRIV_REQUIRES # optional, list the private requirements +) + +set(ulp_app_name ulp_${COMPONENT_NAME}) +set(ulp_riscv_sources "ulp/ulp_main.c") +set(ulp_exp_dep_srcs "main.c") + +ulp_embed_binary(${ulp_app_name} "${ulp_riscv_sources}" "${ulp_exp_dep_srcs}") \ No newline at end of file diff --git a/main/Kconfig.projbuild b/main/Kconfig.projbuild new file mode 100644 index 0000000..7e23439 --- /dev/null +++ b/main/Kconfig.projbuild @@ -0,0 +1,14 @@ +# put here your custom config value +menu "Example Configuration" +config ESP_WIFI_SSID + string "WiFi SSID" + default "myssid" + help + SSID (network name) for the example to connect to. + +config ESP_WIFI_PASSWORD + string "WiFi Password" + default "mypassword" + help + WiFi password (WPA or WPA2) for the example to use. +endmenu diff --git a/main/adc_ifx.c b/main/adc_ifx.c new file mode 100644 index 0000000..40f41aa --- /dev/null +++ b/main/adc_ifx.c @@ -0,0 +1,187 @@ +/* + * adc_ifc.c + * + * Created on: Jan 17, 2023 + * Author: Partha + */ +#include +#include +#include +#include +#include "esp_log.h" +//#include "driver/adc.h" +#include "esp_adc/adc_oneshot.h" +#include "esp_adc/adc_cali.h" +#include "esp_adc/adc_cali_scheme.h" +//#include "esp_adc_cal.h" +#include "data_processing.h" +#include "hmi.h" +#include "ulp_main.h" + +static const char* TAG = "ADC_IF"; + +#define LOG_LOCAL_LEVEL ESP_LOG_INFO + +//static esp_adc_cal_characteristics_t adc1_chars; +RTC_DATA_ATTR uint32_t light_data3; +RTC_DATA_ATTR uint32_t prev_light_data3; + +adc_oneshot_unit_handle_t adc1_handle; +adc_cali_handle_t adc1_cali_handle = NULL; +static int adc_raw[2]; +static int voltage[2]; + +static bool adc_calibration_init(adc_unit_t unit, adc_atten_t atten, adc_cali_handle_t *out_handle) +{ + adc_cali_handle_t handle = NULL; + esp_err_t ret = ESP_FAIL; + bool calibrated = false; + +#if ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED + if (!calibrated) { + ESP_LOGI(TAG, "calibration scheme version is %s", "Curve Fitting"); + adc_cali_curve_fitting_config_t cali_config = { + .unit_id = unit, + .atten = atten, + .bitwidth = ADC_BITWIDTH_DEFAULT, + }; + ret = adc_cali_create_scheme_curve_fitting(&cali_config, &handle); + if (ret == ESP_OK) { + calibrated = true; + } + } +#endif + +#if ADC_CALI_SCHEME_LINE_FITTING_SUPPORTED + if (!calibrated) { + ESP_LOGI(TAG, "calibration scheme version is %s", "Line Fitting"); + adc_cali_line_fitting_config_t cali_config = { + .unit_id = unit, + .atten = atten, + .bitwidth = ADC_BITWIDTH_DEFAULT, + }; + ret = adc_cali_create_scheme_line_fitting(&cali_config, &handle); + if (ret == ESP_OK) { + calibrated = true; + } + } +#endif + + *out_handle = handle; + if (ret == ESP_OK) { + ESP_LOGI(TAG, "Calibration Success"); + } else if (ret == ESP_ERR_NOT_SUPPORTED || !calibrated) { + ESP_LOGW(TAG, "eFuse not burnt, skip software calibration"); + } else { + ESP_LOGE(TAG, "Invalid arg or no memory"); + } + + return calibrated; +} + +void adc_ifx_init(void) +{ + /*esp_adc_cal_value_t val_type = esp_adc_cal_characterize(ADC_UNIT_1, ADC_ATTEN_DB_11, ADC_WIDTH_BIT_DEFAULT, 0, &adc1_chars); + + //Check type of calibration value used to characterize ADC + if (val_type == ESP_ADC_CAL_VAL_EFUSE_VREF) + { + printf("ADC: eFuse Vref"); + } + else if (val_type == ESP_ADC_CAL_VAL_EFUSE_TP) + { + printf("ADC: Two Point"); + } + else + { + printf("ADC: Default"); + } + adc1_ulp_enable(); + ESP_ERROR_CHECK(adc1_config_width(ADC_WIDTH_BIT_DEFAULT));*/ + + //-------------ADC1 Init---------------// + adc_oneshot_unit_init_cfg_t init_config1 = { + .unit_id = ADC_UNIT_1, + .ulp_mode = ADC_ULP_MODE_DISABLE + }; + ESP_ERROR_CHECK(adc_oneshot_new_unit(&init_config1, &adc1_handle)); + + //-------------ADC1 Config---------------// + adc_oneshot_chan_cfg_t config = { + .bitwidth = ADC_BITWIDTH_13, + .atten = ADC_ATTEN_DB_11, + }; + ESP_ERROR_CHECK(adc_oneshot_config_channel(adc1_handle, ADC_CHANNEL_0, &config)); + //ESP_ERROR_CHECK(adc_oneshot_config_channel(adc1_handle, ADC_CHANNEL_1, &config)); + + //-------------ADC1 Calibration Init---------------// + if(false == adc_calibration_init(ADC_UNIT_1, ADC_ATTEN_DB_11, &adc1_cali_handle)) + { + ESP_LOGI(TAG, "ADC Calibration NOT Supported"); + } +} + +static void adc_cal_deinit(adc_cali_handle_t handle) +{ +#if ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED + ESP_LOGI(TAG, "deregister %s calibration scheme", "Curve Fitting"); + ESP_ERROR_CHECK(adc_cali_delete_scheme_curve_fitting(handle)); + +#elif ADC_CALI_SCHEME_LINE_FITTING_SUPPORTED + ESP_LOGI(TAG, "deregister %s calibration scheme", "Line Fitting"); + ESP_ERROR_CHECK(adc_cali_delete_scheme_line_fitting(handle)); +#endif +} + +void adx_ifx_deinit(void) +{ + //adc_cal_deinit(adc1_cali_handle); + adc_oneshot_del_unit(adc1_handle); +} + +uint32_t adc_if_get_batt_mV(void) +{ + //uint32_t val = 4*esp_adc_cal_raw_to_voltage(adc1_get_raw(ADC1_CHANNEL_0), &adc1_chars); + ESP_ERROR_CHECK(adc_oneshot_read(adc1_handle, ADC_CHANNEL_0, &adc_raw[0])); + ESP_ERROR_CHECK(adc_cali_raw_to_voltage(adc1_cali_handle, adc_raw[0], &voltage[0])); + return 4*voltage[0]; +} + +#if 0 +uint32_t adc_if_get_light_mV(void) +{ + uint32_t test_val = 0; + //uint32_t val = esp_adc_cal_raw_to_voltage(adc1_get_raw(ADC1_CHANNEL_1), &adc1_chars); + ESP_ERROR_CHECK(adc_oneshot_read(adc1_handle, ADC_CHANNEL_1, &adc_raw[1])); + ESP_ERROR_CHECK(adc_cali_raw_to_voltage(adc1_cali_handle, adc_raw[1], &voltage[1])); + + uint32_t val = voltage[1]; + + ESP_LOGI(TAG, "Light mV: %ld", val); + test_val = (val*255)/2504; + //if(data_get_light_sensor_gp() && data_get_light_sensor_gn()) + { + /*if the new light_sensor value is greater than GB_threshold or lower than GN_threshold*/ + //if((data_get_light_sensor_gn() > test_val) || (data_get_light_sensor_gp() < test_val)) + { + /* set the prev_light_data to the previous reading */ + //ESP_ERROR_CHECK(adc_cali_raw_to_voltage(adc1_cali_handle, ulp_raw_light_data, (int *)&prev_light_data)); + //prev_light_data = ulp_light_data; + //ulp_prev_light_data=ulp_light_data;//light_data; + //prev_light_data = (255*prev_light_data)/2504; + //ulp_light_data = (255*val)/2504; + //ESP_LOGI(TAG,"LIGHT_GN = %ld\nLIGHT_GP = %ld",data_get_light_sensor_gn(),data_get_light_sensor_gp()); + ESP_LOGI(TAG,"Updating Prev_light_data"); + prev_light_data3 = light_data3; + light_data3 = test_val; + //ulp_light_data = val; + } + } + return val; +} + +uint32_t adc_if_get_prev_light_mV(void) +{ + return prev_light_data3; +} +#endif diff --git a/main/adc_ifx.h b/main/adc_ifx.h new file mode 100644 index 0000000..80ff1d1 --- /dev/null +++ b/main/adc_ifx.h @@ -0,0 +1,18 @@ +/* + * adc_ifx.h + * + * Created on: Jan 17, 2023 + * Author: Partha + */ + +#ifndef MAIN_ADC_IFX_H_ +#define MAIN_ADC_IFX_H_ + +void adc_ifx_init(void); +void adx_ifx_deinit(void); +uint32_t adc_if_get_batt_mV(void); +uint32_t adc_if_get_light_mV(void); +uint32_t adc_if_get_prev_light_mV(void); + + +#endif /* MAIN_ADC_IFX_H_ */ diff --git a/main/comms.c b/main/comms.c new file mode 100644 index 0000000..578a2c5 --- /dev/null +++ b/main/comms.c @@ -0,0 +1,2125 @@ +/* + * comms.c + * + * Created on: Jan 16, 2023 + * Author: Sword + */ + + + +#include "rtc.h" +#include "nvm.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include +#include "esp_timer.h" +#include +#include +#include +#include "modem.h" +#include "wifi_Client.h" +#include "main.h" +#include "comms.h" +#include "port.h" +#include "data_processing.h" +#include "ota.h" +#include "hmi.h" + +#define LOG_LOCAL_LEVEL ESP_LOG_INFO +#include "esp_log.h" + +// Development support: force the operation of the following configuration functions +#ifdef SET_CFG_BITS +// set 1 to force the appropriate functions +#define FORCE_MCU_CONFIG_DOWNLOAD 1 +#define FORCE_MCU_PROG_DOWNLOAD 1 +#define FORCE_MODEM_PROG_DOWNLOAD 1 +#else +#define FORCE_MCU_CONFIG_DOWNLOAD 0 +#define FORCE_MCU_PROG_DOWNLOAD 0 +#define FORCE_MODEM_PROG_DOWNLOAD 0 +#endif + +/* Set 1 to use "unwired/[IMEI]", e.g. "unwired/862061049756488" +* Set 0 to use "unwiredct" +*/ +#define COMMS_PUBLISH_WITH_IMEI 0 +#define JWT_LEN 1024 + + + +//#define MCU_SP4_URL "https://parthasarathimishra.com/hae/tempstick/%s/mcu_config_download/" + + +/* Name of file to create in modem file system for the downloaded image. +* This is arbitrary, but we name the upper and lower version differently +* to avoid possible mixing up at the firmware level (the server can +* still mix them up if a lower app was put at the /higher URL) +*/ +#if ST_OTA_HIGHER_APPLICATION +/* A running "higher" app must download and install a "lower" app and vice versa. */ +#define MCU_FW_UPDATE_FILE "lrsm0005_fw_ota_image_lower.bin" +#else +#define MCU_FW_UPDATE_FILE "lrsm0005_fw_ota_image_higher.bin" +#endif + +//#define MCU_FW_BIN_FILE_URL1_HIGHER "https://parthasarathimishra.com/hae/azuma/%s/mcu_pgm_download/lrsm0005_fw_ota_image_higher.bin" +//#define MCU_FW_BIN_FILE_URL1_LOWER "https://parthasarathimishra.com/hae/azuma/%s/mcu_pgm_download/lrsm0005_fw_ota_image_lower.bin" +#define MCU_PROG_VER_URL SERVER_URL_BASE "mcu_pgm_download/version" +//#define MODEM_FW_BIN_FILE_URL1 SERVER_URL_BASE "modem_pgm_download" +#define MODEM_PROG_VER_URL SERVER_URL_BASE "modem_pgm_download/version" +#define WHITELIST_URL SERVER_URL_BASE "whitelist" +//#define MCU_FW_BIN_FILE_URL1 "https://parthasarathimishra.com/hae/azuma/%s/mcu_pgm_download/" MCU_FW_UPDATE_FILE +//#define MCU_FW_BIN_FILE_URL1 "https://www.parthasarathimishra.com/hae/tempstick/%s/mcu_pgm_download/OTA.bin" + + +//#define MODEM_FW_BIN_FILE_URL1 "https://www.parthasarathimishra.com/hae/tempstick/%s/modem_pgm_download/MOTA.bin"/*upgrade*/ +//#define MODEM_FW_BIN_FILE_URL1 "https://www.parthasarathimishra.com/hae/tempstick/%s/modem_pgm_download/Update_BG77LAR02A04_01.009.01.009-R02A04_01.006.01.006.bin"/*downgrade*/ + + + +#define MQTT_PUB_TOPIC_LEN 48 + +#define MCU_CONFIG_FLAG_WHITELIST_UPDATE 0x1 +#define MCU_CONFIG_FLAG_MCU_UPDATE 0x2 +#define MCU_CONFIG_FLAG_MODEM_UPDATE 0x4 + +#define HTTP_RETRY_COUNT_MAX 5 +#define HTTP_POST_RETRY_MAX 2 +#define HTTP_RETRY_WAIT 20000 + +static const char *TAG = "COMMS"; + +extern uint32_t g_ConfigUpdate; +extern uint32_t g_McuUpdate; +extern uint32_t g_ModemUpdate; +extern uint32_t g_version; + +typedef enum +{ + COMMS_EVENT_START, + COMMS_EVENT_TIMER, + COMMS_EVENT_STOP, + COMMS_EVENT_CONNECT, +} comms_event_t; + +/* State of the comms process */ +typedef enum +{ + COMMS_STATE_INIT, + COMMS_STATE_WAIT_MODEM, + COMMS_STATE_WAIT_NET_CONNECT, + COMMS_STATE_WIFI_CONNECT, + COMMS_STATE_WIFI_POST_REQ, + COMMS_STATE_WIFI_GET_REQ, + COMMS_STATE_WAIT_HTTP_SEND_CONFIG_FLAGS, + COMMS_STATE_WAIT_HTTP_GET_CONFIG_FLAGS, + COMMS_STATE_WAIT_HTTP_POST_REQ, + COMMS_STATE_WAIT_HTTP_POST_RES, + COMMS_STATE_WAIT_HTTP_SEND_SP5, + COMMS_STATE_WAIT_HTTP_GET_SP5, + COMMS_STATE_WAIT_HTTP_SEND_SP6, + COMMS_STATE_WAIT_HTTP_GET_SP6, + COMMS_STATE_WAIT_HTTP_GET_MODEM_UPDATE, /* Get modem update version */ + COMMS_STATE_WAIT_MODEM_UPDATE, /* Wait for modem to do its thing */ + COMMS_STATE_WAIT_HTTP_GET_MCU_UPDATE, /* Get version */ + COMMS_STATE_WAIT_HTTP_GET_MCU_FILE, /* Download file */ + COMMS_STATE_WAIT_MCU_UPDATE, /* Install update */ + COMMS_STATE_GOING_IDLE, + COMMS_STATE_IDLE, + COMMS_STATE_WAIT, + COMMS_STATE_WAIT_MODEM_OFF, + +} comms_state_t; + + +typedef int (*comms_switch_cb)(comms_state_t init_state, const char* url,const char* msg, comms_state_t success_state); + +typedef struct +{ + comms_state_t state; + + /* Timer */ + bool poll_timer; + + /* User start callback */ + comms_op_cb_t start_cb; + bool is_starting; + + /* User connect callback */ + comms_op_cb_t connect_cb; + + char mqtt_pub_topic[MQTT_PUB_TOPIC_LEN]; + /* Printing an SP2 message: + * Header: 3 + 1 + [IMEI-15] +1 + 10 + 1+ 10 + 1 = 42 + * [32],[4],[4],[3] = 46 * 20 = 920 + * Footer: 3 + * 42 + 920 + 3 = 965 + * Add buffer overflow protection in writing routines. + */ + char mqtt_buf[1024]; /* Also general buffer */ + //char jwt[JWT_LEN]; + uint8_t overflow_check; + int mqtt_pub_counter; + + /* flagged actions to take */ + bool get_whitelist; + bool get_mcu_update; + bool get_modem_update; + + /* Status of the last communication cycle + * OK or ERROR + */ + int last_cycle_status; + + /* Status of last pending operation */ + bool last_op_success; + bool wf1_msg; + + int httpRetryCnt; + comms_state_t http_init_state; +} comms_t; + +/* Unique timer ID for this process for use with timer module */ +//#define COMMS_TIMER_ID 1 +esp_timer_handle_t comms_timer; +/* Local process state */ + +static comms_t comms; + + +//nvs_handle_t my_handle; +extern uint8_t onBoarded; +extern uint8_t comms_mode; +comms_medium_t comms_medium; + +static bool comms_do_wifi_backup; +static bool comms_do_cell_backup; +static bool comms_posting_failed; + +uint8_t checkin_cycle_counter; +uint8_t number_of_check_in_to_do; + +char jsonMessage[2560]; +char http_post_header[250]; + +#if (FAKE_NETWORK == 1) +char server_resp[] = "{\"request\":\"settings\",\"id\":10608508,\"minTemp\":-1.11,\"maxTemp\":26.67,\"minHum\":10,\"maxHum\":80,\"voltageQuit\":2.3,\"alertInterval\":900,\"sendInterval\":60,\"sendDetails\":1,\"postURLNumber\":2,\"postURLMax\":3,\"tmpThA_GP\":71.11,\"tmpThA_GN\":70,\"tmpThB_GP\":71.11,\"tmpThB_GN\":70,\"tmpThC_GP\":71.11,\"tmpThC_GN\":70,\"tmpThD_GP\":-44.44,\"tmpThD_GN\":-45.56,\"tmpThE_GP\":-44.44,\"tmpThE_GN\":-45.56,\"tmpThF_GP\":-44.44,\"tmpThF_GN\":-45.56,\"T_TKN\":5,\"humThA_GP\":103,\"humThA_GN\":101,\"humThB_GP\":103,\"humThB_GN\":101,\"humThC_GP\":103,\"humThC_GN\":101,\"humThD_GP\":-1,\"humThD_GN\":-3,\"humThE_GP\":-1,\"humThE_GN\":-3,\"humThF_GP\":-1,\"humThF_GN\":-3,\"H_TKN\":5,\"TC_M\":1,\"TC_TYPE\":\"K\",\"tcThA_GP\":71.11,\"tcThA_GN\":70,\"tcThB_GP\":71.11,\"tcThB_GN\":70,\"tcThC_GP\":71.11,\"tcThC_GN\":70,\"tcThD_GP\":-168.33,\"tcThD_GN\":-169.44,\"tcThE_GP\":-168.33,\"tcThE_GN\":-169.44,\"tcThF_GP\":-168.33,\"tcThF_GN\":-169.44,\"TC_TKN\":5,\"LT_M\":3,\"LT_LVLGP\":200,\"LT_LVLGN\":50,\"LT_LOCK\":900,\"LT_TKN\":5,\"AC_M\":1,\"AC_LVL\":15000,\"AC_INT\":60,\"AC_LOCK\":60,\"AC_TKN\":5,\"PWR_M\":3,\"PWR_DBNC\":60,\"PWR_TKN\":5,\"PUSH_TKN\":5,\"TKN_RLD\":300}"; +#endif +/* ------------------------------------------------------------------------- */ + +static const char* state_str(comms_state_t s) +{ + switch (s) { + case COMMS_STATE_INIT:return "INIT"; + case COMMS_STATE_WAIT_MODEM:return "WAIT_MODEM"; + case COMMS_STATE_WAIT_NET_CONNECT:return "WAIT_NET_CONNECT"; + case COMMS_STATE_WIFI_CONNECT:return "WIFI_CONNECT"; + case COMMS_STATE_WIFI_POST_REQ:return "WIFI_POST_REQ"; + case COMMS_STATE_WIFI_GET_REQ:return "WIFI_GET_REQ"; + case COMMS_STATE_WAIT_HTTP_SEND_CONFIG_FLAGS:return "WAIT_HTTP_SEND_CONFIG_FLAGS"; + case COMMS_STATE_WAIT_HTTP_GET_CONFIG_FLAGS:return "WAIT_HTTP_GET_CONFIG_FLAGS"; + case COMMS_STATE_WAIT_HTTP_POST_REQ:return "WAIT_HTTP_POST_REQ"; + case COMMS_STATE_WAIT_HTTP_POST_RES:return "WAIT_HTTP_POST_RES"; + case COMMS_STATE_WAIT_HTTP_SEND_SP5:return "WAIT_HTTP_SEND_SP5"; + case COMMS_STATE_WAIT_HTTP_GET_SP5:return "HTTP_GET_SP5"; + case COMMS_STATE_WAIT_HTTP_SEND_SP6:return "HTTP_SEND_SP6"; + case COMMS_STATE_WAIT_HTTP_GET_SP6:return "HTTP_GET_SP6"; + case COMMS_STATE_WAIT_HTTP_GET_MODEM_UPDATE:return "WAIT_HTTP_GET_MODEM_UPDATE"; + case COMMS_STATE_WAIT_HTTP_GET_MCU_UPDATE:return "WAIT_HTTP_GET_MCU_UPDATE"; + case COMMS_STATE_WAIT_HTTP_GET_MCU_FILE:return "WAIT_HTTP_GET_MCU_FILE"; + case COMMS_STATE_WAIT_MODEM_UPDATE:return "WAIT_MODEM_UPDATE"; + case COMMS_STATE_WAIT_MCU_UPDATE:return "WAIT_MCU_UPDATE"; + case COMMS_STATE_GOING_IDLE: return "COMMS_STATE_GOING_IDLE"; + case COMMS_STATE_IDLE:return "IDLE"; + case COMMS_STATE_WAIT:return "STATE_WAIT"; + case COMMS_STATE_WAIT_MODEM_OFF:return "WAIT_MODEM_OFF"; + default: + return ""; + } +} + +static esp_err_t build_http_headerBodyMsg(uint32_t len) +{ + /* jsonMessage address is the same address as msg*/ + uint32_t header_len = 0; + int index = 0; + + /* Setup the HTTP header*/ + sprintf(http_post_header, HTTP_POST_HEADER,(unsigned int)len); + + /* Calculate http-header length*/ + header_len = strlen(http_post_header); + + /* Shift jsonMessage right by length of http-header*/ + if( (len+header_len)>= 2560) + { + ESP_LOGI(TAG,"Shifting exceeded the maximum size of jsonMessage buffer"); + return ESP_FAIL; + } + + /* Shift the message in jsonMessage buffer to right by length of http-header*/ + for(index = len-1; index >= 0; index--) + { + jsonMessage[index+header_len] = jsonMessage[index]; + + /* Copy http-header at the beginning of jsonMessage*/ + if(index < header_len) + jsonMessage[index] = http_post_header[index]; + } + return ESP_OK; +} + +static void transition(comms_state_t state_to) +{ + ESP_LOGD(TAG,"%s->%s\n", state_str(comms.state), state_str(state_to)); + comms.state = state_to; +} + + +/* These handlers handle completion events for commands issued by the BG96 modem driver. +* If success, the comms process continues by way of a "timer" event. +* If fail, the comms process stops what it was doing and goes back to "idle" state. +* The comms process is started once at startup and does not stop thereafter. +*/ +static void modem_start_cb(int status) +{ + comms.poll_timer = true; + if (MODEM_STATUS_OK == status) + { + /* started */ + transition(COMMS_STATE_WAIT_MODEM); + } + else + { + /* Nope - back to init */ + ESP_LOGW(TAG,"BG96 startup failed.\r\n"); + + if(comms_mode == COMMS_OVER_CELL) + { + hmi_stop_continued_led_state(BLUE_LED_FLASHING); //stop BLUE_LED_FLASHING event + + if(!onBoarded) //Unable to connect to LTE network + { + hmi_set_leds_state(RED_LED_FLASHING); + } //Unable to connect to LTE network + } + + /* Set the posting_failed to be true */ + comms_posting_failed = true; + + if(COMMS_OVER_CELL_WIFI_BACKUP == comms_mode) + { + comms_do_wifi_backup = true; + } + + transition(COMMS_STATE_GOING_IDLE); + } +} +//bool net_connected = false; +static void net_connect_cb(int status) +{ + //net_connected = true; + comms.poll_timer = true; + if (MODEM_STATUS_OK == status) + { + /* connected */ + ESP_LOGI(TAG,"Network connection Successful.\r\n"); + } + else + { + /* Nope - back to init */ + ESP_LOGW(TAG,"Network connection failed.\r\n"); + + /* Set the posting_failed to be true */ + comms_posting_failed = true; + + if(COMMS_OVER_CELL_WIFI_BACKUP == comms_mode) + { + comms_do_wifi_backup = true; + } + + if(comms_mode == COMMS_OVER_CELL) + { + hmi_stop_continued_led_state(BLUE_LED_FLASHING); //stop BLUE_LED_FLASHING event + + if(!onBoarded) //Unable to connect to LTE network + { + hmi_set_leds_state(RED_LED_FLASHING); + } //Unable to connect to LTE network + } + transition(COMMS_STATE_GOING_IDLE); + } +} + +static void http_op_cb(int status) +{ + if (MODEM_STATUS_OK == status) + { + /*Connected. Set the poll_timer to be true*/ + comms.poll_timer = true; + } + else + { + /*If not connected then check the number of http retries if it's greater than zero*/ + if(comms.httpRetryCnt) + { + /*decrement the number of retries by 1*/ + comms.httpRetryCnt--; + + /*start a timer for 20sec*/ + esp_timer_start_once(comms_timer, 1000*HTTP_RETRY_WAIT); + + /*Logging waiting message*/ + ESP_LOGI(TAG,"Waiting for another HTTP Retry.\r\n"); + + /*transition to COMMS_STATE_WAIT state*/ + transition(COMMS_STATE_WAIT); + } + else + { + /*Reinitialize the counter of http retries with 3*/ + comms.httpRetryCnt = HTTP_RETRY_COUNT_MAX; + + /*Set the poll_timer to be true*/ + comms.poll_timer = true; + + /* Nope - back to idle */ + ESP_LOGW(TAG,"HTTP operation failed.\r\n"); + + //SP1_Mqtt_Tx(heartbeat_time); //creating sp1 message + //int retval = start_mqtt_publish_sequence(); /* Run the MQTT publish sequence if nothing else pending */ + int retval = MODEM_STATUS_ERROR; + if(MODEM_STATUS_OK==retval) + { + ESP_LOGI(TAG,"MQTT Publish SP1 message success"); + } + else + { + ESP_LOGI(TAG,"MQTT Publish SP1 message failed"); + } + + /*transition to COMMS_STATE_GOING_IDLE state*/ + transition(COMMS_STATE_GOING_IDLE); + } + } +} + + + +static void http_post_op_cb(int status) +{ + if (MODEM_STATUS_OK == status) + { + comms.poll_timer = true; + + /* Update the number of already done check-ins */ + checkin_cycle_counter++; + + /* Clear history array (So that its current readings don't affect the readings of the next sector) + * Just clear the array (don't clear anything from NVS) */ + data_clear_history(); + + /* Check if this was the last check-in to do (in other words, check if there are no more previous readings to send to server) */ + if(checkin_cycle_counter == number_of_check_in_to_do) + { + /* Reset the last post sector in the NVS partition to 0*/ + nvm_set_last_posted_history_sector(0); + + /* successfully posted. */ + ESP_LOGI(TAG,"HTTP post message SUCCESS.\r\n"); + + /* Clear History sectors + * Clear from NVS Partition */ + nvm_clear_history_sector(NVM_HISTORY_ALL_SECTORS); + + /* Reset the posting_failed to be false */ + comms_posting_failed = false; + comms_do_wifi_backup = false; + + /*Set the last operation to be completed successfully*/ + comms.last_op_success = true; + + comms.httpRetryCnt = HTTP_RETRY_COUNT_MAX; + } + else + { + /* Coming here means that there were some previous readings that are stored in NVS and need to posted in multiple check-in cycles + * and we already posted the readings in history_sector x ----> so we need to update the last_posted_sector flag */ + + /* Update the last post sector in the NVS partition */ + uint8_t x = nvm_get_last_posted_history_sector()+1; + nvm_set_last_posted_history_sector(x); + + /* Wait some time before doing the next check-in of the remaining previous readings */ + vTaskDelay(2000/portTICK_PERIOD_MS); + + /* Do a transition to "COMMS_STATE_WAIT_HTTP_POST_REQ" state */ + transition(COMMS_STATE_WAIT_HTTP_POST_REQ); + } + } + else + { + if(comms.httpRetryCnt) + { + /*decrement the number of retries by 1*/ + comms.httpRetryCnt--; + + /*start a timer for 20sec*/ + esp_timer_start_once(comms_timer, 1000*HTTP_RETRY_WAIT); + + /*Logging waiting message*/ + ESP_LOGI(TAG,"Waiting for another HTTP Retry.\r\n"); + + /*Set the poll_timer to be true*/ + comms.poll_timer = true; + + /*transition to COMMS_STATE_WAIT state*/ + transition(COMMS_STATE_WAIT); + } + else + { + /*Reinitialize the counter of http_post retries with 3*/ + comms.httpRetryCnt = HTTP_POST_RETRY_MAX; + + /*Set the poll_timer to be true*/ + comms.poll_timer = true; + + /* Nope - back to idle */ + /* failed. */ + ESP_LOGW(TAG,"HTTP post message FAILED.\r\n"); + comms.last_op_success = false; + + /* Give Red-led indication*/ + if(comms_mode == COMMS_OVER_CELL) + { + hmi_stop_continued_led_state(BLUE_LED_FLASHING); //stop BLUE_LED_FLASHING event + + if(!onBoarded) //Unable to connect to LTE network + { + hmi_set_leds_state(RED_LED_FLASHING); + } //Unable to connect to LTE network + } + + /* alternating between three servers + * + * transition to COMMS_STATE_GOING_IDLE state if the connection to the servers failed*/ + + switch(data_get_postToServer()){ + + case TEMPSTICK_SERVER1: + if( 1 == data_get_postUrlMax()) + { + ESP_LOGI(TAG,"Just one server available"); + + /* Set the posting_failed to be true */ + comms_posting_failed = true; + + /* Do wifi backup for the check-in process */ + if(COMMS_OVER_CELL_WIFI_BACKUP == comms_mode) + { + comms_do_wifi_backup = true; + } + + transition(COMMS_STATE_GOING_IDLE); + } + else + { + data_set_postToServer(TEMPSTICK_SERVER2); + ESP_LOGI(TAG,"Transition to the next server --> %d",TEMPSTICK_SERVER2); + transition(COMMS_STATE_WAIT_HTTP_POST_REQ); + } + break; + case TEMPSTICK_SERVER2: + if( 2 == data_get_postUrlMax()) + { + ESP_LOGI(TAG,"Just two servers available"); + + /* Set the posting_failed to be true */ + comms_posting_failed = true; + + /* Do wifi backup for the check-in process */ + if(COMMS_OVER_CELL_WIFI_BACKUP == comms_mode) + { + comms_do_wifi_backup = true; + } + + transition(COMMS_STATE_GOING_IDLE); + } + else + { + data_set_postToServer(TEMPSTICK_SERVER3); + ESP_LOGI(TAG,"Transition to the next server --> %d",TEMPSTICK_SERVER3); + transition(COMMS_STATE_WAIT_HTTP_POST_REQ); + } + break; + case TEMPSTICK_SERVER3: + data_set_postToServer(TEMPSTICK_SERVER1); + ESP_LOGI(TAG,"Transition to default server --> %d then going to IDLE",TEMPSTICK_SERVER1); + + /* Set the posting_failed to be true */ + comms_posting_failed = true; + + /* Do wifi backup for the check-in process */ + if(COMMS_OVER_CELL_WIFI_BACKUP == comms_mode) + { + comms_do_wifi_backup = true; + } + + transition(COMMS_STATE_GOING_IDLE); + break; + default: + + data_set_postToServer(TEMPSTICK_SERVER1); + ESP_LOGI(TAG,"connection to servers Failed"); + ESP_LOGI(TAG,"Transition to default server --> %d then going to IDLE",TEMPSTICK_SERVER1); + + /* Set the posting_failed to be true */ + comms_posting_failed = true; + + /* Do wifi backup for the check-in process */ + if(COMMS_OVER_CELL_WIFI_BACKUP == comms_mode) + { + comms_do_wifi_backup = true; + } + + transition(COMMS_STATE_GOING_IDLE); + break; + + + + } + } + } +} + +static void fotadl_op_cb(int status) +{ + comms.poll_timer = true; + if (MODEM_STATUS_OK == status) + { + /* completed. */ + ESP_LOGI(TAG,"Modem upgrade SUCCESS.\r\n"); + } + else + { + if(comms.httpRetryCnt) + { + /*decrement the number of retries by 1*/ + comms.httpRetryCnt--; + + /*start a timer for 20sec*/ + esp_timer_start_once(comms_timer, 1000*HTTP_RETRY_WAIT); + + /*Logging waiting message*/ + ESP_LOGI(TAG,"Waiting for another HTTP Retry.\r\n"); + + /*Set the poll_timer to be true*/ + comms.poll_timer = true; + + /*transition to COMMS_STATE_WAIT state*/ + transition(COMMS_STATE_WAIT); + } + else + { + /*Reinitialize the counter of http retries with 3*/ + comms.httpRetryCnt = HTTP_RETRY_COUNT_MAX; + + /*Set the poll_timer to be true*/ + comms.poll_timer = true; + + /* Nope - back to idle */ + /* failed. */ + /* failed. */ + /* failed. */ + ESP_LOGW(TAG,"Modem upgrade FAILED.\r\n"); + /* Give Red-led indication*/ + if(comms_mode == COMMS_OVER_CELL) + { + hmi_stop_continued_led_state(BLUE_LED_FLASHING); //stop BLUE_LED_FLASHING event + + if(!onBoarded) //Unable to connect to LTE network + { + hmi_set_leds_state(RED_LED_FLASHING); + } //Unable to connect to LTE network + } + transition(COMMS_STATE_GOING_IDLE); + } + /* Let state handle it */ +} +} + + +static int start_http_get_request(comms_state_t init_state,const char* url, const char* log_msg, comms_state_t success_state) +{ + /* Reset the operation status flag */ + comms.last_op_success = false; + /* Initialize the comms.http_init_state to init_state */ + comms.http_init_state = init_state; + /* Now make the GET request. */ + /* Setup URL */ + memset(comms.mqtt_buf, 0, sizeof(comms.mqtt_buf)); + snprintf(comms.mqtt_buf, sizeof(comms.mqtt_buf), url, modem_get_imei()); + + /* Download the GET data to modem */ + int retval = modem_http_get_to_buf(http_op_cb, comms.mqtt_buf); + + if (retval == MODEM_STATUS_OK) + { + ESP_LOGI(TAG,"GET %s\r\n", log_msg); + transition(success_state); + } + else + { + ESP_LOGE(TAG,"GET %s failed.\r\n", log_msg); + comms.poll_timer = true; + + /* Give Red-led indication*/ + if(comms_mode == COMMS_OVER_CELL) + { + hmi_stop_continued_led_state(BLUE_LED_FLASHING); //stop BLUE_LED_FLASHING event + + if(!onBoarded) //Unable to connect to LTE network + { + hmi_set_leds_state(RED_LED_FLASHING); + } //Unable to connect to LTE network + } + + transition(COMMS_STATE_GOING_IDLE); + } + return retval; +} + + +static int start_http_post_request(comms_state_t init_state,const char* url, const char* message, comms_state_t success_state) +{ + esp_err_t ret; + + /* Reset the operation status flag */ + comms.last_op_success = false; + /* Initialize the comms.http_init_state to init_state */ + comms.http_init_state = init_state; + + + /* Setup URL */ + memset(comms.mqtt_buf, 0, sizeof(comms.mqtt_buf)); + snprintf(comms.mqtt_buf, sizeof(comms.mqtt_buf), url, modem_get_imei()); + + //sprintf(http_post_header,HTTP_POST_HEADER,(uint32_t)strlen(message)); + /*concatenate http-header with http-body*/ + //strcat(http_post_header,message); + + /* Build the headerBody of the http-post message*/ + ret = build_http_headerBodyMsg((uint32_t)strlen(jsonMessage)); + //ret = ESP_OK; + + if(ESP_OK == ret) + { + /* Send HTTP POST data to modem to upload it to server*/ + int retval = modem_http_post_message(http_post_op_cb, comms.mqtt_buf, message); + + if (retval == MODEM_STATUS_OK) + { + ESP_LOGI(TAG,"HTTP-POST Started\r\n"); + transition(success_state); + } + else + { + ESP_LOGE(TAG,"HTTP-POST failed to proceed\r\n"); + } + return retval; + } + else + { + ESP_LOGI(TAG,"Failed to build header-body of http-post message"); + return MODEM_STATUS_ERROR; + } +} + + +static void fwdl_op_cb(int status) +{ + if (MODEM_STATUS_OK == status) + { + /* Firmware file was downloaded to the modem. */ + ESP_LOGI(TAG,"MCU FW download SUCCESS.\r\n"); + + comms.last_op_success = true; + /* Continue in the current state */ + comms.poll_timer = true; + } + else + { + if(comms.httpRetryCnt) + { + /*decrement the number of retries by 1*/ + comms.httpRetryCnt--; + + /*start a timer for 20sec*/ + esp_timer_start_once(comms_timer, 1000*HTTP_RETRY_WAIT); + + /*Logging waiting message*/ + ESP_LOGI(TAG,"Waiting for another HTTP Retry.\r\n"); + + /*transition to COMMS_STATE_WAIT state*/ + transition(COMMS_STATE_WAIT); + } + else + { + /*Reinitialize the counter of http retries with 3*/ + comms.httpRetryCnt = HTTP_RETRY_COUNT_MAX; + + /*Set the poll_timer to be true*/ + comms.poll_timer = true; + + /* Nope - back to idle */ + /* Firmware file not downloaded. */ + ESP_LOGW(TAG,"MCU FW download operation failed.\r\n"); + //SP1_Mqtt_Tx(heartbeat_time); //creating sp1 message + // int retval = start_mqtt_publish_sequence(); /* Run the MQTT publish sequence if nothing else pending */ + int retval = MODEM_STATUS_ERROR; + if(MODEM_STATUS_OK==retval) + { + ESP_LOGI(TAG,"MQTT Publish SP1 message success"); + } + else + { + ESP_LOGI(TAG,"MQTT Publish SP1 message failed"); + } + + comms.last_op_success = false; + + /*transition to COMMS_STATE_GOING_IDLE state*/ + transition(COMMS_STATE_GOING_IDLE); + } + } +} + +static void fwupd_op_cb(int status) +{ + comms.poll_timer = true; + if (MODEM_STATUS_OK == status) + { + /* Firmware file was installed into device. */ + ESP_LOGI(TAG,"MCU FW update SUCCESS.\r\n"); + + comms.last_op_success = true; + } + else + { + /* Firmware file not installed. */ + ESP_LOGW(TAG,"MCU FW installation failed.\r\n"); + transition(COMMS_STATE_GOING_IDLE); + comms.poll_timer = true; + comms.last_op_success = false; + } +} + +/* ------------------------------------------------------------------------- */ +/* OTA firmware update. + * These callbacks handle the file transfer from the modem and interface with + * the OTA_btl firmware update system. + * + * The main interface is the OTA_Offline_Init and OTA_Offline_Data functions. + * These are added to interface with the stock OTA_btl update engine. + * + * To initialize, we use OTA_Offline_Init(file_size) API. + * This will either accept or reject the firmware image based on + * available space. + * + * To feed update data, call OTA_Offline_Data with a chunk of data. + * + * Be mindful of the return values and feed them back to the updater engine. + * + */ + +static int ota_file_open_cb(uint32_t fileSize) +{ + int retval = MODEM_STATUS_OK; + + esp_err_t res = ota_init(fileSize); + if (ESP_OK == res) { + ESP_LOGI(TAG,"OTA file opened\r\n"); + } + else { + ESP_LOGI(TAG,"OTA file open error: %d\r\n", res); + /* This will abort the entire update process. */ + retval = MODEM_STATUS_ERROR; + } + + return retval; +} + +static int ota_file_data_cb(const char* buf, int buf_len) +{ + int retval = MODEM_STATUS_OK; + + /* Data callback: we can receive a buffer up to MODEM_FREAD_SIZE bytes */ + esp_err_t res = ota_get_data_to_buffer(buf, buf_len); + + if (ESP_OK == res) { + ESP_LOGI(TAG,"%d bytes OTA data processed\r\n", buf_len); + } + else { + ESP_LOGI(TAG,"%d bytes OTA data error: %d\r\n", buf_len, res); + /* This will abort the entire update process. */ + retval = MODEM_STATUS_ERROR; + } + + return retval; +} + +static int sum_digits(int digit) +{ + int sum = 0; + while (digit > 0) + { + sum = sum + digit % 10; + digit = digit / 10; + } + return sum; +} +/** +This function is used to check if IMEI has correct length (15) +to check if IMEI has numerical values (0-9) +to check if the parsed IMEI is same as hardware IMEI +to check if IMEI is valid by help of luhn algorithm +https://www.geeksforgeeks.org/luhn-algorithm/ +*/ +static bool imei_check_valid(char *message_imei) +{ + //find the length of message imei + int len = strlen(message_imei); + int sum = 0; + ESP_LOGI(TAG,"IMEI : %s",message_imei); + + //check length of imei field + if (len != 15){ + //invalid IMEI + ESP_LOGW(TAG,"Invalid IMEI length"); + return false; + } + if(!strcmp(message_imei,modem_get_imei())){ + + for(int i = len-1 ; i >= 0; i--) + { + //check if message imei fields contain numbers (0-9) + if((message_imei[i] > 47) && (message_imei[i] < 58)){ + int digit = (message_imei[i] - 48); + // Doubling every alternate beginning at [13] digit + //ignore last number [14] and first number [0] as well + if (i % 2 != 0) + digit = 2 * digit; + // Finding sum of the digits + // if digit*2 is a two digit number add the two digits + sum += sum_digits(digit); + + } + else{ + ESP_LOGW(TAG,"Invalid IMEI (not numerical values)"); + return false; + } + } + } + else{ + ESP_LOGI(TAG,"Message IMEI doesn't match board IMEI"); + return false; + } + + return (sum % 10 == 0); +} + +void check_for_update(){ + + if(g_ConfigUpdate==true){ + + // get the data from server + //transition(); + comms.poll_timer=true; /* just for a test*/ + transition(COMMS_STATE_GOING_IDLE); /* just for a test*/ + } + else if(g_McuUpdate==true){ + + // that mean we should check for program update + //transition(); + comms.poll_timer=true; /* just for a test*/ + transition(COMMS_STATE_WAIT_HTTP_SEND_SP5); /* just for a test*/ + } + else if(g_ModemUpdate==true){ + // that mean we need to update the modem software. + comms.poll_timer=true; + transition(COMMS_STATE_WAIT_HTTP_SEND_SP6); + } + else + { + comms.poll_timer=true; + transition(COMMS_STATE_GOING_IDLE); + + } +} + +/* function for parsing SP5 message */ +// format example +/*SP5 IMEI epoch T FW_V EP */ +/* | | | | | */ +/* | | | | | */ +/*SP5 866349048889004 1676395843 FW_2002 EP */ +static void Comms_Parse_SP5(char *buf, int len) +{ + char messageheader[4] = {0}; /*ex: SPx*/ + char messageIMEI[15] = {0}; + // char messageIMEI[] = "866349048890473";/*//hard coded IMEI*/ + char epochTime[30] = {0}; + char firmware_version[10] = {0}; + char *strret = NULL; + uint32_t new_fw_version = 0; + char epcheck[2] = {0}; + int ret_sp5 = COMMS_STATUS_ERROR; + + /**********************************************************************************************************/ + /*SP5*/ + strret = strtok(buf, " "); + strcpy(messageheader, strret); + ESP_LOGI(TAG,"%s message is received",messageheader); + + /**********************************************************************************************************/ + /*IMEI*/ + strret = strtok (NULL," "); + strcpy(messageIMEI, strret); + ret_sp5 = imei_check_valid(messageIMEI); + if(ret_sp5 != false){ + //ok IMEI + ESP_LOGI(TAG,"Fetched IMEI matches board"); + } + else{ + ESP_LOGW(TAG,"INVALID IMEI"); + comms.poll_timer = true; + transition(COMMS_STATE_GOING_IDLE); + return; + //return ret_sp5; + } + + /**********************************************************************************************************/ + /*epoch time*/ + strret = strtok (NULL," "); + strcpy(epochTime, strret); + ESP_LOGI(TAG,"epoch Time : %s",epochTime); + + /**********************************************************************************************************/ + /*new FW version*/ + strret = strtok(NULL, "FW_"); + strcpy(firmware_version,strret); + new_fw_version = (uint32_t)atoi(firmware_version); + ESP_LOGI(TAG,"Firmware version from SP5: %ld",new_fw_version); //logging/printing FR_version message for tracing + ESP_LOGI(TAG,"Board Firmware version: %ld",g_version); + + /**********************************************************************************************************/ + /*EP*/ + /* strret = strtok (NULL," "); + strcpy(epcheck, strret); + if(!strcmp(epcheck,"EP\"") || !strcmp(epcheck,"EP")){ + ESP_LOGI(TAG,"(%s) %s message is terminated", epcheck,messageheader); + } + else{ + ESP_LOGI(TAG,"(%s) %s message is not terminated!!", epcheck,messageheader); + }*/ + + /**********************************************************************************************************/ + /*check if the new version is greater than current version*/ + if(!(new_fw_version > g_version)) + { + ESP_LOGI(TAG,"MCU F/W UP TO DATE"); + /*if its not check if modem update needed*/ + /*read ModemFlag*/ + if(g_ModemUpdate == true) + { + ESP_LOGI(TAG,"Going to state COMMS_STATE_WAIT_HTTP_SEND_SP6"); + comms.poll_timer = true; + transition(COMMS_STATE_WAIT_HTTP_SEND_SP6); + } + else { + /* */ + comms.poll_timer = true; + transition(COMMS_STATE_GOING_IDLE); + } + } + else + { + /*Logging/printing this message*/ + ESP_LOGI(TAG,"F/W Update NEEDED"); + ESP_LOGI(TAG,"GET MCU UPDATE"); + comms.poll_timer = true; + transition(COMMS_STATE_WAIT_HTTP_GET_MCU_UPDATE); + /*reading OTA files*/ + } +} + + + +/* function for parsing SP6 message */ +// format example +/*SP6 IMEI epoch T FW_V EP */ +/* | | | | | */ +/* | | | | | */ +/*SP6 866349048889004 1676395909 BG77LAR02A04_01.009.01.009 EP */ +static void Comms_Parse_SP6(char *buf, int len) +{ + char messageheader[4] = {'0'}; /*ex: SPx*/ + char messageIMEI[15] = {'0'}; +// char messageIMEI[] = "866349048890473";/*//hard coded IMEI*/ + char epochTime[30] = {'0'}; + char modem_sp6_fwv[50] = {'0'}; + int ret_sp6 = COMMS_STATUS_ERROR; + char* strret = NULL; + char epcheck[2] = {0}; + + /**********************************************************************************************************/ + /*SP6*/ + strret = strtok(buf, " "); + strcpy(messageheader, strret); + ESP_LOGI(TAG,"%s message is received",messageheader); + + /**********************************************************************************************************/ + /*IMEI*/ + strret = strtok (NULL," "); + strcpy(messageIMEI, strret); + ret_sp6 = imei_check_valid(messageIMEI); + if(ret_sp6 != false){ + //ok IMEI + ESP_LOGI(TAG,"Fetched IMEI matches board"); + } + else{ + ESP_LOGW(TAG,"INVALID IMEI!!"); + comms.poll_timer = true; + transition(COMMS_STATE_GOING_IDLE); + return; + } + + /**********************************************************************************************************/ + /*epoch Time*/ + strret = strtok (NULL," "); + strcpy(epochTime, strret); + ESP_LOGI(TAG,"epoch Time : %s",epochTime); + + /**********************************************************************************************************/ + /*modem version from SP6 */ + strret = strtok (NULL," "); + strcpy(modem_sp6_fwv, strret); + ESP_LOGI(TAG,"Board modem firmware version: %s",modem_get_fw_ver()); + ESP_LOGI(TAG,"Modem firmware version from SP6: %s",modem_sp6_fwv); + + /**********************************************************************************************************/ + /*EP*/ + strret = strtok (NULL," "); + strcpy(epcheck, strret); + if(!strcmp(epcheck,"EP\"") || !strcmp(epcheck,"EP")){ + ESP_LOGI(TAG,"(%s) %s message is terminated",epcheck,messageheader); + } + else{ + ESP_LOGI(TAG,"(%s) %s message is not terminated!!",epcheck,messageheader); + + } + + /**********************************************************************************************************/ + /*Case: + + str1 SP6 fw: BG77LAR02A04_01.009.01.009 + str2 fw: BG77LAR02A04_01.008.01.008 + + 9 is the first non-matching character in str1 greater + than that of str2. return > 0(update needed) + + + str1 SP6 fw: BG77LAR02A04_01.008.01.008 + str2 fw: BG77LAR02A04_01.009.01.009 + + '9' is the first non-matching character in str1 lower + than that of str2. return < 0 + + */ + if(strcmp(modem_sp6_fwv,modem_get_fw_ver()) <= 0) + { + + /*If the existing version is the same go to idle*/ + comms.poll_timer = true; + ESP_LOGI(TAG,"No update need GOING TO IDLE FROM SP6"); + transition(COMMS_STATE_GOING_IDLE); + + } + else + { + /*Logging/printing this message*/ + ESP_LOGI(TAG,"F/W Modem Update NEEDED"); + ESP_LOGI(TAG,"GET MODEM UPDATE"); + comms.poll_timer = true; + transition(COMMS_STATE_WAIT_HTTP_GET_MODEM_UPDATE); + } +} + + +esp_err_t comms_http_request(comms_switch_cb cb,comms_state_t init_state, const char* msg, comms_state_t success_state,const char* url1,const char* url2,const char* url3){ + esp_err_t retval = ESP_FAIL; + int32_t val=data_get_postToServer(); + switch(val){ + + case TEMPSTICK_SERVER1: + + /* make the get/post request to server 1. */ + //ESP_LOGI(TAG,"get/post request to server 1........... "); + retval = cb(init_state, url1,msg, success_state); + + break; + case TEMPSTICK_SERVER2: + + /* make the get/post request to server 2. */ + //ESP_LOGI(TAG,"get/post request to server 2........... "); + retval = cb(init_state, url2, msg, success_state); + break; + + case TEMPSTICK_SERVER3: + + /* make the get/post request to server 3. */ + //ESP_LOGI(TAG,"get/post request to server 3........... "); + retval = cb(init_state, url3,msg, success_state); + break; + + default: + data_set_postToServer(TEMPSTICK_SERVER1); + ESP_LOGI(TAG,"connection to server %ld failed ",data_get_postToServer()); + ESP_LOGI(TAG,"connect to the default server "); + comms.poll_timer=true; + transition(init_state); + break; +} + + return retval; +} + +/* ------------------------------------------------------------------------- */ + +/*Handler for COMMS timer*/ +static void timer_handler(void* context) +{ + comms.poll_timer = true; +} + +static int state_machine(comms_event_t evt) +{ + int retval = COMMS_STATUS_OK; + switch (comms.state) + { + case COMMS_STATE_INIT: + if (evt == COMMS_EVENT_START) + { + /* Set the number of check-in cycles to do and reset the checkin_cycle_counter */ + number_of_check_in_to_do = nvm_get_last_written_history_sector() - nvm_get_last_posted_history_sector(); + checkin_cycle_counter = 0; + + ESP_LOGI(TAG,"---------> Number of check-in cycles to do is %d",number_of_check_in_to_do); + + /* Reset the backup flag */ + comms_do_wifi_backup = false; + comms_do_cell_backup = false; + + /* Status is ERROR until cleared by successful completion. */ + comms.last_cycle_status = COMMS_STATUS_ERROR; + + /*This must be changed to true inside modem_start_cb to transfer to the next state*/ + comms.poll_timer = false; + + if (modem_is_started()) + { + modem_start_cb(MODEM_STATUS_OK); + } + else + { + /* start the bg96 process */ + retval = modem_start(modem_start_cb); + if (retval == MODEM_STATUS_OK) + { + comms.is_starting = true; + ESP_LOGI(TAG,"Process starting.\n"); + transition(COMMS_STATE_WAIT_MODEM); + } + } + } + break; + case COMMS_STATE_WAIT_MODEM: + + /* Wait for BG96 startup event */ + if (evt == COMMS_EVENT_TIMER) + { +#if (FAKE_NETWORK == 1) + data_parse_http_response(server_resp); + comms.poll_timer = true; + comms.last_cycle_status = COMMS_STATUS_OK; + transition(COMMS_STATE_GOING_IDLE); +#else + + /* Start the LED-event of connecting to network */ + if(!comms_do_cell_backup) + { + hmi_set_leds_state(BLUE_LED_FLASHING); //connecting to LTE network + } + + /* Check if need to do check-in over WIFI */ + if((COMMS_OVER_CELL != comms_mode) && (COMMS_OVER_CELL_WIFI_BACKUP != comms_mode) && (!comms_do_cell_backup)) + { + comms.poll_timer = true; + + transition(COMMS_STATE_WIFI_CONNECT); + break; + } + + if(comms_do_cell_backup) + comms_do_cell_backup = false; + + /* modem is started. connect to network */ + retval = modem_network_connect(net_connect_cb); + if (retval == MODEM_STATUS_OK) + { + /* Set the communication_medium flag to be CELL */ + comms_medium = COMMS_MEDIUM_CELL; + + ESP_LOGI(TAG,"LTE Connecting to Cellular network\r\n"); + transition(COMMS_STATE_WAIT_NET_CONNECT); + } +#endif + } + + break; + + case COMMS_STATE_WAIT_NET_CONNECT: + + /* Wait for BG96 network connect event */ + if (evt == COMMS_EVENT_TIMER) + { + ESP_LOGI(TAG,"Network connected\r\n"); + + comms.httpRetryCnt = HTTP_RETRY_COUNT_MAX; + + /* Network connected */ + comms.poll_timer = true; + comms.last_cycle_status = COMMS_STATUS_OK; + comms.httpRetryCnt = HTTP_POST_RETRY_MAX; //Setting the number of http_post retries + transition(COMMS_STATE_WAIT_HTTP_POST_REQ); + } + break; + + case COMMS_STATE_WIFI_CONNECT: + if(evt == COMMS_EVENT_TIMER) + { + /* Set the communication_medium flag to be WIFI */ + comms_medium = COMMS_MEDIUM_WIFI; + + /* Initialize the wifi */ + retval = wifi_first_init(); + + /* If the initialization retval is OK then continue to connect to the registered WIFI access-point */ + if(retval == WIFI_OK) + { + /* Connect to the registered WIFI access-point */ + retval = Connect_wifi_sta(WIFI_CLIENT_MODE); + + /* if the connection retval is OK then jump to the "WIFI_POST_REQ" state */ + if(retval == WIFI_OK) + { + /* Do a transition to "WIFI_POST_REQ" */ + transition(COMMS_STATE_WIFI_POST_REQ); + } + else + { + /* Print this Log */ + ESP_LOGI(TAG,"Failed to connect to the WIFI access-point"); + + /* Set the posting_failed to be true */ + comms_posting_failed = true; + + /* Do cellular backup for the check-in process */ + if(COMMS_OVER_WIFI_CELL_BACKUP) + { + comms_do_cell_backup = true; + } + + /* Do a transition to "GOING_IDLE" state */ + transition(COMMS_STATE_GOING_IDLE); + } + } + else + { + /* Print this Log */ + ESP_LOGI(TAG,"Failed to initialize the WIFI"); + + /* Set the posting_failed to be true */ + comms_posting_failed = true; + + /* Do cellular backup for the check-in process */ + if(COMMS_OVER_WIFI_CELL_BACKUP) + { + comms_do_cell_backup = true; + } + + /* Do a transition to "GOING_IDLE" state */ + transition(COMMS_STATE_GOING_IDLE); + } + + /* Set poll_timer to true to allow executing whatever next state */ + comms.poll_timer = true; + } + + break; + + case COMMS_STATE_WIFI_POST_REQ: + if(evt == COMMS_EVENT_TIMER) + { + /* Get the address of the receiving buffer */ + char *buf = modem_get_rxbuf(); + + /* Do WIFI post-request for the CHECK_IN message + * (Creating the check-in string is done internally inside this function) + * (Also, Switching between the 3-servers are done inside this function) */ + retval = http_client_do_post_request(jsonMessage,buf); + + /* check whether POST-Req was successful and managed to receive/parse server-response or not*/ + if(retval == WIFI_OK) + { + /* Update the number of already done check-ins */ + checkin_cycle_counter++; + + /* Clear history array (So that its current readings don't affect the readings of the next sector) + * Just clear the array (don't clear anything from NVS) */ + data_clear_history(); + + /* Check if this was the last check-in to do (in other words, check if there are no more previous readings to send to server) */ + if(checkin_cycle_counter == number_of_check_in_to_do) + { + /* Close the connection of http-post */ + http_client_post_stop(); + + /* Reset the last post sector in the NVS partition to 0*/ + nvm_set_last_posted_history_sector(0); + + /* Clear History sectors + * Clear from NVS Partition */ + nvm_clear_history_sector(NVM_HISTORY_ALL_SECTORS); + + + /* Print the POST server response */ + ESP_LOGI(TAG,"HTTP-POST response is :\n%s\n",buf); + + /* Parse the server-response */ + data_parse_http_response((const char*)buf); + + /* Reset the posting_failed to be false */ + comms_posting_failed = false; + + /* Don't do cellular backup */ + comms_do_cell_backup = false; + + /* Do a transition to "WIFI_GET_REQ" state */ + transition(COMMS_STATE_WIFI_GET_REQ); + } + else + { + /* Coming here means that there were some previous readings that are stored in NVS and need to posted in multiple check-in cycles + * and we already posted the readings in history_sector x ----> so we need to update the last_posted_sector flag */ + + /* Update the last post sector in the NVS partition */ + uint8_t x = nvm_get_last_posted_history_sector()+1; + nvm_set_last_posted_history_sector(x); + + /* Wait some time before doing the next check-in of the remaining previous readings */ + vTaskDelay(2000/portTICK_PERIOD_MS); + } + } + else + { + /* Close the connection of http-post */ + http_client_post_stop(); + + /* Print this Log */ + ESP_LOGI(TAG,"Failed to do WIFI POST-Request"); + + /* Set the posting_failed to be true */ + comms_posting_failed = true; + + /* Do cellular backup for the check-in process */ + if(COMMS_OVER_WIFI_CELL_BACKUP) + { + comms_do_cell_backup = true; + } + + /* Do a transition to "GOING_IDLE" state */ + transition(COMMS_STATE_GOING_IDLE); + } + + /* Set poll_timer to true to allow executing whatever next state */ + comms.poll_timer = true; + } + + break; + + case COMMS_STATE_WIFI_GET_REQ: + if(evt == COMMS_EVENT_TIMER) + { + /* Get the address of the receiving buffer */ + char *buf = modem_get_rxbuf(); + + /* Do WIFI get-request for the SP messages + * Parsing SP5 message and checking the firmware version is done internally inside this function + * (Also, Starting WIFI-OTA session is done internally inside this function) + * (Also, Switching between the 3-servers are done inside this function) + * (Also, Parsing the server-response -if get request succeeded- is done internally inside this function */ + retval = http_client_do_get_request(GET_CONFIGURATIONS,(char*)modem_get_imei(),buf); + + /* check whether GET-Req was successful and managed to receive/parse server-response or not*/ + if(retval != WIFI_OK) + { + /* Print this Log */ + ESP_LOGI(TAG,"Failed to do GET-Request"); + } + + /* Set poll_timer to true to allow executing whatever next state */ + comms.poll_timer = true; + + /* Do a transition to "GOING_IDLE" state */ + transition(COMMS_STATE_GOING_IDLE); + } + + break; + + case COMMS_STATE_WAIT_HTTP_SEND_CONFIG_FLAGS: + + /* Wait for BG96 HTTP setup event */ + if (evt == COMMS_EVENT_TIMER) + { + + retval= comms_http_request(start_http_get_request,COMMS_STATE_WAIT_HTTP_SEND_CONFIG_FLAGS,"configuration flags",COMMS_STATE_WAIT_HTTP_GET_CONFIG_FLAGS,MCU_GET_CONFIG_FLAGS_URL1,MCU_GET_CONFIG_FLAGS_URL2,MCU_GET_CONFIG_FLAGS_URL3); + + } + break; + + case COMMS_STATE_WAIT_HTTP_GET_CONFIG_FLAGS: + + /* Wait for BG96 HTTP GET config event */ + if (evt == COMMS_EVENT_TIMER) + { + /* Get the buffer and process the configuration. */ + int len = 0; + char* buf = 0; + retval = modem_http_get_buf(&buf, &len); + if (retval == MODEM_STATUS_OK) + { + ESP_LOGI(TAG,"CONFIG BUF :\n%s\n",buf); + + /// Parsing config ........ + retval = data_parsing_config(buf,len); + if(!retval){ + //if parsing success check update flags g_ConfigUpdate, g_McuUpdate, g_ModemUpdate. + ESP_LOGI(TAG,"config Parsing success"); + check_for_update(); + } + else + { + ESP_LOGI(TAG,"config Parsing Failed"); + } + } + else{ + ESP_LOGI(TAG,"Modem get buff Failed (GET_CONFIG_FLAGS state)"); + comms.poll_timer= true; + transition(COMMS_STATE_GOING_IDLE); + } + } + + break; + + case COMMS_STATE_WAIT_HTTP_POST_REQ: + if(evt == COMMS_EVENT_TIMER) + { +//suceesUrl = 1 + data_create_checkin_string(jsonMessage, sizeof(jsonMessage)); + + retval=comms_http_request(start_http_post_request,COMMS_STATE_WAIT_HTTP_POST_REQ,jsonMessage,COMMS_STATE_WAIT_HTTP_POST_RES,MCU_POST_URL1,MCU_POST_URL2,MCU_POST_URL3); + + } + + break; + + case COMMS_STATE_WAIT_HTTP_POST_RES: + + /* Wait for BG96 HTTP GET config event */ + if (evt == COMMS_EVENT_TIMER) + { + /* Get the buffer and process the configuration. */ + int len = 0; + char* buf = 0; + retval = modem_http_get_buf(&buf, &len); + if (retval == MODEM_STATUS_OK) + { + + ESP_LOGI(TAG,"HTTP-POST response is :\n%s\n",buf); + data_parse_http_response((const char *)buf); + + + //comms_update_onboarding_status(); + if(NVM_ONBOARDING_NOT_SET_VAL != nvm_read_onboarding_flag(CELL_ONBOARDING_KEY)) + { + nvm_write_onboarding_flag(CELL_ONBOARDING_KEY,NVM_ONBOARDING_SET_VAL); + } + + comms.poll_timer= true; + transition(COMMS_STATE_WAIT_HTTP_SEND_CONFIG_FLAGS); + } + else{ + comms.poll_timer= true; + transition(COMMS_STATE_GOING_IDLE); + } + } + + break; + + case COMMS_STATE_WAIT_HTTP_SEND_SP5: + + /* Wait for comms timer event */ + if (evt == COMMS_EVENT_TIMER) + { + /* Now make the GET request. */ + retval = comms_http_request(start_http_get_request,COMMS_STATE_WAIT_HTTP_SEND_SP5,"McuUpdate",COMMS_STATE_WAIT_HTTP_GET_SP5,MCU_FW_VERSION_URL1,MCU_FW_VERSION_URL2,MCU_FW_VERSION_URL3); + + } + break; + + case COMMS_STATE_WAIT_HTTP_GET_SP5: + + /* Wait for BG96 HTTP GET config event */ + if (evt == COMMS_EVENT_TIMER) + { + /* Get the buffer and process the configuration. */ + int len = 0; + char* buf = 0; + retval = modem_http_get_buf(&buf, &len); + if (retval == MODEM_STATUS_OK) + { + + ESP_LOGI(TAG,"SP5 BUF: %s",buf); + + //SP5 parsing... + Comms_Parse_SP5(buf, len); + } + else + { + ESP_LOGI(TAG,"SP5 Parsing Failed"); + comms.poll_timer = true; + transition(COMMS_STATE_GOING_IDLE); + } + } + break; + + + case COMMS_STATE_WAIT_HTTP_SEND_SP6: + + /* Wait for comms timer event */ + if (evt == COMMS_EVENT_TIMER) + { + /* Now make the GET request. */ + retval = comms_http_request(start_http_get_request,COMMS_STATE_WAIT_HTTP_SEND_SP6,"ModemUpdate",COMMS_STATE_WAIT_HTTP_GET_SP6,MODEM_FW_VERSION_URL1,MODEM_FW_VERSION_URL2,MODEM_FW_VERSION_URL3); + + } + break; + + case COMMS_STATE_WAIT_HTTP_GET_SP6: + + /* Wait for BG96 HTTP GET config event */ + if (evt == COMMS_EVENT_TIMER) + { + /* Get the buffer and process the configuration. */ + int len = 0; + char* buf = 0; + retval = modem_http_get_buf(&buf, &len); + if (retval == MODEM_STATUS_OK) + { + + ESP_LOGI(TAG,"SP6 BUF: %s",buf); + + //SP6 parsing... + Comms_Parse_SP6(buf, len); + } + else + { + ESP_LOGI(TAG,"SP6 Parsing Failed"); + comms.poll_timer = true; + transition(COMMS_STATE_GOING_IDLE); + } + } + break; + + case COMMS_STATE_WAIT_HTTP_GET_MODEM_UPDATE: + + /* Wait for BG96 HTTP GET modem update event */ + if (evt == COMMS_EVENT_TIMER) + { + comms.get_modem_update = false; + /* Get the buffer and process the configuration. */ + int len = 0; + char* buf = 0; + retval = modem_http_get_buf(&buf, &len); + if (retval == MODEM_STATUS_OK) + { + // if (COMMS_STATUS_OK == check_modem_update(buf, len)) + { + /* Different firmware on server. Use it. */ + /* Setup URL */ + memset(comms.mqtt_buf, 0, sizeof(comms.mqtt_buf)); + + + switch(data_get_postToServer()){ + + case TEMPSTICK_SERVER1: + + /* make the POST request to server 1. */ + ESP_LOGI(TAG,"Get Modem bin file from server 1"); + snprintf(comms.mqtt_buf, sizeof(comms.mqtt_buf), MODEM_FW_BIN_FILE_URL1, modem_get_imei()); + + break; + case TEMPSTICK_SERVER2: + + /* make the POST request to server 2. */ + ESP_LOGI(TAG,"Get Modem bin file from server 2"); + snprintf(comms.mqtt_buf, sizeof(comms.mqtt_buf), MODEM_FW_BIN_FILE_URL2, modem_get_imei()); + break; + + case TEMPSTICK_SERVER3: + + /* make the POST request to server 3. */ + ESP_LOGI(TAG,"Get Modem bin file from server 3"); + snprintf(comms.mqtt_buf, sizeof(comms.mqtt_buf), MODEM_FW_BIN_FILE_URL3, modem_get_imei()); + break; + + } + + + /* Download the GET data to modem */ + int retval = modem_update_modem(fotadl_op_cb, comms.mqtt_buf); + if (retval == MODEM_STATUS_OK) + { + hmi_set_leds_state(BLUE_LED_FLASHING_OTA); + ESP_LOGI(TAG,"FOTADL started\r\n"); + transition(COMMS_STATE_WAIT_MODEM_UPDATE); + break; + } + else + { + ESP_LOGE(TAG,"FOTADL failed to start\r\n"); + /* Continue with session */ + } + } + } + } + break; + + case COMMS_STATE_WAIT_MODEM_UPDATE: + + /* Wait for modem update callback. */ + if (evt == COMMS_EVENT_TIMER) + { + /* In either case, stop the comm process. We want to connect again to do the uplink, + * and we can do that by returning "UPDATED" status, allowing main + * to schedule another connection attempt right away - if desired. + */ + comms.last_cycle_status = COMMS_STATUS_UPDATED; + comms.poll_timer = true; /* request state machine to be polled again right away in new state */ + hmi_stop_ota_event(); + transition(COMMS_STATE_GOING_IDLE); + } + break; + + case COMMS_STATE_WAIT_HTTP_GET_MCU_UPDATE: + + /* Set http_init_state to COMMS_STATE_WAIT_HTTP_GET_MCU_UPDATE */ + comms.http_init_state = COMMS_STATE_WAIT_HTTP_GET_MCU_UPDATE; + + /* Wait for BG96 HTTP GET MCU update event */ + //if (evt == COMMS_EVENT_TIMER) + { + comms.get_mcu_update = false; + /* Get the buffer and process the MCU fw version message. */ + //int len = 0; + //char* buf = 0; + //retval = modem_http_get_buf(&buf, &len); + //if (retval == MODEM_STATUS_OK) + { + //if (COMMS_STATUS_OK == check_mcu_update(buf, len)) + { + /* Different firmware on server. Use it. */ + /* Setup URL: + * Need to download either upper or lower version of the application, + * depending on what we're running now. (i.e. if we are the lower app, need + * to get the upper app) + */ + memset(comms.mqtt_buf, 0, sizeof(comms.mqtt_buf)); + +#if ST_OTA_HIGHER_APPLICATION +//// snprintf(comms.mqtt_buf, sizeof(comms.mqtt_buf), MCU_FW_BIN_FILE_URL1_LOWER, modem_get_imei()); +#elif ST_OTA_LOWER_APPLICATION +// snprintf(comms.mqtt_buf, sizeof(comms.mqtt_buf), MCU_FW_BIN_FILE_URL1_HIGHER, modem_get_imei()); +#else +//// snprintf(comms.mqtt_buf, sizeof(comms.mqtt_buf), MCU_FW_BIN_FILE_URL1_LOWER, modem_get_imei()); +#endif + /*Creating file path and store it in comms.mqtt_buf*/ +// snprintf(comms.mqtt_buf, sizeof(comms.mqtt_buf), MCU_FW_BIN_FILE_URL1, modem_get_imei()); + + switch(data_get_postToServer()){ + + case TEMPSTICK_SERVER1: + + /* make the get request to server 1. */ + ESP_LOGI(TAG,"Get MCU bin file from server 1"); + snprintf(comms.mqtt_buf, sizeof(comms.mqtt_buf), MCU_FW_BIN_FILE_URL1, modem_get_imei()); + break; + + case TEMPSTICK_SERVER2: + + /* make the get request to server 2. */ + ESP_LOGI(TAG,"Get MCU bin file from server 2"); + snprintf(comms.mqtt_buf, sizeof(comms.mqtt_buf), MCU_FW_BIN_FILE_URL2, modem_get_imei()); + break; + + case TEMPSTICK_SERVER3: + + /* make the get request to server 3. */ + ESP_LOGI(TAG,"Get MCU bin file from server 3"); + snprintf(comms.mqtt_buf, sizeof(comms.mqtt_buf), MCU_FW_BIN_FILE_URL3, modem_get_imei()); + break; + + } + + + + /* Download the file data to modem file system */ + int retval = modem_http_get_to_file(fwdl_op_cb, comms.mqtt_buf, MCU_OTA_FILE_LOCAL); + + if (retval == MODEM_STATUS_OK) + { + ESP_LOGI(TAG,"MCU FW download started\r\n"); + ///hmi_set_offload_mode(false); + transition(COMMS_STATE_WAIT_HTTP_GET_MCU_FILE); + //hmi_set_update_mode(true); + break; + } + else + { + ESP_LOGE(TAG,"MCU FW download failed to start\r\n"); + /* Continue with session */ + } + } + } + } + + break; + + case COMMS_STATE_WAIT_HTTP_GET_MCU_FILE: + + /* Wait for download complete callback. */ + if (evt == COMMS_EVENT_TIMER) + { + if (comms.last_op_success) + { + /* Download is ready. Now we can start the read from file operation on the bg96 driver + * and use the callbacks to drive the update. The bg96 process is driving the update. + */ + retval = modem_read_from_file( + fwupd_op_cb, /* called when completed or failed at any point */ + MCU_OTA_FILE_LOCAL, + ota_file_open_cb, /* Can fail and continue the comms state machine */ + ota_file_data_cb); /* Callback for the file data in chunks */ + + if (retval == MODEM_STATUS_OK) + { + hmi_set_leds_state(BLUE_LED_FLASHING_OTA); + ESP_LOGI(TAG,"MCU FW update started\r\n"); + transition(COMMS_STATE_WAIT_MCU_UPDATE); + break; + } + else + { + ESP_LOGE(TAG,"MCU FW update failed to start\r\n"); + /* Continue with session */ + //hmi_set_update_mode(false); + } + } + } + break; + + case COMMS_STATE_WAIT_MCU_UPDATE: + + /* Wait while updating. */ + if (evt == COMMS_EVENT_TIMER) + { + if (comms.last_op_success) + { + /* If it completes, it will ping this and here and we finish it up. + * OTA_terminate_connection sets the flag that is handled in OTA_Tick() + * and main to do a reset to start the new application after comm completes. + */ + ESP_LOGD(TAG,"Ending OTA session, ready for reset\r\n"); + + ota_finish_processing(); + + /* Clear this, in case we have just turned on and have updated - + * no need to trigger the startup callback in main. + */ + comms.is_starting = false; + } + } + break; + + case COMMS_STATE_GOING_IDLE: + + /* Check if we can use WIFI as backup technique for check-in */ + if((COMMS_OVER_CELL_WIFI_BACKUP == comms_mode) && (comms_do_wifi_backup)) + { + /* Print this log */ + ESP_LOGI(TAG,"Doing WIFI-BACKUP for CHECK-IN process."); + + /* Transfer the control state to "WIFI_CONNECT" */ + transition(COMMS_STATE_WIFI_CONNECT); + + /* Set the comms.poll_timer to be true */ + comms.poll_timer = true; + + /* Reset the wifi-backup flag */ + comms_do_wifi_backup = false; + + /* Break from the state-machine */ + break; + } + else if((COMMS_OVER_WIFI_CELL_BACKUP == comms_mode) && (comms_do_cell_backup)) + { + /* Print this log */ + ESP_LOGI(TAG,"Doing CELL-BACKUP for CHECK-IN process."); + + /* Transfer the control state to "WAIT_MODEM" */ + transition(COMMS_STATE_WAIT_MODEM); + + /* Set the comms.poll_timer to be true */ + comms.poll_timer = true; + + /* Reset the cell-backup flag */ + //comms_do_cell_backup = false; + + /* Break from the state-machine */ + break; + } + + ESP_LOGI(TAG,"Process going idle.\n"); + + /* Reset the backup flag */ + comms_do_wifi_backup = false; + comms_do_cell_backup = false; + +#if (FAKE_NETWORK == 1) + comms_update_onboarding_status(); +#endif + + /* Stop BLUE_LED_FLASHING if it's still running*/ + hmi_stop_continued_led_state(BLUE_LED_FLASHING); //stop BLUE_LED_FLASHING event + + + /* Check if MCU failed to post the check-in message to the tempstick-server */ + if(comms_posting_failed) + { + /* Print this log */ + ESP_LOGI(TAG," -----> Posting the check-in message failed.\n Storing sensor data to NVS to be published in the next successful CHECK-IN process "); + + /**/ + // put your code here to store sensor data to NVS + data_save_history(); + + /* Reset the comms_posting_failed flag */ + comms_posting_failed = false; + } + + /*===========================================*/ + /* Make sure that wifi is turned-off*/ + if(wifi_isStarted()) + { + retval = wifi_stop(); + } + + /* Make sure that modem is turned-off*/ + if(modem_is_started()) + { + retval = modem_stop(); + } + /*===========================================*/ + transition(COMMS_STATE_WAIT_MODEM_OFF); + comms.poll_timer = true; + + break; + + case COMMS_STATE_IDLE: + if (evt == COMMS_EVENT_CONNECT) + { + /* Set the number of check-in cycles to do and reset the checkin_cycle_counter */ + number_of_check_in_to_do = nvm_get_last_written_history_sector() - nvm_get_last_posted_history_sector(); + checkin_cycle_counter = 0; + + ESP_LOGI(TAG, "Inside comms IDLE state \r\n"); + + /* Status is ERROR until cleared by successful completion. */ + comms.last_cycle_status = COMMS_STATUS_ERROR; + + if (modem_is_ready()) + { + modem_start_cb(MODEM_STATUS_OK); + } + else if(!modem_is_started()) + { + /* start the bg77 process */ + retval = modem_start(modem_start_cb); + + if (retval == MODEM_STATUS_OK) + { + ESP_LOGI(TAG,"Waiting for Modem.\n"); + transition(COMMS_STATE_WAIT_MODEM); + } + } + else + { + ESP_LOGI(TAG, "Modem is busy. Comm cycle aborted.\r\n"); + } + } + break; + + case COMMS_STATE_WAIT: + check_in_attempts_count(comms.httpRetryCnt,HTTP_RETRY_COUNT_MAX); + esp_timer_stop(comms_timer); + comms.poll_timer = true; + transition(comms.http_init_state); + ESP_LOGI(TAG,"Number of remaining HTTP retry is : %d\n", comms.httpRetryCnt); + break; + + case COMMS_STATE_WAIT_MODEM_OFF: + if(!modem_is_started()) + { + /* transition to INIT state only if not started. */ + transition(COMMS_STATE_IDLE); + + /* Invoke callback if supplied.*/ + if(comms.connect_cb) + { + comms.connect_cb(comms.last_cycle_status); + comms.connect_cb = 0; + } + } + else + { + //ESP_LOGW(TAG,"Modem is busy.\r\n"); + comms.poll_timer = true; + } + break; + + default: + break; + } + + return retval; +} + +/* ------------------------------------------------------------------------- */ + + + /* Initialize. */ +int comms_init(void) +{ + int retval = COMMS_STATUS_OK; + + memset(&comms, 0, sizeof(comms)); + comms.overflow_check = 0xFF; + + /*Initializing the COMMS_TIMER */ + const esp_timer_create_args_t comms_timer_args = { + .callback = &timer_handler, + /* argument specified here will be passed to timer callback function */ + .arg = (void*) comms_timer, + .name = "comms-timer" + }; + esp_timer_create(&comms_timer_args, &comms_timer); + + comms.poll_timer = false; + + ESP_LOGI(TAG,"Process initialized.\n"); + + return retval; +} + +/* Start the process */ +int comms_start(comms_op_cb_t start_cb, comms_op_cb_t connect_cb) +{ + comms.start_cb = start_cb; + comms.connect_cb = connect_cb; + int retval = state_machine(COMMS_EVENT_START); + return retval; +} + +/* Stop the process */ +int comms_stop(void) +{ + int retval = state_machine(COMMS_EVENT_STOP); + return retval; +} + +/* Poll the process */ +int comms_poll(void) +{ + int retval = COMMS_STATUS_OK; + if (comms.poll_timer) + { + comms.poll_timer = false; + retval = state_machine(COMMS_EVENT_TIMER); + } + else if (0 /* */) + { + } + + return retval; +} + +int comms_connect(comms_op_cb_t cb) +{ + comms.connect_cb = cb; + int retval = state_machine(COMMS_EVENT_CONNECT); + return retval; +} + +/* Check if the process needs to be polled */ +bool comms_needs_poll(void) +{ + return + comms.poll_timer; +} + + +/* Check if the process is started */ +bool comms_is_started(void) +{ + return comms.state != COMMS_STATE_INIT; +} + +bool comms_is_idle(void) +{ + return comms.state == COMMS_STATE_IDLE; +} + +int comms_get_status(void) +{ + return comms.last_cycle_status; +} + +/* ------ Process Callbacks ------------------------- */ + +__attribute__((weak)) void comms_ready_cb(void) { } + + + + diff --git a/main/comms.h b/main/comms.h new file mode 100644 index 0000000..9ab89b1 --- /dev/null +++ b/main/comms.h @@ -0,0 +1,283 @@ +/* + * comms.h + * + * Created on: Jan 16, 2023 + * Author: Sword + */ + +#ifndef MAIN_COMMS_H_ +#define MAIN_COMMS_H_ + + +#include +#include +#include "sdkconfig.h" +#include "main.h" +/* comms.h + * + * Copyright 2020 HAE Innovations + * + * Celluar Communications process manager. + * + * Handles communication to/from server over cell modem, + * collecting and sending events from queue, processing configuration + * and firmware updates from server, etc. + * + * Author: E. Ross + */ + +#define COMMS_STATUS_UPDATED 1 +#define COMMS_STATUS_OK 0 +#define COMMS_STATUS_ERROR -1 + + +#define MCU_BASE_URL1 "https://testdevice.tempstickapi.com" +#define MCU_BASE_URL2 "https://testdevice.tempstickapi.com" +#define MCU_BASE_URL3 "https://testdevice.tempstickapi.com" +#define MCU_BASE_URL4 "http://testdevice.tempstickapi.com" + + +#define MCU_ONBOARDING_URL "https://device-status.idealsciences%u.com" +#define POSTING_ONBOARDING "POST /sensor-account.php HTTP/1.0" +#define ON_BOARDING_SERVER_DOMAIN_NAME "device-status.idealsciences.com" +#define USER_AGENT_ONBOARDING "SensorDHT/1.0" +#define AUTHERIZATION_VALUE_ONBOARDING "Basic ZGV2OmRldjEyMw==" +#define CONTENT_TYPE_VALUE_ONBOARDING "application/x-www-form-urlencoded" +#define ONBOARDING_SERVER_POSTURL_MAX 3 +#define ONBOARDING_SERVER_POSTURL_MIN 1 + + +#define PARTHA_SERVER_BASE_URL "https://www.parthasarathimishra.com" +#define TESTING_SERVER_BASE_URL "http://3.90.70.38:8080" + + +typedef enum +{ + COMMS_OVER_CELL_WIFI_BACKUP = 1, + COMMS_OVER_WIFI_CELL_BACKUP, + COMMS_OVER_CELL, + COMMS_OVER_WIFI, + COMMS_MODE_5 //wifi as default for all readings /cellular for alerts /wifi back up for alerts +}comms_type_t; + +typedef enum +{ + COMMS_MEDIUM_CELL, + COMMS_MEDIUM_WIFI, +}comms_medium_t; + +#if (TEMPSTICK_SERVER == 1) + + +/*HTTP POST header component for tempstick server*/ +#define END_POINT_POSTING1 "POST / HTTP/1.1\r\n" +#define END_POINT_AUTHERIZATION "Authorization: Bearer 19730e88-886d-4c94-89d6-3066b79b7630\r\n" +#define AUTHERIZATION_VALUE "Bearer 19730e88-886d-4c94-89d6-3066b79b7630" +#define END_POINT_HOST "Host: testdevice.tempstickapi.com\r\n" +#define HOST_VALUE "testdevice.tempstickapi.com" +#define END_POINT_USER_AGENT "User-Agent: \"SensorDHT\\/1.0\"\r\n" +#define USER_AGENT_VALUE "\"SensorDHT\\/1.0\"" +#define END_POINT_CONTENT_TYPE "Content-Type: application/json\r\n" +#define CONTENT_TYPE_VALUE "application/json" +#define END_POINT_CONTENT_LEN "Content-Length: %u\r\n\r\n" + +#define HTTP_POST_HEADER END_POINT_POSTING1 END_POINT_AUTHERIZATION END_POINT_HOST END_POINT_USER_AGENT END_POINT_CONTENT_TYPE END_POINT_CONTENT_LEN + + +// URL to post on servers 1, 2, and 3 +#define MCU_POST_URL1 MCU_BASE_URL1 +#define MCU_POST_URL2 MCU_BASE_URL2 +#define MCU_POST_URL3 MCU_BASE_URL3 + +//URL to get configuration flags from servers 1, 2, and 3 +#define MCU_GET_CONFIG_FLAGS_URL1 TESTING_SERVER_BASE_URL"/hae/tempstick/%s/config/"//MCU_BASE_URL1//config/flag/server1 +#define MCU_GET_CONFIG_FLAGS_URL2 TESTING_SERVER_BASE_URL"/hae/tempstick/%s/config/"//MCU_BASE_URL2//config/flag/server2 +#define MCU_GET_CONFIG_FLAGS_URL3 TESTING_SERVER_BASE_URL"/hae/tempstick/%s/config/"//MCU_BASE_URL3//config/flag/server3 + +/* this endpoint not implemented yet in the code (customer pending) */ +// if the config_update flag is set +// URL to get settings from servers 1, 2, and 3 +#define MCU_GET_SETTINGS_URL1 TESTING_SERVER_BASE_URL//settings/server1 +#define MCU_GET_SETTINGS_URL2 TESTING_SERVER_BASE_URL//settings/server2 +#define MCU_GET_SETTINGS_URL3 TESTING_SERVER_BASE_URL//settings/server3 + +//URL to get MCU FW version from servers 1, 2, and 3 +#define MCU_FW_VERSION_URL1 TESTING_SERVER_BASE_URL"/hae/tempstick/%s/mcu_pgm_download/version/"/*MCU_BASE_URL1//mcu/fw/version/server1*/ +#define MCU_FW_VERSION_URL2 TESTING_SERVER_BASE_URL"/hae/tempstick/%s/mcu_pgm_download/version/"//MCU_BASE_URL2//mcu/fw/version/server2 +#define MCU_FW_VERSION_URL3 TESTING_SERVER_BASE_URL"/hae/tempstick/%s/mcu_pgm_download/version/"//MCU_BASE_URL3//mcu/fw/version/server3 + +//URL to get MCU FW bin file from servers 1, 2, and 3 +#define MCU_FW_BIN_FILE_URL1 TESTING_SERVER_BASE_URL"/hae/tempstick/%s/mcu_pgm_download/OTA.bin"//MCU_BASE_URL1//mcu/fw/bin/file/server1 +#define MCU_FW_BIN_FILE_URL2 TESTING_SERVER_BASE_URL"/hae/tempstick/%s/mcu_pgm_download/OTA.bin"//MCU_BASE_URL2//mcu/fw/bin/file/server2 +#define MCU_FW_BIN_FILE_URL3 TESTING_SERVER_BASE_URL"/hae/tempstick/%s/mcu_pgm_download/OTA.bin"//MCU_BASE_URL3//mcu/fw/bin/file/server3 + +//URL to get MODEM FW version from servers 1, 2, and 3 +#define MODEM_FW_VERSION_URL1 TESTING_SERVER_BASE_URL"/hae/tempstick/%s/modem_pgm_download/version/"//MCU_BASE_URL1//modem/fw/version/server1 +#define MODEM_FW_VERSION_URL2 TESTING_SERVER_BASE_URL"/hae/tempstick/%s/modem_pgm_download/version/"//MCU_BASE_URL2//modem/fw/version/server2 +#define MODEM_FW_VERSION_URL3 TESTING_SERVER_BASE_URL"/hae/tempstick/%s/modem_pgm_download/version/"//MCU_BASE_URL3//modem/fw/version/server3 + +//URL to get MODEM FW bin file from servers 1, 2, and 3 +#define MODEM_FW_BIN_FILE_URL1 TESTING_SERVER_BASE_URL"/hae/tempstick/%s/modem_pgm_download/MOTA.bin"//MCU_BASE_URL1//modem/fw/bin/file/server1 +#define MODEM_FW_BIN_FILE_URL2 TESTING_SERVER_BASE_URL"/hae/tempstick/%s/modem_pgm_download/MOTA.bin"//MCU_BASE_URL2//modem/fw/bin/file/server2 +#define MODEM_FW_BIN_FILE_URL3 TESTING_SERVER_BASE_URL"/hae/tempstick/%s/modem_pgm_download/MOTA.bin"//MCU_BASE_URL3//modem/fw/bin/file/server3 + + +#else + +#if (TESTING_SERVER==1) + +/*HTTP POST header component for Partha server*/ +#define END_POINT_POSTING1 "POST /hae/tempstick/send HTTP/1.1\r\n" +#define END_POINT_AUTHERIZATION "Authorization: Bearer 19730e88-886d-4c94-89d6-3066b79b7630\r\n" +#define AUTHERIZATION_VALUE "Bearer 19730e88-886d-4c94-89d6-3066b79b7630" +#define END_POINT_HOST "Host: 3.90.70.38:8080\r\n" +#define HOST_VALUE "3.90.70.38:8080" +#define END_POINT_USER_AGENT "User-Agent: \"SensorDHT\\/1.0\"\r\n" +#define USER_AGENT_VALUE "\"SensorDHT\\/1.0\"" +#define END_POINT_CONTENT_TYPE "Content-Type: application/json\r\n" +#define CONTENT_TYPE_VALUE "application/json" +#define END_POINT_CONTENT_LEN "Content-Length: %u\r\n\r\n" +/*HTTP POST header */ +#define HTTP_POST_HEADER END_POINT_POSTING1 END_POINT_AUTHERIZATION END_POINT_HOST END_POINT_USER_AGENT END_POINT_CONTENT_TYPE END_POINT_CONTENT_LEN + + +// URL to post on servers 1, 2, and 3 +#define MCU_POST_URL1 TESTING_SERVER_BASE_URL"/hae/tempstick/send" +#define MCU_POST_URL2 TESTING_SERVER_BASE_URL"/hae/tempstick/send" +#define MCU_POST_URL3 TESTING_SERVER_BASE_URL"/hae/tempstick/send" + +//URL to get configuration flags from servers 1, 2, and 3 +#define MCU_GET_CONFIG_FLAGS_URL1 TESTING_SERVER_BASE_URL"/hae/tempstick/%s/config/"//MCU_BASE_URL1//config/flag/server1 +#define MCU_GET_CONFIG_FLAGS_URL2 TESTING_SERVER_BASE_URL"/hae/tempstick/%s/config/"//MCU_BASE_URL2//config/flag/server2 +#define MCU_GET_CONFIG_FLAGS_URL3 TESTING_SERVER_BASE_URL"/hae/tempstick/%s/config/"//MCU_BASE_URL3//config/flag/server3 + +/* this endpoint not implemented yet in the code (customer pending) */ +// if the config_update flag is set +// URL to get settings from servers 1, 2, and 3 +#define MCU_GET_SETTINGS_URL1 TESTING_SERVER_BASE_URL//settings/server1 +#define MCU_GET_SETTINGS_URL2 TESTING_SERVER_BASE_URL//settings/server2 +#define MCU_GET_SETTINGS_URL3 TESTING_SERVER_BASE_URL//settings/server3 + +//URL to get MCU FW version from servers 1, 2, and 3 +#define MCU_FW_VERSION_URL1 TESTING_SERVER_BASE_URL"/hae/tempstick/%s/mcu_pgm_download/version/"/*MCU_BASE_URL1//mcu/fw/version/server1*/ +#define MCU_FW_VERSION_URL2 TESTING_SERVER_BASE_URL"/hae/tempstick/%s/mcu_pgm_download/version/"//MCU_BASE_URL2//mcu/fw/version/server2 +#define MCU_FW_VERSION_URL3 TESTING_SERVER_BASE_URL"/hae/tempstick/%s/mcu_pgm_download/version/"//MCU_BASE_URL3//mcu/fw/version/server3 + +//URL to get MCU FW bin file from servers 1, 2, and 3 +#define MCU_FW_BIN_FILE_URL1 TESTING_SERVER_BASE_URL"/hae/tempstick/%s/mcu_pgm_download/OTA.bin"//MCU_BASE_URL1//mcu/fw/bin/file/server1 +#define MCU_FW_BIN_FILE_URL2 TESTING_SERVER_BASE_URL"/hae/tempstick/%s/mcu_pgm_download/OTA.bin"//MCU_BASE_URL2//mcu/fw/bin/file/server2 +#define MCU_FW_BIN_FILE_URL3 TESTING_SERVER_BASE_URL"/hae/tempstick/%s/mcu_pgm_download/OTA.bin"//MCU_BASE_URL3//mcu/fw/bin/file/server3 + +//URL to get MODEM FW version from servers 1, 2, and 3 +#define MODEM_FW_VERSION_URL1 TESTING_SERVER_BASE_URL"/hae/tempstick/%s/modem_pgm_download/version/"//MCU_BASE_URL1//modem/fw/version/server1 +#define MODEM_FW_VERSION_URL2 TESTING_SERVER_BASE_URL"/hae/tempstick/%s/modem_pgm_download/version/"//MCU_BASE_URL2//modem/fw/version/server2 +#define MODEM_FW_VERSION_URL3 TESTING_SERVER_BASE_URL"/hae/tempstick/%s/modem_pgm_download/version/"//MCU_BASE_URL3//modem/fw/version/server3 + +//URL to get MODEM FW bin file from servers 1, 2, and 3 +#define MODEM_FW_BIN_FILE_URL1 TESTING_SERVER_BASE_URL"/hae/tempstick/%s/modem_pgm_download/MOTA.bin"//MCU_BASE_URL1//modem/fw/bin/file/server1 +#define MODEM_FW_BIN_FILE_URL2 TESTING_SERVER_BASE_URL"/hae/tempstick/%s/modem_pgm_download/MOTA.bin"//MCU_BASE_URL2//modem/fw/bin/file/server2 +#define MODEM_FW_BIN_FILE_URL3 TESTING_SERVER_BASE_URL"/hae/tempstick/%s/modem_pgm_download/MOTA.bin"//MCU_BASE_URL3//modem/fw/bin/file/server3 + + +#else +/*HTTP POST header component for Partha server*/ +#define END_POINT_POSTING1 "POST /hae/tempstick/send.php HTTP/1.1\r\n" +#define END_POINT_AUTHERIZATION "Authorization: Bearer 19730e88-886d-4c94-89d6-3066b79b7630\r\n" +#define END_POINT_HOST "Host: www.parthasarathimishra.com\r\n" +#define END_POINT_USER_AGENT "User-Agent: \"SensorDHT\\/1.0\"\r\n" +#define END_POINT_CONTENT_TYPE "Content-Type: application/json\r\n" +#define END_POINT_CONTENT_LEN "Content-Length: %u\r\n\r\n" +/*HTTP POST header */ +#define HTTP_POST_HEADER END_POINT_POSTING1 END_POINT_AUTHERIZATION END_POINT_HOST END_POINT_USER_AGENT END_POINT_CONTENT_TYPE END_POINT_CONTENT_LEN + + +// URL to post on servers 1, 2, and 3 +#define MCU_POST_URL1 PARTHA_SERVER_BASE_URL"/hae/tempstick/send.php" +#define MCU_POST_URL2 PARTHA_SERVER_BASE_URL"/hae/tempstick/send.php" +#define MCU_POST_URL3 PARTHA_SERVER_BASE_URL"/hae/tempstick/send.php" + +//URL to get configuration flags from servers 1, 2, and 3 +#define MCU_GET_CONFIG_FLAGS_URL1 PARTHA_SERVER_BASE_URL"/hae/tempstick/%s/config/"//MCU_BASE_URL1//config/flag/server1 +#define MCU_GET_CONFIG_FLAGS_URL2 PARTHA_SERVER_BASE_URL"/hae/tempstick/%s/config/"//MCU_BASE_URL2//config/flag/server2 +#define MCU_GET_CONFIG_FLAGS_URL3 PARTHA_SERVER_BASE_URL"/hae/tempstick/%s/config/"//MCU_BASE_URL3//config/flag/server3 + +/* this endpoint not implemented yet in the code (customer pending) */ +// if the config_update flag is set +// URL to get settings from servers 1, 2, and 3 +#define MCU_GET_SETTINGS_URL1 MCU_BASE_URL1//settings/server1 +#define MCU_GET_SETTINGS_URL2 MCU_BASE_URL2//settings/server2 +#define MCU_GET_SETTINGS_URL3 MCU_BASE_URL3//settings/server3 + +//URL to get MCU FW version from servers 1, 2, and 3 +#define MCU_FW_VERSION_URL1 PARTHA_SERVER_BASE_URL"/hae/tempstick/%s/mcu_pgm_download/version/"/*MCU_BASE_URL1//mcu/fw/version/server1*/ +#define MCU_FW_VERSION_URL2 PARTHA_SERVER_BASE_URL"/hae/tempstick/%s/mcu_pgm_download/version/"//MCU_BASE_URL2//mcu/fw/version/server2 +#define MCU_FW_VERSION_URL3 PARTHA_SERVER_BASE_URL"/hae/tempstick/%s/mcu_pgm_download/version/"//MCU_BASE_URL3//mcu/fw/version/server3 + +//URL to get MCU FW bin file from servers 1, 2, and 3 +#define MCU_FW_BIN_FILE_URL1 PARTHA_SERVER_BASE_URL"/hae/tempstick/%s/mcu_pgm_download/OTA.bin"//MCU_BASE_URL1//mcu/fw/bin/file/server1 +#define MCU_FW_BIN_FILE_URL2 PARTHA_SERVER_BASE_URL"/hae/tempstick/%s/mcu_pgm_download/OTA.bin"//MCU_BASE_URL2//mcu/fw/bin/file/server2 +#define MCU_FW_BIN_FILE_URL3 PARTHA_SERVER_BASE_URL"/hae/tempstick/%s/mcu_pgm_download/OTA.bin"//MCU_BASE_URL3//mcu/fw/bin/file/server3 + +//URL to get MODEM FW version from servers 1, 2, and 3 +#define MODEM_FW_VERSION_URL1 PARTHA_SERVER_BASE_URL"/hae/tempstick/%s/modem_pgm_download/version/"//MCU_BASE_URL1//modem/fw/version/server1 +#define MODEM_FW_VERSION_URL2 PARTHA_SERVER_BASE_URL"/hae/tempstick/%s/modem_pgm_download/version/"//MCU_BASE_URL2//modem/fw/version/server2 +#define MODEM_FW_VERSION_URL3 PARTHA_SERVER_BASE_URL"/hae/tempstick/%s/modem_pgm_download/version/"//MCU_BASE_URL3//modem/fw/version/server3 + +//URL to get MODEM FW bin file from servers 1, 2, and 3 +#define MODEM_FW_BIN_FILE_URL1 PARTHA_SERVER_BASE_URL"/hae/tempstick/%s/modem_pgm_download/MOTA.bin"//MCU_BASE_URL1//modem/fw/bin/file/server1 +#define MODEM_FW_BIN_FILE_URL2 PARTHA_SERVER_BASE_URL"/hae/tempstick/%s/modem_pgm_download/MOTA.bin"//MCU_BASE_URL2//modem/fw/bin/file/server2 +#define MODEM_FW_BIN_FILE_URL3 PARTHA_SERVER_BASE_URL"/hae/tempstick/%s/modem_pgm_download/MOTA.bin"//MCU_BASE_URL3//modem/fw/bin/file/server3 +#endif +#endif + + + + + + +/* TEMPSTICK servers URL's */ +typedef enum { + TEMPSTICK_SERVER1=1, + TEMPSTICK_SERVER2, + TEMPSTICK_SERVER3 +}serverUrl_t; + + /* Operation complete indication callback */ +typedef void (*comms_op_cb_t)(int status); + +/* Initialize process. */ +int comms_init(void); + +/* Start process. + * The server is contacted for configuration. + * When this processes completes, the callback is notified. + */ +int comms_start(comms_op_cb_t start_cb, comms_op_cb_t connect_cb); + +/* Stop process. */ +int comms_stop(void); + +/* Poll process. */ +int comms_poll(void); + +/* Check if the process needs to be polled. */ +bool comms_needs_poll(void); + +/* Connect to server once process has completed startup and is idle +* Optional callback is invoked when process completes. +*/ +int comms_connect(comms_op_cb_t cb); + +/* Check if the process is idle and not doing any communications. */ +bool comms_is_idle(void); + +/* Check if the process is started */ +bool comms_is_started(void); + +/* Get the status of the last communication attempt. + * OK - everything completed. + * ERROR - something failed. + */ +int comms_get_status(void); + +#endif /* MAIN_COMMS_H_ */ diff --git a/main/data_processing.c b/main/data_processing.c new file mode 100644 index 0000000..9916ffc --- /dev/null +++ b/main/data_processing.c @@ -0,0 +1,2603 @@ +/* + * data_processing.c + * + * Created on: Feb 3, 2023 + * Author: Partha + */ +#include +#include +#include "nvs_flash.h" +#include "esp_system.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include +#include "sys/time.h" +#include "driver/gpio.h" +#include "esp_log.h" +#include "math.h" +#include "sdkconfig.h" +#include "time.h" +#include "rtc_wdt.h" +#include "modem.h" +#include "esp_mac.h" +#include "uart_ifx.h" +#include "esp_task_wdt.h" +#include "port.h" +#include "adc_ifx.h" +#include "ulp_main.h" +#include "i2c_sensors.h" +#include "data_processing.h" +#include "ulp_main.h" +#include "main.h" +#include "hmi.h" +#include "comms.h" +#include "lwip/ip4_addr.h" +#include "wifi_Init.h" +#include "nvm.h" +static const char* TAG = "DATA"; + +#define LOG_LOCAL_LEVEL ESP_LOG_INFO +#include "esp_log.h" + +extern bool isCycleCompleted; +extern uint8_t comms_mode; +extern comms_medium_t comms_medium; + +extern uint8_t checkin_cycle_counter; +extern uint8_t number_of_check_in_to_do; + +static char thermocouple_type; + +uint32_t g_version = 0; +uint32_t g_wifiConnectTime; +float g_voltage = 0; +bool g_usbConnected = 0; +bool g_enableButtonTiming; +RTC_DATA_ATTR static bool g_prevUsbConnected; +uint32_t light_mv = 0; +uint8_t checkInAttemptNumber = 1; +time_t g_wakeUpTime = 0; +uint32_t g_StatusFlags = 0; +uint32_t g_triggerFlags1 = 0; +uint32_t g_triggerFlags2 = 0; + +// Configuration global variable +uint32_t g_server_time = 0; +uint32_t g_ID; +uint32_t g_SensorInt; +uint32_t g_ConfigUpdate; +uint32_t g_McuUpdate; +uint32_t g_ModemUpdate; + + + +/*RTC_DATA_ATTR static uint16_t g_triggersThatCanWakeTheHost; +RTC_DATA_ATTR static uint16_t g_strobedHumidityFlags; +RTC_DATA_ATTR static uint16_t g_strobedMiscFlags; +RTC_DATA_ATTR static uint16_t g_strobedMotionFlags; +RTC_DATA_ATTR static uint16_t g_strobedTemperatureFlags; +RTC_DATA_ATTR static uint16_t g_strobedThermocoupleFlags;*/ + +extern uint8_t wakeHostForStrobedTrigger2; +extern void set_delay_sleep(void); + +typedef struct +{ + uint8_t accel : 2; + uint8_t vusb : 2; + uint8_t lowv: 2; + uint8_t pushbtn: 2; +}isr_data_t; + +static isr_data_t isr_data; + + +void IRAM_ATTR accel_int1_isr(void *args) +{ + isr_data.accel = 1 + gpio_get_level(9); +} + +void IRAM_ATTR vusb_detect_isr(void *args) +{ + isr_data.vusb = 1 + gpio_get_level(10); +} + +void IRAM_ATTR lowv_detect_isr(void *args) +{ + isr_data.lowv = 1 + gpio_get_level(38); +} + +void IRAM_ATTR push_button_isr(void *args) +{ + isr_data.pushbtn = 1 + gpio_get_level(5); +} + + +char urlConnect[70]={0}; +static int32_t postToServer=1; +static bool isTempPresent = false; +static bool isAccelPresent = false; +static bool isThermocouplePresent = false; + + typedef struct { + + //Sensor Data + uint8_t thermocoupleMode; + uint8_t thermocoupleType; + uint8_t lightSensorMode; + + uint8_t accelerometerMode; + uint8_t accelerometerInterval; + uint8_t accelerometerLockoutInSeconds; + uint8_t powerMonitorMode; + uint8_t powerMonitorDebounceInSeconds; + + //uint8_t lightSensorLevelGP; + //uint8_t lightSensorLevelGN; + + //lightTh + uint8_t lightSensorLevel; + + // OTHERS + uint8_t historyIndex; + uint8_t numberOfHistoryLogEntriesUntilRetriesAreNotAllowed; + + bool sendDetails; + + uint16_t lightSensorLockoutInSeconds; + + //acclTh + uint16_t accelerometerLevel; + + // INTERVALS + uint32_t sendInterval; + uint32_t alertInterval; + + //Limits + int32_t minHum; + int32_t maxHum; + + // DYNAMIC VARS + int32_t postURLNumber; + int32_t postURLMax; // Highest URL to try + + //Limits + float minTemp; + float maxTemp; + float voltageQuit; + + //limits Tc + float maxTcTemp; + float minTcTemp; + + //limits probe + float maxProbeTemp; + float minProbeTemp; + +}settings; + + settings *esp_settings = (settings*)(&ulp_settings_structure); + + RTC_DATA_ATTR historyLog_t _logs[NVM_MAX_NUMBER_OF_IN_ONE_SECTOR] = {}; + + +typedef struct +{ + // Stored in RTC RAM during Deep Sleeps. This reduces wear on the FLASH. + + // TIMING + uint32_t timeOfLastRadioCalibration; + uint32_t checkInClock; + uint32_t retry1Clock; + uint32_t retry2Clock; + int8_t lteRssi; // Modem signal strength + + // WIFI CONFIG + uint8_t bssid[6]; + esp_netif_ip_info_t localIp; + esp_netif_dns_info_t dns1; + esp_netif_dns_info_t dns2; + uint8_t wifiChannel; + int32_t wifi_rssi; + + // OTHERS + uint32_t operatingMode; + uint32_t initializationVector[4]; + bool initializationVectorCreated; + uint32_t checkInCount; + float temperatureAtLastRadioCalibration; + bool retriesAreInProgress; +}rtcRamData_t; + +RTC_DATA_ATTR rtcRamData_t _rtcRamData; + +uint32_t data_get_send_interval(void) +{ + if(esp_settings->sendInterval) + return esp_settings->sendInterval; + else + return 900; +} + +bool data_is_usb_connected(void) +{ + return g_usbConnected; +} + +static esp_err_t data_parse_float_value(float *target_buffer, const char needle[], const char *http_resp) +{ + esp_err_t retval = ESP_FAIL; + + char *ret = NULL; + char *start_add = NULL; + char *end_add = NULL; + char parse_value[] = {'0'}; + + int len = 0; + + /*1- Extract temperature limits*/ + ret = strstr(http_resp, needle); + if(ret) + { + /*2- get the starting address of the value*/ + start_add = strstr(ret,(char*)":") + 1; + + /*3- get the ending address of the value*/ + end_add = strstr(ret,(char*)",") + 1; + + if((char *)1 == end_add) + end_add = start_add + strlen(start_add) + 1; + + /*4- Calculate the length of the value*/ + len = end_add - start_add; + + /*5- copy the value into the buffer*/ + snprintf(parse_value, len, "%s", start_add); + + /*6- Assign the double value to the target buffer*/ + *target_buffer = atof(parse_value); + + retval = ESP_OK; + } + + return retval; +} + +static esp_err_t data_parse_int_value(int32_t *target_buffer, const char needle[], const char *http_resp) +{ + esp_err_t retval = ESP_FAIL; + + char *ret = NULL; + char *start_add = NULL; + char *end_add = NULL; + char parse_value[] = {'0'}; + + int len = 0; + + /*1- Extract temperature limits*/ + ret = strstr(http_resp, needle); + if(ret) + { + /*2- get the starting address of the value*/ + start_add = strstr(ret,(char*)":") + 1; + + /*3- get the ending address of the value*/ + end_add = strstr(ret,(char*)",") + 1; + + if((char *)1 == end_add) + end_add = start_add + strlen(start_add) + 1; + + /*4- Calculate the length of the value*/ + len = end_add - start_add; + + /*5- copy the value into the buffer*/ + snprintf(parse_value, len, "%s", start_add); + + /*6- Assign the double value to the target buffer*/ + *target_buffer = atoi(parse_value); + + retval = ESP_OK; + } + + return retval; +} + +static esp_err_t data_parse_uint8_value(uint8_t *target_buffer, const char needle[], const char *http_resp) +{ + esp_err_t retval = ESP_FAIL; + + char *ret = NULL; + char *start_add = NULL; + char *end_add = NULL; + char parse_value[] = {'0'}; + + int len = 0; + + /*1- Extract temperature limits*/ + ret = strstr(http_resp, needle); + if(ret) + { + /*2- get the starting address of the value*/ + start_add = strstr(ret,(char*)":") + 1; + + /*3- get the ending address of the value*/ + end_add = strstr(ret,(char*)",") + 1; + + if((char *)1 == end_add) + end_add = start_add + strlen(start_add) + 1; + + /*4- Calculate the length of the value*/ + len = end_add - start_add; + + /*5- copy the value into the buffer*/ + snprintf(parse_value, len, "%s", start_add); + + /*6- Assign the double value to the target buffer*/ + *target_buffer = atoi(parse_value); + + retval = ESP_OK; + } + + return retval; +} + +static esp_err_t data_parse_uint16_value(uint16_t *target_buffer, const char needle[], const char *http_resp) +{ + esp_err_t retval = ESP_FAIL; + + char *ret = NULL; + char *start_add = NULL; + char *end_add = NULL; + char parse_value[] = {'0'}; + + int len = 0; + + /*1- Extract temperature limits*/ + ret = strstr(http_resp, needle); + if(ret) + { + /*2- get the starting address of the value*/ + start_add = strstr(ret,(char*)":") + 1; + + /*3- get the ending address of the value*/ + end_add = strstr(ret,(char*)",") + 1; + + if((char *)1 == end_add) + end_add = start_add + strlen(start_add) + 1; + + /*4- Calculate the length of the value*/ + len = end_add - start_add; + + /*5- copy the value into the buffer*/ + snprintf(parse_value, len, "%s", start_add); + + /*6- Assign the double value to the target buffer*/ + *target_buffer = atoi(parse_value); + + retval = ESP_OK; + } + + return retval; +} + +static esp_err_t data_parse_uint_value(uint32_t *target_buffer, const char needle[], const char *http_resp) +{ + esp_err_t retval = ESP_FAIL; + + char *ret = NULL; + char *start_add = NULL; + char *end_add = NULL; + char parse_value[] = {'0'}; + + int len = 0; + + /*1- Extract temperature limits*/ + ret = strstr(http_resp, needle); + if(ret) + { + /*2- get the starting address of the value*/ + start_add = strstr(ret,(char*)":") + 1; + + /*3- get the ending address of the value*/ + end_add = strstr(ret,(char*)",") + 1; + + if((char *)1 == end_add) + end_add = start_add + strlen(start_add) + 1; + + /*4- Calculate the length of the value*/ + len = end_add - start_add; + + /*5- copy the value into the buffer*/ + snprintf(parse_value, len, "%s", start_add); + + /*6- Assign the double value to the target buffer*/ + *target_buffer = atoi(parse_value); + + retval = ESP_OK; + } + + return retval; +} + +static esp_err_t data_parse_String_value(char *target_buffer, const char needle[], const char *http_resp) +{ + esp_err_t retval = ESP_FAIL; + + char *ret = NULL; + char *start_add = NULL; + char *end_add = NULL; + + + int len = 0; + + /*1- Extract temperature limits*/ + ret = strstr(http_resp, needle); + if(ret) + { + /*2- get the starting address of the value*/ + start_add = strstr(ret,(char*)":") + 2; + + /*3- get the ending address of the value*/ + end_add = strstr(ret,(char*)","); + + /*4- Calculate the length of the value*/ + len = end_add - start_add; + + /*5- copy the value into the buffer*/ + snprintf(target_buffer, len, "%s", start_add); + + retval = ESP_OK; + } + + return retval; +} + + + +static void setAccelerometerPowerState(void) +{ + switch(esp_settings->accelerometerMode) + { + case 0: // Disable accelerometer + if(ESP_FAIL == i2c_set_mc3419_mode(MC3419_STANDBY_MODE)) // Only mode register can be written in WAKE mode. All other registers are read-only. It appears that clearing the interrupt flags is an exception to this rule. + ESP_LOGI(TAG,"Accelerometer error #6."); + if(ESP_FAIL == i2c_clear_mc3419_int_flag()) + ESP_LOGI(TAG,"Accelerometer error #4."); + break; + + case 1: // "Bumping" motion detection. + if(ESP_FAIL == i2c_set_mc3419_mode(MC3419_WAKE_MODE)) // Only mode register can be written in WAKE mode. All other registers are read-only. It appears that clearing the interrupt flags is an exception to this rule. + ESP_LOGI(TAG,"Accelerometer error #5."); + else + ESP_LOGI(TAG,"Accelerometer mode now is WAKEUP mode.\n Accelerometer is ready to receive Interrupts"); + + if(ESP_FAIL == i2c_clear_mc3419_int_flag()) + ESP_LOGI(TAG,"Accelerometer error #4."); + break; + + default: // All other yet-to-be-implemented modes. + ESP_LOGI(TAG,"Setting Accelerometer mode to be STANDBY Mode"); + if(ESP_FAIL == i2c_set_mc3419_mode(MC3419_STANDBY_MODE)) // Only mode register can be written in WAKE mode. All other registers are read-only. It appears that clearing the interrupt flags is an exception to this rule. + ESP_LOGI(TAG,"Accelerometer error #6."); + if(ESP_FAIL == i2c_clear_mc3419_int_flag()) + ESP_LOGI(TAG,"Accelerometer error #4."); + break; + } +} + +static void data_clear_sensor_strobes(uint16_t tempFlags, uint16_t humiFlags, uint16_t thermocoupleFlags, uint16_t motionFlags, uint16_t miscFlags) +{ + ulp_ulp_strobedTemperatureFlags &= ~tempFlags; // Clear the masked strobed interrupt flags. + ulp_ulp_strobedHumidityFlags &= ~humiFlags; // Clear the masked strobed interrupt flags. + ulp_ulp_strobedThermocoupleFlags &= ~thermocoupleFlags; // Clear the masked strobed interrupt flags. + ulp_ulp_strobedMiscFlags &= ~miscFlags; // Clear the masked strobed interrupt flags. + ulp_ulp_strobedMotionFlags &= ~motionFlags; // Clear the masked strobed interrupt flags. +} + + + +static void data_parse_limits(const char *http_resp) +{ + //parse the value of minTemp + data_parse_float_value(&(esp_settings->minTemp), "minTemp", http_resp); + ESP_LOGI(TAG,"minTemp = %f",esp_settings->minTemp); + ulp_temperature_raw_min_thr = (uint32_t)(esp_settings->minTemp+273.15)*64; + + //parse the value of maxTemp + data_parse_float_value(&(esp_settings->maxTemp), "maxTemp", http_resp); + ESP_LOGI(TAG,"maxTemp = %f",esp_settings->maxTemp); + ulp_temperature_raw_max_thr = (uint32_t)(esp_settings->maxTemp+273.15)*64; + + //parse the value of minHum + data_parse_int_value(&(esp_settings->minHum), "minHum", http_resp); + ESP_LOGI(TAG,"minHum = %ld",esp_settings->minHum); + ulp_humidity_raw_min_thr = (uint32_t)esp_settings->minHum*512; + + //parse the value of maxHum + data_parse_int_value(&(esp_settings->maxHum), "maxHum", http_resp); + ESP_LOGI(TAG,"maxHum = %ld",esp_settings->maxHum); + ulp_humidity_raw_max_thr = (uint32_t)esp_settings->maxHum*512; + + //parse the value of voltageQuit + data_parse_float_value(&(esp_settings->voltageQuit), "voltageQuit", http_resp); + ESP_LOGI(TAG,"voltageQuit = %f",esp_settings->voltageQuit); +} + +static void data_parse_intervals(const char *http_resp) +{ + //uint32_t prevSendInterval = esp_settings->sendInterval; + uint8_t prev_commsMode = comms_mode; + + //Parse server time + data_parse_uint_value(&g_server_time, "time", http_resp); + + if(g_server_time) + { + struct timeval tv; + tv.tv_sec = g_server_time; + settimeofday(&tv, NULL); + } + + //parse the value of alertInterval + data_parse_uint_value(&(esp_settings->alertInterval), "alertInterval", http_resp); + ESP_LOGI(TAG,"alertInterval = %ld",esp_settings->alertInterval); + + //parse the value of sendInterval + data_parse_uint_value(&(esp_settings->sendInterval), "sendInterval", http_resp); + ESP_LOGI(TAG,"sendInterval = %ld",esp_settings->sendInterval); + + //parse the value of commsMode + data_parse_uint8_value(&(comms_mode), "commsMode", http_resp); + + /* Make sure that the comms-mode is between 1 and 5 and not equal to the old comms-mode (to save the life of NVS) */ + if((comms_mode > 0) && (comms_mode < 5) && (prev_commsMode != comms_mode)) + { + /* Store the COMMS-Mode in NVS */ + nvm_write_comms_mode(comms_mode); + + ESP_LOGI(TAG,"commsMode = %d",comms_mode); + } + else + { + comms_mode = prev_commsMode; + } + + // update checkin timer period, only if time period has changed. + //if(prevSendInterval != esp_settings->sendInterval) + { + update_checkin_timer((uint64_t)esp_settings->sendInterval); + } +} + +static void data_parse_dynamicVariables(const char *http_resp) +{ + /* parse the value of sendDetails*/ + uint32_t sendDetails = 0; + data_parse_uint_value(&(sendDetails), "sendDetails", http_resp); + if(sendDetails == 1) + { + esp_settings->sendDetails = true; + ESP_LOGI(TAG,"sendDetails = true"); + } + else + { + esp_settings->sendDetails = false; + ESP_LOGI(TAG,"sendDetails = false"); + } + + + /* parse the value of postURLNumber*/ + data_parse_int_value(&(esp_settings->postURLNumber), "postURLNumber", http_resp); + ESP_LOGI(TAG,"postURLNumber = %ld",esp_settings->postURLNumber); + + /* parse the value of postURLMax*/ + data_parse_int_value(&(esp_settings->postURLMax), "postURLMax", http_resp); + ESP_LOGI(TAG,"postURLMax = %ld",esp_settings->postURLMax); +} + +static void data_parse_temperature(const char *http_resp) +{ +#if 0 + /*Temperature Thresholds/Tokens:*/ + /* parse the value of tmpThA_GP*/ + data_parse_float_value(&(esp_settings->temperatureThresholds.thresholdA_GP), "tmpThA_GP", http_resp); + ESP_LOGI(TAG,"Temp_thresholdA_GP = %f",esp_settings->temperatureThresholds.thresholdA_GP); + + /* parse the value of tmpThA_GN*/ + data_parse_float_value(&(esp_settings->temperatureThresholds.thresholdA_GN), "tmpThA_GN", http_resp); + ESP_LOGI(TAG,"Temp_thresholdA_GN = %f",esp_settings->temperatureThresholds.thresholdA_GN); + + /* parse the value of tmpThB_GP*/ + data_parse_float_value(&(esp_settings->temperatureThresholds.thresholdB_GP), "tmpThB_GP", http_resp); + ESP_LOGI(TAG,"Temp_thresholdB_GP = %f",esp_settings->temperatureThresholds.thresholdB_GP); + + /* parse the value of tmpThB_GN*/ + data_parse_float_value(&(esp_settings->temperatureThresholds.thresholdB_GN), "tmpThB_GN", http_resp); + ESP_LOGI(TAG,"Temp_thresholdB_GN = %f",esp_settings->temperatureThresholds.thresholdB_GN); + + /* parse the value of tmpThC_GP*/ + data_parse_float_value(&(esp_settings->temperatureThresholds.thresholdC_GP), "tmpThC_GP", http_resp); + ESP_LOGI(TAG,"Temp_thresholdC_GP = %f",esp_settings->temperatureThresholds.thresholdC_GP); + + /* parse the value of tmpThC_GN*/ + data_parse_float_value(&(esp_settings->temperatureThresholds.thresholdC_GN), "tmpThC_GN", http_resp); + ESP_LOGI(TAG,"Temp_thresholdC_GN = %f",esp_settings->temperatureThresholds.thresholdC_GN); + + /* parse the value of tmpThD_GP*/ + data_parse_float_value(&(esp_settings->temperatureThresholds.thresholdD_GP), "tmpThD_GP", http_resp); + ESP_LOGI(TAG,"Temp_thresholdD_GP = %f",esp_settings->temperatureThresholds.thresholdD_GP); + + /* parse the value of tmpThD_GN*/ + data_parse_float_value(&(esp_settings->temperatureThresholds.thresholdD_GN), "tmpThD_GN", http_resp); + ESP_LOGI(TAG,"Temp_thresholdD_GN = %f",esp_settings->temperatureThresholds.thresholdD_GN); + + /* parse the value of tmpThE_GP*/ + data_parse_float_value(&(esp_settings->temperatureThresholds.thresholdE_GP), "tmpThE_GP", http_resp); + ESP_LOGI(TAG,"Temp_thresholdE_GP = %f",esp_settings->temperatureThresholds.thresholdE_GP); + + /* parse the value of tmpThE_GN*/ + data_parse_float_value(&(esp_settings->temperatureThresholds.thresholdE_GN), "tmpThE_GN", http_resp); + ESP_LOGI(TAG,"Temp_thresholdE_GN = %f",esp_settings->temperatureThresholds.thresholdE_GN); + + /* parse the value of tmpThF_GP*/ + data_parse_float_value(&(esp_settings->temperatureThresholds.thresholdF_GP), "tmpThF_GP", http_resp); + ESP_LOGI(TAG,"Temp_thresholdF_GP = %f",esp_settings->temperatureThresholds.thresholdF_GP); + + /* parse the value of tmpThF_GN*/ + data_parse_float_value(&(esp_settings->temperatureThresholds.thresholdF_GN), "tmpThF_GN", http_resp); + ESP_LOGI(TAG,"Temp_thresholdF_GN = %f",esp_settings->temperatureThresholds.thresholdF_GN); + + /* parse the value of T_TKN*/ + data_parse_uint8_value(&(esp_settings->temperatureTokens), "T_TKN", http_resp); + ESP_LOGI(TAG,"Temperature Tokens = %d",esp_settings->temperatureTokens); +#endif +} + +static void data_parse_humidity(const char *http_resp) +{ +#if 0 + /*Humidity Thresholds/Tokens:*/ + /* parse the value of humThA_GP*/ + data_parse_float_value(&(esp_settings->humidityThresholds.thresholdA_GP), "humThA_GP", http_resp); + ESP_LOGI(TAG,"Humi_thresholdA_GP = %f",esp_settings->humidityThresholds.thresholdA_GP); + + /* parse the value of humThA_GN*/ + data_parse_float_value(&(esp_settings->humidityThresholds.thresholdA_GN), "humThA_GN", http_resp); + ESP_LOGI(TAG,"Humi_thresholdA_GN = %f",esp_settings->humidityThresholds.thresholdA_GN); + + /* parse the value of humThB_GP*/ + data_parse_float_value(&(esp_settings->humidityThresholds.thresholdB_GP), "humThB_GP", http_resp); + ESP_LOGI(TAG,"Humi_thresholdB_GP = %f",esp_settings->humidityThresholds.thresholdB_GP); + + /* parse the value of humThB_GN*/ + data_parse_float_value(&(esp_settings->humidityThresholds.thresholdB_GN), "humThB_GN", http_resp); + ESP_LOGI(TAG,"Humi_thresholdB_GN = %f",esp_settings->humidityThresholds.thresholdB_GN); + + /* parse the value of humThC_GP*/ + data_parse_float_value(&(esp_settings->humidityThresholds.thresholdC_GP), "humThC_GP", http_resp); + ESP_LOGI(TAG,"Humi_thresholdC_GP = %f",esp_settings->humidityThresholds.thresholdC_GP); + + /* parse the value of humThC_GN*/ + data_parse_float_value(&(esp_settings->humidityThresholds.thresholdC_GN), "humThC_GN", http_resp); + ESP_LOGI(TAG,"Humi_thresholdC_GN = %f",esp_settings->humidityThresholds.thresholdC_GN); + + /* parse the value of humThD_GP*/ + data_parse_float_value(&(esp_settings->humidityThresholds.thresholdD_GP), "humThD_GP", http_resp); + ESP_LOGI(TAG,"Humi_thresholdD_GP = %f",esp_settings->humidityThresholds.thresholdD_GP); + + /* parse the value of humThD_GN*/ + data_parse_float_value(&(esp_settings->humidityThresholds.thresholdD_GN), "humThD_GN", http_resp); + ESP_LOGI(TAG,"Humi_thresholdD_GN = %f",esp_settings->humidityThresholds.thresholdD_GN); + + /* parse the value of humThE_GP*/ + data_parse_float_value(&(esp_settings->humidityThresholds.thresholdE_GP), "humThE_GP", http_resp); + ESP_LOGI(TAG,"Humi_thresholdE_GP = %f",esp_settings->humidityThresholds.thresholdE_GP); + + /* parse the value of humThE_GN*/ + data_parse_float_value(&(esp_settings->humidityThresholds.thresholdE_GN), "humThE_GN", http_resp); + ESP_LOGI(TAG,"Humi_thresholdE_GN = %f",esp_settings->humidityThresholds.thresholdE_GN); + + /* parse the value of humThF_GP*/ + data_parse_float_value(&(esp_settings->humidityThresholds.thresholdF_GP), "humThF_GP", http_resp); + ESP_LOGI(TAG,"Humi_thresholdF_GP = %f",esp_settings->humidityThresholds.thresholdF_GP); + + /* parse the value of humThF_GN*/ + data_parse_float_value(&(esp_settings->humidityThresholds.thresholdF_GN), "humThF_GN", http_resp); + ESP_LOGI(TAG,"Humi_thresholdF_GN = %f",esp_settings->humidityThresholds.thresholdF_GN); + + /* parse the value of H_TKN*/ + data_parse_uint8_value(&(esp_settings->humidityTokens), "H_TKN", http_resp); + ESP_LOGI(TAG,"Humi_tokens = %d",esp_settings->humidityTokens); +#endif +} + +static void data_parse_thermocouple(const char *http_resp) +{ + int32_t *x = (int32_t*)&ulp_thermo_raw_min_thr; + /*Thermocouple Thresholds/Tokens/mode:*/ + /* parse the value of tcTh*/ + data_parse_float_value(&(esp_settings->maxTcTemp), "maxTcTemp", http_resp); + if(esp_settings->maxTcTemp == 0) + { + esp_settings->maxTcTemp = 50; + } + ESP_LOGI(TAG,"max thermocoupleThreshold = %f",esp_settings->maxTcTemp); + ulp_thermo_raw_max_thr = esp_settings->maxTcTemp; + //ulp_thermo_raw_max_thr = esp_settings->maxTcTemp*16; + /* parse the value of tcTh*/ + data_parse_float_value(&(esp_settings->minTcTemp), "minTcTemp", http_resp); + if(esp_settings->minTcTemp == 0) + { + esp_settings->minTcTemp = -100; + } + ESP_LOGI(TAG,"min thermocoupleThreshold = %f",esp_settings->minTcTemp); + *x = (int32_t)esp_settings->minTcTemp; + /*ulp_thermo_raw_min_thr = (esp_settings->minTcTemp+4096); + ulp_thermo_raw_min_thr |= 0x8000; + ulp_thermo_raw_min_thr *= 16;*/ +#if 0 + /* parse the value of tcThA_GP*/ + data_parse_float_value(&(esp_settings->thermocoupleThresholds.thresholdA_GP), "tcThA_GP", http_resp); + ESP_LOGI(TAG,"thermocoupleThresholds.thresholdA_GP = %f",esp_settings->thermocoupleThresholds.thresholdA_GP); + + /* parse the value of tcThA_GN*/ + data_parse_float_value(&(esp_settings->thermocoupleThresholds.thresholdA_GN), "tcThA_GN", http_resp); + ESP_LOGI(TAG,"thermocoupleThresholds.thresholdA_GN = %f",esp_settings->thermocoupleThresholds.thresholdA_GN); + + /* parse the value of tcThB_GP*/ + data_parse_float_value(&(esp_settings->thermocoupleThresholds.thresholdB_GP), "tcThB_GP", http_resp); + ESP_LOGI(TAG,"thermocoupleThresholds.thresholdB_GP = %f",esp_settings->thermocoupleThresholds.thresholdB_GP); + + /* parse the value of tcThB_GN*/ + data_parse_float_value(&(esp_settings->thermocoupleThresholds.thresholdB_GN), "tcThB_GN", http_resp); + ESP_LOGI(TAG,"thermocoupleThresholds.thresholdB_GN = %f",esp_settings->thermocoupleThresholds.thresholdB_GN); + + /* parse the value of tcThC_GP*/ + data_parse_float_value(&(esp_settings->thermocoupleThresholds.thresholdC_GP), "tcThC_GP", http_resp); + ESP_LOGI(TAG,"thermocoupleThresholds.thresholdC_GP = %f",esp_settings->thermocoupleThresholds.thresholdC_GP); + + /* parse the value of tcThC_GN*/ + data_parse_float_value(&(esp_settings->thermocoupleThresholds.thresholdC_GN), "tcThC_GN", http_resp); + ESP_LOGI(TAG,"thermocoupleThresholds.thresholdC_GN = %f",esp_settings->thermocoupleThresholds.thresholdC_GN); + + /* parse the value of tcThD_GP*/ + data_parse_float_value(&(esp_settings->thermocoupleThresholds.thresholdD_GP), "tcThD_GP", http_resp); + ESP_LOGI(TAG,"thermocoupleThresholds.thresholdD_GP = %f",esp_settings->thermocoupleThresholds.thresholdD_GP); + + /* parse the value of tcThD_GN*/ + data_parse_float_value(&(esp_settings->thermocoupleThresholds.thresholdD_GN), "tcThD_GN", http_resp); + ESP_LOGI(TAG,"thermocoupleThresholds.thresholdD_GN = %f",esp_settings->thermocoupleThresholds.thresholdD_GN); + + /* parse the value of tcThE_GP*/ + data_parse_float_value(&(esp_settings->thermocoupleThresholds.thresholdE_GP), "tcThE_GP", http_resp); + ESP_LOGI(TAG,"thermocoupleThresholds.thresholdE_GP = %f",esp_settings->thermocoupleThresholds.thresholdE_GP); + + /* parse the value of tcThE_GN*/ + data_parse_float_value(&(esp_settings->thermocoupleThresholds.thresholdE_GN), "tcThE_GN", http_resp); + ESP_LOGI(TAG,"thermocoupleThresholds.thresholdE_GN = %f",esp_settings->thermocoupleThresholds.thresholdE_GN); + + /* parse the value of tcThF_GP*/ + data_parse_float_value(&(esp_settings->thermocoupleThresholds.thresholdF_GP), "tcThF_GP", http_resp); + ESP_LOGI(TAG,"thermocoupleThresholds.thresholdF_GP = %f",esp_settings->thermocoupleThresholds.thresholdF_GP); + + /* parse the value of tcThF_GN*/ + data_parse_float_value(&(esp_settings->thermocoupleThresholds.thresholdF_GN), "tcThF_GN", http_resp); + ESP_LOGI(TAG,"thermocoupleThresholds.thresholdF_GN = %f",esp_settings->thermocoupleThresholds.thresholdF_GN); + + /* parse the value of TC_TKN*/ + data_parse_uint8_value(&(esp_settings->thermocoupleTokens), "TC_TKN", http_resp); + ESP_LOGI(TAG,"thermocoupleTokens = %d",esp_settings->thermocoupleTokens); +#endif + /* parse the value of TC_M*/ + data_parse_String_value((char*)&(thermocouple_type), "TC_TYPE", http_resp); + switch(thermocouple_type) + { + case 'K': esp_settings->thermocoupleType = THERMOCOUPLE_TYPE_K; break; + case 'J': esp_settings->thermocoupleType = THERMOCOUPLE_TYPE_J; break; + case 'T': esp_settings->thermocoupleType = THERMOCOUPLE_TYPE_T; break; + case 'N': esp_settings->thermocoupleType = THERMOCOUPLE_TYPE_N; break; + case 'S': esp_settings->thermocoupleType = THERMOCOUPLE_TYPE_S; break; + case 'E': esp_settings->thermocoupleType = THERMOCOUPLE_TYPE_E; break; + case 'B': esp_settings->thermocoupleType = THERMOCOUPLE_TYPE_B; break; + case 'R': esp_settings->thermocoupleType = THERMOCOUPLE_TYPE_R; break; + + default: esp_settings->thermocoupleType = THERMOCOUPLE_TYPE_K; break; + } + ESP_LOGI(TAG,"thermocoupleType = %c",thermocouple_type); + ESP_LOGI(TAG,"thermocoupleType = %d",esp_settings->thermocoupleType); + + /*Setting thermocouple type in the MCP9600 module*/ + i2c_mcp9600_set_type(esp_settings->thermocoupleType); + + /* parse the value of TC_M*/ + data_parse_uint8_value(&(esp_settings->thermocoupleMode), "TC_M", http_resp); + ESP_LOGI(TAG,"thermocoupleMode = %d",esp_settings->thermocoupleMode); + + /*Process thermocouple mode*/ + data_processSensorModes(THERMOCOUPLE_SENSOR); + +} + +#if 0 +uint32_t data_get_light_sensor_gp(void) +{ + if(esp_settings->lightSensorLevelGP == 0) + return 200; + return esp_settings->lightSensorLevelGP; +} + +uint32_t data_get_light_sensor_gn(void) +{ + if(esp_settings->lightSensorLevelGN == 0) + return 50; + return esp_settings->lightSensorLevelGN; +} +#endif + +uint8_t data_get_light_sensor_threshold(void) +{ + if(esp_settings->lightSensorLevel == 0) + return 130; + return esp_settings->lightSensorLevel; +} + +static void data_parse_lightSensor(const char *http_resp) +{ + /* parse the value of LT_M*/ + data_parse_uint8_value(&(esp_settings->lightSensorMode), "LT_M", http_resp); + ESP_LOGI(TAG,"lightSensorMode = %d",esp_settings->lightSensorMode); + +#if 0 + /* parse the value of LT_LVLGP*/ + data_parse_uint8_value(&(esp_settings->lightSensorLevelGP), "LT_LVLGP", http_resp); + ESP_LOGI(TAG,"lightSensorLevelGP = %d",esp_settings->lightSensorLevelGP); + + /* parse the value of LT_LVLGN*/ + data_parse_uint8_value(&(esp_settings->lightSensorLevelGN), "LT_LVLGN", http_resp); + ESP_LOGI(TAG,"lightSensorLevelGN = %d",esp_settings->lightSensorLevelGN); +#endif + + /* parse the value of LT_LVL*/ + data_parse_uint8_value(&(esp_settings->lightSensorLevel), "lightTh", http_resp); + ESP_LOGI(TAG,"lightSensorLevel = %d",esp_settings->lightSensorLevel); + + /* parse the value of LT_LOCK*/ + data_parse_uint16_value(&(esp_settings->lightSensorLockoutInSeconds), "LT_LOCK", http_resp); + ESP_LOGI(TAG,"lightSensorLockoutInSeconds = %d",esp_settings->lightSensorLockoutInSeconds); + + /* parse the value of LT_TKN*/ + //data_parse_uint8_value(&(esp_settings->lightSensorTokens), "LT_TKN", http_resp); + //ESP_LOGI(TAG,"lightSensorTokens = %d",esp_settings->lightSensorTokens); + + /*Process light_sensor mode*/ + data_processSensorModes(LIGHT_SENSOR); +} + +static void data_parse_accelerometer(const char *http_resp) +{ + /* Enabling power to accelerometer to set the new motion-detection level*/ + port_accel_pwr_enable(1); + + /* Wait some time till the sensor get powered on*/ + vTaskDelay(100/portTICK_PERIOD_MS); + + /* parse the value of AC_M*/ + data_parse_uint8_value(&(esp_settings->accelerometerMode), "AC_M", http_resp); + ESP_LOGI(TAG,"accelerometerMode = %d",esp_settings->accelerometerMode); + + /* parse the value of AC_LVL*/ + data_parse_uint16_value(&(esp_settings->accelerometerLevel), "AC_LVL", http_resp); + ESP_LOGI(TAG,"accelerometerLevel = %d",esp_settings->accelerometerLevel); + + /* parse the value of AC_INT*/ + data_parse_uint8_value(&(esp_settings->accelerometerInterval), "AC_INT", http_resp); + ESP_LOGI(TAG,"accelerometerInterval = %d",esp_settings->accelerometerInterval); + + /* parse the value of AC_LOCK*/ + data_parse_uint8_value(&(esp_settings->accelerometerLockoutInSeconds), "AC_LOCK", http_resp); + ESP_LOGI(TAG,"accelerometerLockoutInSeconds = %d",esp_settings->accelerometerLockoutInSeconds); + + /* parse the value of AC_TKN*/ + //data_parse_uint8_value(&(esp_settings->accelerometerTokens), "AC_TKN", http_resp); + //ESP_LOGI(TAG,"accelerometerTokens = %d",esp_settings->accelerometerTokens); + + /*Process accelerometer mode*/ + data_processSensorModes(ACCELEROMETER_SENSOR); + + /*Set Accelerometer motion-detection level*/ + //i2c_set_mc3419_motionThreshold(esp_settings->accelerometerLevel); + //ESP_LOGI(TAG,"The new motion_detection threshold %d has been set",esp_settings->accelerometerLevel); + + /* Disabling accelerometer power*/ + //port_accel_pwr_enable(0); +} + +static void data_parse_power(const char *http_resp) +{ + /* parse the value of PWR_M*/ + data_parse_uint8_value(&(esp_settings->powerMonitorMode), "PWR_M", http_resp); + ESP_LOGI(TAG,"powerMonitorMode = %d",esp_settings->powerMonitorMode); + + /* parse the value of PWR_DBNC*/ + data_parse_uint8_value(&(esp_settings->powerMonitorDebounceInSeconds), "PWR_DBNC", http_resp); + ESP_LOGI(TAG,"powerMonitorDebounceInSeconds = %d",esp_settings->powerMonitorDebounceInSeconds); + + /* parse the value of PWR_TKN*/ + //data_parse_uint8_value(&(esp_settings->powerMonitorTokens), "PWR_TKN", http_resp); + //ESP_LOGI(TAG,"powerMonitorTokens = %d",esp_settings->powerMonitorTokens); + + /*Process power_monitor mode*/ + data_processSensorModes(POWER_MONITOR_SENSOR); +} + +static void data_parse_pushbutton(const char *http_resp) +{ + /* parse the value of PUSH_TKN*/ + //data_parse_uint8_value(&(esp_settings->pushbuttonTokens), "PUSH_TKN", http_resp); + //ESP_LOGI(TAG,"pushbuttonTokens = %d",esp_settings->pushbuttonTokens); + + /* parse the value of TKN_RLD*/ + //data_parse_uint16_value(&(esp_settings->tokenReloadIntervalInSeconds), "TKN_RLD", http_resp); + //ESP_LOGI(TAG,"tokenReloadIntervalInSeconds = %d",esp_settings->tokenReloadIntervalInSeconds); +} + +uint16_t data_get_motion_threshold(void) +{ + if(0 == esp_settings->accelerometerLevel) + return 1000; + + return esp_settings->accelerometerLevel; +} + +bool data_setTempPresent(bool status) +{ + isTempPresent = status; + return status; +} + +bool data_setAccelPresent(bool status) +{ + isAccelPresent = status; + return status; +} + +bool data_setThermocouplePresent(bool status) +{ + isThermocouplePresent = status; + return status; +} + +void data_set_accel_int1_wakeup(void) +{ + isr_data.accel = 2; +} + +void data_set_pushbutton_int0_wakeup(void) +{ + isr_data.pushbtn = 1; +} + +void data_set_vusb_init_interrupt(void) +{ + isr_data.vusb = 1 + gpio_get_level(10); +} + +batteryChargingState_t detect_if_usb_is_charging(void) +{ + static int counter = 0; + static int usb_state; + static int prev_usb_state; + static int is_first; + static int transition; + static int high_low; + static int low_high; + static int always_low = 0; + static int always_high = 0; + static bool always_state_set = false; + + batteryChargingState_t battery_charging_state = BATTERY_CHARGED; + + /*Read charging status pin up to 20 readings*/ + + if(g_usbConnected == 1) + { + /*Reading the state of USB-Charging pin*/ + usb_state = port_is_charging(); + + //ESP_LOGI(TAG,"USB current state = %d and previous state = %d",usb_state,prev_usb_state); + + if(usb_state == 0) + { + always_low++; // 11 + always_high = 0; + } + else + { + always_high++; + always_low = 0; + } + + /*Assuming prev_usb_state is the same as usb_state just for the first reading*/ + if(!is_first) + { + is_first = 1; + prev_usb_state = usb_state; + } + + /*Check if there is a transition*/ + if(prev_usb_state != usb_state) + { + always_state_set = false; + hmi_set_leds_state(BLUE_RED_LEDS_USB_OFF); + //ESP_LOGI(TAG,"USB current state = %d and previous state = %d",usb_state,prev_usb_state); + counter = 0; + transition = 1; + low_high = high_low = 0; + + /*Detect the edge of that transition*/ + if(prev_usb_state > usb_state) + { + high_low = 1; + } + else + { + low_high = 1; + } + prev_usb_state = usb_state; + } + + if(transition) + counter++; + + if(counter > 10) + { + if(high_low) + { + counter = 0; + transition = 0; + battery_charging_state = BATTERY_CHARGING; + } + else if(low_high) + { + counter = 0; + transition = 0; + battery_charging_state = BATTERY_CHARGED; + } + low_high = high_low = 0; + } + else + { + if(always_low >= 10) + { + battery_charging_state = BATTERY_CHARGING; + always_low--; + if(!always_state_set) + { + always_state_set = true; + ESP_LOGI(TAG,"#### BATTERY is charging ######"); + hmi_set_leds_state(BLUE_RED_LEDS_FLASHING_1SEC); + } + } + else if(always_high >= 10) + { + battery_charging_state = BATTERY_CHARGED; + always_high--; + if(!always_state_set) + { + ESP_LOGI(TAG,"#### BATTERY is charged #######"); + always_state_set = true; + hmi_set_leds_state(BLUE_RED_LEDS_SOLD); + } + } + + } + } + return battery_charging_state; +} + +void data_check_button_holding_time(void) +{ + static uint16_t button_pressed_time; + int button_state = 5; + + /* 1. Check whether the USB is connected or not */ + if(g_usbConnected) + { + /*2. Read button state */ + button_state = port_is_pushbuttonNotPressed(); //pressed ---> 0 not_pressed ---> 1 + + /*3. Check the button state*/ + if(!button_state) + { + /*3.1. If pressed then increased the button_pressed_time by 100ms */ + button_pressed_time += 100; + } + else + { + /*3.2. If released then reset the button_pressed_time to 0 and end the function*/ + button_pressed_time = 0; + + /*3.3. Stop button_timing*/ + g_enableButtonTiming = 0; + + /*4.3. Exit the function*/ + return; + } + + /*4. Check whether the button_pressed_time is >= 10 seconds (10000ms) */ + if(button_pressed_time >= 10000) + { + /* 4.1. Reset button_pressed_time */ + button_pressed_time = 0; + + /* 4.2. Erase the NVS storage */ + ESP_ERROR_CHECK(nvs_flash_erase()); + + /* 4.3. Reset the device (Software reset) */ + esp_restart(); + } + } + else + { + /* If USB is not connected then reset button_pressed_time to 0 */ + button_pressed_time = 0; + + /* and button_timing */ + g_enableButtonTiming = false; + } +} + +void data_task(void *pvParameters) +{ + batteryChargingState_t charging_state; + + for(;;) + { + /*Check the State of USB and battery (is the battery charging or fully charged) to set the corresponding LED event */ + charging_state = detect_if_usb_is_charging(); + + /* Check the state of ButtonTiming and USB */ + if(g_enableButtonTiming) + data_check_button_holding_time(); //If buttonTiming is enabled then start button_timing + + /* Check if the accelerometer isr_flag has been set by its isr_handler */ + if(isr_data.accel) + { + /* Log the state of the accelerometer INT1 pin*/ + ESP_LOGI(TAG, "ACCEL INT1 %s", (isr_data.accel == 2)?"HIGH":"LOW"); + + /* Was the accelerometer INT1 pin High ?*/ + if(isr_data.accel == 2) + { + /* Clear the interrupt flag*/ + i2c_clear_mc3419_int_flag(); + + /* Set the motion detection strobe*/ + if(ulp_ulp_triggersThatCanWakeTheHost & WAKE_HOST_ON_MOVEMENT_DETECTION) + { + ulp_ulp_strobedMotionFlags |= STROBED_MOTION_MOVEMENT_DETECTED; + + // Rise a trigger flag to do the check-in process before going to deep-sleep + wakeHostForStrobedTrigger2++; + + /* Check if the device-last cycle is completed and the device now is in pausing period*/ + if(isCycleCompleted) + { +#if (SENS_INT_WAKEUP == 0) + //set_sleep_mode(); + set_delay_sleep(); +#else + //set_periodic_sleep_mode(); + set_delay_sleep(); //If yes then ----> trigger the check-in process(set the sensorNeeded flag to enable sensor_task) +#endif + } + /* Reduce the accelerometer tokens by 1*/ + //if(esp_settings->accelerometerTokens) + //esp_settings->accelerometerTokens--; + } + } + /* Reset the isr flag */ + isr_data.accel = 0; + } + + /* Check if the VUSB isr_flag has been set by its isr_handler */ + if(isr_data.vusb) + { + /* Log the state of the USB */ + ESP_LOGI(TAG, "VUSB %s", (isr_data.vusb == 2)?"CONNECTED":"DISCONNECTED"); + + /* did the USB get connected ?*/ + if(isr_data.vusb == 2) + { + /* Update the previous state of USB*/ + g_prevUsbConnected = g_usbConnected; + + /* Set the new state of USB to be true (connected) */ + g_usbConnected = 1; + + /* Set the usb_connection_flag in HMI */ + hmi_set_usb_connection_state(true); + + /* Process the the current and previous states of USB if the power_mode is enabled */ + data_process_power_thresholds(); + + /* Check the state battery charging to set the corresponding LED-Event in the HMI */ + if(charging_state == BATTERY_CHARGING) + hmi_set_leds_state(BLUE_RED_LEDS_FLASHING_1SEC); + else if(charging_state == BATTERY_CHARGED) + hmi_set_leds_state(BLUE_RED_LEDS_SOLD); + + } /* did the USB get disconnected ?*/ + else if(isr_data.vusb == 1) + { + /* Update the previous state of USB*/ + g_prevUsbConnected = g_usbConnected; + + /* Set the new state of USB to be false (disconnected) */ + g_usbConnected = 0; + + /* Process the the current and previous states of USB if the power_mode is enabled */ + data_process_power_thresholds(); + + /* Reset the usb_connection_flag in HMI */ + hmi_set_usb_connection_state(false); + //hmi_set_leds_state(BLUE_RED_LEDS_OFF); + } + + /*Check if we should trigger check-in process when connecting and disconnecting USB*/ + if(ulp_ulp_triggersThatCanWakeTheHost & (WAKE_HOST_ON_SWITCH_FROM_BATTERY_TO_USB | WAKE_HOST_ON_SWITCH_FROM_USB_TO_BATTERY)) + { + /* Check if the device-last cycle is completed and the device now is in pausing period*/ + if(isCycleCompleted) + { +#if (SENS_INT_WAKEUP == 0) + //set_sleep_mode(); + set_delay_sleep(); +#else + //set_periodic_sleep_mode(); + set_delay_sleep(); //If yes then ----> trigger the check-in process(set the sensorNeeded flag to enable sensor_task) +#endif + } + } + isr_data.vusb = 0; + } + + if(isr_data.lowv == 2) + { + ESP_LOGI(TAG, "LOW VOLTAGE"); + isr_data.lowv = 0; + } + + /* Check if the PushButton isr_flag has been set by its isr_handler */ + if(isr_data.pushbtn) + { + /* did the pushbutton get pressed ?*/ + if(isr_data.pushbtn == 1) + { + /* Log the state of the button (pressed) */ + ESP_LOGI(TAG, "BUTTON PRESSED"); + + /* Enable Button_timing to start timing for button_pressed period*/ + g_enableButtonTiming = true; + + //update the strobe of the check_in and reduce pushbuttonTokens + ulp_ulp_strobedMiscFlags |= STROBED_MISC_CHECK_IN_REQUESTED; + + // Rise a trigger flag to do the check-in process before going to deep-sleep + wakeHostForStrobedTrigger2++; + /* if(esp_settings->pushbuttonTokens) + { + esp_settings->pushbuttonTokens--; + wakeHostForStrobedTrigger2++; + }*/ + + //only when button press enabled (checking device is on and working properly) + //port_blue_led_on(); + hmi_set_leds_state(BLUE_LED_SOLID); + + /* Check if the device-last cycle is completed and the device now is in pausing period*/ + if(isCycleCompleted) + { +#if (SENS_INT_WAKEUP == 0) + //set_sleep_mode(); + set_delay_sleep(); +#else + //set_periodic_sleep_mode(); + set_delay_sleep(); //If yes then ----> trigger the check-in process(set the sensorNeeded flag to enable sensor_task) +#endif + } + } + else if(isr_data.pushbtn == 2) + { + /**/ + } + isr_data.pushbtn = 0; + } + vTaskDelay(100 / portTICK_PERIOD_MS); + } + vTaskDelete(NULL); +} + +/***************** ***************Buffer Example (json format)****************************************/ +static uint32_t data_get_history_field_uint_values(uint8_t index, historyLog_field_t field) +{ + switch(field) + { + case HISTORY_TEMP_FIELD: break; + case HISTORY_HUMI_FIELD: break; + case HISTORY_THERM_FIELD: break; + case HISTORY_LIGHT_FIELD: return (uint32_t)_logs[index].logLight; + case HISTORY_TIME_FIELD: return (uint32_t)_logs[index].logCheckInTime; + case HISTORY_TRIG1_FIELD: return (uint32_t)_logs[index].logTriggerFlags1; + case HISTORY_TRIG2_FIELD: return (uint32_t)_logs[index].logTriggerFlags2; + case HISTORY_XAXIS_FIELD: return (uint32_t)_logs[index].logXaxis; + case HISTORY_YAXIS_FIELD: return (uint32_t)_logs[index].logYaxis; + case HISTORY_ZAXIS_FIELD: return (uint32_t)_logs[index].logZaxis; + case HISTORY_RSSI_FIELD: break; + case HISTORY_STAUS_FIELD: return (uint32_t)_logs[index].logStatusFlags; + case HISTORY_RECORD_FIELD: break; + } + return 0; +} +#if 0 +static int32_t data_get_history_field_int_values(uint8_t index, historyLog_field_t field) +{ + switch(field) + { + case HISTORY_TEMP_FIELD: break; + case HISTORY_HUMI_FIELD: break; + case HISTORY_THERM_FIELD: break; + case HISTORY_LIGHT_FIELD: break; + case HISTORY_TIME_FIELD: break; + case HISTORY_TRIG1_FIELD: break; + case HISTORY_TRIG2_FIELD: break; + case HISTORY_XAXIS_FIELD: return (int32_t)_logs[index].logXaxis; + case HISTORY_YAXIS_FIELD: return (int32_t)_logs[index].logYaxis; + case HISTORY_ZAXIS_FIELD: return (int32_t)_logs[index].logZaxis; + case HISTORY_RSSI_FIELD: return (int32_t)_logs[index].logRSSI; + case HISTORY_STAUS_FIELD: break; + case HISTORY_RECORD_FIELD: return (int32_t)_logs[index].logHistoryRecorded; + } + return 0; +} +#endif +static float data_get_history_field_float_values(uint8_t index, historyLog_field_t field) +{ + switch(field) + { + case HISTORY_TEMP_FIELD: return _logs[index].logTemp; + case HISTORY_HUMI_FIELD: return _logs[index].logHumidity; + case HISTORY_THERM_FIELD: return _logs[index].logThermocoupleTemp; + case HISTORY_LIGHT_FIELD: break; + case HISTORY_TIME_FIELD: break; + case HISTORY_TRIG1_FIELD: break; + case HISTORY_TRIG2_FIELD: break; + case HISTORY_XAXIS_FIELD: break; + case HISTORY_YAXIS_FIELD: break; + case HISTORY_ZAXIS_FIELD: break; + case HISTORY_RSSI_FIELD: break; + case HISTORY_STAUS_FIELD: break; + case HISTORY_RECORD_FIELD: break; + } + return 0; +} + +static size_t data_add_float_history_to_buf(char* buff, uint32_t len, size_t n, historyLog_field_t field, size_t size_of_written_sector_data) +{ + float target = 0; + bool history_included = false; + + /* Set the key of the requested field in the check-in JSON string */ + if(field == HISTORY_TEMP_FIELD) + n += snprintf(buff + n, len - n, ",\"tempC\":["); + else if(field == HISTORY_HUMI_FIELD) + n += snprintf(buff + n, len - n, ",\"humidity\":["); + else if(field == HISTORY_THERM_FIELD) + n += snprintf(buff + n, len - n, ",\"TcTemp\":["); + + /* make sure that the size of written data in the nvs-sector is more than 0 (make sure that there are some data) */ + if(size_of_written_sector_data) + { + /* Include all the values for the requested field in the check-in JSON string */ + for (uint8_t x = 0; x < NVM_MAX_NUMBER_OF_IN_ONE_SECTOR; x++) + { + if(_logs[x].logHistoryRecorded) + { + /* Get the value of the field "field" and index "x" and store it in the variable "target" */ + target = data_get_history_field_float_values(x,field); + + /* Check if the index is the first index */ + if(x == 0) + n += snprintf(buff + n, len - n, "%0.2f",target); + else + n += snprintf(buff + n, len - n, ",%0.2f",target); + + /**/ + history_included = true; + + } + } + } + + /* get the current data of that field */ + if(field == HISTORY_TEMP_FIELD) + target = get_temperature_data(); + else if(field == HISTORY_HUMI_FIELD) + target = get_humidity_data(); + else if(field == HISTORY_THERM_FIELD) + target = get_thermocouple_data(); + + /* Check if need to append the current sensor reading */ + if((number_of_check_in_to_do - checkin_cycle_counter) == 1) + { + /* Check whether we are posting the current readings only or history¤t readings ? */ + if(history_included) + { + n += snprintf(buff + n, len - n, ",%0.2f]", target); + } + else + { + n += snprintf(buff + n, len - n, "%0.2f]", target); + } + } + else + { + n += snprintf(buff + n, len - n, "]"); + } + + vTaskDelay(1/portTICK_PERIOD_MS); + + return n; +} + +static size_t data_add_uint_history_to_buf(char* buff, uint32_t len, size_t n, historyLog_field_t field, size_t size_of_written_sector_data) +{ + uint32_t target = 0; + bool history_included = false; + + /* Set the key of the requested field in the check-in JSON string */ + if(field == HISTORY_LIGHT_FIELD) + n += snprintf(buff + n, len - n, ",\"LT_STATE\":["); + else if(field == HISTORY_TRIG1_FIELD) + n += snprintf(buff + n, len - n, ",\"TRIG1\":["); + else if(field == HISTORY_TRIG2_FIELD) + n += snprintf(buff + n, len - n, ",\"TRIG2\":["); + else if(field == HISTORY_STAUS_FIELD) + n += snprintf(buff + n, len - n, ",\"PWR_STATE\":["); + else if(field == HISTORY_TIME_FIELD) + n += snprintf(buff + n, len - n, ",\"server_time\":["); + else if(field == HISTORY_XAXIS_FIELD) + n += snprintf(buff + n, len - n, ",\"ACC_X_STATE\":["); + else if(field == HISTORY_YAXIS_FIELD) + n += snprintf(buff + n, len - n, ",\"ACC_Y_STATE\":["); + else if(field == HISTORY_ZAXIS_FIELD) + n += snprintf(buff + n, len - n, ",\"ACC_Z_STATE\":["); + + /* make sure that the size of written data in the nvs-sector is more than 0 (make sure that there are some data) */ + if(size_of_written_sector_data) + { + /* Include all the values for the requested field in the check-in JSON string */ + for (uint8_t x = 0; x < NVM_MAX_NUMBER_OF_IN_ONE_SECTOR; x++) + { + if(_logs[x].logHistoryRecorded) + { + /* Get the value of the field "field" and index "x" and store it in the variable "target" */ + target = data_get_history_field_uint_values(x,field); + + /* Check if the index is the first index */ + if(x == 0) + n += snprintf(buff + n, len - n, "%ld",target); + else + n += snprintf(buff + n, len - n, ",%ld",target); + + /**/ + history_included = true; + + } + } + } + + /* get the current data of that field */ + if(field == HISTORY_LIGHT_FIELD) + target = ((get_light_data() > esp_settings->lightSensorLevel)?1:0); + else if(field == HISTORY_TRIG1_FIELD) + target = g_triggerFlags1 ; + else if(field == HISTORY_TRIG2_FIELD) + target = g_triggerFlags2 ; + else if(field == HISTORY_STAUS_FIELD) + target = (1 & (!g_usbConnected)); + else if(field == HISTORY_XAXIS_FIELD) + target = get_accel_x(); + else if(field == HISTORY_YAXIS_FIELD) + target = get_accel_y(); + else if(field == HISTORY_ZAXIS_FIELD) + target = get_accel_z(); + else if(field == HISTORY_TIME_FIELD) + { + target = g_wakeUpTime; + } + + /* Check if need to append the current sensor reading */ + if((number_of_check_in_to_do - checkin_cycle_counter) == 1) + { + /* Check whether we are posting the current readings only or history¤t readings ? */ + if(history_included) + { + n += snprintf(buff + n, len - n, ",%ld]", target); + } + else + { + n += snprintf(buff + n, len - n, "%ld]", target); + } + } + else + { + n += snprintf(buff + n, len - n, "]"); + } + + vTaskDelay(1/portTICK_PERIOD_MS); + + return n; +} +#if 0 +static size_t data_add_rssi_history_to_buf(char* buff, uint32_t len, size_t n, size_t size_of_written_sector_data) +{ + int32_t target = 0; + bool history_included = false; + + /* Set the key of the requested field in the check-in JSON string */ + n += snprintf(buff + n, len - n, ",\"RSSI\":["); + + /* make sure that the size of written data in the nvs-sector is more than 0 (make sure that there are some data) */ + if(size_of_written_sector_data) + { + /* Include all the values for the requested field in the check-in JSON string */ + for (uint8_t x = 0; x < NVM_MAX_NUMBER_OF_IN_ONE_SECTOR; x++) + { + if(_logs[x].logHistoryRecorded) + { + /* Get the value of the field "field" and index "x" and store it in the variable "target" */ + target = _logs[x].logRSSI; + + /* Check if the index is the first index */ + if(x == 0) + n += snprintf(buff + n, len - n, "%ld",target); + else + n += snprintf(buff + n, len - n, ",%ld",target); + + /**/ + history_included = true; + + } + } + } + + /* get the current data of that field */ + target = ((wifi_station_connected())? data_get_wifi_rssi() : modem_Rssi()); + + /* Check if need to append the current sensor reading */ + if((number_of_check_in_to_do - checkin_cycle_counter) == 1) + { + /* Check whether we are posting the current readings only or history¤t readings ? */ + if(history_included) + { + n += snprintf(buff + n, len - n, ",%ld]", target); + } + else + { + n += snprintf(buff + n, len - n, "%ld]", target); + } + } + else + { + n += snprintf(buff + n, len - n, "]"); + } + + vTaskDelay(1/portTICK_PERIOD_MS); + return n; +} + + +static size_t data_add_time_history_to_buf(char* buff, uint32_t len, size_t n, size_t size_of_written_sector_data) +{ + time_t target = 0; + bool history_included = false; + + /* Set the key of the requested field in the check-in JSON string */ + n += snprintf(buff + n, len - n, ",\"server_time\":["); + + /* make sure that the size of written data in the nvs-sector is more than 0 (make sure that there are some data) */ + if(size_of_written_sector_data) + { + /* Include all the values for the requested field in the check-in JSON string */ + for (uint8_t x = 0; x < NVM_MAX_NUMBER_OF_IN_ONE_SECTOR; x++) + { + if(_logs[x].logHistoryRecorded) + { + /* Get the value of the field "field" and index "x" and store it in the variable "target" */ + target = _logs[x].logCheckInTime; + + /* Check if the index is the first index */ + if(x == 0) + n += snprintf(buff + n, len - n, "%llu",target); + else + n += snprintf(buff + n, len - n, ",%llu",target); + + /**/ + history_included = true; + + } + } + } + + /* get the current data of that field */ + time(&g_wakeUpTime); + + /* Check if need to append the current sensor reading */ + if((number_of_check_in_to_do - checkin_cycle_counter) == 1) + { + /* Check whether we are posting the current readings only or history¤t readings ? */ + if(history_included) + { + n += snprintf(buff + n, len - n, ",%llu]", g_wakeUpTime); + } + else + { + n += snprintf(buff + n, len - n, "%llu]", g_wakeUpTime); + } + } + else + { + n += snprintf(buff + n, len - n, "]"); + } + + vTaskDelay(1/portTICK_PERIOD_MS); + return n; +} +#endif +/**old message format + * {"id":2765778,"mac_addr":"D2:33:2A:BF:71:3C","attempt":1, + * "tempC":[22.52],"humidity":[37.50],"server_time":[1674766545], + * "wifi_connect_time":[1],"RSSI":[-57],"LT_STATE":[0],"PWR_STATE":[0], + * "TRIG1":[0],"TRIG2":[0],"vcc":3.40,"version":2001,"tmpThA_GP":71.11, + * "tmpThA_GN":70.00,"tmpThB_GP":71.11,"tmpThB_GN":70.00,"tmpThC_GP":71.11, + * "tmpThC_GN":70.00,"tmpThD_GP":-44.44,"tmpThD_GN":-45.56,"tmpThE_GP":-44.44, + * "tmpThE_GN":-45.56,"tmpThF_GP":-44.44,"tmpThF_GN":-45.56,"humThA_GP":103.00, + * "humThA_GN":101.00,"humThB_GP":103.00,"humThB_GN":101.00,"humThC_GP":103.00, + * "humThC_GN":101.00,"humThD_GP":-1.00,"humThD_GN":-3.00,"humThE_GP":-1.00, + * "humThE_GN":-3.00,"humThF_GP":-1.00,"humThF_GN":-3.00,"tcThA_GP":71.11, + * "tcThA_GN":70.00,"tcThB_GP":71.11,"tcThB_GN":70.00,"tcThC_GP":71.11, + * "tcThC_GN":70.00,"tcThD_GP":-168.33,"tcThD_GN":-169.44,"tcThE_GP":-168.33, + * "tcThE_GN":-169.44,"tcThF_GP":-168.33,"tcThF_GN":-169.44,"sendSecs":900, + * "postURLMax":3,"urlconnect":"testdevice.tempstickapi.com"} + * + * */ + + +/*new message format*/ +/*{"id":"TS00123456","mac_addr":"BC:3C:86:A3:C9:C8","attempt":1,"tempC":[17.94], + * "humidity":[33.70],"server_time":[2],"wifi_connect_time":[4],"RSSI":[-65], + * "TRIG1":[0],"TRIG2":[128],"w":1,"vcc":3.21,"version":2004,"cVersion":2002, + * "maxTemp":201.00,"minTemp":-100.00,"maxHum":101.00,"minHum":-1.00,"maxTcTemp":201.00, + * "minTcTemp":-100.00,"maxProbeTemp":201.00,"minProbeTemp":-100.00,"lightTh":129, + * "acclTh":80,"alertSecs":300,"sendSecs":300,"postURLMax":0,"urlconnect":"v2.idealsciences2.com"}*/ +void data_create_checkin_string(char *buff, size_t len) +{ + uint32_t chipId = 0; + char chipIdHex[8]; + uint8_t mac_base[6] = {0}; + char mac_str[20]; + size_t n = 0; + size_t size_of_written_sector_data = 0; + uint8_t sector_to_read_from = nvm_get_last_posted_history_sector() + 1; + + /**/ + data_show_history(sector_to_read_from, false, &size_of_written_sector_data); + + esp_efuse_mac_get_default(mac_base); + esp_read_mac(mac_base, ESP_MAC_WIFI_STA); + + sprintf(chipIdHex, "%02X%02X%02X", mac_base[5], mac_base[4], mac_base[3]); + chipId = (uint32_t)strtol(chipIdHex, NULL, 16); + + sprintf(mac_str, "%02X:%02X:%02X:%02X:%02X:%02X", mac_base[0], mac_base[1], mac_base[2], mac_base[3], mac_base[4], mac_base[5]); + + strcpy(buff, ""); + + //ID + n = snprintf(buff, len, "{\"id\":%ld", chipId); // {"id":2765778, + + //MAC ID + n += snprintf(buff + n, len - n, ",\"mac_addr\":\"%s\"", mac_str); //"mac_addr":"D2:33:2A:BF:71:3C" + + //IMEI + n += snprintf(buff + n, len - n, ",\"IMEI\":\"%s\"", modem_get_imei()); //"IMEI":"866349048889004" + + //ICCID + n += snprintf(buff + n, len - n, ",\"SIM number\":\"%s\"", modem_get_iccid()); //"SIM number":"8901240205100030994" + + //Attempt + n += snprintf(buff + n, len - n, ",\"attempt\":%d", checkInAttemptNumber);//,"attempt":1 + + //Temperature Sensor + if(isTempPresent) + { + //n += snprintf(buff + n, len - n, ",\"tempC\":[%f]", get_temperature_data()); // ,"tempC":[22.52] + n = data_add_float_history_to_buf(buff,len,n,HISTORY_TEMP_FIELD,size_of_written_sector_data); //1 + + //n += snprintf(buff + n, len - n, ",\"humidity\":[%f]", get_humidity_data()); // ,"humidity":[37.50] + n = data_add_float_history_to_buf(buff,len,n,HISTORY_HUMI_FIELD,size_of_written_sector_data); //2 + } +#if 1 + //Thermocouple Sensor + if(isThermocouplePresent) + { + //n += snprintf(buff + n, len - n, ",\"TcTemp\":[%f]", get_thermocouple_data()); + n = data_add_float_history_to_buf(buff,len,n,HISTORY_THERM_FIELD,size_of_written_sector_data); //3 + } + + //Accelerometer Sensor + if(isAccelPresent) + { + /*n += snprintf(buff + n, len - n, ",\"ACC_X_STATE\":[%d]", get_accel_x()); + n += snprintf(buff + n, len - n, ",\"ACC_Y_STATE\":[%d]", get_accel_y()); + n += snprintf(buff + n, len - n, ",\"ACC_Z_STATE\":[%d]", get_accel_z());*/ + n = data_add_uint_history_to_buf(buff,len,n,HISTORY_XAXIS_FIELD,size_of_written_sector_data); //4 + n = data_add_uint_history_to_buf(buff,len,n,HISTORY_YAXIS_FIELD,size_of_written_sector_data); //5 + n = data_add_uint_history_to_buf(buff,len,n,HISTORY_ZAXIS_FIELD,size_of_written_sector_data); //6 + } + + //Light Sensor State + //n += snprintf(buff + n, len - n, ",\"LT_STATE\":[%d]", (light_mv > 800)?1:0);// ,"LT_STATE":[0] + n = data_add_uint_history_to_buf(buff,len,n,HISTORY_LIGHT_FIELD,size_of_written_sector_data); //7 + + //Power State + //n += snprintf(buff + n, len - n, ",\"PWR_STATE\":[%d]", 1 & (!g_usbConnected));// ,"PWR_STATE":[0] + n = data_add_uint_history_to_buf(buff,len,n,HISTORY_STAUS_FIELD,size_of_written_sector_data); //8 + +#endif + + + //Server time + //time_t timeNow; + //time(&g_wakeUpTime); + //n += snprintf(buff + n, len - n, ",\"server_time\":[%llu]", g_wakeUpTime);// ,"server_time":[1674766545] + //n = data_add_time_history_to_buf(buff,len,n,size_of_written_sector_data); //9 + n = data_add_uint_history_to_buf(buff,len,n,HISTORY_TIME_FIELD,size_of_written_sector_data); //9 + + // Comms medium + if(comms_medium == COMMS_MEDIUM_CELL) + n += snprintf(buff + n, len - n, ",\"comms_medium\":\"LTE\""); + else + { + // wifi connect time + n += snprintf(buff + n, len - n, ",\"wifi_connect_time\":[%ld]",g_wifiConnectTime);// ,"wifi_connect_time":[1] + // Comms medium + n += snprintf(buff + n, len - n, ",\"comms_medium\":\"WIFI\""); + } + + // Comms mode + n += snprintf(buff + n, len - n, ",\"comms_mode\":[%d]",comms_mode); + + //RSSI + n += snprintf(buff + n, len - n, ",\"RSSI\":[%ld]", ((wifi_station_connected())? data_get_wifi_rssi() : modem_Rssi())); + //n = data_add_rssi_history_to_buf(buff,len,n,size_of_written_sector_data); //10 + + // trigger 1 value + //n += snprintf(buff + n, len - n, ",\"TRIG1\":[%ld]", g_triggerFlags1);// ,"TRIG1":[0] + n = data_add_uint_history_to_buf(buff,len,n,HISTORY_TRIG1_FIELD,size_of_written_sector_data); //11 + + // trigger 2 value + //n += snprintf(buff + n, len - n, ",\"TRIG2\":[%ld]", g_triggerFlags2);// ,"TRIG1":[0] + n = data_add_uint_history_to_buf(buff,len,n,HISTORY_TRIG2_FIELD,size_of_written_sector_data); //12 + + //w + //n += snprintf(buff + n, len - n, ",\"TcTemp\":[%f]", get_thermocouple_data()); + + //Battery Voltage + n += snprintf(buff + n, len - n, ",\"vcc\":%0.2f", g_voltage);// ,"vcc":3.40 + + //Firmware Version + n += snprintf(buff + n, len - n, ",\"version\":%ld", g_version); // ,"version":2004 +// n += snprintf(buff + n, len - n, ",\"cVersion\":%ld", ); // ,"cVersion":2002 + + //TempHumi_mode & maxTemp & minTemp + n += snprintf(buff + n, len - n, ",\"tempC_mode\":1"); + n += snprintf(buff + n, len - n, ",\"maxTemp\":%0.2f", esp_settings->maxTemp); // ,"maxTemp":201 + n += snprintf(buff + n, len - n, ",\"minTemp\":%0.2f", esp_settings->minTemp ); //,"minTemp":-100 + + + //maxHum & minHum & humidity_mode + n += snprintf(buff + n, len - n, ",\"humidity_mode\":1"); + n += snprintf(buff + n, len - n, ",\"maxHum\":%ld", esp_settings->maxHum); // ,"maxHum":101 + n += snprintf(buff + n, len - n, ",\"minHum\":%ld", esp_settings->minHum ); //,"minHum":-1 + + + //maxTcTemp & minTcTemp & TcTemp_mode + n += snprintf(buff + n, len - n, ",\"TcTemp_mode\":%d",esp_settings->thermocoupleMode); + n += snprintf(buff + n, len - n, ",\"maxTcTemp\":%0.2f", esp_settings->maxTcTemp); // ,"maxTcTemp":201 + n += snprintf(buff + n, len - n, ",\"minTcTemp\":%0.2f", esp_settings->minTcTemp ); //,"minTcTemp":-100 + + //maxProbeTemp & minProbeTemp + n += snprintf(buff + n, len - n, ",\"maxProbeTemp\":%0.2f", esp_settings->maxProbeTemp); // ,"maxProbeTemp":201 + n += snprintf(buff + n, len - n, ",\"minProbeTemp\":%0.2f", esp_settings->minProbeTemp ); //,"minProbeTemp":-100 + + //acclTh & accl_mode + n += snprintf(buff + n, len - n, ",\"accl_mode\":%d",esp_settings->accelerometerMode); + n += snprintf(buff + n, len - n, ",\"acclTh\":%d", esp_settings->accelerometerLevel ); //,"acclTh":-100 + + //lightTh & light_mode + n += snprintf(buff + n, len - n, ",\"light_mode\":%d",esp_settings->lightSensorMode); + n += snprintf(buff + n, len - n, ",\"lightTh\":%d", esp_settings->lightSensorLevel ); //,"lightTh":-100 + + //powerMonitor_mode + n += snprintf(buff + n, len - n, ",\"powerMonitor_mode\":%d",esp_settings->powerMonitorMode); + + //alert Interval + n += snprintf(buff + n, len - n, ",\"alertSecs\":%ld", esp_settings->alertInterval); // ,"alertInterval":300 + + //send Interval + n += snprintf(buff + n, len - n, ",\"sendSecs\":%ld", esp_settings->sendInterval); // ,"sendSecs":900 + + //POST URL Max + n += snprintf(buff + n, len - n, ",\"postURLMax\":%ld",esp_settings->postURLMax); // ,"postURLMax":3 + + //POST URL Max + data_set_urlConnect(); +#if (TEMPSTICK_SERVER == 1) + n += snprintf(buff + n, len - n, ",\"urlconnect\":\"%s\"",(char*)(&urlConnect[8])); //,"urlconnect":"testdevice.tempstickapi.com" +#else + n += snprintf(buff + n, len - n, ",\"urlconnect\":\"%s\"",(char*)(&urlConnect[7])); //,"urlconnect":"testdevice.tempstickapi.com" +#endif + //Closure + strcat(buff, "}"); +} + + + +void data_update_trigger_flags(void) +{ + /*Reset the trigger variables before setting the new flags*/ + g_triggerFlags1 = 0; + g_triggerFlags2 = 0; + + /* Setting the bits of TRIGGER_1 variable */ + if(ulp_ulp_strobedTemperatureFlags & STROBED_SENSOR_MEASUREMENT_EXCEEDED_UPPER_THRESHOLD) g_triggerFlags1 |= STROBED_TEMPERATURE_MEASUREMENT_EXCEEDED_UPPER_THRESHOLD; + if(ulp_ulp_strobedTemperatureFlags & STROBED_SENSOR_MEASUREMENT_FELL_BELOW_LOWER_THRESHOLD) g_triggerFlags1 |= STROBED_TEMPERATURE_MEASUREMENT_FELL_BELOW_LOWER_THRESHOLD; + if(ulp_ulp_strobedHumidityFlags & STROBED_SENSOR_MEASUREMENT_EXCEEDED_UPPER_THRESHOLD) g_triggerFlags1 |= STROBED_HUMIDITY_MEASUREMENT_EXCEEDED_UPPER_THRESHOLD; + if(ulp_ulp_strobedHumidityFlags & STROBED_SENSOR_MEASUREMENT_FELL_BELOW_LOWER_THRESHOLD) g_triggerFlags1 |= STROBED_HUMIDITY_MEASUREMENT_FELL_BELOW_LOWER_THRESHOLD; + if(ulp_ulp_strobedThermocoupleFlags & STROBED_SENSOR_MEASUREMENT_EXCEEDED_UPPER_THRESHOLD) g_triggerFlags1 |= STROBED_THERMOCOUPLE_MEASUREMENT_EXCEEDED_UPPER_THRESHOLD; + if(ulp_ulp_strobedThermocoupleFlags & STROBED_SENSOR_MEASUREMENT_FELL_BELOW_LOWER_THRESHOLD) g_triggerFlags1 |= STROBED_THERMOCOUPLE_MEASUREMENT_FELL_BELOW_LOWER_THRESHOLD; + /*if(ulp_ulp_strobedDigitalTempProbes & STROBED_SENSOR_MEASUREMENT_EXCEEDED_UPPER_THRESHOLD) g_triggerFlags1 |= STROBED_EXTERNAL_TEMP_PROBE_MEASUREMENT_EXCEEDED_UPPER_THRESHOLD; + if(ulp_ulp_strobedDigitalTempProbes & STROBED_SENSOR_MEASUREMENT_FELL_BELOW_LOWER_THRESHOLD) g_triggerFlags1 |= STROBED_EXTERNAL_TEMP_PROBE_MEASUREMENT_FELL_BELOW_LOWER_THRESHOLD; */ + if(ulp_ulp_strobedMiscFlags & STROBED_MISC_DEVICE_OPERATE_IN_ALERT_MODE) g_triggerFlags1 |= STROBED_DEVICE_OPERATE_IN_ALERT_MODE; + + /* Setting the bits of TRIGGER_2 variable */ + if(ulp_ulp_strobedMiscFlags & STROBED_MISC_REGULAR_SCHEDULED_CHECK_IN) g_triggerFlags2 |= STROBED_REGULAR_SCHEDULED_SENDINTERVAL_CHECKIN; + if(ulp_ulp_strobedMiscFlags & STROBED_MISC_CHANGE_FROM_BATTERY_TO_USB) g_triggerFlags2 |= STROBED_POWER_CHANGE_FROM_BATTERY_TO_USB; + if(ulp_ulp_strobedMiscFlags & STROBED_MISC_CHANGE_FROM_USB_TO_BATTERY) g_triggerFlags2 |= STROBED_POWER_CHANGE_FROM_USB_TO_BATTERY; + if(ulp_ulp_strobedMotionFlags & STROBED_MOTION_MOVEMENT_DETECTED) g_triggerFlags2 |= STROBED_MOTION_MOVEMENT_WAS_DETECTED; + if(ulp_ulp_strobedMiscFlags & STROBED_MISC_CHANGE_FROM_LIGHT_TO_DARK) g_triggerFlags2 |= STROBED_LIGHT_TRANSITION_FROM_LIGHT_TO_DARK; + if(ulp_ulp_strobedMiscFlags & STROBED_MISC_CHANGE_FROM_DARK_TO_LIGHT) g_triggerFlags2 |= STROBED_LIGHT_TRANSITION_FROM_DARK_TO_LIGHT; + if(ulp_ulp_strobedMiscFlags & STROBED_MISC_CHECK_IN_REQ_AFTER_POWER_ON) g_triggerFlags2 |= STROBED_CHECK_IN_REQUESTED_AFTER_POWER_ON; + if(ulp_ulp_strobedMiscFlags & STROBED_MISC_CHECK_IN_REQUESTED) g_triggerFlags2 |= STROBED_BUTTON_CHECK_IN_REQUESTED; // Pushbutton. + + + data_clear_sensor_strobes(0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF); //Clear all strobed_flags for the next cycle + + ESP_LOGI(TAG,"g_tiggerFlags1 and g_tiggerFlags1 have been updated successfully"); + ESP_LOGI(TAG,"g_triggerFlags1 = 0x%X (hex)",(unsigned int)g_triggerFlags1); + ESP_LOGI(TAG,"g_triggerFlags2 = 0x%X (hex)",(unsigned int)g_triggerFlags2); +} + +void data_parse_http_response(const char *http_resp) +{ + /*1- parse limits from the response*/ + data_parse_limits(http_resp); + + /*2- parse intervals from the response*/ + data_parse_intervals(http_resp); + + /*3- parse intervals from the response*/ + data_parse_dynamicVariables(http_resp); + + /*4- parse temperature from the response*/ + data_parse_temperature(http_resp); + + /*5- parse humidity from the response*/ + data_parse_humidity(http_resp); + + /*6- parse thermocouple from the response*/ + data_parse_thermocouple(http_resp); + + /*7- parse lightSensor from the response*/ + data_parse_lightSensor(http_resp); + + /*8- parse accelerometer from the response*/ + data_parse_accelerometer(http_resp); + + /*9- parse power from the response*/ + data_parse_power(http_resp); + + /*10- parse pushbuttons from the response*/ + data_parse_pushbutton(http_resp); +} + +void data_processSensorModes(sensorType_t sensor) +{ + uint16_t tempFlags16; + + tempFlags16 = 0; + + switch(sensor) + { + case TEMPERATURE_SENSOR: + break; + + case HUMIDITY_SENSOR: + break; + + case THERMOCOUPLE_SENSOR: + if(isThermocouplePresent) + { + switch(esp_settings->thermocoupleMode) + { + case 0: + ulp_ulp_triggersThatCanWakeTheHost &= ~WAKE_HOST_WHEN_THERMOCOUPLE_CROSSES_LIMITS; // Disable thermocouple interrupt triggers + //tempFlags16 |= ( STROBED_SENSOR_MEASUREMENT_EXCEEDED_THRESHOLD_A | STROBED_SENSOR_MEASUREMENT_RETURNED_FROM_ABOVE_THRESHOLD_A | STROBED_SENSOR_MEASUREMENT_EXCEEDED_THRESHOLD_B | STROBED_SENSOR_MEASUREMENT_RETURNED_FROM_ABOVE_THRESHOLD_B | STROBED_SENSOR_MEASUREMENT_EXCEEDED_THRESHOLD_C | STROBED_SENSOR_MEASUREMENT_RETURNED_FROM_ABOVE_THRESHOLD_C | STROBED_SENSOR_MEASUREMENT_FELL_BELOW_THRESHOLD_D | STROBED_SENSOR_MEASUREMENT_RETURNED_FROM_BELOW_THRESHOLD_D | STROBED_SENSOR_MEASUREMENT_FELL_BELOW_THRESHOLD_E | STROBED_SENSOR_MEASUREMENT_RETURNED_FROM_BELOW_THRESHOLD_E | STROBED_SENSOR_MEASUREMENT_FELL_BELOW_THRESHOLD_F | STROBED_SENSOR_MEASUREMENT_RETURNED_FROM_BELOW_THRESHOLD_F ); + tempFlags16 |= ( STROBED_SENSOR_MEASUREMENT_EXCEEDED_UPPER_THRESHOLD | STROBED_SENSOR_MEASUREMENT_FELL_BELOW_LOWER_THRESHOLD); + break; + + case 1: + ulp_ulp_triggersThatCanWakeTheHost |= WAKE_HOST_WHEN_THERMOCOUPLE_CROSSES_LIMITS; // Enable thermocouple interrupt triggers + break; + + default: + ulp_ulp_triggersThatCanWakeTheHost &= ~WAKE_HOST_WHEN_THERMOCOUPLE_CROSSES_LIMITS; // Disable thermocouple interrupt triggers + //tempFlags16 |= ( STROBED_SENSOR_MEASUREMENT_EXCEEDED_THRESHOLD_A | STROBED_SENSOR_MEASUREMENT_RETURNED_FROM_ABOVE_THRESHOLD_A | STROBED_SENSOR_MEASUREMENT_EXCEEDED_THRESHOLD_B | STROBED_SENSOR_MEASUREMENT_RETURNED_FROM_ABOVE_THRESHOLD_B | STROBED_SENSOR_MEASUREMENT_EXCEEDED_THRESHOLD_C | STROBED_SENSOR_MEASUREMENT_RETURNED_FROM_ABOVE_THRESHOLD_C | STROBED_SENSOR_MEASUREMENT_FELL_BELOW_THRESHOLD_D | STROBED_SENSOR_MEASUREMENT_RETURNED_FROM_BELOW_THRESHOLD_D | STROBED_SENSOR_MEASUREMENT_FELL_BELOW_THRESHOLD_E | STROBED_SENSOR_MEASUREMENT_RETURNED_FROM_BELOW_THRESHOLD_E | STROBED_SENSOR_MEASUREMENT_FELL_BELOW_THRESHOLD_F | STROBED_SENSOR_MEASUREMENT_RETURNED_FROM_BELOW_THRESHOLD_F ); + tempFlags16 |= ( STROBED_SENSOR_MEASUREMENT_EXCEEDED_UPPER_THRESHOLD | STROBED_SENSOR_MEASUREMENT_FELL_BELOW_LOWER_THRESHOLD); + break; + } + data_clear_sensor_strobes(0,0,tempFlags16,0,0); + } + break; + + case LIGHT_SENSOR: + + /* 1- Check the first bit of lightSensorMode */ + if(esp_settings->lightSensorMode & 0x01) + { + ulp_ulp_triggersThatCanWakeTheHost |= WAKE_HOST_ON_LIGHT_TO_DARK; // Enable light-to-dark + tempFlags16 |= STROBED_MISC_CHANGE_FROM_LIGHT_TO_DARK; + } + else + { + ulp_ulp_triggersThatCanWakeTheHost &= ~WAKE_HOST_ON_LIGHT_TO_DARK; // Disable light-to-dark + tempFlags16 |= STROBED_MISC_CHANGE_FROM_LIGHT_TO_DARK; + } + + /* 2- Check the second bit of lightSensorMode */ + if(esp_settings->lightSensorMode & 0x02) + { + ulp_ulp_triggersThatCanWakeTheHost |= WAKE_HOST_ON_DARK_TO_LIGHT; // Enable dark-to-light + tempFlags16 |= STROBED_MISC_CHANGE_FROM_DARK_TO_LIGHT; + } + else + { + ulp_ulp_triggersThatCanWakeTheHost &= ~WAKE_HOST_ON_DARK_TO_LIGHT; // Disable dark-to-light + tempFlags16 |= STROBED_MISC_CHANGE_FROM_DARK_TO_LIGHT; + } + + /* This if block should be removed because if any of the first two bits were 1 then both condition will be set */ + if(esp_settings->lightSensorMode & 0x03) + { + ulp_ulp_triggersThatCanWakeTheHost |= WAKE_HOST_ON_LIGHT_TO_DARK; // Enable light-to-dark + ulp_ulp_triggersThatCanWakeTheHost |= WAKE_HOST_ON_DARK_TO_LIGHT; // Enable dark-to-light + + tempFlags16 |= STROBED_MISC_CHANGE_FROM_LIGHT_TO_DARK; + tempFlags16 |= STROBED_MISC_CHANGE_FROM_DARK_TO_LIGHT; + } + + data_clear_sensor_strobes(0,0,0,0,tempFlags16); + + break; + + case ACCELEROMETER_SENSOR: + if(isAccelPresent) + { + setAccelerometerPowerState(); // Change state before clearing the interrupt flags. + + switch(esp_settings->accelerometerMode) + { + case 0: // Accelerometer triggers disabled. + ulp_ulp_triggersThatCanWakeTheHost &= ~WAKE_HOST_ON_MOVEMENT_DETECTION; + tempFlags16 |= STROBED_MOTION_MOVEMENT_DETECTED; + break; + + case 1: // "Bumping" motion triggers a check-in. + ulp_ulp_triggersThatCanWakeTheHost |= WAKE_HOST_ON_MOVEMENT_DETECTION; + break; + + default: // Accelerometer triggers disabled. + ulp_ulp_triggersThatCanWakeTheHost &= ~WAKE_HOST_ON_MOVEMENT_DETECTION; + tempFlags16 |= STROBED_MOTION_MOVEMENT_DETECTED; + break; + } + + i2c_clear_mc3419_int_flag(); + data_clear_sensor_strobes(0,0,0,tempFlags16,0); + } + break; + + case POWER_MONITOR_SENSOR: + + /* 1- Check the first bit of powerMonitorMode */ + if(esp_settings->powerMonitorMode & 0x01) + { + ulp_ulp_triggersThatCanWakeTheHost |= WAKE_HOST_ON_SWITCH_FROM_BATTERY_TO_USB; // Enable battery-to-usb triggering + tempFlags16 |= STROBED_MISC_CHANGE_FROM_BATTERY_TO_USB; + } + else + { + ulp_ulp_triggersThatCanWakeTheHost &= ~WAKE_HOST_ON_SWITCH_FROM_BATTERY_TO_USB; // Disable battery-to-usb triggering + tempFlags16 |= STROBED_MISC_CHANGE_FROM_BATTERY_TO_USB; + } + + /* 2- Check the second bit of powerMonitorMode */ + if(esp_settings->powerMonitorMode & 0x02) + { + ulp_ulp_triggersThatCanWakeTheHost |= WAKE_HOST_ON_SWITCH_FROM_USB_TO_BATTERY; // Enable usb-to-battery triggering + tempFlags16 |= STROBED_MISC_CHANGE_FROM_USB_TO_BATTERY; + } + else + { + ulp_ulp_triggersThatCanWakeTheHost &= ~WAKE_HOST_ON_SWITCH_FROM_USB_TO_BATTERY; // Disable usb-to-battery triggering + tempFlags16 |= STROBED_MISC_CHANGE_FROM_USB_TO_BATTERY; + } + + /* This if block should be removed because if any of the first two bits were 1 then both condition will be set */ + if(esp_settings->powerMonitorMode & 0x03) + { + ulp_ulp_triggersThatCanWakeTheHost |= WAKE_HOST_ON_SWITCH_FROM_BATTERY_TO_USB; + ulp_ulp_triggersThatCanWakeTheHost |= WAKE_HOST_ON_SWITCH_FROM_USB_TO_BATTERY; + + tempFlags16 |= STROBED_MISC_CHANGE_FROM_BATTERY_TO_USB; + tempFlags16 |= STROBED_MISC_CHANGE_FROM_USB_TO_BATTERY; + } + + data_clear_sensor_strobes(0,0,0,0,tempFlags16); + + break; + } +} + +uint8_t data_process_tempHumi_thresholds(float raw_data, float prev_raw_data, sensorType_t sensor) +{ + //uint8_t enable_thsProcess = 1; + uint8_t useTokens = 0; + uint8_t wakeHostForStrobedTrigger = 0; + + //uint8_t *tokenregister = NULL; + + switch(sensor) + { + case LIGHT_SENSOR: + break; + + case ACCELEROMETER_SENSOR: + break; + + case POWER_MONITOR_SENSOR: + break; + + case TEMPERATURE_SENSOR: + + /* Set the tokens register to be ThermoCouple token-registers */ + //tokenregister = &(esp_settings->temperatureTokens); + + /* Process thresholds for ENS210-TempData*/ + if((raw_data > esp_settings->maxTemp) && (prev_raw_data < esp_settings->maxTemp)) + { + (ulp_ulp_strobedTemperatureFlags) |= STROBED_SENSOR_MEASUREMENT_EXCEEDED_UPPER_THRESHOLD; + useTokens = 1; + } + else if((raw_data < esp_settings->minTemp) && (prev_raw_data > esp_settings->minTemp)) + { + (ulp_ulp_strobedTemperatureFlags) |= STROBED_SENSOR_MEASUREMENT_FELL_BELOW_LOWER_THRESHOLD; + useTokens = 1; + } + + break; + + case HUMIDITY_SENSOR: + + /* Set the tokens register to be Humidity token registers */ + //tokenregister = &(esp_settings->humidityTokens); + + /* Process thresholds for ENS210-HumiData*/ + if((raw_data > esp_settings->maxHum) && (prev_raw_data < esp_settings->maxHum)) + { + (ulp_ulp_strobedHumidityFlags) |= STROBED_SENSOR_MEASUREMENT_EXCEEDED_UPPER_THRESHOLD; + useTokens = 1; + } + else if((raw_data < esp_settings->minHum) && (prev_raw_data > esp_settings->minHum)) + { + (ulp_ulp_strobedHumidityFlags) |= STROBED_SENSOR_MEASUREMENT_FELL_BELOW_LOWER_THRESHOLD; + useTokens = 1; + } + break; + + case THERMOCOUPLE_SENSOR: + + if((ulp_ulp_triggersThatCanWakeTheHost & WAKE_HOST_WHEN_THERMOCOUPLE_CROSSES_LIMITS)) + { + /* Set the tokens register to be ThermoCouple token-registers */ + //tokenregister = &(esp_settings->thermocoupleTokens); + + /* Process thresholds for MCP9600-TcData*/ + if((raw_data > esp_settings->maxTcTemp) && (prev_raw_data < esp_settings->maxTcTemp)) + { + (ulp_ulp_strobedThermocoupleFlags) |= STROBED_SENSOR_MEASUREMENT_EXCEEDED_UPPER_THRESHOLD; + useTokens = 1; + } + else if((raw_data < esp_settings->minTcTemp) && (prev_raw_data > esp_settings->minTcTemp)) + { + (ulp_ulp_strobedThermocoupleFlags) |= STROBED_SENSOR_MEASUREMENT_FELL_BELOW_LOWER_THRESHOLD; + useTokens = 1; + } + break; + } + break; + } + + /* Process the sensor-Tokens*/ + if((useTokens == 1)) + { + wakeHostForStrobedTrigger = 1; + ESP_LOGI(TAG,"Sensor flags have been set to wake the host"); + } + + + return wakeHostForStrobedTrigger; +} + +uint8_t data_process_lightSen_thresholds(uint32_t prev_raw_data, uint32_t raw_data) +{ + uint8_t wakeHostForStrobedTrigger = 0; + + /* Check if light now has been detected and in the previous state there were no light*/ + if((raw_data > esp_settings->lightSensorLevel) && (prev_raw_data < esp_settings->lightSensorLevel)) + { + //ESP_LOGI(TAG, "Light Detected --> Set DARK_TO_LIGHT flag "); + + /* Check if we should do check-in when changing from dark to light*/ + if(ulp_ulp_triggersThatCanWakeTheHost & WAKE_HOST_ON_DARK_TO_LIGHT) + { + ulp_ulp_strobedMiscFlags |= STROBED_MISC_CHANGE_FROM_DARK_TO_LIGHT; + + wakeHostForStrobedTrigger = 1; + /* Reduce light tokens by 1*/ + /*if(esp_settings->lightSensorTokens) + { + esp_settings->lightSensorTokens--; + wakeHostForStrobedTrigger = 1; + }*/ + } + } + else if((raw_data < esp_settings->lightSensorLevel) && (prev_raw_data > esp_settings->lightSensorLevel)) + { + //ESP_LOGI(TAG, "Light didn't detected --> Set LIGHT_TO_DARK flag "); + + /* Check if we should do check-in when changing from light to dark*/ + if(ulp_ulp_triggersThatCanWakeTheHost & WAKE_HOST_ON_LIGHT_TO_DARK) + { + ulp_ulp_strobedMiscFlags |= STROBED_MISC_CHANGE_FROM_LIGHT_TO_DARK; + + wakeHostForStrobedTrigger = 1; + /* Reduce light tokens by 1*/ + /*if(esp_settings->lightSensorTokens) + { + esp_settings->lightSensorTokens--; + wakeHostForStrobedTrigger = 1; + }*/ + } + } + else + { + /*If none of the previous conditions are true then ---> current light_data is within Light_thresholds*/ + //ESP_LOGI(TAG," Light_GP > current_data > Light_GN "); + } + + + return wakeHostForStrobedTrigger; +} + +void data_process_power_thresholds(void) +{ + /* Check if switch occurred from battery to usb*/ + if((g_usbConnected == 1) && (g_prevUsbConnected == 0)) + { + /* Set the switch-to-usb strobe*/ + if(ulp_ulp_triggersThatCanWakeTheHost & WAKE_HOST_ON_SWITCH_FROM_BATTERY_TO_USB) + { + ulp_ulp_strobedMiscFlags |= STROBED_MISC_CHANGE_FROM_BATTERY_TO_USB; + + // Rise a trigger flag to do the check-in process before going to deep-sleep + wakeHostForStrobedTrigger2++; + + /* Reduce the power tokens by 1*/ + /*if(esp_settings->powerMonitorTokens) + esp_settings->powerMonitorTokens--;*/ + } + } + else if((g_usbConnected == 0) && (g_prevUsbConnected == 1)) + { + /* Set the switch-to-battery strobe*/ + if(ulp_ulp_triggersThatCanWakeTheHost & WAKE_HOST_ON_SWITCH_FROM_USB_TO_BATTERY) + { + ulp_ulp_strobedMiscFlags |= STROBED_MISC_CHANGE_FROM_USB_TO_BATTERY; + + // Rise a trigger flag to do the check-in process before going to deep-sleep + wakeHostForStrobedTrigger2++; + + /* Reduce the power tokens by 1*/ + /*if(esp_settings->powerMonitorTokens) + esp_settings->powerMonitorTokens--;*/ + } + else + { + ESP_LOGI(TAG,"g_triggersThatCanWakeTheHost & WAKE_HOST_ON_SWITCH_FROM_USB_TO_BATTERY = failed"); + } + } +} + + + +void data_save_history(void) +{ + ESP_LOGI(TAG, "data_save_history()"); + + /* Check if the current history array is full */ + if (esp_settings->historyIndex > (NVM_MAX_NUMBER_OF_IN_ONE_SECTOR - 1)) + { + /* If so then clear it (clear the current history array) and start storing again from index 0 + * in NVM it will also starts storing in a new history_sector */ + data_clear_history(); + esp_settings->historyIndex = 0; + } + + _logs[esp_settings->historyIndex].logTemp = get_temperature_data(); + _logs[esp_settings->historyIndex].logHumidity = get_humidity_data(); + _logs[esp_settings->historyIndex].logThermocoupleTemp = get_thermocouple_data(); + _logs[esp_settings->historyIndex].logLight = ((get_light_data() > esp_settings->lightSensorLevel)?1:0); + _logs[esp_settings->historyIndex].logXaxis = get_accel_x(); + _logs[esp_settings->historyIndex].logYaxis = get_accel_y(); + _logs[esp_settings->historyIndex].logZaxis = get_accel_z(); + _logs[esp_settings->historyIndex].logCheckInTime = g_wakeUpTime; + //_logs[esp_settings->historyIndex].logRSSI = ((wifi_station_connected())? data_get_wifi_rssi() : modem_Rssi()); + _logs[esp_settings->historyIndex].logStatusFlags = (1 & (!g_usbConnected)); + _logs[esp_settings->historyIndex].logTriggerFlags1 = g_triggerFlags1; + _logs[esp_settings->historyIndex].logTriggerFlags2 = g_triggerFlags2; + _logs[esp_settings->historyIndex].logHistoryRecorded = true; + + esp_settings->historyIndex++; + + if (esp_settings->historyIndex > (NVM_MAX_NUMBER_OF_IN_ONE_SECTOR - 1)) + { + esp_settings->historyIndex = 0; + } + + /* Store history data in NVM */ + nvm_write_history_data(_logs); +} + +void data_show_history(uint8_t sector, bool print_logs, size_t* size_of_written_sector_data) +{ + ESP_LOGI(TAG, "data_show_history()"); + + /* Read the NVS-sector from the NVM storage */ + *size_of_written_sector_data = nvm_read_history_data(_logs,sector); + + /* if print_logs flag is true then print the LOGS of the history data */ + if(print_logs) + { + for (uint8_t x = 0; x < NVM_MAX_NUMBER_OF_IN_ONE_SECTOR; x++) + { + if(_logs[x].logHistoryRecorded) + { + printf("I: %d", x); + if(isTempPresent) + { + printf(" Temp: %f", _logs[x].logTemp); + printf(" Hum: %f", _logs[x].logHumidity); + } + + if(isAccelPresent) + { + printf(" X axis: %d", _logs[x].logXaxis); + printf(" Y axis: %d", _logs[x].logYaxis); + printf(" Z axis: %d", _logs[x].logZaxis); + } + + if(isThermocouplePresent) + { + printf(" TcTemp: %f", _logs[x].logThermocoupleTemp); + } + + printf(" Time: %ld", _logs[x].logCheckInTime); + //printf(" RSSI: %d", _logs[x].logRSSI); + printf(" Status: 0x%X", _logs[x].logStatusFlags); + printf(" Triggers, Part 1: 0x%X", (unsigned int)_logs[x].logTriggerFlags1); + printf(" Triggers, Part 2: 0x%X\r\n", (unsigned int)_logs[x].logTriggerFlags2); + } + } + } +} + +bool data_clear_history(void) +{ + bool dataChanged; + uint8_t x; + + dataChanged = false; + + ESP_LOGI(TAG, "data_clear_history()"); + + for (x = 0; x < NVM_MAX_NUMBER_OF_IN_ONE_SECTOR; x++) + { + if(false != _logs[x].logHistoryRecorded) + { + dataChanged = true; + _logs[x].logHistoryRecorded = false; + } + } + + if(0 != esp_settings->historyIndex) + { + dataChanged = true; + esp_settings->historyIndex = 0; + + /* Clear all the sectors from the NVM storage*/ + //nvm_clear_history_sector(NVM_HISTORY_ALL_SECTORS); + } + + return dataChanged; +} + + + +/* rtcRamStruc functions */ +void data_initialize_rtc_ram(void) +{ + _rtcRamData.timeOfLastRadioCalibration = 0; + _rtcRamData.checkInClock = 0; + _rtcRamData.retry1Clock = 0; + _rtcRamData.retry2Clock = 0; + + _rtcRamData.lteRssi = -128; + + + // INITIALIZE OPERATING MODE + if(CHECK_IN_MODE != _rtcRamData.operatingMode) + { + _rtcRamData.operatingMode = CHECK_IN_MODE; //ON_BOARDING_MODE; //made it check-in by default for testing + } + + _rtcRamData.initializationVectorCreated = false; + _rtcRamData.checkInCount = 0; + _rtcRamData.temperatureAtLastRadioCalibration = 200; // Out-of-range for normal operation, so a radio calibration will occur before the next radio use. + _rtcRamData.retriesAreInProgress = false; +} + +void data_set_ap_mac_addr(uint8_t *bssid) +{ + for(int i=0; i<6; i++) + { + _rtcRamData.bssid[i] = bssid[i]; + } +} + +uint8_t* data_get_ap_mac_addr(void) +{ + return ((uint8_t*)&_rtcRamData.bssid[0]); +} + +void data_set_local_ip_addr(esp_netif_ip_info_t* ip_infos) +{ + _rtcRamData.localIp.ip.addr = ip_infos->ip.addr; + _rtcRamData.localIp.gw.addr = ip_infos->gw.addr; + _rtcRamData.localIp.netmask.addr = ip_infos->netmask.addr; +} + +uint32_t data_get_ip_addr(void) +{ + return _rtcRamData.localIp.ip.addr; +} + +uint32_t data_get_gw_addr(void) +{ + return _rtcRamData.localIp.gw.addr; +} + +uint32_t data_get_netmask_addr(void) +{ + return _rtcRamData.localIp.netmask.addr; +} + +void data_set_wifi_channel(uint8_t channel) +{ + _rtcRamData.wifiChannel = channel; +} + +uint8_t data_get_wifi_channel(void) +{ + return _rtcRamData.wifiChannel; +} + +void data_set_wifi_rssi(int32_t rsi) +{ + _rtcRamData.wifi_rssi = rsi; +} + +int32_t data_get_wifi_rssi(void) +{ + return _rtcRamData.wifi_rssi; +} + +void data_set_main_and_backup_dns(esp_netif_dns_info_t* dns1, esp_netif_dns_info_t* dns2) +{ + _rtcRamData.dns1.ip.u_addr.ip4.addr = dns1->ip.u_addr.ip4.addr; + _rtcRamData.dns2.ip.u_addr.ip4.addr = dns2->ip.u_addr.ip4.addr; +} + +uint32_t data_get_mode(void) +{ + return _rtcRamData.operatingMode; +} + +void data_clearWifiConnectionSettings(void) +{ + _rtcRamData.wifiChannel = 1; // FCC allows only channels 1 through 13 in the USA, but 12 and 13 must be low power, which I don't think we can control. My linksys router only allows channels 1-11. + memset(_rtcRamData.bssid, 0, sizeof(_rtcRamData.bssid)); + _rtcRamData.localIp.ip.addr = 0; + _rtcRamData.localIp.gw.addr = 0; + _rtcRamData.localIp.netmask.addr = 0; + _rtcRamData.dns1.ip.u_addr.ip4.addr = 0; + _rtcRamData.dns2.ip.u_addr.ip4.addr = 0; +} + + + + +/*******************************************************************/ +/* Buffer(Json Sample) */ +/*{ "request": "settings", "time":1675859084, "id":10608508, + * "SensorInt":1, "ConfigUpdate":0, "McuUpdate:0", "ModemUpdate":0 } + */ +/*******************************************************************/ + +esp_err_t data_parsing_config(char *buff,int len){ + esp_err_t retval = ESP_FAIL; + char *ret = NULL; + char server_request[11]={0}; + //char setting_req[]="settings"; + ret = strstr(buff, (const char*)"settings"); + data_parse_String_value(server_request,"request",buff); + if( ret != NULL ){ + //retval = data_parse_uint_value(&g_server_time,"time", buff); + retval = data_parse_uint_value(&g_ID,"id", buff); + retval = data_parse_uint_value(&g_SensorInt,"SensorInt", buff); + retval = data_parse_uint_value(&g_ConfigUpdate,"ConfigUpdate", buff); + retval = data_parse_uint_value(&g_McuUpdate,"McuUpdate", buff); + retval = data_parse_uint_value(&g_ModemUpdate,"ModemUpdate", buff); + ESP_LOGI(TAG, "ConfigUpdate: %ld McuUpdate: %ld ModemUpdate: %ld", g_ConfigUpdate, g_McuUpdate, g_ModemUpdate); + } + else + { + ESP_LOGI(TAG, "Invalid request :%s",server_request); + } + return retval; +} + + +/****************************************************************************/ + +/* function input + maxretrynum = HTTP_RETRY_COUNT = 5 + httpRetryCnt is the current retry count + + +*/ +esp_err_t check_in_attempts_count( int httpRetryCnt, int maxretrynum ) +{ + esp_err_t retval = ESP_OK; + + checkInAttemptNumber = 1 + maxretrynum - httpRetryCnt; + + return retval; +} + + +/* should use in main.c to initiate sendDetails var*/ +void init_send_Details(void) +{ + esp_settings->sendDetails = true; +} + +/********************************************************/ + +int32_t data_get_postUrlMax(void){ + + return esp_settings->postURLMax; +} + +void data_init_postUrlMax(int32_t val){ + + esp_settings->postURLMax = val; +// ESP_LOGI(TAG,"postURLMax = %ld",esp_settings->postURLMax); +} + +/********************************************************/ + +int32_t data_get_postToServer(void){ + + return postToServer; +} + + +void data_set_postToServer(int32_t val){ + + postToServer = val; +} + + +void data_init_postToServer(){ + /*initiate postURLNumber to pointing to default server*/ + + if(esp_settings->postURLNumber == 0) + { + esp_settings->postURLNumber = 1; + } + postToServer = esp_settings->postURLNumber; + //ESP_LOGI(TAG,"Initiate postToServer = %ld ",postToServer); +} + +/********************************************************/ +uint32_t data_get_alertInterval(){ + + return esp_settings->alertInterval; +} +/********************************************************/ +void data_set_urlConnect(void) +{ + if(TEMPSTICK_SERVER) + { + switch(esp_settings->postURLNumber) + { + case TEMPSTICK_SERVER1: + sprintf(urlConnect, "%s",MCU_BASE_URL1 ); + ESP_LOGI(TAG,"urlConnect server1 : %s",(char*)(&urlConnect[8])); + break; + case TEMPSTICK_SERVER2: + sprintf(urlConnect, "%s",MCU_BASE_URL2 ); + ESP_LOGI(TAG,"urlConnect server2 : %s",(char*)(&urlConnect[8])); + break; + case TEMPSTICK_SERVER3: + sprintf(urlConnect, "%s",MCU_BASE_URL3 ); + ESP_LOGI(TAG,"urlConnect server3 : %s",(char*)(&urlConnect[8])); + break; + } + } + else + { + sprintf(urlConnect, "%s",TESTING_SERVER_BASE_URL ); + ESP_LOGI(TAG,"urlConnect test server : %s",(char*)(&urlConnect[7])); + + } + +} + + + + + diff --git a/main/data_processing.h b/main/data_processing.h new file mode 100644 index 0000000..19a815a --- /dev/null +++ b/main/data_processing.h @@ -0,0 +1,298 @@ +/* + * data_processing.h + * + * Created on: Feb 3, 2023 + * Author: Partha + */ + +#ifndef MAIN_DATA_PROCESSING_H_ +#define MAIN_DATA_PROCESSING_H_ + +#include "sdkconfig.h" +#include "esp_netif.h" + +typedef struct +{ + // If at some point in the future more data needs to fit into this structure, the floats can be replaced with signed scaled int16s to save space. + // Simply convert the floats to scaled signed int16s on-the-fly when storing the log, and convert them back on-the-fly when displaying the log + // or sending them to the server. Because of the limited range utilized by the floats, you can probably multiply them by 100, store them as ints, + // and then divide them by 100 after retrieving them. Check to see if any weird out-of-range indicators in the floats would break this system + // before implementing it. You would need to alter the deviceSaveHistory(), deviceShowHistory(), and sendDataToServer() functions, and possibly + // the deviceClearHistory() functions, and adapt to the rtcRamData structure. + bool logHistoryRecorded; // Flag that indicates if the entry is empty or filled with valid data. + //int8_t logRSSI; + uint8_t logStatusFlags; + uint16_t logXaxis; + uint16_t logYaxis; + uint16_t logZaxis; + uint32_t logTriggerFlags1; + uint32_t logTriggerFlags2; + uint32_t logLight; + uint32_t logCheckInTime; + float logTemp; + float logHumidity; + float logThermocoupleTemp; +}historyLog_t; + +typedef enum +{ + HISTORY_TEMP_FIELD = 1, + HISTORY_HUMI_FIELD, + HISTORY_THERM_FIELD, + HISTORY_LIGHT_FIELD, + HISTORY_TIME_FIELD, + HISTORY_TRIG1_FIELD, + HISTORY_TRIG2_FIELD, + HISTORY_XAXIS_FIELD, + HISTORY_YAXIS_FIELD, + HISTORY_ZAXIS_FIELD, + HISTORY_RSSI_FIELD, + HISTORY_STAUS_FIELD, + HISTORY_RECORD_FIELD +}historyLog_field_t; + +#define ON_BOARDING_MODE 0x01010101 +#define ALERT_MODE 0x02020202 +#define CHECK_IN_MODE 0x03030303 +#define DEVICE_RESET_MODE 0x04040404 +#define USER_FEEDBACK_MODE 0x05050505 + +#define WAKE_HOST_LOWER_BYTE_DISABLED 0x00 +#define WAKE_HOST_LOWER_BYTE_ON_MOVEMENT_DETECTION 0x01 // 0 = disabled, 1 = enabled. +#define WAKE_HOST_LOWER_BYTE_ON_LIGHT_TO_DARK 0x02 // 0 = disabled, 1 = enabled. +#define WAKE_HOST_LOWER_BYTE_ON_DARK_TO_LIGHT 0x04 // 0 = disabled, 1 = enabled. +#define WAKE_HOST_LOWER_BYTE_ON_SWITCH_FROM_USB_TO_BATTERY 0x08 // 0 = disabled, 1 = enabled. +#define WAKE_HOST_LOWER_BYTE_ON_SWITCH_FROM_BATTERY_TO_USB 0x10 // 0 = disabled, 1 = enabled. +#define WAKE_HOST_LOWER_BYTE_WHEN_THERMOCOUPLE_CROSSES_LIMITS 0x20 // 0 = disabled, 1 = enabled. +#define WAKE_HOST_LOWER_BYTE_UNUSED_A 0x40 // 0 = disabled, 1 = enabled. +#define WAKE_HOST_LOWER_BYTE_UNUSED_B 0x80 // 0 = disabled, 1 = enabled. + +#define WAKE_HOST_UPPER_BYTE_UNUSED_C 0x01 // 0 = disabled, 1 = enabled. +#define WAKE_HOST_UPPER_BYTE_UNUSED_D 0x02 // 0 = disabled, 1 = enabled. +#define WAKE_HOST_UPPER_BYTE_UNUSED_E 0x04 // 0 = disabled, 1 = enabled. +#define WAKE_HOST_UPPER_BYTE_UNUSED_F 0x08 // 0 = disabled, 1 = enabled. +#define WAKE_HOST_UPPER_BYTE_UNUSED_G 0x10 // 0 = disabled, 1 = enabled. +#define WAKE_HOST_UPPER_BYTE_UNUSED_H 0x20 // 0 = disabled, 1 = enabled. +#define WAKE_HOST_UPPER_BYTE_UNUSED_I 0x40 // 0 = disabled, 1 = enabled. +#define WAKE_HOST_UPPER_BYTE_UNUSED_J 0x80 // 0 = disabled, 1 = enabled. + +// 16-bit masks +#define WAKE_HOST_DISABLED (uint16_t)WAKE_HOST_LOWER_BYTE_DISABLED +#define WAKE_HOST_ON_MOVEMENT_DETECTION (uint16_t)WAKE_HOST_LOWER_BYTE_ON_MOVEMENT_DETECTION +#define WAKE_HOST_ON_LIGHT_TO_DARK (uint16_t)WAKE_HOST_LOWER_BYTE_ON_LIGHT_TO_DARK +#define WAKE_HOST_ON_DARK_TO_LIGHT (uint16_t)WAKE_HOST_LOWER_BYTE_ON_DARK_TO_LIGHT +#define WAKE_HOST_ON_SWITCH_FROM_USB_TO_BATTERY (uint16_t)WAKE_HOST_LOWER_BYTE_ON_SWITCH_FROM_USB_TO_BATTERY +#define WAKE_HOST_ON_SWITCH_FROM_BATTERY_TO_USB (uint16_t)WAKE_HOST_LOWER_BYTE_ON_SWITCH_FROM_BATTERY_TO_USB +#define WAKE_HOST_WHEN_THERMOCOUPLE_CROSSES_LIMITS (uint16_t)WAKE_HOST_LOWER_BYTE_WHEN_THERMOCOUPLE_CROSSES_LIMITS +#define WAKE_HOST_UNUSED_A (uint16_t)WAKE_HOST_LOWER_BYTE_UNUSED_A +#define WAKE_HOST_UNUSED_B (uint16_t)WAKE_HOST_LOWER_BYTE_UNUSED_B +#define WAKE_HOST_UNUSED_C (uint16_t)(WAKE_HOST_UPPER_BYTE_UNUSED_C << 8) +#define WAKE_HOST_UNUSED_D (uint16_t)(WAKE_HOST_UPPER_BYTE_UNUSED_D << 8) +#define WAKE_HOST_UNUSED_E (uint16_t)(WAKE_HOST_UPPER_BYTE_UNUSED_E << 8) +#define WAKE_HOST_UNUSED_F (uint16_t)(WAKE_HOST_UPPER_BYTE_UNUSED_F << 8) +#define WAKE_HOST_UNUSED_G (uint16_t)(WAKE_HOST_UPPER_BYTE_UNUSED_G << 8) +#define WAKE_HOST_UNUSED_H (uint16_t)(WAKE_HOST_UPPER_BYTE_UNUSED_H << 8) +#define WAKE_HOST_UNUSED_I (uint16_t)(WAKE_HOST_UPPER_BYTE_UNUSED_I << 8) +#define WAKE_HOST_UNUSED_J (uint16_t)(WAKE_HOST_UPPER_BYTE_UNUSED_J << 8) + +#define STROBED_SENSOR_MEASUREMENT_EXCEEDED_THRESHOLD_A 0x0001 +#define STROBED_SENSOR_MEASUREMENT_RETURNED_FROM_ABOVE_THRESHOLD_A 0x0002 +#define STROBED_SENSOR_MEASUREMENT_EXCEEDED_THRESHOLD_B 0x0004 +#define STROBED_SENSOR_MEASUREMENT_RETURNED_FROM_ABOVE_THRESHOLD_B 0x0008 +#define STROBED_SENSOR_MEASUREMENT_EXCEEDED_THRESHOLD_C 0x0010 +#define STROBED_SENSOR_MEASUREMENT_RETURNED_FROM_ABOVE_THRESHOLD_C 0x0020 +#define STROBED_SENSOR_MEASUREMENT_FELL_BELOW_THRESHOLD_D 0x0040 +#define STROBED_SENSOR_MEASUREMENT_RETURNED_FROM_BELOW_THRESHOLD_D 0x0080 +#define STROBED_SENSOR_MEASUREMENT_FELL_BELOW_THRESHOLD_E 0x0100 +#define STROBED_SENSOR_MEASUREMENT_RETURNED_FROM_BELOW_THRESHOLD_E 0x0200 +#define STROBED_SENSOR_MEASUREMENT_FELL_BELOW_THRESHOLD_F 0x0400 +#define STROBED_SENSOR_MEASUREMENT_RETURNED_FROM_BELOW_THRESHOLD_F 0x0800 +#define STROBED_SENSOR_UNUSED_A 0x1000 +#define STROBED_SENSOR_UNUSED_B 0x2000 +#define STROBED_SENSOR_UNUSED_C 0x4000 +#define STROBED_SENSOR_UNUSED_D 0x8000 + +#define STROBED_MOTION_LOWER_BYTE_MOVEMENT_DETECTED 0x01 +#define STROBED_MOTION_LOWER_BYTE_UNUSED_A 0x02 +#define STROBED_MOTION_LOWER_BYTE_UNUSED_B 0x04 +#define STROBED_MOTION_LOWER_BYTE_UNUSED_C 0x08 +#define STROBED_MOTION_LOWER_BYTE_UNUSED_D 0x10 +#define STROBED_MOTION_LOWER_BYTE_UNUSED_E 0x20 +#define STROBED_MOTION_LOWER_BYTE_UNUSED_F 0x40 +#define STROBED_MOTION_LOWER_BYTE_UNUSED_G 0x80 + +#define STROBED_MOTION_UPPER_BYTE_UNUSED_H 0x01 +#define STROBED_MOTION_UPPER_BYTE_UNUSED_I 0x02 +#define STROBED_MOTION_UPPER_BYTE_UNUSED_J 0x04 +#define STROBED_MOTION_UPPER_BYTE_UNUSED_K 0x08 +#define STROBED_MOTION_UPPER_BYTE_UNUSED_L 0x10 +#define STROBED_MOTION_UPPER_BYTE_UNUSED_M 0x20 +#define STROBED_MOTION_UPPER_BYTE_UNUSED_N 0x40 +#define STROBED_MOTION_UPPER_BYTE_UNUSED_O 0x80 + +// 16-bit masks +#define STROBED_MOTION_MOVEMENT_DETECTED (uint16_t)STROBED_MOTION_LOWER_BYTE_MOVEMENT_DETECTED +#define STROBED_MOTION_UNUSED_A (uint16_t)STROBED_MOTION_LOWER_BYTE_UNUSED_A +#define STROBED_MOTION_UNUSED_B (uint16_t)STROBED_MOTION_LOWER_BYTE_UNUSED_B +#define STROBED_MOTION_UNUSED_C (uint16_t)STROBED_MOTION_LOWER_BYTE_UNUSED_C +#define STROBED_MOTION_UNUSED_D (uint16_t)STROBED_MOTION_LOWER_BYTE_UNUSED_D +#define STROBED_MOTION_UNUSED_E (uint16_t)STROBED_MOTION_LOWER_BYTE_UNUSED_E +#define STROBED_MOTION_UNUSED_F (uint16_t)STROBED_MOTION_LOWER_BYTE_UNUSED_F +#define STROBED_MOTION_UNUSED_G (uint16_t)STROBED_MOTION_LOWER_BYTE_UNUSED_G +#define STROBED_MOTION_UNUSED_H (uint16_t)(STROBED_MOTION_LOWER_BYTE_UNUSED_H << 8) +#define STROBED_MOTION_UNUSED_I (uint16_t)(STROBED_MOTION_LOWER_BYTE_UNUSED_I << 8) +#define STROBED_MOTION_UNUSED_J (uint16_t)(STROBED_MOTION_LOWER_BYTE_UNUSED_J << 8) +#define STROBED_MOTION_UNUSED_K (uint16_t)(STROBED_MOTION_LOWER_BYTE_UNUSED_K << 8) +#define STROBED_MOTION_UNUSED_L (uint16_t)(STROBED_MOTION_LOWER_BYTE_UNUSED_L << 8) +#define STROBED_MOTION_UNUSED_M (uint16_t)(STROBED_MOTION_LOWER_BYTE_UNUSED_M << 8) +#define STROBED_MOTION_UNUSED_N (uint16_t)(STROBED_MOTION_LOWER_BYTE_UNUSED_N << 8) +#define STROBED_MOTION_UNUSED_O (uint16_t)(STROBED_MOTION_LOWER_BYTE_UNUSED_O << 8) + +#define STROBED_MISC_LOWER_BYTE_CHECK_IN_REQUESTED 0x01 +#define STROBED_MISC_LOWER_BYTE_CHANGE_FROM_LIGHT_TO_DARK 0x02 +#define STROBED_MISC_LOWER_BYTE_CHANGE_FROM_DARK_TO_LIGHT 0x04 +#define STROBED_MISC_LOWER_BYTE_CHANGE_FROM_USB_TO_BATTERY 0x08 +#define STROBED_MISC_LOWER_BYTE_CHANGE_FROM_BATTERY_TO_USB 0x10 +#define STROBED_MISC_LOWER_BYTE_THERMOCOUPLE_PLUGGED_IN 0x20 +#define STROBED_MISC_LOWER_BYTE_THERMOCOUPLE_UNPLUGGED 0x40 +#define STROBED_MISC_LOWER_BYTE_REGULAR_SCHEDULED_CHECK_IN 0x80 + +#define STROBED_MISC_UPPER_BYTE_CHECK_IN_REQ_AFTER_POWER_ON 0x01 +#define STROBED_MISC_UPPER_BYTE_DEVICE_OPERATE_IN_ALERT_MODE 0x02 +#define STROBED_MISC_UPPER_BYTE_UNUSED_D 0x04 +#define STROBED_MISC_UPPER_BYTE_UNUSED_E 0x08 +#define STROBED_MISC_UPPER_BYTE_UNUSED_F 0x10 +#define STROBED_MISC_UPPER_BYTE_UNUSED_G 0x20 +#define STROBED_MISC_UPPER_BYTE_UNUSED_H 0x40 +#define STROBED_MISC_UPPER_BYTE_UNUSED_I 0x80 + +// 16-bit masks +#define STROBED_MISC_CHECK_IN_REQUESTED (uint16_t)STROBED_MISC_LOWER_BYTE_CHECK_IN_REQUESTED +#define STROBED_MISC_CHANGE_FROM_LIGHT_TO_DARK (uint16_t)STROBED_MISC_LOWER_BYTE_CHANGE_FROM_LIGHT_TO_DARK +#define STROBED_MISC_CHANGE_FROM_DARK_TO_LIGHT (uint16_t)STROBED_MISC_LOWER_BYTE_CHANGE_FROM_DARK_TO_LIGHT +#define STROBED_MISC_CHANGE_FROM_USB_TO_BATTERY (uint16_t)STROBED_MISC_LOWER_BYTE_CHANGE_FROM_USB_TO_BATTERY +#define STROBED_MISC_CHANGE_FROM_BATTERY_TO_USB (uint16_t)STROBED_MISC_LOWER_BYTE_CHANGE_FROM_BATTERY_TO_USB +#define STROBED_MISC_THERMOCOUPLE_PLUGGED_IN (uint16_t)STROBED_MISC_LOWER_BYTE_THERMOCOUPLE_PLUGGED_IN +#define STROBED_MISC_THERMOCOUPLE_UNPLUGGED (uint16_t)STROBED_MISC_LOWER_BYTE_THERMOCOUPLE_UNPLUGGED +#define STROBED_MISC_REGULAR_SCHEDULED_CHECK_IN (uint16_t)STROBED_MISC_LOWER_BYTE_REGULAR_SCHEDULED_CHECK_IN +#define STROBED_MISC_CHECK_IN_REQ_AFTER_POWER_ON (uint16_t)(STROBED_MISC_UPPER_BYTE_CHECK_IN_REQ_AFTER_POWER_ON << 8) +#define STROBED_MISC_DEVICE_OPERATE_IN_ALERT_MODE (uint16_t)(STROBED_MISC_UPPER_BYTE_DEVICE_OPERATE_IN_ALERT_MODE << 8) +#define STROBED_MISC_UNUSED_D (uint16_t)(STROBED_MISC_UPPER_BYTE_UNUSED_D << 8) +#define STROBED_MISC_UNUSED_E (uint16_t)(STROBED_MISC_UPPER_BYTE_UNUSED_E << 8) +#define STROBED_MISC_UNUSED_F (uint16_t)(STROBED_MISC_UPPER_BYTE_UNUSED_F << 8) +#define STROBED_MISC_UNUSED_G (uint16_t)(STROBED_MISC_UPPER_BYTE_UNUSED_G << 8) +#define STROBED_MISC_UNUSED_H (uint16_t)(STROBED_MISC_UPPER_BYTE_UNUSED_H << 8) +#define STROBED_MISC_UNUSED_I (uint16_t)(STROBED_MISC_UPPER_BYTE_UNUSED_I << 8) + +#define CURRENT_STATUS_LIGHT_DETECTED 0x01 +#define CURRENT_STATUS_POWERED_BY_USB 0x02 +#define CURRENT_STATUS_UNUSED_A 0x04 +#define CURRENT_STATUS_UNUSED_B 0x08 +#define CURRENT_STATUS_UNUSED_C 0x10 +#define CURRENT_STATUS_UNUSED_D 0x20 +#define CURRENT_STATUS_UNUSED_E 0x40 +#define CURRENT_STATUS_UNUSED_F 0x80 + +#define LIGHT_SENSOR_VREF_1V024 0x00 // Vref = 1.024V +#define LIGHT_SENSOR_VREF_2V048 0x01 // Vref = 2.048V +#define LIGHT_SENSOR_VREF_2V500 0x02 // Vref = 2.500V +#define LIGHT_SENSOR_VREF_VDD 0x03 // Vref = Vdd + +#define LIGHT_DETECTED true +#define LIGHT_UNDETECTED false + +/* TRIGGER 1 bits */ +#define STROBED_TEMPERATURE_MEASUREMENT_EXCEEDED_UPPER_THRESHOLD 0x0001 +#define STROBED_TEMPERATURE_MEASUREMENT_FELL_BELOW_LOWER_THRESHOLD 0x0002 +#define STROBED_HUMIDITY_MEASUREMENT_EXCEEDED_UPPER_THRESHOLD 0x0004 +#define STROBED_HUMIDITY_MEASUREMENT_FELL_BELOW_LOWER_THRESHOLD 0x0008 +#define STROBED_THERMOCOUPLE_MEASUREMENT_EXCEEDED_UPPER_THRESHOLD 0x0010 +#define STROBED_THERMOCOUPLE_MEASUREMENT_FELL_BELOW_LOWER_THRESHOLD 0x0020 +#define STROBED_EXTERNAL_TEMP_PROBE_MEASUREMENT_EXCEEDED_UPPER_THRESHOLD 0x0040 +#define STROBED_EXTERNAL_TEMP_PROBE_MEASUREMENT_FELL_BELOW_LOWER_THRESHOLD 0x0080 +#define STROBED_DEVICE_OPERATE_IN_ALERT_MODE 0x0100 + + +/* TRIGGER 2 bits */ +#define STROBED_REGULAR_SCHEDULED_SENDINTERVAL_CHECKIN 0x0001 +#define STROBED_POWER_CHANGE_FROM_BATTERY_TO_USB 0x0002 +#define STROBED_POWER_CHANGE_FROM_USB_TO_BATTERY 0x0004 +#define STROBED_MOTION_MOVEMENT_WAS_DETECTED 0x0008 +#define STROBED_LIGHT_TRANSITION_FROM_LIGHT_TO_DARK 0x0010 +#define STROBED_LIGHT_TRANSITION_FROM_DARK_TO_LIGHT 0x0020 +#define STROBED_CHECK_IN_REQUESTED_AFTER_POWER_ON 0x4000 +#define STROBED_BUTTON_CHECK_IN_REQUESTED 0x8000 + + +#define STROBED_SENSOR_MEASUREMENT_EXCEEDED_UPPER_THRESHOLD 0x0001 +#define STROBED_SENSOR_MEASUREMENT_FELL_BELOW_LOWER_THRESHOLD 0x0002 + +typedef enum +{ + TEMPERATURE_SENSOR, + HUMIDITY_SENSOR, + THERMOCOUPLE_SENSOR, + LIGHT_SENSOR, + ACCELEROMETER_SENSOR, + POWER_MONITOR_SENSOR +}sensorType_t; + +typedef enum +{ + BATTERY_CHARGING, + BATTERY_CHARGED, + BATTERY_FAULT +}batteryChargingState_t; + +void data_initialize_rtc_ram(void); +bool data_setTempPresent(bool status); +bool data_setAccelPresent(bool status); +bool data_setThermocouplePresent(bool status); + +uint16_t data_get_motion_threshold(void); +uint32_t data_get_send_interval(void); +bool data_is_usb_connected(void); +void data_task(void *pvParameters); +void data_update_trigger_flags(void); +void data_create_checkin_string(char *buff, size_t len); + +void data_parse_http_response(const char *http_resp); +void data_processSensorModes(sensorType_t sensor); +uint8_t data_process_tempHumi_thresholds(float raw_data, float prev_raw_data, sensorType_t sensor); +uint8_t data_process_lightSen_thresholds(uint32_t prev_raw_data, uint32_t raw_data); +#if 0 +uint32_t data_get_light_sensor_gp(void); +uint32_t data_get_light_sensor_gn(void); +#endif +uint8_t data_get_light_sensor_threshold(void); +void data_process_power_thresholds(void); + +void data_save_history(void); +void data_show_history(uint8_t sector, bool print_logs, size_t* size_of_written_sector_data); +bool data_clear_history(void); +uint32_t data_get_mode(void); +esp_err_t data_parsing_config(char *buff,int len); +esp_err_t check_in_attempts_count( int httpRetryCnt, int maxretrynum ); +void init_send_Details(void); +int32_t data_get_postToServer(void); +int32_t data_get_postUrlMax(void); +void data_init_postUrlMax(int32_t val); +void data_set_postToServer(int32_t val); +void data_init_postToServer(void); +uint32_t data_get_alertInterval(void); + +void data_set_ap_mac_addr(uint8_t *bssid); +void data_set_wifi_rssi(int32_t rsi); +int32_t data_get_wifi_rssi(void); +uint8_t* data_get_ap_mac_addr(void); +void data_set_local_ip_addr(esp_netif_ip_info_t* ip_infos); +uint32_t data_get_ip_addr(void); +uint32_t data_get_gw_addr(void); +uint32_t data_get_netmask_addr(void); +void data_set_wifi_channel(uint8_t channel); +uint8_t data_get_wifi_channel(void); +void data_clearWifiConnectionSettings(void); +void data_set_main_and_backup_dns(esp_netif_dns_info_t* dns1, esp_netif_dns_info_t* dns2); + +void data_set_urlConnect(void); +#endif /* MAIN_DATA_PROCESSING_H_ */ diff --git a/main/hmi.c b/main/hmi.c new file mode 100644 index 0000000..24174dc --- /dev/null +++ b/main/hmi.c @@ -0,0 +1,656 @@ +/* + * hmi.c + * + * Created on: Feb 13, 2023 + * Author: Sword + */ + +#include +#include "nvs_flash.h" +#include "esp_system.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "freertos/semphr.h" +#include "driver/gpio.h" +#include "esp_log.h" +#include "sdkconfig.h" +#include "esp_timer.h" +#include "uart_ifx.h" +#include "esp_task_wdt.h" +#include "modem.h" +#include "comms.h" +#include "port.h" +#include "adc_ifx.h" +#include "i2c_sensors.h" +#include "data_processing.h" +#include "hmi.h" + + +static const char* TAG = "HMI"; + +#define LOG_LOCAL_LEVEL ESP_LOG_INFO + +#define HMI_BUF_SIZE 20 +#define HMI_EVENTS_ITERATION_COUNTS 8 + +#define LED_SOLID_DURATION 300 +#define OTA_UPDATE_DURATION 1000 // Duration for BLUE_FLASHING event when OTA session is happening +#define BLUE_FLASHING_DURARION 500 // Duration for BLUE_FLASHING led_event +#define RED_FLASHING_DURARION 1000 // Duration for RED_FLASHING led_event +#define BLUE_RED_FLASHING_1SEC_DURARION 1000 // Duration for BLUE_RED_FLASHING led_event +#define BLUE_RED_SOLID_CHARGED_DURARION 9700 // Duration for BLUE_RED_SOLID_CHARGED led_event +#define BLUE_RED_FLASHING_CHARGED_DURARION 100 // Duration for BLUE_RED_FLASHING_CHARGING led_event +#define BLUE_RED_FLASHING_200ms_DURARION 200 // Duration for BLUE_RED_FLASHING led_event +#define NORMAL_HMI_DURATION 1000 // Duration for NORMAL_HMI cycle (cycle without triggered events) + +static QueueHandle_t hmi_queue; // FIFO queue that stores the leds event + + +static bool usb_connection_state = false; // USB connection state flag (true--> connected, false--> disconnected) +static bool continue_current_leds_state; // Led_event Continuing flag +static bool pushbutton_state = false; // pushbutton state flag +static bool blue_red_sync = false; // Synchronization flag when usb_charging is the current usb_led_event +static bool device_failure_state = false; +static bool device_not_onboarded_state = false; // ON-BOARDED flag when device data didn't get sent to server +static bool ota_update_session = false; // OTA-Update flag to indicate that firmware update is happening right now +static bool alternate_cycle_for_both = false; // A flag to make both LEDs blink in an alternating cycle + +static hmi_leds_state_t continued_leds_state; // Chosen led_event to be continued after 5 times of execution +static hmi_leds_state_t leds_state = BLUE_RED_LEDS_OFF; // Led_event when usb is not connected +static hmi_leds_state_t prev_leds_state = BLUE_RED_LEDS_OFF; // prev Led_event when usb is not connected + + +static hmi_leds_state_t usb_leds_state = BLUE_RED_LEDS_OFF; // Led_event when usb is connected + +static uint8_t num_events_in_queue; // Number of Events in hmi_queue +static uint16_t hmi_duration = NORMAL_HMI_DURATION; // Duration for each Led_event cycle +static uint8_t fully_charged_counter; + +/************* STATIC FUNCTIONS ****************/ + +/* This function should be executed when the pushbutton is pressed (HIGHEST priority)*/ +static void hmi_pushbutton_pressed_task(void) +{ + /* 1- Execute the BLUE_LED_SOLID event*/ + hmi_duration = LED_SOLID_DURATION; + port_blue_led_on(); + port_red_led_off(); + + + /* 2- Delay duration is equal to BLUE_FLASHING_DURARION*/ + vTaskDelay(hmi_duration / portTICK_PERIOD_MS); + + + /* 3- Check if the pushbutton is not pressed*/ + if(port_is_pushbuttonNotPressed()) + { + /* If yes ---> reset pushbutton_state flag*/ + pushbutton_state = false; + } + +} + +/* This function should be executed when the device failure is occurred (second HIGHEST priority)*/ +static void hmi_device_failure_task(void) +{ + /* 1- Execute the RED_LED_SOLID event*/ + hmi_duration = LED_SOLID_DURATION; + port_blue_led_off(); + port_red_led_on(); + + + /* 2- Delay duration is equal to BLUE_FLASHING_DURARION*/ + vTaskDelay(hmi_duration / portTICK_PERIOD_MS); + +} + +/* This function should be executed when the device is not on-boarded yet (Third HIGHEST priority)*/ +static void hmi_device_not_onboarded_task(void) +{ + /* 1- Execute the RED_LED_FLASHING event*/ + hmi_duration = RED_FLASHING_DURARION; + port_blue_led_off(); + port_red_led_toggle(); + + + /* 2- Delay duration is equal to BLUE_FLASHING_DURARION*/ + vTaskDelay(hmi_duration / portTICK_PERIOD_MS); +} + +/* This function should be executed when OTA Update is happening ( device_not_onboarded > priority > events_in_queue)*/ +static void hmi_ota_firmware_update_task(void) +{ + /* 1- Execute the RED_LED_FLASHING event*/ + hmi_duration = OTA_UPDATE_DURATION; + port_blue_led_toggle(); + port_red_led_toggle(); + + alternate_cycle_for_both = true; + + /* 2- Delay duration is equal to BLUE_FLASHING_DURARION*/ + vTaskDelay(hmi_duration / portTICK_PERIOD_MS); +} + +/* This function should be executed when USB is not connected ( device_failure > priority > USB)*/ +static void hmi_events_in_queue_task(void) +{ + int counter = 0; + + /*Check if the current led_event shall be continued or not */ + if((true == continue_current_leds_state) && (continued_leds_state == prev_leds_state)) + { + /*if true: the new led_state is the same as the old led state */ + leds_state = prev_leds_state; + } + else + { + /*Extract the event from the queue (if exists)*/ + xQueueReceive(hmi_queue, &leds_state, (TickType_t)100); + + /*Set the previous led_state*/ + prev_leds_state = leds_state; + + + /*Reduce number of led_events in queue by 1*/ + num_events_in_queue--; + + /*Log*/ + ESP_LOGI(TAG,"Extracting LED_EVENT = %d from HMI-QUEUE to execute it",leds_state); + + } + + /*Check if BLUE & RED LED should be synchronized*/ + if((BLUE_RED_LEDS_FLASHING_200ms == leds_state) && (false == blue_red_sync)) + { + /*Turn off both leds for synchronization*/ + port_red_led_off(); + port_blue_led_off(); + blue_red_sync = true; + } + + /*Each event should occur 5 times to observe it clearly*/ + for(counter = 0; counter < HMI_EVENTS_ITERATION_COUNTS; counter++) + { + /* 1- Evaluate the extracted event*/ + switch(leds_state) + { + case BLUE_LED_FLASHING: //LTE_connecting + hmi_duration = BLUE_FLASHING_DURARION; + port_blue_led_toggle(); + port_red_led_off(); + break; + + case BLUE_LED_SOLID: //pushbutton_pressed + break; + + case RED_LED_FLASHING: //Device has not been on-boarded + break; + + case RED_LED_SOLID: //Device Failure. Need to reset + break; + + case BLUE_RED_LEDS_FLASHING_200ms: //low battery warning + hmi_duration = BLUE_RED_FLASHING_200ms_DURARION; + port_red_led_toggle(); + port_blue_led_toggle(); + break; + + case BLUE_RED_LEDS_FLASHING_1SEC: //USB_PLUGGED_CHARGING + case BLUE_RED_LEDS_SOLD: //USB_PLUGGED_CHARGED + case BLUE_RED_LEDS_USB_OFF: + case BLUE_LED_FLASHING_OTA: // OTA-SESSION is happening + break; + + case BLUE_RED_LEDS_OFF: + hmi_duration = NORMAL_HMI_DURATION; + port_red_led_off(); + port_blue_led_off(); + break; + } + + /* 2- Delay duration is dynamic according the extracted led_event*/ + vTaskDelay(hmi_duration / portTICK_PERIOD_MS); + + /* 3- Check the pushbutton state and device failure state*/ + if((true == pushbutton_state) || (true == device_failure_state)) + { + /*If yes then break the for-loop*/ + break; + } + } + + /*Reset the Synchronization flag*/ + blue_red_sync = false; +} + +/* This function should be executed when USB is connected (LOWEST priority)*/ +static void hmi_usb_connected_task(void) +{ + /*Evaluate the extracted event*/ + switch(usb_leds_state) + { + case BLUE_LED_FLASHING: + case BLUE_LED_SOLID: + case RED_LED_FLASHING: + case RED_LED_SOLID: + case BLUE_LED_FLASHING_OTA: + case BLUE_RED_LEDS_FLASHING_200ms: + break; + + /* Charging LED-event is violate toggling each one second (on, off, on, off and continue like this) */ + case BLUE_RED_LEDS_FLASHING_1SEC: + hmi_duration = BLUE_RED_FLASHING_1SEC_DURARION; + port_red_led_toggle(); + port_blue_led_toggle(); + break; + + /* Charged LED-event is violate toggling 2 times each 100ms and then of for 9.7 second */ + case BLUE_RED_LEDS_SOLD: + if(fully_charged_counter < 3) + { + /* Increase the fully_charged_counter by 1 */ + fully_charged_counter++; + + hmi_duration = BLUE_RED_FLASHING_CHARGED_DURARION; + port_red_led_toggle(); + port_blue_led_toggle(); + } + else + { + /* Reset the fully_charged_counter to 0 */ + fully_charged_counter = 0; + + hmi_duration = BLUE_RED_SOLID_CHARGED_DURARION; + port_red_led_off(); + port_blue_led_off(); + } + break; + + case BLUE_RED_LEDS_USB_OFF: + hmi_duration = BLUE_RED_FLASHING_1SEC_DURARION; + port_red_led_off(); + port_blue_led_off(); + break; + + case BLUE_RED_LEDS_OFF: + break; + } + + vTaskDelay(hmi_duration / portTICK_PERIOD_MS); +} + + + + +/************ NON-STATIC FUNCTIONS *************/ +/* This function is to initialize HMI service (Creating hmi_queu and turn off both leds)*/ +void hmi_init(void) +{ + /* 1- Create the HMI-QUEUE*/ + hmi_queue = xQueueCreate(HMI_BUF_SIZE, sizeof(uint8_t)); + + /* 2- Set the hmi_duration to normal and turn off both leds*/ + hmi_duration = NORMAL_HMI_DURATION; + num_events_in_queue = 0; + continue_current_leds_state = false; + port_red_led_off(); + port_blue_led_off(); + + ESP_LOGI(TAG,"HMI-Service has been initialized successfully"); +} + +/* This function is used to set the state of USB-CONNECTION*/ +void hmi_set_usb_connection_state(bool usb_state) +{ + usb_connection_state = usb_state; +} + +#if 0 +void hmi_do_usb_event_inside_hmi(bool decision) +{ + do_it_inside_hmi = decision; +} + +void hmi_exception_usb_event(void) +{ + /* Check if to do the USB event inside hmi-task or outside it (inside pausing-task) */ + if(do_it_inside_hmi) + { + /* Check the USB-LED-event */ + if(usb_leds_state == BLUE_RED_LEDS_FLASHING_1SEC) + { + /* Turn off both LEDs */ + port_red_led_off(); + port_blue_led_off(); + + /* Wait for about 300ms (to simulate the measurement time) */ + vTaskDelay(300/portTICK_PERIOD_MS); + + /* Turn on both LEDs */ + port_red_led_on(); + port_blue_led_on(); + + /* Wait for about 333ms */ + vTaskDelay(333/portTICK_PERIOD_MS); + + /* Turn off both LEDs */ + port_red_led_off(); + port_blue_led_off(); + + /* Wait for about 333ms */ + vTaskDelay(333/portTICK_PERIOD_MS); + + /* Turn on both LEDs */ + port_red_led_on(); + port_blue_led_on(); + + /* Wait for about 333ms */ + vTaskDelay(333/portTICK_PERIOD_MS); + + /* Turn off both LEDs */ + port_red_led_off(); + port_blue_led_off(); + } + else if(usb_leds_state == BLUE_RED_LEDS_SOLD) + { + /* Turn off both LEDs */ + port_red_led_off(); + port_blue_led_off(); + + /* Wait for about 300ms (to simulate the measurement time) */ + vTaskDelay(300/portTICK_PERIOD_MS); + + /* Turn on both LEDs */ + port_red_led_on(); + port_blue_led_on(); + + /* Wait for about 1000ms */ + vTaskDelay(1000/portTICK_PERIOD_MS); + + /* Turn off both LEDs */ + port_red_led_off(); + port_blue_led_off(); + } + } + else + { + if(usb_leds_state == BLUE_RED_LEDS_FLASHING_1SEC) + { + port_red_led_on(); + port_blue_led_on(); + + vTaskDelay(333/portTICK_PERIOD_MS); + + port_red_led_off(); + port_blue_led_off(); + + vTaskDelay(333/portTICK_PERIOD_MS); + + port_red_led_on(); + port_blue_led_on(); + + vTaskDelay(333/portTICK_PERIOD_MS); + + port_red_led_off(); + port_blue_led_off(); + } + else if(usb_leds_state == BLUE_RED_LEDS_SOLD) + { + port_red_led_on(); + port_blue_led_on(); + + vTaskDelay(1000/portTICK_PERIOD_MS); + + port_red_led_off(); + port_blue_led_off(); + } + } +} +#endif + +/* This function is used to set which Led_event should be executed next time*/ +void hmi_set_leds_state(hmi_leds_state_t status) +{ + uint32_t batt_mv; + float g_voltage ; + + /*Check if the led-event should be pushed to the hmi_queue*/ + switch(status) + { + case BLUE_LED_FLASHING: //Should be pushed to hmi_queue + + /*Continue executing this led_event till it's stopped by hmi_stop_continued_led_state() function */ + continue_current_leds_state = true; // RISE the led_event continuing_Flag + continued_leds_state = BLUE_LED_FLASHING; // Set the flag to be continued to be BLUE_LED_FLASHING + num_events_in_queue++; // increase the number of events in hmi_queue by 1 + xQueueSend(hmi_queue, &status, 100); // Push the new led_state to the hmi_queue (if possible) + blue_red_sync = false; // reset synchronization flag + ESP_LOGI(TAG,"BLUE Flashing (continuing) has been added to hmi_queue"); + + break; + + case RED_LED_FLASHING: //Should not be pushed to hmi_queue(it has its own function --> hmi_device_not_onboarded_task()) + device_not_onboarded_state = true; //Set the device_not_onboarded_state flag to be true + blue_red_sync = false; //reset synchronization flag + ESP_LOGI(TAG,"RED LED should Flashes now (if no higher-priority event is occurred)"); + break; + + case BLUE_LED_SOLID: //Should not be pushed to hmi_queue(it has its own function --> hmi_pushbutton_pressed_task()) + pushbutton_state = true; //Set the pushbutton_state flag to be true + blue_red_sync = false; //reset synchronization flag + break; + + case RED_LED_SOLID: //Should not be pushed to hmi_queue(it has its own function --> hmi_device_failure_task()) + device_failure_state = true; //Set the device_failure_state flag to be true + blue_red_sync = false; //reset synchronization flag + break; + + case BLUE_RED_LEDS_OFF: //Should be pushed to hmi_queue + + xQueueSend(hmi_queue, &status, 100); // Push the new led_state to the hmi_queue (if possible) + num_events_in_queue++; // increase the number of events in hmi_queue by 1 + blue_red_sync = false; // reset synchronization flag + + break; + + case BLUE_RED_LEDS_FLASHING_200ms: + num_events_in_queue++; // increase the number of events in hmi_queue by 1 + xQueueSend(hmi_queue, &status, 100); // Push the new led_state to the hmi_queue (if possible) + ESP_LOGI(TAG,"BLUE_RED_LED_FLASHING_200ms has been added to hmi_queue"); + break; + + case BLUE_RED_LEDS_FLASHING_1SEC: //Should not be pushed to hmi_queue(it has its own function --> hmi_usb_connected_task()) + + /* Check if the USB is plugged and the battery is existed */ + if((true == usb_connection_state)) + { + /*Update the current usb_leds_state*/ + usb_leds_state = status; + + ESP_LOGI(TAG,"Voilate Flashing has been set"); + } + else + { + ESP_LOGI(TAG,"Voilate Flashing can't be set. Battery may not be connected"); + } + break; + + case BLUE_RED_LEDS_SOLD: //Should not be pushed to hmi_queue(it has its own function --> hmi_usb_connected_task()) + + /* Check if the USB is plugged and the battery is existed and its voltage level is fine */ + if((true == usb_connection_state)) + { + /*Update the current usb_leds_state*/ + usb_leds_state = status; + + /*reset synchronization flag*/ + blue_red_sync = false; + + ESP_LOGI(TAG,"Voilate Solid has been set"); + } + else + { + ESP_LOGI(TAG,"Voilate Solid can't be set. Battery may not be connected or its volt. level is too low"); + } + break; + + case BLUE_LED_FLASHING_OTA: //Should not be pushed to hmi_queue(it has its own function --> hmi_ota_firmware_update_task()) + + /*reset synchronization flag*/ + blue_red_sync = false; + + /* set ota_flag*/ + ota_update_session = true; + + break; + + + case BLUE_RED_LEDS_USB_OFF: + /* Check if the USB is plugged and the battery is existed and its voltage level is fine */ + if((true == usb_connection_state)) + { + /*Update the current usb_leds_state*/ + usb_leds_state = status; + + /*reset synchronization flag*/ + blue_red_sync = false; + + //ESP_LOGI(TAG,"Voilate Solid/Flashing has been stopped"); + } + } + + /*Exit the critical shared section between different tasks*/ + //taskEXIT_CRITICAL(&hmi_mutex); +} + +/* This function is used to stop the continuing led_event*/ +void hmi_stop_continued_led_state(hmi_leds_state_t led_event) +{ + /* Check if the led_event that should be stopped is the same as the current continuing led_event*/ + if(continued_leds_state == led_event) + { + /*If yes then : */ + /* 1- Disallow continuing the current running Led_event */ + continue_current_leds_state = false; + + /* 2- Set the continued Led_event to be BLUE_RED_LEDS_OFF (and it won't executed because the continue flag is false)*/ + continued_leds_state = BLUE_RED_LEDS_OFF; + + /*Log*/ + ESP_LOGI(TAG,"Stopping the current continued LED_EVENT = %d",led_event); + } +} + +/* This function is used to stop red flashing*/ +void hmi_stop_red_flashing(void) +{ + device_not_onboarded_state = false; +} + +/* This function is used to stop ota_LED-event */ +void hmi_stop_ota_event(void) +{ + ota_update_session = false; +} + +bool leds_enabled = true; +void set_leds_enable(bool status) +{ + leds_enabled = status; + if(status == false) + { + port_red_led_off(); + port_blue_led_off(); + } +} + +/* This is the hmi_task that will be executed periodically*/ +void hmi_task(void *pvParameters) +{ + for(;;) + { + while(leds_enabled == false) + { + vTaskDelay(10 / portTICK_PERIOD_MS); + port_red_led_off(); + port_blue_led_off(); + blue_red_sync = false; + } + + + if(true == pushbutton_state) // 1) Check if the pushbutton is pressed + { + /* reset the alternating flag */ + alternate_cycle_for_both = false; + + /*If pushbutton is pressed then do the following task*/ + hmi_pushbutton_pressed_task(); + } + else if(true == device_failure_state) // 2) Check if the device failure is occurred + { + /* reset the alternating flag */ + alternate_cycle_for_both = false; + + /*If device failure is occurred then do the following task*/ + hmi_device_failure_task(); + } + else if(true == device_not_onboarded_state) // 3) Check if the device failure is occurred + { + /* reset the alternating flag */ + alternate_cycle_for_both = false; + + /*If device has not been onBoarded yet then do the following task*/ + hmi_device_not_onboarded_task(); + } + else if(true == ota_update_session) // 4) Check if the OTA-Session is happening now + { + /*Check if the alternating flag is false*/ + if(false == alternate_cycle_for_both) + { + /*Turn on the BLUE and turn off the RED*/ + port_red_led_off(); + port_blue_led_on(); + alternate_cycle_for_both = true; + } + /*If device is doing OTA-Update session now then do the following task*/ + hmi_ota_firmware_update_task(); + } + else + { + if((0 < num_events_in_queue) || (true == continue_current_leds_state)) // 5) Check if there are led_events in the hmi_queue + { + /* reset the alternating flag */ + alternate_cycle_for_both = false; + + /*If there are led_events inside the hmi_queue then do the following task*/ + hmi_events_in_queue_task(); + } + else + { + if(true == usb_connection_state) // 6) Check if the USB is plugged + { + /*Check if the synchronization flag is false*/ + if(false == blue_red_sync) + { + /*Turn off both leds for synchronization*/ + port_red_led_off(); + port_blue_led_off(); + blue_red_sync = true; + } + /*If USB is connected then do the following task*/ + hmi_usb_connected_task(); + } + else + { + // If none of the previous conditions were true then turn off both leds + hmi_duration = NORMAL_HMI_DURATION; + port_red_led_off(); + port_blue_led_off(); + vTaskDelay(hmi_duration / portTICK_PERIOD_MS); + } + } + } + } + vTaskDelete(NULL); +} diff --git a/main/hmi.h b/main/hmi.h new file mode 100644 index 0000000..75c28fb --- /dev/null +++ b/main/hmi.h @@ -0,0 +1,35 @@ +/* + * hmi.h + * + * Created on: Feb 13, 2023 + * Author: Sword + */ + +#ifndef MAIN_HMI_H_ +#define MAIN_HMI_H_ + +typedef enum{ + BLUE_LED_FLASHING, // Connecting to LTE Network + BLUE_LED_FLASHING_OTA, // OTA Update Firmware + BLUE_LED_SOLID, // Button pressed for a User invoked check-in + RED_LED_FLASHING, // Device has not been on-boarded + RED_LED_SOLID, // Device Failure. Need to reset + BLUE_RED_LEDS_FLASHING_200ms, // Low battery warning + BLUE_RED_LEDS_FLASHING_1SEC, // Battery Charging + BLUE_RED_LEDS_SOLD, // Battery Charged 100% + BLUE_RED_LEDS_USB_OFF, + BLUE_RED_LEDS_OFF +}hmi_leds_state_t; + +void hmi_init(void); +void hmi_set_leds_state(hmi_leds_state_t status); +void hmi_stop_continued_led_state(hmi_leds_state_t led_event); +void hmi_set_usb_connection_state(bool usb_state); +void hmi_stop_red_flashing(void); +void hmi_stop_ota_event(void); +void hmi_task(void *pvParameters); +void set_leds_enable(bool status); +void hmi_do_usb_event_inside_hmi(bool decision); +void hmi_exception_usb_event(void); + +#endif /* MAIN_HMI_H_ */ diff --git a/main/i2c_sensors.c b/main/i2c_sensors.c new file mode 100644 index 0000000..e12c9a7 --- /dev/null +++ b/main/i2c_sensors.c @@ -0,0 +1,1729 @@ +/* + * i2c_sensors.c + * + * Created on: Jan 23, 2023 + * Author: Sword + */ + + +#include "driver/i2c.h" +#include +#include +#include "esp_log.h" +#include "driver/gpio.h" +#include "i2c_sensors.h" +#include "data_processing.h" +#include "ulp_main.h" +#include "port.h" + +static const char *TAG = "I2C"; +#define LOG_LOCAL_LEVEL ESP_LOG_INFO + +#define I2C_MASTER_SCL_IO GPIO_NUM_2 /*!< GPIO number used for I2C master clock */ +#define I2C_MASTER_SDA_IO GPIO_NUM_3 /*!< GPIO number used for I2C master data */ +#define I2C_MASTER_NUM 0 /*!< I2C master i2c port number, the number of i2c peripheral interfaces available will depend on the chip */ +#define I2C_MASTER_FREQ_HZ 100000 /*!< I2C master clock frequency */ +#define I2C_MASTER_TX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */ +#define I2C_MASTER_RX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */ +#define I2C_MASTER_TIMEOUT_MS (1000/ portTICK_PERIOD_MS) + +/*buffers to store incoming data/values from different sensors*/ +//union byteAccessibleUint16 rawHumidity; +//union byteAccessibleUint16 rawTemperature; +//union byteAccessibleInt16 rawThermocoupleTemperature; + +typedef struct +{ + union + { + uint8_t state:2; + uint8_t res_mod:1; + uint8_t reserv:1; + uint8_t i2c_wdt:1; + uint8_t reser2:2; + uint8_t otp_busy:1; + uint8_t data; + }; +}status_t; + +//Sensor Data +/*RTC_DATA_ATTR static float temperature; +RTC_DATA_ATTR static float humidity; +RTC_DATA_ATTR static float thermocoupleTemp;*/ + +static float temperature; +static float humidity; +static float thermocoupleTemp; + +RTC_DATA_ATTR uint32_t light_data; +RTC_DATA_ATTR uint32_t prev_light_data; +float light_full_scale; +//Sensor previous Data +/*RTC_DATA_ATTR static float prev_temperature; +RTC_DATA_ATTR static float prev_humidity; +RTC_DATA_ATTR static float prev_thermocoupleTemp;*/ + +static uint16_t ens210_devid; +static uint8_t mc3419_chipId; +static uint8_t mcp9600_idRevision; + +static uint16_t accel_x; +static uint16_t accel_y; +static uint16_t accel_z; + +static uint8_t i2cBuffer[6]; + +esp_err_t i2c_get_accel_reg_byte(uint8_t *reg, uint8_t *byte); + +void i2c_master_init(void) +{ + /*Set the port number of i2c-peripheral on chip*/ + i2c_port_t i2c_master_port = I2C_MASTER_NUM; + + /*setting the i2c peripheral to act as an i2c-master*/ + i2c_config_t conf = { + .mode = I2C_MODE_MASTER, + .sda_io_num = I2C_MASTER_SDA_IO, + .scl_io_num = I2C_MASTER_SCL_IO, + .sda_pullup_en = GPIO_PULLUP_DISABLE, + .scl_pullup_en = GPIO_PULLUP_DISABLE, + .master.clk_speed = I2C_MASTER_FREQ_HZ, + }; + + /*Configuring the i2c with the previous settings*/ + ESP_ERROR_CHECK(i2c_param_config(i2c_master_port, &conf)); + + /*Install the configured i2c driver*/ + ESP_ERROR_CHECK(i2c_driver_install(i2c_master_port, conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0)); + +} + +/*Sensors initialization functions*/ +/**********************************/ +bool i2c_initialize_temp_humidity_sensor(void) +{ + bool flag = false; + if(ESP_OK == i2c_ens210_set_active_mode()) + { + flag = true; + ESP_LOGI(TAG, "ENS210 Setting Active Mode"); + } + + if(ESP_OK == i2c_ens210_fetch_dev_id()) + { + ESP_LOGI(TAG, "ENS210 part ID: %02X", get_ens210_devId()); + } + + if(ESP_OK != i2c_start_temp_humid()) + { + flag = false; + } + return flag; +} + +bool i2c_initialize_accel_sensor(void) +{ + bool flag = flag; + + if(ESP_OK == i2c_get_mc3419_state()) + { + flag = true; + + /* These settings should be set in standby mode (before switch to wakeup mode)*/ + /* ACCELEROMETER threshold should be set at each accelerometer initialization */ + + /* 1- switch to STANDBY mode*/ + if(ESP_OK == i2c_set_mc3419_mode(MC3419_STANDBY_MODE)) + { + /* 2- Set Initial motion threshold*/ + if(ESP_OK == i2c_set_mc3419_motionThreshold(data_get_motion_threshold())) + { + /* 3- Enable interrupt flag INT1 for accelerometer*/ + i2c_enable_mc3419_motion_int(true); + + /* 4- Clear all pending INT flags*/ + i2c_clear_mc3419_int_flag(); + + /*LOG*/ + ESP_LOGI(TAG,"The new motion_detection threshold %d has been set",data_get_motion_threshold()); + } + } + + if(ESP_OK == i2c_set_mc3419_mode(MC3419_WAKE_MODE)) + { + if(ESP_OK == i2c_fetch_mc3419_chipId()) + { + ESP_LOGI(TAG, "MC3419 Chip Id: %02X", get_mc3419_chipId()); + + i2c_get_mc3419_state(); + } + else + { + ESP_LOGI(TAG, "Failed to get MC3419 chipid"); + flag = false; + } + } + else + { + ESP_LOGI(TAG, "Failed to set MC3419 to wake mode"); + flag = false; + } + } + else + { + ESP_LOGI(TAG, "Failed to get MC3419 state"); + } + + return flag; +} + + +/*ENS210-Sensor functions*/ +/**********************************/ +esp_err_t i2c_start_temp_humid(void) +{ + esp_err_t ret = ESP_FAIL; + + i2cBuffer[0] = ENS210_SENS_RUN; + i2cBuffer[1] = 3; + ret = i2c_master_write_to_device(I2C_MASTER_NUM, ENS210_ADDR, i2cBuffer, 2, 1000 / portTICK_PERIOD_MS); + if(ret != ESP_OK) + { + ESP_LOGI(TAG, "Failed to send sensor run request to ENS210."); + return ret; + } + + i2cBuffer[0] = ENS210_SENS_START; + i2cBuffer[1] = 3; + ret = i2c_master_write_to_device(I2C_MASTER_NUM, ENS210_ADDR, i2cBuffer, 2, 131 / portTICK_PERIOD_MS); + if(ret != ESP_OK) + { + ESP_LOGI(TAG, "Failed to send sensor start request to ENS210."); + } + return ret; +} + +esp_err_t i2c_stop_temp_humid(void) +{ + esp_err_t ret = ESP_FAIL; + + i2cBuffer[0] = ENS210_SENS_STOP; + i2cBuffer[1] = 3; + ret = i2c_master_write_to_device(I2C_MASTER_NUM, ENS210_ADDR, i2cBuffer, 2, 1000 / portTICK_PERIOD_MS); + if(ret != ESP_OK) + { + ESP_LOGI(TAG, "Failed to send sensor stop request to ENS210."); + return ret; + } + return ret; +} + +esp_err_t i2c_fetch_temp(void) +{ + uint16_t temp = 0; + uint16_t hum = 0; + float tempC = 0; + + // Read temperature and humidity + i2cBuffer[0] = ENS210_T_VAL; + esp_err_t ret = ESP_FAIL; + + ret = i2c_master_write_to_device(I2C_MASTER_NUM, ENS210_ADDR, &i2cBuffer[0], 1, (I2C_MASTER_TIMEOUT_MS)); + + if(ESP_OK != ret) + { + ESP_LOGI(TAG, "Failed to send T_VAL command to ENS210 sensor."); + return ret; + } + + ret = i2c_master_read_from_device(I2C_MASTER_NUM, ENS210_ADDR, i2cBuffer, 6, (I2C_MASTER_TIMEOUT_MS)); + + if(ret == ESP_OK) + { + //ESP_LOGI(TAG, "Reading temperature and humidity from ENS210 sensor"); + } + else + { + ESP_LOGI(TAG, "Failed to read from ENS210 sensor"); + return ret; + } + + if(i2cBuffer[2] & 0x01) + { + temp = i2cBuffer[0] | (i2cBuffer[1] << 8); + tempC = temp/64.0; + tempC -= 273.15; + ulp_ulp_prev_temperature = ulp_ulp_temperature; + ulp_ulp_temperature = tempC; + ulp_ens_temp_raw = temp; + temperature = tempC; + } + else + { + ESP_LOGI(TAG, "Invalid temperature data"); + } + + if(i2cBuffer[5] & 0x01) + { + hum = i2cBuffer[3] | (i2cBuffer[4] << 8); + ulp_ulp_prev_humidity = ulp_ulp_humidity; + ulp_ulp_humidity = hum/512.0; + humidity = hum/512.0; + ulp_humidity_raw = hum; + } + else + { + ESP_LOGI(TAG, "Invalid humidity data"); + } + + return ret; +} + +float get_temperature_data(void) +{ + return temperature; +} + +float get_prev_temperature_data(void) +{ + return ulp_ulp_prev_temperature; +} + +float get_humidity_data(void) +{ + return humidity; +} + +float get_prev_humidity_data(void) +{ + return ulp_ulp_prev_humidity; +} + +esp_err_t i2c_ens210_fetch_dev_id(void) +{ + i2cBuffer[0] = ENS210_PART_ID; + esp_err_t ret = i2c_master_write_to_device(I2C_MASTER_NUM, ENS210_ADDR, i2cBuffer, 1, 1000 / portTICK_PERIOD_MS); + if(ret != ESP_OK) + { + ESP_LOGI(TAG, "Failed to send part ID request to ENS210."); + return ret; + } + vTaskDelay(100 / portTICK_PERIOD_MS); + + ret = i2c_master_read_from_device(I2C_MASTER_NUM, ENS210_ADDR, i2cBuffer, 2, (I2C_MASTER_TIMEOUT_MS)); + if(ESP_OK != ret) + { + ESP_LOGI(TAG, "Failed to receive any part ID response from ENS210."); + } + ens210_devid = i2cBuffer[1] | (i2cBuffer[0] << 8); + return ret; +} + +uint16_t get_ens210_devId(void) +{ + return ens210_devid; +} + +esp_err_t i2c_ens210_set_active_mode(void) +{ + i2cBuffer[0] = ENS210_SYS_CTRL; + i2cBuffer[1] = 0; + esp_err_t ret = i2c_master_write_to_device(I2C_MASTER_NUM, ENS210_ADDR, i2cBuffer, 2, I2C_MASTER_TIMEOUT_MS); + if(ret != ESP_OK) + { + ESP_LOGI(TAG, "Failed to send active mode write request to ENS210."); + return ret; + } + + vTaskDelay(1000 / portTICK_PERIOD_MS); + + i2cBuffer[0] = ENS210_SYS_STAT; + ret = i2c_master_write_to_device(I2C_MASTER_NUM, ENS210_ADDR, i2cBuffer, 1, I2C_MASTER_TIMEOUT_MS); + if(ret != ESP_OK) + { + ESP_LOGI(TAG, "Failed to send sys stat read request to ENS210."); + return ret; + } + + ret = i2c_master_read_from_device(I2C_MASTER_NUM, ENS210_ADDR, i2cBuffer, 1, I2C_MASTER_TIMEOUT_MS); + if(ESP_OK != ret) + { + ESP_LOGI(TAG, "Failed to receive sys stat response from ENS210."); + } + else + { + ESP_LOGI(TAG, "ENS210 sys stat: %d", i2cBuffer[0]); + } + return ret; +} + + +/*MC3419-Sensor functions*/ +/**********************************/ +esp_err_t i2c_fetch_mc3419_chipId(void) +{ + i2cBuffer[0] = CHIP_IDENTIFICATION_REGISTER; + esp_err_t ret = i2c_master_write_to_device(I2C_MASTER_NUM, MC3419_ADDR, i2cBuffer, 1, I2C_MASTER_TIMEOUT_MS); + if(ret != ESP_OK) + { + ESP_LOGI(TAG, "Failed to send chip id request to MC3419."); + return ret; + } + ret = i2c_master_read_from_device(I2C_MASTER_NUM, MC3419_ADDR, i2cBuffer, 1, I2C_MASTER_TIMEOUT_MS); + if(ESP_OK != ret) + { + ESP_LOGI(TAG, "Failed to get chip id response from MC3419."); + } + else + { + mc3419_chipId = i2cBuffer[0]; + } + return ret; +} + +uint16_t get_mc3419_chipId(void) +{ + return mc3419_chipId; +} + +esp_err_t i2c_get_accel_reg_byte(uint8_t *reg, uint8_t *byte) +{ + esp_err_t ret = i2c_master_write_to_device(I2C_MASTER_NUM, MC3419_ADDR, reg, 1, I2C_MASTER_TIMEOUT_MS); + if(ret != ESP_OK) + { + ESP_LOGI(TAG, "Failed to send read reg request to MC3419."); + return ret; + } + ret = i2c_master_read_from_device(I2C_MASTER_NUM, MC3419_ADDR, byte, 1, I2C_MASTER_TIMEOUT_MS); + if(ESP_OK != ret) + { + ESP_LOGI(TAG, "Failed to get read reg response from MC3419."); + } + return ret; +} + +esp_err_t i2c_set_mc3419_mode(uint8_t mode) +{ + status_t s; + i2cBuffer[0] = MODE_REGISTER; + + i2c_get_accel_reg_byte(i2cBuffer, (uint8_t *)&s); + + s.state = 1; + s.res_mod = mode; + + i2cBuffer[1] = s.data; + + esp_err_t ret = i2c_master_write_to_device(I2C_MASTER_NUM, MC3419_ADDR, i2cBuffer, 2, I2C_MASTER_TIMEOUT_MS); + if(ret != ESP_OK) + { + ESP_LOGI(TAG, "Failed to send mode request to MC3419."); + } + return ret; + +} + +esp_err_t i2c_get_mc3419_state(void) +{ + i2cBuffer[0] = DEVICE_STATUS_REGISTER; + status_t status; + + esp_err_t ret = i2c_master_write_to_device(I2C_MASTER_NUM, MC3419_ADDR, i2cBuffer, 1, I2C_MASTER_TIMEOUT_MS); + if(ret != ESP_OK) + { + ESP_LOGI(TAG, "Failed to send status reg request to MC3419."); + return ret; + } + ret = i2c_master_read_from_device(I2C_MASTER_NUM, MC3419_ADDR, (uint8_t *)&status, 1, I2C_MASTER_TIMEOUT_MS); + if(ESP_OK != ret) + { + ESP_LOGI(TAG, "Failed to get status reg response from MC3419."); + } + else + { + ESP_LOGI(TAG, "Device Status: STATE: %d RES_MODE: %d I2C_WDT: %d OTP_BUSY: %d", status.state, status.res_mod, status.i2c_wdt, status.otp_busy); + } + return ret; +} + +esp_err_t i2c_fetch_accel_pos(void) +{ + i2cBuffer[0] = XOUT_ACCELEROMETER_DATA_LSB_REGISTER; + esp_err_t ret = i2c_master_write_to_device(I2C_MASTER_NUM, MC3419_ADDR, i2cBuffer, 1, I2C_MASTER_TIMEOUT_MS); + if(ret != ESP_OK) + { + ESP_LOGI(TAG, "Failed to send XYZ request to MC3419."); + return ret; + } + ret = i2c_master_read_from_device(I2C_MASTER_NUM, MC3419_ADDR, i2cBuffer, 6, I2C_MASTER_TIMEOUT_MS); + if(ESP_OK != ret) + { + ESP_LOGI(TAG, "Failed to get XYZ response from MC3419."); + } + else + { + accel_x = i2cBuffer[0] | (i2cBuffer[1] << 8); + accel_y = i2cBuffer[2] | (i2cBuffer[3] << 8); + accel_z = i2cBuffer[4] | (i2cBuffer[5] << 8); + } + return ret; +} + +esp_err_t i2c_clear_mc3419_int_flag(void) +{ + /* 1- Creating i2c buffer for sending and receiving */ + uint8_t i2cBuffer[2]; + + /* 3- Setting up the register address and its value */ + i2cBuffer[0] = INTERRUPT_STATUS_REGISTER; + i2cBuffer[1] = 0x00; // Clear all pending interrupt flags. + esp_err_t ret = i2c_master_write_to_device(I2C_MASTER_NUM, MC3419_ADDR, &i2cBuffer[0], 2, (I2C_MASTER_TIMEOUT_MS)); + + if(ret != ESP_OK) + { + ESP_LOGI(TAG, "Failed to clear all pending interrupt flags of MC3419."); + return ret; + } + + //Log the following message for indication + ESP_LOGI(TAG,"all pending interrupt flags of MC3419 have been cleared successfully"); + + vTaskDelay(1000 / portTICK_PERIOD_MS); + return ret; + +} + +esp_err_t i2c_get_mc3419_int_flags(uint8_t *flags) +{ + /* 1- Creating i2c buffer for sending and receiving */ + uint8_t i2cBuffer[2]; + + /* 2- Set the register address and the receiving buffer*/ + i2cBuffer[0] = INTERRUPT_STATUS_REGISTER; + + /* 3- read one byte from the INTERRUPT_STATUS_REGISTER*/ + esp_err_t ret = i2c_get_accel_reg_byte(&i2cBuffer[0],&i2cBuffer[1]); + + if(ret != ESP_OK) + { + ESP_LOGI(TAG, "Failed to read one from the INTERRUPT_STATUS_REGISTER of MC3419."); + return ret; + } + + //Log the following message for indication + ESP_LOGI(TAG,"Reading one byte from the INTERRUPT_STATUS_REGISTER of MC3419 successfully"); + + /* 4- Storing the received byte in the corresponding pointer*/ + *flags = i2cBuffer[1]; + + vTaskDelay(1000 / portTICK_PERIOD_MS); + return ret; +} + +esp_err_t i2c_enable_mc3419_motion_int(bool enableFlag) +{ + // Return true if ok, return false if invalid data or error. + uint8_t tempByte; + uint8_t tempMode; + + /* 1- Creating i2c buffer for sending and receiving */ + uint8_t i2cBuffer[2]; + + /* 2- Set the register address (MODE_REGISTER)*/ + i2cBuffer[0] = MODE_REGISTER; + + /* 3- Read current mode, so we can return to it after configuring the device*/ + esp_err_t ret = i2c_get_accel_reg_byte(&i2cBuffer[0],&tempMode); + + if(ret != ESP_OK) + { + ESP_LOGI(TAG, "Failed to read the current mode of MC3419."); + return ret; + } + + // Keep only the mode bits. + tempMode &= 0x03; + + /* 4- Switch to STANDBY mode if necessary*/ + if(MC3419_STANDBY_MODE != tempMode) + { + ret = i2c_set_mc3419_mode(MC3419_STANDBY_MODE); + if(ret != ESP_OK) + { + ESP_LOGI(TAG, "Failed to switch to STANDBY-MODE for MC3419."); + return ret; // I2C error. + } + } + + + /* 5- Set the register address (INTERRUPT_ENABLE_REGISTER)*/ + i2cBuffer[0] = INTERRUPT_ENABLE_REGISTER; + + /* 6- Read and update AnyMotion interrupt enable bit.*/ + ret = i2c_get_accel_reg_byte(&i2cBuffer[0],&tempByte); + + ESP_LOGI(TAG, "MC3419 interrupt register: 0x%X", tempByte); + + if(ret != ESP_OK) + { + ESP_LOGI(TAG, "Failed to read interrupt enable bit of MC3419."); + return ret; + } + + if(enableFlag) + tempByte |= 0x04; // Enable AnyMotion interrupt. + else + tempByte &= ~0x04; // Disable AnyMotion interrupt. + + /* 7- Setting up the register address and its value */ + i2cBuffer[0] = INTERRUPT_ENABLE_REGISTER; + i2cBuffer[1] = tempByte; + ret = i2c_master_write_to_device(I2C_MASTER_NUM, MC3419_ADDR, &i2cBuffer[0], 2, (I2C_MASTER_TIMEOUT_MS)); + if(ret != ESP_OK) + { + ESP_LOGI(TAG, "Failed to update the AnyMotion interrupt enable bit of MC3419."); + return ret; + } + + vTaskDelay(100 / portTICK_PERIOD_MS); + i2cBuffer[0] = INTERRUPT_ENABLE_REGISTER; + + /* Read INTERRUPT_ENABLE_REGISTER to confirm if the interrupt flags are set.*/ + ret = i2c_get_accel_reg_byte(&i2cBuffer[0],&tempByte); + + ESP_LOGI(TAG, "MC3419 INTERRUPT_ENABLE_REGISTER: 0x%X", tempByte); + + if(ret != ESP_OK) + { + ESP_LOGI(TAG, "Failed to read INTERRUPT_ENABLE_REGISTER of MC3419."); + return ret; + } + + + /* 4- Restore original mode.*/ + if(MC3419_STANDBY_MODE != tempMode) + { + ret = i2c_set_mc3419_mode(tempMode); + if(ret != ESP_OK) + { + ESP_LOGI(TAG, "Failed to restore the original mode of MC3419."); + return ret; // I2C error. + } + } + + // From MC3419 data sheet + if(MC3419_WAKE_MODE == tempMode) + vTaskDelay(1000 / portTICK_PERIOD_MS); + + // No error. Data valid. + return ret; +} + +esp_err_t i2c_set_mc3419_motionThreshold(uint16_t threshold) +{ + // Return true if ok, return false if invalid data or error. + uint8_t tempByte; + uint8_t tempMode; + + /* Creating i2c buffer for sending and receiving */ + uint8_t i2cBuffer[2]; + + // Read current mode, so we can return to it after configuring the device. + i2cBuffer[0] = MODE_REGISTER; + + /* Read and update AnyMotion interrupt enable bit.*/ + esp_err_t ret = i2c_get_accel_reg_byte(&i2cBuffer[0],&tempMode); + if(ret != ESP_OK) + { + ESP_LOGI(TAG, "Failed to read the mode of MC3419."); + return ret; + } + + // Keep only the mode bits. + tempMode &= 0x03; + + /* Switch to STANDBY mode if necessary*/ + if(MC3419_STANDBY_MODE != tempMode) + { + ret = i2c_set_mc3419_mode(MC3419_STANDBY_MODE); + if(ret != ESP_OK) + { + ESP_LOGI(TAG, "Failed to switch to STANDBY-MODE for MC3419."); + return ret; // I2C error. + } + } + + // Set sample rate. + i2cBuffer[0] = SAMPLE_RATE_REGISTER; + i2cBuffer[1] = 0x08; // Sample rates are different for the MC3419 and MC3419-P chips. + ret = i2c_master_write_to_device(I2C_MASTER_NUM, MC3419_ADDR, &i2cBuffer[0], 2, (I2C_MASTER_TIMEOUT_MS)); + if(ret != ESP_OK) + { + ESP_LOGI(TAG, "Failed to set the new sample rate of MC3419."); + return ret; + } + + // Disable decimation. + i2cBuffer[0] = FIFO_CONTROL_2_AND_SAMPLE_RATE_2_REGISTER; + i2cBuffer[1] = 0x00; + ret = i2c_master_write_to_device(I2C_MASTER_NUM, MC3419_ADDR, &i2cBuffer[0], 2, (I2C_MASTER_TIMEOUT_MS)); + if(ret != ESP_OK) + { + ESP_LOGI(TAG, "Failed to disable decimation of MC3419."); + return ret; + } + + // Configure AnyMotion feature. + i2cBuffer[0] = ANY_MOTION_THRESHOLD_MSB_REGISTER; + i2cBuffer[1] = (uint8_t)((threshold >> 8) & 0x007F); // Bit 7 is reserved. + ret = i2c_master_write_to_device(I2C_MASTER_NUM, MC3419_ADDR, &i2cBuffer[0], 2, (I2C_MASTER_TIMEOUT_MS)); + if(ret != ESP_OK) + { + ESP_LOGI(TAG, "Failed to configure AnyMotion feature of MC3419."); + return ret; + } + + i2cBuffer[0] = ANY_MOTION_THRESHOLD_LSB_REGISTER; + i2cBuffer[1] = (uint8_t)(threshold & 0x00FF); + ret = i2c_master_write_to_device(I2C_MASTER_NUM, MC3419_ADDR, &i2cBuffer[0], 2, (I2C_MASTER_TIMEOUT_MS)); + if(ret != ESP_OK) + { + ESP_LOGI(TAG, "Failed to set the value LSB threshold of MC3419."); + return ret; + } + + i2cBuffer[0] = ANY_MOTION_DEBOUNCE_REGISTER; + i2cBuffer[1] = 0x00; + ret = i2c_master_write_to_device(I2C_MASTER_NUM, MC3419_ADDR, &i2cBuffer[0], 2, (I2C_MASTER_TIMEOUT_MS)); + if(ret != ESP_OK) + { + ESP_LOGI(TAG, "Failed to set the value of DEBOUNCE_REGISTER of MC3419."); + return ret; + } + + // Enable AnyMotion feature. + i2cBuffer[0] = MOTION_CONTROL_REGISTER; + ret = i2c_get_accel_reg_byte(&i2cBuffer[0],&tempByte); + if(ret != ESP_OK) + { + ESP_LOGI(TAG, "Failed to enable AnyMotion feature of MC3419."); + return ret; + } + + // Motion block in reset? + if(0x80 == (tempByte & 0x80)) + { + ESP_LOGI(TAG, "Warning: resetting accelerometer motion control block."); + + // Reset Motion block. + i2cBuffer[0] = MOTION_CONTROL_REGISTER; + i2cBuffer[1] = 0x80; + esp_err_t ret = i2c_master_write_to_device(I2C_MASTER_NUM, MC3419_ADDR, &i2cBuffer[0], 2, (I2C_MASTER_TIMEOUT_MS)); + if(ret != ESP_OK) + { + ESP_LOGI(TAG, "Failed to Reset Motion block of MC3419."); + return ret; + } + } + + // Enable AnyMotion feature. + i2cBuffer[0] = MOTION_CONTROL_REGISTER; + i2cBuffer[1] = 0x04; + ret = i2c_master_write_to_device(I2C_MASTER_NUM, MC3419_ADDR, &i2cBuffer[0], 2, (I2C_MASTER_TIMEOUT_MS)); + if(ret != ESP_OK) + { + ESP_LOGI(TAG, "Failed to Enable AnyMotion feature again of MC3419."); + return ret; + } + + // Configure interrupt hardware pins. + i2cBuffer[0] = GPIO_CONTROL_REGISTER; + i2cBuffer[1] = 0xCC; // Configure both interrupt pins as push-pull, active high. + ret = i2c_master_write_to_device(I2C_MASTER_NUM, MC3419_ADDR, &i2cBuffer[0], 2, (I2C_MASTER_TIMEOUT_MS)); + if(ret != ESP_OK) + { + ESP_LOGI(TAG, "Failed to configure interrupt hardware pins of MC3419."); + return ret; + } + + /* Restore original mode.*/ + if(MC3419_STANDBY_MODE != tempMode) + { + ret = i2c_set_mc3419_mode(tempMode); + if(ret != ESP_OK) + { + ESP_LOGI(TAG, "Failed to restore the original mode of MC3419."); + return ret; // I2C error. + } + } + + // From MC3419 data sheet + if(MC3419_WAKE_MODE == tempMode) + vTaskDelay(1000 / portTICK_PERIOD_MS); + + // No error. Data valid. + return ret; + +} + +uint16_t get_accel_x(void) +{ + return accel_x; +} + +uint16_t get_accel_y(void) +{ + return accel_y; +} + +uint16_t get_accel_z(void) +{ + return accel_z; +} + + +/*MCP9600-Sensor functions*/ +/**********************************/ +bool i2c_initialize_thermocouple_sensor(void) +{ + bool flag = false; + if(ESP_OK == i2c_mcp9600_set_type(THERMOCOUPLE_TYPE_K)) + { + flag = true; + } + + if(ESP_OK == i2c_mcp9600_fetch_dev_id()) + { + ESP_LOGI(TAG, "MCP9600 part ID & Revision: %02X", get_mcp9600_devId()); + } + + if(ESP_OK != i2c_start_thermocoupleConversion()) + { + flag = false; + } + return flag; +} + +esp_err_t i2c_mcp9600_set_burst_mode(void) +{ + /* 1- Creating i2c buffer for sending and receiving */ + uint8_t i2cBuffer[2]; + + + /*A Burst Mode of one sample will execute, then device will go into Shutdown mode*/ + /* we have to clear the flags that are related to the previous conversion + * The configuration register is as following + * + * Bit7 | Bit6 | Bit5 | Bit4 | Bit3 | Bit2 | Bit1 | Bit0 + * ------------------------------------------------------------------------------ + * Cold-Junc| ADC Measurement | Burst Mode Temperature | Shutdown + * resol. | Resolution | Samples | Modes + * + *cold-Junction/Ambient Sensor Resolution: + * 0 = 0.0625°C + * 1 = 0.25°C + *bit 6-5 ADC Measurement Resolution: ADC Resolution bits (see Table 5-3): + * 00 =18-bit Resolution + * 01 =16-bit Resolution + * 10 =14-bit Resolution + * 11 =12-bit Resolution + *bit 4-2 Burst Mode Temperature Samples: Number of Temperature Samples bits + * 000 = 1 sample + * 001 = 2 samples + * 010 = 4 samples + * 011 = 8 samples + * 100 = 16 samples + * 101 = 32 samples + * 110 = 64 samples + * 111 = 128 samples + *bit 1-0 Shutdown Modes: Shutdown Mode bits + * 00 = Normal operation + * 01 = Shutdown mode + * 10 = Burst mode + * 11 = Unimplemented: this setting has no effect + * + * */ + + /* 3- Setting up the required sensor configurations */ + i2cBuffer[0] = MCP9600_DEVICE_CONFIG_REG; + i2cBuffer[1] = 0xA2; // 0.25C cold junction resolution, 16-bit ADC resolution, 1 sample when in Burst mode, Burst mode. + esp_err_t ret = i2c_master_write_to_device(I2C_MASTER_NUM, MCP9600_ADDR, &i2cBuffer[0], 2, (I2C_MASTER_TIMEOUT_MS)); + + if(ret != ESP_OK) + { + ESP_LOGI(TAG, "Failed to Burst-mode and its configuration to MCP9600."); + return ret; + } + + //Log the following message for indication + //ESP_LOGI(TAG,"Burst-mode and its configuration have been set to MCP9600\r\n"); + + vTaskDelay(1000 / portTICK_PERIOD_MS); + return ret; + +} + +esp_err_t i2c_mcp9600_fetch_dev_id(void) +{ + /* 1- Creating i2c buffer for sending and receiving */ + uint8_t i2cBuffer[2]; + + /* 2- LOOK FOR A MCP9600 SENSOR (THERMOCOOUPLE) */ + i2cBuffer[0] = MCP9600_DEVICE_ID_REVISION; + esp_err_t ret = i2c_master_write_to_device(I2C_MASTER_NUM, MCP9600_ADDR, &i2cBuffer[0], 1, (I2C_MASTER_TIMEOUT_MS)); + if(ret != ESP_OK) + { + ESP_LOGI(TAG, "Failed to send part ID request to MCP9600."); + return ret; + } + + /* Delay for some time Required by MCP9600 data sheet */ + vTaskDelay(100/portTICK_PERIOD_MS); + + /* Note that the MCP9600 chip reads out big endian. + * Chip ID must be 0x40 and revision must be greater than 0x13. + * Older chips have a bad bug in them. + * */ + + ret = i2c_master_read_from_device(I2C_MASTER_NUM, MCP9600_ADDR, &i2cBuffer[0], 2,(I2C_MASTER_TIMEOUT_MS)); + if(ESP_OK != ret) + { + ESP_LOGI(TAG, "Failed to receive any part ID response from MCP9600."); + } + + /*Store the device ID in its corresponding buffer*/ + mcp9600_idRevision = i2cBuffer[1] | (i2cBuffer[0] << 8); + return ret; +} + +uint16_t get_mcp9600_devId(void) +{ + return mcp9600_idRevision; +} + +esp_err_t i2c_start_thermocoupleConversion(void) +{ + esp_err_t ret = ESP_FAIL; + + /* 1- Creating i2c buffer for sending and receiving */ + uint8_t i2cBuffer[2]; + + /* we have to clear the flags that are related to the previous conversion + * (Clear Burst Complete and Th Update bits) + * The status register is as following + * + * Bit7 | Bit6 | Bit5 | Bit4 | Bit3 | Bit2 | Bit1 | Bit0 + * ------------------------------------------------------------------------------ + * Burst |TH Update| Short | Input | Alert 4 | Alert 3 | Alert 2 | Alert 1 + * Complete | | Circuit | Range | Status | Status | Status | Status + * + * Burst Complete: Burst Mode Conversions Status Flag bit + * 1 = TΔ register Burst mode conversions complete + * 0 = Writing ‘0’ has no effect + * Once Burst mode is enabled, this bit is normally set after the first burst is complete. User can clear it and + * poll the bit periodically until the next burst of temperature conversions is complete + * TH Update: Temperature Update Flag bit + * 1 = Temperature conversion complete + * 0 = Writing ‘0’ has no effect + * This bit is normally set. User can clear it and poll the bit until the next temperature conversion is complete + * + * */ + + /* 2- Clear both the Burst Complete flag and ThUpdate flag to start a new conversion */ + i2cBuffer[0] = MCP9600_STATUS_REG; + i2cBuffer[1] = 0xC0; + ret = i2c_master_write_to_device(I2C_MASTER_NUM, MCP9600_ADDR, &i2cBuffer[0], 2, (I2C_MASTER_TIMEOUT_MS)); + + if(ret != ESP_OK) + { + ESP_LOGI(TAG, "Failed to reset flags of MCP9600 that are related to previous conversion"); + return ret; + } + + ret = i2c_mcp9600_set_burst_mode(); + if(ESP_OK != ret) + { + return ret; + } + + //Log the following message for indication + //ESP_LOGI(TAG,"Setting up for new conversion process\r\n"); + + return ret; + +} + +esp_err_t i2c_fetch_thermocoupleTemp(void) +{ + esp_err_t ret = ESP_FAIL; + uint16_t temp; + uint8_t counter = 0; + + /* 1- Creating i2c buffer for sending and receiving */ + uint8_t i2cBuffer[2]; + + + /*Clear flags*/ + i2c_start_thermocoupleConversion(); + + /* 2- Wait until the previously-started conversions get completed */ + do + { + /*Send the request to read from the MCP9600 status register*/ + i2cBuffer[0] = MCP9600_STATUS_REG; + ret = i2c_master_write_to_device(I2C_MASTER_NUM, MCP9600_ADDR, &i2cBuffer[0], 1, (I2C_MASTER_TIMEOUT_MS)); + if(ESP_OK != ret) + { + ESP_LOGI(TAG, "Failed to send status request to MCP9600 sensor."); + return ret; + } + + /*Read the response from the MCP9600*/ + ret = i2c_master_read_from_device(I2C_MASTER_NUM, MCP9600_ADDR, &i2cBuffer[0], 1, (I2C_MASTER_TIMEOUT_MS)); + if(ESP_OK != ret) + { + ESP_LOGI(TAG, "Failed to receive any status response from MCP9600 sensor."); + return ret; + } + + /*Check the time-out*/ + counter++; + if (3 < counter){ // Wait for at least one complete temperature conversion to occur since waking up. This can take up to 332 milliseconds, including the temperature calculation time. + ESP_LOGI(TAG, "Timeout for getting data from MCP9600 sensor."); + return(ESP_FAIL); // Timeout. + } + + /* Delay for some time Required by MCP9600 data sheet */ + vTaskDelay(111/portTICK_PERIOD_MS); + + } while (!(i2cBuffer[0] & MCP9600_TH_UPDATE_BIT)); + + /* If Input Range Bit (temperature valid flag) is set then + * there is a sensor error, such as an open or shorted thermocouple, etc*/ + + /* 3- Check to ensure that input-range-bit didn't set*/ + if(!(i2cBuffer[0] & MCP9600_INPUT_RANGE_BIT)) + { + /* 4- Read the conversion result */ + /*Send the request to MCP9600 to read the temperature*/ + i2cBuffer[0] = MCP9600_HOT_JUNCTION_REG; + ret = i2c_master_write_to_device(I2C_MASTER_NUM, MCP9600_ADDR, &i2cBuffer[0],1, (I2C_MASTER_TIMEOUT_MS)); + if(ESP_OK != ret) + { + ESP_LOGI(TAG, "Failed to send temperature request to MCP9600 sensor."); + return ret; + } + + /*Read the response from MCP9600*/ + ret = i2c_master_read_from_device(I2C_MASTER_NUM, MCP9600_ADDR, &i2cBuffer[0], 2, (I2C_MASTER_TIMEOUT_MS)); + if(ESP_OK != ret) + { + ESP_LOGI(TAG, "Failed to receive any temperature response from MCP9600 sensor."); + return ret; + } + + /*Check if the temperature is equal or greater than zero*/ + /*temp = i2cBuffer[1] | (i2cBuffer[0] << 8); + if(temp >= 0) + thermocoupleTemp = (i2cBuffer[1]*16) + (i2cBuffer[0] /16); + else + thermocoupleTemp = (i2cBuffer[1]*16) + (i2cBuffer[0] /16) - 4096;*/ + + temp = i2cBuffer[1] | (i2cBuffer[0] << 8); + ulp_ulp_prev_thermocoupleTemp = ulp_ulp_thermocoupleTemp; + ulp_ulp_thermocoupleTemp = temp; + ulp_ulp_thermocoupleTemp /= 16; + thermocoupleTemp = temp/16.0; + if(temp & 0x8000) // Adjust for sign bit + { + ulp_ulp_thermocoupleTemp -= 4096; + thermocoupleTemp -= 4096; + } + + ulp_thermo_temp_raw = ulp_ulp_thermocoupleTemp; + + } + + /* Delay for some time Required by MCP9600 data sheet */ + vTaskDelay(100/portTICK_PERIOD_MS); + + return ret; + +} + +float get_thermocouple_data(void) +{ + return thermocoupleTemp; +} + +float get_prev_thermocouple_data(void) +{ + return ulp_ulp_prev_thermocoupleTemp; +} + +esp_err_t i2c_mcp9600_set_alert_config(alertNum_t alertNum) +{ + /* 1- Creating i2c buffer for sending and receiving */ + uint8_t i2cBuffer[2]; + + /* Bit7 | Bit6 | Bit5 | Bit4 | Bit3 | Bit2 | Bit1 | Bit0 + * ----------------------------------------------------------------------------------- + * Interrupt| --------------- | Monitor | Rise or | ActiveHigh | Comp/Int | Alert + * clear | | TH/TC | Fall | ActiveLow | | Enable + *bit 7 Interrupt Clear: Interrupt Clear bit + * 1 = Clears Interrupt flag (forced ‘0’ by device) + * 0 = Normal state or cleared state + *bit 6-5 Unimplemented: Read as ‘0’ + *bit 4 Monitor TH or TC: Temperature Maintain/Detect bit + * 1 = Alert monitor for TC cold-junction sensor + * 0 = Alert monitor for TH thermocouple temperature + *bit 3 Rise/Fall: Alert Temperature Direction bit + * 1 = Alert limit for falling or cooling temperatures + * 0 = Alert limit for rising or heating temperatures + *bit 2 Active-High/Low: Alert State bit + * 1 = Active-high + * 0 = Active-low + *bit 1 Comp./Int.: Alert Mode bit + * 1 = Interrupt mode: Interrupt clears bit (bit 7) – must be set to deassert the alert output + * 0 = Comparator mode + *bit 0 Alert Enable: Alert Output Enable bit + * 1 = Alert output is enabled + * 0 = Alert output is disabled + */ + + /* 3- Determine which Alert to set */ + switch(alertNum) + { + case 1: i2cBuffer[0] = MCP9600_ALERT1_CONFIG_REG; break; + case 2: i2cBuffer[0] = MCP9600_ALERT2_CONFIG_REG; break; + case 3: i2cBuffer[0] = MCP9600_ALERT3_CONFIG_REG; break; + case 4: i2cBuffer[0] = MCP9600_ALERT4_CONFIG_REG; break; + default: i2cBuffer[0] = 0; break; + } + + i2cBuffer[1] = 0b10000111; + esp_err_t ret = i2c_master_write_to_device(I2C_MASTER_NUM, MCP9600_ADDR, &i2cBuffer[0], 2, (I2C_MASTER_TIMEOUT_MS)); + + if(ret != ESP_OK) + { + ESP_LOGI(TAG, "Failed to set Alert%d configurations MCP9600.",alertNum); + return ret; + } + + //Log the following message for indication + ESP_LOGI(TAG,"Set Alert%d confiurations",alertNum); + + vTaskDelay(1000 / portTICK_PERIOD_MS); + return ret; + +} + +esp_err_t i2c_mcp9600_set_alert_limit(alertNum_t alertNum, float alertLimit) +{ + /* 1- Creating i2c buffer for sending and receiving */ + uint8_t i2cBuffer[3]; + uint16_t limitValue = 0; + uint16_t temp; + + /* 2- Determine which Alert to set */ + switch(alertNum) + { + case 1: i2cBuffer[0] = MCP9600_ALERT1_LIMIT_REG; break; + case 2: i2cBuffer[0] = MCP9600_ALERT2_LIMIT_REG; break; + case 3: i2cBuffer[0] = MCP9600_ALERT3_LIMIT_REG; break; + case 4: i2cBuffer[0] = MCP9600_ALERT4_LIMIT_REG; break; + default: i2cBuffer[0] = 0; break; + } + + + /*Check if the alert limit is positive or negative*/ + if(alertLimit < 0) + { + limitValue |= 0b0000100000000000; + alertLimit *= -1; + } + + /*init the value for the buffer*/ + if(alertLimit > 2047) + limitValue = 2047; + else + { + temp = (uint16_t)(alertLimit); + temp &= 0b0000011111111111; + limitValue = temp << 4; + } + + /*Estimate the fraction*/ + temp = (((uint16_t)(alertLimit*100)) % 100); + if(temp>=25 && temp<50) + limitValue &= 4; + else if(temp>=50 && temp<75) + limitValue &= 8; + else + limitValue &= 12; + + /* 3- Put the limit in the i2c buffer*/ + i2cBuffer[1] = limitValue>>8; //high byte firstly + i2cBuffer[2] = limitValue; //low byte secondly + + /*Send the limit*/ + esp_err_t ret = i2c_master_write_to_device(I2C_MASTER_NUM, MCP9600_ADDR, &i2cBuffer[0], 3, (I2C_MASTER_TIMEOUT_MS)); + + if(ret != ESP_OK) + { + ESP_LOGI(TAG, "Failed to set Alert%d limit MCP9600.",alertNum); + return ret; + } + + //Log the following message for indication + ESP_LOGI(TAG,"Set Alert%d limit",alertNum); + + vTaskDelay(1000 / portTICK_PERIOD_MS); + return ret; +} + +esp_err_t i2c_mcp9600_set_alert_hyst(alertNum_t alertNum, float alertHyst) +{ + /* 1- Creating i2c buffer for sending and receiving */ + uint8_t i2cBuffer[2]; + + /* 2- Determine which Alert to set */ + switch(alertNum) + { + case 1: i2cBuffer[0] = MCP9600_ALERT1_HYST_REG; break; + case 2: i2cBuffer[0] = MCP9600_ALERT2_HYST_REG; break; + case 3: i2cBuffer[0] = MCP9600_ALERT3_HYST_REG; break; + case 4: i2cBuffer[0] = MCP9600_ALERT4_HYST_REG; break; + default: i2cBuffer[0] = 0; break; + } + + /* 3- constrain alertHyst*/ + if(alertHyst > 255) + alertHyst = 255; + else if(alertHyst < 0) + alertHyst = 0; + + /*Put the Hyst in i2c buffer*/ + i2cBuffer[1] = (uint16_t)(alertHyst); + + /*Send the limit*/ + esp_err_t ret = i2c_master_write_to_device(I2C_MASTER_NUM, MCP9600_ADDR, &i2cBuffer[0], 2, (I2C_MASTER_TIMEOUT_MS)); + + if(ret != ESP_OK) + { + ESP_LOGI(TAG, "Failed to set Alert%d Hysteresis MCP9600.",alertNum); + return ret; + } + + //Log the following message for indication + ESP_LOGI(TAG,"Set Alert%d Hysteresis",alertNum); + + vTaskDelay(1000 / portTICK_PERIOD_MS); + return ret; + +} + +esp_err_t i2c_mcp9600_set_sleep(void) +{ + /* 1- Creating i2c buffer for sending and receiving */ + uint8_t i2cBuffer[2]; + + /* 2- Start new conversion */ + i2cBuffer[0] = MCP9600_DEVICE_CONFIG_REG; + i2cBuffer[1] = 0xA1; // 0.25C cold junction resolution, 16-bit ADC resolution, 1 sample when in Burst mode, Shutdown mode. + esp_err_t ret = i2c_master_write_to_device(I2C_MASTER_NUM, MCP9600_ADDR, &i2cBuffer[0], 2, (I2C_MASTER_TIMEOUT_MS)); + + if(ret != ESP_OK) + { + ESP_LOGI(TAG, "Failed to set Shutdown-mode and its configuration to MCP9600."); + return ret; + } + + //Log the following message for indication + ESP_LOGI(TAG,"Shutdown-mode and its configuration have been set to MCP9600\r\n"); + + vTaskDelay(1000 / portTICK_PERIOD_MS); + return ret; +} + +esp_err_t i2c_mcp9600_set_type(uint8_t thermocoupleType) +{ + uint8_t tempThermocoupleType; + + /* 1- Creating i2c buffer for sending and receiving */ + uint8_t i2cBuffer[2]; + + tempThermocoupleType = thermocoupleType; + tempThermocoupleType &= 0x70; // Keep thermocouple type. Set filter coefficient to "Filter off". + + /* 2- Start new conversion */ + i2cBuffer[0] = MCP9600_THERMOCOUPLE_CONFIG; + i2cBuffer[1] = tempThermocoupleType; + esp_err_t ret = i2c_master_write_to_device(I2C_MASTER_NUM, MCP9600_ADDR, &i2cBuffer[0], 2, (I2C_MASTER_TIMEOUT_MS)); + + if(ret != ESP_OK) + { + ESP_LOGI(TAG, "Failed to set thermocouple type of MCP9600."); + return ret; + } + + //Log the following message for indication + ESP_LOGI(TAG,"Thermocouple type has been set successfully\r\n"); + + vTaskDelay(1000 / portTICK_PERIOD_MS); + return ret; + + +} + + + +bool i2c_initialize_light_sensor(void) +{ + /* Fetch manufacturer ID */ + esp_err_t ret = i2c_opt3001_fetch_manufact_id(); + + if(ret != ESP_OK) + { + return false; + } + + /* Fetch Device ID */ + ret = i2c_opt3001_fetch_dev_id(); + + if(ret != ESP_OK) + { + return false; + } + + /* Set the Conversion-Time */ + ret = i2c_opt3001_set_conversion_time(CONVERSION_TIME_800Ms); + + if(ret != ESP_OK) + { + return false; + } + + /* Set the Converion-mode */ + ret = i2c_opt3001_set_conversion_mode(SINGLE_SHOT_CONVERSION_MODE); + + if(ret != ESP_OK) + { + return false; + } + + /* Set the FULL_SCALE_LUX range */ + ret = i2c_opt3001_set_full_lux_scale(FULL_SCALE_RANGE_LUX_655); + + if(ret != ESP_OK) + { + return false; + } + + return true; +} + +esp_err_t i2c_opt3001_fetch_manufact_id(void) +{ + /* 1- Creating i2c buffer for sending and receiving */ + uint8_t i2cBuffer[2]; + + /* 2- LOOK FOR A OPT3001 SENSOR (Light sensor) */ + i2cBuffer[0] = MANUFACTURER_ID_REGISTER; + esp_err_t ret = i2c_master_write_to_device(I2C_MASTER_NUM, OPT3001_ADDR, &i2cBuffer[0], 1, (I2C_MASTER_TIMEOUT_MS)); + if(ret != ESP_OK) + { + ESP_LOGI(TAG, "Failed to send manufacturer ID request to OPT3001."); + return ret; + } + + /* Delay for some time Required */ + vTaskDelay(100/portTICK_PERIOD_MS); + + + ret = i2c_master_read_from_device(I2C_MASTER_NUM, OPT3001_ADDR, &i2cBuffer[0], 2,(I2C_MASTER_TIMEOUT_MS)); + if(ESP_OK != ret) + { + ESP_LOGI(TAG, "Failed to receive any manufacturer ID response from OPT3001."); + } + else + { + ESP_LOGI(TAG, "The manufacturer ID response from OPT3001 is 0x%X%X",i2cBuffer[0],i2cBuffer[1]); + } + + return ret; + +} + +esp_err_t i2c_opt3001_fetch_dev_id(void) +{ + /* 1- Creating i2c buffer for sending and receiving */ + uint8_t i2cBuffer[2]; + + /* 2- LOOK FOR A OPT3001 SENSOR (Light sensor) */ + i2cBuffer[0] = DEVICE_ID_REGISTER; + esp_err_t ret = i2c_master_write_to_device(I2C_MASTER_NUM, OPT3001_ADDR, &i2cBuffer[0], 1, (I2C_MASTER_TIMEOUT_MS)); + if(ret != ESP_OK) + { + ESP_LOGI(TAG, "Failed to send Device ID request to OPT3001."); + return ret; + } + + /* Delay for some time Required */ + vTaskDelay(100/portTICK_PERIOD_MS); + + + ret = i2c_master_read_from_device(I2C_MASTER_NUM, OPT3001_ADDR, &i2cBuffer[0], 2,(I2C_MASTER_TIMEOUT_MS)); + if(ESP_OK != ret) + { + ESP_LOGI(TAG, "Failed to receive any Device ID response from OPT3001."); + } + else + { + ESP_LOGI(TAG, "The Device ID response from OPT3001 is 0x%X%X",i2cBuffer[0],i2cBuffer[1]); + } + + return ret; + +} + +uint16_t i2c_opt3001_fetch_configuration(void) +{ + /* 1- Creating i2c buffer for sending and receiving */ + uint8_t i2cBuffer[2]; + uint16_t config_reg; + + /* 2- LOOK FOR A OPT3001 SENSOR (Light sensor) */ + i2cBuffer[0] = CONFIGURATION_REGISTER; + esp_err_t ret = i2c_master_write_to_device(I2C_MASTER_NUM, OPT3001_ADDR, &i2cBuffer[0], 1, (I2C_MASTER_TIMEOUT_MS)); + if(ret != ESP_OK) + { + ESP_LOGI(TAG, "Failed to send configuration request to OPT3001."); + return 0xFFFF; + } + + /* Delay for some time Required */ + vTaskDelay(100/portTICK_PERIOD_MS); + + + ret = i2c_master_read_from_device(I2C_MASTER_NUM, OPT3001_ADDR, &i2cBuffer[0], 2,(I2C_MASTER_TIMEOUT_MS)); + if(ESP_OK != ret) + { + ESP_LOGI(TAG, "Failed to receive any configuration response from OPT3001."); + return 0xFFFF; + } + + config_reg = ((i2cBuffer[0]<<8)|i2cBuffer[1]); + return config_reg; + +} + +conversionFlagState_t i2c_opt3001_get_conv_ready_flag(void) +{ + /* Read the configuration register*/ + uint16_t config_reg = i2c_opt3001_fetch_configuration(); + + /* Check if MCU failed to read the configuration register */ + if(0xFFFF == config_reg) + { + return FAILED_TO_READ_CONVERSION_READY_FLAG; + } + + /* Extract and check the Conversion_ready_flag bit from the configuration register */ + if((config_reg & 7)) + return CONVERSION_READY_FLAG_IS_SET; + else + return CONVERSION_READY_FLAG_IS_NOT_SET_YET; + +} + +esp_err_t i2c_opt3001_fetch_light_data(void) +{ + conversionFlagState_t conv_flag; + uint16_t result; + uint8_t exponent; + uint8_t counter = 0; + + /* 1- Creating i2c buffer for sending and receiving */ + uint8_t i2cBuffer[3]; + + /* Set the Conversion-Time */ + esp_err_t ret = i2c_opt3001_set_conversion_time(CONVERSION_TIME_800Ms); + + if(ret != ESP_OK) + { + return ret; + } + + /* Set the Converion-mode */ + ret = i2c_opt3001_set_conversion_mode(SINGLE_SHOT_CONVERSION_MODE); + + if(ret != ESP_OK) + { + return ret; + } + + /* delay for 0.6 second for conversion process */ + vTaskDelay(850/portTICK_PERIOD_MS); + + /* Read the conversion ready flag */ + conv_flag = i2c_opt3001_get_conv_ready_flag(); + + /* Wait to complete the conversion process */ + //while(CONVERSION_READY_FLAG_IS_SET != conv_flag) + //{ + // if((conv_flag == FAILED_TO_READ_CONVERSION_READY_FLAG) || (counter == 20)) + // { + // if(conv_flag == FAILED_TO_READ_CONVERSION_READY_FLAG) + // { + // ESP_LOGI(TAG,"Failed to read light data from the OPT3001 sensor (issue with analog conversion process)"); + // } + // else if(counter == 20) + // { + // ESP_LOGI(TAG,"Failed to read light data from the OPT3001 sensor (timeout)"); + // } + // return ESP_FAIL; + // } + // + // /* Wait for another 100ms*/ + // vTaskDelay(100/portTICK_PERIOD_MS); + // counter++; + // + // /* Read the conversion ready flag */ + // conv_flag = i2c_opt3001_get_conv_ready_flag(); + //} + + /* Send the address of the result register */ + i2cBuffer[0] = RESULT_REGISTER; + ret = i2c_master_write_to_device(I2C_MASTER_NUM, OPT3001_ADDR, &i2cBuffer[0], 1, (I2C_MASTER_TIMEOUT_MS)); + if(ret != ESP_OK) + { + ESP_LOGI(TAG, "Failed to send result request to OPT3001."); + return ESP_FAIL; + } + + /* Delay for some time Required */ + vTaskDelay(100/portTICK_PERIOD_MS); + + /* Read the result register of the OPT3001 sensor */ + ret = i2c_master_read_from_device(I2C_MASTER_NUM, OPT3001_ADDR, &i2cBuffer[0], 2,(I2C_MASTER_TIMEOUT_MS)); + if(ESP_OK != ret) + { + ESP_LOGI(TAG, "Failed to receive any configuration response from OPT3001."); + return ESP_FAIL; + } + + //ESP_LOGI(TAG,"-----> Result register is equal to = 0x%X%X",i2cBuffer[0],i2cBuffer[1]); + + result = ((i2cBuffer[0]<<8) | i2cBuffer[1]); + result = result & 0x0FFF; + //exponent = (i2cBuffer[0] & 0xF0)>>4; + + //light_data = 0.01 * pow(2,exponent) * result; + prev_light_data = light_data; + light_data = light_full_scale * result; + ulp_light_data_opt = light_data; + + return ESP_OK; +} + +uint32_t get_light_data(void) +{ + return light_data; +} + +uint32_t get_prev_light_data(void) +{ + return prev_light_data; +} + +esp_err_t i2c_opt3001_set_full_lux_scale(fullScaleRangeLux_t scale) +{ + /*Note that the exponent field can be disabled (set to zero) by enabling the exponent mask (configuration register, + ME field = 1) and manually programming the full-scale range (configuration register, RN[3:0] < 1100b (0Ch)), + allowing for simpler operation in a manually-programmed, full-scale mode + */ + + /* 1- Creating i2c buffer for sending and receiving */ + uint8_t i2cBuffer[3]; + + uint8_t bit = 0; + + /* Read the configuration register*/ + uint16_t config_reg = i2c_opt3001_fetch_configuration(); + + + /* Check if MCU failed to read the configuration register */ + if(0xFFFF == config_reg) + { + return ESP_FAIL; + } + + /* Set the Mask-exponent-field bit to 1 */ + config_reg = config_reg | (1<<2); + + /* Check the requested Full-scale */ + for(uint8_t i = 0; i<4; i++) + { + bit = scale & (1<>8; + i2cBuffer[2] = config_reg&0xFF; + + /* Send the new value of the configuration register */ + esp_err_t ret = i2c_master_write_to_device(I2C_MASTER_NUM, OPT3001_ADDR, &i2cBuffer[0], 3, (I2C_MASTER_TIMEOUT_MS)); + if(ret != ESP_OK) + { + ESP_LOGI(TAG, "Failed to send/write the new FullScale-configuration to OPT3001."); + return ret; + } + else + { + switch(scale) + { + case FULL_SCALE_RANGE_LUX_40: + ESP_LOGI(TAG, "The new FullScale-configurations (40) have been written to OPT3001 successfully"); + break; + case FULL_SCALE_RANGE_LUX_82: + ESP_LOGI(TAG, "The new FullScale-configurations (82) have been written to OPT3001 successfully"); + break; + case FULL_SCALE_RANGE_LUX_164: + ESP_LOGI(TAG, "The new FullScale-configurations (164) have been written to OPT3001 successfully"); + break; + case FULL_SCALE_RANGE_LUX_327: + ESP_LOGI(TAG, "The new FullScale-configurations (327) have been written to OPT3001 successfully"); + break; + case FULL_SCALE_RANGE_LUX_655: + ESP_LOGI(TAG, "The new FullScale-configurations (655) have been written to OPT3001 successfully"); + break; + case FULL_SCALE_RANGE_LUX_1314: + ESP_LOGI(TAG, "The new FullScale-configurations (1314) have been written to OPT3001 successfully"); + break; + case FULL_SCALE_RANGE_LUX_2621: + ESP_LOGI(TAG, "The new FullScale-configurations (2621) have been written to OPT3001 successfully"); + break; + case FULL_SCALE_RANGE_LUX_5241: + ESP_LOGI(TAG, "The new FullScale-configurations (5241) have been written to OPT3001 successfully"); + break; + case FULL_SCALE_RANGE_LUX_10483: + ESP_LOGI(TAG, "The new FullScale-configurations (10483) have been written to OPT3001 successfully"); + break; + case FULL_SCALE_RANGE_LUX_20966: + ESP_LOGI(TAG, "The new FullScale-configurations (20966) have been written to OPT3001 successfully"); + break; + case FULL_SCALE_RANGE_LUX_41933: + ESP_LOGI(TAG, "The new FullScale-configurations (41933) have been written to OPT3001 successfully"); + break; + case FULL_SCALE_RANGE_LUX_83865: + ESP_LOGI(TAG, "The new FullScale-configurations (83865) have been written to OPT3001 successfully"); + break; + } + } + + /* Set the light_full_scale that will be used in the result calculation */ + light_full_scale = 0.01*pow(2,scale); + ulp_light_exponent = scale; + + return ret; +} + +esp_err_t i2c_opt3001_set_conversion_time(lightConversionTime_t CTime) +{ + /* 1- Creating i2c buffer for sending and receiving */ + uint8_t i2cBuffer[3]; + + /* Read the configuration register*/ + uint16_t config_reg = i2c_opt3001_fetch_configuration(); + + /* Check if MCU failed to read the configuration register */ + if(0xFFFF == config_reg) + { + return ESP_FAIL; + } + + /* Set the corresponding bits for the conversion-time in the configuration register */ + switch(CTime) + { + case CONVERSION_TIME_100Ms: config_reg = config_reg & (~(1<<11)); break; + case CONVERSION_TIME_800Ms: config_reg = config_reg | (1<<11); break; + } + + /* Send the new values for the configuration register */ + i2cBuffer[0] = CONFIGURATION_REGISTER; + i2cBuffer[1] = config_reg>>8; + i2cBuffer[2] = config_reg&0xFF; + + + esp_err_t ret = i2c_master_write_to_device(I2C_MASTER_NUM, OPT3001_ADDR, &i2cBuffer[0], 3, (I2C_MASTER_TIMEOUT_MS)); + if(ret != ESP_OK) + { + ESP_LOGI(TAG, "Failed to send/write the new Time-configuration to OPT3001."); + return ret; + } + else + { + //ESP_LOGI(TAG, "The new Time-configurations have been written to OPT3001 successfully"); + } + + return ret; + +} + +esp_err_t i2c_opt3001_set_conversion_mode(lightConversionMode_t CMode) +{ + /* 1- Creating i2c buffer for sending and receiving */ + uint8_t i2cBuffer[3]; + + /* Read the configuration register*/ + uint16_t config_reg = i2c_opt3001_fetch_configuration(); + + /* Check if MCU failed to read the configuration register */ + if(0xFFFF == config_reg) + { + return ESP_FAIL; + } + + /* Set the corresponding bits for the conversion-mode in the configuration register */ + switch(CMode) + { + case SHUT_DOWN_CONVERSION_MODE: + config_reg = config_reg & (~(1<<9)); + config_reg = config_reg & (~(1<<10)); + break; + case SINGLE_SHOT_CONVERSION_MODE: + config_reg = config_reg | (1<<9); + config_reg = config_reg & (~(1<<10)); + break; + case CONTINUOUS_CONVERSION_MODE: + config_reg = config_reg | (1<<9); + config_reg = config_reg | (1<<10); + break; + } + + /* Send the new values for the configuration register */ + i2cBuffer[0] = CONFIGURATION_REGISTER; + i2cBuffer[1] = config_reg>>8; + i2cBuffer[2] = config_reg&0xFF; + + esp_err_t ret = i2c_master_write_to_device(I2C_MASTER_NUM, OPT3001_ADDR, &i2cBuffer[0], 3, (I2C_MASTER_TIMEOUT_MS)); + if(ret != ESP_OK) + { + ESP_LOGI(TAG, "Failed to send/write the new mode-configuration to OPT3001."); + return ret; + } + else + { + //ESP_LOGI(TAG, "The new mode-configurations have been written to OPT3001 successfully"); + } + + return ret; + +} + diff --git a/main/i2c_sensors.h b/main/i2c_sensors.h new file mode 100644 index 0000000..64f94e4 --- /dev/null +++ b/main/i2c_sensors.h @@ -0,0 +1,281 @@ +/* + * i2c_sensors.h + * + * Created on: Jan 23, 2023 + * Author: Sword + */ + +#ifndef MAIN_I2C_SENSORS_H_ +#define MAIN_I2C_SENSORS_H_ + +// Sensor Addresses +#define ENS210_ADDR 0x43 // Base address of 0x43 left shifted one bit to make room for the read/#write bit. Temperature and humidity sensor +#define MCP9600_ADDR 0x60 // Base address of 0x60 left shifted one bit to make room for the read/#write bit. Thermocouple interface chip +#define MC3419_ADDR 0xD8 // Base address of 0x6C left shifted one bit to make room for the read/#write bit. Accelerometer +#define OPT3001_ADDR 0x44 + +// ENS210 Registers +#define ENS210_PART_ID 0x00 +#define ENS210_DIE_REV 0x02 +#define ENS210_UID 0x04 +#define ENS210_SYS_CTRL 0x10 +#define ENS210_SYS_STAT 0x11 +#define ENS210_SENS_RUN 0x21 +#define ENS210_SENS_START 0x22 +#define ENS210_SENS_STOP 0x23 +#define ENS210_SENS_STAT 0x24 +#define ENS210_T_VAL 0x30 +#define ENS210_H_VAL 0x33 + +// MCP9600 Registers +#define MCP9600_HOT_JUNCTION_REG 0x00 +#define MCP9600_DELTA_JUNCTION_REG 0x01 +#define MCP9600_COLD_JUNCTION_REG 0x02 +#define MCP9600_STATUS_REG 0x04 +#define MCP9600_THERMOCOUPLE_CONFIG 0x05 +#define MCP9600_DEVICE_CONFIG_REG 0x06 +#define MCP9600_ALERT1_CONFIG_REG 0x08 +#define MCP9600_ALERT2_CONFIG_REG 0x09 +#define MCP9600_ALERT3_CONFIG_REG 0x0A +#define MCP9600_ALERT4_CONFIG_REG 0x0B +#define MCP9600_ALERT1_HYST_REG 0x0C +#define MCP9600_ALERT2_HYST_REG 0x0D +#define MCP9600_ALERT3_HYST_REG 0x0E +#define MCP9600_ALERT4_HYST_REG 0x0F +#define MCP9600_ALERT1_LIMIT_REG 0x10 +#define MCP9600_ALERT2_LIMIT_REG 0x11 +#define MCP9600_ALERT3_LIMIT_REG 0x12 +#define MCP9600_ALERT4_LIMIT_REG 0x13 +#define MCP9600_DEVICE_ID_REVISION 0x20 + +// MCP9600 Bits +#define MCP9600_INPUT_RANGE_BIT 0x10 +#define MCP9600_BURST_COMPLETE_BIT 0x80 +#define MCP9600_TH_UPDATE_BIT 0x40 +#define MCP9600_ALERT_ENABLE_BIT 0x01 + +#define MCP9600_ALERT1_STATUS 0x01 +#define MCP9600_ALERT2_STATUS 0x02 +#define MCP9600_ALERT3_STATUS 0x04 +#define MCP9600_ALERT4_STATUS 0x08 + +// Thermocouple types: +#define THERMOCOUPLE_TYPE_K 0x00 +#define THERMOCOUPLE_TYPE_J 0x10 +#define THERMOCOUPLE_TYPE_T 0x20 +#define THERMOCOUPLE_TYPE_N 0x30 +#define THERMOCOUPLE_TYPE_S 0x40 +#define THERMOCOUPLE_TYPE_E 0x50 +#define THERMOCOUPLE_TYPE_B 0x60 +#define THERMOCOUPLE_TYPE_R 0x70 + +// MACRO DEFINITIONS + +//MC3419 +#define MC3419_ADDR 0x6C + +//MC3419 Modes +#define MC3419_STANDBY_MODE 0x00 +#define MC3419_WAKE_MODE 0x01 + +// MC3419 Registers +#define DEVICE_STATUS_REGISTER 0x05 +#define INTERRUPT_ENABLE_REGISTER 0x06 +#define GPIO_CONTROL_REGISTER 0x33 +#define MODE_REGISTER 0x07 +#define SAMPLE_RATE_REGISTER 0x08 +#define MOTION_CONTROL_REGISTER 0x09 + +#define FIFO_STATUS_REGISTER 0x0A +#define FIFO_READ_POINTER_REGISTER 0x0B +#define FIFO_WRITE_POINTER_REGISTER 0x0C + +#define XOUT_ACCELEROMETER_DATA_LSB_REGISTER 0x0D +#define XOUT_ACCELEROMETER_DATA_MSB_REGISTER 0x0E +#define YOUT_ACCELEROMETER_DATA_LSB_REGISTER 0x0F +#define YOUT_ACCELEROMETER_DATA_MSB_REGISTER 0x10 +#define ZOUT_ACCELEROMETER_DATA_LSB_REGISTER 0x11 +#define ZOUT_ACCELEROMETER_DATA_MSB_REGISTER 0x12 + +#define STATUS_REGISTER 0x13 +#define INTERRUPT_STATUS_REGISTER 0x14 +#define CHIP_IDENTIFICATION_REGISTER 0x18 +#define RESET_REGISTER 0x1C +#define RANGE_SELECT_CONTROL_REGISTER 0x20 + +#define X_OFFSET_LSB_REGISTER 0x21 +#define X_OFFSET_MSB_REGISTER 0x22 +#define Y_OFFSET_LSB_REGISTER 0x23 +#define Y_OFFSET_MSB_REGISTER 0x24 +#define Z_OFFSET_LSB_REGISTER 0x25 +#define Z_OFFSET_MSB_REGISTER 0x26 + +#define X_GAIN_REGISTER 0x27 +#define Y_GAIN_REGISTER 0x28 +#define Z_GAIN_REGISTER 0x29 + +#define FIFO_CONTROL_REGISTER 0x2D +#define FIFO_THRESHOLD_REGISTER 0x2E +#define FIFO_INTERRUPT_STATUS_REGISTER 0x2F +#define FIFO_CONTROL_2_AND_SAMPLE_RATE_2_REGISTER 0x30 + +#define COMM_CONTROL_REGISTER 0x31 +#define GPIO_CONTROL_REGISTER 0x33 +#define SECURITY_OPT_REGISTER 0x3B + +#define TILT_FLIP_THRESHOLD_LSB_REGISTER 0x40 +#define TILT_FLIP_THRESHOLD_MSB_REGISTER 0x41 +#define TILT_FLIP_DEBOUNCE_REGISTER 0x42 + +#define ANY_MOTION_THRESHOLD_LSB_REGISTER 0x43 +#define ANY_MOTION_THRESHOLD_MSB_REGISTER 0x44 +#define ANY_MOTION_DEBOUNCE_REGISTER 0x45 + +#define SHAKE_THRESHOLD_LSB_REGISTER 0x46 +#define SHAKE_THRESHOLD_MSB_REGISTER 0x47 +#define PEAK_TO_PEAK_DURATION_LSB_REGISTER 0x48 +#define SHAKE_DURATION_AND_PEAK_TO_PEAK_DURATION_MSB_REGISTER 0x49 + +#define TIMER_CONTROL_REGISTER 0x4A +#define READ_COUNT_REGISTER 0x4B + + +//OPT3001 Registers addresses +#define RESULT_REGISTER 0x00 +#define CONFIGURATION_REGISTER 0x01 +#define LOW_LIMIT_REGISTER 0x02 +#define HIGH_LIMIT_REGISTER 0x03 +#define MANUFACTURER_ID_REGISTER 0x7E +#define DEVICE_ID_REGISTER 0x7F + + +//Enable/Disable ACK +#define ACK_EN 1 +#define NACK_EN 0 + + +typedef enum +{ + ALERT1 = 1, + ALERT2, + ALERT3, + ALERT4, +}alertNum_t; + +typedef enum +{ + CONVERSION_TIME_100Ms, + CONVERSION_TIME_800Ms +}lightConversionTime_t; + +typedef enum +{ + SHUT_DOWN_CONVERSION_MODE, + SINGLE_SHOT_CONVERSION_MODE, + CONTINUOUS_CONVERSION_MODE +}lightConversionMode_t; + +typedef enum +{ + CONVERSION_READY_FLAG_IS_SET, + CONVERSION_READY_FLAG_IS_NOT_SET_YET, + FAILED_TO_READ_CONVERSION_READY_FLAG, +}conversionFlagState_t; + +typedef enum +{ + FULL_SCALE_RANGE_LUX_40, + FULL_SCALE_RANGE_LUX_82, + FULL_SCALE_RANGE_LUX_164, + FULL_SCALE_RANGE_LUX_327, + FULL_SCALE_RANGE_LUX_655, + FULL_SCALE_RANGE_LUX_1314, + FULL_SCALE_RANGE_LUX_2621, + FULL_SCALE_RANGE_LUX_5241, + FULL_SCALE_RANGE_LUX_10483, + FULL_SCALE_RANGE_LUX_20966, + FULL_SCALE_RANGE_LUX_41933, + FULL_SCALE_RANGE_LUX_83865, +}fullScaleRangeLux_t; + +/*union for 2 bytes access and indivisual byte access*/ +union byteAccessibleInt16 +{ + int16_t accessAsInt16; + uint8_t accessAsByte[2]; +}; + +union byteAccessibleUint16 +{ + uint16_t accessAsUint16; + uint8_t accessAsByte[2]; +}; + +//Initialize the esp32 as i2c-master +void i2c_master_init(void); + +//Start-measuring and Reading function for the temperature and humidity sensor +bool i2c_initialize_temp_humidity_sensor(void); +esp_err_t i2c_ens210_fetch_dev_id(void); +uint16_t get_ens210_devId(void); +esp_err_t i2c_start_temp_humid(void); +esp_err_t i2c_stop_temp_humid(void); +esp_err_t i2c_ens210_set_active_mode(void); +esp_err_t i2c_fetch_temp(void); +esp_err_t i2c_fetch_humid(void); +float get_temperature_data(void); +float get_prev_temperature_data(void); +float get_humidity_data(void); +float get_prev_humidity_data(void); + +//Read the accelerometer input interrupt-flag +void readAccelerometerInterruptFlag(void); + +//Start-measuring and Reading functions for the Thermocouple sensor +void detectThermocoupleChip(void); +void startThermocoupleConversion(void); +void readThermocoupleTemperature(void); + +bool i2c_initialize_accel_sensor(void); +esp_err_t i2c_fetch_mc3419_chipId(void); +uint16_t get_mc3419_chipId(void); +esp_err_t i2c_fetch_accel_pos(void); +esp_err_t i2c_set_mc3419_mode(uint8_t mode); +esp_err_t i2c_get_mc3419_state(void); +esp_err_t i2c_clear_mc3419_int_flag(void); +esp_err_t i2c_get_mc3419_int_flags(uint8_t *flags); +esp_err_t i2c_enable_mc3419_motion_int(bool enableFlag); +esp_err_t i2c_set_mc3419_motionThreshold(uint16_t threshold); +uint16_t get_accel_x(void); +uint16_t get_accel_y(void); +uint16_t get_accel_z(void); + + +bool i2c_initialize_thermocouple_sensor(void); +esp_err_t i2c_mcp9600_fetch_dev_id(void); +uint16_t get_mcp9600_devId(void); +esp_err_t i2c_start_thermocoupleConversion(void); +esp_err_t i2c_fetch_thermocoupleTemp(void); +float get_thermocouple_data(void); +float get_prev_thermocouple_data(void); +esp_err_t i2c_mcp9600_set_burst_mode(void); +esp_err_t i2c_mcp9600_set_alert_config(alertNum_t alertNum); +esp_err_t i2c_mcp9600_set_alert_limit(alertNum_t alertNum, float alertLimit); +esp_err_t i2c_mcp9600_set_alert_hyst(alertNum_t alertNum, float alertHyst); +esp_err_t i2c_mcp9600_set_sleep(void); +esp_err_t i2c_mcp9600_set_type(uint8_t thermocoupleType); + + +bool i2c_initialize_light_sensor(void); +esp_err_t i2c_opt3001_fetch_dev_id(void); +esp_err_t i2c_opt3001_fetch_manufact_id(void); +uint16_t i2c_opt3001_fetch_configuration(void); +esp_err_t i2c_opt3001_fetch_light_data(void); +conversionFlagState_t i2c_opt3001_get_conv_ready_flag(void); +uint32_t get_light_data(void); +uint32_t get_prev_light_data(void); +esp_err_t i2c_opt3001_set_full_lux_scale(fullScaleRangeLux_t scale); +esp_err_t i2c_opt3001_set_conversion_time(lightConversionTime_t CTime); +esp_err_t i2c_opt3001_set_conversion_mode(lightConversionMode_t CMode); + +#endif /* MAIN_I2C_SENSORS_H_ */ diff --git a/main/main.c b/main/main.c new file mode 100644 index 0000000..abc8060 --- /dev/null +++ b/main/main.c @@ -0,0 +1,48 @@ + +#include +#include +#include +#include "esp_log.h" +#include "nvm.h" +#include "port.h" +#include "uart_ifx.h" +#include "wifi_webServer.h" +#include "comms.h" +#include "main.h" + +static const char* TAG = "MAIN"; +uint8_t comms_mode = DEFAULT_COMMS_MODE; +void app_main(void) +{ + + ESP_LOGI(TAG,"*** Starting app_main ***"); + + /* Initialize the dedicated NVS partition */ + nvm_init(); + port_init(); + uart_ifx_init(); + + /* Create the UART tasks for both UART0 and UART1 */ + uart_create_rx_tasks(); + + /* read the comms-mode from the NVS (if any) */ + comms_mode = nvm_read_comms_mode(); + + if((COMMS_OVER_CELL != comms_mode)) + { + /* Start On-Boarding process */ + webserver_start(); + + /* Wait till the onboarding process is completed */ + while(!webserver_get_status()) + { + //ESP_LOGI(TAG," -------------> PASSWORD is: %s",wifi_get_pswd()); + vTaskDelay(750/portTICK_PERIOD_MS); + } + } + + ESP_LOGI(TAG," -------------> Wifi Connected ... :)"); + + while(1); + vTaskDelete(NULL); +} diff --git a/main/main.h b/main/main.h new file mode 100644 index 0000000..698c0ff --- /dev/null +++ b/main/main.h @@ -0,0 +1,33 @@ +/* + * main.h + * + * Created on: Feb 11, 2023 + * Author: Nael + */ + +#ifndef MAIN_MAIN_H_ +#define MAIN_MAIN_H_ + +#define SENS_INT_WAKEUP 0 +#define SENS_INT_WAKEUP0 1 + +/*************** Cellular Configs **************/ +#define FAKE_NETWORK 0 +#define TEMPSTICK_SERVER 1 +#define TESTING_SERVER 1 // 0 Partha server, 1 Ranjeet server. +/***********************************************/ + +/***************** WIFI Configs ****************/ +#define WIFI_NEEDED 1 +/***********************************************/ + +#define DEFAULT_COMMS_MODE 1 + +void update_checkin_timer(uint64_t checkin_interval); +#if (SENS_INT_WAKEUP == 1) +void set_periodic_sleep_mode(); +#else +void set_sleep_mode(); +#endif + +#endif /* MAIN_MAIN_H_ */ diff --git a/main/modem.c b/main/modem.c new file mode 100644 index 0000000..4c6d673 --- /dev/null +++ b/main/modem.c @@ -0,0 +1,3109 @@ +/* + * bg96.c + * + * Created on: Jan 11, 2023 + * Author: Sword + */ + +/* Includes -----------------------------------------------------------------*/ +#include "uart_ifx.h" +#include "port.h" +#include "esp_system.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include +#include +#include "esp_timer.h" +#include +#include +#include "rtc.h" +#include "modem.h" + +static const char* TAG = "BG77"; + +#define LOG_LOCAL_LEVEL ESP_LOG_INFO +#include "esp_log.h" + +/* Logging configuration */ +#define LOG_MODULE "BG77" +#define LOG_LEVEL LOG_LEVEL_INFO + +/* Local buffer to formulate commands as necessary */ +#define MODEM_TX_BUFFER_LEN 3072 + +/* Modem receiver buffer: expected to hold entire response for any command */ +#define MODEM_RX_BUFFER_LEN 4096 + +/* This drive is expecting this particular device in the ATI response */ +#define MODEM_DEVICE_MATCH_STRING "BG77" + +/* Match the expected service mode int the QCSQ command for signal strength. + * For CAT-M1, string differs my modem model, e.g. "CAT-M1" for BG96, "eMTC" for BG77 + */ +#define MODEM_QCSQ_SERIVCE_MODE_MATCH_1 "eMTC" +#define MODEM_QCSQ_SERIVCE_MODE_MATCH_2 "NBIoT" + +/* Modem QFREAD chunk size. This must fit into the RX buffer taking into + * account possible responses + */ +#define MODEM_FREAD_SIZE (MODEM_RX_BUFFER_LEN - 128) + +/* Maximum number of QFREAD command issuances (retries) we will use to transfer a file. + * The actual number of QFREAD command issuances is dependent upon the file size determined by QFLST. + */ +#define MODEM_FREAD_MAX_PACKET_TRANSFERS 196 + +#define MODEM_IMEI_START 2 /* ignore first 2 characters */ +#define MODEM_IMEI_LEN 16 + +#define BG96_ICCID_START 10 /* ignore first 8 characters */ +#define BG96_ICCID_LEN 20 + +#define JWT_LEN 442 + +/* Max number of bytes that can be sent after QMTPUB command */ +#define MODEM_MQTT_PUB_BYTES_MAX 1548 + +/* Set to 1 to enable the use of BG96 STATUS pin to improve reliability + * and speed of modem power up and shutdown operations. + */ +#define MODEM_USE_STATUS_PIN 1 + +/* Time to wait for modem to turn on */ +#define MODEM_STARTUP_STATUS_TIMEOUT_MS 10000 + +/* Time to wait for modem AT interface to ready */ +#define MODEM_STARTUP_RDY_TIMEOUT_MS 5000 + +/* Granularity of the process timer for polling events */ +#define MODEM_TIMER_GRANULARITY_MS 500 + +/* Maximum number of commands supported in one sequence */ +#define MODEM_MAX_SEQUENCE 17 + +/* Unique timer ID for this process for use with timer module */ +//#define MODEM_TIMER_ID 0 + +/* 500-1000 ms */ +#define MODEM_PWRKEY_ON_DELAY_MS 750 + +/* 650-1500 ms */ +#define MODEM_PWRKEY_OFF_DELAY_MS 1000 + +/* >= 2000 ms */ +#define MODEM_PWRKEY_RESET_DELAY_MS 2500 + +/* Set to enable QHTTP OK parsing, clear to timeout and parse anyways */ +#define USE_QHTTPREAD_OK 1 + +/* Periodic monitoring of STATUS while waiting to confirm shutdown */ +#define MODEM_SHUTDOWN_STATUS_MONITOR_PERIOD_MS 2000 + +#define MODEM_SHUTDOWN_COUNT_WARNING_SEC 10 + +#define MODEM_SHUTDOWN_COUNT_LIMIT_SEC 65 + +/* Indicate modem power as indicated with STATUS line on green LED. */ +#define MODEM_DEBUG_MODEM_POWER_STATE 0 + +/* Enable the "blind modem" option to ignore the STATUS line state + * and the "APP RDY" indication when turning on and off the modem. + */ +#define MODEM_BLIND_MODEM 0 + +#define MODEM_MODEM_FWVER_FROM_QGMR 1 + +/* ------------------------------------------------------------------------- */ + +typedef enum { + MODEM_EVENT_START, + MODEM_EVENT_TIMER, + MODEM_EVENT_UART, + MODEM_EVENT_STOP, + MODEM_EVENT_SEND_CMD, +} modem_event_t; + +/* State of the bg96 process */ +typedef enum { + MODEM_STATE_INIT, + MODEM_STATE_READY, + MODEM_STATE_WAIT_POWERUP, + MODEM_STATE_WAIT_STARTUP, + MODEM_STATE_WAIT_STARTUP_RDY, + MODEM_STATE_WAIT_POWERDOWN, + MODEM_STATE_WAIT_POWERKEY, + MODEM_STATE_CMD, + +} modem_state_t; + +/* Status is OK (match response), ERROR (match error) or TIMEOUT (retries and/or wait exhausted). + * Returns OK or ERROR in processing to help direct which command to call subsequently in + * the sequence. + */ +typedef int (*modem_cmd_handler_t)(int status, const char *buf, int len); + +/* Command setup function, passed the parameters + * Intended to write to tx buf and assign that as the command. + * Return OK to assign buf as cmd_str. + * Must print a null-terminated string. + */ +typedef int (*modem_cmd_setup_t)(const void *params, char *buf, int len); + +/* Allows command to send custom information */ +typedef int (*modem_send_t)(void); + +typedef struct { + const char *host; + int port; + const char *client_id; + //const char* jwt; + const char *pub_topic; + const char *pub_data; + int pub_data_len; + +} modem_mqtt_setup_params_t; + +typedef struct { + /* input params */ + const char *url; + const char *file; /* for get_to_file */ + const char *post_message; + + /* output params */ + char *buf; + int len; + +} modem_http_setup_params_t; + +typedef struct { + const char *file; + uint32_t file_size; + uint32_t transferred_bytes; + uint16_t chunk_size; + uint16_t expected_bytes; + uint16_t read_size; + uint16_t file_handle; /* from +QFOPEN: */ + + modem_read_from_file_open open_cb; + modem_read_from_file_data data_cb; + +} modem_file_params_t; + +typedef struct { + + const char *cmd_str; + const char *response_match_str; /* null allowed */ + const char *err_match_str; /* null allowed */ + + const int wait_ms; + const int retries; + + /* Called after command is sent */ + const modem_send_t send; + + /* Called on timeout or match on response or err strings. */ + const modem_cmd_handler_t handler; + + /* Called on command setup */ + const modem_cmd_setup_t setup; + + /* Pointer to setup parameters */ + const void *params; + +} modem_cmd_t; + +typedef struct { + modem_state_t state; + + /* Timer */ + bool poll_timer; + + /* UART queue flag */ + bool poll_uart; + + /* Poll periods counter in units of timer granularity */ + int poll_periods; + + /* User start callback */ + modem_start_cb_t start_cb; + + /* Command processing state */ + bool is_startup; /* in startup mode */ + + /* Command sequencer */ + const modem_cmd_t *cmd_list[MODEM_MAX_SEQUENCE]; /* list of commands*/ + int cmd_num; /* number in list */ + int cmd_retries; /* count of retries */ + int cmd_sequence; /* current command in list */ + bool cmd_repeat; /* option to repeat a command if set true */ + modem_op_cb_t cmd_complete_cb; + + /* Device IMEI */ + char imei[MODEM_IMEI_LEN]; + char iccid[BG96_ICCID_LEN]; + + /* Device FW version e.g. BG95M2LAR01A01 or BG77LAR02A02_01.001.01.001 */ + char fw_ver[MODEM_FWVER_LEN]; + + modem_signal_strength_t sig_strength; + + /* Command parameters */ + modem_mqtt_setup_params_t mqtt_params; + modem_http_setup_params_t http_params; + modem_file_params_t file_params; + + /* Shutdown state monitoring */ + int shutdown_counter; + bool shutdown_qpowd; + uint16_t shutdown_qpowd_failures; + uint16_t shutdown_pwrkey_failures; + +} modem_t; + +/* Local process state */ + +static modem_t bg96; + +esp_timer_handle_t modem_timer; +/* ------------------------------------------------------------------------- */ + +/* comm buffers */ +static char txBuf[MODEM_TX_BUFFER_LEN]; +static char rxBuf[MODEM_RX_BUFFER_LEN]; +static uint16_t rx_idx = 0; + +/************** Device-Comms-Data *************/ +extern uint8_t comms_mode; + +/* Signal strength data stored after GetSignalStrength is called. */ +//static MODEM_SignalStrength_t m_signalStrength; +/* Wrapping scanner treats RX buffer like a circular buffer and retains state + * over calls. It allows scanning for strings that might wrap around. + */ +typedef struct { + int RxScannerState; + int RxScannerIdx; +} ScanContext_t; + +static ScanContext_t RxScanContextSuccess; /* scanner for success string */ +static ScanContext_t RxScanContextError; /* scanner for failure string */ +/* AT Commands -------------------------------------------------------------*/ + +// Note: These AT commands end with AT_OK response +// ATI, +#define ATI "ATI\r\n" +#define AT_QPOWD "AT+QPOWD\r\n" +//#define AT_CGDCONT "AT+CGDCONT=1,\"IPV4V6\",\"\",\"0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0\",0,0,0,0\r\n" +//#define AT_CGDCONT_ALT "AT+CGDCONT=1,\"IP\",\"\"\r\n" +#define AT_CGDCONT "AT+CGDCONT=1,\"IPV4V6\",\"hologram\"\r\n" +#define AT_QICSGP "AT+QICSGP=1,1,\"\",\"\",\"\",0\r\n" +#define AT_QIACT "AT+QIACT=1\r\n" + +#define AT_QHTTPPOST "AT+QHTTPPOST=%u,80,60\r\n" +#define AT_QHTTPCFG_RHD "AT+QHTTPCFG=\"requestheader\",1\r\n" +#define AT_QHTTPCFG_RHD_0 "AT+QHTTPCFG=\"requestheader\",0\r\n" +#define AT_QHTTPCFG_CTX "AT+QHTTPCFG=\"contextid\",1\r\n" +#define AT_QHTTPURL "AT+QHTTPURL=%u,80\r\n" /* host */ +#define AT_QHTTPGET "AT+QHTTPGET=80\r\n" +#define AT_QHTTPREAD "AT+QHTTPREAD=80\r\n" +#define AT_QHTTPREADFILE "AT+QHTTPREADFILE=\"%s\",80\r\n" /* file name */ + +#define AT_QFLDS "AT+QFLDS=\"UFS\"" +#define AT_QFLST "AT+QFLST=\"%s\"\r\n" /* file name */ +#define AT_QFOPEN "AT+QFOPEN=\"%s\",2\r\n" /* file name, mode=2 (readonly, fail if not found) */ +#define AT_QFREAD "AT+QFREAD=%d,%u\r\n" /* file handle, chunk size */ +#define AT_QFCLOSE "AT+QFCLOSE=%d\r\n" /* file handle */ +#define AT_QFOTADL "AT+QFOTADL=%s\r\n" /* host */ +#define AT_ECHO_OFF "ATE0\r\n" +#define AT_CGSN "AT+CGSN\r\n" +#define AT_QCCID "AT+QCCID\r\n" +#define AT_CGMR "AT+CGMR\r\n" +#define AT_QGMR "AT+QGMR\r\n" +#define AT_CPIN "AT+CPIN?\r\n" +#define AT_CFUN_OFF "AT+CFUN=0\r\n" +#define AT_CFUN_FULL "AT+CFUN=1\r\n" +#define AT_COPS "AT+COPS?\r\n" +#define AT_QCFG_IOTOPMODE "AT+QCFG=\"iotopmode\",2,1\r\n" /* LTE-M immediately */ +#define AT_QMTCFG_WILL "AT+QMTCFG=\"will\",0\r\n" +#define AT_QMTCFG_TIMEOUT "AT+QMTCFG=\"timeout\",0,60,3,1\r\n" /* Qianwen, used to be: "AT+QMTCFG=\"timeout\",0,60,3,0\r\n", 1000 */ +#define AT_QMTCFG_KEEPALIVE "AT+QMTCFG=\"keepalive\",0,60\r\n" +#define AT_QMTOPEN "AT+QMTOPEN=0,\"%s\",%d\r\n" /* host, port */ +#define AT_QMTCLOSE "AT+QMTCLOSE=0\r\n" +#define AT_QMTDISC "AT+QMTDISC=0\r\n" +//#define AT_QMTCONN_CID "AT+QMTCONN=0,\"projects/pwc-production/locations/us-central1/registries/unwiredprime/devices/CTD-%s\",\"unused\",\"%s\"\r\n" /* clientID, username,password */ +#define AT_QMTCONN_CID "AT+QMTCONN=0,\"%s\"\r\n" /* clientID*/ +#define AT_QMTPUB "AT+QMTPUB=0,0,0,0,\"/devices/CTD-%s/events\"\r\n" /* topic, note that actual message data follows " and that \r\n is likely sent to the server */ +#define AT_QCSQ "AT+QCSQ\r\n" +#define AT_CTZU "AT+CTZU=1\r\n" +#define AT_CCLK "AT+CCLK?\r\n" +#define AT_IFC "AT+IFC=2,2\r\n" +#define AT_QFDEL "AT+QFDEL=\"" MCU_OTA_FILE_LOCAL "\"\r\n" +#define AT_QFUPL "AT+QFUPL=\"cacert.pem\",1244,100\r\n" +#define AT_QMTCFG_SSL "AT+QMTCFG=\"ssl\",0,1,0\r\n" +#define AT_QSSLCFG_CACERT "AT+QSSLCFG=\"cacert\",0,\"cacert.pem\"\r\n" +#define AT_QSSLCFG_SECLEVEL "AT+QSSLCFG=\"seclevel\",0,0\r\n" +#define AT_QSSLCFG_SSLVER "AT+QSSLCFG=\"sslversion\",0,3\r\n" +#define AT_QSSLCFG_CIPH "AT+QSSLCFG=\"ciphersuite\",0,0XFFFF\r\n" +#define AT_QSSLCFG_IGNRTIME "AT+QSSLCFG=\"ignorelocaltime\",0,1\r\n" +#define AT_QMTCFG_VERSION "AT+QMTCFG=\"version\",0,4\r\n" + +/* Responses */ +#define AT_OK "\r\nOK\r\n" +#define AT_ERROR "\r\nERROR\r\n" +#define AT_CONNECT "CONNECT\r\n" +#define AT_HTTPPOST_SUCCESS "+QHTTPPOST: 0,200" +#define AT_QHTTPGET_SUCCESS "\r\n+QHTTPGET: 0,200" +#define AT_QHTTPREAD_SUCCESS "+QHTTPREAD: 0" +#define AT_QHTTPREADFILE_SUCCESS "\r\n+QHTTPREADFILE: 0" +#define AT_QFLST_SUCCESS "\r\n+QFLST: \"%s\"" +#define AT_QFOPEN_SUCCESS "\r\n+QFOPEN:" +#define AT_CPIN_RESPONSE "\r\n+CPIN: READY" /* every response will be at least this long */ +#define AT_IND_QMTOPEN "\r\n+QMTOPEN: 0,0" +#define AT_IND_QMTCONN "\r\n+QMTCONN: 0,0,0" +#define AT_IND_QMTPUB "\r\n+QMTPUB: 0,0,0" +#define AT_IND_QFUPL "\r\n+QFUPL:" +#define AT_IND_QMTCLOSE "\r\n+QMTCLOSE: 0,0" +#define AT_IND_CME_ERROR "\r\n+CME ERROR:" +#define AT_QENG_RESPONSE "\r\n+QENG:" //Partha = March 11, 2022 + +/* Unsolicited Result Codes */ +#define URC_RDY "\r\nRDY\r\n" + +#define CTRLZ (0x1A) +#define ESC (0x1B) + +/* Notes: + * Possiblity of getting time from the network. + * Using NITZ method, BGxx may automatically obtain it and set it in internal RTC. + * Command sequence: + * AT+CTZU=1 enable automatic timezone update (in effect automatic time update) + * optional: AT+CTZR=2 automatic timezone reporting: emit +CTZV indication + * Get time: AT+CCLK? + * + */ + +/* --------------------------------------------------------------------------*/ + +//definition a new function to return signal strength +int modem_Rssi() { + + return bg96.sig_strength.rssi; + +} + +char* modem_get_rxbuf(void) +{ + return (char*)(rxBuf); +} + + +/* Transfer bytes from queue to supplied buffer */ +int board_uart_rx_stream_poll(uint8_t* buf, uint16_t* rx_idx, int buf_len) +{ + int bytesCopied = 0; + //vTaskDelay(10 / portTICK_PERIOD_MS); + while(uart_ifx_uart1_ifx_get_rx_data(&buf[(*rx_idx)++]) && (*rx_idx <= buf_len)) + { + bytesCopied++; + } + return bytesCopied; +} + + +/* forward decl */ +static int start_cmd_sequence(void); + +static int handle_imei_cmd(int status, const char *buf, int len) { + int retval = MODEM_STATUS_ERROR; + + if (status == MODEM_STATUS_OK) { + strncpy(bg96.imei, buf + MODEM_IMEI_START, MODEM_IMEI_LEN); + bg96.imei[MODEM_IMEI_LEN - 1] = 0; + + ESP_LOGI(TAG,"IMEI No: %s\r\n", bg96.imei); + + retval = MODEM_STATUS_OK; + } + + return retval; +} + +#define ATI_REVISION_STR "Revision: " + + + +static int handle_iccid_cmd(int status, const char* buf, int len){ + + int retval = MODEM_STATUS_ERROR; + + if (status == MODEM_STATUS_OK) + { + strncpy(bg96.iccid, buf + BG96_ICCID_START, BG96_ICCID_LEN); + bg96.iccid[BG96_ICCID_LEN - 1] = '\0'; + + ESP_LOGI(TAG,"ICCID No: %s", bg96.iccid); + retval = MODEM_STATUS_OK; + } + + return retval; +} + +static int handle_ati_cmd(int status, const char *buf, int len) { + int retval = MODEM_STATUS_ERROR; + + if (status == MODEM_STATUS_OK) { + /* Find the expected device type */ + if (strstr(buf, MODEM_DEVICE_MATCH_STRING) != NULL) { + retval = MODEM_STATUS_OK; + + ESP_LOGI(TAG,MODEM_DEVICE_MATCH_STRING " detected!\r\n"); + } else { + ESP_LOGW(TAG,"Device " MODEM_DEVICE_MATCH_STRING "not detected\r\n"); + } + +#if MODEM_MODEM_FWVER_FROM_QGMR == 0 + /* Find the firmware version */ + char* start_ptr = strstr(buf, ATI_REVISION_STR); + if (start_ptr) { + start_ptr += strlen(ATI_REVISION_STR); + char* end_ptr = strstr(start_ptr, "\r"); + if (end_ptr) { + int len = end_ptr - start_ptr; + len = (len > MODEM_FWVER_LEN-1) ? MODEM_FWVER_LEN-1 : len; + memcpy(bg96.fw_ver, start_ptr, len); + bg96.fw_ver[MODEM_FWVER_LEN - 1] = 0; /* ensure terminated */ + } + } + + if (bg96.fw_ver[0]) { + ESP_LOGI(TAG,"FW: %s\r\n", bg96.fw_ver); + } + else { + ESP_LOGI(TAG,"Cannot get firmware version\r\n"); + } +#endif + + } + + return retval; +} + +#if MODEM_MODEM_FWVER_FROM_QGMR +static int handle_qgmr_cmd(int status, const char *buf, int len) { + int retval = MODEM_STATUS_ERROR; + + if (status == MODEM_STATUS_OK) { + /* firmware version is modem+application string returned by modem before OK + e.g. BG77LAR02A02_01.001.01.001 + */ + const char *start_ptr = buf; + if (start_ptr) { + /* If modem starts revision string with \r\n, skip those. */ + if (start_ptr[0] == '\r' && start_ptr[1] == '\n') { + start_ptr += 2; + } + /* look for a trailing \r\n, which may be part of version, or part of \r\nOK\r\n sent after + */ + const char *end_ptr = strstr(start_ptr, "\r\n"); + if (end_ptr) { + int len = end_ptr - start_ptr; + len = (len > MODEM_FWVER_LEN - 1) ? MODEM_FWVER_LEN - 1 : len; + memcpy(bg96.fw_ver, start_ptr, len); + bg96.fw_ver[MODEM_FWVER_LEN - 1] = 0; /* ensure terminated */ + } + } + + if (bg96.fw_ver[0]) { + ESP_LOGI(TAG,"FW: %s\r\n", bg96.fw_ver); + } else { + ESP_LOGI(TAG,"Cannot get firmware version\r\n"); + } + + /* OK regardless; modem can continue to run */ + retval = MODEM_STATUS_OK; + } + + return retval; +} +#endif + +/*static int handle_flds_cmd(int status, const char *buf, int len) { + + ESP_LOGI(TAG,"AT+QFLDS response is: %s",buf); + return status; +}*/ + +static int handle_cops_cmd(int status, const char *buf, int len) { +#if FAKE_NETWORK + return MODEM_STATUS_OK; +#else + /* Return OK to pass this command, or anything else to continue polling. */ + char *token; + if ((strstr(rxBuf, "\"") != NULL)) { + token = strtok(rxBuf, "\""); + token = strtok(NULL, "\""); + ESP_LOGI(TAG,"The Operator is: %s\r\n", token); + ESP_LOGI(TAG,"Connected to network.\r\n"); + status = MODEM_STATUS_OK; + } + else + { + /* If the comms_mode is CELL-ONLY then make at cops command-retries infinite. otherwise make it limited to 120 retries */ + if(comms_mode == 3) + { + bg96.cmd_repeat = true; + } + else + { + status = MODEM_STATUS_TIMEOUT; + } + } + + return status; +#endif +} + +static int handle_qfdel_cmd(int status, const char *buf, int len) { + status = MODEM_STATUS_OK; + return status; +} + +#define AT_CCLK_IND "+CCLK:" + +static int handle_cclk_cmd(int status, const char *buf, int len) { + int retval = MODEM_STATUS_ERROR; + + /* Working with response like: +CCLK: "20/09/09,16:11:40-16" yy/MM/dd,hh:mm:ss-zz + * Timezone offset is in quarter-hour units. -16 is -4 hours from GMT/UTC. + * A negative offset means we need to add those hours to the local epoch to get back + * to GMT. + * NOTE!! GMT is reqired to be the system-wide time base: + * - Each modem provides local time with offset; we convert to GMT + * - Server time must also be in GMT. Currently, this is correct: SP1 timestamps + * generated by are in GMT. (https://dev.web.unwiredprime.com/api/v1/trackers/tracker/866349040012464/mcu_config_download) + */ + /* The modem under test actually spits out a nonsense time of +CCLK: "80/01/06,00:25:27 + * when not connected to a network. (Year = 2080) + */ + if (status == MODEM_STATUS_OK) { + char *s = strstr(rxBuf, AT_CCLK_IND); + //char* s = "+CCLK: \"20/09/09,16:11:40-16\""; + if (s) { + rtc_timestamp_t ts; + s += strlen(AT_CCLK_IND) + 2; /* past space and " */ + ts.Year = atoi(s) + 2000; + s += 3; + ts.Month = atoi(s); + s += 3; + ts.MonthDay = atoi(s); + s += 3; + ts.Hour = atoi(s); + s += 3; + ts.Minute = atoi(s); + s += 3; + ts.Second = atoi(s); + /* Try to convert the offset, plus or minus. If it can't it is 0 and + * no harm done. + */ + s += 2; + int tz_offset_sec = atoi(s) * 15 * 60; /* modem provides 1/4 hour increments */ +#if SET_TIME_FROM_SERVER == 0 + + /* Set time just once - here, or from the SP1 record */ + if (!rtc_is_set()) { + rtc_set_timestamp_tz(&ts, tz_offset_sec); + } + + ESP_LOGI(TAG,"Set time: %d/%d/%d,%d:%d:%d %d -> %ld\r\n", + ts.Year, ts.Month, ts.MonthDay, ts.Hour, ts.Minute, ts.Second, tz_offset_sec, + rtc_get_epoch()); +#else + /* Print time modem provides, but do not use it. */ + ESP_LOGI(TAG,"Modem time: %d/%d/%d,%d:%d:%d %d\r\n", + ts.Year, ts.Month, ts.MonthDay, ts.Hour, ts.Minute, ts.Second, tz_offset_sec); +#endif + } + + retval = MODEM_STATUS_OK; + } + return retval; +} + + + +static int handle_qcsq_cmd(int status, const char *buf, int len) { + int retval = MODEM_STATUS_ERROR; + + /* Working with response like: +QCSQ: "CAT-M1",-52,-81,195,-10 */ + if (status == MODEM_STATUS_OK) { + char *s = strtok(rxBuf, ","); + if ((s != NULL) && (strstr(s, MODEM_QCSQ_SERIVCE_MODE_MATCH_1) || strstr(s, MODEM_QCSQ_SERIVCE_MODE_MATCH_2))) { + /* parse the 4 fields */ + s = strtok(NULL, ","); + if (s){ + bg96.sig_strength.rssi = atoi(s); + s = strtok(NULL, ","); + if (s){ + bg96.sig_strength.rsrp = atoi(s); + s = strtok(NULL, ","); + if (s){ + bg96.sig_strength.sinr = atoi(s); + s = strtok(NULL, ","); + if (s){ + bg96.sig_strength.rsrq = atoi(s); + retval = MODEM_STATUS_OK; + ESP_LOGI(TAG,"Signal strength: %d %d %d %d\r\n", + bg96.sig_strength.rssi, + bg96.sig_strength.rsrp, + bg96.sig_strength.sinr, + bg96.sig_strength.rsrq); + } + } + } + } + retval = MODEM_STATUS_OK; + } else { + ESP_LOGW(TAG,"Signal strength : did not find expected service mode\r\n"); + bg96.cmd_repeat = true; + } + // to pass the command anyways + // retval = MODEM_STATUS_ERROR; + } + return retval; +} +/* +static int setup_qmtopen_cmd(const void *params, char *buf, int len) { + snprintf(buf, len, AT_QMTOPEN, bg96.mqtt_params.host, + bg96.mqtt_params.port); + + return MODEM_STATUS_OK; +} + +static int setup_qmtconn_cmd(const void *params, char *buf, int len) { + snprintf(buf, len, AT_QMTCONN_CID,bg96.mqtt_params.client_id); //, bg96.imei, bg96.mqtt_params.jwt);//bg96.mqtt_params.client_id,); + return MODEM_STATUS_OK; +} + +static int setup_qmtpub_cmd(const void *params, char *buf, int len) { + snprintf(buf, len, AT_QMTPUB, bg96.imei); //bg96.mqtt_params.pub_topic); + + return MODEM_STATUS_OK; +} +*/ + +/* Write the length of the URL in the command */ +static int setup_qhttpurl_cmd(const void *params, char *buf, int len) { + snprintf(buf, len, AT_QHTTPURL, strlen(bg96.http_params.url)); + + return MODEM_STATUS_OK; +} + + +/* Write the length of the POST message in the command */ +static int setup_qhttppost_cmd(const void *params, char *buf, int len) { + snprintf(buf, len, AT_QHTTPPOST, strlen(bg96.http_params.post_message)); + vTaskDelay(1000 / portTICK_PERIOD_MS); + return MODEM_STATUS_OK; +} + + +/* Write the length of the URL in the command */ +static int setup_qhttpreadfile_cmd(const void *params, char *buf, int len) { + snprintf(buf, len, AT_QHTTPREADFILE, bg96.http_params.file); + + return MODEM_STATUS_OK; +} + +static int setup_qfotadl_cmd(const void *params, char *buf, int len) { + /* Send the URL */ + snprintf(buf, len, AT_QFOTADL, bg96.http_params.url); + ESP_LOGW(TAG,"setup_qfotadl_cmd"); + ESP_LOGI(TAG,"buf: %s",buf); + return MODEM_STATUS_OK; +} + + +static int handle_qhttpread_cmd(int status, const char *buf, int len) { + bg96.http_params.buf = 0; + bg96.http_params.len = 0; + + /* Parse response */ +#if USE_QHTTPREAD_OK + if (status == MODEM_STATUS_OK) +#else + if (status == MODEM_STATUS_TIMEOUT) +#endif + { + /* status is error until we prove correctness of response and + * user arguments are updated + */ + status = MODEM_STATUS_ERROR; + + /* Ensure null-termination when searching for strings */ + rxBuf[MODEM_RX_BUFFER_LEN - 1] = 0; + + /* Find the connect response */ + char *start_ptr = strstr(rxBuf, AT_CONNECT); + if (start_ptr != NULL) { + start_ptr += strlen(AT_CONNECT); /* point to next */ + +#if USE_QHTTPREAD_OK /* Use OK to frame response. */ + /* Find the trailing OK response */ + char *end_ptr = strstr(start_ptr, AT_OK); + if (end_ptr != NULL) { + int rlen = end_ptr - start_ptr; + + bg96.http_params.buf = start_ptr; + bg96.http_params.len = rlen; + /* terminate the buffer at the OK before returning to user */ + *end_ptr = 0; + /* now we are complete */ + status = MODEM_STATUS_OK; + } +#else /* Do NOT use OK to frame response. */ + /* Without OK to frame response, we just gather all bytes received. */ + bg96.http_params.buf = start_ptr; + bg96.http_params.len = strlen(start_ptr); + status = MODEM_STATUS_OK; +#endif + } + } + + return status; +} + +/* Send the URL after the CONNECT response or as a send + * handler for any command. + */ +static int send_qhttpurl_cmd(void) { + ESP_LOGI(TAG,"Send URL: %s\r\n", bg96.http_params.url); + uart_ifx_uart1_send_bytes((uint8_t *)bg96.http_params.url, strlen(bg96.http_params.url)); + + return MODEM_STATUS_OK; +} + +static int send_qhttpost_cmd(void) { + ESP_LOGI(TAG,"Send post_message: %s\r\n", bg96.http_params.post_message); + uart_ifx_uart1_send_bytes((uint8_t *)bg96.http_params.post_message, strlen(bg96.http_params.post_message)); + + return MODEM_STATUS_OK; +} + +#if 0 +static int handle_qhttppost_cmd(int status, const char *buf, int len) +{ + + /* Parse the response from the rx buffer */ + char *ptr = strstr((char*) buf, "+QHTTPPOST: 0,200,"); + if (ptr) + { + /*if that response exists then returns OK*/ + return MODEM_STATUS_OK; + } + else + { + /*if that response doesn't exists ----> then search if there's an CME error message*/ + ptr = strstr((char*) buf, "+CME ERROR:"); + if (ptr) + return MODEM_STATUS_ERROR; + else + return MODEM_STATUS_HTTP_POST_WAITRES; + } +} +#endif + +static int send_qmtpub_cmd(void) { + if (bg96.mqtt_params.pub_data && bg96.mqtt_params.pub_data_len > 0) { + ESP_LOGI(TAG,"publishing: [%s]\r\n", bg96.mqtt_params.pub_data); + uart_ifx_uart1_send_bytes((uint8_t*)bg96.mqtt_params.pub_data, bg96.mqtt_params.pub_data_len); + } else { + ESP_LOGW(TAG,"publishing null data\r\n"); + } + + char buf[1] = { + /* Send end of message character (ctrl+z) */ + CTRLZ, + //0 /* null-terminate for nice trace printing */ + }; + uart_ifx_uart1_send_bytes((uint8_t*)buf, sizeof(buf)); + + return MODEM_STATUS_OK; +} + +static int send_qfupl_cmd(void) { + char buf[1244] = + "-----BEGIN CERTIFICATE----- \ +MIIDazCCAlOgAwIBAgIUHMeQp85hERg7OQNJpIpRenYRRwkwDQYJKoZIhvcNAQEL \ +BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM \ +GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMTAyMjUxMzUwNDdaFw0yMTAz \ +MjcxMzUwNDdaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw \ +HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggEiMA0GCSqGSIb3DQEB \ +AQUAA4IBDwAwggEKAoIBAQDFMVwzDmlbfaZ+oYQwva49wQ5MB2uTLlJ3APHmSOos \ +2bsRXzZf/68rsvZNF/khLoreoW/oi0lJAA/vi7oJuKvdZKovtrwiOk8z4uYEZR8D \ +I3Y7xnIen4jZMjUrGnAUpRd2NQOqt2kScTbSxXvS2GuDxt+nBh2PS34WWBWp1HP0 \ +4zztRYHFUfsnsc21/DMzL86uc2jZQq0fJEWu0qwxTDunIXn6tQYFDFgLasSmZv4d \ +/NSNcbKLYjvUoUnbdqdTEzeshGTBM+zLxakN+Zdxc88Bb83vvNa686lzPZF/LAXT \ +erEr+Yq4SxpQ5Hn9Nj5d5wxRQSDzmtns/jJmk1zhLrIZAgMBAAGjUzBRMB0GA1Ud \ +DgQWBBQrE77qN2Tw7ia5DMHBvgBmwr0zHDAfBgNVHSMEGDAWgBQrE77qN2Tw7ia5 \ +DMHBvgBmwr0zHDAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBm \ +eqBPGy1TCNEDa3dMWgO9pK9zsuDGv+J9b2TiqnTvub5uW5z+qV2f7bBsuOZRWzv3 \ +4P9oGjgH+/HFpz+kSvBIRoEjjtX48LyD5H9ah0ALzQt5vXN7Q6QR4bWEtZFYlaOW \ +6Yd4v2DOtyBCa6g33Jf0Hw1OaYPzRmRsbqdB/Izg60ENZFXKCPFvHNIVP7IytEaz \ +gdghpaHdqGSFlbBxtfzk7vNqVoepX9kULaOhNdaDlMZE+nA+unHZc4zd0wDLVB+p \ +8fYZf6JfLRkQoZmdprsa0mtVOXLBwH6C2+lj8mxz6T9Or07LjxpkJB2dxGBiE6b9 \ +zkcHc7vljutOr+sbR1aK \ +-----END CERTIFICATE-----"; + int len = strlen(buf); + ESP_LOGI(TAG,"Buffer: [%d]\r\n", len); + uart_ifx_uart1_send_bytes((uint8_t*)buf, len); + + char cbuf[1] = { + /* Send end of message character (ctrl+z) */ + CTRLZ, + //0 /* null-terminate for nice trace printing */ + }; + uart_ifx_uart1_send_bytes((uint8_t*)cbuf, sizeof(cbuf)); + + return MODEM_STATUS_OK; +} + +/* --------------------------------------------------------------------------*/ +/* File read command processing. + */ + +static int setup_qflst_cmd(const void *params, char *buf, int len) { + /* Send the file name */ + snprintf(buf, len, AT_QFLST, bg96.file_params.file); + + return MODEM_STATUS_OK; +} + +static int handle_qflst_cmd(int status, const char *buf, int len) { + int retval = MODEM_STATUS_ERROR; + + bg96.file_params.file_size = 0; + + if (status == MODEM_STATUS_OK) { + /* Parse the file size from the received response */ + char *ptr = strstr((char*) rxBuf, ","); + if (ptr) { + ptr++; + bg96.file_params.file_size = (uint32_t) atoi(ptr); + ESP_LOGI(TAG,"Found file [%s] on modem. size=%ld\r\n", + bg96.file_params.file, bg96.file_params.file_size); + retval = MODEM_STATUS_OK; + } else { + ESP_LOGI(TAG,"Cannot find file size for [%s]\r\n", + bg96.file_params.file); + } + } else { + ESP_LOGI(TAG,"Cannot find downloaded file [%s] on modem\r\n", + bg96.file_params.file); + } + + return retval; +} + +static int handle_qfotadl_cmd(int status, const char* buf, int len){ + ESP_LOGI(TAG,"DFOTA handle_qfotadl_cmd "); + char* s = NULL; + char errorcode[2] ={0}; + int dfotaerr_idx = -1; + + s = strstr(rxBuf, "HTTPEND"); + if(s == NULL) + { + ESP_LOGI(TAG,"DFOTA package checking\\validation has been failed "); + return MODEM_STATUS_ERROR; + } + ESP_LOGI(TAG,"DFOTA ERROR %s",s); + strncpy(errorcode, &s[9], 1 /*only error index*/); + dfotaerr_idx = atoi(errorcode); + + ESP_LOGI(TAG,"DFOTA ERROR IDX %d",dfotaerr_idx); + + if(dfotaerr_idx != 0){ + + status = MODEM_STATUS_ERROR; + } + else{ + + status = MODEM_STATUS_OK; + } + + return status; +} + +static int setup_qfopen_cmd(const void *params, char *buf, int len) { + /* Send the file name */ + snprintf(buf, len, AT_QFOPEN, bg96.file_params.file); + + return MODEM_STATUS_OK; +} + +static int handle_qfopen_cmd(int status, const char *buf, int len) { + if (status == MODEM_STATUS_OK) { + /* Need the file handle */ + char *ptr = strstr((char*) rxBuf, "+QFOPEN:"); + if (ptr) { + ptr += strlen("+QFOPEN:"); + bg96.file_params.file_handle = atoi(ptr); + /* Initialize the file state */ + bg96.file_params.transferred_bytes = 0; + bg96.file_params.chunk_size = MODEM_FREAD_SIZE; + ESP_LOGI(TAG,"Opened file %s with handle: %d\r\n", + bg96.file_params.file, bg96.file_params.file_handle); + } else { + /* Can't get handle? Uh oh */ + status = MODEM_STATUS_ERROR; + ESP_LOGI(TAG,"Unable to get handle for %s\r\n", bg96.file_params.file); + } + + if (status == MODEM_STATUS_OK) { + /* Call the user callback */ + if (bg96.file_params.open_cb) { + /* User callback can return error, which will fail the whole read procedure */ + status = bg96.file_params.open_cb(bg96.file_params.file_size); + bg96.file_params.open_cb = 0; /* call only once */ + } + } + } + return status; +} + +/* BG96 response search strings */ +#define SFU_APP_MODEM_CONNECT_SEARCH "\r\nCONNECT 0\r\n" +#define SFU_APP_MODEM_CONNECT_PREFIX "\r\nCONNECT " + +/* Length of the CONNECT response string that we will support, including null-terminator */ +#define SFU_APP_MODEM_CONNECT_BUF_LEN sizeof("\r\nCONNECT 999999\r\n") + +/* Compute the expected number of bytes in the modem's response to an FREAD */ +static int expectedNumFREADResponseBytes(uint32_t len) { + int n = strlen(SFU_APP_MODEM_CONNECT_PREFIX); + + /* digits in CONNECT read_length field */ + n += (len < 10) ? 1 : (len < 100) ? 2 : (len < 1000) ? 3 : 4; + + n += 2; /* trailing \r\n */ + + n += len; + + n += strlen(AT_OK); + + ESP_LOGI(TAG,"FREAD expect response len=%d for %ld\r\n", n, len); + + return n; +} + +/* + * Process the FREAD response from the BG96 modem. + * + * The FREAD response must begin at offset 0 in the provided buffer. + * The potential length of the entire response + * (e.g. maximum size of provided buffer) must be specified in buf_len parameter. + * It is not required to know the exact response length as this API will figure it out safely. + * + * Return MODEM_STATUS_ERROR if anything fails including buffer not containing a CONNECT response + * or properly formed CONNECT response. + */ +static int ParseFREAD(const char *buf, int buf_len, /* input arguments: pointer to receive buffer and its length */ +const char **data_, int *data_len_) /* output arguments: pointer to recovered data and its length */ +{ + /* Deal with the buffer expecting a response from the BG96 of the form: + * \r\nCONNECT \r\n + * + * \r\nOK\r\n + * + * We cannot assume the caller's buffer is null-terminated anywhere. + * + * We must: + * a) extract the read_length parameter + * b) find the offset of the data in the buffer + * c) copy the data to a word-aligned buffer for processing the SFU_APP_Data(). + * + * The input buffer can be of any length. We will chunk it into our own buffer + * and call the underlying API as often as needed to consume all bytes in the + * caller's buffer before returning. + */ + + /* Temporary buffer to search for the connect string safely */ + char connect_buf[SFU_APP_MODEM_CONNECT_BUF_LEN]; + + /* Check arguments and basic buffer length sanity check */ + if (buf == NULL || buf_len < strlen(SFU_APP_MODEM_CONNECT_SEARCH)) { + return MODEM_STATUS_ERROR; + } + + /* First we need to build a null-terminated string to operate on, so we copy what + * could be the modem response into our buffer and terminate it. + * Maximum size will be limited to 6 digits, so that is + * "\r\nCONNECT 999999\r\n" = 18 characters. + */ + const int max_copy = SFU_APP_MODEM_CONNECT_BUF_LEN - 1; + /* Copy up to BUF LEN characters into temp buffer */ + const int init_copy = buf_len > max_copy ? max_copy : buf_len; + memcpy(connect_buf, buf, init_copy); + connect_buf[init_copy] = 0; /* null terminate for safe string operations on it */ + ESP_LOGI(TAG,"Copied %d bytes\r\n", init_copy); + + /* Find the length */ + const char *start_ptr = strstr(connect_buf, SFU_APP_MODEM_CONNECT_PREFIX); + if (start_ptr == NULL) { + return MODEM_STATUS_ERROR; + } + int offset = start_ptr - connect_buf; /* should be 0 but support other cases too */ + ESP_LOGI(TAG,"Offset=%d\r\n", offset); + const char *ptr = start_ptr + strlen(SFU_APP_MODEM_CONNECT_PREFIX); + int data_len = atoi(ptr); + if (data_len <= 0) { + return MODEM_STATUS_ERROR; + } + ESP_LOGI(TAG,"data_len=%d\r\n", data_len); + /* Offset of actual data immediately follows the \r\n */ + ptr = strstr(ptr, "\r\n"); + if (ptr == NULL) { + return MODEM_STATUS_ERROR; + } + ptr += 2; + + /* data offset into user buffer is specified finally here. */ + offset += (ptr - start_ptr); + ESP_LOGI(TAG,"Offset=%d\n", offset); + + /* check that the data length reported by CONNECT response is actually + * present in the buffer supplied. + */ + if (data_len > (buf_len - offset)) { + return MODEM_STATUS_ERROR; + } + + /* Return the actual data length and a pointer to it */ + *data_ = buf + offset; + *data_len_ = data_len; + + return MODEM_STATUS_OK; +} + +static int setup_qfread_cmd(const void *params, char *buf, int len) { + /* Send the number of bytes we read this call */ + bg96.file_params.read_size = bg96.file_params.chunk_size; + + /* Adjust to the actual number of bytes remaining */ + if ((bg96.file_params.file_size - bg96.file_params.transferred_bytes) + < bg96.file_params.chunk_size) { + bg96.file_params.read_size = bg96.file_params.file_size + - bg96.file_params.transferred_bytes; + } + + /* This is used in the handler to mark when we have received the response */ + bg96.file_params.expected_bytes = expectedNumFREADResponseBytes( + bg96.file_params.read_size); + + ESP_LOGI(TAG, + "setup qfread: handle:%d read_size:%d file_size:%ld chunk_size:%d xfered:%ld expect:%d\r\n", + bg96.file_params.file_handle, bg96.file_params.read_size, + bg96.file_params.file_size, bg96.file_params.chunk_size, + bg96.file_params.transferred_bytes, + bg96.file_params.expected_bytes); + + snprintf(buf, len, AT_QFREAD, bg96.file_params.file_handle, + bg96.file_params.read_size); + + return MODEM_STATUS_OK; +} + +/* This is how we are handling the QFREAD command response. + * We need to frame it somehow, and we do that by waiting for the expected number of + * bytes to arrive. But to have this handler called, we need to kick it with something, + * and we use the "\r\nOK\r\n" string expected at the end. We will, however, see this + * string embedded within the firmware image, so we must be careful not to end prematurely. + * + * Coming into this function, we will expect status = MODEM_STATUS_OK to indicate match for the \r\nOK\r\n string. + * then, we look for the number of bytes recevied and compare. If these match, we return STATUS_OK. + * If they do not, we must return TIMEOUT to keep looking. If the error condition was found, we have a + * similar problem with finding it in the stream, so we don't look for it and instead rely on the + * command timeout to abort. + * + * Also, we need to retry the FREAD command until the transfer is done, + * to do that we must return TIMEOUT always until it is done, then OK, or ERROR in any error state. + */ +static int handle_qfread_cmd(int status, const char *buf, int len) { + /* Pass ERROR and TIMEOUT through, only handle OK */ + if (status == MODEM_STATUS_OK) { + /* Found \r\nOK\r\n in the stream. Do we have the expected number of bytes? */ + if (rx_idx < bg96.file_params.expected_bytes) { + /* No, this was an embedded \r\nOK\r\n so continue scanning */ + status = MODEM_STATUS_TIMEOUT; + + /* Required to reset the scanner state (and update the index) for next OK */ + RxScanContextSuccess.RxScannerState = 0; + RxScanContextSuccess.RxScannerIdx = rx_idx; + + /* In the last UART event we got a numnber of bytes to bring it to rx_idx, + * and in that chunk we found OK but NOT expected number of bytes. This means + * we expect at least another UART event to kick the next scan. + */ + ESP_LOGI(TAG,"Found embedded OK, rx_idx=%d scanidx=%d\r\n", rx_idx, + RxScanContextSuccess.RxScannerIdx); + } else { + const char *data; + int data_len; + status = ParseFREAD(rxBuf, MODEM_RX_BUFFER_LEN, &data, &data_len); + if (status == MODEM_STATUS_OK) { + ESP_LOGI(TAG,"%d bytes file data read successfully\r\n", data_len); + /* Invoke user callback, which can also fail the transfer */ + if (bg96.file_params.data_cb) { + status = bg96.file_params.data_cb(data, data_len); + if (status == MODEM_STATUS_OK) { + /* Increment the number of bytes transfered only after success on user callback */ + bg96.file_params.transferred_bytes += + bg96.file_params.read_size; + ESP_LOGI(TAG,"%d bytes processed\r\n", data_len); + } else { + ESP_LOGI(TAG,"%d bytes failed to process.\r\n", data_len); + } + } + } else { + ESP_LOGI(TAG,"Failed to parse FREAD response\r\n"); + } + + ESP_LOGI(TAG,"Transfer %ld/%ld %ld%% complete\r\n", + bg96.file_params.transferred_bytes, + bg96.file_params.file_size, + (bg96.file_params.transferred_bytes * 100) + / bg96.file_params.file_size); + + /* If status is OK at this point, we must set it to TIMEOUT to continue reading the file */ + if (status == MODEM_STATUS_OK) { + /* If we have received all bytes, we can terminate the transfer */ + if (bg96.file_params.transferred_bytes + < bg96.file_params.file_size) { + bg96.cmd_repeat = true; + } + } + } + } + /* Must return TIMEOUT until all bytes have been tranferred, unless ERROR to signal + * transfer failed and abort the command sequence and OK to signal all done. + */ + return status; +} + +static int setup_qfclose_cmd(const void *params, char *buf, int len) { + /* Send the file handle */ + snprintf(buf, len, AT_QFCLOSE, bg96.file_params.file_handle); + + return MODEM_STATUS_OK; +} + +/* Command table + * Allows command chaining + * Each entry has a response process function + */ + +#define MODEM_DEFAULT_CMD_TIMEOUT_MS 5000 +#define MODEM_DEFAULT_CMD_RETRIES 5 + +/* Align with timeout given to modem in AT_QMTCFG_TIMEOUT */ +#define MODEM_MQTT_CONN_CMD_TIMEOUT_MS 60000 + +typedef enum { + AT_CMD_IDX_ECHO_OFF = 0, + AT_CMD_IDX_IFC, + AT_CMD_IDX_IDENT, +#if MODEM_MODEM_FWVER_FROM_QGMR + AT_CMD_IDX_QGMR, +#endif + AT_CMD_IDX_IMEI, + AT_CMD_IDX_ICCID, //AT_QCCID to get ICCID +#if FAKE_NETWORK + AT_CMD_IDX_SETCCLK, +#endif + AT_CMD_IDX_CTZU, + AT_CMD_IDX_CPIN, + AT_CMD_IDX_CGDCONT_ALT, + AT_CMD_IDX_CFUN_OFF, + AT_CMD_IDX_CFUN, + AT_CMD_IDX_COPS, + AT_CMD_IDX_QCSQ, + AT_CMD_IDX_QCFG_IOTMODE, + AT_CMD_IDX_CCLK, + AT_CMD_IDX_QICSGP, + AT_CMD_IDX_QIACT, + + //AT_CMD_IDX_QMTCFG_SSL, + AT_CMD_IDX_QFDEL, + //AT_CMD_IDX_QFUPL, + /*AT_CMD_IDX_QFUPL_SEND, + AT_CMD_IDX_QSSLCFG_CACERT, + AT_CMD_IDX_QSSLCFG_SECLEVEL, + AT_CMD_IDX_QSSLCFG_SSLVER, + AT_CMD_IDX_QSSLCFG_CIPH, + AT_CMD_IDX_QSSLCFG_IGNRTIME, + AT_CMD_IDX_QMTCFG_WILL, + AT_CMD_IDX_QMTCFG_TIMEOUT, + AT_CMD_IDX_QMTCFG_KEEPALIVE, + AT_CMD_IDX_QMTCFG_VERSION, + AT_CMD_IDX_QMTOPEN, + AT_CMD_IDX_QMTCONN_CID,*/ + + //AT_CMD_IDX_QMTPUB, + //AT_CMD_IDX_QMTPUB_SEND, /* not an actual command, part 2 of the QMTPUB operation */ + //AT_CMD_IDX_QMTCLOSE, + + AT_CMD_IDX_QHTTPCFG_CTX, + AT_CMD_IDX_QHTTPCFG_RHD, + AT_CMD_IDX_QHTTPCFG_RHD_0, + AT_CMD_IDX_QHTTPURL, + AT_CMD_IDX_QHTTPURL_SET, + AT_CMD_IDX_QHTTPPOST, + AT_CMD_IDX_QHTTPPOST_SET, + AT_CMD_IDX_QHTTPGET, + AT_CMD_IDX_QHTTPREAD, + AT_CMD_IDX_QHTTPREADFILE, + + AT_CMD_IDX_QPOWD, + + AT_CMD_IDX_QFOTADL, + AT_CMD_IDX_QFOTADL_WAIT_HTTPEND, + AT_CMD_IDX_QFOTADL_WAIT_END, + + //AT_CMD_IDX_QFLDS, + AT_CMD_IDX_QFLST, + AT_CMD_IDX_QFOPEN, + AT_CMD_IDX_QFREAD, + AT_CMD_IDX_QFCLOSE, + +// AT_CMD_IDX_QENG_SVCELL, //Partha - March 11, 2022 +// AT_CMD_IDX_QENG_NBCELL //Partha - March 11, 2022 +} modem_at_cmd_idx_t; + +static const modem_cmd_t cmd_table[] = + { + + /* ATE0 */ + { AT_ECHO_OFF, AT_OK, 0, MODEM_DEFAULT_CMD_TIMEOUT_MS, + MODEM_DEFAULT_CMD_RETRIES, 0, 0, 0, 0 }, + + /* IFC */ + { AT_IFC, AT_OK, 0, MODEM_DEFAULT_CMD_TIMEOUT_MS, + MODEM_DEFAULT_CMD_RETRIES, 0, 0, 0, 0 }, + + /* ATI */ + { ATI, AT_OK, 0, MODEM_DEFAULT_CMD_TIMEOUT_MS, MODEM_DEFAULT_CMD_RETRIES, + 0, handle_ati_cmd, 0, 0 }, + +#if MODEM_MODEM_FWVER_FROM_QGMR + /* QGMR */ + { AT_QGMR, AT_OK, 0, MODEM_DEFAULT_CMD_TIMEOUT_MS, + MODEM_DEFAULT_CMD_RETRIES, 0, handle_qgmr_cmd, 0, 0 }, +#endif + + /* CGSN */ + { AT_CGSN, AT_OK, 0, MODEM_DEFAULT_CMD_TIMEOUT_MS, + MODEM_DEFAULT_CMD_RETRIES, 0, handle_imei_cmd, 0, 0 }, + /* QCCID */ + { AT_QCCID, AT_OK, 0, MODEM_DEFAULT_CMD_TIMEOUT_MS, MODEM_DEFAULT_CMD_RETRIES, 0, handle_iccid_cmd, 0, 0 }, + +#if FAKE_NETWORK + /* SETCCLK */ + /* Set the modem's RTC for testing without network + * Note: timezone offset is in units of 1/4 hour, so -20 is -5 hours (EST timezone) + * Below time is local to EST. It should be converted to GMT epoch and that is used + * as the system-wide time base for SP1/2 publish messages. + */ + { "AT+CCLK=\"20/10/04,15:43:10-20\"\r\n", AT_OK, 0, MODEM_DEFAULT_CMD_TIMEOUT_MS, MODEM_DEFAULT_CMD_RETRIES, 0, 0, 0, 0 }, +#endif + + /* Network connection */ + + /* CTZU */ + { AT_CTZU, AT_OK, 0, MODEM_DEFAULT_CMD_TIMEOUT_MS, + MODEM_DEFAULT_CMD_RETRIES, 0, 0, 0, 0 }, + + /* CPIN */ + { AT_CPIN, AT_OK, 0, 5000, MODEM_DEFAULT_CMD_RETRIES, 0, 0, 0, 0 }, + + /* CGDCONT_ALT */ + { AT_CGDCONT, AT_OK, 0, MODEM_DEFAULT_CMD_TIMEOUT_MS, + MODEM_DEFAULT_CMD_RETRIES, 0, 0, 0, 0 }, + + /* CFUN_OFF */ + { AT_CFUN_OFF, AT_OK, AT_IND_CME_ERROR, 15000, + MODEM_DEFAULT_CMD_RETRIES, 0, 0, 0, 0 }, + + /* CFUN */ + { AT_CFUN_FULL, AT_OK, AT_IND_CME_ERROR, 15000, + MODEM_DEFAULT_CMD_RETRIES, 0, 0, 0, 0 }, + + /* COPS + * Wait for timeout and use handler function to look for the operators we want to connect with. + * Retry for up to 2 minutes. + */ + // { AT_COPS, 0, 0, 1000, 120, 0, handle_cops_cmd, 0, 0 }, + { AT_COPS, AT_OK, 0, 2000, 60, 0, handle_cops_cmd, 0, 0 }, + /* QCSQ */ + { AT_QCSQ, AT_OK, 0, MODEM_DEFAULT_CMD_TIMEOUT_MS, + 20, 0, handle_qcsq_cmd, 0, 0 }, + + /* QCFG_IOTMODE */ + { AT_QCFG_IOTOPMODE, AT_OK, 0, MODEM_DEFAULT_CMD_TIMEOUT_MS, + MODEM_DEFAULT_CMD_RETRIES, 0, 0, 0, 0 }, + + /* CCLK */ + { AT_CCLK, AT_OK, 0, MODEM_DEFAULT_CMD_TIMEOUT_MS, + MODEM_DEFAULT_CMD_RETRIES, 0, handle_cclk_cmd, 0, 0 }, + + /* PDP context commands: + * CGDCONT sets it up + * CGACT activates it + * OR + * QICSGP sets it up + * QIACT activates it + * QI commands are in the TCP(IP) AT command manual, while CG are standard AT commands. + * https://forums.quectel.com/t/what-is-the-difference-between-cgdcont-and-qicsgp/152 + * "When using module’s embedded stacks like TCP and UDP protocol, you need to use AT+QICSGP to configure the APN. + * While using PPP, you need to use AT+CGDCONT to configure the APN." + * I also suspect that these commands need to be run before MQTT communications. We are not using PPP. + * They are included in the network connection sequence. + */ + + /* QICSGP */ + { AT_QICSGP, AT_OK, AT_ERROR, MODEM_DEFAULT_CMD_TIMEOUT_MS, + MODEM_DEFAULT_CMD_RETRIES, 0, 0, 0, 0 }, + + /* QIACT + * Maximum response time 150 seconds. + */ + { AT_QIACT, 0, 0, 5000, MODEM_DEFAULT_CMD_RETRIES, 0, 0, 0, 0 }, + + /* QSSLCFG_CACERT */ + /*{ AT_QMTCFG_SSL, AT_OK, 0, MODEM_DEFAULT_CMD_TIMEOUT_MS, + MODEM_DEFAULT_CMD_RETRIES, 0, 0, 0, 0 },*/ + /* MQTT connection */ + { AT_QFDEL, 0, 0, 5000, MODEM_DEFAULT_CMD_RETRIES, 0, + handle_qfdel_cmd, 0, 0 }, + + /* MQTT connection */ + /*{ AT_QFUPL, "CONNECT", AT_IND_CME_ERROR, 5000, + MODEM_DEFAULT_CMD_RETRIES, 0, 0, 0, 0 },*/ + /* Send data then wait for indication. */ + //{ 0 /* no command */, AT_OK, AT_IND_CME_ERROR, 180 * 1000, + // 0 /* no retries */, send_qfupl_cmd, 0, 0, 0 }, + + /* QSSLCFG_CACERT */ + /*{ AT_QSSLCFG_CACERT, AT_OK, 0, MODEM_DEFAULT_CMD_TIMEOUT_MS, + MODEM_DEFAULT_CMD_RETRIES, 0, 0, 0, 0 },*/ + + /* QMTCFG_WILL */ + /*{ AT_QSSLCFG_SECLEVEL, AT_OK, 0, MODEM_DEFAULT_CMD_TIMEOUT_MS, + MODEM_DEFAULT_CMD_RETRIES, 0, 0, 0, 0 },*/ + + /* QMTCFG_WILL */ + /*{ AT_QSSLCFG_SSLVER, AT_OK, 0, MODEM_DEFAULT_CMD_TIMEOUT_MS, + MODEM_DEFAULT_CMD_RETRIES, 0, 0, 0, 0 },*/ + + /* QMTCFG_WILL */ + /*{ AT_QSSLCFG_CIPH, AT_OK, 0, MODEM_DEFAULT_CMD_TIMEOUT_MS, + MODEM_DEFAULT_CMD_RETRIES, 0, 0, 0, 0 },*/ + + /* QMTCFG_WILL */ + /*{ AT_QSSLCFG_IGNRTIME, AT_OK, 0, MODEM_DEFAULT_CMD_TIMEOUT_MS, + MODEM_DEFAULT_CMD_RETRIES, 0, 0, 0, 0 },*/ + + /* QMTCFG_WILL */ + /*{ AT_QMTCFG_WILL, AT_OK, 0, MODEM_DEFAULT_CMD_TIMEOUT_MS, + MODEM_DEFAULT_CMD_RETRIES, 0, 0, 0, 0 },*/ + /* AT_QMTCFG_TIMEOUT */ + /*{ AT_QMTCFG_TIMEOUT, AT_OK, 0, MODEM_DEFAULT_CMD_TIMEOUT_MS, + MODEM_DEFAULT_CMD_RETRIES, 0, 0, 0, 0 },*/ + + /* AT_QMTCFG_KEEPALIVE */ + /*{ AT_QMTCFG_KEEPALIVE, AT_OK, 0, MODEM_DEFAULT_CMD_TIMEOUT_MS, + MODEM_DEFAULT_CMD_RETRIES, 0, 0, 0, 0 },*/ + + /* AT_QMTCFG_VERSION */ + /*{ AT_QMTCFG_VERSION, AT_OK, 0, MODEM_DEFAULT_CMD_TIMEOUT_MS, + MODEM_DEFAULT_CMD_RETRIES, 0, 0, 0, 0 },*/ + + /* QMTOPEN */ + /*{ AT_QMTOPEN, AT_IND_QMTOPEN, 0, MODEM_MQTT_CONN_CMD_TIMEOUT_MS, + MODEM_DEFAULT_CMD_RETRIES, 0, 0, setup_qmtopen_cmd, 0 },*/ + + /* QMTCONN_CID */ + /*{ AT_QMTCONN_CID, AT_IND_QMTCONN, 0, + MODEM_MQTT_CONN_CMD_TIMEOUT_MS, MODEM_DEFAULT_CMD_RETRIES, + 0, 0, setup_qmtconn_cmd, 0 },*/ + + /* MQTT publish */ + + /* QMTPUB + * Publish messages. + * AT+QMTPUB=0,0,0,0,"topic/pub" + * >This is test data, hello MQTT. //After receiving >, input data "This is test data, hello MQTT." and + * then send it. The maximum length of the data is 1548 bytes and the + * data that beyond 1548 bytes will be omitted. After inputting data, + * tap Ctrl+Z to send. + * OK + * +QMTPUB: 0,0,0 + * + * Note: need to wait for ">" from modem after command is sent before sending our data. + * Publish is then split into two operations: AT_QMTPUB command which waits for ">", + * then send the data and waits for the indication. + */ + /*{ AT_QMTPUB, ">", AT_IND_CME_ERROR, 5000, + MODEM_DEFAULT_CMD_RETRIES, 0, 0, setup_qmtpub_cmd, 0 },*/ + /* Send data then wait for indication. */ + //{ 0 /* no command */, AT_IND_QMTPUB, AT_IND_CME_ERROR, 180 + // * 1000, 0 /* no retries */, send_qmtpub_cmd, 0, 0, 0 }, + + /* QMTCLOSE + * Note: + * The QMTCLOSE: indication does not appear within a 10s timeout. The manual has no specification on how long + * this might take. Instead, we wait for the command's OK response and continue as if the connection + * had closed. + */ + //{ AT_QMTCLOSE, AT_OK /* AT_IND_QMTCLOSE */, 0, + // MODEM_DEFAULT_CMD_TIMEOUT_MS, MODEM_DEFAULT_CMD_RETRIES, + // 0, 0, 0, 0 }, + + /* HTTP */ + + /* QHTTPCFG_CTX */ + { AT_QHTTPCFG_CTX, AT_OK, AT_IND_CME_ERROR, + MODEM_DEFAULT_CMD_TIMEOUT_MS, MODEM_DEFAULT_CMD_RETRIES, + 0, 0, 0, 0 }, + + /* QHTTPCFG_RHD */ + { AT_QHTTPCFG_RHD, AT_OK, AT_IND_CME_ERROR, + MODEM_DEFAULT_CMD_TIMEOUT_MS, MODEM_DEFAULT_CMD_RETRIES, + 0, 0, 0, 0 }, + + { AT_QHTTPCFG_RHD_0, AT_OK, AT_IND_CME_ERROR, + MODEM_DEFAULT_CMD_TIMEOUT_MS, MODEM_DEFAULT_CMD_RETRIES, + 0, 0, 0, 0 }, + + /* QHTTPURL + * Wait for CONNECT + */ + { AT_QHTTPURL, AT_CONNECT, AT_IND_CME_ERROR, + MODEM_DEFAULT_CMD_TIMEOUT_MS, MODEM_DEFAULT_CMD_RETRIES, + 0, 0, setup_qhttpurl_cmd, 0 }, + /* then send URL then wait for OK */ + { 0, AT_OK, AT_IND_CME_ERROR, MODEM_DEFAULT_CMD_TIMEOUT_MS, + MODEM_DEFAULT_CMD_RETRIES, send_qhttpurl_cmd, 0, 0, 0 }, + + /* QHTTPPOST + * Wait for CONNECT + */ + { AT_QHTTPPOST, AT_CONNECT, AT_IND_CME_ERROR, + 80000, MODEM_DEFAULT_CMD_RETRIES, + 0, 0, setup_qhttppost_cmd, 0 }, + /* then send POST-Message then wait for OK */ + { 0, AT_HTTPPOST_SUCCESS, AT_IND_CME_ERROR, 60000, + MODEM_DEFAULT_CMD_RETRIES, send_qhttpost_cmd, 0, 0, 0 }, + + /* QHTTPGET + * If is 0, then wait for +QHTTPGET indication. Then use QHTTPREAD to get the response. + * If is 1, then wait for CONNECT then OK to frame response from this command + * Default appears to be 0. + */ + { AT_QHTTPGET, AT_QHTTPGET_SUCCESS, AT_IND_CME_ERROR, 80000, + 0 /* no retries */, 0, 0, 0, 0 }, + + /* QHTTPREAD + * Look for OK response before +QHTTPREAD indication to frame the GET content. */ +#if USE_QHTTPREAD_OK + /* OK, +QHTTPREAD response expected. Timeout equal to QHTTPREAD command timeout. */ + { AT_QHTTPREAD, AT_QHTTPREAD_SUCCESS, /*AT_IND_CME_ERROR*/ 0, 80000, + 3, 0, handle_qhttpread_cmd, 0, 0 }, +#else + /* No OK Response expected, wait for timeout then parse. */ + { AT_QHTTPREAD, 0, 0, 3000, MODEM_DEFAULT_CMD_RETRIES, 0, handle_qhttpread_cmd, 0, 0 }, +#endif + + /* QHTTPREADFILE + * Look for OK response to frame the GET content. */ + { AT_QHTTPREADFILE, AT_QHTTPREADFILE_SUCCESS, AT_IND_CME_ERROR, + 5*60*1000, MODEM_DEFAULT_CMD_RETRIES, 0, 0, + setup_qhttpreadfile_cmd, 0 }, + + /* QPOWD + * This command default is "1" - normal shutdown. + It is recommended to execute AT+QPOWD command to power off the module, as it is the safest and best + way. This procedure is realized by letting the module log off from the network and allowing the software to + enter a secure and safe data state before disconnecting the power supply. + After sending AT+QPOWD, do not enter any other AT commands. When the command is executed + successfully, the module will output POWERED DOWN and set the STATUS pin as low to enter power-off + state. In order to avoid data loss, it is suggested to wait for 1s at least to disconnect the power supply after + the STATUS pin is set as low and the URC POWERED DOWN is outputted. If POWERED DOWN cannot + be received within 65s, the power supply shall be disconnected compulsorily. + * + * Our procedure is to enter command and wait for standard OK to complete command sequence, + * then we monitor STATUS pin for the 65 seconds. If it is still up after that we + * can try PWRKEY and start waiting again. + */ + { AT_QPOWD, AT_OK, 0, MODEM_DEFAULT_CMD_TIMEOUT_MS, + MODEM_DEFAULT_CMD_RETRIES, 0, 0, 0, 0 }, + + /* Send QFOTADL with URL, wait for OK */ + { AT_QFOTADL, AT_OK, AT_IND_CME_ERROR, + MODEM_DEFAULT_CMD_TIMEOUT_MS, MODEM_DEFAULT_CMD_RETRIES, + 0, 0, setup_qfotadl_cmd, 0 }, + /* then wait 25 mins for process to complete with "END" + * Need multiple phases: download from server phase: HTTPEND + * Update phase: END. If server download didn't complete, fail it. + */ + { 0, "\"HTTPEND\",0", "\"HTTPEND\",", 25 * 60 * 1000, 0, 0, handle_qfotadl_cmd,0, 0 }, + { 0, "\"END\"", AT_IND_CME_ERROR, 25 * 60* 1000, 0, 0, 0, 0, 0 }, + + + //{ AT_QFLDS, AT_OK, AT_IND_CME_ERROR, MODEM_DEFAULT_CMD_TIMEOUT_MS, MODEM_DEFAULT_CMD_RETRIES, 0, handle_flds_cmd, 0, 0 }, + /* File transfer procedure: + * 1. Look for specific file, get file size from response. setup, handler : set size + * 2. Open file. handler: success : get file handle, call user open cb, init transfer state. + * 3 read file repeatedly until bytes consumed. Use handler to control this as a retry. + */ + { AT_QFLST, AT_OK, AT_IND_CME_ERROR, + MODEM_DEFAULT_CMD_TIMEOUT_MS, MODEM_DEFAULT_CMD_RETRIES, + 0, handle_qflst_cmd, setup_qflst_cmd, 0 }, { AT_QFOPEN, + AT_OK, AT_IND_CME_ERROR, MODEM_DEFAULT_CMD_TIMEOUT_MS, + MODEM_DEFAULT_CMD_RETRIES, 0, handle_qfopen_cmd, + setup_qfopen_cmd, 0 }, + /* Look for OK response to frame FREAD data. This is dangerous by itself because \r\nOK\r\n is likely located within + * the byte stream. To make this work, we use the handler in combination to check that we have found \r\nOK\r\n AND the + * expected number of bytes. + */ + { AT_QFREAD, AT_OK /* See note */, + 0 /* do not look for error response */, + 10000 /* timeout */, 0 /* no retries */, 0, + handle_qfread_cmd, setup_qfread_cmd, 0 }, { AT_QFCLOSE, + AT_OK, AT_IND_CME_ERROR, MODEM_DEFAULT_CMD_TIMEOUT_MS, + MODEM_DEFAULT_CMD_RETRIES, 0, 0, setup_qfclose_cmd, 0 } + + }; + +#define MODEM_NUM_CMDS (sizeof(cmd_table) / sizeof(cmd_table[0])) + +static int add_cmd(const modem_cmd_t *cmd) { + int retval = MODEM_STATUS_ERROR; + if (cmd) { + if (bg96.cmd_num < MODEM_MAX_SEQUENCE) { + bg96.cmd_list[bg96.cmd_num++] = cmd; + retval = MODEM_STATUS_OK; + } + } + return retval; +} + +int modem_network_connect(modem_op_cb_t cb) { + bg96.cmd_num = 0; + + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_CTZU])) { + return MODEM_STATUS_ERROR; + } + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_CPIN])) { + return MODEM_STATUS_ERROR; + } + /*if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_CGDCONT_ALT])) { + return MODEM_STATUS_ERROR; + }*/ + /*if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_CFUN_OFF])) { + return MODEM_STATUS_ERROR; + }*/ + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_CFUN])) { + return MODEM_STATUS_ERROR; + } + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_COPS])) { + return MODEM_STATUS_ERROR; + } + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_QCSQ])) { + return MODEM_STATUS_ERROR; + } + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_QCFG_IOTMODE])) { + return MODEM_STATUS_ERROR; + } + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_QFDEL])) { + return MODEM_STATUS_ERROR; + } + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_QCFG_IOTMODE])) { + return MODEM_STATUS_ERROR; + } + /*if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_QICSGP])) { + return MODEM_STATUS_ERROR; + }*/ +#if FAKE_NETWORK +#else + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_QIACT])) { + return MODEM_STATUS_ERROR; + } +#endif + + bg96.cmd_complete_cb = cb; + + int retval = start_cmd_sequence(); + + if (retval == MODEM_STATUS_OK) { + ESP_LOGI(TAG,"Starting connect network sequence %d\r\n", bg96.cmd_num); + } + return retval; + +} + +#if 0 +int modem_mqtt_connect(modem_op_cb_t cb, const char *host, int port, + const char *client_id) //, const char* jwt) +{ + bg96.cmd_num = 0; + /*if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_QMTCFG_SSL])) { + return MODEM_STATUS_ERROR; + } + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_QFDEL])) { + return MODEM_STATUS_ERROR; + } + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_QFUPL])) { + return MODEM_STATUS_ERROR; + } + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_QFUPL_SEND])) { + return MODEM_STATUS_ERROR; + } + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_QSSLCFG_CACERT])) { + return MODEM_STATUS_ERROR; + } + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_QSSLCFG_SECLEVEL])) { + return MODEM_STATUS_ERROR; + } + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_QSSLCFG_SSLVER])) { + return MODEM_STATUS_ERROR; + } + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_QSSLCFG_CIPH])) { + return MODEM_STATUS_ERROR; + } + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_QSSLCFG_IGNRTIME])) { + return MODEM_STATUS_ERROR; + }*/ + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_QMTCFG_WILL])) { + return MODEM_STATUS_ERROR; + } + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_QMTCFG_TIMEOUT])) { + return MODEM_STATUS_ERROR; + } + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_QMTCFG_KEEPALIVE])) { + return MODEM_STATUS_ERROR; + } + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_QMTCFG_VERSION])) { + return MODEM_STATUS_ERROR; + } + + /* Get signal strength at this location, more reliable than right after COPS. */ + /*if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_QCSQ])) { //Not needed - Partha March 14, 2022 + return MODEM_STATUS_ERROR; + }*/ + + /* Also get time here, may be more reliable. Time is needed before the first publish, below. */ + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_CCLK])) { + return MODEM_STATUS_ERROR; + } +#if FAKE_NETWORK + /*Don't do the actual MQTT connection */ + //For testing the new WF1 and WF2 messages - Partha - March 16, 2022 + + +#else + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_QMTOPEN])) { + return MODEM_STATUS_ERROR; + } + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_QMTCONN_CID])) { + return MODEM_STATUS_ERROR; + } + + // //Get Serving cell data - Partha - March 12, 2022 + // if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_QENG_SVCELL])) { + // return MODEM_STATUS_ERROR; + // } + // + // //GEt neighbout cell list - Partha - March 12, 2022 + // if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_QENG_NBCELL])) { + // return MODEM_STATUS_ERROR; + // } + +#endif + + bg96.cmd_complete_cb = cb; + bg96.mqtt_params.host = host; + bg96.mqtt_params.port = port; + //bg96.mqtt_params.jwt = jwt; + bg96.mqtt_params.client_id = client_id; + + int retval = start_cmd_sequence(); + + if (retval == MODEM_STATUS_OK) { + ESP_LOGI(TAG,"Starting connect mqtt sequence %d\r\n", bg96.cmd_num); + } + return retval; +} + +/* Publish data to the specific topic */ +int modem_mqtt_publish(modem_op_cb_t cb, const char *topic, const char *data, + int len) { + bg96.cmd_num = 0; + + if (!topic || !data) { + return MODEM_STATUS_ERROR; + } +#if FAKE_NETWORK + /*Don't do the actual MQTT connection */ +#else + /* Two-step operation, see QMTPUB command description. */ + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_QMTPUB])) { + return MODEM_STATUS_ERROR; + } + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_QMTPUB_SEND])) { + return MODEM_STATUS_ERROR; + } +#endif + bg96.cmd_complete_cb = cb; + bg96.mqtt_params.pub_topic = topic; + bg96.mqtt_params.pub_data = data; + bg96.mqtt_params.pub_data_len = len; + + int retval = start_cmd_sequence(); + + if (retval == MODEM_STATUS_OK) { + ESP_LOGI(TAG,"Starting mqtt publish %d bytes to %s\r\n", len, topic); + } + return retval; +} + +int modem_mqtt_close(modem_op_cb_t cb) { + bg96.cmd_num = 0; + +#if FAKE_NETWORK + /*Don't do the actual MQTT connection */ +#else + /* + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_QMTDISC])) { + return MODEM_STATUS_ERROR; + } + */ + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_QMTCLOSE])) { + return MODEM_STATUS_ERROR; + } +#endif + bg96.cmd_complete_cb = cb; + + int retval = start_cmd_sequence(); + + if (retval == MODEM_STATUS_OK) { + ESP_LOGI(TAG,"Starting mqtt close\r\n"); + } + return retval; +} +#endif +/* Setup the HTTP context */ +int modem_http_setup(modem_op_cb_t cb) { + bg96.cmd_num = 0; + + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_QHTTPCFG_CTX])) { + return MODEM_STATUS_ERROR; + } + + bg96.cmd_complete_cb = cb; + + int retval = start_cmd_sequence(); + + if (retval == MODEM_STATUS_OK) { + ESP_LOGI(TAG,"Starting http setup\r\n"); + } + return retval; +} + +/* Make an HTTP GET request and store result in supplied buffer */ +int modem_http_get_to_buf(modem_op_cb_t cb, const char *url) { + bg96.cmd_num = 0; + +#if FAKE_NETWORK + /*Don't do the actual HTTP connection */ +#else + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_QHTTPCFG_RHD_0])) { + return MODEM_STATUS_ERROR; + } + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_QHTTPURL])) { + return MODEM_STATUS_ERROR; + } + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_QHTTPURL_SET])) { + return MODEM_STATUS_ERROR; + } + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_QHTTPGET])) { + return MODEM_STATUS_ERROR; + } + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_QHTTPREAD])) { + return MODEM_STATUS_ERROR; + } +#endif + bg96.cmd_complete_cb = cb; + bg96.http_params.url = url; + + int retval = start_cmd_sequence(); + + if (retval == MODEM_STATUS_OK) { + ESP_LOGI(TAG,"Starting http get to buffer from url: %s\r\n", url); + } + return retval; +} + +/* Make an HTTP GET request and store result to file on modem file system. + * Use modem_read_from_file to get contents. + */ +int modem_http_get_to_file(modem_op_cb_t cb, const char *url, const char *file) { + bg96.cmd_num = 0; +#if FAKE_NETWORK + /*Don't do the actual HTTP connection */ +#else + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_QHTTPURL])) { + return MODEM_STATUS_ERROR; + } + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_QHTTPURL_SET])) { + return MODEM_STATUS_ERROR; + } + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_QHTTPGET])) { + return MODEM_STATUS_ERROR; + } + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_QHTTPREADFILE])) { + return MODEM_STATUS_ERROR; + } +#endif + bg96.cmd_complete_cb = cb; + bg96.http_params.url = url; + bg96.http_params.file = file; + + int retval = start_cmd_sequence(); + + if (retval == MODEM_STATUS_OK) { + ESP_LOGI(TAG,"Starting http get to file from url: %s file: %s\r\n", + bg96.http_params.url, bg96.http_params.file); + } + return retval; +} + +int modem_http_post_message(modem_op_cb_t cb, const char *url, const char *message) { + bg96.cmd_num = 0; +#if FAKE_NETWORK + /*Don't do the actual HTTP connection */ +#else + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_QHTTPCFG_RHD])) { + return MODEM_STATUS_ERROR; + } + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_QHTTPURL])) { + return MODEM_STATUS_ERROR; + } + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_QHTTPURL_SET])) { + return MODEM_STATUS_ERROR; + } + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_QHTTPPOST])) { + return MODEM_STATUS_ERROR; + } + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_QHTTPPOST_SET])) { + return MODEM_STATUS_ERROR; + } + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_QHTTPREAD])) { + return MODEM_STATUS_ERROR; + } +#endif + bg96.cmd_complete_cb = cb; + bg96.http_params.url = url; + bg96.http_params.post_message = message; + + int retval = start_cmd_sequence(); + + if (retval == MODEM_STATUS_OK) { + ESP_LOGI(TAG,"Starting http-post to send the json-formatted message");//: %s to url: %s \r\n", + //bg96.http_params.post_message, bg96.http_params.url); + } + return retval; +} + +int modem_read_from_file(modem_op_cb_t cb, const char *file, + modem_read_from_file_open cbOpen, modem_read_from_file_data cbData) { + bg96.cmd_num = 0; +#if FAKE_NETWORK + /*Don't do the actual read from file connection */ +#else + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_QFLST])) { + return MODEM_STATUS_ERROR; + } + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_QFOPEN])) { + return MODEM_STATUS_ERROR; + } + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_QFREAD])) { + return MODEM_STATUS_ERROR; + } + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_QFCLOSE])) { + return MODEM_STATUS_ERROR; + } +#endif + bg96.cmd_complete_cb = cb; + /* setup handler for QFLST uses this field for file name */ + bg96.file_params.file = file; + bg96.file_params.open_cb = cbOpen; + bg96.file_params.data_cb = cbData; + + int retval = start_cmd_sequence(); + + if (retval == MODEM_STATUS_OK) { + ESP_LOGI(TAG,"Starting read from file: %s\r\n", file); + } + return retval; +} + +/* Update modem command sequence. */ +int modem_update_modem(modem_op_cb_t cb, const char *url) { + bg96.cmd_num = 0; + ESP_LOGI(TAG,"cmd-> AT_CMD_IDX_QFOTADL"); + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_QFOTADL])) { + return MODEM_STATUS_ERROR; + } + + ESP_LOGI(TAG,"cmd-> AT_CMD_IDX_QFOTADL_WAIT_HTTPEND"); + if (MODEM_STATUS_ERROR + == add_cmd(&cmd_table[AT_CMD_IDX_QFOTADL_WAIT_HTTPEND])) { + return MODEM_STATUS_ERROR; + } + ESP_LOGI(TAG,"cmd-> AT_CMD_IDX_QFOTADL_WAIT_END"); + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_QFOTADL_WAIT_END])) { + return MODEM_STATUS_ERROR; + } + + bg96.cmd_complete_cb = cb; + bg96.http_params.url = url; + + int retval = start_cmd_sequence(); + + if (retval == MODEM_STATUS_OK) { + ESP_LOGI(TAG,"Started modem update sequence\r\n"); + } + return retval; +} + +/* Internal command sequence */ +static int shutdown_sequence(modem_op_cb_t cb) { + bg96.cmd_num = 0; + +#if 1 // Set 0 for testing error handling + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_QPOWD])) { + return MODEM_STATUS_ERROR; + } +#endif + bg96.cmd_complete_cb = cb; + + int retval = start_cmd_sequence(); + + if (retval == MODEM_STATUS_OK) { + ESP_LOGI(TAG,"Starting shutdown sequence\r\n"); + } + return retval; +} + +/* Functions ----------------------------------------------------------------*/ +extern bool uart1_rx_needed; + +static int start_rx_stream() { + memset(&RxScanContextSuccess, 0, sizeof(RxScanContextSuccess)); + memset(&RxScanContextError, 0, sizeof(RxScanContextError)); + memset(rxBuf, 0, MODEM_RX_BUFFER_LEN); + rx_idx = 0; + + uart1_rx_needed = true; + //bg96.poll_uart = true; + + return MODEM_STATUS_OK; +} + +static void stop_rx_stream() { + uart1_rx_needed = false; + bg96.poll_uart = false; +} + +/* Scan RX buffer with len characters in it for given string. + * Different from strstr, this function won't terminate on finding 0 in rxBuf. + * This handles modem's startup \0RDY indication. + */ +int scan_rx_buffer(int num_bytes, const char *str, ScanContext_t *scanContext, + const char *buf, int len) { + int str_len = strlen(str); + while (num_bytes > 0) { + /* Look for consecutive sequence of characters from str in buffer */ + if (buf[scanContext->RxScannerIdx] + == str[scanContext->RxScannerState]) { + scanContext->RxScannerState++; + if (scanContext->RxScannerState == str_len) { + return MODEM_STATUS_OK; + } + } else if (buf[scanContext->RxScannerIdx] == str[0]) { + scanContext->RxScannerState = 1; + if (scanContext->RxScannerState == str_len) { + return MODEM_STATUS_OK; + } + } else { + scanContext->RxScannerState = 0; + } + + if (++scanContext->RxScannerIdx == len) { + /* wrap the scanner around */ + scanContext->RxScannerIdx = 0; + } + + num_bytes--; + } + return MODEM_STATUS_ERROR; +} + +/* ------------------------------------------------------------------------- */ + +static const char* state_str(modem_state_t s) { + switch (s) { + case MODEM_STATE_INIT: + return "INIT"; + case MODEM_STATE_READY: + return "READY"; + case MODEM_STATE_WAIT_POWERUP: + return "WAIT_POWERUP"; + case MODEM_STATE_WAIT_STARTUP: + return "WAIT_STARTUP"; + case MODEM_STATE_WAIT_STARTUP_RDY: + return "WAIT_STARTUP_RDY"; + case MODEM_STATE_WAIT_POWERDOWN: + return "WAIT_POWERDOWN"; + case MODEM_STATE_CMD: + return "CMD"; + default: + return ""; + } +} + +static void transition(modem_state_t state_to) { + ESP_LOGI(TAG,"%s->%s\n", state_str(bg96.state), state_str(state_to)); + bg96.state = state_to; +} + +static int transition_ready(void) { + transition(MODEM_STATE_READY); + if (bg96.start_cb) { + bg96.start_cb(MODEM_STATUS_OK); + bg96.start_cb = 0; /* only send notification once */ + } + return MODEM_STATUS_OK; +} + +/* Monitor the stream periodically */ +static int monitor_rx_stream(const char *success, const char *error) { + /* Copy bytes from the circular buffer to the receive buffer for processing. + * The goal is to look for complete success or error strings + */ + uint16_t prev_rx_idx = rx_idx; + + int bytesCopied = board_uart_rx_stream_poll((uint8_t*) rxBuf, &rx_idx, sizeof(rxBuf)); + + if(bytesCopied > 0) + { + //ESP_LOGI(TAG,"Got %d bytes %d\r\n", bytesCopied, rx_idx); + //ESP_LOGI(TAG, "Uart RX: %s", rxBuf); + if(strstr(rxBuf,"+QIND: \"FOTA\",\"DOWNLOADING\"")) + { + + rx_idx = 0; + //ESP_LOGI(TAG, "Unecessary DFOTA DOWNLOADING LOGS"); + ESP_LOGI(TAG, "%s",rxBuf); + } + else + { + ESP_LOGI(TAG, "Uart RX:"); + } + + } + else + { + rx_idx = prev_rx_idx; + } + + if (rx_idx != 0) // if something in the buffer + { + /* Check for success and error strings in buffer */ + if (success && scan_rx_buffer(bytesCopied, success, &RxScanContextSuccess, rxBuf, MODEM_RX_BUFFER_LEN - 1) == MODEM_STATUS_OK) + { + ESP_LOGI(TAG, "VERIFIED RESPONSE: %s", success); + return MODEM_STATUS_OK; + } + + if (error && scan_rx_buffer(bytesCopied, error, &RxScanContextError, rxBuf, MODEM_RX_BUFFER_LEN - 1) == MODEM_STATUS_OK) + { + return MODEM_STATUS_ERROR; + } + } + + if(strstr(rxBuf,success)) + { + ESP_LOGI(TAG, "VERIFIED RESPONSE: %s", success); + return MODEM_STATUS_OK; + } + + if(strstr(rxBuf,error)) + { + return MODEM_STATUS_ERROR; + } + + + //ESP_LOGI(TAG, "Timeout .... didn't fined %s or %s", success,error); + + + + /* So far found nothing that matches */ + return MODEM_STATUS_TIMEOUT; +} + +/* Send the current command in the sequence */ +static int send_command(const modem_cmd_t *cmd) // const char* cmd, int timeout_ms) +{ + int retval = MODEM_STATUS_OK; + + /*Checking the passed command(check it it's zero or not)*/ + if (cmd->response_match_str) { + /* Start the receive stream */ + retval = start_rx_stream(); + } else { + /*return MODEM_STATUS_OK */ + retval = MODEM_STATUS_OK; + } + + if (MODEM_STATUS_OK == retval) { + if(ESP_OK == esp_timer_start_once(modem_timer, 1000*(cmd->wait_ms))) + { + retval = MODEM_STATUS_OK; + } + if (MODEM_STATUS_OK == retval) { + const char *cmd_str = cmd->cmd_str; + /* Invoke setup function */ + if (cmd->setup) { + if (MODEM_STATUS_OK + == cmd->setup(cmd->params, txBuf, sizeof(txBuf))) { + cmd_str = txBuf; + } + } + if (cmd_str) { + /* trace the command sent to modem */ + ESP_LOGI(TAG,"SEND: %s",cmd_str); + uart_ifx_uart1_send_bytes((uint8_t *)cmd_str, strlen(cmd_str)); + } + /* Invoke the optional command-specific send function */ + if (cmd->send) { + cmd->send(); + } + + transition(MODEM_STATE_CMD); + } else { + stop_rx_stream(); + } + } + + return retval; +} + +/* Run a command sequence + * Return index of last command the suceeded, + * if it matchs the number of commands-1 then it completed. + */ + +static int start_cmd_sequence(void) { +#if FAKE_COMMS + /* Don't issue any commands */ + if (bg96.cmd_complete_cb) { + bg96.cmd_complete_cb(MODEM_STATUS_OK); + bg96.cmd_complete_cb = 0; + } + return MODEM_STATUS_OK; +#else + int retval = MODEM_STATUS_OK; + + bg96.cmd_sequence = 0; + + /* Submit each command to the command state */ + if (bg96.cmd_sequence < bg96.cmd_num) { + const modem_cmd_t *cmd = bg96.cmd_list[bg96.cmd_sequence]; + if (cmd) { + bg96.cmd_retries = 0; + retval = send_command(cmd); + } + } else { + /* Sequence wasn't started for whatever reason, indicate to caller + * that it is done. + */ + if (bg96.cmd_complete_cb) { + bg96.cmd_complete_cb(MODEM_STATUS_OK); + bg96.cmd_complete_cb = 0; + } + } + return retval; +#endif +} + +static int end_cmd_sequence(int status) { + stop_rx_stream(); + + ESP_LOGI(TAG,"Ending command sequence : %d %d\r\n", bg96.is_startup, status); + + /* end a command sequence + * notify callback with result + */ + if (bg96.cmd_complete_cb) { + bg96.cmd_complete_cb(status); + bg96.cmd_complete_cb = 0; + } + + if (bg96.is_startup) { + bg96.is_startup = false; + /* First time in ready */ + transition_ready(); + } else { + /* Go back to ready - only if we were in the CMD state. + * This is to support cases where callbacks modify the state + */ + if (bg96.state == MODEM_STATE_CMD) { + transition(MODEM_STATE_READY); + } + } + + return MODEM_STATUS_OK; +} + +/* Go to the next command if any. + Otherwise end it successfully. + */ +static int next_cmd_sequence(void) { + int retval = MODEM_STATUS_ERROR; + + if (bg96.cmd_repeat) { + ESP_LOGI(TAG,"Repeating command\r\n"); + /* repeat the same command if requested by a command handler. */ + bg96.cmd_repeat = false; + } else { + /* Move to next command in sequence */ + bg96.cmd_sequence++; + } + + ESP_LOGI(TAG,"Next command sequence: %d/%d\r\n", bg96.cmd_sequence + 1, + bg96.cmd_num); + + if (bg96.cmd_sequence == bg96.cmd_num) { + /* Notify success because we've completed all commands. */ + retval = end_cmd_sequence(MODEM_STATUS_OK); + + } else { + const modem_cmd_t *cmd = bg96.cmd_list[bg96.cmd_sequence]; + if (cmd) { + bg96.cmd_retries = 0; + retval = send_command(cmd); + } + } + return retval; +} + +/* Command sequence performed by modem at each startup before entering READY state. */ +static int start_ready_cmd_sequence(void) { + bg96.cmd_num = 0; + + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_ECHO_OFF])) { + return MODEM_STATUS_ERROR; + } +#if BOARD_USE_CTS_RTS + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_IFC])) { + return MODEM_STATUS_ERROR; + } +#endif + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_IDENT])) { + return MODEM_STATUS_ERROR; + } +#if MODEM_MODEM_FWVER_FROM_QGMR + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_QGMR])) { + return MODEM_STATUS_ERROR; + } +#endif + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_IMEI])) { + return MODEM_STATUS_ERROR; + } + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_ICCID])) { + return MODEM_STATUS_ERROR; + } +#if FAKE_NETWORK + /* Set time on modem to test programming of time with CCLK otherwise + * modem's default time is year 2080!! + */ + if (MODEM_STATUS_ERROR == add_cmd(&cmd_table[AT_CMD_IDX_SETCCLK])) { + return MODEM_STATUS_ERROR; +} +#endif + + ESP_LOGI(TAG,"Starting READY command sequence %d\r\n", bg96.cmd_num); + + return start_cmd_sequence(); +} + +static int start_modem(void) { + int retval = MODEM_STATUS_OK; + + bg96.is_startup = true; + +#if MODEM_BLIND_MODEM == 0 + + /* Modem already started ?! */ + if (port_modem_is_on()) { +#if MODEM_DEBUG_MODEM_POWER_STATE + //board_led_green_on(); + hmi_choose_led(HMI_LED_GREEN); +#endif + ESP_LOGI(TAG,"Modem already started. Interface ready.\r\n"); + retval = start_ready_cmd_sequence(); + } else +#endif /* MODEM_BLIND_MODEM */ + { + /* Start the receive stream before we start the modem to support the + * RDY method of determining when modem interface is up. + * We go through two phase: one is waiting for status to go high, then wait + * for RDY or a timeout. + */ + retval = start_rx_stream(); + port_modem_ldo_pin(1); + vTaskDelay(100 / portTICK_PERIOD_MS); + if (MODEM_STATUS_OK == retval) { + /* Start a timer to time power key duration. */ + if(ESP_OK == esp_timer_start_once(modem_timer, 1000*MODEM_PWRKEY_ON_DELAY_MS)) + { + retval = MODEM_STATUS_OK; + } + + if (MODEM_STATUS_OK == retval) { + ESP_LOGI(TAG,"Turning on - asserting power key\r\n"); + port_modem_assert_pwrkey(); + transition(MODEM_STATE_WAIT_POWERUP); +#if MODEM_DEBUG_MODEM_POWER_STATE + //board_led_green_on(); + hmi_choose_led(HMI_LED_GREEN); +#endif + } else { + ESP_LOGI(TAG,"Failed to turn on modem\r\n"); + stop_rx_stream(); + } + } + } + return retval; +} + +#if MODEM_BLIND_MODEM == 0 +static int stop_modem_pwrkey(void) { + int retval = MODEM_STATUS_OK; + + /* Stop any timer that might be on going */ + esp_timer_stop(modem_timer); + + if (port_modem_is_on()) { + /* Start a timer to time power key duration. */ + if(ESP_OK == esp_timer_start_once(modem_timer, 1000*MODEM_PWRKEY_OFF_DELAY_MS)) + { + retval = MODEM_STATUS_OK; + } + if (MODEM_STATUS_OK == retval) { + ESP_LOGI(TAG,"Turning off - asserting power key\r\n"); + bg96.shutdown_counter = 0; + bg96.shutdown_qpowd = false; + port_modem_assert_pwrkey(); + transition(MODEM_STATE_WAIT_POWERKEY); + } else { + ESP_LOGI(TAG,"Failed to turn off modem\r\n"); + transition(MODEM_STATE_INIT); + port_modem_ldo_pin(0); + } + } else { + ESP_LOGI(TAG,"Turning off - modem already off\r\n"); + transition(MODEM_STATE_INIT); + } + return retval; +} +#endif + +static void shutdown_seq_complete_cb(int retval) { + if (MODEM_STATUS_OK == retval) { + esp_timer_stop(modem_timer); + /* Start a timer to monitor STATUS for shutdown. */ + if(ESP_OK == esp_timer_start_once(modem_timer, 1000*MODEM_SHUTDOWN_STATUS_MONITOR_PERIOD_MS)) + { + retval = MODEM_STATUS_OK; + } + bg96.shutdown_counter = 0; + bg96.shutdown_qpowd = true; + transition(MODEM_STATE_WAIT_POWERDOWN); + } else { + ESP_LOGI(TAG,"Failed to turn off with command\r\n"); +#if MODEM_BLIND_MODEM + transition(MODEM_STATE_INIT); + port_modem_ldo_pin(0); +#else + stop_modem_pwrkey(); +#endif + } +} + +static int stop_modem(void) { + int retval = MODEM_STATUS_OK; + + /* Stop any timer that might be on going */ + esp_timer_stop(modem_timer); + +#if MODEM_BLIND_MODEM == 0 + if (port_modem_is_on()) +#endif + { + /* Start the shutdown sequence */ + retval = shutdown_sequence(shutdown_seq_complete_cb); + if (MODEM_STATUS_OK != retval) { + ESP_LOGI(TAG,"Failed to turn off modem with command\r\n"); +#if MODEM_BLIND_MODEM == 0 + retval = stop_modem_pwrkey(); +#endif + } + } +#if MODEM_BLIND_MODEM == 0 + else { + ESP_LOGI(TAG,"Turning off - modem already off\r\n"); + transition(MODEM_STATE_INIT); + } +#endif + return retval; +} + +/* !! Wait an additional period for the UART interface to become active. + * An alternative is: (from BG96 UART app note) + * Note: AT command can be input through UART port only after module is powered + * on and the Unsolicited Result Code "RDY" is output. + * Note: observed that a 0 is output before the RDY code. + * Note: Device outputs "RDY", then later "APP RDY". It doesn't respond until APP RDY. + * Note: Normally this is about 4500 ms after bootup. In some instances, this period + * elapses without detecting "APP RDY", even though modem responds to AT commands. + * + * Notes for BG77: + * RDY seems to appear about when STATUS is raised, this is about 1-2 seconds later. + * APP RDY seems to appear about 3 seconds after RDY. + */ +static int wait_modem_ready(void) { + int retval = MODEM_STATUS_OK; + + /* Note that modem rx stream was started at begining of startup process + * to capture RDY whenever it arrives + */ + if(ESP_OK == esp_timer_start_once(modem_timer, 1000*MODEM_STARTUP_RDY_TIMEOUT_MS)) + { + retval = MODEM_STATUS_OK; + } + + if (MODEM_STATUS_OK == retval) { + transition(MODEM_STATE_WAIT_STARTUP_RDY); + ESP_LOGI(TAG,"Waiting for AT interface activation\r\n"); + } + + return retval; +} + +/* ------------------------------------------------------------------------- */ +#if (WIFI_NEEDED == 1) +extern bool server_uart_flag; +#endif +void uart_ifx_uart1_rx_cb(void) { + bg96.poll_uart = true; +#if (WIFI_NEEDED == 1) + server_uart_flag = 1; +#endif +} + +static void timer_handler(void *context) +{ + bg96.poll_timer = true; +} + +static int state_machine(modem_event_t evt) { + int retval = MODEM_STATUS_OK; + switch (bg96.state) { + case MODEM_STATE_INIT: + if (evt == MODEM_EVENT_START) { + /* Indicate offloading data */ + //hmi_set_offload_mode(true); + ESP_LOGI(TAG,"Process started.\n"); + + /* Start modem and set next state */ + retval = start_modem(); + } else { + //ESP_LOGW(TAG,"Unhandled event %d : state %d\r\n", evt, bg96.state); + } + break; + + /* wait for modem powerkey assertion delay */ + case MODEM_STATE_WAIT_POWERUP: + if (evt == MODEM_EVENT_TIMER) { + //board_modem_deassert_pwrkey(); + port_modem_deassert_pwrkey(); + /* Start a timer to poll for status. */ + if(ESP_OK == esp_timer_start_once(modem_timer, 1000*MODEM_TIMER_GRANULARITY_MS)) + { + retval = MODEM_STATUS_OK; + } + bg96.poll_periods = MODEM_STARTUP_STATUS_TIMEOUT_MS + / MODEM_TIMER_GRANULARITY_MS; + transition(MODEM_STATE_WAIT_STARTUP); + ESP_LOGI(TAG,"Waiting for status activation\r\n"); + } else if (evt == MODEM_EVENT_UART) { + /* Ignore UART events */ + } else { + ESP_LOGW(TAG,"Unhandled event %d : state %d\r\n", evt, bg96.state); + } + break; + + /* wait for modem status to go high */ + case MODEM_STATE_WAIT_STARTUP: + if (evt == MODEM_EVENT_TIMER) { +#if MODEM_BLIND_MODEM + /* Wait for the AT interface to ready */ + retval = wait_modem_ready(); +#else + if (port_modem_is_on()) { + /* Wait for the AT interface to ready */ + retval = wait_modem_ready(); + } else if (--bg96.poll_periods > 0) { + /* Keep waiting */ + esp_timer_start_once(modem_timer, 1000*MODEM_TIMER_GRANULARITY_MS); + } else { + /* Timed out. */ + ESP_LOGI(TAG,"Modem startup timed out\r\n"); + stop_rx_stream(); + transition(MODEM_STATE_INIT); + bg96.start_cb(MODEM_STATUS_ERROR); + } +#endif /* MODEM_BLIND_MODEM */ + } else if (evt == MODEM_EVENT_UART) { + /* Ignore UART events */ + } else { + ESP_LOGI(TAG,"Unhandled event %d : state %d\r\n", evt, bg96.state); + retval = MODEM_STATUS_ERROR; + } + break; + + /* wait for modem AT interface to come up */ + case MODEM_STATE_WAIT_STARTUP_RDY: + + if (evt == MODEM_EVENT_UART) { + /* monitor for the modem interface "ready" indication */ + int res = monitor_rx_stream("RDY", NULL); + if (MODEM_STATUS_OK == res) { + /* Stop the timeout timer waiting for APP RDY now that we have it */ + /* Note: APP RDY seems to come about 3 seconds after RDY. */ + esp_timer_stop(modem_timer); + ESP_LOGI(TAG,"AT interface activated.\r\n"); + // hmi_set_modem_error(false); /* clear modem error on off chance it actually recovered. */ + retval = start_ready_cmd_sequence(); + } else { + /* Keep listening */ + } + } else if (evt == MODEM_EVENT_TIMER) { +#if MODEM_BLIND_MODEM + /* clear this anyways for blind modem testing */ + hmi_set_modem_error(false); +#endif + /* Timed out. */ + ESP_LOGW(TAG,"timeout waiting for modem ready\r\n"); + /* Start ready sequence anyways */ + //retval = start_ready_cmd_sequence(); + retval = MODEM_STATUS_ERROR; + } else { + ESP_LOGI(TAG,"Unhandled event %d : state %d\r\n", evt, bg96.state); + retval = MODEM_STATUS_ERROR; + } + break; + + /* waiting for response from command */ + case MODEM_STATE_CMD: + + if (evt == MODEM_EVENT_TIMER) { + /* Timeout */ + stop_rx_stream(); + + const modem_cmd_t *cmd = bg96.cmd_list[bg96.cmd_sequence]; + if (cmd && cmd->response_match_str) { + /* We will stop the sequence unless a handler can reverse this decision by + * returning an OK or there are retries available. + */ + int res = MODEM_STATUS_ERROR; + + /* If the command had no responses to wait for, invoke the handler now */ + //if (cmd->response_match_str == 0 && cmd->err_match_str == 0) + { + if (cmd->handler) { + res = cmd->handler(MODEM_STATUS_TIMEOUT, rxBuf, rx_idx); + } + } + + if (res == MODEM_STATUS_OK) { + /* A success response from the handler can continue the sequence. */ + retval = next_cmd_sequence(); + } else { + /* Handler was not available or did not reverse the error condition. */ + ESP_LOGW(TAG,"Command response timed out\r\n"); + + /* See if we need to retry */ + if (bg96.cmd_retries++ < cmd->retries) { + ESP_LOGW(TAG,"retry (%d/%d) command (%d/%d): %s\r\n", + bg96.cmd_retries, cmd->retries, + bg96.cmd_sequence + 1, bg96.cmd_num, + cmd->cmd_str); + retval = send_command(cmd); + } else { + if(cmd->cmd_str) + { + ESP_LOGW(TAG,"Command failed: %s", cmd->cmd_str); /* command strings have \r\n */ + } + else + { + ESP_LOGW(TAG,"The command that has the response %s ---> get failed", cmd->response_match_str); + } + retval = end_cmd_sequence(MODEM_STATUS_ERROR); + } + } + } else if (cmd->response_match_str == 0) { + /*Check if there's a timeout handle to be executed*/ + if (cmd->handler) { + /*Call the Command handler*/ + cmd->handler(MODEM_STATUS_OK, rxBuf, rx_idx); + } + /*Execute the next command in the command list*/ + retval = next_cmd_sequence(); + } + } + else if (evt == MODEM_EVENT_UART) { + /* Process the current command */ + const modem_cmd_t *cmd = bg96.cmd_list[bg96.cmd_sequence]; + if (cmd && cmd->response_match_str) + { + /* monitor for responses */ + int res = monitor_rx_stream(cmd->response_match_str, cmd->err_match_str); + + /* Run the handler for found success or error responses */ + if((MODEM_STATUS_OK == res) || (MODEM_STATUS_ERROR == res)) + { + if (cmd->handler) + { + /* A success response from the handler can continue the sequence. */ + ESP_LOGI(TAG," going to handler"); + res = cmd->handler(res, rxBuf, rx_idx); + } + } + + if (MODEM_STATUS_ERROR == res) + { + esp_timer_stop(modem_timer); + /* matched the expected error response, fail the sequence */ + ESP_LOGI(TAG,"MODEM_STATUS_ERROR -> end_cmd_sequence "); + retval = end_cmd_sequence(MODEM_STATUS_ERROR); + } + else if (MODEM_STATUS_OK == res) + { + esp_timer_stop(modem_timer); + ESP_LOGI(TAG,"MODEM_STATUS_OK -> next_cmd_sequence "); + /* matched the expected success response move on to the next */ + retval = next_cmd_sequence(); + } + else + { + /* nothing found yet */ + } + } + } else { + ESP_LOGI(TAG,"Unhandled event %d : state %d\r\n", evt, bg96.state); + retval = MODEM_STATUS_ERROR; + } + + break; + + case MODEM_STATE_READY: + if (evt == MODEM_EVENT_TIMER) { + + } else if (evt == MODEM_EVENT_SEND_CMD) { + /* request to send a command sequence */ + /* must have already been setup */ + } else if (evt == MODEM_EVENT_STOP) { + ESP_LOGI(TAG,"Process stopping.\n"); + retval = stop_modem(); + } else { + ESP_LOGI(TAG,"Unhandled event %d : state %d\r\n", evt, bg96.state); + } + break; + + case MODEM_STATE_WAIT_POWERDOWN: + if (evt == MODEM_EVENT_TIMER) { + /* Monitor STATUS for the shutdown duration. If it is still active every 10 seconds + * we note that in a warning log. + * If it doesn't shutdown after 65 seconds as datasheet says we start an LED + * error sequence. + */ +#if MODEM_BLIND_MODEM == 0 + if (port_modem_is_on()) { + bg96.shutdown_counter++; + /* Start a timer to monitor STATUS for shutdown. */ + if(ESP_OK == esp_timer_start_once(modem_timer, 1000*MODEM_SHUTDOWN_STATUS_MONITOR_PERIOD_MS)) + { + retval = MODEM_STATUS_OK; + } + if ((bg96.shutdown_counter % MODEM_SHUTDOWN_COUNT_WARNING_SEC) + == 0) { + ESP_LOGW(TAG,"Shutting down, modem still on %d\r\n", + bg96.shutdown_counter + / MODEM_SHUTDOWN_COUNT_WARNING_SEC); + } + + if (bg96.shutdown_counter > MODEM_SHUTDOWN_COUNT_LIMIT_SEC) { + /* Waited as long as we're going to. Try power key approach if we were + * doing the QPOWD approach. + */ + if (bg96.shutdown_qpowd) { + bg96.shutdown_qpowd_failures++; + ESP_LOGI(TAG,"Failed to shutdown modem with command. %d\r\n", + bg96.shutdown_qpowd_failures); + retval = stop_modem_pwrkey(); + } else { + /* This is bad. Modem does not appear to be shutdown, + * and it is likely on next power up cycle it won't + * be in the right state to use. + * Solution is to have hard power control of the modem: + * disconnect the power rails, hopefully guaranteeing + * a startup in a known state. + * Without hard power control user must remove batteries. + */ + bg96.shutdown_pwrkey_failures++; + ESP_LOGI(TAG,"Failed to shutdown modem. %d\r\n", + bg96.shutdown_pwrkey_failures); + /* Install an LED sequence to indicate this error condition. + * User would need to remove batteries to recover likely. + */ + // hmi_set_modem_error(true); + transition(MODEM_STATE_INIT); + port_modem_ldo_pin(0); + } + } + } else +#endif /* MODEM_BLIND_MODEM */ + { +#if MODEM_DEBUG_MODEM_POWER_STATE + board_led_green_off(); +#endif + ESP_LOGI(TAG,"Powered down, count=%d [%d %d]\r\n", + bg96.shutdown_counter, bg96.shutdown_qpowd_failures, + bg96.shutdown_pwrkey_failures); + transition(MODEM_STATE_INIT); + port_modem_ldo_pin(0); + } + } else { + ESP_LOGW(TAG,"Unhandled event %d : state %d\r\n", evt, bg96.state); + } + break; + + case MODEM_STATE_WAIT_POWERKEY: + if (evt == MODEM_EVENT_TIMER) { + port_modem_deassert_pwrkey(); + ESP_LOGI(TAG,"Powering down with power key.\r\n"); + if(ESP_OK == esp_timer_start_once(modem_timer, 1000*MODEM_SHUTDOWN_STATUS_MONITOR_PERIOD_MS)) + { + retval = MODEM_STATUS_OK; + } + transition(MODEM_STATE_WAIT_POWERDOWN); + } else { + ESP_LOGW(TAG,"Unhandled event %d : state %d\r\n", evt, bg96.state); + } + break; + + default: + break; + } + + return retval; +} + +/* ------------------------------------------------------------------------- */ + +/* Initialize. */ +int modem_init(void) { + int retval = MODEM_STATUS_OK; + + memset(&bg96, 0, sizeof(bg96)); + + /* Note imei is 15 character string */ + memset(bg96.imei, '0', sizeof(bg96.imei) - 1); + + //timer_initiating(MODEM_TIMER_ID, timer_handler); + //timer_starting(MODEM_TIMER_ID, 1000); + const esp_timer_create_args_t modem_timer_args = { + .callback = &timer_handler, + /* argument specified here will be passed to timer callback function */ + .arg = (void*) modem_timer, + .name = "modem-timer" + }; + esp_timer_create(&modem_timer_args, &modem_timer); + + ESP_LOGI(TAG,"Process initialized.\n"); + + return retval; +} + +/* Start the process */ +int modem_start(modem_start_cb_t cb) { + +#if FAKE_COMMS + /* Go directly to ready state. Add an IMEI and fw ver */ + strcpy(bg96.fw_ver, "BG95M2LAR01A01"); // BG77LAR02A04 + + // Units deployed + //strcpy(bg96.imei, "866349041329859"); + //strcpy(bg96.imei, "866349041332549"); + //strcpy(bg96.imei, "866349041331970"); + + // 866349041329859 -> (extract) 904132985 -> (hex) 35E3F979 -> major=0x35E3 minor=0xF979 + strcpy(bg96.imei, "866349041329859"); + + ESP_LOGI(TAG,"IMEI No: %s\r\n", bg96.imei); + config_set_device_id_from_imei(bg96.imei); + + transition(MODEM_STATE_READY); + if (cb) { + cb(MODEM_STATUS_OK); + } + return MODEM_STATUS_OK; +#else + bg96.start_cb = cb; + int retval = state_machine(MODEM_EVENT_START); + //xTaskCreate(modem_poll, "BG77_POLL", 2048, NULL, 9, NULL); + return retval; +#endif +} + +/* Stop the process */ +int modem_stop(void) { +#if FAKE_COMMS + transition(MODEM_STATE_INIT); + return MODEM_STATUS_OK; +#else + int retval = state_machine(MODEM_EVENT_STOP); + return retval; +#endif +} + +/* Poll the process */ +int modem_poll(void) { + int retval = MODEM_STATUS_OK; + if (bg96.poll_timer) { + bg96.poll_timer = false; + retval = state_machine(MODEM_EVENT_TIMER); + } else if (bg96.poll_uart) { + //bg96.poll_uart = false; + retval = state_machine(MODEM_EVENT_UART); + } + + return retval; +} + +/* Check if the process needs to be polled */ +bool modem_needs_poll(void) { + return bg96.poll_timer || bg96.poll_uart; +} + +/* Check if the process is started */ +bool modem_is_started(void) { + return bg96.state != MODEM_STATE_INIT; +} + +/* Check if the process is ready */ +bool modem_is_ready(void) { + return bg96.state == MODEM_STATE_READY; +} + +const char* modem_get_imei(void) { + return bg96.imei; +} + +const char* modem_get_iccid(void) +{ + return bg96.iccid; +} + + +const modem_signal_strength_t* modem_get_signal_strength(void) { + return &bg96.sig_strength; +} + +const char* modem_get_fw_ver(void) { + return bg96.fw_ver; +} + +int modem_http_get_buf(char **bufptr, int *len) { +#if FAKE_COMMS || FAKE_NETWORK + +#if 0 // TEST MODEM UPDATE SP5 SEQUENCE + + /* First comms: GET CONFIG (ignore flags because first contact) then GET WHITELIST. + * scond comms: GET CONFIG, check flags, then GET WHITELIST + */ + static int iter = 0; + if (iter == 0) { + /* Put in a test configuration record SP3 for comms process to use */ + bg96.http_params.buf = rxBuf; + /* flags scan_int_SEC scan_win_MSEC tx_pwr_DB broadcast_int_MSEC comms_int_MIN */ + /* 0x1 - Whitelist + * 0x2 - MCU update + * 0x4 - Modem update + */ + bg96.http_params.len = snprintf(bg96.http_params.buf, sizeof(rxBuf), "SP3 %s 1599777618 05 15 2500 1 800 2 EP", bg96.imei); + } + else if (iter == 1) { + /* Put in a test configuration record SP4 for comms process to use */ + bg96.http_params.buf = rxBuf; + bg96.http_params.len = snprintf(bg96.http_params.buf, sizeof(rxBuf), "SP4 %s 1599777618 01,0AFF4C001005511C4EAB522599000000 02,20026425603AB04037501A9E3E3EC785 03,9FFE0000000000000000000000000000 EP", bg96.imei); + + } + else if (iter == 2) { + /* Put in a test configuration record SP3 for comms process to use */ + bg96.http_params.buf = rxBuf; + /* flags scan_int_SEC scan_win_MSEC tx_pwr_DB broadcast_int_MSEC comms_int_MIN */ + bg96.http_params.len = snprintf(bg96.http_params.buf, sizeof(rxBuf), "SP3 %s 1599777618 05 15 2500 1 800 2 EP", bg96.imei); + } + else if (iter == 3) { + /* Put in a test configuration record SP4 for comms process to use */ + bg96.http_params.buf = rxBuf; + bg96.http_params.len = snprintf(bg96.http_params.buf, sizeof(rxBuf), "SP4 %s 1599777618 01,0AFF4C001005091C2AC447CC28D56500 02,000906031EC0A8014500000001000000 03,000906031EC0A8014500000001000000 EP", bg96.imei); + } + else if (iter == 4) { + /* Put in a test configuration record SP5 for comms process to use */ + bg96.http_params.buf = rxBuf; + //bg96.http_params.len = snprintf(bg96.http_params.buf, sizeof(rxBuf), "SP5 %s 1599777618 BG77LAR02A04 EP", bg96.imei); + bg96.http_params.len = snprintf(bg96.http_params.buf, sizeof(rxBuf), "SP5 %s 1599777618 BG77LAR02A03 EP", bg96.imei); + } + + if (++iter > 4) { + iter = 0; + } + +#endif + + +#if 0 // TEST MCU UPDATE SP5 SEQUENCE + + /* First comms: GET CONFIG (ignore flags because first contact) then GET WHITELIST. + * scond comms: GET CONFIG, check flags, then GET WHITELIST + */ + static int iter = 0; + if (iter == 0) { + /* Put in a test configuration record SP3 for comms process to use */ + bg96.http_params.buf = rxBuf; + /* flags scan_int_SEC scan_win_MSEC tx_pwr_DB broadcast_int_MSEC comms_int_MIN */ + /* 0x1 - Whitelist + * 0x2 - MCU update + * 0x4 - Modem update + */ + bg96.http_params.len = snprintf(bg96.http_params.buf, sizeof(rxBuf), "SP3 %s 1599777618 02 15 2500 1 800 2 EP", bg96.imei); + } + else if (iter == 1) { + /* Put in a test configuration record SP4 for comms process to use */ + bg96.http_params.buf = rxBuf; + bg96.http_params.len = snprintf(bg96.http_params.buf, sizeof(rxBuf), "SP5 %s 1599777618 LRSM0005_v2 EP", bg96.imei); + + }else if (iter == 2) { + /* Put in a test configuration record SP3 for comms process to use */ + bg96.http_params.buf = rxBuf; + /* flags scan_int_SEC scan_win_MSEC tx_pwr_DB broadcast_int_MSEC comms_int_MIN */ + bg96.http_params.len = snprintf(bg96.http_params.buf, sizeof(rxBuf), "SP3 %s 1599777618 01 15 2500 1 800 2 EP", bg96.imei); + } + else if (iter == 3) { + /* Put in a test configuration record SP4 for comms process to use */ + bg96.http_params.buf = rxBuf; + bg96.http_params.len = snprintf(bg96.http_params.buf, sizeof(rxBuf), "SP4 %s 1599777618 01,0AFF4C001005091C2AC447CC28D56500 02,000906031EC0A8014500000001000000 03,000906031EC0A8014500000001000000 EP", bg96.imei); + } + else if (iter == 4) { + /* Put in a test configuration record SP5 for comms process to use */ + bg96.http_params.buf = rxBuf; + //bg96.http_params.len = snprintf(bg96.http_params.buf, sizeof(rxBuf), "SP5 %s 1599777618 BG77LAR02A04 EP", bg96.imei); + bg96.http_params.len = snprintf(bg96.http_params.buf, sizeof(rxBuf), "SP5 %s 1599777618 BG77LAR02A03 EP", bg96.imei); + } + + if (++iter > 4) { + iter = 0; + } + +#endif + +#if 1 + + /* First comms: GET CONFIG (ignore flags because first contact) then GET WHITELIST. + * scond comms: GET CONFIG, check flags, then GET WHITELIST + */ + static int iter = 0; + if (iter == 0) { + /* Put in a test configuration record SP3 for comms process to use */ + bg96.http_params.buf = rxBuf; + /* flags scan_int_SEC scan_win_MSEC tx_pwr_DB broadcast_int_MSEC comms_int_MIN */ + /* 0x1 - Whitelist + * 0x2 - MCU update + * 0x4 - Modem update + */ + bg96.http_params.len = snprintf(bg96.http_params.buf, sizeof(rxBuf), "SP3 %s 1599777618 01 15 2500 1 800 2 EP", bg96.imei); + } + else if (iter == 1) { + /* Put in a test configuration record SP4 for comms process to use */ + bg96.http_params.buf = rxBuf; + bg96.http_params.len = snprintf(bg96.http_params.buf, sizeof(rxBuf), "SP4 %s 1599777618 01,0AFF4C001005511C4EAB522599000000 02,20026425603AB04037501A9E3E3EC785 03,9FFE0000000000000000000000000000 EP", bg96.imei); + + } + else if (iter == 2) { + /* Put in a test configuration record SP3 for comms process to use */ + bg96.http_params.buf = rxBuf; + /* flags scan_int_SEC scan_win_MSEC tx_pwr_DB broadcast_int_MSEC comms_int_MIN */ + bg96.http_params.len = snprintf(bg96.http_params.buf, sizeof(rxBuf), "SP3 %s 1599777618 05 15 2500 1 800 2 EP", bg96.imei); + } + else if (iter == 3) { + /* Put in a test configuration record SP4 for comms process to use */ + bg96.http_params.buf = rxBuf; + bg96.http_params.len = snprintf(bg96.http_params.buf, sizeof(rxBuf), "SP4 %s 1599777618 01,0AFF4C001005091C2AC447CC28D56500 02,000906031EC0A8014500000001000000 03,000906031EC0A8014500000001000000 EP", bg96.imei); + } + else if (iter == 4) { + /* Put in a test configuration record SP5 for comms process to use */ + bg96.http_params.buf = rxBuf; + //bg96.http_params.len = snprintf(bg96.http_params.buf, sizeof(rxBuf), "SP5 %s 1599777618 BG77LAR02A04 EP", bg96.imei); + bg96.http_params.len = snprintf(bg96.http_params.buf, sizeof(rxBuf), "SP5 %s 1599777618 BG77LAR02A03 EP", bg96.imei); + } + + if (++iter > 4) { + iter = 0; + } + +#endif + +#endif + + if (bufptr && len) { + if (bg96.http_params.buf && bg96.http_params.len > 0) { + *bufptr = bg96.http_params.buf; + *len = bg96.http_params.len; + return MODEM_STATUS_OK; + } + *bufptr = 0; + *len = 0; + } + return MODEM_STATUS_ERROR; +} + +/* ------ Process Callbacks ------------------------- */ + +__attribute__((weak)) void modem_ready_cb(void) { +} + diff --git a/main/modem.h b/main/modem.h new file mode 100644 index 0000000..5990088 --- /dev/null +++ b/main/modem.h @@ -0,0 +1,181 @@ +/* + * bg96.h + * + * Created on: Jan 11, 2023 + * Author: Sword + */ + +#ifndef MAIN_MODEM_H_ +#define MAIN_MODEM_H_ + +#include +#include +#include "sdkconfig.h" + +#define MODEM_STATUS_OK 0 +#define MODEM_STATUS_ERROR -1 +#define MODEM_STATUS_TIMEOUT -2 +#define MODEM_STATUS_MQTT_PUB_OVERFLOW -10 +#define MODEM_STATUS_HTTP_POST_WAITRES -11 +#define MCU_OTA_FILE_LOCAL "OTA.bin" + + +typedef struct +{ + /* Fields read from AT+QCSQ command */ + int16_t rssi; + int16_t rsrp; + int16_t sinr; + int16_t rsrq; + +} modem_signal_strength_t; + + +/* Modem's unique identifier IMEI string, null terminated. + * Maximum size of buffer returned via modem_get_imei(). +*/ + +#define MODEM_IMEI_LEN 16 + + +/* Modem's firmware version string, null terminated. + * This can include format where modem+application versions are reported. + * Maximum size of buffer returned via modem_get_fw_ver(). +*/ +#define MODEM_FWVER_LEN 32 + + +/////////////////////////////////////////////////////////////// +// BG96 module process interface + +typedef void (*modem_start_cb_t)(int status); + +/* Operation complete indication callback */ +typedef void (*modem_op_cb_t)(int status); + + +/* Connect to network service provider + * once the modem is ready. + * + * Non-blocking. + * + * Returns OK if command sequence started. + * Callback is invoked when completed. +*/ +int modem_network_connect(modem_op_cb_t cb); + +/*==== HTTP API ==== */ + +/* Setup the HTTP context */ +int modem_http_setup(modem_op_cb_t cb); + +/* Make an HTTP GET request and frame result in internal buffer */ +int modem_http_get_to_buf(modem_op_cb_t cb, const char* url); +/* Call to get access to framed buffer. */ +int modem_http_get_buf(char** bufptr, int* len); + +/* Make an HTTP GET request and store result to file on modem file system. + * Use modem_read_from_file to get contents. + */ + +int modem_http_post_message(modem_op_cb_t cb, const char *url, const char *message); + +int modem_http_get_to_file(modem_op_cb_t cb, const char* url, const char* file); + +/* Read data from a file on the modem file system. + * Calls user callback Open if the file is found and successfully opened. + * Calls user callback Data to transfer data in chunks. + * + * The file is streamed in chunks via the user Data callback, in the context of + * the bg96 process. It will request from the modem a chunk of data, yield, when + * response is received it invokes Data immediately. When user is finished with the data + * the bg96 process repeats the command/response cycle with the modem. Other processes will + * get to run at least once in between the command/response. + */ +typedef int(*modem_read_from_file_open)(uint32_t fileSize); +typedef int(*modem_read_from_file_data)(const char* buf, int buf_len); + +/* Return OK if operation started, ERROR otherwise. */ +int modem_read_from_file( + modem_op_cb_t cb, /* callback on overall API success of failure */ + const char* file, /* file name string */ + modem_read_from_file_open cbOpen, /* callback when file is opened successfully on modem */ + modem_read_from_file_data cbData); /* callback for each chunk of streamed data of 1024 bytes or less. */ + +/*==== MQTT API ==== */ + +/* Connect to an MQTT server at given port. + * server may be IP address or domain. + * Client ID for MQTT CONNECT +*/ +int modem_mqtt_connect(modem_op_cb_t cb, const char* host, int port, const char* clientID);//, const char* jwt); + +/* Publish data to the specific topic */ +int modem_mqtt_publish(modem_op_cb_t cb, const char* topic, const char* data, int len); + +/* Close MQTT session */ +int modem_mqtt_close(modem_op_cb_t cb); + +/*==== Update API ==== */ + +/* Update the modem from BGXX firmware image available +* at specified URL. +* Must be connected to a network. +*/ +int modem_update_modem(modem_op_cb_t cb, const char* url); + +/*====================*/ + +/* Initialize process. */ +int modem_init(void); + +/* Start process. */ +int modem_start(modem_start_cb_t cb); + +/* Stop process. */ +int modem_stop(void); + +/* Poll process. */ +int modem_poll(void); + +/*declaration signal strength function*/ +int modem_Rssi(void); + +/* Check if the process needs to be polled. */ +bool modem_needs_poll(void); + +/* Check if the process is started */ +bool modem_is_started(void); + +/* Check if the process is ready */ +bool modem_is_ready(void); + + +/**/ +char* modem_get_rxbuf(void); + +/* Get modem IMEI. + * String is valid only after modem has been started and is ready. + */ +const char* modem_get_imei(void); + +/* Get modem ICCID. + * String is valid only after modem has been started and is ready. + */ +const char* modem_get_iccid(void); + +/* Get modem version. + * String is valid only after modem has been started and is ready. + */ +const char* modem_get_fw_ver(void); + +/* Get the signal strength data - only valid if connected */ +const modem_signal_strength_t* modem_get_signal_strength(void); + +/* Get Serving cell data*/ +const char* modem_get_serving_cell(void); + +/* Get neighbour cell list*/ +const char* modem_get_neighbour_cell(void); + +#endif /* MAIN_MODEM_H_ */ diff --git a/main/nvm.c b/main/nvm.c new file mode 100644 index 0000000..9d64e3c --- /dev/null +++ b/main/nvm.c @@ -0,0 +1,1117 @@ +/* + * nvm.c + * + * Created on: Aug 14, 2023 + * Author: Sword + */ + +#include +#include "nvs_flash.h" +#include "nvs.h" +#include "esp_system.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include +#include "hmi.h" +#include "nvm.h" +#include "main.h" + +static const char* TAG = "NVM"; + +#define LOG_LOCAL_LEVEL ESP_LOG_INFO +#include "esp_log.h" + + +nvs_handle_t my_handle; + +RTC_DATA_ATTR static uint8_t last_posted_sector; + +extern uint8_t onBoarded; + + +/**/ +void nvm_init(void) +{ + /* Initialize the dedicated NVS partition */ + esp_err_t ret = nvs_flash_init(); + + /* Check if NVS partition doesn't contain any empty pages or contains data in new format and cannot be recognized by this version of code */ + if((ret == ESP_ERR_NVS_NO_FREE_PAGES) || (ret == ESP_ERR_NVS_NEW_VERSION_FOUND)) + { + /* If so ----> then erase the NVS partition reinitialize it one more time*/ + ESP_ERROR_CHECK(nvs_flash_erase()); + + /* reinitialize NVS partition one more time */ + ret = nvs_flash_init(); + } + + //Check that there is no problem with initializing NVS partition + ESP_ERROR_CHECK(ret); +} + +/**/ +void nvm_clear(void) +{ + /* erase the NVS partition */ + ESP_ERROR_CHECK(nvs_flash_erase()); +} + + + +/**/ +uint8_t nvm_read_onboarding_flag(onboarding_type_t flag_key) +{ + uint8_t onBoarding; + + /*Storing the on-boarding value in the NVS so that to indicate that each time power on/off the value would be the same*/ + //ESP_LOGI(TAG,"Opening Non-Volatile Storage (NVS) handle... "); + esp_err_t err = nvs_open("storage", NVS_READWRITE, &my_handle); + + /* Make sure that NVS is initialized */ + if(ESP_ERR_NVS_NOT_INITIALIZED == err) + { + /* initialized it if not */ + err = nvs_flash_init(); + + /* Check if the response is OK then OPEN it */ + if(err == ESP_OK) + { + /* Retry to open the NVS */ + err = nvs_open("storage", NVS_READWRITE, &my_handle); + } + else + { + /* Print this LOG if failed to initialize it */ + ESP_LOGI(TAG,"Failed to reinitialized The NVS partition"); + } + } + + if (err != ESP_OK) + { + ESP_LOGI(TAG,"Error (%s) opening NVS handle!\n", esp_err_to_name(err)); + } + else + { + //ESP_LOGI(TAG,"Done\nReading on-boarding value from NVS ... "); + + if(WIFI_ONBOARDING_KEY == flag_key) + { + err = nvs_get_u8(my_handle, NVM_WIFI_ONBOARDING_KEY, &onBoarding); + } + else + { + err = nvs_get_u8(my_handle, NVM_CELL_ONBOARDING_KEY, &onBoarding); + } + + switch (err) + { + case ESP_OK: + + ESP_LOGI(TAG,"On-Boarding = %d\n",onBoarding); + + // Close the opened NVS + nvs_close(my_handle); + + return onBoarding; + + break; + + case ESP_ERR_NVS_NOT_FOUND: + ESP_LOGI(TAG,"The on-boarding value is not initialized yet!\n"); + break; + + default: + ESP_LOGI(TAG,"Error (%s) reading!\n", esp_err_to_name(err)); + } + } + + // Close the opened NVS + nvs_close(my_handle); + + return 0; + +} + +/**/ +void nvm_write_onboarding_flag(onboarding_type_t flag_key, uint8_t flag_value) +{ + esp_err_t err; + + /*Storing the on-boarding value in the NVS so that to indicate that each time power on/off the value would be the same*/ + //ESP_LOGI(TAG,"Opening Non-Volatile Storage (NVS) handle... "); + err = nvs_open("storage", NVS_READWRITE, &my_handle); + + /* Make sure that NVS is initialized */ + if(ESP_ERR_NVS_NOT_INITIALIZED == err) + { + /* initialized it if not */ + err = nvs_flash_init(); + + /* Check if the response is OK then OPEN it */ + if(err == ESP_OK) + { + /* Retry to open the NVS */ + err = nvs_open("storage", NVS_READWRITE, &my_handle); + } + else + { + /* Print this LOG if failed to initialize it */ + ESP_LOGI(TAG,"Failed to reinitialized The NVS partition"); + } + } + + if (err != ESP_OK) + { + ESP_LOGI(TAG,"Error (%s) opening NVS handle!\n", esp_err_to_name(err)); + } + else + { + //ESP_LOGI(TAG,"Done\nUpdating on-boarding value in NVS ... "); + + if(WIFI_ONBOARDING_KEY == flag_key) + { + err = nvs_set_u8(my_handle, NVM_WIFI_ONBOARDING_KEY, flag_value); + } + else + { + err = nvs_set_u8(my_handle, NVM_CELL_ONBOARDING_KEY, flag_value); + } + + if (err != ESP_OK) + { + ESP_LOGI(TAG,"Failed"); + } + else + { + //ESP_LOGI(TAG,"Done"); + } + + // Commit written value. + // After setting any values, nvs_commit() must be called to ensure changes are written + // to flash storage. Implementations may write to storage at other times, + // but this is not guaranteed. + hmi_stop_red_flashing(); + + //ESP_LOGI(TAG,"Committing updates in NVS ... "); + + err = nvs_commit(my_handle); + + if (err != ESP_OK) + { + ESP_LOGI(TAG,"Failed Updating on-boarding value in NVS"); + } + else + { + ESP_LOGI(TAG,"Done Updating on-boarding value in NVS"); + } + } + + // Close the opened NVS + nvs_close(my_handle); +} + + + +/**/ +uint8_t nvm_read_comms_mode(void) +{ + uint8_t commsMode; + esp_err_t err; + + /*Storing the on-boarding value in the NVS so that to indicate that each time power on/off the value would be the same*/ + //ESP_LOGI(TAG,"Opening Non-Volatile Storage (NVS) handle... "); + err = nvs_open("storage", NVS_READWRITE, &my_handle); + + /* Make sure that NVS is initialized */ + if(ESP_ERR_NVS_NOT_INITIALIZED == err) + { + /* initialized it if not */ + err = nvs_flash_init(); + + /* Check if the response is OK then OPEN it */ + if(err == ESP_OK) + { + /* Retry to open the NVS */ + err = nvs_open("storage", NVS_READWRITE, &my_handle); + } + else + { + /* Print this LOG if failed to initialize it */ + ESP_LOGI(TAG,"Failed to reinitialized The NVS partition"); + } + } + + if (err != ESP_OK) + { + ESP_LOGI(TAG,"Error (%s) opening NVS handle!\n", esp_err_to_name(err)); + } + else + { + //ESP_LOGI(TAG,"Done\nReading Communication-Mode value from NVS ... "); + + err = nvs_get_u8(my_handle, NVM_COMMS_MODE_KEY, &commsMode); + + switch (err) + { + case ESP_OK: + + ESP_LOGI(TAG,"Communication Mode = %d\n",commsMode); + + // Close the opened NVS + nvs_close(my_handle); + + return commsMode; + + break; + + case ESP_ERR_NVS_NOT_FOUND: + ESP_LOGI(TAG,"The Communication-Mode value is not initialized yet!\n"); + break; + + default: + ESP_LOGI(TAG,"Error (%s) reading!\n", esp_err_to_name(err)); + } + } + + // Close the opened NVS + nvs_close(my_handle); + + return DEFAULT_COMMS_MODE; + +} + +/**/ +void nvm_write_comms_mode(uint8_t commsMode) +{ + esp_err_t err; + + /*Storing the on-boarding value in the NVS so that to indicate that each time power on/off the value would be the same*/ + //ESP_LOGI(TAG,"Opening Non-Volatile Storage (NVS) handle... "); + err = nvs_open("storage", NVS_READWRITE, &my_handle); + + /* Make sure that NVS is initialized */ + if(ESP_ERR_NVS_NOT_INITIALIZED == err) + { + /* initialized it if not */ + err = nvs_flash_init(); + + /* Check if the response is OK then OPEN it */ + if(err == ESP_OK) + { + /* Retry to open the NVS */ + err = nvs_open("storage", NVS_READWRITE, &my_handle); + } + else + { + /* Print this LOG if failed to initialize it */ + ESP_LOGI(TAG,"Failed to reinitialized The NVS partition"); + } + } + + if (err != ESP_OK) + { + ESP_LOGI(TAG,"Error (%s) opening NVS handle!\n", esp_err_to_name(err)); + } + else + { + //ESP_LOGI(TAG,"Done\nUpdating Communication-Mode value in NVS ... "); + + err = nvs_set_u8(my_handle, NVM_COMMS_MODE_KEY, commsMode); + + if (err != ESP_OK) + { + ESP_LOGI(TAG,"Failed"); + } + else + { + //ESP_LOGI(TAG,"Done"); + } + + //ESP_LOGI(TAG,"Committing updates in NVS ... "); + + err = nvs_commit(my_handle); + + if (err != ESP_OK) + { + ESP_LOGI(TAG,"Failed Updating Communication-Mode value in NVS"); + } + else + { + ESP_LOGI(TAG,"Done Updating Communication-Mode value in NVS"); + } + } + + // Close the opened NVS + nvs_close(my_handle); +} + + + +/**/ +esp_err_t nvm_read_wifi_credentials(char* ssid, char* pswd) +{ + esp_err_t err; + size_t ssid_len; + size_t pswd_len; + + /*Storing the on-boarding value in the NVS so that to indicate that each time power on/off the value would be the same*/ + //ESP_LOGI(TAG,"Opening Non-Volatile Storage (NVS) handle... "); + err = nvs_open("storage", NVS_READWRITE, &my_handle); + + /* Make sure that NVS is initialized */ + if(ESP_ERR_NVS_NOT_INITIALIZED == err) + { + /* initialized it if not */ + err = nvs_flash_init(); + + /* Check if the response is OK then OPEN it */ + if(err == ESP_OK) + { + /* Retry to open the NVS */ + err = nvs_open("storage", NVS_READWRITE, &my_handle); + } + else + { + /* Print this LOG if failed to initialize it */ + ESP_LOGI(TAG,"Failed to reinitialized The NVS partition"); + } + } + + /* Make sure that NVS storage has been opened successfully */ + if (err != ESP_OK) + { + ESP_LOGI(TAG,"Error (%s) opening NVS handle!\n", esp_err_to_name(err)); + } + else + { + /* Get the length of the WIFI-SSID */ + nvs_get_str(my_handle, NVM_WIFI_SSID_KEY, NULL, (size_t*)&ssid_len); + + /* Get the length of the WIFI-PSWD */ + nvs_get_str(my_handle, NVM_WIFI_PSWD_KEY, NULL, (size_t*)&pswd_len); + + ESP_LOGI(TAG,"NVM-SSID len = %d, and NVM-PWD len = %d",ssid_len,pswd_len); + + //char* sid = malloc(ssid_len); + //char* pwd = malloc(pswd_len); + + /* Retrieve the WIFI-SSID */ + if(ESP_OK == err) + err = nvs_get_str(my_handle, (const char*)NVM_WIFI_SSID_KEY, ssid, (size_t*)&ssid_len); + + /* Retrieve the WIFI-PSWD */ + if(ESP_OK == err) + err = nvs_get_str(my_handle, (const char*)NVM_WIFI_PSWD_KEY, pswd, (size_t*)&pswd_len); + + /* Check the result of the NVS reading */ + switch (err) + { + case ESP_OK: + + //strcpy(ssid,sid); + //strcpy(pswd,pwd); + ESP_LOGI(TAG,"WIFI_SSID is: %s and WIFI_PSWD is: %s",ssid,pswd); + break; + + case ESP_ERR_NVS_NOT_FOUND: + ESP_LOGI(TAG,"The WIFI_Credentials not initialized yet!\n"); + break; + + default: + ESP_LOGI(TAG,"Error (%s) reading!\n", esp_err_to_name(err)); + } + + //free(sid); + //free(pwd); + } + + // Close the opened NVS + nvs_close(my_handle); + + return err; +} + +/**/ +void nvm_write_wifi_credentials(char* ssid, uint8_t ssid_len, char* pswd, uint8_t pswd_len) +{ + esp_err_t err; + + /*Storing the on-boarding value in the NVS so that to indicate that each time power on/off the value would be the same*/ + //ESP_LOGI(TAG,"Opening Non-Volatile Storage (NVS) handle... "); + err = nvs_open("storage", NVS_READWRITE, &my_handle); + + /* Make sure that NVS is initialized */ + if(ESP_ERR_NVS_NOT_INITIALIZED == err) + { + /* initialized it if not */ + err = nvs_flash_init(); + + /* Check if the response is OK then OPEN it */ + if(err == ESP_OK) + { + /* Retry to open the NVS */ + err = nvs_open("storage", NVS_READWRITE, &my_handle); + } + else + { + /* Print this LOG if failed to initialize it */ + ESP_LOGE(TAG,"Failed to reinitialized The NVS partition"); + } + } + + /* Make sure that NVS storage has been opened successfully */ + if (err != ESP_OK) + { + ESP_LOGE(TAG,"Error (%s) opening NVS handle!\n", esp_err_to_name(err)); + } + else + { + //ESP_LOGI(TAG,"Done\nUpdating WIFI-Credentials in NVS ... "); + + /* Store the WIFI-SSID string in NVS */ + err = nvs_set_str(my_handle, (const char*)NVM_WIFI_SSID_KEY, (const char*)ssid); + + /* If WIFI-SSID stored successfully in NVS then ---> Store the WIFI-PSWD string in NVS */ + if(ESP_OK == err) + err = nvs_set_str(my_handle, (const char*)NVM_WIFI_PSWD_KEY, (const char*)pswd); + + /* Inform the user with one of these logs to indicate failing or succeeding to store wifi-credentials */ + if (err != ESP_OK) + { + ESP_LOGE(TAG,"Failed"); + } + else + { + //ESP_LOGI(TAG,"Done"); + } + + // Commit written value. + // After setting any values, nvs_commit() must be called to ensure changes are written + // to flash storage. Implementations may write to storage at other times, + // but this is not guaranteed. + + //ESP_LOGI(TAG,"Committing updates in NVS ... "); + + err = nvs_commit(my_handle); + + if (err != ESP_OK) + { + ESP_LOGE(TAG,"Failed Updating WIFI-Credentials in NVS"); + } + else + { + ESP_LOGI(TAG,"Done Updating WIFI-Credentials in NVS"); + } + } + + // Close the opened NVS + nvs_close(my_handle); +} + + +#if 0 +/**/ +void nvm_read_wifi_backup_credentials(char* ssid, char* pswd, char* key1, char* key2) +{ + esp_err_t err; + size_t ssid_len; + size_t pswd_len; + + /*Storing the on-boarding value in the NVS so that to indicate that each time power on/off the value would be the same*/ + ESP_LOGI(TAG,"Opening Non-Volatile Storage (NVS) handle... "); + err = nvs_open("storage", NVS_READWRITE, &my_handle); + + /* Make sure that NVS is initialized */ + if(ESP_ERR_NVS_NOT_INITIALIZED == err) + { + /* initialized it if not */ + err = nvs_flash_init(); + + /* Check if the response is OK then OPEN it */ + if(err == ESP_OK) + { + /* Retry to open the NVS */ + err = nvs_open("storage", NVS_READWRITE, &my_handle); + } + else + { + /* Print this LOG if failed to initialize it */ + ESP_LOGI(TAG,"Failed to reinitialized The NVS partition"); + } + } + + /* Make sure that NVS storage has been opened successfully */ + if (err != ESP_OK) + { + ESP_LOGI(TAG,"Error (%s) opening NVS handle!\n", esp_err_to_name(err)); + } + else + { + /* Get the length of the WIFI-SSID */ + nvs_get_str(my_handle, key1, NULL, (size_t*)&ssid_len); + + /* Get the length of the WIFI-PSWD */ + nvs_get_str(my_handle, key2, NULL, (size_t*)&pswd_len); + + ESP_LOGI(TAG,"NVM-SSID len = %d, and NVM-PWD len = %d",ssid_len,pswd_len); + + //char* sid = malloc(ssid_len); + //char* pwd = malloc(pswd_len); + + /* Retrieve the WIFI-SSID */ + if(ESP_OK == err) + err = nvs_get_str(my_handle, (const char*)key1, ssid, (size_t*)&ssid_len); + + /* Retrieve the WIFI-PSWD */ + if(ESP_OK == err) + err = nvs_get_str(my_handle, (const char*)key2, pswd, (size_t*)&pswd_len); + + /* Check the result of the NVS reading */ + switch (err) + { + case ESP_OK: + + //strcpy(ssid,sid); + //strcpy(pswd,pwd); + ESP_LOGI(TAG,"WIFI_SSID is: %s and WIFI_PSWD is: %s",ssid,pswd); + break; + + case ESP_ERR_NVS_NOT_FOUND: + ESP_LOGI(TAG,"The WIFI_Credentials not initialized yet!\n"); + break; + + default: + ESP_LOGI(TAG,"Error (%s) reading!\n", esp_err_to_name(err)); + } + + //free(sid); + //free(pwd); + } + + // Close the opened NVS + nvs_close(my_handle); +} + +/**/ +void nvm_write_wifi_backup_credentials(char* ssid1, char* pswd1, char* ssid2, char* pswd2) +{ + esp_err_t err; + + /*Storing the on-boarding value in the NVS so that to indicate that each time power on/off the value would be the same*/ + ESP_LOGI(TAG,"Opening Non-Volatile Storage (NVS) handle... "); + err = nvs_open("storage", NVS_READWRITE, &my_handle); + + /* Make sure that NVS is initialized */ + if(ESP_ERR_NVS_NOT_INITIALIZED == err) + { + /* initialized it if not */ + err = nvs_flash_init(); + + /* Check if the response is OK then OPEN it */ + if(err == ESP_OK) + { + /* Retry to open the NVS */ + err = nvs_open("storage", NVS_READWRITE, &my_handle); + } + else + { + /* Print this LOG if failed to initialize it */ + ESP_LOGE(TAG,"Failed to reinitialized The NVS partition"); + } + } + + /* Make sure that NVS storage has been opened successfully */ + if (err != ESP_OK) + { + ESP_LOGE(TAG,"Error (%s) opening NVS handle!\n", esp_err_to_name(err)); + } + else + { + ESP_LOGI(TAG,"Done\nUpdating WIFI-Credentials in NVS ... "); + + /* Store the WIFI-SSID string in NVS */ + err = nvs_set_str(my_handle, (const char*)NVM_WIFI_SSID_KEY, (const char*)ssid); + + /* If WIFI-SSID stored successfully in NVS then ---> Store the WIFI-PSWD string in NVS */ + if(ESP_OK == err) + err = nvs_set_str(my_handle, (const char*)NVM_WIFI_PSWD_KEY, (const char*)pswd); + + /* Inform the user with one of these logs to indicate failing or succeeding to store wifi-credentials */ + if (err != ESP_OK) + { + ESP_LOGE(TAG,"Failed"); + } + else + { + ESP_LOGI(TAG,"Done"); + } + + // Commit written value. + // After setting any values, nvs_commit() must be called to ensure changes are written + // to flash storage. Implementations may write to storage at other times, + // but this is not guaranteed. + + ESP_LOGI(TAG,"Committing updates in NVS ... "); + + err = nvs_commit(my_handle); + + if (err != ESP_OK) + { + ESP_LOGE(TAG,"Failed"); + } + else + { + ESP_LOGI(TAG,"Done"); + } + } + + // Close the opened NVS + nvs_close(my_handle); +} +#endif + + +/**/ +void nvm_write_history_data(historyLog_t* history_data) +{ + esp_err_t err; + size_t required_size = 0; // value will default to 0, if not set yet in NVS + + char key_str[18]; + uint8_t sector_counter = 1; + + /*Storing the on-boarding value in the NVS so that to indicate that each time power on/off the value would be the same*/ + //ESP_LOGI(TAG,"Opening Non-Volatile Storage (NVS) handle... "); + err = nvs_open("storage", NVS_READWRITE, &my_handle); + + /* Make sure that NVS is initialized */ + if(ESP_ERR_NVS_NOT_INITIALIZED == err) + { + /* initialized it if not */ + err = nvs_flash_init(); + + /* Check if the response is OK then OPEN it */ + if(err == ESP_OK) + { + /* Retry to open the NVS */ + err = nvs_open("storage", NVS_READWRITE, &my_handle); + } + else + { + /* Print this LOG if failed to initialize it */ + ESP_LOGE(TAG,"Failed to reinitialized The NVS partition"); + } + } + + /* Make sure that NVS storage has been opened successfully */ + if (err != ESP_OK) + { + ESP_LOGE(TAG,"Error (%s) opening NVS handle!\n", esp_err_to_name(err)); + } + else + { + do + { + /* Setup the NVS sector to write to */ + sprintf(key_str,NVM_HISTORY_DATA_KEY,sector_counter); + + /* get the size of the history space */ + err = nvs_get_blob(my_handle, key_str, NULL, &required_size); + + /* Check if we can store data at that sector or not*/ + if(required_size >= (NVM_MAX_NUMBER_OF_IN_ONE_SECTOR*sizeof(historyLog_t))) + { + /* Reset the required_size again to 0 */ + required_size = 0; + + /* if not then check the next sector */ + sector_counter++; + } + else + { + /* if yes then increase the size of data to be stored by one element */ + required_size += sizeof(historyLog_t); + break; + } + }while(sector_counter <= NVM_NUMBER_OF_SECTORS); + + /* Make sure that there are some free sectors to store data in */ + if(sector_counter <= NVM_NUMBER_OF_SECTORS) + { + /* set the new values for the history data */ + err = nvs_set_blob(my_handle, key_str, history_data, required_size); + + if (err != ESP_OK && err != ESP_ERR_NVS_NOT_FOUND) + ESP_LOGI(TAG," ---> History space not there"); + + if (required_size == 0) + { + ESP_LOGI(TAG," ---> Nothing saved yet"); + } + else + { + // Commit + err = nvs_commit(my_handle); + if (err == ESP_OK) + ESP_LOGI(TAG," ---> the new history data has been committed successfully to nvm-sector %d\nand its size now is %d (max allowed size is %d)",sector_counter,required_size,(NVM_MAX_NUMBER_OF_IN_ONE_SECTOR*sizeof(historyLog_t))); + } + } + else + { + ESP_LOGE(TAG," ----> All the NVM sectors are full. can't store additional data"); + } + } + + // Close + nvs_close(my_handle); +} + +/**/ +size_t nvm_read_history_data(historyLog_t* history_data, uint8_t sector_number) +{ + esp_err_t err; + size_t required_size = 0; // value will default to 0, if not set yet in NVS + + char key_str[18]; + + /*Storing the on-boarding value in the NVS so that to indicate that each time power on/off the value would be the same*/ + //ESP_LOGI(TAG,"Opening Non-Volatile Storage (NVS) handle... "); + err = nvs_open("storage", NVS_READWRITE, &my_handle); + + /* Make sure that NVS is initialized */ + if(ESP_ERR_NVS_NOT_INITIALIZED == err) + { + /* initialized it if not */ + err = nvs_flash_init(); + + /* Check if the response is OK then OPEN it */ + if(err == ESP_OK) + { + /* Retry to open the NVS */ + err = nvs_open("storage", NVS_READWRITE, &my_handle); + } + else + { + /* Print this LOG if failed to initialize it */ + ESP_LOGI(TAG,"Failed to reinitialized The NVS partition"); + } + } + + if (err != ESP_OK) + { + ESP_LOGI(TAG,"Error (%s) opening NVS handle!\n", esp_err_to_name(err)); + } + else + { + /* Setup the NVS sector to write to */ + sprintf(key_str,NVM_HISTORY_DATA_KEY,sector_number); + + // obtain required memory space to store blob being read from NVS + err = nvs_get_blob(my_handle, key_str, NULL, &required_size); + + if (err != ESP_OK && err != ESP_ERR_NVS_NOT_FOUND) + ESP_LOGI(TAG," ---> History not found yet"); + + //ESP_LOGI(TAG,"History data are:"); + + if (required_size == 0) + { + ESP_LOGI(TAG," ---> Nothing saved yet!\n"); + } + else + { + err = nvs_get_blob(my_handle, key_str, history_data, &required_size); + if (err != ESP_OK) + { + ESP_LOGI(TAG," ---> ERROR in retrieving history data for NVM sector %d",sector_number); + } + } + } + + // Close + nvs_close(my_handle); + + return required_size; +} + +/**/ +void nvm_clear_history_sector(uint8_t sector_num) +{ + esp_err_t wifi_err; + uint8_t wifi_onboarding; + uint8_t cell_onboarding; + uint8_t comms_mode; + char ssid[32] = {0}; + char pswd[64] = {0}; + + ESP_LOGI(TAG,"Clearing NVM History Sectors After successful POST process"); + + /* If there are some written data in the first sector ---> then this means that you should clear it. otherwise no (just to save read-write cycles for nvs) */ + if(nvm_read_history_data(NULL,1)) + { + /* 1- Firstly retrieve stored data in NVS */ + wifi_onboarding = nvm_read_onboarding_flag(WIFI_ONBOARDING_KEY); + cell_onboarding = nvm_read_onboarding_flag(CELL_ONBOARDING_KEY); + comms_mode = nvm_read_comms_mode(); + wifi_err = nvm_read_wifi_credentials(ssid,pswd); + + /* Reload the WDT */ + vTaskDelay(10/portTICK_PERIOD_MS); + + /* 2- Clear NVS partition */ + nvm_clear(); + + /* Reload the WDT */ + vTaskDelay(10/portTICK_PERIOD_MS); + + /* 3- Store the retrieved data again in NVS */ + nvm_write_onboarding_flag(WIFI_ONBOARDING_KEY,wifi_onboarding); + nvm_write_onboarding_flag(CELL_ONBOARDING_KEY,cell_onboarding); + nvm_write_comms_mode(comms_mode); + if(wifi_err == ESP_OK) + nvm_write_wifi_credentials(ssid,32,pswd,64); + } + + +#if 0 + esp_err_t err; + char key_str[18]; + + /*Storing the on-boarding value in the NVS so that to indicate that each time power on/off the value would be the same*/ + ESP_LOGI(TAG,"Opening Non-Volatile Storage (NVS) handle... "); + err = nvs_open("storage", NVS_READWRITE, &my_handle); + + /* Make sure that NVS is initialized */ + if(ESP_ERR_NVS_NOT_INITIALIZED == err) + { + /* initialized it if not */ + err = nvs_flash_init(); + + /* Check if the response is OK then OPEN it */ + if(err == ESP_OK) + { + /* Retry to open the NVS */ + err = nvs_open("storage", NVS_READWRITE, &my_handle); + } + else + { + /* Print this LOG if failed to initialize it */ + ESP_LOGI(TAG,"Failed to reinitialized The NVS partition"); + } + } + + if (err != ESP_OK) + { + ESP_LOGI(TAG,"Error (%s) opening NVS handle!\n", esp_err_to_name(err)); + } + else + { + for(int sector_counter=1; sector_counter<=NVM_NUMBER_OF_SECTORS; sector_counter++) + { + /* Setup the NVS sector to clear */ + sprintf(key_str,NVM_HISTORY_DATA_KEY,sector_counter); + + /* Check which sector number need to be cleared */ + if((sector_num == sector_counter) || ((sector_num == NVM_HISTORY_ALL_SECTORS))) + { + /* set the new values for the history data */ + err = nvs_set_blob(my_handle, key_str, NULL, 0); + if(err != ESP_OK) + { + ESP_LOGI(TAG,"Failed to clear sector %d",sector_counter); + break; + } + else + { + /* Check if the sector_num isn't equal to the NVM_HISTORY_ALL_SECTORS then break the loop after first successful clear process */ + if(sector_num != NVM_HISTORY_ALL_SECTORS) + { + break; + } + } + } + } +#endif +#if 0 + if((sector_num == NVM_HISTORY_SECTOR_1) || ((sector_num == NVM_HISTORY_ALL_SECTORS))) + { + /* set the new values for the history data */ + err = nvs_set_blob(my_handle, NVM_HISTORY_SECTOR1, NULL, 0); + if(err != ESP_OK) + { + ESP_LOGI(TAG,"Failed to clear sector 1"); + } + } + + if((err == ESP_OK) && ((sector_num == NVM_HISTORY_SECTOR_2) || (sector_num == NVM_HISTORY_ALL_SECTORS))) + { + /* set the new values for the history data */ + err = nvs_set_blob(my_handle, NVM_HISTORY_SECTOR2, NULL, 0); + if(err != ESP_OK) + { + ESP_LOGI(TAG,"Failed to clear sector 2"); + } + } + + if((err == ESP_OK) && ((sector_num == NVM_HISTORY_SECTOR_3) || (sector_num == NVM_HISTORY_ALL_SECTORS))) + { + /* set the new values for the history data */ + err = nvs_set_blob(my_handle, NVM_HISTORY_SECTOR3, NULL, 0); + if(err != ESP_OK) + { + ESP_LOGI(TAG,"Failed to clear sector 3"); + } + } + + if((err == ESP_OK) && ((sector_num == NVM_HISTORY_SECTOR_4) || (sector_num == NVM_HISTORY_ALL_SECTORS))) + { + /* set the new values for the history data */ + err = nvs_set_blob(my_handle, NVM_HISTORY_SECTOR4, NULL, 0); + if(err != ESP_OK) + { + ESP_LOGI(TAG,"Failed to clear sector 4"); + } + } + + if((err == ESP_OK) && ((sector_num == NVM_HISTORY_SECTOR_5) || (sector_num == NVM_HISTORY_ALL_SECTORS))) + { + /* set the new values for the history data */ + err = nvs_set_blob(my_handle, NVM_HISTORY_SECTOR5, NULL, 0); + if(err != ESP_OK) + { + ESP_LOGI(TAG,"Failed to clear sector 5"); + } + } + + if((err == ESP_OK) && ((sector_num == NVM_HISTORY_SECTOR_6) || (sector_num == NVM_HISTORY_ALL_SECTORS))) + { + /* set the new values for the history data */ + err = nvs_set_blob(my_handle, NVM_HISTORY_SECTOR6, NULL, 0); + if(err != ESP_OK) + { + ESP_LOGI(TAG,"Failed to clear sector 6"); + } + } + + if((err == ESP_OK) && ((sector_num == NVM_HISTORY_SECTOR_7) || (sector_num == NVM_HISTORY_ALL_SECTORS))) + { + /* set the new values for the history data */ + err = nvs_set_blob(my_handle, NVM_HISTORY_SECTOR7, NULL, 0); + if(err != ESP_OK) + { + ESP_LOGI(TAG,"Failed to clear sector 7"); + } + } + + if((err == ESP_OK) && ((sector_num == NVM_HISTORY_SECTOR_8) || (sector_num == NVM_HISTORY_ALL_SECTORS))) + { + /* set the new values for the history data */ + err = nvs_set_blob(my_handle, NVM_HISTORY_SECTOR8, NULL, 0); + if(err != ESP_OK) + { + ESP_LOGI(TAG,"Failed to clear sector 8"); + } + } +#endif +// err = nvs_commit(my_handle); +// } + + // Close +// nvs_close(my_handle); +} + +/**/ +uint8_t nvm_get_last_written_history_sector(void) +{ + esp_err_t err; + size_t required_size = 0; // value will default to 0, if not set yet in NVS + + char key_str[18]; + uint8_t sector_counter = 1; + + /*Storing the on-boarding value in the NVS so that to indicate that each time power on/off the value would be the same*/ + //ESP_LOGI(TAG,"Opening Non-Volatile Storage (NVS) handle... "); + err = nvs_open("storage", NVS_READWRITE, &my_handle); + + /* Make sure that NVS is initialized */ + if(ESP_ERR_NVS_NOT_INITIALIZED == err) + { + /* initialized it if not */ + err = nvs_flash_init(); + + /* Check if the response is OK then OPEN it */ + if(err == ESP_OK) + { + /* Retry to open the NVS */ + err = nvs_open("storage", NVS_READWRITE, &my_handle); + } + else + { + /* Print this LOG if failed to initialize it */ + ESP_LOGI(TAG,"Failed to reinitialized The NVS partition"); + } + } + + if (err != ESP_OK) + { + ESP_LOGI(TAG,"Error (%s) opening NVS handle!\n", esp_err_to_name(err)); + } + else + { + do + { + /* Setup the key of NVS sector to read the size of it's written data */ + sprintf(key_str,NVM_HISTORY_DATA_KEY,sector_counter); + + /* get the size of the history space */ + err = nvs_get_blob(my_handle, key_str, NULL, &required_size); + + /* Check if that sector is not full */ + if(required_size >= (NVM_MAX_NUMBER_OF_IN_ONE_SECTOR*sizeof(historyLog_t))) + { + /* Reset the required_size again to 0 */ + required_size = 0; + + /* if full then check the next sector */ + sector_counter++; + } + else + { + /* if not full then return the sector_number */ + break; + } + }while(sector_counter <= NVM_NUMBER_OF_SECTORS); + + if(sector_counter > NVM_NUMBER_OF_SECTORS) + { + /* Setup the key of NVS sector to read it's written data */ + sector_counter--; + } + } + + // Close + nvs_close(my_handle); + + return sector_counter; +} + + + +/**/ +void nvm_set_last_posted_history_sector(uint8_t sector_num) +{ + if(sector_num <= NVM_NUMBER_OF_SECTORS) + last_posted_sector = sector_num; + else + last_posted_sector = 0; +} + +/**/ +uint8_t nvm_get_last_posted_history_sector(void) +{ + return last_posted_sector; +} + + + + diff --git a/main/nvm.h b/main/nvm.h new file mode 100644 index 0000000..cbf0e83 --- /dev/null +++ b/main/nvm.h @@ -0,0 +1,74 @@ +/* + * nvm.h + * + * Created on: Aug 14, 2023 + * Author: Sword + */ + +#ifndef MAIN_NVM_H_ +#define MAIN_NVM_H_ + +#include "data_processing.h" + +#define NVM_CELL_ONBOARDING_KEY "on_boarding" +#define NVM_WIFI_ONBOARDING_KEY "wifi_onboarding" +#define NVM_WIFI_SSID_KEY "wifi_ssid" +#define NVM_WIFI_SSID_LENGTH_KEY "wifi_ssid_len" +#define NVM_WIFI_PSWD_KEY "wifi_pswd" +#define NVM_WIFI_PSWD_LENGTH_KEY "wifi_pswd_len" +#define NVM_COMMS_MODE_KEY "commsMode" +#define NVM_HISTORY_DATA_KEY "history_data%u" + +#define NVM_HISTORY_SECTOR1 "history_data1" +#define NVM_HISTORY_SECTOR2 "history_data2" +#define NVM_HISTORY_SECTOR3 "history_data3" +#define NVM_HISTORY_SECTOR4 "history_data4" +#define NVM_HISTORY_SECTOR5 "history_data5" +#define NVM_HISTORY_SECTOR6 "history_data6" +#define NVM_HISTORY_SECTOR7 "history_data7" +#define NVM_HISTORY_SECTOR8 "history_data8" + +#define NVM_ONBOARDING_SET_VAL 1 +#define NVM_ONBOARDING_NOT_SET_VAL 0 +#define NVM_ONBOARDING_NOT_STORED_VAL 2 + +#define NVM_MAX_NUMBER_OF_ALL_READINGS 750 //max number of sensor_readings in all NVM sector +#define NVM_MAX_NUMBER_OF_IN_ONE_SECTOR 20 //max number of readings in one NVM/NVS sector +#define NVM_NUMBER_OF_SECTORS ((NVM_MAX_NUMBER_OF_ALL_READINGS) / NVM_MAX_NUMBER_OF_IN_ONE_SECTOR) // ----> number_of_sectors = max_num_readings / number of readings in one NVM sector +#define NVM_ONE_SECOTR_SIZE (37 * (NVM_NUMBER_OF_SECTORS)) + +#define NVM_HISTORY_ALL_SECTORS (NVM_NUMBER_OF_SECTORS+1) + +typedef enum +{ + WIFI_ONBOARDING_KEY, + CELL_ONBOARDING_KEY +}onboarding_type_t; + + +void nvm_init(void); +void nvm_clear(void); + + +uint8_t nvm_read_onboarding_flag(onboarding_type_t flag_key); +void nvm_write_onboarding_flag(onboarding_type_t flag_key, uint8_t flag_value); + + +uint8_t nvm_read_comms_mode(void); +void nvm_write_comms_mode(uint8_t commsMode); + + +esp_err_t nvm_read_wifi_credentials(char* ssid, char* pswd); +void nvm_write_wifi_credentials(char* ssid, uint8_t ssid_len, char* pswd, uint8_t pswd_len); + + +void nvm_write_history_data(historyLog_t* history_data); +size_t nvm_read_history_data(historyLog_t* history_data, uint8_t sector_number); +void nvm_clear_history_sector(uint8_t sector_num); +uint8_t nvm_get_last_written_history_sector(void); + + +void nvm_set_last_posted_history_sector(uint8_t sector_num); +uint8_t nvm_get_last_posted_history_sector(void); + +#endif /* MAIN_NVM_H_ */ diff --git a/main/ota.c b/main/ota.c new file mode 100644 index 0000000..d5b891a --- /dev/null +++ b/main/ota.c @@ -0,0 +1,424 @@ +/* + * ota.c + * + * Created on: Feb 13, 2023 + * Author: Sword + */ + + +/* OTA example + This example code is in the Public Domain (or CC0 licensed, at your option.) + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. + */ +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "esp_system.h" +#include "esp_event.h" +#include "esp_ota_ops.h" +#include "esp_app_format.h" +#include "esp_log.h" +#include "esp_flash_partitions.h" +#include "esp_partition.h" +#include "nvs.h" +#include "nvs_flash.h" +#include "driver/gpio.h" +#include "ota.h" + + +#define BUFFSIZE 2048 +#define HASH_LEN 32 /* SHA-256 digest length */ +#define LOG_LOCAL_LEVEL ESP_LOG_INFO + +static const char *TAG = "OTA"; + +/*an ota data write buffer ready to write to the flash*/ +static char *ota_write_data; +static ota_bytes_status_t ota_bytes = OTA_BYTES_WRITTEN_WAIT; +static uint32_t ota_file_size = OTA_WITH_SEQUENTIAL_WRITES; + +esp_ota_handle_t update_handle; +const esp_partition_t *update_partition = NULL; +const esp_partition_t *configured = NULL; +const esp_partition_t *running = NULL; + +static uint8_t ota_needed = OTA_NOT_NEEDED; +static int data_read = -1; +int binary_file_length; +bool image_header_was_checked; + +#define OTA_URL_SIZE 256 + + +/******************************************************/ +/********** Static Functions for OTA-Process **********/ +/******************************************************/ +static void print_sha256 (const uint8_t *image_hash, const char *label) +{ + char hash_print[HASH_LEN * 2 + 1]; + hash_print[HASH_LEN * 2] = 0; + for (int i = 0; i < HASH_LEN; ++i) { + sprintf(&hash_print[i * 2], "%02x", image_hash[i]); + } + ESP_LOGI(TAG, "%s: %s", label, hash_print); +} + +static void ota_start_session(void) +{ + /* update handle : set by esp_ota_begin(), must be freed via esp_ota_end() */ + update_handle = 0; + update_partition = NULL; + + /* Get partition info of currently configured boot app (the partition for current app)*/ + configured = esp_ota_get_boot_partition(); + /* Get partition info of currently running app (the partition for current app)*/ + running = esp_ota_get_running_partition(); + + + ESP_LOGI(TAG, "Starting OTA session"); + + /* The result of esp_ota_get_boot_partition() is usually the same as esp_ota_get_running_partition(). + * The two results are not equal if the configured boot partition does not contain a valid app (meaning that + * the running partition will be an app that the bootloader chose via fallback) */ + if (configured != running) { + ESP_LOGW(TAG, "Configured OTA boot partition at offset 0x%08x, but running from offset 0x%08x", + (unsigned int)configured->address, (unsigned int)running->address); + ESP_LOGW(TAG, "(This can happen if either the OTA boot data or preferred boot image become corrupted somehow.)"); + } + ESP_LOGI(TAG, "Running partition type %d subtype %d (offset 0x%08x)", + running->type, running->subtype, (unsigned int)running->address); + + /* The following line returns the next OTA app partition which should be written with a new firmware*/ + /* So, update_partition is the partition where the new image will be written*/ + update_partition = esp_ota_get_next_update_partition(NULL); + + assert(update_partition != NULL); + ESP_LOGI(TAG, "Writing to partition subtype %d at offset 0x%x", + update_partition->subtype, (unsigned int)update_partition->address); + + /*deal with all receive packet*/ + image_header_was_checked = false; + +} + +static void ota_process_incoming_image(void) +{ + esp_err_t err; + + if ((data_read < 0) && (OTA_NEEDED == ota_needed)) { + ESP_LOGE(TAG, "Error: No OTA data have been received yet"); + } + else if ((data_read > 0) && (OTA_NEEDED == ota_needed)) { + if (image_header_was_checked == false) { + esp_app_desc_t new_app_info; + if (data_read > sizeof(esp_image_header_t) + sizeof(esp_image_segment_header_t) + sizeof(esp_app_desc_t)) { + // check current version with downloading + /* 1- Check the firmware version of the new fetched-app*/ + memcpy(&new_app_info, &ota_write_data[sizeof(esp_image_header_t) + sizeof(esp_image_segment_header_t)], sizeof(esp_app_desc_t)); + ESP_LOGI(TAG, "New firmware version: %s", new_app_info.version); + + /* 2- Check the firmware version of the current running app*/ + esp_app_desc_t running_app_info; + if (esp_ota_get_partition_description(running, &running_app_info) == ESP_OK) { + ESP_LOGI(TAG, "Running firmware version: %s", running_app_info.version); + } + + /* 3- Check the firmware version of the last disabled/aborted/invalid app (which is an app that )*/ + const esp_partition_t* last_invalid_app = esp_ota_get_last_invalid_partition(); + esp_app_desc_t invalid_app_info; + if (esp_ota_get_partition_description(last_invalid_app, &invalid_app_info) == ESP_OK) { + /*---> Stop OTA updating*/ + ESP_LOGI(TAG, "Last invalid firmware version: %s", invalid_app_info.version); + } + + // check current version with last invalid partition + /* 4- Compare the new fetched-image with the last invalid-image*/ + if (last_invalid_app != NULL) { + if (memcmp(invalid_app_info.version, new_app_info.version, sizeof(new_app_info.version)) == 0) { + /*---> Stop OTA updating*/ + ESP_LOGW(TAG, "New version is the same as invalid version."); + ESP_LOGW(TAG, "Previously, there was an attempt to launch the firmware with %s version, but it failed.", invalid_app_info.version); + ESP_LOGW(TAG, "The firmware has been rolled back to the previous version."); + + /* EXIT OTA task*/ + ota_bytes = OTA_BYTES_WRITTEN_FAILED; + return; + } + } + + /* 5- Compare the new-fetched-image with the current running-image*/ + if (memcmp(new_app_info.version, running_app_info.version, sizeof(new_app_info.version)) == 0) { + /*---> Stop OTA updating*/ + ESP_LOGW(TAG, "Current running version is the same as a new. We will not continue the update."); + + /* EXIT OTA task*/ + ota_bytes = OTA_BYTES_WRITTEN_FAILED; + return; + } + + /* 7- Start an OTA-update writing to the specified partition. + The specified partition is erased to the specified image size. + If image size is not yet known, pass OTA_SIZE_UNKNOWN which will cause the entire partition to be erased.*/ + err = esp_ota_begin(update_partition, ota_file_size, &update_handle); + if (err != ESP_OK) { + /*---> Stop OTA updating*/ + ESP_LOGE(TAG, "esp_ota_begin failed (%s)", esp_err_to_name(err)); + esp_ota_abort(update_handle); + ESP_LOGI(TAG, "Aborting the update-data partition"); + + /* EXIT OTA task*/ + ota_bytes = OTA_BYTES_WRITTEN_FAILED; + return; + } + + /* 6- Set the image_header_checked flag to be true*/ + image_header_was_checked = true; + + ESP_LOGI(TAG, "esp_ota_begin succeeded"); + } else { + /*---> Stop OTA updating*/ + ESP_LOGE(TAG, "received package is not fit len"); + esp_ota_abort(update_handle); + ESP_LOGI(TAG, "Aborting the update-data partition"); + + /* EXIT OTA task*/ + ota_bytes = OTA_BYTES_WRITTEN_FAILED; + return; + } + } + /* 8- Write OTA update data to partition. + * This function can be called multiple times as data is received during the OTA operation. + * Data is written sequentially to the partition */ + err = esp_ota_write( update_handle, (const void *)ota_write_data, data_read); + if (err != ESP_OK) { + /*---> Stop OTA updating*/ + esp_ota_abort(update_handle); + ESP_LOGI(TAG, "Aborting the update-data partition"); + + /* EXIT OTA task*/ + ota_bytes = OTA_BYTES_WRITTEN_FAILED; + return; + } + /* 9- Set the binary file length*/ + binary_file_length += data_read; + /* Reset data_read variable to 0*/ + data_read = 0; + ESP_LOGD(TAG, "Written bytes length %d", binary_file_length); + ota_bytes = OTA_BYTES_WRITTEN_SUCCESS; + } + else if ((data_read == 0) && (OTA_FINISHED == ota_needed)) { + ESP_LOGI(TAG, "OTA session finished"); + ota_bytes = OTA_BYTES_WRITTEN_SUCCESS; + return; + } +} + +static void ota_end_session(void) +{ + esp_err_t err; + if(OTA_BYTES_WRITTEN_SUCCESS == ota_bytes) + { + ESP_LOGI(TAG, "Total Write binary data length: %d", binary_file_length); + /* 10- Checks if entire data in the response has been read without any error */ + if ( OTA_FINISHED != ota_needed ) { + ESP_LOGI(TAG, "OTA session stopped for errors but didn't get finished"); + esp_ota_abort(update_handle); + ESP_LOGI(TAG, "Aborting the update-data partition"); + /* EXIT OTA task*/ + return ; + } + + /* 11- Finish OTA update and validate newly written app image*/ + err = esp_ota_end(update_handle); + if (err != ESP_OK) { + /*---> Stop OTA updating*/ + if (err == ESP_ERR_OTA_VALIDATE_FAILED) { + ESP_LOGI(TAG, "Image validation failed, image is corrupted"); + } else { + ESP_LOGI(TAG, "esp_ota_end failed (%s)!", esp_err_to_name(err)); + } + /* EXIT OTA task*/ + return ; + } + + /* 12- Set the new validated-written image to be the boot partition (Configure OTA data for a new boot partition) + * On the next restart, ESP will boot from that new partition*/ + err = esp_ota_set_boot_partition(update_partition); + if (err != ESP_OK) { + /*Stop OTA update*/ + ESP_LOGI(TAG, "esp_ota_set_boot_partition failed (%s)!", esp_err_to_name(err)); + + /* EXIT OTA task*/ + return ; + } + /* 13- Restart the device (ESP32)*/ + ESP_LOGI(TAG, "Prepare to restart system!"); + esp_restart(); + return ; + } + else if(OTA_BYTES_WRITTEN_FAILED == ota_bytes) + { + ESP_LOGI(TAG,"No Changing in boot_partition"); + } +} + +static bool diagnostic(void) +{ + /* gpio_config_t io_conf; + io_conf.intr_type = GPIO_INTR_DISABLE; + io_conf.mode = GPIO_MODE_INPUT; + io_conf.pin_bit_mask = (1ULL << CONFIG_EXAMPLE_GPIO_DIAGNOSTIC); + io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE; + io_conf.pull_up_en = GPIO_PULLUP_ENABLE; + gpio_config(&io_conf); + + ESP_LOGI(TAG, "Diagnostics (5 sec)..."); + vTaskDelay(5000 / portTICK_PERIOD_MS); + + bool diagnostic_is_ok = gpio_get_level(CONFIG_EXAMPLE_GPIO_DIAGNOSTIC); + + gpio_reset_pin(CONFIG_EXAMPLE_GPIO_DIAGNOSTIC);*/ + return true; +} + + +void ota_set_needed(void) +{ + ota_needed = OTA_NEEDED; +} + +void ota_set_not_needed(void) +{ + ota_needed = OTA_NOT_NEEDED; +} + +void ota_set_finished(void) +{ + ota_needed = OTA_FINISHED; +} + +/******************************************************/ +/* Functions that gonna be used in comms state machine*/ +/******************************************************/ +esp_err_t ota_init(uint32_t fileSize) +{ + /*This function should be invoked in the ota_file_open_cb() in comms.c (instead of the OTA_Offline_Init())*/ + uint8_t sha_256[HASH_LEN] = { 0 }; + esp_partition_t partition; + + // get sha256 digest for the partition table + partition.address = ESP_PARTITION_TABLE_OFFSET; + partition.size = ESP_PARTITION_TABLE_MAX_LEN; + partition.type = ESP_PARTITION_TYPE_DATA; + esp_partition_get_sha256(&partition, sha_256); + print_sha256(sha_256, "SHA-256 for the partition table: "); + + // get sha256 digest for bootloader + partition.address = ESP_BOOTLOADER_OFFSET; + partition.size = ESP_PARTITION_TABLE_OFFSET; + partition.type = ESP_PARTITION_TYPE_APP; + esp_partition_get_sha256(&partition, sha_256); + print_sha256(sha_256, "SHA-256 for bootloader: "); + + // get sha256 digest for running partition + esp_partition_get_sha256(esp_ota_get_running_partition(), sha_256); + print_sha256(sha_256, "SHA-256 for current firmware: "); + + const esp_partition_t *running = esp_ota_get_running_partition(); + esp_ota_img_states_t ota_state; + if (esp_ota_get_state_partition(running, &ota_state) == ESP_OK) { + if (ota_state == ESP_OTA_IMG_PENDING_VERIFY) { + // run diagnostic function ... + bool diagnostic_is_ok = diagnostic(); + if (diagnostic_is_ok) { + ESP_LOGI(TAG, "Diagnostics completed successfully! Continuing execution ..."); + esp_ota_mark_app_valid_cancel_rollback(); + } else { + ESP_LOGE(TAG, "Diagnostics failed! Start rollback to the previous version ..."); + esp_ota_mark_app_invalid_rollback_and_reboot(); + + } + } + } + + /*set the ota file size */ + if(0 == fileSize) + fileSize = OTA_WITH_SEQUENTIAL_WRITES; + else + ota_file_size = fileSize; + + /* Initialize OTA session*/ + ota_start_session(); + + /* */ + return ESP_OK; +} + +esp_err_t ota_get_data_to_buffer(const char* buf, int buf_len) +{ + /* This function should be called in comms.c inside the callback function ota_file_data_cb() */ + /* This function should copy the bytes that we get from qfread command via uart*/ + /* handle of qfread cmd stores the incoming bytes from modem via uart in buf */ + /* After that we gonna use ota-buffer in ota_process_incoming_image() function to start ota-session*/ + + esp_err_t retval = ESP_FAIL; + int index = 0; + + /*Check if the number of bytes to be processed is greater than ota-buffer size*/ + /*if(BUFFSIZE < buf_len) + { + ESP_LOGI(TAG, "Number of bytes to be processed is greater than the size of OTA buffer"); + return retval; + }*/ + + /* Set the status of ota-bytes to be processed ---> OTA_BYTES_WRITTEN_WAIT*/ + ota_bytes = OTA_BYTES_WRITTEN_WAIT; + + /* Reset the number of bytes that have been read to 0 (because the initial value is -1)*/ + data_read = 0; + + /*Copy the incoming bytes (from uart) to ota-buffer */ + //for(index = 0; index < buf_len; index++) + { + ota_write_data = (char*)buf; + data_read = buf_len; + } + + /*Start OTA_Writing session*/ + ota_set_needed(); + + /*OTA process and writing for the copied bytes*/ + ota_process_incoming_image(); + + /* Check the status of the bytes after OTA-processing/OTA-writing */ + if(OTA_BYTES_WRITTEN_SUCCESS == ota_bytes) + retval = ESP_OK; + else if(OTA_BYTES_WRITTEN_FAILED == ota_bytes) + retval = ESP_FAIL; + + return retval; +} + +void ota_finish_processing(void) +{ + /*This function should be invoked in the COMMS_STATE_WAIT_MCU_UPDATE state in comms state machine + * (instead of the OTA_terminate_connection() )*/ + + /* Reset data_read variable to 0*/ + data_read = 0; + + /* Rise ota_finish flag*/ + ota_set_finished(); + + /* Rise the bytes_success flag*/ + ota_process_incoming_image(); + + /* End the ota_session by validating the image and then rebooting */ + ota_end_session(); +} + + + + diff --git a/main/ota.h b/main/ota.h new file mode 100644 index 0000000..df3ae5d --- /dev/null +++ b/main/ota.h @@ -0,0 +1,32 @@ +/* + * ota.h + * + * Created on: Feb 13, 2023 + * Author: Sword + */ + +#ifndef MAIN_OTA_H_ +#define MAIN_OTA_H_ + +typedef enum{ + OTA_NEEDED, + OTA_NOT_NEEDED, + OTA_FINISHED +}ota_status_t; + + +typedef enum{ + OTA_BYTES_WRITTEN_SUCCESS, + OTA_BYTES_WRITTEN_FAILED, + OTA_BYTES_WRITTEN_WAIT +}ota_bytes_status_t; + +void ota_set_needed(void); +void ota_set_not_needed(void); +void ota_set_finished(void); + +esp_err_t ota_init(uint32_t fileSize); +esp_err_t ota_get_data_to_buffer(const char* buf, int buf_len); +void ota_finish_processing(void); + +#endif /* MAIN_OTA_H_ */ diff --git a/main/port.c b/main/port.c new file mode 100644 index 0000000..9a942df --- /dev/null +++ b/main/port.c @@ -0,0 +1,254 @@ +/* + * port.c + * + * Created on: Jan 16, 2023 + * Author: Partha + */ + +#include +#include +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "driver/rtc_io.h" +#include "freertos/queue.h" +#include "driver/gpio.h" +#include "port.h" +#include "uart_ifx.h" + +static const char* TAG = "PORT"; + +#define LOG_LOCAL_LEVEL ESP_LOG_INFO +#include "esp_log.h" + +#define ESP_INTR_FLAG_DEFAULT 0 + +#define LED_BLUE_PIN 12 +#define LED_RED_PIN 13 + +#define UD_RAD_PWRKEY_PIN 20 +#define UD_RAD_RESET_PIN 21 +#define MODEM_LDO_EN_PIN 33 + +#define RAD_STATUS_PIN 19 + +#define USB_CHG_STATUS_PIN 34 + +#define LIGHT_SENSOR_EN_PIN 35 +#define ACCEL_PWN_PIN 11 + +#define ADC_BATT_MON_PIN 1 +#define ADC_LIGHT_SEN_PIN 2 + +#define VBAT_SENSE_EN_PIN 14 + +#define LOWV_DETECT_PIN 38 + +#define PIN_MASK(x) (1ULL << x) + +extern void IRAM_ATTR accel_int1_isr(void *args); +extern void IRAM_ATTR vusb_detect_isr(void *args); +extern void IRAM_ATTR lowv_detect_isr(void *args); +extern void IRAM_ATTR push_button_isr(void *args); + +static bool red_led_status = 0; +static bool blue_led_status = 0; + +static void init_outputs(void) +{ + gpio_config_t io_conf = {0}; + + io_conf.intr_type = GPIO_INTR_DISABLE; + io_conf.mode = GPIO_MODE_OUTPUT; + io_conf.pin_bit_mask = PIN_MASK(LED_RED_PIN) | \ + PIN_MASK(LED_BLUE_PIN) | \ + PIN_MASK(UD_RAD_PWRKEY_PIN) | \ + PIN_MASK(UD_RAD_RESET_PIN) | \ + PIN_MASK(MODEM_LDO_EN_PIN) | \ + PIN_MASK(ACCEL_PWN_PIN) | \ + /* PIN_MASK(LIGHT_SENSOR_EN_PIN) |*/ + PIN_MASK(VBAT_SENSE_EN_PIN); + io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE; + io_conf.pull_up_en = GPIO_PULLUP_DISABLE; + + ESP_ERROR_CHECK(gpio_config(&io_conf)); + + //Initialize all Outputs to LOW + gpio_set_level(LED_RED_PIN, 0); + gpio_set_level(LED_BLUE_PIN, 0); + gpio_set_level(UD_RAD_PWRKEY_PIN, 0); + gpio_set_level(UD_RAD_RESET_PIN, 0); + gpio_set_level(MODEM_LDO_EN_PIN, 0); + gpio_set_level(ACCEL_PWN_PIN, 0); + gpio_set_level(LIGHT_SENSOR_EN_PIN, 0); + gpio_set_level(VBAT_SENSE_EN_PIN, 0); +} + +static void init_inputs(void) +{ + gpio_config_t io_conf = {0}; + + io_conf.mode = GPIO_MODE_INPUT; + io_conf.pin_bit_mask = PIN_MASK(ADC_BATT_MON_PIN) | \ + PIN_MASK(ADC_LIGHT_SEN_PIN) | \ + /* PIN_MASK(ALER1_IN_PIN) | \*/ + PIN_MASK(ALER2_IN_PIN) | \ + PIN_MASK(ALER3_IN_PIN) | \ + PIN_MASK(ALER4_IN_PIN) | \ + PIN_MASK(RAD_STATUS_PIN) | \ + PIN_MASK(USB_CHG_STATUS_PIN); + io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE; + io_conf.pull_up_en = GPIO_PULLUP_DISABLE; + + ESP_ERROR_CHECK(gpio_config(&io_conf)); +} + +static void init_isrs(void) +{ + gpio_config_t io_conf = {0}; + + io_conf.intr_type = GPIO_INTR_ANYEDGE; + io_conf.mode = GPIO_MODE_INPUT; + io_conf.pin_bit_mask = PIN_MASK(ACCEL_INT1_PIN) | \ + PIN_MASK(VUSB_DETECT_PIN) | \ + PIN_MASK(LOWV_DETECT_PIN) | \ + PIN_MASK(SWITCH_INPUT_PIN); + io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE; + io_conf.pull_up_en = GPIO_PULLUP_DISABLE; + ESP_ERROR_CHECK(gpio_config(&io_conf)); + + gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT); + gpio_isr_handler_add(ACCEL_INT1_PIN, accel_int1_isr, (void *)ACCEL_INT1_PIN); + gpio_isr_handler_add(VUSB_DETECT_PIN, vusb_detect_isr, (void *)VUSB_DETECT_PIN); + gpio_isr_handler_add(LOWV_DETECT_PIN, lowv_detect_isr, (void *)LOWV_DETECT_PIN); + gpio_isr_handler_add(SWITCH_INPUT_PIN, push_button_isr, (void *)SWITCH_INPUT_PIN); +} + +void port_init(void) +{ + init_outputs(); + init_inputs(); + init_isrs(); + + gpio_deep_sleep_hold_dis(); + /*rtc_gpio_init(LED_BLUE_PIN); + rtc_gpio_set_direction(LED_BLUE_PIN, RTC_GPIO_MODE_OUTPUT_ONLY); + rtc_gpio_pulldown_dis(LED_BLUE_PIN); + rtc_gpio_pullup_dis(LED_BLUE_PIN); + rtc_gpio_set_level(LED_BLUE_PIN, 1);*/ +} + +void port_red_led_on(void) +{ + gpio_set_level(LED_RED_PIN, 0); + red_led_status = 1; +} +void port_red_led_off(void) +{ + gpio_set_level(LED_RED_PIN, 1); + red_led_status = 0; +} + +void port_red_led_toggle(void) +{ + if(red_led_status) + { + port_red_led_off(); + } + else + { + port_red_led_on(); + } +} + +bool port_red_led_is_on(void) +{ + return red_led_status; +} + +void port_blue_led_on(void) +{ + gpio_set_level(LED_BLUE_PIN, 0); + blue_led_status = 1; +} +void port_blue_led_off(void) +{ + gpio_set_level(LED_BLUE_PIN, 1); + blue_led_status = 0; +} + +int port_is_pushbuttonNotPressed(void) +{ + return gpio_get_level(SWITCH_INPUT_PIN); +} + +void port_blue_led_toggle(void) +{ + if(blue_led_status) + { + port_blue_led_off(); + } + else + { + port_blue_led_on(); + } +} + +bool port_blue_led_is_on(void) +{ + return blue_led_status; +} + +void port_modem_assert_pwrkey(void) +{ + gpio_set_level(UD_RAD_PWRKEY_PIN, 1); +} + +void port_modem_deassert_pwrkey(void) +{ + gpio_set_level(UD_RAD_PWRKEY_PIN, 0); +} + +int port_modem_is_on(void) +{ + return gpio_get_level(RAD_STATUS_PIN); +} + +int port_is_usb_connected(void) +{ + return gpio_get_level(VUSB_DETECT_PIN); +} + +int port_is_charging(void) +{ + return gpio_get_level(USB_CHG_STATUS_PIN); +} + +void port_vbatt_sense_enable(int en) +{ + gpio_set_level(VBAT_SENSE_EN_PIN, en); +} + +void port_accel_pwr_enable(int en) +{ + gpio_set_level(ACCEL_PWN_PIN, en); +} + +void port_light_sensor_enable(int en) +{ + gpio_set_level(LIGHT_SENSOR_EN_PIN, en); +} + +void port_modem_ldo_pin(uint8_t en) +{ + gpio_set_level(MODEM_LDO_EN_PIN, en); +} + +int port_usb_charge_status(void) +{ + return gpio_get_level(USB_CHG_STATUS_PIN); +} + + + diff --git a/main/port.h b/main/port.h new file mode 100644 index 0000000..45f85d4 --- /dev/null +++ b/main/port.h @@ -0,0 +1,52 @@ +/* + * port.h + * + * Created on: Jan 16, 2023 + * Author: Partha + */ + +#ifndef MAIN_PORT_H_ +#define MAIN_PORT_H_ + +#include +#include "sdkconfig.h" +#include "stdbool.h" + +#define ALER1_IN_PIN 4 +#define ALER2_IN_PIN 6 +#define ALER3_IN_PIN 7 +#define ALER4_IN_PIN 37 + +#define SWITCH_INPUT_PIN 5 + +#define ACCEL_INT1_PIN 9 +#define VUSB_DETECT_PIN 10 + +void port_init(void); + +uint8_t *port_get_isr(void); + +void port_red_led_on(void); +void port_red_led_off(void); +void port_red_led_toggle(void); +bool port_red_led_is_on(void); + +void port_blue_led_on(void); +void port_blue_led_off(void); +void port_blue_led_toggle(void); +bool port_blue_led_is_on(void); + +void port_modem_assert_pwrkey(void); +void port_modem_deassert_pwrkey(void); +int port_is_usb_connected(void); +int port_modem_is_on(void); +int port_is_charging(void); +int port_is_pushbuttonNotPressed(void); +void port_vbatt_sense_enable(int en); +void port_accel_pwr_enable(int en); +void port_light_sensor_enable(int en); +void port_modem_ldo_pin(uint8_t en); +int port_usb_charge_status(void); + + +#endif /* MAIN_PORT_H_ */ diff --git a/main/rtc.c b/main/rtc.c new file mode 100644 index 0000000..a8fceda --- /dev/null +++ b/main/rtc.c @@ -0,0 +1,224 @@ +/* + * rtc.c + * + * Created on: Jan 16, 2023 + * Author: Sword + */ +#include "rtc.h" +#include +#include + + + +/** Date and time set to: 1st of December 2014, 23 hour 59 min and 31 seconds */ +#define SET_HOUR 13 /*< Set hour to the RTC */ +#define SET_MINUTE 0 /*< Set minute to the RTC */ +#define SET_SECOND 0 /*< Set second to the RTC */ +#define SET_WEEKDAY 3 /*< Set weekday to the RTC */ +#define SET_YEARDAY 16 /*< day in the year, range 0 to 365 */ +#define SET_DAY 16 /*< Set day to the RTC */ +#define SET_MONTH 1 /*< Set month to the RTC */ +#define SET_YEAR 2023 /*< Set year to the RTC */ + +#define RTC_SUBSECOND_COUNTER_LOAD_VALUE 32767 + +static const char* TAG = "RTC"; + +#define LOG_LOCAL_LEVEL ESP_LOG_INFO +#include "esp_log.h" + +static bool rtc_set = false; + +int app_rtc_init(void) +{ + int retval = RTC_STATUS_OK; + + //RTC_InitType RTC_Init_struct; + //RTC_StructInit(&RTC_Init_struct); + + //SysCtrl_PeripheralClockCmd(CLOCK_PERIPH_RTC, ENABLE); + /* Try to enable the down-counter to use as a millisecond counter, but + * does not seem to work without this __NOP delay. + */ + //RTC_Init_struct.RTC_TLR1 = RTC_SUBSECOND_COUNTER_LOAD_VALUE; + //RTC_Init(&RTC_Init_struct); + + /** Delay between two write in RTC->TCR register has to be + * at least 3 x 32k cycle + 2 CPU cycle. For that reason it + * is neccessary to add the delay. + */ + // for (volatile uint32_t i = 0; i < 600; i++) { + // __asm("NOP"); + // } + + //RTC_DateTimeType RTC_DateTime; + + struct tm rtc_time; + + /* Set the present time and date */ + /*RTC_DateTime.Second = SET_SECOND; + RTC_DateTime.Minute = SET_MINUTE; + RTC_DateTime.Hour = SET_HOUR; + RTC_DateTime.WeekDay = SET_WEEKDAY; + RTC_DateTime.MonthDay = SET_DAY; + RTC_DateTime.Month = SET_MONTH; + RTC_DateTime.Year = SET_YEAR; + RTC_SetTimeDate(&RTC_DateTime);*/ + + rtc_time.tm_sec = SET_SECOND; + rtc_time.tm_min = SET_MINUTE; + rtc_time.tm_hour = SET_HOUR; + rtc_time.tm_wday = SET_WEEKDAY; + rtc_time.tm_mday = SET_DAY; + rtc_time.tm_mon = SET_MONTH; + rtc_time.tm_year = SET_YEAR; + rtc_time.tm_yday = SET_YEARDAY; + + time_t t = mktime(&rtc_time); + struct timeval now = { .tv_sec = t }; + + settimeofday(&now, NULL); + + /* Enable RTC */ + // RTC_Cmd(ENABLE); + /* Enable RTC clockwatch */ + // RTC_ClockwatchCmd(ENABLE); + + rtc_set = false; + + return retval; +} + +void rtc_get_timestamp(rtc_timestamp_t* ts) +{ + if (ts) { + //RTC_DateTimeType RTC_DateTime; + //RTC_GetTimeDate(&RTC_DateTime); + /* RTC subsecond counter is a count-down counter */ + struct timeval tv; + gettimeofday(&tv, NULL); + + struct tm *info = localtime( &tv.tv_sec ); + + ts->Millisecond = 7+1000*(info->tm_sec); //((RTC_SUBSECOND_COUNTER_LOAD_VALUE - RTC_GetTimerValue()) * 1000 + RTC_SUBSECOND_COUNTER_LOAD_VALUE) / + ts->Second = info->tm_sec; + ts->Minute = info->tm_min; + ts->Hour = info->tm_hour; + ts->WeekDay = info->tm_wday; + ts->MonthDay = info->tm_mday; + ts->Month = info->tm_mon; + ts->Year = info->tm_year; + } +} + +void rtc_set_timestamp(rtc_timestamp_t* ts) +{ + if (ts) { + + rtc_set_timestamp_tz(ts, 0); + } +} + +/* Set timestamp including a timezone offset in seconds. +* The timezone offset may be positive or negative. It is applied +* by subtraction, so a -ve offset (e.g. UTC-5) results in the +* timezone offset being added to the local timestamp +*/ +void rtc_set_timestamp_tz(rtc_timestamp_t* ts, int32_t tz_offset_sec) +{ + if (ts) { + + struct tm buf; + buf.tm_year = ts->Year - 1900; + buf.tm_mon = ts->Month - 1; + buf.tm_mday = ts->MonthDay; + buf.tm_hour = ts->Hour; + buf.tm_min = ts->Minute; + buf.tm_sec = ts->Second; + time_t t = mktime(&buf); + + /* Apply offset */ + t -= tz_offset_sec; + /* + if (!rtc_is_set()) { + rtc_set_epoch((uint32_t)t); + } + */ + rtc_set_epoch((uint32_t)t); + } +} + +void rtc_set_epoch(uint32_t epoch) +{ + /* + * struct tm + Member Type Meaning Range + tm_sec int seconds after the minute 0 - 60 * + tm_min int minutes after the hour 0 - 59 + tm_hour int hours since midnight 0 - 23 + tm_mday int day of the month 1 - 31 + tm_mon int months since January 0 - 11 + tm_year int years since 1900 + tm_wday int days since Sunday 0 - 6 + tm_yday int days since January 1 0 - 365 + tm_isdst int Daylight Saving Time flag + */ + + struct tm* buf; + time_t t = epoch; + + buf = localtime(&t); + + ESP_LOGD(TAG,"rtc_set_epoch: %s\n", asctime(buf)); + + //RTC_DateTimeType RTC_DateTime; + // + ///* Set the present time and date */ + //RTC_DateTime.Second = buf->tm_sec; + //RTC_DateTime.Minute = buf->tm_min; + //RTC_DateTime.Hour = buf->tm_hour; + //RTC_DateTime.WeekDay = buf->tm_wday; + //RTC_DateTime.MonthDay = buf->tm_mday; + //RTC_DateTime.Month = buf->tm_mon + 1; + //RTC_DateTime.Year = buf->tm_year + 1900; + //RTC_SetTimeDate(&RTC_DateTime); + + time_t tmi = mktime(buf); + struct timeval now = { .tv_sec = tmi }; + + settimeofday(&now, NULL); + + rtc_set = true; +} + +uint32_t rtc_get_epoch(void) +{ + struct timeval tv; + gettimeofday(&tv, NULL); + + struct tm *info = localtime( &tv.tv_sec ); + + struct tm buf; + buf.tm_year = info->tm_year - 1900; + buf.tm_mon = info->tm_mon - 1; + buf.tm_mday = info->tm_mday; + buf.tm_hour = info->tm_hour; + buf.tm_min = info->tm_min; + buf.tm_sec = info->tm_sec; + buf.tm_isdst = 0; + + time_t t = mktime(&buf); + + ESP_LOGD(TAG,"rtc_get_epoch: %s\n", ctime(&t)); + + return (uint32_t)t; +} + +bool rtc_is_set(void) +{ + return rtc_set; +} + + + + diff --git a/main/rtc.h b/main/rtc.h new file mode 100644 index 0000000..f282f72 --- /dev/null +++ b/main/rtc.h @@ -0,0 +1,78 @@ +/* + * rtc.h + * + * Created on: Jan 16, 2023 + * Author: Sword + * APIs to access the RTC. + * + */ + + +#ifndef MAIN_RTC_H_ +#define MAIN_RTC_H_ + +#include +#include + +#define RTC_STATUS_OK 0 +#define RTC_STATUS_ERROR -1 + +typedef struct +{ + uint16_t Millisecond; + + uint8_t Second; /*!< Specify the present second to be set to RTC clockwatch. + This parameter can be integer value in range from 0 to 59 */ + + uint8_t Minute; /*!< Specify the present minute to be set to RTC clockwatch. + This parameter can be integer value in range from 0 to 59 */ + + uint8_t Hour; /*!< Specify the present hour to be set to RTC clockwatch. + This parameter can be integer value in range from 0 to 23 */ + + uint8_t WeekDay; /*!< Specify the present day in the week to be set to RTC clockwatch. + This parameter can be an integer value in range from 0 to 7 */ + + uint8_t MonthDay; /*!< Specify the present day in the month to be set to RTC clockwatch. + This parameter can be an integer value in range from 1 to 31 (depends on month) */ + + uint8_t Month; /*!< Specify the present month to be set to RTC clockwatch. + This parameter can be an integer value in range from 1 to 12 (depends on month) */ + + uint16_t Year; /*!< Specify the present year to be set to RTC clockwatch. + This parameter can be an integer value in range from 0 to 3999 (depends on month) */ + +} rtc_timestamp_t; + +/* Initialize RTC. Must be called at each program startup to enable + * access to RTC. + * This will use a default time only once. Time is retained as long + * as backup power and 32 kHz OSC are running. + * Return true if RTC initialized from power-on-reset, false otherwise. + */ +int rtc_init(void); + +/* Get RTC time as a timestamp */ +void rtc_get_timestamp(rtc_timestamp_t* ts); +/* Set RTC time as a timestamp */ +void rtc_set_timestamp(rtc_timestamp_t* ts); + +/* Set timestamp including a timezone offset in seconds. +* The timezone offset may be positive or negative. It is applied +* by subtraction, so a -ve offset (e.g. UTC-5) results in the +* timezone offset being added to the local timestamp +*/ +void rtc_set_timestamp_tz(rtc_timestamp_t* ts, int32_t tz_offset_sec); + +/* true if rtc has been set by set_timestamp or set_epoch. */ +bool rtc_is_set(void); + +/* Get RTC time in units of epoch time (standard unix time: seconds since 1970) */ +uint32_t rtc_get_epoch(void); + +/* Set RTC current time according to epoch. Note, epoch is UTC/GMT. Should a "local" time be + * desired, subtract or add the necessary offset. E.g. MST is UTC-6 or -7 hours depending on DST. + */ +void rtc_set_epoch(uint32_t epoch); + +#endif /* MAIN_RTC_H_ */ diff --git a/main/uart_ifx.c b/main/uart_ifx.c new file mode 100644 index 0000000..bd2be29 --- /dev/null +++ b/main/uart_ifx.c @@ -0,0 +1,270 @@ +/* + * uart.c + * + * Created on: Jan 10, 2023 + * Author: Partha + */ + +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "driver/uart.h" +#include "esp_log.h" +#include "uart_ifx.h" + +static const char *TAG = "UART_IFX"; +#define LOG_LOCAL_LEVEL ESP_LOG_INFO + +#define BUF_SIZE 4096 +#define RD_BUF_SIZE (BUF_SIZE) + +static QueueHandle_t uart0_queue; +static QueueHandle_t uart1_queue; + +static uint8_t buffer1[BUF_SIZE]; +static uint8_t buffer2[BUF_SIZE]; + +QueueHandle_t uart0_data_queue; +QueueHandle_t uart1_data_queue; + +bool uart1_rx_needed = false; + +static size_t buffer2_size = 0; + +static void uart0_event_task(void *pvParameters) +{ + uart_event_t event; + + for(;;) + { + //Waiting for UART event. + if(xQueueReceive(uart0_queue, (void * )&event, (TickType_t)portMAX_DELAY)) + { + bzero(buffer1, RD_BUF_SIZE); + ESP_LOGI(TAG, "uart[%d] event:", UART_NUM_0); + + switch(event.type) + { + //Event of UART receiving data + /*We'd better handler data event fast, there would be much more data events than + other types of events. If we take too much time on data event, the queue might + be full.*/ + case UART_DATA: + //ESP_LOGI(TAG, "[UART DATA]: %d", event.size); + /*uart_read_bytes(UART_NUM_0, buffer1, event.size, portMAX_DELAY); + + for(int index = 0; index < event.size; index++) + { + xQueueSend(uart0_data_queue, &buffer1[index], 10); + } + uart_ifx_uart0_rx_cb();*/ + break; + + //Event of HW FIFO overflow detected + case UART_FIFO_OVF: + ESP_LOGI(TAG, "hw fifo overflow"); + // If fifo overflow happened, you should consider adding flow control for your application. + // The ISR has already reset the rx FIFO, + // As an example, we directly flush the rx buffer here in order to read more data. + uart_flush_input(UART_NUM_0); + xQueueReset(uart0_queue); + break; + + //Event of UART ring buffer full + case UART_BUFFER_FULL: + ESP_LOGI(TAG, "ring buffer full"); + // If buffer full happened, you should consider increasing your buffer size + // As an example, we directly flush the rx buffer here in order to read more data. + uart_flush_input(UART_NUM_0); + xQueueReset(uart0_queue); + break; + + //Event of UART RX break detected + case UART_BREAK: + ESP_LOGI(TAG, "uart rx break"); + break; + + //Event of UART parity check error + case UART_PARITY_ERR: + ESP_LOGI(TAG, "uart parity error"); + break; + + //Event of UART frame error + case UART_FRAME_ERR: + ESP_LOGI(TAG, "uart frame error"); + break; + + //Others + default: + ESP_LOGI(TAG, "uart event type: %d", event.type); + break; + } + } + } + vTaskDelete(NULL); +} + + +static void uart1_event_task(void *pvParameters) +{ + uart_event_t event; + portMUX_TYPE uMutex = portMUX_INITIALIZER_UNLOCKED; + + for(;;) + { + //Waiting for UART event. + if(xQueueReceive(uart1_queue, (void * )&event, (TickType_t)portMAX_DELAY)) + { + bzero(buffer2, RD_BUF_SIZE); + //ESP_LOGI(TAG, "uart[%d] event:", UART_NUM_1); + + switch(event.type) + { + //Event of UART receiving data + /*We'd better handler data event fast, there would be much more data events than + other types of events. If we take too much time on data event, the queue might + be full.*/ + case UART_DATA: + //ESP_LOGI(TAG, "[UART DATA]: %d", event.size); + uart_read_bytes(UART_NUM_1, buffer2, event.size, portMAX_DELAY); + if(uart1_rx_needed) + { + buffer2_size = event.size; + //ESP_LOGI(TAG, "UART Rx: %s", buffer2); + taskENTER_CRITICAL(&uMutex); + for(int index = 0; index < event.size; index++) + { + xQueueSend(uart1_data_queue, &buffer2[index], 1000); + } + taskEXIT_CRITICAL(&uMutex); + uart_ifx_uart1_rx_cb(); + } + //ESP_LOGI(TAG, "UART RX: %s%s", buffer2, (!uart1_rx_needed)?" [MISSED]":""); + break; + //Event of HW FIFO overflow detected + + case UART_FIFO_OVF: + ESP_LOGI(TAG, "hw fifo overflow"); + // If fifo overflow happened, you should consider adding flow control for your application. + // The ISR has already reset the rx FIFO, + // As an example, we directly flush the rx buffer here in order to read more data. + uart_flush_input(UART_NUM_1); + xQueueReset(uart1_queue); + break; + + //Event of UART ring buffer full + case UART_BUFFER_FULL: + ESP_LOGI(TAG, "ring buffer full"); + // If buffer full happened, you should consider increasing your buffer size + // As an example, we directly flush the rx buffer here in order to read more data. + uart_flush_input(UART_NUM_1); + xQueueReset(uart1_queue); + break; + + //Event of UART RX break detected + case UART_BREAK: + ESP_LOGI(TAG, "uart rx break"); + break; + + //Event of UART parity check error + case UART_PARITY_ERR: + ESP_LOGI(TAG, "uart parity error"); + break; + + //Event of UART frame error + case UART_FRAME_ERR: + ESP_LOGI(TAG, "uart frame error"); + break; + + //Others + default: + ESP_LOGI(TAG, "uart event type: %d", event.type); + break; + } + } + } + vTaskDelete(NULL); +} + +void uart_create_rx_tasks(void) +{ + //Create a task to handler UART event from ISR + //xTaskCreate(uart0_event_task, "uart0_event_task", 2048, NULL, 18, NULL); + xTaskCreate(uart1_event_task, "uart1_event_task", 2048, NULL, 19, NULL); +} + +void uart_ifx_init(void) +{ + uart_config_t uart_config = { + .baud_rate = 115200, + .data_bits = UART_DATA_8_BITS, + .parity = UART_PARITY_DISABLE, + .stop_bits = UART_STOP_BITS_1, + .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, + .source_clk = UART_SCLK_APB, + }; + + //Install UART driver, and get the queue. + //ESP_ERROR_CHECK(uart_driver_install(UART_NUM_0, (BUF_SIZE+1024), (BUF_SIZE+1024), 20, &uart0_queue, 0)); + //ESP_ERROR_CHECK(uart_param_config(UART_NUM_0, &uart_config)); + + ESP_ERROR_CHECK(uart_driver_install(UART_NUM_1, (BUF_SIZE+1024), (BUF_SIZE+1024), 20, &uart1_queue, 0)); + ESP_ERROR_CHECK(uart_param_config(UART_NUM_1, &uart_config)); + + //Set UART log level + esp_log_level_set(TAG, ESP_LOG_INFO); + + //Set UART pins (using UART0 default pins ie no changes.) + ESP_ERROR_CHECK(uart_set_pin(UART_NUM_0, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE)); + ESP_ERROR_CHECK(uart_set_pin(UART_NUM_1, 17, 18, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE)); + + //uart0_data_queue = xQueueCreate(BUF_SIZE, sizeof(uint8_t)); + uart1_data_queue = xQueueCreate(BUF_SIZE, sizeof(uint8_t)); +} + +uint8_t uart_ifx_uart0_ifx_get_rx_data(uint8_t *rx) +{ + if(xQueueReceive(uart0_data_queue, rx, (TickType_t)100) == pdPASS) + { + return 1; + } + return 0; +} + +uint8_t uart_ifx_uart1_ifx_get_rx_data(uint8_t *rx) +{ + if(xQueueReceive(uart1_data_queue, rx, (TickType_t)100) == pdPASS) + { + return 1; + } + return 0; +} + +void uart_ifx_uart0_send_byte(uint8_t data) +{ + uart_write_bytes(UART_NUM_0, &data, 1); +} + +void uart_ifx_uart1_send_byte(uint8_t data) +{ + uart_write_bytes(UART_NUM_1, &data, 1); +} + +void uart_ifx_uart0_send_bytes(uint8_t *data, size_t length) +{ + uart_write_bytes(UART_NUM_0, data, length); +} + +void uart_ifx_uart1_send_bytes(uint8_t *data, size_t length) +{ + uart_write_bytes(UART_NUM_1, data, length); +} + +uint8_t *uart_ifx_uart1_get_rx_buffer(size_t *len) +{ + *len = buffer2_size; + return buffer2; +} + diff --git a/main/uart_ifx.h b/main/uart_ifx.h new file mode 100644 index 0000000..5d918b7 --- /dev/null +++ b/main/uart_ifx.h @@ -0,0 +1,26 @@ +/* + * uart.h + * + * Created on: Jan 10, 2023 + * Author: Partha + */ + +#ifndef MAIN_UART_IFX_H_ +#define MAIN_UART_IFX_H_ + +#include +#include + +void uart_ifx_init(void); +uint8_t uart_ifx_uart0_ifx_get_rx_data(uint8_t *rx); +uint8_t uart_ifx_uart1_ifx_get_rx_data(uint8_t *rx); +void uart_ifx_uart0_send_byte(uint8_t data); +void uart_ifx_uart1_send_byte(uint8_t data); +void uart_ifx_uart0_send_bytes(uint8_t *data, size_t length); +void uart_ifx_uart1_send_bytes(uint8_t *data, size_t length); +uint8_t *uart_ifx_uart1_get_rx_buffer(size_t *len); +void uart_create_rx_tasks(void); +__attribute__((weak)) void uart_ifx_uart0_rx_cb(void); +__attribute__((weak)) void uart_ifx_uart1_rx_cb(void); + +#endif /* MAIN_UART_IFX_H_ */ diff --git a/main/ulp/sensors_registers.h b/main/ulp/sensors_registers.h new file mode 100644 index 0000000..0a6cefb --- /dev/null +++ b/main/ulp/sensors_registers.h @@ -0,0 +1,321 @@ +/* + * sensors_registers.h + * + * Created on: Mar 8, 2023 + * Author: Sword + */ + +#ifndef MAIN_ULP_SENSORS_REGISTERS_H_ +#define MAIN_ULP_SENSORS_REGISTERS_H_ + +// Sensor Addresses +#define ENS210_ADDR 0x43 // Base address of 0x43 left shifted one bit to make room for the read/#write bit. Temperature and humidity sensor +#define MCP9600_ADDR 0x60 // Base address of 0x60 left shifted one bit to make room for the read/#write bit. Thermocouple interface chip +#define MC3419_ADDR 0x6C + +// ENS210 Registers +#define ENS210_PART_ID 0x00 +#define ENS210_DIE_REV 0x02 +#define ENS210_UID 0x04 +#define ENS210_SYS_CTRL 0x10 +#define ENS210_SYS_STAT 0x11 +#define ENS210_SENS_RUN 0x21 +#define ENS210_SENS_START 0x22 +#define ENS210_SENS_STOP 0x23 +#define ENS210_SENS_STAT 0x24 +#define ENS210_T_VAL 0x30 +#define ENS210_H_VAL 0x33 + +// MCP9600 Registers +#define MCP9600_HOT_JUNCTION_REG 0x00 +#define MCP9600_DELTA_JUNCTION_REG 0x01 +#define MCP9600_COLD_JUNCTION_REG 0x02 +#define MCP9600_STATUS_REG 0x04 +#define MCP9600_THERMOCOUPLE_CONFIG 0x05 +#define MCP9600_DEVICE_CONFIG_REG 0x06 +#define MCP9600_ALERT1_CONFIG_REG 0x08 +#define MCP9600_ALERT2_CONFIG_REG 0x09 +#define MCP9600_ALERT3_CONFIG_REG 0x0A +#define MCP9600_ALERT4_CONFIG_REG 0x0B +#define MCP9600_ALERT1_HYST_REG 0x0C +#define MCP9600_ALERT2_HYST_REG 0x0D +#define MCP9600_ALERT3_HYST_REG 0x0E +#define MCP9600_ALERT4_HYST_REG 0x0F +#define MCP9600_ALERT1_LIMIT_REG 0x10 +#define MCP9600_ALERT2_LIMIT_REG 0x11 +#define MCP9600_ALERT3_LIMIT_REG 0x12 +#define MCP9600_ALERT4_LIMIT_REG 0x13 +#define MCP9600_DEVICE_ID_REVISION 0x20 + +// MCP9600 Bits +#define MCP9600_INPUT_RANGE_BIT 0x10 +#define MCP9600_BURST_COMPLETE_BIT 0x80 +#define MCP9600_TH_UPDATE_BIT 0x40 +#define MCP9600_ALERT_ENABLE_BIT 0x01 + +#define MCP9600_ALERT1_STATUS 0x01 +#define MCP9600_ALERT2_STATUS 0x02 +#define MCP9600_ALERT3_STATUS 0x04 +#define MCP9600_ALERT4_STATUS 0x08 + +// Thermocouple types: +#define THERMOCOUPLE_TYPE_K 0x00 +#define THERMOCOUPLE_TYPE_J 0x10 +#define THERMOCOUPLE_TYPE_T 0x20 +#define THERMOCOUPLE_TYPE_N 0x30 +#define THERMOCOUPLE_TYPE_S 0x40 +#define THERMOCOUPLE_TYPE_E 0x50 +#define THERMOCOUPLE_TYPE_B 0x60 +#define THERMOCOUPLE_TYPE_R 0x70 + + +#define WAKE_HOST_LOWER_BYTE_DISABLED 0x00 +#define WAKE_HOST_LOWER_BYTE_ON_MOVEMENT_DETECTION 0x01 // 0 = disabled, 1 = enabled. +#define WAKE_HOST_LOWER_BYTE_ON_LIGHT_TO_DARK 0x02 // 0 = disabled, 1 = enabled. +#define WAKE_HOST_LOWER_BYTE_ON_DARK_TO_LIGHT 0x04 // 0 = disabled, 1 = enabled. +#define WAKE_HOST_LOWER_BYTE_ON_SWITCH_FROM_USB_TO_BATTERY 0x08 // 0 = disabled, 1 = enabled. +#define WAKE_HOST_LOWER_BYTE_ON_SWITCH_FROM_BATTERY_TO_USB 0x10 // 0 = disabled, 1 = enabled. +#define WAKE_HOST_LOWER_BYTE_WHEN_THERMOCOUPLE_CROSSES_LIMITS 0x20 // 0 = disabled, 1 = enabled. +#define WAKE_HOST_LOWER_BYTE_UNUSED_A 0x40 // 0 = disabled, 1 = enabled. +#define WAKE_HOST_LOWER_BYTE_UNUSED_B 0x80 // 0 = disabled, 1 = enabled. + +#define WAKE_HOST_UPPER_BYTE_UNUSED_C 0x01 // 0 = disabled, 1 = enabled. +#define WAKE_HOST_UPPER_BYTE_UNUSED_D 0x02 // 0 = disabled, 1 = enabled. +#define WAKE_HOST_UPPER_BYTE_UNUSED_E 0x04 // 0 = disabled, 1 = enabled. +#define WAKE_HOST_UPPER_BYTE_UNUSED_F 0x08 // 0 = disabled, 1 = enabled. +#define WAKE_HOST_UPPER_BYTE_UNUSED_G 0x10 // 0 = disabled, 1 = enabled. +#define WAKE_HOST_UPPER_BYTE_UNUSED_H 0x20 // 0 = disabled, 1 = enabled. +#define WAKE_HOST_UPPER_BYTE_UNUSED_I 0x40 // 0 = disabled, 1 = enabled. +#define WAKE_HOST_UPPER_BYTE_UNUSED_J 0x80 // 0 = disabled, 1 = enabled. + +// 16-bit masks +#define WAKE_HOST_DISABLED (uint16_t)WAKE_HOST_LOWER_BYTE_DISABLED +#define WAKE_HOST_ON_MOVEMENT_DETECTION (uint16_t)WAKE_HOST_LOWER_BYTE_ON_MOVEMENT_DETECTION +#define WAKE_HOST_ON_LIGHT_TO_DARK (uint16_t)WAKE_HOST_LOWER_BYTE_ON_LIGHT_TO_DARK +#define WAKE_HOST_ON_DARK_TO_LIGHT (uint16_t)WAKE_HOST_LOWER_BYTE_ON_DARK_TO_LIGHT +#define WAKE_HOST_ON_SWITCH_FROM_USB_TO_BATTERY (uint16_t)WAKE_HOST_LOWER_BYTE_ON_SWITCH_FROM_USB_TO_BATTERY +#define WAKE_HOST_ON_SWITCH_FROM_BATTERY_TO_USB (uint16_t)WAKE_HOST_LOWER_BYTE_ON_SWITCH_FROM_BATTERY_TO_USB +#define WAKE_HOST_WHEN_THERMOCOUPLE_CROSSES_LIMITS (uint16_t)WAKE_HOST_LOWER_BYTE_WHEN_THERMOCOUPLE_CROSSES_LIMITS +#define WAKE_HOST_UNUSED_A (uint16_t)WAKE_HOST_LOWER_BYTE_UNUSED_A +#define WAKE_HOST_UNUSED_B (uint16_t)WAKE_HOST_LOWER_BYTE_UNUSED_B +#define WAKE_HOST_UNUSED_C (uint16_t)(WAKE_HOST_UPPER_BYTE_UNUSED_C << 8) +#define WAKE_HOST_UNUSED_D (uint16_t)(WAKE_HOST_UPPER_BYTE_UNUSED_D << 8) +#define WAKE_HOST_UNUSED_E (uint16_t)(WAKE_HOST_UPPER_BYTE_UNUSED_E << 8) +#define WAKE_HOST_UNUSED_F (uint16_t)(WAKE_HOST_UPPER_BYTE_UNUSED_F << 8) +#define WAKE_HOST_UNUSED_G (uint16_t)(WAKE_HOST_UPPER_BYTE_UNUSED_G << 8) +#define WAKE_HOST_UNUSED_H (uint16_t)(WAKE_HOST_UPPER_BYTE_UNUSED_H << 8) +#define WAKE_HOST_UNUSED_I (uint16_t)(WAKE_HOST_UPPER_BYTE_UNUSED_I << 8) +#define WAKE_HOST_UNUSED_J (uint16_t)(WAKE_HOST_UPPER_BYTE_UNUSED_J << 8) + +#define STROBED_SENSOR_MEASUREMENT_EXCEEDED_THRESHOLD_A 0x0001 +#define STROBED_SENSOR_MEASUREMENT_RETURNED_FROM_ABOVE_THRESHOLD_A 0x0002 +#define STROBED_SENSOR_MEASUREMENT_EXCEEDED_THRESHOLD_B 0x0004 +#define STROBED_SENSOR_MEASUREMENT_RETURNED_FROM_ABOVE_THRESHOLD_B 0x0008 +#define STROBED_SENSOR_MEASUREMENT_EXCEEDED_THRESHOLD_C 0x0010 +#define STROBED_SENSOR_MEASUREMENT_RETURNED_FROM_ABOVE_THRESHOLD_C 0x0020 +#define STROBED_SENSOR_MEASUREMENT_FELL_BELOW_THRESHOLD_D 0x0040 +#define STROBED_SENSOR_MEASUREMENT_RETURNED_FROM_BELOW_THRESHOLD_D 0x0080 +#define STROBED_SENSOR_MEASUREMENT_FELL_BELOW_THRESHOLD_E 0x0100 +#define STROBED_SENSOR_MEASUREMENT_RETURNED_FROM_BELOW_THRESHOLD_E 0x0200 +#define STROBED_SENSOR_MEASUREMENT_FELL_BELOW_THRESHOLD_F 0x0400 +#define STROBED_SENSOR_MEASUREMENT_RETURNED_FROM_BELOW_THRESHOLD_F 0x0800 +#define STROBED_SENSOR_UNUSED_A 0x1000 +#define STROBED_SENSOR_UNUSED_B 0x2000 +#define STROBED_SENSOR_UNUSED_C 0x4000 +#define STROBED_SENSOR_UNUSED_D 0x8000 + +#define STROBED_MOTION_LOWER_BYTE_MOVEMENT_DETECTED 0x01 +#define STROBED_MOTION_LOWER_BYTE_UNUSED_A 0x02 +#define STROBED_MOTION_LOWER_BYTE_UNUSED_B 0x04 +#define STROBED_MOTION_LOWER_BYTE_UNUSED_C 0x08 +#define STROBED_MOTION_LOWER_BYTE_UNUSED_D 0x10 +#define STROBED_MOTION_LOWER_BYTE_UNUSED_E 0x20 +#define STROBED_MOTION_LOWER_BYTE_UNUSED_F 0x40 +#define STROBED_MOTION_LOWER_BYTE_UNUSED_G 0x80 + +#define STROBED_MOTION_UPPER_BYTE_UNUSED_H 0x01 +#define STROBED_MOTION_UPPER_BYTE_UNUSED_I 0x02 +#define STROBED_MOTION_UPPER_BYTE_UNUSED_J 0x04 +#define STROBED_MOTION_UPPER_BYTE_UNUSED_K 0x08 +#define STROBED_MOTION_UPPER_BYTE_UNUSED_L 0x10 +#define STROBED_MOTION_UPPER_BYTE_UNUSED_M 0x20 +#define STROBED_MOTION_UPPER_BYTE_UNUSED_N 0x40 +#define STROBED_MOTION_UPPER_BYTE_UNUSED_O 0x80 + +// 16-bit masks +#define STROBED_MOTION_MOVEMENT_DETECTED (uint16_t)STROBED_MOTION_LOWER_BYTE_MOVEMENT_DETECTED +#define STROBED_MOTION_UNUSED_A (uint16_t)STROBED_MOTION_LOWER_BYTE_UNUSED_A +#define STROBED_MOTION_UNUSED_B (uint16_t)STROBED_MOTION_LOWER_BYTE_UNUSED_B +#define STROBED_MOTION_UNUSED_C (uint16_t)STROBED_MOTION_LOWER_BYTE_UNUSED_C +#define STROBED_MOTION_UNUSED_D (uint16_t)STROBED_MOTION_LOWER_BYTE_UNUSED_D +#define STROBED_MOTION_UNUSED_E (uint16_t)STROBED_MOTION_LOWER_BYTE_UNUSED_E +#define STROBED_MOTION_UNUSED_F (uint16_t)STROBED_MOTION_LOWER_BYTE_UNUSED_F +#define STROBED_MOTION_UNUSED_G (uint16_t)STROBED_MOTION_LOWER_BYTE_UNUSED_G +#define STROBED_MOTION_UNUSED_H (uint16_t)(STROBED_MOTION_LOWER_BYTE_UNUSED_H << 8) +#define STROBED_MOTION_UNUSED_I (uint16_t)(STROBED_MOTION_LOWER_BYTE_UNUSED_I << 8) +#define STROBED_MOTION_UNUSED_J (uint16_t)(STROBED_MOTION_LOWER_BYTE_UNUSED_J << 8) +#define STROBED_MOTION_UNUSED_K (uint16_t)(STROBED_MOTION_LOWER_BYTE_UNUSED_K << 8) +#define STROBED_MOTION_UNUSED_L (uint16_t)(STROBED_MOTION_LOWER_BYTE_UNUSED_L << 8) +#define STROBED_MOTION_UNUSED_M (uint16_t)(STROBED_MOTION_LOWER_BYTE_UNUSED_M << 8) +#define STROBED_MOTION_UNUSED_N (uint16_t)(STROBED_MOTION_LOWER_BYTE_UNUSED_N << 8) +#define STROBED_MOTION_UNUSED_O (uint16_t)(STROBED_MOTION_LOWER_BYTE_UNUSED_O << 8) + +#define STROBED_MISC_LOWER_BYTE_CHECK_IN_REQUESTED 0x01 +#define STROBED_MISC_LOWER_BYTE_CHANGE_FROM_LIGHT_TO_DARK 0x02 +#define STROBED_MISC_LOWER_BYTE_CHANGE_FROM_DARK_TO_LIGHT 0x04 +#define STROBED_MISC_LOWER_BYTE_CHANGE_FROM_USB_TO_BATTERY 0x08 +#define STROBED_MISC_LOWER_BYTE_CHANGE_FROM_BATTERY_TO_USB 0x10 +#define STROBED_MISC_LOWER_BYTE_THERMOCOUPLE_PLUGGED_IN 0x20 +#define STROBED_MISC_LOWER_BYTE_THERMOCOUPLE_UNPLUGGED 0x40 +#define STROBED_MISC_LOWER_BYTE_UNUSED_A 0x80 + +#define STROBED_MISC_UPPER_BYTE_UNUSED_B 0x01 +#define STROBED_MISC_UPPER_BYTE_UNUSED_C 0x02 +#define STROBED_MISC_UPPER_BYTE_UNUSED_D 0x04 +#define STROBED_MISC_UPPER_BYTE_UNUSED_E 0x08 +#define STROBED_MISC_UPPER_BYTE_UNUSED_F 0x10 +#define STROBED_MISC_UPPER_BYTE_UNUSED_G 0x20 +#define STROBED_MISC_UPPER_BYTE_UNUSED_H 0x40 +#define STROBED_MISC_UPPER_BYTE_UNUSED_I 0x80 + +// 16-bit masks +#define STROBED_MISC_CHECK_IN_REQUESTED (uint16_t)STROBED_MISC_LOWER_BYTE_CHECK_IN_REQUESTED +#define STROBED_MISC_CHANGE_FROM_LIGHT_TO_DARK (uint16_t)STROBED_MISC_LOWER_BYTE_CHANGE_FROM_LIGHT_TO_DARK +#define STROBED_MISC_CHANGE_FROM_DARK_TO_LIGHT (uint16_t)STROBED_MISC_LOWER_BYTE_CHANGE_FROM_DARK_TO_LIGHT +#define STROBED_MISC_CHANGE_FROM_USB_TO_BATTERY (uint16_t)STROBED_MISC_LOWER_BYTE_CHANGE_FROM_USB_TO_BATTERY +#define STROBED_MISC_CHANGE_FROM_BATTERY_TO_USB (uint16_t)STROBED_MISC_LOWER_BYTE_CHANGE_FROM_BATTERY_TO_USB +#define STROBED_MISC_THERMOCOUPLE_PLUGGED_IN (uint16_t)STROBED_MISC_LOWER_BYTE_THERMOCOUPLE_PLUGGED_IN +#define STROBED_MISC_THERMOCOUPLE_UNPLUGGED (uint16_t)STROBED_MISC_LOWER_BYTE_THERMOCOUPLE_UNPLUGGED +#define STROBED_MISC_REGULAR_SCHEDULED_CHECK_IN (uint16_t)STROBED_MISC_LOWER_BYTE_REGULAR_SCHEDULED_CHECK_IN +#define STROBED_MISC_CHECK_IN_REQ_AFTER_POWER_ON (uint16_t)(STROBED_MISC_UPPER_BYTE_CHECK_IN_REQ_AFTER_POWER_ON << 8) +#define STROBED_MISC_DEVICE_OPERATE_IN_ALERT_MODE (uint16_t)(STROBED_MISC_UPPER_BYTE_DEVICE_OPERATE_IN_ALERT_MODE << 8) +#define STROBED_MISC_UNUSED_D (uint16_t)(STROBED_MISC_UPPER_BYTE_UNUSED_D << 8) +#define STROBED_MISC_UNUSED_E (uint16_t)(STROBED_MISC_UPPER_BYTE_UNUSED_E << 8) +#define STROBED_MISC_UNUSED_F (uint16_t)(STROBED_MISC_UPPER_BYTE_UNUSED_F << 8) +#define STROBED_MISC_UNUSED_G (uint16_t)(STROBED_MISC_UPPER_BYTE_UNUSED_G << 8) +#define STROBED_MISC_UNUSED_H (uint16_t)(STROBED_MISC_UPPER_BYTE_UNUSED_H << 8) +#define STROBED_MISC_UNUSED_I (uint16_t)(STROBED_MISC_UPPER_BYTE_UNUSED_I << 8) + +#define CURRENT_STATUS_LIGHT_DETECTED 0x01 +#define CURRENT_STATUS_POWERED_BY_USB 0x02 +#define CURRENT_STATUS_UNUSED_A 0x04 +#define CURRENT_STATUS_UNUSED_B 0x08 +#define CURRENT_STATUS_UNUSED_C 0x10 +#define CURRENT_STATUS_UNUSED_D 0x20 +#define CURRENT_STATUS_UNUSED_E 0x40 +#define CURRENT_STATUS_UNUSED_F 0x80 + +#define LIGHT_SENSOR_VREF_1V024 0x00 // Vref = 1.024V +#define LIGHT_SENSOR_VREF_2V048 0x01 // Vref = 2.048V +#define LIGHT_SENSOR_VREF_2V500 0x02 // Vref = 2.500V +#define LIGHT_SENSOR_VREF_VDD 0x03 // Vref = Vdd + +#define LIGHT_DETECTED true +#define LIGHT_UNDETECTED false + + +/* TRIGGER 1 bits */ +#define STROBED_TEMPERATURE_MEASUREMENT_EXCEEDED_UPPER_THRESHOLD 0x0001 +#define STROBED_TEMPERATURE_MEASUREMENT_FELL_BELOW_LOWER_THRESHOLD 0x0002 +#define STROBED_HUMIDITY_MEASUREMENT_EXCEEDED_UPPER_THRESHOLD 0x0004 +#define STROBED_HUMIDITY_MEASUREMENT_FELL_BELOW_LOWER_THRESHOLD 0x0008 +#define STROBED_THERMOCOUPLE_MEASUREMENT_EXCEEDED_UPPER_THRESHOLD 0x0010 +#define STROBED_THERMOCOUPLE_MEASUREMENT_FELL_BELOW_LOWER_THRESHOLD 0x0020 +#define STROBED_EXTERNAL_TEMP_PROBE_MEASUREMENT_EXCEEDED_UPPER_THRESHOLD 0x0040 +#define STROBED_EXTERNAL_TEMP_PROBE_MEASUREMENT_FELL_BELOW_LOWER_THRESHOLD 0x0080 +#define STROBED_DEVICE_OPERATE_IN_ALERT_MODE 0x0100 + + +/* TRIGGER 2 bits */ +#define STROBED_REGULAR_SCHEDULED_SENDINTERVAL_CHECKIN 0x0001 +#define STROBED_POWER_CHANGE_FROM_BATTERY_TO_USB 0x0002 +#define STROBED_POWER_CHANGE_FROM_USB_TO_BATTERY 0x0004 +#define STROBED_MOTION_MOVEMENT_WAS_DETECTED 0x0008 +#define STROBED_LIGHT_TRANSITION_FROM_LIGHT_TO_DARK 0x0010 +#define STROBED_LIGHT_TRANSITION_FROM_DARK_TO_LIGHT 0x0020 +#define STROBED_CHECK_IN_REQUESTED_AFTER_POWER_ON 0x4000 +#define STROBED_BUTTON_CHECK_IN_REQUESTED 0x8000 + + +#define STROBED_SENSOR_MEASUREMENT_EXCEEDED_UPPER_THRESHOLD 0x0001 +#define STROBED_SENSOR_MEASUREMENT_FELL_BELOW_LOWER_THRESHOLD 0x0002 + + +typedef enum +{ + ULP_OK, + ULP_ERROR +}ULP_STATUS_t; + + +typedef enum +{ + ULP_TEMPERATURE_SENSOR, + ULP_HUMIDITY_SENSOR, + ULP_THERMOCOUPLE_SENSOR, + ULP_LIGHT_SENSOR, + ULP_ACCELEROMETER_SENSOR, + ULP_POWER_MONITOR_SENSOR +}ulpSensorType_t; + + +typedef struct{ + + //Sensor Data + uint8_t thermocoupleMode; + uint8_t thermocoupleType; + uint8_t lightSensorMode; + + uint8_t accelerometerMode; + uint8_t accelerometerInterval; + uint8_t accelerometerLockoutInSeconds; + uint8_t powerMonitorMode; + uint8_t powerMonitorDebounceInSeconds; + + //uint8_t lightSensorLevelGP; + //uint8_t lightSensorLevelGN; + + //lightTh + uint8_t lightSensorLevel; + + + // OTHERS + uint8_t historyIndex; + uint8_t numberOfHistoryLogEntriesUntilRetriesAreNotAllowed; + + uint8_t sendDetails; + + uint16_t lightSensorLockoutInSeconds; + //acclTh + uint16_t accelerometerLevel; + + // INTERVALS + uint32_t sendInterval; + uint32_t alertInterval; + + //Limits + int32_t minHum; + int32_t maxHum; + + // DYNAMIC VARS + int32_t postURLNumber; + int32_t postURLMax; // Highest URL to try + + //Limits + float minTemp; + float maxTemp; + float voltageQuit; + + //limits Tc + float maxTcTemp; + float minTcTemp; + + //limits probe + float maxProbeTemp; + float minProbeTemp; + +}settings; + + + +#endif /* MAIN_ULP_SENSORS_REGISTERS_H_ */ diff --git a/main/ulp/ulp_main.c b/main/ulp/ulp_main.c new file mode 100644 index 0000000..d49c100 --- /dev/null +++ b/main/ulp/ulp_main.c @@ -0,0 +1,730 @@ +/* + * ulp_main.c + * + * Created on: Feb 17, 2023 + * Author: Partha + */ +#include +#include +#include "ulp_riscv.h" +#include "ulp_riscv_utils.h" +#include "ulp_riscv_gpio.h" +#include "sensors_registers.h" +#include "ulp_riscv_i2c_ulp_core.h" +#include "sdkconfig.h" + +#define I2C_MASTER_NUM 0 +#define ULP_CLOCK_CYCLE_IN_MS 8500 + + +volatile uint32_t server_time = 0; +volatile uint32_t is_sleep = 0; + +/*Settings structure*/ +volatile settings settings_structure; + + +/*Sensor variables*/ +//Sensor Data +float ulp_temperature; +float ulp_humidity; +float ulp_thermocoupleTemp; + +//Sensor previous Data +float ulp_prev_temperature; +float ulp_prev_humidity; +float ulp_prev_thermocoupleTemp; + + +/*Sensor flags and triggers*/ +uint16_t ulp_triggersThatCanWakeTheHost; +uint16_t ulp_strobedHumidityFlags; +uint16_t ulp_strobedMiscFlags; +uint16_t ulp_strobedMotionFlags; +uint16_t ulp_strobedTemperatureFlags; +uint16_t ulp_strobedThermocoupleFlags; + + +uint32_t wakeup_type = 0; +uint32_t ens_dev_id = 0; +uint32_t mcp9600_dev_id = 0; +uint32_t temp_needed = 0; + + +//Temp, Humi, Thermo raw_thresholds +uint32_t humidity_raw_max_thr = 0; +uint32_t humidity_raw_min_thr = 0; +uint32_t temperature_raw_max_thr = 0; +uint32_t temperature_raw_min_thr = 0; +uint32_t thermo_raw_max_thr = 0; +int32_t thermo_raw_min_thr = 0; + +//Sensor Raw values +uint32_t humidity_raw = 0; +uint32_t prev_humidity_raw = 0; +uint32_t thermo_temp_raw = 0; //need to be signed +uint32_t prev_thermo_temp_raw = 0; //need to be signed +uint32_t ens_temp_raw = 0; +uint32_t prev_ens_temp_raw = 0; + + +uint8_t data[8]; +uint32_t ens_dev_id; +uint32_t opt_dev_id; +uint32_t opt_manf_id; +uint32_t config_reg = 0; +uint32_t result_reg = 0; +uint32_t light_exponent = 0; +uint32_t light_data_opt = 0; +uint32_t prev_light_data_opt = 0; + +static uint8_t buff[8]; + +/****************************************************************************************/ +/********************************** General ULP-Functions *******************************/ + +static void ulp_initialize_variables(void) +{ + server_time = 0; + + //Sensor Data + ulp_temperature = 0; + ulp_humidity = 0; + ulp_thermocoupleTemp = 0; + + //Sensor previous Data + ulp_prev_temperature = 0; + ulp_prev_humidity = 0; + ulp_prev_thermocoupleTemp = 0; + + //Strobes and triggers variables + ulp_triggersThatCanWakeTheHost = 0; + ulp_strobedHumidityFlags = 0; + ulp_strobedMiscFlags = 0; + ulp_strobedMotionFlags = 0; + ulp_strobedTemperatureFlags = 0; + ulp_strobedThermocoupleFlags = 0; + + //Settings structure + settings_structure.accelerometerInterval = 0; + settings_structure.accelerometerLevel = 0; + settings_structure.accelerometerLockoutInSeconds = 0; + settings_structure.accelerometerMode = 0; + //settings_structure.accelerometerTokens = 0; + settings_structure.alertInterval = 0; + settings_structure.historyIndex = 0; +} + +/****************************************************************************************/ +/******************************** MCP9600-Thermocouple Sensor ***************************/ +static void set_thermocouple_type(uint8_t type) +{ + uint8_t tempThermocoupleType; + tempThermocoupleType = type; + tempThermocoupleType &= 0x70; + + /*Start new conversion */ + buff[0] = tempThermocoupleType; + ulp_riscv_i2c_master_set_slave_addr(0x60); + ulp_riscv_i2c_master_set_slave_reg_addr(0x05); + ulp_riscv_i2c_master_write_to_device(buff, 1); + + ulp_riscv_delay_cycles(500 * ULP_CLOCK_CYCLE_IN_MS); + ulp_riscv_delay_cycles(500 * ULP_CLOCK_CYCLE_IN_MS); +} + +static void get_thermocouple_dev_id(void) +{ + memset(buff, 0, 2); + + ulp_riscv_i2c_master_set_slave_addr(0x60); + ulp_riscv_i2c_master_set_slave_reg_addr(0x20); + ulp_riscv_i2c_master_read_from_device(buff, 1); + + ulp_riscv_delay_cycles(100 * ULP_CLOCK_CYCLE_IN_MS); + + mcp9600_dev_id = buff[0];//buff[1] | (buff[0] << 8); +} +#if 1 + +static void mcp_set_burst_mode(void) +{ + //printf("Setting Burst mode\n"); + ulp_riscv_i2c_master_set_slave_addr(0x60); + ulp_riscv_i2c_master_set_slave_reg_addr(0x06); + buff[0] = 0xA2; + ulp_riscv_i2c_master_write_to_device(buff, 1); + ulp_riscv_delay_cycles(1000 * ULP_CLOCK_CYCLE_IN_MS); +} + +static void mcp_start_conversion(void) +{ + memset(buff, 0, 2); + + //printf("Starting thermocouple conversion\n"); + ulp_riscv_i2c_master_set_slave_addr(0x60); + + ulp_riscv_i2c_master_set_slave_reg_addr(0x04); + buff[0] = 0xC0; + ulp_riscv_i2c_master_write_to_device(buff, 1); + ulp_riscv_delay_cycles(100 * ULP_CLOCK_CYCLE_IN_MS); + + mcp_set_burst_mode(); +} + +static void mcp_get_temp(void) +{ + uint16_t temp = 0; + uint8_t counter = 0; + uint8_t err = 1; + + memset(buff, 0, 6); + + mcp_start_conversion(); + + do + { + //ulp_riscv_i2c_master_set_slave_addr(0x60); + ulp_riscv_i2c_master_set_slave_reg_addr(0x04); + ulp_riscv_i2c_master_read_from_device(buff, 1); + + if(counter > 3) + { + //printf("Timeout for getting thermocouple temp\n"); + err = 0; + break; + } + counter++; + ulp_riscv_delay_cycles(111 * ULP_CLOCK_CYCLE_IN_MS); + } + while (!(buff[0] & 0x40)); + + if(err && !(buff[0] & 0x10)) + { + memset(buff, 0, 6); + //ulp_riscv_i2c_master_set_slave_addr(0x60); + + ulp_riscv_i2c_master_set_slave_reg_addr(0x00); + ulp_riscv_i2c_master_read_from_device(buff, 1); + + ulp_riscv_i2c_master_set_slave_reg_addr(0x00); + //ulp_riscv_i2c_master_read_from_device(buff + 1, 1); + ulp_riscv_i2c_master_read_from_device(buff + 1, 2); + + ulp_riscv_delay_cycles(10 * ULP_CLOCK_CYCLE_IN_MS); + prev_thermo_temp_raw = thermo_temp_raw; + + temp = buff[1] | (buff[0] << 8); + + + thermo_temp_raw = temp; + thermo_temp_raw /= 16; + + if(temp & 0x8000) // Adjust for sign bit + thermo_temp_raw -= 4096; + + } + ulp_riscv_delay_cycles(100 * ULP_CLOCK_CYCLE_IN_MS); +} +#endif + + +/****************************************************************************************/ +/************************** ENS210-Temperature & Humidity Sensor ************************/ + +static void ens_set_active(void) +{ + //ESN Setting to active mode + //printf("ESN Setting to active mode\n"); + ulp_riscv_i2c_master_set_slave_reg_addr(0x10); + buff[0] = 0; + ulp_riscv_i2c_master_write_to_device(buff, 1); +} + +static void ens_init(void) +{ + ulp_riscv_i2c_master_set_slave_addr(0x43); + ens_set_active(); + ulp_riscv_delay_cycles(100 * ULP_CLOCK_CYCLE_IN_MS); + ens_set_active(); + + ulp_riscv_delay_cycles(500 * ULP_CLOCK_CYCLE_IN_MS); + + //ESN Reading sys stat + //("ESN Reading sys stat\n"); + ulp_riscv_i2c_master_set_slave_reg_addr(0x11); + buff[0] = 0; + ulp_riscv_i2c_master_read_from_device(buff, 1); + //("ENS Sys stat: %d\n", buff[0]); + ulp_riscv_delay_cycles(100 * ULP_CLOCK_CYCLE_IN_MS); + + //Reading device id + //("ESN Reading device id\n"); + memset(buff, 0, 2); + ulp_riscv_i2c_master_set_slave_reg_addr(0x00); + ulp_riscv_i2c_master_read_from_device(buff, 1); + ulp_riscv_delay_cycles(100 * ULP_CLOCK_CYCLE_IN_MS); + + ulp_riscv_i2c_master_set_slave_reg_addr(0x01); + ulp_riscv_i2c_master_read_from_device(buff + 1, 1); + ulp_riscv_delay_cycles(100 * ULP_CLOCK_CYCLE_IN_MS); + ens_dev_id = buff[0] | (buff[1] << 8); +} + +static void ens_start(void) +{ + ulp_riscv_i2c_master_set_slave_addr(0x43); + + //Sens Run + ulp_riscv_i2c_master_set_slave_reg_addr(0x21); + buff[0] = 3; + ulp_riscv_i2c_master_write_to_device(buff, 1); + ulp_riscv_delay_cycles(100 * ULP_CLOCK_CYCLE_IN_MS); + + //Sens Start + ulp_riscv_i2c_master_set_slave_reg_addr(0x22); + buff[0] = 3; + ulp_riscv_i2c_master_write_to_device(buff, 1); + ulp_riscv_delay_cycles(500 * ULP_CLOCK_CYCLE_IN_MS); +} + +static void ens_read_temp(void) +{ + uint8_t index = 0; + + memset(buff, 0, 6); + + ulp_riscv_i2c_master_set_slave_addr(0x43); + ulp_riscv_i2c_master_set_slave_reg_addr(0x30); + + ulp_riscv_i2c_master_read_from_device(buff, 1); + ulp_riscv_delay_cycles(100 * ULP_CLOCK_CYCLE_IN_MS); + + ulp_riscv_i2c_master_set_slave_reg_addr(0x31); + ulp_riscv_i2c_master_read_from_device(buff + 1, 1); + ulp_riscv_delay_cycles(100 * ULP_CLOCK_CYCLE_IN_MS); + + ulp_riscv_i2c_master_set_slave_reg_addr(0x32); + ulp_riscv_i2c_master_read_from_device(buff + 2, 1); + ulp_riscv_delay_cycles(100 * ULP_CLOCK_CYCLE_IN_MS); + + ulp_riscv_i2c_master_set_slave_reg_addr(0x33); + ulp_riscv_i2c_master_read_from_device(buff + 3, 1); + ulp_riscv_delay_cycles(100 * ULP_CLOCK_CYCLE_IN_MS); + + ulp_riscv_i2c_master_set_slave_reg_addr(0x34); + ulp_riscv_i2c_master_read_from_device(buff + 4, 1); + ulp_riscv_delay_cycles(100 * ULP_CLOCK_CYCLE_IN_MS); + + ulp_riscv_i2c_master_set_slave_reg_addr(0x35); + ulp_riscv_i2c_master_read_from_device(buff + 5, 1); + ulp_riscv_delay_cycles(100 * ULP_CLOCK_CYCLE_IN_MS); + + if(buff[2] & 0x01) + { + prev_ens_temp_raw = ens_temp_raw; + ens_temp_raw = buff[0] | (buff[1] << 8); + //tempC = temp/64.0; + //tempC -= 273.15; + } + + if(buff[5] & 0x01) + { + prev_humidity_raw = humidity_raw; + humidity_raw = buff[3] | (buff[4] << 8); + //hum = hum/512.0; + } +} + +uint8_t ulp_data_process_tempHumi_thresholds(uint32_t raw_data, uint32_t prev_raw_data, ulpSensorType_t sensor) +{ + uint8_t useTokens = 0; + uint8_t wakeHostForStrobedTrigger = 0; + + switch(sensor) + { + case ULP_LIGHT_SENSOR: + break; + + case ULP_ACCELEROMETER_SENSOR: + break; + + case ULP_POWER_MONITOR_SENSOR: + break; + + case ULP_TEMPERATURE_SENSOR: + + + /* Process thresholds for ENS210-TempData*/ + if((raw_data > temperature_raw_max_thr) && (prev_raw_data < temperature_raw_max_thr)) + { + (ulp_strobedTemperatureFlags) |= STROBED_SENSOR_MEASUREMENT_EXCEEDED_UPPER_THRESHOLD; + wakeup_type |= (1<<3); + wakeHostForStrobedTrigger = 1; + } + else if((raw_data < temperature_raw_min_thr) && (prev_raw_data > temperature_raw_min_thr)) + { + (ulp_strobedTemperatureFlags) |= STROBED_SENSOR_MEASUREMENT_FELL_BELOW_LOWER_THRESHOLD; + wakeup_type |= (1<<4); + wakeHostForStrobedTrigger = 1; + } + + break; + + case ULP_HUMIDITY_SENSOR: + + /* Process thresholds for ENS210-HumiData*/ + if((raw_data > humidity_raw_max_thr) && (prev_raw_data < humidity_raw_max_thr)) + { + (ulp_strobedHumidityFlags) |= STROBED_SENSOR_MEASUREMENT_EXCEEDED_UPPER_THRESHOLD; + wakeup_type |= (1<<5); + wakeHostForStrobedTrigger = 1; + } + else if((raw_data < humidity_raw_min_thr) && (prev_raw_data > humidity_raw_min_thr)) + { + (ulp_strobedHumidityFlags) |= STROBED_SENSOR_MEASUREMENT_FELL_BELOW_LOWER_THRESHOLD; + wakeup_type |= (1<<6); + wakeHostForStrobedTrigger = 1; + } + break; + + case ULP_THERMOCOUPLE_SENSOR: + + if((ulp_triggersThatCanWakeTheHost & WAKE_HOST_WHEN_THERMOCOUPLE_CROSSES_LIMITS)) + { + /* Process thresholds for MCP9600-TcData*/ + if((raw_data > thermo_raw_max_thr) && (prev_raw_data < thermo_raw_max_thr)) + { + (ulp_strobedThermocoupleFlags) |= STROBED_SENSOR_MEASUREMENT_EXCEEDED_UPPER_THRESHOLD; + wakeup_type |= (1<<7); + wakeHostForStrobedTrigger = 1; + } + else if((raw_data < thermo_raw_min_thr) && (prev_raw_data > thermo_raw_min_thr)) + { + (ulp_strobedThermocoupleFlags) |= STROBED_SENSOR_MEASUREMENT_FELL_BELOW_LOWER_THRESHOLD; + wakeup_type |= (1<<8); + wakeHostForStrobedTrigger = 1; + } + break; + } + break; + } + + return wakeHostForStrobedTrigger; +} + + +uint8_t ulp_data_process_tempHumi_thresholds2(uint32_t raw_data, uint32_t prev_raw_data, uint8_t sensor) +{ + //uint8_t enable_thsProcess = 1; + uint8_t useTokens = 0; + uint8_t wakeHostForStrobedTrigger = 0; + uint32_t thr = 0; + uint32_t thr2 = 0; + + switch(sensor) + { + case 1: + + /* Set the tokens register to be ThermoCouple token-registers */ + //tokenregister = &(esp_settings->temperatureTokens); + + thr = ((26.6+273.15)*64); + thr2 = ((-1.1+273.15)*64); + /* Process thresholds for ENS210-TempData*/ + if((raw_data > thr) && (prev_raw_data < thr)) + { + wakeup_type |= (1<<3); + wakeHostForStrobedTrigger = 1; + } + else if((raw_data < thr2) && (prev_raw_data > thr2)) + { + wakeup_type |= (1<<4); + wakeHostForStrobedTrigger = 1; + } + + break; + + case 2: + + /* Set the tokens register to be Humidity token registers */ + //tokenregister = &(esp_settings->humidityTokens); + + /* Process thresholds for ENS210-HumiData*/ + if((raw_data > (512*80)) && (prev_raw_data < (512*80))) + { + wakeup_type |= (1<<5); + wakeHostForStrobedTrigger = 1; + } + else if((raw_data < (512*10)) && (prev_raw_data > (512*10))) + { + wakeup_type |= (1<<6); + wakeHostForStrobedTrigger = 1; + } + break; + + case 3: + + { + /* Set the tokens register to be ThermoCouple token-registers */ + //tokenregister = &(esp_settings->thermocoupleTokens); + + /* Process thresholds for MCP9600-TcData*/ + if((raw_data > 50) && (prev_raw_data < 50)) + { + wakeup_type |= (1<<7); + wakeHostForStrobedTrigger = 1; + } + else if((raw_data < -100) && (prev_raw_data > -100)) + { + wakeup_type |= (1<<8); + wakeHostForStrobedTrigger = 1; + } + break; + } + break; + } + + return wakeHostForStrobedTrigger; +} + + + +/**********************************************************************/ +/************************Light sensor**********************************/ +/**********************************************************************/ +void opt_init(void) +{ + /* Fetch manufacturer ID */ + data[0] = 0; + data[1] = 0; + ulp_riscv_i2c_master_set_slave_addr(0x44); + ulp_riscv_i2c_master_set_slave_reg_addr(0x7E); + ulp_riscv_i2c_master_read_from_device(data, 2); + ulp_riscv_delay_cycles(500 * ULP_CLOCK_CYCLE_IN_MS); + opt_manf_id = (data[0]<<8)|(data[1]); + + /* Fetch Device ID */ + data[0] = 0; + data[1] = 0; + ulp_riscv_i2c_master_set_slave_addr(0x44); + ulp_riscv_i2c_master_set_slave_reg_addr(0x7F); + ulp_riscv_i2c_master_read_from_device(data, 2); + ulp_riscv_delay_cycles(500 * ULP_CLOCK_CYCLE_IN_MS); + opt_dev_id = (data[0]<<8)|(data[1]); +} + +void opt_read_reg(void) +{ + uint8_t data[8]; + uint8_t exponent = 0; + uint16_t result =1 ; + uint32_t result_reg2 = 0; + + + /* Fetch Configuration register */ + data[0] = 0; + data[1] = 0; + ulp_riscv_i2c_master_set_slave_addr(0x44); + ulp_riscv_i2c_master_set_slave_reg_addr(0x01); + ulp_riscv_i2c_master_read_from_device(data, 1); + ulp_riscv_i2c_master_read_from_device(data+1, 2); + ulp_riscv_delay_cycles(100 * ULP_CLOCK_CYCLE_IN_MS); + config_reg = (data[0]<<8)|(data[1]); + + /* Set the single shot mode */ + config_reg = config_reg | (1<<9); + config_reg = config_reg & (~(1<<10)); + + + /* Send the new value of the configuration register */ + data[0] = config_reg>>8; + data[1] = config_reg&255; + ulp_riscv_i2c_master_set_slave_reg_addr(0x01); + ulp_riscv_i2c_master_write_to_device(data, 2); + ulp_riscv_delay_cycles(800 * ULP_CLOCK_CYCLE_IN_MS); + + /* Wait for the CRF from the opt3001 sensor */ + while(config_reg & (1<<9)) + { + ulp_riscv_i2c_master_set_slave_addr(0x44); + ulp_riscv_i2c_master_set_slave_reg_addr(0x01); + ulp_riscv_i2c_master_read_from_device(data, 1); + ulp_riscv_i2c_master_read_from_device(data+1, 2); + ulp_riscv_delay_cycles(100 * ULP_CLOCK_CYCLE_IN_MS); + config_reg = (data[0]<<8)|(data[1]); + } + + /* Fetch Light sensor result register */ + data[0] = 0; + data[1] = 0; + ulp_riscv_i2c_master_set_slave_addr(0x44); + ulp_riscv_i2c_master_set_slave_reg_addr(0x00); + ulp_riscv_i2c_master_read_from_device(data, 1); + ulp_riscv_i2c_master_read_from_device(data+1, 2); + result_reg = (data[0]<<8)|(data[1]); + result_reg2 = result_reg & 0xFFF; + + for(int i=1; i<=light_exponent; i++) + result *=2; + + + prev_light_data_opt = light_data_opt; + light_data_opt = 0.01*result*result_reg2; + //light_data_opt = 0.16 * result_reg2; +} + +uint8_t ulp_data_process_lightSen_thresholds(uint32_t prev_raw_data, uint32_t raw_data) +{ + uint8_t wakeHostForStrobedTrigger = 0; + +#if 0 + /* Check if light now has been detected and in the previous state there were no light*/ + /* (Current_data > Threshold_GP) && (Previous_data < Threshold_GN)*/ + if((raw_data > settings_structure.lightSensorLevelGP) && (prev_raw_data < settings_structure.lightSensorLevelGN)) + { + + /* Check if we should do check-in when changing from dark to light*/ + if(ulp_triggersThatCanWakeTheHost & WAKE_HOST_ON_DARK_TO_LIGHT) + { + ulp_strobedMiscFlags |= STROBED_MISC_CHANGE_FROM_DARK_TO_LIGHT; + + /* Reduce light tokens by 1*/ + if(settings_structure.lightSensorTokens) + { + settings_structure.lightSensorTokens--; + wakeHostForStrobedTrigger = 1; + } + } + }/* (Current_data < Threshold_GN) && (Previous_data > Threshold_GP)*/ + else if((raw_data < settings_structure.lightSensorLevelGN) && (prev_raw_data > settings_structure.lightSensorLevelGP)) + { + + /* Check if we should do check-in when changing from light to dark*/ + if(ulp_triggersThatCanWakeTheHost & WAKE_HOST_ON_LIGHT_TO_DARK) + { + ulp_strobedMiscFlags |= STROBED_MISC_CHANGE_FROM_LIGHT_TO_DARK; + + /* Reduce light tokens by 1*/ + if(settings_structure.lightSensorTokens) + { + settings_structure.lightSensorTokens--; + wakeHostForStrobedTrigger = 1; + } + } + } + else + { + } +#endif + + + /* Check if light now has been detected and in the previous state there were no light*/ + if((raw_data > settings_structure.lightSensorLevel) && (prev_raw_data < settings_structure.lightSensorLevel)) + { + /* Check if we should do check-in when changing from dark to light*/ + if(ulp_triggersThatCanWakeTheHost & WAKE_HOST_ON_DARK_TO_LIGHT) + { + ulp_strobedMiscFlags |= STROBED_MISC_CHANGE_FROM_DARK_TO_LIGHT; + wakeHostForStrobedTrigger = 1; + wakeup_type |= (1<<1); + } + } + else if((raw_data < settings_structure.lightSensorLevel) && (prev_raw_data > settings_structure.lightSensorLevel)) + { + /* Check if we should do check-in when changing from light to dark*/ + if(ulp_triggersThatCanWakeTheHost & WAKE_HOST_ON_LIGHT_TO_DARK) + { + ulp_strobedMiscFlags |= STROBED_MISC_CHANGE_FROM_LIGHT_TO_DARK; + wakeHostForStrobedTrigger = 1; + wakeup_type |= (1<<2); + } + } + + return wakeHostForStrobedTrigger; +} + +int main(void) +{ + int cycle_count = 0; + int wakeHostForStrobedTrigger = 0; + ulp_initialize_variables(); + + ens_init(); + set_thermocouple_type(0); + get_thermocouple_dev_id(); + mcp_start_conversion(); + ens_start(); + + for(;;) + { + /*if(temp_needed) + { + ens_read_temp(); + mcp_get_temp(); + }*/ + if(is_sleep) + { + server_time += 2; + + ens_read_temp(); + //wakeHostForStrobedTrigger += ulp_data_process_tempHumi_thresholds2(ens_temp_raw, prev_ens_temp_raw, 1); + wakeHostForStrobedTrigger += ulp_data_process_tempHumi_thresholds(ens_temp_raw, prev_ens_temp_raw, ULP_TEMPERATURE_SENSOR); + //wakeHostForStrobedTrigger += ulp_data_process_tempHumi_thresholds2(humidity_raw, prev_humidity_raw, 2); + wakeHostForStrobedTrigger += ulp_data_process_tempHumi_thresholds(humidity_raw, prev_humidity_raw, ULP_HUMIDITY_SENSOR); + + if((ulp_triggersThatCanWakeTheHost & WAKE_HOST_WHEN_THERMOCOUPLE_CROSSES_LIMITS)) + { + mcp_get_temp(); + //wakeHostForStrobedTrigger += ulp_data_process_tempHumi_thresholds2(thermo_temp_raw, prev_thermo_temp_raw, 3); + wakeHostForStrobedTrigger += ulp_data_process_tempHumi_thresholds(thermo_temp_raw, prev_thermo_temp_raw, ULP_THERMOCOUPLE_SENSOR); + } + + if(ulp_triggersThatCanWakeTheHost & (WAKE_HOST_ON_DARK_TO_LIGHT|WAKE_HOST_ON_LIGHT_TO_DARK)) + { + opt_read_reg(); + wakeHostForStrobedTrigger += ulp_data_process_lightSen_thresholds(prev_light_data_opt,light_data_opt); + } + + + + if(wakeHostForStrobedTrigger > 0) + { + wakeHostForStrobedTrigger = 0; + is_sleep = 0; + ulp_riscv_wakeup_main_processor(); + } +#if 0 + //if(tempC > 50.0) (tempC > (threshold+273.15)*64) + if(ens_temp_raw > 20681) + { + wakeup_type |= 1; + } + + if(thermo_temp_raw > 800) + { + wakeup_type |= 2; + } + /*if(thermoTemp > 50.0) + { + is_sleep = 0; + temp_needed = 0; + wakeup_type = 2; + ulp_riscv_wakeup_main_processor(); + }*/ + if(wakeup_type) + { + is_sleep = 0; + temp_needed = 0; + ulp_riscv_wakeup_main_processor(); + } +#endif + } + + ulp_riscv_delay_cycles(1000 * ULP_CLOCK_CYCLE_IN_MS); + } + return 0; +} + + + diff --git a/main/wifi_Client.c b/main/wifi_Client.c new file mode 100644 index 0000000..139319c --- /dev/null +++ b/main/wifi_Client.c @@ -0,0 +1,643 @@ +/* + * tempstick_wifi_client.c + * + * Created on: Jul 28, 2023 + * Author: Sword + */ + + +#include +#include +#include "esp_log.h" +#include "nvs_flash.h" +#include "esp_event.h" +#include "esp_netif.h" +#include "esp_tls.h" +#include "esp_crt_bundle.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "esp_system.h" +#include "esp_http_client.h" +#include "wifi_Client.h" +#include "wifi_Init.h" +#include "comms.h" +#include "modem.h" +#include "wifi_OTA.h" +#include "esp_mac.h" +#include "data_processing.h" +#include "hmi.h" + +#if (WIFI_NEEDED == 1) +static const char* TAG = "CLIENT"; +#define LOG_LOCAL_LEVEL ESP_LOG_INFO + +extern uint32_t g_version; +extern uint32_t g_McuUpdate; + +bool isDataNeeded = false; +bool getBinFile; + +static char *output_buffer; +static server_type_t selected_server; +deviceToServer_msgType_t post_msg_type; + +char url[200]; +//char onboarding_host[] = ON_BOARDING_SERVER_DOMAIN_NAME; + +char *params; +uint8_t http_client_test_task_end = 0; +uint8_t http_client_post_task_end = 0; +uint8_t http_client_get_task_end = 0; +esp_err_t http_client_test_err; +esp_err_t http_client_post_err; +esp_err_t http_client_get_err; + + + +esp_err_t http_event_handler(esp_http_client_event_t *evt) +{ + //static char *output_buffer; // Buffer to store response of http request from event handler + //static int output_len; // Stores number of bytes read + switch(evt->event_id) + { + case HTTP_EVENT_ERROR: + ESP_LOGD(TAG, "HTTP_EVENT_ERROR"); + break; + + case HTTP_EVENT_ON_CONNECTED: + ESP_LOGD(TAG, "HTTP_EVENT_ON_CONNECTED"); + break; + + case HTTP_EVENT_HEADER_SENT: + ESP_LOGD(TAG, "HTTP_EVENT_HEADER_SENT"); + break; + + case HTTP_EVENT_ON_HEADER: + ESP_LOGD(TAG, "HTTP_EVENT_ON_HEADER, key=%s, value=%s", evt->header_key, evt->header_value); + break; + + case HTTP_EVENT_ON_DATA: + ESP_LOGI(TAG, "HTTP_EVENT_ON_DATA, len=%d", evt->data_len); + /* + * Check for chunked encoding is added as the URL for chunked encoding used in this example returns binary data. + * However, event handler can also be used in case chunked encoding is used. + */ + /*if (!esp_http_client_is_chunked_response(evt->client)) + { + // If user_data buffer is configured, copy the response into the buffer + if (evt->user_data) + { + memcpy(evt->user_data + output_len, evt->data, evt->data_len); + } + else + { + if (output_buffer == NULL) + { + output_buffer = (char *)pvPortMalloc(esp_http_client_get_content_length(evt->client)); + output_len = 0; + if (output_buffer == NULL) + { + ESP_LOGE(TAG, "Failed to allocate memory for output buffer"); + return ESP_FAIL; + } + } + memcpy(output_buffer + output_len, evt->data, evt->data_len); + } + output_len += evt->data_len; + }*/ + if(isDataNeeded && (evt->data_len > 0)) + { + //output_buffer = (char *)pvPortMalloc(evt->data_len); + memcpy(output_buffer, evt->data, evt->data_len); + output_buffer[evt->data_len] = 0; + isDataNeeded = false; + //ESP_LOGI(TAG, "%s\n", output_buffer); + } + + break; + + case HTTP_EVENT_ON_FINISH: + ESP_LOGI(TAG, "HTTP_EVENT_ON_FINISH"); + /*if (output_buffer != NULL) + { + ESP_LOGI(TAG, "HTTP Response:\n%s", output_buffer); + vPortFree(output_buffer); + output_buffer = NULL; + } + output_len = 0;*/ + break; + + case HTTP_EVENT_DISCONNECTED: + //isDataNeeded = false; + //vPortFree(output_buffer); + + ESP_LOGI(TAG, "HTTP_EVENT_DISCONNECTED"); + int mbedtls_err = 0; + esp_err_t err = esp_tls_get_and_clear_last_error((esp_tls_error_handle_t)evt->data, &mbedtls_err, NULL); + if (err != 0) + { + ESP_LOGI(TAG, "Last esp error code: 0x%x\nLast mbedtls failure: 0x%x", err, mbedtls_err); + } + /*if (output_buffer != NULL) + { + vPortFree(output_buffer); + output_buffer = NULL; + } + output_len = 0;*/ + break; + + case HTTP_EVENT_REDIRECT: + ESP_LOGI(TAG, "HTTP_EVENT_REDIRECTED"); + break; + } + return ESP_OK; +} + +static int sum_digits(int digit) +{ + int sum = 0; + while (digit > 0) + { + sum = sum + digit % 10; + digit = digit / 10; + } + return sum; +} + +static bool imei_check_valid(char *message_imei) +{ + //find the length of message imei + int len = strlen(message_imei); + int sum = 0; + ESP_LOGI(TAG,"IMEI : %s",message_imei); + + //check length of imei field + if (len != 15){ + //invalid IMEI + ESP_LOGW(TAG,"Invalid IMEI length"); + return false; + } + if(!strcmp(message_imei,modem_get_imei())){ + + for(int i = len-1 ; i >= 0; i--) + { + //check if message imei fields contain numbers (0-9) + if((message_imei[i] > 47) && (message_imei[i] < 58)){ + int digit = (message_imei[i] - 48); + // Doubling every alternate beginning at [13] digit + //ignore last number [14] and first number [0] as well + if (i % 2 != 0) + digit = 2 * digit; + // Finding sum of the digits + // if digit*2 is a two digit number add the two digits + sum += sum_digits(digit); + + } + else{ + ESP_LOGW(TAG,"Invalid IMEI (not numerical values)"); + return false; + } + } + } + else{ + ESP_LOGI(TAG,"Message IMEI doesn't match board IMEI"); + return false; + } + + return (sum % 10 == 0); +} + +/*SP5 866349048889004 1676395843 FW_2002 EP */ +static void wifi_Parse_SP5(char *buf, int len) +{ + char messageheader[4] = {0}; /*ex: SPx*/ + char messageIMEI[15] = {0}; + // char messageIMEI[] = "866349048890473";/*//hard coded IMEI*/ + char epochTime[30] = {0}; + char firmware_version[10] = {0}; + char *strret = NULL; + uint32_t new_fw_version = 0; + int ret_sp5 = -1; + + /**********************************************************************************************************/ + /*SP5*/ + strret = strtok(buf, " "); + strcpy(messageheader, strret); + ESP_LOGI(TAG,"%s message is received",messageheader); + + /**********************************************************************************************************/ + /*IMEI*/ + strret = strtok (NULL," "); + strcpy(messageIMEI, strret); + ret_sp5 = imei_check_valid(messageIMEI); + if(ret_sp5 != false){ + //ok IMEI + ESP_LOGI(TAG,"Fetched IMEI matches board"); + } + else{ + ESP_LOGW(TAG,"INVALID IMEI"); + return; + //return ret_sp5; + } + + /**********************************************************************************************************/ + /*epoch time*/ + strret = strtok (NULL," "); + strcpy(epochTime, strret); + ESP_LOGI(TAG,"epoch Time : %s",epochTime); + + /**********************************************************************************************************/ + /*new FW version*/ + strret = strtok(NULL, "FW_"); + strcpy(firmware_version,strret); + new_fw_version = (uint32_t)atoi(firmware_version); + ESP_LOGI(TAG,"Firmware version from SP5: %ld\nBoard Firmware version: %ld",new_fw_version,g_version); //logging/printing FR_version message for tracing + + /**********************************************************************************************************/ + /*check if the new version is greater than current version*/ + if(!(new_fw_version > g_version)) + { + ESP_LOGI(TAG,"MCU F/W UP TO DATE"); + } + else + { + /*Logging/printing this message*/ + ESP_LOGI(TAG,"F/W Update NEEDED\nGET MCU UPDATE"); + + /*reading OTA files*/ + getBinFile = true; + /*reading OTA files*/ + } +} + + + +static void http_client_test_task(void *pvParameters) +{ + esp_http_client_config_t config = { + .url = (const char*)url, + .crt_bundle_attach = esp_crt_bundle_attach, + .event_handler = http_event_handler + }; + + //config.event_handler = http_event_handler; + //config.url = (char *)pvPortMalloc((1 + strlen(url))*sizeof(char)); + //strcpy((char *)config.url, url); + + esp_http_client_handle_t client = esp_http_client_init(&config); + esp_err_t err = esp_http_client_perform(client); + + if (err == ESP_OK) + { + ESP_LOGI(TAG, "HTTPS Status = %d, content_length = %lld", esp_http_client_get_status_code(client), esp_http_client_get_content_length(client)); + } + else + { + ESP_LOGE(TAG, "Error perform http request %s", esp_err_to_name(err)); + } + //vPortFree((char *)config.url); + esp_http_client_cleanup(client); + http_client_test_err = err; + http_client_test_task_end = 1; + vTaskDelete(NULL); +} + +esp_http_client_handle_t client_post; +static void http_client_post_task(void *pvParameters) +{ + /* make sure that the client_post is not initialized before (to be able to initialized it without any problems) */ + if(!client_post) + { + /* Set the configurations */ + esp_http_client_config_t config = { + .url = (const char*)url, + .method = HTTP_METHOD_POST, + .buffer_size = 2560, + .crt_bundle_attach = esp_crt_bundle_attach, + .event_handler = http_event_handler + }; + + /* Initialize client_post with the entered configurations */ + client_post = esp_http_client_init(&config); + } + + /* Set the header of the post message */ + if(post_msg_type == CHECK_IN_STR) + { + esp_http_client_set_header(client_post, "Authorization", AUTHERIZATION_VALUE); + //esp_http_client_set_header(client, "Host", "testdevice.tempstickapi.com"); + esp_http_client_set_header(client_post, "User-Agent", USER_AGENT_VALUE); + esp_http_client_set_header(client_post, "Content-Type", CONTENT_TYPE_VALUE); + } + else if(post_msg_type == ON_BOARDING_STR) + { + esp_http_client_set_header(client_post, "Authorization", AUTHERIZATION_VALUE_ONBOARDING); + //esp_http_client_set_header(client, "Host", ON_BOARDING_SERVER_DOMAIN_NAME); + esp_http_client_set_header(client_post, "User-Agent", USER_AGENT_ONBOARDING); + esp_http_client_set_header(client_post, "Content-Type", CONTENT_TYPE_VALUE_ONBOARDING); + } + + /* Set the check-in message */ + esp_http_client_set_post_field(client_post, params, strlen(params)); + + esp_err_t err = esp_http_client_perform(client_post); + + if (err == ESP_OK) + { + ESP_LOGI(TAG, "HTTPS Status = %d, content_length = %lld", esp_http_client_get_status_code(client_post), esp_http_client_get_content_length(client_post)); + } + else + { + ESP_LOGE(TAG, "Error perform http request %s", esp_err_to_name(err)); + } + + //esp_http_client_cleanup(client_post); + http_client_post_err = err; + http_client_post_task_end = 1; + vTaskDelete(NULL); +} + +static void http_client_get_task(void *pvParameters) +{ + esp_http_client_config_t config = { + .url = (const char*)url, // Replace with your desired URL + .method = HTTP_METHOD_GET, + .cert_pem = NULL, + .event_handler = http_event_handler + }; + + esp_http_client_handle_t client = esp_http_client_init(&config); + esp_err_t err = esp_http_client_perform(client); + + if (err == ESP_OK) { + ESP_LOGI(TAG, "HTTP GET Status = %d, content_length = %lld", + esp_http_client_get_status_code(client), + esp_http_client_get_content_length(client)); + } else { + ESP_LOGE(TAG, "HTTP GET request failed: %s", esp_err_to_name(err)); + } + + esp_http_client_cleanup(client); + http_client_get_err = err; + http_client_get_task_end = 1; + vTaskDelete(NULL); +} + + +esp_err_t http_client_test(char *url1) +{ + strcpy(url,url1); + isDataNeeded = false; + http_client_test_task_end = 0; + xTaskCreate(http_client_test_task, "http_client_test_task", 4096, NULL, 17, NULL); + while(!http_client_test_task_end) + { + vTaskDelay(10 / portTICK_PERIOD_MS); + } + return http_client_test_err; +} + +esp_err_t http_client_post(char *url1, char *params1, char *response) +{ + http_client_post_task_end = 0; + strcpy(url,url1); + params = params1; + output_buffer = response; + isDataNeeded = true; + xTaskCreate(http_client_post_task, "http_client_post_task", 4096, NULL, 17, NULL); + while(!http_client_post_task_end) + { + vTaskDelay(10 / portTICK_PERIOD_MS); + } + return http_client_post_err; +} + +void http_client_post_stop(void) +{ + esp_http_client_cleanup(client_post); + client_post = NULL; +} + +esp_err_t http_client_get(const char *url1, char *response) +{ + http_client_get_task_end = 0; + strcpy(url,url1); + output_buffer = response; + isDataNeeded = true; + xTaskCreate(http_client_get_task, "http_client_get_task", 4096, NULL, 17, NULL); + while(!http_client_get_task_end) + { + vTaskDelay(10 / portTICK_PERIOD_MS); + } + return http_client_get_err; +} + + + +esp_err_t http_client_do_get_request(get_req_type_t target_url, char* device_imei, char *response_buf) +{ + uint8_t retval = WIFI_FAIL; + char server_url[200]; + + switch(target_url) + { + case GET_CONFIGURATIONS: + + ESP_LOGI(TAG,"/******** Configuration -SP3- GET request ********/"); + + /* Try with server-1 */ + if(selected_server == SERVER_ONE) + { + sprintf(server_url, MCU_GET_CONFIG_FLAGS_URL1, device_imei); + retval = http_client_get((const char*)server_url,response_buf); + if(retval != WIFI_OK) + { + ESP_LOGI(TAG,"Server-1 fails to connect. Switching to Server-2"); + selected_server = SERVER_TWO; + } + } + + /* Try with server-2 if & only if server-1 fails to connect */ + if(selected_server == SERVER_TWO) + { + sprintf(server_url, MCU_GET_CONFIG_FLAGS_URL2, device_imei); + http_client_get((const char*)server_url,response_buf); + if(retval != WIFI_OK) + { + selected_server = SERVER_THREE; + ESP_LOGI(TAG,"Server-2 fails to connect. Switching to Server-3"); + } + } + + /* Try with server-3 if & only if server-2 fails to connect */ + if(selected_server == SERVER_THREE) + { + sprintf(server_url, MCU_GET_CONFIG_FLAGS_URL3, device_imei); + http_client_get((const char*)server_url,response_buf); + if(retval != WIFI_OK) + { + selected_server = SERVER_ONE; + ESP_LOGI(TAG,"Server-3 fails to connect. Stopping WIFI-Client."); + retval = WIFI_FAIL; + } + } + + /* Parse the SP3 response */ + if(retval == ESP_OK) + data_parsing_config(response_buf, strlen(response_buf)); + else + break; + + /* IF MCU-Update flag is set then continue to the next case. if not then break */ + if(!g_McuUpdate) + { + break; + } + + case GET_MCU_UPDATE_VERSION: + + ESP_LOGI(TAG,"/******** MCU_Update -SP5- GET request ********/"); + + /* Try with server-1 */ + if(selected_server == SERVER_ONE) + { + sprintf(server_url, MCU_FW_VERSION_URL1, device_imei); + retval = http_client_get((const char*)server_url,response_buf); + if(retval != WIFI_OK) + { + selected_server = SERVER_TWO; + ESP_LOGI(TAG,"Server-1 fails to connect. Switching to Server-2"); + } + } + + /* Try with server-2 if & only if server-1 fails to connect */ + if(selected_server == SERVER_TWO) + { + sprintf(server_url, MCU_FW_VERSION_URL2, device_imei); + http_client_get((const char*)server_url,response_buf); + if(retval != WIFI_OK) + { + ESP_LOGI(TAG,"Server-2 fails to connect. Switching to Server-3"); + selected_server = SERVER_THREE; + } + } + + /* Try with server-3 if & only if server-2 fails to connect */ + if(selected_server == SERVER_THREE) + { + sprintf(server_url, MCU_FW_VERSION_URL3, device_imei); + http_client_get((const char*)server_url,response_buf); + if(retval != WIFI_OK) + { + selected_server = SERVER_ONE; + ESP_LOGI(TAG,"Server-3 fails to connect. Stopping WIFI-Client."); + retval = WIFI_FAIL; + } + } + + /* Parse the SP5 response */ + if(retval == ESP_OK) + wifi_Parse_SP5(response_buf, strlen(response_buf)); + + /* Enable WIFI-OTA if MCU-FW is less than the one in SP5 message */ + if(getBinFile) + { + wifi_ota_start_firmware_update(device_imei); + hmi_set_leds_state(BLUE_LED_FLASHING_OTA); + while(OTA_IN_PROGRESS == wifi_ota_get_status()) + { + vTaskDelay(100/portTICK_PERIOD_MS); + } + + /* LOG this error message */ + hmi_stop_ota_event(); + ESP_LOGE(TAG,"Error in WIFI-OTA process. continuing on the current firmware."); + retval = ESP_FAIL; + } + + break; + + case GET_MODEM_UPDATE_VERSION: + break; + + default: + } + + return retval; +} + +esp_err_t http_client_do_post_request(char *post_params, char *response_buf) +{ + uint8_t retval = WIFI_FAIL; + selected_server = SERVER_ONE; + + /* Try with server-1 */ + if(selected_server == SERVER_ONE) + { + /* Set the POST-URL to be Server1 */ + data_set_postToServer(TEMPSTICK_SERVER1); + + /* Create the Check-in message */ + data_create_checkin_string(post_params,2304); + + /* Printing the check-in string */ + ESP_LOGI(TAG,"%s",post_params); + + /* Post that Check-in message to the target server */ + retval = http_client_post((char*)MCU_POST_URL1,post_params,response_buf); + if(retval != WIFI_OK) + { + selected_server = SERVER_TWO; + ESP_LOGI(TAG,"Server-1 fails to connect. Switching to Server-2"); + } + } + + /* Try with server-2 if & only if server-1 fails to connect */ + if(selected_server == SERVER_TWO) + { + /* Set the POST-URL to be Server2 */ + data_set_postToServer(TEMPSTICK_SERVER2); + + /* Create the Check-in message */ + data_create_checkin_string(post_params,2304); + + /* Post that Check-in message to the target server */ + retval = http_client_post((char*)MCU_POST_URL2,post_params,response_buf); + if(retval != WIFI_OK) + { + ESP_LOGI(TAG,"Server-2 fails to connect. Switching to Server-3"); + selected_server = SERVER_THREE; + } + } + + /* Try with server-3 if & only if server-2 fails to connect */ + if(selected_server == SERVER_THREE) + { + /* Set the POST-URL to be Server3 */ + data_set_postToServer(TEMPSTICK_SERVER3); + + /* Create the Check-in message */ + data_create_checkin_string(post_params,2304); + + /* Post that Check-in message to the target server */ + retval = http_client_post((char*)MCU_POST_URL3,post_params,response_buf); + if(retval != WIFI_OK) + { + selected_server = SERVER_ONE; + ESP_LOGI(TAG,"Server-3 fails to connect. Stopping WIFI-Client."); + retval = WIFI_FAIL; + } + } + + return retval; +} + +void wifi_set_post_str_type(deviceToServer_msgType_t str) +{ + post_msg_type = str; +} + + +#endif + + diff --git a/main/wifi_Client.h b/main/wifi_Client.h new file mode 100644 index 0000000..c7027ce --- /dev/null +++ b/main/wifi_Client.h @@ -0,0 +1,50 @@ +/* + * tempstick_wifi_client.h + * + * Created on: Jul 28, 2023 + * Author: Sword + */ + +#ifndef MAIN_WIFI_CLIENT_H_ +#define MAIN_WIFI_CLIENT_H_ + +#define WIFI_OK 0 +#define WIFI_FAIL -1 +#define WIFI_MCU_UPDATE_NEEDED 2 + +#define WIFI_OK 0 +#define WIFI_FAIL -1 +#define WIFI_MCU_UPDATE_NEEDED 2 + +typedef enum +{ + GET_CONFIGURATIONS, + GET_MCU_UPDATE_VERSION, + GET_MODEM_UPDATE_VERSION +}get_req_type_t; + +typedef enum +{ + SERVER_ONE, + SERVER_TWO, + SERVER_THREE +}server_type_t; + +#include "wifi_Init.h" +#include "main.h" +#if (WIFI_NEEDED == 1) +esp_err_t http_client_test(char *url); +esp_err_t http_client_post(char *url, char *params, char *response); +void http_client_post_stop(void); +esp_err_t http_client_get(const char *url1, char *response); + +esp_err_t http_client_do_get_request(get_req_type_t target_url, char* device_imei, char *response_buf); +esp_err_t http_client_do_post_request(char *post_params, char *response_buf); +void wifi_set_post_str_type(deviceToServer_msgType_t str);; + +bool registerAcctWithServer(char *typeStr, char *customerAccountIdStr, char *customerAccountPasswordStr, char *customerAccountPasswordAgainStr, char *responseStr, uint16_t responseStrSize); +#endif + + + +#endif /* MAIN_WIFI_CLIENT_H_ */ diff --git a/main/wifi_Init.c b/main/wifi_Init.c new file mode 100644 index 0000000..62de11e --- /dev/null +++ b/main/wifi_Init.c @@ -0,0 +1,671 @@ +/* + * wifi_Init.c + * + * Created on: 1/8/2023 + * Author: Sword + */ + + + +#include "esp_system.h" +#include "esp_event.h" +#include "esp_netif.h" +#include "esp_wifi.h" +#include "esp_mac.h" +#include "lwip/ip4_addr.h" +#include "freertos/event_groups.h" +#include "wifi_Init.h" +#include "wifi_Client.h" +#include "string.h" +#include "main.h" +#include "nvm.h" +#include "data_processing.h" + +#if (WIFI_NEEDED == 1) +static const char* TAG = "WIFI"; + +#define LOG_LOCAL_LEVEL ESP_LOG_INFO +#include "esp_log.h" + +#define ESP_MAXIMUM_RETRY 5 +#define WIFI_CONNECTED_BIT BIT0 +#define WIFI_FAIL_BIT BIT1 +#define WIFI_SCAN_DONE_BIT BIT2 +#define WIFI_AP_CONNECTED_BIT BIT3 +#define WIFI_AP_DISCONNECTED_BIT BIT4 +#define WIFI_DISCONNECTED_BIT BIT5 + +#define WIFI_AP_SSID "Sensor Setup " + +static char g_pWifiSsidA[MAX_SSID_LEN]; +static char g_pWifiPasswordA[MAX_PASSPHRASE_LEN]; +static char g_pWifiSsidB[MAX_SSID_LEN]; +static char g_pWifiPasswordB[MAX_PASSPHRASE_LEN]; + +/* WIFI connection TIME */ +uint32_t g_wifiStartTime; +extern uint32_t g_wifiConnectTime; + +/* WIFI SSID's & PASSWORDS */ +static char Sta_Ssid[MAX_SSID_LEN]; +static char Sta_Pwd[MAX_PASSPHRASE_LEN] = {0}; + +RTC_DATA_ATTR uint32_t wifiSelection; +wifi_ap_record_t scanned_networks[20]; +uint8_t device_wifi_onboarded; + +/* WIFI RSSI & STATUS */ +static uint8_t isStaConnected; +static bool isStarted; +static bool isInitialized; +static bool isHandlerRegister; + +/* FreeRTOS event group to signal when we are connected*/ +static EventGroupHandle_t s_wifi_event_group; +static bool set_wifi_bits; +static int s_retry_num = 0; +static bool turnOffStation; + +/* This structure holds the WIFI configurations (modes, ip's, ssid&pwd ...etc )*/ +esp_netif_t *sta_netif; +esp_netif_t *ap_netif; +wifi_config_t wifi_config; +esp_netif_ip_info_t wifi_sta_ip_infos; + + +/* This is the handler that will be executed when receiving any WIFI-events or IP-events */ +static void event_handler(void *arg, esp_event_base_t event_base, + int32_t event_id, void *event_data) +{ + if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) + { + /* This Log will be printed as a result of esp_wifi_start (when the wifi mode is STA or AP&STA )*/ + ESP_LOGI(TAG, " -----> Station(Client) mode Start"); + } + else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_AP_START) + { + /* This Log will be printed as a result of esp_wifi_start (when the wifi mode is AP or AP&STA )*/ + ESP_LOGI(TAG, " -----> ACCESS-POINT Start"); + } + else if(event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_CONNECTED) + { + /* This Log will be printed as a result of esp_wifi_connect (when the wifi mode is STA or AP&STA ) + * Indicates successful connection to the wifi-network or to the access point */ + ESP_LOGI(TAG, " -----> Station(client) Connected to the registered AP"); + } + else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) + { + if(turnOffStation) + { + if(set_wifi_bits) + { + xEventGroupSetBits(s_wifi_event_group, WIFI_DISCONNECTED_BIT); + } + ESP_LOGI(TAG, " ---> Disconnecting wifi-station successfully"); + } + else + { + isStaConnected = 0; + if (s_retry_num < ESP_MAXIMUM_RETRY) + { + esp_wifi_connect(); + s_retry_num++; + ESP_LOGI(TAG, " ---> Retry to connect to the AP !!!"); + } + else + { + if(set_wifi_bits) + { + xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT); + } + } + ESP_LOGI(TAG, " ---> Connecting to the registered AP failed !!!"); + } + } + else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) + { + ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data; + ESP_LOGI(TAG, "------> The Device got the ip-address:" IPSTR, IP2STR(&event->ip_info.ip)); + s_retry_num = 0; + if(set_wifi_bits) + { + xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT); + } + + /* 1- Take and store the ip-address infos */ + data_set_local_ip_addr(&event->ip_info); + } + else if(event_base == WIFI_EVENT && event_id == WIFI_EVENT_SCAN_DONE) + { + if(set_wifi_bits) + { + xEventGroupSetBits(s_wifi_event_group, WIFI_SCAN_DONE_BIT); + } + } + else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_AP_STACONNECTED) + { + wifi_event_ap_staconnected_t* event = (wifi_event_ap_staconnected_t*) event_data; + ESP_LOGI(TAG, "station "MACSTR" join, AID=%d", MAC2STR(event->mac), event->aid); + if(set_wifi_bits) + { + xEventGroupSetBits(s_wifi_event_group, WIFI_AP_CONNECTED_BIT); + } + } + else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_AP_STADISCONNECTED) + { + wifi_event_ap_stadisconnected_t* event = (wifi_event_ap_stadisconnected_t*) event_data; + ESP_LOGI(TAG, "station "MACSTR" leave, AID=%d", MAC2STR(event->mac), event->aid); + if(set_wifi_bits) + { + xEventGroupSetBits(s_wifi_event_group, WIFI_AP_DISCONNECTED_BIT); + } + } +} + + +/* Functions for Starting WIFI as Client, Server and Scan nearby networks */ +esp_err_t Connect_wifi_sta(uint8_t mode) +{ + /* Create the return variable */ + esp_err_t retval = ESP_FAIL; + + time_t timeNow; + time(&timeNow); + uint32_t temp_time=0; + + g_wifiStartTime = (uint32_t)timeNow; + + /* Check if the esp-32 was connected to network before. If so then disconnect it and reconnect again after 3sec */ + if(isStaConnected) + { + wifi_sta_disconnecting(); + vTaskDelay(3000/portTICK_PERIOD_MS); + } + + /* Create a WIFI-event group and create its corresponding bits */ + s_wifi_event_group = xEventGroupCreate(); + set_wifi_bits = true; + EventBits_t bits; + + /* Set the wifi_disconnecting flag to be false */ + turnOffStation = false; + + // 2 - Wi-Fi Configuration Phase + + /* Assign a handler that will be executed when receiving any WIFI-events */ + //esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, event_handler, NULL); + + /* Update the SSID and Password that ESP32 will use them to connect to the network when acting acting as WIFI-STATION */ + /*if(wifiSelection) + { + strcpy((char *)wifi_config.sta.ssid, g_pWifiSsidB); + strcpy((char *)wifi_config.sta.password, g_pWifiPasswordB); + } + else*/ + { +#ifdef STORING_TO_NVM + //device_wifi_onboarded = nvm_read_onboarding_flag(WIFI_ONBOARDING_KEY); + if(device_wifi_onboarded) + { + /* Connecting to the network that has been registered since the last onboarding process + * This if-block will be executed when doing the CHECK-IN process */ + nvm_read_wifi_credentials(Sta_Ssid,Sta_Pwd); + } +#endif + + /* Copying the network credentials to the wifi_config structure so that the esp-client can connect to */ + strcpy((char *)wifi_config.sta.ssid, Sta_Ssid); + strcpy((char *)wifi_config.sta.password, Sta_Pwd); + + } + + /* Make sure that there's a valid entered SSID to connect to */ + if((Sta_Ssid[0] == 0)) + { + //ESP_LOGE(TAG,"----> There's no valid SSID to connect to"); + return ESP_FAIL; + } + + /* Set the WIFI-mode & WIFI-configs then start and connect to the WIFI network */ + ESP_LOGI(TAG," Initializing and starting WIFI-Client "); + ESP_ERROR_CHECK(esp_wifi_set_mode(mode)); + wifi_config.sta.threshold.authmode = WIFI_AUTH_WPA2_PSK; + ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config)); + if(!isStarted) + ESP_ERROR_CHECK(esp_wifi_start()); + + /**/ + ESP_ERROR_CHECK(esp_wifi_connect()); + + //ESP_LOGI(TAG, "wifi_init_sta finished."); + ESP_LOGI(TAG, "WIFI STA connection Start..."); + + /* block to wait for one or more bits to be set within a previously created event group (s_wifi_event_group) */ + bits = xEventGroupWaitBits(s_wifi_event_group, WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, pdFALSE, pdFALSE, portMAX_DELAY); + + /* xEventGroupWaitBits() returns the bits before the call returned, hence we can test which event actually + * happened. */ + if (bits & WIFI_CONNECTED_BIT) + { + /* Set the WIFI connect Time */ + time(&timeNow); + temp_time = (timeNow - g_wifiStartTime); + g_wifiConnectTime = (uint8_t)((temp_time > 255)? 255 : temp_time); + + /* Get the RSSI value of WIFI */ + /*int wifi_rssi; + esp_wifi_sta_get_rssi((int*)&wifi_rssi);*/ + wifi_ap_record_t ap_info; + esp_wifi_sta_get_ap_info(&ap_info); + data_set_wifi_rssi(ap_info.rssi); + ESP_LOGI(TAG, "Connected to AP SSID:%s password:%s", Sta_Ssid, Sta_Pwd); + + /* 2- Take and store the dns-server info */ + esp_netif_dns_info_t dns1, dns2; + esp_netif_get_dns_info(sta_netif,ESP_NETIF_DNS_MAIN,&dns1); + esp_netif_get_dns_info(sta_netif,ESP_NETIF_DNS_BACKUP,&dns2); + data_set_main_and_backup_dns(&dns1,&dns2); + + /* 3- Take and store the mac-address of connected AP */ + data_set_ap_mac_addr((uint8_t*)&wifi_config.sta.bssid); + + /* 4- Take and store the wifi-channel */ + data_set_wifi_channel(wifi_config.sta.channel); + + /* Set the connection flag */ + isStaConnected = 1; + + /* set the return value to be ESP_OK */ + retval = ESP_OK; + } + else if (bits & WIFI_FAIL_BIT) + { + ESP_LOGI(TAG, "Failed to connect to SSID:%s, password:%s", Sta_Ssid, Sta_Pwd); + isStaConnected = 0; + + /* set the return value to be ESP_FAIL */ + retval = ESP_FAIL; + } + else + { + ESP_LOGE(TAG, "UNEXPECTED EVENT"); + } + + /* Delete the created event group after receiving the required bits or "UNEXPECTED EVENT" */ + vEventGroupDelete(s_wifi_event_group); + set_wifi_bits = false; + + /* return this value */ + return retval; +} + +void Wifi_Init_SoftAp(void) +{ + char ap_ssid[32]; + char mac_str[15]; + uint8_t mac_base[6] = {0}; + + /* Check if the onboarded-flag is false (Don't start AP unless the device hasn't been on-boarded) */ + //if(!device_wifi_onboarded) + { + /* Read the device mac-address */ + esp_efuse_mac_get_default(mac_base); + esp_read_mac(mac_base, ESP_MAC_WIFI_SOFTAP); + + /* Set the SSID-name of the esp32-AP (Sensor Setup -deviceID-) */ + strcpy(ap_ssid, WIFI_AP_SSID); + sprintf(mac_str, "%02X%02X%02X", mac_base[3], mac_base[4], mac_base[5]); + strcat(ap_ssid, mac_str); + ESP_LOGI(TAG, "AP SSID: %s", ap_ssid); + + /* Start event group to read the connection bits */ + s_wifi_event_group = xEventGroupCreate(); + set_wifi_bits = true; + + /* Set the configurations for the esp-32 AP */ + wifi_config.ap.max_connection = 4; + wifi_config.ap.authmode = WIFI_AUTH_OPEN; + strcpy((char *)wifi_config.sta.ssid, ""); + strcpy((char *)wifi_config.sta.password, ""); + wifi_config.sta.threshold.authmode = WIFI_AUTH_WPA2_PSK; + + /* Set the SSID and PASSWORD of the esp-32 AP */ + strcpy((char *)wifi_config.ap.ssid, ap_ssid); + wifi_config.ap.ssid_len = strlen(ap_ssid); + + /* Set the WIFI-mode to be AP&STA */ + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_APSTA)); + ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &wifi_config)); + ESP_ERROR_CHECK(esp_wifi_start()); + isStarted = true; + + ESP_LOGI(TAG, "Access-Point Initialization finished."); + + /* Waiting until either the connection is established (WIFI_CONNECTED_BIT) or connection failed for the maximum + * number of re-tries (WIFI_FAIL_BIT). The bits are set by event_handler() (see above) */ + EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group, WIFI_AP_CONNECTED_BIT, pdFALSE, pdFALSE, portMAX_DELAY); + + /* xEventGroupWaitBits() returns the bits before the call returned, hence we can test which event actually + * happened. */ + if (bits & WIFI_AP_CONNECTED_BIT) + { + ESP_LOGI(TAG, "AP Connected"); + } + else if (bits & WIFI_FAIL_BIT) + { + ESP_LOGI(TAG, "AP failed to connect"); + } + else + { + ESP_LOGE(TAG, "UNEXPECTED EVENT"); + } + + vEventGroupDelete(s_wifi_event_group); + set_wifi_bits = false; + } +} + +void wifi_scan_start(uint16_t *apCount, wifi_ap_record_t **list) +{ + s_wifi_event_group = xEventGroupCreate(); + set_wifi_bits = true; + + wifi_scan_config_t scan_config = { + .ssid = NULL, + .bssid = NULL, + .channel = 0, + .show_hidden = true, + .scan_type = WIFI_SCAN_TYPE_ACTIVE, + .scan_time.active.min = 10, + .scan_time.active.max = 10000 + }; + ESP_LOGI(TAG, "Start Scan"); + + esp_wifi_scan_start(&scan_config, true); + EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group, WIFI_SCAN_DONE_BIT, pdFALSE, pdFALSE, 5000 / portTICK_PERIOD_MS); + esp_wifi_scan_stop(); + ESP_LOGI(TAG, "Stop Scan"); + + vTaskDelay(100/portTICK_PERIOD_MS); + + if (bits & WIFI_SCAN_DONE_BIT) + { + esp_wifi_scan_get_ap_num(apCount); + + if(apCount) + { + //*list = (wifi_ap_record_t *)pvPortMalloc(sizeof(wifi_ap_record_t) * (*apCount)); + *list = scanned_networks; + if((*apCount)<20) + ESP_ERROR_CHECK((esp_wifi_scan_get_ap_records(apCount, *list))); + else + { + *apCount = 20; + ESP_ERROR_CHECK((esp_wifi_scan_get_ap_records(apCount, *list))); + } + } + } + + vEventGroupDelete(s_wifi_event_group); + set_wifi_bits = false; +} + + + +/* Update the wifi credentials (SSID&PWD) of the target network */ +void wifi_update_credentials(char *ssid, char *pwd) +{ + /* Update the SSID and password that the ESP will use when acting as wifi-client (station) */ + strcpy(Sta_Ssid, ssid); + strcpy(Sta_Pwd, pwd); +} + +uint8_t wifi_station_connected(void) +{ + return isStaConnected; +} + +bool wifi_isStarted(void) +{ + return isStarted; +} + +char *wifi_get_ssid(void) +{ + return Sta_Ssid; +} + +char *wifi_get_pswd(void) +{ + return Sta_Pwd; +} + +void wifi_switchToPrimaryNetwork(void) +{ + if(0 != wifiSelection) + { + wifiSelection = 0; // Primary WiFi + data_clearWifiConnectionSettings(); + } +} // End of switchToPrimaryWifiNetwork() + + + +/* Functions to Set/get WIFI-credentials of networkA */ +char *wifi_get_ssidA(void) +{ + return g_pWifiSsidA; +} + +char *wifi_get_pswdA(void) +{ + return g_pWifiPasswordA; +} + +void wifi_set_ssidA(char* ssid) +{ + strcpy(g_pWifiSsidA,ssid); +} + +void wifi_set_pswdA(char* pswd) +{ + strcpy(g_pWifiPasswordA,pswd); +} + + + +/* Functions to Set/get WIFI-credentials of networkA */ +char *wifi_get_ssidB(void) +{ + return g_pWifiSsidB; +} + +char *wifi_get_pswdB(void) +{ + return g_pWifiPasswordB; +} + +void wifi_set_ssidB(char* ssid) +{ + strcpy(g_pWifiSsidB,ssid); +} + +void wifi_set_pswdB(char* pswd) +{ + strcpy(g_pWifiPasswordB,pswd); +} + + + +/* WIFI functions for Initialization and De-initialization */ +esp_err_t wifi_first_init(void) +{ + /* Create the return variable */ + esp_err_t retval = ESP_FAIL; + + if(isInitialized) + { + return ESP_OK; + } + + /* Initialize the underlying TCP/IP stack */ + retval = esp_netif_init(); + + /* Create default event loop */ + retval = esp_event_loop_create_default(); + + /* Do the required initialization for setting the device -esp32- to act as WiFi-station and WIFI-AP */ + sta_netif = esp_netif_create_default_wifi_sta(); + + // if(!device_wifi_onboarded) + { + esp_netif_t *ap_netif = esp_netif_create_default_wifi_ap(); + /* Stop the DHCP server to change the IP address of AP-gateway */ + retval = esp_netif_dhcps_stop(ap_netif); + + /* Create the structure of the new IP-address of the AP */ + esp_netif_ip_info_t ip_info; + + /* Set the IP-address to [10.10.1.1] and the same thing for gateway and subnet-mask is [255.255.255.0] */ + IP4_ADDR(&ip_info.ip, 10, 10, 1, 1); + IP4_ADDR(&ip_info.gw, 10, 10, 1, 1); + IP4_ADDR(&ip_info.netmask, 255, 255, 255, 0); + + /* Update the IP-address info with the new ones */ + retval = esp_netif_set_ip_info(ap_netif, &ip_info); + ESP_LOGI(TAG, "esp_netif_set_ip_info(): 0x%X", retval); + + /* Restart the DHCP server again */ + retval = esp_netif_dhcps_start(ap_netif); + } + + /* Load the default init_configurations */ + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + retval = esp_wifi_init(&cfg); + + /* Set the initialization flag */ + isInitialized = true; + + /* Initialize and register the wifi and ip event-handler */ + wifi_register_event_handlers(); + + /* return the result */ + return retval; +} + +/* function for registering the handler for the received wifi or ip events (called once at the beginning of the program)*/ +void wifi_register_event_handlers(void) +{ + if(!isHandlerRegister) + { + /* 1- Assign the handler for receiving any wifi-event */ + ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL)); + + /* 2- Assign a handler that will be executed when receiving the STA_GOT_IP event (when the ESP32 receive an IP from the DHCP of the router or the Access-Point) */ + esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, event_handler, NULL); + + isHandlerRegister = true; + } +} + +esp_err_t wifi_stop(void) +{ + /* Create the return variable */ + esp_err_t retval = ESP_FAIL; + + /* Create a WIFI-event group and create its corresponding bits */ + s_wifi_event_group = xEventGroupCreate(); + set_wifi_bits = true; + EventBits_t bits; + + //esp_wifi_restore(); + //esp_wifi_deinit(); + esp_wifi_stop(); + + /* block to wait for one or more bits to be set within a previously created event group (s_wifi_event_group) */ + bits = xEventGroupWaitBits(s_wifi_event_group, WIFI_AP_DISCONNECTED_BIT | WIFI_FAIL_BIT, pdFALSE, pdFALSE, portMAX_DELAY); + + /* xEventGroupWaitBits() returns the bits before the call returned, hence we can test which event actually + * happened. */ + if (bits & WIFI_AP_DISCONNECTED_BIT) + { + ESP_LOGI(TAG, "WIFI has been Stopped"); + retval = ESP_OK; + } + else + { + ESP_LOGE(TAG, "Failed to Stop WIFI. UNEXPECTED EVENT"); + retval = ESP_FAIL; + } + + /* Delete the created event group after receiving the required bits or "UNEXPECTED EVENT" */ + vEventGroupDelete(s_wifi_event_group); + set_wifi_bits = false; + + //ESP_ERROR_CHECK(esp_event_handler_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler)); + isStaConnected = 0; + isStarted = false; + ap_netif = NULL; + //isInitialized = false; + + /* return the result */ + return retval; + +} + +void wifi_sta_disconnecting(void) +{ + EventBits_t bits; + + if(isStaConnected) + { + /* Create a WIFI-event group and create its corresponding bits */ + s_wifi_event_group = xEventGroupCreate(); + set_wifi_bits = true; + + /* Set the station turn-off flag to be true */ + turnOffStation = true; + + /* Disconnect the WIFI-Station */ + ESP_ERROR_CHECK(esp_wifi_disconnect()); + + /* block to wait for one or more bits to be set within a previously created event group (s_wifi_event_group) */ + bits = xEventGroupWaitBits(s_wifi_event_group, WIFI_DISCONNECTED_BIT | WIFI_FAIL_BIT, pdFALSE, pdFALSE, portMAX_DELAY); + + /* xEventGroupWaitBits() returns the bits before the call returned, hence we can test which event actually + * happened. */ + if (bits & WIFI_DISCONNECTED_BIT) + { + ESP_LOGI(TAG, "WIFI has been disconnected"); + //ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP,&event_handler)); + //isHandlerRegister = false; + isStaConnected = 0; + } + else + { + ESP_LOGE(TAG, "Failed to disconnect WIFI-Station. UNEXPECTED EVENT"); + } + + /* Delete the created event group after receiving the required bits or "UNEXPECTED EVENT" */ + vEventGroupDelete(s_wifi_event_group); + set_wifi_bits = false; + } +} + + + +bool safeStrCat(char *dest, uint16_t destSize, char *source) +{ + + if(strlen(source) > (destSize - 1 - strlen(dest))) + return(false); + + strcat(dest, source); + return(true); +} // End of safeStrCat + + +#endif + + + diff --git a/main/wifi_Init.h b/main/wifi_Init.h new file mode 100644 index 0000000..b723161 --- /dev/null +++ b/main/wifi_Init.h @@ -0,0 +1,64 @@ +/* + * tempstick_wifi.h + * + * Created on: Jul 28, 2023 + * Author: Sword + */ + +#ifndef MAIN_WIFI_INIT_H_ +#define MAIN_WIFI_INIT_H_ + +#include "main.h" +#if (WIFI_NEEDED == 1) +#include "esp_wifi.h" + +typedef enum +{ + CHECK_IN_STR, + ON_BOARDING_STR +}deviceToServer_msgType_t; + + +#define STORING_TO_NVM + + +#define WIFI_CLIENT_MODE 1 +#define WIFI_AP_MODE 2 +#define WIFI_CLIENT_AP_MODE 3 + + +esp_err_t Connect_wifi_sta(uint8_t mode); +uint8_t wifi_station_connected(void); +bool wifi_isStarted(void); +void Wifi_Init_SoftAp(void); + +esp_err_t wifi_first_init(void); +esp_err_t wifi_stop(void); +void wifi_register_event_handlers(void); +void wifi_sta_disconnecting(void); +void wifi_scan_start(uint16_t *apCount, wifi_ap_record_t **list); + + +void wifi_update_credentials(char *ssid, char *pwd); +char *wifi_get_ssid(void); +char *wifi_get_pswd(void); +void wifi_switchToPrimaryNetwork(void); + + +char *wifi_get_ssidA(void); +char *wifi_get_pswdA(void); +void wifi_set_ssidA(char* ssid); +void wifi_set_pswdA(char* pswd); + +char *wifi_get_ssidB(void); +char *wifi_get_pswdB(void); +void wifi_set_ssidB(char* ssid); +void wifi_set_pswdB(char* pswd); + +bool safeStrCat(char *dest, uint16_t destSize, char *source); + +#endif + + + +#endif /* MAIN_WIFI_INIT_H_ */ diff --git a/main/wifi_OTA.c b/main/wifi_OTA.c new file mode 100644 index 0000000..f9e1e64 --- /dev/null +++ b/main/wifi_OTA.c @@ -0,0 +1,283 @@ +/* OTA example + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "esp_system.h" +#include "esp_event.h" +#include "esp_log.h" +#include "esp_ota_ops.h" +#include "esp_crt_bundle.h" +#include "esp_app_format.h" +#include "esp_http_client.h" +#include "esp_flash_partitions.h" +#include "esp_partition.h" +#include "errno.h" +#include "main.h" +#include "comms.h" +#include "wifi_OTA.h" + +#define BUFFSIZE 1024 +#define HASH_LEN 32 /* SHA-256 digest length */ + +static const char *TAG = "WIFI_OTA"; +/*an ota data write buffer ready to write to the flash*/ +static char ota_write_data[BUFFSIZE + 1] = { 0 }; + +#define OTA_URL_SIZE 256 + +char ota_url[OTA_URL_SIZE]; +wifi_ota_status_t ota_process_state; + +static void http_cleanup(esp_http_client_handle_t client) +{ + esp_http_client_close(client); + esp_http_client_cleanup(client); +} + +static void task_fatal_error(void) +{ + ESP_LOGE(TAG, "Exiting task due to fatal error during ota process..."); + (void)vTaskDelete(NULL); + ota_process_state = OTA_FATAL_ERROR; +} + +static void print_sha256 (const uint8_t *image_hash, const char *label) +{ + char hash_print[HASH_LEN * 2 + 1]; + hash_print[HASH_LEN * 2] = 0; + for (int i = 0; i < HASH_LEN; ++i) { + sprintf(&hash_print[i * 2], "%02x", image_hash[i]); + } + ESP_LOGI(TAG, "%s: %s", label, hash_print); +} + +static void infinite_loop(void) +{ + int i = 0; + ESP_LOGI(TAG, "The firmware that is available on the server is an OLD image\n WIFI-OTA stopped."); + ota_process_state = OTA_FATAL_ERROR; +} + +static void wifi_ota_task(void *pvParameter) +{ + esp_err_t err; + /* update handle : set by esp_ota_begin(), must be freed via esp_ota_end() */ + esp_ota_handle_t update_handle = 0 ; + const esp_partition_t *update_partition = NULL; + + ESP_LOGI(TAG, "Starting WIFI Firmware Update Process"); + + const esp_partition_t *configured = esp_ota_get_boot_partition(); + const esp_partition_t *running = esp_ota_get_running_partition(); + + if (configured != running) { + ESP_LOGW(TAG, "Configured OTA boot partition at offset 0x%08"PRIx32", but running from offset 0x%08"PRIx32,configured->address, running->address); + ESP_LOGW(TAG, "(This can happen if either the OTA boot data or preferred boot image become corrupted somehow.)"); + } + ESP_LOGI(TAG, "Running partition type %d subtype %d (offset 0x%08"PRIx32")",running->type, running->subtype, running->address); + + esp_http_client_config_t config = { + .url = ota_url, + .crt_bundle_attach = esp_crt_bundle_attach, + .timeout_ms = 5000, + .keep_alive_enable = true, + }; + + esp_http_client_handle_t client = esp_http_client_init(&config); + if (client == NULL) { + ESP_LOGE(TAG, "Failed to initialise HTTP connection"); + task_fatal_error(); + } + else + { + ESP_LOGI(TAG,"URL is : %s",config.url); + } + + err = esp_http_client_open(client, 0); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to open HTTP connection: %s", esp_err_to_name(err)); + esp_http_client_cleanup(client); + task_fatal_error(); + } + esp_http_client_fetch_headers(client); + + update_partition = esp_ota_get_next_update_partition(NULL); + assert(update_partition != NULL); + ESP_LOGI(TAG, "Writing to partition subtype %d at offset 0x%"PRIx32,update_partition->subtype, update_partition->address); + + int binary_file_length = 0; + /*deal with all receive packet*/ + bool image_header_was_checked = false; + while (1) { + int data_read = esp_http_client_read(client, ota_write_data, BUFFSIZE); + if (data_read < 0) { + ESP_LOGE(TAG, "Error: SSL data read error"); + http_cleanup(client); + task_fatal_error(); + } else if (data_read > 0) { + if (image_header_was_checked == false) { + esp_app_desc_t new_app_info; + if (data_read > sizeof(esp_image_header_t) + sizeof(esp_image_segment_header_t) + sizeof(esp_app_desc_t)) { + // check current version with downloading + memcpy(&new_app_info, &ota_write_data[sizeof(esp_image_header_t) + sizeof(esp_image_segment_header_t)], sizeof(esp_app_desc_t)); + ESP_LOGI(TAG, "New firmware version: %s", new_app_info.version); + + esp_app_desc_t running_app_info; + if (esp_ota_get_partition_description(running, &running_app_info) == ESP_OK) { + ESP_LOGI(TAG, "Running firmware version: %s", running_app_info.version); + } + + const esp_partition_t* last_invalid_app = esp_ota_get_last_invalid_partition(); + esp_app_desc_t invalid_app_info; + if (esp_ota_get_partition_description(last_invalid_app, &invalid_app_info) == ESP_OK) { + ESP_LOGI(TAG, "Last invalid firmware version: %s", invalid_app_info.version); + } + + // check current version with last invalid partition + if (last_invalid_app != NULL) { + if (memcmp(invalid_app_info.version, new_app_info.version, sizeof(new_app_info.version)) == 0) { + ESP_LOGW(TAG, "New version is the same as invalid version."); + ESP_LOGW(TAG, "Previously, there was an attempt to launch the firmware with %s version, but it failed.", invalid_app_info.version); + ESP_LOGW(TAG, "The firmware has been rolled back to the previous version."); + http_cleanup(client); + infinite_loop(); + } + } +#ifndef CONFIG_EXAMPLE_SKIP_VERSION_CHECK + if (memcmp(new_app_info.version, running_app_info.version, sizeof(new_app_info.version)) == 0) { + ESP_LOGW(TAG, "Current running version is the same as a new. We will not continue the update."); + http_cleanup(client); + infinite_loop(); + } +#endif + + image_header_was_checked = true; + + err = esp_ota_begin(update_partition, OTA_WITH_SEQUENTIAL_WRITES, &update_handle); + if (err != ESP_OK) { + ESP_LOGE(TAG, "esp_ota_begin failed (%s)", esp_err_to_name(err)); + http_cleanup(client); + esp_ota_abort(update_handle); + task_fatal_error(); + } + ESP_LOGI(TAG, "esp_ota_begin succeeded"); + } else { + ESP_LOGE(TAG, "received package is not fit len"); + http_cleanup(client); + esp_ota_abort(update_handle); + task_fatal_error(); + } + } + err = esp_ota_write( update_handle, (const void *)ota_write_data, data_read); + if (err != ESP_OK) { + http_cleanup(client); + esp_ota_abort(update_handle); + task_fatal_error(); + } + binary_file_length += data_read; + ESP_LOGI(TAG, "Written image length %d", binary_file_length); + } else if (data_read == 0) { + /* + * As esp_http_client_read never returns negative error code, we rely on + * `errno` to check for underlying transport connectivity closure if any + */ + if (errno == ECONNRESET || errno == ENOTCONN) { + ESP_LOGE(TAG, "Connection closed, errno = %d", errno); + break; + } + if (esp_http_client_is_complete_data_received(client) == true) { + ESP_LOGI(TAG, "Connection closed"); + break; + } + } + } + ESP_LOGI(TAG, "Total Write binary data length: %d", binary_file_length); + if (esp_http_client_is_complete_data_received(client) != true) { + ESP_LOGE(TAG, "Error in receiving complete file"); + http_cleanup(client); + esp_ota_abort(update_handle); + task_fatal_error(); + } + + err = esp_ota_end(update_handle); + if (err != ESP_OK) { + if (err == ESP_ERR_OTA_VALIDATE_FAILED) { + ESP_LOGE(TAG, "Image validation failed, image is corrupted"); + } else { + ESP_LOGE(TAG, "esp_ota_end failed (%s)!", esp_err_to_name(err)); + } + http_cleanup(client); + task_fatal_error(); + } + + err = esp_ota_set_boot_partition(update_partition); + if (err != ESP_OK) { + ESP_LOGE(TAG, "esp_ota_set_boot_partition failed (%s)!", esp_err_to_name(err)); + http_cleanup(client); + task_fatal_error(); + } + ESP_LOGI(TAG, "Prepare to restart system!"); + esp_restart(); + return ; +} + +wifi_ota_status_t wifi_ota_get_status(void) +{ + return ota_process_state; +} + +void wifi_ota_start_firmware_update(char* device_imei) +{ + ESP_LOGI(TAG, "/****************** WIFI-OTA ********************/"); + + sprintf(ota_url,MCU_FW_BIN_FILE_URL1,device_imei); + + ota_process_state = OTA_IN_PROGRESS; + + uint8_t sha_256[HASH_LEN] = { 0 }; + esp_partition_t partition; + + // get sha256 digest for the partition table + partition.address = ESP_PARTITION_TABLE_OFFSET; + partition.size = ESP_PARTITION_TABLE_MAX_LEN; + partition.type = ESP_PARTITION_TYPE_DATA; + esp_partition_get_sha256(&partition, sha_256); + print_sha256(sha_256, "SHA-256 for the partition table: "); + + // get sha256 digest for bootloader + partition.address = ESP_BOOTLOADER_OFFSET; + partition.size = ESP_PARTITION_TABLE_OFFSET; + partition.type = ESP_PARTITION_TYPE_APP; + esp_partition_get_sha256(&partition, sha_256); + print_sha256(sha_256, "SHA-256 for bootloader: "); + + // get sha256 digest for running partition + esp_partition_get_sha256(esp_ota_get_running_partition(), sha_256); + print_sha256(sha_256, "SHA-256 for current firmware: "); + + const esp_partition_t *running = esp_ota_get_running_partition(); + esp_ota_img_states_t ota_state; + if (esp_ota_get_state_partition(running, &ota_state) == ESP_OK) { + if (ota_state == ESP_OTA_IMG_PENDING_VERIFY) { + // run diagnostic function ... + bool diagnostic_is_ok = true; + if (diagnostic_is_ok) { + ESP_LOGI(TAG, "Diagnostics completed successfully! Continuing execution ..."); + esp_ota_mark_app_valid_cancel_rollback(); + } else { + ESP_LOGE(TAG, "Diagnostics failed! Start rollback to the previous version ..."); + esp_ota_mark_app_invalid_rollback_and_reboot(); + } + } + } + + xTaskCreate(&wifi_ota_task, "wifi_ota_task", 4096, NULL, 5, NULL); +} diff --git a/main/wifi_OTA.h b/main/wifi_OTA.h new file mode 100644 index 0000000..9c6263a --- /dev/null +++ b/main/wifi_OTA.h @@ -0,0 +1,22 @@ +/* + * wifi_OTA.h + * + * Created on: Jul 31, 2023 + * Author: Sword + */ + +#ifndef WIFI_OTA_H_ +#define WIFI_OTA_H_ + +typedef enum +{ + OTA_IS_STOPPED, + OTA_IN_PROGRESS, + OTA_FATAL_ERROR, + OTA_COMPLETED +}wifi_ota_status_t; + +void wifi_ota_start_firmware_update(char* device_imei); +wifi_ota_status_t wifi_ota_get_status(void); + +#endif /* WIFI_OTA_H_ */ diff --git a/main/wifi_webServer.c b/main/wifi_webServer.c new file mode 100644 index 0000000..68b6fb4 --- /dev/null +++ b/main/wifi_webServer.c @@ -0,0 +1,1645 @@ +/* + * tempstick_wifi_server.c + * + * Created on: Jul 28, 2023 + * Author: Sword + */ + +#include "esp_system.h" +#include "sdkconfig.h" +#include "esp_wifi.h" +#include "esp_netif.h" +#include "esp_event.h" +#include "freertos/event_groups.h" +#include "lwip/sockets.h" +#include "lwip/dns.h" +#include "lwip/netdb.h" +#include "esp_tls_crypto.h" +#include "esp_mac.h" +#include "wifi_Client.h" +#include "wifi_WebServer.h" +#include "wifi_Init.h" +#include "comms.h" +#include "data_processing.h" +#include "hmi.h" +#include "nvm.h" +#include "modem.h" +#include "i2c_sensors.h" +#include "mbedtls/base64.h" + +#include +#include + +#include "lwip/tcp.h" +#include "lwip/udp.h" + +#if (WIFI_NEEDED == 1) +static const char* TAG = "SERVER"; + +#define LOG_LOCAL_LEVEL ESP_LOG_INFO +#include "esp_log.h" + +//#define BOARD_TEST + +#define SSID_MAX_LENGTH 32 // Max length corrected to 32 bytes in board version 3.1.1 in ESP8266WiFiSTA.cpp file +#define PASSWORD_MAX_LENGTH 64 // Set by the ESP32 + + +typedef enum +{ WLAN_NOT_TESTING, + WLAN_WIFI_CONNECTING, + WLAN_WIFI_WAITING_TO_CONNECT, + WLAN_WIFI_CONNECTED, + WLAN_TEST_SUCCESS, + WLAN_CONNECT_TO_SERVER_2, + WLAN_SERVER_1_WAITING_TO_CONNECT, + WLAN_SERVER_2_WAITING_TO_CONNECT +}wlanTesting_t; + +typedef enum +{ WLAN_NO_ERROR, + WLAN_SSID_TOO_LONG, + WLAN_PASSWORD_TOO_LONG, + WLAN_FAILED_WIFI, + WLAN_FAILED_INTERNET, + WLAN_SSID_EMPTY +}wlanError_t; + +typedef enum +{ WLAN_IDLE, + WLAN_WORKING, + WLAN_ERROR, + WLAN_DONE, + WLAN_TRY_WIFI, + WLAN_TRY_INTERNET +}wlanStatus_t; + + +extern uint32_t g_version; + +uint8_t g_onboarding_status = 99; +bool g_onboardingCompleted = false; +bool g_wlanOnboardingDone = false; +bool g_pageServed = false; + +uint32_t g_onboardingStepStartTime; // Used for on-boarding time-out. +uint32_t g_onboardingStepTimeout; // Used for on-boarding time-out. + +/*char g_wlanPasswordStr[PASSWORD_MAX_LENGTH + 1] = {0}; +char g_wlanSsidStr[SSID_MAX_LENGTH + 1] = {0};*/ +char g_wlanTargetSsid = 0; + +wlanError_t g_wlanError = WLAN_NO_ERROR; +wlanStatus_t g_wlanStatus = WLAN_IDLE; +wlanTesting_t g_wlanTesting = WLAN_NOT_TESTING; +wlanTesting_t g_wlanTestingPreviousState = WLAN_NOT_TESTING; + +bool g_servedRoot; +bool g_servedSid; +bool g_servedStatus; + +static httpd_handle_t serverHandle; +static bool acc_registered; + +extern uint8_t device_wifi_onboarded; + +/* Function to filter multipart form data */ +//////////////////////////////////////////////////////////// + +// Function to extract the value between two boundaries +void extract_field_value(const char *start, const char *end, char *result, int max_length) { + int length = end - start; + if (length > max_length) { + length = max_length; + } + strncpy(result, start, length); + + // TODO : Test when length is exceeded + result[length] = '\0'; // Null-terminate the string +} + +// Function to find and extract SSID and Password from the content +void extract_ssid_and_password(const char *content, char *ssid, char *password) { + const char *ssid_start, *ssid_end; + const char *password_start, *password_end; + + // Find the SSID field + ssid_start = strstr(content, "Content-Disposition: form-data; name=\"ssid\""); + if (ssid_start) { + ssid_start = strstr(ssid_start, "\r\n\r\n"); // Skip the header and find the actual value + if (ssid_start) { + ssid_start += 4; // Skip the "\r\n\r\n" part + ssid_end = strstr(ssid_start, "\r\n"); + if (ssid_end) { + extract_field_value(ssid_start, ssid_end, ssid, SSID_MAX_LENGTH); + } + } + } + + // Find the Password field + password_start = strstr(content, "Content-Disposition: form-data; name=\"password\""); + if (password_start) { + password_start = strstr(password_start, "\r\n\r\n"); // Skip the header and find the actual value + if (password_start) { + password_start += 4; // Skip the "\r\n\r\n" part + password_end = strstr(password_start, "\r\n"); + if (password_end) { + extract_field_value(password_start, password_end, password, PASSWORD_MAX_LENGTH); + + } + } + } +} + +////////////////////////////////////end ////////////////////// + +/* Function to get millis */ +uint32_t get_millis(void) +{ + TickType_t ticks = xTaskGetTickCount(); + return ((ticks * 1000) / configTICK_RATE_HZ); +} + +/* Converts a hex character to its integer value */ +char from_hex(char ch) { + return isdigit(ch) ? ch - '0' : tolower(ch) - 'a' + 10; +} + +/* Converts an integer value to its hex character*/ +char to_hex(char code) { + static char hex[] = "0123456789abcdef"; + return hex[code & 15]; +} + +char *url_decode(char *str) +{ + char *pstr = str, *buf = pvPortMalloc(strlen(str) + 1), *pbuf = buf; + while (*pstr) { + if (*pstr == '%') { + if (pstr[1] && pstr[2]) { + *pbuf++ = from_hex(pstr[1]) << 4 | from_hex(pstr[2]); + pstr += 2; + } + } else if (*pstr == '+') { + *pbuf++ = ' '; + } else { + *pbuf++ = *pstr; + } + pstr++; + } + *pbuf = '\0'; + return buf; +} + + + + +#ifdef BOARD_TEST +const char *main_resp = " Temp Stick Setup - Ideal Sciences

Temp Stick Setup

Step 1 Select WiFi Network
Step 2 Test Connection
Step 3 Complete

Select a WiFi Network

(Leave blank if no password required)

Test Connection

Give us about 30 seconds as we test your WiFi connection

WiFi Setup Complete

The sensor successfully connected to your WiFi network

Let's assign your sensor to an Ideal Sciences account:

-or-


Create Account

Login

The email and/or password you submitted is incorrect.

Account Setup Complete


SENSOR ID:

MAC ADDR:

Board Testing

Battery
Light
ENS210
MC3419
MCP9600T
BG77

LEDs

"; +#else +const char *main_resp = "WiFi Switch Setup - Azuma

Temp Stick Setup

Step 1 Select WiFi Network
Step 2 Test Connection
Step 3 Complete

Select a WiFi Network

Enter Custom SSID (Hidden Networks)

(Leave blank if no password required)

Test Connection

Give us about 30 seconds as wetest your WiFi connection

WiFi Setup Complete

The sensor successfully connected to your WiFi network


SENSOR ID:

MAC ADDR:

"; +//const char* main_resp = "Temp Stick Setup - Ideal Sciences

Temp Stick Setup

Step 1Select WiFi Network
Step 2Test Connection
Step 3Complete

Select a WiFi Network

(Leave blank if no password required)

Test Connection

Give us about 30 seconds as we test your WiFi connection


"; + +#endif +static esp_err_t root_handler(httpd_req_t *req) +{ + httpd_resp_send(req, main_resp, strlen(main_resp)); + + vTaskDelay(50/portTICK_PERIOD_MS); + + g_onboardingStepStartTime = get_millis(); + g_onboardingStepTimeout = (10 * 60 * 1000); // 10 minutes. + + return ESP_OK; +} +static const httpd_uri_t root = { + .uri = "/", + .method = HTTP_GET, + .handler = root_handler, + .user_ctx = NULL +}; + + + +const char *promise_min_js = "(function(a){function b(){this._callbacks=[];}b.prototype.then=function(a,c){var d;if(this._isdone)d=a.apply(c,this.result);else{d=new b();this._callbacks.push(function(){var b=a.apply(c,arguments);if(b&&typeof b.then==='function')b.then(d.done,d);});}return d;};b.prototype.done=function(){this.result=arguments;this._isdone=true;for(var a=0;a=300)&&j.status!==304);h.done(a,j.responseText,j);}};j.send(k);return h;}function h(a){return function(b,c,d){return g(a,b,c,d);};}var i={Promise:b,join:c,chain:d,ajax:g,get:h('GET'),post:h('POST'),put:h('PUT'),del:h('DELETE'),ENOXHR:1,ETIMEOUT:2,ajaxTimeout:0};if(typeof define==='function'&&define.amd)define(function(){return i;});else a.promise=i;})(this);"; +static esp_err_t promise_min_js_handler(httpd_req_t *req) +{ + /* Respond with empty body */ + httpd_resp_send(req, promise_min_js, strlen(promise_min_js)); + + vTaskDelay(50/portTICK_PERIOD_MS); + + g_onboardingStepStartTime = get_millis(); + g_onboardingStepTimeout = (10 * 60 * 1000); // 10 minutes. + + return ESP_OK; +} +static const httpd_uri_t promise_min_js_t = { + .uri = "/promise.min.js", + .method = HTTP_GET, + .handler = promise_min_js_handler, + .user_ctx = NULL +}; + + + +const char *ki_min_js = "!function(a,b,c,d){function e(c){b.push.apply(this,c&&c.nodeType?[c]:\"\"+c===c?a.querySelectorAll(c):d)}$=function(b){return/^f/.test(typeof b)?/c/.test(a.readyState)?b():$(a).on(\"DOMContentLoaded\",b):new e(b)},$[c]=e[c]=$.fn=e.fn={length:0,on:function(a,b){return this.each(function(c){c.addEventListener(a,b)})},off:function(a,b){return this.each(function(c){c.removeEventListener(a,b)})},each:function(a,c){return b.forEach.call(this,a,c),this},splice:b.splice}}(document,[],\"prototype\");"; +static esp_err_t ki_min_js_handler(httpd_req_t *req) +{ + /* Respond with empty body */ + httpd_resp_send(req, ki_min_js, strlen(ki_min_js)); + + vTaskDelay(50/portTICK_PERIOD_MS); + + g_onboardingStepStartTime = get_millis(); + g_onboardingStepTimeout = (10 * 60 * 1000); // 10 minutes. + + return ESP_OK; +} +static const httpd_uri_t ki_min_js_t = { + .uri = "/ki.min.js", + .method = HTTP_GET, + .handler = ki_min_js_handler, + .user_ctx = NULL +}; + + + +const char *style = "body{font-family: Arial, sans-serif; background-color: #eaeaea; padding: 0; margin: 0;}h2{margin: 0 0 10px 0;}label{display: block; margin: 10px 0px;}button{font-size: 18px; font-family: DroidSans, Arial, sans-serif; border: 0; background-color: #0b5bb5; color: #fff; padding: 15px; cursor: pointer; display: block; width: 100%;}button:disabled{background-color: #eaeaea; color:#aaaaaa; cursor:not-allowed;}.header{padding: 15px 0; background: #111; color: #fff; margin-bottom: 8px;}.header h1{font-size:26px; line-height: 26px; font-weight: bold; margin: 0; text-align: center;}.container{padding: 15px;}#setup-steps{list-style-type: none; padding: 0px; margin: 0px; position: relative;}#setup-steps li{position: absolute; display: inline-block;}#setup-steps li span{padding: 10px; font-size: 18px; background-color: #a8a8a8; color: white; font-weight: normal; border-radius: 20px; min-width: 20px; display: inline-block; text-align: center;}#setup-steps li.active span{/*background-color: #7ed600;*/ background-color: #0b5bb5; font-weight: bold;}#setup-step-1{left:0px;}#setup-step-2{left:42%;}#setup-step-3{right:0px;}input:not([type=\"radio\"]):not([type=\"checkbox\"]), select{font-size: 18px; font-family: DroidSans, Arial, sans-serif; padding: 10px; width: 95%}input[type=\"checkbox\"]{float: left; margin-right: 10px;}.col_50{width: 49%; display: inline-block;}.section{transition: margin-left ease-in 0.5s}.step_name{display: inline-block; min-width: 260px; background-color: #a8a8a8; color: white; padding: 10px; display: inline-block; text-shadow: 1px 1px 1px black; position: relative;}.step_name.active{background-color: #7ed600}.show-for-medium-down{display:none;}@media screen and (max-width: 800px){.col_50{width: 100%; display: block; margin-bottom: 15px;}.section{width: 100%; max-width: 100% !important;}.show-for-medium-down{display:block;}}@media screen and (max-width:1023px){.hide_for_medium_down{display:none;}}.step_name .step_num{font-weight: bold; font-size: 30px; text-transform: uppercase;}.step_name .step_label{position: absolute; right: 15px; top: 18px;}.align-top{vertical-align: top;}.loader{content:url('data:image/gif;base64,R0lGODlhFAAUAKUAACRqvIy23Mza7GSWzOTu9KzG5Hym1PT6/Dx+xLzS7Jy65Nzm9Gye1PT2/NTi9Oz2/ISu3EyKzMTa7Dx6xJS23Mze7Gya1Ozy/LTO7Pz6/MTW7KTC5HSe1CRuvGSa1OTu/LTK5ISq3ER+xLzW7KS+5OTq9Iyy3FSOzJS63Mze9Pz+/HSi1P///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQICgAAACwAAAAAFAAUAAAGwECWcDgMUIhIIkHREDJWwothkRQuLBshB8qCTFJVIYpRYj1ZDgSXeKGyLgxTN6TyiMosibsAKVxYBRgZQhkKCiwLAwAWQg0gEBAjVSomHR0rf0MEJJJVECcOYSphGYNDIyCBCWFCEROvAwmpIBisLK6wSKOTYQ8CoVULEk1DBw60bkkOCRgOphUgKU0LDrsq1CwHAhgVjZkHGAIsAmASCcQXxETbTSMab9ysF81CGu9oGJlJDRWm9kLa1NmqAKxKEAAh+QQICgAAACwAAAAAFAAUAIUMWrSErtzE2uxUjszk6vSsyuR0ntTs9vxEgsScuuTU4vRkmtQkary80uz8+vzM2uzs8vwUYrSUutxklszk7vS0yuR8ptT09vykwuRsmtTM3uwMXrSMstxcksycvuTc5vQkbrzE1uz8/vzk7vy0zuyEqtz0+vxsntTM3vT///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGxsCUcDgsVIhIIqRhEiYSwkuCkhRSPCEnNOU5farChgeSkkA/py3xQk5BPKQUBiOSnNoKakpD0lz2Gg5CIhVHFCUDHEIOKCQkX0kiGAMDCW1RApBJGBaaSCJggkQoIaUaYEIGHR0TFhqlIaeoJxOrAZ9gJqBJBw8KYBwDv0MmChWPVSIcICAWbRoVKH8fCrsOFiUpHxMMGVFtJiQPKQ8oIggRkJlJDyR/DVkPAAOoECTDpUILAAJgF4FC8qWg0GEYKiEaDCYJAgAh+QQICgAAACwAAAAAFAAUAIUMWrSErtzE2uxMhsTk6vRsmtSsxuTs9vycuuRcksw8esTU4vR8ptRcjsz8+vyUttzM2uxUjszs8vy80uykwuREgsQUXrRUiszk7vR0otT09vykvuRkmtREfsSEqtzM3uwMXrSMstxMhsxsntS0zuycvuRklsw8fsTc5vR8qtT8/vyUutzE1uzk7vz0+vzM3vT///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGv0CYcDh8LYhIoubjELJYQtdEkhRKSEfY01nCVIUfkkYLxZQmSQ0VpiFBYIIPjLQ5CAnr8GeMWqiEDh9yEhQBBoAvJCQoXxMBAWJKAoxVExteVX+ZSC9PLHJfMA+PARsfnqBfo48bSJpJTVUHEFlJFCmUUQuKuUQqFA0RK2MwYRBjKR4ugAgIMBgBFyFCakIoIAMOCSYqHB2UC5hEFyAvMCIiMAsnGaEsAAVCFekwHgq1SAsRawP0Egy9Qo1o9yUIACH5BAgKAAAALAAAAAAUABQAhSRqvIy23Mza7FySzOTu9KzG5Hym1PT6/Dx+xNzm9Gye1LzS7Jy65PT2/NTi9Gya1Oz2/ISu3FSKzDx6xJS23Mze7GSa1Ozy/LTO7Pz6/OTq9HSe1MTa7CRuvGSW1OTu/LTK5ISq3ER+xNzq9MTW7KTC5Iyy3FSOzJS63Mze9Pz+/HSi1P///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbEQJZwOEw5iEhio5IRkkjCQ6WRFF4wR9ZT6MBcqsIKhrqFgCrJxpfVwAhYHDRnQWVd6uIpK+FQCVV8bHlCGSkYGAlgXVhNQw0ciVUJHHVJflWXQwMTnBJgQhggBRgkHpwTnp8YowVQQyqNSQeKJyZgCyUERBcrAB0mmUQLJiFjQh4AHiMsDAyNKiAYdiURBUIJbywjCAosIREqJgprI2tEKwiJCissGg8MnxUTEUIb7CwlD5FJIwZr9kIgMND1aUgACp+CAAAh+QQICgAAACwAAAAAFAAUAIUMWrSErtzE2uxUiszk6vSsyuRsntScuuTs9vzc5vRkltREgsQkaryMttzU4vS80ux8ptT8+vzM2uxckszs8vykwuQUXrRcjszk7vS0yuSkvuT09vxsmtSUttyEqtzM3uwMXrSMstxUjsx0otScvuTc6vRkmtQkbrzE1ux8qtT8/vzk7vy0zuz0+vyUutzM3vT///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGvUCYcDh8OYhIouNCEaJQwtZnk3QCOE4ozMFqVmED0Av2hCEyn2RCInRYFirJWPCgwih2E0NRgqU8LUIqCUcbHyxpdyMMJyEqVQksLA4RSiIhXwkCXkgqlVWPRB4TEwojX0ISTygvKQqkp6gvq0dDnl+hahAVmQJ2QhQdIhO8kJKUQiEiARgwGSyfcWOGiEIEtSsGDTAVvCwaCMC/QwccBDAHB3ckD6gJHMUu6mQkzVUYJHbpUQ+cqDAFMqAKAgAh+QQICgAAACwAAAAAFAAUAIUMWrSErtzE2uxMhsTk6vSsxuRsmtTs9vycuuQ8esTc5vRcksy80uzU4vR8ptT8+vyUttzM2uxcjszs8vykwuREgsQUYrRUjszk7vS0zux0otT09vykvuREfsTE1uzM3uwMXrSMstxMhsy0yuRsntScvuQ8fsTc6vRkmtS81uyEqtz8/vyUutzk7vz0+vzM3vT///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGwUCYcDgkaYhI4skxEQ5EQoykkRS+EgEnFIYCCKpCjUkBq0AjoEuSQIURTAbYYrGqWMiwyUYYugQwMAgIK0IuKg4wLhEZH0ITEBcSFIRIKwoZGQ0PRAoOFGAKAntJK5tVlEMlAasIYEIfHrEvqqyuMBGxHm1DqEimSRgcKaCiRBsjqx5gDQyZpgUBBU0fH5SWVBsfjI4njiUjtxEwAhkujqNEDCVNsTAHDOJgGCXKMO0w2k1VEwzm9vUuPqCz9WFXkiAAOzhzTTFRUytROC9ESnl3ODZPR05pdUFRdkRLdlFTM3FwWDVaSnhUdytxN243cEtNVFFNNWo3cmV3YjRsa1EvTjE=');}.hide{display:none;}.button_account{background-color: white; color: #444; padding: 10px 8px; border: 1px solid #444; margin-right: 15px;}.button_account.active{background-color: #0b5bb5; color:white;}.red{color:red;}"; +static esp_err_t style_css_handler(httpd_req_t *req) +{ + /* Respond with empty body */ + httpd_resp_send(req, style, strlen(style)); + + vTaskDelay(50/portTICK_PERIOD_MS); + + g_onboardingStepStartTime = get_millis(); + g_onboardingStepTimeout = (10 * 60 * 1000); // 10 minutes. + + return ESP_OK; +} +static const httpd_uri_t style_css = { + .uri = "/style.css", + .method = HTTP_GET, + .handler = style_css_handler, + .user_ctx = NULL +}; + +char *sid = "{\"sid\":\"%s\",\"mac\":\"%s\",\"version\":\"%ld\"}"; +char *sid_data; +static esp_err_t sid_handler(httpd_req_t *req) +{ + char mac_str[20]; + uint8_t mac_base[6] = {0}; + + g_onboardingStepStartTime = get_millis(); + g_onboardingStepTimeout = (10 * 60 * 1000); // 10 minutes. + + esp_efuse_mac_get_default(mac_base); + esp_read_mac(mac_base, ESP_MAC_WIFI_STA); + + sprintf(mac_str, "%02X%02X%02X%02X%02X%02X", mac_base[0], mac_base[1], mac_base[2], mac_base[3], mac_base[4], mac_base[5]); + + sid_data = pvPortMalloc(100 * sizeof(char)); + sprintf(sid_data, sid, mac_str, mac_str,g_version); + + httpd_resp_send(req, sid_data, strlen(sid_data)); + vTaskDelay(50/portTICK_PERIOD_MS); + + vPortFree(sid_data); + return ESP_OK; +} +static const httpd_uri_t sid_t = { + .uri = "/sid", + .method = HTTP_GET, + .handler = sid_handler, + .user_ctx = NULL +}; + + + +char *scan_response; +static esp_err_t wirelessNetworks_handler(httpd_req_t *req) +{ + uint16_t apCount = 0; + wifi_ap_record_t *list = 0; + char temp[50]; + bool duplicateSsid; + int x; + + + ESP_LOGI(TAG,"OnBoarding : Step 1 > Scanning for Networks... Waiting for User to enter SSID and Password and click 'Next'..."); + + + g_onboardingStepStartTime = get_millis(); + g_onboardingStepTimeout = (10 * 60 * 1000); // 10 minutes. + + scan_response = pvPortMalloc(1024 * sizeof(char)); + + if( (WLAN_IDLE == g_wlanStatus) || (WLAN_DONE == g_wlanStatus) ) + { + wifi_scan_start(&apCount, &list); + } + + ESP_LOGI(TAG,"Access points found: %d",apCount); + + if(apCount) + { + strcpy(scan_response, "["); + + for(int ap_idx = 0; ap_idx < apCount; ap_idx++) + { + // CHECK FOR DUPLICATE SSIDs. (SAME NETWORK, BUT SOMETIMES ON A DIFFERENT CHANNEL, SOMETIMES ON SAME CHANNEL) + duplicateSsid = false; + for(x=0; x 0) + { + strcat(scan_response, ","); + } + strcat(scan_response, "{\"ssid\":\""); + strcat(scan_response, (char *)list[ap_idx].ssid); + strcat(scan_response, "\",\"password\":"); + + if(list[ap_idx].group_cipher == WIFI_CIPHER_TYPE_NONE) + { + sprintf(temp, "0"); + } + else + { + sprintf(temp, "1"); + } + + strcat(scan_response, temp); + /*sprintf(temp, "%d", list[ap_idx].rssi); + strcat(scan_response, "\",\"rssi\":"); + strcat(scan_response, temp);*/ + strcat(scan_response, "}"); + } + + ESP_LOGI(TAG,"Index: %d, SSID: %s, Encryption: %d, RSSI: %d",ap_idx,(char *)list[ap_idx].ssid,list[ap_idx].group_cipher,list[ap_idx].rssi); + } + + strcat(scan_response, "]"); + //vPortFree(list); + } + else + { + strcpy(scan_response, "{\"error\":\"No available wifi networks\"}"); + } + + httpd_resp_send(req, scan_response, strlen(scan_response)); + + vTaskDelay(100/portTICK_PERIOD_MS); + vPortFree(scan_response); + + return ESP_OK; +} +static const httpd_uri_t wirelessNetworks = { + .uri = "/wirelessNetworks", + .method = HTTP_GET, + .handler = wirelessNetworks_handler, + .user_ctx = NULL +}; + + +static esp_err_t wlan_handler(httpd_req_t *req) +{ + char *content; + char temp[30]; + memset(temp, 0, 30); + + ESP_LOGI(TAG,"OnBoarding : Step 2 > Testing Connection..."); + + g_onboardingStepStartTime = get_millis(); + g_onboardingStepTimeout = (10 * 60 * 1000); // 10 minutes. + + content = pvPortMalloc(300 * sizeof(char)); + memset(content, 0, 300); + httpd_req_recv(req, content, 300); + + if(strlen(content)) + { + g_wlanError = WLAN_NO_ERROR; + startOnboardingGetSsidAndPassword(content); + + Connect_wifi_sta(WIFI_CLIENT_AP_MODE); + + /* Start LED blinking */ + + + if(wifi_station_connected()) + { + + + // STORE WIFI CREDENTIALS TEMPORARILY. THEY ARE NOT COMMITTED TO FLASH UNTIL /restart + memset(wifi_get_ssidA(), 0, (SSID_MAX_LENGTH + 1)); + memset(wifi_get_pswdA(), 0, (PASSWORD_MAX_LENGTH + 1)); + memset(wifi_get_ssidB(), 0, (SSID_MAX_LENGTH + 1)); + memset(wifi_get_pswdB(), 0, (PASSWORD_MAX_LENGTH + 1)); + + strncpy(wifi_get_ssidA(), wifi_get_ssid(), SSID_MAX_LENGTH); + strncpy(wifi_get_pswdA(), wifi_get_pswd(), PASSWORD_MAX_LENGTH); + + // SAVE AP'S MAC ADDR + //data_set_ap_mac_addr(data_get_ap_mac_addr()); + + // ESP_LOGI(TAG,"find heap size"); + // int mem = esp_get_free_heap_size(); + // ESP_LOGI(TAG, "Free heap size: %u", mem); + + vTaskDelay(2000/portTICK_PERIOD_MS); + + + + + ESP_LOGI(TAG, "Attempting connection to google.com :)"); + + if(ESP_OK == http_client_test("https://www.google.com")) + { + ESP_LOGI(TAG, "Connection to internet successful.\nOnBoarding : Step 2 > Wifi Connection Success!\n"); + g_onboarding_status = 9; + } + else + { + + ESP_LOGI(TAG, "Connection to google.com failed.\nUnable to connect to the internet."); + g_onboarding_status = 1; + } + } + else + { + ESP_LOGI(TAG,"Failed to connect to WiFi. No SSID available."); + g_onboarding_status = 0; + } + } + + vPortFree(content); + + httpd_resp_send(req, "", 0); + + vTaskDelay(50/portTICK_PERIOD_MS); + + return ESP_OK; +} +static const httpd_uri_t wlan = +{ + .uri = "/wlan", + .method = HTTP_POST, + .handler = wlan_handler, + .user_ctx = NULL +}; + + + +static esp_err_t status_handler(httpd_req_t *req) +{ + char response[10]; + + g_onboardingStepStartTime = get_millis(); + g_onboardingStepTimeout = (10 * 60 * 1000); // 10 minutes. + + strcpy(response, ""); + + strcpy(response, "0"); + + switch(g_onboarding_status) + { + case 0: + strcpy(response, "0"); + break; + + case 1: + strcpy(response, "1"); + break; + + case 9: + // WIFI CREDENTIALS WORKED + strcpy(response, "9"); + break; + + case 99: + strcpy(response, "99"); + break; + + default: + strcpy(response, "99"); + break; + } + + httpd_resp_send(req, response, strlen(response)); + + vTaskDelay(50/portTICK_PERIOD_MS); + + return ESP_OK; +} +static const httpd_uri_t status = +{ + .uri = "/status", + .method = HTTP_GET, + .handler = status_handler, + .user_ctx = NULL +}; + +static esp_err_t acc_handler(httpd_req_t *req) +{ + char response[180];// = (char *)pvPortMalloc(100 * sizeof(char)); + char t[50];//= (char *)pvPortMalloc(50 * sizeof(char)); + char e[50];// = (char *)pvPortMalloc(50 * sizeof(char)); + char p[50];// = (char *)pvPortMalloc(50 * sizeof(char)); + char pa[50];// = (char *)pvPortMalloc(50 * sizeof(char)); + char content[100];// = (char *)pvPortMalloc(100 * sizeof(char)); + + g_onboardingStepStartTime = get_millis(); + g_onboardingStepTimeout = (10 * 60 * 1000); // 10 minutes. + + bool restart_cond = false; + + memset(content, 0, 100); + memset(t, 0, 50); + memset(e, 0, 50); + memset(p, 0, 50); + memset(pa, 0, 50); + httpd_req_recv(req, content, 100); + + if(strlen(content)) + { + //ESP_LOGI(TAG, "%s", content); + + char *h = strtok(content, "&"); + strcpy(t, h); + h = strtok(NULL, "&"); + strcpy(e, h); + h = strtok(NULL, "&"); + strcpy(p, h); + h = strtok(NULL, "&"); + if(h != NULL) + { + strcpy(pa, h); + } + + h = strtok(t, "="); + if(!strcmp(h, "t")) + { + h = strtok(NULL, "="); + strcpy(t, h); + } + + h = strtok(e, "="); + if(!strcmp(h, "e")) + { + h = strtok(NULL, "="); + strcpy(e, h); + } + + h = strtok(p, "="); + if(!strcmp(h, "p")) + { + h = strtok(NULL, "="); + strcpy(p, h); + } + + if(!strcmp(t, "c")) + { + h = strtok(pa, "="); + if(!strcmp(h, "pa")) + { + h = strtok(NULL, "="); + strcpy(pa, h); + } + } + else + { + strcpy(pa, ""); + } + //ESP_LOGI(TAG, "t=%s e=%s p=%s pa=%s", t, e, p, pa); + } + + if(!registerAcctWithServer(t, e, p, pa, response, strlen(response))) + { + ESP_LOGI(TAG,"Connection to server failed."); + restart_cond = true; + } + + ESP_LOGI(TAG,"Server response is: %s",response); + + httpd_resp_send(req, response, strlen(response)); + + if(restart_cond) + { + esp_restart(); + } + + //vTaskDelay(200/portTICK_PERIOD_MS); + + /*vPortFree(t); + vPortFree(e); + vPortFree(p); + vPortFree(pa); + + vPortFree(urlConnectionString); + vPortFree(content); + vPortFree(post_params); + vPortFree(mac_str); + vPortFree(response);*/ + + //start_remaining_tasks(); + + return ESP_OK; +} +static const httpd_uri_t acc = { + .uri = "/acc", + .method = HTTP_POST, + .handler = acc_handler, + .user_ctx = NULL +}; + +static esp_err_t restart_handler(httpd_req_t *req) +{ + ESP_LOGI(TAG,"OnBoarding : Step 3 > Account Creation Success!"); + + httpd_resp_send(req, "", 0); + +#ifdef STORING_TO_NVM + /* CLEAR SIMULATED EEPROMS AND HISTORY SECTORS */ + nvm_clear(); +#endif + + g_onboardingCompleted = true; + + /* Set the wifi-onboarded flag to be true */ + device_wifi_onboarded = true; + + g_onboardingStepStartTime = get_millis(); + g_onboardingStepTimeout = (10 * 60 * 1000); // 10 minutes. + + vTaskDelay(50/portTICK_PERIOD_MS); + + return ESP_OK; +} +static const httpd_uri_t restart = { + .uri = "/restart", + .method = HTTP_POST, + .handler = restart_handler, + .user_ctx = NULL +}; + + +static esp_err_t getWlan_handler(httpd_req_t *req) +{ + char response[100]; + + g_onboardingStepStartTime = get_millis(); + g_onboardingStepTimeout = (10 * 60 * 1000); // 10 minutes. + + sprintf(response,"{\"wlanA\":\"%s\",\"wlanB\":\"%s\"}",wifi_get_ssidA(),wifi_get_ssidB()); + + httpd_resp_send(req, response, strlen(response)); + + vTaskDelay(50/portTICK_PERIOD_MS); + + return ESP_OK; +} +static const httpd_uri_t getWlan = { + .uri = "/get/wlan", + .method = HTTP_GET, + .handler = getWlan_handler, + .user_ctx = NULL +}; + + + +static esp_err_t setWlan_handler(httpd_req_t *req) +{ + char *content; + + char *pPassword; + char *pSsid; + char val[10]; + char buf[100]; + int ret, buflen; + + g_onboardingStepStartTime = get_millis(); + g_onboardingStepTimeout = (10 * 60 * 1000); // 10 minutes. + + content = pvPortMalloc(100 * sizeof(char)); + memset(content, 0, 100); + httpd_req_recv(req, content, 100); + + if( (WLAN_IDLE == g_wlanStatus) || (WLAN_DONE == g_wlanStatus) ) + { + ESP_LOGI(TAG,"Get SSID and password"); + + g_wlanTargetSsid = 0; // Default + /*memset(g_wlanSsidStr, 0, (SSID_MAX_LENGTH + 1)); + memset(g_wlanPasswordStr, 0, (PASSWORD_MAX_LENGTH + 1));*/ + wifi_update_credentials((char*)0, (char*)0); + + g_wlanError = WLAN_NO_ERROR; + + // Update global copy of SSID and password for wlan testing state machine to be able to store the SSID and password after successful testing. + startOnboardingGetSsidAndPassword(content); + + // Check to see if WiFi credentials testing is requested + if(WLAN_NO_ERROR == g_wlanError) + { + // Determine target SSID and password + buflen = httpd_req_get_url_query_len(req) + 1; + if (buflen > 1) { + ret = httpd_req_get_url_query_str(req, buf, buflen); + if (ret == ESP_OK) { + char param[32]; + if (httpd_query_key_value(buf, "wlan", param, sizeof(param)) == ESP_OK) { + if (strcmp(param, "A") == 0) { + g_wlanTargetSsid = 'A'; + } else if (strcmp(param, "B") == 0) { + g_wlanTargetSsid = 'B'; + } + } + } + } + + // Update global copy of SSID and password for wlan testing state machine to be able to store the SSID and password after successful testing. + /*strncpy(g_wlanSsidStr, ssidStr, SSID_MAX_LENGTH); + strncpy(g_wlanPasswordStr, passwordStr, PASSWORD_MAX_LENGTH);*/ + //wifi_update_credentials(ssidStr, passwordStr); + + // Determine if WiFi testing is requested + if(ESP_OK == httpd_req_get_hdr_value_str(req,"test",val,strlen(val))) + { + if(0 == strcmp("1", val)) + { + ESP_LOGI(TAG,"Begin testing WiFi credentials"); + + // Begin testing WiFi credentials + if(wifi_station_connected()) // Disconnect if WiFi is already connected. + { + wifi_sta_disconnecting(); + vTaskDelay(10); // Delay after disconnect function call + } + + vTaskDelay(10); // Most of the other WiFi routines require a minimum of 4 millisecond vTaskDelay. This delay is added just to be safe. + + //WiFi.config(IPAddress(0,0,0,0), IPAddress(0,0,0,0), IPAddress(0,0,0,0), IPAddress(0,0,0,0), IPAddress(0,0,0,0)); + + if (/*0 != passwordStr[0]*/wifi_get_pswd()) + Connect_wifi_sta(WIFI_CLIENT_AP_MODE); + else + Connect_wifi_sta(WIFI_CLIENT_AP_MODE); + vTaskDelay(10); + + // Update WLAN validation state + g_wlanStatus = WLAN_TRY_WIFI; + g_wlanError = WLAN_NO_ERROR; + + g_wlanTesting = WLAN_WIFI_CONNECTING; // Set the status here instead of in the wifi testing state machine, because the smart phone app could poll the status before the state machine could set it. + } + } + + if(WLAN_WIFI_CONNECTING != g_wlanTesting) // Is testing being skipped? + { + ESP_LOGI(TAG,"WiFi credentials testing skipped"); + + pSsid = NULL; + pPassword = NULL; // Prevent compiler error + + // Save WiFi credentials + if('A' == g_wlanTargetSsid) + { + pSsid = wifi_get_ssidA(); + pPassword = wifi_get_pswdA(); + } + + if('B' == g_wlanTargetSsid) + { + pSsid = wifi_get_ssidB(); + pPassword = wifi_get_pswdB(); + } + + if(NULL != pSsid) // Make sure the pointers are set. + { + memset(pSsid, 0, (SSID_MAX_LENGTH + 1)); + memset(pPassword, 0, (PASSWORD_MAX_LENGTH + 1)); + + strncpy(pSsid, wifi_get_ssid(), SSID_MAX_LENGTH); + strncpy(pPassword, wifi_get_pswd(), PASSWORD_MAX_LENGTH); + + //writeWifiCredentialsToFlash(); + } + } + } + } + + vTaskDelay(50/portTICK_PERIOD_MS); + + return ESP_OK; +} +static const httpd_uri_t setWlan = { + .uri = "/set/wlan", + .method = HTTP_GET, + .handler = setWlan_handler, + .user_ctx = NULL +}; + + +static esp_err_t deleteWlanA_handler(httpd_req_t *req) +{ + + char response[100]; + char *sidA = wifi_get_ssidA(); + char *pwdA = wifi_get_ssidA(); + char *sidB = wifi_get_ssidB(); + char *pwdB = wifi_get_pswdB(); + + g_onboardingStepStartTime = get_millis(); + g_onboardingStepTimeout = (10 * 60 * 1000); // 10 minutes. + + // Delete SSID A + memset(sidA, 0, (SSID_MAX_LENGTH + 1)); + memset(pwdA, 0, (PASSWORD_MAX_LENGTH + 1)); + + if(sidB) // If SSID B exists, bump it up to become SSID A + { + strncpy(sidA, sidB, SSID_MAX_LENGTH); + strncpy(pwdA, sidB, PASSWORD_MAX_LENGTH); + + memset(sidB, 0, (SSID_MAX_LENGTH + 1)); + memset(pwdB, 0, (PASSWORD_MAX_LENGTH + 1)); + } + + //writeWifiCredentialsToFlash(); + + strcpy(response,"{\"success\":\"1\"}"); + httpd_resp_send(req, response, strlen(response)); + + vTaskDelay(50/portTICK_PERIOD_MS); + + return ESP_OK; +} +static const httpd_uri_t deleteWlanA = { + .uri = "/delete/wlanA", + .method = HTTP_GET, + .handler = deleteWlanA_handler, + .user_ctx = NULL +}; + + +static esp_err_t deleteWlanB_handler(httpd_req_t *req) +{ + char response[100]; + char *sidB = wifi_get_ssidB(); + char *pwdB = wifi_get_pswdB(); + + g_onboardingStepStartTime = get_millis(); + g_onboardingStepTimeout = (10 * 60 * 1000); // 10 minutes. + + // Delete SSID B + memset(sidB, 0, (SSID_MAX_LENGTH + 1)); + memset(pwdB, 0, (PASSWORD_MAX_LENGTH + 1)); + + //writeWifiCredentialsToFlash(); + + strcpy(response,"{\"success\":\"1\"}"); + httpd_resp_send(req, response, strlen(response)); + + vTaskDelay(50/portTICK_PERIOD_MS); + return ESP_OK; +} +static const httpd_uri_t deleteWlanB = { + .uri = "/delete/wlanB", + .method = HTTP_GET, + .handler = deleteWlanB_handler, + .user_ctx = NULL +}; + + +static esp_err_t getWlanStatus_handler(httpd_req_t *req) +{ + char response[100]; + + g_onboardingStepStartTime = get_millis(); + g_onboardingStepTimeout = (10 * 60 * 1000); // 10 minutes. + + safeStrCat(response, sizeof(response), (char*)"{\"status\":\""); + switch(g_wlanStatus) + { + case WLAN_IDLE: safeStrCat(response, sizeof(response), (char*)"idle"); ESP_LOGI(TAG,"WLAN status: idle"); break; + case WLAN_WORKING: safeStrCat(response, sizeof(response), (char*)"working"); ESP_LOGI(TAG,"WLAN status: working"); break; + case WLAN_ERROR: safeStrCat(response, sizeof(response), (char*)"error"); ESP_LOGI(TAG,"WLAN status: error"); g_wlanStatus = WLAN_IDLE; break; // Clear the error flag because it was reported. + case WLAN_DONE: safeStrCat(response, sizeof(response), (char*)"done"); ESP_LOGI(TAG,"WLAN status: done"); break; + case WLAN_TRY_WIFI: safeStrCat(response, sizeof(response), (char*)"try_wifi"); ESP_LOGI(TAG,"WLAN status: try_wifi"); break; + case WLAN_TRY_INTERNET: safeStrCat(response, sizeof(response), (char*)"try_internet"); ESP_LOGI(TAG,"WLAN status: try_internet"); break; + default: safeStrCat(response, sizeof(response), (char*)"undefined_status"); ESP_LOGI(TAG,"WLAN status: undefined_status"); break; + } + + safeStrCat(response, sizeof(response), (char*)"\",\"error\":\""); + switch(g_wlanError) + { + case WLAN_NO_ERROR: safeStrCat(response, sizeof(response), (char*)"\"}"); ESP_LOGI(TAG,"WLAN error: no_error\n"); break; + case WLAN_SSID_TOO_LONG: safeStrCat(response, sizeof(response), (char*)"ssid_too_long\"}"); ESP_LOGI(TAG,"WLAN error: ssid_too_long\n"); break; + case WLAN_PASSWORD_TOO_LONG: safeStrCat(response, sizeof(response), (char*)"password_too_long\"}"); ESP_LOGI(TAG,"WLAN error: password_too_long\n"); break; + case WLAN_FAILED_WIFI: safeStrCat(response, sizeof(response), (char*)"failed_wifi\"}"); ESP_LOGI(TAG,"WLAN error: failed_wifi\n"); break; + case WLAN_FAILED_INTERNET: safeStrCat(response, sizeof(response), (char*)"failed_internet\"}"); ESP_LOGI(TAG,"WLAN error: failed_internet\n"); break; + default: safeStrCat(response, sizeof(response), (char*)"undefined_error\"}"); ESP_LOGI(TAG,"WLAN error: undefined_error\n"); break; + } + g_wlanError = WLAN_NO_ERROR; + + strcpy(response,"{\"success\":\"1\"}"); + httpd_resp_send(req, response, strlen(response)); + + vTaskDelay(50/portTICK_PERIOD_MS); + return ESP_OK; +} +static const httpd_uri_t getWlanStatus = { + .uri = "/get/wlanStatus", + .method = HTTP_GET, + .handler = getWlanStatus_handler, + .user_ctx = NULL +}; + + +static esp_err_t readSensors_handler(httpd_req_t *req) +{ + char response[200]; + char floatStr[32]; + + g_onboardingStepStartTime = get_millis(); + g_onboardingStepTimeout = (10 * 60 * 1000); // 10 minutes. + + + //getSensorsDataDirectly(); + + response[0] = 0; + safeStrCat(response, sizeof(response), (char*)"{\"tempC\":"); + sprintf(floatStr, "%.2f", get_temperature_data()); + safeStrCat(response, sizeof(response), floatStr); + + safeStrCat(response, sizeof(response), (char*)"{,\"humidity\":"); + sprintf(floatStr, "%.2f", get_humidity_data()); + safeStrCat(response, sizeof(response), floatStr); + + safeStrCat(response, sizeof(response), (char*)"}"); + + httpd_resp_send(req, response, strlen(response)); + + vTaskDelay(50/portTICK_PERIOD_MS); + return ESP_OK; +} +static const httpd_uri_t readSensors = { + .uri = "/get/readings", + .method = HTTP_GET, + .handler = readSensors_handler, + .user_ctx = NULL +}; + + +static esp_err_t done_handler(httpd_req_t *req) +{ + g_onboardingStepStartTime = get_millis(); + g_onboardingStepTimeout = (10 * 60 * 1000); // 10 minutes. + + g_wlanOnboardingDone = true; + + vTaskDelay(50/portTICK_PERIOD_MS); + return ESP_OK; +} +static const httpd_uri_t doneOn = { + .uri = "/done", + .method = HTTP_GET, + .handler = done_handler, + .user_ctx = NULL +}; + + +static esp_err_t factoryReset_handler(httpd_req_t *req) +{ + g_onboardingStepStartTime = get_millis(); + g_onboardingStepTimeout = (10 * 60 * 1000); // 10 minutes. + + startOnboardingShutdown(); + + esp_restart(); + + vTaskDelay(50/portTICK_PERIOD_MS); + return ESP_OK; +} +static const httpd_uri_t factoryReset = { + .uri = "/factoryReset", + .method = HTTP_GET, + .handler = factoryReset_handler, + .user_ctx = NULL +}; + + + + +void startOnboarding(void *pvParameters) +{ + char *pPassword; + char *pSsid; + char initialPasswordA[PASSWORD_MAX_LENGTH + 1]; + char initialPasswordB[PASSWORD_MAX_LENGTH + 1]; + char initialSsidA[SSID_MAX_LENGTH + 1]; + char initialSsidB[SSID_MAX_LENGTH + 1]; + httpd_config_t config = HTTPD_DEFAULT_CONFIG(); + config.lru_purge_enable = true; + config.max_uri_handlers = 19; + uint32_t timeout = 0; + uint8_t serverConnectionAttempt = 0; + //int8_t currentWifiChannel; + + g_wlanError = WLAN_NO_ERROR; + g_wlanStatus = WLAN_IDLE; + g_wlanTesting = WLAN_NOT_TESTING; + g_wlanTestingPreviousState = WLAN_NOT_TESTING; + + g_servedRoot = false; + g_servedSid = false; + g_servedStatus = false; + //currentWifiChannel = -1; // Initialized so that the current wifi channel will be printed to the monitor. + + memcpy(initialSsidA, wifi_get_ssidA(), sizeof(initialSsidA)); + memcpy(initialPasswordA, wifi_get_pswdA(), sizeof(initialPasswordA)); + memcpy(initialSsidB, wifi_get_ssidB(), sizeof(initialSsidB)); + memcpy(initialPasswordB, wifi_get_pswdB(), sizeof(initialPasswordB)); + + // Start the httpd server + ESP_LOGI(TAG, "******** START ON-BOARDING ********\nStarting server on port: '%d'", config.server_port); + + /* Start the hmi-not-onbooarded LED-event */ + hmi_set_leds_state(RED_LED_FLASHING); + + if (httpd_start(&serverHandle, &config) == ESP_OK) + { + /**/ + g_onboardingStepStartTime = get_millis(); + g_onboardingStepTimeout = (20 * 60 * 1000); // 20 minutes. + + // Set URI handlers + ESP_ERROR_CHECK(httpd_register_uri_handler(serverHandle, &root)); + ESP_ERROR_CHECK(httpd_register_uri_handler(serverHandle, &ki_min_js_t)); + ESP_ERROR_CHECK(httpd_register_uri_handler(serverHandle, &promise_min_js_t)); + ESP_ERROR_CHECK(httpd_register_uri_handler(serverHandle, &style_css)); + ESP_ERROR_CHECK(httpd_register_uri_handler(serverHandle, &sid_t)); + ESP_ERROR_CHECK(httpd_register_uri_handler(serverHandle, &wirelessNetworks)); + ESP_ERROR_CHECK(httpd_register_uri_handler(serverHandle, &wlan)); + ESP_ERROR_CHECK(httpd_register_uri_handler(serverHandle, &status)); + ESP_ERROR_CHECK(httpd_register_uri_handler(serverHandle, &acc)); + ESP_ERROR_CHECK(httpd_register_uri_handler(serverHandle, &restart)); + + ESP_ERROR_CHECK(httpd_register_uri_handler(serverHandle, &getWlan)); + ESP_ERROR_CHECK(httpd_register_uri_handler(serverHandle, &setWlan)); + ESP_ERROR_CHECK(httpd_register_uri_handler(serverHandle, &deleteWlanA)); + ESP_ERROR_CHECK(httpd_register_uri_handler(serverHandle, &deleteWlanB)); + ESP_ERROR_CHECK(httpd_register_uri_handler(serverHandle, &getWlanStatus)); + + ESP_ERROR_CHECK(httpd_register_uri_handler(serverHandle, &readSensors)); + ESP_ERROR_CHECK(httpd_register_uri_handler(serverHandle, &doneOn)); + //ESP_ERROR_CHECK(httpd_register_uri_handler(serverHandle, &deleteWifiAndReset)); + ESP_ERROR_CHECK(httpd_register_uri_handler(serverHandle, &factoryReset)); + ESP_LOGI(TAG, "OnBoarding : Step 0 > Waiting for User to connect to soft AP and download configuration page..."); + + while(1) + { + // Exit onboarding? + if(g_onboardingCompleted || g_wlanOnboardingDone) + { + ESP_LOGI(TAG,"On-boarding complete."); + +#ifdef STORING_TO_NVM + /* Store the wifi-onboarded flag in nvs */ + nvm_write_onboarding_flag(WIFI_ONBOARDING_KEY, device_wifi_onboarded); + + /* Store the wifi-credentials to nvm */ + nvm_write_wifi_credentials(wifi_get_ssid(), (uint8_t)strlen(wifi_get_ssid()), wifi_get_pswd(), (uint8_t)strlen(wifi_get_pswd())); +#endif + + break; + } + + // Onboarding timeout? + if ( ((get_millis() - g_onboardingStepStartTime) > g_onboardingStepTimeout)) + { + ESP_LOGI(TAG,"\nOn-boarding timed-out.\n"); + g_onboardingCompleted = false; + g_wlanOnboardingDone = false; + break; + } + + // Process the wlan testing state machine + if(g_wlanTestingPreviousState != g_wlanTesting) + { + g_wlanTestingPreviousState = g_wlanTesting; + ESP_LOGI(TAG,"\nWLAN testing switched to state: %d",g_wlanTesting); + } + + // Test if pushbutton requested server mode has timed out. + /*if( g_serverModeRequested && *g_pWifiSsidA && !g_pageServed && (300000 < (millis() - serverModeStartTime)) ) + { + Serial.println(F("\nPushbutton initiated server mode timed out.\n")); + g_onboardingCompleted = false; + g_wlanOnboardingDone = true; + break; + }*/ + + switch(g_wlanTesting) + { + case WLAN_NOT_TESTING: + break; + + + case WLAN_WIFI_CONNECTING: + //currentWifiChannel = -1; + ESP_LOGI(TAG,"Attempting to connect using WiFi channel:"); + + timeout = get_millis(); + g_wlanTesting = WLAN_WIFI_WAITING_TO_CONNECT; + break; + + + case WLAN_WIFI_WAITING_TO_CONNECT: + if(wifi_station_connected()) + { + ESP_LOGI(TAG,"\nConnected to WiFi on channel: %d",data_get_wifi_channel()); + + // Save AP's MAC address + //data_set_ap_mac_addr(data_get_ap_mac_addr()); + + serverConnectionAttempt = 0; + g_wlanTesting = WLAN_WIFI_CONNECTED; + } + else + { + if(30000 < (get_millis() - timeout)) // WiFi connection attempt timed out? + { + ESP_LOGI(TAG,"Failed to connect to WiFi!"); + + if(wifi_station_connected()) // Disconnect if WiFi is connected. + { + wifi_sta_disconnecting(); + vTaskDelay(10/portTICK_PERIOD_MS); // Delay after disconnect function call + } + + g_wlanStatus = WLAN_ERROR; + g_wlanError = WLAN_FAILED_WIFI; + + g_wlanTesting = WLAN_NOT_TESTING; // Reset state machine. + } + } + break; + + + case WLAN_WIFI_CONNECTED: + + ESP_LOGI(TAG,"Attempting connection to google.com"); + + g_wlanStatus = WLAN_TRY_INTERNET; + + serverConnectionAttempt++; + + vTaskDelay(50/portTICK_PERIOD_MS); // Feed the watchdog timer + /*if(g_client.connected()) + { + g_client.stop(); + yield(); // Feed the watchdog timer + g_client.flush(); + yield(); // Feed the watchdog timer + }*/ + + if(http_client_test("https://www.google.com")) + { + ESP_LOGI(TAG,"Connected to google.com"); + + vTaskDelay(100/portTICK_PERIOD_MS); // Feed the watchdog timer + /*if(g_client.connected()) + { + g_client.stop(); + yield(); // Feed the watchdog timer + g_client.flush(); + yield(); // Feed the watchdog timer + }*/ + + g_wlanTesting = WLAN_TEST_SUCCESS; + } + else + { + if(10 < serverConnectionAttempt) // MAKE REPEATED ATTEMPTS OVER 10 SECONDS // http://forum.arduino.cc/index.php?topic=433836.0 + { + ESP_LOGI(TAG,"Failed to connect to google.com"); + + serverConnectionAttempt = 0; + g_wlanTesting = WLAN_CONNECT_TO_SERVER_2; + } + else + { + timeout = get_millis(); + g_wlanTesting = WLAN_SERVER_1_WAITING_TO_CONNECT; + } + } + break; + + + case WLAN_SERVER_1_WAITING_TO_CONNECT: + if(1000 < (get_millis() - timeout)) + g_wlanTesting = WLAN_WIFI_CONNECTED; + break; + + + case WLAN_CONNECT_TO_SERVER_2: + ESP_LOGI(TAG,"Attempting connection to tempstick.com"); + + serverConnectionAttempt++; + + vTaskDelay(50/portTICK_PERIOD_MS); // Feed the watchdog timer + /*if(g_client.connected()) + { + g_client.stop(); + yield(); // Feed the watchdog timer + g_client.flush(); + yield(); // Feed the watchdog timer + }*/ + + if(http_client_test("http://www.tempstick.com")) + { + ESP_LOGI(TAG,"Connected to tempstick.com"); + + vTaskDelay(50/portTICK_PERIOD_MS); // Feed the watchdog timer + /*if(g_client.connected()) + { + g_client.stop(); + yield(); // Feed the watchdog timer + g_client.flush(); + yield(); // Feed the watchdog timer + }*/ + + g_wlanTesting = WLAN_TEST_SUCCESS; + } + else + { + if(10 < serverConnectionAttempt) // MAKE REPEATED ATTEMPTS OVER 10 SECONDS // http://forum.arduino.cc/index.php?topic=433836.0 + { + ESP_LOGI(TAG,"Failed to connect to tempstick.com"); + + vTaskDelay(50/portTICK_PERIOD_MS); // Feed the watchdog timer + /*if(g_client.connected()) + { + g_client.stop(); + yield(); // Feed the watchdog timer + g_client.flush(); + yield(); // Feed the watchdog timer + }*/ + + if(wifi_station_connected()) // Disconnect if WiFi is connected. + { + wifi_sta_disconnecting(); + vTaskDelay(100/portTICK_PERIOD_MS); // Delay after disconnect function call + } + + g_wlanStatus = WLAN_ERROR; + g_wlanError = WLAN_FAILED_INTERNET; + + g_wlanTesting = WLAN_NOT_TESTING; // Reset state machine. + } + else + { + timeout = get_millis(); + g_wlanTesting = WLAN_SERVER_2_WAITING_TO_CONNECT; + } + } + break; + + + case WLAN_SERVER_2_WAITING_TO_CONNECT: + if(1000 < (get_millis() - timeout)) + g_wlanTesting = WLAN_CONNECT_TO_SERVER_2; + break; + + + case WLAN_TEST_SUCCESS: + ESP_LOGI(TAG,"WLAN test success"); + + // Save WiFi credentials + pSsid = NULL; + pPassword = NULL; // Prevent compiler error. + + if('A' == g_wlanTargetSsid) + { + pSsid = wifi_get_ssidA(); + pPassword = wifi_get_pswdA(); + } + + if('B' == g_wlanTargetSsid) + { + pSsid = wifi_get_ssidB(); + pPassword = wifi_get_pswdB(); + } + + if(NULL != pSsid) + { + memset(pSsid, 0, (SSID_MAX_LENGTH + 1)); + memset(pPassword, 0, (PASSWORD_MAX_LENGTH + 1)); + + /*strncpy(pSsid, g_wlanSsidStr, SSID_MAX_LENGTH); + strncpy(pPassword, g_wlanPasswordStr, PASSWORD_MAX_LENGTH);*/ + strncpy(pSsid, wifi_get_ssid(), SSID_MAX_LENGTH); + strncpy(pPassword, wifi_get_pswd(), PASSWORD_MAX_LENGTH); + + //writeWifiCredentialsToFlash(); + } + + g_wlanStatus = WLAN_DONE; + g_wlanError = WLAN_NO_ERROR; + + g_wlanTesting = WLAN_NOT_TESTING; // Reset state machine. + break; + + + default: + ESP_LOGI(TAG,"\nWLAN testing programming error. Locking up."); + while(1) + { + vTaskDelay(100/portTICK_PERIOD_MS); + } + break; + } // End of switch(g_wlanTesting) + + vTaskDelay(100/portTICK_PERIOD_MS); + } + + startOnboardingShutdown(); + + if(g_wlanOnboardingDone) // Real-time server mode exit. + { + //readWifiCredentialsFromFlash(NULL, 0, NULL, 0, NULL, 0, NULL, 0); + + if(wifi_get_ssidA()) // SSID set? + { + if( (0 != strcmp(initialSsidA, wifi_get_ssidA())) || (0 != strcmp(initialPasswordA, wifi_get_pswdA())) || + (0 != strcmp(initialSsidB, wifi_get_ssidB())) || (0 != strcmp(initialPasswordB, wifi_get_pswdB())) ) // Did the customer change any WiFi settings? + { + ESP_LOGI(TAG,"Smart phone app done. WiFi settings exist. WiFi changed. Resetting."); + wifi_switchToPrimaryNetwork(); + esp_restart(); //resetCoprocessor(); // Reset Temp Stick to force a check in with the new WiFi settings. This function does not return. + } + else + { + ESP_LOGI(TAG,"Smart phone app done. WiFi settings exist. WiFi not changed. Returning to sleep"); + //goToSleep(0xFFFFFFFE, _rtcRamData.rfWakeMode); // Return to sleep. (Sleep may have been interrupted by the server mode request). This function does not return. + } + } + else + { + ESP_LOGI(TAG,"Smart phone app done. No WiFi settings. Resetting."); + esp_restart(); //resetCoprocessor(); // Reset Temp Stick to re-enter onboarding. This function does not return. + } + } + else + { + if(g_onboardingCompleted) + { + ESP_LOGI(TAG,"Legacy onboarding completed. Resetting."); + wifi_switchToPrimaryNetwork(); +#ifdef STORING_TO_NVM + esp_restart(); //resetCoprocessor(); // Reset Temp Stick to force check in with the new WiFi settings. This function does not return. +#endif + } + else + { + // Onboarding timed out. + + if( (g_servedSid || g_servedStatus) && (!g_servedRoot) ) // Did smartphone app connection timeout, instead of legacy 10.10.1.1? + { + ESP_LOGI(TAG,"Smart phone app connection timed out. Returning to sleep."); + //goToSleep(0xFFFFFFFE, _rtcRamData.rfWakeMode); // Return to sleep. (Sleep may have been interrupted by the server mode request). This function does not return. + } + else + { + ESP_LOGI(TAG,"Legacy onboarding timed out. Locking up."); + //goToSleep(0xFFFFFFFF, RF_CAL); // Onboarding timed out. Shut down until a POR occurs. The 0xFFFFFFFF is a special argument that puts the coprocessor into its own deep sleep until a POR occurs. This function does not return. + } + } + } + + vTaskDelete(NULL); + //return; + } + + ESP_LOGI(TAG, "Error starting server!"); + vTaskDelete(NULL); + //return NULL; +} + +void webserver_stop(httpd_handle_t server) +{ + if (server) { + /* Stop the httpd server */ + if(ESP_FAIL == httpd_stop(server)) + { + ESP_LOGI(TAG, "Failed to stop server"); + } + } +} + +void webserver_start(void) +{ +#ifdef STORING_TO_NVM + device_wifi_onboarded = nvm_read_onboarding_flag(WIFI_ONBOARDING_KEY); +#endif + + if(!device_wifi_onboarded) + { + wifi_first_init(); + Wifi_Init_SoftAp(); + xTaskCreate(startOnboarding, "onboarding_task", 8192, NULL, 16, NULL); + } + else + { + g_onboardingCompleted = true; + } +} + +bool webserver_get_status(void) +{ + if(g_onboardingCompleted && device_wifi_onboarded) + return true; + else + return false; +} + + + +void startOnboardingShutdown(void) +{ + ESP_LOGI(TAG,"Shutting down on-boaring server"); + + /* Stop the on-boarding server */ + webserver_stop(serverHandle); + + /* Disconnecting the wifi-station from wifi-network */ + wifi_sta_disconnecting(); + + /* Stop the wifi service */ + wifi_stop(); + + ESP_LOGI(TAG," ----> on-boaring server has been shut down"); + /* wait for 1.5sec */ + vTaskDelay(1500/portTICK_PERIOD_MS); + + /* Turn off on_boarding led event */ + hmi_stop_red_flashing(); + +} + +void startOnboardingGetSsidAndPassword(char *content) +{ + char *ssid; + char *pwd_encoded; + char *pwd; + + ssid = pvPortMalloc((SSID_MAX_LENGTH + 1) * sizeof(char)); + pwd_encoded = pvPortMalloc((PASSWORD_MAX_LENGTH + 1) * sizeof(char)); + pwd = pvPortMalloc((PASSWORD_MAX_LENGTH + 1) * sizeof(char)); + + if (!(*content == '-')) // Content conforms to query parameters + { + /* Fetch SSID from query parameter */ + if ( httpd_query_key_value(content, "ssid", ssid, SSID_MAX_LENGTH ) != ESP_OK ) + ESP_LOGI(TAG, "Failed to get SSID : %s", ssid); + + /* Fetch password from query parameter */ + if ( httpd_query_key_value(content, "password", pwd_encoded,PASSWORD_MAX_LENGTH ) == ESP_OK ) { + pwd = url_decode(pwd_encoded); + } + else + ESP_LOGI(TAG, "Failed to fetch WiFi password"); + } + else { // Check if Content starts wit Multi-part form data format + extract_field_value(content, "ssid", ssid, SSID_MAX_LENGTH); + extract_field_value(content, "password", pwd_encoded, PASSWORD_MAX_LENGTH); + pwd = url_decode(pwd_encoded); + } + + wifi_update_credentials(ssid, pwd); + + vPortFree(ssid); + vPortFree(pwd_encoded); + vPortFree(pwd); +} + + +bool registerAcctWithServer(char *typeStr, char *customerAccountIdStr, char *customerAccountPasswordStr, char *customerAccountPasswordAgainStr, char *responseStr, uint16_t responseStrSize) +{ + char urlConnectionString[100];// = (char *)pvPortMalloc(100 * sizeof(char)); + char *post_params = modem_get_rxbuf();// = (char *)pvPortMalloc(1024 * sizeof(char)); + char mac_str[20];// = (char *)pvPortMalloc(20 * sizeof(char)); + uint8_t mac_base[6] = {0}; + char chipId[7]; + bool retval = false; + + uint8_t connection_test = 1; + esp_err_t connection_result = ESP_FAIL; + + memset(chipId, 0, 7); + memset(post_params, 0, 100); + + + esp_efuse_mac_get_default(mac_base); + esp_read_mac(mac_base, ESP_MAC_WIFI_STA); + sprintf(mac_str, "%02X%02X%02X%02X%02X%02X", mac_base[0], mac_base[1], mac_base[2], mac_base[3], mac_base[4], mac_base[5]); + + strcpy(chipId, mac_str + 6); + + sprintf(post_params, "type=%s&email=%s&pass=%s&pass_again=%s&sensor=%s&mac=%s&wifi=%s&wallEquip=%d&version=%ld", + typeStr, customerAccountIdStr, customerAccountPasswordStr, customerAccountPasswordAgainStr, chipId, mac_str, wifi_get_ssid(), 0, g_version); + + ESP_LOGI(TAG,"On-boarding string length is: %u\nOn-boarding string content is: %s",strlen(post_params),post_params); + + do + { + /* Setup the URL of the target onboarding server */ + //sprintf(urlConnectionString, MCU_ONBOARDING_URL,connection_test); + strcpy(urlConnectionString, "https://device-status.idealsciences.com"); + ESP_LOGI(TAG, "Attempting connection to on-boarding server: %s", urlConnectionString); + + /* Setup and concatenate the path of the target URL */ + strcat(urlConnectionString, "/sensor-account.php"); + ESP_LOGI(TAG, "Sending POST data to %s", urlConnectionString); + + /* Setup the posting-string to be ON_BOARDING_STR */ + wifi_set_post_str_type(ON_BOARDING_STR); + + /* wait for 5 seconds before doing any connection with the server (just to give some time of disconnection with server if the device has connected to it before that) */ + vTaskDelay(5000/portTICK_PERIOD_MS); + + /* Do the HTTP-POST request with the onboarding string */ + connection_result = http_client_post(urlConnectionString, post_params, responseStr); + + /* Close the connection of http-post */ + http_client_post_stop(); + + /**/ + //sprintf(onboarding_host,ON_BOARDING_SERVER_DOMAIN_NAME,connection_test); + + /* Test the connection with the onboarding server */ + //connection_result = http_client_test(urlConnectionString); + + /* Check the result of the connection */ + if(ESP_OK == connection_result) + break; + + /* Increase the connection_test counter by 1 */ + connection_test++; + + }while(connection_test < 4); + + /* Check if the connection was successful */ + if(connection_test < 4/*ESP_OK == connection_result*/) + { + /* Print this LOG */ + //ESP_LOGI(TAG, "Connected to on-boarding server."); + // + ///* Delay for 8 seconds */ + //vTaskDelay(8000/portTICK_PERIOD_MS); + // + ///**/ + //strcat(urlConnectionString, "/sensor-account.php"); + //ESP_LOGI(TAG, "Sending POST data to %s", urlConnectionString); + // + ///**/ + //wifi_set_post_str_type(ON_BOARDING_STR); + + /**/ + if(ESP_OK == connection_result/*http_client_post(urlConnectionString, post_params, responseStr)*/) + { + ESP_LOGI(TAG, "Response OK\n%s", responseStr); + acc_registered = true; + retval = true; + } + else + { + ESP_LOGI(TAG, "Error Response"); + strcpy(responseStr, "{\"err\":1,\"msg\":\"Server timed out, refresh the page and try again.\"}"); + retval = true; + } + } + else + { + strcpy(responseStr, "{\"err\":1,\"msg\":\"Server or internet unavailable, Server will restart. connect,refresh the page and try again.\"}"); + retval = false; + } + + wifi_set_post_str_type(CHECK_IN_STR); + + return retval; +} + + +#endif + + diff --git a/main/wifi_webServer.h b/main/wifi_webServer.h new file mode 100644 index 0000000..406f9d7 --- /dev/null +++ b/main/wifi_webServer.h @@ -0,0 +1,30 @@ +/* + * tempstick_wifi_server.h + * + * Created on: Jul 28, 2023 + * Author: Sword + */ + +#ifndef MAIN_WIFI_WEBSERVER_H_ +#define MAIN_WIFI_WEBSERVER_H_ + +#include "main.h" +#if (WIFI_NEEDED == 1) +#include "esp_http_server.h" + + +typedef enum +{ + SERVER_IS_STOPPED, + SERVER_IS_RUNNING +}wifi_webServer_status_t; + +bool webserver_get_status(void); +void webserver_stop(httpd_handle_t server); +void webserver_start(void); + +void startOnboardingGetSsidAndPassword(char *content); +void startOnboardingShutdown(void); +bool registerAcctWithServer(char *typeStr, char *customerAccountIdStr, char *customerAccountPasswordStr, char *customerAccountPasswordAgainStr, char *responseStr, uint16_t responseStrSize); +#endif +#endif /* MAIN_WIFI_WEBSERVER_H_ */ diff --git a/partitions.csv b/partitions.csv new file mode 100644 index 0000000..931598b --- /dev/null +++ b/partitions.csv @@ -0,0 +1,7 @@ +# ESP-IDF Partition Table,,,,, +# Name, Type, SubType, Offset, Size, Flags +nvs, data, nvs,0x9000, 0x14000, +otadata, data, ota,0x1d000, 0x2000, +phy_init, data, phy,0x1f000, 0x1000, +ota_0, app, ota_0,0x20000,0x1a0000, +ota_1, app, ota_1,0x1c0000,0x1a0000, diff --git a/release.bat b/release.bat new file mode 100644 index 0000000..a4ade4c --- /dev/null +++ b/release.bat @@ -0,0 +1,14 @@ +rmdir release +del release.zip +mkdir release +cd build +copy *.bin ..\release +cd partition_table +copy *.bin ..\..\release +cd.. +cd bootloader +copy *.bin ..\..\release +cd.. +copy flash_args ..\release +cd.. +tar -a -c -f release.zip release \ No newline at end of file diff --git a/sdkconfig b/sdkconfig new file mode 100644 index 0000000..565d077 --- /dev/null +++ b/sdkconfig @@ -0,0 +1,2022 @@ +# +# Automatically generated file. DO NOT EDIT. +# Espressif IoT Development Framework (ESP-IDF) 5.3.1 Project Configuration +# +CONFIG_SOC_ADC_SUPPORTED=y +CONFIG_SOC_DAC_SUPPORTED=y +CONFIG_SOC_UART_SUPPORTED=y +CONFIG_SOC_TWAI_SUPPORTED=y +CONFIG_SOC_CP_DMA_SUPPORTED=y +CONFIG_SOC_DEDICATED_GPIO_SUPPORTED=y +CONFIG_SOC_GPTIMER_SUPPORTED=y +CONFIG_SOC_SUPPORTS_SECURE_DL_MODE=y +CONFIG_SOC_ULP_FSM_SUPPORTED=y +CONFIG_SOC_RISCV_COPROC_SUPPORTED=y +CONFIG_SOC_USB_OTG_SUPPORTED=y +CONFIG_SOC_PCNT_SUPPORTED=y +CONFIG_SOC_PHY_SUPPORTED=y +CONFIG_SOC_WIFI_SUPPORTED=y +CONFIG_SOC_ULP_SUPPORTED=y +CONFIG_SOC_CCOMP_TIMER_SUPPORTED=y +CONFIG_SOC_ASYNC_MEMCPY_SUPPORTED=y +CONFIG_SOC_EFUSE_KEY_PURPOSE_FIELD=y +CONFIG_SOC_EFUSE_SUPPORTED=y +CONFIG_SOC_TEMP_SENSOR_SUPPORTED=y +CONFIG_SOC_CACHE_SUPPORT_WRAP=y +CONFIG_SOC_RTC_FAST_MEM_SUPPORTED=y +CONFIG_SOC_RTC_SLOW_MEM_SUPPORTED=y +CONFIG_SOC_RTC_MEM_SUPPORTED=y +CONFIG_SOC_PSRAM_DMA_CAPABLE=y +CONFIG_SOC_XT_WDT_SUPPORTED=y +CONFIG_SOC_I2S_SUPPORTED=y +CONFIG_SOC_RMT_SUPPORTED=y +CONFIG_SOC_SDM_SUPPORTED=y +CONFIG_SOC_GPSPI_SUPPORTED=y +CONFIG_SOC_LEDC_SUPPORTED=y +CONFIG_SOC_I2C_SUPPORTED=y +CONFIG_SOC_SYSTIMER_SUPPORTED=y +CONFIG_SOC_AES_SUPPORTED=y +CONFIG_SOC_MPI_SUPPORTED=y +CONFIG_SOC_SHA_SUPPORTED=y +CONFIG_SOC_HMAC_SUPPORTED=y +CONFIG_SOC_DIG_SIGN_SUPPORTED=y +CONFIG_SOC_FLASH_ENC_SUPPORTED=y +CONFIG_SOC_SECURE_BOOT_SUPPORTED=y +CONFIG_SOC_MEMPROT_SUPPORTED=y +CONFIG_SOC_TOUCH_SENSOR_SUPPORTED=y +CONFIG_SOC_BOD_SUPPORTED=y +CONFIG_SOC_CLK_TREE_SUPPORTED=y +CONFIG_SOC_MPU_SUPPORTED=y +CONFIG_SOC_WDT_SUPPORTED=y +CONFIG_SOC_SPI_FLASH_SUPPORTED=y +CONFIG_SOC_RNG_SUPPORTED=y +CONFIG_SOC_LIGHT_SLEEP_SUPPORTED=y +CONFIG_SOC_DEEP_SLEEP_SUPPORTED=y +CONFIG_SOC_LP_PERIPH_SHARE_INTERRUPT=y +CONFIG_SOC_PM_SUPPORTED=y +CONFIG_SOC_XTAL_SUPPORT_40M=y +CONFIG_SOC_ADC_RTC_CTRL_SUPPORTED=y +CONFIG_SOC_ADC_DIG_CTRL_SUPPORTED=y +CONFIG_SOC_ADC_ARBITER_SUPPORTED=y +CONFIG_SOC_ADC_DIG_IIR_FILTER_SUPPORTED=y +CONFIG_SOC_ADC_DIG_IIR_FILTER_UNIT_BINDED=y +CONFIG_SOC_ADC_MONITOR_SUPPORTED=y +CONFIG_SOC_ADC_DMA_SUPPORTED=y +CONFIG_SOC_ADC_PERIPH_NUM=2 +CONFIG_SOC_ADC_MAX_CHANNEL_NUM=10 +CONFIG_SOC_ADC_ATTEN_NUM=4 +CONFIG_SOC_ADC_DIGI_CONTROLLER_NUM=2 +CONFIG_SOC_ADC_PATT_LEN_MAX=32 +CONFIG_SOC_ADC_DIGI_MIN_BITWIDTH=12 +CONFIG_SOC_ADC_DIGI_MAX_BITWIDTH=12 +CONFIG_SOC_ADC_DIGI_IIR_FILTER_NUM=2 +CONFIG_SOC_ADC_DIGI_RESULT_BYTES=2 +CONFIG_SOC_ADC_DIGI_DATA_BYTES_PER_CONV=2 +CONFIG_SOC_ADC_DIGI_MONITOR_NUM=2 +CONFIG_SOC_ADC_SAMPLE_FREQ_THRES_HIGH=83333 +CONFIG_SOC_ADC_SAMPLE_FREQ_THRES_LOW=611 +CONFIG_SOC_ADC_RTC_MIN_BITWIDTH=13 +CONFIG_SOC_ADC_RTC_MAX_BITWIDTH=13 +CONFIG_SOC_ADC_CALIBRATION_V1_SUPPORTED=y +CONFIG_SOC_ADC_SELF_HW_CALI_SUPPORTED=y +CONFIG_SOC_ADC_SHARED_POWER=y +CONFIG_SOC_BROWNOUT_RESET_SUPPORTED=y +CONFIG_SOC_CACHE_WRITEBACK_SUPPORTED=y +CONFIG_SOC_CP_DMA_MAX_BUFFER_SIZE=4095 +CONFIG_SOC_CPU_CORES_NUM=1 +CONFIG_SOC_CPU_INTR_NUM=32 +CONFIG_SOC_CPU_BREAKPOINTS_NUM=2 +CONFIG_SOC_CPU_WATCHPOINTS_NUM=2 +CONFIG_SOC_CPU_WATCHPOINT_MAX_REGION_SIZE=64 +CONFIG_SOC_DAC_CHAN_NUM=2 +CONFIG_SOC_DAC_RESOLUTION=8 +CONFIG_SOC_GPIO_PORT=1 +CONFIG_SOC_GPIO_PIN_COUNT=47 +CONFIG_SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER=y +CONFIG_SOC_GPIO_FILTER_CLK_SUPPORT_APB=y +CONFIG_SOC_GPIO_SUPPORT_RTC_INDEPENDENT=y +CONFIG_SOC_GPIO_SUPPORT_FORCE_HOLD=y +CONFIG_SOC_GPIO_VALID_GPIO_MASK=0x7FFFFFFFFFFF +CONFIG_SOC_GPIO_IN_RANGE_MAX=46 +CONFIG_SOC_GPIO_OUT_RANGE_MAX=45 +CONFIG_SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK=0x00007FFFFC000000 +CONFIG_SOC_GPIO_CLOCKOUT_BY_IO_MUX=y +CONFIG_SOC_GPIO_CLOCKOUT_CHANNEL_NUM=3 +CONFIG_SOC_DEDIC_GPIO_OUT_CHANNELS_NUM=8 +CONFIG_SOC_DEDIC_GPIO_IN_CHANNELS_NUM=8 +CONFIG_SOC_DEDIC_GPIO_ALLOW_REG_ACCESS=y +CONFIG_SOC_DEDIC_GPIO_HAS_INTERRUPT=y +CONFIG_SOC_DEDIC_GPIO_OUT_AUTO_ENABLE=y +CONFIG_SOC_I2C_NUM=2 +CONFIG_SOC_HP_I2C_NUM=2 +CONFIG_SOC_I2C_FIFO_LEN=32 +CONFIG_SOC_I2C_CMD_REG_NUM=16 +CONFIG_SOC_I2C_SUPPORT_SLAVE=y +CONFIG_SOC_I2C_SUPPORT_HW_CLR_BUS=y +CONFIG_SOC_I2C_SUPPORT_REF_TICK=y +CONFIG_SOC_I2C_SUPPORT_APB=y +CONFIG_SOC_I2S_NUM=1 +CONFIG_SOC_I2S_HW_VERSION_1=y +CONFIG_SOC_I2S_SUPPORTS_APLL=y +CONFIG_SOC_I2S_SUPPORTS_PLL_F160M=y +CONFIG_SOC_I2S_SUPPORTS_DMA_EQUAL=y +CONFIG_SOC_I2S_SUPPORTS_LCD_CAMERA=y +CONFIG_SOC_I2S_APLL_MIN_FREQ=250000000 +CONFIG_SOC_I2S_APLL_MAX_FREQ=500000000 +CONFIG_SOC_I2S_APLL_MIN_RATE=10675 +CONFIG_SOC_I2S_LCD_I80_VARIANT=y +CONFIG_SOC_LCD_I80_SUPPORTED=y +CONFIG_SOC_LCD_I80_BUSES=1 +CONFIG_SOC_LCD_I80_BUS_WIDTH=24 +CONFIG_SOC_LEDC_HAS_TIMER_SPECIFIC_MUX=y +CONFIG_SOC_LEDC_SUPPORT_APB_CLOCK=y +CONFIG_SOC_LEDC_SUPPORT_REF_TICK=y +CONFIG_SOC_LEDC_SUPPORT_XTAL_CLOCK=y +CONFIG_SOC_LEDC_CHANNEL_NUM=8 +CONFIG_SOC_LEDC_TIMER_BIT_WIDTH=14 +CONFIG_SOC_LEDC_SUPPORT_FADE_STOP=y +CONFIG_SOC_MMU_LINEAR_ADDRESS_REGION_NUM=5 +CONFIG_SOC_MMU_PERIPH_NUM=1 +CONFIG_SOC_MPU_MIN_REGION_SIZE=0x20000000 +CONFIG_SOC_MPU_REGIONS_MAX_NUM=8 +CONFIG_SOC_PCNT_GROUPS=1 +CONFIG_SOC_PCNT_UNITS_PER_GROUP=4 +CONFIG_SOC_PCNT_CHANNELS_PER_UNIT=2 +CONFIG_SOC_PCNT_THRES_POINT_PER_UNIT=2 +CONFIG_SOC_RMT_GROUPS=1 +CONFIG_SOC_RMT_TX_CANDIDATES_PER_GROUP=4 +CONFIG_SOC_RMT_RX_CANDIDATES_PER_GROUP=4 +CONFIG_SOC_RMT_CHANNELS_PER_GROUP=4 +CONFIG_SOC_RMT_MEM_WORDS_PER_CHANNEL=64 +CONFIG_SOC_RMT_SUPPORT_RX_DEMODULATION=y +CONFIG_SOC_RMT_SUPPORT_TX_ASYNC_STOP=y +CONFIG_SOC_RMT_SUPPORT_TX_LOOP_COUNT=y +CONFIG_SOC_RMT_SUPPORT_TX_SYNCHRO=y +CONFIG_SOC_RMT_SUPPORT_TX_CARRIER_DATA_ONLY=y +CONFIG_SOC_RMT_SUPPORT_REF_TICK=y +CONFIG_SOC_RMT_SUPPORT_APB=y +CONFIG_SOC_RMT_CHANNEL_CLK_INDEPENDENT=y +CONFIG_SOC_RTCIO_PIN_COUNT=22 +CONFIG_SOC_RTCIO_INPUT_OUTPUT_SUPPORTED=y +CONFIG_SOC_RTCIO_HOLD_SUPPORTED=y +CONFIG_SOC_RTCIO_WAKE_SUPPORTED=y +CONFIG_SOC_SDM_GROUPS=1 +CONFIG_SOC_SDM_CHANNELS_PER_GROUP=8 +CONFIG_SOC_SDM_CLK_SUPPORT_APB=y +CONFIG_SOC_SPI_HD_BOTH_INOUT_SUPPORTED=y +CONFIG_SOC_SPI_PERIPH_NUM=3 +CONFIG_SOC_SPI_DMA_CHAN_NUM=3 +CONFIG_SOC_SPI_MAX_CS_NUM=6 +CONFIG_SOC_SPI_MAXIMUM_BUFFER_SIZE=72 +CONFIG_SOC_SPI_MAX_PRE_DIVIDER=8192 +CONFIG_SOC_SPI_SUPPORT_DDRCLK=y +CONFIG_SOC_SPI_SLAVE_SUPPORT_SEG_TRANS=y +CONFIG_SOC_SPI_SUPPORT_CD_SIG=y +CONFIG_SOC_SPI_SUPPORT_CONTINUOUS_TRANS=y +CONFIG_SOC_SPI_SUPPORT_CLK_APB=y +CONFIG_SOC_SPI_SUPPORT_SLAVE_HD_VER2=y +CONFIG_SOC_SPI_PERIPH_SUPPORT_CONTROL_DUMMY_OUT=y +CONFIG_SOC_SPI_SUPPORT_OCT=y +CONFIG_SOC_SPI_SCT_SUPPORTED=y +CONFIG_SOC_SPI_SCT_REG_NUM=27 +CONFIG_SOC_SPI_SCT_BUFFER_NUM_MAX=y +CONFIG_SOC_SPI_SCT_CONF_BITLEN_MAX=0x7FFFFD +CONFIG_SOC_MEMSPI_IS_INDEPENDENT=y +CONFIG_SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED=y +CONFIG_SOC_MEMSPI_SRC_FREQ_40M_SUPPORTED=y +CONFIG_SOC_MEMSPI_SRC_FREQ_26M_SUPPORTED=y +CONFIG_SOC_MEMSPI_SRC_FREQ_20M_SUPPORTED=y +CONFIG_SOC_SYSTIMER_COUNTER_NUM=y +CONFIG_SOC_SYSTIMER_ALARM_NUM=3 +CONFIG_SOC_SYSTIMER_BIT_WIDTH_LO=32 +CONFIG_SOC_SYSTIMER_BIT_WIDTH_HI=32 +CONFIG_SOC_TIMER_GROUPS=2 +CONFIG_SOC_TIMER_GROUP_TIMERS_PER_GROUP=2 +CONFIG_SOC_TIMER_GROUP_COUNTER_BIT_WIDTH=64 +CONFIG_SOC_TIMER_GROUP_SUPPORT_XTAL=y +CONFIG_SOC_TIMER_GROUP_SUPPORT_APB=y +CONFIG_SOC_TIMER_GROUP_TOTAL_TIMERS=4 +CONFIG_SOC_TOUCH_SENSOR_VERSION=2 +CONFIG_SOC_TOUCH_SENSOR_NUM=15 +CONFIG_SOC_TOUCH_SUPPORT_SLEEP_WAKEUP=y +CONFIG_SOC_TOUCH_SUPPORT_WATERPROOF=y +CONFIG_SOC_TOUCH_SUPPORT_PROX_SENSING=y +CONFIG_SOC_TOUCH_PROXIMITY_CHANNEL_NUM=3 +CONFIG_SOC_TOUCH_SAMPLE_CFG_NUM=1 +CONFIG_SOC_TWAI_CONTROLLER_NUM=1 +CONFIG_SOC_TWAI_CLK_SUPPORT_APB=y +CONFIG_SOC_TWAI_BRP_MIN=2 +CONFIG_SOC_TWAI_BRP_MAX=32768 +CONFIG_SOC_TWAI_SUPPORTS_RX_STATUS=y +CONFIG_SOC_UART_NUM=2 +CONFIG_SOC_UART_HP_NUM=2 +CONFIG_SOC_UART_SUPPORT_WAKEUP_INT=y +CONFIG_SOC_UART_SUPPORT_APB_CLK=y +CONFIG_SOC_UART_SUPPORT_REF_TICK=y +CONFIG_SOC_UART_FIFO_LEN=128 +CONFIG_SOC_UART_BITRATE_MAX=5000000 +CONFIG_SOC_SPIRAM_SUPPORTED=y +CONFIG_SOC_SPIRAM_XIP_SUPPORTED=y +CONFIG_SOC_USB_OTG_PERIPH_NUM=1 +CONFIG_SOC_SHA_DMA_MAX_BUFFER_SIZE=3968 +CONFIG_SOC_SHA_SUPPORT_DMA=y +CONFIG_SOC_SHA_SUPPORT_RESUME=y +CONFIG_SOC_SHA_CRYPTO_DMA=y +CONFIG_SOC_SHA_SUPPORT_SHA1=y +CONFIG_SOC_SHA_SUPPORT_SHA224=y +CONFIG_SOC_SHA_SUPPORT_SHA256=y +CONFIG_SOC_SHA_SUPPORT_SHA384=y +CONFIG_SOC_SHA_SUPPORT_SHA512=y +CONFIG_SOC_SHA_SUPPORT_SHA512_224=y +CONFIG_SOC_SHA_SUPPORT_SHA512_256=y +CONFIG_SOC_SHA_SUPPORT_SHA512_T=y +CONFIG_SOC_MPI_MEM_BLOCKS_NUM=4 +CONFIG_SOC_MPI_OPERATIONS_NUM=3 +CONFIG_SOC_RSA_MAX_BIT_LEN=4096 +CONFIG_SOC_AES_SUPPORT_DMA=y +CONFIG_SOC_AES_SUPPORT_GCM=y +CONFIG_SOC_EFUSE_DIS_DOWNLOAD_ICACHE=y +CONFIG_SOC_EFUSE_DIS_DOWNLOAD_DCACHE=y +CONFIG_SOC_EFUSE_HARD_DIS_JTAG=y +CONFIG_SOC_EFUSE_SOFT_DIS_JTAG=y +CONFIG_SOC_EFUSE_DIS_BOOT_REMAP=y +CONFIG_SOC_EFUSE_DIS_LEGACY_SPI_BOOT=y +CONFIG_SOC_EFUSE_DIS_ICACHE=y +CONFIG_SOC_SECURE_BOOT_V2_RSA=y +CONFIG_SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS=3 +CONFIG_SOC_EFUSE_REVOKE_BOOT_KEY_DIGESTS=y +CONFIG_SOC_SUPPORT_SECURE_BOOT_REVOKE_KEY=y +CONFIG_SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX=64 +CONFIG_SOC_FLASH_ENCRYPTION_XTS_AES=y +CONFIG_SOC_FLASH_ENCRYPTION_XTS_AES_OPTIONS=y +CONFIG_SOC_FLASH_ENCRYPTION_XTS_AES_128=y +CONFIG_SOC_FLASH_ENCRYPTION_XTS_AES_256=y +CONFIG_SOC_MEMPROT_CPU_PREFETCH_PAD_SIZE=16 +CONFIG_SOC_MEMPROT_MEM_ALIGN_SIZE=4 +CONFIG_SOC_AES_CRYPTO_DMA=y +CONFIG_SOC_AES_SUPPORT_AES_128=y +CONFIG_SOC_AES_SUPPORT_AES_192=y +CONFIG_SOC_AES_SUPPORT_AES_256=y +CONFIG_SOC_PHY_DIG_REGS_MEM_SIZE=21 +CONFIG_SOC_WIFI_LIGHT_SLEEP_CLK_WIDTH=12 +CONFIG_SOC_SPI_MEM_SUPPORT_AUTO_WAIT_IDLE=y +CONFIG_SOC_SPI_MEM_SUPPORT_SW_SUSPEND=y +CONFIG_SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE=y +CONFIG_SOC_SPI_MEM_SUPPORT_WRAP=y +CONFIG_SOC_PM_SUPPORT_EXT0_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_EXT1_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_EXT_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_WIFI_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_WIFI_PD=y +CONFIG_SOC_PM_SUPPORT_RTC_PERIPH_PD=y +CONFIG_SOC_PM_SUPPORT_RTC_FAST_MEM_PD=y +CONFIG_SOC_PM_SUPPORT_RTC_SLOW_MEM_PD=y +CONFIG_SOC_PM_SUPPORT_RC_FAST_PD=y +CONFIG_SOC_PM_SUPPORT_VDDSDIO_PD=y +CONFIG_SOC_CONFIGURABLE_VDDSDIO_SUPPORTED=y +CONFIG_SOC_CLK_APLL_SUPPORTED=y +CONFIG_SOC_CLK_RC_FAST_D256_SUPPORTED=y +CONFIG_SOC_RTC_SLOW_CLK_SUPPORT_RC_FAST_D256=y +CONFIG_SOC_CLK_RC_FAST_SUPPORT_CALIBRATION=y +CONFIG_SOC_CLK_XTAL32K_SUPPORTED=y +CONFIG_SOC_COEX_HW_PTI=y +CONFIG_SOC_EXTERNAL_COEX_LEADER_TX_LINE=y +CONFIG_SOC_TEMPERATURE_SENSOR_SUPPORT_FAST_RC=y +CONFIG_SOC_WIFI_HW_TSF=y +CONFIG_SOC_WIFI_FTM_SUPPORT=y +CONFIG_SOC_WIFI_WAPI_SUPPORT=y +CONFIG_SOC_WIFI_CSI_SUPPORT=y +CONFIG_SOC_WIFI_MESH_SUPPORT=y +CONFIG_SOC_WIFI_SUPPORT_VARIABLE_BEACON_WINDOW=y +CONFIG_SOC_WIFI_NAN_SUPPORT=y +CONFIG_SOC_ULP_HAS_ADC=y +CONFIG_IDF_CMAKE=y +CONFIG_IDF_TOOLCHAIN="gcc" +CONFIG_IDF_TARGET_ARCH_XTENSA=y +CONFIG_IDF_TARGET_ARCH="xtensa" +CONFIG_IDF_TARGET="esp32s2" +CONFIG_IDF_INIT_VERSION="5.3.1" +CONFIG_IDF_TARGET_ESP32S2=y +CONFIG_IDF_FIRMWARE_CHIP_ID=0x0002 + +# +# Build type +# +CONFIG_APP_BUILD_TYPE_APP_2NDBOOT=y +# CONFIG_APP_BUILD_TYPE_RAM is not set +CONFIG_APP_BUILD_GENERATE_BINARIES=y +CONFIG_APP_BUILD_BOOTLOADER=y +CONFIG_APP_BUILD_USE_FLASH_SECTIONS=y +# CONFIG_APP_REPRODUCIBLE_BUILD is not set +# CONFIG_APP_NO_BLOBS is not set +# end of Build type + +# +# Bootloader config +# + +# +# Bootloader manager +# +CONFIG_BOOTLOADER_COMPILE_TIME_DATE=y +CONFIG_BOOTLOADER_PROJECT_VER=1 +# end of Bootloader manager + +CONFIG_BOOTLOADER_OFFSET_IN_FLASH=0x1000 +CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG is not set +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_PERF is not set +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_NONE is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_NONE is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_ERROR is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_WARN is not set +CONFIG_BOOTLOADER_LOG_LEVEL_INFO=y +# CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE is not set +CONFIG_BOOTLOADER_LOG_LEVEL=3 + +# +# Serial Flash Configurations +# +# CONFIG_BOOTLOADER_FLASH_DC_AWARE is not set +CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT=y +# end of Serial Flash Configurations + +CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y +# CONFIG_BOOTLOADER_FACTORY_RESET is not set +# CONFIG_BOOTLOADER_APP_TEST is not set +CONFIG_BOOTLOADER_REGION_PROTECTION_ENABLE=y +CONFIG_BOOTLOADER_WDT_ENABLE=y +# CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE is not set +CONFIG_BOOTLOADER_WDT_TIME_MS=9000 +# CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_ALWAYS is not set +CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0 +# CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC is not set +# end of Bootloader config + +# +# Security features +# +CONFIG_SECURE_BOOT_V2_RSA_SUPPORTED=y +CONFIG_SECURE_BOOT_V2_PREFERRED=y +# CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT is not set +# CONFIG_SECURE_BOOT is not set +# CONFIG_SECURE_FLASH_ENC_ENABLED is not set +CONFIG_SECURE_ROM_DL_MODE_ENABLED=y +# end of Security features + +# +# Application manager +# +CONFIG_APP_COMPILE_TIME_DATE=y +# CONFIG_APP_EXCLUDE_PROJECT_VER_VAR is not set +# CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR is not set +# CONFIG_APP_PROJECT_VER_FROM_CONFIG is not set +CONFIG_APP_RETRIEVE_LEN_ELF_SHA=16 +# end of Application manager + +CONFIG_ESP_ROM_HAS_CRC_LE=y +CONFIG_ESP_ROM_HAS_MZ_CRC32=y +CONFIG_ESP_ROM_HAS_UART_BUF_SWITCH=y +CONFIG_ESP_ROM_NEEDS_SWSETUP_WORKAROUND=y +CONFIG_ESP_ROM_HAS_REGI2C_BUG=y +CONFIG_ESP_ROM_HAS_NEWLIB=y +CONFIG_ESP_ROM_HAS_NEWLIB_NANO_FORMAT=y +CONFIG_ESP_ROM_HAS_NEWLIB_32BIT_TIME=y +CONFIG_ESP_ROM_USB_OTG_NUM=3 +CONFIG_ESP_ROM_HAS_FLASH_COUNT_PAGES_BUG=y +CONFIG_ESP_ROM_HAS_SW_FLOAT=y +CONFIG_ESP_ROM_USB_SERIAL_DEVICE_NUM=-1 +CONFIG_ESP_ROM_SUPPORT_DEEP_SLEEP_WAKEUP_STUB=y + +# +# Boot ROM Behavior +# +CONFIG_BOOT_ROM_LOG_ALWAYS_ON=y +# CONFIG_BOOT_ROM_LOG_ALWAYS_OFF is not set +# CONFIG_BOOT_ROM_LOG_ON_GPIO_HIGH is not set +# CONFIG_BOOT_ROM_LOG_ON_GPIO_LOW is not set +# end of Boot ROM Behavior + +# +# Serial flasher config +# +# CONFIG_ESPTOOLPY_NO_STUB is not set +# CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set +# CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set +CONFIG_ESPTOOLPY_FLASHMODE_DIO=y +# CONFIG_ESPTOOLPY_FLASHMODE_DOUT is not set +CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR=y +CONFIG_ESPTOOLPY_FLASHMODE="dio" +CONFIG_ESPTOOLPY_FLASHFREQ_80M=y +# CONFIG_ESPTOOLPY_FLASHFREQ_40M is not set +# CONFIG_ESPTOOLPY_FLASHFREQ_26M is not set +# CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set +CONFIG_ESPTOOLPY_FLASHFREQ_80M_DEFAULT=y +CONFIG_ESPTOOLPY_FLASHFREQ="80m" +# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_2MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_32MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE="4MB" +# CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE is not set +CONFIG_ESPTOOLPY_BEFORE_RESET=y +# CONFIG_ESPTOOLPY_BEFORE_NORESET is not set +CONFIG_ESPTOOLPY_BEFORE="default_reset" +CONFIG_ESPTOOLPY_AFTER_RESET=y +# CONFIG_ESPTOOLPY_AFTER_NORESET is not set +CONFIG_ESPTOOLPY_AFTER="hard_reset" +CONFIG_ESPTOOLPY_MONITOR_BAUD=115200 +# end of Serial flasher config + +# +# Partition Table +# +# CONFIG_PARTITION_TABLE_SINGLE_APP is not set +# CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE is not set +# CONFIG_PARTITION_TABLE_TWO_OTA is not set +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_OFFSET=0x8000 +CONFIG_PARTITION_TABLE_MD5=y +# end of Partition Table + +# +# Example Configuration +# +CONFIG_ESP_WIFI_SSID="myssid" +CONFIG_ESP_WIFI_PASSWORD="mypassword" +# end of Example Configuration + +# +# Compiler options +# +# CONFIG_COMPILER_OPTIMIZATION_DEBUG is not set +CONFIG_COMPILER_OPTIMIZATION_SIZE=y +# CONFIG_COMPILER_OPTIMIZATION_PERF is not set +# CONFIG_COMPILER_OPTIMIZATION_NONE is not set +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y +# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT is not set +# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE is not set +CONFIG_COMPILER_FLOAT_LIB_FROM_GCCLIB=y +CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL=2 +# CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT is not set +CONFIG_COMPILER_HIDE_PATHS_MACROS=y +# CONFIG_COMPILER_CXX_EXCEPTIONS is not set +# CONFIG_COMPILER_CXX_RTTI is not set +CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y +# CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set +# CONFIG_COMPILER_STACK_CHECK_MODE_STRONG is not set +# CONFIG_COMPILER_STACK_CHECK_MODE_ALL is not set +# CONFIG_COMPILER_WARN_WRITE_STRINGS is not set +# CONFIG_COMPILER_DISABLE_GCC12_WARNINGS is not set +# CONFIG_COMPILER_DISABLE_GCC13_WARNINGS is not set +# CONFIG_COMPILER_DUMP_RTL_FILES is not set +CONFIG_COMPILER_RT_LIB_GCCLIB=y +CONFIG_COMPILER_RT_LIB_NAME="gcc" +# CONFIG_COMPILER_ORPHAN_SECTIONS_WARNING is not set +CONFIG_COMPILER_ORPHAN_SECTIONS_PLACE=y +# end of Compiler options + +# +# Component config +# + +# +# Application Level Tracing +# +# CONFIG_APPTRACE_DEST_JTAG is not set +CONFIG_APPTRACE_DEST_NONE=y +# CONFIG_APPTRACE_DEST_UART1 is not set +CONFIG_APPTRACE_DEST_UART_NONE=y +CONFIG_APPTRACE_UART_TASK_PRIO=1 +CONFIG_APPTRACE_LOCK_ENABLE=y +# end of Application Level Tracing + +# +# Bluetooth +# +# CONFIG_BT_ENABLED is not set +CONFIG_BT_ALARM_MAX_NUM=50 +# end of Bluetooth + +# +# Console Library +# +# CONFIG_CONSOLE_SORTED_HELP is not set +# end of Console Library + +# +# Driver Configurations +# + +# +# TWAI Configuration +# +# CONFIG_TWAI_ISR_IN_IRAM is not set +CONFIG_TWAI_ERRATA_FIX_LISTEN_ONLY_DOM=y +# end of TWAI Configuration + +# +# Legacy ADC Driver Configuration +# +CONFIG_ADC_DISABLE_DAC=y +# CONFIG_ADC_SUPPRESS_DEPRECATE_WARN is not set + +# +# Legacy ADC Calibration Configuration +# +# CONFIG_ADC_CALI_SUPPRESS_DEPRECATE_WARN is not set +# end of Legacy ADC Calibration Configuration +# end of Legacy ADC Driver Configuration + +# +# Legacy DAC Driver Configurations +# +# CONFIG_DAC_SUPPRESS_DEPRECATE_WARN is not set +# end of Legacy DAC Driver Configurations + +# +# Legacy Timer Group Driver Configurations +# +# CONFIG_GPTIMER_SUPPRESS_DEPRECATE_WARN is not set +# end of Legacy Timer Group Driver Configurations + +# +# Legacy RMT Driver Configurations +# +# CONFIG_RMT_SUPPRESS_DEPRECATE_WARN is not set +# end of Legacy RMT Driver Configurations + +# +# Legacy I2S Driver Configurations +# +# CONFIG_I2S_SUPPRESS_DEPRECATE_WARN is not set +# end of Legacy I2S Driver Configurations + +# +# Legacy PCNT Driver Configurations +# +# CONFIG_PCNT_SUPPRESS_DEPRECATE_WARN is not set +# end of Legacy PCNT Driver Configurations + +# +# Legacy SDM Driver Configurations +# +# CONFIG_SDM_SUPPRESS_DEPRECATE_WARN is not set +# end of Legacy SDM Driver Configurations + +# +# Legacy Temperature Sensor Driver Configurations +# +# CONFIG_TEMP_SENSOR_SUPPRESS_DEPRECATE_WARN is not set +# end of Legacy Temperature Sensor Driver Configurations +# end of Driver Configurations + +# +# eFuse Bit Manager +# +# CONFIG_EFUSE_CUSTOM_TABLE is not set +# CONFIG_EFUSE_VIRTUAL is not set +CONFIG_EFUSE_MAX_BLK_LEN=256 +# end of eFuse Bit Manager + +# +# ESP-TLS +# +CONFIG_ESP_TLS_USING_MBEDTLS=y +CONFIG_ESP_TLS_USE_DS_PERIPHERAL=y +# CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS is not set +# CONFIG_ESP_TLS_SERVER_SESSION_TICKETS is not set +# CONFIG_ESP_TLS_SERVER_CERT_SELECT_HOOK is not set +# CONFIG_ESP_TLS_SERVER_MIN_AUTH_MODE_OPTIONAL is not set +# CONFIG_ESP_TLS_PSK_VERIFICATION is not set +# CONFIG_ESP_TLS_INSECURE is not set +# end of ESP-TLS + +# +# ADC and ADC Calibration +# +# CONFIG_ADC_ONESHOT_CTRL_FUNC_IN_IRAM is not set +# CONFIG_ADC_CONTINUOUS_ISR_IRAM_SAFE is not set +CONFIG_ADC_DISABLE_DAC_OUTPUT=y +# CONFIG_ADC_ENABLE_DEBUG_LOG is not set +# end of ADC and ADC Calibration + +# +# Wireless Coexistence +# +CONFIG_ESP_COEX_ENABLED=y +# CONFIG_ESP_COEX_EXTERNAL_COEXIST_ENABLE is not set +# end of Wireless Coexistence + +# +# Common ESP-related +# +CONFIG_ESP_ERR_TO_NAME_LOOKUP=y +# end of Common ESP-related + +# +# ESP-Driver:DAC Configurations +# +# CONFIG_DAC_CTRL_FUNC_IN_IRAM is not set +# CONFIG_DAC_ISR_IRAM_SAFE is not set +# CONFIG_DAC_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:DAC Configurations + +# +# ESP-Driver:GPIO Configurations +# +# CONFIG_GPIO_CTRL_FUNC_IN_IRAM is not set +# end of ESP-Driver:GPIO Configurations + +# +# ESP-Driver:GPTimer Configurations +# +CONFIG_GPTIMER_ISR_HANDLER_IN_IRAM=y +# CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM is not set +# CONFIG_GPTIMER_ISR_IRAM_SAFE is not set +# CONFIG_GPTIMER_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:GPTimer Configurations + +# +# ESP-Driver:I2C Configurations +# +# CONFIG_I2C_ISR_IRAM_SAFE is not set +# CONFIG_I2C_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:I2C Configurations + +# +# ESP-Driver:I2S Configurations +# +# CONFIG_I2S_ISR_IRAM_SAFE is not set +# CONFIG_I2S_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:I2S Configurations + +# +# ESP-Driver:LEDC Configurations +# +# CONFIG_LEDC_CTRL_FUNC_IN_IRAM is not set +# end of ESP-Driver:LEDC Configurations + +# +# ESP-Driver:PCNT Configurations +# +# CONFIG_PCNT_CTRL_FUNC_IN_IRAM is not set +# CONFIG_PCNT_ISR_IRAM_SAFE is not set +# CONFIG_PCNT_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:PCNT Configurations + +# +# ESP-Driver:RMT Configurations +# +# CONFIG_RMT_ISR_IRAM_SAFE is not set +# CONFIG_RMT_RECV_FUNC_IN_IRAM is not set +# CONFIG_RMT_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:RMT Configurations + +# +# ESP-Driver:Sigma Delta Modulator Configurations +# +# CONFIG_SDM_CTRL_FUNC_IN_IRAM is not set +# CONFIG_SDM_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:Sigma Delta Modulator Configurations + +# +# ESP-Driver:SPI Configurations +# +# CONFIG_SPI_MASTER_IN_IRAM is not set +CONFIG_SPI_MASTER_ISR_IN_IRAM=y +# CONFIG_SPI_SLAVE_IN_IRAM is not set +CONFIG_SPI_SLAVE_ISR_IN_IRAM=y +# end of ESP-Driver:SPI Configurations + +# +# ESP-Driver:Touch Sensor Configurations +# +# CONFIG_TOUCH_CTRL_FUNC_IN_IRAM is not set +# CONFIG_TOUCH_ISR_IRAM_SAFE is not set +# CONFIG_TOUCH_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:Touch Sensor Configurations + +# +# ESP-Driver:Temperature Sensor Configurations +# +# CONFIG_TEMP_SENSOR_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:Temperature Sensor Configurations + +# +# ESP-Driver:UART Configurations +# +# CONFIG_UART_ISR_IN_IRAM is not set +# end of ESP-Driver:UART Configurations + +# +# Ethernet +# +CONFIG_ETH_ENABLED=y +CONFIG_ETH_USE_SPI_ETHERNET=y +# CONFIG_ETH_SPI_ETHERNET_DM9051 is not set +# CONFIG_ETH_SPI_ETHERNET_W5500 is not set +# CONFIG_ETH_SPI_ETHERNET_KSZ8851SNL is not set +# CONFIG_ETH_USE_OPENETH is not set +# CONFIG_ETH_TRANSMIT_MUTEX is not set +# end of Ethernet + +# +# Event Loop Library +# +# CONFIG_ESP_EVENT_LOOP_PROFILING is not set +CONFIG_ESP_EVENT_POST_FROM_ISR=y +CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=y +# end of Event Loop Library + +# +# GDB Stub +# +CONFIG_ESP_GDBSTUB_ENABLED=y +# CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME is not set +CONFIG_ESP_GDBSTUB_SUPPORT_TASKS=y +CONFIG_ESP_GDBSTUB_MAX_TASKS=32 +# end of GDB Stub + +# +# ESP HTTP client +# +CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y +# CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set +# CONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH is not set +# CONFIG_ESP_HTTP_CLIENT_ENABLE_CUSTOM_TRANSPORT is not set +# end of ESP HTTP client + +# +# HTTP Server +# +CONFIG_HTTPD_MAX_REQ_HDR_LEN=512 +CONFIG_HTTPD_MAX_URI_LEN=512 +CONFIG_HTTPD_ERR_RESP_NO_DELAY=y +CONFIG_HTTPD_PURGE_BUF_LEN=32 +# CONFIG_HTTPD_LOG_PURGE_DATA is not set +# CONFIG_HTTPD_WS_SUPPORT is not set +# CONFIG_HTTPD_QUEUE_WORK_BLOCKING is not set +# end of HTTP Server + +# +# ESP HTTPS OTA +# +# CONFIG_ESP_HTTPS_OTA_DECRYPT_CB is not set +# CONFIG_ESP_HTTPS_OTA_ALLOW_HTTP is not set +# end of ESP HTTPS OTA + +# +# ESP HTTPS server +# +# end of ESP HTTPS server + +# +# Hardware Settings +# + +# +# Chip revision +# +CONFIG_ESP32S2_REV_MIN_0=y +# CONFIG_ESP32S2_REV_MIN_1 is not set +CONFIG_ESP32S2_REV_MIN_FULL=0 +CONFIG_ESP_REV_MIN_FULL=0 + +# +# Maximum Supported ESP32-S2 Revision (Rev v1.99) +# +CONFIG_ESP32S2_REV_MAX_FULL=199 +CONFIG_ESP_REV_MAX_FULL=199 +# end of Chip revision + +# +# MAC Config +# +CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_STA=y +CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_AP=y +CONFIG_ESP_MAC_UNIVERSAL_MAC_ADDRESSES_TWO=y +CONFIG_ESP_MAC_UNIVERSAL_MAC_ADDRESSES=2 +# CONFIG_ESP32S2_UNIVERSAL_MAC_ADDRESSES_ONE is not set +CONFIG_ESP32S2_UNIVERSAL_MAC_ADDRESSES_TWO=y +CONFIG_ESP32S2_UNIVERSAL_MAC_ADDRESSES=2 +# CONFIG_ESP_MAC_USE_CUSTOM_MAC_AS_BASE_MAC is not set +# end of MAC Config + +# +# Sleep Config +# +# CONFIG_ESP_SLEEP_POWER_DOWN_FLASH is not set +CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND=y +# CONFIG_ESP_SLEEP_MSPI_NEED_ALL_IO_PU is not set +CONFIG_ESP_SLEEP_RTC_BUS_ISO_WORKAROUND=y +# CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND is not set +CONFIG_ESP_SLEEP_WAIT_FLASH_READY_EXTRA_DELAY=0 +# CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION is not set +# CONFIG_ESP_SLEEP_DEBUG is not set +CONFIG_ESP_SLEEP_GPIO_ENABLE_INTERNAL_RESISTORS=y +# end of Sleep Config + +# +# RTC Clock Config +# +CONFIG_RTC_CLK_SRC_INT_RC=y +# CONFIG_RTC_CLK_SRC_EXT_CRYS is not set +# CONFIG_RTC_CLK_SRC_EXT_OSC is not set +# CONFIG_RTC_CLK_SRC_INT_8MD256 is not set +CONFIG_RTC_CLK_CAL_CYCLES=576 +# end of RTC Clock Config + +# +# Peripheral Control +# +CONFIG_PERIPH_CTRL_FUNC_IN_IRAM=y +# end of Peripheral Control + +# +# Main XTAL Config +# +CONFIG_XTAL_FREQ_40=y +CONFIG_XTAL_FREQ=40 +# end of Main XTAL Config + +CONFIG_ESP_SPI_BUS_LOCK_ISR_FUNCS_IN_IRAM=y +# end of Hardware Settings + +# +# LCD and Touch Panel +# + +# +# LCD Touch Drivers are maintained in the IDF Component Registry +# + +# +# LCD Peripheral Configuration +# +CONFIG_LCD_PANEL_IO_FORMAT_BUF_SIZE=32 +# CONFIG_LCD_ENABLE_DEBUG_LOG is not set +# end of LCD Peripheral Configuration +# end of LCD and Touch Panel + +# +# ESP NETIF Adapter +# +CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL=120 +CONFIG_ESP_NETIF_TCPIP_LWIP=y +# CONFIG_ESP_NETIF_LOOPBACK is not set +CONFIG_ESP_NETIF_USES_TCPIP_WITH_BSD_API=y +# CONFIG_ESP_NETIF_RECEIVE_REPORT_ERRORS is not set +# CONFIG_ESP_NETIF_L2_TAP is not set +# CONFIG_ESP_NETIF_BRIDGE_EN is not set +# end of ESP NETIF Adapter + +# +# Partition API Configuration +# +# end of Partition API Configuration + +# +# PHY +# +CONFIG_ESP_PHY_ENABLED=y +CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE=y +# CONFIG_ESP_PHY_INIT_DATA_IN_PARTITION is not set +CONFIG_ESP_PHY_MAX_WIFI_TX_POWER=20 +CONFIG_ESP_PHY_MAX_TX_POWER=20 +CONFIG_ESP_PHY_RF_CAL_PARTIAL=y +# CONFIG_ESP_PHY_RF_CAL_NONE is not set +# CONFIG_ESP_PHY_RF_CAL_FULL is not set +CONFIG_ESP_PHY_CALIBRATION_MODE=0 +# CONFIG_ESP_PHY_PLL_TRACK_DEBUG is not set +# end of PHY + +# +# Power Management +# +# CONFIG_PM_ENABLE is not set +# end of Power Management + +# +# ESP PSRAM +# +# CONFIG_SPIRAM is not set +# end of ESP PSRAM + +# +# ESP Ringbuf +# +# CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH is not set +# end of ESP Ringbuf + +# +# ESP System Settings +# +CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_80=y +# CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_160 is not set +# CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240 is not set +CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=80 + +# +# Cache config +# +CONFIG_ESP32S2_INSTRUCTION_CACHE_8KB=y +# CONFIG_ESP32S2_INSTRUCTION_CACHE_16KB is not set +# CONFIG_ESP32S2_INSTRUCTION_CACHE_LINE_16B is not set +CONFIG_ESP32S2_INSTRUCTION_CACHE_LINE_32B=y +# CONFIG_ESP32S2_DATA_CACHE_0KB is not set +CONFIG_ESP32S2_DATA_CACHE_8KB=y +# CONFIG_ESP32S2_DATA_CACHE_16KB is not set +# CONFIG_ESP32S2_DATA_CACHE_LINE_16B is not set +CONFIG_ESP32S2_DATA_CACHE_LINE_32B=y +# CONFIG_ESP32S2_INSTRUCTION_CACHE_WRAP is not set +# CONFIG_ESP32S2_DATA_CACHE_WRAP is not set +# end of Cache config + +# +# Memory +# +# CONFIG_ESP32S2_RTCDATA_IN_FAST_MEM is not set +# CONFIG_ESP32S2_USE_FIXED_STATIC_RAM_SIZE is not set +# end of Memory + +# +# Trace memory +# +# CONFIG_ESP32S2_TRAX is not set +CONFIG_ESP32S2_TRACEMEM_RESERVE_DRAM=0x0 +# end of Trace memory + +# CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT is not set +CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT=y +# CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set +# CONFIG_ESP_SYSTEM_PANIC_GDBSTUB is not set +CONFIG_ESP_SYSTEM_PANIC_REBOOT_DELAY_SECONDS=0 +CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE=y +CONFIG_ESP_SYSTEM_RTC_FAST_MEM_AS_HEAP_DEPCHECK=y +CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP=y + +# +# Memory protection +# +CONFIG_ESP_SYSTEM_MEMPROT_FEATURE=y +CONFIG_ESP_SYSTEM_MEMPROT_FEATURE_LOCK=y +# end of Memory protection + +CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32 +CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=3584 +CONFIG_ESP_MAIN_TASK_AFFINITY_CPU0=y +# CONFIG_ESP_MAIN_TASK_AFFINITY_NO_AFFINITY is not set +CONFIG_ESP_MAIN_TASK_AFFINITY=0x0 +CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE=2048 +CONFIG_ESP_CONSOLE_UART_DEFAULT=y +# CONFIG_ESP_CONSOLE_USB_CDC is not set +# CONFIG_ESP_CONSOLE_UART_CUSTOM is not set +# CONFIG_ESP_CONSOLE_NONE is not set +CONFIG_ESP_CONSOLE_UART=y +CONFIG_ESP_CONSOLE_UART_NUM=0 +CONFIG_ESP_CONSOLE_ROM_SERIAL_PORT_NUM=0 +CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 +CONFIG_ESP_INT_WDT=y +CONFIG_ESP_INT_WDT_TIMEOUT_MS=300 +CONFIG_ESP_TASK_WDT_EN=y +CONFIG_ESP_TASK_WDT_INIT=y +# CONFIG_ESP_TASK_WDT_PANIC is not set +CONFIG_ESP_TASK_WDT_TIMEOUT_S=5 +CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=y +# CONFIG_ESP_PANIC_HANDLER_IRAM is not set +# CONFIG_ESP_DEBUG_STUBS_ENABLE is not set +CONFIG_ESP_DEBUG_OCDAWARE=y +CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_4=y + +# +# Brownout Detector +# +# CONFIG_ESP_BROWNOUT_DET is not set +# end of Brownout Detector + +# CONFIG_ESP32S2_KEEP_USB_ALIVE is not set +CONFIG_ESP_SYSTEM_BROWNOUT_INTR=y +# end of ESP System Settings + +# +# IPC (Inter-Processor Call) +# +CONFIG_ESP_IPC_TASK_STACK_SIZE=1024 +# end of IPC (Inter-Processor Call) + +# +# ESP Timer (High Resolution Timer) +# +# CONFIG_ESP_TIMER_PROFILING is not set +CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER=y +CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER=y +CONFIG_ESP_TIMER_TASK_STACK_SIZE=3584 +CONFIG_ESP_TIMER_INTERRUPT_LEVEL=1 +# CONFIG_ESP_TIMER_SHOW_EXPERIMENTAL is not set +CONFIG_ESP_TIMER_TASK_AFFINITY=0x0 +CONFIG_ESP_TIMER_TASK_AFFINITY_CPU0=y +CONFIG_ESP_TIMER_ISR_AFFINITY_CPU0=y +# CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD is not set +CONFIG_ESP_TIMER_IMPL_SYSTIMER=y +# end of ESP Timer (High Resolution Timer) + +# +# Wi-Fi +# +CONFIG_ESP_WIFI_ENABLED=y +CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM=10 +CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM=32 +# CONFIG_ESP_WIFI_STATIC_TX_BUFFER is not set +CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER=y +CONFIG_ESP_WIFI_TX_BUFFER_TYPE=1 +CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER_NUM=32 +CONFIG_ESP_WIFI_STATIC_RX_MGMT_BUFFER=y +# CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUFFER is not set +CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUF=0 +CONFIG_ESP_WIFI_RX_MGMT_BUF_NUM_DEF=5 +# CONFIG_ESP_WIFI_CSI_ENABLED is not set +# CONFIG_ESP_WIFI_AMPDU_TX_ENABLED is not set +CONFIG_ESP_WIFI_AMPDU_RX_ENABLED=y +CONFIG_ESP_WIFI_RX_BA_WIN=6 +CONFIG_ESP_WIFI_NVS_ENABLED=y +CONFIG_ESP_WIFI_SOFTAP_BEACON_MAX_LEN=752 +CONFIG_ESP_WIFI_MGMT_SBUF_NUM=32 +# CONFIG_ESP_WIFI_IRAM_OPT is not set +# CONFIG_ESP_WIFI_EXTRA_IRAM_OPT is not set +CONFIG_ESP_WIFI_RX_IRAM_OPT=y +CONFIG_ESP_WIFI_ENABLE_WPA3_SAE=y +CONFIG_ESP_WIFI_ENABLE_SAE_PK=y +CONFIG_ESP_WIFI_SOFTAP_SAE_SUPPORT=y +CONFIG_ESP_WIFI_ENABLE_WPA3_OWE_STA=y +# CONFIG_ESP_WIFI_SLP_IRAM_OPT is not set +CONFIG_ESP_WIFI_SLP_DEFAULT_MIN_ACTIVE_TIME=50 +CONFIG_ESP_WIFI_SLP_DEFAULT_MAX_ACTIVE_TIME=10 +CONFIG_ESP_WIFI_SLP_DEFAULT_WAIT_BROADCAST_DATA_TIME=15 +# CONFIG_ESP_WIFI_FTM_ENABLE is not set +# CONFIG_ESP_WIFI_STA_DISCONNECTED_PM_ENABLE is not set +# CONFIG_ESP_WIFI_GMAC_SUPPORT is not set +CONFIG_ESP_WIFI_SOFTAP_SUPPORT=y +# CONFIG_ESP_WIFI_SLP_BEACON_LOST_OPT is not set +CONFIG_ESP_WIFI_ESPNOW_MAX_ENCRYPT_NUM=7 +# CONFIG_ESP_WIFI_NAN_ENABLE is not set +CONFIG_ESP_WIFI_MBEDTLS_CRYPTO=y +CONFIG_ESP_WIFI_MBEDTLS_TLS_CLIENT=y +# CONFIG_ESP_WIFI_WAPI_PSK is not set +# CONFIG_ESP_WIFI_11KV_SUPPORT is not set +# CONFIG_ESP_WIFI_MBO_SUPPORT is not set +# CONFIG_ESP_WIFI_DPP_SUPPORT is not set +# CONFIG_ESP_WIFI_11R_SUPPORT is not set +# CONFIG_ESP_WIFI_WPS_SOFTAP_REGISTRAR is not set + +# +# WPS Configuration Options +# +# CONFIG_ESP_WIFI_WPS_STRICT is not set +# CONFIG_ESP_WIFI_WPS_PASSPHRASE is not set +# end of WPS Configuration Options + +# CONFIG_ESP_WIFI_DEBUG_PRINT is not set +# CONFIG_ESP_WIFI_TESTING_OPTIONS is not set +CONFIG_ESP_WIFI_ENTERPRISE_SUPPORT=y +# CONFIG_ESP_WIFI_ENT_FREE_DYNAMIC_BUFFER is not set +# end of Wi-Fi + +# +# Core dump +# +# CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH is not set +# CONFIG_ESP_COREDUMP_ENABLE_TO_UART is not set +CONFIG_ESP_COREDUMP_ENABLE_TO_NONE=y +# end of Core dump + +# +# FAT Filesystem support +# +CONFIG_FATFS_VOLUME_COUNT=2 +CONFIG_FATFS_LFN_NONE=y +# CONFIG_FATFS_LFN_HEAP is not set +# CONFIG_FATFS_LFN_STACK is not set +# CONFIG_FATFS_SECTOR_512 is not set +CONFIG_FATFS_SECTOR_4096=y +# CONFIG_FATFS_CODEPAGE_DYNAMIC is not set +CONFIG_FATFS_CODEPAGE_437=y +# CONFIG_FATFS_CODEPAGE_720 is not set +# CONFIG_FATFS_CODEPAGE_737 is not set +# CONFIG_FATFS_CODEPAGE_771 is not set +# CONFIG_FATFS_CODEPAGE_775 is not set +# CONFIG_FATFS_CODEPAGE_850 is not set +# CONFIG_FATFS_CODEPAGE_852 is not set +# CONFIG_FATFS_CODEPAGE_855 is not set +# CONFIG_FATFS_CODEPAGE_857 is not set +# CONFIG_FATFS_CODEPAGE_860 is not set +# CONFIG_FATFS_CODEPAGE_861 is not set +# CONFIG_FATFS_CODEPAGE_862 is not set +# CONFIG_FATFS_CODEPAGE_863 is not set +# CONFIG_FATFS_CODEPAGE_864 is not set +# CONFIG_FATFS_CODEPAGE_865 is not set +# CONFIG_FATFS_CODEPAGE_866 is not set +# CONFIG_FATFS_CODEPAGE_869 is not set +# CONFIG_FATFS_CODEPAGE_932 is not set +# CONFIG_FATFS_CODEPAGE_936 is not set +# CONFIG_FATFS_CODEPAGE_949 is not set +# CONFIG_FATFS_CODEPAGE_950 is not set +CONFIG_FATFS_CODEPAGE=437 +CONFIG_FATFS_FS_LOCK=0 +CONFIG_FATFS_TIMEOUT_MS=10000 +CONFIG_FATFS_PER_FILE_CACHE=y +# CONFIG_FATFS_USE_FASTSEEK is not set +CONFIG_FATFS_VFS_FSTAT_BLKSIZE=0 +# CONFIG_FATFS_IMMEDIATE_FSYNC is not set +# CONFIG_FATFS_USE_LABEL is not set +CONFIG_FATFS_LINK_LOCK=y +# end of FAT Filesystem support + +# +# FreeRTOS +# + +# +# Kernel +# +# CONFIG_FREERTOS_SMP is not set +CONFIG_FREERTOS_UNICORE=y +CONFIG_FREERTOS_HZ=100 +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set +# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL is not set +CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536 +# CONFIG_FREERTOS_USE_IDLE_HOOK is not set +# CONFIG_FREERTOS_USE_TICK_HOOK is not set +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 +# CONFIG_FREERTOS_ENABLE_BACKWARD_COMPATIBILITY is not set +CONFIG_FREERTOS_TIMER_SERVICE_TASK_NAME="Tmr Svc" +# CONFIG_FREERTOS_TIMER_TASK_AFFINITY_CPU0 is not set +CONFIG_FREERTOS_TIMER_TASK_NO_AFFINITY=y +CONFIG_FREERTOS_TIMER_SERVICE_TASK_CORE_AFFINITY=0x7FFFFFFF +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=1 +# CONFIG_FREERTOS_USE_TRACE_FACILITY is not set +# CONFIG_FREERTOS_USE_LIST_DATA_INTEGRITY_CHECK_BYTES is not set +# CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set +# CONFIG_FREERTOS_USE_APPLICATION_TASK_TAG is not set +# end of Kernel + +# +# Port +# +# CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set +CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS=y +# CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK is not set +# CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP is not set +CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y +CONFIG_FREERTOS_ISR_STACKSIZE=1536 +CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y +CONFIG_FREERTOS_TICK_SUPPORT_CORETIMER=y +CONFIG_FREERTOS_CORETIMER_0=y +# CONFIG_FREERTOS_CORETIMER_1 is not set +CONFIG_FREERTOS_SYSTICK_USES_CCOUNT=y +# CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH is not set +# CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set +# end of Port + +CONFIG_FREERTOS_PORT=y +CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF +CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y +CONFIG_FREERTOS_DEBUG_OCDAWARE=y +CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT=y +CONFIG_FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH=y +CONFIG_FREERTOS_NUMBER_OF_CORES=1 +# end of FreeRTOS + +# +# Hardware Abstraction Layer (HAL) and Low Level (LL) +# +CONFIG_HAL_ASSERTION_EQUALS_SYSTEM=y +# CONFIG_HAL_ASSERTION_DISABLE is not set +# CONFIG_HAL_ASSERTION_SILENT is not set +# CONFIG_HAL_ASSERTION_ENABLE is not set +CONFIG_HAL_DEFAULT_ASSERTION_LEVEL=2 +CONFIG_HAL_SPI_MASTER_FUNC_IN_IRAM=y +CONFIG_HAL_SPI_SLAVE_FUNC_IN_IRAM=y +# end of Hardware Abstraction Layer (HAL) and Low Level (LL) + +# +# Heap memory debugging +# +CONFIG_HEAP_POISONING_DISABLED=y +# CONFIG_HEAP_POISONING_LIGHT is not set +# CONFIG_HEAP_POISONING_COMPREHENSIVE is not set +CONFIG_HEAP_TRACING_OFF=y +# CONFIG_HEAP_TRACING_STANDALONE is not set +# CONFIG_HEAP_TRACING_TOHOST is not set +# CONFIG_HEAP_USE_HOOKS is not set +# CONFIG_HEAP_TASK_TRACKING is not set +# CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS is not set +# CONFIG_HEAP_PLACE_FUNCTION_INTO_FLASH is not set +# end of Heap memory debugging + +# +# Log output +# +# CONFIG_LOG_DEFAULT_LEVEL_NONE is not set +# CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set +# CONFIG_LOG_DEFAULT_LEVEL_WARN is not set +CONFIG_LOG_DEFAULT_LEVEL_INFO=y +# CONFIG_LOG_DEFAULT_LEVEL_DEBUG is not set +# CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set +CONFIG_LOG_DEFAULT_LEVEL=3 +CONFIG_LOG_MAXIMUM_EQUALS_DEFAULT=y +# CONFIG_LOG_MAXIMUM_LEVEL_DEBUG is not set +# CONFIG_LOG_MAXIMUM_LEVEL_VERBOSE is not set +CONFIG_LOG_MAXIMUM_LEVEL=3 +# CONFIG_LOG_MASTER_LEVEL is not set +CONFIG_LOG_COLORS=y +# CONFIG_LOG_TIMESTAMP_SOURCE_RTOS is not set +CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM=y +# end of Log output + +# +# LWIP +# +CONFIG_LWIP_ENABLE=y +CONFIG_LWIP_LOCAL_HOSTNAME="espressif" +# CONFIG_LWIP_NETIF_API is not set +CONFIG_LWIP_TCPIP_TASK_PRIO=18 +# CONFIG_LWIP_TCPIP_CORE_LOCKING is not set +# CONFIG_LWIP_CHECK_THREAD_SAFETY is not set +CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y +# CONFIG_LWIP_L2_TO_L3_COPY is not set +# CONFIG_LWIP_IRAM_OPTIMIZATION is not set +# CONFIG_LWIP_EXTRA_IRAM_OPTIMIZATION is not set +CONFIG_LWIP_TIMERS_ONDEMAND=y +CONFIG_LWIP_MAX_SOCKETS=10 +# CONFIG_LWIP_USE_ONLY_LWIP_SELECT is not set +# CONFIG_LWIP_SO_LINGER is not set +CONFIG_LWIP_SO_REUSE=y +CONFIG_LWIP_SO_REUSE_RXTOALL=y +# CONFIG_LWIP_SO_RCVBUF is not set +# CONFIG_LWIP_NETBUF_RECVINFO is not set +CONFIG_LWIP_IP_DEFAULT_TTL=64 +CONFIG_LWIP_IP4_FRAG=y +# CONFIG_LWIP_IP4_REASSEMBLY is not set +CONFIG_LWIP_IP_REASS_MAX_PBUFS=10 +# CONFIG_LWIP_IP_FORWARD is not set +# CONFIG_LWIP_STATS is not set +CONFIG_LWIP_ESP_GRATUITOUS_ARP=y +CONFIG_LWIP_GARP_TMR_INTERVAL=60 +CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 +CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y +# CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set +CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y +# CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set +CONFIG_LWIP_DHCP_OPTIONS_LEN=68 +CONFIG_LWIP_NUM_NETIF_CLIENT_DATA=0 +CONFIG_LWIP_DHCP_COARSE_TIMER_SECS=1 + +# +# DHCP server +# +CONFIG_LWIP_DHCPS=y +CONFIG_LWIP_DHCPS_LEASE_UNIT=60 +CONFIG_LWIP_DHCPS_MAX_STATION_NUM=8 +CONFIG_LWIP_DHCPS_STATIC_ENTRIES=y +# end of DHCP server + +# CONFIG_LWIP_AUTOIP is not set +CONFIG_LWIP_IPV4=y +# CONFIG_LWIP_IPV6 is not set +# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set +CONFIG_LWIP_NETIF_LOOPBACK=y +CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 + +# +# TCP +# +CONFIG_LWIP_MAX_ACTIVE_TCP=16 +CONFIG_LWIP_MAX_LISTENING_TCP=16 +CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y +CONFIG_LWIP_TCP_MAXRTX=12 +CONFIG_LWIP_TCP_SYNMAXRTX=12 +CONFIG_LWIP_TCP_MSS=1440 +CONFIG_LWIP_TCP_TMR_INTERVAL=250 +CONFIG_LWIP_TCP_MSL=60000 +CONFIG_LWIP_TCP_FIN_WAIT_TIMEOUT=20000 +CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5744 +CONFIG_LWIP_TCP_WND_DEFAULT=5744 +CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 +CONFIG_LWIP_TCP_ACCEPTMBOX_SIZE=6 +CONFIG_LWIP_TCP_QUEUE_OOSEQ=y +CONFIG_LWIP_TCP_OOSEQ_TIMEOUT=6 +CONFIG_LWIP_TCP_OOSEQ_MAX_PBUFS=4 +# CONFIG_LWIP_TCP_SACK_OUT is not set +CONFIG_LWIP_TCP_OVERSIZE_MSS=y +# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set +CONFIG_LWIP_TCP_RTO_TIME=1500 +# end of TCP + +# +# UDP +# +CONFIG_LWIP_MAX_UDP_PCBS=16 +CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 +# end of UDP + +# +# Checksums +# +# CONFIG_LWIP_CHECKSUM_CHECK_IP is not set +# CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set +# CONFIG_LWIP_CHECKSUM_CHECK_ICMP is not set +# end of Checksums + +CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY=y +# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU0 is not set +CONFIG_LWIP_TCPIP_TASK_AFFINITY=0x7FFFFFFF +# CONFIG_LWIP_PPP_SUPPORT is not set +# CONFIG_LWIP_SLIP_SUPPORT is not set + +# +# ICMP +# +# CONFIG_LWIP_ICMP is not set +# end of ICMP + +# +# LWIP RAW API +# +CONFIG_LWIP_MAX_RAW_PCBS=16 +# end of LWIP RAW API + +# +# SNTP +# +CONFIG_LWIP_SNTP_MAX_SERVERS=1 +# CONFIG_LWIP_DHCP_GET_NTP_SRV is not set +CONFIG_LWIP_SNTP_UPDATE_DELAY=3600000 +CONFIG_LWIP_SNTP_STARTUP_DELAY=y +CONFIG_LWIP_SNTP_MAXIMUM_STARTUP_DELAY=5000 +# end of SNTP + +# +# DNS +# +CONFIG_LWIP_DNS_MAX_SERVERS=3 +# CONFIG_LWIP_FALLBACK_DNS_SERVER_SUPPORT is not set +# end of DNS + +CONFIG_LWIP_BRIDGEIF_MAX_PORTS=7 +CONFIG_LWIP_ESP_LWIP_ASSERT=y + +# +# Hooks +# +# CONFIG_LWIP_HOOK_TCP_ISN_NONE is not set +CONFIG_LWIP_HOOK_TCP_ISN_DEFAULT=y +# CONFIG_LWIP_HOOK_TCP_ISN_CUSTOM is not set +CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_NONE=y +# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_DEFAULT is not set +# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_CUSTOM is not set +# end of Hooks + +CONFIG_LWIP_DEBUG=y +CONFIG_LWIP_DEBUG_ESP_LOG=y +CONFIG_LWIP_NETIF_DEBUG=y +# CONFIG_LWIP_PBUF_DEBUG is not set +# CONFIG_LWIP_ETHARP_DEBUG is not set +# CONFIG_LWIP_API_LIB_DEBUG is not set +# CONFIG_LWIP_SOCKETS_DEBUG is not set +# CONFIG_LWIP_IP_DEBUG is not set +# CONFIG_LWIP_DHCP_STATE_DEBUG is not set +# CONFIG_LWIP_DHCP_DEBUG is not set +# CONFIG_LWIP_IP6_DEBUG is not set +# CONFIG_LWIP_ICMP6_DEBUG is not set +# CONFIG_LWIP_TCP_DEBUG is not set +# CONFIG_LWIP_UDP_DEBUG is not set +# CONFIG_LWIP_SNTP_DEBUG is not set +# CONFIG_LWIP_DNS_DEBUG is not set +# CONFIG_LWIP_BRIDGEIF_DEBUG is not set +# CONFIG_LWIP_BRIDGEIF_FDB_DEBUG is not set +# CONFIG_LWIP_BRIDGEIF_FW_DEBUG is not set +# end of LWIP + +# +# mbedTLS +# +CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y +# CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC is not set +# CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC is not set +CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y +CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384 +CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 +# CONFIG_MBEDTLS_DYNAMIC_BUFFER is not set +# CONFIG_MBEDTLS_DEBUG is not set + +# +# mbedTLS v3.x related +# +# CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 is not set +# CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH is not set +# CONFIG_MBEDTLS_X509_TRUSTED_CERT_CALLBACK is not set +# CONFIG_MBEDTLS_SSL_CONTEXT_SERIALIZATION is not set +CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE=y +CONFIG_MBEDTLS_PKCS7_C=y +# end of mbedTLS v3.x related + +# +# Certificate Bundle +# +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=y +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=y +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE is not set +# CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE is not set +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEPRECATED_LIST is not set +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS=160 +# end of Certificate Bundle + +# CONFIG_MBEDTLS_ECP_RESTARTABLE is not set +CONFIG_MBEDTLS_CMAC_C=y +CONFIG_MBEDTLS_HARDWARE_AES=y +CONFIG_MBEDTLS_AES_USE_INTERRUPT=y +CONFIG_MBEDTLS_AES_INTERRUPT_LEVEL=0 +CONFIG_MBEDTLS_HARDWARE_GCM=y +CONFIG_MBEDTLS_GCM_SUPPORT_NON_AES_CIPHER=y +CONFIG_MBEDTLS_HARDWARE_MPI=y +# CONFIG_MBEDTLS_LARGE_KEY_SOFTWARE_MPI is not set +CONFIG_MBEDTLS_MPI_USE_INTERRUPT=y +CONFIG_MBEDTLS_MPI_INTERRUPT_LEVEL=0 +CONFIG_MBEDTLS_HARDWARE_SHA=y +CONFIG_MBEDTLS_ROM_MD5=y +# CONFIG_MBEDTLS_ATCA_HW_ECDSA_SIGN is not set +# CONFIG_MBEDTLS_ATCA_HW_ECDSA_VERIFY is not set +CONFIG_MBEDTLS_HAVE_TIME=y +# CONFIG_MBEDTLS_PLATFORM_TIME_ALT is not set +# CONFIG_MBEDTLS_HAVE_TIME_DATE is not set +CONFIG_MBEDTLS_ECDSA_DETERMINISTIC=y +CONFIG_MBEDTLS_SHA512_C=y +# CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT is not set +# CONFIG_MBEDTLS_TLS_SERVER_ONLY is not set +CONFIG_MBEDTLS_TLS_CLIENT_ONLY=y +# CONFIG_MBEDTLS_TLS_DISABLED is not set +CONFIG_MBEDTLS_TLS_CLIENT=y +CONFIG_MBEDTLS_TLS_ENABLED=y + +# +# TLS Key Exchange Methods +# +# CONFIG_MBEDTLS_PSK_MODES is not set +CONFIG_MBEDTLS_KEY_EXCHANGE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y +# end of TLS Key Exchange Methods + +CONFIG_MBEDTLS_SSL_RENEGOTIATION=y +CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y +# CONFIG_MBEDTLS_SSL_PROTO_GMTSSL1_1 is not set +# CONFIG_MBEDTLS_SSL_PROTO_DTLS is not set +CONFIG_MBEDTLS_SSL_ALPN=y +CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS=y +CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS=y + +# +# Symmetric Ciphers +# +CONFIG_MBEDTLS_AES_C=y +# CONFIG_MBEDTLS_CAMELLIA_C is not set +# CONFIG_MBEDTLS_DES_C is not set +# CONFIG_MBEDTLS_BLOWFISH_C is not set +# CONFIG_MBEDTLS_XTEA_C is not set +CONFIG_MBEDTLS_CCM_C=y +CONFIG_MBEDTLS_GCM_C=y +# CONFIG_MBEDTLS_NIST_KW_C is not set +# end of Symmetric Ciphers + +# CONFIG_MBEDTLS_RIPEMD160_C is not set + +# +# Certificates +# +CONFIG_MBEDTLS_PEM_PARSE_C=y +CONFIG_MBEDTLS_PEM_WRITE_C=y +CONFIG_MBEDTLS_X509_CRL_PARSE_C=y +CONFIG_MBEDTLS_X509_CSR_PARSE_C=y +# end of Certificates + +CONFIG_MBEDTLS_ECP_C=y +# CONFIG_MBEDTLS_DHM_C is not set +CONFIG_MBEDTLS_ECDH_C=y +CONFIG_MBEDTLS_ECDSA_C=y +# CONFIG_MBEDTLS_ECJPAKE_C is not set +CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP521R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP192K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP224K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP256K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP256R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED=y +CONFIG_MBEDTLS_ECP_NIST_OPTIM=y +CONFIG_MBEDTLS_ECP_FIXED_POINT_OPTIM=y +# CONFIG_MBEDTLS_POLY1305_C is not set +# CONFIG_MBEDTLS_CHACHA20_C is not set +# CONFIG_MBEDTLS_HKDF_C is not set +# CONFIG_MBEDTLS_THREADING_C is not set +CONFIG_MBEDTLS_ERROR_STRINGS=y +# end of mbedTLS + +# +# ESP-MQTT Configurations +# +CONFIG_MQTT_PROTOCOL_311=y +# CONFIG_MQTT_PROTOCOL_5 is not set +CONFIG_MQTT_TRANSPORT_SSL=y +CONFIG_MQTT_TRANSPORT_WEBSOCKET=y +CONFIG_MQTT_TRANSPORT_WEBSOCKET_SECURE=y +# CONFIG_MQTT_MSG_ID_INCREMENTAL is not set +# CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED is not set +# CONFIG_MQTT_REPORT_DELETED_MESSAGES is not set +# CONFIG_MQTT_USE_CUSTOM_CONFIG is not set +# CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED is not set +# CONFIG_MQTT_CUSTOM_OUTBOX is not set +# end of ESP-MQTT Configurations + +# +# Newlib +# +CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y +# CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF is not set +# CONFIG_NEWLIB_STDOUT_LINE_ENDING_CR is not set +# CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF is not set +# CONFIG_NEWLIB_STDIN_LINE_ENDING_LF is not set +CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y +# CONFIG_NEWLIB_NANO_FORMAT is not set +CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT=y +# CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC is not set +# CONFIG_NEWLIB_TIME_SYSCALL_USE_HRT is not set +# CONFIG_NEWLIB_TIME_SYSCALL_USE_NONE is not set +# end of Newlib + +# +# NVS +# +# CONFIG_NVS_ENCRYPTION is not set +# CONFIG_NVS_ASSERT_ERROR_CHECK is not set +# CONFIG_NVS_LEGACY_DUP_KEYS_COMPATIBILITY is not set +# end of NVS + +# +# OpenThread +# +# CONFIG_OPENTHREAD_ENABLED is not set + +# +# Thread Operational Dataset +# +CONFIG_OPENTHREAD_NETWORK_NAME="OpenThread-ESP" +CONFIG_OPENTHREAD_MESH_LOCAL_PREFIX="fd00:db8:a0:0::/64" +CONFIG_OPENTHREAD_NETWORK_CHANNEL=15 +CONFIG_OPENTHREAD_NETWORK_PANID=0x1234 +CONFIG_OPENTHREAD_NETWORK_EXTPANID="dead00beef00cafe" +CONFIG_OPENTHREAD_NETWORK_MASTERKEY="00112233445566778899aabbccddeeff" +CONFIG_OPENTHREAD_NETWORK_PSKC="104810e2315100afd6bc9215a6bfac53" +# end of Thread Operational Dataset + +CONFIG_OPENTHREAD_XTAL_ACCURACY=130 +# CONFIG_OPENTHREAD_SPINEL_ONLY is not set +CONFIG_OPENTHREAD_RX_ON_WHEN_IDLE=y + +# +# Thread Address Query Config +# +# end of Thread Address Query Config +# end of OpenThread + +# +# Protocomm +# +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_0=y +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_1=y +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_2=y +# end of Protocomm + +# +# PThreads +# +CONFIG_PTHREAD_TASK_PRIO_DEFAULT=5 +CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 +CONFIG_PTHREAD_STACK_MIN=768 +CONFIG_PTHREAD_TASK_CORE_DEFAULT=-1 +CONFIG_PTHREAD_TASK_NAME_DEFAULT="pthread" +# end of PThreads + +# +# MMU Config +# +CONFIG_MMU_PAGE_SIZE_64KB=y +CONFIG_MMU_PAGE_MODE="64KB" +CONFIG_MMU_PAGE_SIZE=0x10000 +# end of MMU Config + +# +# Main Flash configuration +# + +# +# SPI Flash behavior when brownout +# +CONFIG_SPI_FLASH_BROWNOUT_RESET_XMC=y +CONFIG_SPI_FLASH_BROWNOUT_RESET=y +# end of SPI Flash behavior when brownout + +# +# Optional and Experimental Features (READ DOCS FIRST) +# + +# +# Features here require specific hardware (READ DOCS FIRST!) +# +CONFIG_SPI_FLASH_SUSPEND_TSUS_VAL_US=50 +# end of Optional and Experimental Features (READ DOCS FIRST) +# end of Main Flash configuration + +# +# SPI Flash driver +# +# CONFIG_SPI_FLASH_VERIFY_WRITE is not set +# CONFIG_SPI_FLASH_ENABLE_COUNTERS is not set +CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y +CONFIG_SPI_FLASH_DANGEROUS_WRITE_ABORTS=y +# CONFIG_SPI_FLASH_DANGEROUS_WRITE_FAILS is not set +# CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED is not set +# CONFIG_SPI_FLASH_BYPASS_BLOCK_ERASE is not set +CONFIG_SPI_FLASH_YIELD_DURING_ERASE=y +CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS=20 +CONFIG_SPI_FLASH_ERASE_YIELD_TICKS=1 +CONFIG_SPI_FLASH_WRITE_CHUNK_SIZE=8192 +# CONFIG_SPI_FLASH_SIZE_OVERRIDE is not set +# CONFIG_SPI_FLASH_CHECK_ERASE_TIMEOUT_DISABLED is not set +# CONFIG_SPI_FLASH_OVERRIDE_CHIP_DRIVER_LIST is not set + +# +# Auto-detect flash chips +# +CONFIG_SPI_FLASH_VENDOR_XMC_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_GD_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_ISSI_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_MXIC_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_WINBOND_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_BOYA_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_TH_SUPPORTED=y +CONFIG_SPI_FLASH_SUPPORT_ISSI_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_MXIC_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_GD_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_WINBOND_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_BOYA_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_TH_CHIP=y +# end of Auto-detect flash chips + +CONFIG_SPI_FLASH_ENABLE_ENCRYPTED_READ_WRITE=y +# end of SPI Flash driver + +# +# SPIFFS Configuration +# +CONFIG_SPIFFS_MAX_PARTITIONS=3 + +# +# SPIFFS Cache Configuration +# +CONFIG_SPIFFS_CACHE=y +CONFIG_SPIFFS_CACHE_WR=y +# CONFIG_SPIFFS_CACHE_STATS is not set +# end of SPIFFS Cache Configuration + +CONFIG_SPIFFS_PAGE_CHECK=y +CONFIG_SPIFFS_GC_MAX_RUNS=10 +# CONFIG_SPIFFS_GC_STATS is not set +CONFIG_SPIFFS_PAGE_SIZE=256 +CONFIG_SPIFFS_OBJ_NAME_LEN=32 +# CONFIG_SPIFFS_FOLLOW_SYMLINKS is not set +CONFIG_SPIFFS_USE_MAGIC=y +CONFIG_SPIFFS_USE_MAGIC_LENGTH=y +CONFIG_SPIFFS_META_LENGTH=4 +CONFIG_SPIFFS_USE_MTIME=y + +# +# Debug Configuration +# +# CONFIG_SPIFFS_DBG is not set +# CONFIG_SPIFFS_API_DBG is not set +# CONFIG_SPIFFS_GC_DBG is not set +# CONFIG_SPIFFS_CACHE_DBG is not set +# CONFIG_SPIFFS_CHECK_DBG is not set +# CONFIG_SPIFFS_TEST_VISUALISATION is not set +# end of Debug Configuration +# end of SPIFFS Configuration + +# +# TCP Transport +# + +# +# Websocket +# +CONFIG_WS_TRANSPORT=y +CONFIG_WS_BUFFER_SIZE=1024 +# CONFIG_WS_DYNAMIC_BUFFER is not set +# end of Websocket +# end of TCP Transport + +# +# Ultra Low Power (ULP) Co-processor +# +CONFIG_ULP_COPROC_ENABLED=y +# CONFIG_ULP_COPROC_TYPE_FSM is not set +CONFIG_ULP_COPROC_TYPE_RISCV=y +CONFIG_ULP_COPROC_RESERVE_MEM=6144 + +# +# ULP RISC-V Settings +# +# CONFIG_ULP_RISCV_INTERRUPT_ENABLE is not set +CONFIG_ULP_RISCV_UART_BAUDRATE=9600 +CONFIG_ULP_RISCV_I2C_RW_TIMEOUT=500 +# end of ULP RISC-V Settings + +# +# ULP Debugging Options +# +# end of ULP Debugging Options +# end of Ultra Low Power (ULP) Co-processor + +# +# Unity unit testing library +# +CONFIG_UNITY_ENABLE_FLOAT=y +CONFIG_UNITY_ENABLE_DOUBLE=y +# CONFIG_UNITY_ENABLE_64BIT is not set +# CONFIG_UNITY_ENABLE_COLOR is not set +CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y +# CONFIG_UNITY_ENABLE_FIXTURE is not set +# CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL is not set +# end of Unity unit testing library + +# +# USB-OTG +# +CONFIG_USB_HOST_CONTROL_TRANSFER_MAX_SIZE=256 +CONFIG_USB_HOST_HW_BUFFER_BIAS_BALANCED=y +# CONFIG_USB_HOST_HW_BUFFER_BIAS_IN is not set +# CONFIG_USB_HOST_HW_BUFFER_BIAS_PERIODIC_OUT is not set + +# +# Root Hub configuration +# +CONFIG_USB_HOST_DEBOUNCE_DELAY_MS=250 +CONFIG_USB_HOST_RESET_HOLD_MS=30 +CONFIG_USB_HOST_RESET_RECOVERY_MS=30 +CONFIG_USB_HOST_SET_ADDR_RECOVERY_MS=10 +# end of Root Hub configuration + +# CONFIG_USB_HOST_ENABLE_ENUM_FILTER_CALLBACK is not set +CONFIG_USB_OTG_SUPPORTED=y +# end of USB-OTG + +# +# Virtual file system +# +CONFIG_VFS_SUPPORT_IO=y +CONFIG_VFS_SUPPORT_DIR=y +CONFIG_VFS_SUPPORT_SELECT=y +CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT=y +# CONFIG_VFS_SELECT_IN_RAM is not set +CONFIG_VFS_SUPPORT_TERMIOS=y +CONFIG_VFS_MAX_COUNT=8 + +# +# Host File System I/O (Semihosting) +# +CONFIG_VFS_SEMIHOSTFS_MAX_MOUNT_POINTS=1 +# end of Host File System I/O (Semihosting) +# end of Virtual file system + +# +# Wear Levelling +# +# CONFIG_WL_SECTOR_SIZE_512 is not set +CONFIG_WL_SECTOR_SIZE_4096=y +CONFIG_WL_SECTOR_SIZE=4096 +# end of Wear Levelling + +# +# Wi-Fi Provisioning Manager +# +CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16 +CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 +CONFIG_WIFI_PROV_BLE_FORCE_ENCRYPTION=y +CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y +# CONFIG_WIFI_PROV_STA_FAST_SCAN is not set +# end of Wi-Fi Provisioning Manager +# end of Component config + +# CONFIG_IDF_EXPERIMENTAL_FEATURES is not set + +# Deprecated options for backward compatibility +# CONFIG_APP_BUILD_TYPE_ELF_RAM is not set +# CONFIG_NO_BLOBS is not set +# CONFIG_ESP32S2_NO_BLOBS is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_NONE is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_ERROR is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_WARN is not set +CONFIG_LOG_BOOTLOADER_LEVEL_INFO=y +# CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE is not set +CONFIG_LOG_BOOTLOADER_LEVEL=3 +# CONFIG_APP_ROLLBACK_ENABLE is not set +# CONFIG_FLASH_ENCRYPTION_ENABLED is not set +# CONFIG_FLASHMODE_QIO is not set +# CONFIG_FLASHMODE_QOUT is not set +CONFIG_FLASHMODE_DIO=y +# CONFIG_FLASHMODE_DOUT is not set +CONFIG_MONITOR_BAUD=115200 +# CONFIG_OPTIMIZATION_LEVEL_DEBUG is not set +# CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG is not set +# CONFIG_COMPILER_OPTIMIZATION_DEFAULT is not set +CONFIG_OPTIMIZATION_LEVEL_RELEASE=y +CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE=y +CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y +# CONFIG_OPTIMIZATION_ASSERTIONS_SILENT is not set +# CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED is not set +CONFIG_OPTIMIZATION_ASSERTION_LEVEL=2 +# CONFIG_CXX_EXCEPTIONS is not set +CONFIG_STACK_CHECK_NONE=y +# CONFIG_STACK_CHECK_NORM is not set +# CONFIG_STACK_CHECK_STRONG is not set +# CONFIG_STACK_CHECK_ALL is not set +# CONFIG_WARN_WRITE_STRINGS is not set +# CONFIG_ESP32_APPTRACE_DEST_TRAX is not set +CONFIG_ESP32_APPTRACE_DEST_NONE=y +CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y +CONFIG_ADC2_DISABLE_DAC=y +# CONFIG_EXTERNAL_COEX_ENABLE is not set +# CONFIG_ESP_WIFI_EXTERNAL_COEXIST_ENABLE is not set +# CONFIG_EVENT_LOOP_PROFILING is not set +CONFIG_POST_EVENTS_FROM_ISR=y +CONFIG_POST_EVENTS_FROM_IRAM_ISR=y +CONFIG_GDBSTUB_SUPPORT_TASKS=y +CONFIG_GDBSTUB_MAX_TASKS=32 +# CONFIG_OTA_ALLOW_HTTP is not set +# CONFIG_ESP_SYSTEM_PD_FLASH is not set +CONFIG_ESP32S2_RTC_CLK_SRC_INT_RC=y +# CONFIG_ESP32S2_RTC_CLK_SRC_EXT_CRYS is not set +# CONFIG_ESP32S2_RTC_CLK_SRC_EXT_OSC is not set +# CONFIG_ESP32S2_RTC_CLK_SRC_INT_8MD256 is not set +CONFIG_ESP32S2_RTC_CLK_CAL_CYCLES=576 +CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y +# CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION is not set +CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=20 +CONFIG_ESP32_PHY_MAX_TX_POWER=20 +# CONFIG_ESP32S2_SPIRAM_SUPPORT is not set +CONFIG_ESP32S2_DEFAULT_CPU_FREQ_80=y +# CONFIG_ESP32S2_DEFAULT_CPU_FREQ_160 is not set +# CONFIG_ESP32S2_DEFAULT_CPU_FREQ_240 is not set +CONFIG_ESP32S2_DEFAULT_CPU_FREQ_MHZ=80 +# CONFIG_ESP32S2_PANIC_PRINT_HALT is not set +CONFIG_ESP32S2_PANIC_PRINT_REBOOT=y +# CONFIG_ESP32S2_PANIC_SILENT_REBOOT is not set +# CONFIG_ESP32S2_PANIC_GDBSTUB is not set +CONFIG_ESP32S2_ALLOW_RTC_FAST_MEM_AS_HEAP=y +CONFIG_ESP32S2_MEMPROT_FEATURE=y +CONFIG_ESP32S2_MEMPROT_FEATURE_LOCK=y +CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32 +CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2304 +CONFIG_MAIN_TASK_STACK_SIZE=3584 +CONFIG_CONSOLE_UART_DEFAULT=y +# CONFIG_CONSOLE_UART_CUSTOM is not set +# CONFIG_CONSOLE_UART_NONE is not set +# CONFIG_ESP_CONSOLE_UART_NONE is not set +CONFIG_CONSOLE_UART=y +CONFIG_CONSOLE_UART_NUM=0 +CONFIG_CONSOLE_UART_BAUDRATE=115200 +CONFIG_INT_WDT=y +CONFIG_INT_WDT_TIMEOUT_MS=300 +CONFIG_TASK_WDT=y +CONFIG_ESP_TASK_WDT=y +# CONFIG_TASK_WDT_PANIC is not set +CONFIG_TASK_WDT_TIMEOUT_S=5 +CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0=y +# CONFIG_ESP32_DEBUG_STUBS_ENABLE is not set +CONFIG_ESP32S2_DEBUG_OCDAWARE=y +# CONFIG_BROWNOUT_DET is not set +# CONFIG_ESP32S2_BROWNOUT_DET is not set +# CONFIG_ESP32S2_BROWNOUT_DET is not set +CONFIG_IPC_TASK_STACK_SIZE=1024 +CONFIG_TIMER_TASK_STACK_SIZE=3584 +CONFIG_ESP32_WIFI_ENABLED=y +CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 +CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 +# CONFIG_ESP32_WIFI_STATIC_TX_BUFFER is not set +CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER=y +CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1 +CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32 +# CONFIG_ESP32_WIFI_CSI_ENABLED is not set +# CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED is not set +CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y +CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y +CONFIG_ESP32_WIFI_RX_BA_WIN=6 +CONFIG_ESP32_WIFI_RX_BA_WIN=6 +CONFIG_ESP32_WIFI_NVS_ENABLED=y +CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752 +CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32 +# CONFIG_ESP32_WIFI_IRAM_OPT is not set +CONFIG_ESP32_WIFI_RX_IRAM_OPT=y +CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE=y +CONFIG_ESP32_WIFI_ENABLE_WPA3_OWE_STA=y +CONFIG_WPA_MBEDTLS_CRYPTO=y +CONFIG_WPA_MBEDTLS_TLS_CLIENT=y +# CONFIG_WPA_WAPI_PSK is not set +# CONFIG_WPA_11KV_SUPPORT is not set +# CONFIG_WPA_MBO_SUPPORT is not set +# CONFIG_WPA_DPP_SUPPORT is not set +# CONFIG_WPA_11R_SUPPORT is not set +# CONFIG_WPA_WPS_SOFTAP_REGISTRAR is not set +# CONFIG_WPA_WPS_STRICT is not set +# CONFIG_WPA_DEBUG_PRINT is not set +# CONFIG_WPA_TESTING_OPTIONS is not set +# CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH is not set +# CONFIG_ESP32_ENABLE_COREDUMP_TO_UART is not set +CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE=y +CONFIG_TIMER_TASK_PRIORITY=1 +CONFIG_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_TIMER_QUEUE_LENGTH=10 +# CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK is not set +# CONFIG_HAL_ASSERTION_SILIENT is not set +# CONFIG_L2_TO_L3_COPY is not set +CONFIG_ESP_GRATUITOUS_ARP=y +CONFIG_GARP_TMR_INTERVAL=60 +CONFIG_TCPIP_RECVMBOX_SIZE=32 +CONFIG_TCP_MAXRTX=12 +CONFIG_TCP_SYNMAXRTX=12 +CONFIG_TCP_MSS=1440 +CONFIG_TCP_MSL=60000 +CONFIG_TCP_SND_BUF_DEFAULT=5744 +CONFIG_TCP_WND_DEFAULT=5744 +CONFIG_TCP_RECVMBOX_SIZE=6 +CONFIG_TCP_QUEUE_OOSEQ=y +CONFIG_TCP_OVERSIZE_MSS=y +# CONFIG_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_TCP_OVERSIZE_DISABLE is not set +CONFIG_UDP_RECVMBOX_SIZE=6 +CONFIG_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_TCPIP_TASK_AFFINITY_NO_AFFINITY=y +# CONFIG_TCPIP_TASK_AFFINITY_CPU0 is not set +CONFIG_TCPIP_TASK_AFFINITY=0x7FFFFFFF +# CONFIG_PPP_SUPPORT is not set +CONFIG_ESP32S2_TIME_SYSCALL_USE_RTC_SYSTIMER=y +CONFIG_ESP32S2_TIME_SYSCALL_USE_RTC_FRC1=y +# CONFIG_ESP32S2_TIME_SYSCALL_USE_RTC is not set +# CONFIG_ESP32S2_TIME_SYSCALL_USE_SYSTIMER is not set +# CONFIG_ESP32S2_TIME_SYSCALL_USE_FRC1 is not set +# CONFIG_ESP32S2_TIME_SYSCALL_USE_NONE is not set +CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT=5 +CONFIG_ESP32_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 +CONFIG_ESP32_PTHREAD_STACK_MIN=768 +CONFIG_ESP32_PTHREAD_TASK_CORE_DEFAULT=-1 +CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT="pthread" +CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y +# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_FAILS is not set +# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED is not set +CONFIG_ESP32S2_ULP_COPROC_ENABLED=y +CONFIG_ESP32S2_ULP_COPROC_RISCV=y +CONFIG_ESP32S2_ULP_COPROC_RESERVE_MEM=6144 +CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y +CONFIG_SUPPORT_TERMIOS=y +CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS=1 +# End of deprecated options diff --git a/sdkconfig.old b/sdkconfig.old new file mode 100644 index 0000000..565d077 --- /dev/null +++ b/sdkconfig.old @@ -0,0 +1,2022 @@ +# +# Automatically generated file. DO NOT EDIT. +# Espressif IoT Development Framework (ESP-IDF) 5.3.1 Project Configuration +# +CONFIG_SOC_ADC_SUPPORTED=y +CONFIG_SOC_DAC_SUPPORTED=y +CONFIG_SOC_UART_SUPPORTED=y +CONFIG_SOC_TWAI_SUPPORTED=y +CONFIG_SOC_CP_DMA_SUPPORTED=y +CONFIG_SOC_DEDICATED_GPIO_SUPPORTED=y +CONFIG_SOC_GPTIMER_SUPPORTED=y +CONFIG_SOC_SUPPORTS_SECURE_DL_MODE=y +CONFIG_SOC_ULP_FSM_SUPPORTED=y +CONFIG_SOC_RISCV_COPROC_SUPPORTED=y +CONFIG_SOC_USB_OTG_SUPPORTED=y +CONFIG_SOC_PCNT_SUPPORTED=y +CONFIG_SOC_PHY_SUPPORTED=y +CONFIG_SOC_WIFI_SUPPORTED=y +CONFIG_SOC_ULP_SUPPORTED=y +CONFIG_SOC_CCOMP_TIMER_SUPPORTED=y +CONFIG_SOC_ASYNC_MEMCPY_SUPPORTED=y +CONFIG_SOC_EFUSE_KEY_PURPOSE_FIELD=y +CONFIG_SOC_EFUSE_SUPPORTED=y +CONFIG_SOC_TEMP_SENSOR_SUPPORTED=y +CONFIG_SOC_CACHE_SUPPORT_WRAP=y +CONFIG_SOC_RTC_FAST_MEM_SUPPORTED=y +CONFIG_SOC_RTC_SLOW_MEM_SUPPORTED=y +CONFIG_SOC_RTC_MEM_SUPPORTED=y +CONFIG_SOC_PSRAM_DMA_CAPABLE=y +CONFIG_SOC_XT_WDT_SUPPORTED=y +CONFIG_SOC_I2S_SUPPORTED=y +CONFIG_SOC_RMT_SUPPORTED=y +CONFIG_SOC_SDM_SUPPORTED=y +CONFIG_SOC_GPSPI_SUPPORTED=y +CONFIG_SOC_LEDC_SUPPORTED=y +CONFIG_SOC_I2C_SUPPORTED=y +CONFIG_SOC_SYSTIMER_SUPPORTED=y +CONFIG_SOC_AES_SUPPORTED=y +CONFIG_SOC_MPI_SUPPORTED=y +CONFIG_SOC_SHA_SUPPORTED=y +CONFIG_SOC_HMAC_SUPPORTED=y +CONFIG_SOC_DIG_SIGN_SUPPORTED=y +CONFIG_SOC_FLASH_ENC_SUPPORTED=y +CONFIG_SOC_SECURE_BOOT_SUPPORTED=y +CONFIG_SOC_MEMPROT_SUPPORTED=y +CONFIG_SOC_TOUCH_SENSOR_SUPPORTED=y +CONFIG_SOC_BOD_SUPPORTED=y +CONFIG_SOC_CLK_TREE_SUPPORTED=y +CONFIG_SOC_MPU_SUPPORTED=y +CONFIG_SOC_WDT_SUPPORTED=y +CONFIG_SOC_SPI_FLASH_SUPPORTED=y +CONFIG_SOC_RNG_SUPPORTED=y +CONFIG_SOC_LIGHT_SLEEP_SUPPORTED=y +CONFIG_SOC_DEEP_SLEEP_SUPPORTED=y +CONFIG_SOC_LP_PERIPH_SHARE_INTERRUPT=y +CONFIG_SOC_PM_SUPPORTED=y +CONFIG_SOC_XTAL_SUPPORT_40M=y +CONFIG_SOC_ADC_RTC_CTRL_SUPPORTED=y +CONFIG_SOC_ADC_DIG_CTRL_SUPPORTED=y +CONFIG_SOC_ADC_ARBITER_SUPPORTED=y +CONFIG_SOC_ADC_DIG_IIR_FILTER_SUPPORTED=y +CONFIG_SOC_ADC_DIG_IIR_FILTER_UNIT_BINDED=y +CONFIG_SOC_ADC_MONITOR_SUPPORTED=y +CONFIG_SOC_ADC_DMA_SUPPORTED=y +CONFIG_SOC_ADC_PERIPH_NUM=2 +CONFIG_SOC_ADC_MAX_CHANNEL_NUM=10 +CONFIG_SOC_ADC_ATTEN_NUM=4 +CONFIG_SOC_ADC_DIGI_CONTROLLER_NUM=2 +CONFIG_SOC_ADC_PATT_LEN_MAX=32 +CONFIG_SOC_ADC_DIGI_MIN_BITWIDTH=12 +CONFIG_SOC_ADC_DIGI_MAX_BITWIDTH=12 +CONFIG_SOC_ADC_DIGI_IIR_FILTER_NUM=2 +CONFIG_SOC_ADC_DIGI_RESULT_BYTES=2 +CONFIG_SOC_ADC_DIGI_DATA_BYTES_PER_CONV=2 +CONFIG_SOC_ADC_DIGI_MONITOR_NUM=2 +CONFIG_SOC_ADC_SAMPLE_FREQ_THRES_HIGH=83333 +CONFIG_SOC_ADC_SAMPLE_FREQ_THRES_LOW=611 +CONFIG_SOC_ADC_RTC_MIN_BITWIDTH=13 +CONFIG_SOC_ADC_RTC_MAX_BITWIDTH=13 +CONFIG_SOC_ADC_CALIBRATION_V1_SUPPORTED=y +CONFIG_SOC_ADC_SELF_HW_CALI_SUPPORTED=y +CONFIG_SOC_ADC_SHARED_POWER=y +CONFIG_SOC_BROWNOUT_RESET_SUPPORTED=y +CONFIG_SOC_CACHE_WRITEBACK_SUPPORTED=y +CONFIG_SOC_CP_DMA_MAX_BUFFER_SIZE=4095 +CONFIG_SOC_CPU_CORES_NUM=1 +CONFIG_SOC_CPU_INTR_NUM=32 +CONFIG_SOC_CPU_BREAKPOINTS_NUM=2 +CONFIG_SOC_CPU_WATCHPOINTS_NUM=2 +CONFIG_SOC_CPU_WATCHPOINT_MAX_REGION_SIZE=64 +CONFIG_SOC_DAC_CHAN_NUM=2 +CONFIG_SOC_DAC_RESOLUTION=8 +CONFIG_SOC_GPIO_PORT=1 +CONFIG_SOC_GPIO_PIN_COUNT=47 +CONFIG_SOC_GPIO_SUPPORT_PIN_GLITCH_FILTER=y +CONFIG_SOC_GPIO_FILTER_CLK_SUPPORT_APB=y +CONFIG_SOC_GPIO_SUPPORT_RTC_INDEPENDENT=y +CONFIG_SOC_GPIO_SUPPORT_FORCE_HOLD=y +CONFIG_SOC_GPIO_VALID_GPIO_MASK=0x7FFFFFFFFFFF +CONFIG_SOC_GPIO_IN_RANGE_MAX=46 +CONFIG_SOC_GPIO_OUT_RANGE_MAX=45 +CONFIG_SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK=0x00007FFFFC000000 +CONFIG_SOC_GPIO_CLOCKOUT_BY_IO_MUX=y +CONFIG_SOC_GPIO_CLOCKOUT_CHANNEL_NUM=3 +CONFIG_SOC_DEDIC_GPIO_OUT_CHANNELS_NUM=8 +CONFIG_SOC_DEDIC_GPIO_IN_CHANNELS_NUM=8 +CONFIG_SOC_DEDIC_GPIO_ALLOW_REG_ACCESS=y +CONFIG_SOC_DEDIC_GPIO_HAS_INTERRUPT=y +CONFIG_SOC_DEDIC_GPIO_OUT_AUTO_ENABLE=y +CONFIG_SOC_I2C_NUM=2 +CONFIG_SOC_HP_I2C_NUM=2 +CONFIG_SOC_I2C_FIFO_LEN=32 +CONFIG_SOC_I2C_CMD_REG_NUM=16 +CONFIG_SOC_I2C_SUPPORT_SLAVE=y +CONFIG_SOC_I2C_SUPPORT_HW_CLR_BUS=y +CONFIG_SOC_I2C_SUPPORT_REF_TICK=y +CONFIG_SOC_I2C_SUPPORT_APB=y +CONFIG_SOC_I2S_NUM=1 +CONFIG_SOC_I2S_HW_VERSION_1=y +CONFIG_SOC_I2S_SUPPORTS_APLL=y +CONFIG_SOC_I2S_SUPPORTS_PLL_F160M=y +CONFIG_SOC_I2S_SUPPORTS_DMA_EQUAL=y +CONFIG_SOC_I2S_SUPPORTS_LCD_CAMERA=y +CONFIG_SOC_I2S_APLL_MIN_FREQ=250000000 +CONFIG_SOC_I2S_APLL_MAX_FREQ=500000000 +CONFIG_SOC_I2S_APLL_MIN_RATE=10675 +CONFIG_SOC_I2S_LCD_I80_VARIANT=y +CONFIG_SOC_LCD_I80_SUPPORTED=y +CONFIG_SOC_LCD_I80_BUSES=1 +CONFIG_SOC_LCD_I80_BUS_WIDTH=24 +CONFIG_SOC_LEDC_HAS_TIMER_SPECIFIC_MUX=y +CONFIG_SOC_LEDC_SUPPORT_APB_CLOCK=y +CONFIG_SOC_LEDC_SUPPORT_REF_TICK=y +CONFIG_SOC_LEDC_SUPPORT_XTAL_CLOCK=y +CONFIG_SOC_LEDC_CHANNEL_NUM=8 +CONFIG_SOC_LEDC_TIMER_BIT_WIDTH=14 +CONFIG_SOC_LEDC_SUPPORT_FADE_STOP=y +CONFIG_SOC_MMU_LINEAR_ADDRESS_REGION_NUM=5 +CONFIG_SOC_MMU_PERIPH_NUM=1 +CONFIG_SOC_MPU_MIN_REGION_SIZE=0x20000000 +CONFIG_SOC_MPU_REGIONS_MAX_NUM=8 +CONFIG_SOC_PCNT_GROUPS=1 +CONFIG_SOC_PCNT_UNITS_PER_GROUP=4 +CONFIG_SOC_PCNT_CHANNELS_PER_UNIT=2 +CONFIG_SOC_PCNT_THRES_POINT_PER_UNIT=2 +CONFIG_SOC_RMT_GROUPS=1 +CONFIG_SOC_RMT_TX_CANDIDATES_PER_GROUP=4 +CONFIG_SOC_RMT_RX_CANDIDATES_PER_GROUP=4 +CONFIG_SOC_RMT_CHANNELS_PER_GROUP=4 +CONFIG_SOC_RMT_MEM_WORDS_PER_CHANNEL=64 +CONFIG_SOC_RMT_SUPPORT_RX_DEMODULATION=y +CONFIG_SOC_RMT_SUPPORT_TX_ASYNC_STOP=y +CONFIG_SOC_RMT_SUPPORT_TX_LOOP_COUNT=y +CONFIG_SOC_RMT_SUPPORT_TX_SYNCHRO=y +CONFIG_SOC_RMT_SUPPORT_TX_CARRIER_DATA_ONLY=y +CONFIG_SOC_RMT_SUPPORT_REF_TICK=y +CONFIG_SOC_RMT_SUPPORT_APB=y +CONFIG_SOC_RMT_CHANNEL_CLK_INDEPENDENT=y +CONFIG_SOC_RTCIO_PIN_COUNT=22 +CONFIG_SOC_RTCIO_INPUT_OUTPUT_SUPPORTED=y +CONFIG_SOC_RTCIO_HOLD_SUPPORTED=y +CONFIG_SOC_RTCIO_WAKE_SUPPORTED=y +CONFIG_SOC_SDM_GROUPS=1 +CONFIG_SOC_SDM_CHANNELS_PER_GROUP=8 +CONFIG_SOC_SDM_CLK_SUPPORT_APB=y +CONFIG_SOC_SPI_HD_BOTH_INOUT_SUPPORTED=y +CONFIG_SOC_SPI_PERIPH_NUM=3 +CONFIG_SOC_SPI_DMA_CHAN_NUM=3 +CONFIG_SOC_SPI_MAX_CS_NUM=6 +CONFIG_SOC_SPI_MAXIMUM_BUFFER_SIZE=72 +CONFIG_SOC_SPI_MAX_PRE_DIVIDER=8192 +CONFIG_SOC_SPI_SUPPORT_DDRCLK=y +CONFIG_SOC_SPI_SLAVE_SUPPORT_SEG_TRANS=y +CONFIG_SOC_SPI_SUPPORT_CD_SIG=y +CONFIG_SOC_SPI_SUPPORT_CONTINUOUS_TRANS=y +CONFIG_SOC_SPI_SUPPORT_CLK_APB=y +CONFIG_SOC_SPI_SUPPORT_SLAVE_HD_VER2=y +CONFIG_SOC_SPI_PERIPH_SUPPORT_CONTROL_DUMMY_OUT=y +CONFIG_SOC_SPI_SUPPORT_OCT=y +CONFIG_SOC_SPI_SCT_SUPPORTED=y +CONFIG_SOC_SPI_SCT_REG_NUM=27 +CONFIG_SOC_SPI_SCT_BUFFER_NUM_MAX=y +CONFIG_SOC_SPI_SCT_CONF_BITLEN_MAX=0x7FFFFD +CONFIG_SOC_MEMSPI_IS_INDEPENDENT=y +CONFIG_SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED=y +CONFIG_SOC_MEMSPI_SRC_FREQ_40M_SUPPORTED=y +CONFIG_SOC_MEMSPI_SRC_FREQ_26M_SUPPORTED=y +CONFIG_SOC_MEMSPI_SRC_FREQ_20M_SUPPORTED=y +CONFIG_SOC_SYSTIMER_COUNTER_NUM=y +CONFIG_SOC_SYSTIMER_ALARM_NUM=3 +CONFIG_SOC_SYSTIMER_BIT_WIDTH_LO=32 +CONFIG_SOC_SYSTIMER_BIT_WIDTH_HI=32 +CONFIG_SOC_TIMER_GROUPS=2 +CONFIG_SOC_TIMER_GROUP_TIMERS_PER_GROUP=2 +CONFIG_SOC_TIMER_GROUP_COUNTER_BIT_WIDTH=64 +CONFIG_SOC_TIMER_GROUP_SUPPORT_XTAL=y +CONFIG_SOC_TIMER_GROUP_SUPPORT_APB=y +CONFIG_SOC_TIMER_GROUP_TOTAL_TIMERS=4 +CONFIG_SOC_TOUCH_SENSOR_VERSION=2 +CONFIG_SOC_TOUCH_SENSOR_NUM=15 +CONFIG_SOC_TOUCH_SUPPORT_SLEEP_WAKEUP=y +CONFIG_SOC_TOUCH_SUPPORT_WATERPROOF=y +CONFIG_SOC_TOUCH_SUPPORT_PROX_SENSING=y +CONFIG_SOC_TOUCH_PROXIMITY_CHANNEL_NUM=3 +CONFIG_SOC_TOUCH_SAMPLE_CFG_NUM=1 +CONFIG_SOC_TWAI_CONTROLLER_NUM=1 +CONFIG_SOC_TWAI_CLK_SUPPORT_APB=y +CONFIG_SOC_TWAI_BRP_MIN=2 +CONFIG_SOC_TWAI_BRP_MAX=32768 +CONFIG_SOC_TWAI_SUPPORTS_RX_STATUS=y +CONFIG_SOC_UART_NUM=2 +CONFIG_SOC_UART_HP_NUM=2 +CONFIG_SOC_UART_SUPPORT_WAKEUP_INT=y +CONFIG_SOC_UART_SUPPORT_APB_CLK=y +CONFIG_SOC_UART_SUPPORT_REF_TICK=y +CONFIG_SOC_UART_FIFO_LEN=128 +CONFIG_SOC_UART_BITRATE_MAX=5000000 +CONFIG_SOC_SPIRAM_SUPPORTED=y +CONFIG_SOC_SPIRAM_XIP_SUPPORTED=y +CONFIG_SOC_USB_OTG_PERIPH_NUM=1 +CONFIG_SOC_SHA_DMA_MAX_BUFFER_SIZE=3968 +CONFIG_SOC_SHA_SUPPORT_DMA=y +CONFIG_SOC_SHA_SUPPORT_RESUME=y +CONFIG_SOC_SHA_CRYPTO_DMA=y +CONFIG_SOC_SHA_SUPPORT_SHA1=y +CONFIG_SOC_SHA_SUPPORT_SHA224=y +CONFIG_SOC_SHA_SUPPORT_SHA256=y +CONFIG_SOC_SHA_SUPPORT_SHA384=y +CONFIG_SOC_SHA_SUPPORT_SHA512=y +CONFIG_SOC_SHA_SUPPORT_SHA512_224=y +CONFIG_SOC_SHA_SUPPORT_SHA512_256=y +CONFIG_SOC_SHA_SUPPORT_SHA512_T=y +CONFIG_SOC_MPI_MEM_BLOCKS_NUM=4 +CONFIG_SOC_MPI_OPERATIONS_NUM=3 +CONFIG_SOC_RSA_MAX_BIT_LEN=4096 +CONFIG_SOC_AES_SUPPORT_DMA=y +CONFIG_SOC_AES_SUPPORT_GCM=y +CONFIG_SOC_EFUSE_DIS_DOWNLOAD_ICACHE=y +CONFIG_SOC_EFUSE_DIS_DOWNLOAD_DCACHE=y +CONFIG_SOC_EFUSE_HARD_DIS_JTAG=y +CONFIG_SOC_EFUSE_SOFT_DIS_JTAG=y +CONFIG_SOC_EFUSE_DIS_BOOT_REMAP=y +CONFIG_SOC_EFUSE_DIS_LEGACY_SPI_BOOT=y +CONFIG_SOC_EFUSE_DIS_ICACHE=y +CONFIG_SOC_SECURE_BOOT_V2_RSA=y +CONFIG_SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS=3 +CONFIG_SOC_EFUSE_REVOKE_BOOT_KEY_DIGESTS=y +CONFIG_SOC_SUPPORT_SECURE_BOOT_REVOKE_KEY=y +CONFIG_SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX=64 +CONFIG_SOC_FLASH_ENCRYPTION_XTS_AES=y +CONFIG_SOC_FLASH_ENCRYPTION_XTS_AES_OPTIONS=y +CONFIG_SOC_FLASH_ENCRYPTION_XTS_AES_128=y +CONFIG_SOC_FLASH_ENCRYPTION_XTS_AES_256=y +CONFIG_SOC_MEMPROT_CPU_PREFETCH_PAD_SIZE=16 +CONFIG_SOC_MEMPROT_MEM_ALIGN_SIZE=4 +CONFIG_SOC_AES_CRYPTO_DMA=y +CONFIG_SOC_AES_SUPPORT_AES_128=y +CONFIG_SOC_AES_SUPPORT_AES_192=y +CONFIG_SOC_AES_SUPPORT_AES_256=y +CONFIG_SOC_PHY_DIG_REGS_MEM_SIZE=21 +CONFIG_SOC_WIFI_LIGHT_SLEEP_CLK_WIDTH=12 +CONFIG_SOC_SPI_MEM_SUPPORT_AUTO_WAIT_IDLE=y +CONFIG_SOC_SPI_MEM_SUPPORT_SW_SUSPEND=y +CONFIG_SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE=y +CONFIG_SOC_SPI_MEM_SUPPORT_WRAP=y +CONFIG_SOC_PM_SUPPORT_EXT0_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_EXT1_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_EXT_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_WIFI_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_WIFI_PD=y +CONFIG_SOC_PM_SUPPORT_RTC_PERIPH_PD=y +CONFIG_SOC_PM_SUPPORT_RTC_FAST_MEM_PD=y +CONFIG_SOC_PM_SUPPORT_RTC_SLOW_MEM_PD=y +CONFIG_SOC_PM_SUPPORT_RC_FAST_PD=y +CONFIG_SOC_PM_SUPPORT_VDDSDIO_PD=y +CONFIG_SOC_CONFIGURABLE_VDDSDIO_SUPPORTED=y +CONFIG_SOC_CLK_APLL_SUPPORTED=y +CONFIG_SOC_CLK_RC_FAST_D256_SUPPORTED=y +CONFIG_SOC_RTC_SLOW_CLK_SUPPORT_RC_FAST_D256=y +CONFIG_SOC_CLK_RC_FAST_SUPPORT_CALIBRATION=y +CONFIG_SOC_CLK_XTAL32K_SUPPORTED=y +CONFIG_SOC_COEX_HW_PTI=y +CONFIG_SOC_EXTERNAL_COEX_LEADER_TX_LINE=y +CONFIG_SOC_TEMPERATURE_SENSOR_SUPPORT_FAST_RC=y +CONFIG_SOC_WIFI_HW_TSF=y +CONFIG_SOC_WIFI_FTM_SUPPORT=y +CONFIG_SOC_WIFI_WAPI_SUPPORT=y +CONFIG_SOC_WIFI_CSI_SUPPORT=y +CONFIG_SOC_WIFI_MESH_SUPPORT=y +CONFIG_SOC_WIFI_SUPPORT_VARIABLE_BEACON_WINDOW=y +CONFIG_SOC_WIFI_NAN_SUPPORT=y +CONFIG_SOC_ULP_HAS_ADC=y +CONFIG_IDF_CMAKE=y +CONFIG_IDF_TOOLCHAIN="gcc" +CONFIG_IDF_TARGET_ARCH_XTENSA=y +CONFIG_IDF_TARGET_ARCH="xtensa" +CONFIG_IDF_TARGET="esp32s2" +CONFIG_IDF_INIT_VERSION="5.3.1" +CONFIG_IDF_TARGET_ESP32S2=y +CONFIG_IDF_FIRMWARE_CHIP_ID=0x0002 + +# +# Build type +# +CONFIG_APP_BUILD_TYPE_APP_2NDBOOT=y +# CONFIG_APP_BUILD_TYPE_RAM is not set +CONFIG_APP_BUILD_GENERATE_BINARIES=y +CONFIG_APP_BUILD_BOOTLOADER=y +CONFIG_APP_BUILD_USE_FLASH_SECTIONS=y +# CONFIG_APP_REPRODUCIBLE_BUILD is not set +# CONFIG_APP_NO_BLOBS is not set +# end of Build type + +# +# Bootloader config +# + +# +# Bootloader manager +# +CONFIG_BOOTLOADER_COMPILE_TIME_DATE=y +CONFIG_BOOTLOADER_PROJECT_VER=1 +# end of Bootloader manager + +CONFIG_BOOTLOADER_OFFSET_IN_FLASH=0x1000 +CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG is not set +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_PERF is not set +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_NONE is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_NONE is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_ERROR is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_WARN is not set +CONFIG_BOOTLOADER_LOG_LEVEL_INFO=y +# CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE is not set +CONFIG_BOOTLOADER_LOG_LEVEL=3 + +# +# Serial Flash Configurations +# +# CONFIG_BOOTLOADER_FLASH_DC_AWARE is not set +CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT=y +# end of Serial Flash Configurations + +CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y +# CONFIG_BOOTLOADER_FACTORY_RESET is not set +# CONFIG_BOOTLOADER_APP_TEST is not set +CONFIG_BOOTLOADER_REGION_PROTECTION_ENABLE=y +CONFIG_BOOTLOADER_WDT_ENABLE=y +# CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE is not set +CONFIG_BOOTLOADER_WDT_TIME_MS=9000 +# CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_ALWAYS is not set +CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0 +# CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC is not set +# end of Bootloader config + +# +# Security features +# +CONFIG_SECURE_BOOT_V2_RSA_SUPPORTED=y +CONFIG_SECURE_BOOT_V2_PREFERRED=y +# CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT is not set +# CONFIG_SECURE_BOOT is not set +# CONFIG_SECURE_FLASH_ENC_ENABLED is not set +CONFIG_SECURE_ROM_DL_MODE_ENABLED=y +# end of Security features + +# +# Application manager +# +CONFIG_APP_COMPILE_TIME_DATE=y +# CONFIG_APP_EXCLUDE_PROJECT_VER_VAR is not set +# CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR is not set +# CONFIG_APP_PROJECT_VER_FROM_CONFIG is not set +CONFIG_APP_RETRIEVE_LEN_ELF_SHA=16 +# end of Application manager + +CONFIG_ESP_ROM_HAS_CRC_LE=y +CONFIG_ESP_ROM_HAS_MZ_CRC32=y +CONFIG_ESP_ROM_HAS_UART_BUF_SWITCH=y +CONFIG_ESP_ROM_NEEDS_SWSETUP_WORKAROUND=y +CONFIG_ESP_ROM_HAS_REGI2C_BUG=y +CONFIG_ESP_ROM_HAS_NEWLIB=y +CONFIG_ESP_ROM_HAS_NEWLIB_NANO_FORMAT=y +CONFIG_ESP_ROM_HAS_NEWLIB_32BIT_TIME=y +CONFIG_ESP_ROM_USB_OTG_NUM=3 +CONFIG_ESP_ROM_HAS_FLASH_COUNT_PAGES_BUG=y +CONFIG_ESP_ROM_HAS_SW_FLOAT=y +CONFIG_ESP_ROM_USB_SERIAL_DEVICE_NUM=-1 +CONFIG_ESP_ROM_SUPPORT_DEEP_SLEEP_WAKEUP_STUB=y + +# +# Boot ROM Behavior +# +CONFIG_BOOT_ROM_LOG_ALWAYS_ON=y +# CONFIG_BOOT_ROM_LOG_ALWAYS_OFF is not set +# CONFIG_BOOT_ROM_LOG_ON_GPIO_HIGH is not set +# CONFIG_BOOT_ROM_LOG_ON_GPIO_LOW is not set +# end of Boot ROM Behavior + +# +# Serial flasher config +# +# CONFIG_ESPTOOLPY_NO_STUB is not set +# CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set +# CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set +CONFIG_ESPTOOLPY_FLASHMODE_DIO=y +# CONFIG_ESPTOOLPY_FLASHMODE_DOUT is not set +CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR=y +CONFIG_ESPTOOLPY_FLASHMODE="dio" +CONFIG_ESPTOOLPY_FLASHFREQ_80M=y +# CONFIG_ESPTOOLPY_FLASHFREQ_40M is not set +# CONFIG_ESPTOOLPY_FLASHFREQ_26M is not set +# CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set +CONFIG_ESPTOOLPY_FLASHFREQ_80M_DEFAULT=y +CONFIG_ESPTOOLPY_FLASHFREQ="80m" +# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_2MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_32MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE="4MB" +# CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE is not set +CONFIG_ESPTOOLPY_BEFORE_RESET=y +# CONFIG_ESPTOOLPY_BEFORE_NORESET is not set +CONFIG_ESPTOOLPY_BEFORE="default_reset" +CONFIG_ESPTOOLPY_AFTER_RESET=y +# CONFIG_ESPTOOLPY_AFTER_NORESET is not set +CONFIG_ESPTOOLPY_AFTER="hard_reset" +CONFIG_ESPTOOLPY_MONITOR_BAUD=115200 +# end of Serial flasher config + +# +# Partition Table +# +# CONFIG_PARTITION_TABLE_SINGLE_APP is not set +# CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE is not set +# CONFIG_PARTITION_TABLE_TWO_OTA is not set +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_OFFSET=0x8000 +CONFIG_PARTITION_TABLE_MD5=y +# end of Partition Table + +# +# Example Configuration +# +CONFIG_ESP_WIFI_SSID="myssid" +CONFIG_ESP_WIFI_PASSWORD="mypassword" +# end of Example Configuration + +# +# Compiler options +# +# CONFIG_COMPILER_OPTIMIZATION_DEBUG is not set +CONFIG_COMPILER_OPTIMIZATION_SIZE=y +# CONFIG_COMPILER_OPTIMIZATION_PERF is not set +# CONFIG_COMPILER_OPTIMIZATION_NONE is not set +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y +# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT is not set +# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE is not set +CONFIG_COMPILER_FLOAT_LIB_FROM_GCCLIB=y +CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL=2 +# CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT is not set +CONFIG_COMPILER_HIDE_PATHS_MACROS=y +# CONFIG_COMPILER_CXX_EXCEPTIONS is not set +# CONFIG_COMPILER_CXX_RTTI is not set +CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y +# CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set +# CONFIG_COMPILER_STACK_CHECK_MODE_STRONG is not set +# CONFIG_COMPILER_STACK_CHECK_MODE_ALL is not set +# CONFIG_COMPILER_WARN_WRITE_STRINGS is not set +# CONFIG_COMPILER_DISABLE_GCC12_WARNINGS is not set +# CONFIG_COMPILER_DISABLE_GCC13_WARNINGS is not set +# CONFIG_COMPILER_DUMP_RTL_FILES is not set +CONFIG_COMPILER_RT_LIB_GCCLIB=y +CONFIG_COMPILER_RT_LIB_NAME="gcc" +# CONFIG_COMPILER_ORPHAN_SECTIONS_WARNING is not set +CONFIG_COMPILER_ORPHAN_SECTIONS_PLACE=y +# end of Compiler options + +# +# Component config +# + +# +# Application Level Tracing +# +# CONFIG_APPTRACE_DEST_JTAG is not set +CONFIG_APPTRACE_DEST_NONE=y +# CONFIG_APPTRACE_DEST_UART1 is not set +CONFIG_APPTRACE_DEST_UART_NONE=y +CONFIG_APPTRACE_UART_TASK_PRIO=1 +CONFIG_APPTRACE_LOCK_ENABLE=y +# end of Application Level Tracing + +# +# Bluetooth +# +# CONFIG_BT_ENABLED is not set +CONFIG_BT_ALARM_MAX_NUM=50 +# end of Bluetooth + +# +# Console Library +# +# CONFIG_CONSOLE_SORTED_HELP is not set +# end of Console Library + +# +# Driver Configurations +# + +# +# TWAI Configuration +# +# CONFIG_TWAI_ISR_IN_IRAM is not set +CONFIG_TWAI_ERRATA_FIX_LISTEN_ONLY_DOM=y +# end of TWAI Configuration + +# +# Legacy ADC Driver Configuration +# +CONFIG_ADC_DISABLE_DAC=y +# CONFIG_ADC_SUPPRESS_DEPRECATE_WARN is not set + +# +# Legacy ADC Calibration Configuration +# +# CONFIG_ADC_CALI_SUPPRESS_DEPRECATE_WARN is not set +# end of Legacy ADC Calibration Configuration +# end of Legacy ADC Driver Configuration + +# +# Legacy DAC Driver Configurations +# +# CONFIG_DAC_SUPPRESS_DEPRECATE_WARN is not set +# end of Legacy DAC Driver Configurations + +# +# Legacy Timer Group Driver Configurations +# +# CONFIG_GPTIMER_SUPPRESS_DEPRECATE_WARN is not set +# end of Legacy Timer Group Driver Configurations + +# +# Legacy RMT Driver Configurations +# +# CONFIG_RMT_SUPPRESS_DEPRECATE_WARN is not set +# end of Legacy RMT Driver Configurations + +# +# Legacy I2S Driver Configurations +# +# CONFIG_I2S_SUPPRESS_DEPRECATE_WARN is not set +# end of Legacy I2S Driver Configurations + +# +# Legacy PCNT Driver Configurations +# +# CONFIG_PCNT_SUPPRESS_DEPRECATE_WARN is not set +# end of Legacy PCNT Driver Configurations + +# +# Legacy SDM Driver Configurations +# +# CONFIG_SDM_SUPPRESS_DEPRECATE_WARN is not set +# end of Legacy SDM Driver Configurations + +# +# Legacy Temperature Sensor Driver Configurations +# +# CONFIG_TEMP_SENSOR_SUPPRESS_DEPRECATE_WARN is not set +# end of Legacy Temperature Sensor Driver Configurations +# end of Driver Configurations + +# +# eFuse Bit Manager +# +# CONFIG_EFUSE_CUSTOM_TABLE is not set +# CONFIG_EFUSE_VIRTUAL is not set +CONFIG_EFUSE_MAX_BLK_LEN=256 +# end of eFuse Bit Manager + +# +# ESP-TLS +# +CONFIG_ESP_TLS_USING_MBEDTLS=y +CONFIG_ESP_TLS_USE_DS_PERIPHERAL=y +# CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS is not set +# CONFIG_ESP_TLS_SERVER_SESSION_TICKETS is not set +# CONFIG_ESP_TLS_SERVER_CERT_SELECT_HOOK is not set +# CONFIG_ESP_TLS_SERVER_MIN_AUTH_MODE_OPTIONAL is not set +# CONFIG_ESP_TLS_PSK_VERIFICATION is not set +# CONFIG_ESP_TLS_INSECURE is not set +# end of ESP-TLS + +# +# ADC and ADC Calibration +# +# CONFIG_ADC_ONESHOT_CTRL_FUNC_IN_IRAM is not set +# CONFIG_ADC_CONTINUOUS_ISR_IRAM_SAFE is not set +CONFIG_ADC_DISABLE_DAC_OUTPUT=y +# CONFIG_ADC_ENABLE_DEBUG_LOG is not set +# end of ADC and ADC Calibration + +# +# Wireless Coexistence +# +CONFIG_ESP_COEX_ENABLED=y +# CONFIG_ESP_COEX_EXTERNAL_COEXIST_ENABLE is not set +# end of Wireless Coexistence + +# +# Common ESP-related +# +CONFIG_ESP_ERR_TO_NAME_LOOKUP=y +# end of Common ESP-related + +# +# ESP-Driver:DAC Configurations +# +# CONFIG_DAC_CTRL_FUNC_IN_IRAM is not set +# CONFIG_DAC_ISR_IRAM_SAFE is not set +# CONFIG_DAC_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:DAC Configurations + +# +# ESP-Driver:GPIO Configurations +# +# CONFIG_GPIO_CTRL_FUNC_IN_IRAM is not set +# end of ESP-Driver:GPIO Configurations + +# +# ESP-Driver:GPTimer Configurations +# +CONFIG_GPTIMER_ISR_HANDLER_IN_IRAM=y +# CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM is not set +# CONFIG_GPTIMER_ISR_IRAM_SAFE is not set +# CONFIG_GPTIMER_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:GPTimer Configurations + +# +# ESP-Driver:I2C Configurations +# +# CONFIG_I2C_ISR_IRAM_SAFE is not set +# CONFIG_I2C_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:I2C Configurations + +# +# ESP-Driver:I2S Configurations +# +# CONFIG_I2S_ISR_IRAM_SAFE is not set +# CONFIG_I2S_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:I2S Configurations + +# +# ESP-Driver:LEDC Configurations +# +# CONFIG_LEDC_CTRL_FUNC_IN_IRAM is not set +# end of ESP-Driver:LEDC Configurations + +# +# ESP-Driver:PCNT Configurations +# +# CONFIG_PCNT_CTRL_FUNC_IN_IRAM is not set +# CONFIG_PCNT_ISR_IRAM_SAFE is not set +# CONFIG_PCNT_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:PCNT Configurations + +# +# ESP-Driver:RMT Configurations +# +# CONFIG_RMT_ISR_IRAM_SAFE is not set +# CONFIG_RMT_RECV_FUNC_IN_IRAM is not set +# CONFIG_RMT_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:RMT Configurations + +# +# ESP-Driver:Sigma Delta Modulator Configurations +# +# CONFIG_SDM_CTRL_FUNC_IN_IRAM is not set +# CONFIG_SDM_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:Sigma Delta Modulator Configurations + +# +# ESP-Driver:SPI Configurations +# +# CONFIG_SPI_MASTER_IN_IRAM is not set +CONFIG_SPI_MASTER_ISR_IN_IRAM=y +# CONFIG_SPI_SLAVE_IN_IRAM is not set +CONFIG_SPI_SLAVE_ISR_IN_IRAM=y +# end of ESP-Driver:SPI Configurations + +# +# ESP-Driver:Touch Sensor Configurations +# +# CONFIG_TOUCH_CTRL_FUNC_IN_IRAM is not set +# CONFIG_TOUCH_ISR_IRAM_SAFE is not set +# CONFIG_TOUCH_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:Touch Sensor Configurations + +# +# ESP-Driver:Temperature Sensor Configurations +# +# CONFIG_TEMP_SENSOR_ENABLE_DEBUG_LOG is not set +# end of ESP-Driver:Temperature Sensor Configurations + +# +# ESP-Driver:UART Configurations +# +# CONFIG_UART_ISR_IN_IRAM is not set +# end of ESP-Driver:UART Configurations + +# +# Ethernet +# +CONFIG_ETH_ENABLED=y +CONFIG_ETH_USE_SPI_ETHERNET=y +# CONFIG_ETH_SPI_ETHERNET_DM9051 is not set +# CONFIG_ETH_SPI_ETHERNET_W5500 is not set +# CONFIG_ETH_SPI_ETHERNET_KSZ8851SNL is not set +# CONFIG_ETH_USE_OPENETH is not set +# CONFIG_ETH_TRANSMIT_MUTEX is not set +# end of Ethernet + +# +# Event Loop Library +# +# CONFIG_ESP_EVENT_LOOP_PROFILING is not set +CONFIG_ESP_EVENT_POST_FROM_ISR=y +CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=y +# end of Event Loop Library + +# +# GDB Stub +# +CONFIG_ESP_GDBSTUB_ENABLED=y +# CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME is not set +CONFIG_ESP_GDBSTUB_SUPPORT_TASKS=y +CONFIG_ESP_GDBSTUB_MAX_TASKS=32 +# end of GDB Stub + +# +# ESP HTTP client +# +CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y +# CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set +# CONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH is not set +# CONFIG_ESP_HTTP_CLIENT_ENABLE_CUSTOM_TRANSPORT is not set +# end of ESP HTTP client + +# +# HTTP Server +# +CONFIG_HTTPD_MAX_REQ_HDR_LEN=512 +CONFIG_HTTPD_MAX_URI_LEN=512 +CONFIG_HTTPD_ERR_RESP_NO_DELAY=y +CONFIG_HTTPD_PURGE_BUF_LEN=32 +# CONFIG_HTTPD_LOG_PURGE_DATA is not set +# CONFIG_HTTPD_WS_SUPPORT is not set +# CONFIG_HTTPD_QUEUE_WORK_BLOCKING is not set +# end of HTTP Server + +# +# ESP HTTPS OTA +# +# CONFIG_ESP_HTTPS_OTA_DECRYPT_CB is not set +# CONFIG_ESP_HTTPS_OTA_ALLOW_HTTP is not set +# end of ESP HTTPS OTA + +# +# ESP HTTPS server +# +# end of ESP HTTPS server + +# +# Hardware Settings +# + +# +# Chip revision +# +CONFIG_ESP32S2_REV_MIN_0=y +# CONFIG_ESP32S2_REV_MIN_1 is not set +CONFIG_ESP32S2_REV_MIN_FULL=0 +CONFIG_ESP_REV_MIN_FULL=0 + +# +# Maximum Supported ESP32-S2 Revision (Rev v1.99) +# +CONFIG_ESP32S2_REV_MAX_FULL=199 +CONFIG_ESP_REV_MAX_FULL=199 +# end of Chip revision + +# +# MAC Config +# +CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_STA=y +CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_AP=y +CONFIG_ESP_MAC_UNIVERSAL_MAC_ADDRESSES_TWO=y +CONFIG_ESP_MAC_UNIVERSAL_MAC_ADDRESSES=2 +# CONFIG_ESP32S2_UNIVERSAL_MAC_ADDRESSES_ONE is not set +CONFIG_ESP32S2_UNIVERSAL_MAC_ADDRESSES_TWO=y +CONFIG_ESP32S2_UNIVERSAL_MAC_ADDRESSES=2 +# CONFIG_ESP_MAC_USE_CUSTOM_MAC_AS_BASE_MAC is not set +# end of MAC Config + +# +# Sleep Config +# +# CONFIG_ESP_SLEEP_POWER_DOWN_FLASH is not set +CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND=y +# CONFIG_ESP_SLEEP_MSPI_NEED_ALL_IO_PU is not set +CONFIG_ESP_SLEEP_RTC_BUS_ISO_WORKAROUND=y +# CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND is not set +CONFIG_ESP_SLEEP_WAIT_FLASH_READY_EXTRA_DELAY=0 +# CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION is not set +# CONFIG_ESP_SLEEP_DEBUG is not set +CONFIG_ESP_SLEEP_GPIO_ENABLE_INTERNAL_RESISTORS=y +# end of Sleep Config + +# +# RTC Clock Config +# +CONFIG_RTC_CLK_SRC_INT_RC=y +# CONFIG_RTC_CLK_SRC_EXT_CRYS is not set +# CONFIG_RTC_CLK_SRC_EXT_OSC is not set +# CONFIG_RTC_CLK_SRC_INT_8MD256 is not set +CONFIG_RTC_CLK_CAL_CYCLES=576 +# end of RTC Clock Config + +# +# Peripheral Control +# +CONFIG_PERIPH_CTRL_FUNC_IN_IRAM=y +# end of Peripheral Control + +# +# Main XTAL Config +# +CONFIG_XTAL_FREQ_40=y +CONFIG_XTAL_FREQ=40 +# end of Main XTAL Config + +CONFIG_ESP_SPI_BUS_LOCK_ISR_FUNCS_IN_IRAM=y +# end of Hardware Settings + +# +# LCD and Touch Panel +# + +# +# LCD Touch Drivers are maintained in the IDF Component Registry +# + +# +# LCD Peripheral Configuration +# +CONFIG_LCD_PANEL_IO_FORMAT_BUF_SIZE=32 +# CONFIG_LCD_ENABLE_DEBUG_LOG is not set +# end of LCD Peripheral Configuration +# end of LCD and Touch Panel + +# +# ESP NETIF Adapter +# +CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL=120 +CONFIG_ESP_NETIF_TCPIP_LWIP=y +# CONFIG_ESP_NETIF_LOOPBACK is not set +CONFIG_ESP_NETIF_USES_TCPIP_WITH_BSD_API=y +# CONFIG_ESP_NETIF_RECEIVE_REPORT_ERRORS is not set +# CONFIG_ESP_NETIF_L2_TAP is not set +# CONFIG_ESP_NETIF_BRIDGE_EN is not set +# end of ESP NETIF Adapter + +# +# Partition API Configuration +# +# end of Partition API Configuration + +# +# PHY +# +CONFIG_ESP_PHY_ENABLED=y +CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE=y +# CONFIG_ESP_PHY_INIT_DATA_IN_PARTITION is not set +CONFIG_ESP_PHY_MAX_WIFI_TX_POWER=20 +CONFIG_ESP_PHY_MAX_TX_POWER=20 +CONFIG_ESP_PHY_RF_CAL_PARTIAL=y +# CONFIG_ESP_PHY_RF_CAL_NONE is not set +# CONFIG_ESP_PHY_RF_CAL_FULL is not set +CONFIG_ESP_PHY_CALIBRATION_MODE=0 +# CONFIG_ESP_PHY_PLL_TRACK_DEBUG is not set +# end of PHY + +# +# Power Management +# +# CONFIG_PM_ENABLE is not set +# end of Power Management + +# +# ESP PSRAM +# +# CONFIG_SPIRAM is not set +# end of ESP PSRAM + +# +# ESP Ringbuf +# +# CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH is not set +# end of ESP Ringbuf + +# +# ESP System Settings +# +CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_80=y +# CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_160 is not set +# CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240 is not set +CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=80 + +# +# Cache config +# +CONFIG_ESP32S2_INSTRUCTION_CACHE_8KB=y +# CONFIG_ESP32S2_INSTRUCTION_CACHE_16KB is not set +# CONFIG_ESP32S2_INSTRUCTION_CACHE_LINE_16B is not set +CONFIG_ESP32S2_INSTRUCTION_CACHE_LINE_32B=y +# CONFIG_ESP32S2_DATA_CACHE_0KB is not set +CONFIG_ESP32S2_DATA_CACHE_8KB=y +# CONFIG_ESP32S2_DATA_CACHE_16KB is not set +# CONFIG_ESP32S2_DATA_CACHE_LINE_16B is not set +CONFIG_ESP32S2_DATA_CACHE_LINE_32B=y +# CONFIG_ESP32S2_INSTRUCTION_CACHE_WRAP is not set +# CONFIG_ESP32S2_DATA_CACHE_WRAP is not set +# end of Cache config + +# +# Memory +# +# CONFIG_ESP32S2_RTCDATA_IN_FAST_MEM is not set +# CONFIG_ESP32S2_USE_FIXED_STATIC_RAM_SIZE is not set +# end of Memory + +# +# Trace memory +# +# CONFIG_ESP32S2_TRAX is not set +CONFIG_ESP32S2_TRACEMEM_RESERVE_DRAM=0x0 +# end of Trace memory + +# CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT is not set +CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT=y +# CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set +# CONFIG_ESP_SYSTEM_PANIC_GDBSTUB is not set +CONFIG_ESP_SYSTEM_PANIC_REBOOT_DELAY_SECONDS=0 +CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE=y +CONFIG_ESP_SYSTEM_RTC_FAST_MEM_AS_HEAP_DEPCHECK=y +CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP=y + +# +# Memory protection +# +CONFIG_ESP_SYSTEM_MEMPROT_FEATURE=y +CONFIG_ESP_SYSTEM_MEMPROT_FEATURE_LOCK=y +# end of Memory protection + +CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32 +CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=3584 +CONFIG_ESP_MAIN_TASK_AFFINITY_CPU0=y +# CONFIG_ESP_MAIN_TASK_AFFINITY_NO_AFFINITY is not set +CONFIG_ESP_MAIN_TASK_AFFINITY=0x0 +CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE=2048 +CONFIG_ESP_CONSOLE_UART_DEFAULT=y +# CONFIG_ESP_CONSOLE_USB_CDC is not set +# CONFIG_ESP_CONSOLE_UART_CUSTOM is not set +# CONFIG_ESP_CONSOLE_NONE is not set +CONFIG_ESP_CONSOLE_UART=y +CONFIG_ESP_CONSOLE_UART_NUM=0 +CONFIG_ESP_CONSOLE_ROM_SERIAL_PORT_NUM=0 +CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 +CONFIG_ESP_INT_WDT=y +CONFIG_ESP_INT_WDT_TIMEOUT_MS=300 +CONFIG_ESP_TASK_WDT_EN=y +CONFIG_ESP_TASK_WDT_INIT=y +# CONFIG_ESP_TASK_WDT_PANIC is not set +CONFIG_ESP_TASK_WDT_TIMEOUT_S=5 +CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=y +# CONFIG_ESP_PANIC_HANDLER_IRAM is not set +# CONFIG_ESP_DEBUG_STUBS_ENABLE is not set +CONFIG_ESP_DEBUG_OCDAWARE=y +CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_4=y + +# +# Brownout Detector +# +# CONFIG_ESP_BROWNOUT_DET is not set +# end of Brownout Detector + +# CONFIG_ESP32S2_KEEP_USB_ALIVE is not set +CONFIG_ESP_SYSTEM_BROWNOUT_INTR=y +# end of ESP System Settings + +# +# IPC (Inter-Processor Call) +# +CONFIG_ESP_IPC_TASK_STACK_SIZE=1024 +# end of IPC (Inter-Processor Call) + +# +# ESP Timer (High Resolution Timer) +# +# CONFIG_ESP_TIMER_PROFILING is not set +CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER=y +CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER=y +CONFIG_ESP_TIMER_TASK_STACK_SIZE=3584 +CONFIG_ESP_TIMER_INTERRUPT_LEVEL=1 +# CONFIG_ESP_TIMER_SHOW_EXPERIMENTAL is not set +CONFIG_ESP_TIMER_TASK_AFFINITY=0x0 +CONFIG_ESP_TIMER_TASK_AFFINITY_CPU0=y +CONFIG_ESP_TIMER_ISR_AFFINITY_CPU0=y +# CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD is not set +CONFIG_ESP_TIMER_IMPL_SYSTIMER=y +# end of ESP Timer (High Resolution Timer) + +# +# Wi-Fi +# +CONFIG_ESP_WIFI_ENABLED=y +CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM=10 +CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM=32 +# CONFIG_ESP_WIFI_STATIC_TX_BUFFER is not set +CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER=y +CONFIG_ESP_WIFI_TX_BUFFER_TYPE=1 +CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER_NUM=32 +CONFIG_ESP_WIFI_STATIC_RX_MGMT_BUFFER=y +# CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUFFER is not set +CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUF=0 +CONFIG_ESP_WIFI_RX_MGMT_BUF_NUM_DEF=5 +# CONFIG_ESP_WIFI_CSI_ENABLED is not set +# CONFIG_ESP_WIFI_AMPDU_TX_ENABLED is not set +CONFIG_ESP_WIFI_AMPDU_RX_ENABLED=y +CONFIG_ESP_WIFI_RX_BA_WIN=6 +CONFIG_ESP_WIFI_NVS_ENABLED=y +CONFIG_ESP_WIFI_SOFTAP_BEACON_MAX_LEN=752 +CONFIG_ESP_WIFI_MGMT_SBUF_NUM=32 +# CONFIG_ESP_WIFI_IRAM_OPT is not set +# CONFIG_ESP_WIFI_EXTRA_IRAM_OPT is not set +CONFIG_ESP_WIFI_RX_IRAM_OPT=y +CONFIG_ESP_WIFI_ENABLE_WPA3_SAE=y +CONFIG_ESP_WIFI_ENABLE_SAE_PK=y +CONFIG_ESP_WIFI_SOFTAP_SAE_SUPPORT=y +CONFIG_ESP_WIFI_ENABLE_WPA3_OWE_STA=y +# CONFIG_ESP_WIFI_SLP_IRAM_OPT is not set +CONFIG_ESP_WIFI_SLP_DEFAULT_MIN_ACTIVE_TIME=50 +CONFIG_ESP_WIFI_SLP_DEFAULT_MAX_ACTIVE_TIME=10 +CONFIG_ESP_WIFI_SLP_DEFAULT_WAIT_BROADCAST_DATA_TIME=15 +# CONFIG_ESP_WIFI_FTM_ENABLE is not set +# CONFIG_ESP_WIFI_STA_DISCONNECTED_PM_ENABLE is not set +# CONFIG_ESP_WIFI_GMAC_SUPPORT is not set +CONFIG_ESP_WIFI_SOFTAP_SUPPORT=y +# CONFIG_ESP_WIFI_SLP_BEACON_LOST_OPT is not set +CONFIG_ESP_WIFI_ESPNOW_MAX_ENCRYPT_NUM=7 +# CONFIG_ESP_WIFI_NAN_ENABLE is not set +CONFIG_ESP_WIFI_MBEDTLS_CRYPTO=y +CONFIG_ESP_WIFI_MBEDTLS_TLS_CLIENT=y +# CONFIG_ESP_WIFI_WAPI_PSK is not set +# CONFIG_ESP_WIFI_11KV_SUPPORT is not set +# CONFIG_ESP_WIFI_MBO_SUPPORT is not set +# CONFIG_ESP_WIFI_DPP_SUPPORT is not set +# CONFIG_ESP_WIFI_11R_SUPPORT is not set +# CONFIG_ESP_WIFI_WPS_SOFTAP_REGISTRAR is not set + +# +# WPS Configuration Options +# +# CONFIG_ESP_WIFI_WPS_STRICT is not set +# CONFIG_ESP_WIFI_WPS_PASSPHRASE is not set +# end of WPS Configuration Options + +# CONFIG_ESP_WIFI_DEBUG_PRINT is not set +# CONFIG_ESP_WIFI_TESTING_OPTIONS is not set +CONFIG_ESP_WIFI_ENTERPRISE_SUPPORT=y +# CONFIG_ESP_WIFI_ENT_FREE_DYNAMIC_BUFFER is not set +# end of Wi-Fi + +# +# Core dump +# +# CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH is not set +# CONFIG_ESP_COREDUMP_ENABLE_TO_UART is not set +CONFIG_ESP_COREDUMP_ENABLE_TO_NONE=y +# end of Core dump + +# +# FAT Filesystem support +# +CONFIG_FATFS_VOLUME_COUNT=2 +CONFIG_FATFS_LFN_NONE=y +# CONFIG_FATFS_LFN_HEAP is not set +# CONFIG_FATFS_LFN_STACK is not set +# CONFIG_FATFS_SECTOR_512 is not set +CONFIG_FATFS_SECTOR_4096=y +# CONFIG_FATFS_CODEPAGE_DYNAMIC is not set +CONFIG_FATFS_CODEPAGE_437=y +# CONFIG_FATFS_CODEPAGE_720 is not set +# CONFIG_FATFS_CODEPAGE_737 is not set +# CONFIG_FATFS_CODEPAGE_771 is not set +# CONFIG_FATFS_CODEPAGE_775 is not set +# CONFIG_FATFS_CODEPAGE_850 is not set +# CONFIG_FATFS_CODEPAGE_852 is not set +# CONFIG_FATFS_CODEPAGE_855 is not set +# CONFIG_FATFS_CODEPAGE_857 is not set +# CONFIG_FATFS_CODEPAGE_860 is not set +# CONFIG_FATFS_CODEPAGE_861 is not set +# CONFIG_FATFS_CODEPAGE_862 is not set +# CONFIG_FATFS_CODEPAGE_863 is not set +# CONFIG_FATFS_CODEPAGE_864 is not set +# CONFIG_FATFS_CODEPAGE_865 is not set +# CONFIG_FATFS_CODEPAGE_866 is not set +# CONFIG_FATFS_CODEPAGE_869 is not set +# CONFIG_FATFS_CODEPAGE_932 is not set +# CONFIG_FATFS_CODEPAGE_936 is not set +# CONFIG_FATFS_CODEPAGE_949 is not set +# CONFIG_FATFS_CODEPAGE_950 is not set +CONFIG_FATFS_CODEPAGE=437 +CONFIG_FATFS_FS_LOCK=0 +CONFIG_FATFS_TIMEOUT_MS=10000 +CONFIG_FATFS_PER_FILE_CACHE=y +# CONFIG_FATFS_USE_FASTSEEK is not set +CONFIG_FATFS_VFS_FSTAT_BLKSIZE=0 +# CONFIG_FATFS_IMMEDIATE_FSYNC is not set +# CONFIG_FATFS_USE_LABEL is not set +CONFIG_FATFS_LINK_LOCK=y +# end of FAT Filesystem support + +# +# FreeRTOS +# + +# +# Kernel +# +# CONFIG_FREERTOS_SMP is not set +CONFIG_FREERTOS_UNICORE=y +CONFIG_FREERTOS_HZ=100 +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set +# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL is not set +CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536 +# CONFIG_FREERTOS_USE_IDLE_HOOK is not set +# CONFIG_FREERTOS_USE_TICK_HOOK is not set +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 +# CONFIG_FREERTOS_ENABLE_BACKWARD_COMPATIBILITY is not set +CONFIG_FREERTOS_TIMER_SERVICE_TASK_NAME="Tmr Svc" +# CONFIG_FREERTOS_TIMER_TASK_AFFINITY_CPU0 is not set +CONFIG_FREERTOS_TIMER_TASK_NO_AFFINITY=y +CONFIG_FREERTOS_TIMER_SERVICE_TASK_CORE_AFFINITY=0x7FFFFFFF +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=1 +# CONFIG_FREERTOS_USE_TRACE_FACILITY is not set +# CONFIG_FREERTOS_USE_LIST_DATA_INTEGRITY_CHECK_BYTES is not set +# CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set +# CONFIG_FREERTOS_USE_APPLICATION_TASK_TAG is not set +# end of Kernel + +# +# Port +# +# CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set +CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS=y +# CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK is not set +# CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP is not set +CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y +CONFIG_FREERTOS_ISR_STACKSIZE=1536 +CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y +CONFIG_FREERTOS_TICK_SUPPORT_CORETIMER=y +CONFIG_FREERTOS_CORETIMER_0=y +# CONFIG_FREERTOS_CORETIMER_1 is not set +CONFIG_FREERTOS_SYSTICK_USES_CCOUNT=y +# CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH is not set +# CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set +# end of Port + +CONFIG_FREERTOS_PORT=y +CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF +CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y +CONFIG_FREERTOS_DEBUG_OCDAWARE=y +CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT=y +CONFIG_FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH=y +CONFIG_FREERTOS_NUMBER_OF_CORES=1 +# end of FreeRTOS + +# +# Hardware Abstraction Layer (HAL) and Low Level (LL) +# +CONFIG_HAL_ASSERTION_EQUALS_SYSTEM=y +# CONFIG_HAL_ASSERTION_DISABLE is not set +# CONFIG_HAL_ASSERTION_SILENT is not set +# CONFIG_HAL_ASSERTION_ENABLE is not set +CONFIG_HAL_DEFAULT_ASSERTION_LEVEL=2 +CONFIG_HAL_SPI_MASTER_FUNC_IN_IRAM=y +CONFIG_HAL_SPI_SLAVE_FUNC_IN_IRAM=y +# end of Hardware Abstraction Layer (HAL) and Low Level (LL) + +# +# Heap memory debugging +# +CONFIG_HEAP_POISONING_DISABLED=y +# CONFIG_HEAP_POISONING_LIGHT is not set +# CONFIG_HEAP_POISONING_COMPREHENSIVE is not set +CONFIG_HEAP_TRACING_OFF=y +# CONFIG_HEAP_TRACING_STANDALONE is not set +# CONFIG_HEAP_TRACING_TOHOST is not set +# CONFIG_HEAP_USE_HOOKS is not set +# CONFIG_HEAP_TASK_TRACKING is not set +# CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS is not set +# CONFIG_HEAP_PLACE_FUNCTION_INTO_FLASH is not set +# end of Heap memory debugging + +# +# Log output +# +# CONFIG_LOG_DEFAULT_LEVEL_NONE is not set +# CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set +# CONFIG_LOG_DEFAULT_LEVEL_WARN is not set +CONFIG_LOG_DEFAULT_LEVEL_INFO=y +# CONFIG_LOG_DEFAULT_LEVEL_DEBUG is not set +# CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set +CONFIG_LOG_DEFAULT_LEVEL=3 +CONFIG_LOG_MAXIMUM_EQUALS_DEFAULT=y +# CONFIG_LOG_MAXIMUM_LEVEL_DEBUG is not set +# CONFIG_LOG_MAXIMUM_LEVEL_VERBOSE is not set +CONFIG_LOG_MAXIMUM_LEVEL=3 +# CONFIG_LOG_MASTER_LEVEL is not set +CONFIG_LOG_COLORS=y +# CONFIG_LOG_TIMESTAMP_SOURCE_RTOS is not set +CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM=y +# end of Log output + +# +# LWIP +# +CONFIG_LWIP_ENABLE=y +CONFIG_LWIP_LOCAL_HOSTNAME="espressif" +# CONFIG_LWIP_NETIF_API is not set +CONFIG_LWIP_TCPIP_TASK_PRIO=18 +# CONFIG_LWIP_TCPIP_CORE_LOCKING is not set +# CONFIG_LWIP_CHECK_THREAD_SAFETY is not set +CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y +# CONFIG_LWIP_L2_TO_L3_COPY is not set +# CONFIG_LWIP_IRAM_OPTIMIZATION is not set +# CONFIG_LWIP_EXTRA_IRAM_OPTIMIZATION is not set +CONFIG_LWIP_TIMERS_ONDEMAND=y +CONFIG_LWIP_MAX_SOCKETS=10 +# CONFIG_LWIP_USE_ONLY_LWIP_SELECT is not set +# CONFIG_LWIP_SO_LINGER is not set +CONFIG_LWIP_SO_REUSE=y +CONFIG_LWIP_SO_REUSE_RXTOALL=y +# CONFIG_LWIP_SO_RCVBUF is not set +# CONFIG_LWIP_NETBUF_RECVINFO is not set +CONFIG_LWIP_IP_DEFAULT_TTL=64 +CONFIG_LWIP_IP4_FRAG=y +# CONFIG_LWIP_IP4_REASSEMBLY is not set +CONFIG_LWIP_IP_REASS_MAX_PBUFS=10 +# CONFIG_LWIP_IP_FORWARD is not set +# CONFIG_LWIP_STATS is not set +CONFIG_LWIP_ESP_GRATUITOUS_ARP=y +CONFIG_LWIP_GARP_TMR_INTERVAL=60 +CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 +CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y +# CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set +CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y +# CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set +CONFIG_LWIP_DHCP_OPTIONS_LEN=68 +CONFIG_LWIP_NUM_NETIF_CLIENT_DATA=0 +CONFIG_LWIP_DHCP_COARSE_TIMER_SECS=1 + +# +# DHCP server +# +CONFIG_LWIP_DHCPS=y +CONFIG_LWIP_DHCPS_LEASE_UNIT=60 +CONFIG_LWIP_DHCPS_MAX_STATION_NUM=8 +CONFIG_LWIP_DHCPS_STATIC_ENTRIES=y +# end of DHCP server + +# CONFIG_LWIP_AUTOIP is not set +CONFIG_LWIP_IPV4=y +# CONFIG_LWIP_IPV6 is not set +# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set +CONFIG_LWIP_NETIF_LOOPBACK=y +CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 + +# +# TCP +# +CONFIG_LWIP_MAX_ACTIVE_TCP=16 +CONFIG_LWIP_MAX_LISTENING_TCP=16 +CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y +CONFIG_LWIP_TCP_MAXRTX=12 +CONFIG_LWIP_TCP_SYNMAXRTX=12 +CONFIG_LWIP_TCP_MSS=1440 +CONFIG_LWIP_TCP_TMR_INTERVAL=250 +CONFIG_LWIP_TCP_MSL=60000 +CONFIG_LWIP_TCP_FIN_WAIT_TIMEOUT=20000 +CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5744 +CONFIG_LWIP_TCP_WND_DEFAULT=5744 +CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 +CONFIG_LWIP_TCP_ACCEPTMBOX_SIZE=6 +CONFIG_LWIP_TCP_QUEUE_OOSEQ=y +CONFIG_LWIP_TCP_OOSEQ_TIMEOUT=6 +CONFIG_LWIP_TCP_OOSEQ_MAX_PBUFS=4 +# CONFIG_LWIP_TCP_SACK_OUT is not set +CONFIG_LWIP_TCP_OVERSIZE_MSS=y +# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set +CONFIG_LWIP_TCP_RTO_TIME=1500 +# end of TCP + +# +# UDP +# +CONFIG_LWIP_MAX_UDP_PCBS=16 +CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 +# end of UDP + +# +# Checksums +# +# CONFIG_LWIP_CHECKSUM_CHECK_IP is not set +# CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set +# CONFIG_LWIP_CHECKSUM_CHECK_ICMP is not set +# end of Checksums + +CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY=y +# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU0 is not set +CONFIG_LWIP_TCPIP_TASK_AFFINITY=0x7FFFFFFF +# CONFIG_LWIP_PPP_SUPPORT is not set +# CONFIG_LWIP_SLIP_SUPPORT is not set + +# +# ICMP +# +# CONFIG_LWIP_ICMP is not set +# end of ICMP + +# +# LWIP RAW API +# +CONFIG_LWIP_MAX_RAW_PCBS=16 +# end of LWIP RAW API + +# +# SNTP +# +CONFIG_LWIP_SNTP_MAX_SERVERS=1 +# CONFIG_LWIP_DHCP_GET_NTP_SRV is not set +CONFIG_LWIP_SNTP_UPDATE_DELAY=3600000 +CONFIG_LWIP_SNTP_STARTUP_DELAY=y +CONFIG_LWIP_SNTP_MAXIMUM_STARTUP_DELAY=5000 +# end of SNTP + +# +# DNS +# +CONFIG_LWIP_DNS_MAX_SERVERS=3 +# CONFIG_LWIP_FALLBACK_DNS_SERVER_SUPPORT is not set +# end of DNS + +CONFIG_LWIP_BRIDGEIF_MAX_PORTS=7 +CONFIG_LWIP_ESP_LWIP_ASSERT=y + +# +# Hooks +# +# CONFIG_LWIP_HOOK_TCP_ISN_NONE is not set +CONFIG_LWIP_HOOK_TCP_ISN_DEFAULT=y +# CONFIG_LWIP_HOOK_TCP_ISN_CUSTOM is not set +CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_NONE=y +# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_DEFAULT is not set +# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_CUSTOM is not set +# end of Hooks + +CONFIG_LWIP_DEBUG=y +CONFIG_LWIP_DEBUG_ESP_LOG=y +CONFIG_LWIP_NETIF_DEBUG=y +# CONFIG_LWIP_PBUF_DEBUG is not set +# CONFIG_LWIP_ETHARP_DEBUG is not set +# CONFIG_LWIP_API_LIB_DEBUG is not set +# CONFIG_LWIP_SOCKETS_DEBUG is not set +# CONFIG_LWIP_IP_DEBUG is not set +# CONFIG_LWIP_DHCP_STATE_DEBUG is not set +# CONFIG_LWIP_DHCP_DEBUG is not set +# CONFIG_LWIP_IP6_DEBUG is not set +# CONFIG_LWIP_ICMP6_DEBUG is not set +# CONFIG_LWIP_TCP_DEBUG is not set +# CONFIG_LWIP_UDP_DEBUG is not set +# CONFIG_LWIP_SNTP_DEBUG is not set +# CONFIG_LWIP_DNS_DEBUG is not set +# CONFIG_LWIP_BRIDGEIF_DEBUG is not set +# CONFIG_LWIP_BRIDGEIF_FDB_DEBUG is not set +# CONFIG_LWIP_BRIDGEIF_FW_DEBUG is not set +# end of LWIP + +# +# mbedTLS +# +CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y +# CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC is not set +# CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC is not set +CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y +CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384 +CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 +# CONFIG_MBEDTLS_DYNAMIC_BUFFER is not set +# CONFIG_MBEDTLS_DEBUG is not set + +# +# mbedTLS v3.x related +# +# CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 is not set +# CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH is not set +# CONFIG_MBEDTLS_X509_TRUSTED_CERT_CALLBACK is not set +# CONFIG_MBEDTLS_SSL_CONTEXT_SERIALIZATION is not set +CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE=y +CONFIG_MBEDTLS_PKCS7_C=y +# end of mbedTLS v3.x related + +# +# Certificate Bundle +# +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=y +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=y +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE is not set +# CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE is not set +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEPRECATED_LIST is not set +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS=160 +# end of Certificate Bundle + +# CONFIG_MBEDTLS_ECP_RESTARTABLE is not set +CONFIG_MBEDTLS_CMAC_C=y +CONFIG_MBEDTLS_HARDWARE_AES=y +CONFIG_MBEDTLS_AES_USE_INTERRUPT=y +CONFIG_MBEDTLS_AES_INTERRUPT_LEVEL=0 +CONFIG_MBEDTLS_HARDWARE_GCM=y +CONFIG_MBEDTLS_GCM_SUPPORT_NON_AES_CIPHER=y +CONFIG_MBEDTLS_HARDWARE_MPI=y +# CONFIG_MBEDTLS_LARGE_KEY_SOFTWARE_MPI is not set +CONFIG_MBEDTLS_MPI_USE_INTERRUPT=y +CONFIG_MBEDTLS_MPI_INTERRUPT_LEVEL=0 +CONFIG_MBEDTLS_HARDWARE_SHA=y +CONFIG_MBEDTLS_ROM_MD5=y +# CONFIG_MBEDTLS_ATCA_HW_ECDSA_SIGN is not set +# CONFIG_MBEDTLS_ATCA_HW_ECDSA_VERIFY is not set +CONFIG_MBEDTLS_HAVE_TIME=y +# CONFIG_MBEDTLS_PLATFORM_TIME_ALT is not set +# CONFIG_MBEDTLS_HAVE_TIME_DATE is not set +CONFIG_MBEDTLS_ECDSA_DETERMINISTIC=y +CONFIG_MBEDTLS_SHA512_C=y +# CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT is not set +# CONFIG_MBEDTLS_TLS_SERVER_ONLY is not set +CONFIG_MBEDTLS_TLS_CLIENT_ONLY=y +# CONFIG_MBEDTLS_TLS_DISABLED is not set +CONFIG_MBEDTLS_TLS_CLIENT=y +CONFIG_MBEDTLS_TLS_ENABLED=y + +# +# TLS Key Exchange Methods +# +# CONFIG_MBEDTLS_PSK_MODES is not set +CONFIG_MBEDTLS_KEY_EXCHANGE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y +# end of TLS Key Exchange Methods + +CONFIG_MBEDTLS_SSL_RENEGOTIATION=y +CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y +# CONFIG_MBEDTLS_SSL_PROTO_GMTSSL1_1 is not set +# CONFIG_MBEDTLS_SSL_PROTO_DTLS is not set +CONFIG_MBEDTLS_SSL_ALPN=y +CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS=y +CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS=y + +# +# Symmetric Ciphers +# +CONFIG_MBEDTLS_AES_C=y +# CONFIG_MBEDTLS_CAMELLIA_C is not set +# CONFIG_MBEDTLS_DES_C is not set +# CONFIG_MBEDTLS_BLOWFISH_C is not set +# CONFIG_MBEDTLS_XTEA_C is not set +CONFIG_MBEDTLS_CCM_C=y +CONFIG_MBEDTLS_GCM_C=y +# CONFIG_MBEDTLS_NIST_KW_C is not set +# end of Symmetric Ciphers + +# CONFIG_MBEDTLS_RIPEMD160_C is not set + +# +# Certificates +# +CONFIG_MBEDTLS_PEM_PARSE_C=y +CONFIG_MBEDTLS_PEM_WRITE_C=y +CONFIG_MBEDTLS_X509_CRL_PARSE_C=y +CONFIG_MBEDTLS_X509_CSR_PARSE_C=y +# end of Certificates + +CONFIG_MBEDTLS_ECP_C=y +# CONFIG_MBEDTLS_DHM_C is not set +CONFIG_MBEDTLS_ECDH_C=y +CONFIG_MBEDTLS_ECDSA_C=y +# CONFIG_MBEDTLS_ECJPAKE_C is not set +CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP521R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP192K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP224K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP256K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP256R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED=y +CONFIG_MBEDTLS_ECP_NIST_OPTIM=y +CONFIG_MBEDTLS_ECP_FIXED_POINT_OPTIM=y +# CONFIG_MBEDTLS_POLY1305_C is not set +# CONFIG_MBEDTLS_CHACHA20_C is not set +# CONFIG_MBEDTLS_HKDF_C is not set +# CONFIG_MBEDTLS_THREADING_C is not set +CONFIG_MBEDTLS_ERROR_STRINGS=y +# end of mbedTLS + +# +# ESP-MQTT Configurations +# +CONFIG_MQTT_PROTOCOL_311=y +# CONFIG_MQTT_PROTOCOL_5 is not set +CONFIG_MQTT_TRANSPORT_SSL=y +CONFIG_MQTT_TRANSPORT_WEBSOCKET=y +CONFIG_MQTT_TRANSPORT_WEBSOCKET_SECURE=y +# CONFIG_MQTT_MSG_ID_INCREMENTAL is not set +# CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED is not set +# CONFIG_MQTT_REPORT_DELETED_MESSAGES is not set +# CONFIG_MQTT_USE_CUSTOM_CONFIG is not set +# CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED is not set +# CONFIG_MQTT_CUSTOM_OUTBOX is not set +# end of ESP-MQTT Configurations + +# +# Newlib +# +CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y +# CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF is not set +# CONFIG_NEWLIB_STDOUT_LINE_ENDING_CR is not set +# CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF is not set +# CONFIG_NEWLIB_STDIN_LINE_ENDING_LF is not set +CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y +# CONFIG_NEWLIB_NANO_FORMAT is not set +CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT=y +# CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC is not set +# CONFIG_NEWLIB_TIME_SYSCALL_USE_HRT is not set +# CONFIG_NEWLIB_TIME_SYSCALL_USE_NONE is not set +# end of Newlib + +# +# NVS +# +# CONFIG_NVS_ENCRYPTION is not set +# CONFIG_NVS_ASSERT_ERROR_CHECK is not set +# CONFIG_NVS_LEGACY_DUP_KEYS_COMPATIBILITY is not set +# end of NVS + +# +# OpenThread +# +# CONFIG_OPENTHREAD_ENABLED is not set + +# +# Thread Operational Dataset +# +CONFIG_OPENTHREAD_NETWORK_NAME="OpenThread-ESP" +CONFIG_OPENTHREAD_MESH_LOCAL_PREFIX="fd00:db8:a0:0::/64" +CONFIG_OPENTHREAD_NETWORK_CHANNEL=15 +CONFIG_OPENTHREAD_NETWORK_PANID=0x1234 +CONFIG_OPENTHREAD_NETWORK_EXTPANID="dead00beef00cafe" +CONFIG_OPENTHREAD_NETWORK_MASTERKEY="00112233445566778899aabbccddeeff" +CONFIG_OPENTHREAD_NETWORK_PSKC="104810e2315100afd6bc9215a6bfac53" +# end of Thread Operational Dataset + +CONFIG_OPENTHREAD_XTAL_ACCURACY=130 +# CONFIG_OPENTHREAD_SPINEL_ONLY is not set +CONFIG_OPENTHREAD_RX_ON_WHEN_IDLE=y + +# +# Thread Address Query Config +# +# end of Thread Address Query Config +# end of OpenThread + +# +# Protocomm +# +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_0=y +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_1=y +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_2=y +# end of Protocomm + +# +# PThreads +# +CONFIG_PTHREAD_TASK_PRIO_DEFAULT=5 +CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 +CONFIG_PTHREAD_STACK_MIN=768 +CONFIG_PTHREAD_TASK_CORE_DEFAULT=-1 +CONFIG_PTHREAD_TASK_NAME_DEFAULT="pthread" +# end of PThreads + +# +# MMU Config +# +CONFIG_MMU_PAGE_SIZE_64KB=y +CONFIG_MMU_PAGE_MODE="64KB" +CONFIG_MMU_PAGE_SIZE=0x10000 +# end of MMU Config + +# +# Main Flash configuration +# + +# +# SPI Flash behavior when brownout +# +CONFIG_SPI_FLASH_BROWNOUT_RESET_XMC=y +CONFIG_SPI_FLASH_BROWNOUT_RESET=y +# end of SPI Flash behavior when brownout + +# +# Optional and Experimental Features (READ DOCS FIRST) +# + +# +# Features here require specific hardware (READ DOCS FIRST!) +# +CONFIG_SPI_FLASH_SUSPEND_TSUS_VAL_US=50 +# end of Optional and Experimental Features (READ DOCS FIRST) +# end of Main Flash configuration + +# +# SPI Flash driver +# +# CONFIG_SPI_FLASH_VERIFY_WRITE is not set +# CONFIG_SPI_FLASH_ENABLE_COUNTERS is not set +CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y +CONFIG_SPI_FLASH_DANGEROUS_WRITE_ABORTS=y +# CONFIG_SPI_FLASH_DANGEROUS_WRITE_FAILS is not set +# CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED is not set +# CONFIG_SPI_FLASH_BYPASS_BLOCK_ERASE is not set +CONFIG_SPI_FLASH_YIELD_DURING_ERASE=y +CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS=20 +CONFIG_SPI_FLASH_ERASE_YIELD_TICKS=1 +CONFIG_SPI_FLASH_WRITE_CHUNK_SIZE=8192 +# CONFIG_SPI_FLASH_SIZE_OVERRIDE is not set +# CONFIG_SPI_FLASH_CHECK_ERASE_TIMEOUT_DISABLED is not set +# CONFIG_SPI_FLASH_OVERRIDE_CHIP_DRIVER_LIST is not set + +# +# Auto-detect flash chips +# +CONFIG_SPI_FLASH_VENDOR_XMC_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_GD_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_ISSI_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_MXIC_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_WINBOND_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_BOYA_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_TH_SUPPORTED=y +CONFIG_SPI_FLASH_SUPPORT_ISSI_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_MXIC_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_GD_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_WINBOND_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_BOYA_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_TH_CHIP=y +# end of Auto-detect flash chips + +CONFIG_SPI_FLASH_ENABLE_ENCRYPTED_READ_WRITE=y +# end of SPI Flash driver + +# +# SPIFFS Configuration +# +CONFIG_SPIFFS_MAX_PARTITIONS=3 + +# +# SPIFFS Cache Configuration +# +CONFIG_SPIFFS_CACHE=y +CONFIG_SPIFFS_CACHE_WR=y +# CONFIG_SPIFFS_CACHE_STATS is not set +# end of SPIFFS Cache Configuration + +CONFIG_SPIFFS_PAGE_CHECK=y +CONFIG_SPIFFS_GC_MAX_RUNS=10 +# CONFIG_SPIFFS_GC_STATS is not set +CONFIG_SPIFFS_PAGE_SIZE=256 +CONFIG_SPIFFS_OBJ_NAME_LEN=32 +# CONFIG_SPIFFS_FOLLOW_SYMLINKS is not set +CONFIG_SPIFFS_USE_MAGIC=y +CONFIG_SPIFFS_USE_MAGIC_LENGTH=y +CONFIG_SPIFFS_META_LENGTH=4 +CONFIG_SPIFFS_USE_MTIME=y + +# +# Debug Configuration +# +# CONFIG_SPIFFS_DBG is not set +# CONFIG_SPIFFS_API_DBG is not set +# CONFIG_SPIFFS_GC_DBG is not set +# CONFIG_SPIFFS_CACHE_DBG is not set +# CONFIG_SPIFFS_CHECK_DBG is not set +# CONFIG_SPIFFS_TEST_VISUALISATION is not set +# end of Debug Configuration +# end of SPIFFS Configuration + +# +# TCP Transport +# + +# +# Websocket +# +CONFIG_WS_TRANSPORT=y +CONFIG_WS_BUFFER_SIZE=1024 +# CONFIG_WS_DYNAMIC_BUFFER is not set +# end of Websocket +# end of TCP Transport + +# +# Ultra Low Power (ULP) Co-processor +# +CONFIG_ULP_COPROC_ENABLED=y +# CONFIG_ULP_COPROC_TYPE_FSM is not set +CONFIG_ULP_COPROC_TYPE_RISCV=y +CONFIG_ULP_COPROC_RESERVE_MEM=6144 + +# +# ULP RISC-V Settings +# +# CONFIG_ULP_RISCV_INTERRUPT_ENABLE is not set +CONFIG_ULP_RISCV_UART_BAUDRATE=9600 +CONFIG_ULP_RISCV_I2C_RW_TIMEOUT=500 +# end of ULP RISC-V Settings + +# +# ULP Debugging Options +# +# end of ULP Debugging Options +# end of Ultra Low Power (ULP) Co-processor + +# +# Unity unit testing library +# +CONFIG_UNITY_ENABLE_FLOAT=y +CONFIG_UNITY_ENABLE_DOUBLE=y +# CONFIG_UNITY_ENABLE_64BIT is not set +# CONFIG_UNITY_ENABLE_COLOR is not set +CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y +# CONFIG_UNITY_ENABLE_FIXTURE is not set +# CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL is not set +# end of Unity unit testing library + +# +# USB-OTG +# +CONFIG_USB_HOST_CONTROL_TRANSFER_MAX_SIZE=256 +CONFIG_USB_HOST_HW_BUFFER_BIAS_BALANCED=y +# CONFIG_USB_HOST_HW_BUFFER_BIAS_IN is not set +# CONFIG_USB_HOST_HW_BUFFER_BIAS_PERIODIC_OUT is not set + +# +# Root Hub configuration +# +CONFIG_USB_HOST_DEBOUNCE_DELAY_MS=250 +CONFIG_USB_HOST_RESET_HOLD_MS=30 +CONFIG_USB_HOST_RESET_RECOVERY_MS=30 +CONFIG_USB_HOST_SET_ADDR_RECOVERY_MS=10 +# end of Root Hub configuration + +# CONFIG_USB_HOST_ENABLE_ENUM_FILTER_CALLBACK is not set +CONFIG_USB_OTG_SUPPORTED=y +# end of USB-OTG + +# +# Virtual file system +# +CONFIG_VFS_SUPPORT_IO=y +CONFIG_VFS_SUPPORT_DIR=y +CONFIG_VFS_SUPPORT_SELECT=y +CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT=y +# CONFIG_VFS_SELECT_IN_RAM is not set +CONFIG_VFS_SUPPORT_TERMIOS=y +CONFIG_VFS_MAX_COUNT=8 + +# +# Host File System I/O (Semihosting) +# +CONFIG_VFS_SEMIHOSTFS_MAX_MOUNT_POINTS=1 +# end of Host File System I/O (Semihosting) +# end of Virtual file system + +# +# Wear Levelling +# +# CONFIG_WL_SECTOR_SIZE_512 is not set +CONFIG_WL_SECTOR_SIZE_4096=y +CONFIG_WL_SECTOR_SIZE=4096 +# end of Wear Levelling + +# +# Wi-Fi Provisioning Manager +# +CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16 +CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 +CONFIG_WIFI_PROV_BLE_FORCE_ENCRYPTION=y +CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y +# CONFIG_WIFI_PROV_STA_FAST_SCAN is not set +# end of Wi-Fi Provisioning Manager +# end of Component config + +# CONFIG_IDF_EXPERIMENTAL_FEATURES is not set + +# Deprecated options for backward compatibility +# CONFIG_APP_BUILD_TYPE_ELF_RAM is not set +# CONFIG_NO_BLOBS is not set +# CONFIG_ESP32S2_NO_BLOBS is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_NONE is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_ERROR is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_WARN is not set +CONFIG_LOG_BOOTLOADER_LEVEL_INFO=y +# CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE is not set +CONFIG_LOG_BOOTLOADER_LEVEL=3 +# CONFIG_APP_ROLLBACK_ENABLE is not set +# CONFIG_FLASH_ENCRYPTION_ENABLED is not set +# CONFIG_FLASHMODE_QIO is not set +# CONFIG_FLASHMODE_QOUT is not set +CONFIG_FLASHMODE_DIO=y +# CONFIG_FLASHMODE_DOUT is not set +CONFIG_MONITOR_BAUD=115200 +# CONFIG_OPTIMIZATION_LEVEL_DEBUG is not set +# CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG is not set +# CONFIG_COMPILER_OPTIMIZATION_DEFAULT is not set +CONFIG_OPTIMIZATION_LEVEL_RELEASE=y +CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE=y +CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y +# CONFIG_OPTIMIZATION_ASSERTIONS_SILENT is not set +# CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED is not set +CONFIG_OPTIMIZATION_ASSERTION_LEVEL=2 +# CONFIG_CXX_EXCEPTIONS is not set +CONFIG_STACK_CHECK_NONE=y +# CONFIG_STACK_CHECK_NORM is not set +# CONFIG_STACK_CHECK_STRONG is not set +# CONFIG_STACK_CHECK_ALL is not set +# CONFIG_WARN_WRITE_STRINGS is not set +# CONFIG_ESP32_APPTRACE_DEST_TRAX is not set +CONFIG_ESP32_APPTRACE_DEST_NONE=y +CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y +CONFIG_ADC2_DISABLE_DAC=y +# CONFIG_EXTERNAL_COEX_ENABLE is not set +# CONFIG_ESP_WIFI_EXTERNAL_COEXIST_ENABLE is not set +# CONFIG_EVENT_LOOP_PROFILING is not set +CONFIG_POST_EVENTS_FROM_ISR=y +CONFIG_POST_EVENTS_FROM_IRAM_ISR=y +CONFIG_GDBSTUB_SUPPORT_TASKS=y +CONFIG_GDBSTUB_MAX_TASKS=32 +# CONFIG_OTA_ALLOW_HTTP is not set +# CONFIG_ESP_SYSTEM_PD_FLASH is not set +CONFIG_ESP32S2_RTC_CLK_SRC_INT_RC=y +# CONFIG_ESP32S2_RTC_CLK_SRC_EXT_CRYS is not set +# CONFIG_ESP32S2_RTC_CLK_SRC_EXT_OSC is not set +# CONFIG_ESP32S2_RTC_CLK_SRC_INT_8MD256 is not set +CONFIG_ESP32S2_RTC_CLK_CAL_CYCLES=576 +CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y +# CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION is not set +CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=20 +CONFIG_ESP32_PHY_MAX_TX_POWER=20 +# CONFIG_ESP32S2_SPIRAM_SUPPORT is not set +CONFIG_ESP32S2_DEFAULT_CPU_FREQ_80=y +# CONFIG_ESP32S2_DEFAULT_CPU_FREQ_160 is not set +# CONFIG_ESP32S2_DEFAULT_CPU_FREQ_240 is not set +CONFIG_ESP32S2_DEFAULT_CPU_FREQ_MHZ=80 +# CONFIG_ESP32S2_PANIC_PRINT_HALT is not set +CONFIG_ESP32S2_PANIC_PRINT_REBOOT=y +# CONFIG_ESP32S2_PANIC_SILENT_REBOOT is not set +# CONFIG_ESP32S2_PANIC_GDBSTUB is not set +CONFIG_ESP32S2_ALLOW_RTC_FAST_MEM_AS_HEAP=y +CONFIG_ESP32S2_MEMPROT_FEATURE=y +CONFIG_ESP32S2_MEMPROT_FEATURE_LOCK=y +CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32 +CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2304 +CONFIG_MAIN_TASK_STACK_SIZE=3584 +CONFIG_CONSOLE_UART_DEFAULT=y +# CONFIG_CONSOLE_UART_CUSTOM is not set +# CONFIG_CONSOLE_UART_NONE is not set +# CONFIG_ESP_CONSOLE_UART_NONE is not set +CONFIG_CONSOLE_UART=y +CONFIG_CONSOLE_UART_NUM=0 +CONFIG_CONSOLE_UART_BAUDRATE=115200 +CONFIG_INT_WDT=y +CONFIG_INT_WDT_TIMEOUT_MS=300 +CONFIG_TASK_WDT=y +CONFIG_ESP_TASK_WDT=y +# CONFIG_TASK_WDT_PANIC is not set +CONFIG_TASK_WDT_TIMEOUT_S=5 +CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0=y +# CONFIG_ESP32_DEBUG_STUBS_ENABLE is not set +CONFIG_ESP32S2_DEBUG_OCDAWARE=y +# CONFIG_BROWNOUT_DET is not set +# CONFIG_ESP32S2_BROWNOUT_DET is not set +# CONFIG_ESP32S2_BROWNOUT_DET is not set +CONFIG_IPC_TASK_STACK_SIZE=1024 +CONFIG_TIMER_TASK_STACK_SIZE=3584 +CONFIG_ESP32_WIFI_ENABLED=y +CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 +CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 +# CONFIG_ESP32_WIFI_STATIC_TX_BUFFER is not set +CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER=y +CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1 +CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32 +# CONFIG_ESP32_WIFI_CSI_ENABLED is not set +# CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED is not set +CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y +CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y +CONFIG_ESP32_WIFI_RX_BA_WIN=6 +CONFIG_ESP32_WIFI_RX_BA_WIN=6 +CONFIG_ESP32_WIFI_NVS_ENABLED=y +CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752 +CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32 +# CONFIG_ESP32_WIFI_IRAM_OPT is not set +CONFIG_ESP32_WIFI_RX_IRAM_OPT=y +CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE=y +CONFIG_ESP32_WIFI_ENABLE_WPA3_OWE_STA=y +CONFIG_WPA_MBEDTLS_CRYPTO=y +CONFIG_WPA_MBEDTLS_TLS_CLIENT=y +# CONFIG_WPA_WAPI_PSK is not set +# CONFIG_WPA_11KV_SUPPORT is not set +# CONFIG_WPA_MBO_SUPPORT is not set +# CONFIG_WPA_DPP_SUPPORT is not set +# CONFIG_WPA_11R_SUPPORT is not set +# CONFIG_WPA_WPS_SOFTAP_REGISTRAR is not set +# CONFIG_WPA_WPS_STRICT is not set +# CONFIG_WPA_DEBUG_PRINT is not set +# CONFIG_WPA_TESTING_OPTIONS is not set +# CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH is not set +# CONFIG_ESP32_ENABLE_COREDUMP_TO_UART is not set +CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE=y +CONFIG_TIMER_TASK_PRIORITY=1 +CONFIG_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_TIMER_QUEUE_LENGTH=10 +# CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK is not set +# CONFIG_HAL_ASSERTION_SILIENT is not set +# CONFIG_L2_TO_L3_COPY is not set +CONFIG_ESP_GRATUITOUS_ARP=y +CONFIG_GARP_TMR_INTERVAL=60 +CONFIG_TCPIP_RECVMBOX_SIZE=32 +CONFIG_TCP_MAXRTX=12 +CONFIG_TCP_SYNMAXRTX=12 +CONFIG_TCP_MSS=1440 +CONFIG_TCP_MSL=60000 +CONFIG_TCP_SND_BUF_DEFAULT=5744 +CONFIG_TCP_WND_DEFAULT=5744 +CONFIG_TCP_RECVMBOX_SIZE=6 +CONFIG_TCP_QUEUE_OOSEQ=y +CONFIG_TCP_OVERSIZE_MSS=y +# CONFIG_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_TCP_OVERSIZE_DISABLE is not set +CONFIG_UDP_RECVMBOX_SIZE=6 +CONFIG_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_TCPIP_TASK_AFFINITY_NO_AFFINITY=y +# CONFIG_TCPIP_TASK_AFFINITY_CPU0 is not set +CONFIG_TCPIP_TASK_AFFINITY=0x7FFFFFFF +# CONFIG_PPP_SUPPORT is not set +CONFIG_ESP32S2_TIME_SYSCALL_USE_RTC_SYSTIMER=y +CONFIG_ESP32S2_TIME_SYSCALL_USE_RTC_FRC1=y +# CONFIG_ESP32S2_TIME_SYSCALL_USE_RTC is not set +# CONFIG_ESP32S2_TIME_SYSCALL_USE_SYSTIMER is not set +# CONFIG_ESP32S2_TIME_SYSCALL_USE_FRC1 is not set +# CONFIG_ESP32S2_TIME_SYSCALL_USE_NONE is not set +CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT=5 +CONFIG_ESP32_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 +CONFIG_ESP32_PTHREAD_STACK_MIN=768 +CONFIG_ESP32_PTHREAD_TASK_CORE_DEFAULT=-1 +CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT="pthread" +CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y +# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_FAILS is not set +# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED is not set +CONFIG_ESP32S2_ULP_COPROC_ENABLED=y +CONFIG_ESP32S2_ULP_COPROC_RISCV=y +CONFIG_ESP32S2_ULP_COPROC_RESERVE_MEM=6144 +CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y +CONFIG_SUPPORT_TERMIOS=y +CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS=1 +# End of deprecated options