Added Azuma wifi backup code

This commit is contained in:
unknown 2025-04-03 12:37:40 +05:30
parent 5e9656265b
commit c1dd342432
44 changed files with 15527 additions and 1 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*]

17
.cproject Normal file
View File

@ -0,0 +1,17 @@
<?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.503389380">
<storageModule buildSystemId="org.eclipse.cdt.core.defaultConfigDataProvider" id="org.eclipse.cdt.core.default.config.503389380" 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 kind="src" path=""/>
<pathentry excluding="**/CMakeFiles/**" kind="out" path="build"/>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
</cproject>

20
.project Normal file
View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>Azuma-wifi-switch</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,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,45 @@
# Azuma_wifi_switch
**Edit a file, create a new file, and clone from Bitbucket in under 2 minutes**
When you're done, you can delete the content in this README and update the file with details for others getting started with your repository.
*We recommend that you open this README in another tab as you perform the tasks below. You can [watch our video](https://youtu.be/0ocf7u76WSo) for a full demo of all the steps in this tutorial. Open the video in a new tab to avoid leaving Bitbucket.*
---
## Edit a file
Youll start by editing this README file to learn how to edit a file in Bitbucket.
1. Click **Source** on the left side.
2. Click the README.md link from the list of files.
3. Click the **Edit** button.
4. Delete the following text: *Delete this line to make a change to the README from Bitbucket.*
5. After making your change, click **Commit** and then **Commit** again in the dialog. The commit page will open and youll see the change you just made.
6. Go back to the **Source** page.
---
## Create a file
Next, youll add a new file to this repository.
1. Click the **New file** button at the top of the **Source** page.
2. Give the file a filename of **contributors.txt**.
3. Enter your name in the empty file space.
4. Click **Commit** and then **Commit** again in the dialog.
5. Go back to the **Source** page.
Before you move on, go ahead and explore the repository. You've already seen the **Source** page, but check out the **Commits**, **Branches**, and **Settings** pages.
---
## Clone a repository
Use these steps to clone from SourceTree, our client for using the repository command-line free. Cloning allows you to work on your files locally. If you don't yet have SourceTree, [download and install first](https://www.sourcetreeapp.com/). If you prefer to clone from the command line, see [Clone a repository](https://confluence.atlassian.com/x/4whODQ).
1. Youll see the clone button under the **Source** heading. Click that button.
2. Now click **Check out in SourceTree**. You may need to create a SourceTree account or log in.
3. When you see the **Clone New** dialog in SourceTree, update the destination path and name if youd like to and then click **Clone**.
4. Open the directory you just created to see your repositorys files.
Now that you're more familiar with your Bitbucket repository, go ahead and add a new file locally. You can [push your change back to Bitbucket with SourceTree](https://confluence.atlassian.com/x/iqyBMg), or you can [add, commit,](https://confluence.atlassian.com/x/8QhODQ) and [push from the command line](https://confluence.atlassian.com/x/NQ0zDQ).

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 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 mqtt# 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

35
main/MCP39F501.h Normal file
View File

@ -0,0 +1,35 @@
/*
* MCP39F501.h
*
* Created on: Feb 25, 2025
* Author: Manticore
*/
#ifndef MAIN_MCP39F501_H_
#define MAIN_MCP39F501_H_
#define MCP39F501_HEADER "0xa5"
#define MCP39F501_OK "0x00"
#define MCP39F501_TIMEOUT "0xff"
#define MCP39F501_CSFAIL "0x01"
#define MCP39F501_BADCSUM "0x02"
#define MCP39F501_INOVFLOW "0x03"
#define MCP39F501_OUTOVFLOW "0x04"
#define MCP39F501_TOOSHORT "0x05"
#define MCP39F501_TOOLONG "0x06"
#define MCP39F501_INBAD "0x07"
#define MCP39F501_INSIZE "0x08"
#define MCP39F501_EV_OC "0x8000"
#define MCP39F501_EV_OV "0x4000"
#define MCP39F501_EV_OP "0x2000"
#define MCP39F501_EV_UV "0x1000"
#define MCP39F501_EV_OF "0x0800"
#define MCP39F501_EV_UF "0x0400"
#define MCP39F501_EV_OT "0x0200"
#define MCP39F501_EV_UT "0x0100"
#define MCP39F501_EV_VSA "0x0080"
#define MCP39F501_EV_VSU "0x0040"
#endif /* MAIN_MCP39F501_H_ */

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

2106
main/comms.c Normal file

File diff suppressed because it is too large Load Diff

152
main/comms.h Normal file
View File

@ -0,0 +1,152 @@
#ifndef __COMMS_H_
#define __COMMS_H_
#include <stdint.h>
#include <stdbool.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://54.204.230.201:8081"
/*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/azuma/%s/update/" //MCU_BASE_URL1//config/flag/server1
#define MCU_GET_CONFIG_FLAGS_URL2 TESTING_SERVER_BASE_URL"/hae/azuma/%s/update/" //MCU_BASE_URL2//config/flag/server2
#define MCU_GET_CONFIG_FLAGS_URL3 TESTING_SERVER_BASE_URL"/hae/azuma/%s/update/" //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/azuma/%s/mcu_pgm_download/version/"/*MCU_BASE_URL1//mcu/fw/version/server1*/
#define MCU_FW_VERSION_URL2 TESTING_SERVER_BASE_URL"/hae/azuma/%s/mcu_pgm_download/version/"//MCU_BASE_URL2//mcu/fw/version/server2
#define MCU_FW_VERSION_URL3 TESTING_SERVER_BASE_URL"/hae/azuma/%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/azuma/%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/azuma/%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/azuma/%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/azuma/%s/modem_pgm_download/version/"//MCU_BASE_URL1//modem/fw/version/server1
#define MODEM_FW_VERSION_URL2 TESTING_SERVER_BASE_URL"/hae/azuma/%s/modem_pgm_download/version/"//MCU_BASE_URL2//modem/fw/version/server2
#define MODEM_FW_VERSION_URL3 TESTING_SERVER_BASE_URL"/hae/azuma/%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/azuma/%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/azuma/%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/azuma/%s/modem_pgm_download/MOTA.bin"//MCU_BASE_URL3//modem/fw/bin/file/server3
/* TEMPSTICK servers URL's */
typedef enum {
TEMPSTICK_SERVER1=1,
TEMPSTICK_SERVER2,
TEMPSTICK_SERVER3
}serverUrl_t;
#define COMMS_STATUS_UPDATED 1
#define COMMS_STATUS_OK 0
#define COMMS_STATUS_ERROR -1
/* 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);
void SP1_Mqtt_Tx(int );
#endif /* __COMMS_H_ */

474
main/data_processing.c Normal file
View File

@ -0,0 +1,474 @@
/*
* data_processing.c
*
* Created on: Feb 3, 2023
* Author: Partha
*/
#include <stdio.h>
#include <stdlib.h>
#include "nvs_flash.h"
#include "esp_system.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include <string.h>
#include "sys/time.h"
#include "driver/gpio.h"
#include "esp_log.h"
#include "math.h"
#include "sdkconfig.h"
#include "time.h"
#include "rtc_wdt.h"
#include "modem.h"
#include "esp_mac.h"
#include "uart_ifx.h"
#include "esp_task_wdt.h"
#include "port.h"
#include "adc_ifx.h"
#include "data_processing.h"
#include "main.h"
#include "hmi.h"
#include "comms.h"
#include "lwip/ip4_addr.h"
#include "wifi_Init.h"
#include "nvm.h"
#include "wifi_OTA.h"
static const char* TAG = "DATA";
#define LOG_LOCAL_LEVEL ESP_LOG_INFO
#include "esp_log.h"
#define IMEI "353165803930522"
extern bool isCycleCompleted;
extern uint8_t comms_mode;
extern uint8_t checkin_cycle_counter;
extern uint8_t number_of_check_in_to_do;
static char thermocouple_type;
uint32_t g_version = 0;
uint32_t g_wifiConnectTime;
float g_voltage = 0;
bool g_usbConnected = 0;
bool g_enableButtonTiming;
RTC_DATA_ATTR static bool g_prevUsbConnected;
uint32_t light_mv = 0;
uint8_t checkInAttemptNumber = 1;
time_t g_wakeUpTime = 0;
uint32_t g_StatusFlags = 0;
uint32_t g_triggerFlags1 = 0;
uint32_t g_triggerFlags2 = 0;
// Configuration global variable
uint32_t g_server_time = 0;
uint32_t g_ID;
uint32_t g_SensorInt;
uint32_t g_ConfigUpdate;
uint32_t g_McuUpdate;
uint32_t g_ModemUpdate;
RTC_DATA_ATTR historyLog_t _logs[NVM_MAX_NUMBER_OF_IN_ONE_SECTOR] = {};
typedef struct
{
// Stored in RTC RAM during Deep Sleeps. This reduces wear on the FLASH.
// TIMING
uint32_t timeOfLastRadioCalibration;
uint32_t checkInClock;
uint32_t retry1Clock;
uint32_t retry2Clock;
int8_t lteRssi; // Modem signal strength
// WIFI CONFIG
uint8_t bssid[6];
esp_netif_ip_info_t localIp;
esp_netif_dns_info_t dns1;
esp_netif_dns_info_t dns2;
uint8_t wifiChannel;
int32_t wifi_rssi;
// OTHERS
uint32_t operatingMode;
uint32_t initializationVector[4];
bool initializationVectorCreated;
uint32_t checkInCount;
float temperatureAtLastRadioCalibration;
bool retriesAreInProgress;
}rtcRamData_t;
RTC_DATA_ATTR rtcRamData_t _rtcRamData;
static esp_err_t data_parse_float_value(float *target_buffer, const char needle[], const char *http_resp)
{
esp_err_t retval = ESP_FAIL;
char *ret = NULL;
char *start_add = NULL;
char *end_add = NULL;
char parse_value[] = {'0'};
int len = 0;
/*1- Extract temperature limits*/
ret = strstr(http_resp, needle);
if(ret)
{
/*2- get the starting address of the value*/
start_add = strstr(ret,(char*)":") + 1;
/*3- get the ending address of the value*/
end_add = strstr(ret,(char*)",") + 1;
if((char *)1 == end_add)
end_add = start_add + strlen(start_add) + 1;
/*4- Calculate the length of the value*/
len = end_add - start_add;
/*5- copy the value into the buffer*/
snprintf(parse_value, len, "%s", start_add);
/*6- Assign the double value to the target buffer*/
*target_buffer = atof(parse_value);
retval = ESP_OK;
}
return retval;
}
static esp_err_t data_parse_int_value(int32_t *target_buffer, const char needle[], const char *http_resp)
{
esp_err_t retval = ESP_FAIL;
char *ret = NULL;
char *start_add = NULL;
char *end_add = NULL;
char parse_value[] = {'0'};
int len = 0;
/*1- Extract temperature limits*/
ret = strstr(http_resp, needle);
if(ret)
{
/*2- get the starting address of the value*/
start_add = strstr(ret,(char*)":") + 1;
/*3- get the ending address of the value*/
end_add = strstr(ret,(char*)",") + 1;
if((char *)1 == end_add)
end_add = start_add + strlen(start_add) + 1;
/*4- Calculate the length of the value*/
len = end_add - start_add;
/*5- copy the value into the buffer*/
snprintf(parse_value, len, "%s", start_add);
/*6- Assign the double value to the target buffer*/
*target_buffer = atoi(parse_value);
retval = ESP_OK;
}
return retval;
}
static esp_err_t data_parse_uint8_value(uint8_t *target_buffer, const char needle[], const char *http_resp)
{
esp_err_t retval = ESP_FAIL;
char *ret = NULL;
char *start_add = NULL;
char *end_add = NULL;
char parse_value[] = {'0'};
int len = 0;
/*1- Extract temperature limits*/
ret = strstr(http_resp, needle);
if(ret)
{
/*2- get the starting address of the value*/
start_add = strstr(ret,(char*)":") + 1;
/*3- get the ending address of the value*/
end_add = strstr(ret,(char*)",") + 1;
if((char *)1 == end_add)
end_add = start_add + strlen(start_add) + 1;
/*4- Calculate the length of the value*/
len = end_add - start_add;
/*5- copy the value into the buffer*/
snprintf(parse_value, len, "%s", start_add);
/*6- Assign the double value to the target buffer*/
*target_buffer = atoi(parse_value);
retval = ESP_OK;
}
return retval;
}
static esp_err_t data_parse_uint16_value(uint16_t *target_buffer, const char needle[], const char *http_resp)
{
esp_err_t retval = ESP_FAIL;
char *ret = NULL;
char *start_add = NULL;
char *end_add = NULL;
char parse_value[] = {'0'};
int len = 0;
/*1- Extract temperature limits*/
ret = strstr(http_resp, needle);
if(ret)
{
/*2- get the starting address of the value*/
start_add = strstr(ret,(char*)":") + 1;
/*3- get the ending address of the value*/
end_add = strstr(ret,(char*)",") + 1;
if((char *)1 == end_add)
end_add = start_add + strlen(start_add) + 1;
/*4- Calculate the length of the value*/
len = end_add - start_add;
/*5- copy the value into the buffer*/
snprintf(parse_value, len, "%s", start_add);
/*6- Assign the double value to the target buffer*/
*target_buffer = atoi(parse_value);
retval = ESP_OK;
}
return retval;
}
static esp_err_t data_parse_uint_value(uint32_t *target_buffer, const char needle[], const char *http_resp)
{
esp_err_t retval = ESP_FAIL;
char *ret = NULL;
char *start_add = NULL;
char *end_add = NULL;
char parse_value[] = {'0'};
int len = 0;
/*1- Extract temperature limits*/
ret = strstr(http_resp, needle);
if(ret)
{
/*2- get the starting address of the value*/
start_add = strstr(ret,(char*)":") + 1;
/*3- get the ending address of the value*/
end_add = strstr(ret,(char*)",") + 1;
if((char *)1 == end_add)
end_add = start_add + strlen(start_add) + 1;
/*4- Calculate the length of the value*/
len = end_add - start_add;
/*5- copy the value into the buffer*/
snprintf(parse_value, len, "%s", start_add);
/*6- Assign the double value to the target buffer*/
*target_buffer = atoi(parse_value);
retval = ESP_OK;
}
return retval;
}
static esp_err_t data_parse_String_value(char *target_buffer, const char needle[], const char *http_resp)
{
esp_err_t retval = ESP_FAIL;
char *ret = NULL;
char *start_add = NULL;
char *end_add = NULL;
int len = 0;
/*1- Extract temperature limits*/
ret = strstr(http_resp, needle);
if(ret)
{
/*2- get the starting address of the value*/
start_add = strstr(ret,(char*)":") + 2;
/*3- get the ending address of the value*/
end_add = strstr(ret,(char*)",");
/*4- Calculate the length of the value*/
len = end_add - start_add;
/*5- copy the value into the buffer*/
snprintf(target_buffer, len, "%s", start_add);
retval = ESP_OK;
}
return retval;
}
void data_set_ap_mac_addr(uint8_t *bssid)
{
for(int i=0; i<6; i++)
{
_rtcRamData.bssid[i] = bssid[i];
}
}
uint8_t* data_get_ap_mac_addr(void)
{
return ((uint8_t*)&_rtcRamData.bssid[0]);
}
void data_set_local_ip_addr(esp_netif_ip_info_t* ip_infos)
{
_rtcRamData.localIp.ip.addr = ip_infos->ip.addr;
_rtcRamData.localIp.gw.addr = ip_infos->gw.addr;
_rtcRamData.localIp.netmask.addr = ip_infos->netmask.addr;
}
uint32_t data_get_ip_addr(void)
{
return _rtcRamData.localIp.ip.addr;
}
uint32_t data_get_gw_addr(void)
{
return _rtcRamData.localIp.gw.addr;
}
uint32_t data_get_netmask_addr(void)
{
return _rtcRamData.localIp.netmask.addr;
}
void data_set_wifi_channel(uint8_t channel)
{
_rtcRamData.wifiChannel = channel;
}
uint8_t data_get_wifi_channel(void)
{
return _rtcRamData.wifiChannel;
}
void data_set_wifi_rssi(int32_t rsi)
{
_rtcRamData.wifi_rssi = rsi;
}
int32_t data_get_wifi_rssi(void)
{
return _rtcRamData.wifi_rssi;
}
void data_set_main_and_backup_dns(esp_netif_dns_info_t* dns1, esp_netif_dns_info_t* dns2)
{
_rtcRamData.dns1.ip.u_addr.ip4.addr = dns1->ip.u_addr.ip4.addr;
_rtcRamData.dns2.ip.u_addr.ip4.addr = dns2->ip.u_addr.ip4.addr;
}
uint32_t data_get_mode(void)
{
return _rtcRamData.operatingMode;
}
void data_clearWifiConnectionSettings(void)
{
_rtcRamData.wifiChannel = 1; // FCC allows only channels 1 through 13 in the USA, but 12 and 13 must be low power, which I don't think we can control. My linksys router only allows channels 1-11.
memset(_rtcRamData.bssid, 0, sizeof(_rtcRamData.bssid));
_rtcRamData.localIp.ip.addr = 0;
_rtcRamData.localIp.gw.addr = 0;
_rtcRamData.localIp.netmask.addr = 0;
_rtcRamData.dns1.ip.u_addr.ip4.addr = 0;
_rtcRamData.dns2.ip.u_addr.ip4.addr = 0;
}
/*******************************************************************/
/* Buffer(Json Sample) */
/*{ "request": "settings", "time":1675859084, "id":10608508,
* "SensorInt":1, "ConfigUpdate":0, "McuUpdate:0", "ModemUpdate":0 }
*/
/*******************************************************************/
esp_err_t data_parsing_config(char *buff,int len){
esp_err_t retval = ESP_FAIL;
char server_request[11]={0};
// char setting_req[]="settings";
// ret = strstr(buff, (const char*)"settings");
// data_parse_String_value(server_request,"request",buff);
// if( ret != NULL ){
if(1){
//retval = data_parse_uint_value(&g_server_time,"time", buff);
retval = data_parse_uint_value(&g_ID,"id", buff);
retval = data_parse_uint_value(&g_SensorInt,"SensorInt", buff);
retval = data_parse_uint_value(&g_ConfigUpdate,"ConfigUpdate", buff);
retval = data_parse_uint_value(&g_McuUpdate,"McuUpdate", buff);
retval = data_parse_uint_value(&g_ModemUpdate,"ModemUpdate", buff);
ESP_LOGI(TAG, "ConfigUpdate: %luMcuUpdate: %lu ModemUpdate: %lu", g_ConfigUpdate, g_McuUpdate, g_ModemUpdate);
g_McuUpdate = 1;
//g_ConfigUpdate = 1;
if(g_ConfigUpdate == 1)
ESP_LOGI(TAG, "Configuration update = 1 ");
}
if(g_McuUpdate == 1){
ESP_LOGI(TAG, "g_McuUpdate update = 1 ");
}
else
{
ESP_LOGI(TAG, "Invalid request :%s",server_request);
}
return retval;
}
/****************************************************************************/
/* function input
maxretrynum = HTTP_RETRY_COUNT = 5
httpRetryCnt is the current retry count
*/
esp_err_t check_in_attempts_count( int httpRetryCnt, int maxretrynum )
{
esp_err_t retval = ESP_OK;
checkInAttemptNumber = 1 + maxretrynum - httpRetryCnt;
return retval;
}

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

721
main/hmi.c Normal file
View File

@ -0,0 +1,721 @@
/*
* 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 "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)
/*LED definitions*/
#define RED_TRI_LED 0
#define GREEN_TRI_LED 1
#define BLUE_TRI_LED 2
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();
}
}
/* State of the hmi process */
typedef enum
{
HMI_STATE_INIT,
HMI_STATE_RUN,
} hmi_state_t;
typedef struct
{
hmi_state_t state;
/* Timer */
bool poll_timer;
/* General 1 sec timer */
int sec_timer;
int active_led;
bool red_led_on;
bool green_led_on;
bool blue_led_on;
uint8_t led_state;
int** blink_pattern;
} hmi_t;
static hmi_t hmi;
int hmi_choose_led(int led_color,uint8_t op_mode)
{
// int retval=HMI_STATUS_OK;
hmi.led_state = op_mode; /*led state ( on,off or blinking).*/
switch (led_color)
{
case RED_TRI_LED:
hmi.red_led_on = 1;
hmi.green_led_on = 0;
hmi.blue_led_on = 0;
break;
case GREEN_TRI_LED:
hmi.red_led_on = 0;
hmi.green_led_on = 1;
hmi.blue_led_on = 0;
break;
case BLUE_TRI_LED:
hmi.red_led_on = 0;
hmi.green_led_on = 0;
hmi.blue_led_on = 1;
break;
default:
hmi.red_led_on = 0;
hmi.green_led_on = 0;
hmi.blue_led_on = 0;
break;
}
return 0;
}
/* 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);
}

56
main/hmi.h Normal file
View File

@ -0,0 +1,56 @@
/*
* hmi.h
*
* Created on: Feb 13, 2023
* Author: Sword
*/
#ifndef MAIN_HMI_H_
#define MAIN_HMI_H_
#include <stdbool.h>
#include <stdbool.h>
#include <stdint.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;
typedef enum
{
HMI_LED_RED,
HMI_LED_GREEN,
HMI_LED_BLUE,
HMI_LED__MAX__
} hmi_led_type_t;
typedef enum
{
HMI_LED_OFF = 0,
HMI_LED_ON,
HMI_LED_BLINK,
} hmi_led_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);
int hmi_choose_led(int led_color,uint8_t op_mode);
#endif /* MAIN_HMI_H_ */

677
main/main.c Normal file
View File

@ -0,0 +1,677 @@
#include <stdint.h>
#include <stdio.h>
#include <string.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"
#include "ota.h"
#include "MCP39F501.h"
#include "wifi_OTA.h"
#include "wifi_Init.h"
#include "MCP39F501.h"
#include "esp_system.h"
#include "esp_mac.h"
#include "mqtt_client.h"
#include "esp_ota_ops.h"
#include "lwip/sockets.h"
#include "lwip/dns.h"
#include "lwip/netdb.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "freertos/queue.h"
#include "esp_timer.h"
#include <sys/time.h>
#include "rtc.h"
#include "wifi_Client.h"
#include "data_processing.h"
#include "driver/gpio.h"
#include "comms.h"
#include "driver/timer.h"
#include "port.h"
#define HEARTBEAT_TIME_SEC_TEST 2
#define HEARTBEAT_TIME_SEC 2 //14400
/* Unique timer ID for checking the value of isTestMode variable (should not be true for more than 1hr) */
#define COMMS_TESTMODE_ID 3
#define TESTMODE_DURATION 3600000
//#define RESTART_THRESHOLD 10 // Threshold in seconds
//communication init flag
extern bool deviceCfged;
extern int config_heartbeat_time;
bool isCommInit = false;
bool isTestMode = false;
bool isFirstRun = true;
bool isTestModeTimerOff = true;
int heartbeat_time = HEARTBEAT_TIME_SEC;
bool testmode_timeout = false;
static bool heartbeat_event_flag = false;
// Global variable to store the initialization timestamp
uint32_t init_timestamp = 0;
// Global variable to store the last check timestamp
uint32_t last_check_timestamp = 0;
#define IMEI "353165803930522"
#define CONFIG_BROKER_URL "mqtt://broker.mqtt.cool"
#define MQTT_TOPIC_SUB "/topic/qos0"
#define MQTT_TOPIC_PUB "/topic/qos0"
#define WEB_SERVER "54.204.230.201"
#define WEB_PORT "8081"
#define WEB_PATH "/hae/azuma/353165803930522/update/"
#define MCU_CONFIG "/hae/azuma/353165803930522/mcu_config_download/"
#define MCU_PROG_VER "/hae/azuma/353165803930522/mcu_pgm_download/version/"
#define MCU_UPDATE "/hae/azuma/353165803930522/update/"
#define BROCKER_URL_TEST "mqtt://broker.mqtt.cool:1883"
// #define BROCKER_URL_TEST "mqtt://azumamqtt1.cedalo.cloud:1883"
char MAC_ID[16] ="353165803930522\0";
uint8_t comms_mode = DEFAULT_COMMS_MODE;
char HTTP_GET_DATA[512];
bool RelayState_1 = false;
bool PreviousRelayState_1 = false;
#define RELAY_PIN 42 // Define GPIO14
#define RELAY_ON 1
#define RELAY_OFF 0
#define HOURS_TO_SECONDS_COEFF 3600
#define TIMER_DIVIDER 16 // Prescaler (80MHz / 16 = 5MHz)
#define TIMER_SCALE (APB_CLK_FREQ / TIMER_DIVIDER) // 5,000,000 ticks per second
#define TIMER_INTERVAL_SEC 5 // 1-minute interval
bool timer_on = false;
const char *TAG = "main";
/* This timer triggers server connections based on a fundamental
* timer (e.g. heartbeat timer). It never resets.
*/
static uint32_t comms_timer = 0;
uint32_t extern_comms_timer = 0;
/* flag associated with comm process intervals signaling that a
* connection should be made.
*/
bool initialize_completed_event_flag = false;
/*Relay-Controlling*/
void board_relay_on(void)
{
gpio_set_level(RELAY_PIN, RELAY_ON); // Set GPIO14 HIGH
ESP_LOGI(TAG,"Relay ON");
}
void board_relay_off(void)
{
gpio_set_level(RELAY_PIN, RELAY_OFF); // Set GPIO14 LOW
ESP_LOGI(TAG,"Relay OFF");
}
static void comms_started_cb(int status)
{
/* Comms process has started and configuration has been updated. */
initialize_completed_event_flag = true;
}
static void comms_connect_cb(int status)
{
isCommInit = true;
}
bool main_hearbeat = 0;
int app_tick()
{
static int retval;
/* This heartbeat is for timing communication cycles and other main system functions. */
if (heartbeat_event_flag)
{
heartbeat_event_flag = false;
comms_timer++;
extern_comms_timer++;
ESP_LOGI(TAG, "Comms timer value = %d",(uint8_t)comms_timer);
if(comms_timer >= heartbeat_time) //2 mins
{
comms_timer = 0;
extern_comms_timer = 0;
main_hearbeat = 1;
}
if(main_hearbeat)
{
main_hearbeat = 0;
if(isCommInit == true)
{
isCommInit = false ;
isFirstRun = false;
comms_start(comms_started_cb, comms_connect_cb);
}
}
if(isTestMode)
{
heartbeat_time = HEARTBEAT_TIME_SEC_TEST;
if(isTestModeTimerOff)
{
isTestModeTimerOff = false;
/*Start COMMS_TESTMODE_TIMER to prevent the "TESTMODE" to last more than 1hr*/
// timer_start(COMMS_TESTMODE_ID,TESTMODE_DURATION);
}
}
else
{
//Seraj
// if(isFirstRun == false){
if(deviceCfged == true) {
//don't set hbt as default value
heartbeat_time = config_heartbeat_time;
//heartbeat_time = 180;
}
else{
heartbeat_time = HEARTBEAT_TIME_SEC;
//heartbeat_time = 180;
}
// }
}
/* Heartbeat event is driven by watchdog. Servicing is automatic */
// watchdog_service();
/* comms process */
if (comms_needs_poll())
{
int retval = comms_poll();
if (retval != 0)
{
ESP_LOGE(TAG, "comms poll error: %d\r\n", retval);
}
}
}
return retval;
}
int sum_digits(int digit)
{
int sum = 0;
while (digit > 0)
{
sum = sum + digit % 10;
digit = digit / 10;
}
return sum;
}
void get_mac_add(void) { // The function modifies the passed buffer
uint8_t mac[6];
esp_efuse_mac_get_default(mac);
printf("MAC Address (Hex): %02X:%02X:%02X:%02X:%02X:%02X\n",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
// Convert MAC address to a decimal string
char full_mac_decimal[20];
int len = snprintf(full_mac_decimal, sizeof(full_mac_decimal), "%d%d%d%d%d%d",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
// Ensure exactly 15 characters
if (len < 15) {
memset(MAC_ID, '0', 15 - len);
strcpy(MAC_ID + (15 - len), full_mac_decimal);
} else {
strncpy(MAC_ID, full_mac_decimal, 15);
}
// MAC_ID[15] = '\0';
printf("Formatted MAC (15 Characters): %s\n", MAC_ID);
}
static bool mac_check_valid(char *message_mac)
{
//find the length of message imei
int len = strlen(message_mac);
int sum = 0;
ESP_LOGI(TAG,"MESSAGE MAC_ID : %s\r\n",message_mac);
ESP_LOGI(TAG,"BOARD MAC_ID : %s\r\n",MAC_ID);
ESP_LOGI(TAG,"SIZE OF MAC ID : %d\r\n",len);
//check length of imei field
if (len != 15){
//invalid IMEI
ESP_LOGW(TAG,"Invalid MAC length");
return false;
}
if(!strcmp(message_mac,MAC_ID)){
for(int i = len-1 ; i >= 0; i--)
{
//check if message imei fields contain numbers (0-9)
if((message_mac[i] > 47) && (message_mac[i] < 58)){
int digit = (message_mac[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 MAC (not numerical values)\r\n");
return false;
}
}
}
else{
ESP_LOGI(TAG,"Message MAC doesn't match board MAC ID\r\n");
return false;
}
return (sum % 10 == 0);
}
static int Comms_Parse_SP4(char *buf, int len){
char messageheader[4] = {0};
char date_time[18] = {'0'};
char messageIMEI[15] = {'0'};
char testMode[3] = {'0'};
int sp4_ret = -1;
char* strret = NULL;
char hbeat[5] = {'0'};
char epcheck[2] = {0};
strret = strtok(buf," ");
strcpy(messageheader, strret);
ESP_LOGI(TAG,"%s message is received \r\n",messageheader);
while(strret != NULL){
strret = strtok (NULL," ");
strcpy(messageIMEI, strret);
//messageIMEI[15] = '\0';
sp4_ret = mac_check_valid(messageIMEI);
if(sp4_ret != false){
//ok IMEI
ESP_LOGI(TAG,"Fetched IMEI matches board.\r\n");
}
else{
ESP_LOGI(TAG,"INVALID IMEI!!\r\n");
// comms.poll_timer = true;
// transition(COMMS_STATE_GOING_IDLE);
return sp4_ret;
}
/*Parse string for date/time*/
strret = strtok (NULL," ");
strcpy(date_time, strret);
ESP_LOGI(TAG,"Date Time : %s\r\n",date_time);
strret = strtok (NULL," ");
if(strret[0] == '1'){
RelayState_1 = true;
}else
{
RelayState_1 = false;
}
ESP_LOGI(TAG,"Relay State : %d\r\n",RelayState_1);
// //heartbeat_time = (buf[43] - 48) * HOURS_TO_SECONDS_COEFF ;
// heartbeat_time = (buf[44] - 48) * HOURS_TO_SECONDS_COEFF ;
//
// LOG_INFO("Heartbeat time in hrs : %d\r\n", (heartbeat_time/HOURS_TO_SECONDS_COEFF));
strret = strtok (NULL," ");
strcpy(hbeat, strret+2);
ESP_LOGI(TAG,"fetched Heartbeat time value %s \r\n", hbeat);
ESP_LOGI(TAG,"previous Heartbeat time value %d \r\n", config_heartbeat_time);
/*moved changing heartbeat so that it comes after looking for test mode field and configuring it*/
config_heartbeat_time = atoi(hbeat);
strret = strtok(NULL," ");
strcpy(testMode, strret);
if(testMode[2] == '1')
{
if(testmode_timeout){
isTestMode = false;
testmode_timeout = false;
}
else{
isTestMode = true;
}
}
else
{
isTestMode = false;
}
//=====================================
ESP_LOGI(TAG,"Test Mode: %d\r\n",isTestMode);
//maximum heartbeat time is 4 days (96 hours)
if((config_heartbeat_time != 0) && (config_heartbeat_time < 97 && config_heartbeat_time > 0)){
ESP_LOGI(TAG,"Valid fetched Heartbeat time value\r\n");
config_heartbeat_time *= HOURS_TO_SECONDS_COEFF;
deviceCfged = true;
}
else{
config_heartbeat_time = HEARTBEAT_TIME_SEC;
deviceCfged = true;
ESP_LOGI(TAG,"Invalid fetched Heartbeat time value\r\n");
}
ESP_LOGI(TAG,"Heartbeat time in Sec : %d\r\n", config_heartbeat_time);
ESP_LOGI(TAG,"Heartbeat time in Hrs : %d\r\n", (config_heartbeat_time/HOURS_TO_SECONDS_COEFF));
//___________________________
strret = strtok (NULL," ");
strcpy(epcheck, strret);
if(!strcmp(epcheck,"EP\"") || !strcmp(epcheck,"EP")){
ESP_LOGI(TAG,"(%s) %s message is terminated\r\n", epcheck,messageheader);
break;
}
else{
ESP_LOGI(TAG,"(%s) %s message is not terminated!! \r\n", epcheck,messageheader);
}
}
/* ============================
temp[0] = date_time[0];
temp[1] = date_time[1];
temp[2] = date_time[2];
temp[3] = date_time[3];
RTC_DateTime.Year = atoi(temp);
==============TEST==============
LOG_INFO("Year: %d\r\n",RTC_DateTime.Year);
============================
temp[0] = date_time[5];
temp[1] = date_time[6];
temp[2] = ' ';
temp[3] = ' ';
RTC_DateTime.Month = atoi(temp); //mm value to integer
==============TEST==============
LOG_INFO("Month: %d\r\n",RTC_DateTime.Month);
============================
temp[0] = date_time[8];
temp[1] = date_time[9];
temp[2] = ' ';
temp[3] =' ';
RTC_DateTime.MonthDay = atoi(temp); //dd value to integer
==============TEST==============
LOG_INFO("MonthDay: %d\r\n",RTC_DateTime.MonthDay);
============================
temp[0] = date_time[11];
temp[1] = date_time[12];
temp[2] = ' ';
temp[3] =' ';
RTC_DateTime.Hour = atoi(temp); //HH value to integer
==============TEST==============
LOG_INFO("Hour: %d\r\n",RTC_DateTime.Hour);
============================
temp[0] = date_time[14];
temp[1] = date_time[15];
temp[2] = ' ';
temp[3] = ' ';
RTC_DateTime.Minute = atoi(temp); //hh value t integer
==============TEST==============
LOG_INFO("Minute: %d\r\n",RTC_DateTime.Minute);
============================
temp[0] = date_time[17];
temp[1] = ' ';
temp[2] = ' ';
temp[3] = ' ';
RTC_DateTime.WeekDay = atoi(temp);
==============TEST==============
LOG_INFO("WeekDay: %d\r\n",RTC_DateTime.WeekDay);
============================
//rtc_set_timestamp(&rtcData);
RTC_SetTimeDate(&RTC_DateTime);*/
// update relay state if changed
if(RelayState_1 != PreviousRelayState_1)
{
ESP_LOGI(TAG,"Previous Relay State :%d \n",PreviousRelayState_1);
PreviousRelayState_1 = RelayState_1; /* update PreviousRelayState */
if(RelayState_1 == true)
{
/*============================*/
board_relay_on();
//board_led_all_off();
//board_led_green_on();
//hmi_choose_led(HMI_LED_GREEN, HMI_LED_ON);
ESP_LOGI(TAG,"Board relay state : %d\n",RelayState_1);
}
else
{
/*============================*/
board_relay_off();
//board_led_all_off();
//board_led_red_on();
// hmi_choose_led(HMI_LED_RED, HMI_LED_ON);
ESP_LOGI(TAG,"Board relay state : %d\n ",RelayState_1);
}
}
else
{
ESP_LOGI(TAG,"Previous Relay State :%d \n",PreviousRelayState_1);
ESP_LOGI(TAG,"No changes in Relay State\r\n");
/*Transition to idle state*/
//comms.poll_timer = true; //polling the comms_timer
//Comms_Check_TestMode();
}
int retval = COMMS_STATUS_OK;
//creating sp1 message
SP1_Mqtt_Tx(config_heartbeat_time);
/* Run the MQTT publish sequence if nothing else pending */
// retval = start_mqtt_publish_sequence();
if(retval == 1)
{
ESP_LOGI(TAG,"MQTT Publish SP1 message success");
}
else
{
ESP_LOGI(TAG,"MQTT Publish SP1 message failed");
}
return 0;
}
// Interrupt Service Routine (ISR)
void IRAM_ATTR timer_isr_callback(void *param) {
int timer_idx = (int)param;
// Clear the interrupt flag
timer_group_clr_intr_status_in_isr(TIMER_GROUP_0, timer_idx);
// Re-enable the timer alarm
timer_group_enable_alarm_in_isr(TIMER_GROUP_0, timer_idx);
heartbeat_event_flag = true;
}
// Timer Initialization
void my_timer_init() {
// Disable existing interrupts before registering a new one
timer_deinit(TIMER_GROUP_0, TIMER_0);
timer_config_t config = {
.divider = TIMER_DIVIDER,
.counter_dir = TIMER_COUNT_UP,
.alarm_en = TIMER_ALARM_EN,
.auto_reload = true, // Restart timer after reaching the alarm value
.intr_type = TIMER_INTR_LEVEL
};
timer_init(TIMER_GROUP_0, TIMER_0, &config);
timer_set_counter_value(TIMER_GROUP_0, TIMER_0, 0);
timer_set_alarm_value(TIMER_GROUP_0, TIMER_0, TIMER_SCALE * TIMER_INTERVAL_SEC);
timer_enable_intr(TIMER_GROUP_0, TIMER_0);
// Register the ISR with SHARED interrupt flag
esp_err_t err = timer_isr_callback_add(TIMER_GROUP_0, TIMER_0, timer_isr_callback, (void*)TIMER_0, ESP_INTR_FLAG_SHARED | ESP_INTR_FLAG_IRAM);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to register timer ISR: %s", esp_err_to_name(err));
return;
}
// Start the timer
timer_start(TIMER_GROUP_0, TIMER_0);
}
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();
/*
while(1) {
port_red_led_on();
vTaskDelay(1000 / portTICK_PERIOD_MS);
port_red_led_off();
vTaskDelay(1000 / portTICK_PERIOD_MS);
port_blue_led_on();
vTaskDelay(1000 / portTICK_PERIOD_MS);
port_blue_led_off();
vTaskDelay(1000 / portTICK_PERIOD_MS);
port_green_led_on();
vTaskDelay(1000 / portTICK_PERIOD_MS);
port_green_led_off();
// app_tick();
ESP_LOGI(TAG, "LED testing running ....");
}*/
// get_mac(mac_address);
// printf("MAC Address in main: %s\n", mac_address);
/*while(1){
port_vbatt_sense_enable(0);
ESP_LOGI(TAG, "Realy ON");
vTaskDelay(1500/portTICK_PERIOD_MS);
port_accel_pwr_enable(1);
ESP_LOGI(TAG, "Realy OFF");
vTaskDelay(1500/portTICK_PERIOD_MS);
}*/
/* Start On-Boarding process */
webserver_start();
get_mac_add();
/* Wait till the onboarding process is completed */
while(!webserver_get_status())
{
vTaskDelay(750/portTICK_PERIOD_MS);
ESP_LOGI(TAG, "Waiting from wifi connect .....");
port_blue_led_toggle();
}
port_red_led_off();
port_green_led_on();
wifi_first_init();
// Connect_wifi_sta(WIFI_MODE_STA);
uint8_t ret = comms_init();
if ( ret == COMMS_STATUS_OK )
{
ESP_LOGI(TAG, "Comms init Successfully :) ");
comms_start(comms_started_cb, comms_connect_cb);
} else
{
ESP_LOGW(TAG, "Comms init faild :(");
}
my_timer_init();
// char url_sp4[]="http://54.204.230.201:8081/hae/azuma/128101153943920/mcu_config_download/";
// char res[512];
// http_client_get(url_sp4, res);
// ESP_LOGI(TAG, "SP4 ===> messgage \n %s",res);
//
// Comms_Parse_SP4(res, sizeof(res));
while(1) {
vTaskDelay(1000 / portTICK_PERIOD_MS);
app_tick();
ESP_LOGI(TAG, "App tick running ....");
}
}

38
main/main.h Normal file
View File

@ -0,0 +1,38 @@
/*
* main.h
*
* Created on: Feb 11, 2023
* Author: Nael
*/
#ifndef MAIN_MAIN_H_
#define MAIN_MAIN_H_
#include <stdint.h>
extern char MAC_ID[16];
#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
#define BUILD_VERSION_STRING "LRSM0009C_Azuma_v0.5"
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_ */

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

258
main/port.c Normal file
View File

@ -0,0 +1,258 @@
/*
* 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 26
#define LED_RED_PIN 20
#define LED_GREEN_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 42
#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 bool green_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(LED_GREEN_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, 1);
gpio_set_level(LED_BLUE_PIN, 1);
gpio_set_level(LED_GREEN_PIN, 1);
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_green_led_off(void)
{
gpio_set_level(LED_GREEN_PIN, 1);
green_led_status = 0;
}
void port_green_led_on(void)
{
gpio_set_level(LED_GREEN_PIN, 0);
green_led_status = 1;
}
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);
}

55
main/port.h Normal file
View File

@ -0,0 +1,55 @@
/*
* 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_green_led_on(void);
void port_green_led_off(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_ */

437
main/rtc.c Normal file
View File

@ -0,0 +1,437 @@
/*
* rtc.c
*
* Created on: Jan 16, 2023
* Author: Sword
*/
#include "rtc.h"
#include <time.h>
#include <sys/time.h>
#include "esp_sntp.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "lwip/sockets.h"
#include "lwip/err.h"
#include "lwip/netdb.h"
#include "lwip/icmp.h"
#include "esp_system.h"
#include "esp_log.h"
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include "nvm.h"
#include "nvs_flash.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 26 /*< Set day to the RTC */
#define SET_MONTH 2 /*< Set month to the RTC */
#define SET_YEAR 2025 /*< 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"
#include "esp_sntp.h"
static bool rtc_set = false;
#define PING_HOST "8.8.8.8" // Google DNS
#define CHECK_INTERVAL 1 //60000 // Check every 60 seconds
#define MAX_DISCONNECT_TIME 5 //86400 // 24 hours in seconds
#define SEC 3600
static time_t last_successful_ping = 0;
/// Internet monitor //
time_t get_sntp_time()
{
struct timeval tv;
gettimeofday(&tv, NULL);
return tv.tv_sec; // Return UNIX timestamp
}
bool ping_test()
{
struct sockaddr_in target_addr;
target_addr.sin_addr.s_addr = inet_addr(PING_HOST);
target_addr.sin_family = AF_INET;
target_addr.sin_port = htons(0);
int sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
if (sock < 0)
{
ESP_LOGE(TAG, "Socket creation failed");
return false;
}
struct icmp_echo_hdr echo_req;
memset(&echo_req, 0, sizeof(echo_req));
echo_req.id = htons(1);
echo_req.seqno = htons(1);
echo_req.type = ICMP_ECHO;
if (sendto(sock, &echo_req, sizeof(echo_req), 0, (struct sockaddr *)&target_addr, sizeof(target_addr)) < 0)
{
ESP_LOGE(TAG, "Ping send failed");
close(sock);
return false;
}
fd_set read_fds;
struct timeval timeout = {1, 0}; // 1 second timeout
FD_ZERO(&read_fds);
FD_SET(sock, &read_fds);
if (select(sock + 1, &read_fds, NULL, NULL, &timeout) > 0)
{
ESP_LOGI(TAG, "Internet is available");
close(sock);
return true;
}
ESP_LOGW(TAG, "Ping timeout, no internet");
close(sock);
return false;
}
void internet_monitor_task(void *pvParameter)
{
while (1)
{
time_t current_time = get_sntp_time();
if (ping_test())
{
last_successful_ping = current_time;
}
if (last_successful_ping > 0 && (current_time - last_successful_ping) > MAX_DISCONNECT_TIME)
{
ESP_LOGE(TAG, "No internet for %d hours, restarting...", (MAX_DISCONNECT_TIME/SEC));
/* erase the NVS partition */
ESP_ERROR_CHECK(nvs_flash_erase());
esp_restart();
}
vTaskDelay(pdMS_TO_TICKS(CHECK_INTERVAL)); // Wait before next check
}
}
// END ///
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;
}
///////////////////////////////////////////////////////
/*
void time_sync_notification_cb(struct timeval_1 *tv) {
ESP_LOGI(TAG, "Time synchronization event received");
}
*/
void obtain_time(void) {
ESP_LOGI(TAG, "Initializing SNTP");
const char *ntp_servers[] = {
"pool.ntp.org",
"time.google.com",
"1.pool.ntp.org"
};
int server_index = 0;
int num_servers = sizeof(ntp_servers) / sizeof(ntp_servers[0]);
time_t now = 0;
struct tm timeinfo = { 0 };
while (server_index < num_servers) {
ESP_LOGI(TAG, "Using NTP server: %s", ntp_servers[server_index]);
esp_sntp_setoperatingmode(SNTP_OPMODE_POLL);
esp_sntp_setservername(0, ntp_servers[server_index]);
esp_sntp_init();
int retry = 0;
const int max_retries = 10;
while (timeinfo.tm_year < (2020 - 1900) && retry < max_retries) {
ESP_LOGI(TAG, "Waiting for system time to be set... (%d/%d)", retry + 1, max_retries);
vTaskDelay(2000 / portTICK_PERIOD_MS);
time(&now);
localtime_r(&now, &timeinfo);
retry++;
}
if (timeinfo.tm_year >= (2020 - 1900)) {
ESP_LOGI(TAG, "Time synchronized: %s", asctime(&timeinfo));
// create internet monitor task
xTaskCreate(&internet_monitor_task, "internet_monitor_task", 4096, NULL, 5, NULL);
return; // Exit the function since time is successfully obtained
}
ESP_LOGE(TAG, "Failed to sync time with %s, switching to next server...", ntp_servers[server_index]);
esp_sntp_stop(); // Stop SNTP before switching
server_index++; // Move to the next server
}
ESP_LOGE(TAG, "All NTP servers failed! Check network settings.");
}
/*void obtain_time(void) {
ESP_LOGI(TAG, "Initializing SNTP");
esp_sntp_setoperatingmode(SNTP_OPMODE_POLL);
esp_sntp_setservername(0, "pool.ntp.org"); // Set NTP server
// sntp_set_time_sync_notification_cb(time_sync_notification_cb);
esp_sntp_init();
// Wait for time to be set
time_t now = 0;
struct tm timeinfo = { 0 };
int retry = 0;
const int max_retries = 10;
while (timeinfo.tm_year < (2020 - 1900) && ++retry < max_retries) {
ESP_LOGI(TAG, "Waiting for system time to be set... (%d/%d)", retry, max_retries);
vTaskDelay(2000 / portTICK_PERIOD_MS);
time(&now);
localtime_r(&now, &timeinfo);
}
if (retry >= max_retries) {
ESP_LOGE(TAG, "Failed to obtain time");
} else {
ESP_LOGI(TAG, "Time synchronized");
}
}*/
void get_time(char *time_str, size_t size) { // Buffer is provided by the caller
time_t now;
struct tm timeinfo;
time(&now);
// ESP_LOGI(TAG, "Time print start %ld", now);
localtime_r(&now, &timeinfo);
const char *weekdays[] = {"0", "1", "2", "3",
"4", "5", "6"};
// Format time string
snprintf(time_str, size, "%04d/%02d/%02d_%02d:%02d:%02d_%s",
timeinfo.tm_year + 1900,
timeinfo.tm_mon + 1, timeinfo.tm_mday,
timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec,
weekdays[timeinfo.tm_wday]);
ESP_LOGI(TAG, "Formatted Time: %s", time_str);
}
///////////////////////////////////////////////////////

83
main/rtc.h Normal file
View File

@ -0,0 +1,83 @@
/*
* 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>
#include "esp_sntp.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);
void get_time(char *, size_t );
void obtain_time(void);
#endif /* MAIN_RTC_H_ */

272
main/uart_ifx.c Normal file
View File

@ -0,0 +1,272 @@
/*
* 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 = 4800,
.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;
}

710
main/wifi_Client.c Normal file
View File

@ -0,0 +1,710 @@
/*
* tempstick_wifi_client.c
*
* Created on: Jul 28, 2023
* Author: Sword
*/
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include "esp_err.h"
#include "esp_log.h"
#include "esp_netif_types.h"
#include "main.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"
#include "comms.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;
char http_resp[512];
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;
ESP_LOGI(TAG, "%s\n", output_buffer);
strcpy(http_resp, output_buffer);
ESP_LOGI(TAG, "http_resp ==> %s\n", http_resp);
}
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_REDIRECT");
esp_http_client_set_redirection(evt->client);
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 mac_check_valid(char *message_imei)
{
//find the length of message imei
int len = strlen(message_imei);
ESP_LOGI(TAG,"Received MAC ID : %s",message_imei);
ESP_LOGI(TAG,"Board MAC ID : %s",MAC_ID);
//check length of imei field
if (len != 15){
//invalid IMEI
ESP_LOGW(TAG,"Invalid MAC length");
return false;
}
if(!strcmp(message_imei,MAC_ID)){
ESP_LOGW(TAG,"Valid MAC ");
return true;
}
else{
ESP_LOGI(TAG,"Message IMEI doesn't match board IMEI");
return false;
}
}
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);
ESP_LOGI(TAG,"Board IMEI : %s",MAC_ID);
//check length of imei field
if (len != 15){
//invalid IMEI
ESP_LOGW(TAG,"Invalid MAC length");
return false;
}
if(!strcmp(message_imei,MAC_ID)){
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);
ESP_LOGW(TAG,"Sum value = %d",sum);
ESP_LOGW(TAG,"Sum mod value = %d",sum %10);
}
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 = mac_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: %lu\nBoard Firmware version: %lu",new_fw_version,g_version); //logging/printing FR_version message for tracing
/**********************************************************************************************************/
// test version
new_fw_version = 1;
/*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,
.user_data = http_resp,
.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);
}
isDataNeeded = false;
return http_client_get_err;
}
esp_err_t http_get_response_buf(char* bufptr, int len)
{
if (bufptr && len)
{
uint16_t buf_len = strlen(http_resp);
ESP_LOGI(TAG, "output_buffer => : %s\n",output_buffer);
ESP_LOGI(TAG, "http_resp => : %s\n",http_resp);
ESP_LOGI(TAG, " buf len %d", buf_len);
if (http_resp && buf_len > 0) {
strcpy(bufptr, http_resp);
// *bufptr = output_buffer;
len = buf_len;
ESP_LOGI(TAG, "BUF: %s\nLEN : %d", bufptr, len);
return ESP_OK;
}
bufptr = 0;
len = 0;
}
return ESP_FAIL;
}
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:
break;
}
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

52
main/wifi_Client.h Normal file
View File

@ -0,0 +1,52 @@
/*
* 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_get_response_buf(char* bufptr, int len);
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_ */

679
main/wifi_Init.c Normal file
View File

@ -0,0 +1,679 @@
/*
* 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"
#include "port.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 "Azuma Wifi 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;
int qmtopen_retries = 0;
bool qmtopen_fail = false;
bool qmtclose_fail = false;
bool cops_fail = false;
/* 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 */
ESP_LOGI(TAG," Device Onboarded.....Reading WiFi Credentials....");
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)
{
port_red_led_on();
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

68
main/wifi_Init.h Normal file
View File

@ -0,0 +1,68 @@
/*
* 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_STATUS_OK 0
#define WIFI_STATUS_ERROR -1
#define WIFI_STATUS_TIMEOUT -2
#define WIFI_STATUS_MQTT_PUB_OVERFLOW -10
#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_ */

284
main/wifi_OTA.c Normal file
View File

@ -0,0 +1,284 @@
/* 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"
#include "comms.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_ */

1654
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