导航部分效果最好的版本,主分支

This commit is contained in:
2026-04-13 23:30:22 +08:00
commit 350fd830f4
1679 changed files with 1464081 additions and 0 deletions

View File

@@ -0,0 +1,469 @@
/*******************************************************************************
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_H_
#define _VL53L1_PLATFORM_H_
#include "vl53l1_ll_def.h"
#include "vl53l1_platform_log.h"
#define VL53L1_IPP_API
#include "vl53l1_platform_ipp_imports.h"
#include "vl53l1_platform_user_data.h"
#ifdef __cplusplus
extern "C"
{
#endif
#ifndef VL53_USE_FREERTOS_DELAY
#define VL53_USE_FREERTOS_DELAY 1
#endif
#ifndef VL53L1_DEFAULT_ADDR_8BIT
#define VL53L1_DEFAULT_ADDR_8BIT 0x52u
#endif
/**
* @file vl53l1_platform.h
*
* @brief All end user OS/platform/application porting
*/
/**
* @brief Initialise platform comms.
*
* @param[in] pdev : pointer to device structure (device handle)
* @param[in] comms_type : selects between I2C and SPI
* @param[in] comms_speed_khz : unsigned short containing the I2C speed in kHz
*
* @return VL53L1_ERROR_NONE Success
* @return "Other error code" See ::VL53L1_Error
*/
VL53L1_Error VL53L1_CommsInitialise(
VL53L1_Dev_t *pdev,
uint8_t comms_type,
uint16_t comms_speed_khz);
/**
* @brief Close platform comms.
*
* @param[in] pdev : pointer to device structure (device handle)
*
* @return VL53L1_ERROR_NONE Success
* @return "Other error code" See ::VL53L1_Error
*/
VL53L1_Error VL53L1_CommsClose(
VL53L1_Dev_t *pdev);
/**
* @brief Writes the supplied byte buffer to the device
*
* @param[in] pdev : pointer to device structure (device handle)
* @param[in] index : uint16_t register index value
* @param[in] pdata : pointer to uint8_t (byte) buffer containing the data to be written
* @param[in] count : number of bytes in the supplied byte buffer
*
* @return VL53L1_ERROR_NONE Success
* @return "Other error code" See ::VL53L1_Error
*/
VL53L1_Error VL53L1_WriteMulti(
VL53L1_Dev_t *pdev,
uint16_t index,
uint8_t *pdata,
uint32_t count);
/**
* @brief Reads the requested number of bytes from the device
*
* @param[in] pdev : pointer to device structure (device handle)
* @param[in] index : uint16_t register index value
* @param[out] pdata : pointer to the uint8_t (byte) buffer to store read data
* @param[in] count : number of bytes to read
*
* @return VL53L1_ERROR_NONE Success
* @return "Other error code" See ::VL53L1_Error
*/
VL53L1_Error VL53L1_ReadMulti(
VL53L1_Dev_t *pdev,
uint16_t index,
uint8_t *pdata,
uint32_t count);
/**
* @brief Writes a single byte to the device
*
* @param[in] pdev : pointer to device structure (device handle)
* @param[in] index : uint16_t register index value
* @param[in] data : uint8_t data value to write
*
* @return VL53L1_ERROR_NONE Success
* @return "Other error code" See ::VL53L1_Error
*/
VL53L1_Error VL53L1_WrByte(
VL53L1_Dev_t *pdev,
uint16_t index,
uint8_t data);
/**
* @brief Writes a single word (16-bit unsigned) to the device
*
* Manages the big-endian nature of the device register map
* (first byte written is the MS byte).
*
* @param[in] pdev : pointer to device structure (device handle)
* @param[in] index : uint16_t register index value
* @param[in] data : uin16_t data value write
*
* @return VL53L1_ERROR_NONE Success
* @return "Other error code" See ::VL53L1_Error
*/
VL53L1_Error VL53L1_WrWord(
VL53L1_Dev_t *pdev,
uint16_t index,
uint16_t data);
/**
* @brief Writes a single dword (32-bit unsigned) to the device
*
* Manages the big-endian nature of the device register map
* (first byte written is the MS byte).
*
* @param[in] pdev : pointer to device structure (device handle)
* @param[in] index : uint16_t register index value
* @param[in] data : uint32_t data value to write
*
* @return VL53L1_ERROR_NONE Success
* @return "Other error code" See ::VL53L1_Error
*/
VL53L1_Error VL53L1_WrDWord(
VL53L1_Dev_t *pdev,
uint16_t index,
uint32_t data);
/**
* @brief Reads a single byte from the device
*
* @param[in] pdev : pointer to device structure (device handle)
* @param[in] index : uint16_t register index
* @param[out] pdata : pointer to uint8_t data value
*
* @return VL53L1_ERROR_NONE Success
* @return "Other error code" See ::VL53L1_Error
*
*/
VL53L1_Error VL53L1_RdByte(
VL53L1_Dev_t *pdev,
uint16_t index,
uint8_t *pdata);
/**
* @brief Reads a single word (16-bit unsigned) from the device
*
* Manages the big-endian nature of the device (first byte read is the MS byte).
*
* @param[in] pdev : pointer to device structure (device handle)
* @param[in] index : uint16_t register index value
* @param[out] pdata : pointer to uint16_t data value
*
* @return VL53L1_ERROR_NONE Success
* @return "Other error code" See ::VL53L1_Error
*/
VL53L1_Error VL53L1_RdWord(
VL53L1_Dev_t *pdev,
uint16_t index,
uint16_t *pdata);
/**
* @brief Reads a single dword (32-bit unsigned) from the device
*
* Manages the big-endian nature of the device (first byte read is the MS byte).
*
* @param[in] pdev : pointer to device structure (device handle)
* @param[in] index : uint16_t register index value
* @param[out] pdata : pointer to uint32_t data value
*
* @return VL53L1_ERROR_NONE Success
* @return "Other error code" See ::VL53L1_Error
*/
VL53L1_Error VL53L1_RdDWord(
VL53L1_Dev_t *pdev,
uint16_t index,
uint32_t *pdata);
/**
* @brief Implements a programmable wait in us
*
* @param[in] pdev : pointer to device structure (device handle)
* @param[in] wait_us : integer wait in micro seconds
*
* @return VL53L1_ERROR_NONE Success
* @return "Other error code" See ::VL53L1_Error
*/
VL53L1_Error VL53L1_WaitUs(
VL53L1_Dev_t *pdev,
int32_t wait_us);
/**
* @brief Implements a programmable wait in ms
*
* @param[in] pdev : pointer to device structure (device handle)
* @param[in] wait_ms : integer wait in milliseconds
*
* @return VL53L1_ERROR_NONE Success
* @return "Other error code" See ::VL53L1_Error
*/
VL53L1_Error VL53L1_WaitMs(
VL53L1_Dev_t *pdev,
int32_t wait_ms);
/**
* @brief Get the frequency of the timer used for ranging results time stamps
*
* @param[out] ptimer_freq_hz : pointer for timer frequency
*
* @return VL53L1_ERROR_NONE Success
* @return "Other error code" See ::VL53L1_Error
*/
VL53L1_Error VL53L1_GetTimerFrequency(int32_t *ptimer_freq_hz);
/**
* @brief Get the timer value in units of timer_freq_hz (see VL53L1_get_timestamp_frequency())
*
* @param[out] ptimer_count : pointer for timer count value
*
* @return VL53L1_ERROR_NONE Success
* @return "Other error code" See ::VL53L1_Error
*/
VL53L1_Error VL53L1_GetTimerValue(int32_t *ptimer_count);
/**
* @brief Set the mode of a specified GPIO pin
*
* @param pin - an identifier specifying the pin being modified - defined per platform
*
* @param mode - an identifier specifying the requested mode - defined per platform
*
* @return VL53L1_ERROR_NONE Success
* @return "Other error code" See ::VL53L1_Error
*/
VL53L1_Error VL53L1_GpioSetMode(uint8_t pin, uint8_t mode);
/**
* @brief Set the value of a specified GPIO pin
*
* @param pin - an identifier specifying the pin being modified - defined per platform
*
* @param value - a value to set on the GPIO pin - typically 0 or 1
*
* @return VL53L1_ERROR_NONE Success
* @return "Other error code" See ::VL53L1_Error
*/
VL53L1_Error VL53L1_GpioSetValue(uint8_t pin, uint8_t value);
/**
* @brief Get the value of a specified GPIO pin
*
* @param pin - an identifier specifying the pin being modified - defined per platform
*
* @param pvalue - a value retrieved from the GPIO pin - typically 0 or 1
*
* @return VL53L1_ERROR_NONE Success
* @return "Other error code" See ::VL53L1_Error
*/
VL53L1_Error VL53L1_GpioGetValue(uint8_t pin, uint8_t *pvalue);
/**
* @brief Sets and clears the XShutdown pin on the Ewok
*
* @param value - the value for xshutdown - 0 = in reset, 1 = operational
*
* @return VL53L1_ERROR_NONE Success
* @return "Other error code" See ::VL53L1_Error
*/
VL53L1_Error VL53L1_GpioXshutdown(uint8_t value);
/**
* @brief Sets and clears the Comms Mode pin (NCS) on the Ewok
*
* @param value - the value for comms select - 0 = I2C, 1 = SPI
*
* @return VL53L1_ERROR_NONE Success
* @return "Other error code" See ::VL53L1_Error
*/
VL53L1_Error VL53L1_GpioCommsSelect(uint8_t value);
/**
* @brief Enables and disables the power to the Ewok module
*
* @param value - the state of the power supply - 0 = power off, 1 = power on
*
* @return VL53L1_ERROR_NONE Success
* @return "Other error code" See ::VL53L1_Error
*/
VL53L1_Error VL53L1_GpioPowerEnable(uint8_t value);
/**
* @brief Enables callbacks to the supplied funtion pointer when Ewok interrupts ocurr
*
* @param function - a function callback supplies by the caller, for interrupt notification
* @param edge_type - falling edge or rising edge interrupt detection
*
* @return VL53L1_ERROR_NONE Success
* @return "Other error code" See ::VL53L1_Error
*/
VL53L1_Error VL53L1_GpioInterruptEnable(void (*function)(void), uint8_t edge_type);
/**
* @brief Disables the callback on Ewok interrupts
*
* @return VL53L1_ERROR_NONE Success
* @return "Other error code" See ::VL53L1_Error
*/
VL53L1_Error VL53L1_GpioInterruptDisable(void);
/*
* @brief Gets current system tick count in [ms]
*
* @return time_ms : current time in [ms]
*
* @return VL53L1_ERROR_NONE Success
* @return "Other error code" See ::VL53L1_Error
*/
VL53L1_Error VL53L1_GetTickCount(
VL53L1_Dev_t *pdev,
uint32_t *ptime_ms);
void VL53L1_PlatformAttachBus(
VL53L1_Dev_t *pdev,
I2C_HandleTypeDef *hi2c,
uint8_t i2c_addr_8bit,
uint16_t io_timeout_ms,
void *bus_lock);
void VL53L1_PlatformAttachPins(
VL53L1_Dev_t *pdev,
GPIO_TypeDef *xshut_port,
uint16_t xshut_pin,
GPIO_TypeDef *gpio1_port,
uint16_t gpio1_pin);
VL53L1_Error VL53L1_PlatformSetXShut(
VL53L1_Dev_t *pdev,
GPIO_PinState state);
VL53L1_Error VL53L1_PlatformBootDevice(
VL53L1_Dev_t *pdev,
uint32_t reset_low_ms,
uint32_t boot_wait_ms);
VL53L1_Error VL53L1_PlatformChangeAddress(
VL53L1_Dev_t *pdev,
uint8_t new_addr_8bit);
uint32_t VL53L1_PlatformGetTick(void);
/**
* @brief Register "wait for value" polling routine
*
* Port of the V2WReg Script function WaitValueMaskEx()
*
* @param[in] pdev : pointer to device structure (device handle)
* @param[in] timeout_ms : timeout in [ms]
* @param[in] index : uint16_t register index value
* @param[in] value : value to wait for
* @param[in] mask : mask to be applied before comparison with value
* @param[in] poll_delay_ms : polling delay been each read transaction in [ms]
*
* @return VL53L1_ERROR_NONE Success
* @return "Other error code" See ::VL53L1_Error
*/
VL53L1_Error VL53L1_WaitValueMaskEx(
VL53L1_Dev_t *pdev,
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,90 @@
/*******************************************************************************
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_INIT_H_
#define _VL53L1_PLATFORM_INIT_H_
#include "vl53l1_platform.h"
#ifdef __cplusplus
extern "C"
{
#endif
/**
* @file vl53l1_platform_init.h
*
* @brief EwokPlus25 comms and GPIO init
*/
/**
* @brief Initialise platform comms, GPIO and reset device
*
* Initialises comms, sets the states of GPIO (xshutdown, ncs,
* EVK device power regulator enable) and resets the device
*
* @param[in] pdev : pointer to device structure (device handle)
* @param[in] i2c_slave_address : I2C slave address
* @param[in] comms_type : Comms type: VL53L1_I2C or VL53L1_SPI
* @param[in] comms_speed_khz : 400kHz recommended for I2C
*
* @return VL53L1_ERROR_NONE Success
* @return "Other error code" See ::VL53L1_Error
*/
VL53L1_Error VL53L1_platform_init(
VL53L1_Dev_t *pdev,
uint8_t i2c_slave_address,
uint8_t comms_type,
uint16_t comms_speed_khz);
/**
* @brief Close platform comms and GPIO
*
* Puts the device into reset, disables the EVK device power regulator
* and closes comms
*
* @param[in] pdev : pointer to device structure (device handle)
*
* @return VL53L1_ERROR_NONE Success
* @return "Other error code" See ::VL53L1_Error
*/
VL53L1_Error VL53L1_platform_terminate(
VL53L1_Dev_t *pdev);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,6 @@
#ifdef VL53L1_NEEDS_IPP
# undef VL53L1_IPP_API
# define VL53L1_IPP_API __declspec(dllimport)
# pragma comment (lib, "EwokPlus25API_IPP")
#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 1
/*!< 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,135 @@
/*******************************************************************************
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_DATA_H_
#define _VL53L1_PLATFORM_USER_DATA_H_
#ifndef __KERNEL__
#include <stdlib.h>
#endif
#include "main.h"
#include "vl53l1_def.h"
#ifdef __cplusplus
extern "C"
{
#endif
/**
* @file vl53l1_platform_user_data.h
*
* @brief All end user OS/platform/application porting
*/
/** @brief Contains the current state and internal values of the API
*/
typedef struct {
VL53L1_DevData_t Data;
/*!< Low Level Driver data structure */
uint8_t i2c_slave_address;
/*!< ST API expects the 8-bit I2C address, default 0x52 */
uint8_t comms_type;
/*!< Type of comms : VL53L1_I2C or VL53L1_SPI */
uint16_t comms_speed_khz;
/*!< Comms speed [kHz] : typically 400kHz for I2C */
I2C_HandleTypeDef *hi2c;
GPIO_TypeDef *xshut_port;
uint16_t xshut_pin;
GPIO_TypeDef *gpio1_port;
uint16_t gpio1_pin;
void *bus_lock;
const char *name;
uint8_t id;
uint8_t is_present;
uint16_t io_timeout_ms;
uint32_t new_data_ready_poll_duration_ms;
/*!< New data ready poll duration in ms - for debug */
} VL53L1_Dev_t;
/**
* @brief Declare the device Handle as a pointer of the structure @a VL53L1_Dev_t.
*
*/
typedef VL53L1_Dev_t *VL53L1_DEV;
/**
* @def PALDevDataGet
* @brief Get ST private structure @a VL53L1_DevData_t data access
*
* @param Dev Device Handle
* @param field ST structure field name
* It maybe used and as real data "ref" not just as "get" for sub-structure item
* like PALDevDataGet(FilterData.field)[i] or
* PALDevDataGet(FilterData.MeasurementIndex)++
*/
#define PALDevDataGet(Dev, field) (Dev->Data.field)
/**
* @def PALDevDataSet(Dev, field, data)
* @brief Set ST private structure @a VL53L1_DevData_t data field
* @param Dev Device Handle
* @param field ST structure field name
* @param data Data to be set
*/
#define PALDevDataSet(Dev, field, data) ((Dev->Data.field) = (data))
/**
* @def VL53L1DevStructGetLLDriverHandle
* @brief Get LL Driver handle @a VL53L0_Dev_t data access
*
* @param Dev Device Handle
*/
#define VL53L1DevStructGetLLDriverHandle(Dev) (&Dev->Data.LLData)
/**
* @def VL53L1DevStructGetLLResultsHandle
* @brief Get LL Results handle @a VL53L0_Dev_t data access
*
* @param Dev Device Handle
*/
#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_

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_ */

View File

@@ -0,0 +1,539 @@
#include "vl53l1_platform.h"
#include "vl53l1_api.h"
#if VL53_USE_FREERTOS_DELAY
#include "FreeRTOS.h"
#include "task.h"
#endif
#if defined(configSUPPORT_STATIC_ALLOCATION) || defined(configUSE_MUTEXES)
#include "semphr.h"
#define VL53L1_USE_FREERTOS_MUTEX 1
#else
#define VL53L1_USE_FREERTOS_MUTEX 0
#endif
static VL53L1_Dev_t *s_platform_default_dev;
static VL53L1_Error vl53l1_hal_to_pal(HAL_StatusTypeDef hal_status)
{
switch (hal_status) {
case HAL_OK:
return VL53L1_ERROR_NONE;
case HAL_TIMEOUT:
return VL53L1_ERROR_TIME_OUT;
default:
return VL53L1_ERROR_CONTROL_INTERFACE;
}
}
static VL53L1_Error vl53l1_validate_dev(VL53L1_Dev_t *pdev)
{
if ((pdev == NULL) || (pdev->hi2c == NULL)) {
return VL53L1_ERROR_CONTROL_INTERFACE;
}
if (pdev->i2c_slave_address == 0u) {
return VL53L1_ERROR_INVALID_PARAMS;
}
return VL53L1_ERROR_NONE;
}
static VL53L1_Error vl53l1_bus_lock(VL53L1_Dev_t *pdev)
{
#if VL53L1_USE_FREERTOS_MUTEX
if ((pdev != NULL) && (pdev->bus_lock != NULL)) {
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
const TickType_t wait_ticks = pdMS_TO_TICKS((pdev->io_timeout_ms == 0u) ? 10u : pdev->io_timeout_ms);
if (xSemaphoreTake((SemaphoreHandle_t)pdev->bus_lock, wait_ticks) != pdTRUE) {
return VL53L1_ERROR_TIME_OUT;
}
}
}
#else
SUPPRESS_UNUSED_WARNING(pdev);
#endif
return VL53L1_ERROR_NONE;
}
static void vl53l1_bus_unlock(VL53L1_Dev_t *pdev)
{
#if VL53L1_USE_FREERTOS_MUTEX
if ((pdev != NULL) && (pdev->bus_lock != NULL)) {
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
(void)xSemaphoreGive((SemaphoreHandle_t)pdev->bus_lock);
}
}
#else
SUPPRESS_UNUSED_WARNING(pdev);
#endif
}
static void vl53l1_delay_ms(uint32_t wait_ms)
{
if (wait_ms == 0u) {
return;
}
#if VL53_USE_FREERTOS_DELAY
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
vTaskDelay(pdMS_TO_TICKS(wait_ms));
return;
}
#endif
HAL_Delay(wait_ms);
}
static void vl53l1_enable_cycle_counter(void)
{
if ((CoreDebug->DEMCR & CoreDebug_DEMCR_TRCENA_Msk) == 0u) {
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
}
if ((DWT->CTRL & DWT_CTRL_CYCCNTENA_Msk) == 0u) {
DWT->CYCCNT = 0u;
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
}
}
static void vl53l1_delay_us_blocking(uint32_t wait_us)
{
uint32_t cycles_per_us;
uint32_t start_cycles;
uint32_t wait_cycles;
if (wait_us == 0u) {
return;
}
cycles_per_us = HAL_RCC_GetHCLKFreq() / 1000000u;
if (cycles_per_us == 0u) {
HAL_Delay(1u);
return;
}
vl53l1_enable_cycle_counter();
start_cycles = DWT->CYCCNT;
wait_cycles = cycles_per_us * wait_us;
while ((DWT->CYCCNT - start_cycles) < wait_cycles) {
}
}
void VL53L1_PlatformAttachBus(
VL53L1_Dev_t *pdev,
I2C_HandleTypeDef *hi2c,
uint8_t i2c_addr_8bit,
uint16_t io_timeout_ms,
void *bus_lock)
{
if (pdev == NULL) {
return;
}
pdev->hi2c = hi2c;
pdev->i2c_slave_address = i2c_addr_8bit;
pdev->io_timeout_ms = (io_timeout_ms == 0u) ? 100u : io_timeout_ms;
pdev->bus_lock = bus_lock;
pdev->comms_type = VL53L1_I2C;
if (pdev->comms_speed_khz == 0u) {
pdev->comms_speed_khz = 400u;
}
if (s_platform_default_dev == NULL) {
s_platform_default_dev = pdev;
}
}
void VL53L1_PlatformAttachPins(
VL53L1_Dev_t *pdev,
GPIO_TypeDef *xshut_port,
uint16_t xshut_pin,
GPIO_TypeDef *gpio1_port,
uint16_t gpio1_pin)
{
if (pdev == NULL) {
return;
}
pdev->xshut_port = xshut_port;
pdev->xshut_pin = xshut_pin;
pdev->gpio1_port = gpio1_port;
pdev->gpio1_pin = gpio1_pin;
}
VL53L1_Error VL53L1_PlatformSetXShut(
VL53L1_Dev_t *pdev,
GPIO_PinState state)
{
if ((pdev == NULL) || (pdev->xshut_port == NULL)) {
return VL53L1_ERROR_INVALID_PARAMS;
}
HAL_GPIO_WritePin(pdev->xshut_port, pdev->xshut_pin, state);
return VL53L1_ERROR_NONE;
}
VL53L1_Error VL53L1_PlatformBootDevice(
VL53L1_Dev_t *pdev,
uint32_t reset_low_ms,
uint32_t boot_wait_ms)
{
VL53L1_Error status = VL53L1_PlatformSetXShut(pdev, GPIO_PIN_RESET);
if (status != VL53L1_ERROR_NONE) {
return status;
}
vl53l1_delay_ms(reset_low_ms);
status = VL53L1_PlatformSetXShut(pdev, GPIO_PIN_SET);
if (status != VL53L1_ERROR_NONE) {
return status;
}
vl53l1_delay_ms(boot_wait_ms);
return VL53L1_ERROR_NONE;
}
uint32_t VL53L1_PlatformGetTick(void)
{
return HAL_GetTick();
}
VL53L1_Error VL53L1_CommsInitialise(
VL53L1_Dev_t *pdev,
uint8_t comms_type,
uint16_t comms_speed_khz)
{
if (pdev == NULL) {
return VL53L1_ERROR_INVALID_PARAMS;
}
pdev->comms_type = comms_type;
pdev->comms_speed_khz = comms_speed_khz;
if (comms_type != VL53L1_I2C) {
return VL53L1_ERROR_CONTROL_INTERFACE;
}
pdev->comms_type = VL53L1_I2C;
return vl53l1_validate_dev(pdev);
}
VL53L1_Error VL53L1_CommsClose(VL53L1_Dev_t *pdev)
{
SUPPRESS_UNUSED_WARNING(pdev);
return VL53L1_ERROR_NONE;
}
VL53L1_Error VL53L1_WriteMulti(
VL53L1_Dev_t *pdev,
uint16_t index,
uint8_t *pdata,
uint32_t count)
{
HAL_StatusTypeDef hal_status;
VL53L1_Error status;
if ((pdata == NULL) || (count == 0u) || (count > 0xFFFFu)) {
return VL53L1_ERROR_INVALID_PARAMS;
}
status = vl53l1_validate_dev(pdev);
if (status != VL53L1_ERROR_NONE) {
return status;
}
status = vl53l1_bus_lock(pdev);
if (status != VL53L1_ERROR_NONE) {
return status;
}
hal_status = HAL_I2C_Mem_Write(
pdev->hi2c,
pdev->i2c_slave_address,
index,
I2C_MEMADD_SIZE_16BIT,
pdata,
(uint16_t)count,
pdev->io_timeout_ms);
vl53l1_bus_unlock(pdev);
return vl53l1_hal_to_pal(hal_status);
}
VL53L1_Error VL53L1_ReadMulti(
VL53L1_Dev_t *pdev,
uint16_t index,
uint8_t *pdata,
uint32_t count)
{
HAL_StatusTypeDef hal_status;
VL53L1_Error status;
if ((pdata == NULL) || (count == 0u) || (count > 0xFFFFu)) {
return VL53L1_ERROR_INVALID_PARAMS;
}
status = vl53l1_validate_dev(pdev);
if (status != VL53L1_ERROR_NONE) {
return status;
}
status = vl53l1_bus_lock(pdev);
if (status != VL53L1_ERROR_NONE) {
return status;
}
hal_status = HAL_I2C_Mem_Read(
pdev->hi2c,
pdev->i2c_slave_address,
index,
I2C_MEMADD_SIZE_16BIT,
pdata,
(uint16_t)count,
pdev->io_timeout_ms);
vl53l1_bus_unlock(pdev);
return vl53l1_hal_to_pal(hal_status);
}
VL53L1_Error VL53L1_WrByte(
VL53L1_Dev_t *pdev,
uint16_t index,
uint8_t data)
{
return VL53L1_WriteMulti(pdev, index, &data, 1u);
}
VL53L1_Error VL53L1_WrWord(
VL53L1_Dev_t *pdev,
uint16_t index,
uint16_t data)
{
uint8_t buffer[2];
buffer[0] = (uint8_t)(data >> 8);
buffer[1] = (uint8_t)(data & 0xFFu);
return VL53L1_WriteMulti(pdev, index, buffer, VL53L1_BYTES_PER_WORD);
}
VL53L1_Error VL53L1_WrDWord(
VL53L1_Dev_t *pdev,
uint16_t index,
uint32_t data)
{
uint8_t buffer[4];
buffer[0] = (uint8_t)(data >> 24);
buffer[1] = (uint8_t)(data >> 16);
buffer[2] = (uint8_t)(data >> 8);
buffer[3] = (uint8_t)(data & 0xFFu);
return VL53L1_WriteMulti(pdev, index, buffer, VL53L1_BYTES_PER_DWORD);
}
VL53L1_Error VL53L1_RdByte(
VL53L1_Dev_t *pdev,
uint16_t index,
uint8_t *pdata)
{
if (pdata == NULL) {
return VL53L1_ERROR_INVALID_PARAMS;
}
return VL53L1_ReadMulti(pdev, index, pdata, 1u);
}
VL53L1_Error VL53L1_RdWord(
VL53L1_Dev_t *pdev,
uint16_t index,
uint16_t *pdata)
{
uint8_t buffer[2] = {0u, 0u};
VL53L1_Error status;
if (pdata == NULL) {
return VL53L1_ERROR_INVALID_PARAMS;
}
status = VL53L1_ReadMulti(pdev, index, buffer, VL53L1_BYTES_PER_WORD);
if (status == VL53L1_ERROR_NONE) {
*pdata = (uint16_t)(((uint16_t)buffer[0] << 8) | buffer[1]);
}
return status;
}
VL53L1_Error VL53L1_RdDWord(
VL53L1_Dev_t *pdev,
uint16_t index,
uint32_t *pdata)
{
uint8_t buffer[4] = {0u, 0u, 0u, 0u};
VL53L1_Error status;
if (pdata == NULL) {
return VL53L1_ERROR_INVALID_PARAMS;
}
status = VL53L1_ReadMulti(pdev, index, buffer, VL53L1_BYTES_PER_DWORD);
if (status == VL53L1_ERROR_NONE) {
*pdata = ((uint32_t)buffer[0] << 24)
| ((uint32_t)buffer[1] << 16)
| ((uint32_t)buffer[2] << 8)
| (uint32_t)buffer[3];
}
return status;
}
VL53L1_Error VL53L1_WaitUs(
VL53L1_Dev_t *pdev,
int32_t wait_us)
{
SUPPRESS_UNUSED_WARNING(pdev);
if (wait_us <= 0) {
return VL53L1_ERROR_NONE;
}
if (wait_us >= 1000) {
vl53l1_delay_ms((uint32_t)wait_us / 1000u);
wait_us %= 1000;
}
vl53l1_delay_us_blocking((uint32_t)wait_us);
return VL53L1_ERROR_NONE;
}
VL53L1_Error VL53L1_WaitMs(
VL53L1_Dev_t *pdev,
int32_t wait_ms)
{
SUPPRESS_UNUSED_WARNING(pdev);
if (wait_ms > 0) {
vl53l1_delay_ms((uint32_t)wait_ms);
}
return VL53L1_ERROR_NONE;
}
VL53L1_Error VL53L1_GetTimerFrequency(int32_t *ptimer_freq_hz)
{
if (ptimer_freq_hz == NULL) {
return VL53L1_ERROR_INVALID_PARAMS;
}
*ptimer_freq_hz = 1000;
return VL53L1_ERROR_NONE;
}
VL53L1_Error VL53L1_GetTimerValue(int32_t *ptimer_count)
{
if (ptimer_count == NULL) {
return VL53L1_ERROR_INVALID_PARAMS;
}
*ptimer_count = (int32_t)HAL_GetTick();
return VL53L1_ERROR_NONE;
}
VL53L1_Error VL53L1_GpioSetMode(uint8_t pin, uint8_t mode)
{
SUPPRESS_UNUSED_WARNING(pin);
SUPPRESS_UNUSED_WARNING(mode);
return VL53L1_ERROR_NONE;
}
VL53L1_Error VL53L1_GpioSetValue(uint8_t pin, uint8_t value)
{
SUPPRESS_UNUSED_WARNING(pin);
SUPPRESS_UNUSED_WARNING(value);
return VL53L1_ERROR_NONE;
}
VL53L1_Error VL53L1_GpioGetValue(uint8_t pin, uint8_t *pvalue)
{
SUPPRESS_UNUSED_WARNING(pin);
if (pvalue == NULL) {
return VL53L1_ERROR_INVALID_PARAMS;
}
*pvalue = 0u;
return VL53L1_ERROR_NONE;
}
VL53L1_Error VL53L1_GpioXshutdown(uint8_t value)
{
if (s_platform_default_dev == NULL) {
return VL53L1_ERROR_CONTROL_INTERFACE;
}
return VL53L1_PlatformSetXShut(s_platform_default_dev, value ? GPIO_PIN_SET : GPIO_PIN_RESET);
}
VL53L1_Error VL53L1_GpioCommsSelect(uint8_t value)
{
SUPPRESS_UNUSED_WARNING(value);
return VL53L1_ERROR_NONE;
}
VL53L1_Error VL53L1_GpioPowerEnable(uint8_t value)
{
SUPPRESS_UNUSED_WARNING(value);
return VL53L1_ERROR_NONE;
}
VL53L1_Error VL53L1_GpioInterruptEnable(void (*function)(void), uint8_t edge_type)
{
SUPPRESS_UNUSED_WARNING(function);
SUPPRESS_UNUSED_WARNING(edge_type);
return VL53L1_ERROR_NONE;
}
VL53L1_Error VL53L1_GpioInterruptDisable(void)
{
return VL53L1_ERROR_NONE;
}
VL53L1_Error VL53L1_GetTickCount(
VL53L1_Dev_t *pdev,
uint32_t *ptick_count_ms)
{
SUPPRESS_UNUSED_WARNING(pdev);
if (ptick_count_ms == NULL) {
return VL53L1_ERROR_INVALID_PARAMS;
}
*ptick_count_ms = HAL_GetTick();
return VL53L1_ERROR_NONE;
}
VL53L1_Error VL53L1_WaitValueMaskEx(
VL53L1_Dev_t *pdev,
uint32_t timeout_ms,
uint16_t index,
uint8_t value,
uint8_t mask,
uint32_t poll_delay_ms)
{
VL53L1_Error status = VL53L1_ERROR_NONE;
uint32_t start_time_ms = 0u;
uint32_t current_time_ms = 0u;
uint8_t byte_value = 0u;
uint8_t found = 0u;
if (pdev == NULL) {
return VL53L1_ERROR_INVALID_PARAMS;
}
status = VL53L1_GetTickCount(pdev, &start_time_ms);
if (status != VL53L1_ERROR_NONE) {
return status;
}
pdev->new_data_ready_poll_duration_ms = 0u;
while ((status == VL53L1_ERROR_NONE) &&
(pdev->new_data_ready_poll_duration_ms < timeout_ms) &&
(found == 0u)) {
status = VL53L1_RdByte(pdev, index, &byte_value);
if (status != VL53L1_ERROR_NONE) {
break;
}
if ((byte_value & mask) == value) {
found = 1u;
break;
}
if (poll_delay_ms > 0u) {
status = VL53L1_WaitMs(pdev, (int32_t)poll_delay_ms);
}
VL53L1_GetTickCount(pdev, &current_time_ms);
pdev->new_data_ready_poll_duration_ms = current_time_ms - start_time_ms;
}
if ((found == 0u) && (status == VL53L1_ERROR_NONE)) {
status = VL53L1_ERROR_TIME_OUT;
}
return status;
}
VL53L1_Error VL53L1_PlatformChangeAddress(
VL53L1_Dev_t *pdev,
uint8_t new_addr_8bit)
{
VL53L1_Error status;
if ((pdev == NULL) || (new_addr_8bit == 0u)) {
return VL53L1_ERROR_INVALID_PARAMS;
}
status = VL53L1_SetDeviceAddress(pdev, new_addr_8bit);
if (status == VL53L1_ERROR_NONE) {
pdev->i2c_slave_address = new_addr_8bit;
vl53l1_delay_ms(2u);
}
return status;
}

View File

@@ -0,0 +1,103 @@
/*******************************************************************************
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.
******************************************************************************/
/**
* @file vl53l1_platform_init.c
* @brief EwokPlus25 comms and GPIO init
*
*/
#include "vl53l1_ll_def.h"
#include "vl53l1_platform.h"
#include "vl53l1_platform_init.h"
VL53L1_Error VL53L1_platform_init(
VL53L1_Dev_t *pdev,
uint8_t i2c_slave_address,
uint8_t comms_type,
uint16_t comms_speed_khz)
{
/*
* Initialise comms, GPIOs (xshutdown, ncs, EVK power regulator enable)
* and reset Device
*/
VL53L1_Error status = VL53L1_ERROR_NONE;
if (pdev == NULL)
return VL53L1_ERROR_INVALID_PARAMS;
/* remember comms settings */
pdev->i2c_slave_address = (i2c_slave_address == 0u) ? VL53L1_DEFAULT_ADDR_8BIT : i2c_slave_address;
pdev->comms_type = comms_type;
pdev->comms_speed_khz = (comms_speed_khz == 0u) ? 400u : comms_speed_khz;
if (status == VL53L1_ERROR_NONE) /*lint !e774 always true*/
status =
VL53L1_CommsInitialise(
pdev,
pdev->comms_type,
pdev->comms_speed_khz);
pdev->io_timeout_ms = (pdev->io_timeout_ms == 0u) ? 100u : pdev->io_timeout_ms;
if ((status == VL53L1_ERROR_NONE) && (pdev->xshut_port != NULL)) {
status = VL53L1_PlatformBootDevice(pdev, 2u, 2u);
} else if (status == VL53L1_ERROR_NONE) {
status = VL53L1_WaitMs(pdev, 2);
}
return status;
}
VL53L1_Error VL53L1_platform_terminate(
VL53L1_Dev_t *pdev)
{
/*
* Puts the device into reset, disables EVK power regulator
* and closes comms
*/
VL53L1_Error status = VL53L1_ERROR_NONE;
/* put device in reset when an XSHUT pin is attached */
if ((status == VL53L1_ERROR_NONE) && (pdev != NULL) && (pdev->xshut_port != NULL))
status = VL53L1_PlatformSetXShut(pdev, GPIO_PIN_RESET);
/* close the comms interfaces */
if (status == VL53L1_ERROR_NONE)
status = VL53L1_CommsClose(pdev);
return status;
}

View File

@@ -0,0 +1,131 @@
/*
* COPYRIGHT (C) STMicroelectronics 2015. All rights reserved.
*
* This software is the confidential and proprietary information of
* STMicroelectronics ("Confidential Information"). You shall not
* disclose such Confidential Information and shall use it only in
* accordance with the terms of the license agreement you entered into
* with STMicroelectronics
*
* Programming Golden Rule: Keep it Simple!
*
*/
/**
* @file vl53l1_platform_log.c
*
* @brief Code function definitions for EwokPlus25 Platform Logging Layer
*/
#include <stdio.h> // sprintf(), vsnprintf(), printf()
#include <string.h>
#include <stdarg.h>
#include <stdlib.h>
#include "vl53l1_platform_log.h"
#include "vl53l1_platform_user_config.h"
#ifdef VL53L1_LOG_ENABLE
char * _trace_filename = NULL;
FILE *_tracefile = NULL;
uint32_t _trace_level = VL53L1_TRACE_LEVEL_WARNING;
uint32_t _trace_modules = VL53L1_TRACE_MODULE_NONE;
uint32_t _trace_functions = VL53L1_TRACE_FUNCTION_ALL;
int8_t VL53L1_trace_config(
char *filename,
uint32_t modules,
uint32_t level,
uint32_t functions)
{
int8_t status = 0;
// // Something in the commented out code below causes ncsim to crash!
//
// if (((_trace_filename != NULL) && (_trace_filename != filename)) ||strcmp(filename,"")==0)
// {
// if ( _tracefile != NULL )
// {
// fclose(_tracefile);
// _tracefile = NULL;
// }
// free(_trace_filename);
// _trace_filename = NULL;
// }
//
if (((filename != NULL) && (_tracefile == NULL)) && strcmp(filename,""))
{
_tracefile = fopen(filename, "w+");
//TODO: Add time and header banner to the log file to indicate we've just opened a new log session
if ( _tracefile != NULL )
{
_trace_filename = (char*)malloc((strlen(filename) + 1) * sizeof(char));
strcpy(_trace_filename, filename);
}
else
{
printf("VL53L1_trace_config(): failed to open log file (%s)\n", filename);
status = 1;
}
}
_trace_modules = modules;
_trace_level = level;
_trace_functions = functions;
return status;
}
void VL53L1_trace_print_module_function(uint32_t module, uint32_t level, uint32_t function, const char *format, ...)
{
if ( ((level <=_trace_level) && ((module & _trace_modules) > 0))
|| ((function & _trace_functions) > 0) )
{
va_list arg_list;
char message[VL53L1_MAX_STRING_LENGTH];
va_start(arg_list, format);
vsnprintf(message, VL53L1_MAX_STRING_LENGTH-1, format, arg_list); /*lint !e534 ignore return*/
va_end(arg_list);
if (_tracefile != NULL)
{
fprintf(_tracefile, message); /*lint !e592 ignore format specifier*/
}
else
{
printf(message); /*lint !e592 ignore format specifier*/
}
// if (_tracefile != NULL)
// fprintf(_tracefile, message);
// else
// printf(message);
} /*lint !e438 ignore issues with arg_list*/
}
uint32_t VL53L1_get_trace_functions(void)
{
return _trace_functions;
}
void VL53L1_set_trace_functions(uint32_t function)
{
_trace_functions = function;
}
uint32_t VL53L1_clock(void)
{
/* Returns current tick count in [ms] */
uint32_t tick_count_ms = (uint32_t)clock();
return tick_count_ms;
}
#endif // VL53L1_LOG_ENABLE

View File

@@ -0,0 +1,229 @@
#include "robot_params.h"
#if PARAM_VL53_USE_L1X
#include "vl53_board.h"
#include "FreeRTOS.h"
#include "task.h"
#include "vl53_calibration_config.h"
static void vl53_ema_init(Vl53EMA_t *ema, float alpha)
{
ema->x = 0.0f;
ema->alpha = alpha;
ema->initialized = 0u;
}
static float vl53_ema_update(Vl53EMA_t *ema, float measurement)
{
if (ema->initialized == 0u) {
ema->x = measurement;
ema->initialized = 1u;
return ema->x;
}
ema->x = ema->alpha * measurement + (1.0f - ema->alpha) * ema->x;
return ema->x;
}
static const Vl53L1RuntimeCalibration_t *vl53_get_runtime_calibration(uint8_t id)
{
switch (id) {
case 0: return &k_vl53l1_left_calibration[0];
case 1: return &k_vl53l1_left_calibration[1];
case 2: return &k_vl53l1_right_calibration[0];
case 3: return &k_vl53l1_right_calibration[1];
default: return NULL;
}
}
static VL53L1_Error vl53_apply_runtime_calibration(VL53L1_DEV dev, uint8_t id)
{
const Vl53L1RuntimeCalibration_t *cal = vl53_get_runtime_calibration(id);
if ((cal == NULL) || (cal->calibrated == 0u)) {
return VL53L1_ERROR_NONE;
}
return VL53L1_SetCalibrationData(dev, (VL53L1_CalibrationData_t *)&cal->data);
}
static uint32_t vl53_sanitize_timing_budget_us(uint32_t timing_budget_us)
{
if (timing_budget_us < 20000u) {
return 20000u;
}
if (timing_budget_us > 1000000u) {
return 1000000u;
}
return timing_budget_us;
}
static uint32_t vl53_compute_inter_measurement_ms(uint32_t timing_budget_us)
{
uint32_t timing_budget_ms = (timing_budget_us + 999u) / 1000u;
/* UM2356: inter-measurement period shorter than timing budget时会立即开始下一帧。 */
if (timing_budget_ms < 25u) {
timing_budget_ms = 25u;
}
return timing_budget_ms;
}
static VL53L1_Error vl53_configure_ranging_profile(VL53L1_DEV dev, uint32_t timing_budget_us)
{
VL53L1_Error status;
const uint32_t inter_measurement_ms = vl53_compute_inter_measurement_ms(timing_budget_us);
status = VL53L1_SetPresetMode(dev, VL53L1_PRESETMODE_LITE_RANGING);
if (status != VL53L1_ERROR_NONE) return status;
status = VL53L1_SetDistanceMode(dev, VL53L1_DISTANCEMODE_LONG);
if (status != VL53L1_ERROR_NONE) return status;
status = VL53L1_SetMeasurementTimingBudgetMicroSeconds(dev, timing_budget_us);
if (status != VL53L1_ERROR_NONE) return status;
status = VL53L1_SetInterMeasurementPeriodMilliSeconds(dev, inter_measurement_ms);
if (status != VL53L1_ERROR_NONE) return status;
status = VL53L1_SetLimitCheckEnable(dev, VL53L1_CHECKENABLE_SIGMA_FINAL_RANGE, 1u);
if (status != VL53L1_ERROR_NONE) return status;
status = VL53L1_SetLimitCheckEnable(dev, VL53L1_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE, 1u);
if (status != VL53L1_ERROR_NONE) return status;
return VL53L1_ERROR_NONE;
}
static VL53L1_Error vl53_do_static_init(VL53L1_DEV dev, uint32_t timing_budget_us, uint8_t id)
{
VL53L1_Error status;
status = VL53L1_StaticInit(dev);
if (status != VL53L1_ERROR_NONE) return status;
status = vl53_apply_runtime_calibration(dev, id);
if (status != VL53L1_ERROR_NONE) return status;
return vl53_configure_ranging_profile(dev, timing_budget_us);
}
VL53L1_Error Vl53Board_Init(Vl53Board_t *board, const Vl53BoardHwCfg_t *hw_cfgs, uint8_t count, uint32_t timing_budget_us)
{
if ((board == NULL) || (hw_cfgs == NULL) || (count == 0u) || (count > VL53_MAX_DEVS_PER_BOARD)) {
return VL53L1_ERROR_INVALID_PARAMS;
}
memset(board, 0, sizeof(Vl53Board_t));
board->dev_count = count;
board->timing_budget_us = vl53_sanitize_timing_budget_us((timing_budget_us == 0u) ? 33000u : timing_budget_us);
for (uint8_t i = 0; i < count; i++) {
board->dev[i].name = hw_cfgs[i].name;
board->dev[i].id = hw_cfgs[i].id;
board->dev[i].comms_type = VL53L1_I2C;
board->dev[i].comms_speed_khz = 400u;
board->dev[i].is_present = 0u;
VL53L1_PlatformAttachBus(&board->dev[i], hw_cfgs[i].hi2c, VL53L1_DEFAULT_ADDR_8BIT, 100u, NULL);
VL53L1_PlatformAttachPins(&board->dev[i], hw_cfgs[i].xshut_port, hw_cfgs[i].xshut_pin, NULL, 0u);
(void)VL53L1_PlatformSetXShut(&board->dev[i], GPIO_PIN_RESET);
vl53_ema_init(&board->ema[i], PARAM_VL53_EMA_ALPHA);
}
vTaskDelay(pdMS_TO_TICKS(10u));
for (uint8_t i = 0; i < count; i++) {
if (VL53L1_PlatformSetXShut(&board->dev[i], GPIO_PIN_SET) != VL53L1_ERROR_NONE) continue;
vTaskDelay(pdMS_TO_TICKS(20u));
board->dev[i].i2c_slave_address = VL53L1_DEFAULT_ADDR_8BIT;
if (VL53L1_CommsInitialise(&board->dev[i], VL53L1_I2C, board->dev[i].comms_speed_khz) != VL53L1_ERROR_NONE) continue;
if (VL53L1_WaitDeviceBooted(&board->dev[i]) != VL53L1_ERROR_NONE) continue;
if (VL53L1_PlatformChangeAddress(&board->dev[i], hw_cfgs[i].runtime_addr_8bit) != VL53L1_ERROR_NONE) continue;
if (VL53L1_DataInit(&board->dev[i]) != VL53L1_ERROR_NONE) continue;
if (vl53_do_static_init(&board->dev[i], board->timing_budget_us, hw_cfgs[i].id) != VL53L1_ERROR_NONE) continue;
board->init_mask |= (uint8_t)(1u << i);
board->dev[i].is_present = 1u;
}
return VL53L1_ERROR_NONE;
}
VL53L1_Error Vl53Board_StartContinuous(Vl53Board_t *board)
{
if (board == NULL) return VL53L1_ERROR_INVALID_PARAMS;
for (uint8_t i = 0; i < board->dev_count; i++) {
if (board->init_mask & (1u << i)) {
(void)VL53L1_StartMeasurement(&board->dev[i]);
}
}
return VL53L1_ERROR_NONE;
}
VL53L1_Error Vl53Board_StopContinuous(Vl53Board_t *board)
{
if (board == NULL) return VL53L1_ERROR_INVALID_PARAMS;
for (uint8_t i = 0; i < board->dev_count; i++) {
if (board->init_mask & (1u << i)) {
(void)VL53L1_StopMeasurement(&board->dev[i]);
}
}
return VL53L1_ERROR_NONE;
}
VL53L1_Error Vl53Board_ReadAll(Vl53Board_t *board, Vl53BoardSnapshot_t *snapshot)
{
if ((board == NULL) || (snapshot == NULL)) return VL53L1_ERROR_INVALID_PARAMS;
memset(snapshot, 0, sizeof(Vl53BoardSnapshot_t));
snapshot->tick_ms = xTaskGetTickCount() * portTICK_PERIOD_MS;
for (uint8_t i = 0; i < board->dev_count; i++) {
if ((board->init_mask & (1u << i)) == 0u) {
snapshot->range_status[i] = 255u;
continue;
}
uint8_t ready = 0u;
if (VL53L1_GetMeasurementDataReady(&board->dev[i], &ready) != VL53L1_ERROR_NONE) continue;
if (ready != 0u) {
VL53L1_RangingMeasurementData_t data;
memset(&data, 0, sizeof(data));
if (VL53L1_GetRangingMeasurementData(&board->dev[i], &data) == VL53L1_ERROR_NONE) {
snapshot->range_mm[i] = (data.RangeMilliMeter < 0) ? 0u : (uint16_t)data.RangeMilliMeter;
snapshot->range_status[i] = data.RangeStatus;
if (data.RangeStatus == 0u) {
snapshot->valid_mask |= (uint8_t)(1u << i);
#if PARAM_VL53_USE_EMA_FILTER
snapshot->range_mm_filtered[i] = vl53_ema_update(&board->ema[i], (float)snapshot->range_mm[i]);
#else
snapshot->range_mm_filtered[i] = (float)snapshot->range_mm[i];
board->ema[i].x = (float)snapshot->range_mm[i];
board->ema[i].initialized = 1u;
#endif
} else {
snapshot->range_mm_filtered[i] = board->ema[i].x;
}
(void)VL53L1_ClearInterruptAndStartMeasurement(&board->dev[i]);
}
} else {
snapshot->range_mm_filtered[i] = board->ema[i].x;
}
}
return VL53L1_ERROR_NONE;
}
#endif

View File

@@ -0,0 +1,56 @@
#ifndef VL53_BOARD_H
#define VL53_BOARD_H
#include <stdint.h>
#include <string.h>
#include "vl53l1_api.h"
#include "vl53l1_platform.h"
#ifdef __cplusplus
extern "C" {
#endif
#define VL53_MAX_DEVS_PER_BOARD 4
typedef struct {
I2C_HandleTypeDef *hi2c;
GPIO_TypeDef *xshut_port;
uint16_t xshut_pin;
uint8_t runtime_addr_8bit;
const char *name;
uint8_t id;
} Vl53BoardHwCfg_t;
typedef struct {
float x;
float alpha;
uint8_t initialized;
} Vl53EMA_t;
typedef struct {
uint32_t tick_ms;
uint16_t range_mm[VL53_MAX_DEVS_PER_BOARD];
float range_mm_filtered[VL53_MAX_DEVS_PER_BOARD];
uint8_t range_status[VL53_MAX_DEVS_PER_BOARD];
uint8_t valid_mask;
} Vl53BoardSnapshot_t;
typedef struct {
VL53L1_Dev_t dev[VL53_MAX_DEVS_PER_BOARD];
Vl53EMA_t ema[VL53_MAX_DEVS_PER_BOARD];
uint8_t init_mask;
uint8_t dev_count;
uint32_t timing_budget_us;
} Vl53Board_t;
VL53L1_Error Vl53Board_Init(Vl53Board_t *board, const Vl53BoardHwCfg_t *hw_cfgs, uint8_t count, uint32_t timing_budget_us);
VL53L1_Error Vl53Board_StartContinuous(Vl53Board_t *board);
VL53L1_Error Vl53Board_StopContinuous(Vl53Board_t *board);
VL53L1_Error Vl53Board_ReadAll(Vl53Board_t *board, Vl53BoardSnapshot_t *snapshot);
#ifdef __cplusplus
}
#endif
#endif /* VL53_BOARD_H */

View File

@@ -0,0 +1,221 @@
#ifndef VL53L1_CALIBRATION_CONFIG_H
#define VL53L1_CALIBRATION_CONFIG_H
#include <stdint.h>
#include "vl53l1_def.h"
typedef struct {
uint8_t calibrated;
VL53L1_CalibrationData_t data;
} Vl53L1RuntimeCalibration_t;
/*
* VL53L1X 按 UM2356 建议应在产线完成 RefSPAD / Offset / Xtalk 校准,
* 上电后在 DataInit() + StaticInit() 之后用 SetCalibrationData() 回灌。
*
* 当前先提供空白占位,未标定时保持 calibrated = 0驱动将跳过加载。
*/
static const Vl53L1RuntimeCalibration_t k_vl53l1_left_calibration[2] = {
{
.calibrated = 0u,
.data = {
.struct_version = 3970629922u,
.customer = {
.global_config__spad_enables_ref_0 = 223u,
.global_config__spad_enables_ref_1 = 247u,
.global_config__spad_enables_ref_2 = 251u,
.global_config__spad_enables_ref_3 = 254u,
.global_config__spad_enables_ref_4 = 255u,
.global_config__spad_enables_ref_5 = 7u,
.global_config__ref_en_start_select = 0u,
.ref_spad_man__num_requested_ref_spads = 11u,
.ref_spad_man__ref_location = 1u,
.algo__crosstalk_compensation_plane_offset_kcps = 0u,
.algo__crosstalk_compensation_x_plane_gradient_kcps = 0,
.algo__crosstalk_compensation_y_plane_gradient_kcps = 0,
.ref_spad_char__total_rate_target_mcps = 2560u,
.algo__part_to_part_range_offset_mm = 0,
.mm_config__inner_offset_mm = 35,
.mm_config__outer_offset_mm = 9,
},
.add_off_cal_data = {
.result__mm_inner_actual_effective_spads = 280u,
.result__mm_outer_actual_effective_spads = 1344u,
.result__mm_inner_peak_signal_count_rtn_mcps = 397u,
.result__mm_outer_peak_signal_count_rtn_mcps = 1305u,
},
.optical_centre = {
.x_centre = 144u,
.y_centre = 112u,
},
.gain_cal = {
.standard_ranging_gain_factor = 2011u,
},
.cal_peak_rate_map = {
.cal_distance_mm = 0,
.max_samples = 0u,
.width = 0u,
.height = 0u,
.peak_rate_mcps = {
0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
0u
}
}
}
},
{
.calibrated = 0u,
.data = {
.struct_version = 3970629922u,
.customer = {
.global_config__spad_enables_ref_0 = 255u,
.global_config__spad_enables_ref_1 = 189u,
.global_config__spad_enables_ref_2 = 255u,
.global_config__spad_enables_ref_3 = 255u,
.global_config__spad_enables_ref_4 = 255u,
.global_config__spad_enables_ref_5 = 15u,
.global_config__ref_en_start_select = 0u,
.ref_spad_man__num_requested_ref_spads = 14u,
.ref_spad_man__ref_location = 1u,
.algo__crosstalk_compensation_plane_offset_kcps = 0u,
.algo__crosstalk_compensation_x_plane_gradient_kcps = 0,
.algo__crosstalk_compensation_y_plane_gradient_kcps = 0,
.ref_spad_char__total_rate_target_mcps = 2560u,
.algo__part_to_part_range_offset_mm = 0,
.mm_config__inner_offset_mm = 37,
.mm_config__outer_offset_mm = 9,
},
.add_off_cal_data = {
.result__mm_inner_actual_effective_spads = 280u,
.result__mm_outer_actual_effective_spads = 1288u,
.result__mm_inner_peak_signal_count_rtn_mcps = 470u,
.result__mm_outer_peak_signal_count_rtn_mcps = 1456u,
},
.optical_centre = {
.x_centre = 112u,
.y_centre = 128u,
},
.gain_cal = {
.standard_ranging_gain_factor = 2011u,
},
.cal_peak_rate_map = {
.cal_distance_mm = 0,
.max_samples = 0u,
.width = 0u,
.height = 0u,
.peak_rate_mcps = {
0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
0u
}
}
}
},
};
static const Vl53L1RuntimeCalibration_t k_vl53l1_right_calibration[2] = {
{
.calibrated = 0u,
.data = {
.struct_version = 3970629922u,
.customer = {
.global_config__spad_enables_ref_0 = 159u,
.global_config__spad_enables_ref_1 = 254u,
.global_config__spad_enables_ref_2 = 255u,
.global_config__spad_enables_ref_3 = 255u,
.global_config__spad_enables_ref_4 = 239u,
.global_config__spad_enables_ref_5 = 15u,
.global_config__ref_en_start_select = 0u,
.ref_spad_man__num_requested_ref_spads = 6u,
.ref_spad_man__ref_location = 1u,
.algo__crosstalk_compensation_plane_offset_kcps = 0u,
.algo__crosstalk_compensation_x_plane_gradient_kcps = 0,
.algo__crosstalk_compensation_y_plane_gradient_kcps = 0,
.ref_spad_char__total_rate_target_mcps = 2560u,
.algo__part_to_part_range_offset_mm = 0,
.mm_config__inner_offset_mm = 54,
.mm_config__outer_offset_mm = 31,
},
.add_off_cal_data = {
.result__mm_inner_actual_effective_spads = 224u,
.result__mm_outer_actual_effective_spads = 1456u,
.result__mm_inner_peak_signal_count_rtn_mcps = 336u,
.result__mm_outer_peak_signal_count_rtn_mcps = 1382u,
},
.optical_centre = {
.x_centre = 112u,
.y_centre = 112u,
},
.gain_cal = {
.standard_ranging_gain_factor = 2011u,
},
.cal_peak_rate_map = {
.cal_distance_mm = 0,
.max_samples = 0u,
.width = 0u,
.height = 0u,
.peak_rate_mcps = {
0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
0u
}
}
}
},
{
.calibrated = 0u,
.data = {
.struct_version = 3970629922u,
.customer = {
.global_config__spad_enables_ref_0 = 255u,
.global_config__spad_enables_ref_1 = 255u,
.global_config__spad_enables_ref_2 = 255u,
.global_config__spad_enables_ref_3 = 191u,
.global_config__spad_enables_ref_4 = 191u,
.global_config__spad_enables_ref_5 = 11u,
.global_config__ref_en_start_select = 0u,
.ref_spad_man__num_requested_ref_spads = 11u,
.ref_spad_man__ref_location = 2u,
.algo__crosstalk_compensation_plane_offset_kcps = 0u,
.algo__crosstalk_compensation_x_plane_gradient_kcps = 0,
.algo__crosstalk_compensation_y_plane_gradient_kcps = 0,
.ref_spad_char__total_rate_target_mcps = 2560u,
.algo__part_to_part_range_offset_mm = 0,
.mm_config__inner_offset_mm = 30,
.mm_config__outer_offset_mm = 5,
},
.add_off_cal_data = {
.result__mm_inner_actual_effective_spads = 224u,
.result__mm_outer_actual_effective_spads = 1456u,
.result__mm_inner_peak_signal_count_rtn_mcps = 334u,
.result__mm_outer_peak_signal_count_rtn_mcps = 1524u,
},
.optical_centre = {
.x_centre = 112u,
.y_centre = 96u,
},
.gain_cal = {
.standard_ranging_gain_factor = 2011u,
},
.cal_peak_rate_map = {
.cal_distance_mm = 0,
.max_samples = 0u,
.width = 0u,
.height = 0u,
.peak_rate_mcps = {
0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u,
0u
}
}
}
},
};
#endif /* VL53L1_CALIBRATION_CONFIG_H */