STS_P2 #1

Merged
sundp merged 4 commits from STS_P2 into RM2_1 2024-08-28 12:48:15 +08:00
44 changed files with 7203 additions and 1737 deletions

View File

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>STS_O7</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
</buildSpec>
<natures>
</natures>
</projectDescription>

51
Core/Inc/i2c.h Normal file
View File

@ -0,0 +1,51 @@
/**
******************************************************************************
* @file i2c.h
* @brief This file contains all the function prototypes for
* the i2c.c file
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __I2C_H__
#define __I2C_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
void MX_I2C2_Init(void);
/* USER CODE BEGIN Prototypes */
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /* __I2C_H__ */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -41,7 +41,7 @@
/*#define HAL_DAC_MODULE_ENABLED */
/*#define HAL_GTZC_MODULE_ENABLED */
/*#define HAL_HSEM_MODULE_ENABLED */
/*#define HAL_I2C_MODULE_ENABLED */
#define HAL_I2C_MODULE_ENABLED
/*#define HAL_I2S_MODULE_ENABLED */
/*#define HAL_IPCC_MODULE_ENABLED */
/*#define HAL_IRDA_MODULE_ENABLED */

200
Core/Src/i2c.c Normal file
View File

@ -0,0 +1,200 @@
/**
******************************************************************************
* @file i2c.c
* @author Yunhorn (r) Technology Limited Application Team
* @brief This file provides code for the configuration
* of the I2C instances.
******************************************************************************
* @attention
*
* Copyright (c) 2023 Yunhorn Technology Limited.
* Copyright (c) 2023 Shenzhen Yunhorn Technology Co., Ltd.
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "i2c.h"
#include "main.h"
#include "yunhorn_sts_prd_conf.h"
/* USER CODE BEGIN 0 */
I2C_HandleTypeDef hi2c2;
DMA_HandleTypeDef hdma_i2c2_rx;
DMA_HandleTypeDef hdma_i2c2_tx;
/* USER CODE END 0 */
/* I2C2 init function */
/**
* @brief I2C2 Initialization Function
* @param None
* @retval None
*/
void MX_I2C2_Init(void)
{
/* USER CODE BEGIN I2C2_Init 0 */
/* USER CODE END I2C2_Init 0 */
/* USER CODE BEGIN I2C2_Init 1 */
/* USER CODE END I2C2_Init 1 */
hi2c2.Instance = I2C2;
//hi2c2.Init.Timing = 0x20303E5D; //0x2010091A = 400K Fast Mode, 0x20303E5D, 100K Standard mode, 0x20000209 Fast Mode Plus, 1Mbps
hi2c2.Init.Timing = I2C2_STANDARD_100K; //2024-07-12 UPDATE
hi2c2.Init.OwnAddress1 = 0;
hi2c2.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c2.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c2.Init.OwnAddress2 = 0;
hi2c2.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
hi2c2.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c2.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
if (HAL_I2C_Init(&hi2c2) != HAL_OK)
{
Error_Handler();
}
/** Configure Analogue filter
*/
if (HAL_I2CEx_ConfigAnalogFilter(&hi2c2, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
{
Error_Handler();
}
/** Configure Digital filter
*/
if (HAL_I2CEx_ConfigDigitalFilter(&hi2c2, 0) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN I2C2_Init 2 */
/* USER CODE END I2C2_Init 2 */
}
void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
if(i2cHandle->Instance==I2C2)
{
/* USER CODE BEGIN I2C2_MspInit 0 */
/* USER CODE END I2C2_MspInit 0 */
/** Initializes the peripherals clocks
*/
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_I2C2;
PeriphClkInitStruct.I2c2ClockSelection = RCC_I2C2CLKSOURCE_PCLK1;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
Error_Handler();
}
__HAL_RCC_GPIOA_CLK_ENABLE();
/**I2C2 GPIO Configuration
PA12 ------> I2C2_SCL
PA11 ------> I2C2_SDA
*/
GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_11;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_NOPULL; //GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF4_I2C2;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* I2C2 clock enable */
__HAL_RCC_I2C2_CLK_ENABLE();
/* I2C2 DMA Init */
/* I2C2_RX Init */
hdma_i2c2_rx.Instance = DMA1_Channel4;
hdma_i2c2_rx.Init.Request = DMA_REQUEST_I2C2_RX;
hdma_i2c2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_i2c2_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_i2c2_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_i2c2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_i2c2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_i2c2_rx.Init.Mode = DMA_NORMAL;
hdma_i2c2_rx.Init.Priority = DMA_PRIORITY_LOW;
if (HAL_DMA_Init(&hdma_i2c2_rx) != HAL_OK)
{
Error_Handler();
}
#ifdef STM32WL55xx
if (HAL_DMA_ConfigChannelAttributes(&hdma_i2c2_rx, DMA_CHANNEL_NPRIV) != HAL_OK)
{
Error_Handler();
}
#endif
__HAL_LINKDMA(i2cHandle,hdmarx,hdma_i2c2_rx);
/* I2C2_TX Init */
hdma_i2c2_tx.Instance = DMA1_Channel5;
hdma_i2c2_tx.Init.Request = DMA_REQUEST_I2C2_TX;
hdma_i2c2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_i2c2_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_i2c2_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_i2c2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_i2c2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_i2c2_tx.Init.Mode = DMA_NORMAL;
hdma_i2c2_tx.Init.Priority = DMA_PRIORITY_LOW;
if (HAL_DMA_Init(&hdma_i2c2_tx) != HAL_OK)
{
Error_Handler();
}
#ifdef STM32WL55xx
if (HAL_DMA_ConfigChannelAttributes(&hdma_i2c2_tx, DMA_CHANNEL_NPRIV) != HAL_OK)
{
Error_Handler();
}
#endif
__HAL_LINKDMA(i2cHandle,hdmatx,hdma_i2c2_tx);
/* USER CODE BEGIN I2C2_MspInit 1 */
/* USER CODE END I2C2_MspInit 1 */
}
}
void HAL_I2C_MspDeInit(I2C_HandleTypeDef* i2cHandle)
{
if(i2cHandle->Instance==I2C2)
{
/* USER CODE BEGIN I2C2_MspDeInit 0 */
/* USER CODE END I2C2_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_I2C2_CLK_DISABLE();
/**I2C2 GPIO Configuration
PA12 ------> I2C2_SCL
PA11 ------> I2C2_SDA
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_12);
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_11);
/* I2C2 DMA DeInit */
HAL_DMA_DeInit(i2cHandle->hdmarx);
HAL_DMA_DeInit(i2cHandle->hdmatx);
/* USER CODE BEGIN I2C2_MspDeInit 1 */
/* USER CODE END I2C2_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -1,224 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file: main.c *
* @author Yunhorn (r) Technology Limited Application Team *
* @brief Yunhorn (r) SmarToilets (r) Product configuration file. *
******************************************************************************
* @attention
*
* Copyright (c) 2023 Yunhorn Technology Limited.
* Copyright (c) 2023 Shenzhen Yunhorn Technology Co., Ltd.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "app_lorawan.h"
#include "gpio.h"
#include "usart.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "yunhorn_sts_sensors.h"
#include "sts_cmox_hmac_sha.h"
#include "spi.h"
#include "dma.h"
#include "tim.h"
#include "sts_lamp_bar.h"
#include "sys_app.h"
#include "acc_hal_integration.h"
#include "example_bring_up.h"
#include "example_multiple_service_usage.h"
#include "example_detector_distance.h"
#include "example_detector_presence.h"
#include "example_detector_distance_recorded.h"
#include "example_service_sparse.h"
#include "ref_app_wave_to_exit.h"
#include "ref_app_smart_presence.h"
#include "ref_app_tank_level.h"
#include "ref_app_parking.h"
#include "acc_detector_presence.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
MX_GPIO_Init();
MX_DMA_Init();
MX_USART2_UART_Init();
MX_TIM1_Init();
MX_SPI1_Init();
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_LoRaWAN_Init();
/* USER CODE BEGIN 2 */
STS_Lamp_Bar_Self_Test_Simple();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
MX_LoRaWAN_Process();
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Configure LSE Drive Capability
*/
HAL_PWR_EnableBkUpAccess();
__HAL_RCC_LSEDRIVE_CONFIG(RCC_LSEDRIVE_LOW);
/** Configure the main internal regulator output voltage
*/
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE|RCC_OSCILLATORTYPE_MSI;
RCC_OscInitStruct.LSEState = RCC_LSE_ON;
RCC_OscInitStruct.MSIState = RCC_MSI_ON;
RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;
RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_11;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Configure the SYSCLKSource, HCLK, PCLK1 and PCLK2 clocks dividers
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK3|RCC_CLOCKTYPE_HCLK
|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1
|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.AHBCLK3Divider = RCC_SYSCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
}
/* USER CODE BEGIN 4 */
/* USER CODE END 4 */
/**
* @brief This function is executed in case of error occurrence.
* @retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
while (1)
{
}
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
while (1)
{
}
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

View File

@ -1,315 +0,0 @@
int sts_presence_rss_fall_rise_detection(void)
{
const acc_hal_t *hal = acc_hal_integration_get_implementation();
if (!acc_rss_activate(hal))
{
APP_LOG(TS_OFF, VLEVEL_H,"Failed to activate RSS\n");
return EXIT_FAILURE;
}
acc_rss_override_sensor_id_check_at_creation(true);
acc_detector_presence_configuration_t presence_configuration = acc_detector_presence_configuration_create();
if (presence_configuration == NULL)
{
APP_LOG(TS_OFF, VLEVEL_H,"Failed to create configuration\n");
acc_rss_deactivate();
return EXIT_FAILURE;
}
switch (sts_rss_config_updated_flag)
{
case STS_RSS_CONFIG_DEFAULT:
set_default_configuration(presence_configuration);
break;
case STS_RSS_CONFIG_SIMPLE:
sts_rss_set_current_configuration_simple(presence_configuration);
APP_LOG(TS_OFF, VLEVEL_L,"\r\n##### YUNHORN STS *** Simple *** cfg applied\n");
break;
case STS_RSS_CONFIG_FULL:
sts_rss_set_current_configuration_full(presence_configuration);
APP_LOG(TS_OFF, VLEVEL_L,"\r\n######### YUNHORN STS *** FULL *** cfg applied\n");
break;
default:
break;
}
sts_rss_config_updated_flag = STS_RSS_CONFIG_DEFAULT; //update finished, set to 0
acc_detector_presence_handle_t handle = acc_detector_presence_create(presence_configuration);
if (handle == NULL)
{
APP_LOG(TS_OFF, VLEVEL_H,"Failed to create detector\n");
acc_detector_presence_configuration_destroy(&presence_configuration);
acc_detector_presence_destroy(&handle);
acc_rss_deactivate();
return EXIT_FAILURE;
}
// ******** First Half detection of fall down and rise up
if (!acc_detector_presence_activate(handle))
{
APP_LOG(TS_OFF, VLEVEL_H, "Failed to activate detector \n");
return false;
}
bool success = true;
const int iterations = (DEFAULT_UPDATE_RATE_PRESENCE+1);
acc_detector_presence_result_t result;
uint8_t average_result = 0;
float average_distance =0.0f;
float average_score =0.0f;
for (int i = 0; i < (iterations/2); i++)
{
success = acc_detector_presence_get_next(handle, &result);
if (!success)
{
APP_LOG(TS_OFF, VLEVEL_H,"acc_detector_presence_get_next() failed\n");
break;
}
print_result(result);
//if (!result.data_saturated)
{
if (result.presence_detected)
{
average_result++;
average_distance += result.presence_distance;
average_score += result.presence_score;
}
if (sts_presence_fall_detection == 1)
{
sts_motion_dataset[motion_count].presence_distance = result.presence_distance;
sts_motion_dataset[motion_count].presence_score = result.presence_score;
if (motion_count ++ == DEFAULT_MOTION_DATASET_LEN)
{
STS_YunhornCheckStandardDeviation();
motion_count = 0;
}
}
}
acc_integration_sleep_ms(1000 / DEFAULT_UPDATE_RATE_PRESENCE); // DEFAULT_UPDATE_RATE);
}
acc_detector_presence_deactivate(handle);
APP_LOG(TS_OFF, VLEVEL_L,"First Half Presence Detection, Motion Count = %u \r\n", (int)motion_count);
// ******** Second Half detection of fall down and rise up
set_default_fall_rise_configuration(presence_configuration);
if (!acc_detector_presence_reconfigure(&handle, presence_configuration))
{
APP_LOG(TS_OFF, VLEVEL_M,"Failed to reconfigure detector\n");
acc_detector_presence_configuration_destroy(&presence_configuration);
acc_detector_presence_destroy(&handle);
acc_rss_deactivate();
return EXIT_FAILURE;
}
if (!acc_detector_presence_activate(handle))
{
APP_LOG(TS_OFF, VLEVEL_H, "Failed to activate detector \n");
return false;
}
acc_detector_presence_configuration_destroy(&presence_configuration);
for (int i = 0; i < (iterations/2); i++)
{
success = acc_detector_presence_get_next(handle, &result);
if (!success)
{
APP_LOG(TS_OFF, VLEVEL_H,"acc_detector_presence_get_next() failed\n");
break;
}
print_result(result);
//if (!result.data_saturated)
{
if (result.presence_detected)
{
average_result++;
average_distance += result.presence_distance;
average_score += result.presence_score;
}
if (sts_presence_fall_detection == 1)
{
sts_motion_dataset[motion_count].presence_distance = result.presence_distance;
sts_motion_dataset[motion_count].presence_score = result.presence_score;
if (motion_count ++ == DEFAULT_MOTION_DATASET_LEN)
{
STS_YunhornCheckStandardDeviation();
motion_count = 0;
}
}
}
acc_integration_sleep_ms(1000 / DEFAULT_UPDATE_RATE_PRESENCE); // DEFAULT_UPDATE_RATE);
}
APP_LOG(TS_OFF, VLEVEL_L,"Second Half, Fall Rise Detection, Motion Count = %u \r\n", (int)motion_count);
sts_rss_result = (average_result > 3)? 1: 0;
average_distance = (1000.0f*average_distance)/average_result; // in meters
average_score = (1000.0f*average_score)/average_result;
sts_presence_rss_distance = average_distance;
sts_presence_rss_score = average_score;
if (average_score !=0) //if (sts_rss_result)
{
APP_LOG(TS_OFF, VLEVEL_H,"\r\n######## Motion: %u Distance=%u mm, Score=%u Average_result=%u out of %u \r\n",
(uint8_t)sts_rss_result,(int) average_distance, (int)(average_score), (int)average_result, (int)iterations);
}
bool deactivated = acc_detector_presence_deactivate(handle);
acc_detector_presence_destroy(&handle);
acc_rss_deactivate();
if (deactivated && success)
{
//APP_LOG(TS_OFF, VLEVEL_M,"Application finished OK\n");
return EXIT_SUCCESS;
}
return EXIT_FAILURE;
}
int sts_presence_rss_presence_detection(void)
{
const acc_hal_t *hal = acc_hal_integration_get_implementation();
if (!acc_rss_activate(hal))
{
APP_LOG(TS_OFF, VLEVEL_H,"Failed to activate RSS\n");
return EXIT_FAILURE;
}
acc_rss_override_sensor_id_check_at_creation(true);
acc_detector_presence_configuration_t presence_configuration = acc_detector_presence_configuration_create();
if (presence_configuration == NULL)
{
APP_LOG(TS_OFF, VLEVEL_H,"Failed to create configuration\n");
acc_rss_deactivate();
return EXIT_FAILURE;
}
switch (sts_rss_config_updated_flag)
{
case STS_RSS_CONFIG_DEFAULT:
set_default_configuration(presence_configuration);
break;
case STS_RSS_CONFIG_SIMPLE:
sts_rss_set_current_configuration_simple(presence_configuration);
APP_LOG(TS_OFF, VLEVEL_L,"\r\n##### YUNHORN STS *** Simple *** cfg applied\n");
break;
case STS_RSS_CONFIG_FULL:
sts_rss_set_current_configuration_full(presence_configuration);
APP_LOG(TS_OFF, VLEVEL_L,"\r\n######### YUNHORN STS *** FULL *** cfg applied\n");
break;
default:
break;
}
sts_rss_config_updated_flag = STS_RSS_CONFIG_DEFAULT; //update finished, set to 0
acc_detector_presence_handle_t handle = acc_detector_presence_create(presence_configuration);
if (handle == NULL)
{
APP_LOG(TS_OFF, VLEVEL_H,"Failed to create detector\n");
acc_detector_presence_configuration_destroy(&presence_configuration);
acc_detector_presence_destroy(&handle);
acc_rss_deactivate();
return EXIT_FAILURE;
}
acc_detector_presence_configuration_destroy(&presence_configuration);
if (!acc_detector_presence_activate(handle))
{
APP_LOG(TS_OFF, VLEVEL_H,"Failed to activate detector\n");
acc_detector_presence_destroy(&handle);
acc_rss_deactivate();
return EXIT_FAILURE;
}
bool success = true;
const int iterations = DEFAULT_UPDATE_RATE_PRESENCE;
acc_detector_presence_result_t result;
uint8_t average_result = 0;
float average_distance =0.0f;
float average_score =0.0f;
for (int i = 0; i < iterations; i++)
{
success = acc_detector_presence_get_next(handle, &result);
if (!success)
{
APP_LOG(TS_OFF, VLEVEL_H,"acc_detector_presence_get_next() failed\n");
break;
}
print_result(result);
//if (!result.data_saturated)
{
if (result.presence_detected)
{
average_result++;
average_distance += result.presence_distance;
average_score += result.presence_score;
}
if (sts_presence_fall_detection == 1)
{
sts_motion_dataset[motion_count].presence_distance = result.presence_distance;
sts_motion_dataset[motion_count].presence_score = result.presence_score;
if (motion_count ++ == DEFAULT_MOTION_DATASET_LEN)
{
STS_YunhornCheckStandardDeviation();
motion_count = 0;
}
}
}
acc_integration_sleep_ms(1000 / DEFAULT_UPDATE_RATE_PRESENCE); // DEFAULT_UPDATE_RATE);
}
sts_rss_result = (average_result > 3)? 1: 0;
average_distance = (1000.0f*average_distance)/average_result; // in meters
average_score = (1000.0f*average_score)/average_result;
sts_presence_rss_distance = average_distance;
sts_presence_rss_score = average_score;
if (average_score !=0) //if (sts_rss_result)
{
APP_LOG(TS_OFF, VLEVEL_H,"\r\n######## Motion: %u Distance=%u mm, Score=%u Average_result=%u out of %u \r\n",
(uint8_t)sts_rss_result,(int) average_distance, (int)(average_score), (int)average_result, (int)iterations);
}
bool deactivated = acc_detector_presence_deactivate(handle);
acc_detector_presence_destroy(&handle);
acc_rss_deactivate();
if (deactivated && success)
{
//APP_LOG(TS_OFF, VLEVEL_M,"Application finished OK\n");
return EXIT_SUCCESS;
}
return EXIT_FAILURE;
}

View File

@ -1,624 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file yunhorn_sts_lamp_bar.c *
* @author Yunhorn (r) Technology Limited Application Team *
* @brief Yunhorn (r) SmarToilets (r) Product configuration file. *
******************************************************************************
* @attention
*
* Copyright (c) 2022 Yunhorn Technology Limited.
* Copyright (c) 2022 Shenzhen Yunhorn Technology Co., Ltd.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
#include "main.h"
#include "dma.h"
#include "tim.h"
#include "string.h"
#include "sys_app.h"
#include "stm32_systime.h"
#include "sts_lamp_bar.h"
#include "ref_app_smart_presence.h"
#include "yunhorn_sts_sensors.h"
#define ONE_PULSE (36)
#define ZERO_PULSE (20)
#define LED_DATA_LEN (24)
#define WS2812B_DATA_LEN (LED_DATA_LEN * (STS_LAMP_BAR_LED_NUM+4))
#define DEFAULT_LUMINANCE_LEVEL (20)
#define RESET_PULSE (10) //(80) TO FIX DARK_COLOR AND SM2
typedef struct ws2812b_e {
uint16_t head[3];
uint16_t GRB[24*STS_LAMP_BAR_LED_NUM];
uint16_t tail;
} WS2812B_FrameTypeDef;
volatile WS2812B_FrameTypeDef rgb_buf = {
.head[0] = 0,
.head[1] = 0,
.head[2] = 0,
.tail = 0
};
uint8_t color_rgb[8][3] = { //STS_COLOR R G B MAPPING TABLE
{0,0,0},{0,1,0},{1,0,0},{0,0,1},{1,1,0},{1,0,1},{0,1,1},{1,1,1}
};
volatile uint8_t sts_service_mask;
volatile uint8_t sts_work_mode = STS_DUAL_MODE;
volatile uint8_t sts_reed_hall_ext_int = 0;
volatile uint8_t sts_status_color = STS_DARK;
volatile uint8_t sts_lamp_bar_color = STS_GREEN; //puColor
volatile uint8_t sts_cloud_netcolor = STS_GREEN; //netColor
volatile uint8_t sts_occupancy_status;
volatile uint8_t sts_reed_hall_changed_flag = 1;
volatile uint8_t sts_reed_hall_result =0;
volatile uint8_t sts_tof_result_changed_flag = 0;
volatile uint8_t sts_water_leakage_result=0;
volatile uint8_t sts_water_leakage_changed_flag=0;
volatile uint8_t sts_rss_result_changed_flag = 0;
volatile uint8_t sts_rss_result = STS_RESULT_NO_MOTION;
volatile uint8_t sts_rss_2nd_result = STS_RESULT_NO_MOTION; //2nd RSS sensor status
volatile uint8_t sts_tof_result = STS_RESULT_NO_MOTION;
volatile uint8_t last_sts_rss_result;
volatile uint8_t last_sts_reed_hall_result = 2; //Initial state, not 0, not 1
volatile uint8_t last_lamp_bar_color;
extern volatile uint8_t sts_presence_fall_detection;
extern volatile float sts_presence_rss_distance;
extern volatile uint8_t sensor_data_ready;
extern SysTime_t mems_event_time;
extern volatile uint32_t event_start_time, event_stop_time;
uint8_t luminance_level = DEFAULT_LUMINANCE_LEVEL;
void STS_YunhornSTSEventP1_Process(void)
{
STS_Lamp_Bar_Refresh();
if ((sts_work_mode == STS_WIRED_MODE) || (sts_work_mode == STS_REEDSWITCH_MODE) || (sts_work_mode == STS_DUAL_MODE))
{
STS_Reed_Hall_Presence_Detection();
if (sts_reed_hall_result == last_sts_reed_hall_result) {
sts_reed_hall_changed_flag = 0;
} else {
sts_reed_hall_changed_flag = 1;
STS_Combined_Status_Processing();
}
last_sts_reed_hall_result = sts_reed_hall_result;
}
}
void STS_YunhornSTSEventP2_Process(void)
{
STS_Lamp_Bar_Refresh();
if ((sts_work_mode >= STS_RSS_MODE) && (sts_work_mode <= STS_TOF_RSS_MODE))
{
STS_RSS_Smart_Presence_Detection();
STS_Reed_Hall_Presence_Detection();
if (sts_rss_result == last_sts_rss_result) {
sts_rss_result_changed_flag =0;
} else {
sts_rss_result_changed_flag =1;
last_sts_rss_result = sts_rss_result;
}
if (sts_reed_hall_result == last_sts_reed_hall_result)
{
sts_reed_hall_changed_flag = 0;
} else
{
sts_reed_hall_changed_flag = 1;
}
if (sts_service_mask > 0 ) {
sts_rss_result_changed_flag =0;
sts_reed_hall_changed_flag = 0;
}
STS_Combined_Status_Processing();
last_sts_rss_result = sts_rss_result;
last_sts_reed_hall_result = sts_reed_hall_result;
}
}
void STS_Reed_Hall_Presence_Detection(void)
{
// HAL_Delay(50); // BOUNCING ELIMIATION
if (STS_Reed_Hall_State == STS_Status_Door_Open)
{
sts_reed_hall_result = STS_Status_Door_Open;
} else if (STS_Reed_Hall_State == STS_Status_Door_Close)
{
sts_reed_hall_result = STS_Status_Door_Close;
}
//sts_reed_hall_result = ((STS_Reed_Hall_State)&STS_Status_Door_Open);
// HAL_Delay(20); // BOUNCING ELIMIATION
sts_reed_hall_changed_flag = 0;
sts_reed_hall_ext_int = 0;
}
void STS_RSS_Smart_Presence_Detection(void)
{
STS_Lamp_Bar_Refresh();
//sts_presence_rss_presence_detection();
sts_presence_rss_fall_rise_detection();
// if (sts_presence_fall_detection) {
// STS_YunhornSTSFallDetection();
// }
}
/*
* STS P3 process, Lamp Bar Scoller
*/
void STS_YunhornSTSEventP3_Process(void)
{
STS_Lamp_Bar_Refresh();
if (STS_Reed_Hall_State == STS_Status_Door_Open)
{
sts_lamp_bar_color =STS_GREEN;
}
else
{
sts_lamp_bar_color =STS_RED;
}
STS_Lamp_Bar_Scoller(sts_lamp_bar_color, luminance_level);
}
/*
* STS P4 Process, STS_CAP_Sensor_Detection Process
* STS_CAP_SWITCH(ON) Boost Voltage to 5V, then hold for 1000 ms
* HAL_Delay(1000) (ms)
* STS_CAP_Read_Data() Read STS_CAP_DATA state
* STS_CAP_SWITCH(OFF) Switch Off Boosted Voltage
*/
void STS_YunhornSTSEventP4_Process(void)
{
APP_LOG(TS_OFF, VLEVEL_L, "\r\n P4 Testing Process\r\n");
}
/*
* STS P5 Process, Detection ToF distance (VL53L0X)
*
*/
void STS_YunhornSTSEventP5_Process(void)
{
APP_LOG(TS_OFF, VLEVEL_L, "\r\n P5 Testing Process\r\n");
}
/*
* STS P6 Process, Detection ToF IN-OUT PEOPLE COUNT (VL53L3X)
*
*/
void STS_YunhornSTSEventP6_Process(void)
{
APP_LOG(TS_OFF, VLEVEL_L, "\r\n P6 Testing Process\r\n");
}
/*
* STS P7 Process, Detection IAQ Sensors
* air quality and odor level sensors
*/
void STS_YunhornSTSEventP7_Process(void)
{
APP_LOG(TS_OFF, VLEVEL_L, "\r\n P7 Testing Process\r\n");
}
/*
* STS P8 Process, Detection xxx Sensors
* xxx sensors
*/
void STS_YunhornSTSEventP8_Process(void)
{
APP_LOG(TS_OFF, VLEVEL_L, "\r\n P8 Testing Process\r\n");
}
void STS_Lamp_Bar_Set_Dark(void)
{
for (uint8_t i=0; i< STS_LAMP_BAR_LED_NUM; i++)
{
STS_WS2812B_Set_RGB(0x00,0x00,0x00,i);
}
//STS_WS2812B_Refresh();
}
void STS_WS2812B_Refresh(void)
{
HAL_TIM_PWM_Start_DMA(&STS_LAMP_BAR_HTIM, STS_LAMP_BAR_TIM_CHANNEL, (uint32_t *)&rgb_buf, (RESET_PULSE+WS2812B_DATA_LEN+1));
//HAL_TIM_PWM_Start_IT(&STS_LAMP_BAR_HTIM, STS_LAMP_BAR_TIM_CHANNEL);
}
void STS_Lamp_Bar_Init(void)
{
if (sts_service_mask == STS_SERVICE_MASK_L0)
{
STS_Lamp_Bar_Set_STS_RGB_Color(STS_GREEN, luminance_level);
//STS_WS2812B_Refresh();
HAL_Delay(200);
STS_Lamp_Bar_Set_STS_RGB_Color(STS_RED, luminance_level);
//STS_WS2812B_Refresh();
HAL_Delay(200);
STS_Lamp_Bar_Set_STS_RGB_Color(STS_BLUE, luminance_level);
//STS_WS2812B_Refresh();
HAL_Delay(200);
}
}
//marquee scoller
void STS_Lamp_Bar_Scoller(uint8_t color, uint8_t luminance_level)
{
STS_Lamp_Bar_Set_Dark();
for(uint8_t i = 0; i<(STS_LAMP_BAR_LED_NUM+1); i++)
{
//if (sts_service_mask < STS_SERVICE_MASK_L1)
// STS_WS2812B_Refresh();
HAL_Delay(60);
if (i < STS_LAMP_BAR_LED_NUM) {
STS_WS2812B_Set_RGB(color_rgb[color][0]*luminance_level,color_rgb[color][1]*luminance_level, color_rgb[color][2]*luminance_level, i);
}
}
HAL_Delay(10);
//if (sts_service_mask == STS_SERVICE_MASK_L0) {
// STS_WS2812B_Refresh();
//}
}
void STS_WS2812B_Set_RGB(uint8_t R, uint8_t G, uint8_t B, uint8_t idx)
{
if (idx < STS_LAMP_BAR_LED_NUM)
{
for (uint8_t j = 0; j < 8; j ++)
{
rgb_buf.GRB[idx*24+j] = (G&(0X80)>>j)? ONE_PULSE : ZERO_PULSE;
rgb_buf.GRB[idx*24+8+j] = (R&(0X80)>>j)? ONE_PULSE : ZERO_PULSE;
rgb_buf.GRB[idx*24+16+j] = (B&(0X80)>>j)? ONE_PULSE : ZERO_PULSE;
}
}
// CHANGED AT 2023-05-10
if (sts_service_mask == STS_SERVICE_MASK_L0) {
STS_WS2812B_Refresh();
}
}
void STS_Lamp_Bar_Set_RGB_Color(uint8_t red, uint8_t green, uint8_t blue )
{
HAL_Delay(1);
for(uint8_t i = 0; i < STS_LAMP_BAR_LED_NUM; i++)
{
for (uint8_t j = 0; j < 8; j ++)
{
rgb_buf.GRB[i*24+j] = (green&(0x80)>>j)? ONE_PULSE : ZERO_PULSE;
rgb_buf.GRB[i*24+8+j] = (red&(0x80)>>j)? ONE_PULSE : ZERO_PULSE;
rgb_buf.GRB[i*24+16+j] = (blue&(0x80)>>j)? ONE_PULSE : ZERO_PULSE;
}
}
if (sts_service_mask == STS_SERVICE_MASK_L0) {
STS_WS2812B_Refresh();
}
}
void STS_Lamp_Bar_Refresh(void)
{
STS_Lamp_Bar_Set_STS_RGB_Color(sts_lamp_bar_color, luminance_level);
}
void STS_Lamp_Bar_Set_STS_RGB_Color(uint8_t sts_lamp_color, uint8_t luminance_level)
{
uint8_t lum = luminance_level;
STS_Lamp_Bar_Set_RGB_Color(0x0, 0x0, 0x0);
switch (sts_lamp_color)
{
case STS_DARK:
STS_Lamp_Bar_Set_RGB_Color(0x0, 0x0, 0x0);
break;
case STS_GREEN:
STS_Lamp_Bar_Set_RGB_Color(0x0, lum, 0x0);
break;
case STS_RED:
STS_Lamp_Bar_Set_RGB_Color(lum, 0x0, 0x0);
break;
case STS_BLUE:
STS_Lamp_Bar_Set_RGB_Color(0x0, 0x0, lum);
break;
case STS_YELLOW:
STS_Lamp_Bar_Set_RGB_Color(lum, lum, 0x0);
break;
case STS_PINK:
STS_Lamp_Bar_Set_RGB_Color(lum, 0x0, lum);
break;
case STS_CYAN:
STS_Lamp_Bar_Set_RGB_Color(0x0, lum, lum);
break;
case STS_WHITE:
STS_Lamp_Bar_Set_RGB_Color(lum, lum, lum);
break;
case STS_RED_BLUE:
STS_Lamp_Bar_Set_RGB_Color(lum, 0x0, 0x0);
HAL_Delay(300);
STS_Lamp_Bar_Set_RGB_Color(0x0, 0x0, lum);
HAL_Delay(300);
break;
}
}
void STS_Reed_Hall_Working(void)
{
}
void STS_Combined_Status_Processing(void)
{
mems_event_time = SysTimeGetMcuTime();
if ((sts_rss_result == STS_RESULT_MOTION) || (sts_reed_hall_result == STS_Status_Door_Close) || (sts_tof_result == STS_RESULT_PRESENCE))
{
if (event_start_time == 0) {
event_start_time = mems_event_time.Seconds;
event_stop_time = 0;
APP_LOG(TS_OFF, VLEVEL_L, "\r\n Event Started at %6u Seconds \r\n", event_start_time);
}
} else if ((sts_rss_result != STS_RESULT_MOTION) || (sts_reed_hall_result != STS_Status_Door_Close) || (sts_tof_result != STS_RESULT_PRESENCE))
{
if (event_stop_time ==0)
{
event_stop_time = mems_event_time.Seconds;
event_start_time = 0;
APP_LOG(TS_OFF, VLEVEL_L, "\r\n Event Stop at %6u Seconds \r\n", event_stop_time);
}
}
switch (sts_work_mode)
{
case STS_NETWORK_MODE:
sts_status_color = sts_cloud_netcolor;
break;
case STS_WIRED_MODE: // NO LAMP BAR FOR THOSE WATER LEAKAGE SENSOR OR SOAP CAPACITY SENSORS
sts_status_color = STS_DARK;
sts_water_leakage_result = (sts_reed_hall_result == STS_Status_Door_Open )?STS_RESULT_WATER_LEAKAGE_YES:STS_RESULT_WATER_LEAKAGE_NO;
sts_water_leakage_changed_flag = 1;
break;
case STS_REEDSWITCH_MODE:
sts_status_color = (sts_reed_hall_result == STS_Status_Door_Open )? STS_GREEN: STS_RED;
break;
case STS_RSS_MODE:
if (sts_rss_result == STS_RESULT_NO_MOTION){
sts_status_color = STS_GREEN;
} else if ((sts_rss_result == STS_RESULT_MOTION))
{
sts_status_color = STS_RED;
}
break;
case STS_DUAL_MODE:
if ((sts_rss_result == STS_RESULT_NO_MOTION) && (sts_reed_hall_result == STS_Status_Door_Open ))
{
sts_status_color = STS_GREEN;
} else if ((sts_rss_result == STS_RESULT_MOTION) || (sts_reed_hall_result == STS_Status_Door_Close ))
{
sts_status_color = STS_RED;
}
break;
case STS_REMOTE_REED_RSS_MODE:
if ((sts_rss_result == STS_RESULT_NO_MOTION) && (sts_reed_hall_result == STS_Status_Door_Open ))
{
sts_status_color = STS_GREEN;
} else if ((sts_rss_result == STS_RESULT_MOTION) || (sts_reed_hall_result == STS_Status_Door_Close ))
{
sts_status_color = STS_RED;
}
break;
case STS_DUAL_RSS_MODE:
if ((sts_rss_result == STS_RESULT_NO_MOTION) && (sts_rss_2nd_result == STS_RESULT_NO_MOTION))
{
sts_status_color = STS_GREEN;
} else if ((sts_rss_result == STS_RESULT_MOTION) || (sts_rss_2nd_result == STS_RESULT_MOTION))
{
sts_status_color = STS_RED;
}
break;
case STS_TOF_RSS_MODE:
if ((sts_rss_result == STS_RESULT_NO_MOTION) && (sts_tof_result == STS_RESULT_NO_PRESENCE)){
sts_status_color = STS_GREEN;
} else if ((sts_rss_result == STS_RESULT_MOTION) || (sts_tof_result == STS_RESULT_PRESENCE))
{
sts_status_color = STS_RED;
}
break;
// TO-DO LIST ***********************************************************
case STS_TOF_DISTANCE_MODE:
if ((sts_tof_result == STS_RESULT_NO_PRESENCE)) {
sts_status_color = STS_GREEN;
} else if ((sts_tof_result == STS_RESULT_PRESENCE)) {
sts_status_color = STS_RED;
}
break;
case STS_TOF_PRESENCE_MODE:
if ((sts_tof_result == STS_RESULT_NO_PRESENCE)) {
sts_status_color = STS_GREEN;
} else if ((sts_tof_result == STS_RESULT_PRESENCE)) {
sts_status_color = STS_RED;
}
break;
case STS_TOF_IN_OUT_MODE:
if ((sts_tof_result == STS_RESULT_NO_PRESENCE)) {
sts_status_color = STS_GREEN;
} else if ((sts_tof_result == STS_RESULT_PRESENCE)) {
sts_status_color = STS_RED;
}
break;
// TO-DO LIST ***********************************************************
default:
break;
}
if (sts_status_color == STS_RED_BLUE)
{
STS_Lamp_Bar_Set_STS_RGB_Color(sts_lamp_bar_color, luminance_level);
}
if ((sts_work_mode == STS_WIRED_MODE) || (sts_service_mask > STS_SERVICE_MASK_L0))
{
sts_status_color = STS_DARK;
sts_lamp_bar_color = STS_DARK;
last_lamp_bar_color = STS_DARK;
STS_Lamp_Bar_Set_Dark();
}
else
{
//if ((last_lamp_bar_color != sts_status_color))
{
sts_lamp_bar_color = ((sts_service_mask == STS_SERVICE_MASK_L0)? sts_status_color:STS_DARK);
STS_Lamp_Bar_Set_STS_RGB_Color(sts_lamp_bar_color, luminance_level);
if ((sts_service_mask == STS_SERVICE_MASK_L0) || (sts_lamp_bar_color == STS_DARK))
{
// STS_WS2812B_Refresh();
}
last_lamp_bar_color = sts_lamp_bar_color;
}
}
if ((sts_rss_result_changed_flag)|| (sts_reed_hall_changed_flag) || (sts_tof_result_changed_flag) || (sts_water_leakage_changed_flag))
{
sensor_data_ready = 1;
STS_PRESENCE_SENSOR_Prepare_Send_Data();
sts_rss_result_changed_flag =0;
sts_reed_hall_changed_flag =0;
sts_tof_result_changed_flag =0;
sts_water_leakage_changed_flag=0;
}
}
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{
__HAL_TIM_SetCompare(&STS_LAMP_BAR_HTIM, STS_LAMP_BAR_TIM_CHANNEL,0);
HAL_TIM_PWM_Stop_DMA(&STS_LAMP_BAR_HTIM,STS_LAMP_BAR_TIM_CHANNEL);
}
void STS_Lamp_Bar_Self_Test_Simple(void)
{
uint8_t color=0, luminance_level=10;
APP_LOG(TS_OFF, VLEVEL_M, "\r\n [#1] RGB Space Lumianance Level Testing Start\r\n");
for (color=STS_GREEN; color <= STS_RED_BLUE; color++)
{
luminance_level = 10;
do {
STS_Lamp_Bar_Set_STS_RGB_Color(color, luminance_level);
HAL_Delay(10);
luminance_level += 20;
} while (luminance_level < 99);
//STS_Lamp_Bar_Set_Dark();
}
APP_LOG(TS_OFF, VLEVEL_M, "\r\n [#1] RGB Space Lumianance Level Testing Finished\r\n");
}
void STS_Lamp_Bar_Self_Test(void)
{
uint8_t color=0, luminance_level=10;
APP_LOG(TS_OFF, VLEVEL_M, "\r\n YunHorn STS Indicative Lamp Self Test\r\n");
STS_Lamp_Bar_Self_Test_Simple();
APP_LOG(TS_OFF, VLEVEL_H, "\r\n [#2] Scoller Testing\r\n");
for (color = STS_GREEN; color <= STS_RED_BLUE; color++)
{
STS_Lamp_Bar_Scoller(color, luminance_level);
}
STS_Lamp_Bar_Set_Dark();
APP_LOG(TS_OFF, VLEVEL_M, "\r\n [##] YunHorn STS Indicative Lamp Self Test Finished\r\n");
if ((sts_work_mode == STS_WIRED_MODE) )
{
STS_Lamp_Bar_Set_Dark();
} else
{
STS_Lamp_Bar_Set_STS_RGB_Color(STS_GREEN, luminance_level);
}
}
void sts_rgb_unit_test(void)
{
APP_LOG(TS_OFF, VLEVEL_L, "\r\n STS Lamp Bar Init...\r\n");
STS_Lamp_Bar_Set_Dark();
STS_Lamp_Bar_Full_Color_Gradient();
STS_Lamp_Bar_Self_Test();
do {
for (uint8_t i=0; i<9; i++)
{
APP_LOG(TS_OFF, VLEVEL_L, "\r\n STS Lamp Bar color = %d...\r\n", i);
STS_Lamp_Bar_Set_STS_RGB_Color(i, luminance_level);
STS_Combined_Status_Processing();
HAL_Delay(6000);
STS_Lamp_Bar_Set_Dark();
}
} while(1);
}

View File

@ -1,555 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file yunhorn_sts_presence_sensor.c *
* @author Yunhorn (r) Technology Limited Application Team *
* @brief Yunhorn (r) SmarToilets (r) Product configuration file. *
******************************************************************************
* @attention
*
* Copyright (c) 2022 Yunhorn Technology Limited.
* Copyright (c) 2022 Shenzhen Yunhorn Technology Co., Ltd.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "stdint.h"
#include "platform.h"
#include "sys_conf.h"
#include "sys_app.h"
#include "stdio.h"
#include "stm32_systime.h"
#include "adc_if.h"
#include "gpio.h"
#include "LmHandler.h"
#include "lora_app.h"
#include "yunhorn_sts_prd_conf.h"
#include "yunhorn_sts_sensors.h"
#include "sts_cmox_hmac_sha.h"
/* USER CODE BEGIN Includes */
#if (defined(YUNHORN_STS_O6_ENABLED) && defined(USE_ACCONEER_A111))
//#include "yunhorn_sts_rss_sensor.h"
extern volatile uint8_t sts_ac_code[20];
volatile uint32_t rfac_timer;
extern volatile uint8_t sensor_data_ready;
volatile STS_OO_SensorStatusDataTypeDef sts_o6_sensorData;
volatile STS_PRESENCE_SENSOR_Event_Status_t sts_o6_event_status;
volatile float sts_distance_rss_distance;
extern volatile float sts_presence_rss_distance, sts_presence_rss_score;
volatile uint8_t sts_rss_config_updated_flag = 0;
extern volatile uint8_t mems_int1_detected, link_wakeup, link_sleep;
volatile uint32_t event_start_time, event_stop_time;
extern volatile STS_OO_RSS_SensorTuneDataTypeDef sts_presence_rss_config;
extern volatile sts_cfg_nvm_t sts_cfg_nvm;
extern volatile uint8_t sts_fall_detection_acc_threshold, sts_fall_detection_depth_threshold, sts_occupancy_overtime_threshold;
extern volatile uint8_t sts_reed_hall_result, sts_rss_result, sts_rss_2nd_result,sts_tof_result, sts_status_color, sts_lamp_bar_color, sts_work_mode, sts_service_mask;
extern volatile distance_measure_cfg_t distance_cfg;
extern uint8_t sts_fall_rising_detected_result;
extern volatile uint16_t sts_fall_rising_pattern_factor1;
extern volatile uint16_t sts_roc_acc_standard_variance;
extern uint8_t luminance_level;
SysTime_t mems_event_time;
#endif
/* USER CODE END Includes */
/* External variables ---------------------------------------------------------*/
/* USER CODE BEGIN EV */
/* USER CODE END EV */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP */
#if (defined(YUNHORN_STS_O6_ENABLED) && defined(USE_ACCONEER_A111))
#endif
/* USER CODE END PFP */
/* Exported functions --------------------------------------------------------*/
void STS_YunhornAuthenticationCode_Process(void)
{
if (sts_ac_code[0] == 0x00) {
APP_LOG(TS_OFF,VLEVEL_H, "Initial AC CODE blank... \r\n");
return;
}
sts_service_mask = (sts_hmac_verify()!= 0)? STS_SERVICE_MASK_L2:STS_SERVICE_MASK_L0;
if (sts_service_mask == STS_SERVICE_MASK_L2) {
sts_ac_code[0] = 0x0;
}
APP_LOG(TS_OFF, VLEVEL_H, "STS_SERVICE_MASK:%d \r\n",sts_service_mask);
}
void STS_YunhornSTSEventRFAC_Process(void)
{
if (sts_ac_code[0] ==0x0)
{
if ((rfac_timer >= STS_BURN_IN_RFAC) && (rfac_timer < (STS_BURN_IN_RFAC +3)))
{
APP_LOG(TS_OFF, VLEVEL_H, "\r\n -------------------RFAC Process\r\n");
STS_SENSOR_Upload_Message(YUNHORN_STS_O6_USER_APP_CTRL_REPLY_PORT, 4, "RFAC");
}
if ((rfac_timer > (STS_BURN_IN_RFAC + 2)))
{
APP_LOG(TS_OFF, VLEVEL_H, "\r\n -------------------Verify RFAC Success or Not\r\n");
sts_service_mask = (sts_hmac_verify()!= 0)? STS_SERVICE_MASK_L2:STS_SERVICE_MASK_L0;
if (sts_service_mask == STS_SERVICE_MASK_L2) {
sts_ac_code[0] = 0x0;
}
}
}
}
void STS_FallDetection_LampBarProcess(void)
{
uint8_t buf[32]={0x0};
uint8_t i=0;
switch (sts_fall_rising_detected_result)
{
case STS_PRESENCE_LAYDOWN:
break;
case STS_PRESENCE_FALL:
sts_lamp_bar_color = STS_BLUE; //STS_RED_BLUE;
sts_status_color = STS_BLUE; //STS_RED_BLUE;
sts_rss_result = STS_RESULT_MOTION;
STS_Lamp_Bar_Set_STS_RGB_Color(sts_lamp_bar_color, luminance_level);
buf[i++] = (uint8_t)sts_lamp_bar_color;
buf[i++] = (uint8_t)sts_work_mode;
buf[i++] = (uint8_t)sts_fall_rising_detected_result;
buf[i++] = (uint8_t)(sts_fall_rising_pattern_factor1/10 + 0x30)&0xFF;
buf[i++] = (uint8_t)(sts_fall_rising_pattern_factor1%10 + 0x30)&0xFF;
buf[i++] = (uint8_t)(sts_roc_acc_standard_variance/10 + 0x30)&0xFF;
buf[i++] = (uint8_t)(sts_roc_acc_standard_variance%10 + 0x30)&0xFF;
break;
case STS_PRESENCE_RISING:
sts_lamp_bar_color = STS_RED; // normal occupancy status
sts_status_color = STS_RED; // normal occupancy status
sts_rss_result = STS_RESULT_MOTION;
STS_Lamp_Bar_Set_STS_RGB_Color(sts_lamp_bar_color, luminance_level);
buf[i++] = (uint8_t)sts_lamp_bar_color;
buf[i++] = (uint8_t)sts_work_mode;
buf[i++] = (uint8_t)sts_fall_rising_detected_result;
// TESTING ONLY TO BE REMOVED
buf[i++] = (uint8_t)(sts_fall_rising_pattern_factor1/10 + 0x30)&0xFF;
buf[i++] = (uint8_t)(sts_fall_rising_pattern_factor1%10 + 0x30)&0xFF;
buf[i++] = (uint8_t)(sts_roc_acc_standard_variance/10 + 0x30)&0xFF;
buf[i++] = (uint8_t)(sts_roc_acc_standard_variance%10 + 0x30)&0xFF;
break;
default:
break;
}
APP_LOG(TS_OFF, VLEVEL_L, "\r\n <<<<<<<<<<<<<< Fall Rise state=%d, send buf size = %d \r\n",
sts_fall_rising_detected_result, i )
STS_SENSOR_Upload_Message((LORAWAN_USER_APP_PORT+2), i, (char*)buf);
sts_fall_rising_detected_result = STS_PRESENCE_NONE;
}
void STS_YunhornSTSFallDetection(void)
{
//APP_LOG(TS_OFF, VLEVEL_M, "\r\n YUNHORN STS FALL DETECTION \r\n");
//STS_YunhornCheckStandardDeviation();
}
void STS_PRESENCE_SENSOR_NVM_CFG(void)
{
sts_presence_rss_config.default_start_m = (float)((float)sts_cfg_nvm.p[RSS_CFG_START_M]*0.1f);
sts_presence_rss_config.default_length_m = (float)((float)sts_cfg_nvm.p[RSS_CFG_LENGTH_M]*0.1f);
sts_presence_rss_config.default_threshold = (float)((float)sts_cfg_nvm.p[RSS_CFG_THRESHOLD]*0.1f);
sts_presence_rss_config.default_receiver_gain = (float)((float)sts_cfg_nvm.p[RSS_CFG_RECEIVER_GAIN]*0.01f);
sts_presence_rss_config.default_zone_length_m = DEFAULT_ZONE_LENGTH;
sts_presence_rss_config.default_profile = (float)(sts_cfg_nvm.p[RSS_CFG_PROFILE]);
sts_presence_rss_config.default_update_rate_tracking = (float)(sts_cfg_nvm.p[RSS_CFG_RATE_TRACKING]);
sts_presence_rss_config.default_update_rate_presence = (float)(sts_cfg_nvm.p[RSS_CFG_RATE_PRESENCE]);
sts_presence_rss_config.default_hwaas = (float)(sts_cfg_nvm.p[RSS_CFG_HWAAS]);
sts_presence_rss_config.default_nbr_removed_pc = (float)(sts_cfg_nvm.p[RSS_CFG_NBR_REMOVED_PC]);
//filter parameter
sts_presence_rss_config.default_inter_frame_deviation_time_const = (float)(sts_cfg_nvm.p[RSS_CFG_ITE_DEVIATION]*0.1f);
sts_presence_rss_config.default_inter_frame_fast_cutoff = (float)(sts_cfg_nvm.p[RSS_CFG_ITE_FAST_CUTOFF]);
sts_presence_rss_config.default_inter_frame_slow_cutoff = (float)(sts_cfg_nvm.p[RSS_CFG_ITE_SLOW_CUTOFF]*0.01f);
sts_presence_rss_config.default_intra_frame_time_const = (float)(sts_cfg_nvm.p[RSS_CFG_ITR_TIME]);
sts_presence_rss_config.default_intra_frame_weight = (float)(sts_cfg_nvm.p[RSS_CFG_ITR_WEIGHT]*0.1f);
sts_presence_rss_config.default_output_time_const = (float)(sts_cfg_nvm.p[RSS_CFG_OUTPUT_TIME]*0.1f);
//filter parameter
sts_presence_rss_config.default_downsampling_factor = (float)(sts_cfg_nvm.p[RSS_CFG_DOWNSAMPLING_FACTOR]);
sts_presence_rss_config.default_power_save_mode = (float)(sts_cfg_nvm.p[RSS_CFG_POWER_MODE]);
sts_rss_config_updated_flag = STS_RSS_CONFIG_FULL; //set to 2 for FULL config effect in next detection
}
void STS_PRESENCE_SENSOR_NVM_CFG_SIMPLE(void)
{
sts_presence_rss_config.default_start_m = (float)(sts_cfg_nvm.p[RSS_CFG_START_M]*0.1f);
sts_presence_rss_config.default_length_m = (float)(sts_cfg_nvm.p[RSS_CFG_LENGTH_M]*0.1f);
sts_presence_rss_config.default_threshold = (float)(sts_cfg_nvm.p[RSS_CFG_THRESHOLD]*0.1f);
sts_presence_rss_config.default_receiver_gain = (float)(sts_cfg_nvm.p[RSS_CFG_RECEIVER_GAIN]*0.01f);
sts_rss_config_updated_flag = STS_RSS_CONFIG_SIMPLE; //set to 1 for simple config effect in next detection
}
void STS_PRESENCE_SENSOR_Init_Send_Data(void)
{
sts_o6_sensorData.lamp_bar_color = STS_GREEN;
sts_o6_sensorData.workmode = STS_DUAL_MODE;
sts_o6_sensorData.state_sensor1_on_off = 0x0;
sts_o6_sensorData.state_sensor2_on_off = 0x0;
sts_o6_sensorData.state_sensor3_on_off = 0x0;
sts_o6_sensorData.state_sensor4_on_off = 0x0;
sts_o6_sensorData.rss_presence_distance = 0x0;
sts_o6_sensorData.rss_presence_score = 0x0;
sts_o6_sensorData.fall_state = STS_PRESENCE_NONE;
sts_o6_sensorData.fall_speed = 0x0;
sts_o6_sensorData.fall_gravity = 0x0;
sts_o6_sensorData.event_start_time = 0x0;
sts_o6_sensorData.event_stop_time = 0x0;
sts_o6_sensorData.overtime = 0x0;
sts_o6_sensorData.battery_Pct = 99; // 99% as init value
sts_o6_sensorData.dutycycletimelevel = 1;
sensor_data_ready = 0;
}
void STS_PRESENCE_SENSOR_Prepare_Send_Data(void)
{
sts_o6_sensorData.lamp_bar_color = sts_lamp_bar_color;
sts_o6_sensorData.workmode = sts_work_mode;
sts_o6_sensorData.state_sensor1_on_off = ((STS_Reed_Hall_State == STS_Status_Door_Open)? 0U:1U);
sts_o6_sensorData.state_sensor2_on_off = sts_rss_result;
sts_o6_sensorData.state_sensor3_on_off = sts_tof_result;
sts_o6_sensorData.state_sensor4_on_off = sts_rss_2nd_result;
if (sts_rss_result == STS_RESULT_MOTION)
{
sts_o6_sensorData.rss_presence_distance = (uint16_t)(sts_presence_rss_distance)&0xFFFF;
sts_o6_sensorData.rss_presence_score = (uint16_t)(sts_presence_rss_score)&0xFFFF;
} else {
sts_o6_sensorData.rss_presence_distance = 0x0;
sts_o6_sensorData.rss_presence_score = 0x0;
}
sts_o6_sensorData.fall_state = sts_fall_rising_detected_result;
if (sts_fall_rising_detected_result != STS_PRESENCE_NONE)
{
sts_o6_sensorData.fall_speed = (uint8_t)sts_fall_rising_pattern_factor1;
sts_o6_sensorData.fall_gravity = (uint8_t)sts_roc_acc_standard_variance;
}
sts_o6_sensorData.overtime = (event_stop_time - event_start_time)> (sts_occupancy_overtime_threshold*60)? 1:0;
sts_o6_sensorData.event_start_time = event_start_time;
sts_o6_sensorData.event_stop_time = event_stop_time;
}
void STS_PRESENCE_SENSOR_Read(STS_OO_SensorStatusDataTypeDef *o6_data)
{
o6_data->lamp_bar_color = (uint8_t)sts_o6_sensorData.lamp_bar_color;
o6_data->workmode = (uint8_t)sts_o6_sensorData.workmode;
o6_data->state_sensor1_on_off = (uint8_t)sts_o6_sensorData.state_sensor1_on_off;
o6_data->state_sensor2_on_off = (uint8_t)sts_o6_sensorData.state_sensor2_on_off;
o6_data->state_sensor3_on_off = (uint8_t)sts_o6_sensorData.state_sensor3_on_off;
o6_data->state_sensor4_on_off = (uint8_t)sts_o6_sensorData.state_sensor4_on_off;
o6_data->rss_presence_distance = (uint16_t)sts_o6_sensorData.rss_presence_distance;
o6_data->rss_presence_score = (uint16_t)sts_o6_sensorData.rss_presence_score;
o6_data->event_start_time = (uint32_t)sts_o6_sensorData.event_start_time;
o6_data->event_stop_time = (uint32_t)sts_o6_sensorData.event_stop_time;
o6_data->overtime = (uint8_t)sts_o6_sensorData.overtime;
o6_data->battery_Pct = (uint8_t)sts_o6_sensorData.battery_Pct;
o6_data->dutycycletimelevel = (uint8_t)sts_o6_sensorData.dutycycletimelevel;
}
void STS_PRESENCE_SENSOR_GetValue(void)
{
}
void STS_PRESENCE_SENSOR_WakeUp_Process_Sampling(void)
{
if ((sensor_data_ready ==0)) {
STS_PRESENCE_SENSOR_GetValue();
}
}
void STS_PRESENCE_SENSOR_After_Wake_Up()
{
}
/**
* @brief Initializes the motion sensors
* @param Instance Motion sensor instance
* @param Functions Motion sensor functions. Could be :
* - MOTION_ACCELERO for instance
* @retval BSP status
*/
void STS_PRESENCE_SENSOR_Init(void)
{
APP_LOG(TS_ON, VLEVEL_M, "##### YunHorn SmarToilets(r) Presence Sensor Started\r\n");
sts_o6_sensorData.workmode = (uint8_t)STS_DUAL_MODE;
sts_o6_sensorData.lamp_bar_color = (uint8_t)STS_GREEN;
sts_o6_sensorData.battery_Pct = 99;
sts_o6_sensorData.dutycycletimelevel = 1;
sts_o6_sensorData.event_start_time = 0;
sts_o6_sensorData.event_stop_time = 0;
STS_SENSOR_Power_ON(0);
STS_PRESENCE_SENSOR_REEDSWITCH_HALL_Init();
STS_PRESENCE_SENSOR_TOF_Init();
STS_PRESENCE_SENSOR_RSS_Init();
mems_int1_detected=0;
}
void STS_PRESENCE_SENSOR_TOF_Init(void)
{
APP_LOG(TS_ON, VLEVEL_H, "##### YunHorn SmarToilets(r) MEMS TOF Initializing \r\n");
}
void STS_PRESENCE_SENSOR_REEDSWITCH_HALL_Init(void)
{
APP_LOG(TS_ON, VLEVEL_H, "##### YunHorn SmarToilets(r) REED SWITCH HALL ELEMENT Initializing \r\n");
}
void STS_PRESENCE_SENSOR_RSS_Init(void)
{
APP_LOG(TS_ON, VLEVEL_H, "##### YunHorn SmarToilets(r) MEMS RSS Initializing \r\n");
STS_SENSOR_Power_ON(0);
STS_PRESENCE_SENSOR_NVM_CFG();
sts_rss_config_updated_flag = STS_RSS_CONFIG_DEFAULT;
mems_int1_detected=0;
}
void STS_MOTION_SENSOR_ACT_INACT_DURATION_Init()
{
}
void STS_PRESENCE_SENSOR_Get_Event_Status(STS_PRESENCE_SENSOR_Event_Status_t *Status)
{
uint8_t int_source=0;
SysTime_t mems_event_time;
//int_source = ADXL345_GetRegisterValue(ADXL345_REG_INT_SOURCE);
if (int_source & 0x10) {
mems_event_time = SysTimeGetMcuTime();
Status->WakeUpStatus = 1U;
event_start_time = mems_event_time.Seconds;
}
else {
Status->WakeUpStatus =0U;
}
if (int_source & 0x08) {
mems_event_time = SysTimeGetMcuTime();
Status->SleepStatus = 1U;
event_stop_time = mems_event_time.Seconds;
}
else {
Status->SleepStatus = 0U;
}
}
void STS_PRESENCE_SENSOR_Distance_Measure_Process(void)
{
uint8_t exit_status = EXIT_SUCCESS, i=0;
APP_LOG(TS_OFF, VLEVEL_H, "\r\n ****start_m=%u length_m=%u profile=%u hwaas=%u \r\n",
(unsigned int)(distance_cfg.start_m*1000),(unsigned int)(distance_cfg.length_m*1000),
(unsigned int)(distance_cfg.acc_profile),(unsigned int)(distance_cfg.hwaas));
do
{
exit_status = sts_distance_rss_detector_distance();
HAL_Delay(100);
i++;
} while ((exit_status == EXIT_FAILURE) && (i < 1));
}
void STS_PRESENCE_SENSOR_Function_Test_Process(uint8_t *self_test_result, uint8_t count)
{
uint8_t bring_up_result[20];
STS_SENSOR_Power_ON(0);
HAL_Init();
MX_GPIO_Init();
HAL_Delay(150); //wait for sensor ready
for (uint8_t i=0;i < count; i++) //while(1)
{
STS_Lamp_Bar_Self_Test_Simple();
sts_presence_rss_bring_up_test(bring_up_result);
HAL_Delay(5000);
STS_PRESENCE_SENSOR_Distance_Measure_Process();
}
memcpy(self_test_result,bring_up_result, 10);
mems_int1_detected=0;
}
void STS_PRESENCE_SENSOR_Enable_Wake_Up_Detection()
{
}
void STS_PRESENCE_SENSOR_Disable_Wake_Up_Detection(void)
{
}
uint8_t STS_SENSOR_MEMS_Get_ID(uint8_t *devID)
{
uint8_t scanned_id[2] = {0x0,0x0};
#ifdef YUNHORN_STS_O6_ENABLED
if (hal_test_spi_read_chipid(scanned_id))
{
devID[0] = scanned_id[0];
devID[1] = scanned_id[1];
return true;
}
else
{
return false;
}
#endif
}
/*
uint16_t STS_RSS_A111_GetDeviceIDValue(void)
{
uint16_t devid=0;
if (STS_SENSOR_MEMS_Get_ID(&devid))
{
return (uint16_t)devid;
} else return 0;
}
*/
void STS_SENSOR_Power_ON(uint8_t cnt)
{
switch (cnt) {
case 0:
case 1:
case 2:
#ifdef YUNHORN_STS_M7_ENABLED
HAL_GPIO_WritePin(MEMS_POWER_GPIO_Port, MEMS_POWER_Pin, GPIO_PIN_SET);
#endif
#ifdef YUNHORN_STS_O6_ENABLED
HAL_GPIO_WritePin(MEMS_POWER_GPIO_Port, MEMS_POWER_Pin, GPIO_PIN_SET);
#endif
break;
default:
break;
}
}
void STS_SENSOR_Power_OFF(uint8_t cnt)
{
switch (cnt) {
case 0:
case 1:
case 2:
#ifdef YUNHORN_STS_M7_ENABLED
HAL_GPIO_WritePin(MEMS_POWER_GPIO_Port, MEMS_POWER_Pin, GPIO_PIN_RESET);
#endif
#ifdef YUNHORN_STS_O6_ENABLED
HAL_GPIO_WritePin(MEMS_POWER_GPIO_Port, MEMS_POWER_Pin, GPIO_PIN_RESET);
#endif
break;
default:
break;
}
}
void STS_SENSOR_MEMS_Reset(uint8_t cnt)
{
switch (cnt) {
case 0:
case 1:
case 2:
#ifdef YUNHORN_STS_M7_ENABLED
HAL_GPIO_WritePin(MEMS_RESET_GPIO_Port, MEMS_RESET_Pin, GPIO_PIN_SET);
#endif
#ifdef YUNHORN_STS_O6_ENABLED
HAL_GPIO_WritePin(MEMS_RESET_GPIO_Port, MEMS_RESET_Pin, GPIO_PIN_RESET);
HAL_Delay(100);
HAL_GPIO_WritePin(MEMS_RESET_GPIO_Port, MEMS_RESET_Pin, GPIO_PIN_SET);
#endif
break;
default:
break;
}
}
/* USER CODE BEGIN EF */
/* USER CODE END EF */
/* Private Functions Definition -----------------------------------------------*/
/* USER CODE BEGIN PrFD */
/* USER CODE END PrFD */

View File

@ -17,11 +17,11 @@
<configuration artifactExtension="elf" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf" description="" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.debug.548833444" name="Debug" parent="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.debug">
<folderInfo id="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.debug.548833444." name="/" resourcePath="">
<toolChain id="com.st.stm32cube.ide.mcu.gnu.managedbuild.toolchain.exe.debug.1245189394" name="MCU ARM GCC" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.toolchain.exe.debug">
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_mcu.1668122417" name="MCU" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_mcu" useByScannerDiscovery="true" value="STM32WL55JCIx" valueType="string"/>
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_mcu.1668122417" name="MCU" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_mcu" useByScannerDiscovery="true" value="STM32WLE5CCUx" valueType="string"/>
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_cpuid.377546145" name="CPU" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_cpuid" useByScannerDiscovery="false" value="0" valueType="string"/>
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_coreid.653319510" name="Core" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_coreid" useByScannerDiscovery="false" value="0" valueType="string"/>
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_board.1155291299" name="Board" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_board" useByScannerDiscovery="false" value="NUCLEO-WL55JC1" valueType="string"/>
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.defaults.2103610047" name="Defaults" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.defaults" useByScannerDiscovery="false" value="com.st.stm32cube.ide.common.services.build.inputs.revA.1.0.5 || Debug || true || Executable || com.st.stm32cube.ide.mcu.gnu.managedbuild.option.toolchain.value.workspace || NUCLEO-WL55JC1 || 0 || 0 || arm-none-eabi- || ${gnu_tools_for_stm32_compiler_path} || ../../Core/Inc | ../../LoRaWAN/Target | ../../../../../../../Utilities/misc | ../../../../../../../Middlewares/Third_Party/SubGHz_Phy | ../../../../../../../Utilities/lpm/tiny_lpm | ../../../../../../../Middlewares/Third_Party/SubGHz_Phy/stm32_radio_driver | ../../../../../../../Drivers/CMSIS/Device/ST/STM32WLxx/Include | ../../../../../../../Utilities/sequencer | ../../../../../../../Middlewares/Third_Party/LoRaWAN/LmHandler/Packages | ../../LoRaWAN/App | ../../../../../../../Middlewares/Third_Party/LoRaWAN/Mac/Region | ../../../../../../../Drivers/STM32WLxx_HAL_Driver/Inc | ../../../../../../../Drivers/STM32WLxx_HAL_Driver/Inc/Legacy | ../../../../../../../Utilities/trace/adv_trace | ../../../../../../../Drivers/BSP/STM32WLxx_Nucleo | ../../../../../../../Utilities/timer | ../../../../../../../Middlewares/Third_Party/LoRaWAN/Mac | ../../../../../../../Middlewares/Third_Party/LoRaWAN/Utilities | ../../../../../../../Middlewares/Third_Party/LoRaWAN/Crypto | ../../../../../../../Middlewares/Third_Party/LoRaWAN/LmHandler | ../../../../../../../Drivers/CMSIS/Include || || || USE_HAL_DRIVER | STM32WL55xx | CORE_CM4 || || || || || ${workspace_loc:/${ProjName}/STM32WL55JCIX_FLASH.ld} || true || NonSecure || || secure_nsclib.o || || None || " valueType="string"/>
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_board.1155291299" name="Board" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_board" useByScannerDiscovery="false" value="YUNHORN-STS-WLE5CC" valueType="string"/>
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.defaults.2103610047" name="Defaults" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.defaults" useByScannerDiscovery="false" value="com.st.stm32cube.ide.common.services.build.inputs.revA.1.0.5 || Debug || true || Executable || com.st.stm32cube.ide.mcu.gnu.managedbuild.option.toolchain.value.workspace || NUCLEO-WL55JC1 || 0 || 0 || arm-none-eabi- || ${gnu_tools_for_stm32_compiler_path} || ../../Core/Inc | ../../LoRaWAN/Target | ../../../../../../../Utilities/misc | ../../../../../../../Middlewares/Third_Party/SubGHz_Phy | ../../../../../../../Utilities/lpm/tiny_lpm | ../../../../../../../Middlewares/Third_Party/SubGHz_Phy/stm32_radio_driver | ../../../../../../../Drivers/CMSIS/Device/ST/STM32WLxx/Include | ../../../../../../../Utilities/sequencer | ../../../../../../../Middlewares/Third_Party/LoRaWAN/LmHandler/Packages | ../../LoRaWAN/App | ../../../../../../../Middlewares/Third_Party/LoRaWAN/Mac/Region | ../../../../../../../Drivers/STM32WLxx_HAL_Driver/Inc | ../../../../../../../Drivers/STM32WLxx_HAL_Driver/Inc/Legacy | ../../../../../../../Utilities/trace/adv_trace | ../../../../../../../Drivers/BSP/STM32WLxx_Nucleo | ../../../../../../../Utilities/timer | ../../../../../../../Middlewares/Third_Party/LoRaWAN/Mac | ../../../../../../../Middlewares/Third_Party/LoRaWAN/Utilities | ../../../../../../../Middlewares/Third_Party/LoRaWAN/Crypto | ../../../../../../../Middlewares/Third_Party/LoRaWAN/LmHandler | ../../../../../../../Drivers/CMSIS/Include || || || USE_HAL_DRIVER | STM32WLE5xx | CORE_CM4 || || || || || ${workspace_loc:/${ProjName}/STM32WLE5CCUX_FLASH.ld} || true || NonSecure || || secure_nsclib.o || || None || " valueType="string"/>
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.targetplatform.611324519" isAbstract="false" osList="all" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.targetplatform"/>
<builder buildPath="${workspace_loc:/LoRaWAN_End_Node}/Debug" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.builder.216780214" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.builder"/>
<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.288747390" name="MCU GCC Assembler" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler">
@ -129,11 +129,11 @@
<configuration artifactExtension="elf" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.release.842072465" name="Release" parent="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.release">
<folderInfo id="com.st.stm32cube.ide.mcu.gnu.managedbuild.config.exe.release.842072465." name="/" resourcePath="">
<toolChain id="com.st.stm32cube.ide.mcu.gnu.managedbuild.toolchain.exe.release.628144182" name="MCU ARM GCC" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.toolchain.exe.release">
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_mcu.2079728176" name="MCU" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_mcu" useByScannerDiscovery="true" value="STM32WL55JCIx" valueType="string"/>
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_mcu.2079728176" name="MCU" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_mcu" useByScannerDiscovery="true" value="STM32WLE5CCUx" valueType="string"/>
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_cpuid.467096959" name="CPU" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_cpuid" useByScannerDiscovery="false" value="0" valueType="string"/>
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_coreid.1220095777" name="Core" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_coreid" useByScannerDiscovery="false" value="0" valueType="string"/>
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_board.2109882892" name="Board" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_board" useByScannerDiscovery="false" value="NUCLEO-WL55JC1" valueType="string"/>
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.defaults.239742593" name="Defaults" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.defaults" useByScannerDiscovery="false" value="com.st.stm32cube.ide.common.services.build.inputs.revA.1.0.5 || Release || false || Executable || com.st.stm32cube.ide.mcu.gnu.managedbuild.option.toolchain.value.workspace || NUCLEO-WL55JC1 || 0 || 0 || arm-none-eabi- || ${gnu_tools_for_stm32_compiler_path} || ../../Core/Inc | ../../LoRaWAN/Target | ../../../../../../../Utilities/misc | ../../../../../../../Middlewares/Third_Party/SubGHz_Phy | ../../../../../../../Utilities/lpm/tiny_lpm | ../../../../../../../Middlewares/Third_Party/SubGHz_Phy/stm32_radio_driver | ../../../../../../../Drivers/CMSIS/Device/ST/STM32WLxx/Include | ../../../../../../../Utilities/sequencer | ../../../../../../../Middlewares/Third_Party/LoRaWAN/LmHandler/Packages | ../../LoRaWAN/App | ../../../../../../../Middlewares/Third_Party/LoRaWAN/Mac/Region | ../../../../../../../Drivers/STM32WLxx_HAL_Driver/Inc | ../../../../../../../Drivers/STM32WLxx_HAL_Driver/Inc/Legacy | ../../../../../../../Utilities/trace/adv_trace | ../../../../../../../Drivers/BSP/STM32WLxx_Nucleo | ../../../../../../../Utilities/timer | ../../../../../../../Middlewares/Third_Party/LoRaWAN/Mac | ../../../../../../../Middlewares/Third_Party/LoRaWAN/Utilities | ../../../../../../../Middlewares/Third_Party/LoRaWAN/Crypto | ../../../../../../../Middlewares/Third_Party/LoRaWAN/LmHandler | ../../../../../../../Drivers/CMSIS/Include || || || USE_HAL_DRIVER | STM32WL55xx | CORE_CM4 || || || || || ${workspace_loc:/${ProjName}/STM32WL55JCIX_FLASH.ld} || true || NonSecure || || secure_nsclib.o || || None || " valueType="string"/>
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_board.2109882892" name="Board" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_board" useByScannerDiscovery="false" value="YUNHORN-STS-WLE5Cx" valueType="string"/>
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.defaults.239742593" name="Defaults" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.defaults" useByScannerDiscovery="false" value="com.st.stm32cube.ide.common.services.build.inputs.revA.1.0.5 || Release || false || Executable || com.st.stm32cube.ide.mcu.gnu.managedbuild.option.toolchain.value.workspace || NUCLEO-WL55JC1 || 0 || 0 || arm-none-eabi- || ${gnu_tools_for_stm32_compiler_path} || ../../Core/Inc | ../../LoRaWAN/Target | ../../../../../../../Utilities/misc | ../../../../../../../Middlewares/Third_Party/SubGHz_Phy | ../../../../../../../Utilities/lpm/tiny_lpm | ../../../../../../../Middlewares/Third_Party/SubGHz_Phy/stm32_radio_driver | ../../../../../../../Drivers/CMSIS/Device/ST/STM32WLxx/Include | ../../../../../../../Utilities/sequencer | ../../../../../../../Middlewares/Third_Party/LoRaWAN/LmHandler/Packages | ../../LoRaWAN/App | ../../../../../../../Middlewares/Third_Party/LoRaWAN/Mac/Region | ../../../../../../../Drivers/STM32WLxx_HAL_Driver/Inc | ../../../../../../../Drivers/STM32WLxx_HAL_Driver/Inc/Legacy | ../../../../../../../Utilities/trace/adv_trace | ../../../../../../../Drivers/BSP/STM32WLxx_Nucleo | ../../../../../../../Utilities/timer | ../../../../../../../Middlewares/Third_Party/LoRaWAN/Mac | ../../../../../../../Middlewares/Third_Party/LoRaWAN/Utilities | ../../../../../../../Middlewares/Third_Party/LoRaWAN/Crypto | ../../../../../../../Middlewares/Third_Party/LoRaWAN/LmHandler | ../../../../../../../Drivers/CMSIS/Include || || || USE_HAL_DRIVER | STM32WLE5xx | CORE_CM4 || || || || || ${workspace_loc:/${ProjName}/STM32WLE5CCUX_FLASH.ld} || true || NonSecure || || secure_nsclib.o || || None || " valueType="string"/>
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.nanoscanffloat.1874218879" name="Use float with scanf from newlib-nano (-u _scanf_float)" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.nanoscanffloat" useByScannerDiscovery="false" value="false" valueType="boolean"/>
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.nanoprintffloat.1776401448" name="Use float with printf from newlib-nano (-u _printf_float)" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.nanoprintffloat" useByScannerDiscovery="false" value="false" valueType="boolean"/>
<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.convertbinary.639397767" name="Convert to binary file (-O binary)" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.convertbinary" useByScannerDiscovery="false" value="true" valueType="boolean"/>

View File

@ -447,6 +447,11 @@
<type>1</type>
<locationURI>copy_PARENT/Core/Src/gpio.c</locationURI>
</link>
<link>
<name>Application/User/Core/i2c.c</name>
<type>1</type>
<locationURI>copy_PARENT/Core/Src/i2c.c</locationURI>
</link>
<link>
<name>Application/User/Core/main.c</name>
<type>1</type>

View File

@ -0,0 +1,2 @@
eclipse.preferences.version=1
encoding/<project>=UTF-8

View File

@ -0,0 +1,223 @@
/*
Copyright (c) 2021, STMicroelectronics - All Rights Reserved
This file : part of VL53L1X ULP and : dual licensed,
either 'STMicroelectronics
Proprietary license'
or 'BSD 3-clause "New" or "Revised" License' , at your option.
*******************************************************************************
'STMicroelectronics Proprietary license'
*******************************************************************************
License terms: STMicroelectronics Proprietary in accordance with licensing
terms at www.st.com/sla0081
STMicroelectronics confidential
Reproduction and Communication of this document : strictly prohibited unless
specifically authorized in writing by STMicroelectronics.
*******************************************************************************
Alternatively, VL53L1X ULP may be distributed under the terms of
'BSD 3-clause "New" or "Revised" License', in which case the following
provisions apply instead of the ones mentioned above :
*******************************************************************************
License terms: BSD 3-clause "New" or "Revised" License.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************
*/
/****************************************/
/* VL53L1X Low Power basic ranging */
/****************************************/
/*
* This example shows how to use the VL53L1X Ultra Low Power driver in a very
* simple example. It initializes the VL53L1X driver, configure the sensor and
* starts a ranging to capture 200 frames.
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "sys_app.h"
#include "VL53L1X_ULP_api.h"
extern uint8_t ToF_EventDetected;
/*
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_L,"############### TOF EVENT DETECTED \r\n");
ToF_EventDetected =0;
return 1;
} else {
return 0;
}
}
*/
int Example_1_basic_ranging(void)
{ /*
int sts_vl53lx_ranging(uint8_t vl_model, 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, uint16_t i_ambient_kcps);
*/
/*********************************/
/* VL53L1X ranging variables */
/*********************************/
uint8_t status, loop;
uint8_t dev;
uint16_t sensor_id;
uint8_t measurement_status;
uint16_t estimated_distance_mm, signal_kcps, sigma_mm, ambient_kcps;
/*********************************/
/* Customer platform */
/*********************************/
/* Default VL53L1X Ultra Low Power I2C address */
dev = 0x52;
/* (Optional) Change I2C address */
// status = VL53L1X_ULP_SetI2CAddress(dev, 0x52); //0x20
// dev = 0x20;
/*********************************/
/* Power on sensor and init */
/*********************************/
/* (Optional) Check if there is a VL53L1X sensor connected */
status = VL53L1X_ULP_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_ULP_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_ULP_SetInterruptConfiguration(dev, 800, 1); //i_distance_threshold_mm
/* (Optional) Program a 10Hz ranging frequency */
status = VL53L1X_ULP_SetInterMeasurementInMs(dev, 100); // range_interval_ms
{
/* Increase the macro timing. This is equivalent as increasing the integration time */
status = VL53L1X_ULP_SetMacroTiming(dev, 100); // micro_timing_ms
/* Enable all the SPADS */
status = VL53L1X_ULP_SetROI(dev, 16); // SPADS { 1 -- 16 }
// 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);
/* Reduce at maximum the SPADS */
//status = VL53L1X_ULP_SetROI(dev, 4);
// 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);
// 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);
}
/*********************************/
/* Ranging loop */
/*********************************/
status = VL53L1X_ULP_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_ULP_ClearInterrupt(dev);
/* Dump debug data */
status = VL53L1X_ULP_DumpDebugData(dev, &measurement_status,
&estimated_distance_mm, &sigma_mm, &signal_kcps, &ambient_kcps);
APP_LOG(TS_OFF,VLEVEL_L,"Target detected! Interrupt raised by sensor, Distance =%d mm \r\n", estimated_distance_mm );
loop++;
}
}
status = VL53L1X_ULP_StopRanging(dev);
APP_LOG(TS_OFF,VLEVEL_L,"End of VL53L1X ultra low power demo\n");
return status;
}

View File

@ -0,0 +1,217 @@
/*
Copyright (c) 2021, STMicroelectronics - All Rights Reserved
This file : part of VL53L1X ULP and : dual licensed,
either 'STMicroelectronics
Proprietary license'
or 'BSD 3-clause "New" or "Revised" License' , at your option.
*******************************************************************************
'STMicroelectronics Proprietary license'
*******************************************************************************
License terms: STMicroelectronics Proprietary in accordance with licensing
terms at www.st.com/sla0081
STMicroelectronics confidential
Reproduction and Communication of this document : strictly prohibited unless
specifically authorized in writing by STMicroelectronics.
*******************************************************************************
Alternatively, VL53L1X ULP may be distributed under the terms of
'BSD 3-clause "New" or "Revised" License', in which case the following
provisions apply instead of the ones mentioned above :
*******************************************************************************
License terms: BSD 3-clause "New" or "Revised" License.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************
*/
/****************************************/
/* VL53L1X Low Power tune sensor */
/****************************************/
/*
* This example shows how to tune the VL53L1X Low power for a specific
* application, playing with sigma and signal threshold.
* It initializes the VL53L1X driver, configure the sensor and
* starts a ranging to capture 200 frames.
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "../../STM32CubeIDE/Drivers/BSP/vl53l1x_uld/VL53L1X_ULP_api.h"
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)
}
uint8_t Example_2_tune_sensor_with_debug_data(void)
{
/*********************************/
/* VL53L1X ranging variables */
/*********************************/
uint8_t status, loop;
uint8_t dev;
uint16_t sensor_id;
uint8_t measurement_status;
uint16_t estimated_distance_mm, signal_kcps, sigma_mm, ambient_kcps;
/*********************************/
/* Customer platform */
/*********************************/
/* Default VL53L1X Ultra Low Power I2C address */
dev = 0x52;
/* (Optional) Change I2C address */
// status = VL53L1X_ULP_SetI2CAddress(dev, 0x20);
// dev = 0x20;
/*********************************/
/* Power on sensor and init */
/*********************************/
/* (Optional) Check if there is a VL53L1X sensor connected */
status = VL53L1X_ULP_GetSensorId(dev, &sensor_id);
if(status || (sensor_id != 0xEACC))
{
printf("VL53L1X not detected at requested address\n");
return status;
}
/* (Mandatory) Init VL53L1X sensor */
status = VL53L1X_ULP_SensorInit(dev);
if(status)
{
printf("VL53L1X ultra low power Loading failed\n");
return status;
}
printf("VL53L1X ultra low power ready !\n");
/*********************************/
/* Sensor tuning */
/*********************************/
/* Here we will change some settings to tune the sensor valid measurements.
* The sensor can output 2 thresholds used to define a valid distance :
* - Sigma threshold. This is the estimated standard deviation of the
* measurement. A low value means that the accuracy is good. Reducing
* this threshold reduces the max ranging distance, but it reduces the
* number of false-positives.
*
* - Signal threshold. This is the quantity of photons measured by the
* sensor. A high value means that the accuracy is good. Increasing
* this threshold reduces the max ranging distance, but it reduces the
* number of false-positives.
*/
/* 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);
/* Example for longer distance measurements. Max distance increased
* but false-positives may appear */
// status |= VL53L1X_ULP_SetSigmaThreshold(dev, 60);
// status |= VL53L1X_ULP_SetSignalThreshold(dev, 1200);
/*********************************/
/* Sensor configuration */
/*********************************/
/* (Optional) Program sensor to output interrupt when a new measurement is
* ready, even if the distance is not valid */
status = VL53L1X_ULP_SetInterruptConfiguration(dev, 0, 0);
/* (Optional) Program a 10Hz ranging frequency */
status = VL53L1X_ULP_SetInterMeasurementInMs(dev, 100);
/*********************************/
/* Ranging loop */
/*********************************/
status = VL53L1X_ULP_StartRanging(dev);
if(status)
{
printf("VL53L1X_ULP_StartRanging failed with status %u\n", status);
return status;
}
printf("Ranging started. Put your hand close to the sensor to generate an interrupt...\n");
loop = 0;
while(loop < 200)
{
/* 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_ULP_ClearInterrupt(dev);
/* Dump debug data */
status = VL53L1X_ULP_DumpDebugData(dev, &measurement_status,
&estimated_distance_mm, &sigma_mm, &signal_kcps, &ambient_kcps);
/* Print debug data. Measurement status 0 means that a valid target
* has been detected */
printf("DEBUG DATA : Status = %2u, Estimated distance = %4u mm, Signal = %6u kcps, Sigma = %3u mm\n",
measurement_status,
estimated_distance_mm,
signal_kcps,
sigma_mm);
loop++;
}
}
status = VL53L1X_ULP_StopRanging(dev);
printf("End of VL53L1X ultra low power demo\n");
return status;
}

View File

@ -0,0 +1,185 @@
/*
Copyright (c) 2021, STMicroelectronics - All Rights Reserved
This file : part of VL53L1X ULP and : dual licensed,
either 'STMicroelectronics
Proprietary license'
or 'BSD 3-clause "New" or "Revised" License' , at your option.
*******************************************************************************
'STMicroelectronics Proprietary license'
*******************************************************************************
License terms: STMicroelectronics Proprietary in accordance with licensing
terms at www.st.com/sla0081
STMicroelectronics confidential
Reproduction and Communication of this document : strictly prohibited unless
specifically authorized in writing by STMicroelectronics.
*******************************************************************************
Alternatively, VL53L1X ULP may be distributed under the terms of
'BSD 3-clause "New" or "Revised" License', in which case the following
provisions apply instead of the ones mentioned above :
*******************************************************************************
License terms: BSD 3-clause "New" or "Revised" License.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************
*/
/****************************************/
/* VL53L1X Low Power basic ranging */
/****************************************/
/*
* This example shows how to use the VL53L1X Ultra Low Power driver for
* detecting a user at long distance (>60cm). Please note that the proposed
* configuration also increase the power consumption.
* The example initializes the VL53L1X driver, configure the sensor and
* starts a ranging to capture 200 frames.
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "../../STM32CubeIDE/Drivers/BSP/vl53l1x_uld/VL53L1X_ULP_api.h"
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)
}
uint8_t Example_3_long_ranging(void)
{
/*********************************/
/* VL53L1X ranging variables */
/*********************************/
uint8_t status, loop;
uint8_t dev;
uint16_t sensor_id;
/*********************************/
/* Customer platform */
/*********************************/
/* Default VL53L1X Ultra Low Power I2C address */
dev = 0x52;
/* (Optional) Change I2C address */
// status = VL53L1X_ULP_SetI2CAddress(dev, 0x20);
// dev = 0x20;
/*********************************/
/* Power on sensor and init */
/*********************************/
/* (Optional) Check if there is a VL53L1X sensor connected */
status = VL53L1X_ULP_GetSensorId(dev, &sensor_id);
if(status || (sensor_id != 0xEACC))
{
printf("VL53L1X not detected at requested address\n");
return status;
}
/* (Mandatory) Init VL53L1X sensor */
status = VL53L1X_ULP_SensorInit(dev);
if(status)
{
printf("VL53L1X ultra low power Loading failed\n");
return status;
}
printf("VL53L1X ultra low power ready !\n");
/*********************************/
/* Sensor configuration */
/*********************************/
/* (Optional) Program sensor to raise an interrupt ONLY below 600mm */
status = VL53L1X_ULP_SetInterruptConfiguration(dev, 600, 1);
/* (Optional) Program a 10Hz ranging frequency */
status = VL53L1X_ULP_SetInterMeasurementInMs(dev, 100);
/* Increase the macro timing. This is equivalent as increasing the integration time */
status = VL53L1X_ULP_SetMacroTiming(dev, 100);
/* Enable all the SPADS */
status = VL53L1X_ULP_SetROI(dev, 16);
/* Relax some limits. Be careful, it can create false-positives !*/
status |= VL53L1X_ULP_SetSigmaThreshold(dev, 60);
status |= VL53L1X_ULP_SetSignalThreshold(dev, 1200);
/*********************************/
/* Ranging loop */
/*********************************/
status = VL53L1X_ULP_StartRanging(dev);
if(status)
{
printf("VL53L1X_ULP_StartRanging failed with status %u\n", status);
return status;
}
printf("Ranging started. Put your hand close to the sensor to generate an interrupt...\n");
loop = 0;
while(loop < 200)
{
/* 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_ULP_ClearInterrupt(dev);
printf("Target detected! Interrupt raised by sensor\n");
loop++;
}
}
status = VL53L1X_ULP_StopRanging(dev);
printf("End of VL53L1X ultra low power demo\n");
return status;
}

View File

@ -0,0 +1,180 @@
/*
Copyright (c) 2021, STMicroelectronics - All Rights Reserved
This file : part of VL53L1X ULP and : dual licensed,
either 'STMicroelectronics
Proprietary license'
or 'BSD 3-clause "New" or "Revised" License' , at your option.
*******************************************************************************
'STMicroelectronics Proprietary license'
*******************************************************************************
License terms: STMicroelectronics Proprietary in accordance with licensing
terms at www.st.com/sla0081
STMicroelectronics confidential
Reproduction and Communication of this document : strictly prohibited unless
specifically authorized in writing by STMicroelectronics.
*******************************************************************************
Alternatively, VL53L1X ULP may be distributed under the terms of
'BSD 3-clause "New" or "Revised" License', in which case the following
provisions apply instead of the ones mentioned above :
*******************************************************************************
License terms: BSD 3-clause "New" or "Revised" License.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************
*/
/****************************************/
/* VL53L1X Low Power basic ranging */
/****************************************/
/*
* This example shows how to use the VL53L1X Ultra Low Power driver with the
* lowest possible power consumption.
* The example initializes the VL53L1X driver, configure the sensor and
* starts a ranging to capture 200 frames.
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "../../STM32CubeIDE/Drivers/BSP/vl53l1x_uld/VL53L1X_ULP_api.h"
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)
}
uint8_t Example_4_ultra_low_power(void)
{
/*********************************/
/* VL53L1X ranging variables */
/*********************************/
uint8_t status, loop;
uint8_t dev;
uint16_t sensor_id;
/*********************************/
/* Customer platform */
/*********************************/
/* Default VL53L1X Ultra Low Power I2C address */
dev = 0x52;
/* (Optional) Change I2C address */
// status = VL53L1X_ULP_SetI2CAddress(dev, 0x20);
// dev = 0x20;
/*********************************/
/* Power on sensor and init */
/*********************************/
/* (Optional) Check if there is a VL53L1X sensor connected */
status = VL53L1X_ULP_GetSensorId(dev, &sensor_id);
if(status || (sensor_id != 0xEACC))
{
printf("VL53L1X not detected at requested address\n");
return status;
}
/* (Mandatory) Init VL53L1X sensor */
status = VL53L1X_ULP_SensorInit(dev);
if(status)
{
printf("VL53L1X ultra low power Loading failed\n");
return status;
}
printf("VL53L1X ultra low power ready !\n");
/*********************************/
/* Sensor configuration */
/*********************************/
/* (Optional) Program sensor to raise an interrupt ONLY below 300mm */
status = VL53L1X_ULP_SetInterruptConfiguration(dev, 300, 1);
/* (Optional) Program a 10Hz ranging frequency */
status = VL53L1X_ULP_SetInterMeasurementInMs(dev, 100);
/* Reduce the macro timing to minimum. This is equivalent as reducing the integration time */
status = VL53L1X_ULP_SetMacroTiming(dev, 1);
/* Reduce at maximum the SPADS */
status = VL53L1X_ULP_SetROI(dev, 4);
/*********************************/
/* Ranging loop */
/*********************************/
status = VL53L1X_ULP_StartRanging(dev);
if(status)
{
printf("VL53L1X_ULP_StartRanging failed with status %u\n", status);
return status;
}
printf("Ranging started. Put your hand close to the sensor to generate an interrupt...\n");
loop = 0;
while(loop < 200)
{
/* 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_ULP_ClearInterrupt(dev);
printf("Target detected! Interrupt raised by sensor\n");
loop++;
}
}
status = VL53L1X_ULP_StopRanging(dev);
printf("End of VL53L1X ultra low power demo\n");
return status;
}

188
TOF/App/app_tof.c Normal file
View File

@ -0,0 +1,188 @@
/**
******************************************************************************
* @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 <stdio.h>
#include "53l1a2_ranging_sensor.h"
#include "stm32wlxx_nucleo.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define TIMING_BUDGET (30U) /* 16 ms < TimingBudget < 500 ms */
#define POLLING_PERIOD (250U) /* refresh rate for polling mode (milliseconds, shall be consistent with TimingBudget value) */
/* Private variables ---------------------------------------------------------*/
static RANGING_SENSOR_Capabilities_t Cap;
static RANGING_SENSOR_ProfileConfig_t Profile;
static int32_t status = 0;
static volatile uint8_t PushButtonDetected = 0;
volatile uint8_t ToF_EventDetected = 0;
/* Private function prototypes -----------------------------------------------*/
static void MX_53L1A2_SimpleRanging_Init(void);
static void MX_53L1A2_SimpleRanging_Process(void);
static void print_result(RANGING_SENSOR_Result_t *Result);
static int32_t decimal_part(float_t x);
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 */
MX_53L1A2_SimpleRanging_Init();
/* USER CODE BEGIN TOF_Init_PostTreatment */
/* USER CODE END TOF_Init_PostTreatment */
}
/*
* LM background task
*/
void MX_TOF_Process(void)
{
/* USER CODE BEGIN TOF_Process_PreTreatment */
/* USER CODE END TOF_Process_PreTreatment */
MX_53L1A2_SimpleRanging_Process();
/* USER CODE BEGIN TOF_Process_PostTreatment */
/* USER CODE END TOF_Process_PostTreatment */
}
static void MX_53L1A2_SimpleRanging_Init(void)
{
/* Initialize Virtual COM Port */
BSP_COM_Init(COM1);
/* Initialize button */
BSP_PB_Init(BUTTON_KEY, BUTTON_MODE_EXTI);
printf("53L1A2 Simple Ranging demo application\n");
status = VL53L1A2_RANGING_SENSOR_Init(VL53L1A2_DEV_CENTER);
if (status != BSP_ERROR_NONE)
{
printf("VL53L1A2_RANGING_SENSOR_Init failed\n");
while(1);
}
}
static void MX_53L1A2_SimpleRanging_Process(void)
{
uint32_t Id;
RANGING_SENSOR_Result_t Result;
VL53L1A2_RANGING_SENSOR_ReadID(VL53L1A2_DEV_CENTER, &Id);
VL53L1A2_RANGING_SENSOR_GetCapabilities(VL53L1A2_DEV_CENTER, &Cap);
Profile.RangingProfile = RS_MULTI_TARGET_MEDIUM_RANGE;
Profile.TimingBudget = TIMING_BUDGET; /* 16 ms < TimingBudget < 500 ms */
Profile.Frequency = 0; /* Induces intermeasurement period, set to ZERO for normal ranging */
Profile.EnableAmbient = 1; /* Enable: 1, Disable: 0 */
Profile.EnableSignal = 1; /* Enable: 1, Disable: 0 */
/* set the profile if different from default one */
VL53L1A2_RANGING_SENSOR_ConfigProfile(VL53L1A2_DEV_CENTER, &Profile);
status = VL53L1A2_RANGING_SENSOR_Start(VL53L1A2_DEV_CENTER, RS_MODE_BLOCKING_CONTINUOUS);
if (status != BSP_ERROR_NONE)
{
printf("VL53L1A2_RANGING_SENSOR_Start failed\n");
while(1);
}
while (1)
{
/* polling mode */
status = VL53L1A2_RANGING_SENSOR_GetDistance(VL53L1A2_DEV_CENTER, &Result);
if (status == BSP_ERROR_NONE)
{
print_result(&Result);
}
HAL_Delay(POLLING_PERIOD);
}
}
static void print_result(RANGING_SENSOR_Result_t *Result)
{
uint8_t i, j;
for (i = 0; i < RANGING_SENSOR_MAX_NB_ZONES; i++)
{
printf("\nTargets = %lu", (unsigned long)Result->ZoneResult[i].NumberOfTargets);
for (j = 0; j < Result->ZoneResult[i].NumberOfTargets; j++)
{
printf("\n |---> ");
printf("Status = %ld, Distance = %5ld mm ",
(long)Result->ZoneResult[i].Status[j],
(long)Result->ZoneResult[i].Distance[j]);
if (Profile.EnableAmbient)
printf(", Ambient = %ld.%02ld kcps/spad",
(long)Result->ZoneResult[i].Ambient[j],
(long)decimal_part(Result->ZoneResult[i].Ambient[j]));
if (Profile.EnableSignal)
printf(", Signal = %ld.%02ld kcps/spad",
(long)Result->ZoneResult[i].Signal[j],
(long)decimal_part(Result->ZoneResult[i].Signal[j]));
}
}
printf ("\n");
}
static int32_t decimal_part(float_t x)
{
int32_t int_part = (int32_t) x;
return (int32_t)((x - int_part) * 100);
}
void BSP_PB_Callback(Button_TypeDef Button)
{
PushButtonDetected = 1;
}
#ifdef __cplusplus
}
#endif

41
TOF/App/app_tof.h Normal file
View File

@ -0,0 +1,41 @@
/**
******************************************************************************
* @file : app_tof.h
* @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.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __APP_TOF_H
#define __APP_TOF_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
/* Exported defines ----------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
void MX_TOF_Init(void);
void MX_TOF_Process(void);
#ifdef __cplusplus
}
#endif
#endif /* __APP_TOF_H */

View File

@ -0,0 +1,442 @@
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "sys_app.h"
/* USER CODE BEGIN Includes */
#include "app_tof_peoplecount.h"
#include "VL53L1X_API.h"
#include "VL53l1X_calibration.h"
#include "X-NUCLEO-53L1A1.h"
#include "app_tof.h"
/* USER CODE END Includes */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
extern I2C_HandleTypeDef hi2c2;
volatile sts_people_count_sensor_data_t sts_people_count_sensor_data={0,0,0,2,'M',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
volatile sts_ppc_cfg_type_t ppc_cfg[3] = {
{DOOR_JAM_2000, 8, 2000,0,1600,8,33,DISTANCE_MODE_SHORT,175,247},
{DOOR_JAM_2000, 8, 2000,0,1600,8,33,DISTANCE_MODE_SHORT,175,247},
{DOOR_JAM_2400, 10, 2400,0,1600,8,33,DISTANCE_MODE_LONG,175,231},
};
volatile sts_zone_center_by_rows_of_spads_t zone_center[3]={
{4, 151, 247},
{6, 159, 239},
{8, 175, 231},
};
volatile uint8_t sts_distance_mode = DISTANCE_MODE_LONG;
volatile uint8_t sts_people_count_number_changed = 0;
uint16_t dev=0x52;
int status = 0;
volatile int IntCount;
#define isInterrupt 1 /* If isInterrupt = 1 then device working in interrupt mode, else device working in polling mode */
/* USER CODE END PV */
static int PplCounter;
static int center[2] = {FRONT_ZONE_CENTER,BACK_ZONE_CENTER}; //{ppc_cfg[sts_distance_mode].front_zone_center, ppc_cfg[sts_distance_mode].back_zone_center}; /* these are the spad center of the 2 4*16 zones */
static int Zone = 0;
static int PathTrack[] = {0,0,0,0};
static int PathTrackFillingSize = 1; // init this to 1 as we start from state where nobody is any of the zones
static int LeftPreviousStatus = NOBODY;
static int RightPreviousStatus = NOBODY;
static int PeopleCount = 0;
static uint16_t Distances[2][DISTANCES_ARRAY_SIZE];
static uint8_t DistancesTableSize[2] = {0,0};
/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE END PFP */
//void sts_tof_vl53lx_peoplecount(void);
//int sts_tof_vl53lx_peoplecount_subprocess(void);
/* USER CODE BEGIN 0 */
#define VL53L1X_INT_Pin (GPIO_PIN_3) // WL55JC GPIO_PIN_10, F401xE ==>(GPIO_PIN_4)
#if 0
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if (GPIO_Pin==VL53L1X_INT_Pin)
{
IntCount++;
}
}
#endif
/* USER CODE END 0 */
int ProcessPeopleCountingData(int16_t Distance, uint8_t zone, uint8_t RangeStatus) {
uint16_t MinDistance;
uint8_t i;
#ifdef TRACE_PPC
#define TIMES_WITH_NO_EVENT 10// was 40
static uint32_t trace_count = TIMES_WITH_NO_EVENT; // replace by 0 if you want to trace the first TIMES_WITH_NO_EVENT values
#endif
int CurrentZoneStatus = NOBODY;
int AllZonesCurrentStatus = 0;
int AnEventHasOccured = 0;
// Add just picked distance to the table of the corresponding zone
if (DistancesTableSize[zone] < ppc_cfg[sts_distance_mode].distance_array_size) {
Distances[zone][DistancesTableSize[zone]] = Distance;
DistancesTableSize[zone] ++;
}
else {
for (i=1; i<ppc_cfg[sts_distance_mode].distance_array_size; i++)
Distances[zone][i-1] = Distances[zone][i];
Distances[zone][ppc_cfg[sts_distance_mode].distance_array_size-1] = Distance;
}
// pick up the min distance
MinDistance = Distances[zone][0];
if (DistancesTableSize[zone] >= 2) {
for (i=1; i<DistancesTableSize[zone]; i++) {
if (Distances[zone][i] < MinDistance)
MinDistance = Distances[zone][i];
}
}
if (MinDistance < ppc_cfg[sts_distance_mode].dist_threshold) {
// Someone is in !
CurrentZoneStatus = SOMEONE;
}
// left zone
if (zone == LEFT) {
if (CurrentZoneStatus != LeftPreviousStatus) {
// event in left zone has occured
AnEventHasOccured = 1;
if (CurrentZoneStatus == SOMEONE) {
AllZonesCurrentStatus += 1;
}
// need to check right zone as well ...
if (RightPreviousStatus == SOMEONE) {
// event in left zone has occured
AllZonesCurrentStatus += 2;
}
// remember for next time
LeftPreviousStatus = CurrentZoneStatus;
}
}
// right zone
else {
if (CurrentZoneStatus != RightPreviousStatus) {
// event in left zone has occured
AnEventHasOccured = 1;
if (CurrentZoneStatus == SOMEONE) {
AllZonesCurrentStatus += 2;
}
// need to left right zone as well ...
if (LeftPreviousStatus == SOMEONE) {
// event in left zone has occured
AllZonesCurrentStatus += 1;
}
// remember for next time
RightPreviousStatus = CurrentZoneStatus;
}
}
#ifdef TRACE_PPC
// print debug data only when someone is within the field of view
trace_count++;
if ((CurrentZoneStatus == SOMEONE) || (LeftPreviousStatus == SOMEONE) || (RightPreviousStatus == SOMEONE))
trace_count = 0;
#if 0
if (trace_count < TIMES_WITH_NO_EVENT)
printf ("%d,%d,%d,%d,%d\n", zone, Distance, MinDistance, RangeStatus, PeopleCount);
#endif
#endif
// if an event has occured
if (AnEventHasOccured) {
if (PathTrackFillingSize < 4) {
PathTrackFillingSize ++;
}
// if nobody anywhere lets check if an exit or entry has happened
if ((LeftPreviousStatus == NOBODY) && (RightPreviousStatus == NOBODY)) {
// check exit or entry only if PathTrackFillingSize is 4 (for example 0 1 3 2) and last event is 0 (nobobdy anywhere)
if (PathTrackFillingSize == 4) {
// check exit or entry. no need to check PathTrack[0] == 0 , it is always the case
if ((PathTrack[1] == 1) && (PathTrack[2] == 3) && (PathTrack[3] == 2)) {
// This an entry
PeopleCount ++;
// reset the table filling size in case an entry or exit just found
DistancesTableSize[0] = 0;
DistancesTableSize[1] = 0;
APP_LOG(TS_OFF, VLEVEL_M,"Walk In, People Count=%d\n", PeopleCount);
sts_people_count_sensor_data.Walk_In_People_Count ++;
sts_people_count_number_changed = 1;
} else if ((PathTrack[1] == 2) && (PathTrack[2] == 3) && (PathTrack[3] == 1)) {
// This an exit
PeopleCount --;
// reset the table filling size in case an entry or exit just found
DistancesTableSize[0] = 0;
DistancesTableSize[1] = 0;
APP_LOG(TS_OFF, VLEVEL_M,"Walk Out, People Count=%d\n", PeopleCount);
sts_people_count_sensor_data.Walk_Out_People_Count ++;
sts_people_count_number_changed = 1;
} else {
// reset the table filling size also in case of unexpected path
DistancesTableSize[0] = 0;
DistancesTableSize[1] = 0;
APP_LOG(TS_OFF, VLEVEL_M,"Walk Around ie. Wrong path\n");
sts_people_count_sensor_data.Walk_Around_People_Count ++;
}
}
PathTrackFillingSize = 1;
}
else {
// update PathTrack
// example of PathTrack update
// 0
// 0 1
// 0 1 3
// 0 1 3 1
// 0 1 3 3
// 0 1 3 2 ==> if next is 0 : check if exit
PathTrack[PathTrackFillingSize-1] = AllZonesCurrentStatus;
}
#if 1
#ifdef TRACE_PPC
if (AnEventHasOccured) {
for (int j=0; j<PathTrackFillingSize; j++)
printf ("%d ", PathTrack[j]);
}
printf("\n");
#endif
#endif
}
//printf ("Inside PeopleCount = %d , returned\n", PeopleCount);
// output debug data to main host machine
return(PeopleCount);
}
void STS_people_count_sensor_Read(sts_people_count_sensor_data_t *sts_p2_sensor_data)
{
sts_p2_sensor_data->Walk_In_People_Count = sts_people_count_sensor_data.Walk_In_People_Count;
sts_p2_sensor_data->Walk_Out_People_Count = sts_people_count_sensor_data.Walk_Out_People_Count;
sts_p2_sensor_data->Walk_Around_People_Count = sts_people_count_sensor_data.Walk_Around_People_Count;
sts_p2_sensor_data->Count_Period = sts_people_count_sensor_data.Count_Period;
sts_p2_sensor_data->Count_Period_Unit = sts_people_count_sensor_data.Count_Period_Unit;
// Sum Day counting
// if not end of day ---
sts_people_count_sensor_data.Sum_Day_Walk_In_People_Count += sts_people_count_sensor_data.Walk_In_People_Count;
sts_people_count_sensor_data.Sum_Day_Walk_Out_People_Count += sts_people_count_sensor_data.Walk_Out_People_Count;
sts_people_count_sensor_data.Sum_Day_Walk_Around_People_Count += sts_people_count_sensor_data.Walk_Around_People_Count;
sts_p2_sensor_data->Sum_Day_Walk_In_People_Count = sts_people_count_sensor_data.Sum_Day_Walk_In_People_Count;
sts_p2_sensor_data->Sum_Day_Walk_Out_People_Count = sts_people_count_sensor_data.Sum_Day_Walk_Out_People_Count;
sts_p2_sensor_data->Sum_Day_Walk_Around_People_Count = sts_people_count_sensor_data.Sum_Day_Walk_Around_People_Count;
// else reset day counter
#if 0
sts_people_count_sensor_data.Sum_Day_Walk_In_People_Count = 0;
sts_people_count_sensor_data.Sum_Day_Walk_Out_People_Count = 0;
sts_people_count_sensor_data.Sum_Day_Walk_Around_People_Count = 0;
#endif
// Sum Week counting
// if not end of week ---
sts_people_count_sensor_data.Sum_Week_Walk_In_People_Count += sts_people_count_sensor_data.Sum_Day_Walk_In_People_Count;
sts_people_count_sensor_data.Sum_Week_Walk_Out_People_Count += sts_people_count_sensor_data.Sum_Day_Walk_Out_People_Count;
sts_people_count_sensor_data.Sum_Week_Walk_Around_People_Count += sts_people_count_sensor_data.Sum_Day_Walk_Around_People_Count;
// else reset week counter
#if 0
sts_people_count_sensor_data.Sum_Week_Walk_In_People_Count = 0;
sts_people_count_sensor_data.Sum_Week_Walk_Out_People_Count = 0;
sts_people_count_sensor_data.Sum_Week_Walk_Around_People_Count = 0;
#endif
// Sum Month counting
// if not end of month ---
sts_people_count_sensor_data.Sum_Month_Walk_In_People_Count += sts_people_count_sensor_data.Sum_Day_Walk_In_People_Count;
sts_people_count_sensor_data.Sum_Month_Walk_Out_People_Count += sts_people_count_sensor_data.Sum_Day_Walk_Out_People_Count;
sts_people_count_sensor_data.Sum_Month_Walk_Around_People_Count += sts_people_count_sensor_data.Sum_Day_Walk_Around_People_Count;
// else reset month counter
#if 0
sts_people_count_sensor_data.Sum_Month_Walk_In_People_Count = 0;
sts_people_count_sensor_data.Sum_Month_Walk_Out_People_Count = 0;
sts_people_count_sensor_data.Sum_Month_Walk_Around_People_Count = 0;
#endif
// Sum Year counting
// if not end of year ---
sts_people_count_sensor_data.Sum_Year_Walk_In_People_Count += sts_people_count_sensor_data.Sum_Day_Walk_In_People_Count;
sts_people_count_sensor_data.Sum_Year_Walk_Out_People_Count += sts_people_count_sensor_data.Sum_Day_Walk_Out_People_Count;
sts_people_count_sensor_data.Sum_Year_Walk_Around_People_Count += sts_people_count_sensor_data.Sum_Day_Walk_Around_People_Count;
// else reset year counter
#if 0
sts_people_count_sensor_data.Sum_Year_Walk_In_People_Count = 0;
sts_people_count_sensor_data.Sum_Year_Walk_Out_People_Count = 0;
sts_people_count_sensor_data.Sum_Year_Walk_Around_People_Count = 0;
#endif
// Sum LifeCycle counting
sts_people_count_sensor_data.Sum_LifeCycle_Walk_In_People_Count += sts_people_count_sensor_data.Sum_Day_Walk_In_People_Count;
sts_people_count_sensor_data.Sum_LifeCycle_Walk_Out_People_Count += sts_people_count_sensor_data.Sum_Day_Walk_Out_People_Count;
sts_people_count_sensor_data.Sum_LifeCycle_Walk_Around_People_Count += sts_people_count_sensor_data.Sum_Day_Walk_Around_People_Count;
//reset counter of counting period
sts_people_count_sensor_data.Walk_In_People_Count = 0;
sts_people_count_sensor_data.Walk_Out_People_Count = 0;
sts_people_count_sensor_data.Walk_Around_People_Count = 0;
// reset counter at end of day TODO XXX
// reset counter at end of week TODO XXX
// reset counter at end of month TODO XXX
// reset counter at end of year TODO XXX
// reset counter at end of year TODO XXX
// write to NVM store TODO XXX
}
void STS_TOF_VL53LX_PeopleCounting_Process_Init(void)
{
APP_LOG(TS_OFF, VLEVEL_M,"############### TOF VL53LX_ PEOPLE COUNTING PROCESS INITIALIZATION\r\n");
sts_tof_vl53lx_peoplecount_init();
}
void STS_TOF_VL53LX_PeopleCounting_Process_Start(void* context)
{
//APP_LOG(TS_OFF, VLEVEL_M,"############### TOF VL53LX_ PEOPLE COUNTING SUB-PROCESS \r\n");
{
status = sts_tof_vl53lx_peoplecount_start();
//APP_LOG(TS_OFF, VLEVEL_M,"############### SUB-PROCESS running .... \r\n");
}
}
int sts_tof_vl53lx_peoplecount_init(void)
{
//int8_t error;
uint8_t byteData, sensorState=0;
uint16_t wordData;
/* int PplCounter = 0;*/
/* MCU Configuration----------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
/* Configure the system clock */
/* Initialize all configured peripherals */
APP_LOG(TS_OFF, VLEVEL_L,"XNUCLEO53L1A1_Init Start .......... \r\n");
status = XNUCLEO53L1A1_Init();
APP_LOG(TS_OFF, VLEVEL_L,"XNUCLEO53L1A1_Init Status : %X\n", status);
status = XNUCLEO53L1A1_ResetId(XNUCLEO53L1A1_DEV_CENTER, 0); // Reset ToF sensor
HAL_Delay(2);
status = XNUCLEO53L1A1_ResetId(XNUCLEO53L1A1_DEV_CENTER, 1); // Reset ToF sensor
// Those basic I2C read functions can be used to check your own I2C functions */
status = VL53L1_RdByte(dev, 0x010F, &byteData);
APP_LOG(TS_OFF, VLEVEL_L,"VL53L1X Model_ID: %X\n", byteData);
status = VL53L1_RdByte(dev, 0x0110, &byteData);
APP_LOG(TS_OFF, VLEVEL_L,"VL53L1X Module_Type: %X\n", byteData);
status = VL53L1_RdWord(dev, 0x010F, &wordData);
APP_LOG(TS_OFF, VLEVEL_L,"VL53L1X: %X\n", wordData);
while (sensorState == 0) {
status = VL53L1X_BootState(dev, &sensorState);
HAL_Delay(2);
}
APP_LOG(TS_OFF, VLEVEL_L,"Chip booted\n");
/* Initialize and configure the device according to people counting need */
status = VL53L1X_SensorInit(dev);
status += VL53L1X_SetDistanceMode(dev, ppc_cfg[sts_distance_mode].distance_mode); /* 1=short, 2=long, DISTANCE_MODE */
status += VL53L1X_SetTimingBudgetInMs(dev, ppc_cfg[sts_distance_mode].timing_budget); /* TIMING_BUDGET, in ms possible values [15, 20, 50, 100, 200, 500] */
status += VL53L1X_SetInterMeasurementInMs(dev, ppc_cfg[sts_distance_mode].timing_budget);
status += VL53L1X_SetROI(dev, ppc_cfg[sts_distance_mode].rows_of_SPADS, 16); /* minimum ROI 4,4 */
center[0]=ppc_cfg[sts_distance_mode].front_zone_center;
center[1]=ppc_cfg[sts_distance_mode].back_zone_center;
if (status != 0) {
APP_LOG(TS_OFF, VLEVEL_L,"Initialization or configuration of the device\n");
return (-1);
}
APP_LOG(TS_OFF, VLEVEL_L,"Start counting people with profile : %s...\n", PROFILE_STRING);
status = VL53L1X_StartRanging(dev); /* This function has to be called to enable the ranging */
if (status != 0) {
APP_LOG(TS_OFF, VLEVEL_L,"Error in start ranging\n");
return (-1);
}
return 0;
}
int sts_tof_vl53lx_peoplecount_start(void)
{
//uint8_t byteData, sensorState=0;
//uint16_t wordData;
uint16_t Distance, Signal;
uint8_t RangeStatus;
uint8_t dataReady;
//char DisplayStr[5];
/* read and display data */
while (dataReady == 0) {
status = VL53L1X_CheckForDataReady(dev, &dataReady);
HAL_Delay(1);
}
dataReady = 0;
status += VL53L1X_GetRangeStatus(dev, &RangeStatus);
status += VL53L1X_GetDistance(dev, &Distance);
status += VL53L1X_GetSignalPerSpad(dev, &Signal);
status += VL53L1X_ClearInterrupt(dev); /* clear interrupt has to be called to enable next interrupt*/
if (status != 0) {
APP_LOG(TS_OFF, VLEVEL_L,"Error in operating the device\n");
return (-1);
}
//HAL_Delay(WAIT_BEFORE_PROGRAMMING_OTHER_ZONE_CENTER); // 10, 8, 7, 6 tested OK
status = VL53L1X_SetROICenter(dev, center[Zone]);
if (status != 0) {
APP_LOG(TS_OFF, VLEVEL_L,"Error in chaning the center of the ROI\n");
return (-1);
}
// check the status of the ranging. In case of error, lets assume the distance is the max of the use case
// Value RangeStatus string Comment
// 0 VL53L1_RANGESTATUS_RANGE_VALID Ranging measurement is valid
// 1 VL53L1_RANGESTATUS_SIGMA_FAIL Raised if sigma estimator check is above the internal defined threshold
// 2 VL53L1_RANGESTATUS_SIGNAL_FAIL Raised if signal value is below the internal defined threshold
// 4 VL53L1_RANGESTATUS_OUTOFBOUNDS_ FAIL Raised when phase is out of bounds
// 5 VL53L1_RANGESTATUS_HARDWARE_FAIL Raised in case of HW or VCSEL failure
// 7 VL53L1_RANGESTATUS_WRAP_TARGET_ FAIL Wrapped target, not matching phases
// 8 VL53L1_RANGESTATUS_PROCESSING_ FAIL Internal algorithm underflow or overflow
// 14 VL53L1_RANGESTATUS_RANGE_INVALID The reported range is invalid
if ((RangeStatus == 0) || (RangeStatus == 4) || (RangeStatus == 7)) {
if (Distance <= ppc_cfg[sts_distance_mode].min_distance) //MIN_DISTANCE) // wraparound case see the explanation at the constants definition place
Distance = ppc_cfg[sts_distance_mode].max_distance + ppc_cfg[sts_distance_mode].min_distance; //MAX_DISTANCE + MIN_DISTANCE;
}
else // severe error cases
Distance = ppc_cfg[sts_distance_mode].max_distance; //MAX_DISTANCE;
// inject the new ranged distance in the people counting algorithm
PplCounter = ProcessPeopleCountingData(Distance, Zone, RangeStatus);
//printf("\PplCounter =%d \n\r", PplCounter);
//sprintf(DisplayStr, "%4d", PplCounter); // only use for special EVK with display
//XNUCLEO53L1A1_SetDisplayString(DisplayStr);
//APP_LOG(TS_OFF, VLEVEL_H,"%d,%d,%d\n", Zone, Distance, Signal);
Zone++;
Zone = Zone%2;
return 0;
}

View File

@ -0,0 +1,150 @@
/**
******************************************************************************
* @file : app_tof_peoplecount.h
* @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.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __APP_TOF_PEOPLECOUNT_H
#define __APP_TOF_PEOPLECOUNT_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
/* Exported defines ----------------------------------------------------------*/
// People Counting defines
#define NOBODY 0
#define SOMEONE 1
#define LEFT 0
#define RIGHT 1
#define DOOR_JAM_2000 0
#define DOOR_JAM_2400 1
#define DOOR_JAM_3000 2
#define ON_SIDE 3
// define here the profile for your case.
#define PPC_PROFILE DOOR_JAM_2400
#define TRACE_PPC 1
// time budget in ms 20,33,50,100,200,500
#define tbms_20 20
#define tbms_33 33
#define tbms_50 50
#define tbms_100 100
#define tbms_200 200
#define tbms_500 500
//PPC_PROFILE DOOR_JAM_2400
#if PPC_PROFILE == DOOR_JAM_2400
#define PROFILE_STRING "DOOR_JAM_2400"
#define DISTANCES_ARRAY_SIZE 10 // nb of samples
#define MAX_DISTANCE 2400 // mm was 2400
#define MIN_DISTANCE 0 // mm
#define DIST_THRESHOLD 1600 // mm
#define ROWS_OF_SPADS 8 // 8x16 SPADs ROI
#define TIMING_BUDGET 33 //33 // was 20 ms, I found 33 ms has better succes rate with lower reflectance target
#define DISTANCE_MODE DISTANCE_MODE_LONG
#endif
#if ROWS_OF_SPADS == 4
#define FRONT_ZONE_CENTER 151
#define BACK_ZONE_CENTER 247
#elif ROWS_OF_SPADS == 6
#define FRONT_ZONE_CENTER 159
#define BACK_ZONE_CENTER 239
#elif ROWS_OF_SPADS == 8
#define FRONT_ZONE_CENTER 175 // was 167, see UM2555 on st.com, centre = 175 has better return signal rate for the ROI #1
#define BACK_ZONE_CENTER 231
#endif
/* Exported functions --------------------------------------------------------*/
enum distance_mode {
DISTANCE_MODE_SIDE=0,
DISTANCE_MODE_SHORT,
DISTANCE_MODE_LONG,
};
typedef struct STS_ZONE_CENTRE_BY_ROWS_OF_SPADS
{
uint8_t rows_of_spads;
uint8_t front_zone_center;
uint8_t back_zone_center;
} sts_zone_center_by_rows_of_spads_t;
typedef struct STS_PPC_CFG_Type {
uint8_t profile_name;
uint8_t distance_array_size;
uint16_t max_distance;
uint16_t min_distance;
uint16_t dist_threshold;
uint8_t rows_of_SPADS; /* minimum ROI 4,4 */
uint16_t timing_budget; /* TIMING_BUDGET, in ms possible values [15, 20, 33, 50, 100, 200, 500] */
uint8_t distance_mode; /* 1=short, 2=long, DISTANCE_MODE */
uint8_t front_zone_center;
uint8_t back_zone_center;
} sts_ppc_cfg_type_t;
typedef struct STS_People_Count_Sensor_Data_Type {
uint16_t Walk_In_People_Count;
uint16_t Walk_Out_People_Count;
uint16_t Walk_Around_People_Count;
uint8_t Count_Period;
uint8_t Count_Period_Unit;
uint16_t Sum_Day_Walk_In_People_Count;
uint16_t Sum_Day_Walk_Out_People_Count;
uint16_t Sum_Day_Walk_Around_People_Count;
uint16_t Sum_Week_Walk_In_People_Count;
uint16_t Sum_Week_Walk_Out_People_Count;
uint16_t Sum_Week_Walk_Around_People_Count;
uint16_t Sum_Month_Walk_In_People_Count;
uint16_t Sum_Month_Walk_Out_People_Count;
uint16_t Sum_Month_Walk_Around_People_Count;
uint16_t Sum_Year_Walk_In_People_Count;
uint16_t Sum_Year_Walk_Out_People_Count;
uint16_t Sum_Year_Walk_Around_People_Count;
uint32_t Sum_LifeCycle_Walk_In_People_Count;
uint32_t Sum_LifeCycle_Walk_Out_People_Count;
uint32_t Sum_LifeCycle_Walk_Around_People_Count;
} sts_people_count_sensor_data_t;
void STS_TOF_VL53LX_PeopleCounting_Process_Init(void);
void STS_TOF_VL53LX_PeopleCounting_Process_Start(void*);
int sts_tof_vl53lx_peoplecount_init(void);
int sts_tof_vl53lx_peoplecount_start(void);
//int sts_tof_vl53lx_peoplecount(void);
int ProcessPeopleCountingData(int16_t Distance, uint8_t zone, uint8_t RangeStatus);
void STS_people_count_sensor_Read(sts_people_count_sensor_data_t *sts_p2_sensor_data);
#ifdef __cplusplus
}
#endif
#endif /* __APP_TOF_PEOPLECOUNT_H */

61
TOF/Target/53l1a2_conf.h Normal file
View File

@ -0,0 +1,61 @@
/**
******************************************************************************
* @file 53l1a2_conf.h
* @author IMG SW Application Team
* @brief This file contains definitions for the ToF components bus interfaces
* when using the X-NUCLEO-53L1A2 expansion board
******************************************************************************
* @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.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef VL53L1A2_CONF_H
#define VL53L1A2_CONF_H
#include "stm32wlxx_hal.h"
#include "stm32wlxx_nucleo_bus.h"
#include "stm32wlxx_nucleo_errno.h"
#ifdef __cplusplus
extern "C" {
#endif
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/*
* the 53L1A2 BSP driver uses this symbol to allocate a structure for each device
* if you are only using the on-board sensor without break-out boards
* change its to (1U) in order to save space in RAM memory
*/
#define RANGING_SENSOR_INSTANCES_NBR (3U)
#define VL53L1A2_hi2c (hi2c2)
#define VL53L1A2_I2C_SCL_GPIO_PORT BUS_I2C2_SCL_GPIO_PORT
#define VL53L1A2_I2C_SCL_GPIO_PIN BUS_I2C2_SCL_GPIO_PIN
#define VL53L1A2_I2C_SDA_GPIO_PORT BUS_I2C2_SDA_GPIO_PORT
#define VL53L1A2_I2C_SDA_GPIO_PIN BUS_I2C2_SDA_GPIO_PIN
#define VL53L1A2_I2C_Init BSP_I2C2_Init
#define VL53L1A2_I2C_DeInit BSP_I2C2_DeInit
#define VL53L1A2_I2C_WriteReg BSP_I2C2_Send
#define VL53L1A2_I2C_ReadReg BSP_I2C2_Recv
#define VL53L1A2_GetTick BSP_GetTick
#ifdef __cplusplus
}
#endif
#endif /* VL53L1A2_CONF_H */

View File

@ -0,0 +1,30 @@
/**
******************************************************************************
* @file app_tof_pin_conf.c
* @author IMG SW Application Team
* @brief This file contains functions for TOF pins
******************************************************************************
* @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.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "app_tof_pin_conf.h"
extern volatile uint8_t ToF_EventDetected;
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if (GPIO_Pin == TOF_INT_EXTI_PIN)
{
ToF_EventDetected = 1;
}
}

View File

@ -0,0 +1,38 @@
/**
******************************************************************************
* @file app_tof_pin_conf.h
* @author IMG SW Application Team
* @brief This file contains definitions for TOF pins
******************************************************************************
* @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.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __APP_TOF_PIN_CONF_H__
#define __APP_TOF_PIN_CONF_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "stm32wlxx_hal.h"
/* Exported symbols ----------------------------------------------------------*/
#define TOF_INT_EXTI_PIN (GPIO_PIN_3) // (GPIO_PIN_4)
#define TOF_INT_EXTI_PORT (GPIOB)
#ifdef __cplusplus
}
#endif
#endif /* __APP_TOF_PIN_CONF_H__ */

3
readme.MD Normal file
View File

@ -0,0 +1,3 @@
--- STS P2 ---
VL53L1X

View File

@ -45,7 +45,8 @@ STS_O7 For Occupancy sensors
2024-06-26 RTM for pixel-network STS_RSS_MODE = 3 P113 switch
2024-07-30 revert back ...not good for alarm so far
2024-08-06 start focus on fall detection
2024-08-06 a...
2024-08-06 fall detection for O7, Motion detection for O6
2024-08-28 STS-P2
*****************************************************************************
*/

View File

@ -0,0 +1,610 @@
/*
Copyright (c) 2021, STMicroelectronics - All Rights Reserved
This file : part of VL53L1X ULP and : dual licensed,
either 'STMicroelectronics
Proprietary license'
or 'BSD 3-clause "New" or "Revised" License' , at your option.
*******************************************************************************
'STMicroelectronics Proprietary license'
*******************************************************************************
License terms: STMicroelectronics Proprietary in accordance with licensing
terms at www.st.com/sla0081
STMicroelectronics confidential
Reproduction and Communication of this document : strictly prohibited unless
specifically authorized in writing by STMicroelectronics.
*******************************************************************************
Alternatively, VL53L1X ULP may be distributed under the terms of
'BSD 3-clause "New" or "Revised" License', in which case the following
provisions apply instead of the ones mentioned above :
*******************************************************************************
License terms: BSD 3-clause "New" or "Revised" License.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************
*/
/**
* @file VL53L1X_ULP_api.c
* @brief Functions implementation
*/
#include "VL53L1X_ULP_api.h"
#include <math.h>
static const uint8_t VL53L1X_ULP_DEFAULT_CONFIGURATION[] = {
0x00, /* 0x2d */
0x00, /* 0x2e */
0x00, /* 0x2f */
0x11, /* 0x30 */
0x02, /* 0x31 */
0x00, /* 0x32 */
0x02, /* 0x33 */
0x08, /* 0x34 */
0x00, /* 0x35 */
0x08, /* 0x36 */
0x10, /* 0x37 */
0x01, /* 0x38 */
0x01, /* 0x39 */
0x00, /* 0x3a */
0x00, /* 0x3b */
0x00, /* 0x3c */
0x00, /* 0x3d */
0xff, /* 0x3e */
0x00, /* 0x3f */
0x0F, /* 0x40 */
0x00, /* 0x41 */
0x00, /* 0x42 */
0x00, /* 0x43 */
0x00, /* 0x44 */
0x00, /* 0x45 */
0x20, /* 0x46 */
0x0b, /* 0x47 */
0x00, /* 0x48 */
0x00, /* 0x49 */
0x02, /* 0x4a */
0x14, /* 0x4b */
0x21, /* 0x4c */
0x00, /* 0x4d */
0x00, /* 0x4e */
0x05, /* 0x4f */
0x00, /* 0x50 */
0x00, /* 0x51 */
0x00, /* 0x52 */
0x00, /* 0x53 */
0xc8, /* 0x54 */
0x00, /* 0x55 */
0x00, /* 0x56 */
0x38, /* 0x57 */
0xff, /* 0x58 */
0x01, /* 0x59 */
0x00, /* 0x5a */
0x08, /* 0x5b */
0x00, /* 0x5c */
0x00, /* 0x5d */
0x00, /* 0x5e */
0x01, /* 0x5f */
0x0b, /* 0x60 */
0x00, /* 0x61 */
0x02, /* 0x62 */
0x09, /* 0x63 */
0x00, /* 0x64 */
0xb4, /* 0x65 */
0x00, /* 0x66 */
0xbb, /* 0x67 */
0x08, /* 0x68 */
0x38, /* 0x69 */
0x00, /* 0x6a */
0x00, /* 0x6b */
0x00, /* 0x6c */
0x00, /* 0x6d */
0x0f, /* 0x6e */
0x89, /* 0x6f */
0x00, /* 0x70 */
0x00, /* 0x71 */
0x00, /* 0x72 */
0x00, /* 0x73 */
0x00, /* 0x74 */
0x00, /* 0x75 */
0x00, /* 0x76 */
0x01, /* 0x77 */
0x07, /* 0x78 */
0x05, /* 0x79 */
0x06, /* 0x7a */
0x06, /* 0x7b */
0x00, /* 0x7c */
0x00, /* 0x7d */
0x02, /* 0x7e */
0xc7, /* 0x7f */
0xff, /* 0x80 */
0x9B, /* 0x81 */
0x00, /* 0x82 */
0x00, /* 0x83 */
0x00, /* 0x84 */
0x01, /* 0x85 */
0x00, /* 0x86 */
0x00 /* 0x87 */
};
uint8_t VL53L1X_ULP_GetSensorId(
uint16_t dev,
uint16_t *p_id)
{
uint8_t status = VL53L1X_ULP_ERROR_NONE;
status |= VL53L1X_ULP_RdWord(dev,
VL53L1X_ULP_IDENTIFICATION__MODEL_ID, p_id);
return status;
}
uint8_t VL53L1X_ULP_SetI2CAddress(
uint16_t dev,
uint8_t new_address)
{
uint8_t status = VL53L1X_ULP_ERROR_NONE;
status |= VL53L1X_ULP_WrByte(dev, VL53L1X_ULP_I2C_SLAVE__DEVICE_ADDRESS,
(uint8_t)(new_address >> (uint8_t)1));
return status;
}
uint8_t VL53L1X_ULP_SensorInit(
uint16_t dev)
{
uint8_t status = VL53L1X_ULP_ERROR_NONE;
uint8_t Addr, tmp;
uint8_t continue_loop = 1;
uint16_t i = 0;
do{
status |= VL53L1X_ULP_RdByte(dev,
VL53L1X_ULP_FIRMWARE__SYSTEM_STATUS, &tmp);
if(tmp == (uint8_t)0x3) /* Sensor booted */
{
continue_loop = (uint8_t)0;
}
else if(i < (uint16_t)1000) /* Wait for boot */
{
i++;
}
else /* Timeout 1000ms reached */
{
continue_loop = (uint8_t)0;
status |= (uint8_t)VL53L1X_ULP_ERROR_TIMEOUT;
}
VL53L1X_ULP_WaitMs(1);
}while(continue_loop == (uint8_t)1);
/* Load default configuration */
for (Addr = (uint8_t)0x2D; Addr <= (uint8_t)0x87; Addr++)
{
status |= VL53L1X_ULP_WrByte(dev, Addr,
VL53L1X_ULP_DEFAULT_CONFIGURATION[
Addr - (uint8_t)0x2D]);
}
/* Start VHV */
status |= VL53L1X_ULP_WrByte(dev, VL53L1X_ULP_SYSTEM_START, (uint8_t)0x40);
i = (uint8_t)0;
continue_loop = (uint8_t)1;
do{
status |= VL53L1X_ULP_CheckForDataReady(dev, &tmp);
if(tmp == (uint8_t)1) /* Data ready */
{
continue_loop = (uint8_t)0;
}
else if(i < (uint16_t)1000) /* Wait for answer */
{
i++;
}
else /* Timeout 1000ms reached */
{
continue_loop = (uint8_t)0;
status |= (uint8_t)VL53L1X_ULP_ERROR_TIMEOUT;
}
VL53L1X_ULP_WaitMs(1);
}while(continue_loop == (uint8_t)1);
status |= VL53L1X_ULP_ClearInterrupt(dev);
status |= VL53L1X_ULP_StopRanging(dev);
status |= VL53L1X_ULP_WrByte(dev,
VL53L1X_ULP_VHV_CONFIG__TIMEOUT_MACROP_LOOP_BOUND,
(uint8_t)0x09);
status |= VL53L1X_ULP_WrByte(dev, 0x0B, (uint8_t)0);
status |= VL53L1X_ULP_WrWord(dev, 0x0024, 0x500);
status |= VL53L1X_ULP_WrByte(dev, 0x81, 0b10001010);
status |= VL53L1X_ULP_WrByte(dev, 0x004B, 0x03);
/* Set default inter-measurement */
status |= VL53L1X_ULP_SetInterMeasurementInMs(dev, 1000);
return status;
}
uint8_t VL53L1X_ULP_CheckForDataReady(
uint16_t dev,
uint8_t *p_is_data_ready)
{
uint8_t status = VL53L1X_ULP_ERROR_NONE;
uint8_t temp;
uint8_t int_pol;
status |= VL53L1X_ULP_RdByte(dev, VL53L1X_ULP_GPIO_HV_MUX__CTRL, &temp);
temp = temp & (uint8_t)0x10;
temp = temp >> 4;
if (temp == (uint8_t)1)
{
int_pol = (uint8_t)0;
}
else
{
int_pol = (uint8_t)1;
}
status |= VL53L1X_ULP_RdByte(dev, VL53L1X_ULP_GPIO__TIO_HV_STATUS, &temp);
if ((temp & (uint8_t)1) == int_pol)
{
*p_is_data_ready = (uint8_t)1;
}
else
{
*p_is_data_ready = (uint8_t)0;
}
return status;
}
uint8_t VL53L1X_ULP_ClearInterrupt(
uint16_t dev)
{
uint8_t status = VL53L1X_ULP_ERROR_NONE;
status |= VL53L1X_ULP_WrByte(dev, VL53L1X_ULP_SYSTEM__INTERRUPT_CLEAR, 0x01);
return status;
}
uint8_t VL53L1X_ULP_StartRangingSingleShot(
uint16_t dev)
{
uint8_t status = VL53L1X_ULP_ERROR_NONE;
status |= VL53L1X_ULP_WrByte(dev, VL53L1X_ULP_SYSTEM_START, 0x10);
return status;
}
uint8_t VL53L1X_ULP_StartRanging(
uint16_t dev)
{
uint8_t status = VL53L1X_ULP_ERROR_NONE;
status |= VL53L1X_ULP_WrByte(dev, VL53L1X_ULP_SYSTEM_START, 0x40);
return status;
}
uint8_t VL53L1X_ULP_StopRanging(
uint16_t dev)
{
uint8_t status = VL53L1X_ULP_ERROR_NONE;
status |= VL53L1X_ULP_WrByte(dev, VL53L1X_ULP_SYSTEM_START, 0x00);
return status;
}
uint8_t VL53L1X_ULP_DumpDebugData(
uint16_t dev,
uint8_t *p_measurement_status,
uint16_t *p_estimated_distance_mm,
uint16_t *p_sigma_mm,
uint16_t *p_signal_kcps,
uint16_t *p_ambient_kcps)
{
uint8_t status = VL53L1X_ULP_ERROR_NONE;
uint8_t status_rtn[24] = { 255, 255, 255, 5, 2, 4, 1, 7, 3, 0,
255, 255, 9, 13, 255, 255, 255, 255, 10, 6,
255, 255, 11, 12
};
status |= VL53L1X_ULP_RdByte(dev, 0x0089, p_measurement_status);
status |= VL53L1X_ULP_RdWord(dev, 0x0096, p_estimated_distance_mm);
status |= VL53L1X_ULP_RdWord(dev, 0x008E, p_signal_kcps);
status |= VL53L1X_ULP_RdWord(dev, 0x0092, p_sigma_mm);
status |= VL53L1X_ULP_RdWord(dev, 0x0090, p_ambient_kcps);
(*p_signal_kcps) *= (uint16_t)8;
(*p_sigma_mm) /= (uint16_t)4;
(*p_ambient_kcps) *= (uint16_t)8;
*p_measurement_status = (*p_measurement_status) & (uint8_t)0x1F;
if ((*p_measurement_status) < (uint8_t)24)
{
*p_measurement_status = status_rtn[(*p_measurement_status)];
}
return status;
}
uint8_t VL53L1X_ULP_SetMacroTiming(
uint16_t dev,
uint16_t macro_timing)
{
uint8_t status = VL53L1X_ULP_ERROR_NONE;
if(((uint16_t)macro_timing >= (uint16_t)1)
&& ((uint16_t)macro_timing <= (uint16_t)255))
{
status |= VL53L1X_ULP_WrWord(dev,
VL53L1X_ULP_RANGE_CONFIG_A, macro_timing);
status |= VL53L1X_ULP_WrWord(dev,
VL53L1X_ULP_RANGE_CONFIG_B,
macro_timing + (uint16_t)0x1);
}
else
{
status = VL53L1X_ULP_ERROR_INVALID_ARGUMENT;
}
return status;
}
uint8_t VL53L1X_ULP_GetMacroTiming(
uint16_t dev,
uint16_t *p_macro_timing)
{
uint8_t status = VL53L1X_ULP_ERROR_NONE;
status |= VL53L1X_ULP_RdWord(dev,
VL53L1X_ULP_RANGE_CONFIG_A, p_macro_timing);
return status;
}
uint8_t VL53L1X_ULP_SetInterMeasurementInMs(
uint16_t dev,
uint32_t inter_measurement_ms)
{
uint8_t status = VL53L1X_ULP_ERROR_NONE;
uint16_t clock_pll;
float_t inter_measurement_factor = (float_t)1.055;
if(((uint32_t)inter_measurement_ms >= (uint32_t)10)
&& ((uint32_t)inter_measurement_ms <= (uint32_t)60000))
{
status |= VL53L1X_ULP_RdWord(dev,
VL53L1X_ULP_RESULT__OSC_CALIBRATE_VAL, &clock_pll);
clock_pll = clock_pll & (uint16_t)0x3FF;
inter_measurement_factor = inter_measurement_factor
* (float_t)inter_measurement_ms
* (float_t)clock_pll;
status |= VL53L1X_ULP_WrDWord(dev, VL53L1X_ULP_INTERMEASUREMENT_MS,
(uint32_t)inter_measurement_factor);
}
else
{
status = VL53L1X_ULP_ERROR_INVALID_ARGUMENT;
}
return status;
}
uint8_t VL53L1X_ULP_GetInterMeasurementInMs(
uint16_t dev,
uint32_t *p_inter_measurement_ms)
{
uint8_t status = VL53L1X_ULP_ERROR_NONE;
uint16_t clock_pll;
uint32_t tmp;
float_t clock_pll_factor = (float_t)1.055;
status |= VL53L1X_ULP_RdDWord(dev, VL53L1X_ULP_INTERMEASUREMENT_MS, &tmp);
status |= VL53L1X_ULP_RdWord(dev,
VL53L1X_ULP_RESULT__OSC_CALIBRATE_VAL, &clock_pll);
if(clock_pll == (uint16_t)0)
{
status |= VL53L1X_ULP_ERROR_INVALID_ARGUMENT;
}
else
{
clock_pll = clock_pll & (uint16_t)0x3FF;
clock_pll_factor = clock_pll_factor * (float_t)clock_pll;
clock_pll = (uint16_t)clock_pll_factor;
*p_inter_measurement_ms = (uint16_t)(tmp/(uint32_t)clock_pll);
}
return status;
}
uint8_t VL53L1X_ULP_SetROI(
uint16_t dev,
uint8_t roi_width)
{
uint8_t tmp, status = VL53L1X_ULP_ERROR_NONE;
status |= VL53L1X_ULP_RdByte(dev, 0x013E, &tmp);
if(((roi_width >= (uint8_t)4))
&& ((roi_width <= (uint8_t)16)))
{
if (roi_width > (uint8_t)10)
{
tmp = (uint8_t)199;
}
status |= VL53L1X_ULP_WrByte(dev, 0x007F, tmp);
status |= VL53L1X_ULP_WrByte(dev, 0x0080,
((roi_width - (uint8_t)1) << 4)
| (roi_width - (uint8_t)1));
}
else
{
status |= VL53L1X_ULP_ERROR_INVALID_ARGUMENT;
}
return status;
}
uint8_t VL53L1X_ULP_GetROI(
uint16_t dev,
uint8_t *p_roi_width)
{
uint8_t tmp, status = VL53L1X_ULP_ERROR_NONE;
status |= VL53L1X_ULP_RdByte(dev, 0x0080, &tmp);
*p_roi_width = (tmp & (uint8_t)0x0F) + (uint8_t)1;
return status;
}
uint8_t VL53L1X_ULP_SetInterruptConfiguration(
uint16_t dev,
uint16_t distance_threshold_mm,
uint8_t enable_interrupt_only_below_threshold)
{
uint8_t tmp, status = VL53L1X_ULP_ERROR_NONE;
if(enable_interrupt_only_below_threshold == (uint8_t)0)
{
tmp = (uint8_t)0x20;
}
else
{
tmp = (uint8_t)0x0;
}
status |= VL53L1X_ULP_WrByte(dev,
VL53L1X_ULP_SYSTEM__INTERRUPT, tmp);
status |= VL53L1X_ULP_WrWord(dev,
VL53L1X_ULP_THRESH_HIGH, distance_threshold_mm);
status |= VL53L1X_ULP_WrWord(dev,
VL53L1X_ULP_THRESH_LOW, distance_threshold_mm);
return status;
}
uint8_t VL53L1X_ULP_GetInterruptConfiguration(
uint16_t dev,
uint16_t *p_distance_threshold_mm,
uint8_t *p_interrupt_enabled_only_below_threshold)
{
uint8_t tmp, status = VL53L1X_ULP_ERROR_NONE;
status |= VL53L1X_ULP_RdWord(dev,
VL53L1X_ULP_THRESH_HIGH, p_distance_threshold_mm);
status |= VL53L1X_ULP_RdByte(dev,
VL53L1X_ULP_SYSTEM__INTERRUPT, &tmp);
if(tmp == (uint8_t)0x20)
{
*p_interrupt_enabled_only_below_threshold = 0;
}
else
{
*p_interrupt_enabled_only_below_threshold = 1;
}
return status;
}
uint8_t VL53L1X_ULP_SetSignalThreshold(
uint16_t dev,
uint16_t signal_kcps)
{
uint8_t status = VL53L1X_ULP_ERROR_NONE;
if(((signal_kcps >= (uint16_t)1))
&& ((signal_kcps <= (uint16_t)16384)))
{
status |= VL53L1X_ULP_WrWord(dev,
VL53L1X_ULP_MIN_COUNT_RATE_RTN_LIMIT_MCPS,signal_kcps>>3);
}
else
{
status |= VL53L1X_ULP_ERROR_INVALID_ARGUMENT;
}
return status;
}
uint8_t VL53L1X_ULP_GetSignalThreshold(
uint16_t dev,
uint16_t *p_signal_kcps)
{
uint8_t status = VL53L1X_ULP_ERROR_NONE;
uint16_t tmp = 0;
status |= VL53L1X_ULP_RdWord(dev,
VL53L1X_ULP_MIN_COUNT_RATE_RTN_LIMIT_MCPS, &tmp);
*p_signal_kcps = tmp <<3;
return status;
}
uint8_t VL53L1X_ULP_SetSigmaThreshold(
uint16_t dev,
uint16_t sigma_mm)
{
uint8_t status = VL53L1X_ULP_ERROR_NONE;
if(sigma_mm>(uint16_t)((uint16_t)0xFFFF>>2))
{
status |= (uint8_t)VL53L1X_ULP_ERROR_INVALID_ARGUMENT;
}
else
{
status |= VL53L1X_ULP_WrWord(dev,
VL53L1X_ULP_RANGE_CONFIG__SIGMA_THRESH, sigma_mm<<2);
}
return status;
}
uint8_t VL53L1X_ULP_GetSigmaThreshold(
uint16_t dev,
uint16_t *p_sigma_mm)
{
uint8_t status = VL53L1X_ULP_ERROR_NONE;
status |= VL53L1X_ULP_RdWord(dev,
VL53L1X_ULP_RANGE_CONFIG__SIGMA_THRESH, p_sigma_mm);
*p_sigma_mm = *p_sigma_mm >> 2;
return status;
}

View File

@ -0,0 +1,419 @@
/*
* Copyright (c) 2021, STMicroelectronics - All Rights Reserved
*
* This file : part of VL53L1X ULP and : dual licensed,
* either 'STMicroelectronics
* Proprietary license'
* or 'BSD 3-clause "New" or "Revised" License' , at your option.
*
********************************************************************************
*
* 'STMicroelectronics Proprietary license'
*
********************************************************************************
*
* License terms: STMicroelectronics Proprietary in accordance with licensing
* terms at www.st.com/sla0081
*
* STMicroelectronics confidential
* Reproduction and Communication of this document : strictly prohibited unless
* specifically authorized in writing by STMicroelectronics.
*
*
********************************************************************************
*
* Alternatively, VL53L1X ULP may be distributed under the terms of
* 'BSD 3-clause "New" or "Revised" License', in which case the following
* provisions apply instead of the ones mentioned above :
*
********************************************************************************
*
* License terms: BSD 3-clause "New" or "Revised" License.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
********************************************************************************
*
*/
/**
* @file VL53L1X api.h
* @brief Functions definition
*/
#ifndef VL53L1X_ULP_API_H_
#define VL53L1X_ULP_API_H_
#include "VL53L1X_ULP_platform.h"
#define VL53L1X_ULP_VERSION "1.0.0"
/**
* @brief Error types.
*/
#define VL53L1X_ULP_ERROR_NONE ((uint8_t)0U)
#define VL53L1X_ULP_ERROR_INVALID_ARGUMENT ((uint8_t)254U)
#define VL53L1X_ULP_ERROR_TIMEOUT ((uint8_t)255U)
/**
* @brief Firmware addresses.
*/
#define VL53L1X_ULP_I2C_SLAVE__DEVICE_ADDRESS ((uint16_t)0x0001)
#define VL53L1X_ULP_VHV_CONFIG__TIMEOUT_MACROP_LOOP_BOUND ((uint16_t)0x0008)
#define VL53L1X_ULP_GPIO_HV_MUX__CTRL ((uint16_t)0x0030)
#define VL53L1X_ULP_GPIO__TIO_HV_STATUS ((uint16_t)0x0031)
#define VL53L1X_ULP_SYSTEM__INTERRUPT ((uint16_t)0x0046)
#define VL53L1X_ULP_RANGE_CONFIG_A ((uint16_t)0x005E)
#define VL53L1X_ULP_RANGE_CONFIG_B ((uint16_t)0x0061)
#define VL53L1X_ULP_RANGE_CONFIG__SIGMA_THRESH ((uint16_t)0x0064)
#define VL53L1X_ULP_MIN_COUNT_RATE_RTN_LIMIT_MCPS ((uint16_t)0x0066)
#define VL53L1X_ULP_INTERMEASUREMENT_MS ((uint16_t)0x006C)
#define VL53L1X_ULP_THRESH_HIGH ((uint16_t)0x0072)
#define VL53L1X_ULP_THRESH_LOW ((uint16_t)0x0074)
#define VL53L1X_ULP_POWER_GO1 ((uint16_t)0x0083)
#define VL53L1X_ULP_FIRMWARE_ENABLE ((uint16_t)0x0085)
#define VL53L1X_ULP_SYSTEM__INTERRUPT_CLEAR ((uint16_t)0x0086)
#define VL53L1X_ULP_SYSTEM_START ((uint16_t)0x0087)
#define VL53L1X_ULP_RESULT__RANGE_STATUS ((uint16_t)0x0089)
#define VL53L1X_ULP_RESULT__SPAD_NB ((uint16_t)0x008C)
#define VL53L1X_ULP_RESULT__SIGNAL_RATE ((uint16_t)0x008E)
#define VL53L1X_ULP_RESULT__AMBIENT_RATE ((uint16_t)0x0090)
#define VL53L1X_ULP_RESULT__SIGMA ((uint16_t)0x0092)
#define VL53L1X_ULP_RESULT__DISTANCE ((uint16_t)0x0096)
#define VL53L1X_ULP_RESULT__OSC_CALIBRATE_VAL ((uint16_t)0x00DE)
#define VL53L1X_ULP_FIRMWARE__SYSTEM_STATUS ((uint16_t)0x00E5)
#define VL53L1X_ULP_IDENTIFICATION__MODEL_ID ((uint16_t)0x010F)
/**
* @brief Functions definitions.
*/
/**
* @brief This function is used to get the sensor id of VL53L1X. The sensor id
* should be 0xEACC.
* @param (uint16_t) dev : Device address.
* @param (uint16_t) *p_id : Sensor id.
* @return (uint8_t) status : 0 if OK.
*/
uint8_t VL53L1X_ULP_GetSensorId(
uint16_t dev,
uint16_t *p_id);
/**
* @brief This function sets a new I2C address to a sensor. It can be used for
* example when multiple sensors share the same I2C bus.
* @param (uint16_t) dev : Device to update.
* @param (uint8_t) new_address : New I2C address.
* @return (uint8_t) status : 0 if I2C address has been correctly
* programmed.
*/
uint8_t VL53L1X_ULP_SetI2CAddress(
uint16_t dev,
uint8_t new_address);
/**
* @brief This function is used to initialize the sensor.
* @param (uint16_t) dev : Device address.
* @return (uint8_t) status : 0 if init is OK.
*/
uint8_t VL53L1X_ULP_SensorInit(
uint16_t dev);
/**
* @brief This function check if a new data is available by polling a dedicated
* register.
* @param (uint16_t) dev : Device address.
* @param (uint8_t) *p_is_data_ready : Pointer containing a flag to know if a
* data is ready : 0 = no data ready, 1 = data ready.
* @return (uint8_t) status : 0 if OK.
*/
uint8_t VL53L1X_ULP_CheckForDataReady(
uint16_t dev,
uint8_t *p_is_data_ready);
/**
* @brief This function clears the interrupt. It needs to be called after a
* ranging data reading to arm the interrupt for the next data ready event.
* @param (uint16_t) dev : Device address.
* @return (uint8_t) status : 0 if OK.
*/
uint8_t VL53L1X_ULP_ClearInterrupt(
uint16_t dev);
/**
* @brief This function starts a ranging session for only one measurement.
* @param (uint16_t) dev : Device address.
* @return (uint8_t) status : 0 if OK.
*/
uint8_t VL53L1X_ULP_StartRangingSingleShot(
uint16_t dev);
/**
* @brief This function starts a ranging session. A manual clear interrupt has
* to be done to restart the next measurement.
* @param (uint16_t) dev : Device address.
* @return (uint8_t) status : 0 if OK.
*/
uint8_t VL53L1X_ULP_StartRanging(
uint16_t dev);
/**
* @brief This function stops the ranging in progress.
* @param (uint16_t) dev : Device address.
* @return (uint8_t) status : 0 if OK.
*/
uint8_t VL53L1X_ULP_StopRanging(
uint16_t dev);
/**
* @brief This function can be used to dump the debug data (estimated distance,
* measurement status, etc). It is particularly useful to tune the device for a
* specific application. The function can be used when a new measurement is
* ready, after clearing the interrupt.
* @param (uint16_t) dev : Device address.
* @param (uint8_t) *p_measurement_status : Measurement status. A value equal to
* 0 means that the estimated distance should be close to the reality.
* @param (uint16_t) *p_estimated_distance_mm : Estimated target distance in mm.
* @param (uint8_t) *p_sigma_mm : Estimated measurements std deviation in mm.
* @param (uint16_t) *p_signal_kcps : Estimated signal rate of the target in kcps.
* @param (uint16_t) *p_signal_mm : Ambient noise from external light in kcps.
* @return (uint8_t) status : 0 if OK.
*/
uint8_t VL53L1X_ULP_DumpDebugData(
uint16_t dev,
uint8_t *p_measurement_status,
uint16_t *p_estimated_distance_mm,
uint16_t *p_sigma_mm,
uint16_t *p_signal_kcps,
uint16_t *p_ambient_kcps);
/**
* @brief Macro timing is equivalent to integration time. A high value increases
* the maximum ranging distance and accuracy, but it also increase the power
* consumption. This function is used to program a new value.
* @param (uint16_t) dev : Device address.
* @param (uint16_t) macro_timing : Macro timing value. Value needs to be
* between 1 and 255. Default is 1 (lowest power consumption).
* @return (uint8_t) status : 0 if OK, or 254 if macro timing is invalid.
*/
uint8_t VL53L1X_ULP_SetMacroTiming(
uint16_t dev,
uint16_t macro_timing);
/**
* @brief Macro timing is equivalent to integration time. A high value increases
* the maximum ranging distance and accuracy, but it also increase the power
* consumption. This function is used to get the programmed value.
* @param (uint16_t) dev : Device address.
* @param (uint16_t) *p_macro_timing : Programmed macro timing value.
* @return (uint8_t) status : 0 if OK.
*/
uint8_t VL53L1X_ULP_GetMacroTiming(
uint16_t dev,
uint16_t *p_macro_timing);
/**
* @brief This function can be used to program the time between 2
* consecutive measurements.
* @param (uint16_t) dev : Device address.
* @param (uint32_t) inter_measurement_ms : Time in milliseconds between 2
* measurements. Min value is 20ms and max is 60000ms. Default is 100ms.
* @return (uint8_t) status : 0 if OK, or 254 if inter-measurement is invalid.
*/
uint8_t VL53L1X_ULP_SetInterMeasurementInMs(
uint16_t dev,
uint32_t inter_measurement_ms);
/**
* @brief This function can be used to get the programmed time between 2
* consecutive measurements.
* @param (uint16_t) dev : Device address.
* @param (uint32_t) *p_inter_measurement_ms : Time in milliseconds between 2
* measurements.
* @return (uint8_t) status : 0 if OK.
*/
uint8_t VL53L1X_ULP_GetInterMeasurementInMs(
uint16_t dev,
uint32_t *p_inter_measurement_ms);
/**
* @brief This function can be used to change the number of SPADs enabled. The
* VL53L1X uses by default a matrix of 256 SPADs which can be reduced. A
* reduced number of SPADs reduces the power consumption, but is also reduces
* the maximum ranging distance and accuracy. By default all SPADs are enabled
* (max ranging distance).
* IMPORTANT : Reducing the number of SPADs does't reduce the FOV.
* @param (uint16_t) dev : Device address.
* @param (uint8_t) roi_width : Size of ROI. The minimum width is 4 (4x4=16
* SPADs), and the maximum is 16 (16x16=256 SPADs).
* @return (uint8_t) status : 0 if OK, or 254 if roi is invalid.
*/
uint8_t VL53L1X_ULP_SetROI(
uint16_t dev,
uint8_t roi_width);
/**
* @brief This function can be used to get the number of SPADs enabled. The
* VL53L1X uses by default a matrix of 256 SPADs which can be reduced. A
* reduced number of SPADs reduces the power consumption, but is also reduces
* the maximum ranging distance and accuracy. By default all SPADs are enabled
* (max ranging distance).
* IMPORTANT : Reducing the number of SPADs does't reduce the FOV.
* @param (uint16_t) dev : Device address.
* @param (uint8_t) *p_roi_width : Size of ROI.
* @return (uint8_t) status : 0 if OK.
*/
uint8_t VL53L1X_ULP_GetROI(
uint16_t dev,
uint8_t *p_roi_width);
/**
* @brief This function can be used to program the interrupt. There are 2
* possible configurations :
* - 1) Interrupt raised when a new measurement is ready, even if the distance
* is wrong. It can be used to debug and tune the sensor.
* - 2) Interrupt raised only when a target is detected. This is more for real
* scene applications.
* By default the sensor is programmed for the first case, it raises an
* interrupt any new measurement is ready.
* @param (uint16_t) dev : Device address.
* @param (uint16_t) distance_threshold_mm : Below this threshold, the
* interrupt will be raised if the measurement is valid (status 0).
* @param (uint8_t) enable_interrupt_only_below_threshold : If this flag is set
* to 0, the sensor is programmed with the first configuration (raise an
* interrupt when a new measurement is ready). Else, the sensor is programmed
* to raise an interrupt ONLY when a valid distance below the threshold is
* reported.
* @return (uint8_t) status : 0 if OK.
*/
uint8_t VL53L1X_ULP_SetInterruptConfiguration(
uint16_t dev,
uint16_t distance_threshold_mm,
uint8_t enable_interrupt_only_below_threshold);
/**
* @brief This function can be used to get the programmed the interrupt. There
* are 2 possible configurations :
* - 1) Interrupt raised when a new measurement is ready, even if the distance
* is wrong. It can be used to debug and tune the sensor.
* - 2) Interrupt raised only when a target is detected. This is more for real
* scene applications.
* By default the sensor is programmed for the first case, it raises an
* interrupt any new measurement is ready.
* @param (uint16_t) dev : Device address.
* @param (uint16_t) *p_distance_threshold_mm : Below this threshold, the
* interrupt will be raised if the measurement is valid (status 0).
* @param (uint8_t) *p_interrupt_enabled_only_below_threshold : If this flag is
* set to 0, the sensor is programmed with the first configuration (raise an
* interrupt when a new measurement is ready). Else, the sensor is programmed
* to raise an interrupt ONLY when a valid distance below the threshold is
* reported.
* @return (uint8_t) status : 0 if OK.
*/
uint8_t VL53L1X_ULP_GetInterruptConfiguration(
uint16_t dev,
uint16_t *p_distance_threshold_mm,
uint8_t *p_interrupt_enabled_only_below_threshold);
/**
* @brief This function sets a new signal threshold in kcps. If a
* target has a lower signal as the programmed value, the measurement status in
* debug value will be equal to 2.
* @param (uint16_t) dev : Device address.
* @param (uint16_t) signal_kcps : New signal threshold in kcps. The default
* value is 1500 kcps. Minimum is 1 kcps, and maximum is 16384 kcps.
* @return (uint8_t) status : 0 if OK, or 254 if the threshold is not valid.
*/
uint8_t VL53L1X_ULP_SetSignalThreshold(
uint16_t dev,
uint16_t signal_kcps);
/**
* @brief This function returns the current signal threshold in kcps. If a
* target has a lower signal as the programmed value, the measurement status in
* debug value will be equal to 2.
* @param (uint16_t) dev : Device address.
* @param (uint16_t) *p_signal_kcps : Pointer of signal threshold in kcps.
* @return (uint8_t) status : 0 if OK.
*/
uint8_t VL53L1X_ULP_GetSignalThreshold(
uint16_t dev,
uint16_t *p_signal_kcps);
/**
* @brief This function programs a new sigma threshold. The sigma corresponds to
* the standard deviation of the returned pulse. If the computed sigma is above
* the programmed value, the measurement status in debug value will be equal to
* 1.
* @param (uint16_t) dev : Device address.
* @param (uint16_t) sigma_mm : New sigma threshold in mm. The default value is
* 45mm. Minimum is 1mm, and maximum is 16383mm.
* @return (uint8_t) status : 0 if OK, or 254 if the threshold is not valid.
*/
uint8_t VL53L1X_ULP_SetSigmaThreshold(
uint16_t dev,
uint16_t sigma_mm);
/**
* @brief This function gets the current sigma threshold. The sigma corresponds
* to the standard deviation of the returned pulse. If the computed sigma is
* above the programmed value, the measurement status in debug value will be
* equal to 1.
* @param (uint16_t) dev : Device address.
* @param (uint16_t) *p_sigma_mm : Current sigma threshold in mm.
* @return (uint8_t) status : 0 if OK.
*/
uint8_t VL53L1X_ULP_GetSigmaThreshold(
uint16_t dev,
uint16_t *p_sigma_mm);
#endif

View File

@ -0,0 +1,149 @@
/*
Copyright (c) 2021, STMicroelectronics - All Rights Reserved
This file : part of VL53L1X ULP and : dual licensed,
either 'STMicroelectronics
Proprietary license'
or 'BSD 3-clause "New" or "Revised" License' , at your option.
*******************************************************************************
'STMicroelectronics Proprietary license'
*******************************************************************************
License terms: STMicroelectronics Proprietary in accordance with licensing
terms at www.st.com/sla0081
STMicroelectronics confidential
Reproduction and Communication of this document : strictly prohibited unless
specifically authorized in writing by STMicroelectronics.
*******************************************************************************
Alternatively, VL53L1X ULP may be distributed under the terms of
'BSD 3-clause "New" or "Revised" License', in which case the following
provisions apply instead of the ones mentioned above :
*******************************************************************************
License terms: BSD 3-clause "New" or "Revised" License.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************
*/
#include "VL53L1X_ULP_platform.h"
extern I2C_HandleTypeDef hi2c2;
uint8_t VL53L1X_ULP_RdDWord(uint16_t dev, uint16_t RegisterAdress, uint32_t *value)
{
uint8_t status = 0;
uint8_t data_write[2];
uint8_t data_read[4];
data_write[0] = (RegisterAdress >> 8) & 0xFF;
data_write[1] = RegisterAdress & 0xFF;
status = HAL_I2C_Master_Transmit(&hi2c2, dev, data_write, 2, 100);
status = HAL_I2C_Master_Receive(&hi2c2, dev, data_read, 4, 100);
*value = ((data_read[0] << 24) | (data_read[1] << 16) |
(data_read[2] << 8) | (data_read[3]));
return status;
}
uint8_t VL53L1X_ULP_RdWord(uint16_t dev, uint16_t RegisterAdress, uint16_t *value)
{
uint8_t status = 0;
uint8_t data_write[2];
uint8_t data_read[2];
data_write[0] = (RegisterAdress >> 8) & 0xFF;
data_write[1] = RegisterAdress & 0xFF;
status = HAL_I2C_Master_Transmit(&hi2c2, dev, data_write, 2, 100);
status = HAL_I2C_Master_Receive(&hi2c2, dev, data_read, 2, 100);
*value = (data_read[0] << 8) | (data_read[1]);
return status;
}
uint8_t VL53L1X_ULP_RdByte(uint16_t dev, uint16_t RegisterAdress, uint8_t *value)
{
uint8_t status = 0;
uint8_t data_write[2];
uint8_t data_read[1];
data_write[0] = (RegisterAdress >> 8) & 0xFF;
data_write[1] = RegisterAdress & 0xFF;
status = HAL_I2C_Master_Transmit(&hi2c2, dev, data_write, 2, 100);
status = HAL_I2C_Master_Receive(&hi2c2, dev, data_read, 1, 100);
*value = data_read[0];
return status;
}
uint8_t VL53L1X_ULP_WrByte(uint16_t dev, uint16_t RegisterAdress, uint8_t value)
{
uint8_t data_write[3];
uint8_t status = 0;
data_write[0] = (RegisterAdress >> 8) & 0xFF;
data_write[1] = RegisterAdress & 0xFF;
data_write[2] = value & 0xFF;
status = HAL_I2C_Master_Transmit(&hi2c2, dev, data_write, 3, 100);
return status;
}
uint8_t VL53L1X_ULP_WrWord(uint16_t dev, uint16_t RegisterAdress, uint16_t value)
{
uint8_t data_write[4];
uint8_t status = 0;
data_write[0] = (RegisterAdress >> 8) & 0xFF;
data_write[1] = RegisterAdress & 0xFF;
data_write[2] = (value >> 8) & 0xFF;
data_write[3] = value & 0xFF;
status = HAL_I2C_Master_Transmit(&hi2c2, dev, data_write, 4, 100);
return status;
}
uint8_t VL53L1X_ULP_WrDWord(uint16_t dev, uint16_t RegisterAdress, uint32_t value)
{
uint8_t data_write[6];
uint8_t status = 0;
data_write[0] = (RegisterAdress >> 8) & 0xFF;
data_write[1] = RegisterAdress & 0xFF;
data_write[2] = (value >> 24) & 0xFF;
data_write[3] = (value >> 16) & 0xFF;
data_write[4] = (value >> 8) & 0xFF;
data_write[5] = value & 0xFF;
status = HAL_I2C_Master_Transmit(&hi2c2, dev, data_write, 6, 100);
return status;
}
void VL53L1X_ULP_WaitMs(uint32_t TimeMs)
{
HAL_Delay(TimeMs);
}

View File

@ -0,0 +1,110 @@
/*
Copyright (c) 2021, STMicroelectronics - All Rights Reserved
This file : part of VL53L1X ULP and : dual licensed,
either 'STMicroelectronics
Proprietary license'
or 'BSD 3-clause "New" or "Revised" License' , at your option.
*******************************************************************************
'STMicroelectronics Proprietary license'
*******************************************************************************
License terms: STMicroelectronics Proprietary in accordance with licensing
terms at www.st.com/sla0081
STMicroelectronics confidential
Reproduction and Communication of this document : strictly prohibited unless
specifically authorized in writing by STMicroelectronics.
*******************************************************************************
Alternatively, VL53L1X ULP may be distributed under the terms of
'BSD 3-clause "New" or "Revised" License', in which case the following
provisions apply instead of the ones mentioned above :
*******************************************************************************
License terms: BSD 3-clause "New" or "Revised" License.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************
*/
#ifndef _VL53L1X_ULP_PLATFORM_H_
#define _VL53L1X_ULP_PLATFORM_H_
#pragma once
#include <stdint.h>
#include <string.h>
/**
* @brief Read 32 bits through I2C.
*/
uint8_t VL53L1X_ULP_RdDWord(uint16_t dev, uint16_t registerAddr, uint32_t *value);
/**
* @brief Read 16 bits through I2C.
*/
uint8_t VL53L1X_ULP_RdWord(uint16_t dev, uint16_t registerAddr, uint16_t *value);
/**
* @brief Read 8 bits through I2C.
*/
uint8_t VL53L1X_ULP_RdByte(uint16_t dev, uint16_t registerAddr, uint8_t *value);
/**
* @brief Write 8 bits through I2C.
*/
uint8_t VL53L1X_ULP_WrByte(uint16_t dev, uint16_t registerAddr, uint8_t value);
/**
* @brief Write 16 bits through I2C.
*/
uint8_t VL53L1X_ULP_WrWord(uint16_t dev, uint16_t RegisterAdress, uint16_t value);
/**
* @brief Write 32 bits through I2C.
*/
uint8_t VL53L1X_ULP_WrDWord(uint16_t dev, uint16_t RegisterAdress, uint32_t value);
/**
* @brief Wait during N milliseconds.
*/
void VL53L1X_ULP_WaitMs(uint32_t TimeMs);
#endif // _VL53L1X_ULP_PLATFORM_H_

850
vl53lx_uld/VL53L1X_api.c Normal file
View File

@ -0,0 +1,850 @@
/*
Copyright (c) 2017, STMicroelectronics - All Rights Reserved
This file : part of VL53L1 Core and : dual licensed,
either 'STMicroelectronics
Proprietary license'
or 'BSD 3-clause "New" or "Revised" License' , at your option.
*******************************************************************************
'STMicroelectronics Proprietary license'
*******************************************************************************
License terms: STMicroelectronics Proprietary in accordance with licensing
terms at www.st.com/sla0081
STMicroelectronics confidential
Reproduction and Communication of this document : strictly prohibited unless
specifically authorized in writing by STMicroelectronics.
*******************************************************************************
Alternatively, VL53L1 Core may be distributed under the terms of
'BSD 3-clause "New" or "Revised" License', in which case the following
provisions apply instead of the ones mentioned above :
*******************************************************************************
License terms: BSD 3-clause "New" or "Revised" License.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************
*/
/**
* @file vl53l1x_api.c
* @brief Functions implementation
*/
#include "VL53L1X_api.h"
#include <string.h>
#if 0
uint8_t VL51L1X_NVM_CONFIGURATION[] = {
0x00, /* 0x00 : not user-modifiable */
0x29, /* 0x01 : 7 bits I2C address (default=0x29), use SetI2CAddress(). Warning: after changing the register value to a new I2C address, the device will only answer to the new address */
0x00, /* 0x02 : not user-modifiable */
0x00, /* 0x03 : not user-modifiable */
0x00, /* 0x04 : not user-modifiable */
0x00, /* 0x05 : not user-modifiable */
0x00, /* 0x06 : not user-modifiable */
0x00, /* 0x07 : not user-modifiable */
0x00, /* 0x08 : not user-modifiable */
0x50, /* 0x09 : not user-modifiable */
0x00, /* 0x0A : not user-modifiable */
0x00, /* 0x0B : not user-modifiable */
0x00, /* 0x0C : not user-modifiable */
0x00, /* 0x0D : not user-modifiable */
0x0a, /* 0x0E : not user-modifiable */
0x00, /* 0x0F : not user-modifiable */
0x00, /* 0x10 : not user-modifiable */
0x00, /* 0x11 : not user-modifiable */
0x00, /* 0x12 : not user-modifiable */
0x00, /* 0x13 : not user-modifiable */
0x00, /* 0x14 : not user-modifiable */
0x00, /* 0x15 : not user-modifiable */
0x00, /* 0x16 : Xtalk calibration value MSB (7.9 format in kcps), use SetXtalk() */
0x00, /* 0x17 : Xtalk calibration value LSB */
0x00, /* 0x18 : not user-modifiable */
0x00, /* 0x19 : not user-modifiable */
0x00, /* 0x1a : not user-modifiable */
0x00, /* 0x1b : not user-modifiable */
0x00, /* 0x1e : Part to Part offset x4 MSB (in mm), use SetOffset() */
0x50, /* 0x1f : Part to Part offset x4 LSB */
0x00, /* 0x20 : not user-modifiable */
0x00, /* 0x21 : not user-modifiable */
0x00, /* 0x22 : not user-modifiable */
0x00, /* 0x23 : not user-modifiable */
}
#endif
const uint8_t VL51L1X_DEFAULT_CONFIGURATION[] = {
0x00, /* 0x2d : set bit 2 and 5 to 1 for fast plus mode (1MHz I2C), else don't touch */
0x00, /* 0x2e : bit 0 if I2C pulled up at 1.8V, else set bit 0 to 1 (pull up at AVDD) */
0x00, /* 0x2f : bit 0 if GPIO pulled up at 1.8V, else set bit 0 to 1 (pull up at AVDD) */
0x01, /* 0x30 : set bit 4 to 0 for active high interrupt and 1 for active low (bits 3:0 must be 0x1), use SetInterruptPolarity() */
0x02, /* 0x31 : bit 1 = interrupt depending on the polarity, use CheckForDataReady() */
0x00, /* 0x32 : not user-modifiable */
0x02, /* 0x33 : not user-modifiable */
0x08, /* 0x34 : not user-modifiable */
0x00, /* 0x35 : not user-modifiable */
0x08, /* 0x36 : not user-modifiable */
0x10, /* 0x37 : not user-modifiable */
0x01, /* 0x38 : not user-modifiable */
0x01, /* 0x39 : not user-modifiable */
0x00, /* 0x3a : not user-modifiable */
0x00, /* 0x3b : not user-modifiable */
0x00, /* 0x3c : not user-modifiable */
0x00, /* 0x3d : not user-modifiable */
0xff, /* 0x3e : not user-modifiable */
0x00, /* 0x3f : not user-modifiable */
0x0F, /* 0x40 : not user-modifiable */
0x00, /* 0x41 : not user-modifiable */
0x00, /* 0x42 : not user-modifiable */
0x00, /* 0x43 : not user-modifiable */
0x00, /* 0x44 : not user-modifiable */
0x00, /* 0x45 : not user-modifiable */
0x20, /* 0x46 : interrupt configuration 0->level low detection, 1-> level high, 2-> Out of window, 3->In window, 0x20-> New sample ready , TBC */
0x0b, /* 0x47 : not user-modifiable */
0x00, /* 0x48 : not user-modifiable */
0x00, /* 0x49 : not user-modifiable */
0x02, /* 0x4a : not user-modifiable */
0x0a, /* 0x4b : not user-modifiable */
0x21, /* 0x4c : not user-modifiable */
0x00, /* 0x4d : not user-modifiable */
0x00, /* 0x4e : not user-modifiable */
0x05, /* 0x4f : not user-modifiable */
0x00, /* 0x50 : not user-modifiable */
0x00, /* 0x51 : not user-modifiable */
0x00, /* 0x52 : not user-modifiable */
0x00, /* 0x53 : not user-modifiable */
0xc8, /* 0x54 : not user-modifiable */
0x00, /* 0x55 : not user-modifiable */
0x00, /* 0x56 : not user-modifiable */
0x38, /* 0x57 : not user-modifiable */
0xff, /* 0x58 : not user-modifiable */
0x01, /* 0x59 : not user-modifiable */
0x00, /* 0x5a : not user-modifiable */
0x08, /* 0x5b : not user-modifiable */
0x00, /* 0x5c : not user-modifiable */
0x00, /* 0x5d : not user-modifiable */
0x01, /* 0x5e : not user-modifiable */
0xcc, /* 0x5f : not user-modifiable */
0x0f, /* 0x60 : not user-modifiable */
0x01, /* 0x61 : not user-modifiable */
0xf1, /* 0x62 : not user-modifiable */
0x0d, /* 0x63 : not user-modifiable */
0x01, /* 0x64 : Sigma threshold MSB (mm in 14.2 format for MSB+LSB), use SetSigmaThreshold(), default value 90 mm */
0x68, /* 0x65 : Sigma threshold LSB */
0x00, /* 0x66 : Min count Rate MSB (MCPS in 9.7 format for MSB+LSB), use SetSignalThreshold() */
0x80, /* 0x67 : Min count Rate LSB */
0x08, /* 0x68 : not user-modifiable */
0xb8, /* 0x69 : not user-modifiable */
0x00, /* 0x6a : not user-modifiable */
0x00, /* 0x6b : not user-modifiable */
0x00, /* 0x6c : Intermeasurement period MSB, 32 bits register, use SetIntermeasurementInMs() */
0x00, /* 0x6d : Intermeasurement period */
0x0f, /* 0x6e : Intermeasurement period */
0x89, /* 0x6f : Intermeasurement period LSB */
0x00, /* 0x70 : not user-modifiable */
0x00, /* 0x71 : not user-modifiable */
0x00, /* 0x72 : distance threshold high MSB (in mm, MSB+LSB), use SetD:tanceThreshold() */
0x00, /* 0x73 : distance threshold high LSB */
0x00, /* 0x74 : distance threshold low MSB ( in mm, MSB+LSB), use SetD:tanceThreshold() */
0x00, /* 0x75 : distance threshold low LSB */
0x00, /* 0x76 : not user-modifiable */
0x01, /* 0x77 : not user-modifiable */
0x0f, /* 0x78 : not user-modifiable */
0x0d, /* 0x79 : not user-modifiable */
0x0e, /* 0x7a : not user-modifiable */
0x0e, /* 0x7b : not user-modifiable */
0x00, /* 0x7c : not user-modifiable */
0x00, /* 0x7d : not user-modifiable */
0x02, /* 0x7e : not user-modifiable */
0xc7, /* 0x7f : ROI center, use SetROI() */
0xff, /* 0x80 : XY ROI (X=Width, Y=Height), use SetROI() */
0x9B, /* 0x81 : not user-modifiable */
0x00, /* 0x82 : not user-modifiable */
0x00, /* 0x83 : not user-modifiable */
0x00, /* 0x84 : not user-modifiable */
0x01, /* 0x85 : not user-modifiable */
0x00, /* 0x86 : clear interrupt, use ClearInterrupt() */
0x00 /* 0x87 : start ranging, use StartRanging() or StopRanging(), If you want an automatic start after VL53L1X_init() call, put 0x40 in location 0x87 */
};
static const uint8_t status_rtn[24] = { 255, 255, 255, 5, 2, 4, 1, 7, 3, 0,
255, 255, 9, 13, 255, 255, 255, 255, 10, 6,
255, 255, 11, 12
};
VL53L1X_ERROR VL53L1X_GetSWVersion(VL53L1X_Version_t *pVersion)
{
VL53L1X_ERROR Status = 0;
pVersion->major = VL53L1X_IMPLEMENTATION_VER_MAJOR;
pVersion->minor = VL53L1X_IMPLEMENTATION_VER_MINOR;
pVersion->build = VL53L1X_IMPLEMENTATION_VER_SUB;
pVersion->revision = VL53L1X_IMPLEMENTATION_VER_REVISION;
return Status;
}
VL53L1X_ERROR VL53L1X_SetI2CAddress(uint16_t dev, uint8_t new_address)
{
VL53L1X_ERROR status = 0;
status = VL53L1_WrByte(dev, VL53L1_I2C_SLAVE__DEVICE_ADDRESS, new_address >> 1);
return status;
}
VL53L1X_ERROR VL53L1X_SensorInit(uint16_t dev)
{
VL53L1X_ERROR status = 0;
uint8_t Addr = 0x00, tmp;
for (Addr = 0x2D; Addr <= 0x87; Addr++){
status = VL53L1_WrByte(dev, Addr, VL51L1X_DEFAULT_CONFIGURATION[Addr - 0x2D]);
}
status = VL53L1X_StartRanging(dev);
tmp = 0;
while(tmp==0){
status = VL53L1X_CheckForDataReady(dev, &tmp);
}
status = VL53L1X_ClearInterrupt(dev);
status = VL53L1X_StopRanging(dev);
status = VL53L1_WrByte(dev, VL53L1_VHV_CONFIG__TIMEOUT_MACROP_LOOP_BOUND, 0x09); /* two bounds VHV */
status = VL53L1_WrByte(dev, 0x0B, 0); /* start VHV from the previous temperature */
return status;
}
VL53L1X_ERROR VL53L1X_ClearInterrupt(uint16_t dev)
{
VL53L1X_ERROR status = 0;
status = VL53L1_WrByte(dev, SYSTEM__INTERRUPT_CLEAR, 0x01);
return status;
}
VL53L1X_ERROR VL53L1X_SetInterruptPolarity(uint16_t dev, uint8_t NewPolarity)
{
uint8_t Temp;
VL53L1X_ERROR status = 0;
status = VL53L1_RdByte(dev, GPIO_HV_MUX__CTRL, &Temp);
Temp = Temp & 0xEF;
status = VL53L1_WrByte(dev, GPIO_HV_MUX__CTRL, Temp | (!(NewPolarity & 1)) << 4);
return status;
}
VL53L1X_ERROR VL53L1X_GetInterruptPolarity(uint16_t dev, uint8_t *pInterruptPolarity)
{
uint8_t Temp;
VL53L1X_ERROR status = 0;
status = VL53L1_RdByte(dev, GPIO_HV_MUX__CTRL, &Temp);
Temp = Temp & 0x10;
*pInterruptPolarity = !(Temp>>4);
return status;
}
VL53L1X_ERROR VL53L1X_StartRanging(uint16_t dev)
{
VL53L1X_ERROR status = 0;
status = VL53L1_WrByte(dev, SYSTEM__MODE_START, 0x40); /* Enable VL53L1X */
return status;
}
VL53L1X_ERROR VL53L1X_StopRanging(uint16_t dev)
{
VL53L1X_ERROR status = 0;
status = VL53L1_WrByte(dev, SYSTEM__MODE_START, 0x00); /* Disable VL53L1X */
return status;
}
VL53L1X_ERROR VL53L1X_CheckForDataReady(uint16_t dev, uint8_t *isDataReady)
{
uint8_t Temp;
uint8_t IntPol;
VL53L1X_ERROR status = 0;
status = VL53L1X_GetInterruptPolarity(dev, &IntPol);
status = VL53L1_RdByte(dev, GPIO__TIO_HV_STATUS, &Temp);
/* Read in the register to check if a new value is available */
if (status == 0){
if ((Temp & 1) == IntPol)
*isDataReady = 1;
else
*isDataReady = 0;
}
return status;
}
VL53L1X_ERROR VL53L1X_SetTimingBudgetInMs(uint16_t dev, uint16_t TimingBudgetInMs)
{
uint16_t DM;
VL53L1X_ERROR status=0;
status = VL53L1X_GetDistanceMode(dev, &DM);
if (DM == 0)
return 1;
else if (DM == 1) { /* Short DistanceMode */
switch (TimingBudgetInMs) {
case 15: /* only available in short distance mode */
VL53L1_WrWord(dev, RANGE_CONFIG__TIMEOUT_MACROP_A_HI,
0x01D);
VL53L1_WrWord(dev, RANGE_CONFIG__TIMEOUT_MACROP_B_HI,
0x0027);
break;
case 20:
VL53L1_WrWord(dev, RANGE_CONFIG__TIMEOUT_MACROP_A_HI,
0x0051);
VL53L1_WrWord(dev, RANGE_CONFIG__TIMEOUT_MACROP_B_HI,
0x006E);
break;
case 33:
VL53L1_WrWord(dev, RANGE_CONFIG__TIMEOUT_MACROP_A_HI,
0x00D6);
VL53L1_WrWord(dev, RANGE_CONFIG__TIMEOUT_MACROP_B_HI,
0x006E);
break;
case 50:
VL53L1_WrWord(dev, RANGE_CONFIG__TIMEOUT_MACROP_A_HI,
0x1AE);
VL53L1_WrWord(dev, RANGE_CONFIG__TIMEOUT_MACROP_B_HI,
0x01E8);
break;
case 100:
VL53L1_WrWord(dev, RANGE_CONFIG__TIMEOUT_MACROP_A_HI,
0x02E1);
VL53L1_WrWord(dev, RANGE_CONFIG__TIMEOUT_MACROP_B_HI,
0x0388);
break;
case 200:
VL53L1_WrWord(dev, RANGE_CONFIG__TIMEOUT_MACROP_A_HI,
0x03E1);
VL53L1_WrWord(dev, RANGE_CONFIG__TIMEOUT_MACROP_B_HI,
0x0496);
break;
case 500:
VL53L1_WrWord(dev, RANGE_CONFIG__TIMEOUT_MACROP_A_HI,
0x0591);
VL53L1_WrWord(dev, RANGE_CONFIG__TIMEOUT_MACROP_B_HI,
0x05C1);
break;
default:
status = 1;
break;
}
} else {
switch (TimingBudgetInMs) {
case 20:
VL53L1_WrWord(dev, RANGE_CONFIG__TIMEOUT_MACROP_A_HI,
0x001E);
VL53L1_WrWord(dev, RANGE_CONFIG__TIMEOUT_MACROP_B_HI,
0x0022);
break;
case 33:
VL53L1_WrWord(dev, RANGE_CONFIG__TIMEOUT_MACROP_A_HI,
0x0060);
VL53L1_WrWord(dev, RANGE_CONFIG__TIMEOUT_MACROP_B_HI,
0x006E);
break;
case 50:
VL53L1_WrWord(dev, RANGE_CONFIG__TIMEOUT_MACROP_A_HI,
0x00AD);
VL53L1_WrWord(dev, RANGE_CONFIG__TIMEOUT_MACROP_B_HI,
0x00C6);
break;
case 100:
VL53L1_WrWord(dev, RANGE_CONFIG__TIMEOUT_MACROP_A_HI,
0x01CC);
VL53L1_WrWord(dev, RANGE_CONFIG__TIMEOUT_MACROP_B_HI,
0x01EA);
break;
case 200:
VL53L1_WrWord(dev, RANGE_CONFIG__TIMEOUT_MACROP_A_HI,
0x02D9);
VL53L1_WrWord(dev, RANGE_CONFIG__TIMEOUT_MACROP_B_HI,
0x02F8);
break;
case 500:
VL53L1_WrWord(dev, RANGE_CONFIG__TIMEOUT_MACROP_A_HI,
0x048F);
VL53L1_WrWord(dev, RANGE_CONFIG__TIMEOUT_MACROP_B_HI,
0x04A4);
break;
default:
status = 1;
break;
}
}
return status;
}
VL53L1X_ERROR VL53L1X_GetTimingBudgetInMs(uint16_t dev, uint16_t *pTimingBudget)
{
uint16_t Temp;
VL53L1X_ERROR status = 0;
status = VL53L1_RdWord(dev, RANGE_CONFIG__TIMEOUT_MACROP_A_HI, &Temp);
switch (Temp) {
case 0x001D :
*pTimingBudget = 15;
break;
case 0x0051 :
case 0x001E :
*pTimingBudget = 20;
break;
case 0x00D6 :
case 0x0060 :
*pTimingBudget = 33;
break;
case 0x1AE :
case 0x00AD :
*pTimingBudget = 50;
break;
case 0x02E1 :
case 0x01CC :
*pTimingBudget = 100;
break;
case 0x03E1 :
case 0x02D9 :
*pTimingBudget = 200;
break;
case 0x0591 :
case 0x048F :
*pTimingBudget = 500;
break;
default:
status = 1;
*pTimingBudget = 0;
}
return status;
}
VL53L1X_ERROR VL53L1X_SetDistanceMode(uint16_t dev, uint16_t DM)
{
uint16_t TB;
VL53L1X_ERROR status = 0;
status = VL53L1X_GetTimingBudgetInMs(dev, &TB);
if (status != 0)
return 1;
switch (DM) {
case 1:
status = VL53L1_WrByte(dev, PHASECAL_CONFIG__TIMEOUT_MACROP, 0x14);
status = VL53L1_WrByte(dev, RANGE_CONFIG__VCSEL_PERIOD_A, 0x07);
status = VL53L1_WrByte(dev, RANGE_CONFIG__VCSEL_PERIOD_B, 0x05);
status = VL53L1_WrByte(dev, RANGE_CONFIG__VALID_PHASE_HIGH, 0x38);
status = VL53L1_WrWord(dev, SD_CONFIG__WOI_SD0, 0x0705);
status = VL53L1_WrWord(dev, SD_CONFIG__INITIAL_PHASE_SD0, 0x0606);
break;
case 2:
status = VL53L1_WrByte(dev, PHASECAL_CONFIG__TIMEOUT_MACROP, 0x0A);
status = VL53L1_WrByte(dev, RANGE_CONFIG__VCSEL_PERIOD_A, 0x0F);
status = VL53L1_WrByte(dev, RANGE_CONFIG__VCSEL_PERIOD_B, 0x0D);
status = VL53L1_WrByte(dev, RANGE_CONFIG__VALID_PHASE_HIGH, 0xB8);
status = VL53L1_WrWord(dev, SD_CONFIG__WOI_SD0, 0x0F0D);
status = VL53L1_WrWord(dev, SD_CONFIG__INITIAL_PHASE_SD0, 0x0E0E);
break;
default:
status = 1;
break;
}
if (status == 0)
status = VL53L1X_SetTimingBudgetInMs(dev, TB);
return status;
}
VL53L1X_ERROR VL53L1X_GetDistanceMode(uint16_t dev, uint16_t *DM)
{
uint8_t TempDM, status=0;
status = VL53L1_RdByte(dev,PHASECAL_CONFIG__TIMEOUT_MACROP, &TempDM);
if (TempDM == 0x14)
*DM=1;
if(TempDM == 0x0A)
*DM=2;
return status;
}
VL53L1X_ERROR VL53L1X_SetInterMeasurementInMs(uint16_t dev, uint16_t InterMeasMs)
{
uint16_t ClockPLL;
VL53L1X_ERROR status = 0;
status = VL53L1_RdWord(dev, VL53L1_RESULT__OSC_CALIBRATE_VAL, &ClockPLL);
ClockPLL = ClockPLL&0x3FF;
VL53L1_WrDWord(dev, VL53L1_SYSTEM__INTERMEASUREMENT_PERIOD,
(uint32_t)(ClockPLL * InterMeasMs * 1.075));
return status;
}
VL53L1X_ERROR VL53L1X_GetInterMeasurementInMs(uint16_t dev, uint16_t *pIM)
{
uint16_t ClockPLL;
VL53L1X_ERROR status = 0;
uint32_t tmp;
status = VL53L1_RdDWord(dev,VL53L1_SYSTEM__INTERMEASUREMENT_PERIOD, &tmp);
*pIM = (uint16_t)tmp;
status = VL53L1_RdWord(dev, VL53L1_RESULT__OSC_CALIBRATE_VAL, &ClockPLL);
ClockPLL = ClockPLL&0x3FF;
*pIM= (uint16_t)(*pIM/(ClockPLL*1.065));
return status;
}
VL53L1X_ERROR VL53L1X_BootState(uint16_t dev, uint8_t *state)
{
VL53L1X_ERROR status = 0;
uint8_t tmp = 0;
status = VL53L1_RdByte(dev,VL53L1_FIRMWARE__SYSTEM_STATUS, &tmp);
*state = tmp;
return status;
}
VL53L1X_ERROR VL53L1X_GetSensorId(uint16_t dev, uint16_t *sensorId)
{
VL53L1X_ERROR status = 0;
uint16_t tmp = 0;
status = VL53L1_RdWord(dev, VL53L1_IDENTIFICATION__MODEL_ID, &tmp);
*sensorId = tmp;
return status;
}
VL53L1X_ERROR VL53L1X_GetDistance(uint16_t dev, uint16_t *distance)
{
VL53L1X_ERROR status = 0;
uint16_t tmp;
status = (VL53L1_RdWord(dev,
VL53L1_RESULT__FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD0, &tmp));
*distance = tmp;
return status;
}
VL53L1X_ERROR VL53L1X_GetSignalPerSpad(uint16_t dev, uint16_t *signalRate)
{
VL53L1X_ERROR status = 0;
uint16_t SpNb=1, signal;
status = VL53L1_RdWord(dev,
VL53L1_RESULT__PEAK_SIGNAL_COUNT_RATE_CROSSTALK_CORRECTED_MCPS_SD0, &signal);
status = VL53L1_RdWord(dev,
VL53L1_RESULT__DSS_ACTUAL_EFFECTIVE_SPADS_SD0, &SpNb);
*signalRate = (uint16_t) (2000.0*signal/SpNb);
return status;
}
VL53L1X_ERROR VL53L1X_GetAmbientPerSpad(uint16_t dev, uint16_t *ambPerSp)
{
VL53L1X_ERROR status = 0;
uint16_t AmbientRate, SpNb = 1;
status = VL53L1_RdWord(dev, RESULT__AMBIENT_COUNT_RATE_MCPS_SD, &AmbientRate);
status = VL53L1_RdWord(dev, VL53L1_RESULT__DSS_ACTUAL_EFFECTIVE_SPADS_SD0, &SpNb);
*ambPerSp=(uint16_t) (2000.0 * AmbientRate / SpNb);
return status;
}
VL53L1X_ERROR VL53L1X_GetSignalRate(uint16_t dev, uint16_t *signal)
{
VL53L1X_ERROR status = 0;
uint16_t tmp;
status = VL53L1_RdWord(dev,
VL53L1_RESULT__PEAK_SIGNAL_COUNT_RATE_CROSSTALK_CORRECTED_MCPS_SD0, &tmp);
*signal = tmp*8;
return status;
}
VL53L1X_ERROR VL53L1X_GetSpadNb(uint16_t dev, uint16_t *spNb)
{
VL53L1X_ERROR status = 0;
uint16_t tmp;
status = VL53L1_RdWord(dev,
VL53L1_RESULT__DSS_ACTUAL_EFFECTIVE_SPADS_SD0, &tmp);
*spNb = tmp >> 8;
return status;
}
VL53L1X_ERROR VL53L1X_GetAmbientRate(uint16_t dev, uint16_t *ambRate)
{
VL53L1X_ERROR status = 0;
uint16_t tmp;
status = VL53L1_RdWord(dev, RESULT__AMBIENT_COUNT_RATE_MCPS_SD, &tmp);
*ambRate = tmp*8;
return status;
}
VL53L1X_ERROR VL53L1X_GetRangeStatus(uint16_t dev, uint8_t *rangeStatus)
{
VL53L1X_ERROR status = 0;
uint8_t RgSt;
*rangeStatus = 255;
status = VL53L1_RdByte(dev, VL53L1_RESULT__RANGE_STATUS, &RgSt);
RgSt = RgSt & 0x1F;
if (RgSt < 24)
*rangeStatus = status_rtn[RgSt];
return status;
}
VL53L1X_ERROR VL53L1X_GetResult(uint16_t dev, VL53L1X_Result_t *pResult)
{
VL53L1X_ERROR status = 0;
uint8_t Temp[17];
uint8_t RgSt = 255;
status = VL53L1_ReadMulti(dev, VL53L1_RESULT__RANGE_STATUS, Temp, 17);
RgSt = Temp[0] & 0x1F;
if (RgSt < 24)
RgSt = status_rtn[RgSt];
pResult->Status = RgSt;
pResult->Ambient = (Temp[7] << 8 | Temp[8]) * 8;
pResult->NumSPADs = Temp[3];
pResult->SigPerSPAD = (Temp[15] << 8 | Temp[16]) * 8;
pResult->Distance = Temp[13] << 8 | Temp[14];
return status;
}
VL53L1X_ERROR VL53L1X_SetOffset(uint16_t dev, int16_t OffsetValue)
{
VL53L1X_ERROR status = 0;
int16_t Temp;
Temp = (OffsetValue*4);
VL53L1_WrWord(dev, ALGO__PART_TO_PART_RANGE_OFFSET_MM,
(uint16_t)Temp);
VL53L1_WrWord(dev, MM_CONFIG__INNER_OFFSET_MM, 0x0);
VL53L1_WrWord(dev, MM_CONFIG__OUTER_OFFSET_MM, 0x0);
return status;
}
VL53L1X_ERROR VL53L1X_GetOffset(uint16_t dev, int16_t *offset)
{
VL53L1X_ERROR status = 0;
uint16_t Temp;
status = VL53L1_RdWord(dev,ALGO__PART_TO_PART_RANGE_OFFSET_MM, &Temp);
Temp = Temp<<3;
Temp = Temp>>5;
*offset = (int16_t)(Temp);
return status;
}
VL53L1X_ERROR VL53L1X_SetXtalk(uint16_t dev, uint16_t XtalkValue)
{
/* XTalkValue in count per second to avoid float type */
VL53L1X_ERROR status = 0;
status = VL53L1_WrWord(dev,
ALGO__CROSSTALK_COMPENSATION_X_PLANE_GRADIENT_KCPS,
0x0000);
status = VL53L1_WrWord(dev, ALGO__CROSSTALK_COMPENSATION_Y_PLANE_GRADIENT_KCPS,
0x0000);
status = VL53L1_WrWord(dev, ALGO__CROSSTALK_COMPENSATION_PLANE_OFFSET_KCPS,
(XtalkValue<<9)/1000); /* * << 9 (7.9 format) and /1000 to convert cps to kpcs */
return status;
}
VL53L1X_ERROR VL53L1X_GetXtalk(uint16_t dev, uint16_t *xtalk )
{
VL53L1X_ERROR status = 0;
uint32_t tmp;
status = VL53L1_RdDWord(dev,ALGO__CROSSTALK_COMPENSATION_PLANE_OFFSET_KCPS, &tmp);
*xtalk = (uint16_t)(tmp*1000)>>9; /* * 1000 to convert kcps to cps and >> 9 (7.9 format) */
return status;
}
VL53L1X_ERROR VL53L1X_SetDistanceThreshold(uint16_t dev, uint16_t ThreshLow,
uint16_t ThreshHigh, uint8_t Window,
uint8_t IntOnNoTarget)
{
VL53L1X_ERROR status = 0;
uint8_t Temp = 0;
status = VL53L1_RdByte(dev, SYSTEM__INTERRUPT_CONFIG_GPIO, &Temp);
Temp = Temp & 0x47;
if (IntOnNoTarget == 0) {
status = VL53L1_WrByte(dev, SYSTEM__INTERRUPT_CONFIG_GPIO,
(Temp | (Window & 0x07)));
} else {
status = VL53L1_WrByte(dev, SYSTEM__INTERRUPT_CONFIG_GPIO,
((Temp | (Window & 0x07)) | 0x40));
}
status = VL53L1_WrWord(dev, SYSTEM__THRESH_HIGH, ThreshHigh);
status = VL53L1_WrWord(dev, SYSTEM__THRESH_LOW, ThreshLow);
return status;
}
VL53L1X_ERROR VL53L1X_GetDistanceThresholdWindow(uint16_t dev, uint16_t *window)
{
VL53L1X_ERROR status = 0;
uint8_t tmp;
status = VL53L1_RdByte(dev,SYSTEM__INTERRUPT_CONFIG_GPIO, &tmp);
*window = (uint16_t)(tmp & 0x7);
return status;
}
VL53L1X_ERROR VL53L1X_GetDistanceThresholdLow(uint16_t dev, uint16_t *low)
{
VL53L1X_ERROR status = 0;
uint16_t tmp;
status = VL53L1_RdWord(dev,SYSTEM__THRESH_LOW, &tmp);
*low = tmp;
return status;
}
VL53L1X_ERROR VL53L1X_GetDistanceThresholdHigh(uint16_t dev, uint16_t *high)
{
VL53L1X_ERROR status = 0;
uint16_t tmp;
status = VL53L1_RdWord(dev,SYSTEM__THRESH_HIGH, &tmp);
*high = tmp;
return status;
}
VL53L1X_ERROR VL53L1X_SetROICenter(uint16_t dev, uint8_t ROICenter)
{
VL53L1X_ERROR status = 0;
status = VL53L1_WrByte(dev, ROI_CONFIG__USER_ROI_CENTRE_SPAD, ROICenter);
return status;
}
VL53L1X_ERROR VL53L1X_GetROICenter(uint16_t dev, uint8_t *ROICenter)
{
VL53L1X_ERROR status = 0;
uint8_t tmp;
status = VL53L1_RdByte(dev, ROI_CONFIG__USER_ROI_CENTRE_SPAD, &tmp);
*ROICenter = tmp;
return status;
}
VL53L1X_ERROR VL53L1X_SetROI(uint16_t dev, uint16_t X, uint16_t Y)
{
uint8_t OpticalCenter;
VL53L1X_ERROR status = 0;
status =VL53L1_RdByte(dev, VL53L1_ROI_CONFIG__MODE_ROI_CENTRE_SPAD, &OpticalCenter);
if (X > 16)
X = 16;
if (Y > 16)
Y = 16;
if (X > 10 || Y > 10){
OpticalCenter = 199;
}
status = VL53L1_WrByte(dev, ROI_CONFIG__USER_ROI_CENTRE_SPAD, OpticalCenter);
status = VL53L1_WrByte(dev, ROI_CONFIG__USER_ROI_REQUESTED_GLOBAL_XY_SIZE,
(Y - 1) << 4 | (X - 1));
return status;
}
VL53L1X_ERROR VL53L1X_GetROI_XY(uint16_t dev, uint16_t *ROI_X, uint16_t *ROI_Y)
{
VL53L1X_ERROR status = 0;
uint8_t tmp;
status = VL53L1_RdByte(dev,ROI_CONFIG__USER_ROI_REQUESTED_GLOBAL_XY_SIZE, &tmp);
*ROI_X = ((uint16_t)tmp & 0x0F) + 1;
*ROI_Y = (((uint16_t)tmp & 0xF0) >> 4) + 1;
return status;
}
VL53L1X_ERROR VL53L1X_SetSignalThreshold(uint16_t dev, uint16_t Signal)
{
VL53L1X_ERROR status = 0;
VL53L1_WrWord(dev,RANGE_CONFIG__MIN_COUNT_RATE_RTN_LIMIT_MCPS,Signal>>3);
return status;
}
VL53L1X_ERROR VL53L1X_GetSignalThreshold(uint16_t dev, uint16_t *signal)
{
VL53L1X_ERROR status = 0;
uint16_t tmp;
status = VL53L1_RdWord(dev,
RANGE_CONFIG__MIN_COUNT_RATE_RTN_LIMIT_MCPS, &tmp);
*signal = tmp <<3;
return status;
}
VL53L1X_ERROR VL53L1X_SetSigmaThreshold(uint16_t dev, uint16_t Sigma)
{
VL53L1X_ERROR status = 0;
if(Sigma>(0xFFFF>>2)){
return 1;
}
/* 16 bits register 14.2 format */
status = VL53L1_WrWord(dev,RANGE_CONFIG__SIGMA_THRESH,Sigma<<2);
return status;
}
VL53L1X_ERROR VL53L1X_GetSigmaThreshold(uint16_t dev, uint16_t *sigma)
{
VL53L1X_ERROR status = 0;
uint16_t tmp;
status = VL53L1_RdWord(dev,RANGE_CONFIG__SIGMA_THRESH, &tmp);
*sigma = tmp >> 2;
return status;
}
VL53L1X_ERROR VL53L1X_StartTemperatureUpdate(uint16_t dev)
{
VL53L1X_ERROR status = 0;
uint8_t tmp=0;
status = VL53L1_WrByte(dev,VL53L1_VHV_CONFIG__TIMEOUT_MACROP_LOOP_BOUND,0x81); /* full VHV */
status = VL53L1_WrByte(dev,0x0B,0x92);
status = VL53L1X_StartRanging(dev);
while(tmp==0){
status = VL53L1X_CheckForDataReady(dev, &tmp);
}
tmp = 0;
status = VL53L1X_ClearInterrupt(dev);
status = VL53L1X_StopRanging(dev);
status = VL53L1_WrByte(dev, VL53L1_VHV_CONFIG__TIMEOUT_MACROP_LOOP_BOUND, 0x09); /* two bounds VHV */
status = VL53L1_WrByte(dev, 0x0B, 0); /* start VHV from the previous temperature */
return status;
}

393
vl53lx_uld/VL53L1X_api.h Normal file
View File

@ -0,0 +1,393 @@
/*
* Copyright (c) 2017, STMicroelectronics - All Rights Reserved
*
* This file : part of VL53L1 Core and : dual licensed,
* either 'STMicroelectronics
* Proprietary license'
* or 'BSD 3-clause "New" or "Revised" License' , at your option.
*
********************************************************************************
*
* 'STMicroelectronics Proprietary license'
*
********************************************************************************
*
* License terms: STMicroelectronics Proprietary in accordance with licensing
* terms at www.st.com/sla0081
*
* STMicroelectronics confidential
* Reproduction and Communication of this document : strictly prohibited unless
* specifically authorized in writing by STMicroelectronics.
*
*
********************************************************************************
*
* Alternatively, VL53L1 Core may be distributed under the terms of
* 'BSD 3-clause "New" or "Revised" License', in which case the following
* provisions apply instead of the ones mentioned above :
*
********************************************************************************
*
* License terms: BSD 3-clause "New" or "Revised" License.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
********************************************************************************
*
*/
/**
* @file vl53l1x_api.h
* @brief Functions definition
*/
#ifndef _API_H_
#define _API_H_
#include "vl53l1_platform.h"
#define VL53L1X_IMPLEMENTATION_VER_MAJOR 3
#define VL53L1X_IMPLEMENTATION_VER_MINOR 2
#define VL53L1X_IMPLEMENTATION_VER_SUB 0
#define VL53L1X_IMPLEMENTATION_VER_REVISION 0000
typedef int8_t VL53L1X_ERROR;
#define SOFT_RESET 0x0000
#define VL53L1_I2C_SLAVE__DEVICE_ADDRESS 0x0001
#define VL53L1_VHV_CONFIG__TIMEOUT_MACROP_LOOP_BOUND 0x0008
#define ALGO__CROSSTALK_COMPENSATION_PLANE_OFFSET_KCPS 0x0016
#define ALGO__CROSSTALK_COMPENSATION_X_PLANE_GRADIENT_KCPS 0x0018
#define ALGO__CROSSTALK_COMPENSATION_Y_PLANE_GRADIENT_KCPS 0x001A
#define ALGO__PART_TO_PART_RANGE_OFFSET_MM 0x001E
#define MM_CONFIG__INNER_OFFSET_MM 0x0020
#define MM_CONFIG__OUTER_OFFSET_MM 0x0022
#define GPIO_HV_MUX__CTRL 0x0030
#define GPIO__TIO_HV_STATUS 0x0031
#define SYSTEM__INTERRUPT_CONFIG_GPIO 0x0046
#define PHASECAL_CONFIG__TIMEOUT_MACROP 0x004B
#define RANGE_CONFIG__TIMEOUT_MACROP_A_HI 0x005E
#define RANGE_CONFIG__VCSEL_PERIOD_A 0x0060
#define RANGE_CONFIG__VCSEL_PERIOD_B 0x0063
#define RANGE_CONFIG__TIMEOUT_MACROP_B_HI 0x0061
#define RANGE_CONFIG__TIMEOUT_MACROP_B_LO 0x0062
#define RANGE_CONFIG__SIGMA_THRESH 0x0064
#define RANGE_CONFIG__MIN_COUNT_RATE_RTN_LIMIT_MCPS 0x0066
#define RANGE_CONFIG__VALID_PHASE_HIGH 0x0069
#define VL53L1_SYSTEM__INTERMEASUREMENT_PERIOD 0x006C
#define SYSTEM__THRESH_HIGH 0x0072
#define SYSTEM__THRESH_LOW 0x0074
#define SD_CONFIG__WOI_SD0 0x0078
#define SD_CONFIG__INITIAL_PHASE_SD0 0x007A
#define ROI_CONFIG__USER_ROI_CENTRE_SPAD 0x007F
#define ROI_CONFIG__USER_ROI_REQUESTED_GLOBAL_XY_SIZE 0x0080
#define SYSTEM__SEQUENCE_CONFIG 0x0081
#define VL53L1_SYSTEM__GROUPED_PARAMETER_HOLD 0x0082
#define SYSTEM__INTERRUPT_CLEAR 0x0086
#define SYSTEM__MODE_START 0x0087
#define VL53L1_RESULT__RANGE_STATUS 0x0089
#define VL53L1_RESULT__DSS_ACTUAL_EFFECTIVE_SPADS_SD0 0x008C
#define RESULT__AMBIENT_COUNT_RATE_MCPS_SD 0x0090
#define VL53L1_RESULT__FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD0 0x0096
#define VL53L1_RESULT__PEAK_SIGNAL_COUNT_RATE_CROSSTALK_CORRECTED_MCPS_SD0 0x0098
#define VL53L1_RESULT__OSC_CALIBRATE_VAL 0x00DE
#define VL53L1_FIRMWARE__SYSTEM_STATUS 0x00E5
#define VL53L1_IDENTIFICATION__MODEL_ID 0x010F
#define VL53L1_ROI_CONFIG__MODE_ROI_CENTRE_SPAD 0x013E
/****************************************
* PRIVATE define do not edit
****************************************/
/**
* @brief defines SW Version
*/
typedef struct {
uint8_t major; /*!< major number */
uint8_t minor; /*!< minor number */
uint8_t build; /*!< build number */
uint32_t revision; /*!< revision number */
} VL53L1X_Version_t;
/**
* @brief defines packed reading results type
*/
typedef struct {
uint8_t Status; /*!< ResultStatus */
uint16_t Distance; /*!< ResultDistance */
uint16_t Ambient; /*!< ResultAmbient */
uint16_t SigPerSPAD;/*!< ResultSignalPerSPAD */
uint16_t NumSPADs; /*!< ResultNumSPADs */
} VL53L1X_Result_t;
/**
* @brief This function returns the SW driver version
*/
VL53L1X_ERROR VL53L1X_GetSWVersion(VL53L1X_Version_t *pVersion);
/**
* @brief This function sets the sensor I2C address used in case multiple devices application, default address 0x52
*/
VL53L1X_ERROR VL53L1X_SetI2CAddress(uint16_t, uint8_t new_address);
/**
* @brief This function loads the 135 bytes default values to initialize the sensor.
* @param dev Device address
* @return 0:success, != 0:failed
*/
VL53L1X_ERROR VL53L1X_SensorInit(uint16_t dev);
/**
* @brief This function clears the interrupt, to be called after a ranging data reading
* to arm the interrupt for the next data ready event.
*/
VL53L1X_ERROR VL53L1X_ClearInterrupt(uint16_t dev);
/**
* @brief This function programs the interrupt polarity\n
* 1=active high (default), 0=active low
*/
VL53L1X_ERROR VL53L1X_SetInterruptPolarity(uint16_t dev, uint8_t IntPol);
/**
* @brief This function returns the current interrupt polarity\n
* 1=active high (default), 0=active low
*/
VL53L1X_ERROR VL53L1X_GetInterruptPolarity(uint16_t dev, uint8_t *pIntPol);
/**
* @brief This function starts the ranging distance operation\n
* The ranging operation is continuous. The clear interrupt has to be done after each get data to allow the interrupt to raise when the next data is ready\n
* 1=active high (default), 0=active low, use SetInterruptPolarity() to change the interrupt polarity if required.
*/
VL53L1X_ERROR VL53L1X_StartRanging(uint16_t dev);
/**
* @brief This function stops the ranging.
*/
VL53L1X_ERROR VL53L1X_StopRanging(uint16_t dev);
/**
* @brief This function checks if the new ranging data is available by polling the dedicated register.
* @param : isDataReady==0 -> not ready; isDataReady==1 -> ready
*/
VL53L1X_ERROR VL53L1X_CheckForDataReady(uint16_t dev, uint8_t *isDataReady);
/**
* @brief This function programs the timing budget in ms.
* Predefined values = 15, 20, 33, 50, 100(default), 200, 500.
*/
VL53L1X_ERROR VL53L1X_SetTimingBudgetInMs(uint16_t dev, uint16_t TimingBudgetInMs);
/**
* @brief This function returns the current timing budget in ms.
*/
VL53L1X_ERROR VL53L1X_GetTimingBudgetInMs(uint16_t dev, uint16_t *pTimingBudgetInMs);
/**
* @brief This function programs the distance mode (1=short, 2=long(default)).
* Short mode max distance is limited to 1.3 m but better ambient immunity.\n
* Long mode can range up to 4 m in the dark with 200 ms timing budget.
*/
VL53L1X_ERROR VL53L1X_SetDistanceMode(uint16_t dev, uint16_t DistanceMode);
/**
* @brief This function returns the current distance mode (1=short, 2=long).
*/
VL53L1X_ERROR VL53L1X_GetDistanceMode(uint16_t dev, uint16_t *pDistanceMode);
/**
* @brief This function programs the Intermeasurement period in ms\n
* Intermeasurement period must be >/= timing budget. This condition is not checked by the API,
* the customer has the duty to check the condition. Default = 100 ms
*/
VL53L1X_ERROR VL53L1X_SetInterMeasurementInMs(uint16_t dev,
uint16_t InterMeasurementInMs);
/**
* @brief This function returns the Intermeasurement period in ms.
*/
VL53L1X_ERROR VL53L1X_GetInterMeasurementInMs(uint16_t dev, uint16_t * pIM);
/**
* @brief This function returns the boot state of the device (1:booted, 0:not booted)
*/
VL53L1X_ERROR VL53L1X_BootState(uint16_t dev, uint8_t *state);
/**
* @brief This function returns the sensor id, sensor Id must be 0xEEAC
*/
VL53L1X_ERROR VL53L1X_GetSensorId(uint16_t dev, uint16_t *id);
/**
* @brief This function returns the distance measured by the sensor in mm
*/
VL53L1X_ERROR VL53L1X_GetDistance(uint16_t dev, uint16_t *distance);
/**
* @brief This function returns the returned signal per SPAD in kcps/SPAD.
* With kcps stands for Kilo Count Per Second
*/
VL53L1X_ERROR VL53L1X_GetSignalPerSpad(uint16_t dev, uint16_t *signalPerSp);
/**
* @brief This function returns the ambient per SPAD in kcps/SPAD
*/
VL53L1X_ERROR VL53L1X_GetAmbientPerSpad(uint16_t dev, uint16_t *amb);
/**
* @brief This function returns the returned signal in kcps.
*/
VL53L1X_ERROR VL53L1X_GetSignalRate(uint16_t dev, uint16_t *signalRate);
/**
* @brief This function returns the current number of enabled SPADs
*/
VL53L1X_ERROR VL53L1X_GetSpadNb(uint16_t dev, uint16_t *spNb);
/**
* @brief This function returns the ambient rate in kcps
*/
VL53L1X_ERROR VL53L1X_GetAmbientRate(uint16_t dev, uint16_t *ambRate);
/**
* @brief This function returns the ranging status error \n
* (0:no error, 1:sigma failed, 2:signal failed, ..., 7:wrap-around)
*/
VL53L1X_ERROR VL53L1X_GetRangeStatus(uint16_t dev, uint8_t *rangeStatus);
/**
* @brief This function returns measurements and the range status in a single read access
*/
VL53L1X_ERROR VL53L1X_GetResult(uint16_t dev, VL53L1X_Result_t *pResult);
/**
* @brief This function programs the offset correction in mm
* @param OffsetValue:the offset correction value to program in mm
*/
VL53L1X_ERROR VL53L1X_SetOffset(uint16_t dev, int16_t OffsetValue);
/**
* @brief This function returns the programmed offset correction value in mm
*/
VL53L1X_ERROR VL53L1X_GetOffset(uint16_t dev, int16_t *Offset);
/**
* @brief This function programs the xtalk correction value in cps (Count Per Second).\n
* This is the number of photons reflected back from the cover glass in cps.
*/
VL53L1X_ERROR VL53L1X_SetXtalk(uint16_t dev, uint16_t XtalkValue);
/**
* @brief This function returns the current programmed xtalk correction value in cps
*/
VL53L1X_ERROR VL53L1X_GetXtalk(uint16_t dev, uint16_t *Xtalk);
/**
* @brief This function programs the threshold detection mode\n
* Example:\n
* VL53L1X_SetDistanceThreshold(dev,100,300,0,1): Below 100 \n
* VL53L1X_SetDistanceThreshold(dev,100,300,1,1): Above 300 \n
* VL53L1X_SetDistanceThreshold(dev,100,300,2,1): Out of window \n
* VL53L1X_SetDistanceThreshold(dev,100,300,3,1): In window \n
* @param dev : device address
* @param ThreshLow(in mm) : the threshold under which one the device raises an interrupt if Window = 0
* @param ThreshHigh(in mm) : the threshold above which one the device raises an interrupt if Window = 1
* @param Window detection mode : 0=below, 1=above, 2=out, 3=in
* @param IntOnNoTarget = 1 (No longer used - just use 1)
*/
VL53L1X_ERROR VL53L1X_SetDistanceThreshold(uint16_t dev, uint16_t ThreshLow,
uint16_t ThreshHigh, uint8_t Window,
uint8_t IntOnNoTarget);
/**
* @brief This function returns the window detection mode (0=below; 1=above; 2=out; 3=in)
*/
VL53L1X_ERROR VL53L1X_GetDistanceThresholdWindow(uint16_t dev, uint16_t *window);
/**
* @brief This function returns the low threshold in mm
*/
VL53L1X_ERROR VL53L1X_GetDistanceThresholdLow(uint16_t dev, uint16_t *low);
/**
* @brief This function returns the high threshold in mm
*/
VL53L1X_ERROR VL53L1X_GetDistanceThresholdHigh(uint16_t dev, uint16_t *high);
/**
* @brief This function programs the ROI (Region of Interest)\n
* The ROI position is centered, only the ROI size can be reprogrammed.\n
* The smallest acceptable ROI size = 4\n
* @param X:ROI Width; Y=ROI Height
*/
VL53L1X_ERROR VL53L1X_SetROI(uint16_t dev, uint16_t X, uint16_t Y);
/**
*@brief This function returns width X and height Y
*/
VL53L1X_ERROR VL53L1X_GetROI_XY(uint16_t dev, uint16_t *ROI_X, uint16_t *ROI_Y);
/**
*@brief This function programs the new user ROI center, please to be aware that there is no check in this function.
*if the ROI center vs ROI size is out of border the ranging function return error #13
*/
VL53L1X_ERROR VL53L1X_SetROICenter(uint16_t dev, uint8_t ROICenter);
/**
*@brief This function returns the current user ROI center
*/
VL53L1X_ERROR VL53L1X_GetROICenter(uint16_t dev, uint8_t *ROICenter);
/**
* @brief This function programs a new signal threshold in kcps (default=1024 kcps\n
*/
VL53L1X_ERROR VL53L1X_SetSignalThreshold(uint16_t dev, uint16_t signal);
/**
* @brief This function returns the current signal threshold in kcps
*/
VL53L1X_ERROR VL53L1X_GetSignalThreshold(uint16_t dev, uint16_t *signal);
/**
* @brief This function programs a new sigma threshold in mm (default=15 mm)
*/
VL53L1X_ERROR VL53L1X_SetSigmaThreshold(uint16_t dev, uint16_t sigma);
/**
* @brief This function returns the current sigma threshold in mm
*/
VL53L1X_ERROR VL53L1X_GetSigmaThreshold(uint16_t dev, uint16_t *signal);
/**
* @brief This function performs the temperature calibration.
* It is recommended to call this function any time the temperature might have changed by more than 8 deg C
* without sensor ranging activity for an extended period.
*/
VL53L1X_ERROR VL53L1X_StartTemperatureUpdate(uint16_t dev);
#endif

View File

@ -0,0 +1,136 @@
/*
* Copyright (c) 2017, STMicroelectronics - All Rights Reserved
*
* This file : part of VL53L1 Core and : dual licensed,
* either 'STMicroelectronics
* Proprietary license'
* or 'BSD 3-clause "New" or "Revised" License' , at your option.
*
********************************************************************************
*
* 'STMicroelectronics Proprietary license'
*
********************************************************************************
*
* License terms: STMicroelectronics Proprietary in accordance with licensing
* terms at www.st.com/sla0081
*
* STMicroelectronics confidential
* Reproduction and Communication of this document : strictly prohibited unless
* specifically authorized in writing by STMicroelectronics.
*
*
********************************************************************************
*
* Alternatively, VL53L1 Core may be distributed under the terms of
* 'BSD 3-clause "New" or "Revised" License', in which case the following
* provisions apply instead of the ones mentioned above :
*
********************************************************************************
*
* License terms: BSD 3-clause "New" or "Revised" License.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
********************************************************************************
*
*/
/**
* @file vl53l1x_calibration.c
* @brief Calibration functions implementation
*/
#include "VL53L1X_api.h"
#include "VL53L1X_calibration.h"
#define ALGO__PART_TO_PART_RANGE_OFFSET_MM 0x001E
#define MM_CONFIG__INNER_OFFSET_MM 0x0020
#define MM_CONFIG__OUTER_OFFSET_MM 0x0022
int8_t VL53L1X_CalibrateOffset(uint16_t dev, uint16_t TargetDistInMm, int16_t *offset)
{
uint8_t i, tmp;
int16_t AverageDistance = 0;
uint16_t distance;
VL53L1X_ERROR status = 0;
status = VL53L1_WrWord(dev, ALGO__PART_TO_PART_RANGE_OFFSET_MM, 0x0);
status = VL53L1_WrWord(dev, MM_CONFIG__INNER_OFFSET_MM, 0x0);
status = VL53L1_WrWord(dev, MM_CONFIG__OUTER_OFFSET_MM, 0x0);
status = VL53L1X_StartRanging(dev); /* Enable VL53L1X sensor */
for (i = 0; i < 50; i++) {
tmp = 0;
while (tmp == 0){
status = VL53L1X_CheckForDataReady(dev, &tmp);
}
status = VL53L1X_GetDistance(dev, &distance);
status = VL53L1X_ClearInterrupt(dev);
AverageDistance = AverageDistance + distance;
}
status = VL53L1X_StopRanging(dev);
AverageDistance = AverageDistance / 50;
*offset = TargetDistInMm - AverageDistance;
status = VL53L1_WrWord(dev, ALGO__PART_TO_PART_RANGE_OFFSET_MM, *offset*4);
return status;
}
int8_t VL53L1X_CalibrateXtalk(uint16_t dev, uint16_t TargetDistInMm, uint16_t *xtalk)
{
uint8_t i, tmp;
float AverageSignalRate = 0;
float AverageDistance = 0;
float AverageSpadNb = 0;
uint16_t distance = 0, spadNum;
uint16_t sr;
VL53L1X_ERROR status = 0;
uint32_t calXtalk;
status = VL53L1_WrWord(dev, 0x0016,0);
status = VL53L1X_StartRanging(dev);
for (i = 0; i < 50; i++) {
tmp = 0;
while (tmp == 0){
status = VL53L1X_CheckForDataReady(dev, &tmp);
}
status= VL53L1X_GetSignalRate(dev, &sr);
status= VL53L1X_GetDistance(dev, &distance);
status = VL53L1X_ClearInterrupt(dev);
AverageDistance = AverageDistance + distance;
status = VL53L1X_GetSpadNb(dev, &spadNum);
AverageSpadNb = AverageSpadNb + spadNum;
AverageSignalRate =
AverageSignalRate + sr;
}
status = VL53L1X_StopRanging(dev);
AverageDistance = AverageDistance / 50;
AverageSpadNb = AverageSpadNb / 50;
AverageSignalRate = AverageSignalRate / 50;
/* Calculate Xtalk value */
calXtalk = (uint16_t)(512*(AverageSignalRate*(1-(AverageDistance/TargetDistInMm)))/AverageSpadNb);
*xtalk = (uint16_t)(calXtalk*1000)>>9;
status = VL53L1_WrWord(dev, 0x0016, calXtalk);
return status;
}

View File

@ -0,0 +1,93 @@
/*
* Copyright (c) 2017, STMicroelectronics - All Rights Reserved
*
* This file : part of VL53L1 Core and : dual licensed,
* either 'STMicroelectronics
* Proprietary license'
* or 'BSD 3-clause "New" or "Revised" License' , at your option.
*
********************************************************************************
*
* 'STMicroelectronics Proprietary license'
*
********************************************************************************
*
* License terms: STMicroelectronics Proprietary in accordance with licensing
* terms at www.st.com/sla0081
*
* STMicroelectronics confidential
* Reproduction and Communication of this document : strictly prohibited unless
* specifically authorized in writing by STMicroelectronics.
*
*
********************************************************************************
*
* Alternatively, VL53L1 Core may be distributed under the terms of
* 'BSD 3-clause "New" or "Revised" License', in which case the following
* provisions apply instead of the ones mentioned above :
*
********************************************************************************
*
* License terms: BSD 3-clause "New" or "Revised" License.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
********************************************************************************
*
*/
/**
* @file vl53l1x_calibration.h
* @brief Calibration Functions definition
*/
#ifndef _CALIBRATION_H_
#define _CALIBRATION_H_
/**
* @brief This function performs the offset calibration.\n
* The function returns the offset value found and programs the offset compensation into the device.
* @param TargetDistInMm target distance in mm, ST recommended 100 mm
* Target reflectance = grey17%
* @return 0:success, !=0: failed
* @return offset pointer contains the offset found in mm
*/
int8_t VL53L1X_CalibrateOffset(uint16_t dev, uint16_t TargetDistInMm, int16_t *offset);
/**
* @brief This function performs the xtalk calibration.\n
* The function returns the xtalk value found and programs the xtalk compensation to the device
* @param TargetDistInMm target distance in mm\n
* The target distance : the distance where the sensor start to "under range"\n
* due to the influence of the photons reflected back from the cover glass becoming strong\n
* It's also called inflection point\n
* Target reflectance = grey 17%
* @return 0: success, !=0: failed
* @return xtalk pointer contains the xtalk value found in cps (number of photons in count per second)
*/
int8_t VL53L1X_CalibrateXtalk(uint16_t dev, uint16_t TargetDistInMm, uint16_t *xtalk);
#endif

View File

@ -0,0 +1,608 @@
/**
* @file X-NUCLEO-53L1A1.c
*
* implement X-NUCLEO-53L1A1 Nucleo BSP
*/
#include "main.h"
#include <string.h>
#include "X-NUCLEO-53L1A1.h"
#include "stm32wlxx_hal.h"
#ifndef HAL_I2C_MODULE_ENABLED
#define HAL_I2C_MODULE_ENABLED
#pragma message("hal conf should enable i2c")
#endif
/* when not customized by application define dummy one */
#ifndef XNUCLEO53L1A1_GetI2cBus
/**
* macro that can be overloaded by user to enforce i2c sharing in RTOS context
*/
#define XNUCLEO53L1A1_GetI2cBus(...) (void)0
#endif
#ifndef XNUCLEO53L1A1_PutI2cBus
/** macro can be overloaded by user to enforce i2c sharing in RTOS context
*/
# define XNUCLEO53L1A1_PutI2cBus(...) (void)0
#endif
/**
* Expander 0 i2c address[7..0] format
*/
#define I2cExpAddr0 ((int)(0x43*2))
/**
* Expander 1 i2c address[7..0] format
*/
#define I2cExpAddr1 ((int)(0x42*2))
/** @} XNUCLEO53L1A1_I2CExpanders*/
/**
* GPIO monitor pin state register
* 16 bit register LSB at lowest offset (little endian)
*/
#define GPMR 0x10
/**
* STMPE1600 GPIO set pin state register
* 16 bit register LSB at lowest offset (little endian)
*/
#define GPSR 0x12
/**
* STMPE1600 GPIO set pin direction register
* 16 bit register LSB at lowest offset
*/
#define GPDR 0x14
/** @} */ /* defgroup XNUCLEO53L1A1_Board */
/****************************************************
*@defgroup XNUCLEO53L1A1_globals
*@{
*/
/**
* i2c handle to be use of all i2c access
* end user shall provide it to
* can be @a XNUCLEO53L1A1_I2C1Configure() @sa XNUCLEO53L1A1_usage
* @warning do not use any XNUCLEO53L1A1_xxx prior to a first init with valid i2c handle
*/
I2C_HandleTypeDef XNUCLEO53L1A1_hi2c;
/**
* cache the full set of expanded GPIO values to avoid i2c reading
*/
static union CurIOVal_u {
uint8_t bytes[4]; /*!< 4 bytes array i/o view */
uint32_t u32; /*!< single dword i/o view */
}
/** cache the extended IO values */
CurIOVal;
/**
* lookup table for for digit to bit position in @a CurIOVal u32
*/
static int DisplayBitPos[4]={0, 7, 16, 16+7};
/** @} XNUCLEO53L1A1_globals*/
/* Forward definition of private function */
static int _ExpanderRd(int I2cExpAddr, int index, uint8_t *data, int n_data);
static int _ExpanderWR(int I2cExpAddr, int index, uint8_t *data, int n_data);
static int _ExpandersSetAllIO(void);
/**
* Expansion board i2c bus recovery
*
* We may get reset in middle of an i2c access (h/w reset button, debug or f/w load)
* hence some agent on bus may be in middle of a transaction and can create issue or even prevent starting (SDA is low)
* this routine does use gpio to manipulate and recover i2c bus line in all cases.
*/
static void _I2cFailRecover(){
GPIO_InitTypeDef GPIO_InitStruct;
int i, nRetry=0;
// We can't assume bus state based on SDA and SCL state (we may be in a data or NAK bit so SCL=SDA=1)
// by setting SDA high and toggling SCL at least 10 time we ensure whatever agent and state
// all agent should end up seeing a "stop" and bus get back to an known idle i2c bus state
// Enable I/O
__GPIOA_CLK_ENABLE();
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_11, GPIO_PIN_SET);
GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_11;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
//TODO we could do this faster by not using HAL delay 1ms for clk timing
do{
for( i=0; i<10; i++){
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12, GPIO_PIN_RESET);
HAL_Delay(1);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12, GPIO_PIN_SET);
HAL_Delay(1);
}
// if( HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_9) == 0 ){
// static int RetryRecover;
// RetryRecover++;
// }
}while(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_11) == 0 && nRetry++<7);
if( HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_11) == 0 ){
__GPIOB_CLK_ENABLE();
//We are still in bad i2c state warm user by blinking led but stay here
GPIO_InitStruct.Pin = LED1_Pin ;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(LED3_GPIO_Port, &GPIO_InitStruct);
do{
HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_Pin, GPIO_PIN_SET);
HAL_Delay(33);
HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_Pin, GPIO_PIN_RESET);
HAL_Delay(33);
HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_Pin, GPIO_PIN_SET);
HAL_Delay(33);
HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_Pin, GPIO_PIN_RESET);
HAL_Delay(33*20);
}while(1);
}
}
int XNUCLEO53L1A1_I2C2Configure() {
int status;
GPIO_InitTypeDef GPIO_InitStruct;
_I2cFailRecover();
/* Peripheral clock enable */
__GPIOA_CLK_ENABLE();
__I2C2_CLK_ENABLE();
/**I2C1 GPIO Configuration\n
PB8 ------> I2C1_SCL\n
PB9 ------> I2C1_SDA
*/
GPIO_InitStruct.Pin = GPIO_PIN_12 | GPIO_PIN_11;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF4_I2C2;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
XNUCLEO53L1A1_hi2c.Instance = I2C2;
//XNUCLEO53L1A1_hi2c.Init.Timing = 0x00300F38; /* set 400KHz fast mode i2c*/
XNUCLEO53L1A1_hi2c.Init.Timing = 0x2010091A; //0x2010091A = 400K Fast Mode, 0x20303E5D, 100K Standard mode, 0x20000209 Fast Mode Plus, 1Mbps
XNUCLEO53L1A1_hi2c.Init.OwnAddress1 = 0;
XNUCLEO53L1A1_hi2c.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
XNUCLEO53L1A1_hi2c.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;
XNUCLEO53L1A1_hi2c.Init.OwnAddress2 = 0;
XNUCLEO53L1A1_hi2c.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;
XNUCLEO53L1A1_hi2c.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;
status = HAL_I2C_Init(&XNUCLEO53L1A1_hi2c);
return status;
}
int XNUCLEO53L1A1_SetIntrStateId(int EnableIntr, int DevNo){
int status;
IRQn_Type IntrNo;
int IntrPin;
switch( DevNo ){
case XNUCLEO53L1A1_DEV_CENTER :
case 'c' :
IntrNo = VL53L1A1_GPIO1_C_INTx;
IntrPin= VL53L1A1_GPIO1_C_GPIO_PIN;
status = 0;
break;
case XNUCLEO53L1A1_DEV_LEFT :
case 'l' :
break;
case 'r' :
case XNUCLEO53L1A1_DEV_RIGHT :
break;
default:
XNUCLEO53L1A1_ErrLog("Invalid DevNo %d",DevNo);
status = -1;
goto done;
}
if( EnableIntr ){
__HAL_GPIO_EXTI_CLEAR_IT(IntrPin);
NVIC_ClearPendingIRQ(IntrNo);
HAL_NVIC_EnableIRQ(IntrNo);
/**
* @note When enabling interrupt end user shall check actual state of the line and soft trigger event if active
* Alternatively user can use API and device feature to clear device Interrupt status to possibly generates a new edge.
* on shared pin configuration this must be repeated for all device.
* The same shall be done after clearing a condition in device and interrupt remain active.
*/
}
else{
HAL_NVIC_DisableIRQ(IntrNo);
__HAL_GPIO_EXTI_CLEAR_IT(IntrPin);
NVIC_ClearPendingIRQ(IntrNo);
}
done:
return status;
}
int XNUCLEO53L1A1_Init(void) {
int status;
// uint8_t ExpanderData[2];
// XNUCLEO53L1A1_USART2_UART_Init();
status = XNUCLEO53L1A1_I2C2Configure();
return status;
}
int XNUCLEO53L1A1_GetPB1(int *state) {
int status;
uint8_t PortValue;
status= _ExpanderRd(I2cExpAddr1, GPMR+1, &PortValue,1);
if( status == 0){
if( PortValue&=0x40 )
PortValue=1;
else
PortValue=0;
}
else{
XNUCLEO53L1A1_ErrLog("i/o error");
}
*state = PortValue;
return status;
}
int XNUCLEO53L1A1_ResetId(int DevNo, int state) {
int status;
switch( DevNo ){
case XNUCLEO53L1A1_DEV_CENTER :
case 'c' :
CurIOVal.bytes[3]&=~0x80; /* bit 15 expender 1 => byte #3 */
if( state )
CurIOVal.bytes[3]|=0x80; /* bit 15 expender 1 => byte #3 */
status= _ExpanderWR(I2cExpAddr1, GPSR+1, &CurIOVal.bytes[3], 1);
break;
case XNUCLEO53L1A1_DEV_LEFT :
case 'l' :
CurIOVal.bytes[1]&=~0x40; /* bit 14 expender 0 => byte #1*/
if( state )
CurIOVal.bytes[1]|=0x40; /* bit 14 expender 0 => byte #1*/
status= _ExpanderWR(I2cExpAddr0, GPSR+1, &CurIOVal.bytes[1], 1);
break;
case 'r' :
case XNUCLEO53L1A1_DEV_RIGHT :
CurIOVal.bytes[1]&=~0x80; /* bit 15 expender 0 => byte #1 */
if( state )
CurIOVal.bytes[1]|=0x80; /* bit 15 expender 0 => byte #1*/
status= _ExpanderWR(I2cExpAddr0, GPSR+1, &CurIOVal.bytes[1], 1);
break;
default:
XNUCLEO53L1A1_ErrLog("Invalid DevNo %d",DevNo);
status = -1;
goto done;
}
//error with valid id
if( status ){
XNUCLEO53L1A1_ErrLog("expander i/o error for DevNo %d state %d ",DevNo, state);
}
done:
return status;
}
void VL53L1A1_EXTI_IOConfigure(int DevNo, int IntPriority, int SubPriority){
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
GPIO_InitStruct.Pull = VL53L1A1_INTR_PIN_PUPD;
switch (DevNo ) {
case XNUCLEO53L1A1_DEV_CENTER:
case 'c':
VL53L1A1_GPIO1_C_CLK_ENABLE();
/*Configure GPIO pin : PA4 */
GPIO_InitStruct.Pin = VL53L1A1_GPIO1_C_GPIO_PIN;
XNUCLEO53L1A1_SetIntrStateId(1,XNUCLEO53L1A1_DEV_CENTER);
HAL_GPIO_Init(VL53L1A1_GPIO1_C_GPIO_PORT, &GPIO_InitStruct);
HAL_NVIC_SetPriority((IRQn_Type)VL53L1A1_GPIO1_C_GPIO_PIN, IntPriority, SubPriority);
break;
#if VL53L1A1_GPIO1_SHARED == 0
case XNUCLEO53L1A1_DEV_LEFT:
case 'l':
break;
case XNUCLEO53L1A1_DEV_RIGHT:
break;
#endif
}
}
void VL53L1A1_EXTI_IOUnconfigure(int DevNo){
switch (DevNo ) {
case XNUCLEO53L1A1_DEV_CENTER:
case 'c':
//XNUCLEO53L1A1_SetIntrStateId(0,XNUCLEO53L1A1_DEV_TOP);
HAL_GPIO_DeInit(VL53L1A1_GPIO1_C_GPIO_PORT, VL53L1A1_GPIO1_C_GPIO_PIN);
__HAL_GPIO_EXTI_CLEAR_IT(VL53L1A1_GPIO1_C_GPIO_PIN);
break;
#if VL53L1A1_GPIO1_SHARED == 0
case XNUCLEO53L1A1_DEV_LEFT:
case 'l':
// XNUCLEO53L1A1_SetIntrStateId(0,XNUCLEO53L1A1_DEV_LEFT);
HAL_GPIO_DeInit(VL53L1A1_GPIO1_L_GPIO_PORT, VL53L1A1_GPIO1_L_GPIO_PIN);
__HAL_GPIO_EXTI_CLEAR_IT(VL53L1A1_GPIO1_L_GPIO_PIN);
break;
case XNUCLEO53L1A1_DEV_RIGHT:
case 'r':
HAL_GPIO_DeInit(VL53L1A1_GPIO1_R_GPIO_PORT, VL53L1A1_GPIO1_R_GPIO_PIN);
__HAL_GPIO_EXTI_CLEAR_IT(VL53L1A1_GPIO1_R_GPIO_PIN);
//XNUCLEO53L1A1_SetIntrStateId(0,XNUCLEO53L1A1_DEV_RIGHT);
break;
#endif
}
}
/**
* Set all i2c expended gpio in one go
* @return i/o operation status
*/
static int _ExpandersSetAllIO(void){
int status;
status = _ExpanderWR(I2cExpAddr0, GPSR, &CurIOVal.bytes[0], 2);
if( status ){
goto done_err;
}
status = _ExpanderWR(I2cExpAddr1, GPSR, &CurIOVal.bytes[2], 2);
done_err:
return status;
}
/**
* STMPE1600 i2c Expender register read
* @param I2cExpAddr Expender address
* @param index register index
* @param data read data buffer
* @param n_data number of byte to read
* @return of if ok else i2c I/O operation status
*/
static int _ExpanderRd(int I2cExpAddr, int index, uint8_t *data, int n_data) {
int status;
uint8_t RegAddr;
RegAddr = index;
XNUCLEO53L1A1_GetI2cBus();
do {
status = HAL_I2C_Master_Transmit(&XNUCLEO53L1A1_hi2c, I2cExpAddr, &RegAddr, 1, 100);
if (status)
break;
status = HAL_I2C_Master_Receive(&XNUCLEO53L1A1_hi2c, I2cExpAddr, data, n_data, n_data * 100);
} while (0);
XNUCLEO53L1A1_PutI2cBus();
return status;
}
/**
* STMPE1600 i2c Expender register write
* @param I2cExpAddr Expender address
* @param index register index
* @param data data buffer
* @param n_data number of byte to write
* @return of if ok else i2c I/O operation status
*/
static int _ExpanderWR(int I2cExpAddr, int index, uint8_t *data, int n_data) {
int status;
uint8_t RegAddr[0x10];
RegAddr[0] = index;
memcpy(RegAddr + 1, data, n_data);
XNUCLEO53L1A1_GetI2cBus();
status = HAL_I2C_Master_Transmit(&XNUCLEO53L1A1_hi2c, I2cExpAddr, RegAddr, n_data + 1, 100);
XNUCLEO53L1A1_PutI2cBus();
return status;
}
/**
* @defgroup XNUCLEO53L1A1_7Segment 7 segment display
*
* macro use for human readable segment building
* @code
* --s0--
* s s
* 5 1
* --s6--
* s s
* 4 2
* --s3-- . s7 (dp)
* @endcode
*
* @{
*/
/** decimal point bit mapping* */
#define DP (1<<7)
//VL6180 shield
//#define S0 (1<<0)
//#define S1 (1<<1)
//#define S2 (1<<2)
//#define S3 (1<<3)
//#define S4 (1<<4)
//#define S5 (1<<5)
//#define S6 (1<<6)
/** sgement s0 bit mapping*/
#define S0 (1<<3)
/** sgement s1 bit mapping*/
#define S1 (1<<5)
/** sgement s2 bit mapping*/
#define S2 (1<<6)
/** sgement s3 bit mapping*/
#define S3 (1<<4)
/** sgement s4 bit mapping*/
#define S4 (1<<0)
/** sgement s5 bit mapping*/
#define S5 (1<<1)
/** sgement s6 bit mapping*/
#define S6 (1<<2)
/**
* build a character by defining the non lighted segment (not one and no DP)
*
* @param ... literal sum and or combine of any macro to define any segment #S0 .. #S6
*
* example '9' is all segment on but S4
* @code
* ['9']= NOT_7_NO_DP(S4),
* @endcode
*/
#define NOT_7_NO_DP( ... ) (uint8_t) ~( __VA_ARGS__ + DP )
/**
* Ascii to 7 segment lookup table
*
* Most common character are supported and follow http://www.twyman.org.uk/Fonts/
* few extra special \@ ^~ ... etc are present for specific demo purpose
*/
static const uint8_t ascii_to_display_lut[256]={
[' ']= 0,
['-']= S6,
['_']= S3,
['=']= S3+S6,
['~']= S0+S3+S6, /* 3 h bar */
['^']= S0, /* use as top bar */
['?']= NOT_7_NO_DP(S5+S3+S2),
['*']= NOT_7_NO_DP(),
['[']= S0+S3+S4+S5,
[']']= S0+S3+S2+S1,
['@']= S0+S3,
['0']= NOT_7_NO_DP(S6),
['1']= S1+S2,
['2']= S0+S1+S6+S4+S3,
['3']= NOT_7_NO_DP(S4+S5),
['4']= S5+S1+S6+S2,
['5']= NOT_7_NO_DP(S1+S4),
['6']= NOT_7_NO_DP(S1),
['7']= S0+S1+S2,
['8']= NOT_7_NO_DP(0),
['9']= NOT_7_NO_DP(S4),
['a']= S2+ S3+ S4+ S6 ,
['b']= NOT_7_NO_DP(S0+S1),
['c']= S6+S4+S3,
['d']= NOT_7_NO_DP(S0+S5),
['e']= NOT_7_NO_DP(S2),
['f']= S6+S5+S4+S0, /* same as F */
['g']= NOT_7_NO_DP(S4), /* same as 9 */
['h']= S6+S5+S4+S2,
['i']= S4,
['j']= S1+S2+S3+S4,
['k']= S6+S5+S4+S2, /* a h */
['l']= S3+S4,
['m']= S0+S4+S2, /* same as */
['n']= S2+S4+S6,
['o']= S6+S4+S3+S2,
['p']= NOT_7_NO_DP(S3+S2), // same as P
['q']= S0+S1+S2+S5+S6,
['r']= S4+S6,
['s']= NOT_7_NO_DP(S1+S4),
['t']= NOT_7_NO_DP(S0+S1+S2),
['u']= S4+S3+S2+S5+S1, // U
['v']= S4+S3+S2, // is u but u use U
['w']= S1+S3+S5,
['x']= NOT_7_NO_DP(S0+S3), // similar to H
['y']= NOT_7_NO_DP(S0+S4),
['z']= S0+S1+S6+S4+S3, // same as 2
['A']= NOT_7_NO_DP(S3),
['B']= NOT_7_NO_DP(S0+S1), /* as b */
['C']= S0+S3+S4+S5, // same as [
['E']= NOT_7_NO_DP(S1+S2),
['F']= S6+S5+S4+S0,
['G']= NOT_7_NO_DP(S4), /* same as 9 */
['H']= NOT_7_NO_DP(S0+S3),
['I']= S1+S2,
['J']= S1+S2+S3+S4,
['K']= NOT_7_NO_DP(S0+S3), /* same as H */
['L']= S3+S4+S5,
['M']= S0+S4+S2, /* same as m*/
['N']= S2+S4+S6, /* same as n*/
['O']= NOT_7_NO_DP(S6),
['P']= NOT_7_NO_DP(S3+S2),
['Q']= NOT_7_NO_DP(S3+S2),
['R']= S4+S6,
['S']= NOT_7_NO_DP(S1+S4), /* sasme as 5 */
['T']= NOT_7_NO_DP(S0+S1+S2), /* sasme as t */
['U']= NOT_7_NO_DP(S6+S0),
['V']= S4+S3+S2, // is u but u use U
['W']= S1+S3+S5,
['X']= NOT_7_NO_DP(S0+S3), // similar to H
['Y']= NOT_7_NO_DP(S0+S4),
['Z']= S0+S1+S6+S4+S3, // same as 2
};
#undef S0
#undef S1
#undef S2
#undef S3
#undef S4
#undef S5
#undef S6
#undef DP
/** @} */
int XNUCLEO53L1A1_SetDisplayString(const char *str) {
int status;
uint32_t Segments;
int BitPos;
int i;
for( i=0; i<4 && str[i]!=0; i++){
Segments = (uint32_t)ascii_to_display_lut[(uint8_t)str[i]];
Segments =(~Segments)&0x7F;
BitPos=DisplayBitPos[i];
CurIOVal.u32 &=~(0x7F<<BitPos);
CurIOVal.u32 |= Segments<<BitPos;
}
/* clear unused digit */
for( ; i<4;i++){
BitPos=DisplayBitPos[i];
CurIOVal.u32 |=0x7F<<BitPos;
}
status = _ExpandersSetAllIO();
if( status ){
XNUCLEO53L1A1_ErrLog("Set i/o");
}
return status;
}
/**
*
* @} XNUCLEO53L1A1_top
*/

View File

@ -0,0 +1,403 @@
/**
* @file X-NUCLEO-53L1A1.h
*
* Created on: Nov 3, 2015
* Author: ST Imaging
*/
#ifndef _X_NUCLEO_53L1A1_H_
#define _X_NUCLEO_53L1A1_H_
#include "stm32wlxx_hal.h"
/**
* @defgroup VL53L1A1_config VL53L1A1 static configuration
* @brief Configure BSP support for USART2 (nucleo virtual com)
* UART support implies that BSP exclusively manages:
* @li HAL_UART_MspInit and HAL_UART_MspDeInit
* @li DMA channel and interrupt
*/
/** @ingroup VL53L1A1_config
* @{*/
#ifndef VL53L1A1_HAVE_UART
/**
* Define this macro at project level if UART is available
*/
#define VL53L1A1_HAVE_UART 0
#endif
#if VL53L1A1_HAVE_UART
/**
* User override of baud rate programmed for uart2 (default to 115200)
*/
#ifndef USART2_BAUD_RATE
# define USART2_BAUD_RATE 115200
#endif
#ifndef VL53L1A1_UART_DMA_RX
/** configure use of dma for uart rx
*
* Default to not use DMA RX when not defined explicitly
*
* require @a VL53L1A1_HAVE_UART
*/
# define VL53L1A1_UART_DMA_RX 0
#endif //VL53L1A1_UART_DMA_RX
#ifndef VL53L1A1_UART_DMA_TX
/** configure use of dma for uart tx
*
* Default to use DMA TX when not defined explicitly by user
*
* require @a VL53L1A1_HAVE_UART
*/
# define VL53L1A1_UART_DMA_TX 1
#endif //VL53L1A1_UART_DMA_RX
#ifndef VL53L1A1_UART_DMA_RX_IRQ_PRI
/** configure usart max irq priority
*
* Default to 0 when not defined explicitly by user
* @warning may not be support by all mcu (only F401 tested)
*/
# define VL53L1A1_UART_DMA_RX_IRQ_PRI 0
#endif
#ifndef VL53L1A1_UART_DMA_TX_IRQ_PRI
/** configure usart dma tx irq priority
*
* Default to 0 when not defined explicitly
* @warning only F401
*/
# define VL53L1A1_UART_DMA_TX_IRQ_PRI 0
#endif
#ifndef VL53L1A1_UART_IRQ_PRI
/**
* User override default uart irq priority 0 to fit application needs
* @warning only supported for f401
*/
# define VL53L1A1_UART_IRQ_PRI 0
#endif
/* provided by MSP part */
extern void XNUCLEO53L1A1_USART2_UART_Init(void);
#else
# define XNUCLEO53L1A1_USART2_UART_Init(...) (void)0
#endif
/** @} */
/**
* Configure interrupt pins pins pull up/down
*
* set to GPIO_NOPULL or GPIO_PULLUP or GPIO_PULLDOWN
*/
#define VL53L1A1_INTR_PIN_PUPD GPIO_PULLUP
/**
* @ingroup VL53L1A1_GPIO1_MAP
* @{
*/
#ifndef VL53L1A1_GPIO1_SHARED
/**
* @brief select use of shared interrupt
*
* Must be set to 0 (or not defined) for one interrupt per sensor
* Must be set to non 0 for shared interrupt line
* see @sa VL53L1A1_GPIO1_C_OPTION
*/
# define VL53L1A1_GPIO1_SHARED 0
#endif
#ifndef VL53L1A1_GPIO1_C_OPTION
/**
* @def VL53L1A1_GPIO1_C_OPTION
* @brief select GPIO1 to exti mapping for center or shared interrupt
*
* Set option value or un-define it to match with board configuration
* @li not defined or 0 : U14=On and U17=off => GPIO1_C = PA4
* @li defined and not 0 : U14=Off and U17=on => GPIO1_C = PC1
*/
# define VL53L1A1_GPIO1_C_OPTION 0
#endif
#ifndef VL53L1A1_GPIO1_L_OPTION
/**
* @def VL53L1A1_GPIO1_L_OPTION
* @brief control left sensor GPIO1 routing solder option
* @warning not used on shared interrupt config
*
* Set option value or un-define it to match with board configuration
* @li not defined or 0 : U10=on and U11=Off => GPIO1_L = PC7
* @li defined and not 0 : U10=off and U11=on => GPIO1_L = PA9
*/
# define VL53L1A1_GPIO1_L_OPTION 0
#endif
#ifndef VL53L1A1_GPIO1_R_OPTION
/**
* @def VL53L1A1_GPIO1_R_OPTION
* @brief control right sensor GPIO1 routing solder option
* @warning not used on shared interrupt config
*
* Set option value or un-define it to match with board configuration
* @li not defined or 0 : U18=on and U15=Off => GPIO1_R = PA10
* @li defined and not 0 : U18=off and U15=on => GPIO1_R = PB5
*/
# define VL53L1A1_GPIO1_R_OPTION 0
#endif
# define VL53L1A1_GPIO1_C_GPIO_PORT GPIOB
# define VL53L1A1_GPIO1_C_CLK_ENABLE __GPIOB_CLK_ENABLE
# define VL53L1A1_GPIO1_C_GPIO_PIN GPIO_PIN_3
# define VL53L1A1_GPIO1_C_INTx EXTI3_IRQn
/* not shared interrupt configuration */
# define VL53L1A1_GPIO1_L_GPIO_PORT GPIOC
# define VL53L1A1_GPIO1_L_CLK_ENABLE __GPIOC_CLK_ENABLE
# define VL53L1A1_GPIO1_L_GPIO_PIN GPIO_PIN_7
# define VL53L1A1_GPIO1_R_GPIO_PORT GPIOA
# define VL53L1A1_GPIO1_R_CLK_ENABLE __GPIOA_CLK_ENABLE
# define VL53L1A1_GPIO1_R_GPIO_PIN GPIO_PIN_10
/** @} */ /* defgroup L53L1A1_GPIO1_MAP */
/**
* @defgroup XNUCLEO53L1A1_Debugging VL053L1A1 debugging
* @{
*/
#ifndef XNUCLEO53L1A1_TRACE
/**
* @brief enable error output via trace
*
* when undefined (default) no trace no error logging is done, it is safe
* to at least count error just to see if any errors ever occur.
*
* Traces formating and output is end user defined via #trace_printf
*/
# define XNUCLEO53L1A1_TRACE TRACE_UART
#endif // XNUCLEO53L1A1_TRACE
/**
* @def XNUCLEO53L1A1_ErrLog(...)
* Macro used to report error log messages with printf format
*
* Our testing version use externally trace_printf,
* We trace out function names and line numbers plus any text formated with some extra arguments
*/
#if XNUCLEO53L1A1_TRACE
# define XNUCLEO53L1A1_ErrLog( msg, ...) trace_printf("[Err] %s l %d \t" msg "\n", __func__, __LINE__, ##__VA_ARGS__)
#else
# define XNUCLEO53L1A1_ErrLog(...) (void)0
#endif
/** @} */ /* group XNUCLEO53L1A1_Debugging */
/**
* @defgroup XNUCLEO53L1A1_Interface X-NUCLEO-53L1A1 BSP API
* @{ */
/**
* 53L0X Device selector
*
* @note Most functions are using a device selector as input. ASCII 'c', 'l' or 'r' are also accepted.
*/
enum XNUCLEO53L1A1_dev_e{
XNUCLEO53L1A1_DEV_LEFT = 0, //!< left satellite device P21 header : 'l'
XNUCLEO53L1A1_DEV_CENTER = 1, //!< center (built-in) vl053 device : 'c"
XNUCLEO53L1A1_DEV_RIGHT= 2 //!< Right satellite device P22 header : 'r'
};
/**
* I2C1 handle
* @note setup and configured by @ref XNUCLEO53L1A1_Init
*/
extern I2C_HandleTypeDef XNUCLEO53L1A1_hi2c;
/** UART2 handle
*
* UART2 is the nucleo Virtual Com Port
* @note setup and configured by @ref XNUCLEO53L1A1_Init*/
#if VL53L1A1_HAVE_UART
extern UART_HandleTypeDef huart2;
#if VL53L1A1_UART_DMA_RX
/** UART2 DMA RX available only if support activated*/
extern DMA_HandleTypeDef hdma_usart2_rx;
#endif
#if VL53L1A1_UART_DMA_TX
/** UART2 DMA TX available only if support activated */
extern DMA_HandleTypeDef hdma_usart2_tx;
#endif
#endif//ifdef VL53L1A1_HAVE_UART
/**
* Initialize VL053L1A1 STM32 expansion board
*
* @note All VL53L0X devices XSDN are asserted and display is turned off
* @return 0 on success
*/
int XNUCLEO53L1A1_Init(void);
/**
* Set Reset (XSDN) state of a given "id" device
* @param DevNo The device number use @ref XNUCLEO53L1A1_dev_e. Char 't' 'c' 'r' can also be used
* @param state State of the device reset (xsdn) pin @warning reset pin is active low
* @return 0 on success
*/
int XNUCLEO53L1A1_ResetId(int DevNo, int state );
/**
* Get PB1 push button state
*
* @param state Actual button state 0/1 boolean type
* @warning In case of error, value of state is unchanged
* @return 0 on success
*/
int XNUCLEO53L1A1_GetPB1(int *state);
/**
* Set the 7 segments display
* @param str String to set on display
* @warning When string is less than 4 digits, display is left-justified and lower digits are blanked.
* To display a 2 digits value, left justified on the 4 digits, use "%4d" formating
* @warning When more than 4 char are present only first 4 are displayed
* @note Characters that do not have 7 segment font matching in @ref ascii_to_display_lut are left blank
* @return 0 on success
*/
int XNUCLEO53L1A1_SetDisplayString(const char *str);
/** @} */ /* defgroup XNUCLEO53L1A1_Interface */
/**
* @ingroup XNUCLEO53L1A1_Interface
* @defgroup MSP_implement MSP and User specific code
*
* Some MSP Micro-controller Support Package code is provided in the BSP source.\n
* The following MSP function and callback are already implemented
* ### UART ###
* @li HAL_UART_MspDeInit and HAL_UART_MspInit
* @li HAL_UART_TxCpltCallback
* @li USART2_IRQHandler
*
* ### EXTI ###
* @li F401RE/L476 EXTI15_10_IRQHandler, EXTI9_5_IRQHandler, EXTI4_IRQHandler and EXTI1_IRQHandler
* @li L053R8 EXTI4_15_IRQHandler, EXTI0_1_IRQHandler and EXTI4_15_IRQHandler
* @li HAL_GPIO_EXTI_Callback
*
* ### DMA ###
* @li L476 DMA1_Channel6_IRQHandler and DMA1_Channel7_IRQHandler
* @li F401 DMA1_Stream5_IRQHandler and DMA1_Stream6_IRQHandler
* @li L053 DMA1_Channel4_5_6_7_IRQHandler
*
* Exact EXTI list depends on soldering options and configured DMA list depends on DMA RX/TX configuration options.
*
* If those functions and callbacks are also to be used by application, the code must be removed or adapted to manage multi-instances
*
* Family-specific code is on dedicated files:
* @li vl53l0A1-l053msp.c for Nucleo-L053R8
* @li vl53l0A1-x4msp.c for Nucleo-F401RE and Nucleo-L476RG
* @li uart_trace.c for generic uart handling
* @{
*/
/**
* @defgroup MSP_implement_common MSP Common to all STM32
*
* MSP adaption that apply to all mcu (F4,L4,L0) with no or little customization.
*
* @{
*/
/**
* Enable Disable interrupt at MCU level (MSP)
*
* Enable/Disable the interrupt for a given sensor Dev number
*
* End user is expected to override VL53L1A1_EXTI_Callback to catch interrupts.
* When the vector is shared applicaton is passed the device and pin corretcy
* In shared line mode application is responsible to find what sensor cause the interrupt and deal with races on interrupt line
*
* @param EnableIntr "boolean" 0 to disable interrupt otherwise interrupt is enabled
* @param DevNo Device number "name" of the sensor see @ref XNUCLEO53L1A1_dev_e
*
* @warning In shared interrupt mode, use only center : other values are not supported and will return an error
* @warning If several lines share the same interrupt vector (l053 mcu), only one sensor interrupt shall be enable at a time
* otherwise the handler may fail to locate and clear the right source (no sharing management)
*
* @return 0 on success \n
* <0 for error (invalid id)
* >0 interrupt configured but with potential sharing on EXTI groups see @ref VL53L1A1_GPIO1_MAP
*/
int XNUCLEO53L1A1_SetIntrStateId(int EnableIntr, int DevNo);
/** @} */ /* MSP_implemant_common */
/**
* MSP Configure expansion board Interrupt i/o
*
* This function configures GPIO i/o and NVIC. See @ref VL53L1A1_GPIO1_MAP for details
* To enable interrupt handling use @ref XNUCLEO53L1A1_SetIntrStateId()
*
* The input pullup/pulldown is configured by static configuration @a #VL53L1A1_INTR_PIN_PUPD
*
* @warning Interrupt is disabled and any pending status flushed out\n
* if initial vl53lx sensor interrupt state is important it must be handled externally (soft trigger)
* @warning If interrupt vector is shared it is better to configure and enable only one at a time
* proper shared management is done but yet some isr could be lost or some other fired spuriously.
*
* @param DevNo device number see @ref XNUCLEO53L1A1_dev_e
* @param IntPriority Interrupt Priority to set
* @param SubPriority Interrupt SubPriority to set
*/
void VL53L1A1_EXTI_IOConfigure(int DevNo, int IntPriority, int SubPriority);
/**
* Un-configure sensor interrupt line to mcu
*
* The line is DeInited (put back to input?)
*
* This function disables the related i/o pin and flush line interrupt pending (not vector)
* this is to permit shared vector to work.
* To turn off vector use @ref XNUCLEO53L1A1_SetIntrStateId()
*
* @warning because vector and line disable are not done atomically with isr disable,
* a last invalid interrupt may be fired.
*
* @param DevNo device see @ref XNUCLEO53L1A1_dev_e
*/
void VL53L1A1_EXTI_IOUnconfigure(int DevNo);
/** @} */ /* MSP_implement */
#endif /* _X_NUCLEO_53L1A1_H_ */

View File

@ -0,0 +1,253 @@
/*
* Copyright (c) 2017, STMicroelectronics - All Rights Reserved
*
* This file is part of VL53L1 Core and is dual licensed,
* either 'STMicroelectronics
* Proprietary license'
* or 'BSD 3-clause "New" or "Revised" License' , at your option.
*
********************************************************************************
*
* 'STMicroelectronics Proprietary license'
*
********************************************************************************
*
* License terms: STMicroelectronics Proprietary in accordance with licensing
* terms at www.st.com/sla0081
*
* STMicroelectronics confidential
* Reproduction and Communication of this document is strictly prohibited unless
* specifically authorized in writing by STMicroelectronics.
*
*
********************************************************************************
*
* Alternatively, VL53L1 Core may be distributed under the terms of
* 'BSD 3-clause "New" or "Revised" License', in which case the following
* provisions apply instead of the ones mentioned above :
*
********************************************************************************
*
* License terms: BSD 3-clause "New" or "Revised" License.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
********************************************************************************
*
*/
/**
* @file vl53l1_error_codes.h
*
* @brief Error Code definitions for VL53L1 API.
*
*/
#ifndef _VL53L1_ERROR_CODES_H_
#define _VL53L1_ERROR_CODES_H_
#include "vl53l1_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/****************************************
* PRIVATE define do not edit
****************************************/
/** @defgroup VL53L1_define_Error_group Error and Warning code returned by API
* The following DEFINE are used to identify the PAL ERROR
* @{
*/
typedef int8_t VL53L1_Error;
#define VL53L1_ERROR_NONE ((VL53L1_Error) 0)
#define VL53L1_ERROR_CALIBRATION_WARNING ((VL53L1_Error) - 1)
/*!< Warning invalid calibration data may be in used
\a VL53L1_InitData()
\a VL53L1_GetOffsetCalibrationData
\a VL53L1_SetOffsetCalibrationData */
#define VL53L1_ERROR_MIN_CLIPPED ((VL53L1_Error) - 2)
/*!< Warning parameter passed was clipped to min before to be applied */
#define VL53L1_ERROR_UNDEFINED ((VL53L1_Error) - 3)
/*!< Unqualified error */
#define VL53L1_ERROR_INVALID_PARAMS ((VL53L1_Error) - 4)
/*!< Parameter passed is invalid or out of range */
#define VL53L1_ERROR_NOT_SUPPORTED ((VL53L1_Error) - 5)
/*!< Function is not supported in current mode or configuration */
#define VL53L1_ERROR_RANGE_ERROR ((VL53L1_Error) - 6)
/*!< Device report a ranging error interrupt status */
#define VL53L1_ERROR_TIME_OUT ((VL53L1_Error) - 7)
/*!< Aborted due to time out */
#define VL53L1_ERROR_MODE_NOT_SUPPORTED ((VL53L1_Error) - 8)
/*!< Asked mode is not supported by the device */
#define VL53L1_ERROR_BUFFER_TOO_SMALL ((VL53L1_Error) - 9)
/*!< ... */
#define VL53L1_ERROR_COMMS_BUFFER_TOO_SMALL ((VL53L1_Error) - 10)
/*!< Supplied buffer is larger than I2C supports */
#define VL53L1_ERROR_GPIO_NOT_EXISTING ((VL53L1_Error) - 11)
/*!< User tried to setup a non-existing GPIO pin */
#define VL53L1_ERROR_GPIO_FUNCTIONALITY_NOT_SUPPORTED ((VL53L1_Error) - 12)
/*!< unsupported GPIO functionality */
#define VL53L1_ERROR_CONTROL_INTERFACE ((VL53L1_Error) - 13)
/*!< error reported from IO functions */
#define VL53L1_ERROR_INVALID_COMMAND ((VL53L1_Error) - 14)
/*!< The command is not allowed in the current device state
* (power down) */
#define VL53L1_ERROR_DIVISION_BY_ZERO ((VL53L1_Error) - 15)
/*!< In the function a division by zero occurs */
#define VL53L1_ERROR_REF_SPAD_INIT ((VL53L1_Error) - 16)
/*!< Error during reference SPAD initialization */
#define VL53L1_ERROR_GPH_SYNC_CHECK_FAIL ((VL53L1_Error) - 17)
/*!< GPH sync interrupt check fail - API out of sync with device*/
#define VL53L1_ERROR_STREAM_COUNT_CHECK_FAIL ((VL53L1_Error) - 18)
/*!< Stream count check fail - API out of sync with device */
#define VL53L1_ERROR_GPH_ID_CHECK_FAIL ((VL53L1_Error) - 19)
/*!< GPH ID check fail - API out of sync with device */
#define VL53L1_ERROR_ZONE_STREAM_COUNT_CHECK_FAIL ((VL53L1_Error) - 20)
/*!< Zone dynamic config stream count check failed - API out of sync */
#define VL53L1_ERROR_ZONE_GPH_ID_CHECK_FAIL ((VL53L1_Error) - 21)
/*!< Zone dynamic config GPH ID check failed - API out of sync */
#define VL53L1_ERROR_XTALK_EXTRACTION_NO_SAMPLE_FAIL ((VL53L1_Error) - 22)
/*!< Thrown when run_xtalk_extraction fn has 0 succesful samples
* when using the full array to sample the xtalk. In this case there is
* not enough information to generate new Xtalk parm info. The function
* will exit and leave the current xtalk parameters unaltered */
#define VL53L1_ERROR_XTALK_EXTRACTION_SIGMA_LIMIT_FAIL ((VL53L1_Error) - 23)
/*!< Thrown when run_xtalk_extraction fn has found that the
* avg sigma estimate of the full array xtalk sample is > than the
* maximal limit allowed. In this case the xtalk sample is too noisy for
* measurement. The function will exit and leave the current xtalk parameters
* unaltered. */
#define VL53L1_ERROR_OFFSET_CAL_NO_SAMPLE_FAIL ((VL53L1_Error) - 24)
/*!< Thrown if there one of stages has no valid offset calibration
* samples. A fatal error calibration not valid */
#define VL53L1_ERROR_OFFSET_CAL_NO_SPADS_ENABLED_FAIL ((VL53L1_Error) - 25)
/*!< Thrown if there one of stages has zero effective SPADS
* Traps the case when MM1 SPADs is zero.
* A fatal error calibration not valid */
#define VL53L1_ERROR_ZONE_CAL_NO_SAMPLE_FAIL ((VL53L1_Error) - 26)
/*!< Thrown if then some of the zones have no valid samples
* A fatal error calibration not valid */
#define VL53L1_ERROR_TUNING_PARM_KEY_MISMATCH ((VL53L1_Error) - 27)
/*!< Thrown if the tuning file key table version does not match with
* expected value. The driver expects the key table version to match
* the compiled default version number in the define
* #VL53L1_TUNINGPARM_KEY_TABLE_VERSION_DEFAULT
* */
#define VL53L1_WARNING_REF_SPAD_CHAR_NOT_ENOUGH_SPADS ((VL53L1_Error) - 28)
/*!< Thrown if there are less than 5 good SPADs are available. */
#define VL53L1_WARNING_REF_SPAD_CHAR_RATE_TOO_HIGH ((VL53L1_Error) - 29)
/*!< Thrown if the final reference rate is greater than
the upper reference rate limit - default is 40 Mcps.
Implies a minimum Q3 (x10) SPAD (5) selected */
#define VL53L1_WARNING_REF_SPAD_CHAR_RATE_TOO_LOW ((VL53L1_Error) - 30)
/*!< Thrown if the final reference rate is less than
the lower reference rate limit - default is 10 Mcps.
Implies maximum Q1 (x1) SPADs selected */
#define VL53L1_WARNING_OFFSET_CAL_MISSING_SAMPLES ((VL53L1_Error) - 31)
/*!< Thrown if there is less than the requested number of
* valid samples. */
#define VL53L1_WARNING_OFFSET_CAL_SIGMA_TOO_HIGH ((VL53L1_Error) - 32)
/*!< Thrown if the offset calibration range sigma estimate is greater
* than 8.0 mm. This is the recommended min value to yield a stable
* offset measurement */
#define VL53L1_WARNING_OFFSET_CAL_RATE_TOO_HIGH ((VL53L1_Error) - 33)
/*!< Thrown when VL53L1_run_offset_calibration() peak rate is greater
than that 50.0Mcps. This is the recommended max rate to avoid
pile-up influencing the offset measurement */
#define VL53L1_WARNING_OFFSET_CAL_SPAD_COUNT_TOO_LOW ((VL53L1_Error) - 34)
/*!< Thrown when VL53L1_run_offset_calibration() when one of stages
range has less that 5.0 effective SPADS. This is the recommended
min value to yield a stable offset */
#define VL53L1_WARNING_ZONE_CAL_MISSING_SAMPLES ((VL53L1_Error) - 35)
/*!< Thrown if one of more of the zones have less than
the requested number of valid samples */
#define VL53L1_WARNING_ZONE_CAL_SIGMA_TOO_HIGH ((VL53L1_Error) - 36)
/*!< Thrown if one or more zones have sigma estimate value greater
* than 8.0 mm. This is the recommended min value to yield a stable
* offset measurement */
#define VL53L1_WARNING_ZONE_CAL_RATE_TOO_HIGH ((VL53L1_Error) - 37)
/*!< Thrown if one of more zones have peak rate higher than
that 50.0Mcps. This is the recommended max rate to avoid
pile-up influencing the offset measurement */
#define VL53L1_WARNING_XTALK_MISSING_SAMPLES ((VL53L1_Error) - 38)
/*!< Thrown to notify that some of the xtalk samples did not yield
* valid ranging pulse data while attempting to measure
* the xtalk signal in vl53l1_run_xtalk_extract(). This can signify any of
* the zones are missing samples, for further debug information the
* xtalk_results struct should be referred to. This warning is for
* notification only, the xtalk pulse and shape have still been generated
*/
#define VL53L1_WARNING_XTALK_NO_SAMPLES_FOR_GRADIENT ((VL53L1_Error) - 39)
/*!< Thrown to notify that some of teh xtalk samples used for gradient
* generation did not yield valid ranging pulse data while attempting to
* measure the xtalk signal in vl53l1_run_xtalk_extract(). This can signify
* that any one of the zones 0-3 yielded no successful samples. The
* xtalk_results struct should be referred to for further debug info.
* This warning is for notification only, the xtalk pulse and shape
* have still been generated.
*/
#define VL53L1_WARNING_XTALK_SIGMA_LIMIT_FOR_GRADIENT ((VL53L1_Error) - 40)
/*!< Thrown to notify that some of the xtalk samples used for gradient
* generation did not pass the sigma limit check while attempting to
* measure the xtalk signal in vl53l1_run_xtalk_extract(). This can signify
* that any one of the zones 0-3 yielded an avg sigma_mm value > the limit.
* The xtalk_results struct should be referred to for further debug info.
* This warning is for notification only, the xtalk pulse and shape
* have still been generated.
*/
#define VL53L1_ERROR_NOT_IMPLEMENTED ((VL53L1_Error) - 41)
/*!< Tells requested functionality has not been implemented yet or
* not compatible with the device */
#define VL53L1_ERROR_PLATFORM_SPECIFIC_START ((VL53L1_Error) - 60)
/*!< Tells the starting code for platform */
/** @} VL53L1_define_Error_group */
#ifdef __cplusplus
}
#endif
#endif /* _VL53L1_ERROR_CODES_H_ */

View File

@ -0,0 +1,431 @@
/*
* This file is part of VL53L1 Platform
*
* Copyright (c) 2016, STMicroelectronics - All Rights Reserved
*
* License terms: BSD 3-clause "New" or "Revised" License.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "vl53l1_platform.h"
#include "vl53l1_platform_log.h"
//#include "vl53l1_api.h"
#include "vl53l1_platform_user_config.h"
#include "stm32wlxx_hal.h"
#include <string.h>
#include <time.h>
#include <math.h>
#include "vl53l1_error_codes.h"
#include "X-NUCLEO-53L1A1.h"
#define I2C_TIME_OUT_BASE 10
#define I2C_TIME_OUT_BYTE 1
#ifdef VL53L1_LOG_ENABLE
#define trace_print(level, ...) VL53L1_trace_print_module_function(VL53L1_TRACE_MODULE_PLATFORM, level, VL53L1_TRACE_FUNCTION_NONE, ##__VA_ARGS__)
#define trace_i2c(...) VL53L1_trace_print_module_function(VL53L1_TRACE_MODULE_NONE, VL53L1_TRACE_LEVEL_NONE, VL53L1_TRACE_FUNCTION_I2C, ##__VA_ARGS__)
#endif
#ifndef HAL_I2C_MODULE_ENABLED
#warning "HAL I2C module must be enable "
#endif
//#define VL53L0X_pI2cHandle (&hi2c1)
/* when not customized by application define dummy one */
#ifndef VL53L1_GetI2cBus
/** This macro can be overloaded by user to enforce i2c sharing in RTOS context
*/
# define VL53L1_GetI2cBus(...) (void)0
#endif
#ifndef VL53L1_PutI2cBus
/** This macro can be overloaded by user to enforce i2c sharing in RTOS context
*/
# define VL53L1_PutI2cBus(...) (void)0
#endif
uint8_t _I2CBuffer[256];
int _I2CWrite(uint16_t Dev, uint8_t *pdata, uint32_t count) {
int status;
int i2c_time_out = I2C_TIME_OUT_BASE+ count* I2C_TIME_OUT_BYTE;
status = HAL_I2C_Master_Transmit(&XNUCLEO53L1A1_hi2c, Dev, pdata, count, i2c_time_out);
if (status) {
//VL6180x_ErrLog("I2C error 0x%x %d len", dev->I2cAddr, len);
//XNUCLEO6180XA1_I2C1_Init(&hi2c1);
}
return status;
}
int _I2CRead(uint16_t Dev, uint8_t *pdata, uint32_t count) {
int status;
int i2c_time_out = I2C_TIME_OUT_BASE+ count* I2C_TIME_OUT_BYTE;
status = HAL_I2C_Master_Receive(&XNUCLEO53L1A1_hi2c, Dev|1, pdata, count, i2c_time_out);
if (status) {
//VL6180x_ErrLog("I2C error 0x%x %d len", dev->I2cAddr, len);
//XNUCLEO6180XA1_I2C1_Init(&hi2c1);
}
return status;
}
VL53L1_Error VL53L1_WriteMulti(uint16_t Dev, uint16_t index, uint8_t *pdata, uint32_t count) {
int status_int;
VL53L1_Error Status = VL53L1_ERROR_NONE;
if (count > sizeof(_I2CBuffer) - 1) {
return VL53L1_ERROR_INVALID_PARAMS;
}
_I2CBuffer[0] = index>>8;
_I2CBuffer[1] = index&0xFF;
memcpy(&_I2CBuffer[2], pdata, count);
VL53L1_GetI2cBus();
status_int = _I2CWrite(Dev, _I2CBuffer, count + 2);
if (status_int != 0) {
Status = VL53L1_ERROR_CONTROL_INTERFACE;
}
VL53L1_PutI2cBus();
return Status;
}
// the ranging_sensor_comms.dll will take care of the page selection
VL53L1_Error VL53L1_ReadMulti(uint16_t Dev, uint16_t index, uint8_t *pdata, uint32_t count) {
VL53L1_Error Status = VL53L1_ERROR_NONE;
int32_t status_int;
_I2CBuffer[0] = index>>8;
_I2CBuffer[1] = index&0xFF;
VL53L1_GetI2cBus();
status_int = _I2CWrite(Dev, _I2CBuffer, 2);
if (status_int != 0) {
Status = VL53L1_ERROR_CONTROL_INTERFACE;
goto done;
}
status_int = _I2CRead(Dev, pdata, count);
if (status_int != 0) {
Status = VL53L1_ERROR_CONTROL_INTERFACE;
}
done:
VL53L1_PutI2cBus();
return Status;
}
VL53L1_Error VL53L1_WrByte(uint16_t Dev, uint16_t index, uint8_t data) {
VL53L1_Error Status = VL53L1_ERROR_NONE;
int32_t status_int;
_I2CBuffer[0] = index>>8;
_I2CBuffer[1] = index&0xFF;
_I2CBuffer[2] = data;
VL53L1_GetI2cBus();
status_int = _I2CWrite(Dev, _I2CBuffer, 3);
if (status_int != 0) {
Status = VL53L1_ERROR_CONTROL_INTERFACE;
}
VL53L1_PutI2cBus();
return Status;
}
VL53L1_Error VL53L1_WrWord(uint16_t Dev, uint16_t index, uint16_t data) {
VL53L1_Error Status = VL53L1_ERROR_NONE;
int32_t status_int;
_I2CBuffer[0] = index>>8;
_I2CBuffer[1] = index&0xFF;
_I2CBuffer[2] = data >> 8;
_I2CBuffer[3] = data & 0x00FF;
VL53L1_GetI2cBus();
status_int = _I2CWrite(Dev, _I2CBuffer, 4);
if (status_int != 0) {
Status = VL53L1_ERROR_CONTROL_INTERFACE;
}
VL53L1_PutI2cBus();
return Status;
}
VL53L1_Error VL53L1_WrDWord(uint16_t Dev, uint16_t index, uint32_t data) {
VL53L1_Error Status = VL53L1_ERROR_NONE;
int32_t status_int;
_I2CBuffer[0] = index>>8;
_I2CBuffer[1] = index&0xFF;
_I2CBuffer[2] = (data >> 24) & 0xFF;
_I2CBuffer[3] = (data >> 16) & 0xFF;
_I2CBuffer[4] = (data >> 8) & 0xFF;
_I2CBuffer[5] = (data >> 0 ) & 0xFF;
VL53L1_GetI2cBus();
status_int = _I2CWrite(Dev, _I2CBuffer, 6);
if (status_int != 0) {
Status = VL53L1_ERROR_CONTROL_INTERFACE;
}
VL53L1_PutI2cBus();
return Status;
}
VL53L1_Error VL53L1_UpdateByte(uint16_t Dev, uint16_t index, uint8_t AndData, uint8_t OrData) {
VL53L1_Error Status = VL53L1_ERROR_NONE;
uint8_t data;
Status = VL53L1_RdByte(Dev, index, &data);
if (Status) {
goto done;
}
data = (data & AndData) | OrData;
Status = VL53L1_WrByte(Dev, index, data);
done:
return Status;
}
VL53L1_Error VL53L1_RdByte(uint16_t Dev, uint16_t index, uint8_t *data) {
VL53L1_Error Status = VL53L1_ERROR_NONE;
int32_t status_int;
_I2CBuffer[0] = index>>8;
_I2CBuffer[1] = index&0xFF;
VL53L1_GetI2cBus();
status_int = _I2CWrite(Dev, _I2CBuffer, 2);
if( status_int ){
Status = VL53L1_ERROR_CONTROL_INTERFACE;
goto done;
}
status_int = _I2CRead(Dev, data, 1);
if (status_int != 0) {
Status = VL53L1_ERROR_CONTROL_INTERFACE;
}
done:
VL53L1_PutI2cBus();
return Status;
}
VL53L1_Error VL53L1_RdWord(uint16_t Dev, uint16_t index, uint16_t *data) {
VL53L1_Error Status = VL53L1_ERROR_NONE;
int32_t status_int;
_I2CBuffer[0] = index>>8;
_I2CBuffer[1] = index&0xFF;
VL53L1_GetI2cBus();
status_int = _I2CWrite(Dev, _I2CBuffer, 2);
if( status_int ){
Status = VL53L1_ERROR_CONTROL_INTERFACE;
goto done;
}
status_int = _I2CRead(Dev, _I2CBuffer, 2);
if (status_int != 0) {
Status = VL53L1_ERROR_CONTROL_INTERFACE;
goto done;
}
*data = ((uint16_t)_I2CBuffer[0]<<8) + (uint16_t)_I2CBuffer[1];
done:
VL53L1_PutI2cBus();
return Status;
}
VL53L1_Error VL53L1_RdDWord(uint16_t Dev, uint16_t index, uint32_t *data) {
VL53L1_Error Status = VL53L1_ERROR_NONE;
int32_t status_int;
_I2CBuffer[0] = index>>8;
_I2CBuffer[1] = index&0xFF;
VL53L1_GetI2cBus();
status_int = _I2CWrite(Dev, _I2CBuffer, 2);
if (status_int != 0) {
Status = VL53L1_ERROR_CONTROL_INTERFACE;
goto done;
}
status_int = _I2CRead(Dev, _I2CBuffer, 4);
if (status_int != 0) {
Status = VL53L1_ERROR_CONTROL_INTERFACE;
goto done;
}
*data = ((uint32_t)_I2CBuffer[0]<<24) + ((uint32_t)_I2CBuffer[1]<<16) + ((uint32_t)_I2CBuffer[2]<<8) + (uint32_t)_I2CBuffer[3];
done:
VL53L1_PutI2cBus();
return Status;
}
VL53L1_Error VL53L1_GetTickCount(
uint32_t *ptick_count_ms)
{
/* Returns current tick count in [ms] */
VL53L1_Error status = VL53L1_ERROR_NONE;
//*ptick_count_ms = timeGetTime();
*ptick_count_ms = 0;
#ifdef VL53L1_LOG_ENABLE
trace_print(
VL53L1_TRACE_LEVEL_DEBUG,
"VL53L1_GetTickCount() = %5u ms;\n",
*ptick_count_ms);
#endif
return status;
}
#define trace_print(level, ...) \
_LOG_TRACE_PRINT(VL53L1_TRACE_MODULE_PLATFORM, \
level, VL53L1_TRACE_FUNCTION_NONE, ##__VA_ARGS__)
#define trace_i2c(...) \
_LOG_TRACE_PRINT(VL53L1_TRACE_MODULE_NONE, \
VL53L1_TRACE_LEVEL_NONE, VL53L1_TRACE_FUNCTION_I2C, ##__VA_ARGS__)
VL53L1_Error VL53L1_GetTimerFrequency(int32_t *ptimer_freq_hz)
{
*ptimer_freq_hz = 0;
trace_print(VL53L1_TRACE_LEVEL_INFO, "VL53L1_GetTimerFrequency: Freq : %dHz\n", *ptimer_freq_hz);
return VL53L1_ERROR_NONE;
}
VL53L1_Error VL53L1_WaitMs(uint16_t dev, int32_t wait_ms){
(void)dev;
HAL_Delay(wait_ms);
return VL53L1_ERROR_NONE;
}
VL53L1_Error VL53L1_WaitUs(uint16_t dev, int32_t wait_us){
(void)dev;
HAL_Delay(wait_us/1000);
return VL53L1_ERROR_NONE;
}
VL53L1_Error VL53L1_WaitValueMaskEx(
uint16_t dev,
uint32_t timeout_ms,
uint16_t index,
uint8_t value,
uint8_t mask,
uint32_t poll_delay_ms)
{
/*
* Platform implementation of WaitValueMaskEx V2WReg script command
*
* WaitValueMaskEx(
* duration_ms,
* index,
* value,
* mask,
* poll_delay_ms);
*/
VL53L1_Error status = VL53L1_ERROR_NONE;
uint32_t start_time_ms = 0;
uint32_t current_time_ms = 0;
uint32_t polling_time_ms = 0;
uint8_t byte_value = 0;
uint8_t found = 0;
#ifdef VL53L1_LOG_ENABLE
uint8_t trace_functions = VL53L1_TRACE_FUNCTION_NONE;
#endif
// char register_name[VL53L1_MAX_STRING_LENGTH];
/* look up register name */
#ifdef PAL_EXTENDED
VL53L1_get_register_name(
index,
register_name);
#else
// VL53L1_COPYSTRING(register_name, "");
#endif
/* Output to I2C logger for FMT/DFT */
/*trace_i2c("WaitValueMaskEx(%5d, 0x%04X, 0x%02X, 0x%02X, %5d);\n",
timeout_ms, index, value, mask, poll_delay_ms); */
trace_i2c("WaitValueMaskEx(%5d, %s, 0x%02X, 0x%02X, %5d);\n",
timeout_ms, register_name, value, mask, poll_delay_ms);
/* calculate time limit in absolute time */
VL53L1_GetTickCount(&start_time_ms);
/* remember current trace functions and temporarily disable
* function logging
*/
#ifdef VL53L1_LOG_ENABLE
trace_functions = VL53L1_get_trace_functions();
VL53L1_set_trace_functions(VL53L1_TRACE_FUNCTION_NONE);
#endif
/* wait until value is found, timeout reached on error occurred */
while ((status == VL53L1_ERROR_NONE) &&
(polling_time_ms < timeout_ms) &&
(found == 0)) {
if (status == VL53L1_ERROR_NONE)
status = VL53L1_RdByte(
dev,
index,
&byte_value);
if ((byte_value & mask) == value)
found = 1;
if (status == VL53L1_ERROR_NONE &&
found == 0 &&
poll_delay_ms > 0)
status = VL53L1_WaitMs(
dev,
poll_delay_ms);
/* Update polling time (Compare difference rather than absolute to
negate 32bit wrap around issue) */
VL53L1_GetTickCount(&current_time_ms);
polling_time_ms = current_time_ms - start_time_ms;
}
#ifdef VL53L1_LOG_ENABLE
/* Restore function logging */
VL53L1_set_trace_functions(trace_functions);
#endif
if (found == 0 && status == VL53L1_ERROR_NONE)
status = VL53L1_ERROR_TIME_OUT;
return status;
}

View File

@ -0,0 +1,141 @@
/*
* This file is part of VL53L1 Platform
*
* Copyright (c) 2016, STMicroelectronics - All Rights Reserved
*
* License terms: BSD 3-clause "New" or "Revised" License.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef _VL53L1_PLATFORM_H_
#define _VL53L1_PLATFORM_H_
#include "stm32wlxx_hal.h"
#include "vl53l1_platform_log.h"
#include "vl53l1_types.h"
#include "vl53l1_error_codes.h"
#ifdef __cplusplus
extern "C"
{
#endif
VL53L1_Error VL53L1_CommsInitialise(
uint16_t dev,
uint8_t comms_type,
uint16_t comms_speed_khz);
VL53L1_Error VL53L1_CommsClose(
uint16_t dev);
VL53L1_Error VL53L1_WriteMulti(
uint16_t dev,
uint16_t index,
uint8_t *pdata,
uint32_t count);
VL53L1_Error VL53L1_ReadMulti(
uint16_t dev,
uint16_t index,
uint8_t *pdata,
uint32_t count);
VL53L1_Error VL53L1_WrByte(
uint16_t dev,
uint16_t index,
uint8_t VL53L1_PRM_00005);
VL53L1_Error VL53L1_WrWord(
uint16_t dev,
uint16_t index,
uint16_t VL53L1_PRM_00005);
VL53L1_Error VL53L1_WrDWord(
uint16_t dev,
uint16_t index,
uint32_t VL53L1_PRM_00005);
VL53L1_Error VL53L1_RdByte(
uint16_t dev,
uint16_t index,
uint8_t *pdata);
VL53L1_Error VL53L1_RdWord(
uint16_t dev,
uint16_t index,
uint16_t *pdata);
VL53L1_Error VL53L1_RdDWord(
uint16_t dev,
uint16_t index,
uint32_t *pdata);
VL53L1_Error VL53L1_WaitUs(
uint16_t dev,
int32_t wait_us);
VL53L1_Error VL53L1_WaitMs(
uint16_t dev,
int32_t wait_ms);
VL53L1_Error VL53L1_GetTimerFrequency(int32_t *ptimer_freq_hz);
VL53L1_Error VL53L1_GetTimerValue(int32_t *ptimer_count);
VL53L1_Error VL53L1_GpioSetMode(uint8_t pin, uint8_t mode);
VL53L1_Error VL53L1_GpioSetValue(uint8_t pin, uint8_t value);
VL53L1_Error VL53L1_GpioGetValue(uint8_t pin, uint8_t *pvalue);
VL53L1_Error VL53L1_GpioXshutdown(uint8_t value);
VL53L1_Error VL53L1_GpioCommsSelect(uint8_t value);
VL53L1_Error VL53L1_GpioPowerEnable(uint8_t value);
VL53L1_Error VL53L1_GpioInterruptEnable(void (*function)(void), uint8_t edge_type);
VL53L1_Error VL53L1_GpioInterruptDisable(void);
VL53L1_Error VL53L1_GetTickCount(
uint32_t *ptime_ms);
VL53L1_Error VL53L1_WaitValueMaskEx(
uint16_t dev,
uint32_t timeout_ms,
uint16_t index,
uint8_t value,
uint8_t mask,
uint32_t poll_delay_ms);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,223 @@
/*******************************************************************************
Copyright (C) 2015, STMicroelectronics International N.V.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of STMicroelectronics nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
NON-INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS ARE DISCLAIMED.
IN NO EVENT SHALL STMICROELECTRONICS INTERNATIONAL N.V. BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
********************************************************************************/
/**
* @file vl53l1_platform_log.h
*
* @brief EwokPlus25 platform logging function definition
*/
#ifndef _VL53L1_PLATFORM_LOG_H_
#define _VL53L1_PLATFORM_LOG_H_
#ifdef VL53L1_LOG_ENABLE
#include "vl53l1_platform_user_config.h"
#ifdef _MSC_VER
# define EWOKPLUS_EXPORTS __declspec(dllexport)
#else
# define EWOKPLUS_EXPORTS
#endif
#include "vl53l1_types.h"
#ifdef __cplusplus
extern "C" {
#endif
#include <time.h>
/**
* @brief Set the level, output and specific functions for module logging.
*
*
* @param filename - full path of output log file, NULL for print to stdout
*
* @param modules - Module or None or All to trace
* VL53L1_TRACE_MODULE_NONE
* VL53L1_TRACE_MODULE_API
* VL53L1_TRACE_MODULE_CORE
* VL53L1_TRACE_MODULE_TUNING
* VL53L1_TRACE_MODULE_CHARACTERISATION
* VL53L1_TRACE_MODULE_PLATFORM
* VL53L1_TRACE_MODULE_ALL
*
* @param level - trace level
* VL53L1_TRACE_LEVEL_NONE
* VL53L1_TRACE_LEVEL_ERRORS
* VL53L1_TRACE_LEVEL_WARNING
* VL53L1_TRACE_LEVEL_INFO
* VL53L1_TRACE_LEVEL_DEBUG
* VL53L1_TRACE_LEVEL_ALL
* VL53L1_TRACE_LEVEL_IGNORE
*
* @param functions - function level to trace;
* VL53L1_TRACE_FUNCTION_NONE
* VL53L1_TRACE_FUNCTION_I2C
* VL53L1_TRACE_FUNCTION_ALL
*
* @return status - always VL53L1_ERROR_NONE
*
*/
#define VL53L1_TRACE_LEVEL_NONE 0x00000000
#define VL53L1_TRACE_LEVEL_ERRORS 0x00000001
#define VL53L1_TRACE_LEVEL_WARNING 0x00000002
#define VL53L1_TRACE_LEVEL_INFO 0x00000004
#define VL53L1_TRACE_LEVEL_DEBUG 0x00000008
#define VL53L1_TRACE_LEVEL_ALL 0x00000010
#define VL53L1_TRACE_LEVEL_IGNORE 0x00000020
#define VL53L1_TRACE_FUNCTION_NONE 0x00000000
#define VL53L1_TRACE_FUNCTION_I2C 0x00000001
#define VL53L1_TRACE_FUNCTION_ALL 0x7fffffff
#define VL53L1_TRACE_MODULE_NONE 0x00000000
#define VL53L1_TRACE_MODULE_API 0x00000001
#define VL53L1_TRACE_MODULE_CORE 0x00000002
#define VL53L1_TRACE_MODULE_PROTECTED 0x00000004
#define VL53L1_TRACE_MODULE_HISTOGRAM 0x00000008
#define VL53L1_TRACE_MODULE_REGISTERS 0x00000010
#define VL53L1_TRACE_MODULE_PLATFORM 0x00000020
#define VL53L1_TRACE_MODULE_NVM 0x00000040
#define VL53L1_TRACE_MODULE_CALIBRATION_DATA 0x00000080
#define VL53L1_TRACE_MODULE_NVM_DATA 0x00000100
#define VL53L1_TRACE_MODULE_HISTOGRAM_DATA 0x00000200
#define VL53L1_TRACE_MODULE_RANGE_RESULTS_DATA 0x00000400
#define VL53L1_TRACE_MODULE_XTALK_DATA 0x00000800
#define VL53L1_TRACE_MODULE_OFFSET_DATA 0x00001000
#define VL53L1_TRACE_MODULE_DATA_INIT 0x00002000
#define VL53L1_TRACE_MODULE_REF_SPAD_CHAR 0x00004000
#define VL53L1_TRACE_MODULE_SPAD_RATE_MAP 0x00008000
#ifdef PAL_EXTENDED
#define VL53L1_TRACE_MODULE_SPAD 0x01000000
#define VL53L1_TRACE_MODULE_FMT 0x02000000
#define VL53L1_TRACE_MODULE_UTILS 0x04000000
#define VL53L1_TRACE_MODULE_BENCH_FUNCS 0x08000000
#endif
#define VL53L1_TRACE_MODULE_CUSTOMER_API 0x40000000
#define VL53L1_TRACE_MODULE_ALL 0x7fffffff
extern uint32_t _trace_level;
/*
* NOTE: dynamically exported if we enable logging.
* this way, Python interfaces can access this function, but we don't
* need to include it in the .def files.
*/
EWOKPLUS_EXPORTS int8_t VL53L1_trace_config(
char *filename,
uint32_t modules,
uint32_t level,
uint32_t functions);
/**
* @brief Print trace module function.
*
* @param module - ??
* @param level - ??
* @param function - ??
* @param format - ??
*
*/
EWOKPLUS_EXPORTS void VL53L1_trace_print_module_function(
uint32_t module,
uint32_t level,
uint32_t function,
const char *format, ...);
/**
* @brief Get global _trace_functions parameter
*
* @return _trace_functions
*/
uint32_t VL53L1_get_trace_functions(void);
/**
* @brief Set global _trace_functions parameter
*
* @param[in] function : new function code
*/
void VL53L1_set_trace_functions(uint32_t function);
/*
* @brief Returns the current system tick count in [ms]
*
* @return time_ms : current time in [ms]
*
*/
uint32_t VL53L1_clock(void);
#define LOG_GET_TIME() \
((int)VL53L1_clock())
#define _LOG_TRACE_PRINT(module, level, function, ...) \
VL53L1_trace_print_module_function(module, level, function, ##__VA_ARGS__);
#define _LOG_FUNCTION_START(module, fmt, ...) \
VL53L1_trace_print_module_function(module, _trace_level, VL53L1_TRACE_FUNCTION_ALL, "%6ld <START> %s "fmt"\n", LOG_GET_TIME(), __FUNCTION__, ##__VA_ARGS__);
#define _LOG_FUNCTION_END(module, status, ...)\
VL53L1_trace_print_module_function(module, _trace_level, VL53L1_TRACE_FUNCTION_ALL, "%6ld <END> %s %d\n", LOG_GET_TIME(), __FUNCTION__, (int)status, ##__VA_ARGS__)
#define _LOG_FUNCTION_END_FMT(module, status, fmt, ...)\
VL53L1_trace_print_module_function(module, _trace_level, VL53L1_TRACE_FUNCTION_ALL, "%6ld <END> %s %d "fmt"\n", LOG_GET_TIME(), __FUNCTION__, (int)status, ##__VA_ARGS__)
#define _LOG_GET_TRACE_FUNCTIONS()\
VL53L1_get_trace_functions()
#define _LOG_SET_TRACE_FUNCTIONS(functions)\
VL53L1_set_trace_functions(functions)
#define _LOG_STRING_BUFFER(x) char x[VL53L1_MAX_STRING_LENGTH]
#ifdef __cplusplus
}
#endif
#else /* VL53L1_LOG_ENABLE - no logging */
#define _LOG_TRACE_PRINT(module, level, function, ...)
#define _LOG_FUNCTION_START(module, fmt, ...)
#define _LOG_FUNCTION_END(module, status, ...)
#define _LOG_FUNCTION_END_FMT(module, status, fmt, ...)
#define _LOG_GET_TRACE_FUNCTIONS() 0
#define _LOG_SET_TRACE_FUNCTIONS(functions)
#define _LOG_STRING_BUFFER(x)
#endif /* VL53L1_LOG_ENABLE */
#endif /* _VL53L1_PLATFORM_LOG_H_ */

View File

@ -0,0 +1,84 @@
/*******************************************************************************
Copyright (C) 2015, STMicroelectronics International N.V.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of STMicroelectronics nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
NON-INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS ARE DISCLAIMED.
IN NO EVENT SHALL STMICROELECTRONICS INTERNATIONAL N.V. BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
********************************************************************************/
/**
* @file vl53l1_platform_user_config.h
*
* @brief EwokPlus compile time user modifiable configuration
*/
#ifndef _VL53L1_PLATFORM_USER_CONFIG_H_
#define _VL53L1_PLATFORM_USER_CONFIG_H_
#define VL53L1_BYTES_PER_WORD 2
#define VL53L1_BYTES_PER_DWORD 4
/* Define polling delays */
#define VL53L1_BOOT_COMPLETION_POLLING_TIMEOUT_MS 500
#define VL53L1_RANGE_COMPLETION_POLLING_TIMEOUT_MS 2000
#define VL53L1_TEST_COMPLETION_POLLING_TIMEOUT_MS 60000
#define VL53L1_POLLING_DELAY_MS 1
/* Define LLD TuningParms Page Base Address
* - Part of Patch_AddedTuningParms_11761
*/
#define VL53L1_TUNINGPARM_PUBLIC_PAGE_BASE_ADDRESS 0x8000
#define VL53L1_TUNINGPARM_PRIVATE_PAGE_BASE_ADDRESS 0xC000
#define VL53L1_GAIN_FACTOR__STANDARD_DEFAULT 0x0800
/*!< Default standard ranging gain correction factor
1.11 format. 1.0 = 0x0800, 0.980 = 0x07D7 */
#define VL53L1_OFFSET_CAL_MIN_EFFECTIVE_SPADS 0x0500
/*!< Lower Limit for the MM1 effective SPAD count during offset
calibration Format 8.8 0x0500 -> 5.0 effective SPADs */
#define VL53L1_OFFSET_CAL_MAX_PRE_PEAK_RATE_MCPS 0x1900
/*!< Max Limit for the pre range peak rate during offset
calibration Format 9.7 0x1900 -> 50.0 Mcps.
If larger then in pile up */
#define VL53L1_OFFSET_CAL_MAX_SIGMA_MM 0x0040
/*!< Max sigma estimate limit during offset calibration
Check applies to pre-range, mm1 and mm2 ranges
Format 14.2 0x0040 -> 16.0mm. */
#define VL53L1_MAX_USER_ZONES 169
/*!< Max number of user Zones - maximal limitation from
FW stream divide - value of 254 */
#define VL53L1_MAX_RANGE_RESULTS 2
/*!< Allocates storage for return and reference restults */
#define VL53L1_MAX_STRING_LENGTH 512
#endif /* _VL53L1_PLATFORM_USER_CONFIG_H_ */

View File

@ -0,0 +1,66 @@
/*
* This file is part of VL53L1 Platform
*
* Copyright (c) 2016, STMicroelectronics - All Rights Reserved
*
* License terms: BSD 3-clause "New" or "Revised" License.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFIT S; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef _VL53L1_PLATFORM_USER_DATA_H_
#define _VL53L1_PLATFORM_USER_DATA_H_
#include "stm32xxx_hal.h"
//#include "vl53l1_def.h"
#ifdef __cplusplus
extern "C"
{
#endif
typedef struct {
VL53L1_DevData_t Data;
uint8_t I2cDevAddr;
uint8_t comms_type;
uint16_t comms_speed_khz;
uint32_t new_data_ready_poll_duration_ms;
I2C_HandleTypeDef *I2cHandle;
} VL53L1_Dev_t;
typedef VL53L1_Dev_t *VL53L1_DEV;
#define VL53L1DevDataGet(Dev, field) (Dev->Data.field)
#define VL53L1DevDataSet(Dev, field, VL53L1_PRM_00005) ((Dev->Data.field) = (VL53L1_PRM_00005))
#define VL53L1DevStructGetLLDriverHandle(Dev) (&Dev->Data.LLData)
#define VL53L1DevStructGetLLResultsHandle(Dev) (&Dev->Data.llresults)
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,95 @@
/*******************************************************************************
Copyright (C) 2016, STMicroelectronics International N.V.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of STMicroelectronics nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
NON-INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS ARE DISCLAIMED.
IN NO EVENT SHALL STMICROELECTRONICS INTERNATIONAL N.V. BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
#ifndef _VL53L1_PLATFORM_USER_DEFINES_H_
#define _VL53L1_PLATFORM_USER_DEFINES_H_
#ifdef __cplusplus
extern "C"
{
#endif
/**
* @file vl53l1_platform_user_defines.h
*
* @brief All end user OS/platform/application definitions
*/
/**
* @def do_division_u
* @brief customer supplied division operation - 64-bit unsigned
*
* @param dividend unsigned 64-bit numerator
* @param divisor unsigned 64-bit denominator
*/
#define do_division_u(dividend, divisor) (dividend / divisor)
/**
* @def do_division_s
* @brief customer supplied division operation - 64-bit signed
*
* @param dividend signed 64-bit numerator
* @param divisor signed 64-bit denominator
*/
#define do_division_s(dividend, divisor) (dividend / divisor)
/**
* @def WARN_OVERRIDE_STATUS
* @brief customer supplied macro to optionally output info when a specific
error has been overridden with success within the EwokPlus driver
*
* @param __X__ the macro which enabled the suppression
*/
#define WARN_OVERRIDE_STATUS(__X__)\
trace_print (VL53L1_TRACE_LEVEL_WARNING, #__X__);
#ifdef _MSC_VER
#define DISABLE_WARNINGS() { \
__pragma (warning (push)); \
__pragma (warning (disable:4127)); \
}
#define ENABLE_WARNINGS() { \
__pragma (warning (pop)); \
}
#else
#define DISABLE_WARNINGS()
#define ENABLE_WARNINGS()
#endif
#ifdef __cplusplus
}
#endif
#endif // _VL53L1_PLATFORM_USER_DEFINES_H_

114
vl53lx_uld/vl53l1_types.h Normal file
View File

@ -0,0 +1,114 @@
/*******************************************************************************
Copyright (C) 2015, STMicroelectronics International N.V.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of STMicroelectronics nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
NON-INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS ARE DISCLAIMED.
IN NO EVENT SHALL STMICROELECTRONICS INTERNATIONAL N.V. BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
********************************************************************************/
/**
* @file vl53l1_types.h
* @brief VL53L1 types definition
*/
#ifndef _VL53L1_TYPES_H_
#define _VL53L1_TYPES_H_
/** @defgroup porting_type Basic type definition
* @ingroup api_platform
*
* @brief file vl53l1_types.h files hold basic type definition that may requires porting
*
* contains type that must be defined for the platform\n
* when target platform and compiler provide stdint.h and stddef.h it is enough to include it.\n
* If stdint.h is not available review and adapt all signed and unsigned 8/16/32 bits basic types. \n
* If stddef.h is not available review and adapt NULL definition .
*/
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#ifndef NULL
#error "Error NULL definition should be done. Please add required include "
#endif
#if !defined(STDINT_H) && !defined(_STDINT_H) && !defined(_GCC_STDINT_H) && !defined(__STDINT_DECLS) && !defined(_GCC_WRAP_STDINT_H) && !defined(_STDINT)
#pragma message("Please review type definition of STDINT define for your platform and add to list above ")
/*
* target platform do not provide stdint or use a different #define than above
* to avoid seeing the message below addapt the #define list above or implement
* all type and delete these pragma
*/
/** \ingroup VL53L1_portingType_group
* @{
*/
typedef unsigned long long uint64_t;
/** @brief Typedef defining 32 bit unsigned int type.\n
* The developer should modify this to suit the platform being deployed.
*/
typedef unsigned int uint32_t;
/** @brief Typedef defining 32 bit int type.\n
* The developer should modify this to suit the platform being deployed.
*/
typedef int int32_t;
/** @brief Typedef defining 16 bit unsigned short type.\n
* The developer should modify this to suit the platform being deployed.
*/
typedef unsigned short uint16_t;
/** @brief Typedef defining 16 bit short type.\n
* The developer should modify this to suit the platform being deployed.
*/
typedef short int16_t;
/** @brief Typedef defining 8 bit unsigned char type.\n
* The developer should modify this to suit the platform being deployed.
*/
typedef unsigned char uint8_t;
/** @brief Typedef defining 8 bit char type.\n
* The developer should modify this to suit the platform being deployed.
*/
typedef signed char int8_t;
/** @} */
#endif /* _STDINT_H */
/** use where fractional values are expected
*
* Given a floating point value f it's .16 bit point is (int)(f*(1<<16))*/
typedef uint32_t FixPoint1616_t;
#endif /* VL53L1_TYPES_H_ */