Added Azuma wifi backup code
This commit is contained in:
parent
5e9656265b
commit
c1dd342432
9
.clang-format
Normal file
9
.clang-format
Normal 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
3
.clangd
Normal file
@ -0,0 +1,3 @@
|
||||
CompileFlags:
|
||||
CompilationDatabase: build
|
||||
Remove: [-m*, -f*]
|
17
.cproject
Normal file
17
.cproject
Normal 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
20
.project
Normal 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>
|
2
.settings/org.eclipse.core.resources.prefs
Normal file
2
.settings/org.eclipse.core.resources.prefs
Normal file
@ -0,0 +1,2 @@
|
||||
eclipse.preferences.version=1
|
||||
encoding/<project>=UTF-8
|
9
CMakeLists.txt
Normal file
9
CMakeLists.txt
Normal 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
5
LICENSE
Normal 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.
|
45
README.md
45
README.md
@ -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
|
||||
|
||||
You’ll 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 you’ll see the change you just made.
|
||||
6. Go back to the **Source** page.
|
||||
|
||||
---
|
||||
|
||||
## Create a file
|
||||
|
||||
Next, you’ll 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. You’ll 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 you’d like to and then click **Clone**.
|
||||
4. Open the directory you just created to see your repository’s 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
16
main/CMakeLists.txt
Normal 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
14
main/Kconfig.projbuild
Normal 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
35
main/MCP39F501.h
Normal 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
187
main/adc_ifx.c
Normal 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
18
main/adc_ifx.h
Normal 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
2106
main/comms.c
Normal file
File diff suppressed because it is too large
Load Diff
152
main/comms.h
Normal file
152
main/comms.h
Normal 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
474
main/data_processing.c
Normal 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
298
main/data_processing.h
Normal 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
721
main/hmi.c
Normal 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
56
main/hmi.h
Normal 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
677
main/main.c
Normal 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
38
main/main.h
Normal 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
3109
main/modem.c
Normal file
File diff suppressed because it is too large
Load Diff
181
main/modem.h
Normal file
181
main/modem.h
Normal 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
1118
main/nvm.c
Normal file
File diff suppressed because it is too large
Load Diff
74
main/nvm.h
Normal file
74
main/nvm.h
Normal 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
424
main/ota.c
Normal 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
32
main/ota.h
Normal 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
258
main/port.c
Normal 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
55
main/port.h
Normal 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
437
main/rtc.c
Normal 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
83
main/rtc.h
Normal 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
272
main/uart_ifx.c
Normal 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
26
main/uart_ifx.h
Normal 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_ */
|
321
main/ulp/sensors_registers.h
Normal file
321
main/ulp/sensors_registers.h
Normal 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
730
main/ulp/ulp_main.c
Normal 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
710
main/wifi_Client.c
Normal 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
52
main/wifi_Client.h
Normal 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
679
main/wifi_Init.c
Normal 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
68
main/wifi_Init.h
Normal 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
284
main/wifi_OTA.c
Normal 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
22
main/wifi_OTA.h
Normal 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
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
30
main/wifi_webServer.h
Normal 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
7
partitions.csv
Normal 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,
|
|
Loading…
Reference in New Issue
Block a user