953 lines
33 KiB
C
953 lines
33 KiB
C
/**
|
|
******************************************************************************
|
|
* @file : app_tof.c
|
|
* @author : IMG SW Application Team
|
|
* @brief : This file provides code for the configuration
|
|
* of the STMicroelectronics.X-CUBE-TOF1.3.2.0 instances.
|
|
******************************************************************************
|
|
*
|
|
* @attention
|
|
*
|
|
* Copyright (c) 2022 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.
|
|
*
|
|
******************************************************************************
|
|
*/
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/* Includes ------------------------------------------------------------------*/
|
|
#include "app_tof.h"
|
|
#include "main.h"
|
|
#include "sys_app.h"
|
|
#include <stdio.h>
|
|
#include "usart.h"
|
|
#include <stdlib.h>
|
|
#if (defined(STS_P2)||defined(STS_T6))
|
|
#include "VL53L1X_api.h"
|
|
#elif defined(L8)
|
|
#include "53l8a1_ranging_sensor.h"
|
|
#include "app_tof_pin_conf.h"
|
|
#include "yunhorn_sts_sensors.h"
|
|
#include "sts_lamp_bar.h"
|
|
volatile uint8_t fhmos_fall=0, fhmos_human_movement=0, fhmos_occupancy=0, fhmos_sos_alarm=0;
|
|
volatile uint32_t fhmos_fall_counter=0;
|
|
volatile uint32_t sts_low_threshold=1500, sts_high_threshold=2800, sts_occupancy_threshold=2300;
|
|
extern volatile uint8_t sts_head_level_low;
|
|
volatile sts_fhmos_sensor_config_t fhmos_cfg={70,4,4,8,20,80,20,25};
|
|
volatile sts_fhmos_sensor_cmd_t fhmos_cmd={0x0};
|
|
volatile sts_fhmos_sensor_ambient_height_t fhmos_bg={0x0}, fhmos_gesture={0x0}, fhmos_net={0x0};
|
|
volatile sts_fhmos_sensor_data_t fhmos_data={0};
|
|
extern volatile uint8_t sts_fhmos_result;
|
|
volatile uint8_t sts_mask_bitmap[8]={0x0}, fhmos_gesture_bitmap[8]={0x0};
|
|
extern volatile uint16_t sts_sensor_install_height; //in mm
|
|
extern volatile uint8_t sts_lamp_bar_color;
|
|
extern volatile uint8_t sts_status_color;
|
|
extern volatile uint8_t sts_hall1_read,sts_hall2_read; // Above hall1_read == reed_hall_result, hall2_read == emergency_button
|
|
extern volatile uint8_t sts_pir_read;
|
|
extern volatile uint8_t sts_fhmos_state_changed;
|
|
extern volatile uint8_t sts_fhmos_bitmap_pending;
|
|
#endif
|
|
#include "stm32wlxx_nucleo.h"
|
|
static int to_confirm = 0;
|
|
static uint32_t STS_Get_Center_Range_Distance(RANGING_SENSOR_Result_t *Result);
|
|
/* Private typedef -----------------------------------------------------------*/
|
|
/*
|
|
* The application is to showcase the threshold detection
|
|
* functionality of this device.
|
|
*
|
|
* When the device detects a target that match the configuration an IT is generated
|
|
* and the host will start printing the measurement information on the serial connection (UART).
|
|
*
|
|
* Here is the default configuration:
|
|
*
|
|
* ITConfig.Criteria = RS_IT_IN_WINDOW;
|
|
* ITConfig.LowThreshold = 200; // distance in mm
|
|
* ITConfig.HighThreshold = 600; // distance in mm
|
|
*
|
|
* Other availables interrupt generation criteria for this device are:
|
|
*
|
|
* - RS_IT_DEFAULT // IT if new measurement is ready (no thresholds)
|
|
* - RS_IT_IN_WINDOW // IT if distance > thresh_high
|
|
* - RS_IT_OUT_OF_WINDOW // IT if distance < LowThreshold OR distance > HighThreshold
|
|
* - RS_IT_BELOW_LOW // IT if distance <= LowThreshold
|
|
* - RS_IT_ABOVE_HIGH // IT if distance > HighThreshold
|
|
* - RS_IT_EQUAL_LOW // IT if distance == LowThreshold
|
|
* - RS_IT_NOT_EQUAL_LOW // IT if distance != LowThreshold
|
|
*/
|
|
|
|
/* Private define ------------------------------------------------------------*/
|
|
//#define TIMING_BUDGET (30U) /* 16 ms < TimingBudget < 500 ms */
|
|
#define TIMING_BUDGET (50U) /* 16 ms < TimingBudget < 500 ms */
|
|
#define POLLING_PERIOD (250U) /* refresh rate for polling mode (milliseconds, shall be consistent with TimingBudget value) */
|
|
|
|
#ifdef L8
|
|
/* for VL53L8A1 */
|
|
#define RANGING_FREQUENCY (10U) /* Ranging frequency Hz (shall be consistent with TimingBudget value) */
|
|
#define LOW_THRESHOLD (600U)
|
|
#define HIGH_THRESHOLD (2000U)
|
|
// floor, eg. 2200
|
|
#define OCCUPANCY_THRESHOLD (1500) // assume high people 2000-450 = 1550
|
|
|
|
/* ceiling -------------------- zero - 00 ref. 3000 mm high
|
|
*
|
|
*
|
|
* people high --------------- 2100 mm high people
|
|
*
|
|
*
|
|
*
|
|
*
|
|
* people low ------------------- 900 mm child normal
|
|
*
|
|
*
|
|
*
|
|
* other things ----------------- 400 mm
|
|
*
|
|
*
|
|
* floor ----------------------00000
|
|
*
|
|
*
|
|
*/
|
|
/* Private variables ---------------------------------------------------------*/
|
|
static RANGING_SENSOR_Capabilities_t Cap;
|
|
static RANGING_SENSOR_ProfileConfig_t Profile;
|
|
static RANGING_SENSOR_Result_t Result;
|
|
//static VL53L8CX_ResultsData L8CXResult;
|
|
//static VL53L8CX_Motion_Configuration motion_config; /* Motion configuration*/
|
|
|
|
//static VL53L8CX_Configuration Dev;
|
|
|
|
static void MX_53L8A1_ThresholdDetection_Init(void);
|
|
static void MX_53L8A1_ThresholdDetection_Process(void);
|
|
static void print_result(RANGING_SENSOR_Result_t *Result);
|
|
//static void sts_generate_fall_gesture_map(void);
|
|
#endif
|
|
static int32_t status = 0;
|
|
|
|
volatile uint8_t ToF_EventDetected = 0;
|
|
uint16_t sensor_id=0;
|
|
|
|
/* Private function prototypes -----------------------------------------------*/
|
|
#if (defined(STS_P2)||defined(STS_T6))
|
|
uint8_t sts_vl53lx_ranging(uint16_t *ranged_distance, uint8_t range_mode, uint16_t distance_threshold_mm,
|
|
uint16_t inter_measurement_ms, uint16_t macro_timing,uint16_t roi_width, uint16_t sigma_mm, uint16_t signal_kcps);
|
|
#endif
|
|
uint8_t IsInterruptDetected(uint16_t dev);
|
|
#if (defined(STS_P2)||defined(STS_T6))
|
|
void STS_TOF_VL53LX_Range_Process(uint8_t range_mode, uint16_t *range_distance);
|
|
#endif
|
|
void MX_TOF_Init(void)
|
|
{
|
|
/* USER CODE BEGIN SV */
|
|
|
|
/* USER CODE END SV */
|
|
|
|
/* USER CODE BEGIN TOF_Init_PreTreatment */
|
|
|
|
/* USER CODE END TOF_Init_PreTreatment */
|
|
|
|
/* Initialize the peripherals and the TOF components */
|
|
//APP_LOG(TS_OFF,VLEVEL_L,"\r\n###################### MX TOF Init... \r\n");
|
|
|
|
//MX_53L1A2_SimpleRanging_Init();
|
|
//STS_TOF_VL53LX_PeopleCounting_Process();
|
|
#ifdef L8
|
|
MX_53L8A1_ThresholdDetection_Init();
|
|
MX_53L8A1_ThresholdDetection_Process();
|
|
STS_FHMOS_sensor_config_init();
|
|
//sts_high_threshold = sts_cfg_nvm.sensor_install_height_in_10cm ;
|
|
//sts_low_threshold = sts_cfg_nvm.sensor_install_height_in_10cm -1400;
|
|
STS_TOF_L8_Reconfig();
|
|
|
|
#elif defined(STS_R1D)
|
|
XWL55_WLE5_53L0X_Init();
|
|
#endif
|
|
|
|
/* USER CODE BEGIN TOF_Init_PostTreatment */
|
|
|
|
/* USER CODE END TOF_Init_PostTreatment */
|
|
}
|
|
|
|
|
|
/*
|
|
* LM background task
|
|
*/
|
|
void STS_LMZ_Ambient_Height_Scan_Process(void)
|
|
{
|
|
|
|
#if 1
|
|
uint8_t i=0;
|
|
uint32_t range_distance =0;
|
|
|
|
for (i=0; i<64; i++)
|
|
{
|
|
fhmos_bg.h2cm[i] = 0;
|
|
fhmos_bg.maskoff[i] = 0;
|
|
}
|
|
for (i=0;i<8;i++)
|
|
sts_mask_bitmap[i] =0x0;
|
|
|
|
// printf("sts sensor install height = %4d \r\n", (int)sts_sensor_install_height);
|
|
|
|
|
|
sts_high_threshold = sts_sensor_install_height;
|
|
sts_low_threshold = sts_sensor_install_height-1400;
|
|
//APP_LOG(TS_OFF, VLEVEL_M, "\r\nReconfig ----> Threshold High=%d mm, Low=%d mm \r\n", sts_high_threshold, sts_low_threshold);
|
|
|
|
STS_TOF_L8_Reconfig();
|
|
|
|
status = VL53L8A1_RANGING_SENSOR_Start(VL53L8A1_DEV_CENTER, RS_MODE_ASYNC_CONTINUOUS);
|
|
|
|
if (status != BSP_ERROR_NONE)
|
|
{
|
|
printf("VL53L8A1_RANGING_SENSOR_Start failed\n");
|
|
while (1);
|
|
}
|
|
|
|
if (ToF_EventDetected != 0)
|
|
{
|
|
ToF_EventDetected = 0;
|
|
status = VL53L8A1_RANGING_SENSOR_GetDistance(VL53L8A1_DEV_CENTER, &Result);
|
|
if (status != BSP_ERROR_NONE)
|
|
{
|
|
APP_LOG(TS_OFF, VLEVEL_M, "\r\n x \r\n");
|
|
}
|
|
}
|
|
//STS_TOF_L8_Process();
|
|
|
|
|
|
APP_LOG(TS_OFF, VLEVEL_L, "\r\n ----------------------"
|
|
"\r\n------Threshold %d cm--\r\n", fhmos_cfg.th_gesture_mask_off_height_cm);
|
|
|
|
for (uint8_t i = 0; i < 64; i++)
|
|
{
|
|
/* Print distance and status */
|
|
if (i%8==0) APP_LOG(TS_OFF, VLEVEL_L, "\r\nPosition from Floor [cm]| ");
|
|
if ((Result.ZoneResult[i].NumberOfTargets > 0))
|
|
{
|
|
range_distance = (uint32_t)Result.ZoneResult[i].Distance[0];
|
|
|
|
fhmos_bg.h2cm[i] = abs(sts_sensor_install_height - range_distance)/20; // in 2 cm
|
|
|
|
if (2*fhmos_bg.h2cm[i] < fhmos_cfg.th_gesture_mask_off_height_cm)
|
|
{
|
|
fhmos_bg.maskoff[i] = 0;
|
|
} else
|
|
{
|
|
fhmos_bg.maskoff[i] = 1;
|
|
}
|
|
//sts_mask_bitmap[(uint8_t)(i/8)] |= (fhmos_bg.maskoff[i])<<(7-i%8);
|
|
sts_mask_bitmap[(uint8_t)(i/8)] |= (fhmos_bg.maskoff[i])<<(7-i%8); // 2025-JAN-03 update
|
|
// if (i%8==0) APP_LOG(TS_OFF, VLEVEL_M, "\r\n");
|
|
APP_LOG(TS_OFF, VLEVEL_L, "|%3d ", fhmos_bg.h2cm[i]*2);
|
|
|
|
}
|
|
else {
|
|
fhmos_bg.h2cm[i] = 0;
|
|
APP_LOG(TS_OFF, VLEVEL_L, "|%3d ", fhmos_bg.h2cm[i]);
|
|
}
|
|
|
|
}
|
|
APP_LOG(TS_OFF, VLEVEL_L, "\r\n Thresholds: Headlevel=%4d cm, Gesture Mask off=%d cm, Min body height=%d cm\r\n",
|
|
(uint8_t)fhmos_cfg.th_head_level_height_cm, (uint8_t)fhmos_cfg.th_gesture_mask_off_height_cm, (uint8_t)(fhmos_cfg.th_fall_body_min_height_cm));
|
|
|
|
APP_LOG(TS_OFF, VLEVEL_L, "\r\n\n ------- Mask off matrix \r\n");
|
|
/*
|
|
for (i=0; i<64; i++)
|
|
{
|
|
if (i%8==0) APP_LOG(TS_OFF, VLEVEL_L, "\r\n");
|
|
APP_LOG(TS_OFF, VLEVEL_L, "|%d ", (uint8_t)fhmos_bg.maskoff[i]);
|
|
}
|
|
*/
|
|
APP_LOG(TS_OFF, VLEVEL_L, "\r\n\n ------- Remove Edge \r\n");
|
|
|
|
uint8_t rio_edge[34]={0,1,2,3,4,5,6,7,8,15,16,23,24,31,32,39,40,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63};
|
|
|
|
for (i=0; i<sizeof(rio_edge); i++)
|
|
fhmos_bg.maskoff[rio_edge[i]] = 1;
|
|
|
|
|
|
for (i=0; i<64; i++)
|
|
{
|
|
if (i%8==0) APP_LOG(TS_OFF, VLEVEL_L, "\r\n");
|
|
APP_LOG(TS_OFF, VLEVEL_L, "|%d ", (uint8_t)fhmos_bg.maskoff[i]);
|
|
}
|
|
|
|
APP_LOG(TS_OFF, VLEVEL_L, "\r\n");
|
|
|
|
APP_LOG(TS_OFF, VLEVEL_M, "\r\nmask bitmap \r\n");
|
|
|
|
for (i=0; i<8; i++)
|
|
APP_LOG(TS_OFF, VLEVEL_L, "%02X\r\n",sts_mask_bitmap[i]);
|
|
|
|
|
|
#endif
|
|
}
|
|
|
|
void sts_generate_fall_gesture_map(void)
|
|
{
|
|
uint8_t i=0,head_xy=0, h4=0x0, l4=0x0;
|
|
uint32_t range_distance =0, sts_fall_head_position=8000; // assume max range 8000 mm, actual 4500mm
|
|
|
|
for (i=0; i<64; i++)
|
|
{
|
|
fhmos_gesture.h2cm[i] = 0;
|
|
fhmos_gesture.maskoff[i] = 0;
|
|
}
|
|
fhmos_gesture.head_level =2000; // 1000 mm
|
|
fhmos_gesture.head_xy = 28; //center of FOV
|
|
|
|
for (i=0;i<8;i++)
|
|
fhmos_gesture_bitmap[i]=0x0;
|
|
|
|
for (uint8_t i = 0; i < 64; i++)
|
|
{
|
|
if ((Result.ZoneResult[i].NumberOfTargets > 0) && (fhmos_bg.maskoff[i]==0))
|
|
{
|
|
range_distance = (uint32_t)Result.ZoneResult[i].Distance[0];
|
|
if (range_distance < sts_fall_head_position)
|
|
{
|
|
sts_fall_head_position = range_distance; // simply find out the head level
|
|
head_xy = i; // head x, y coordination in 8x8 matrix
|
|
}
|
|
fhmos_gesture.h2cm[i] = (uint8_t)abs(sts_sensor_install_height - range_distance)/20;
|
|
//fhmos_gesture.maskoff[i] = ((2*fhmos_gesture.h2cm[i])< fhmos_cfg.th_gesture_mask_off_height_cm)? 0:1;
|
|
fhmos_gesture.maskoff[i] = (fhmos_gesture.h2cm[i]==0)? 0:1;
|
|
fhmos_gesture_bitmap[(uint8_t)(i/8)] |= (fhmos_gesture.maskoff[i])<<(7 - i%8); // 2025-JAN-03 UPDATE
|
|
// debug
|
|
// if (i%8==0) printf("\r\n");
|
|
// printf("|%4ld %4d ", range_distance, fhmos_gesture.h2cm[i]);
|
|
}
|
|
else {
|
|
fhmos_gesture.h2cm[i] = 0;
|
|
}
|
|
if (i%8==0) APP_LOG(TS_OFF, VLEVEL_L, "\r\n");
|
|
APP_LOG(TS_OFF, VLEVEL_L, "|%4d ", fhmos_gesture.h2cm[i]);
|
|
}
|
|
|
|
for (i = 0; i < 64; i++)
|
|
{
|
|
if (i%8==0) APP_LOG(TS_OFF, VLEVEL_L, "\r\n");
|
|
APP_LOG(TS_OFF, VLEVEL_L, "|%d ", fhmos_gesture.maskoff[i]);
|
|
}
|
|
|
|
for (i=0; i<8; i++)
|
|
APP_LOG(TS_OFF, VLEVEL_L, "%02x ",fhmos_gesture_bitmap[i]);
|
|
|
|
APP_LOG(TS_OFF, VLEVEL_L, "\r\n");
|
|
for (i = 0; i < 32; i++)
|
|
{
|
|
|
|
if (i%4 == 0) APP_LOG(TS_OFF, VLEVEL_L, "\r\n");
|
|
//h4 = MIN(fhmos_gesture.h2cm[2*i+0],sts_gesture_mask_cap_height_2cm)/8;
|
|
//l4 = MIN(fhmos_gesture.h2cm[2*i+1],sts_gesture_mask_cap_height_2cm)/8;
|
|
h4 = fhmos_gesture.h2cm[2*i+0];
|
|
l4 = fhmos_gesture.h2cm[2*i+1];
|
|
fhmos_gesture.cube[i] = ((h4&0x0f)<<4)|(l4&0x0f);
|
|
APP_LOG(TS_OFF, VLEVEL_L, " [%2d_%2d]", (fhmos_gesture.cube[i]>>4)&0x0f, (fhmos_gesture.cube[i]&0x0f));
|
|
}
|
|
|
|
fhmos_gesture.head_level = 0xff&((sts_sensor_install_height - sts_fall_head_position)/10); // head level from floor in CM
|
|
fhmos_gesture.head_xy = head_xy&0xff;
|
|
|
|
|
|
APP_LOG(TS_OFF, VLEVEL_L, "\r\n Head level =%4d cm, Head_xy=%d X:Y = %2d : %2d \r\n", fhmos_gesture.head_level, head_xy, (head_xy%8), (head_xy/8));
|
|
APP_LOG(TS_OFF, VLEVEL_L, "\r\n Thresholds: Headlevel=%4d cm, Gesture Mask off=%d cm, Min body height=%d cm\r\n",
|
|
(uint8_t)fhmos_cfg.th_head_level_height_cm, (uint8_t)fhmos_cfg.th_gesture_mask_off_height_cm, (uint8_t)(fhmos_cfg.th_fall_body_min_height_cm));
|
|
#if 0
|
|
for (i=0; i<64; i++)
|
|
{
|
|
if (i%8==0) printf("\r\n");
|
|
printf("|%d ", (uint8_t)fhmos_gesture.maskoff[i]);
|
|
}
|
|
for (i=0; i<8; i++)
|
|
printf("%02X\r\n",fhmos_gesture_bitmap[i]);
|
|
#endif
|
|
|
|
sts_fhmos_bitmap_pending = 1;
|
|
APP_LOG(TS_OFF, VLEVEL_L, "\r\n Fall Gesture bitmap Generated\r\n");
|
|
}
|
|
uint16_t MX_TOF_Ranging_Process(void)
|
|
{
|
|
|
|
#if (defined(STS_P2)||defined(STS_T6))
|
|
uint16_t range_distance=0;
|
|
uint8_t range_mode = 2; //STS_TOF_LONG_RANGE;
|
|
STS_TOF_VL53LX_Range_Process(range_mode, &range_distance);
|
|
APP_LOG(TS_OFF, VLEVEL_M, "\n VL53L1 Range distance =%u mm \n\r", (uint16_t)range_distance);
|
|
|
|
return (uint16_t) range_distance;
|
|
#elif defined(L8)
|
|
uint32_t range_distance=0;
|
|
//uint8_t center_roi[4] = {27,28,35,36};
|
|
|
|
if (ToF_EventDetected != 0)
|
|
{
|
|
ToF_EventDetected = 0;
|
|
status = VL53L8A1_RANGING_SENSOR_GetDistance(VL53L8A1_DEV_CENTER, &Result);
|
|
|
|
if (status == BSP_ERROR_NONE)
|
|
{
|
|
range_distance= STS_Get_Center_Range_Distance(&Result);
|
|
} else {
|
|
|
|
APP_LOG(TS_OFF, VLEVEL_M, "\r\n status=%d, x \r\n", status);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
return (uint16_t) range_distance;
|
|
#endif
|
|
|
|
}
|
|
void MX_TOF_Process(void)
|
|
{
|
|
/* USER CODE BEGIN TOF_Process_PreTreatment */
|
|
|
|
/* USER CODE END TOF_Process_PreTreatment */
|
|
|
|
|
|
//APP_LOG(TS_OFF,VLEVEL_L,"\r\n# MX TOF Process... #\r\n");
|
|
//STS_TOF_VL53LX_Range_Process();
|
|
//STS_TOF_VL53LX_PeopleCounting_Process();
|
|
|
|
//sts_tof_vl53lx_peoplecount_subprocess();
|
|
#ifdef L8
|
|
MX_53L8A1_ThresholdDetection_Process();
|
|
|
|
//STS_TOF_L8_Process();
|
|
#endif
|
|
|
|
/* USER CODE BEGIN TOF_Process_PostTreatment */
|
|
|
|
/* USER CODE END TOF_Process_PostTreatment */
|
|
}
|
|
#ifdef L8
|
|
|
|
void STS_TOF_L8_Init(void)
|
|
{
|
|
MX_53L8A1_ThresholdDetection_Init();
|
|
MX_53L8A1_ThresholdDetection_Process();
|
|
}
|
|
|
|
void STS_TOF_L8_Process(void)
|
|
{
|
|
//while (1)
|
|
{
|
|
/* interrupt mode */
|
|
if (ToF_EventDetected != 0)
|
|
{
|
|
ToF_EventDetected = 0;
|
|
#if 1
|
|
if (STS_Status_Door_Close == sts_hall1_read)
|
|
{
|
|
status = VL53L8A1_RANGING_SENSOR_GetDistance(VL53L8A1_DEV_CENTER, &Result);
|
|
if (status == BSP_ERROR_NONE)
|
|
{
|
|
print_result(&Result);
|
|
} else {
|
|
APP_LOG(TS_OFF, VLEVEL_M, "\r\n x \r\n");
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
|
|
void STS_TOF_L8_Reconfig(void)
|
|
{
|
|
MX_53L8A1_ThresholdDetection_ConfigIT(sts_low_threshold, sts_high_threshold);
|
|
}
|
|
|
|
|
|
/* VL53L8A1 */
|
|
static void MX_53L8A1_ThresholdDetection_Init(void)
|
|
{
|
|
/* Initialize Virtual COM Port */
|
|
//BSP_COM_Init(COM1);
|
|
MX_USART2_UART_Init();
|
|
|
|
/* Sensor reset */
|
|
HAL_GPIO_WritePin(VL53L8A1_PWR_EN_C_PORT, VL53L8A1_PWR_EN_C_PIN, GPIO_PIN_RESET);
|
|
HAL_Delay(2);
|
|
HAL_GPIO_WritePin(VL53L8A1_PWR_EN_C_PORT, VL53L8A1_PWR_EN_C_PIN, GPIO_PIN_SET);
|
|
HAL_Delay(2);
|
|
|
|
HAL_GPIO_WritePin(VL53L8A1_LPn_C_PORT, VL53L8A1_LPn_C_PIN, GPIO_PIN_RESET);
|
|
HAL_Delay(2);
|
|
HAL_GPIO_WritePin(VL53L8A1_LPn_C_PORT, VL53L8A1_LPn_C_PIN, GPIO_PIN_SET);
|
|
HAL_Delay(2);
|
|
|
|
|
|
status = VL53L8A1_RANGING_SENSOR_Init(VL53L8A1_DEV_CENTER);
|
|
|
|
if (status != BSP_ERROR_NONE)
|
|
{
|
|
printf("VL53L8A1_RANGING_SENSOR_Init failed\n");
|
|
//while (1);
|
|
}
|
|
|
|
}
|
|
void MX_53L8A1_ThresholdDetection_ConfigIT(uint32_t low_threshold, uint32_t high_threshold)
|
|
{
|
|
|
|
RANGING_SENSOR_ITConfig_t ITConfig;
|
|
|
|
status = VL53L8A1_RANGING_SENSOR_Stop(VL53L8A1_DEV_CENTER);
|
|
|
|
/* threshold parameters */
|
|
ITConfig.Criteria = RS_IT_IN_WINDOW;
|
|
ITConfig.LowThreshold = low_threshold; /* mm */
|
|
ITConfig.HighThreshold = high_threshold; /* mm */
|
|
|
|
VL53L8A1_RANGING_SENSOR_ConfigIT(VL53L8A1_DEV_CENTER, &ITConfig);
|
|
|
|
status = VL53L8A1_RANGING_SENSOR_Start(VL53L8A1_DEV_CENTER, RS_MODE_ASYNC_CONTINUOUS);
|
|
|
|
if (status != BSP_ERROR_NONE)
|
|
{
|
|
printf("VL53L8A1_RANGING_SENSOR_Start failed\n");
|
|
while (1);
|
|
}
|
|
}
|
|
|
|
static void MX_53L8A1_ThresholdDetection_Process(void)
|
|
{
|
|
uint32_t Id;
|
|
|
|
RANGING_SENSOR_ITConfig_t ITConfig;
|
|
|
|
VL53L8A1_RANGING_SENSOR_ReadID(VL53L8A1_DEV_CENTER, &Id);
|
|
VL53L8A1_RANGING_SENSOR_GetCapabilities(VL53L8A1_DEV_CENTER, &Cap);
|
|
|
|
Profile.RangingProfile = RS_PROFILE_8x8_AUTONOMOUS;
|
|
Profile.TimingBudget = TIMING_BUDGET;
|
|
Profile.Frequency = RANGING_FREQUENCY; /* Ranging frequency Hz (shall be consistent with TimingBudget value) */
|
|
Profile.EnableAmbient = 0; /* Enable: 1, Disable: 0 */
|
|
Profile.EnableSignal = 0; /* Enable: 1, Disable: 0 */
|
|
|
|
/* set the profile if different from default one */
|
|
VL53L8A1_RANGING_SENSOR_ConfigProfile(VL53L8A1_DEV_CENTER, &Profile);
|
|
|
|
/* threshold parameters */
|
|
ITConfig.Criteria = RS_IT_IN_WINDOW;
|
|
//ITConfig.LowThreshold = LOW_THRESHOLD; /* mm */
|
|
//ITConfig.HighThreshold = HIGH_THRESHOLD; /* mm */
|
|
|
|
sts_high_threshold = sts_sensor_install_height;
|
|
sts_low_threshold = sts_high_threshold - 1400;
|
|
APP_LOG(TS_OFF, VLEVEL_M, "\r\n Threshold High=%4d, Low=%4d \r\n", sts_high_threshold, sts_low_threshold);
|
|
|
|
ITConfig.LowThreshold = sts_low_threshold;
|
|
ITConfig.HighThreshold = sts_high_threshold;
|
|
|
|
|
|
VL53L8A1_RANGING_SENSOR_ConfigIT(VL53L8A1_DEV_CENTER, &ITConfig);
|
|
|
|
|
|
status = VL53L8A1_RANGING_SENSOR_Start(VL53L8A1_DEV_CENTER, RS_MODE_ASYNC_CONTINUOUS);
|
|
|
|
if (status != BSP_ERROR_NONE)
|
|
{
|
|
printf("VL53L8A1_RANGING_SENSOR_Start failed\n");
|
|
while (1);
|
|
}
|
|
#if 0
|
|
printf("\033[2H\033[2J");
|
|
printf("53L8A1 Threshold Detection demo application\n\r");
|
|
printf("-------------------------------------------\n\r");
|
|
printf("please put a target between %d and %d millimeters from the sensor\n\r",
|
|
LOW_THRESHOLD, HIGH_THRESHOLD);
|
|
#endif
|
|
|
|
#if 0
|
|
while (1)
|
|
{
|
|
/* interrupt mode */
|
|
if (ToF_EventDetected != 0)
|
|
{
|
|
ToF_EventDetected = 0;
|
|
|
|
status = VL53L8A1_RANGING_SENSOR_GetDistance(VL53L8A1_DEV_CENTER, &Result);
|
|
|
|
if (status == BSP_ERROR_NONE)
|
|
{
|
|
print_result(&Result);
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
uint32_t STS_Get_Center_Range_Distance(RANGING_SENSOR_Result_t *Result)
|
|
{
|
|
uint32_t center_range_distance=0, sumd=0;
|
|
uint8_t center_roi[4] = {27,28,35,36}, valid_cnt=0;
|
|
|
|
for (uint8_t i=0; i<4; i++)
|
|
{
|
|
//APP_LOG(TS_OFF, VLEVEL_M, "\r\n ROI#=%d Target=%d, Distance=%d \r\n", center_roi[i], Result->ZoneResult[center_roi[i]].NumberOfTargets, Result->ZoneResult[center_roi[i]].Distance[0]);
|
|
if (Result->ZoneResult[center_roi[i]].NumberOfTargets > 0)
|
|
{
|
|
sumd += (uint32_t)(Result->ZoneResult[center_roi[i]].Distance[0]);
|
|
valid_cnt ++;
|
|
}
|
|
//APP_LOG(TS_OFF, VLEVEL_M, "\r\n CNT=%d, SUM Distance=%d \r\n", valid_cnt, sumd);
|
|
}
|
|
|
|
if (valid_cnt > 2)
|
|
center_range_distance = sumd/valid_cnt;
|
|
|
|
//APP_LOG(TS_OFF, VLEVEL_M, "\r\n Center Range Average=%d mm\r\n", center_range_distance);
|
|
return center_range_distance;
|
|
}
|
|
|
|
static void print_result(RANGING_SENSOR_Result_t *Result)
|
|
{
|
|
int8_t i;
|
|
|
|
uint16_t head_distance_from_ceiling=8000;
|
|
//printf("%c[2H", 27); /* clear screen */
|
|
uint16_t factor1_floor_level_from_ceiling = sts_sensor_install_height; // 50mm min body height
|
|
uint16_t factor2_head_level_from_floor = (10*fhmos_cfg.th_head_level_height_cm); //(sts_sensor_install_height - 10*fhmos_cfg.th_head_level_height_cm);
|
|
uint16_t head_height_level_from_floor=0;
|
|
|
|
sts_head_level_low = 0;
|
|
|
|
/*
|
|
//APP_LOG(TS_OFF, VLEVEL_M, "\r\n Eliminate edge \r\n");
|
|
uint8_t rio_edge[36]={0,1,2,3,4,5,6,7,8,15,16,23,24,31,32,39,40,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63};
|
|
|
|
for (i=0; i<36; i++)
|
|
fhmos_bg.maskoff[rio_edge[i]] = 1;
|
|
*/
|
|
for (i=0; i<64; i++)
|
|
{
|
|
if (0 == fhmos_bg.maskoff[i]) // only within the non-mask-off blocks
|
|
{ // Result.ZoneResult[i].NumberOfTargets > 0)
|
|
if ((Result->ZoneResult[i].Distance[0] < head_distance_from_ceiling)&& (Result->ZoneResult[i].NumberOfTargets > 0))
|
|
head_distance_from_ceiling = Result->ZoneResult[i].Distance[0];
|
|
// find out the min_distance or the highest position level
|
|
}
|
|
}
|
|
|
|
|
|
head_height_level_from_floor = MIN(1400, abs(sts_sensor_install_height - head_distance_from_ceiling));
|
|
|
|
APP_LOG(TS_OFF, VLEVEL_L, "\r\n Raw Head height=%d cm Calculated head level=%d cm\r\n", head_distance_from_ceiling, head_height_level_from_floor );
|
|
|
|
/* state tree */
|
|
|
|
if ((head_distance_from_ceiling <= factor1_floor_level_from_ceiling) && ((head_height_level_from_floor) <= (10*fhmos_cfg.th_head_level_height_cm)) && (head_height_level_from_floor >= (10*fhmos_cfg.th_fall_body_min_height_cm )))
|
|
{
|
|
to_confirm ++;
|
|
if (to_confirm >=3 )
|
|
{
|
|
sts_head_level_low = 1;
|
|
// to_confirm = 0;
|
|
}
|
|
|
|
} else if ((head_distance_from_ceiling < (factor2_head_level_from_floor - 150))) // TODO XXX 50mm gap to avoid flapping back and forth
|
|
{
|
|
sts_head_level_low = 0;
|
|
sts_fhmos_bitmap_pending = 0;
|
|
to_confirm = 0;
|
|
}
|
|
|
|
|
|
|
|
OnSensorL8AStateChanged();
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
#ifdef L8
|
|
/* Represent Color Value Definition
|
|
* Fall Blue 0 The Room is not occupied by Human
|
|
* Green 1 Human in room in normal level (head above 700 mmH from floor level)
|
|
* Yellow 2 Human in low level position for short time potential (Head below 700mmH from floor level
|
|
* Red 3 Human in low level position with time longer than threshold, e.g. 4 mins.(Head below 700 mm from Floor level
|
|
* Human
|
|
* Movement Blue 0 The Room is not occupied by Human
|
|
* Green 1 The room is occupied by human, with movement
|
|
* Yellow 2 The room is occupied by human, with motionless for short period of time (???)
|
|
* Red 3 The room is occupied by human, with motionless for a period of time longer than threshold period, e.g. 5min.
|
|
*
|
|
* Occupancy Blue 0 The room is not occupied by Human
|
|
* Green 1 The room is occupied by human, with movement
|
|
* Red 2 The room is occupied by human, for a short period of time (???)
|
|
*
|
|
* # height is configurable from 10cm to 90 cm, with interval of 1cm
|
|
* # the period of time is configurable, from 1 min to 30 mins, with 15 sec as interval
|
|
*
|
|
* sts_height_threshold (10cm --90 cm, 1cm interval) (10cm=10, 90cm=90, "P11T1XXX"
|
|
* sts_fall_duration_threshold_potential (1 min to 30 min. 15 sec interval, 1800 sec. 1800=15*120, 60=15*4) "P11T2XXX"
|
|
* sts_fall_duration_threshold_confirm (1 min to 30 min. 15 sec interval, 1800 sec. 1800=15*120, 60=15*4) "P11T3XXX"
|
|
*
|
|
* sts_motionless_threshold_short (1 min to 30 min. 15 sec interval, 1800 sec. 1800=15*120, 60=15*4) "P11T4XXX"
|
|
* sts_motionless_threshold_long (1 min to 30 min. 15 sec interval, 1800 sec. 1800=15*120, 60=15*4) "P11T5XXX"
|
|
*
|
|
* sts_occupancy_threshold_overstay (1 min to 30 min. 15 sec interval, 1800 sec. 1800=15*120, 60=15*4) "P11T6XXX"
|
|
*
|
|
*/
|
|
|
|
void STS_FHMOS_sensor_read(sts_fhmos_sensor_data_t *sts_data)
|
|
{
|
|
//uint8_t fhmos_fall=0, fhmos_human_movement=0, fhmos_occupancy=0, fhmos_sos_alarm=0;
|
|
sts_data->state_occupancy = fhmos_data.state_occupancy;
|
|
sts_data->state_fall = fhmos_data.state_fall;
|
|
sts_data->state_human_movement = fhmos_data.state_human_movement;
|
|
sts_data->state_sos_alarm = fhmos_data.state_sos_alarm;
|
|
sts_data->time_stamp_fall_confirmed = fhmos_data.time_stamp_fall_confirmed;
|
|
sts_data->time_stamp_motionless_confirmed = fhmos_data.time_stamp_motionless_confirmed;
|
|
sts_data->time_stamp_overstay_confirmed = fhmos_data.time_stamp_overstay_confirmed;
|
|
sts_data->time_stamp_fall_released = fhmos_data.time_stamp_fall_released;
|
|
sts_data->time_stamp_overstay_released = fhmos_data.time_stamp_overstay_released;
|
|
sts_data->time_stamp_motionless_released= fhmos_data.time_stamp_motionless_released;
|
|
sts_data->state_fall_released = fhmos_data.state_fall_released;
|
|
sts_data->state_occupancy_released = fhmos_data.state_occupancy_released;
|
|
sts_data->state_human_movement_released = fhmos_data.state_human_movement_released;
|
|
|
|
sts_data->lamp_bar_color = sts_lamp_bar_color;
|
|
sts_data->state_hall_1 = sts_hall1_read;
|
|
sts_data->state_hall_2 = sts_hall2_read;
|
|
sts_data->state_PIR = sts_pir_read;;
|
|
//sts_data->state_PIR = fhmos_data.state_PIR;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
#if defined(STS_P2)||defined(STS_T6)||defined(L8)
|
|
uint8_t IsInterruptDetected(uint16_t dev)
|
|
{
|
|
// To be filled with customer HW. This function should
|
|
// return 1 when an interrupt is raised by the ToF on GPIO1 pin (pin7)
|
|
if (ToF_EventDetected )
|
|
{
|
|
APP_LOG(TS_OFF, VLEVEL_M,"############### TOF EVENT DETECTED \r\n");
|
|
ToF_EventDetected =0;
|
|
return 1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#if (defined(STS_P2)||defined(STS_T6))
|
|
void STS_TOF_VL53LX_Range_Process(uint8_t range_mode, uint16_t *range_distance)
|
|
{
|
|
//uint8_t vl53lx_model = STS_TOF_VL53L1X;
|
|
//uint8_t range_mode = STS_TOF_SHORT_RANGE;
|
|
uint16_t i_distance_measured = 0;
|
|
uint16_t i_distance_threshold_mm = 800;
|
|
uint16_t i_inter_measurement_ms=100, i_macro_timing=33;
|
|
uint16_t i_roi_width=16, i_sigma_mm=30, i_signal_kcps=2000;
|
|
|
|
switch (range_mode)
|
|
{
|
|
case STS_TOF_SHORT_RANGE:
|
|
// STS ---002 for short distance
|
|
/* Example for robust and short distance measurements. Max distance reduced
|
|
* but very low number of false-positives */
|
|
//status |= VL53L1X_ULP_SetSigmaThreshold(dev, 30);
|
|
//status |= VL53L1X_ULP_SetSignalThreshold(dev, 2000);
|
|
i_sigma_mm = 30; //increase this for longer distance, reduce for shorter distance
|
|
i_signal_kcps = 2000; // 1000- 6000 kcps
|
|
i_distance_threshold_mm = 900;
|
|
i_inter_measurement_ms = 100; // 100 - 1000 ms
|
|
i_macro_timing = 100;
|
|
//i_roi_width = 16;
|
|
|
|
break;
|
|
|
|
case STS_TOF_LONG_RANGE:
|
|
// STS --- 003 for long range
|
|
/* Relax some limits. Be careful, it can create false-positives !*/
|
|
//status |= VL53L1X_ULP_SetSigmaThreshold(dev, 60);
|
|
//status |= VL53L1X_ULP_SetSignalThreshold(dev, 1200);
|
|
i_sigma_mm = 85; // increase this for longer distance, reduce for short distance
|
|
i_signal_kcps = 1000; // 1000- 6000 kcps
|
|
i_distance_threshold_mm = 4000; //4000;
|
|
i_inter_measurement_ms = 200; // 100 - 1000 ms
|
|
i_macro_timing = 30; // 1 - 100 ms
|
|
i_roi_width = 8;
|
|
|
|
|
|
break;
|
|
|
|
case STS_TOF_LOW_POWER_RANGE:
|
|
// STS---001 for ultra low power
|
|
/* Reduce the macro timing to minimum. This is equivalent as reducing the integration time */
|
|
//status = VL53L1X_ULP_SetMacroTiming(dev, 1);
|
|
i_distance_threshold_mm = 4000;
|
|
i_inter_measurement_ms = 100; // 100 - 1000 ms
|
|
i_macro_timing = 1;
|
|
/* Reduce at maximum the SPADS */
|
|
//status = VL53L1X_ULP_SetROI(dev, 4);
|
|
i_roi_width = 4;
|
|
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
sts_vl53lx_ranging(&i_distance_measured, range_mode, i_distance_threshold_mm, i_inter_measurement_ms,i_macro_timing, i_roi_width, i_sigma_mm, i_signal_kcps);
|
|
APP_LOG(TS_OFF, VLEVEL_M, "I_DISTANCE_MEASURED = %d \n", i_distance_measured);
|
|
*range_distance = i_distance_measured;
|
|
|
|
}
|
|
|
|
void BSP_PB_Callback(Button_TypeDef Button)
|
|
{
|
|
//PushButtonDetected = 1;
|
|
}
|
|
|
|
|
|
uint8_t sts_vl53lx_ranging(uint16_t *ranged_distance, uint8_t range_mode, uint16_t distance_threshold_mm, uint16_t inter_measurement_ms, uint16_t macro_timing,
|
|
uint16_t roi_width, uint16_t sigma_mm, uint16_t signal_kcps)
|
|
{
|
|
uint8_t status=0, dev=0x52;
|
|
uint16_t estimated_distance_mm=0;
|
|
status = VL53L1X_SensorInit(dev);
|
|
status += VL53L1X_SetDistanceMode(dev, 2); /* 1=short, 2=long, DISTANCE_MODE */
|
|
status += VL53L1X_SetTimingBudgetInMs(dev, 100); /* TIMING_BUDGET, in ms possible values [15, 20, 50, 100, 200, 500] */
|
|
status += VL53L1X_SetInterMeasurementInMs(dev, 50);
|
|
status += VL53L1X_SetROI(dev, 8, 8); /* minimum ROI 4,4 */
|
|
if (status != 0) {
|
|
APP_LOG(TS_OFF, VLEVEL_L,"Initialization or configuration of the device\n");
|
|
return (-1);
|
|
}
|
|
status = VL53L1X_StartRanging(dev); /* This function has to be called to enable the ranging */
|
|
if (status != 0) {
|
|
APP_LOG(TS_OFF, VLEVEL_L,"Start Range failed\n");
|
|
return (-1);
|
|
}
|
|
|
|
status = VL53L1X_GetDistance(dev, &estimated_distance_mm);
|
|
APP_LOG(TS_OFF,VLEVEL_M,"Target detected! Distance =%d mm \r\n", estimated_distance_mm );
|
|
*ranged_distance = estimated_distance_mm;
|
|
status = VL53L1X_StopRanging(dev);
|
|
APP_LOG(TS_OFF,VLEVEL_M,"End of VL53L1X Ranging Process\n");
|
|
return status;
|
|
|
|
#if 0
|
|
/*********************************/
|
|
/* VL53L1X ranging variables */
|
|
/*********************************/
|
|
uint8_t status, loop;
|
|
uint8_t dev;
|
|
//uint16_t sensor_id=0;
|
|
uint8_t measurement_status;
|
|
uint16_t estimated_distance_mm, r_signal_kcps, r_sigma_mm, r_ambient_kcps;
|
|
/*********************************/
|
|
/* Customer platform */
|
|
/*********************************/
|
|
/* Default VL53L1X Ultra Low Power I2C address */
|
|
dev = 0x52;
|
|
|
|
/* (Optional) Change I2C address */
|
|
// status = VL53L1X_ULP_SetI2CAddress(dev, 0x52);
|
|
// dev = 0x20;
|
|
|
|
/*********************************/
|
|
/* Power on sensor and init */
|
|
/*********************************/
|
|
APP_LOG(TS_OFF,VLEVEL_L,"Range Mode =%d \r\n",range_mode);
|
|
/* (Optional) Check if there is a VL53L1X sensor connected */
|
|
status = VL53L1X_GetSensorId(dev, &sensor_id);
|
|
APP_LOG(TS_OFF,VLEVEL_L,"VL53L1X address =%X\r\n",sensor_id );
|
|
if(status || (sensor_id != 0xEACC))
|
|
{
|
|
APP_LOG(TS_OFF,VLEVEL_L,"VL53L1X not detected at requested address\n");
|
|
return status;
|
|
}
|
|
/* (Mandatory) Init VL53L1X sensor */
|
|
status = VL53L1X_SensorInit(dev);
|
|
if(status)
|
|
{
|
|
APP_LOG(TS_OFF,VLEVEL_L,"VL53L1X ultra low power Loading failed\n");
|
|
//HAL_Delay(100);
|
|
return status;
|
|
}
|
|
APP_LOG(TS_OFF,VLEVEL_L,"VL53L1X ultra low power ready ! \r\n");
|
|
/*********************************/
|
|
/* Sensor configuration */
|
|
/*********************************/
|
|
/* (Optional) Program sensor to raise an interrupt ONLY below 300mm */
|
|
//status = VL53L1X_SetInterruptConfiguration(dev, distance_threshold_mm, 1); //i_distance_threshold_mm
|
|
status = VL53L1X_SetDistanceThreshold(dev, distance_threshold_mm,distance_threshold_mm, 0,1); //i_distance_threshold_mm
|
|
/* (Optional) Program a 10Hz ranging frequency */
|
|
status = VL53L1X_SetInterMeasurementInMs(dev, inter_measurement_ms); // range_interval_ms
|
|
/* Increase the macro timing. This is equivalent as increasing the integration time */
|
|
//status = VL53L1X_SetMacroTiming(dev, macro_timing); // micro_timing_ms
|
|
status = VL53L1X_SetTimingBudgetInMs(dev, macro_timing);
|
|
/* Enable all the SPADS */
|
|
status = VL53L1X_SetROI(dev, roi_width, roi_width); // SPADS { 1 -- 16 }
|
|
|
|
if(range_mode != STS_TOF_LOW_POWER_RANGE)
|
|
{
|
|
/* Example for robust and short distance measurements. Max distance reduced
|
|
* but very low number of false-positives */
|
|
status |= VL53L1X_SetSigmaThreshold(dev, sigma_mm);
|
|
status |= VL53L1X_SetSignalThreshold(dev, signal_kcps);
|
|
}
|
|
|
|
/*********************************/
|
|
/* Ranging loop */
|
|
/*********************************/
|
|
status = VL53L1X_StartRanging(dev);
|
|
if(status)
|
|
{
|
|
APP_LOG(TS_OFF,VLEVEL_L,"VL53L1X_ULP_StartRanging failed with status %u\n", status);
|
|
return status;
|
|
}
|
|
APP_LOG(TS_OFF,VLEVEL_L,"Ranging started. Put your hand close to the sensor to generate an interrupt...\n");
|
|
loop = 0;
|
|
while(loop < 20)
|
|
{
|
|
/* Use this external function to detect when a hardware interrupt is generated on PIN 7 (GPIO1). It means that a new measurement is ready.
|
|
*/
|
|
|
|
if(IsInterruptDetected(dev))
|
|
{
|
|
/* (Mandatory) Clear HW interrupt to restart measurements */
|
|
VL53L1X_ClearInterrupt(dev);
|
|
/* Dump debug data */
|
|
#if 0
|
|
status = VL53L1X_DumpDebugData(dev, &measurement_status,
|
|
&estimated_distance_mm, &r_sigma_mm, &r_signal_kcps, &r_ambient_kcps);
|
|
*ranged_distance = estimated_distance_mm;
|
|
APP_LOG(TS_OFF,VLEVEL_L,"Target detected! Interrupt raised by sensor, Distance =%d mm \r\n", estimated_distance_mm );
|
|
#endif
|
|
status = VL53L1X_GetDistance(dev, &estimated_distance_mm);
|
|
APP_LOG(TS_OFF,VLEVEL_L,"Target detected! Interrupt raised by sensor, Distance =%d mm \r\n", estimated_distance_mm );
|
|
loop++;
|
|
}
|
|
}
|
|
|
|
status = VL53L1X_StopRanging(dev);
|
|
APP_LOG(TS_OFF,VLEVEL_L,"End of VL53L1X ultra low power demo\n");
|
|
return status;
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|