First Commit

This commit is contained in:
unknown 2025-02-21 15:26:53 +05:30
parent e702d28b9d
commit 2240c57dff
53 changed files with 22862 additions and 6 deletions

9
.clang-format Normal file
View File

@ -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

3
.clangd Normal file
View File

@ -0,0 +1,3 @@
CompileFlags:
CompilationDatabase: build
Remove: [-m*, -f*]

18
.cproject Normal file
View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
<storageModule moduleId="org.eclipse.cdt.core.settings">
<cconfiguration id="org.eclipse.cdt.core.default.config.297119829">
<storageModule buildSystemId="org.eclipse.cdt.core.defaultConfigDataProvider" id="org.eclipse.cdt.core.default.config.297119829" moduleId="org.eclipse.cdt.core.settings" name="Configuration">
<externalSettings/>
<extensions/>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
<storageModule moduleId="org.eclipse.cdt.core.pathentry">
<pathentry excluding="**/CMakeFiles/**" kind="out" path="build"/>
</storageModule>
</cproject>

5
.gdbinit Normal file
View File

@ -0,0 +1,5 @@
target remote :3333
mon reset halt
flushregs
thb app_main
c

53
.gitignore vendored
View File

@ -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

20
.project Normal file
View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>tempstick_cellular_esp32</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.core.cBuilder</name>
<triggers>clean,full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.eclipse.cdt.core.ccnature</nature>
<nature>com.espressif.idf.core.idfNature</nature>
</natures>
</projectDescription>

View File

@ -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

View File

@ -0,0 +1,2 @@
eclipse.preferences.version=1
encoding/<project>=UTF-8

9
CMakeLists.txt Normal file
View File

@ -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})

5
LICENSE Normal file
View File

@ -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.

View File

@ -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.*

16
main/.cproject Normal file
View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
<storageModule moduleId="org.eclipse.cdt.core.settings">
<cconfiguration id="org.eclipse.cdt.core.default.config.1155416132">
<storageModule buildSystemId="org.eclipse.cdt.core.defaultConfigDataProvider" id="org.eclipse.cdt.core.default.config.1155416132" moduleId="org.eclipse.cdt.core.settings" name="Configuration">
<externalSettings/>
<extensions/>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.pathentry">
<pathentry excluding="**/CMakeFiles/**" kind="out" path="build"/>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
</cproject>

20
main/.project Normal file
View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>main</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.core.cBuilder</name>
<triggers>clean,full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.eclipse.cdt.core.ccnature</nature>
<nature>org.eclipse.cdt.cmake.core.cmakeNature</nature>
</natures>
</projectDescription>

16
main/CMakeLists.txt Normal file
View File

@ -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}")

14
main/Kconfig.projbuild Normal file
View File

@ -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

187
main/adc_ifx.c Normal file
View File

@ -0,0 +1,187 @@
/*
* adc_ifc.c
*
* Created on: Jan 17, 2023
* Author: Partha
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <inttypes.h>
#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

18
main/adc_ifx.h Normal file
View File

@ -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_ */

2125
main/comms.c Normal file

File diff suppressed because it is too large Load Diff

283
main/comms.h Normal file
View File

@ -0,0 +1,283 @@
/*
* comms.h
*
* Created on: Jan 16, 2023
* Author: Sword
*/
#ifndef MAIN_COMMS_H_
#define MAIN_COMMS_H_
#include <stdint.h>
#include <stdbool.h>
#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_ */

2603
main/data_processing.c Normal file

File diff suppressed because it is too large Load Diff

298
main/data_processing.h Normal file
View File

@ -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_ */

656
main/hmi.c Normal file
View File

@ -0,0 +1,656 @@
/*
* hmi.c
*
* Created on: Feb 13, 2023
* Author: Sword
*/
#include <stdio.h>
#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);
}

35
main/hmi.h Normal file
View File

@ -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_ */

1729
main/i2c_sensors.c Normal file

File diff suppressed because it is too large Load Diff

281
main/i2c_sensors.h Normal file
View File

@ -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_ */

48
main/main.c Normal file
View File

@ -0,0 +1,48 @@
#include <stdio.h>
#include <stdbool.h>
#include <unistd.h>
#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);
}

33
main/main.h Normal file
View File

@ -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_ */

3109
main/modem.c Normal file

File diff suppressed because it is too large Load Diff

181
main/modem.h Normal file
View File

@ -0,0 +1,181 @@
/*
* bg96.h
*
* Created on: Jan 11, 2023
* Author: Sword
*/
#ifndef MAIN_MODEM_H_
#define MAIN_MODEM_H_
#include <stdint.h>
#include <stdbool.h>
#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_ */

1117
main/nvm.c Normal file

File diff suppressed because it is too large Load Diff

74
main/nvm.h Normal file
View File

@ -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_ */

424
main/ota.c Normal file
View File

@ -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 <string.h>
#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();
}

32
main/ota.h Normal file
View File

@ -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_ */

254
main/port.c Normal file
View File

@ -0,0 +1,254 @@
/*
* port.c
*
* Created on: Jan 16, 2023
* Author: Partha
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <inttypes.h>
#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);
}

52
main/port.h Normal file
View File

@ -0,0 +1,52 @@
/*
* port.h
*
* Created on: Jan 16, 2023
* Author: Partha
*/
#ifndef MAIN_PORT_H_
#define MAIN_PORT_H_
#include <stdint.h>
#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_ */

224
main/rtc.c Normal file
View File

@ -0,0 +1,224 @@
/*
* rtc.c
*
* Created on: Jan 16, 2023
* Author: Sword
*/
#include "rtc.h"
#include <time.h>
#include <sys/time.h>
/** 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;
}

78
main/rtc.h Normal file
View File

@ -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 <stdint.h>
#include <stdbool.h>
#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_ */

270
main/uart_ifx.c Normal file
View File

@ -0,0 +1,270 @@
/*
* uart.c
*
* Created on: Jan 10, 2023
* Author: Partha
*/
#include <stdio.h>
#include <string.h>
#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;
}

26
main/uart_ifx.h Normal file
View File

@ -0,0 +1,26 @@
/*
* uart.h
*
* Created on: Jan 10, 2023
* Author: Partha
*/
#ifndef MAIN_UART_IFX_H_
#define MAIN_UART_IFX_H_
#include <stdint.h>
#include <stddef.h>
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_ */

View File

@ -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_ */

730
main/ulp/ulp_main.c Normal file
View File

@ -0,0 +1,730 @@
/*
* ulp_main.c
*
* Created on: Feb 17, 2023
* Author: Partha
*/
#include <stdbool.h>
#include <string.h>
#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;
}

643
main/wifi_Client.c Normal file
View File

@ -0,0 +1,643 @@
/*
* tempstick_wifi_client.c
*
* Created on: Jul 28, 2023
* Author: Sword
*/
#include <string.h>
#include <stdlib.h>
#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

50
main/wifi_Client.h Normal file
View File

@ -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_ */

671
main/wifi_Init.c Normal file
View File

@ -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

64
main/wifi_Init.h Normal file
View File

@ -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_ */

283
main/wifi_OTA.c Normal file
View File

@ -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 <string.h>
#include <inttypes.h>
#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);
}

22
main/wifi_OTA.h Normal file
View File

@ -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_ */

1645
main/wifi_webServer.c Normal file

File diff suppressed because one or more lines are too long

30
main/wifi_webServer.h Normal file
View File

@ -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_ */

7
partitions.csv Normal file
View File

@ -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,
1 # ESP-IDF Partition Table
2 # Name Type SubType Offset Size Flags
3 nvs data nvs 0x9000 0x14000
4 otadata data ota 0x1d000 0x2000
5 phy_init data phy 0x1f000 0x1000
6 ota_0 app ota_0 0x20000 0x1a0000
7 ota_1 app ota_1 0x1c0000 0x1a0000

14
release.bat Normal file
View File

@ -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

2022
sdkconfig Normal file

File diff suppressed because it is too large Load Diff

2022
sdkconfig.old Normal file

File diff suppressed because it is too large Load Diff