/* USER CODE BEGIN Header */ /** ****************************************************************************** * @file lora_app.c * @author MCD Application Team * @brief Application of the LRWAN Middleware ****************************************************************************** * @attention * * Copyright (c) 2021 STMicroelectronics. * 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 "platform.h" #include "sys_app.h" #include "lora_app.h" #include "stm32_seq.h" #include "stm32_timer.h" #include "utilities_def.h" #include "app_version.h" #include "lorawan_version.h" #include "subghz_phy_version.h" #include "lora_info.h" #include "LmHandler.h" #include "adc_if.h" #include "CayenneLpp.h" #include "sys_sensors.h" #include "flash_if.h" #ifdef CLOCK_SYNC #include "LmhpClockSync.h" #endif /* USER CODE BEGIN Includes */ #include "app_tof_pin_conf.h" #include "app_tof_peoplecount.h" #include "yunhorn_sts_prd_conf.h" #include "yunhorn_sts_sensors.h" #if defined(STS_O6)||defined(STS_T6)||defined(O1L) #include "sts_lamp_bar.h" #endif /* USER CODE END Includes */ /* External variables ---------------------------------------------------------*/ /* USER CODE BEGIN EV */ uint8_t outbuf[128]={0x0}; extern volatile uint8_t sts_ac_code[20], sts_service_mask; extern volatile uint8_t sts_work_mode, sts_cloud_netcolor, sts_lamp_bar_color, sts_status_color, luminance_level; volatile static bool r_b=true; volatile uint8_t heart_beat_timer =0; extern volatile uint8_t sensor_data_ready; extern uint8_t sts_door_jam_profile; extern uint8_t sts_color_occupy_vacant; extern volatile uint16_t sts_sensor_install_height; #ifdef STS_T6 volatile uint8_t PIRValue =0, prev_sts_pir_state=0, sts_pir_state_changed=0; extern volatile uint8_t sts_tof_presence_state; uint32_t lowIn=0; volatile bool lockLow = true, takeLowTime; #endif static uint32_t sts_warm_up_count = 0; extern volatile sts_cfg_nvm_t sts_cfg_nvm; extern volatile uint32_t rfac_timer; extern volatile uint32_t STS_TOFScanPeriod_msec, STS_TxPeriod_sec, STS_HeartBeatTimerPeriod_sec; extern volatile uint8_t sts_pir_state; volatile uint8_t sts_data_buf[LORAWAN_APP_DATA_BUFFER_MAX_SIZE]={0x0}; //volatile LmHandlerAppData_t sts_app_data={ 0, 0, sts_data_buf }; #ifdef STS_M1 extern volatile uint8_t sts_water_leakage_state; #endif static void STS_Show_STS_CFG_NVM(uint8_t * store_value, uint16_t store_size); static uint8_t nvm_stored_value[2*YUNHORN_STS_MAX_NVM_CFG_SIZE]={0x0}; static uint8_t sts_cfg_nvm_factory_default[YUNHORN_STS_MAX_NVM_CFG_SIZE]; volatile sts_cfg_nvm_t sts_cfg_nvm = { sts_mtmcode1, sts_mtmcode2, sts_version, sts_hardware_ver, 0x0A, //Regular TxPeriodicity interval 'S', //Uplink data interval unit, for heart-beat uplink #if defined(STS_P2)||defined(L8)||defined(STS_O6T)||defined(STS_T6) 0x1E, //Heart-beat interval or Sampling interval 'M', //Sampling sensor interval unit, for real-time sensing of MEMS #else 0x3C, //Heart-beat interval , for heart-beat uplink 'M', //Heart-beat interval unit #endif 0x04, // dual mode=4, uni_mode =5 0x00, // sts service mask 0x00, //sts_ioc_mask 0x20, //32 bytes, below start of p[0] 20 BYTES AND 12 BYTES FALL DOWN CFG { // below 20 bytes #ifdef STS_P2 0x0,0x8,0x10,0x0,0x3,0x8,0x21,0x1,0xaf,0xe7, //current work config profile short 0x1,0x8,0x10,0x0,0x3,0x8,0x21,0x1,0xaf,0xe7, //current work config profile long, after measured distance // change the max distance, min distance, SPAD, front center and back center, etc. #else 0x08, //start_m [8]*0.1 meter =0.8 0x19, //lenght_m 0x19=[25]*0.1=2.5f meter 0x0F, //threshold 0X0F=[15]*0.1=1.5f 0x28, //receiver gain 0x28 =[40]*0.01=0.40f max 99=0x63 0x04, //profile [4]=4 0x0A, //rate tracking 0x0A=10= 10U 0x41, //rate presence 0x41=65= 65U 0x3F, //hwaas 0x3F=63 =63U 0x00, //nbr removed pc [0]=0 0x05, //inter frame deviation time const 0x05=[5]*0.1=0.5f 0x0A, //inter frame fast cutoff 0x0A=[10] = 10U 0x01, //inter frame slow cutoff,0x01=1[1]*0.01=0.01f 0x00, //intra frame time const [0]=0 Lower to reduce sensitivity, higher to increase sensitivity 0x0A, //intra frame weight, 0x00=[0]*0.1=0.0F 0x0A=10, 10*0.1=1 FOR FAST MOVEMENT TRACKING FALL DETECTION 0x05, //output time const 0x05=[5]*0.1=0.5 0x02, //downsampling factor [2]=2 0x03, //power saving mode ACTIVE [3] = 3U 0x00, //reserve --P[17] 0x00, //reserve --P[18] 0x00, //reserve --P[19] #endif }, // above 20 bytes 0x21, // color occupy (red:2) | color vacant (green:1) or other 0x20 occupy(red:2) | color vacant (dark:0) for ATAL-HK 20241230 0x06, // sts_door_jam_profile for O6T 0x20, // sensor install height in dm =10 cm, default 32*10=320cm, 3.2meter 0x00, //reserve5 alarm_parameter05 0x06, //reserve6 alarm_mute_or_reset_expire_timer_in_10sec, 60 seconds 0x23, //reserve7 alarm Lamp Bar Flashing color define, 0x20, 2==STS_RED, 0 = STS_DARK, 0x23, 2=STS_RED, 3=STS_BLUE 0x03, //reserve8 occupancy over time threshold 3*10 = 30 minutes 0x09, //reserve8 motionless_duration_threshold_in_min+1, normal: 10 min(0x0A) Minutes (2 min.) 1-9== 2-10min 0x09, //unconscious threshold * 128, 0-9, 9*128=1280 motion level 0x01, //fall_detection_acc_threshold = *10 acceleration measure 0x03, //fall detection_depth_threshold *10cm 0x03, //falldown_confirm_threshold_in_10sec, 0x3=30 sec default // below 20 bytes for RFAC code {0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0} }; /* USER CODE END EV */ /* Private typedef -----------------------------------------------------------*/ /** * @brief LoRa State Machine states */ typedef enum TxEventType_e { /** * @brief Appdata Transmission issue based on timer every TxDutyCycleTime */ TX_ON_TIMER, /** * @brief Appdata Transmission external event plugged on OnSendEvent( ) */ TX_ON_EVENT /* USER CODE BEGIN TxEventType_t */ /* USER CODE END TxEventType_t */ } TxEventType_t; /* USER CODE BEGIN PTD */ /* USER CODE END PTD */ /* Private define ------------------------------------------------------------*/ /** * LEDs period value of the timer in ms */ #define LED_PERIOD_TIME 500 /** * Join switch period value of the timer in ms */ #define JOIN_TIME 2000 /*---------------------------------------------------------------------------*/ /* LoRaWAN NVM configuration */ /*---------------------------------------------------------------------------*/ /** * @brief LoRaWAN NVM Flash address * @note last 2 sector of a 128kBytes device */ #define LORAWAN_NVM_BASE_ADDRESS ((void *)0x0803F000UL) /* USER CODE BEGIN PD */ static const char *slotStrings[] = { "1", "2", "C", "C_MC", "P", "P_MC" }; /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private function prototypes -----------------------------------------------*/ /** * @brief LoRa End Node send request */ static void SendTxData(void); /** * @brief TX timer callback function * @param context ptr of timer context */ static void OnTxTimerEvent(void *context); /** * @brief join event callback function * @param joinParams status of join */ static void OnJoinRequest(LmHandlerJoinParams_t *joinParams); /** * @brief callback when LoRaWAN application has sent a frame * @brief tx event callback function * @param params status of last Tx */ static void OnTxData(LmHandlerTxParams_t *params); /** * @brief callback when LoRaWAN application has received a frame * @param appData data received in the last Rx * @param params status of last Rx */ static void OnRxData(LmHandlerAppData_t *appData, LmHandlerRxParams_t *params); /** * @brief callback when LoRaWAN Beacon status is updated * @param params status of Last Beacon */ static void OnBeaconStatusChange(LmHandlerBeaconParams_t *params); /** * @brief callback when system time has been updated */ static void OnSysTimeUpdate(void); /** * @brief callback when LoRaWAN application Class is changed * @param deviceClass new class */ static void OnClassChange(DeviceClass_t deviceClass); /** * @brief LoRa store context in Non Volatile Memory */ static void StoreContext(void); /** * @brief stop current LoRa execution to switch into non default Activation mode */ static void StopJoin(void); /** * @brief Join switch timer callback function * @param context ptr of Join switch context */ static void OnStopJoinTimerEvent(void *context); /** * @brief Notifies the upper layer that the NVM context has changed * @param state Indicates if we are storing (true) or restoring (false) the NVM context */ static void OnNvmDataChange(LmHandlerNvmContextStates_t state); /** * @brief Store the NVM Data context to the Flash * @param nvm ptr on nvm structure * @param nvm_size number of data bytes which were stored */ static void OnStoreContextRequest(void *nvm, uint32_t nvm_size); /** * @brief Restore the NVM Data context from the Flash * @param nvm ptr on nvm structure * @param nvm_size number of data bytes which were restored */ static void OnRestoreContextRequest(void *nvm, uint32_t nvm_size); /** * Will be called each time a Radio IRQ is handled by the MAC layer * */ static void OnMacProcessNotify(void); /** * @brief Change the periodicity of the uplink frames * @param periodicity uplink frames period in ms * @note Compliance test protocol callbacks */ static void OnTxPeriodicityChanged(uint32_t periodicity); /** * @brief Change the confirmation control of the uplink frames * @param isTxConfirmed Indicates if the uplink requires an acknowledgement * @note Compliance test protocol callbacks */ static void OnTxFrameCtrlChanged(LmHandlerMsgTypes_t isTxConfirmed); /** * @brief Change the periodicity of the ping slot frames * @param pingSlotPeriodicity ping slot frames period in ms * @note Compliance test protocol callbacks */ static void OnPingSlotPeriodicityChanged(uint8_t pingSlotPeriodicity); /** * @brief Will be called to reset the system * @note Compliance test protocol callbacks */ static void OnSystemReset(void); /* USER CODE BEGIN PFP */ /** * @brief LED Tx timer callback function * @param context ptr of LED context */ static void OnTxTimerLedEvent(void *context); /** * @brief LED Rx timer callback function * @param context ptr of LED context */ static void OnRxTimerLedEvent(void *context); /** * @brief LED Join timer callback function * @param context ptr of LED context */ static void OnJoinTimerLedEvent(void *context); /** * @brief STS Wake Up Scan timer callback function * @param context ptr of VL53LX TOF People Counting Process context */ static void OnYunhornSTSWakeUpScanTimerEvent(void *context); /** * @brief STS Lamp Bar timer callback function * @param context ptr of Lamp Bar LED context */ static void OnYunhornSTSLampBarColorTimerEvent(void *context); /** * @brief SYS occupancy, door lock, motion duration check timer callback function * @param context ptr of duration check context */ static void OnYunhornSTSDurationCheckTimerEvent(void *context); /** * @brief Yunhorn STS Occupancy RSS WakeUP timer callback function * @param context ptr of STS RSS WakeUp context */ //static void OnYunhornSTSOORSSWakeUpTimerEvent(void *context); /** * @brief Yunhorn STS Heart beat timer callback function * @param context ptr of context */ static void OnYunhornSTSHeartBeatTimerEvent(void *context); /** * @brief Yunhorn STS Heart Beat Periodicity Chagne function * @param duration of periodicty in ms (1/1000 sec) */ //static void OnYunhornSTSHeartBeatPeriodicityChanged(uint32_t periodicity); /* USER CODE END PFP */ /* Private variables ---------------------------------------------------------*/ /** * @brief LoRaWAN default activation type */ static ActivationType_t ActivationType = LORAWAN_DEFAULT_ACTIVATION_TYPE; /** * @brief LoRaWAN force rejoin even if the NVM context is restored */ static bool ForceRejoin = LORAWAN_FORCE_REJOIN_AT_BOOT; /** * @brief LoRaWAN handler Callbacks */ static LmHandlerCallbacks_t LmHandlerCallbacks = { .GetBatteryLevel = GetBatteryLevel, .GetTemperature = GetTemperatureLevel, .GetUniqueId = GetUniqueId, .GetDevAddr = GetDevAddr, .OnRestoreContextRequest = OnRestoreContextRequest, .OnStoreContextRequest = OnStoreContextRequest, .OnMacProcess = OnMacProcessNotify, .OnNvmDataChange = OnNvmDataChange, .OnJoinRequest = OnJoinRequest, .OnTxData = OnTxData, .OnRxData = OnRxData, .OnBeaconStatusChange = OnBeaconStatusChange, .OnSysTimeUpdate = OnSysTimeUpdate, .OnClassChange = OnClassChange, .OnTxPeriodicityChanged = OnTxPeriodicityChanged, .OnTxFrameCtrlChanged = OnTxFrameCtrlChanged, .OnPingSlotPeriodicityChanged = OnPingSlotPeriodicityChanged, .OnSystemReset = OnSystemReset, }; /** * @brief LoRaWAN handler parameters */ static LmHandlerParams_t LmHandlerParams = { .ActiveRegion = ACTIVE_REGION, .DefaultClass = LORAWAN_DEFAULT_CLASS, .AdrEnable = LORAWAN_ADR_STATE, .IsTxConfirmed = LORAWAN_DEFAULT_CONFIRMED_MSG_STATE, .TxDatarate = LORAWAN_DEFAULT_DATA_RATE, .TxPower = LORAWAN_DEFAULT_TX_POWER, .PingSlotPeriodicity = LORAWAN_DEFAULT_PING_SLOT_PERIODICITY, .RxBCTimeout = LORAWAN_DEFAULT_CLASS_B_C_RESP_TIMEOUT }; /** * @brief Type of Event to generate application Tx */ static TxEventType_t EventType = TX_ON_TIMER; /** * @brief Timer to handle the application Tx */ static UTIL_TIMER_Object_t TxTimer; /** * @brief Timer to handle the application ToF Ranging Scan */ static UTIL_TIMER_Object_t YunhornSTSWakeUpScanTimer; /** * @brief Timer to handle the application Heart beat timer */ static UTIL_TIMER_Object_t YunhornSTSHeartBeatTimer; /** * @brief Timer to handle the application Lamp Bar LED Timer refresh */ static UTIL_TIMER_Object_t STSLampBarColorTimer; /** * @brief Timer to handle the application Duration check Timer */ static UTIL_TIMER_Object_t STSDurationCheckTimer; /** * @brief Tx Timer period */ //static UTIL_TIMER_Time_t TxPeriodicity = APP_TX_DUTYCYCLE; UTIL_TIMER_Time_t TxPeriodicity = APP_TX_DUTYCYCLE; /** * @brief Join Timer period */ static UTIL_TIMER_Object_t StopJoinTimer; /* USER CODE BEGIN PV */ /** * @brief User application buffer */ static uint8_t AppDataBuffer[LORAWAN_APP_DATA_BUFFER_MAX_SIZE]; /** * @brief User application data structure */ static LmHandlerAppData_t AppData = { 0, 0, AppDataBuffer }; /** * @brief Specifies the state of the application LED */ static uint8_t AppLedStateOn = RESET; /** * @brief Timer to handle the application Tx Led to toggle */ static UTIL_TIMER_Object_t TxLedTimer; /** * @brief Timer to handle the application Rx Led to toggle */ static UTIL_TIMER_Object_t RxLedTimer; /** * @brief Timer to handle the application Join Led to toggle */ static UTIL_TIMER_Object_t JoinLedTimer; static volatile bool IsClockSynched = false; /* USER CODE END PV */ /* Exported functions ---------------------------------------------------------*/ /* USER CODE BEGIN EF */ extern volatile uint8_t ToF_EventDetected; SysTime_t sts_pir_start_time, sts_pir_duration_check_time; /* USER CODE END EF */ void LoRaWAN_Init(void) { /* USER CODE BEGIN LoRaWAN_Init_LV */ uint32_t feature_version = 0UL; /* USER CODE END LoRaWAN_Init_LV */ APP_LOG(TS_OFF, VLEVEL_M, "\n\n# YUNHORN SMARTOILETS: (%s) MTM:%d.%d HWFW:%d.%d V:%d.%d.%d #\n\n",(char*)YUNHORN_STS_PRD_STRING, (uint8_t)sts_mtmcode1, (uint8_t)sts_mtmcode2,(uint8_t)sts_hardware_ver,(uint8_t)FirmwareVersion, (uint8_t)MajorVer,(uint8_t)MinorVer,(uint8_t)SubMinorVer); /* USER CODE BEGIN LoRaWAN_Init_1 */ /* Get LoRaWAN APP version*/ APP_LOG(TS_OFF, VLEVEL_M, "APPLICATION_VERSION: V%X.%X.%X\r\n", (uint8_t)(APP_VERSION_MAIN), (uint8_t)(APP_VERSION_SUB1), (uint8_t)(APP_VERSION_SUB2)); /* Get MW LoRaWAN info */ APP_LOG(TS_OFF, VLEVEL_M, "MW_LORAWAN_VERSION: V%X.%X.%X\r\n", (uint8_t)(LORAWAN_VERSION_MAIN), (uint8_t)(LORAWAN_VERSION_SUB1), (uint8_t)(LORAWAN_VERSION_SUB2)); /* Get MW SubGhz_Phy info */ APP_LOG(TS_OFF, VLEVEL_M, "MW_RADIO_VERSION: V%X.%X.%X\r\n", (uint8_t)(SUBGHZ_PHY_VERSION_MAIN), (uint8_t)(SUBGHZ_PHY_VERSION_SUB1), (uint8_t)(SUBGHZ_PHY_VERSION_SUB2)); /* Get LoRaWAN Link Layer info */ LmHandlerGetVersion(LORAMAC_HANDLER_L2_VERSION, &feature_version); APP_LOG(TS_OFF, VLEVEL_M, "L2_SPEC_VERSION: V%X.%X.%X\r\n", (uint8_t)(feature_version >> 24), (uint8_t)(feature_version >> 16), (uint8_t)(feature_version >> 8)); /* Get LoRaWAN Regional Parameters info */ LmHandlerGetVersion(LORAMAC_HANDLER_REGION_VERSION, &feature_version); APP_LOG(TS_OFF, VLEVEL_M, "RP_SPEC_VERSION: V%X-%X.%X.%X\r\n", (uint8_t)(feature_version >> 24), (uint8_t)(feature_version >> 16), (uint8_t)(feature_version >> 8), (uint8_t)(feature_version)); UTIL_TIMER_Create(&TxLedTimer, LED_PERIOD_TIME, UTIL_TIMER_ONESHOT, OnTxTimerLedEvent, NULL); UTIL_TIMER_Create(&RxLedTimer, LED_PERIOD_TIME, UTIL_TIMER_ONESHOT, OnRxTimerLedEvent, NULL); UTIL_TIMER_Create(&JoinLedTimer, LED_PERIOD_TIME, UTIL_TIMER_PERIODIC, OnJoinTimerLedEvent, NULL); UTIL_TIMER_Create(&STSLampBarColorTimer, 2*LED_PERIOD_TIME, UTIL_TIMER_ONESHOT, OnYunhornSTSLampBarColorTimerEvent, NULL); //UTIL_TIMER_Create(&STSDurationCheckTimer, 20*LED_PERIOD_TIME, UTIL_TIMER_ONESHOT, OnYunhornSTSDurationCheckTimerEvent, NULL); if (FLASH_IF_Init(NULL) != FLASH_IF_OK) { Error_Handler(); } /* USER CODE END LoRaWAN_Init_1 */ UTIL_TIMER_Create(&StopJoinTimer, JOIN_TIME, UTIL_TIMER_ONESHOT, OnStopJoinTimerEvent, NULL); UTIL_SEQ_RegTask((1 << CFG_SEQ_Task_LmHandlerProcess), UTIL_SEQ_RFU, LmHandlerProcess); UTIL_SEQ_RegTask((1 << CFG_SEQ_Task_LoRaSendOnTxTimerOrButtonEvent), UTIL_SEQ_RFU, SendTxData); UTIL_SEQ_RegTask((1 << CFG_SEQ_Task_LoRaStoreContextEvent), UTIL_SEQ_RFU, StoreContext); UTIL_SEQ_RegTask((1 << CFG_SEQ_Task_LoRaStopJoinEvent), UTIL_SEQ_RFU, StopJoin); #ifdef CLOCK_SYNC LmHandlerPackageRegister( PACKAGE_ID_CLOCK_SYNC, NULL ); IsClockSynched = false; #endif /* Init Info table used by LmHandler*/ LoraInfo_Init(); /* Init the Lora Stack*/ LmHandlerInit(&LmHandlerCallbacks, APP_VERSION); LmHandlerConfigure(&LmHandlerParams); /* USER CODE BEGIN LoRaWAN_Init_2 */ UTIL_TIMER_Start(&JoinLedTimer); /* USER CODE END LoRaWAN_Init_2 */ LmHandlerJoin(ActivationType, ForceRejoin); if (EventType == TX_ON_TIMER) { /* send every time timer elapses */ UTIL_TIMER_Create(&TxTimer, TxPeriodicity, UTIL_TIMER_ONESHOT, OnTxTimerEvent, NULL); UTIL_TIMER_Start(&TxTimer); } else { /* USER CODE BEGIN LoRaWAN_Init_3 */ /* USER CODE END LoRaWAN_Init_3 */ } /* USER CODE BEGIN LoRaWAN_Init_Last */ #if 0 STS_REBOOT_CONFIG_Init(); UTIL_SEQ_RegTask((1 << CFG_SEQ_Task_YunhornSTSEventRFAC), UTIL_SEQ_RFU, STS_YunhornSTSEventRFAC_Process); #if defined(STS_M1)||defined(STS_O5) UTIL_SEQ_RegTask((1 << CFG_SEQ_Task_YunhornSTSEventP1), UTIL_SEQ_RFU, STS_YunhornSTSEventP1_Process); #endif #if defined(STS_T6)||defined(STS_O6) UTIL_SEQ_RegTask((1 << CFG_SEQ_Task_YunhornSTSEventP3), UTIL_SEQ_RFU, STS_YunhornSTSEventP3_Process); #endif #if defined(STS_P2)||defined(STS_T6)||defined(L8) UTIL_SEQ_RegTask((1 << CFG_SEQ_Task_YunhornSTSEventP5), UTIL_SEQ_RFU, STS_YunhornSTSEventP5_Process); #endif #ifdef STS_R4 UTIL_SEQ_RegTask((1 << CFG_SEQ_Task_YunhornSTSEventP6), UTIL_SEQ_RFU, STS_YunhornSTSEventP6_Process); #endif #ifdef VL53L0 UTIL_SEQ_RegTask((1 << CFG_SEQ_Task_YunhornSTSEventP4), UTIL_SEQ_RFU, STS_YunhornSTSEventP4_Process); #endif #if defined(STS_T6)||defined(L8) UTIL_TIMER_Create(&YunhornSTSWakeUpScanTimer, STS_TOFScanPeriod_msec, UTIL_TIMER_PERIODIC, (void*)OnYunhornSTSWakeUpScanTimerEvent, NULL); //UTIL_TIMER_Create(&YunhornSTSWakeUpScanTimer, STS_TOFScanPeriod_msec, UTIL_TIMER_PERIODIC, (void*)STS_TOF_VL53LX_PresenceDetection_Process_Start, NULL); UTIL_TIMER_Start(&YunhornSTSWakeUpScanTimer); UTIL_TIMER_Start(&STSLampBarColorTimer); #elif defined(STS_P2) UTIL_TIMER_Create(&YunhornSTSWakeUpScanTimer, STS_TOFScanPeriod_msec, UTIL_TIMER_PERIODIC, (void*)STS_TOF_VL53LX_PeopleCounting_Process_Start, NULL); UTIL_TIMER_Start(&YunhornSTSWakeUpScanTimer); #endif // UTIL_TIMER_Create(&YunhornSTSHeartBeatTimer, 1000*STS_HeartBeatTimerPeriod_sec, UTIL_TIMER_PERIODIC, OnYunhornSTSHeartBeatTimerEvent, NULL); // UTIL_TIMER_Create(&YunhornSTSHeartBeatTimer, 1000*STS_HeartBeatTimerPeriod_sec, UTIL_TIMER_ONESHOT, OnYunhornSTSHeartBeatTimerEvent, NULL); // UTIL_TIMER_Start(&YunhornSTSHeartBeatTimer); #endif /* USER CODE END LoRaWAN_Init_Last */ } void STS_Sensor_Init(void) { STS_REBOOT_CONFIG_Init(); UTIL_SEQ_RegTask((1 << CFG_SEQ_Task_YunhornSTSEventRFAC), UTIL_SEQ_RFU, STS_YunhornSTSEventRFAC_Process); #if defined(STS_M1)||defined(STS_O5) UTIL_SEQ_RegTask((1 << CFG_SEQ_Task_YunhornSTSEventP1), UTIL_SEQ_RFU, STS_YunhornSTSEventP1_Process); #endif #if defined(STS_T6)||defined(STS_O6) UTIL_SEQ_RegTask((1 << CFG_SEQ_Task_YunhornSTSEventP3), UTIL_SEQ_RFU, STS_YunhornSTSEventP3_Process); #endif #if defined(STS_P2)||defined(STS_T6)||defined(L8) UTIL_SEQ_RegTask((1 << CFG_SEQ_Task_YunhornSTSEventP5), UTIL_SEQ_RFU, STS_YunhornSTSEventP5_Process); #endif #ifdef STS_R4 UTIL_SEQ_RegTask((1 << CFG_SEQ_Task_YunhornSTSEventP6), UTIL_SEQ_RFU, STS_YunhornSTSEventP6_Process); #endif #ifdef VL53L0 UTIL_SEQ_RegTask((1 << CFG_SEQ_Task_YunhornSTSEventP4), UTIL_SEQ_RFU, STS_YunhornSTSEventP4_Process); #endif #if defined(STS_T6)||defined(L8) UTIL_TIMER_Create(&YunhornSTSWakeUpScanTimer, STS_TOFScanPeriod_msec, UTIL_TIMER_ONESHOT, (void*)OnYunhornSTSWakeUpScanTimerEvent, NULL); //UTIL_TIMER_Create(&YunhornSTSWakeUpScanTimer, STS_TOFScanPeriod_msec, UTIL_TIMER_PERIODIC, (void*)STS_TOF_VL53LX_PresenceDetection_Process_Start, NULL); UTIL_TIMER_Create(&YunhornSTSHeartBeatTimer, 1000*STS_HeartBeatTimerPeriod_sec, UTIL_TIMER_PERIODIC, OnYunhornSTSHeartBeatTimerEvent, NULL); //UTIL_TIMER_Start(&YunhornSTSHeartBeatTimer); ppc_cfg_parameter_update(); // UTIL_TIMER_Start(&YunhornSTSWakeUpScanTimer); //UTIL_TIMER_Start(&STSLampBarColorTimer); #elif defined(STS_P2) UTIL_TIMER_Create(&YunhornSTSWakeUpScanTimer, STS_TOFScanPeriod_msec, UTIL_TIMER_PERIODIC, (void*)STS_TOF_VL53LX_PeopleCounting_Process_Start, NULL); UTIL_TIMER_Start(&YunhornSTSWakeUpScanTimer); #endif // UTIL_TIMER_Create(&YunhornSTSHeartBeatTimer, 1000*STS_HeartBeatTimerPeriod_sec, UTIL_TIMER_PERIODIC, OnYunhornSTSHeartBeatTimerEvent, NULL); // UTIL_TIMER_Create(&YunhornSTSHeartBeatTimer, 1000*STS_HeartBeatTimerPeriod_sec, UTIL_TIMER_ONESHOT, OnYunhornSTSHeartBeatTimerEvent, NULL); // UTIL_TIMER_Start(&YunhornSTSHeartBeatTimer); } void STS_Sensor_Prepare(void) { //STS_TOF_VL53LX_PresenceDetection_Process_Init(); UTIL_TIMER_Start(&YunhornSTSWakeUpScanTimer); } /* USER CODE BEGIN PB_Callbacks */ void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { switch (GPIO_Pin) { #ifdef STS_O5 case HALL1_Pin: if (0 == HALL1_STATE) { HAL_Delay(20); //if (0 == HALL1_STATE) APP_LOG(TS_OFF, VLEVEL_M, "\r\n Button 1 state == 0 \r\n"); } else if (1 == HALL1_STATE) { HAL_Delay(20); //if (1 == HALL1_STATE) APP_LOG(TS_OFF, VLEVEL_M, "\r\n Button 1 state ==1 \r\n"); } HAL_Delay(100); __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin); UTIL_SEQ_SetTask((1 << CFG_SEQ_Task_LoRaSendOnTxTimerOrButtonEvent), CFG_SEQ_Prio_0); break; case HALL2_Pin: if (0 == HALL2_STATE) { HAL_Delay(20); APP_LOG(TS_OFF, VLEVEL_M, "\r\n Button 2 state == 0 \r\n"); } else { HAL_Delay(20); APP_LOG(TS_OFF, VLEVEL_M, "\r\n Button 2 state ==1 \r\n"); } HAL_Delay(100); __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin); UTIL_SEQ_SetTask((1 << CFG_SEQ_Task_LoRaSendOnTxTimerOrButtonEvent), CFG_SEQ_Prio_0); break; #elif defined(STS_M1) case WATER_DETECT_Pin: sts_water_leakage_state = WATER_DETECT_STATE; if (0 == sts_water_leakage_state) { HAL_Delay(20); sts_water_leakage_state = WATER_DETECT_STATE; if (0 == sts_water_leakage_state) APP_LOG(TS_OFF, VLEVEL_M, "\r\n water leakage state == 0 \r\n"); } else { HAL_Delay(20); sts_water_leakage_state = WATER_DETECT_STATE; if (1 == sts_water_leakage_state) APP_LOG(TS_OFF, VLEVEL_M, "\r\n water leakage state == 1 \r\n"); } HAL_Delay(100); __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin); UTIL_SEQ_SetTask((1 << CFG_SEQ_Task_LoRaSendOnTxTimerOrButtonEvent), CFG_SEQ_Prio_0); break; #else case BUT1_Pin: /* Note: when "EventType == TX_ON_TIMER" this GPIO is not initialized */ if (EventType == TX_ON_EVENT) { UTIL_SEQ_SetTask((1 << CFG_SEQ_Task_LoRaSendOnTxTimerOrButtonEvent), CFG_SEQ_Prio_0); } break; #ifndef STS_R4 case BUT2_Pin: UTIL_SEQ_SetTask((1 << CFG_SEQ_Task_LoRaStopJoinEvent), CFG_SEQ_Prio_0); break; #endif #endif #ifdef STM32WL55xx case BUT3_Pin: UTIL_SEQ_SetTask((1 << CFG_SEQ_Task_LoRaStoreContextEvent), CFG_SEQ_Prio_0); break; #endif #ifdef STS_T6 case PIR_Pin: sts_pir_state= PIR_STATE; APP_LOG(TS_OFF, VLEVEL_M, "\r\n PIR_Read=%d \r\n", sts_pir_state); if (sts_pir_state == 1) { if (lockLow) { PIRValue = 1; lockLow = false; sts_pir_start_time = SysTimeGet(); APP_LOG(TS_OFF, VLEVEL_M, "\r\n PIRValue=%d \r\n", PIRValue); if (sts_pir_state != prev_sts_pir_state) { sts_pir_state_changed = 1; } prev_sts_pir_state = sts_pir_state; } takeLowTime = true; } if (sts_pir_state ==0) { if (takeLowTime) { sts_pir_duration_check_time = SysTimeGet(); lowIn = sts_pir_duration_check_time.Seconds; takeLowTime = false; } sts_pir_duration_check_time = SysTimeGet(); if ((!lockLow && (sts_pir_duration_check_time.Seconds - lowIn) > 5)) { PIRValue = 0; lockLow = true; sts_pir_state = 0; APP_LOG(TS_OFF, VLEVEL_M, "\r\n PIRValue=%d \r\n", PIRValue); if (sts_pir_state != prev_sts_pir_state) { sts_pir_state_changed = 1; } prev_sts_pir_state = sts_pir_state; } } // HAL_Delay(50); //__HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin); // APP_LOG(TS_OFF, VLEVEL_M, "\r\nMotion Detection result=%d \r\n", sts_pir_state); if ( sts_pir_state_changed == 1) { sts_pir_state_changed = 0; UTIL_SEQ_SetTask((1 << CFG_SEQ_Task_LoRaSendOnTxTimerOrButtonEvent), CFG_SEQ_Prio_0); } break; #endif #if (defined(VL53L0)||defined(VL53LX)||defined(L8)) case TOF_INT_EXTI_PIN: ToF_EventDetected = 1; break; #endif default: break; } } /* USER CODE END PB_Callbacks */ /* Private functions ---------------------------------------------------------*/ /* USER CODE BEGIN PrFD */ /* USER CODE END PrFD */ static void OnRxData(LmHandlerAppData_t *appData, LmHandlerRxParams_t *params) { /* USER CODE BEGIN OnRxData_1 */ uint8_t RxPort = 0; if (params != NULL) { #ifndef STM32WLE5xx HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_SET); /* LED_BLUE */ #endif UTIL_TIMER_Start(&RxLedTimer); if (params->IsMcpsIndication) { if (appData != NULL) { RxPort = appData->Port; if (appData->Buffer != NULL) { switch (appData->Port) { case LORAWAN_SWITCH_CLASS_PORT: /*this port switches the class*/ if (appData->BufferSize == 1) { switch (appData->Buffer[0]) { case 0: { LmHandlerRequestClass(CLASS_A); break; } case 1: { LmHandlerRequestClass(CLASS_B); break; } case 2: { LmHandlerRequestClass(CLASS_C); break; } default: break; } } /* switch class A/B/C */ DeviceClass_t deviceClass = CLASS_A; LmHandlerGetCurrentClass( &deviceClass ); uint8_t i=0; outbuf[i++] = (uint8_t) 'L'; outbuf[i++] = (uint8_t) sts_mtmcode1; outbuf[i++] = (uint8_t) sts_mtmcode2; outbuf[i++] = (uint8_t) sts_version; outbuf[i++] = (uint8_t) (0x41+ deviceClass); //translate to 'A','B','C' STS_SENSOR_Upload_Message(YUNHORN_STS_USER_APP_CTRL_REPLY_PORT, i, (uint8_t *)outbuf); break; case LORAWAN_USER_APP_PORT: if (appData->BufferSize == 1) { AppLedStateOn = appData->Buffer[0] & 0x01; if (AppLedStateOn == RESET) { APP_LOG(TS_OFF, VLEVEL_H, "LED OFF\r\n"); #ifndef STM32WLE5xx HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_Pin, GPIO_PIN_RESET); /* LED_RED */ #endif } else { APP_LOG(TS_OFF, VLEVEL_H, "LED ON\r\n"); #ifndef STM32WLE5xx HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_Pin, GPIO_PIN_SET); /* LED_RED */ #endif } } break; case YUNHORN_STS_USER_APP_CTRL_PORT: if (appData->BufferSize != 1) { if (appData->BufferSize < 128) { USER_APP_AUTO_RESPONDER_Parse((uint8_t*)appData->Buffer, appData->BufferSize); } } break; default: break; } } } } if (params->RxSlot < RX_SLOT_NONE) { APP_LOG(TS_OFF, VLEVEL_H, "###### D/L FRAME:%04d | PORT:%d | DR:%d | SLOT:%s | RSSI:%d | SNR:%d\r\n", params->DownlinkCounter, RxPort, params->Datarate, slotStrings[params->RxSlot], params->Rssi, params->Snr); } } /* USER CODE END OnRxData_1 */ } void STS_SENSOR_Upload_AppData_Message(LmHandlerAppData_t stsAppdata) { uint32_t nextTxIn =0; LmHandlerErrorStatus_t status; if (LmHandlerIsBusy() == false) { status = LmHandlerSend(&stsAppdata, LmHandlerParams.IsTxConfirmed, false); if (LORAMAC_HANDLER_SUCCESS == status) { APP_LOG(TS_ON, VLEVEL_H, "SEND REQUEST\r\n"); } else if (LORAMAC_HANDLER_DUTYCYCLE_RESTRICTED == status) { nextTxIn = LmHandlerGetDutyCycleWaitTime(); if (nextTxIn > 0) { APP_LOG(TS_ON, VLEVEL_H, "Next Tx in : ~%d second(s)\r\n", (nextTxIn / 1000)); } } } } void STS_SENSOR_Upload_Message(uint8_t appDataPort, uint8_t appBufferSize, uint8_t *appDataBuffer) { LmHandlerErrorStatus_t status = LORAMAC_HANDLER_ERROR; UTIL_TIMER_Time_t nextTxIn = 0; if (LmHandlerIsBusy() == false) { for (uint8_t i=0;i 0) { APP_LOG(TS_ON, VLEVEL_H, "Next Tx in : ~%d second(s)\r\n", (nextTxIn / 1000)); } } } } static void SendTxData(void) { /* USER CODE BEGIN SendTxData_1 */ LmHandlerErrorStatus_t status = LORAMAC_HANDLER_ERROR; uint8_t batteryLevel = GetBatteryLevel(); sensor_t sensor_data; UTIL_TIMER_Time_t nextTxIn = 0; #ifdef STS_P2 sts_people_count_sensor_data_t sts_p2_sensor_data={0x0}; #elif defined(STS_T6) sts_tof_presence_detection_sensor_data_t sts_t6_sensor_data={0x0}; #elif defined(STS_R1)||defined(STS_R1D)||defined(STS_R2)||defined(STS_R5) sts_tof_range_data_t sts_rr_sensor_data={0x0,0x0,0x0}; #elif defined(STS_R4) sts_r_sensor_data_t sts_r4_sensor_data={0}; #elif defined(STS_M1) sts_r_sensor_data_t sts_m1_sensor_data={0}; #elif defined(STS_O5) STS_OO_SensorDataTypeDef oo_data; #endif if (LmHandlerIsBusy() == false) { #ifdef CAYENNE_LPP uint8_t channel = 0; #else /* uint16_t pressure = 0; int16_t temperature = 0; uint16_t humidity = 0; uint32_t i = 0; int32_t latitude = 0; int32_t longitude = 0; uint16_t altitudeGps = 0; */ uint32_t i = 0; #endif /* CAYENNE_LPP */ EnvSensors_Read(&sensor_data); #ifdef STS_O5 STS_O5_SENSOR_Read(&oo_data); #elif defined(STS_R4) //UTIL_SEQ_SetTask((1 << CFG_SEQ_Task_YunhornSTSEventP6), CFG_SEQ_Prio_0); //STS_YunhornSTSEventP6_Process(); STS_R4_sensor_read(&sts_r4_sensor_data); #elif defined(STS_M1) STS_M1_sensor_read(&sts_m1_sensor_data); #endif #ifdef VL53LX #ifdef STS_P2 STS_people_count_sensor_Read(&sts_p2_sensor_data); #elif defined(STS_T6) STS_tof_presence_detection_sensor_Read(&sts_t6_sensor_data); #endif #endif #ifdef VL53L0 //STS_YunhornSTSEventP4_Process(); STS_RR_Sensor_Read(&sts_rr_sensor_data); APP_LOG(TS_OFF, VLEVEL_H, "\r\n VL53L0 sensor data read \r\n"); #ifdef STS_R1 AppData.Port = YUNHORN_STS_R1_LORA_APP_DATA_PORT; /* STS-R1 Data Port */ #elif defined(STS_R1D) AppData.Port = YUNHORN_STS_R1D_LORA_APP_DATA_PORT; /* STS-R1D Data Port */ #elif defined(STS_R2) AppData.Port = YUNHORN_STS_R2_LORA_APP_DATA_PORT; /* STS-R2 Data Port */ #elif defined(STS_R5) AppData.Port = YUNHORN_STS_R5_LORA_APP_DATA_PORT; /* STS-R5 Data Port */ #endif //STS_R1 #endif //VL53L0 #ifdef STS_R4 //SOAP/SANITIZER LEVEL AppData.Port = YUNHORN_STS_R4_LORA_APP_DATA_PORT; /* STS-R4 Data Port */ #elif defined(STS_M1) // WATER LEAKAGE SENSOR AppData.Port = YUNHORN_STS_M1_LORA_APP_DATA_PORT; /* STS-M1 Data Port */ #elif defined(STS_O5) AppData.Port = YUNHORN_STS_O5_LORA_APP_DATA_PORT; /* STS-O5 Data Port */ #endif AppLedStateOn = LED1_STATE; AppData.Buffer[i++] = (uint8_t) (AppLedStateOn|0x80); // for first byte, cannot be 0x0 AppData.Buffer[i++] = (uint8_t) sts_mtmcode1; AppData.Buffer[i++] = (uint8_t) sts_mtmcode2; AppData.Buffer[i++] = (uint8_t) sts_hardware_ver; AppData.Buffer[i++] = (uint8_t) 99*batteryLevel/254; #if 0 APP_LOG(TS_ON, VLEVEL_M, "VDDA: %d\r\n", batteryLevel); APP_LOG(TS_ON, VLEVEL_M, "temp: %d\r\n", (int16_t)(sensor_data.temperature)); //AppData.Port = LORAWAN_USER_APP_PORT; #endif #ifdef STS_P2 AppData.Port = YUNHORN_STS_P2_LORA_APP_DATA_PORT; /* STS-P2 Data Port */ #elif defined(STS_T6) AppData.Port = YUNHORN_STS_T6_LORA_APP_DATA_PORT; /* STS-T6 Data Port */ #elif defined(L8) AppData.Port = YUNHORN_STS_L8_LORA_APP_DATA_PORT; /* STS-L8 Data Port */ #endif #ifdef CAYENNE_LPP CayenneLppReset(); CayenneLppAddBarometricPressure(channel++, sensor_data.pressure); CayenneLppAddTemperature(channel++, sensor_data.temperature); CayenneLppAddRelativeHumidity(channel++, (uint16_t)(sensor_data.humidity)); if ((LmHandlerParams.ActiveRegion != LORAMAC_REGION_US915) && (LmHandlerParams.ActiveRegion != LORAMAC_REGION_AU915) && (LmHandlerParams.ActiveRegion != LORAMAC_REGION_AS923)) { CayenneLppAddDigitalInput(channel++, GetBatteryLevel()); CayenneLppAddDigitalOutput(channel++, AppLedStateOn); } CayenneLppCopy(AppData.Buffer); AppData.BufferSize = CayenneLppGetSize(); #else /* not CAYENNE_LPP */ #if 0 humidity = (uint16_t)(sensor_data.humidity * 10); /* in %*10 */ temperature = (int16_t)(sensor_data.temperature); pressure = (uint16_t)(sensor_data.pressure * 100 / 10); /* in hPa / 10 */ AppData.Buffer[i++] = AppLedStateOn; AppData.Buffer[i++] = (uint8_t)((pressure >> 8) & 0xFF); AppData.Buffer[i++] = (uint8_t)(pressure & 0xFF); AppData.Buffer[i++] = (uint8_t)(temperature & 0xFF); AppData.Buffer[i++] = (uint8_t)((humidity >> 8) & 0xFF); AppData.Buffer[i++] = (uint8_t)(humidity & 0xFF); if ((LmHandlerParams.ActiveRegion == LORAMAC_REGION_US915) || (LmHandlerParams.ActiveRegion == LORAMAC_REGION_AU915) || (LmHandlerParams.ActiveRegion == LORAMAC_REGION_AS923)) { AppData.Buffer[i++] = 0; AppData.Buffer[i++] = 0; AppData.Buffer[i++] = 0; AppData.Buffer[i++] = 0; } else { latitude = sensor_data.latitude; longitude = sensor_data.longitude; AppData.Buffer[i++] = GetBatteryLevel(); /* 1 (very low) to 254 (fully charged) */ AppData.Buffer[i++] = (uint8_t)((latitude >> 16) & 0xFF); AppData.Buffer[i++] = (uint8_t)((latitude >> 8) & 0xFF); AppData.Buffer[i++] = (uint8_t)(latitude & 0xFF); AppData.Buffer[i++] = (uint8_t)((longitude >> 16) & 0xFF); AppData.Buffer[i++] = (uint8_t)((longitude >> 8) & 0xFF); AppData.Buffer[i++] = (uint8_t)(longitude & 0xFF); AppData.Buffer[i++] = (uint8_t)((altitudeGps >> 8) & 0xFF); AppData.Buffer[i++] = (uint8_t)(altitudeGps & 0xFF); } #endif //if 0 #endif /* CAYENNE_LPP */ #ifdef STS_O5 AppData.Buffer[i++] = 1; AppData.Buffer[i++] = (uint8_t)(oo_data.state_sensor1_on_off); #endif #ifdef VL53L0 //VL53L0 #if (defined(STS_R1)||defined(STS_R5)) AppData.Buffer[i++] = 2; AppData.Buffer[i++] = (uint8_t)(sts_rr_sensor_data.tof_1_distance_mm >>8 & 0xFF); AppData.Buffer[i++] = (uint8_t)(sts_rr_sensor_data.tof_1_distance_mm & 0xFF); #elif defined(STS_R1D) AppData.Buffer[i++] = 4; AppData.Buffer[i++] = (uint8_t)(sts_rr_sensor_data.tof_1_distance_mm >>8 & 0xFF); AppData.Buffer[i++] = (uint8_t)(sts_rr_sensor_data.tof_1_distance_mm & 0xFF); AppData.Buffer[i++] = (uint8_t)(sts_rr_sensor_data.tof_2_distance_mm >>8 & 0xFF); AppData.Buffer[i++] = (uint8_t)(sts_rr_sensor_data.tof_2_distance_mm & 0xFF); #elif defined(STS_R5_EXT) AppData.Buffer[i++] = (uint8_t)(sts_rr_sensor_data.tof_3_distance_mm >>8 & 0xFF); AppData.Buffer[i++] = (uint8_t)(sts_rr_sensor_data.tof_3_distance_mm & 0xFF); #endif #endif //VL53L0 #ifdef STS_P2 #ifdef VL53LX // VL53L1X AppData.Buffer[i++] = (uint8_t) 15; //sum of below AppData.Buffer[i++] = (uint8_t)((sts_p2_sensor_data.Walk_In_People_Count>>8) & 0xFF); AppData.Buffer[i++] = (uint8_t)(sts_p2_sensor_data.Walk_In_People_Count & 0xFF); AppData.Buffer[i++] = (uint8_t)((sts_p2_sensor_data.Walk_Out_People_Count>>8) & 0xFF); AppData.Buffer[i++] = (uint8_t)(sts_p2_sensor_data.Walk_Out_People_Count & 0xFF); AppData.Buffer[i++] = (uint8_t)((sts_p2_sensor_data.Walk_Around_People_Count>>8) & 0xFF); AppData.Buffer[i++] = (uint8_t)(sts_p2_sensor_data.Walk_Around_People_Count & 0xFF); #endif // VL53L1X #ifdef VL53LX // VL53L1X AppData.Buffer[i++] = (uint8_t)((sts_p2_sensor_data.Count_Period) & 0xFF); AppData.Buffer[i++] = (uint8_t)((sts_p2_sensor_data.Count_Period_Unit) & 0xFF); AppData.Buffer[i++] = (uint8_t)((sts_p2_sensor_data.Sum_Day_Walk_In_People_Count>>8) & 0xFF); AppData.Buffer[i++] = (uint8_t)(sts_p2_sensor_data.Sum_Day_Walk_In_People_Count & 0xFF); AppData.Buffer[i++] = (uint8_t)((sts_p2_sensor_data.Sum_Day_Walk_Out_People_Count>>8) & 0xFF); AppData.Buffer[i++] = (uint8_t)(sts_p2_sensor_data.Sum_Day_Walk_Out_People_Count & 0xFF); AppData.Buffer[i++] = (uint8_t)((sts_p2_sensor_data.Sum_Day_Walk_Around_People_Count>>8) & 0xFF); AppData.Buffer[i++] = (uint8_t)(sts_p2_sensor_data.Sum_Day_Walk_Around_People_Count & 0xFF); AppData.Buffer[i++] = (uint8_t)(sts_p2_sensor_data.Count_Valid & 0xFF); #endif // VL53L1X #endif //STS_P2 if ((heart_beat_timer != 0L)) { heart_beat_timer=0; sensor_data_ready = 0; AppData.Port = (uint8_t)YUNHORN_STS_T6_LORA_APP_HTBT_PORT; //LORAWAN_USER_APP_PORT+1; AppData.Buffer[i++] = (uint8_t)(AppLedStateOn|0x80)&0x0ff; AppData.Buffer[i++] = (uint8_t)(99*batteryLevel/254)&0xff; } else if ((sensor_data_ready != 0)) { sensor_data_ready = 0; #if defined(STS_T6) AppData.Buffer[i++] = 4; AppData.Buffer[i++] = (uint8_t)((sts_t6_sensor_data.tof_range_presence_state & 0xFF)); AppData.Buffer[i++] = (uint8_t)((sts_t6_sensor_data.pir_motion_sensor_state & 0xFF)); AppData.Buffer[i++] = (uint8_t)((sts_t6_sensor_data.lamp_bar_color & 0xFF)); AppData.Buffer[i++] = (uint8_t)((sts_t6_sensor_data.tof_presence_distance_dm & 0xFF)); #endif //STS_T6 #if defined(L8) AppData.Buffer[i++] = 1; AppData.Buffer[i++] = 8; //testing //(uint8_t)((sts_l8_sensor_data.tof_range_presence_state & 0xFF)); #endif //STS_T6 /* STS-R4 SOAP LEVEL SENSOR */ #ifdef STS_R4 AppData.Buffer[i++] = 2; AppData.Buffer[i++] = (uint8_t)(sts_r4_sensor_data.measure_tech & 0xFF); AppData.Buffer[i++] = (uint8_t)(sts_r4_sensor_data.on_off_event & 0xFF); #endif //STS_R4 /* STS-M1 WATER LEAKAGE SENSOR */ #ifdef STS_M1 AppData.Buffer[i++] = 2; AppData.Buffer[i++] = (uint8_t)(sts_m1_sensor_data.measure_tech & 0xFF); AppData.Buffer[i++] = (uint8_t)(sts_m1_sensor_data.on_off_event & 0xFF); #endif //STS_M1 } //AppData.BufferSize = (uint8_t)(i&(~sts_service_mask)); AppData.BufferSize = (uint8_t)(sts_service_mask > STS_SERVICE_MASK_L1? 0:i)&0xff;; #ifdef CLOCK_SYNC if( IsClockSynched == false ) { status = LmhpClockSyncAppTimeReq( ); if (LORAMAC_HANDLER_SUCCESS == status) { OnSysTimeUpdate(); } } #endif if ((JoinLedTimer.IsRunning) && (LmHandlerJoinStatus() == LORAMAC_HANDLER_SET)) { UTIL_TIMER_Stop(&JoinLedTimer); HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_Pin, GPIO_PIN_RESET); /* LED_RED */ } status = LmHandlerSend(&AppData, LmHandlerParams.IsTxConfirmed, false); if (LORAMAC_HANDLER_SUCCESS == status) { APP_LOG(TS_ON, VLEVEL_L, "SEND REQUEST\r\n"); } else if (LORAMAC_HANDLER_DUTYCYCLE_RESTRICTED == status) { nextTxIn = LmHandlerGetDutyCycleWaitTime(); if (nextTxIn > 0) { APP_LOG(TS_ON, VLEVEL_L, "Next Tx in : ~%d second(s)\r\n", (nextTxIn / 1000)); } } } heart_beat_timer = 0; sensor_data_ready = 0; if (EventType == TX_ON_TIMER) { UTIL_TIMER_Stop(&TxTimer); UTIL_TIMER_SetPeriod(&TxTimer, MAX(nextTxIn, TxPeriodicity)); UTIL_TIMER_Start(&TxTimer); } /* USER CODE END SendTxData_1 */ } static void OnTxTimerEvent(void *context) { /* USER CODE BEGIN OnTxTimerEvent_1 */ if (sts_warm_up_count <= 5) { /* USER CODE END OnTxTimerEvent_1 */ //UTIL_TIMER_Stop(&TxTimer); #ifdef STS_R4 UTIL_SEQ_SetTask((1 << CFG_SEQ_Task_YunhornSTSEventP6), CFG_SEQ_Prio_0); #elif defined(STS_M1) UTIL_SEQ_SetTask((1 << CFG_SEQ_Task_YunhornSTSEventP1), CFG_SEQ_Prio_0); #elif (defined(STS_R1D)||defined(STS_R5)||defined(STS_R1)) APP_LOG(TS_OFF, VLEVEL_H, "\nSET TASK P4\r\n"); UTIL_SEQ_SetTask((1 << CFG_SEQ_Task_YunhornSTSEventP4), CFG_SEQ_Prio_0); #elif (defined(STS_P2)||defined(STS_T6)) UTIL_TIMER_Stop(&YunhornSTSWakeUpScanTimer); APP_LOG(TS_OFF, VLEVEL_M, "\r\n### Warm-up TxTimer Event : %d ###\r\n", sts_warm_up_count); #endif UTIL_SEQ_SetTask((1 << CFG_SEQ_Task_LoRaSendOnTxTimerOrButtonEvent), CFG_SEQ_Prio_0); #if (defined(STS_P2)||defined(STS_T6)) UTIL_TIMER_Start(&YunhornSTSWakeUpScanTimer); #endif sts_warm_up_count++; /*Wait for next tx slot*/ UTIL_TIMER_Start(&TxTimer); /* USER CODE BEGIN OnTxTimerEvent_2 */ } /* USER CODE END OnTxTimerEvent_2 */ } /* USER CODE BEGIN PrFD_LedEvents */ static void OnTxTimerLedEvent(void *context) { HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, GPIO_PIN_RESET); /* LED_GREEN */ } static void OnRxTimerLedEvent(void *context) { HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_RESET); /* LED_BLUE */ } static void OnJoinTimerLedEvent(void *context) { HAL_GPIO_TogglePin(LED3_GPIO_Port, LED3_Pin); /* LED_RED */ } /* USER CODE END PrFD_LedEvents */ static void OnTxData(LmHandlerTxParams_t *params) { /* USER CODE BEGIN OnTxData_1 */ if ((params != NULL)) { /* Process Tx event only if its a mcps response to prevent some internal events (mlme) */ if (params->IsMcpsConfirm != 0) { HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, GPIO_PIN_SET); /* LED_GREEN */ UTIL_TIMER_Start(&TxLedTimer); APP_LOG(TS_OFF, VLEVEL_M, "\r\n###### ========== MCPS-Confirm =============\r\n"); APP_LOG(TS_OFF, VLEVEL_H, "###### U/L FRAME:%04d | PORT:%d | DR:%d | PWR:%d", params->UplinkCounter, params->AppData.Port, params->Datarate, params->TxPower); APP_LOG(TS_OFF, VLEVEL_H, " | MSG TYPE:"); if (params->MsgType == LORAMAC_HANDLER_CONFIRMED_MSG) { APP_LOG(TS_OFF, VLEVEL_H, "CONFIRMED [%s]\r\n", (params->AckReceived != 0) ? "ACK" : "NACK"); } else { APP_LOG(TS_OFF, VLEVEL_H, "UNCONFIRMED\r\n"); } } } /* USER CODE END OnTxData_1 */ } static void OnJoinRequest(LmHandlerJoinParams_t *joinParams) { /* USER CODE BEGIN OnJoinRequest_1 */ if (joinParams != NULL) { if (joinParams->Status == LORAMAC_HANDLER_SUCCESS) { UTIL_TIMER_Stop(&JoinLedTimer); HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_Pin, GPIO_PIN_RESET); /* LED_RED */ APP_LOG(TS_OFF, VLEVEL_M, "\r\n###### = JOINED = "); if (joinParams->Mode == ACTIVATION_TYPE_ABP) { APP_LOG(TS_OFF, VLEVEL_M, "ABP ======================\r\n"); } else { APP_LOG(TS_OFF, VLEVEL_M, "OTAA =====================\r\n"); } AppData.Port = 1; AppData.BufferSize = 16; //UTIL_MEM_cpy_8((uint8_t*)AppData.Buffer, (uint8_t *)"YUNHORN168", 10); UTIL_MEM_cpy_8((uint8_t*)AppData.Buffer, (uint8_t *)(uint8_t*)YUNHORN_STS_PRD_STRING, sizeof(YUNHORN_STS_PRD_STRING)); AppData.BufferSize = sizeof(YUNHORN_STS_PRD_STRING)-1; LmHandlerParams.IsTxConfirmed = true; LmHandlerErrorStatus_t status = LmHandlerSend(&AppData, LmHandlerParams.IsTxConfirmed, false); if (status ==LORAMAC_HANDLER_SUCCESS ) LmHandlerParams.IsTxConfirmed = false; } else { APP_LOG(TS_OFF, VLEVEL_M, "\r\n###### = JOIN FAILED\r\n"); } APP_LOG(TS_OFF, VLEVEL_H, "###### U/L FRAME:JOIN | DR:%d | PWR:%d\r\n", joinParams->Datarate, joinParams->TxPower); } UTIL_TIMER_Start(&STSLampBarColorTimer); UTIL_TIMER_Start(&YunhornSTSHeartBeatTimer); /* USER CODE END OnJoinRequest_1 */ } static void OnBeaconStatusChange(LmHandlerBeaconParams_t *params) { /* USER CODE BEGIN OnBeaconStatusChange_1 */ if (params != NULL) { switch (params->State) { default: case LORAMAC_HANDLER_BEACON_LOST: { APP_LOG(TS_OFF, VLEVEL_M, "\r\n###### BEACON LOST\r\n"); break; } case LORAMAC_HANDLER_BEACON_RX: { APP_LOG(TS_OFF, VLEVEL_M, "\r\n###### BEACON RECEIVED | DR:%d | RSSI:%d | SNR:%d | FQ:%d | TIME:%d | DESC:%d | " "INFO:02X%02X%02X %02X%02X%02X\r\n", params->Info.Datarate, params->Info.Rssi, params->Info.Snr, params->Info.Frequency, params->Info.Time.Seconds, params->Info.GwSpecific.InfoDesc, params->Info.GwSpecific.Info[0], params->Info.GwSpecific.Info[1], params->Info.GwSpecific.Info[2], params->Info.GwSpecific.Info[3], params->Info.GwSpecific.Info[4], params->Info.GwSpecific.Info[5]); break; } case LORAMAC_HANDLER_BEACON_NRX: { APP_LOG(TS_OFF, VLEVEL_M, "\r\n###### BEACON NOT RECEIVED\r\n"); break; } } } /* USER CODE END OnBeaconStatusChange_1 */ } static void OnSysTimeUpdate(void) { /* USER CODE BEGIN OnSysTimeUpdate_1 */ IsClockSynched = true; /* USER CODE END OnSysTimeUpdate_1 */ } static void OnClassChange(DeviceClass_t deviceClass) { /* USER CODE BEGIN OnClassChange_1 */ APP_LOG(TS_OFF, VLEVEL_M, "Switch to Class %c done\r\n", "ABC"[deviceClass]); /* USER CODE END OnClassChange_1 */ } static void OnMacProcessNotify(void) { /* USER CODE BEGIN OnMacProcessNotify_1 */ /* USER CODE END OnMacProcessNotify_1 */ UTIL_SEQ_SetTask((1 << CFG_SEQ_Task_LmHandlerProcess), CFG_SEQ_Prio_0); /* USER CODE BEGIN OnMacProcessNotify_2 */ /* USER CODE END OnMacProcessNotify_2 */ } void OnTxPeriodicityChanged(uint32_t periodicity) { /* USER CODE BEGIN OnTxPeriodicityChanged_1 */ /* USER CODE END OnTxPeriodicityChanged_1 */ TxPeriodicity = periodicity; if (TxPeriodicity == 0) { /* Revert to application default periodicity */ TxPeriodicity = APP_TX_DUTYCYCLE; } /* Update timer periodicity */ UTIL_TIMER_Stop(&TxTimer); UTIL_TIMER_SetPeriod(&TxTimer, TxPeriodicity); UTIL_TIMER_Start(&TxTimer); /* USER CODE BEGIN OnTxPeriodicityChanged_2 */ /* USER CODE END OnTxPeriodicityChanged_2 */ } static void OnTxFrameCtrlChanged(LmHandlerMsgTypes_t isTxConfirmed) { /* USER CODE BEGIN OnTxFrameCtrlChanged_1 */ /* USER CODE END OnTxFrameCtrlChanged_1 */ LmHandlerParams.IsTxConfirmed = isTxConfirmed; /* USER CODE BEGIN OnTxFrameCtrlChanged_2 */ /* USER CODE END OnTxFrameCtrlChanged_2 */ } static void OnPingSlotPeriodicityChanged(uint8_t pingSlotPeriodicity) { /* USER CODE BEGIN OnPingSlotPeriodicityChanged_1 */ /* USER CODE END OnPingSlotPeriodicityChanged_1 */ LmHandlerParams.PingSlotPeriodicity = pingSlotPeriodicity; /* USER CODE BEGIN OnPingSlotPeriodicityChanged_2 */ /* USER CODE END OnPingSlotPeriodicityChanged_2 */ } static void OnSystemReset(void) { /* USER CODE BEGIN OnSystemReset_1 */ /* USER CODE END OnSystemReset_1 */ if ((LORAMAC_HANDLER_SUCCESS == LmHandlerHalt()) && (LmHandlerJoinStatus() == LORAMAC_HANDLER_SET)) { NVIC_SystemReset(); } /* USER CODE BEGIN OnSystemReset_Last */ /* USER CODE END OnSystemReset_Last */ } static void StopJoin(void) { /* USER CODE BEGIN StopJoin_1 */ HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_SET); /* LED_BLUE */ HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, GPIO_PIN_SET); /* LED_GREEN */ HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_Pin, GPIO_PIN_SET); /* LED_RED */ /* USER CODE END StopJoin_1 */ UTIL_TIMER_Stop(&TxTimer); if (LORAMAC_HANDLER_SUCCESS != LmHandlerStop()) { APP_LOG(TS_OFF, VLEVEL_M, "LmHandler Stop on going ...\r\n"); } else { APP_LOG(TS_OFF, VLEVEL_M, "LmHandler Stopped\r\n"); if (LORAWAN_DEFAULT_ACTIVATION_TYPE == ACTIVATION_TYPE_ABP) { ActivationType = ACTIVATION_TYPE_OTAA; APP_LOG(TS_OFF, VLEVEL_M, "LmHandler switch to OTAA mode\r\n"); } else { ActivationType = ACTIVATION_TYPE_ABP; APP_LOG(TS_OFF, VLEVEL_M, "LmHandler switch to ABP mode\r\n"); } LmHandlerConfigure(&LmHandlerParams); LmHandlerJoin(ActivationType, true); UTIL_TIMER_Start(&TxTimer); } UTIL_TIMER_Start(&StopJoinTimer); /* USER CODE BEGIN StopJoin_Last */ /* USER CODE END StopJoin_Last */ } static void OnStopJoinTimerEvent(void *context) { /* USER CODE BEGIN OnStopJoinTimerEvent_1 */ /* USER CODE END OnStopJoinTimerEvent_1 */ if (ActivationType == LORAWAN_DEFAULT_ACTIVATION_TYPE) { UTIL_SEQ_SetTask((1 << CFG_SEQ_Task_LoRaStopJoinEvent), CFG_SEQ_Prio_0); } /* USER CODE BEGIN OnStopJoinTimerEvent_Last */ #ifndef STM32WLE5xx HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_RESET); /* LED_BLUE */ HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, GPIO_PIN_RESET); /* LED_GREEN */ HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_Pin, GPIO_PIN_RESET); /* LED_RED */ #endif /* USER CODE END OnStopJoinTimerEvent_Last */ } static void StoreContext(void) { LmHandlerErrorStatus_t status = LORAMAC_HANDLER_ERROR; /* USER CODE BEGIN StoreContext_1 */ /* USER CODE END StoreContext_1 */ status = LmHandlerNvmDataStore(); if (status == LORAMAC_HANDLER_NVM_DATA_UP_TO_DATE) { APP_LOG(TS_OFF, VLEVEL_M, "NVM DATA UP TO DATE\r\n"); } else if (status == LORAMAC_HANDLER_ERROR) { APP_LOG(TS_OFF, VLEVEL_M, "NVM DATA STORE FAILED\r\n"); } /* USER CODE BEGIN StoreContext_Last */ /* USER CODE END StoreContext_Last */ } static void OnNvmDataChange(LmHandlerNvmContextStates_t state) { /* USER CODE BEGIN OnNvmDataChange_1 */ /* USER CODE END OnNvmDataChange_1 */ if (state == LORAMAC_HANDLER_NVM_STORE) { APP_LOG(TS_OFF, VLEVEL_M, "NVM DATA STORED\r\n"); } else { APP_LOG(TS_OFF, VLEVEL_M, "NVM DATA RESTORED\r\n"); } /* USER CODE BEGIN OnNvmDataChange_Last */ /* USER CODE END OnNvmDataChange_Last */ } static void OnStoreContextRequest(void *nvm, uint32_t nvm_size) { /* USER CODE BEGIN OnStoreContextRequest_1 */ /* USER CODE END OnStoreContextRequest_1 */ /* store nvm in flash */ if (FLASH_IF_Erase(LORAWAN_NVM_BASE_ADDRESS, FLASH_PAGE_SIZE) == FLASH_IF_OK) { FLASH_IF_Write(LORAWAN_NVM_BASE_ADDRESS, (const void *)nvm, nvm_size); } /* USER CODE BEGIN OnStoreContextRequest_Last */ /* USER CODE END OnStoreContextRequest_Last */ } static void OnRestoreContextRequest(void *nvm, uint32_t nvm_size) { /* USER CODE BEGIN OnRestoreContextRequest_1 */ /* USER CODE END OnRestoreContextRequest_1 */ FLASH_IF_Read(nvm, LORAWAN_NVM_BASE_ADDRESS, nvm_size); /* USER CODE BEGIN OnRestoreContextRequest_Last */ /* USER CODE END OnRestoreContextRequest_Last */ } /** * @brief STS Lamp Bar timer callback function * @param context ptr of Lamp Bar LED context */ static void OnYunhornSTSLampBarColorTimerEvent(void *context) { uint8_t high4=(sts_lamp_bar_color>>4)&0x0f, low4=sts_lamp_bar_color&0x0f; #if defined(STS_O6)||defined(STS_T6) //||defined(O1L) //UTIL_SEQ_SetTask((1 << CFG_SEQ_Task_YunhornSTSEventP3), CFG_SEQ_Prio_0); UTIL_TIMER_Stop(&STSLampBarColorTimer); if (high4==0) { STS_Lamp_Bar_Set_STS_RGB_Color(sts_lamp_bar_color, luminance_level); } else { STS_Lamp_Bar_Set_STS_RGB_Color(r_b?high4:low4, luminance_level); r_b = !r_b; } UTIL_TIMER_Start(&STSLampBarColorTimer); #endif } /** * @brief SYS occupancy, door lock, motion duration check timer callback function * @param context ptr of duration check context */ #if 0 static void OnYunhornSTSDurationCheckTimerEvent(void *context) { #ifdef STS_O6 #endif } #endif /** * @brief Yunhorn STS Occupancy RSS WakeUP timer callback function * @param context ptr of STS RSS WakeUp context */ #ifdef STS_O6 static void OnYunhornSTSOORSSWakeUpTimerEvent(void *context) { } #endif /** * @brief Yunhorn STS Heart beat timer callback function * @param context ptr of context */ static void OnYunhornSTSHeartBeatTimerEvent(void *context) { // UTIL_SEQ_SetTask((1 << CFG_SEQ_Task_YunhornSTSEventRFAC), CFG_SEQ_Prio_0); UTIL_TIMER_Stop(&YunhornSTSHeartBeatTimer); uint8_t appHeartBeatDataPort=2, appHeartBeatBufferSize=2, appHeartBeatDataBuffer[32]={0x0}; if ((rfac_timer <(STS_BURN_IN_RFAC+3))&&(sts_cfg_nvm.ac[0]==0x0)&&(sts_cfg_nvm.ac[19]==0x0)) { //APP_LOG(TS_OFF, VLEVEL_M, "\n\n RFAC_TIMER = %d\n\n", rfac_timer); //STS_YunhornSTSEventRFAC_Process(); // the following doesn't executed #if 1 //APP_LOG(TS_OFF, VLEVEL_M, "\n Start send RFAC request \n"); appHeartBeatBufferSize = 4; UTIL_MEM_cpy_8((uint8_t*)appHeartBeatDataBuffer,"RFAC",4); STS_SENSOR_Upload_Message(YUNHORN_STS_USER_APP_CTRL_REPLY_PORT, appHeartBeatBufferSize, (uint8_t*)appHeartBeatDataBuffer); #endif rfac_timer ++; } else { // normal heart-beat process #if 1 #ifdef STS_P2 appHeartBeatDataPort = YUNHORN_STS_P2_LORA_APP_HTBT_PORT; #elif defined(STS_R1) appHeartBeatDataPort = YUNHORN_STS_R1_LORA_APP_HTBT_PORT; #elif defined(STS_R1D) appHeartBeatDataPort = YUNHORN_STS_R1D_LORA_APP_HTBT_PORT; #elif defined(STS_R5) appHeartBeatDataPort = YUNHORN_STS_R5_LORA_APP_HTBT_PORT; #elif defined(STS_R4) appHeartBeatDataPort = YUNHORN_STS_R4_LORA_APP_HTBT_PORT; #elif defined(STS_T6) appHeartBeatDataPort = YUNHORN_STS_T6_LORA_APP_HTBT_PORT; #elif defined(STS_O5) appHeartBeatDataPort = YUNHORN_STS_O5_LORA_APP_HTBT_PORT; #elif defined(STS_M1) appHeartBeatDataPort = YUNHORN_STS_M1_LORA_APP_HTBT_PORT; #endif appHeartBeatBufferSize = 2; appHeartBeatDataBuffer[0]=(uint8_t)(0x80|AppLedStateOn); appHeartBeatDataBuffer[1]=(uint8_t)(SYS_GetBatteryLevel()/100); //TODO XXX change to battery level in mV //APP_LOG(TS_OFF, VLEVEL_M, "\n\n HEART-BEAT TIMER = %d\n\n", rfac_timer); STS_SENSOR_Upload_Message(appHeartBeatDataPort, appHeartBeatBufferSize, (uint8_t*)appHeartBeatDataBuffer); #endif } UTIL_TIMER_Start(&YunhornSTSHeartBeatTimer); } /** * @brief Yunhorn STS Heart Beat Periodicity Chagne function * @param duration of periodicty in ms (1/1000 sec) */ void OnYunhornSTSHeartBeatPeriodicityChanged(uint32_t periodicity) { /* USER CODE BEGIN OnYunhornSTSHeartBeatPeriodicityChanged_1 */ /* USER CODE END OnYunhornSTSHeartBeatPeriodicityChanged_1 */ if (periodicity == 0) { /* Revert to application default Heat-beat periodicity */ periodicity = 10*APP_TX_DUTYCYCLE; //10*10 000 ms } /* Update timer YunhornSTSHeartBeatTimer */ APP_LOG(TS_OFF, VLEVEL_M,"* STS HeartBeatPeriodicity = %u (msec)\r\n", periodicity ); UTIL_TIMER_Stop(&YunhornSTSHeartBeatTimer); UTIL_TIMER_SetPeriod(&YunhornSTSHeartBeatTimer, periodicity); UTIL_TIMER_Start(&YunhornSTSHeartBeatTimer); /* USER CODE BEGIN OnYunhornSTSHeartBeatPeriodicityChanged_2 */ APP_LOG(TS_OFF, VLEVEL_M,"* STS HeartBeatPeriodicity = %u (msec)\r\n", periodicity ); /* USER CODE END OnYunhornSTSHeartBeatPeriodicityChanged_2 */ } /* USER CODE BEGIN PrFD_YunhornSTSWakeUpScanTimerEvents */ static void OnYunhornSTSWakeUpScanTimerEvent(void *context) { #if defined(STS_P2)||defined(STS_T6)||defined(L8) UTIL_TIMER_Stop(&YunhornSTSWakeUpScanTimer); UTIL_SEQ_SetTask((1 << CFG_SEQ_Task_YunhornSTSEventP5), CFG_SEQ_Prio_0); UTIL_TIMER_Start(&YunhornSTSWakeUpScanTimer); #endif } /** * @brief Yunhorn STS Tx Periodicity Change function * @param duration of periodicty in ms (1/1000 sec) */ void OnYunhornSTSTxPeriodicityChanged(uint32_t periodicity) { /* USER CODE BEGIN OnYunhornSTSTxPeriodicityChanged */ /* USER CODE END OnYunhornSTSTxPeriodicityChanged */ /* Update timer OnYunhornSTSTxPeriodicityChanged */ OnTxPeriodicityChanged(periodicity); /* UTIL_TIMER_Stop(&TxTimer); TxPeriodicity = periodicity; UTIL_TIMER_SetPeriod(&TxTimer, TxPeriodicity); UTIL_TIMER_Start(&TxTimer); */ /* USER CODE BEGIN OnYunhornSTSTxPeriodicityChanged */ APP_LOG(TS_OFF, VLEVEL_H,"\n* STS TxPeriodicity = %u (sec)\r\n", TxPeriodicity/1000 ); /* USER CODE END OnYunhornSTSTxPeriodicityChanged */ } void OnStoreSTSCFGContextRequest(void) { /* USER CODE BEGIN OnStoreContextRequest_1 */ #if 0 uint8_t i=0,j=0; uint8_t to_store__value[YUNHORN_STS_MAX_NVM_CFG_SIZE]={0x0}; /* KEEP THIS LOCAL */ sts_cfg_nvm.length = STS_NVM_CFG_SIZE; to_store__value[i++] = sts_cfg_nvm.mtmcode1; to_store__value[i++] = sts_cfg_nvm.mtmcode2; to_store__value[i++] = sts_cfg_nvm.version; to_store__value[i++] = sts_cfg_nvm.hardware_ver; to_store__value[i++] = sts_cfg_nvm.periodicity; to_store__value[i++] = sts_cfg_nvm.unit; to_store__value[i++] = sts_cfg_nvm.sampling; to_store__value[i++] = sts_cfg_nvm.s_unit; to_store__value[i++] = sts_cfg_nvm.work_mode; to_store__value[i++] = sts_cfg_nvm.sts_service_mask; to_store__value[i++] = sts_cfg_nvm.sts_ioc_mask; to_store__value[i++] = (uint8_t) STS_CFG_PCFG_SIZE; //sts_cfg_nvm.length; for (j = 0; j < STS_CFG_PCFG_SIZE; j++) { to_store__value[i++] = (sts_cfg_nvm.p[j]); } to_store__value[i++] = sts_cfg_nvm.color_occupy_vacant; to_store__value[i++] = sts_cfg_nvm.sts_door_jam_profile; to_store__value[i++] = sts_cfg_nvm.sensor_install_height_in_10cm; to_store__value[i++] = sts_cfg_nvm.alarm_parameter05; to_store__value[i++] = sts_cfg_nvm.alarm_mute_reset_timer_in_10sec; to_store__value[i++] = sts_cfg_nvm.alarm_lamp_bar_flashing_color; to_store__value[i++] = sts_cfg_nvm.occupancy_overtime_threshold_in_10min; to_store__value[i++] = sts_cfg_nvm.motionless_duration_threshold_in_min; to_store__value[i++] = sts_cfg_nvm.unconscious_or_motionless_level_threshold; to_store__value[i++] = sts_cfg_nvm.fall_detection_acc_threshold; to_store__value[i++] = sts_cfg_nvm.fall_detection_depth_threshold; to_store__value[i++] = sts_cfg_nvm.fall_confirm_threshold_in_10sec; if ((nvm_stored_value[NVM_AC_CODE_START]!= 0x0) && (nvm_stored_value[NVM_AC_CODE_START+19]!=0x0)) { //APP_LOG(TS_OFF, VLEVEL_M, "\n\r Transfer good NVM Stored ac_code to NVM_STORE_VALUE\r\n"); UTIL_MEM_cpy_8((void*)&to_store__value[NVM_AC_CODE_START], (void*)&nvm_store_value[NVM_AC_CODE_START],YUNHORN_STS_AC_CODE_SIZE); } else if ((sts_ac_code[0]!=0x0) && (sts_ac_code[YUNHORN_STS_AC_CODE_SIZE-1]!=0x0)) { //APP_LOG(TS_OFF, VLEVEL_M, "\n\r Transfer new generated ac_code to NVM_STORE_VALUE\r\n"); UTIL_MEM_cpy_8((void*)&to_store__value[NVM_AC_CODE_START], (void*)sts_ac_code,YUNHORN_STS_AC_CODE_SIZE); UTIL_MEM_cpy_8((void*)&nvm_store_value[NVM_AC_CODE_START], (void*)sts_ac_code,YUNHORN_STS_AC_CODE_SIZE); } #endif /* USER CODE END OnStoreContextRequest_1 */ /* store nvm in flash */ //if ((sts_ac_code[0] != 0 ) && (sts_ac_code[YUNHORN_STS_AC_CODE_SIZE-1] !=0)) { for (uint8_t j=0; j 10)? periodicity : 10; // in seconds unit APP_LOG(TS_OFF, VLEVEL_M, "\n\n Tx periodicity in NVM =%u sec\n",periodicity); TxPeriodicity= periodicity*1000; // to ms uint32_t sampling_heartbeat_periodicity = (sts_cfg_nvm.sampling); //Heart-beat or Sampling interval if ((char)sts_cfg_nvm.s_unit =='M') { sampling_heartbeat_periodicity *= 60; } else if ((char) sts_cfg_nvm.s_unit =='H') { sampling_heartbeat_periodicity *= 3600; } else if ((char) sts_cfg_nvm.s_unit =='S') { sampling_heartbeat_periodicity *= 1; } else if ((char) sts_cfg_nvm.s_unit =='L') { sampling_heartbeat_periodicity *= 100; } STS_HeartBeatTimerPeriod_sec = sampling_heartbeat_periodicity; APP_LOG(TS_OFF, VLEVEL_M, "\n\n sampling or heartbeat periodicity in NVM =%u sec\n",sampling_heartbeat_periodicity); if ((sts_cfg_nvm.ac[0] ==0x0 )&& (sts_cfg_nvm.ac[19]==0x0)) { // ensure it's not in production yet OnYunhornSTSTxPeriodicityChanged(APP_TX_DUTYCYCLE); // in msec unit OnYunhornSTSHeartBeatPeriodicityChanged(STS_HeartBeatTimerPeriod_sec); //TODO XXXX //OnTxPeriodicityChanged(10000); // APP_TX_DUTYCYCLE in msec unit //TxPeriodicity = APP_TX_DUTYCYCLE; } else { //OnYunhornSTSTxPeriodicityChanged(TxPeriodicity); // in msec unit //OnTxPeriodicityChanged(TxPeriodicity); //Heart-beat or Sampling interval //sampling_heartbeat_periodicity = (sampling_heartbeat_periodicity > 0)? sampling_heartbeat_periodicity : 1; // in seconds unit //sampling_heartbeat_periodicity = sampling_heartbeat_periodicity*1000; #ifdef STS_P2 STS_TxPeriod_sec = periodicity; STS_HeartBeatTimerPeriod_sec = sampling_heartbeat_periodicity; sts_people_count_sensor_data->Count_Period = sts_cfg_nvm.periodicity; sts_people_count_sensor_data->Count_Period_Unit = sts_cfg_nvm.unit; #endif #if defined(STS_T6) //STS_HeartBeatTimerPeriod_sec = periodicity; OnYunhornSTSHeartBeatPeriodicityChanged(1000*STS_HeartBeatTimerPeriod_sec); #endif #if defined(STS_R1)||defined(STS_R5)||defined(STS_R4)||defined(STS_R1D)||defined(STS_O5)||defined(STS_M1) OnYunhornSTSHeartBeatPeriodicityChanged(sampling_heartbeat_periodicity*1000); #endif } sts_work_mode = sts_cfg_nvm.work_mode; sts_service_mask = sts_cfg_nvm.sts_service_mask; sts_door_jam_profile = sts_cfg_nvm.sts_door_jam_profile; sts_sensor_install_height = sts_cfg_nvm.sensor_install_height_in_10cm*100; sts_color_occupy_vacant = sts_cfg_nvm.color_occupy_vacant; APP_LOG(TS_OFF, VLEVEL_M, "\r\n Color Occupy =%02x, VACANT =%02x \r\n",((sts_color_occupy_vacant>>4)&0x0f), sts_color_occupy_vacant&0x0f ); ppc_cfg_parameter_update(); #ifdef YUNHORN_STS_O6_ENABLED sts_lamp_bar_color = STS_COLOR_DEFAULT_VACANT; sts_fall_detection_acc_threshold = (uint8_t)sts_cfg_nvm.fall_detection_acc_threshold*10; sts_fall_detection_depth_threshold = (uint8_t)sts_cfg_nvm.fall_detection_depth_threshold*10; //in cm // **** = sts_cfg_nvm.fall_detection_reserve; sts_occupancy_overtime_threshold = (uint8_t)sts_cfg_nvm.occupancy_overtime_threshold*10; // minutes #endif for (uint8_t j=0; j< YUNHORN_STS_AC_CODE_SIZE; j++) { sts_ac_code[j] = sts_cfg_nvm.ac[j]; } //for (uint8_t j=0; j< YUNHORN_STS_AC_CODE_SIZE; j++) //{ // sts_ac_code[j] = sts_cfg_nvm.ac[j]; //} //UTIL_MEM_cpy_8((void*)sts_ac_code,(void*)sts_cfg_nvm.ac, YUNHORN_STS_AC_CODE_SIZE); #ifdef YUNHORN_STS_O6_ENABLED if ((sts_version == sts_cfg_nvm.version)&& (NVM_CFG_PARAMETER_SIZE == sts_cfg_nvm.length)) { STS_PRESENCE_SENSOR_Init(); STS_PRESENCE_SENSOR_RSS_Init(); } #endif } static void STS_Show_STS_CFG_NVM(uint8_t * store_value, uint16_t store_size) { APP_LOG(TS_OFF, VLEVEL_M, "\n-----------------------------------------------\n"); APP_LOG(TS_OFF, VLEVEL_M, "\n00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15\n"); for (uint16_t i=0; i< store_size; i++) { if (i%16==0) APP_LOG(TS_OFF, VLEVEL_M, "\n"); APP_LOG(TS_OFF, VLEVEL_M, "%02X ", store_value[i]); } APP_LOG(TS_OFF, VLEVEL_M, "\n\r"); APP_LOG(TS_OFF, VLEVEL_M, "\n###############################################\n\r"); }