1029 lines
30 KiB
C
1029 lines
30 KiB
C
/* USER CODE BEGIN Header */
|
|
/**
|
|
******************************************************************************
|
|
* @file yunhorn_sts_process.c *
|
|
* @author Yunhorn (r) Technology Limited Application Team *
|
|
* @brief Yunhorn (r) SmarToilets (r) Product configuration file. *
|
|
******************************************************************************
|
|
* @attention
|
|
*
|
|
* Copyright (c) 2022 Yunhorn Technology Limited.
|
|
* Copyright (c) 2022 Shenzhen Yunhorn Technology Co., Ltd.
|
|
* All rights reserved.
|
|
*
|
|
* This software is licensed under terms that can be found in the LICENSE file
|
|
* in the root directory of this software component.
|
|
* If no LICENSE file comes with this software, it is provided AS-IS.
|
|
*
|
|
******************************************************************************
|
|
*/
|
|
/* USER CODE END Header */
|
|
|
|
/* Includes ------------------------------------------------------------------*/
|
|
#include "stdint.h"
|
|
#include "platform.h"
|
|
#include "sys_conf.h"
|
|
#include "sys_app.h"
|
|
#include "stdio.h"
|
|
#include "stm32_systime.h"
|
|
#include "adc_if.h"
|
|
#include "gpio.h"
|
|
#include "LmHandler.h"
|
|
//#include "app_tof.h"
|
|
#include "lora_app.h"
|
|
#include "yunhorn_sts_prd_conf.h"
|
|
#include "yunhorn_sts_sensors.h"
|
|
#include "sts_cmox_hmac_sha.h"
|
|
|
|
/* USER CODE BEGIN Includes */
|
|
extern volatile sts_cfg_nvm_t sts_cfg_nvm;
|
|
extern volatile uint8_t sts_ac_code[20];
|
|
volatile uint8_t sts_service_mask=0;
|
|
volatile uint32_t rfac_timer;
|
|
volatile uint8_t sensor_data_ready=0;
|
|
|
|
extern volatile uint8_t sts_reed_hall_result;
|
|
volatile uint8_t last_sts_reed_hall_result;
|
|
|
|
volatile uint8_t sts_soap_level_state;
|
|
volatile STS_OO_SensorStatusDataTypeDef sts_o7_sensorData;
|
|
volatile STS_PRESENCE_SENSOR_Event_Status_t sts_o7_event_status;
|
|
volatile float sts_distance_rss_distance, sts_sensor_install_height=0;//in mm
|
|
extern volatile float sts_presence_rss_distance, sts_presence_rss_score;
|
|
extern volatile uint8_t sts_hall1_read,sts_hall2_read;
|
|
volatile uint8_t sts_reed_hall_1_result=STS_Status_Door_Open,sts_reed_hall_2_result=STS_Status_SOS_Release, last_sts_reed_hall_1_result=STS_Status_Door_Open, last_sts_reed_hall_2_result=STS_Status_SOS_Release;
|
|
volatile uint8_t sts_reed_hall_1_changed=0, sts_reed_hall_2_changed=0;
|
|
volatile uint8_t sts_rss_config_updated_flag = 0;
|
|
extern volatile uint8_t mems_int1_detected, link_wakeup, link_sleep;
|
|
volatile uint32_t event_start_time=0, event_stop_time=0;
|
|
volatile uint32_t event_door_lock_start_time=0,event_door_lock_stop_time=0;
|
|
extern volatile uint8_t sts_occupancy_overtime_state;
|
|
//extern volatile STS_OO_RSS_SensorTuneDataTypeDef sts_presence_rss_config;
|
|
extern volatile sts_cfg_nvm_t sts_cfg_nvm;
|
|
extern volatile uint8_t sts_fall_detection_acc_threshold, sts_fall_detection_depth_threshold, sts_occupancy_overtime_threshold_in_10min;
|
|
extern volatile uint8_t sts_fall_rising_detected_result_changed_flag;
|
|
extern volatile uint8_t last_sts_fall_rising_detected_result;
|
|
extern volatile uint8_t sts_unconscious_state;
|
|
extern volatile uint16_t sts_unconscious_threshold, sts_unconscious_duration;
|
|
extern volatile uint8_t sts_emergency_button_pushed, sts_rss_2nd_result,sts_tof_result, sts_status_color, sts_lamp_bar_color, sts_service_mask;
|
|
extern volatile distance_measure_cfg_t distance_cfg;
|
|
extern uint8_t sts_fall_rising_detected_result;
|
|
extern volatile uint16_t sts_fall_rising_pattern_factor1;
|
|
extern volatile uint16_t sts_roc_acc_standard_variance;
|
|
extern uint8_t luminance_level;
|
|
SysTime_t mems_event_time;
|
|
volatile uint32_t last_sts_rss_time_stamp=0;
|
|
extern volatile uint8_t sts_reed_hall_ext_int;
|
|
volatile uint8_t sts_occupancy_status;
|
|
volatile uint8_t sts_hall1_changed_flag=0, sts_hall2_changed_flag=0, last_sts_hall1_result=0, last_sts_hall2_result=0;
|
|
volatile uint8_t sts_reed_hall_changed_flag = 0;
|
|
extern volatile uint8_t sts_reed_hall_result;
|
|
volatile uint8_t sts_water_leakage_result=0;
|
|
volatile uint8_t sts_water_leakage_changed_flag=0;
|
|
//extern volatile uint8_t sensor_data_ready;
|
|
#ifdef YUNHORN_STS_R4_ENABLED
|
|
volatile STS_R0_SensorDataTypeDef r4_data;
|
|
#endif
|
|
|
|
#ifdef YUNHORN_STS_O5_ENABLED
|
|
|
|
#endif
|
|
#if defined(STS_O7)||defined(STS_O6)
|
|
extern volatile uint8_t motion_detected_count;
|
|
extern volatile uint8_t motion_in_hs_zone[12][10]; //0.4*12=4.8meter high, past 10 measures
|
|
extern volatile uint8_t detected_hs_zone;
|
|
|
|
extern volatile STS_OO_RSS_SensorTuneDataTypeDef sts_presence_rss_config;
|
|
volatile uint32_t cnt=0;
|
|
extern volatile distance_measure_cfg_t distance_cfg;
|
|
volatile uint8_t sts_work_mode = STS_DUAL_MODE;
|
|
extern uint8_t luminance_level;
|
|
extern volatile uint8_t sts_status_color;
|
|
extern volatile uint8_t sts_lamp_bar_color; //puColor
|
|
extern volatile uint8_t sts_cloud_netcolor; //netColor
|
|
extern volatile bool p2_work_finished;
|
|
volatile uint8_t sts_tof_result_changed_flag = 0;
|
|
|
|
volatile uint8_t sts_rss_result_changed_flag = 0;
|
|
volatile uint8_t sts_rss_result = STS_RESULT_NO_MOTION;
|
|
volatile uint8_t sts_rss_2nd_result = STS_RESULT_NO_MOTION; //2nd RSS sensor status
|
|
volatile uint8_t sts_tof_result = STS_RESULT_NO_MOTION;
|
|
volatile uint8_t last_sts_rss_result=STS_RESULT_NO_MOTION;
|
|
|
|
//extern volatile uint8_t last_sts_reed_hall_result;
|
|
extern volatile uint8_t last_lamp_bar_color;
|
|
extern volatile float sts_presence_rss_distance;
|
|
char sts_presence_fall_detection_message[10][20]={
|
|
"State_Normal",
|
|
"State_Fall_Down",
|
|
"State_Rising_Up",
|
|
"State_Laydown",
|
|
"State_Unconscious",
|
|
"State_StayStill"
|
|
};
|
|
|
|
#endif
|
|
|
|
|
|
/*
|
|
// UTIL_SEQ_SetTask((1 << CFG_SEQ_Task_YunhornSTSEventP4), CFG_SEQ_Prio_0);
|
|
// P1 --- REEDSWITCH, HALL ELEMENT, WATER LEAKAGE
|
|
// P2 --- SEE ABOVE, RSS PRESENCE
|
|
// P3 ----LAMP BAR SCOLLER PROCESS
|
|
// P4 --- TOF DISTANCE VL53L0X simple distance
|
|
// P5 --- TOF IN OUT COUNT VL53L3X in out or duration
|
|
// P6 --- SOAP Level, capacitive measurement
|
|
// P7 --- UltraSonic, 2nd wave UltraSonic range measure
|
|
// P8 --- AIR QUALITY AND ODOR LEVEL, SMOKING DETECTION
|
|
*/
|
|
|
|
|
|
/* USER CODE END Includes */
|
|
|
|
/* External variables ---------------------------------------------------------*/
|
|
/* USER CODE BEGIN EV */
|
|
|
|
/* USER CODE END EV */
|
|
|
|
/* Private typedef -----------------------------------------------------------*/
|
|
/* USER CODE BEGIN PTD */
|
|
|
|
/* USER CODE END PTD */
|
|
|
|
/* Private define ------------------------------------------------------------*/
|
|
|
|
/* USER CODE BEGIN PD */
|
|
|
|
/* USER CODE END PD */
|
|
|
|
/* Private macro -------------------------------------------------------------*/
|
|
/* USER CODE BEGIN PM */
|
|
|
|
/* USER CODE END PM */
|
|
|
|
/* Private variables ---------------------------------------------------------*/
|
|
|
|
/* USER CODE BEGIN PV */
|
|
|
|
/* USER CODE END PV */
|
|
|
|
/* Private function prototypes -----------------------------------------------*/
|
|
/* USER CODE BEGIN PFP */
|
|
#if (defined(YUNHORN_STS_O6_ENABLED) && defined(USE_ACCONEER_A111))
|
|
|
|
#endif
|
|
|
|
/* USER CODE END PFP */
|
|
|
|
/* Exported functions --------------------------------------------------------*/
|
|
|
|
void STS_YunhornAuthenticationCode_Process(void)
|
|
{
|
|
if ((sts_ac_code[0] == 0x00) && (sts_ac_code[19]== 0x0)) {
|
|
APP_LOG(TS_OFF,VLEVEL_M, "Initial AC CODE blank... \r\n");
|
|
return;
|
|
}
|
|
|
|
sts_service_mask = (sts_hmac_verify()!= 0)? STS_SERVICE_MASK_L2:STS_SERVICE_MASK_L0;
|
|
if (sts_service_mask == STS_SERVICE_MASK_L2) {
|
|
sts_ac_code[0] = 0x0;
|
|
sts_ac_code[19]= 0x0;
|
|
}
|
|
APP_LOG(TS_OFF, VLEVEL_H, "STS_SERVICE_MASK:%d \r\n",sts_service_mask);
|
|
}
|
|
|
|
void STS_YunhornSTSEventRFAC_Process(void)
|
|
{
|
|
if ((sts_ac_code[0] ==0x0)&& (sts_ac_code[19]== 0x0))
|
|
{
|
|
if ((rfac_timer >= STS_BURN_IN_RFAC) && (rfac_timer < (STS_BURN_IN_RFAC +3)))
|
|
{
|
|
APP_LOG(TS_OFF, VLEVEL_M, "\r\n -------------------RFAC Process\r\n");
|
|
STS_SENSOR_Upload_Message(LORAWAN_USER_APP_CTRL_REPLY_PORT, 4, (uint8_t *)"RFAC");
|
|
}
|
|
if ((rfac_timer > (STS_BURN_IN_RFAC + 2)))
|
|
{
|
|
APP_LOG(TS_OFF, VLEVEL_M, "\r\n -------------------Verify RFAC Success or Not\r\n");
|
|
sts_service_mask = (sts_hmac_verify()!= 0)? STS_SERVICE_MASK_L2:STS_SERVICE_MASK_L0;
|
|
if (sts_service_mask == STS_SERVICE_MASK_L2) {
|
|
sts_ac_code[0] = 0x0;
|
|
sts_ac_code[19] = 0x0;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
/*
|
|
* STS-P1 --- REEDSWITCH, HALL ELEMENT, WATER LEAKAGE
|
|
*/
|
|
|
|
void STS_YunhornSTSEventP1_Process(void)
|
|
{
|
|
|
|
if (sts_reed_hall_1_changed) {
|
|
sts_reed_hall_1_result = HALL1_STATE; //sts_hall1_read;
|
|
sts_reed_hall_1_changed =0;
|
|
last_sts_reed_hall_1_result = sts_reed_hall_1_result;
|
|
}
|
|
if (sts_reed_hall_2_changed){
|
|
sts_reed_hall_2_result = HALL2_STATE;// sts_hall2_read;
|
|
sts_reed_hall_2_changed =0;
|
|
last_sts_reed_hall_2_result = sts_reed_hall_2_result;
|
|
}
|
|
STS_Combined_Status_Processing();
|
|
}
|
|
|
|
extern volatile uint32_t wcnt;
|
|
|
|
/*
|
|
* STS-P2 --- RSS PRESENCE
|
|
*/
|
|
void STS_YunhornSTSEventP2_Process(void)
|
|
{
|
|
p2_work_finished=false;
|
|
//STS_Lamp_Bar_Refresh(); //TODO XXX eliminate refresh every second.... try
|
|
if ((sts_work_mode >= STS_RSS_MODE) && (sts_work_mode <= STS_TOF_RSS_MODE))
|
|
{
|
|
sts_presence_rss_fall_rise_detection();
|
|
|
|
sts_rss_result_changed_flag = (sts_rss_result == last_sts_rss_result)? 0:1;
|
|
last_sts_rss_result = sts_rss_result;
|
|
|
|
sts_fall_rising_detected_result_changed_flag = (sts_fall_rising_detected_result == last_sts_fall_rising_detected_result)?0:1;
|
|
last_sts_fall_rising_detected_result = sts_fall_rising_detected_result;
|
|
|
|
if (sts_service_mask > 0 ) {
|
|
sts_rss_result_changed_flag =0;
|
|
sts_reed_hall_changed_flag = 0;
|
|
sts_fall_rising_detected_result_changed_flag =0;
|
|
}
|
|
|
|
STS_Combined_Status_Processing();
|
|
}
|
|
p2_work_finished=true;
|
|
}
|
|
|
|
void STS_Reed_Hall_Presence_Detection(void)
|
|
{
|
|
// HAL_Delay(50); // BOUNCING ELIMIATION
|
|
sts_reed_hall_1_result = (sts_hall1_read==0)?STS_Status_Door_Close:STS_Status_Door_Open;
|
|
sts_reed_hall_2_result = (sts_hall2_read==0)?STS_Status_Door_Close:STS_Status_Door_Open;
|
|
|
|
|
|
//sts_reed_hall_result = ((STS_Reed_Hall_State)&STS_Status_Door_Open);
|
|
|
|
// HAL_Delay(20); // BOUNCING ELIMIATION
|
|
|
|
sts_reed_hall_changed_flag = 0;
|
|
|
|
sts_reed_hall_ext_int = 0;
|
|
|
|
}
|
|
|
|
/*
|
|
* STS P3 process, Lamp Bar Scoller
|
|
*/
|
|
void STS_YunhornSTSEventP3_Process(void)
|
|
{
|
|
#if (defined(STS_O6) ||defined(STS_O7))
|
|
if (STS_Reed_Hall_State == STS_Status_Door_Open)
|
|
{
|
|
sts_lamp_bar_color =STS_GREEN;
|
|
}
|
|
else
|
|
{
|
|
sts_lamp_bar_color =STS_RED;
|
|
}
|
|
STS_Lamp_Bar_Scoller(sts_lamp_bar_color, luminance_level);
|
|
#endif
|
|
}
|
|
|
|
|
|
/*
|
|
* STS SOAP Level detection Process, STS_CAP_Sensor_Detection Process
|
|
* STS_CAP_SWITCH(ON) Boost Voltage to 5V, then hold for 1000 ms
|
|
* HAL_Delay(1000) (ms)
|
|
* STS_CAP_Read_Data() Read STS_CAP_DATA state
|
|
* STS_CAP_SWITCH(OFF) Switch Off Boosted Voltage
|
|
*/
|
|
/*
|
|
* STS-P4 Detection ToF distance (VL53L0X)
|
|
*
|
|
*/
|
|
void STS_YunhornSTSEventP4_Process(void)
|
|
{
|
|
STS_SENSOR_Power_ON(0);
|
|
#ifdef LED_ONBOARD
|
|
LED_ON;
|
|
HAL_Delay(10);
|
|
LED_OFF;
|
|
#endif
|
|
#if defined(TOF_1)||defined(TOF_2)
|
|
APP_LOG(TS_OFF, VLEVEL_H, "\r\n TOF_1, TOF_2 RANGING Process\r\n");
|
|
STS_TOF_VL53L0X_Range_Process();
|
|
#endif
|
|
|
|
#ifdef TOF_3
|
|
APP_LOG(TS_OFF, VLEVEL_H, "\r\n TOF 3 RANGING Process ---- TOF250 Ranging \r\n");
|
|
STS_TOF250_Range_Process();
|
|
#endif
|
|
|
|
STS_SENSOR_Power_OFF(0);
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
* STS P5 Process, Detection ToF IN-OUT PEOPLE COUNT (VL53L3X)
|
|
*
|
|
*/
|
|
void STS_YunhornSTSEventP5_Process(void)
|
|
{
|
|
APP_LOG(TS_OFF, VLEVEL_L, "\r\n P5 Testing Process\r\n");
|
|
}
|
|
|
|
/*
|
|
* STS-P6 --- SOAP Level, capacitive measurement
|
|
* STS Soap Level Detection Process, STS_CAP_Sensor_Detection Process
|
|
* STS_CAP_SWITCH(ON) Boost Voltage to 5V, then hold for 1000 ms
|
|
* HAL_Delay(1000) (ms)
|
|
* STS_CAP_Read_Data() Read STS_CAP_DATA state
|
|
* STS_CAP_SWITCH(OFF) Switch Off Boosted Voltage
|
|
*/
|
|
void STS_YunhornSTSEventP6_Process(void)
|
|
{
|
|
APP_LOG(TS_OFF, VLEVEL_H, "\r\n P6 Testing Process\r\n");
|
|
STS_SENSOR_Power_ON(0);
|
|
HAL_Delay(50);
|
|
#ifdef LED_ONBOARD
|
|
LED_ON;
|
|
HAL_Delay(20);
|
|
LED_OFF;
|
|
#endif
|
|
/* 1. Sensor Power On */
|
|
#if defined(SOAP_LEVEL_SENSOR)
|
|
HAL_GPIO_WritePin(SOAP_SWITCH_GPIO_Port, SOAP_SWITCH_Pin, GPIO_PIN_SET);
|
|
|
|
HAL_Delay(1000);
|
|
/* 2. Read sensor state */
|
|
|
|
sts_soap_level_state = HAL_GPIO_ReadPin(SOAP_STATUS_GPIO_Port,SOAP_STATUS_Pin);
|
|
APP_LOG(TS_OFF, VLEVEL_L, "\r\n Soap State = %s \r\n", (sts_soap_level_state==0x0)?" +++ Liquid Detected":" --- No Liquid");
|
|
|
|
HAL_GPIO_WritePin(SOAP_SWITCH_GPIO_Port, SOAP_SWITCH_Pin, GPIO_PIN_RESET);
|
|
|
|
if (sts_soap_level_state == 0x0)
|
|
{
|
|
#ifdef LED_ONBOARD
|
|
LED_ON;
|
|
HAL_Delay(20);
|
|
LED_OFF;
|
|
#endif
|
|
}
|
|
|
|
#endif
|
|
/* 3. Sensor Power Off */
|
|
STS_SENSOR_Power_OFF(0);
|
|
}
|
|
|
|
|
|
/*
|
|
* STS P7 Process, Detection IAQ Sensors
|
|
* air quality and odor level sensors
|
|
*/
|
|
void STS_YunhornSTSEventP7_Process(void)
|
|
{
|
|
APP_LOG(TS_OFF, VLEVEL_L, "\r\n P7 Testing Process\r\n");
|
|
STS_SENSOR_Power_ON(0);
|
|
|
|
STS_SENSOR_Power_OFF(0);
|
|
}
|
|
|
|
|
|
/*
|
|
* STS P8 Process, Detection ETR Sensors, Water flow sensors, pulse counting
|
|
* PA5 sensors , TIM2_ETR, STS-M4
|
|
*/
|
|
void STS_YunhornSTSEventP8_Process(void)
|
|
{
|
|
APP_LOG(TS_OFF, VLEVEL_L, "\r\n P8 Testing Process\r\n");
|
|
|
|
}
|
|
|
|
/*
|
|
* STS P_IO_RS485 Process, Send Out Sensor Data Via RS485 interface
|
|
* sensors
|
|
*/
|
|
|
|
void STS_YunhornSTSEventPIORS485_Process(void)
|
|
{
|
|
APP_LOG(TS_OFF, VLEVEL_L, "\r\n P_IO_RS485 Process\r\n");
|
|
}
|
|
|
|
|
|
void STS_PRESENCE_SENSOR_WakeUp_Process_Sampling(void)
|
|
{
|
|
#if 0
|
|
if ((sensor_data_ready ==0)) {
|
|
STS_PRESENCE_SENSOR_GetValue();
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void STS_PRESENCE_SENSOR_After_Wake_Up()
|
|
{
|
|
|
|
}
|
|
|
|
|
|
void STS_FallDetection_LampBarProcess(void)
|
|
{
|
|
|
|
}
|
|
|
|
void STS_YunhornSTSFallDetection(void)
|
|
{
|
|
//APP_LOG(TS_OFF, VLEVEL_M, "\r\n YUNHORN STS FALL DETECTION \r\n");
|
|
|
|
//STS_YunhornCheckStandardDeviation();
|
|
|
|
}
|
|
|
|
void STS_PRESENCE_SENSOR_NVM_CFG(void)
|
|
{
|
|
sts_presence_rss_config.default_start_m = (float)((float)sts_cfg_nvm.p[RSS_CFG_START_M]*0.1f);
|
|
sts_presence_rss_config.default_length_m = (float)((float)sts_cfg_nvm.p[RSS_CFG_LENGTH_M]*0.1f);
|
|
sts_presence_rss_config.default_threshold = (float)((float)sts_cfg_nvm.p[RSS_CFG_THRESHOLD]*0.1f);
|
|
sts_presence_rss_config.default_receiver_gain = (float)((float)sts_cfg_nvm.p[RSS_CFG_RECEIVER_GAIN]*0.01f);
|
|
|
|
sts_presence_rss_config.default_zone_length_m = DEFAULT_ZONE_LENGTH;
|
|
sts_presence_rss_config.default_profile = (float)(sts_cfg_nvm.p[RSS_CFG_PROFILE]);
|
|
sts_presence_rss_config.default_update_rate_tracking = (float)(sts_cfg_nvm.p[RSS_CFG_RATE_TRACKING]);
|
|
sts_presence_rss_config.default_update_rate_presence = (float)(sts_cfg_nvm.p[RSS_CFG_RATE_PRESENCE]);
|
|
sts_presence_rss_config.default_hwaas = (float)(sts_cfg_nvm.p[RSS_CFG_HWAAS]);
|
|
|
|
sts_presence_rss_config.default_nbr_removed_pc = (float)(sts_cfg_nvm.p[RSS_CFG_NBR_REMOVED_PC]);
|
|
|
|
//filter parameter
|
|
sts_presence_rss_config.default_inter_frame_deviation_time_const = (float)(sts_cfg_nvm.p[RSS_CFG_ITE_DEVIATION]*0.1f);
|
|
sts_presence_rss_config.default_inter_frame_fast_cutoff = (float)(sts_cfg_nvm.p[RSS_CFG_ITE_FAST_CUTOFF]);
|
|
sts_presence_rss_config.default_inter_frame_slow_cutoff = (float)(sts_cfg_nvm.p[RSS_CFG_ITE_SLOW_CUTOFF]*0.01f);
|
|
sts_presence_rss_config.default_intra_frame_time_const = (float)(sts_cfg_nvm.p[RSS_CFG_ITR_TIME]);
|
|
sts_presence_rss_config.default_intra_frame_weight = (float)(sts_cfg_nvm.p[RSS_CFG_ITR_WEIGHT]*0.1f);
|
|
sts_presence_rss_config.default_output_time_const = (float)(sts_cfg_nvm.p[RSS_CFG_OUTPUT_TIME]*0.1f);
|
|
//filter parameter
|
|
|
|
sts_presence_rss_config.default_downsampling_factor = (float)(sts_cfg_nvm.p[RSS_CFG_DOWNSAMPLING_FACTOR]);
|
|
sts_presence_rss_config.default_power_save_mode = (float)(sts_cfg_nvm.p[RSS_CFG_POWER_MODE]);
|
|
|
|
sts_rss_config_updated_flag = STS_RSS_CONFIG_FULL; //set to 2 for FULL config effect in next detection
|
|
}
|
|
|
|
void STS_PRESENCE_SENSOR_NVM_CFG_SIMPLE(void)
|
|
{
|
|
sts_presence_rss_config.default_start_m = (float)(sts_cfg_nvm.p[RSS_CFG_START_M]*0.1f);
|
|
sts_presence_rss_config.default_length_m = (float)(sts_cfg_nvm.p[RSS_CFG_LENGTH_M]*0.1f);
|
|
sts_presence_rss_config.default_threshold = (float)(sts_cfg_nvm.p[RSS_CFG_THRESHOLD]*0.1f);
|
|
sts_presence_rss_config.default_receiver_gain = (float)(sts_cfg_nvm.p[RSS_CFG_RECEIVER_GAIN]*0.01f);
|
|
|
|
sts_rss_config_updated_flag = STS_RSS_CONFIG_SIMPLE; //set to 1 for simple config effect in next detection
|
|
}
|
|
|
|
void STS_PRESENCE_SENSOR_Init_Send_Data(void)
|
|
{
|
|
sts_o7_sensorData.lamp_bar_color = STS_GREEN;
|
|
sts_o7_sensorData.workmode = sts_work_mode; //STS_DUAL_MODE;
|
|
|
|
sts_o7_sensorData.state_sensor1_on_off = 0x0;
|
|
sts_o7_sensorData.state_sensor2_on_off = 0x0;
|
|
sts_o7_sensorData.state_sensor3_on_off = 0x0;
|
|
sts_o7_sensorData.state_sensor4_on_off = 0x0;
|
|
sts_o7_sensorData.rss_presence_distance = 0x0;
|
|
sts_o7_sensorData.rss_presence_score = 0x0;
|
|
sts_o7_sensorData.fall_state = STS_PRESENCE_NONE;
|
|
sts_o7_sensorData.fall_speed = 0x0;
|
|
sts_o7_sensorData.fall_gravity = 0x0;
|
|
sts_o7_sensorData.over_stay_state = 0x0;
|
|
sts_o7_sensorData.over_stay_duration = 0x0;
|
|
sts_o7_sensorData.unconscious_state = 0x0;
|
|
sts_o7_sensorData.unconscious_duration = 0x0;
|
|
|
|
sts_o7_sensorData.event_sensor1_start_time = 0x0;
|
|
sts_o7_sensorData.event_sensor1_duration = 0x0;
|
|
sts_o7_sensorData.event_sensor2_start_time = 0x0;
|
|
sts_o7_sensorData.event_sensor2_duration = 0x0;
|
|
sts_o7_sensorData.event_sensor3_motion_start_time = 0x0;
|
|
sts_o7_sensorData.event_sensor3_motion_duration = 0x0;
|
|
sts_o7_sensorData.event_sensor3_fall_start_time = 0x0;
|
|
sts_o7_sensorData.event_sensor3_fall_duration = 0x0;
|
|
sts_o7_sensorData.event_sensor4_start_time = 0x0;
|
|
sts_o7_sensorData.event_sensor4_duration = 0x0;
|
|
|
|
sts_o7_sensorData.battery_Pct = 99; // 99% as init value
|
|
sts_o7_sensorData.dutycycletimelevel = 1;
|
|
sensor_data_ready = 0;
|
|
}
|
|
|
|
void STS_PRESENCE_SENSOR_Prepare_Send_Data(STS_OO_SensorStatusDataTypeDef *sensor_data)
|
|
{
|
|
sensor_data->lamp_bar_color = sts_lamp_bar_color;
|
|
sensor_data->workmode = sts_work_mode;
|
|
sensor_data->state_sensor1_on_off = HALL1_STATE;//sts_hall1_read; //sts_hsts_reed_hall_result; // sts_hall1_read
|
|
sensor_data->state_sensor2_on_off = sts_rss_result;
|
|
sensor_data->state_sensor3_on_off = HALL2_STATE;//sts_hall2_read; //sts_emergency_button_pushed; //sts_hall2_read
|
|
sensor_data->state_sensor4_on_off = sts_rss_2nd_result;
|
|
|
|
if (sts_rss_result == STS_RESULT_MOTION)
|
|
{
|
|
sensor_data->rss_presence_distance = (uint16_t)(sts_presence_rss_distance)&0xFFFF;
|
|
sensor_data->rss_presence_score = (uint16_t)(sts_presence_rss_score)&0xFFFF;
|
|
// uint8_t sts_unconscious_state;
|
|
// uint16_t sts_unconscious_threshold, sts_unconscious_threshold_duration;
|
|
} else {
|
|
|
|
sensor_data->rss_presence_distance = 0x0;
|
|
sensor_data->rss_presence_score = 0x0;
|
|
}
|
|
sensor_data->unconscious_state=(sts_fall_rising_detected_result == STS_PRESENCE_UNCONSCIOUS)? 1:0;
|
|
sensor_data->over_stay_state = sts_o7_sensorData.over_stay_state;
|
|
sensor_data->over_stay_duration = sts_o7_sensorData.over_stay_duration;
|
|
|
|
sensor_data->fall_state = sts_fall_rising_detected_result;
|
|
if (sts_fall_rising_detected_result == STS_PRESENCE_FALL)
|
|
{
|
|
APP_LOG(TS_OFF, VLEVEL_M, "\r\n......FALL RISING DETECTION RESULT: %25s \r\n",(char*)sts_presence_fall_detection_message[sts_fall_rising_detected_result] );
|
|
sensor_data->fall_speed = (uint8_t)sts_fall_rising_pattern_factor1;
|
|
sensor_data->fall_gravity = (uint8_t)sts_roc_acc_standard_variance;
|
|
}
|
|
|
|
// For occupancy over time process
|
|
//SysTime_t occupy_check_time = SysTimeGetMcuTime();
|
|
if ((sts_occupancy_overtime_threshold_in_10min != 0) && (event_start_time !=0))
|
|
{
|
|
if (sts_occupancy_overtime_state == 1U) {
|
|
sts_status_color = STS_RED_BLUE;
|
|
sts_lamp_bar_color = STS_RED_BLUE;
|
|
}
|
|
//STS_Lamp_Bar_Refresh();
|
|
}
|
|
|
|
|
|
sensor_data_ready = 1;
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief Initializes the motion sensors
|
|
* @param Instance Motion sensor instance
|
|
* @param Functions Motion sensor functions. Could be :
|
|
* - MOTION_ACCELERO for instance
|
|
* @retval BSP status
|
|
*/
|
|
void STS_PRESENCE_SENSOR_Init(void)
|
|
{
|
|
APP_LOG(TS_ON, VLEVEL_M, "##### YunHorn SmarToilets(r) Presence Sensor Started\r\n");
|
|
|
|
sts_o7_sensorData.workmode = (uint8_t)sts_work_mode; //STS_DUAL_MODE;
|
|
sts_o7_sensorData.lamp_bar_color = (uint8_t)STS_GREEN;
|
|
sts_o7_sensorData.battery_Pct = 99;
|
|
sts_o7_sensorData.dutycycletimelevel = 1;
|
|
sts_o7_sensorData.event_sensor1_start_time = 0;
|
|
sts_o7_sensorData.event_sensor1_stop_time = 0;
|
|
sts_o7_sensorData.event_sensor1_duration = 0;
|
|
sts_o7_sensorData.event_sensor2_start_time = 0;
|
|
sts_o7_sensorData.event_sensor2_stop_time = 0;
|
|
sts_o7_sensorData.event_sensor2_duration = 0;
|
|
sts_o7_sensorData.event_sensor3_motion_start_time = 0;
|
|
sts_o7_sensorData.event_sensor3_motion_stop_time = 0;
|
|
sts_o7_sensorData.event_sensor3_motion_duration = 0;
|
|
sts_o7_sensorData.event_sensor3_fall_start_time = 0;
|
|
sts_o7_sensorData.event_sensor3_fall_stop_time = 0;
|
|
sts_o7_sensorData.event_sensor3_fall_duration = 0;
|
|
sts_o7_sensorData.event_sensor4_start_time = 0;
|
|
sts_o7_sensorData.event_sensor4_stop_time = 0;
|
|
sts_o7_sensorData.event_sensor4_duration = 0;
|
|
|
|
sts_o7_sensorData.over_stay_state = 0;
|
|
sts_o7_sensorData.over_stay_duration = 0;
|
|
sts_o7_sensorData.unconscious_duration = 0;
|
|
sts_o7_sensorData.unconscious_state = 0;
|
|
|
|
STS_SENSOR_Power_ON(0);
|
|
STS_PRESENCE_SENSOR_REEDSWITCH_HALL_Init();
|
|
//STS_PRESENCE_SENSOR_TOF_Init();
|
|
//HAL_Delay(2000);
|
|
//STS_PRESENCE_SENSOR_Distance_Measure_Process();
|
|
|
|
mems_int1_detected=0;
|
|
}
|
|
|
|
void STS_PRESENCE_SENSOR_TOF_Init(void)
|
|
{
|
|
APP_LOG(TS_ON, VLEVEL_H, "##### YunHorn SmarToilets(r) MEMS TOF Initializing \r\n");
|
|
|
|
}
|
|
void STS_PRESENCE_SENSOR_REEDSWITCH_HALL_Init(void)
|
|
{
|
|
|
|
APP_LOG(TS_ON, VLEVEL_H, "##### YunHorn SmarToilets(r) REED SWITCH HALL ELEMENT Initializing \r\n");
|
|
|
|
}
|
|
void STS_PRESENCE_SENSOR_RSS_Init(void)
|
|
{
|
|
APP_LOG(TS_ON, VLEVEL_H, "##### YunHorn SmarToilets(r) MEMS RSS Initializing \r\n");
|
|
|
|
STS_SENSOR_Power_ON(0);
|
|
|
|
if ((sts_distance_rss_distance==0)&&(sts_sensor_install_height==0))
|
|
{
|
|
uint8_t exit_status =0;
|
|
exit_status=sts_distance_rss_detector_distance();
|
|
if (exit_status ==0) {
|
|
APP_LOG(TS_ON, VLEVEL_M, "##### RSS Installation Height =%u \r\n", (uint16_t)sts_distance_rss_distance);
|
|
}
|
|
else {
|
|
APP_LOG(TS_ON, VLEVEL_M, "##### RSS Installation Height Error \r\n");
|
|
}
|
|
sts_sensor_install_height=sts_distance_rss_distance;
|
|
}
|
|
|
|
STS_PRESENCE_SENSOR_NVM_CFG();
|
|
|
|
sts_rss_config_updated_flag = STS_RSS_CONFIG_DEFAULT;
|
|
|
|
mems_int1_detected=0;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef STS_M7
|
|
void STS_PRESENCE_SENSOR_Get_Event_Status(STS_PRESENCE_SENSOR_Event_Status_t *Status)
|
|
{
|
|
uint8_t int_source=0;
|
|
SysTime_t mems_event_time;
|
|
//int_source = ADXL345_GetRegisterValue(ADXL345_REG_INT_SOURCE);
|
|
|
|
if (int_source & 0x10) {
|
|
mems_event_time = SysTimeGetMcuTime();
|
|
Status->WakeUpStatus = 1U;
|
|
event_start_time = mems_event_time.Seconds;
|
|
}
|
|
else {
|
|
Status->WakeUpStatus =0U;
|
|
}
|
|
|
|
if (int_source & 0x08) {
|
|
mems_event_time = SysTimeGetMcuTime();
|
|
Status->SleepStatus = 1U;
|
|
event_stop_time = mems_event_time.Seconds;
|
|
}
|
|
else {
|
|
Status->SleepStatus = 0U;
|
|
|
|
}
|
|
|
|
|
|
}
|
|
#endif
|
|
|
|
void STS_PRESENCE_SENSOR_Distance_Measure_Process(void)
|
|
{
|
|
uint8_t exit_status = EXIT_SUCCESS, i=0;
|
|
|
|
APP_LOG(TS_OFF, VLEVEL_L, "\r\n ****start_m=%u length_m=%u profile=%u hwaas=%u \r\n",
|
|
(unsigned int)(distance_cfg.start_m*1000),(unsigned int)(distance_cfg.length_m*1000),
|
|
(unsigned int)(distance_cfg.acc_profile),(unsigned int)(distance_cfg.hwaas));
|
|
do
|
|
{
|
|
exit_status = sts_distance_rss_detector_distance();
|
|
HAL_Delay(100);
|
|
i++;
|
|
} while ((exit_status == EXIT_FAILURE) && (i < 2));
|
|
|
|
}
|
|
|
|
|
|
|
|
void STS_PRESENCE_SENSOR_Function_Test_Process(uint8_t *self_test_result, uint8_t count)
|
|
{
|
|
uint8_t bring_up_result[20];
|
|
STS_SENSOR_Power_ON(0);
|
|
HAL_Init();
|
|
MX_GPIO_Init();
|
|
HAL_Delay(150); //wait for sensor ready
|
|
|
|
for (uint8_t i=0;i < count; i++) //while(1)
|
|
{
|
|
STS_Lamp_Bar_Self_Test_Simple();
|
|
sts_lamp_bar_color = STS_PINK;
|
|
STS_Lamp_Bar_Refresh();
|
|
HAL_Delay(1000);
|
|
sts_presence_rss_bring_up_test(bring_up_result);
|
|
|
|
HAL_Delay(1000);
|
|
|
|
STS_PRESENCE_SENSOR_Distance_Measure_Process();
|
|
|
|
}
|
|
HAL_Delay(1000);
|
|
|
|
memcpy(self_test_result, bring_up_result, 10);
|
|
mems_int1_detected=0;
|
|
}
|
|
|
|
uint8_t STS_SENSOR_MEMS_Get_ID(uint8_t *devID)
|
|
{
|
|
uint8_t scanned_id[2] = {0x0,0x0};
|
|
|
|
#if defined(STS_O7)||defined(STS_O6)
|
|
if (hal_test_spi_read_chipid(scanned_id))
|
|
{
|
|
devID[0] = scanned_id[0];
|
|
devID[1] = scanned_id[1];
|
|
APP_LOG(TS_OFF, VLEVEL_H,"\r\n--------------devID = %02x %02x \r\n",devID[0], devID[1]);
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
#endif
|
|
|
|
}
|
|
|
|
void STS_SENSOR_Power_ON(uint8_t cnt)
|
|
{
|
|
switch (cnt) {
|
|
case 0:
|
|
case 1:
|
|
case 2:
|
|
PME_ON;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
}
|
|
void STS_SENSOR_Power_OFF(uint8_t cnt)
|
|
{
|
|
switch (cnt) {
|
|
case 0:
|
|
case 1:
|
|
case 2:
|
|
PME_OFF;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void STS_SENSOR_MEMS_Reset(uint8_t cnt)
|
|
{
|
|
switch (cnt) {
|
|
case 0:
|
|
case 1:
|
|
case 2:
|
|
HAL_GPIO_TogglePin(MEMS_POWER_GPIO_Port, MEMS_POWER_Pin);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
#ifdef STS_R4
|
|
void YUNHORN_STS_R4_SENSOR_Read(STS_R0_SensorDataTypeDef *r4_data)
|
|
{
|
|
#ifdef SOAP_LEVEL_SENSOR
|
|
r4_data->on_off_event = (sts_soap_level_state==0x0)? 1:0;
|
|
r4_data->measure_tech = 0x0; // capacity measure
|
|
#endif
|
|
|
|
sensor_data_ready = 0x1;
|
|
}
|
|
|
|
void YUNHORN_STS_R4_SENSOR_Init(void)
|
|
{
|
|
r4_data.on_off_event = 0x0;
|
|
r4_data.measure_tech = 0x0;
|
|
sensor_data_ready = 0x0;
|
|
}
|
|
#endif
|
|
|
|
#if defined(YUNHORN_STS_R4_ENABLED)
|
|
void STS_R0_SENSOR_Read(STS_R0_SensorDataTypeDef *r0_data)
|
|
{
|
|
#ifdef SOAP_LEVEL_SENSOR
|
|
r0_data->on_off_event = sts_soap_level_state;
|
|
r0_data->measure_tech = 0; /* 0: capacit, 1:dTof, 2: ultrasonic */
|
|
#elif defined(TOF_1)||defined(TOF_2)||defined(TOF_3)
|
|
r0_data->measure_tech = 1; /* 0: capacit, 1:dTof, 2: ultrasonic */
|
|
r0_data->distance_mm = sts_tof_distance_data[0];
|
|
r0_data->distance1_mm = sts_tof_distance_data[1];
|
|
r0_data->distance2_mm = sts_tof_distance_data[2];
|
|
#elif defined(ROCTEC_R5)
|
|
r0_data->distance1_mm = sts_tof_distance_data[0]+sts_tof_distance_data[1]+sts_tof_distance_data[2];
|
|
#endif
|
|
|
|
sensor_data_ready = 1;
|
|
}
|
|
#endif
|
|
|
|
void STS_SENSOR_NVM_CFG(void)
|
|
{
|
|
|
|
}
|
|
|
|
void STS_SENSOR_NVM_CFG_SIMPLE(void)
|
|
{
|
|
|
|
}
|
|
|
|
#if defined(YUNHORN_STS_O5_ENABLED)
|
|
void STS_O5_SENSOR_Read(STS_OO_SensorDataTypeDef *oo_data)
|
|
{
|
|
|
|
oo_data->state_sensor1_on_off = sts_reed_hall_result;
|
|
|
|
|
|
sensor_data_ready = 1;
|
|
}
|
|
#endif
|
|
|
|
|
|
/* reedswitch 1 on off */
|
|
void OnSensor1StateChanged(void)
|
|
{
|
|
SysTime_t sensor_event_time = SysTimeGetMcuTime();
|
|
if (sts_hall1_read==STS_Status_Door_Close)
|
|
{
|
|
sts_o7_sensorData.event_sensor1_start_time = sensor_event_time.Seconds;
|
|
sts_o7_sensorData.event_sensor1_duration = 0;
|
|
} else if (sts_hall1_read==STS_Status_Door_Open)
|
|
{
|
|
sts_o7_sensorData.event_sensor1_stop_time = sensor_event_time.Seconds;
|
|
//sts_o7_sensorData.event_sensor1_duration = 0;
|
|
}
|
|
|
|
}
|
|
|
|
/* SOS emergency button on off */
|
|
void OnSensor2StateChanged(void)
|
|
{
|
|
SysTime_t sensor_event_time = SysTimeGetMcuTime();
|
|
if (sts_hall2_read==STS_Status_SOS_Pushdown)
|
|
{
|
|
sts_o7_sensorData.event_sensor2_start_time = sensor_event_time.Seconds;
|
|
sts_o7_sensorData.event_sensor2_duration = 0;
|
|
}else if (sts_hall2_read==STS_Status_SOS_Release)
|
|
{
|
|
sts_o7_sensorData.event_sensor2_stop_time = sensor_event_time.Seconds;
|
|
//sts_o7_sensorData.event_sensor2_duration = 0;
|
|
}
|
|
}
|
|
|
|
/* motion sensor RSS ON-OFF */
|
|
void OnSensor3StateChanged(void)
|
|
{
|
|
SysTime_t sensor_event_time = SysTimeGetMcuTime();
|
|
#if 0
|
|
if ((sensor_event_time.Seconds - last_sts_rss_time_stamp) < 3 ) //less than 3 seconds ... return for flipping filter
|
|
{
|
|
return ;
|
|
}
|
|
#endif
|
|
if (sts_rss_result == STS_RESULT_MOTION)
|
|
{
|
|
sts_o7_sensorData.event_sensor3_motion_start_time = sensor_event_time.Seconds;
|
|
sts_o7_sensorData.event_sensor3_motion_duration = 0;
|
|
} else if (sts_rss_result == STS_RESULT_NO_MOTION)
|
|
{
|
|
sts_o7_sensorData.event_sensor3_motion_stop_time = sensor_event_time.Seconds;
|
|
//sts_o7_sensorData.event_sensor3_motion_duration = 0;
|
|
}
|
|
|
|
|
|
last_sts_rss_time_stamp = sensor_event_time.Seconds;
|
|
|
|
}
|
|
|
|
/* motion sensor A: Motion/No-Motion Detection, Unconscious Detection */
|
|
void OnSensor3AStateChanged(void)
|
|
{
|
|
SysTime_t sensor_event_time = SysTimeGetMcuTime();
|
|
#if 0
|
|
if ((sensor_event_time.Seconds - last_sts_rss_time_stamp) < 3 ) //less than 3 seconds ... return for flipping filter
|
|
{
|
|
return ;
|
|
}
|
|
#endif
|
|
if (sts_rss_result == STS_RESULT_MOTION)
|
|
{
|
|
sts_o7_sensorData.event_sensor3_motion_start_time = sensor_event_time.Seconds;
|
|
sts_o7_sensorData.event_sensor3_motion_duration = 0;
|
|
} else if (sts_rss_result == STS_RESULT_NO_MOTION)
|
|
{
|
|
sts_o7_sensorData.event_sensor3_motion_stop_time = sensor_event_time.Seconds;
|
|
//sts_o7_sensorData.event_sensor3_motion_duration = 0;
|
|
}
|
|
|
|
|
|
last_sts_rss_time_stamp = sensor_event_time.Seconds;
|
|
|
|
}
|
|
|
|
/* motion sensor B, Fall Detection suggestionF */
|
|
void OnSensor3BStateChanged(void)
|
|
{
|
|
SysTime_t sensor_event_time = SysTimeGetMcuTime();
|
|
#if 0
|
|
if ((sensor_event_time.Seconds - last_sts_rss_time_stamp) < 3 ) //less than 3 seconds ... return for flipping filter
|
|
{
|
|
return ;
|
|
}
|
|
#endif
|
|
switch (sts_fall_rising_detected_result)
|
|
{
|
|
case STS_PRESENCE_NONE:
|
|
sts_o7_sensorData.event_sensor3_motion_stop_time = sensor_event_time.Seconds;
|
|
break;
|
|
|
|
case STS_PRESENCE_FALL:
|
|
if (motion_in_hs_zone[0][motion_detected_count])
|
|
sts_o7_sensorData.event_sensor3_fall_start_time = sensor_event_time.Seconds;
|
|
sts_o7_sensorData.event_sensor3_fall_duration = 0;
|
|
break;
|
|
|
|
case STS_PRESENCE_RISING:
|
|
|
|
break;
|
|
|
|
case STS_PRESENCE_LAYDOWN:
|
|
case STS_PRESENCE_UNCONSCIOUS:
|
|
sts_o7_sensorData.fall_laydown_duration = 0;
|
|
break;
|
|
case STS_PRESENCE_STAYSTILL:
|
|
|
|
break;
|
|
default:
|
|
break;
|
|
|
|
}
|
|
|
|
last_sts_rss_time_stamp = sensor_event_time.Seconds;
|
|
|
|
|
|
}
|
|
|
|
/* motion sensor C: Over stay detection */
|
|
void OnSensor3CStateChanged(void)
|
|
{
|
|
SysTime_t sensor_event_time = SysTimeGetMcuTime();
|
|
#if 0
|
|
if ((sensor_event_time.Seconds - last_sts_rss_time_stamp) < 3 ) //less than 3 seconds ... return for flipping filter
|
|
{
|
|
return ;
|
|
}
|
|
#endif
|
|
if (sts_rss_result == STS_RESULT_MOTION)
|
|
{
|
|
sts_o7_sensorData.event_sensor3_motion_start_time = sensor_event_time.Seconds;
|
|
sts_o7_sensorData.event_sensor3_motion_duration = 0;
|
|
} else if (sts_rss_result == STS_RESULT_NO_MOTION)
|
|
{
|
|
sts_o7_sensorData.event_sensor3_motion_stop_time = sensor_event_time.Seconds;
|
|
//sts_o7_sensorData.event_sensor3_motion_duration = 0;
|
|
}
|
|
|
|
|
|
last_sts_rss_time_stamp = sensor_event_time.Seconds;
|
|
|
|
}
|
|
|
|
|
|
void OnSensor4StateChanged(void)
|
|
{
|
|
#if 0
|
|
SysTime_t sensor_event_time = SysTimeGetMcuTime();
|
|
// reserved... to be finalized 2024-06-03
|
|
|
|
if (sts_xxx_result)
|
|
sts_o7_sensorData.event_sensor4_start_time = sensor_event_time.Seconds;
|
|
else
|
|
sts_o7_sensorData.event_sensor4_stop_time = sensor_event_time.Seconds;
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
/* USER CODE BEGIN EF */
|
|
|
|
/* USER CODE END EF */
|
|
|
|
/* Private Functions Definition -----------------------------------------------*/
|
|
/* USER CODE BEGIN PrFD */
|
|
|
|
/* USER CODE END PrFD */
|