diff --git a/common/i2c/Base_I2C.c b/common/i2c/Base_I2C.c index ff59664df47d08bb1ad690d85c8a08ecbccdd2c0..18d2da9e707b363f072a99db37b93e9f729fcdbc 100644 --- a/common/i2c/Base_I2C.c +++ b/common/i2c/Base_I2C.c @@ -1,12 +1,15 @@ #include "Base_I2C.h" - -HAL_StatusTypeDef Base_I2C_WriteCmd(uint8_t* hi2cX, uint16_t addr, uint8_t* txData, uint8_t len, uint16_t timeout) +HAL_StatusTypeDef BASE_I2C_Write_Cmd(I2C_HandleTypeDef *hi2cX, uint16_t devAddr, + uint8_t *txData, uint16_t dataLen, uint16_t timeoutMs) { - return HAL_I2C_Master_Transmit((I2C_HandleTypeDef*)hi2cX, addr, (uint8_t*)txData, len, timeout); + return HAL_I2C_Master_Transmit(hi2cX, devAddr, txData, dataLen, timeoutMs); } -HAL_StatusTypeDef Base_I2C_ReadCmd(uint8_t* hi2cX, uint16_t addr, uint8_t* rxData, uint8_t len, uint16_t timeout) +HAL_StatusTypeDef BASE_I2C_Read_Regs(I2C_HandleTypeDef *hi2cX, uint16_t devAddr, + uint8_t regAddr, uint8_t *outBuffer, + uint16_t bufferLen, uint16_t timeoutMs) { - return HAL_I2C_Master_Receive((I2C_HandleTypeDef*)hi2cX, addr, (uint8_t*)rxData, len, timeout); -} + return HAL_I2C_Mem_Read(hi2cX, devAddr, regAddr, I2C_MEMADD_SIZE_8BIT, + outBuffer, bufferLen, timeoutMs); +} \ No newline at end of file diff --git a/common/i2c/Base_I2C.h b/common/i2c/Base_I2C.h index 9e79dad9bf2276ee49d05d031f8bcacd4c4c9285..5a896db71b7b5f1d7674bc8f93dc8d00f1dcfea6 100644 --- a/common/i2c/Base_I2C.h +++ b/common/i2c/Base_I2C.h @@ -1,39 +1,32 @@ -#ifndef __Base_I2C_H -#define __Base_I2C_H +#ifndef BASE_I2C_H +#define BASE_I2C_H -#ifdef __cplusplus -extern "C" { -#endif - -#include "stm32f1xx_hal.h" #include "i2c.h" - /** - * @brief 通过 I2C 接口写入命令数据 - * @param hi2cX: 指向 I2C 句柄的指针,用于指定使用的 I2C 总线实例 - * @param addr: 目标设备的 I2C 地址(7bit),标识要与之通信的从设备 - * @param txData: 指向待发送数据的指针,包含了要写入 I2C 设备的命令或数据内容 - * @param len: 要发送数据的长度,即 txData 中数据的字节数 - * @param timeout: 操作超时时间,若在该时间内操作未完成,则操作失败;单位ms - * @retval HAL_StatusTypeDef: 操作状态,如 HAL_OK 表示成功,其他值表示失败 + * @brief I2C主机发送指令(纯数据发送,无寄存器地址) + * @param hi2cX : I2C句柄指针(如 &hi2c1) + * @param devAddr : I2C设备地址(左移前的7位地址) + * @param txData : 发送数据缓冲区指针 + * @param dataLen : 要发送的数据长度 + * @param timeoutMs : 超时时间(单位ms) + * @retval HAL_StatusTypeDef HAL库状态值(HAL_OK表示成功) */ -HAL_StatusTypeDef Base_I2C_WriteCmd(uint8_t* hi2cX, uint16_t addr, uint8_t* txData, uint8_t len, uint16_t timeout = 100); +HAL_StatusTypeDef BASE_I2C_Write_Cmd(I2C_HandleTypeDef *hi2cX, uint16_t devAddr, + uint8_t *txData, uint16_t dataLen, uint16_t timeoutMs); /** - * @brief 通过 I2C 接口读取命令响应数据 - * @param hi2cX: 指向 I2C 句柄的指针,用于指定使用的 I2C 总线实例 - * @param addr: 目标设备的 I2C 地址(7bit),标识要与之通信的从设备 - * @param rxData: 指向用于存储接收到数据的缓冲区的指针,读取到的数据会存于此 - * @param len: 要读取数据的长度,即期望从 I2C 设备读取的字节数 - * @param timeout: 操作超时时间,若在该时间内操作未完成,则操作失败;单位ms - * @retval HAL_StatusTypeDef: 操作状态,如 HAL_OK 表示成功,其他值表示失败 + * @brief 读取I2C设备多个连续寄存器 + * @param hi2cX : I2C句柄指针(如 &hi2c1) + * @param devAddr : 设备7位I2C地址(左移前) + * @param regAddr : 起始寄存器地址 + * @param outBuffer : 接收数据的缓冲区 + * @param bufferLen : 要读取的字节数 + * @param timeoutMs : 超时时间(单位ms) + * @retval HAL_OK 读取成功, 其他值读取失败 */ -HAL_StatusTypeDef Base_I2C_ReadCmd(uint8_t* hi2cx, uint16_t addr, uint8_t* rxData, uint8_t len, uint16_t timeout = 100); +HAL_StatusTypeDef BASE_I2C_Read_Regs(I2C_HandleTypeDef *hi2cX, uint16_t devAddr, + uint8_t regAddr, uint8_t *outBuffer, + uint16_t bufferLen, uint16_t timeoutMs); -#ifdef __cplusplus -} #endif - -#endif /* __Base_I2C_H */ -//author: 信息23 韩林杏 \ No newline at end of file diff --git a/modules/VL53L0X/inc/bsp_VL53L0X.h b/modules/VL53L0X/inc/bsp_VL53L0X.h new file mode 100644 index 0000000000000000000000000000000000000000..9b7b0bd196646b8bda620b6707fcd047bf0877c4 --- /dev/null +++ b/modules/VL53L0X/inc/bsp_VL53L0X.h @@ -0,0 +1,52 @@ +#ifndef __VL53L0X_H +#define __VL53L0X_H + +#include "vl53l0x_api.h" +#include "vl53l0x_platform.h" +#include "vl53l0x_gen.h" +#include "vl53l0x_cali.h" +#include "vl53l0x_it.h" +#include "sys.h" +#include "my_vl53l0.h" + + +//VL53L0XϵĬIICַΪ0X52(λ) +#define VL53L0X_Addr 0x52 + +//Xshutƽ,ӶʹVL53L0X 1:ʹ 0:ر + + +//ʹ2.8V IOƽģʽ +#define USE_I2C_2V8 1 + +//ģʽ +#define Default_Mode 0// Ĭ +#define HIGH_ACCURACY 1//߾ +#define LONG_RANGE 2// +#define HIGH_SPEED 3// + +//vl53l0xģʽò +typedef struct packed_2 +{ + FixPoint1616_t signalLimit; //Signalֵ + FixPoint1616_t sigmaLimit; //Sigmalֵ + uint32_t timingBudget; //ʱ + uint8_t preRangeVcselPeriod ; //VCSEL + uint8_t finalRangeVcselPeriod ;//VCSELڷΧ + +}mode_data; + + +extern mode_data Mode_data[]; +extern uint8_t AjustOK; + +VL53L0X_Error vl53l0x_init(VL53L0X_Dev_t *dev);//ʼvl53l0x +void print_pal_error(VL53L0X_Error Status);//Ϣӡ +void mode_string(u8 mode,char *buf);//ģʽַʾ +void vl53l0x_test(void);//vl53l0x +void vl53l0x_reset(VL53L0X_Dev_t *dev);//vl53l0xλ + +void vl53l0x_info(void);//ȡvl53l0x豸IDϢ +void One_measurement(u8 mode);//ȡһβ +#endif + diff --git a/modules/VL53L0X/inc/sys.h b/modules/VL53L0X/inc/sys.h new file mode 100644 index 0000000000000000000000000000000000000000..176eeffe87140038b7a749515738e0f8131aa5e6 --- /dev/null +++ b/modules/VL53L0X/inc/sys.h @@ -0,0 +1,60 @@ +/* + * ӲչӲϹȫԴ + * www.lckfb.com + * ֳ֧פ̳κμ⻶ӭʱѧϰ + * ̳club.szlcsc.com + * עbilibili˺ţ塿ǵ¶̬ + * ׬ǮйʦΪ + * + + Change Logs: + * Date Author Notes + * 2024-03-07 LCKFB-LP first version + */ + +#ifndef __SYS_H__ +#define __SYS_H__ + +#include "stm32f4xx.h" + +// λĺ궨壬ֱʹṩBIT_ADDR +#define BIT_ADDR(byte_offset,bitnum) (volatile unsigned long*)(0x42000000 + (byte_offset * 32) + (bitnum * 4)) + +// GPIOBĴλַ +#define GPIOA_OCTL_OFFSET ((GPIOA_BASE + 0x14) - 0x40000000) +#define GPIOB_OCTL_OFFSET ((GPIOB_BASE + 0x14) - 0x40000000) +#define GPIOC_OCTL_OFFSET ((GPIOC_BASE + 0x14) - 0x40000000) +#define GPIOD_OCTL_OFFSET ((GPIOD_BASE + 0x14) - 0x40000000) +#define GPIOE_OCTL_OFFSET ((GPIOE_BASE + 0x14) - 0x40000000) +#define GPIOF_OCTL_OFFSET ((GPIOF_BASE + 0x14) - 0x40000000) +#define GPIOG_OCTL_OFFSET ((GPIOG_BASE + 0x14) - 0x40000000) + +#define GPIOA_ISTAT_OFFSET ((GPIOA_BASE + 0x10) - 0x40000000) +#define GPIOB_ISTAT_OFFSET ((GPIOB_BASE + 0x10) - 0x40000000) +#define GPIOC_ISTAT_OFFSET ((GPIOC_BASE + 0x10) - 0x40000000) +#define GPIOD_ISTAT_OFFSET ((GPIOD_BASE + 0x10) - 0x40000000) +#define GPIOE_ISTAT_OFFSET ((GPIOE_BASE + 0x10) - 0x40000000) +#define GPIOF_ISTAT_OFFSET ((GPIOF_BASE + 0x10) - 0x40000000) +#define GPIOG_ISTAT_OFFSET ((GPIOG_BASE + 0x10) - 0x40000000) + + +// +#define PAin(n) *(BIT_ADDR(GPIOA_ISTAT_OFFSET,n)) // PA +#define PBin(n) *(BIT_ADDR(GPIOB_ISTAT_OFFSET,n)) // PB +#define PCin(n) *(BIT_ADDR(GPIOC_ISTAT_OFFSET,n)) // PC +#define PDin(n) *(BIT_ADDR(GPIOD_ISTAT_OFFSET,n)) // PD +#define PEin(n) *(BIT_ADDR(GPIOE_ISTAT_OFFSET,n)) // PE +#define PFin(n) *(BIT_ADDR(GPIOF_ISTAT_OFFSET,n)) // PF +#define PGin(n) *(BIT_ADDR(GPIOG_ISTAT_OFFSET,n)) // PG + +#define PAout(n) *(BIT_ADDR(GPIOA_OCTL_OFFSET,n)) // PA +#define PBout(n) *(BIT_ADDR(GPIOB_OCTL_OFFSET,n)) // PB +#define PCout(n) *(BIT_ADDR(GPIOC_OCTL_OFFSET,n)) // PC +#define PDout(n) *(BIT_ADDR(GPIOD_OCTL_OFFSET,n)) // PD +#define PEout(n) *(BIT_ADDR(GPIOE_OCTL_OFFSET,n)) // PE +#define PFout(n) *(BIT_ADDR(GPIOF_OCTL_OFFSET,n)) // PF +#define PGout(n) *(BIT_ADDR(GPIOG_OCTL_OFFSET,n)) // PG + + + +#endif diff --git a/modules/VL53L0X/inc/vl53l0x_api.h b/modules/VL53L0X/inc/vl53l0x_api.h new file mode 100644 index 0000000000000000000000000000000000000000..48148e22cac8c9fc1111fff48d0395e3bfac9c64 --- /dev/null +++ b/modules/VL53L0X/inc/vl53l0x_api.h @@ -0,0 +1,1953 @@ +/******************************************************************************* + Copyright 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 _VL53L0X_API_H_ +#define _VL53L0X_API_H_ + +#include "vl53l0x_api_strings.h" +#include "vl53l0x_def.h" +#include "vl53l0x_platform.h" +#include "bsp_vl53l0x.h" + + + +#ifdef __cplusplus +extern "C" +{ +#endif + +#ifdef _MSC_VER +# ifdef VL53L0X_API_EXPORTS +# define VL53L0X_API __declspec(dllexport) +# else +# define VL53L0X_API +# endif +#else +# define VL53L0X_API +#endif + +/** @defgroup VL53L0X_cut11_group VL53L0X cut1.1 Function Definition + * @brief VL53L0X cut1.1 Function Definition + * @{ + */ + +/** @defgroup VL53L0X_general_group VL53L0X General Functions + * @brief General functions and definitions + * @{ + */ + +/** + * @brief Return the VL53L0X PAL Implementation Version + * + * @note This function doesn't access to the device + * + * @param pVersion Pointer to current PAL Implementation Version + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_GetVersion(VL53L0X_Version_t *pVersion); + +/** + * @brief Return the PAL Specification Version used for the current + * implementation. + * + * @note This function doesn't access to the device + * + * @param pPalSpecVersion Pointer to current PAL Specification Version + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_GetPalSpecVersion( + VL53L0X_Version_t *pPalSpecVersion); + +/** + * @brief Reads the Product Revision for a for given Device + * This function can be used to distinguish cut1.0 from cut1.1. + * + * @note This function Access to the device + * + * @param Dev Device Handle + * @param pProductRevisionMajor Pointer to Product Revision Major + * for a given Device + * @param pProductRevisionMinor Pointer to Product Revision Minor + * for a given Device + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_GetProductRevision(VL53L0X_DEV Dev, + uint8_t *pProductRevisionMajor, uint8_t *pProductRevisionMinor); + +/** + * @brief Reads the Device information for given Device + * + * @note This function Access to the device + * + * @param Dev Device Handle + * @param pVL53L0X_DeviceInfo Pointer to current device info for a given + * Device + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_GetDeviceInfo(VL53L0X_DEV Dev, + VL53L0X_DeviceInfo_t *pVL53L0X_DeviceInfo); + +/** + * @brief Read current status of the error register for the selected device + * + * @note This function Access to the device + * + * @param Dev Device Handle + * @param pDeviceErrorStatus Pointer to current error code of the device + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_GetDeviceErrorStatus(VL53L0X_DEV Dev, + VL53L0X_DeviceError *pDeviceErrorStatus); + +/** + * @brief Human readable Range Status string for a given RangeStatus + * + * @note This function doesn't access to the device + * + * @param RangeStatus The RangeStatus code as stored on + * @a VL53L0X_RangingMeasurementData_t + * @param pRangeStatusString The returned RangeStatus string. + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_GetRangeStatusString(uint8_t RangeStatus, + char *pRangeStatusString); + +/** + * @brief Human readable error string for a given Error Code + * + * @note This function doesn't access to the device + * + * @param ErrorCode The error code as stored on ::VL53L0X_DeviceError + * @param pDeviceErrorString The error string corresponding to the ErrorCode + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_GetDeviceErrorString( + VL53L0X_DeviceError ErrorCode, char *pDeviceErrorString); + +/** + * @brief Human readable error string for current PAL error status + * + * @note This function doesn't access to the device + * + * @param PalErrorCode The error code as stored on @a VL53L0X_Error + * @param pPalErrorString The error string corresponding to the + * PalErrorCode + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_GetPalErrorString(VL53L0X_Error PalErrorCode, + char *pPalErrorString); + +/** + * @brief Human readable PAL State string + * + * @note This function doesn't access to the device + * + * @param PalStateCode The State code as stored on @a VL53L0X_State + * @param pPalStateString The State string corresponding to the + * PalStateCode + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_GetPalStateString(VL53L0X_State PalStateCode, + char *pPalStateString); + +/** + * @brief Reads the internal state of the PAL for a given Device + * + * @note This function doesn't access to the device + * + * @param Dev Device Handle + * @param pPalState Pointer to current state of the PAL for a + * given Device + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_GetPalState(VL53L0X_DEV Dev, + VL53L0X_State *pPalState); + +/** + * @brief Set the power mode for a given Device + * The power mode can be Standby or Idle. Different level of both Standby and + * Idle can exists. + * This function should not be used when device is in Ranging state. + * + * @note This function Access to the device + * + * @param Dev Device Handle + * @param PowerMode The value of the power mode to set. + * see ::VL53L0X_PowerModes + * Valid values are: + * VL53L0X_POWERMODE_STANDBY_LEVEL1, + * VL53L0X_POWERMODE_IDLE_LEVEL1 + * @return VL53L0X_ERROR_NONE Success + * @return VL53L0X_ERROR_MODE_NOT_SUPPORTED This error occurs when PowerMode + * is not in the supported list + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_SetPowerMode(VL53L0X_DEV Dev, + VL53L0X_PowerModes PowerMode); + +/** + * @brief Get the power mode for a given Device + * + * @note This function Access to the device + * + * @param Dev Device Handle + * @param pPowerMode Pointer to the current value of the power + * mode. see ::VL53L0X_PowerModes + * Valid values are: + * VL53L0X_POWERMODE_STANDBY_LEVEL1, + * VL53L0X_POWERMODE_IDLE_LEVEL1 + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_GetPowerMode(VL53L0X_DEV Dev, + VL53L0X_PowerModes *pPowerMode); + +/** + * Set or over-hide part to part calibration offset + * \sa VL53L0X_DataInit() VL53L0X_GetOffsetCalibrationDataMicroMeter() + * + * @note This function Access to the device + * + * @param Dev Device Handle + * @param OffsetCalibrationDataMicroMeter Offset (microns) + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_SetOffsetCalibrationDataMicroMeter( + VL53L0X_DEV Dev, int32_t OffsetCalibrationDataMicroMeter); + +/** + * @brief Get part to part calibration offset + * + * @par Function Description + * Should only be used after a successful call to @a VL53L0X_DataInit to backup + * device NVM value + * + * @note This function Access to the device + * + * @param Dev Device Handle + * @param pOffsetCalibrationDataMicroMeter Return part to part + * calibration offset from device (microns) + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_GetOffsetCalibrationDataMicroMeter( + VL53L0X_DEV Dev, int32_t *pOffsetCalibrationDataMicroMeter); + +/** + * Set the linearity corrective gain + * + * @note This function Access to the device + * + * @param Dev Device Handle + * @param LinearityCorrectiveGain Linearity corrective + * gain in x1000 + * if value is 1000 then no modification is applied. + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_SetLinearityCorrectiveGain(VL53L0X_DEV Dev, + int16_t LinearityCorrectiveGain); + +/** + * @brief Get the linearity corrective gain + * + * @par Function Description + * Should only be used after a successful call to @a VL53L0X_DataInit to backup + * device NVM value + * + * @note This function Access to the device + * + * @param Dev Device Handle + * @param pLinearityCorrectiveGain Pointer to the linearity + * corrective gain in x1000 + * if value is 1000 then no modification is applied. + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_GetLinearityCorrectiveGain(VL53L0X_DEV Dev, + uint16_t *pLinearityCorrectiveGain); + +/** + * Set Group parameter Hold state + * + * @par Function Description + * Set or remove device internal group parameter hold + * + * @note This function is not Implemented + * + * @param Dev Device Handle + * @param GroupParamHold Group parameter Hold state to be set (on/off) + * @return VL53L0X_ERROR_NOT_IMPLEMENTED Not implemented + */ +VL53L0X_API VL53L0X_Error VL53L0X_SetGroupParamHold(VL53L0X_DEV Dev, + uint8_t GroupParamHold); + +/** + * @brief Get the maximal distance for actual setup + * @par Function Description + * Device must be initialized through @a VL53L0X_SetParameters() prior calling + * this function. + * + * Any range value more than the value returned is to be considered as + * "no target detected" or + * "no target in detectable range"\n + * @warning The maximal distance depends on the setup + * + * @note This function is not Implemented + * + * @param Dev Device Handle + * @param pUpperLimitMilliMeter The maximal range limit for actual setup + * (in millimeter) + * @return VL53L0X_ERROR_NOT_IMPLEMENTED Not implemented + */ +VL53L0X_API VL53L0X_Error VL53L0X_GetUpperLimitMilliMeter(VL53L0X_DEV Dev, + uint16_t *pUpperLimitMilliMeter); + + +/** + * @brief Get the Total Signal Rate + * @par Function Description + * This function will return the Total Signal Rate after a good ranging is done. + * + * @note This function access to Device + * + * @param Dev Device Handle + * @param pTotalSignalRate Total Signal Rate value in Mega count per second + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_Error VL53L0X_GetTotalSignalRate(VL53L0X_DEV Dev, + FixPoint1616_t *pTotalSignalRate); + +/** @} VL53L0X_general_group */ + +/** @defgroup VL53L0X_init_group VL53L0X Init Functions + * @brief VL53L0X Init Functions + * @{ + */ + +/** + * @brief Set new device address + * + * After completion the device will answer to the new address programmed. + * This function should be called when several devices are used in parallel + * before start programming the sensor. + * When a single device us used, there is no need to call this function. + * + * @note This function Access to the device + * + * @param Dev Device Handle + * @param DeviceAddress The new Device address + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_SetDeviceAddress(VL53L0X_DEV Dev, + uint8_t DeviceAddress); + +/** + * + * @brief One time device initialization + * + * To be called once and only once after device is brought out of reset + * (Chip enable) and booted see @a VL53L0X_WaitDeviceBooted() + * + * @par Function Description + * When not used after a fresh device "power up" or reset, it may return + * @a #VL53L0X_ERROR_CALIBRATION_WARNING meaning wrong calibration data + * may have been fetched from device that can result in ranging offset error\n + * If application cannot execute device reset or need to run VL53L0X_DataInit + * multiple time then it must ensure proper offset calibration saving and + * restore on its own by using @a VL53L0X_GetOffsetCalibrationData() on first + * power up and then @a VL53L0X_SetOffsetCalibrationData() in all subsequent init + * This function will change the VL53L0X_State from VL53L0X_STATE_POWERDOWN to + * VL53L0X_STATE_WAIT_STATICINIT. + * + * @note This function Access to the device + * + * @param Dev Device Handle + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_DataInit(VL53L0X_DEV Dev); + +/** + * @brief Set the tuning settings pointer + * + * This function is used to specify the Tuning settings buffer to be used + * for a given device. The buffer contains all the necessary data to permit + * the API to write tuning settings. + * This function permit to force the usage of either external or internal + * tuning settings. + * + * @note This function Access to the device + * + * @param Dev Device Handle + * @param pTuningSettingBuffer Pointer to tuning settings buffer. + * @param UseInternalTuningSettings Use internal tuning settings value. + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_SetTuningSettingBuffer(VL53L0X_DEV Dev, + uint8_t *pTuningSettingBuffer, uint8_t UseInternalTuningSettings); + +/** + * @brief Get the tuning settings pointer and the internal external switch + * value. + * + * This function is used to get the Tuning settings buffer pointer and the + * value. + * of the switch to select either external or internal tuning settings. + * + * @note This function Access to the device + * + * @param Dev Device Handle + * @param ppTuningSettingBuffer Pointer to tuning settings buffer. + * @param pUseInternalTuningSettings Pointer to store Use internal tuning + * settings value. + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_GetTuningSettingBuffer(VL53L0X_DEV Dev, + uint8_t **ppTuningSettingBuffer, uint8_t *pUseInternalTuningSettings); + +/** + * @brief Do basic device init (and eventually patch loading) + * This function will change the VL53L0X_State from + * VL53L0X_STATE_WAIT_STATICINIT to VL53L0X_STATE_IDLE. + * In this stage all default setting will be applied. + * + * @note This function Access to the device + * + * @param Dev Device Handle + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_StaticInit(VL53L0X_DEV Dev); + +/** + * @brief Wait for device booted after chip enable (hardware standby) + * This function can be run only when VL53L0X_State is VL53L0X_STATE_POWERDOWN. + * + * @note This function is not Implemented + * + * @param Dev Device Handle + * @return VL53L0X_ERROR_NOT_IMPLEMENTED Not implemented + * + */ +VL53L0X_API VL53L0X_Error VL53L0X_WaitDeviceBooted(VL53L0X_DEV Dev); + +/** + * @brief Do an hard reset or soft reset (depending on implementation) of the + * device \nAfter call of this function, device must be in same state as right + * after a power-up sequence.This function will change the VL53L0X_State to + * VL53L0X_STATE_POWERDOWN. + * + * @note This function Access to the device + * + * @param Dev Device Handle + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_ResetDevice(VL53L0X_DEV Dev); + +/** @} VL53L0X_init_group */ + +/** @defgroup VL53L0X_parameters_group VL53L0X Parameters Functions + * @brief Functions used to prepare and setup the device + * @{ + */ + +/** + * @brief Prepare device for operation + * @par Function Description + * Update device with provided parameters + * @li Then start ranging operation. + * + * @note This function Access to the device + * + * @param Dev Device Handle + * @param pDeviceParameters Pointer to store current device parameters. + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_SetDeviceParameters(VL53L0X_DEV Dev, + const VL53L0X_DeviceParameters_t *pDeviceParameters); + +/** + * @brief Retrieve current device parameters + * @par Function Description + * Get actual parameters of the device + * @li Then start ranging operation. + * + * @note This function Access to the device + * + * @param Dev Device Handle + * @param pDeviceParameters Pointer to store current device parameters. + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_GetDeviceParameters(VL53L0X_DEV Dev, + VL53L0X_DeviceParameters_t *pDeviceParameters); + +/** + * @brief Set a new device mode + * @par Function Description + * Set device to a new mode (ranging, histogram ...) + * + * @note This function doesn't Access to the device + * + * @param Dev Device Handle + * @param DeviceMode New device mode to apply + * Valid values are: + * VL53L0X_DEVICEMODE_SINGLE_RANGING + * VL53L0X_DEVICEMODE_CONTINUOUS_RANGING + * VL53L0X_DEVICEMODE_CONTINUOUS_TIMED_RANGING + * VL53L0X_DEVICEMODE_SINGLE_HISTOGRAM + * VL53L0X_HISTOGRAMMODE_REFERENCE_ONLY + * VL53L0X_HISTOGRAMMODE_RETURN_ONLY + * VL53L0X_HISTOGRAMMODE_BOTH + * + * + * @return VL53L0X_ERROR_NONE Success + * @return VL53L0X_ERROR_MODE_NOT_SUPPORTED This error occurs when DeviceMode is + * not in the supported list + */ +VL53L0X_API VL53L0X_Error VL53L0X_SetDeviceMode(VL53L0X_DEV Dev, + VL53L0X_DeviceModes DeviceMode); + +/** + * @brief Get current new device mode + * @par Function Description + * Get actual mode of the device(ranging, histogram ...) + * + * @note This function doesn't Access to the device + * + * @param Dev Device Handle + * @param pDeviceMode Pointer to current apply mode value + * Valid values are: + * VL53L0X_DEVICEMODE_SINGLE_RANGING + * VL53L0X_DEVICEMODE_CONTINUOUS_RANGING + * VL53L0X_DEVICEMODE_CONTINUOUS_TIMED_RANGING + * VL53L0X_DEVICEMODE_SINGLE_HISTOGRAM + * VL53L0X_HISTOGRAMMODE_REFERENCE_ONLY + * VL53L0X_HISTOGRAMMODE_RETURN_ONLY + * VL53L0X_HISTOGRAMMODE_BOTH + * + * @return VL53L0X_ERROR_NONE Success + * @return VL53L0X_ERROR_MODE_NOT_SUPPORTED This error occurs when + * DeviceMode is not in the supported list + */ +VL53L0X_API VL53L0X_Error VL53L0X_GetDeviceMode(VL53L0X_DEV Dev, + VL53L0X_DeviceModes *pDeviceMode); + +/** + * @brief Sets the resolution of range measurements. + * @par Function Description + * Set resolution of range measurements to either 0.25mm if + * fraction enabled or 1mm if not enabled. + * + * @note This function Accesses the device + * + * @param Dev Device Handle + * @param Enable Enable high resolution + * + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_SetRangeFractionEnable(VL53L0X_DEV Dev, + uint8_t Enable); + +/** + * @brief Gets the fraction enable parameter indicating the resolution of + * range measurements. + * + * @par Function Description + * Gets the fraction enable state, which translates to the resolution of + * range measurements as follows :Enabled:=0.25mm resolution, + * Not Enabled:=1mm resolution. + * + * @note This function Accesses the device + * + * @param Dev Device Handle + * @param pEnable Output Parameter reporting the fraction enable state. + * + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_GetFractionEnable(VL53L0X_DEV Dev, + uint8_t *pEnable); + +/** + * @brief Set a new Histogram mode + * @par Function Description + * Set device to a new Histogram mode + * + * @note This function doesn't Access to the device + * + * @param Dev Device Handle + * @param HistogramMode New device mode to apply + * Valid values are: + * VL53L0X_HISTOGRAMMODE_DISABLED + * VL53L0X_DEVICEMODE_SINGLE_HISTOGRAM + * VL53L0X_HISTOGRAMMODE_REFERENCE_ONLY + * VL53L0X_HISTOGRAMMODE_RETURN_ONLY + * VL53L0X_HISTOGRAMMODE_BOTH + * + * @return VL53L0X_ERROR_NONE Success + * @return VL53L0X_ERROR_MODE_NOT_SUPPORTED This error occurs when + * HistogramMode is not in the supported list + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_SetHistogramMode(VL53L0X_DEV Dev, + VL53L0X_HistogramModes HistogramMode); + +/** + * @brief Get current new device mode + * @par Function Description + * Get current Histogram mode of a Device + * + * @note This function doesn't Access to the device + * + * @param Dev Device Handle + * @param pHistogramMode Pointer to current Histogram Mode value + * Valid values are: + * VL53L0X_HISTOGRAMMODE_DISABLED + * VL53L0X_DEVICEMODE_SINGLE_HISTOGRAM + * VL53L0X_HISTOGRAMMODE_REFERENCE_ONLY + * VL53L0X_HISTOGRAMMODE_RETURN_ONLY + * VL53L0X_HISTOGRAMMODE_BOTH + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_GetHistogramMode(VL53L0X_DEV Dev, + VL53L0X_HistogramModes *pHistogramMode); + +/** + * @brief Set Ranging Timing Budget in microseconds + * + * @par Function Description + * Defines the maximum time allowed by the user to the device to run a + * full ranging sequence for the current mode (ranging, histogram, ASL ...) + * + * @note This function Access to the device + * + * @param Dev Device Handle + * @param MeasurementTimingBudgetMicroSeconds Max measurement time in + * microseconds. + * Valid values are: + * >= 17000 microsecs when wraparound enabled + * >= 12000 microsecs when wraparound disabled + * @return VL53L0X_ERROR_NONE Success + * @return VL53L0X_ERROR_INVALID_PARAMS This error is returned if + MeasurementTimingBudgetMicroSeconds out of range + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_SetMeasurementTimingBudgetMicroSeconds( + VL53L0X_DEV Dev, uint32_t MeasurementTimingBudgetMicroSeconds); + +/** + * @brief Get Ranging Timing Budget in microseconds + * + * @par Function Description + * Returns the programmed the maximum time allowed by the user to the + * device to run a full ranging sequence for the current mode + * (ranging, histogram, ASL ...) + * + * @note This function Access to the device + * + * @param Dev Device Handle + * @param pMeasurementTimingBudgetMicroSeconds Max measurement time in + * microseconds. + * Valid values are: + * >= 17000 microsecs when wraparound enabled + * >= 12000 microsecs when wraparound disabled + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_GetMeasurementTimingBudgetMicroSeconds( + VL53L0X_DEV Dev, uint32_t *pMeasurementTimingBudgetMicroSeconds); + +/** + * @brief Gets the VCSEL pulse period. + * + * @par Function Description + * This function retrieves the VCSEL pulse period for the given period type. + * + * @note This function Accesses the device + * + * @param Dev Device Handle + * @param VcselPeriodType VCSEL period identifier (pre-range|final). + * @param pVCSELPulsePeriod Pointer to VCSEL period value. + * @return VL53L0X_ERROR_NONE Success + * @return VL53L0X_ERROR_INVALID_PARAMS Error VcselPeriodType parameter not + * supported. + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_GetVcselPulsePeriod(VL53L0X_DEV Dev, + VL53L0X_VcselPeriod VcselPeriodType, uint8_t *pVCSELPulsePeriod); + +/** + * @brief Sets the VCSEL pulse period. + * + * @par Function Description + * This function retrieves the VCSEL pulse period for the given period type. + * + * @note This function Accesses the device + * + * @param Dev Device Handle + * @param VcselPeriodType VCSEL period identifier (pre-range|final). + * @param VCSELPulsePeriod VCSEL period value + * @return VL53L0X_ERROR_NONE Success + * @return VL53L0X_ERROR_INVALID_PARAMS Error VcselPeriodType parameter not + * supported. + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_SetVcselPulsePeriod(VL53L0X_DEV Dev, + VL53L0X_VcselPeriod VcselPeriodType, uint8_t VCSELPulsePeriod); + +/** + * @brief Sets the (on/off) state of a requested sequence step. + * + * @par Function Description + * This function enables/disables a requested sequence step. + * + * @note This function Accesses the device + * + * @param Dev Device Handle + * @param SequenceStepId Sequence step identifier. + * @param SequenceStepEnabled Demanded state {0=Off,1=On} + * is enabled. + * @return VL53L0X_ERROR_NONE Success + * @return VL53L0X_ERROR_INVALID_PARAMS Error SequenceStepId parameter not + * supported. + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_SetSequenceStepEnable(VL53L0X_DEV Dev, + VL53L0X_SequenceStepId SequenceStepId, uint8_t SequenceStepEnabled); + +/** + * @brief Gets the (on/off) state of a requested sequence step. + * + * @par Function Description + * This function retrieves the state of a requested sequence step, i.e. on/off. + * + * @note This function Accesses the device + * + * @param Dev Device Handle + * @param SequenceStepId Sequence step identifier. + * @param pSequenceStepEnabled Out parameter reporting if the sequence step + * is enabled {0=Off,1=On}. + * @return VL53L0X_ERROR_NONE Success + * @return VL53L0X_ERROR_INVALID_PARAMS Error SequenceStepId parameter not + * supported. + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_GetSequenceStepEnable(VL53L0X_DEV Dev, + VL53L0X_SequenceStepId SequenceStepId, uint8_t *pSequenceStepEnabled); + +/** + * @brief Gets the (on/off) state of all sequence steps. + * + * @par Function Description + * This function retrieves the state of all sequence step in the scheduler. + * + * @note This function Accesses the device + * + * @param Dev Device Handle + * @param pSchedulerSequenceSteps Pointer to struct containing result. + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_GetSequenceStepEnables(VL53L0X_DEV Dev, + VL53L0X_SchedulerSequenceSteps_t *pSchedulerSequenceSteps); + +/** + * @brief Sets the timeout of a requested sequence step. + * + * @par Function Description + * This function sets the timeout of a requested sequence step. + * + * @note This function Accesses the device + * + * @param Dev Device Handle + * @param SequenceStepId Sequence step identifier. + * @param TimeOutMilliSecs Demanded timeout + * @return VL53L0X_ERROR_NONE Success + * @return VL53L0X_ERROR_INVALID_PARAMS Error SequenceStepId parameter not + * supported. + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_SetSequenceStepTimeout(VL53L0X_DEV Dev, + VL53L0X_SequenceStepId SequenceStepId, FixPoint1616_t TimeOutMilliSecs); + +/** + * @brief Gets the timeout of a requested sequence step. + * + * @par Function Description + * This function retrieves the timeout of a requested sequence step. + * + * @note This function Accesses the device + * + * @param Dev Device Handle + * @param SequenceStepId Sequence step identifier. + * @param pTimeOutMilliSecs Timeout value. + * @return VL53L0X_ERROR_NONE Success + * @return VL53L0X_ERROR_INVALID_PARAMS Error SequenceStepId parameter not + * supported. + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_GetSequenceStepTimeout(VL53L0X_DEV Dev, + VL53L0X_SequenceStepId SequenceStepId, + FixPoint1616_t *pTimeOutMilliSecs); + +/** + * @brief Gets number of sequence steps managed by the API. + * + * @par Function Description + * This function retrieves the number of sequence steps currently managed + * by the API + * + * @note This function Accesses the device + * + * @param Dev Device Handle + * @param pNumberOfSequenceSteps Out parameter reporting the number of + * sequence steps. + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_GetNumberOfSequenceSteps(VL53L0X_DEV Dev, + uint8_t *pNumberOfSequenceSteps); + +/** + * @brief Gets the name of a given sequence step. + * + * @par Function Description + * This function retrieves the name of sequence steps corresponding to + * SequenceStepId. + * + * @note This function doesn't Accesses the device + * + * @param SequenceStepId Sequence step identifier. + * @param pSequenceStepsString Pointer to Info string + * + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_GetSequenceStepsInfo( + VL53L0X_SequenceStepId SequenceStepId, char *pSequenceStepsString); + +/** + * Program continuous mode Inter-Measurement period in milliseconds + * + * @par Function Description + * When trying to set too short time return INVALID_PARAMS minimal value + * + * @note This function Access to the device + * + * @param Dev Device Handle + * @param InterMeasurementPeriodMilliSeconds Inter-Measurement Period in ms. + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_SetInterMeasurementPeriodMilliSeconds( + VL53L0X_DEV Dev, uint32_t InterMeasurementPeriodMilliSeconds); + +/** + * Get continuous mode Inter-Measurement period in milliseconds + * + * @par Function Description + * When trying to set too short time return INVALID_PARAMS minimal value + * + * @note This function Access to the device + * + * @param Dev Device Handle + * @param pInterMeasurementPeriodMilliSeconds Pointer to programmed + * Inter-Measurement Period in milliseconds. + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_GetInterMeasurementPeriodMilliSeconds( + VL53L0X_DEV Dev, uint32_t *pInterMeasurementPeriodMilliSeconds); + +/** + * @brief Enable/Disable Cross talk compensation feature + * + * @note This function is not Implemented. + * Enable/Disable Cross Talk by set to zero the Cross Talk value + * by using @a VL53L0X_SetXTalkCompensationRateMegaCps(). + * + * @param Dev Device Handle + * @param XTalkCompensationEnable Cross talk compensation + * to be set 0=disabled else = enabled + * @return VL53L0X_ERROR_NOT_IMPLEMENTED Not implemented + */ +VL53L0X_API VL53L0X_Error VL53L0X_SetXTalkCompensationEnable(VL53L0X_DEV Dev, + uint8_t XTalkCompensationEnable); + +/** + * @brief Get Cross talk compensation rate + * + * @note This function is not Implemented. + * Enable/Disable Cross Talk by set to zero the Cross Talk value by + * using @a VL53L0X_SetXTalkCompensationRateMegaCps(). + * + * @param Dev Device Handle + * @param pXTalkCompensationEnable Pointer to the Cross talk compensation + * state 0=disabled or 1 = enabled + * @return VL53L0X_ERROR_NOT_IMPLEMENTED Not implemented + */ +VL53L0X_API VL53L0X_Error VL53L0X_GetXTalkCompensationEnable(VL53L0X_DEV Dev, + uint8_t *pXTalkCompensationEnable); + +/** + * @brief Set Cross talk compensation rate + * + * @par Function Description + * Set Cross talk compensation rate. + * + * @note This function Access to the device + * + * @param Dev Device Handle + * @param XTalkCompensationRateMegaCps Compensation rate in + * Mega counts per second (16.16 fix point) see datasheet for details + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_SetXTalkCompensationRateMegaCps(VL53L0X_DEV Dev, + FixPoint1616_t XTalkCompensationRateMegaCps); + +/** + * @brief Get Cross talk compensation rate + * + * @par Function Description + * Get Cross talk compensation rate. + * + * @note This function Access to the device + * + * @param Dev Device Handle + * @param pXTalkCompensationRateMegaCps Pointer to Compensation rate + in Mega counts per second (16.16 fix point) see datasheet for details + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_GetXTalkCompensationRateMegaCps(VL53L0X_DEV Dev, + FixPoint1616_t *pXTalkCompensationRateMegaCps); + +/** + * @brief Set Reference Calibration Parameters + * + * @par Function Description + * Set Reference Calibration Parameters. + * + * @note This function Access to the device + * + * @param Dev Device Handle + * @param VhvSettings Parameter for VHV + * @param PhaseCal Parameter for PhaseCal + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_SetRefCalibration(VL53L0X_DEV Dev, + uint8_t VhvSettings, uint8_t PhaseCal); + +/** + * @brief Get Reference Calibration Parameters + * + * @par Function Description + * Get Reference Calibration Parameters. + * + * @note This function Access to the device + * + * @param Dev Device Handle + * @param pVhvSettings Pointer to VHV parameter + * @param pPhaseCal Pointer to PhaseCal Parameter + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_GetRefCalibration(VL53L0X_DEV Dev, + uint8_t *pVhvSettings, uint8_t *pPhaseCal); + +/** + * @brief Get the number of the check limit managed by a given Device + * + * @par Function Description + * This function give the number of the check limit managed by the Device + * + * @note This function doesn't Access to the device + * + * @param pNumberOfLimitCheck Pointer to the number of check limit. + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_GetNumberOfLimitCheck( + uint16_t *pNumberOfLimitCheck); + +/** + * @brief Return a description string for a given limit check number + * + * @par Function Description + * This function returns a description string for a given limit check number. + * The limit check is identified with the LimitCheckId. + * + * @note This function doesn't Access to the device + * + * @param Dev Device Handle + * @param LimitCheckId Limit Check ID + (0<= LimitCheckId < VL53L0X_GetNumberOfLimitCheck() ). + * @param pLimitCheckString Pointer to the + description string of the given check limit. + * @return VL53L0X_ERROR_NONE Success + * @return VL53L0X_ERROR_INVALID_PARAMS This error is + returned when LimitCheckId value is out of range. + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_GetLimitCheckInfo(VL53L0X_DEV Dev, + uint16_t LimitCheckId, char *pLimitCheckString); + +/** + * @brief Return a the Status of the specified check limit + * + * @par Function Description + * This function returns the Status of the specified check limit. + * The value indicate if the check is fail or not. + * The limit check is identified with the LimitCheckId. + * + * @note This function doesn't Access to the device + * + * @param Dev Device Handle + * @param LimitCheckId Limit Check ID + (0<= LimitCheckId < VL53L0X_GetNumberOfLimitCheck() ). + * @param pLimitCheckStatus Pointer to the + Limit Check Status of the given check limit. + * LimitCheckStatus : + * 0 the check is not fail + * 1 the check if fail or not enabled + * + * @return VL53L0X_ERROR_NONE Success + * @return VL53L0X_ERROR_INVALID_PARAMS This error is + returned when LimitCheckId value is out of range. + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_GetLimitCheckStatus(VL53L0X_DEV Dev, + uint16_t LimitCheckId, uint8_t *pLimitCheckStatus); + +/** + * @brief Enable/Disable a specific limit check + * + * @par Function Description + * This function Enable/Disable a specific limit check. + * The limit check is identified with the LimitCheckId. + * + * @note This function doesn't Access to the device + * + * @param Dev Device Handle + * @param LimitCheckId Limit Check ID + * (0<= LimitCheckId < VL53L0X_GetNumberOfLimitCheck() ). + * @param LimitCheckEnable if 1 the check limit + * corresponding to LimitCheckId is Enabled + * if 0 the check limit + * corresponding to LimitCheckId is disabled + * @return VL53L0X_ERROR_NONE Success + * @return VL53L0X_ERROR_INVALID_PARAMS This error is returned + * when LimitCheckId value is out of range. + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_SetLimitCheckEnable(VL53L0X_DEV Dev, + uint16_t LimitCheckId, uint8_t LimitCheckEnable); + +/** + * @brief Get specific limit check enable state + * + * @par Function Description + * This function get the enable state of a specific limit check. + * The limit check is identified with the LimitCheckId. + * + * @note This function Access to the device + * + * @param Dev Device Handle + * @param LimitCheckId Limit Check ID + * (0<= LimitCheckId < VL53L0X_GetNumberOfLimitCheck() ). + * @param pLimitCheckEnable Pointer to the check limit enable + * value. + * if 1 the check limit + * corresponding to LimitCheckId is Enabled + * if 0 the check limit + * corresponding to LimitCheckId is disabled + * @return VL53L0X_ERROR_NONE Success + * @return VL53L0X_ERROR_INVALID_PARAMS This error is returned + * when LimitCheckId value is out of range. + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_GetLimitCheckEnable(VL53L0X_DEV Dev, + uint16_t LimitCheckId, uint8_t *pLimitCheckEnable); + +/** + * @brief Set a specific limit check value + * + * @par Function Description + * This function set a specific limit check value. + * The limit check is identified with the LimitCheckId. + * + * @note This function Access to the device + * + * @param Dev Device Handle + * @param LimitCheckId Limit Check ID + * (0<= LimitCheckId < VL53L0X_GetNumberOfLimitCheck() ). + * @param LimitCheckValue Limit check Value for a given + * LimitCheckId + * @return VL53L0X_ERROR_NONE Success + * @return VL53L0X_ERROR_INVALID_PARAMS This error is returned when either + * LimitCheckId or LimitCheckValue value is out of range. + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_SetLimitCheckValue(VL53L0X_DEV Dev, + uint16_t LimitCheckId, FixPoint1616_t LimitCheckValue); + +/** + * @brief Get a specific limit check value + * + * @par Function Description + * This function get a specific limit check value from device then it updates + * internal values and check enables. + * The limit check is identified with the LimitCheckId. + * + * @note This function Access to the device + * + * @param Dev Device Handle + * @param LimitCheckId Limit Check ID + * (0<= LimitCheckId < VL53L0X_GetNumberOfLimitCheck() ). + * @param pLimitCheckValue Pointer to Limit + * check Value for a given LimitCheckId. + * @return VL53L0X_ERROR_NONE Success + * @return VL53L0X_ERROR_INVALID_PARAMS This error is returned + * when LimitCheckId value is out of range. + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_GetLimitCheckValue(VL53L0X_DEV Dev, + uint16_t LimitCheckId, FixPoint1616_t *pLimitCheckValue); + +/** + * @brief Get the current value of the signal used for the limit check + * + * @par Function Description + * This function get a the current value of the signal used for the limit check. + * To obtain the latest value you should run a ranging before. + * The value reported is linked to the limit check identified with the + * LimitCheckId. + * + * @note This function Access to the device + * + * @param Dev Device Handle + * @param LimitCheckId Limit Check ID + * (0<= LimitCheckId < VL53L0X_GetNumberOfLimitCheck() ). + * @param pLimitCheckCurrent Pointer to current Value for a + * given LimitCheckId. + * @return VL53L0X_ERROR_NONE Success + * @return VL53L0X_ERROR_INVALID_PARAMS This error is returned when + * LimitCheckId value is out of range. + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_GetLimitCheckCurrent(VL53L0X_DEV Dev, + uint16_t LimitCheckId, FixPoint1616_t *pLimitCheckCurrent); + +/** + * @brief Enable (or disable) Wrap around Check + * + * @note This function Access to the device + * + * @param Dev Device Handle + * @param WrapAroundCheckEnable Wrap around Check to be set + * 0=disabled, other = enabled + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_SetWrapAroundCheckEnable(VL53L0X_DEV Dev, + uint8_t WrapAroundCheckEnable); + +/** + * @brief Get setup of Wrap around Check + * + * @par Function Description + * This function get the wrapAround check enable parameters + * + * @note This function Access to the device + * + * @param Dev Device Handle + * @param pWrapAroundCheckEnable Pointer to the Wrap around Check state + * 0=disabled or 1 = enabled + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_GetWrapAroundCheckEnable(VL53L0X_DEV Dev, + uint8_t *pWrapAroundCheckEnable); + +/** + * @brief Set Dmax Calibration Parameters for a given device + * When one of the parameter is zero, this function will get parameter + * from NVM. + * @note This function doesn't Access to the device + * + * @param Dev Device Handle + * @param RangeMilliMeter Calibration Distance + * @param SignalRateRtnMegaCps Signal rate return read at CalDistance + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_SetDmaxCalParameters(VL53L0X_DEV Dev, + uint16_t RangeMilliMeter, FixPoint1616_t SignalRateRtnMegaCps); + +/** + * @brief Get Dmax Calibration Parameters for a given device + * + * + * @note This function Access to the device + * + * @param Dev Device Handle + * @param pRangeMilliMeter Pointer to Calibration Distance + * @param pSignalRateRtnMegaCps Pointer to Signal rate return + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_GetDmaxCalParameters(VL53L0X_DEV Dev, + uint16_t *pRangeMilliMeter, FixPoint1616_t *pSignalRateRtnMegaCps); + +/** @} VL53L0X_parameters_group */ + +/** @defgroup VL53L0X_measurement_group VL53L0X Measurement Functions + * @brief Functions used for the measurements + * @{ + */ + +/** + * @brief Single shot measurement. + * + * @par Function Description + * Perform simple measurement sequence (Start measure, Wait measure to end, + * and returns when measurement is done). + * Once function returns, user can get valid data by calling + * VL53L0X_GetRangingMeasurement or VL53L0X_GetHistogramMeasurement + * depending on defined measurement mode + * User should Clear the interrupt in case this are enabled by using the + * function VL53L0X_ClearInterruptMask(). + * + * @warning This function is a blocking function + * + * @note This function Access to the device + * + * @param Dev Device Handle + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_PerformSingleMeasurement(VL53L0X_DEV Dev); + +/** + * @brief Perform Reference Calibration + * + * @details Perform a reference calibration of the Device. + * This function should be run from time to time before doing + * a ranging measurement. + * This function will launch a special ranging measurement, so + * if interrupt are enable an interrupt will be done. + * This function will clear the interrupt generated automatically. + * + * @warning This function is a blocking function + * + * @note This function Access to the device + * + * @param Dev Device Handle + * @param pVhvSettings Pointer to vhv settings parameter. + * @param pPhaseCal Pointer to PhaseCal parameter. + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_PerformRefCalibration(VL53L0X_DEV Dev, + uint8_t *pVhvSettings, uint8_t *pPhaseCal); + +/** + * @brief Perform XTalk Measurement + * + * @details Measures the current cross talk from glass in front + * of the sensor. + * This functions performs a histogram measurement and uses the results + * to measure the crosstalk. For the function to be successful, there + * must be no target in front of the sensor. + * + * @warning This function is a blocking function + * + * @warning This function is not supported when the final range + * vcsel clock period is set below 10 PCLKS. + * + * @note This function Access to the device + * + * @param Dev Device Handle + * @param TimeoutMs Histogram measurement duration. + * @param pXtalkPerSpad Output parameter containing the crosstalk + * measurement result, in MCPS/Spad. Format fixpoint 16:16. + * @param pAmbientTooHigh Output parameter which indicate that + * pXtalkPerSpad is not good if the Ambient is too high. + * @return VL53L0X_ERROR_NONE Success + * @return VL53L0X_ERROR_INVALID_PARAMS vcsel clock period not supported + * for this operation. Must not be less than 10PCLKS. + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_PerformXTalkMeasurement(VL53L0X_DEV Dev, + uint32_t TimeoutMs, FixPoint1616_t *pXtalkPerSpad, + uint8_t *pAmbientTooHigh); + +/** + * @brief Perform XTalk Calibration + * + * @details Perform a XTalk calibration of the Device. + * This function will launch a ranging measurement, if interrupts + * are enabled an interrupt will be done. + * This function will clear the interrupt generated automatically. + * This function will program a new value for the XTalk compensation + * and it will enable the cross talk before exit. + * This function will disable the VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD. + * + * @warning This function is a blocking function + * + * @note This function Access to the device + * + * @note This function change the device mode to + * VL53L0X_DEVICEMODE_SINGLE_RANGING + * + * @param Dev Device Handle + * @param XTalkCalDistance XTalkCalDistance value used for the XTalk + * computation. + * @param pXTalkCompensationRateMegaCps Pointer to new + * XTalkCompensation value. + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_PerformXTalkCalibration(VL53L0X_DEV Dev, + FixPoint1616_t XTalkCalDistance, + FixPoint1616_t *pXTalkCompensationRateMegaCps); + +/** + * @brief Perform Offset Calibration + * + * @details Perform a Offset calibration of the Device. + * This function will launch a ranging measurement, if interrupts are + * enabled an interrupt will be done. + * This function will clear the interrupt generated automatically. + * This function will program a new value for the Offset calibration value + * This function will disable the VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD. + * + * @warning This function is a blocking function + * + * @note This function Access to the device + * + * @note This function does not change the device mode. + * + * @param Dev Device Handle + * @param CalDistanceMilliMeter Calibration distance value used for the + * offset compensation. + * @param pOffsetMicroMeter Pointer to new Offset value computed by the + * function. + * + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_PerformOffsetCalibration(VL53L0X_DEV Dev, + FixPoint1616_t CalDistanceMilliMeter, int32_t *pOffsetMicroMeter); + +/** + * @brief Start device measurement + * + * @details Started measurement will depend on device parameters set through + * @a VL53L0X_SetParameters() + * This is a non-blocking function. + * This function will change the VL53L0X_State from VL53L0X_STATE_IDLE to + * VL53L0X_STATE_RUNNING. + * + * @note This function Access to the device + * + + * @param Dev Device Handle + * @return VL53L0X_ERROR_NONE Success + * @return VL53L0X_ERROR_MODE_NOT_SUPPORTED This error occurs when + * DeviceMode programmed with @a VL53L0X_SetDeviceMode is not in the supported + * list: + * Supported mode are: + * VL53L0X_DEVICEMODE_SINGLE_RANGING, + * VL53L0X_DEVICEMODE_CONTINUOUS_RANGING, + * VL53L0X_DEVICEMODE_CONTINUOUS_TIMED_RANGING + * @return VL53L0X_ERROR_TIME_OUT Time out on start measurement + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_StartMeasurement(VL53L0X_DEV Dev); + +/** + * @brief Stop device measurement + * + * @details Will set the device in standby mode at end of current measurement\n + * Not necessary in single mode as device shall return automatically + * in standby mode at end of measurement. + * This function will change the VL53L0X_State from VL53L0X_STATE_RUNNING + * to VL53L0X_STATE_IDLE. + * + * @note This function Access to the device + * + * @param Dev Device Handle + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_StopMeasurement(VL53L0X_DEV Dev); + +/** + * @brief Return Measurement Data Ready + * + * @par Function Description + * This function indicate that a measurement data is ready. + * This function check if interrupt mode is used then check is done accordingly. + * If perform function clear the interrupt, this function will not work, + * like in case of @a VL53L0X_PerformSingleRangingMeasurement(). + * The previous function is blocking function, VL53L0X_GetMeasurementDataReady + * is used for non-blocking capture. + * + * @note This function Access to the device + * + * @param Dev Device Handle + * @param pMeasurementDataReady Pointer to Measurement Data Ready. + * 0=data not ready, 1 = data ready + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_GetMeasurementDataReady(VL53L0X_DEV Dev, + uint8_t *pMeasurementDataReady); + +/** + * @brief Wait for device ready for a new measurement command. + * Blocking function. + * + * @note This function is not Implemented + * + * @param Dev Device Handle + * @param MaxLoop Max Number of polling loop (timeout). + * @return VL53L0X_ERROR_NOT_IMPLEMENTED Not implemented + */ +VL53L0X_API VL53L0X_Error VL53L0X_WaitDeviceReadyForNewMeasurement(VL53L0X_DEV Dev, + uint32_t MaxLoop); + +/** + * @brief Retrieve the Reference Signal after a measurements + * + * @par Function Description + * Get Reference Signal from last successful Ranging measurement + * This function return a valid value after that you call the + * @a VL53L0X_GetRangingMeasurementData(). + * + * @note This function Access to the device + * + * @param Dev Device Handle + * @param pMeasurementRefSignal Pointer to the Ref Signal to fill up. + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_GetMeasurementRefSignal(VL53L0X_DEV Dev, + FixPoint1616_t *pMeasurementRefSignal); + +/** + * @brief Retrieve the measurements from device for a given setup + * + * @par Function Description + * Get data from last successful Ranging measurement + * @warning USER should take care about @a VL53L0X_GetNumberOfROIZones() + * before get data. + * PAL will fill a NumberOfROIZones times the corresponding data + * structure used in the measurement function. + * + * @note This function Access to the device + * + * @param Dev Device Handle + * @param pRangingMeasurementData Pointer to the data structure to fill up. + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_GetRangingMeasurementData(VL53L0X_DEV Dev, + VL53L0X_RangingMeasurementData_t *pRangingMeasurementData); + +/** + * @brief Retrieve the measurements from device for a given setup + * + * @par Function Description + * Get data from last successful Histogram measurement + * @warning USER should take care about @a VL53L0X_GetNumberOfROIZones() + * before get data. + * PAL will fill a NumberOfROIZones times the corresponding data structure + * used in the measurement function. + * + * @note This function is not Implemented + * + * @param Dev Device Handle + * @param pHistogramMeasurementData Pointer to the histogram data structure. + * @return VL53L0X_ERROR_NOT_IMPLEMENTED Not implemented + */ +VL53L0X_API VL53L0X_Error VL53L0X_GetHistogramMeasurementData(VL53L0X_DEV Dev, + VL53L0X_HistogramMeasurementData_t *pHistogramMeasurementData); + +/** + * @brief Performs a single ranging measurement and retrieve the ranging + * measurement data + * + * @par Function Description + * This function will change the device mode to VL53L0X_DEVICEMODE_SINGLE_RANGING + * with @a VL53L0X_SetDeviceMode(), + * It performs measurement with @a VL53L0X_PerformSingleMeasurement() + * It get data from last successful Ranging measurement with + * @a VL53L0X_GetRangingMeasurementData. + * Finally it clear the interrupt with @a VL53L0X_ClearInterruptMask(). + * + * @note This function Access to the device + * + * @note This function change the device mode to + * VL53L0X_DEVICEMODE_SINGLE_RANGING + * + * @param Dev Device Handle + * @param pRangingMeasurementData Pointer to the data structure to fill up. + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_PerformSingleRangingMeasurement(VL53L0X_DEV Dev, + VL53L0X_RangingMeasurementData_t *pRangingMeasurementData); + +/** + * @brief Performs a single histogram measurement and retrieve the histogram + * measurement data + * Is equivalent to VL53L0X_PerformSingleMeasurement + + * VL53L0X_GetHistogramMeasurementData + * + * @par Function Description + * Get data from last successful Ranging measurement. + * This function will clear the interrupt in case of these are enabled. + * + * @note This function is not Implemented + * + * @param Dev Device Handle + * @param pHistogramMeasurementData Pointer to the data structure to fill up. + * @return VL53L0X_ERROR_NOT_IMPLEMENTED Not implemented + */ +VL53L0X_API VL53L0X_Error VL53L0X_PerformSingleHistogramMeasurement(VL53L0X_DEV Dev, + VL53L0X_HistogramMeasurementData_t *pHistogramMeasurementData); + +/** + * @brief Set the number of ROI Zones to be used for a specific Device + * + * @par Function Description + * Set the number of ROI Zones to be used for a specific Device. + * The programmed value should be less than the max number of ROI Zones given + * with @a VL53L0X_GetMaxNumberOfROIZones(). + * This version of API manage only one zone. + * + * @param Dev Device Handle + * @param NumberOfROIZones Number of ROI Zones to be used for a + * specific Device. + * @return VL53L0X_ERROR_NONE Success + * @return VL53L0X_ERROR_INVALID_PARAMS This error is returned if + * NumberOfROIZones != 1 + */ +VL53L0X_API VL53L0X_Error VL53L0X_SetNumberOfROIZones(VL53L0X_DEV Dev, + uint8_t NumberOfROIZones); + +/** + * @brief Get the number of ROI Zones managed by the Device + * + * @par Function Description + * Get number of ROI Zones managed by the Device + * USER should take care about @a VL53L0X_GetNumberOfROIZones() + * before get data after a perform measurement. + * PAL will fill a NumberOfROIZones times the corresponding data + * structure used in the measurement function. + * + * @note This function doesn't Access to the device + * + * @param Dev Device Handle + * @param pNumberOfROIZones Pointer to the Number of ROI Zones value. + * @return VL53L0X_ERROR_NONE Success + */ +VL53L0X_API VL53L0X_Error VL53L0X_GetNumberOfROIZones(VL53L0X_DEV Dev, + uint8_t *pNumberOfROIZones); + +/** + * @brief Get the Maximum number of ROI Zones managed by the Device + * + * @par Function Description + * Get Maximum number of ROI Zones managed by the Device. + * + * @note This function doesn't Access to the device + * + * @param Dev Device Handle + * @param pMaxNumberOfROIZones Pointer to the Maximum Number + * of ROI Zones value. + * @return VL53L0X_ERROR_NONE Success + */ +VL53L0X_API VL53L0X_Error VL53L0X_GetMaxNumberOfROIZones(VL53L0X_DEV Dev, + uint8_t *pMaxNumberOfROIZones); + +/** @} VL53L0X_measurement_group */ + +/** @defgroup VL53L0X_interrupt_group VL53L0X Interrupt Functions + * @brief Functions used for interrupt managements + * @{ + */ + +/** + * @brief Set the configuration of GPIO pin for a given device + * + * @note This function Access to the device + * + * @param Dev Device Handle + * @param Pin ID of the GPIO Pin + * @param Functionality Select Pin functionality. + * Refer to ::VL53L0X_GpioFunctionality + * @param DeviceMode Device Mode associated to the Gpio. + * @param Polarity Set interrupt polarity. Active high + * or active low see ::VL53L0X_InterruptPolarity + * @return VL53L0X_ERROR_NONE Success + * @return VL53L0X_ERROR_GPIO_NOT_EXISTING Only Pin=0 is accepted. + * @return VL53L0X_ERROR_GPIO_FUNCTIONALITY_NOT_SUPPORTED This error occurs + * when Functionality programmed is not in the supported list: + * Supported value are: + * VL53L0X_GPIOFUNCTIONALITY_OFF, + * VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_LOW, + * VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_HIGH, + VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_OUT, + * VL53L0X_GPIOFUNCTIONALITY_NEW_MEASURE_READY + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_SetGpioConfig(VL53L0X_DEV Dev, uint8_t Pin, + VL53L0X_DeviceModes DeviceMode, VL53L0X_GpioFunctionality Functionality, + VL53L0X_InterruptPolarity Polarity); + +/** + * @brief Get current configuration for GPIO pin for a given device + * + * @note This function Access to the device + * + * @param Dev Device Handle + * @param Pin ID of the GPIO Pin + * @param pDeviceMode Pointer to Device Mode associated to the Gpio. + * @param pFunctionality Pointer to Pin functionality. + * Refer to ::VL53L0X_GpioFunctionality + * @param pPolarity Pointer to interrupt polarity. + * Active high or active low see ::VL53L0X_InterruptPolarity + * @return VL53L0X_ERROR_NONE Success + * @return VL53L0X_ERROR_GPIO_NOT_EXISTING Only Pin=0 is accepted. + * @return VL53L0X_ERROR_GPIO_FUNCTIONALITY_NOT_SUPPORTED This error occurs + * when Functionality programmed is not in the supported list: + * Supported value are: + * VL53L0X_GPIOFUNCTIONALITY_OFF, + * VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_LOW, + * VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_HIGH, + * VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_OUT, + * VL53L0X_GPIOFUNCTIONALITY_NEW_MEASURE_READY + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_GetGpioConfig(VL53L0X_DEV Dev, uint8_t Pin, + VL53L0X_DeviceModes *pDeviceMode, + VL53L0X_GpioFunctionality *pFunctionality, + VL53L0X_InterruptPolarity *pPolarity); + +/** + * @brief Set low and high Interrupt thresholds for a given mode + * (ranging, ALS, ...) for a given device + * + * @par Function Description + * Set low and high Interrupt thresholds for a given mode (ranging, ALS, ...) + * for a given device + * + * @note This function Access to the device + * + * @note DeviceMode is ignored for the current device + * + * @param Dev Device Handle + * @param DeviceMode Device Mode for which change thresholds + * @param ThresholdLow Low threshold (mm, lux ..., depending on the mode) + * @param ThresholdHigh High threshold (mm, lux ..., depending on the mode) + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_SetInterruptThresholds(VL53L0X_DEV Dev, + VL53L0X_DeviceModes DeviceMode, FixPoint1616_t ThresholdLow, + FixPoint1616_t ThresholdHigh); + +/** + * @brief Get high and low Interrupt thresholds for a given mode + * (ranging, ALS, ...) for a given device + * + * @par Function Description + * Get high and low Interrupt thresholds for a given mode (ranging, ALS, ...) + * for a given device + * + * @note This function Access to the device + * + * @note DeviceMode is ignored for the current device + * + * @param Dev Device Handle + * @param DeviceMode Device Mode from which read thresholds + * @param pThresholdLow Low threshold (mm, lux ..., depending on the mode) + * @param pThresholdHigh High threshold (mm, lux ..., depending on the mode) + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_GetInterruptThresholds(VL53L0X_DEV Dev, + VL53L0X_DeviceModes DeviceMode, FixPoint1616_t *pThresholdLow, + FixPoint1616_t *pThresholdHigh); + +/** + * @brief Return device stop completion status + * + * @par Function Description + * Returns stop completiob status. + * User shall call this function after a stop command + * + * @note This function Access to the device + * + * @param Dev Device Handle + * @param pStopStatus Pointer to status variable to update + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_GetStopCompletedStatus(VL53L0X_DEV Dev, + uint32_t *pStopStatus); + + +/** + * @brief Clear given system interrupt condition + * + * @par Function Description + * Clear given interrupt(s). + * + * @note This function Access to the device + * + * @param Dev Device Handle + * @param InterruptMask Mask of interrupts to clear + * @return VL53L0X_ERROR_NONE Success + * @return VL53L0X_ERROR_INTERRUPT_NOT_CLEARED Cannot clear interrupts + * + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_ClearInterruptMask(VL53L0X_DEV Dev, + uint32_t InterruptMask); + +/** + * @brief Return device interrupt status + * + * @par Function Description + * Returns currently raised interrupts by the device. + * User shall be able to activate/deactivate interrupts through + * @a VL53L0X_SetGpioConfig() + * + * @note This function Access to the device + * + * @param Dev Device Handle + * @param pInterruptMaskStatus Pointer to status variable to update + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_GetInterruptMaskStatus(VL53L0X_DEV Dev, + uint32_t *pInterruptMaskStatus); + +/** + * @brief Configure ranging interrupt reported to system + * + * @note This function is not Implemented + * + * @param Dev Device Handle + * @param InterruptMask Mask of interrupt to Enable/disable + * (0:interrupt disabled or 1: interrupt enabled) + * @return VL53L0X_ERROR_NOT_IMPLEMENTED Not implemented + */ +VL53L0X_API VL53L0X_Error VL53L0X_EnableInterruptMask(VL53L0X_DEV Dev, + uint32_t InterruptMask); + +/** @} VL53L0X_interrupt_group */ + +/** @defgroup VL53L0X_SPADfunctions_group VL53L0X SPAD Functions + * @brief Functions used for SPAD managements + * @{ + */ + +/** + * @brief Set the SPAD Ambient Damper Threshold value + * + * @par Function Description + * This function set the SPAD Ambient Damper Threshold value + * + * @note This function Access to the device + * + * @param Dev Device Handle + * @param SpadAmbientDamperThreshold SPAD Ambient Damper Threshold value + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_SetSpadAmbientDamperThreshold(VL53L0X_DEV Dev, + uint16_t SpadAmbientDamperThreshold); + +/** + * @brief Get the current SPAD Ambient Damper Threshold value + * + * @par Function Description + * This function get the SPAD Ambient Damper Threshold value + * + * @note This function Access to the device + * + * @param Dev Device Handle + * @param pSpadAmbientDamperThreshold Pointer to programmed + * SPAD Ambient Damper Threshold value + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_GetSpadAmbientDamperThreshold(VL53L0X_DEV Dev, + uint16_t *pSpadAmbientDamperThreshold); + +/** + * @brief Set the SPAD Ambient Damper Factor value + * + * @par Function Description + * This function set the SPAD Ambient Damper Factor value + * + * @note This function Access to the device + * + * @param Dev Device Handle + * @param SpadAmbientDamperFactor SPAD Ambient Damper Factor value + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_SetSpadAmbientDamperFactor(VL53L0X_DEV Dev, + uint16_t SpadAmbientDamperFactor); + +/** + * @brief Get the current SPAD Ambient Damper Factor value + * + * @par Function Description + * This function get the SPAD Ambient Damper Factor value + * + * @note This function Access to the device + * + * @param Dev Device Handle + * @param pSpadAmbientDamperFactor Pointer to programmed SPAD Ambient + * Damper Factor value + * @return VL53L0X_ERROR_NONE Success + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_GetSpadAmbientDamperFactor(VL53L0X_DEV Dev, + uint16_t *pSpadAmbientDamperFactor); + +/** + * @brief Performs Reference Spad Management + * + * @par Function Description + * The reference SPAD initialization procedure determines the minimum amount + * of reference spads to be enables to achieve a target reference signal rate + * and should be performed once during initialization. + * + * @note This function Access to the device + * + * @note This function change the device mode to + * VL53L0X_DEVICEMODE_SINGLE_RANGING + * + * @param Dev Device Handle + * @param refSpadCount Reports ref Spad Count + * @param isApertureSpads Reports if spads are of type + * aperture or non-aperture. + * 1:=aperture, 0:=Non-Aperture + * @return VL53L0X_ERROR_NONE Success + * @return VL53L0X_ERROR_REF_SPAD_INIT Error in the Ref Spad procedure. + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_PerformRefSpadManagement(VL53L0X_DEV Dev, + uint32_t *refSpadCount, uint8_t *isApertureSpads); + +/** + * @brief Applies Reference SPAD configuration + * + * @par Function Description + * This function applies a given number of reference spads, identified as + * either Aperture or Non-Aperture. + * The requested spad count and type are stored within the device specific + * parameters data for access by the host. + * + * @note This function Access to the device + * + * @param Dev Device Handle + * @param refSpadCount Number of ref spads. + * @param isApertureSpads Defines if spads are of type + * aperture or non-aperture. + * 1:=aperture, 0:=Non-Aperture + * @return VL53L0X_ERROR_NONE Success + * @return VL53L0X_ERROR_REF_SPAD_INIT Error in the in the reference + * spad configuration. + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_SetReferenceSpads(VL53L0X_DEV Dev, + uint32_t refSpadCount, uint8_t isApertureSpads); + +/** + * @brief Retrieves SPAD configuration + * + * @par Function Description + * This function retrieves the current number of applied reference spads + * and also their type : Aperture or Non-Aperture. + * + * @note This function Access to the device + * + * @param Dev Device Handle + * @param refSpadCount Number ref Spad Count + * @param isApertureSpads Reports if spads are of type + * aperture or non-aperture. + * 1:=aperture, 0:=Non-Aperture + * @return VL53L0X_ERROR_NONE Success + * @return VL53L0X_ERROR_REF_SPAD_INIT Error in the in the reference + * spad configuration. + * @return "Other error code" See ::VL53L0X_Error + */ +VL53L0X_API VL53L0X_Error VL53L0X_GetReferenceSpads(VL53L0X_DEV Dev, + uint32_t *refSpadCount, uint8_t *isApertureSpads); + +/** @} VL53L0X_SPADfunctions_group */ + +/** @} VL53L0X_cut11_group */ + +#ifdef __cplusplus +} +#endif + +#endif /* _VL53L0X_API_H_ */ diff --git a/modules/VL53L0X/inc/vl53l0x_api_calibration.h b/modules/VL53L0X/inc/vl53l0x_api_calibration.h new file mode 100644 index 0000000000000000000000000000000000000000..9f9739ab4f27264e813916666b99355292c5c0b1 --- /dev/null +++ b/modules/VL53L0X/inc/vl53l0x_api_calibration.h @@ -0,0 +1,85 @@ +/******************************************************************************* +Copyright 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 _VL53L0X_API_CALIBRATION_H_ +#define _VL53L0X_API_CALIBRATION_H_ + +#include "vl53l0x_def.h" +#include "vl53l0x_platform.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +VL53L0X_Error VL53L0X_perform_xtalk_calibration(VL53L0X_DEV Dev, + FixPoint1616_t XTalkCalDistance, + FixPoint1616_t *pXTalkCompensationRateMegaCps); + +VL53L0X_Error VL53L0X_perform_offset_calibration(VL53L0X_DEV Dev, + FixPoint1616_t CalDistanceMilliMeter, + int32_t *pOffsetMicroMeter); + +VL53L0X_Error VL53L0X_set_offset_calibration_data_micro_meter(VL53L0X_DEV Dev, + int32_t OffsetCalibrationDataMicroMeter); + +VL53L0X_Error VL53L0X_get_offset_calibration_data_micro_meter(VL53L0X_DEV Dev, + int32_t *pOffsetCalibrationDataMicroMeter); + +VL53L0X_Error VL53L0X_apply_offset_adjustment(VL53L0X_DEV Dev); + +VL53L0X_Error VL53L0X_perform_ref_spad_management(VL53L0X_DEV Dev, + uint32_t *refSpadCount, uint8_t *isApertureSpads); + +VL53L0X_Error VL53L0X_set_reference_spads(VL53L0X_DEV Dev, + uint32_t count, uint8_t isApertureSpads); + +VL53L0X_Error VL53L0X_get_reference_spads(VL53L0X_DEV Dev, + uint32_t *pSpadCount, uint8_t *pIsApertureSpads); + +VL53L0X_Error VL53L0X_perform_phase_calibration(VL53L0X_DEV Dev, + uint8_t *pPhaseCal, const uint8_t get_data_enable, + const uint8_t restore_config); + +VL53L0X_Error VL53L0X_perform_ref_calibration(VL53L0X_DEV Dev, + uint8_t *pVhvSettings, uint8_t *pPhaseCal, uint8_t get_data_enable); + +VL53L0X_Error VL53L0X_set_ref_calibration(VL53L0X_DEV Dev, + uint8_t VhvSettings, uint8_t PhaseCal); + +VL53L0X_Error VL53L0X_get_ref_calibration(VL53L0X_DEV Dev, + uint8_t *pVhvSettings, uint8_t *pPhaseCal); + + + + +#ifdef __cplusplus +} +#endif + +#endif /* _VL53L0X_API_CALIBRATION_H_ */ diff --git a/modules/VL53L0X/inc/vl53l0x_api_core.h b/modules/VL53L0X/inc/vl53l0x_api_core.h new file mode 100644 index 0000000000000000000000000000000000000000..91f20423dc8a17ccd77756e069cf66caf208c607 --- /dev/null +++ b/modules/VL53L0X/inc/vl53l0x_api_core.h @@ -0,0 +1,108 @@ +/******************************************************************************* +Copyright 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 _VL53L0X_API_CORE_H_ +#define _VL53L0X_API_CORE_H_ + +#include "vl53l0x_def.h" +#include "vl53l0x_platform.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +VL53L0X_Error VL53L0X_reverse_bytes(uint8_t *data, uint32_t size); + +VL53L0X_Error VL53L0X_measurement_poll_for_completion(VL53L0X_DEV Dev); + +uint8_t VL53L0X_encode_vcsel_period(uint8_t vcsel_period_pclks); + +uint8_t VL53L0X_decode_vcsel_period(uint8_t vcsel_period_reg); + +uint32_t VL53L0X_isqrt(uint32_t num); + +uint32_t VL53L0X_quadrature_sum(uint32_t a, uint32_t b); + +VL53L0X_Error VL53L0X_get_info_from_device(VL53L0X_DEV Dev, uint8_t option); + +VL53L0X_Error VL53L0X_set_vcsel_pulse_period(VL53L0X_DEV Dev, + VL53L0X_VcselPeriod VcselPeriodType, uint8_t VCSELPulsePeriodPCLK); + +VL53L0X_Error VL53L0X_get_vcsel_pulse_period(VL53L0X_DEV Dev, + VL53L0X_VcselPeriod VcselPeriodType, uint8_t *pVCSELPulsePeriodPCLK); + +uint32_t VL53L0X_decode_timeout(uint16_t encoded_timeout); + +VL53L0X_Error get_sequence_step_timeout(VL53L0X_DEV Dev, + VL53L0X_SequenceStepId SequenceStepId, + uint32_t *pTimeOutMicroSecs); + +VL53L0X_Error set_sequence_step_timeout(VL53L0X_DEV Dev, + VL53L0X_SequenceStepId SequenceStepId, + uint32_t TimeOutMicroSecs); + +VL53L0X_Error VL53L0X_set_measurement_timing_budget_micro_seconds(VL53L0X_DEV Dev, + uint32_t MeasurementTimingBudgetMicroSeconds); + +VL53L0X_Error VL53L0X_get_measurement_timing_budget_micro_seconds(VL53L0X_DEV Dev, + uint32_t *pMeasurementTimingBudgetMicroSeconds); + +VL53L0X_Error VL53L0X_load_tuning_settings(VL53L0X_DEV Dev, + uint8_t *pTuningSettingBuffer); + +VL53L0X_Error VL53L0X_calc_sigma_estimate(VL53L0X_DEV Dev, + VL53L0X_RangingMeasurementData_t *pRangingMeasurementData, + FixPoint1616_t *pSigmaEstimate, uint32_t *pDmax_mm); + +VL53L0X_Error VL53L0X_get_total_xtalk_rate(VL53L0X_DEV Dev, + VL53L0X_RangingMeasurementData_t *pRangingMeasurementData, + FixPoint1616_t *ptotal_xtalk_rate_mcps); + +VL53L0X_Error VL53L0X_get_total_signal_rate(VL53L0X_DEV Dev, + VL53L0X_RangingMeasurementData_t *pRangingMeasurementData, + FixPoint1616_t *ptotal_signal_rate_mcps); + +VL53L0X_Error VL53L0X_get_pal_range_status(VL53L0X_DEV Dev, + uint8_t DeviceRangeStatus, + FixPoint1616_t SignalRate, + uint16_t EffectiveSpadRtnCount, + VL53L0X_RangingMeasurementData_t *pRangingMeasurementData, + uint8_t *pPalRangeStatus); + +uint32_t VL53L0X_calc_timeout_mclks(VL53L0X_DEV Dev, + uint32_t timeout_period_us, uint8_t vcsel_period_pclks); + +uint16_t VL53L0X_encode_timeout(uint32_t timeout_macro_clks); + +#ifdef __cplusplus +} +#endif + +#endif /* _VL53L0X_API_CORE_H_ */ diff --git a/modules/VL53L0X/inc/vl53l0x_api_ranging.h b/modules/VL53L0X/inc/vl53l0x_api_ranging.h new file mode 100644 index 0000000000000000000000000000000000000000..6d9f4b0df3a3fabbb9d0efbad36a9f70a1f0581c --- /dev/null +++ b/modules/VL53L0X/inc/vl53l0x_api_ranging.h @@ -0,0 +1,47 @@ +/******************************************************************************* +Copyright 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 _VL53L0X_API_RANGING_H_ +#define _VL53L0X_API_RANGING_H_ + +#include "vl53l0x_def.h" +#include "vl53l0x_platform.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + + + +#ifdef __cplusplus +} +#endif + +#endif /* _VL53L0X_API_RANGING_H_ */ diff --git a/modules/VL53L0X/inc/vl53l0x_api_strings.h b/modules/VL53L0X/inc/vl53l0x_api_strings.h new file mode 100644 index 0000000000000000000000000000000000000000..20d594a5aeb1b8fa3f1ae8058d7dd5e62656347f --- /dev/null +++ b/modules/VL53L0X/inc/vl53l0x_api_strings.h @@ -0,0 +1,277 @@ +/******************************************************************************* +Copyright 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 VL53L0X_API_STRINGS_H_ +#define VL53L0X_API_STRINGS_H_ + +#include "vl53l0x_def.h" +#include "vl53l0x_platform.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +VL53L0X_Error VL53L0X_get_device_info(VL53L0X_DEV Dev, + VL53L0X_DeviceInfo_t *pVL53L0X_DeviceInfo); + +VL53L0X_Error VL53L0X_get_device_error_string(VL53L0X_DeviceError ErrorCode, + char *pDeviceErrorString); + +VL53L0X_Error VL53L0X_get_range_status_string(uint8_t RangeStatus, + char *pRangeStatusString); + +VL53L0X_Error VL53L0X_get_pal_error_string(VL53L0X_Error PalErrorCode, + char *pPalErrorString); + +VL53L0X_Error VL53L0X_get_pal_state_string(VL53L0X_State PalStateCode, + char *pPalStateString); + +VL53L0X_Error VL53L0X_get_sequence_steps_info( + VL53L0X_SequenceStepId SequenceStepId, + char *pSequenceStepsString); + +VL53L0X_Error VL53L0X_get_limit_check_info(VL53L0X_DEV Dev, uint16_t LimitCheckId, + char *pLimitCheckString); + + +#ifdef USE_EMPTY_STRING + #define VL53L0X_STRING_DEVICE_INFO_NAME "" + #define VL53L0X_STRING_DEVICE_INFO_NAME_TS0 "" + #define VL53L0X_STRING_DEVICE_INFO_NAME_TS1 "" + #define VL53L0X_STRING_DEVICE_INFO_NAME_TS2 "" + #define VL53L0X_STRING_DEVICE_INFO_NAME_ES1 "" + #define VL53L0X_STRING_DEVICE_INFO_TYPE "" + + /* PAL ERROR strings */ + #define VL53L0X_STRING_ERROR_NONE "" + #define VL53L0X_STRING_ERROR_CALIBRATION_WARNING "" + #define VL53L0X_STRING_ERROR_MIN_CLIPPED "" + #define VL53L0X_STRING_ERROR_UNDEFINED "" + #define VL53L0X_STRING_ERROR_INVALID_PARAMS "" + #define VL53L0X_STRING_ERROR_NOT_SUPPORTED "" + #define VL53L0X_STRING_ERROR_RANGE_ERROR "" + #define VL53L0X_STRING_ERROR_TIME_OUT "" + #define VL53L0X_STRING_ERROR_MODE_NOT_SUPPORTED "" + #define VL53L0X_STRING_ERROR_BUFFER_TOO_SMALL "" + #define VL53L0X_STRING_ERROR_GPIO_NOT_EXISTING "" + #define VL53L0X_STRING_ERROR_GPIO_FUNCTIONALITY_NOT_SUPPORTED "" + #define VL53L0X_STRING_ERROR_CONTROL_INTERFACE "" + #define VL53L0X_STRING_ERROR_INVALID_COMMAND "" + #define VL53L0X_STRING_ERROR_DIVISION_BY_ZERO "" + #define VL53L0X_STRING_ERROR_REF_SPAD_INIT "" + #define VL53L0X_STRING_ERROR_NOT_IMPLEMENTED "" + + #define VL53L0X_STRING_UNKNOW_ERROR_CODE "" + + + + /* Range Status */ + #define VL53L0X_STRING_RANGESTATUS_NONE "" + #define VL53L0X_STRING_RANGESTATUS_RANGEVALID "" + #define VL53L0X_STRING_RANGESTATUS_SIGMA "" + #define VL53L0X_STRING_RANGESTATUS_SIGNAL "" + #define VL53L0X_STRING_RANGESTATUS_MINRANGE "" + #define VL53L0X_STRING_RANGESTATUS_PHASE "" + #define VL53L0X_STRING_RANGESTATUS_HW "" + + + /* Range Status */ + #define VL53L0X_STRING_STATE_POWERDOWN "" + #define VL53L0X_STRING_STATE_WAIT_STATICINIT "" + #define VL53L0X_STRING_STATE_STANDBY "" + #define VL53L0X_STRING_STATE_IDLE "" + #define VL53L0X_STRING_STATE_RUNNING "" + #define VL53L0X_STRING_STATE_UNKNOWN "" + #define VL53L0X_STRING_STATE_ERROR "" + + + /* Device Specific */ + #define VL53L0X_STRING_DEVICEERROR_NONE "" + #define VL53L0X_STRING_DEVICEERROR_VCSELCONTINUITYTESTFAILURE "" + #define VL53L0X_STRING_DEVICEERROR_VCSELWATCHDOGTESTFAILURE "" + #define VL53L0X_STRING_DEVICEERROR_NOVHVVALUEFOUND "" + #define VL53L0X_STRING_DEVICEERROR_MSRCNOTARGET "" + #define VL53L0X_STRING_DEVICEERROR_SNRCHECK "" + #define VL53L0X_STRING_DEVICEERROR_RANGEPHASECHECK "" + #define VL53L0X_STRING_DEVICEERROR_SIGMATHRESHOLDCHECK "" + #define VL53L0X_STRING_DEVICEERROR_TCC "" + #define VL53L0X_STRING_DEVICEERROR_PHASECONSISTENCY "" + #define VL53L0X_STRING_DEVICEERROR_MINCLIP "" + #define VL53L0X_STRING_DEVICEERROR_RANGECOMPLETE "" + #define VL53L0X_STRING_DEVICEERROR_ALGOUNDERFLOW "" + #define VL53L0X_STRING_DEVICEERROR_ALGOOVERFLOW "" + #define VL53L0X_STRING_DEVICEERROR_RANGEIGNORETHRESHOLD "" + #define VL53L0X_STRING_DEVICEERROR_UNKNOWN "" + + /* Check Enable */ + #define VL53L0X_STRING_CHECKENABLE_SIGMA_FINAL_RANGE "" + #define VL53L0X_STRING_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE "" + #define VL53L0X_STRING_CHECKENABLE_SIGNAL_REF_CLIP "" + #define VL53L0X_STRING_CHECKENABLE_RANGE_IGNORE_THRESHOLD "" + + /* Sequence Step */ + #define VL53L0X_STRING_SEQUENCESTEP_TCC "" + #define VL53L0X_STRING_SEQUENCESTEP_DSS "" + #define VL53L0X_STRING_SEQUENCESTEP_MSRC "" + #define VL53L0X_STRING_SEQUENCESTEP_PRE_RANGE "" + #define VL53L0X_STRING_SEQUENCESTEP_FINAL_RANGE "" +#else + #define VL53L0X_STRING_DEVICE_INFO_NAME "VL53L0X cut1.0" + #define VL53L0X_STRING_DEVICE_INFO_NAME_TS0 "VL53L0X TS0" + #define VL53L0X_STRING_DEVICE_INFO_NAME_TS1 "VL53L0X TS1" + #define VL53L0X_STRING_DEVICE_INFO_NAME_TS2 "VL53L0X TS2" + #define VL53L0X_STRING_DEVICE_INFO_NAME_ES1 "VL53L0X ES1 or later" + #define VL53L0X_STRING_DEVICE_INFO_TYPE "VL53L0X" + + /* PAL ERROR strings */ + #define VL53L0X_STRING_ERROR_NONE \ + "No Error" + #define VL53L0X_STRING_ERROR_CALIBRATION_WARNING \ + "Calibration Warning Error" + #define VL53L0X_STRING_ERROR_MIN_CLIPPED \ + "Min clipped error" + #define VL53L0X_STRING_ERROR_UNDEFINED \ + "Undefined error" + #define VL53L0X_STRING_ERROR_INVALID_PARAMS \ + "Invalid parameters error" + #define VL53L0X_STRING_ERROR_NOT_SUPPORTED \ + "Not supported error" + #define VL53L0X_STRING_ERROR_RANGE_ERROR \ + "Range error" + #define VL53L0X_STRING_ERROR_TIME_OUT \ + "Time out error" + #define VL53L0X_STRING_ERROR_MODE_NOT_SUPPORTED \ + "Mode not supported error" + #define VL53L0X_STRING_ERROR_BUFFER_TOO_SMALL \ + "Buffer too small" + #define VL53L0X_STRING_ERROR_GPIO_NOT_EXISTING \ + "GPIO not existing" + #define VL53L0X_STRING_ERROR_GPIO_FUNCTIONALITY_NOT_SUPPORTED \ + "GPIO funct not supported" + #define VL53L0X_STRING_ERROR_INTERRUPT_NOT_CLEARED \ + "Interrupt not Cleared" + #define VL53L0X_STRING_ERROR_CONTROL_INTERFACE \ + "Control Interface Error" + #define VL53L0X_STRING_ERROR_INVALID_COMMAND \ + "Invalid Command Error" + #define VL53L0X_STRING_ERROR_DIVISION_BY_ZERO \ + "Division by zero Error" + #define VL53L0X_STRING_ERROR_REF_SPAD_INIT \ + "Reference Spad Init Error" + #define VL53L0X_STRING_ERROR_NOT_IMPLEMENTED \ + "Not implemented error" + + #define VL53L0X_STRING_UNKNOW_ERROR_CODE \ + "Unknown Error Code" + + + + /* Range Status */ + #define VL53L0X_STRING_RANGESTATUS_NONE "No Update " + #define VL53L0X_STRING_RANGESTATUS_RANGEVALID "Range Valid " + #define VL53L0X_STRING_RANGESTATUS_SIGMA "Sigma Fail " + #define VL53L0X_STRING_RANGESTATUS_SIGNAL "Signal Fail " + #define VL53L0X_STRING_RANGESTATUS_MINRANGE "Min Range Fail" + #define VL53L0X_STRING_RANGESTATUS_PHASE "Phase Fail " + #define VL53L0X_STRING_RANGESTATUS_HW "Hardware Fail " + + + /* Range Status */ + #define VL53L0X_STRING_STATE_POWERDOWN "POWERDOWN State" + #define VL53L0X_STRING_STATE_WAIT_STATICINIT \ + "Wait for staticinit State" + #define VL53L0X_STRING_STATE_STANDBY "STANDBY State" + #define VL53L0X_STRING_STATE_IDLE "IDLE State" + #define VL53L0X_STRING_STATE_RUNNING "RUNNING State" + #define VL53L0X_STRING_STATE_UNKNOWN "UNKNOWN State" + #define VL53L0X_STRING_STATE_ERROR "ERROR State" + + + /* Device Specific */ + #define VL53L0X_STRING_DEVICEERROR_NONE "No Update" + #define VL53L0X_STRING_DEVICEERROR_VCSELCONTINUITYTESTFAILURE \ + "VCSEL Continuity Test Failure" + #define VL53L0X_STRING_DEVICEERROR_VCSELWATCHDOGTESTFAILURE \ + "VCSEL Watchdog Test Failure" + #define VL53L0X_STRING_DEVICEERROR_NOVHVVALUEFOUND \ + "No VHV Value found" + #define VL53L0X_STRING_DEVICEERROR_MSRCNOTARGET \ + "MSRC No Target Error" + #define VL53L0X_STRING_DEVICEERROR_SNRCHECK \ + "SNR Check Exit" + #define VL53L0X_STRING_DEVICEERROR_RANGEPHASECHECK \ + "Range Phase Check Error" + #define VL53L0X_STRING_DEVICEERROR_SIGMATHRESHOLDCHECK \ + "Sigma Threshold Check Error" + #define VL53L0X_STRING_DEVICEERROR_TCC \ + "TCC Error" + #define VL53L0X_STRING_DEVICEERROR_PHASECONSISTENCY \ + "Phase Consistency Error" + #define VL53L0X_STRING_DEVICEERROR_MINCLIP \ + "Min Clip Error" + #define VL53L0X_STRING_DEVICEERROR_RANGECOMPLETE \ + "Range Complete" + #define VL53L0X_STRING_DEVICEERROR_ALGOUNDERFLOW \ + "Range Algo Underflow Error" + #define VL53L0X_STRING_DEVICEERROR_ALGOOVERFLOW \ + "Range Algo Overlow Error" + #define VL53L0X_STRING_DEVICEERROR_RANGEIGNORETHRESHOLD \ + "Range Ignore Threshold Error" + #define VL53L0X_STRING_DEVICEERROR_UNKNOWN \ + "Unknown error code" + + /* Check Enable */ + #define VL53L0X_STRING_CHECKENABLE_SIGMA_FINAL_RANGE \ + "SIGMA FINAL RANGE" + #define VL53L0X_STRING_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE \ + "SIGNAL RATE FINAL RANGE" + #define VL53L0X_STRING_CHECKENABLE_SIGNAL_REF_CLIP \ + "SIGNAL REF CLIP" + #define VL53L0X_STRING_CHECKENABLE_RANGE_IGNORE_THRESHOLD \ + "RANGE IGNORE THRESHOLD" + #define VL53L0X_STRING_CHECKENABLE_SIGNAL_RATE_MSRC \ + "SIGNAL RATE MSRC" + #define VL53L0X_STRING_CHECKENABLE_SIGNAL_RATE_PRE_RANGE \ + "SIGNAL RATE PRE RANGE" + + /* Sequence Step */ + #define VL53L0X_STRING_SEQUENCESTEP_TCC "TCC" + #define VL53L0X_STRING_SEQUENCESTEP_DSS "DSS" + #define VL53L0X_STRING_SEQUENCESTEP_MSRC "MSRC" + #define VL53L0X_STRING_SEQUENCESTEP_PRE_RANGE "PRE RANGE" + #define VL53L0X_STRING_SEQUENCESTEP_FINAL_RANGE "FINAL RANGE" +#endif /* USE_EMPTY_STRING */ + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/modules/VL53L0X/inc/vl53l0x_cali.h b/modules/VL53L0X/inc/vl53l0x_cali.h new file mode 100644 index 0000000000000000000000000000000000000000..d4b330980b482d21f97e84d7276e5b1361281ba7 --- /dev/null +++ b/modules/VL53L0X/inc/vl53l0x_cali.h @@ -0,0 +1,26 @@ +#ifndef __VL53L0X_CAIL_H +#define __VL53L0X_CAIL_H + +#include "bsp_vl53l0x.h" + + +//vl53l0xУ׼Ϣṹ嶨 +typedef struct packed_1 +{ + uint8_t adjustok; //У׼ɹ־0XAAУ׼;δУ׼ + uint8_t isApertureSpads; //ApertureSpadsֵ + uint8_t VhvSettings; //VhvSettingsֵ + uint8_t PhaseCal; //PhaseCalֵ + uint32_t XTalkCalDistance; //XTalkCalDistanceֵ + uint32_t XTalkCompensationRateMegaCps;//XTalkCompensationRateMegaCpsֵ + uint32_t CalDistanceMilliMeter; //CalDistanceMilliMeterֵ + int32_t OffsetMicroMeter; //OffsetMicroMeterֵ + uint32_t refSpadCount; //refSpadCountֵ + +}_vl53l0x_adjust; + +extern _vl53l0x_adjust Vl53l0x_data; + +void vl53l0x_calibration_test(VL53L0X_Dev_t *dev); + +#endif diff --git a/modules/VL53L0X/inc/vl53l0x_def.h b/modules/VL53L0X/inc/vl53l0x_def.h new file mode 100644 index 0000000000000000000000000000000000000000..6c9af359ccaecde407ca4fb65cf6563529f52fb1 --- /dev/null +++ b/modules/VL53L0X/inc/vl53l0x_def.h @@ -0,0 +1,640 @@ +/******************************************************************************* +Copyright 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 VL53L0X_def.h + * + * @brief Type definitions for VL53L0X API. + * + */ + + +#ifndef _VL53L0X_DEF_H_ +#define _VL53L0X_DEF_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup VL53L0X_globaldefine_group VL53L0X Defines + * @brief VL53L0X Defines + * @{ + */ + + +/** PAL SPECIFICATION major version */ +#define VL53L0X10_SPECIFICATION_VER_MAJOR 1 +/** PAL SPECIFICATION minor version */ +#define VL53L0X10_SPECIFICATION_VER_MINOR 2 +/** PAL SPECIFICATION sub version */ +#define VL53L0X10_SPECIFICATION_VER_SUB 7 +/** PAL SPECIFICATION sub version */ +#define VL53L0X10_SPECIFICATION_VER_REVISION 1440 + +/** VL53L0X PAL IMPLEMENTATION major version */ +#define VL53L0X10_IMPLEMENTATION_VER_MAJOR 1 +/** VL53L0X PAL IMPLEMENTATION minor version */ +#define VL53L0X10_IMPLEMENTATION_VER_MINOR 0 +/** VL53L0X PAL IMPLEMENTATION sub version */ +#define VL53L0X10_IMPLEMENTATION_VER_SUB 9 +/** VL53L0X PAL IMPLEMENTATION sub version */ +#define VL53L0X10_IMPLEMENTATION_VER_REVISION 3673 + +/** PAL SPECIFICATION major version */ +#define VL53L0X_SPECIFICATION_VER_MAJOR 1 +/** PAL SPECIFICATION minor version */ +#define VL53L0X_SPECIFICATION_VER_MINOR 2 +/** PAL SPECIFICATION sub version */ +#define VL53L0X_SPECIFICATION_VER_SUB 7 +/** PAL SPECIFICATION sub version */ +#define VL53L0X_SPECIFICATION_VER_REVISION 1440 + +/** VL53L0X PAL IMPLEMENTATION major version */ +#define VL53L0X_IMPLEMENTATION_VER_MAJOR 1 +/** VL53L0X PAL IMPLEMENTATION minor version */ +#define VL53L0X_IMPLEMENTATION_VER_MINOR 0 +/** VL53L0X PAL IMPLEMENTATION sub version */ +#define VL53L0X_IMPLEMENTATION_VER_SUB 2 +/** VL53L0X PAL IMPLEMENTATION sub version */ +#define VL53L0X_IMPLEMENTATION_VER_REVISION 4823 +#define VL53L0X_DEFAULT_MAX_LOOP 2000 +#define VL53L0X_MAX_STRING_LENGTH 32 + + +#include "vl53l0x_device.h" +#include "vl53l0x_types.h" + + +/**************************************** + * PRIVATE define do not edit + ****************************************/ + +/** @brief Defines the parameters of the Get Version Functions + */ +typedef struct { + uint32_t revision; /*!< revision number */ + uint8_t major; /*!< major number */ + uint8_t minor; /*!< minor number */ + uint8_t build; /*!< build number */ +} VL53L0X_Version_t; + + +/** @brief Defines the parameters of the Get Device Info Functions + */ +typedef struct { + char Name[VL53L0X_MAX_STRING_LENGTH]; + /*!< Name of the Device e.g. Left_Distance */ + char Type[VL53L0X_MAX_STRING_LENGTH]; + /*!< Type of the Device e.g VL53L0X */ + char ProductId[VL53L0X_MAX_STRING_LENGTH]; + /*!< Product Identifier String */ + uint8_t ProductType; + /*!< Product Type, VL53L0X = 1, VL53L1 = 2 */ + uint8_t ProductRevisionMajor; + /*!< Product revision major */ + uint8_t ProductRevisionMinor; + /*!< Product revision minor */ +} VL53L0X_DeviceInfo_t; + + +/** @defgroup VL53L0X_define_Error_group Error and Warning code returned by API + * The following DEFINE are used to identify the PAL ERROR + * @{ + */ + +typedef int8_t VL53L0X_Error; + +#define VL53L0X_ERROR_NONE ((VL53L0X_Error) 0) +#define VL53L0X_ERROR_CALIBRATION_WARNING ((VL53L0X_Error) -1) + /*!< Warning invalid calibration data may be in used + \a VL53L0X_InitData() + \a VL53L0X_GetOffsetCalibrationData + \a VL53L0X_SetOffsetCalibrationData */ +#define VL53L0X_ERROR_MIN_CLIPPED ((VL53L0X_Error) -2) + /*!< Warning parameter passed was clipped to min before to be applied */ + +#define VL53L0X_ERROR_UNDEFINED ((VL53L0X_Error) -3) + /*!< Unqualified error */ +#define VL53L0X_ERROR_INVALID_PARAMS ((VL53L0X_Error) -4) + /*!< Parameter passed is invalid or out of range */ +#define VL53L0X_ERROR_NOT_SUPPORTED ((VL53L0X_Error) -5) + /*!< Function is not supported in current mode or configuration */ +#define VL53L0X_ERROR_RANGE_ERROR ((VL53L0X_Error) -6) + /*!< Device report a ranging error interrupt status */ +#define VL53L0X_ERROR_TIME_OUT ((VL53L0X_Error) -7) + /*!< Aborted due to time out */ +#define VL53L0X_ERROR_MODE_NOT_SUPPORTED ((VL53L0X_Error) -8) + /*!< Asked mode is not supported by the device */ +#define VL53L0X_ERROR_BUFFER_TOO_SMALL ((VL53L0X_Error) -9) + /*!< ... */ +#define VL53L0X_ERROR_GPIO_NOT_EXISTING ((VL53L0X_Error) -10) + /*!< User tried to setup a non-existing GPIO pin */ +#define VL53L0X_ERROR_GPIO_FUNCTIONALITY_NOT_SUPPORTED ((VL53L0X_Error) -11) + /*!< unsupported GPIO functionality */ +#define VL53L0X_ERROR_INTERRUPT_NOT_CLEARED ((VL53L0X_Error) -12) + /*!< Error during interrupt clear */ +#define VL53L0X_ERROR_CONTROL_INTERFACE ((VL53L0X_Error) -20) + /*!< error reported from IO functions */ +#define VL53L0X_ERROR_INVALID_COMMAND ((VL53L0X_Error) -30) + /*!< The command is not allowed in the current device state + * (power down) */ +#define VL53L0X_ERROR_DIVISION_BY_ZERO ((VL53L0X_Error) -40) + /*!< In the function a division by zero occurs */ +#define VL53L0X_ERROR_REF_SPAD_INIT ((VL53L0X_Error) -50) + /*!< Error during reference SPAD initialization */ +#define VL53L0X_ERROR_NOT_IMPLEMENTED ((VL53L0X_Error) -99) + /*!< Tells requested functionality has not been implemented yet or + * not compatible with the device */ +/** @} VL53L0X_define_Error_group */ + + +/** @defgroup VL53L0X_define_DeviceModes_group Defines Device modes + * Defines all possible modes for the device + * @{ + */ +typedef uint8_t VL53L0X_DeviceModes; + +#define VL53L0X_DEVICEMODE_SINGLE_RANGING ((VL53L0X_DeviceModes) 0) +#define VL53L0X_DEVICEMODE_CONTINUOUS_RANGING ((VL53L0X_DeviceModes) 1) +#define VL53L0X_DEVICEMODE_SINGLE_HISTOGRAM ((VL53L0X_DeviceModes) 2) +#define VL53L0X_DEVICEMODE_CONTINUOUS_TIMED_RANGING ((VL53L0X_DeviceModes) 3) +#define VL53L0X_DEVICEMODE_SINGLE_ALS ((VL53L0X_DeviceModes) 10) +#define VL53L0X_DEVICEMODE_GPIO_DRIVE ((VL53L0X_DeviceModes) 20) +#define VL53L0X_DEVICEMODE_GPIO_OSC ((VL53L0X_DeviceModes) 21) + /* ... Modes to be added depending on device */ +/** @} VL53L0X_define_DeviceModes_group */ + + + +/** @defgroup VL53L0X_define_HistogramModes_group Defines Histogram modes + * Defines all possible Histogram modes for the device + * @{ + */ +typedef uint8_t VL53L0X_HistogramModes; + +#define VL53L0X_HISTOGRAMMODE_DISABLED ((VL53L0X_HistogramModes) 0) + /*!< Histogram Disabled */ +#define VL53L0X_HISTOGRAMMODE_REFERENCE_ONLY ((VL53L0X_HistogramModes) 1) + /*!< Histogram Reference array only */ +#define VL53L0X_HISTOGRAMMODE_RETURN_ONLY ((VL53L0X_HistogramModes) 2) + /*!< Histogram Return array only */ +#define VL53L0X_HISTOGRAMMODE_BOTH ((VL53L0X_HistogramModes) 3) + /*!< Histogram both Reference and Return Arrays */ + /* ... Modes to be added depending on device */ +/** @} VL53L0X_define_HistogramModes_group */ + + +/** @defgroup VL53L0X_define_PowerModes_group List of available Power Modes + * List of available Power Modes + * @{ + */ + +typedef uint8_t VL53L0X_PowerModes; + +#define VL53L0X_POWERMODE_STANDBY_LEVEL1 ((VL53L0X_PowerModes) 0) + /*!< Standby level 1 */ +#define VL53L0X_POWERMODE_STANDBY_LEVEL2 ((VL53L0X_PowerModes) 1) + /*!< Standby level 2 */ +#define VL53L0X_POWERMODE_IDLE_LEVEL1 ((VL53L0X_PowerModes) 2) + /*!< Idle level 1 */ +#define VL53L0X_POWERMODE_IDLE_LEVEL2 ((VL53L0X_PowerModes) 3) + /*!< Idle level 2 */ + +/** @} VL53L0X_define_PowerModes_group */ + + +/** @brief Defines all parameters for the device + */ +typedef struct { + VL53L0X_DeviceModes DeviceMode; + /*!< Defines type of measurement to be done for the next measure */ + VL53L0X_HistogramModes HistogramMode; + /*!< Defines type of histogram measurement to be done for the next + * measure */ + uint32_t MeasurementTimingBudgetMicroSeconds; + /*!< Defines the allowed total time for a single measurement */ + uint32_t InterMeasurementPeriodMilliSeconds; + /*!< Defines time between two consecutive measurements (between two + * measurement starts). If set to 0 means back-to-back mode */ + uint8_t XTalkCompensationEnable; + /*!< Tells if Crosstalk compensation shall be enable or not */ + uint16_t XTalkCompensationRangeMilliMeter; + /*!< CrossTalk compensation range in millimeter */ + FixPoint1616_t XTalkCompensationRateMegaCps; + /*!< CrossTalk compensation rate in Mega counts per seconds. + * Expressed in 16.16 fixed point format. */ + int32_t RangeOffsetMicroMeters; + /*!< Range offset adjustment (mm). */ + + uint8_t LimitChecksEnable[VL53L0X_CHECKENABLE_NUMBER_OF_CHECKS]; + /*!< This Array store all the Limit Check enable for this device. */ + uint8_t LimitChecksStatus[VL53L0X_CHECKENABLE_NUMBER_OF_CHECKS]; + /*!< This Array store all the Status of the check linked to last + * measurement. */ + FixPoint1616_t LimitChecksValue[VL53L0X_CHECKENABLE_NUMBER_OF_CHECKS]; + /*!< This Array store all the Limit Check value for this device */ + + uint8_t WrapAroundCheckEnable; + /*!< Tells if Wrap Around Check shall be enable or not */ +} VL53L0X_DeviceParameters_t; + + +/** @defgroup VL53L0X_define_State_group Defines the current status of the device + * Defines the current status of the device + * @{ + */ + +typedef uint8_t VL53L0X_State; + +#define VL53L0X_STATE_POWERDOWN ((VL53L0X_State) 0) + /*!< Device is in HW reset */ +#define VL53L0X_STATE_WAIT_STATICINIT ((VL53L0X_State) 1) + /*!< Device is initialized and wait for static initialization */ +#define VL53L0X_STATE_STANDBY ((VL53L0X_State) 2) + /*!< Device is in Low power Standby mode */ +#define VL53L0X_STATE_IDLE ((VL53L0X_State) 3) + /*!< Device has been initialized and ready to do measurements */ +#define VL53L0X_STATE_RUNNING ((VL53L0X_State) 4) + /*!< Device is performing measurement */ +#define VL53L0X_STATE_UNKNOWN ((VL53L0X_State) 98) + /*!< Device is in unknown state and need to be rebooted */ +#define VL53L0X_STATE_ERROR ((VL53L0X_State) 99) + /*!< Device is in error state and need to be rebooted */ + +/** @} VL53L0X_define_State_group */ + + +/** @brief Structure containing the Dmax computation parameters and data + */ +typedef struct { + int32_t AmbTuningWindowFactor_K; + /*!< internal algo tuning (*1000) */ + int32_t RetSignalAt0mm; + /*!< intermediate dmax computation value caching */ +} VL53L0X_DMaxData_t; + +/** + * @struct VL53L0X_RangeData_t + * @brief Range measurement data. + */ +typedef struct { + uint32_t TimeStamp; /*!< 32-bit time stamp. */ + uint32_t MeasurementTimeUsec; + /*!< Give the Measurement time needed by the device to do the + * measurement.*/ + + + uint16_t RangeMilliMeter; /*!< range distance in millimeter. */ + + uint16_t RangeDMaxMilliMeter; + /*!< Tells what is the maximum detection distance of the device + * in current setup and environment conditions (Filled when + * applicable) */ + + FixPoint1616_t SignalRateRtnMegaCps; + /*!< Return signal rate (MCPS)\n these is a 16.16 fix point + * value, which is effectively a measure of target + * reflectance.*/ + FixPoint1616_t AmbientRateRtnMegaCps; + /*!< Return ambient rate (MCPS)\n these is a 16.16 fix point + * value, which is effectively a measure of the ambien + * t light.*/ + + uint16_t EffectiveSpadRtnCount; + /*!< Return the effective SPAD count for the return signal. + * To obtain Real value it should be divided by 256 */ + + uint8_t ZoneId; + /*!< Denotes which zone and range scheduler stage the range + * data relates to. */ + uint8_t RangeFractionalPart; + /*!< Fractional part of range distance. Final value is a + * FixPoint168 value. */ + uint8_t RangeStatus; + /*!< Range Status for the current measurement. This is device + * dependent. Value = 0 means value is valid. + * See \ref RangeStatusPage */ +} VL53L0X_RangingMeasurementData_t; + + +#define VL53L0X_HISTOGRAM_BUFFER_SIZE 24 + +/** + * @struct VL53L0X_HistogramData_t + * @brief Histogram measurement data. + */ +typedef struct { + /* Histogram Measurement data */ + uint32_t HistogramData[VL53L0X_HISTOGRAM_BUFFER_SIZE]; + /*!< Histogram data */ + uint8_t HistogramType; /*!< Indicate the types of histogram data : + Return only, Reference only, both Return and Reference */ + uint8_t FirstBin; /*!< First Bin value */ + uint8_t BufferSize; /*!< Buffer Size - Set by the user.*/ + uint8_t NumberOfBins; + /*!< Number of bins filled by the histogram measurement */ + + VL53L0X_DeviceError ErrorStatus; + /*!< Error status of the current measurement. \n + see @a ::VL53L0X_DeviceError @a VL53L0X_GetStatusErrorString() */ +} VL53L0X_HistogramMeasurementData_t; + +#define VL53L0X_REF_SPAD_BUFFER_SIZE 6 + +/** + * @struct VL53L0X_SpadData_t + * @brief Spad Configuration Data. + */ +typedef struct { + uint8_t RefSpadEnables[VL53L0X_REF_SPAD_BUFFER_SIZE]; + /*!< Reference Spad Enables */ + uint8_t RefGoodSpadMap[VL53L0X_REF_SPAD_BUFFER_SIZE]; + /*!< Reference Spad Good Spad Map */ +} VL53L0X_SpadData_t; + +typedef struct { + FixPoint1616_t OscFrequencyMHz; /* Frequency used */ + + uint16_t LastEncodedTimeout; + /* last encoded Time out used for timing budget*/ + + VL53L0X_GpioFunctionality Pin0GpioFunctionality; + /* store the functionality of the GPIO: pin0 */ + + uint32_t FinalRangeTimeoutMicroSecs; + /*!< Execution time of the final range*/ + uint8_t FinalRangeVcselPulsePeriod; + /*!< Vcsel pulse period (pll clocks) for the final range measurement*/ + uint32_t PreRangeTimeoutMicroSecs; + /*!< Execution time of the final range*/ + uint8_t PreRangeVcselPulsePeriod; + /*!< Vcsel pulse period (pll clocks) for the pre-range measurement*/ + + uint16_t SigmaEstRefArray; + /*!< Reference array sigma value in 1/100th of [mm] e.g. 100 = 1mm */ + uint16_t SigmaEstEffPulseWidth; + /*!< Effective Pulse width for sigma estimate in 1/100th + * of ns e.g. 900 = 9.0ns */ + uint16_t SigmaEstEffAmbWidth; + /*!< Effective Ambient width for sigma estimate in 1/100th of ns + * e.g. 500 = 5.0ns */ + + + uint8_t ReadDataFromDeviceDone; /* Indicate if read from device has + been done (==1) or not (==0) */ + uint8_t ModuleId; /* Module ID */ + uint8_t Revision; /* test Revision */ + char ProductId[VL53L0X_MAX_STRING_LENGTH]; + /* Product Identifier String */ + uint8_t ReferenceSpadCount; /* used for ref spad management */ + uint8_t ReferenceSpadType; /* used for ref spad management */ + uint8_t RefSpadsInitialised; /* reports if ref spads are initialised. */ + uint32_t PartUIDUpper; /*!< Unique Part ID Upper */ + uint32_t PartUIDLower; /*!< Unique Part ID Lower */ + FixPoint1616_t SignalRateMeasFixed400mm; /*!< Peek Signal rate + at 400 mm*/ + +} VL53L0X_DeviceSpecificParameters_t; + +/** + * @struct VL53L0X_DevData_t + * + * @brief VL53L0X PAL device ST private data structure \n + * End user should never access any of these field directly + * + * These must never access directly but only via macro + */ +typedef struct { + VL53L0X_DMaxData_t DMaxData; + /*!< Dmax Data */ + int32_t Part2PartOffsetNVMMicroMeter; + /*!< backed up NVM value */ + int32_t Part2PartOffsetAdjustmentNVMMicroMeter; + /*!< backed up NVM value representing additional offset adjustment */ + VL53L0X_DeviceParameters_t CurrentParameters; + /*!< Current Device Parameter */ + VL53L0X_RangingMeasurementData_t LastRangeMeasure; + /*!< Ranging Data */ + VL53L0X_HistogramMeasurementData_t LastHistogramMeasure; + /*!< Histogram Data */ + VL53L0X_DeviceSpecificParameters_t DeviceSpecificParameters; + /*!< Parameters specific to the device */ + VL53L0X_SpadData_t SpadData; + /*!< Spad Data */ + uint8_t SequenceConfig; + /*!< Internal value for the sequence config */ + uint8_t RangeFractionalEnable; + /*!< Enable/Disable fractional part of ranging data */ + VL53L0X_State PalState; + /*!< Current state of the PAL for this device */ + VL53L0X_PowerModes PowerMode; + /*!< Current Power Mode */ + uint16_t SigmaEstRefArray; + /*!< Reference array sigma value in 1/100th of [mm] e.g. 100 = 1mm */ + uint16_t SigmaEstEffPulseWidth; + /*!< Effective Pulse width for sigma estimate in 1/100th + * of ns e.g. 900 = 9.0ns */ + uint16_t SigmaEstEffAmbWidth; + /*!< Effective Ambient width for sigma estimate in 1/100th of ns + * e.g. 500 = 5.0ns */ + uint8_t StopVariable; + /*!< StopVariable used during the stop sequence */ + uint16_t targetRefRate; + /*!< Target Ambient Rate for Ref spad management */ + FixPoint1616_t SigmaEstimate; + /*!< Sigma Estimate - based on ambient & VCSEL rates and + * signal_total_events */ + FixPoint1616_t SignalEstimate; + /*!< Signal Estimate - based on ambient & VCSEL rates and cross talk */ + FixPoint1616_t LastSignalRefMcps; + /*!< Latest Signal ref in Mcps */ + uint8_t *pTuningSettingsPointer; + /*!< Pointer for Tuning Settings table */ + uint8_t UseInternalTuningSettings; + /*!< Indicate if we use Tuning Settings table */ + uint16_t LinearityCorrectiveGain; + /*!< Linearity Corrective Gain value in x1000 */ + uint16_t DmaxCalRangeMilliMeter; + /*!< Dmax Calibration Range millimeter */ + FixPoint1616_t DmaxCalSignalRateRtnMegaCps; + /*!< Dmax Calibration Signal Rate Return MegaCps */ + +} VL53L0X_DevData_t; + + +/** @defgroup VL53L0X_define_InterruptPolarity_group Defines the Polarity + * of the Interrupt + * Defines the Polarity of the Interrupt + * @{ + */ +typedef uint8_t VL53L0X_InterruptPolarity; + +#define VL53L0X_INTERRUPTPOLARITY_LOW ((VL53L0X_InterruptPolarity) 0) +/*!< Set active low polarity best setup for falling edge. */ +#define VL53L0X_INTERRUPTPOLARITY_HIGH ((VL53L0X_InterruptPolarity) 1) +/*!< Set active high polarity best setup for rising edge. */ + +/** @} VL53L0X_define_InterruptPolarity_group */ + + +/** @defgroup VL53L0X_define_VcselPeriod_group Vcsel Period Defines + * Defines the range measurement for which to access the vcsel period. + * @{ + */ +typedef uint8_t VL53L0X_VcselPeriod; + +#define VL53L0X_VCSEL_PERIOD_PRE_RANGE ((VL53L0X_VcselPeriod) 0) +/*!>9)&0xFFFF) +#define VL53L0X_FIXPOINT97TOFIXPOINT1616(Value) \ + (FixPoint1616_t)(Value<<9) + +#define VL53L0X_FIXPOINT1616TOFIXPOINT88(Value) \ + (uint16_t)((Value>>8)&0xFFFF) +#define VL53L0X_FIXPOINT88TOFIXPOINT1616(Value) \ + (FixPoint1616_t)(Value<<8) + +#define VL53L0X_FIXPOINT1616TOFIXPOINT412(Value) \ + (uint16_t)((Value>>4)&0xFFFF) +#define VL53L0X_FIXPOINT412TOFIXPOINT1616(Value) \ + (FixPoint1616_t)(Value<<4) + +#define VL53L0X_FIXPOINT1616TOFIXPOINT313(Value) \ + (uint16_t)((Value>>3)&0xFFFF) +#define VL53L0X_FIXPOINT313TOFIXPOINT1616(Value) \ + (FixPoint1616_t)(Value<<3) + +#define VL53L0X_FIXPOINT1616TOFIXPOINT08(Value) \ + (uint8_t)((Value>>8)&0x00FF) +#define VL53L0X_FIXPOINT08TOFIXPOINT1616(Value) \ + (FixPoint1616_t)(Value<<8) + +#define VL53L0X_FIXPOINT1616TOFIXPOINT53(Value) \ + (uint8_t)((Value>>13)&0x00FF) +#define VL53L0X_FIXPOINT53TOFIXPOINT1616(Value) \ + (FixPoint1616_t)(Value<<13) + +#define VL53L0X_FIXPOINT1616TOFIXPOINT102(Value) \ + (uint16_t)((Value>>14)&0x0FFF) +#define VL53L0X_FIXPOINT102TOFIXPOINT1616(Value) \ + (FixPoint1616_t)(Value<<12) + +#define VL53L0X_MAKEUINT16(lsb, msb) (uint16_t)((((uint16_t)msb)<<8) + \ + (uint16_t)lsb) + +/** @} VL53L0X_define_GeneralMacro_group */ + +/** @} VL53L0X_globaldefine_group */ + + + + + + + +#ifdef __cplusplus +} +#endif + + +#endif /* _VL53L0X_DEF_H_ */ diff --git a/modules/VL53L0X/inc/vl53l0x_device.h b/modules/VL53L0X/inc/vl53l0x_device.h new file mode 100644 index 0000000000000000000000000000000000000000..dc010c295e47d4e813918abd0ca59210707a659d --- /dev/null +++ b/modules/VL53L0X/inc/vl53l0x_device.h @@ -0,0 +1,257 @@ +/******************************************************************************* +Copyright 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. +*******************************************************************************/ + +/** + * Device specific defines. To be adapted by implementer for the targeted + * device. + */ + +#ifndef _VL53L0X_DEVICE_H_ +#define _VL53L0X_DEVICE_H_ + +#include "vl53l0x_types.h" + + +/** @defgroup VL53L0X_DevSpecDefines_group VL53L0X cut1.1 Device Specific Defines + * @brief VL53L0X cut1.1 Device Specific Defines + * @{ + */ + + +/** @defgroup VL53L0X_DeviceError_group Device Error + * @brief Device Error code + * + * This enum is Device specific it should be updated in the implementation + * Use @a VL53L0X_GetStatusErrorString() to get the string. + * It is related to Status Register of the Device. + * @{ + */ +typedef uint8_t VL53L0X_DeviceError; + +#define VL53L0X_DEVICEERROR_NONE ((VL53L0X_DeviceError) 0) + /*!< 0 NoError */ +#define VL53L0X_DEVICEERROR_VCSELCONTINUITYTESTFAILURE ((VL53L0X_DeviceError) 1) +#define VL53L0X_DEVICEERROR_VCSELWATCHDOGTESTFAILURE ((VL53L0X_DeviceError) 2) +#define VL53L0X_DEVICEERROR_NOVHVVALUEFOUND ((VL53L0X_DeviceError) 3) +#define VL53L0X_DEVICEERROR_MSRCNOTARGET ((VL53L0X_DeviceError) 4) +#define VL53L0X_DEVICEERROR_SNRCHECK ((VL53L0X_DeviceError) 5) +#define VL53L0X_DEVICEERROR_RANGEPHASECHECK ((VL53L0X_DeviceError) 6) +#define VL53L0X_DEVICEERROR_SIGMATHRESHOLDCHECK ((VL53L0X_DeviceError) 7) +#define VL53L0X_DEVICEERROR_TCC ((VL53L0X_DeviceError) 8) +#define VL53L0X_DEVICEERROR_PHASECONSISTENCY ((VL53L0X_DeviceError) 9) +#define VL53L0X_DEVICEERROR_MINCLIP ((VL53L0X_DeviceError) 10) +#define VL53L0X_DEVICEERROR_RANGECOMPLETE ((VL53L0X_DeviceError) 11) +#define VL53L0X_DEVICEERROR_ALGOUNDERFLOW ((VL53L0X_DeviceError) 12) +#define VL53L0X_DEVICEERROR_ALGOOVERFLOW ((VL53L0X_DeviceError) 13) +#define VL53L0X_DEVICEERROR_RANGEIGNORETHRESHOLD ((VL53L0X_DeviceError) 14) + +/** @} end of VL53L0X_DeviceError_group */ + + +/** @defgroup VL53L0X_CheckEnable_group Check Enable list + * @brief Check Enable code + * + * Define used to specify the LimitCheckId. + * Use @a VL53L0X_GetLimitCheckInfo() to get the string. + * @{ + */ + +#define VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE 0 +#define VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE 1 +#define VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP 2 +#define VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD 3 +#define VL53L0X_CHECKENABLE_SIGNAL_RATE_MSRC 4 +#define VL53L0X_CHECKENABLE_SIGNAL_RATE_PRE_RANGE 5 + +#define VL53L0X_CHECKENABLE_NUMBER_OF_CHECKS 6 + +/** @} end of VL53L0X_CheckEnable_group */ + + +/** @defgroup VL53L0X_GpioFunctionality_group Gpio Functionality + * @brief Defines the different functionalities for the device GPIO(s) + * @{ + */ +typedef uint8_t VL53L0X_GpioFunctionality; + +#define VL53L0X_GPIOFUNCTIONALITY_OFF \ + ((VL53L0X_GpioFunctionality) 0) /*!< NO Interrupt */ +#define VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_LOW \ + ((VL53L0X_GpioFunctionality) 1) /*!< Level Low (value < thresh_low) */ +#define VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_HIGH \ + ((VL53L0X_GpioFunctionality) 2) /*!< Level High (value > thresh_high) */ +#define VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_OUT \ + ((VL53L0X_GpioFunctionality) 3) + /*!< Out Of Window (value < thresh_low OR value > thresh_high) */ +#define VL53L0X_GPIOFUNCTIONALITY_NEW_MEASURE_READY \ + ((VL53L0X_GpioFunctionality) 4) /*!< New Sample Ready */ + +/** @} end of VL53L0X_GpioFunctionality_group */ + + +/* Device register map */ + +/** @defgroup VL53L0X_DefineRegisters_group Define Registers + * @brief List of all the defined registers + * @{ + */ +#define VL53L0X_REG_SYSRANGE_START 0x000 + /** mask existing bit in #VL53L0X_REG_SYSRANGE_START*/ + #define VL53L0X_REG_SYSRANGE_MODE_MASK 0x0F + /** bit 0 in #VL53L0X_REG_SYSRANGE_START write 1 toggle state in + * continuous mode and arm next shot in single shot mode */ + #define VL53L0X_REG_SYSRANGE_MODE_START_STOP 0x01 + /** bit 1 write 0 in #VL53L0X_REG_SYSRANGE_START set single shot mode */ + #define VL53L0X_REG_SYSRANGE_MODE_SINGLESHOT 0x00 + /** bit 1 write 1 in #VL53L0X_REG_SYSRANGE_START set back-to-back + * operation mode */ + #define VL53L0X_REG_SYSRANGE_MODE_BACKTOBACK 0x02 + /** bit 2 write 1 in #VL53L0X_REG_SYSRANGE_START set timed operation + * mode */ + #define VL53L0X_REG_SYSRANGE_MODE_TIMED 0x04 + /** bit 3 write 1 in #VL53L0X_REG_SYSRANGE_START set histogram operation + * mode */ + #define VL53L0X_REG_SYSRANGE_MODE_HISTOGRAM 0x08 + + +#define VL53L0X_REG_SYSTEM_THRESH_HIGH 0x000C +#define VL53L0X_REG_SYSTEM_THRESH_LOW 0x000E + + +#define VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG 0x0001 +#define VL53L0X_REG_SYSTEM_RANGE_CONFIG 0x0009 +#define VL53L0X_REG_SYSTEM_INTERMEASUREMENT_PERIOD 0x0004 + + +#define VL53L0X_REG_SYSTEM_INTERRUPT_CONFIG_GPIO 0x000A + #define VL53L0X_REG_SYSTEM_INTERRUPT_GPIO_DISABLED 0x00 + #define VL53L0X_REG_SYSTEM_INTERRUPT_GPIO_LEVEL_LOW 0x01 + #define VL53L0X_REG_SYSTEM_INTERRUPT_GPIO_LEVEL_HIGH 0x02 + #define VL53L0X_REG_SYSTEM_INTERRUPT_GPIO_OUT_OF_WINDOW 0x03 + #define VL53L0X_REG_SYSTEM_INTERRUPT_GPIO_NEW_SAMPLE_READY 0x04 + +#define VL53L0X_REG_GPIO_HV_MUX_ACTIVE_HIGH 0x0084 + + +#define VL53L0X_REG_SYSTEM_INTERRUPT_CLEAR 0x000B + +/* Result registers */ +#define VL53L0X_REG_RESULT_INTERRUPT_STATUS 0x0013 +#define VL53L0X_REG_RESULT_RANGE_STATUS 0x0014 + +#define VL53L0X_REG_RESULT_CORE_PAGE 1 +#define VL53L0X_REG_RESULT_CORE_AMBIENT_WINDOW_EVENTS_RTN 0x00BC +#define VL53L0X_REG_RESULT_CORE_RANGING_TOTAL_EVENTS_RTN 0x00C0 +#define VL53L0X_REG_RESULT_CORE_AMBIENT_WINDOW_EVENTS_REF 0x00D0 +#define VL53L0X_REG_RESULT_CORE_RANGING_TOTAL_EVENTS_REF 0x00D4 +#define VL53L0X_REG_RESULT_PEAK_SIGNAL_RATE_REF 0x00B6 + +/* Algo register */ + +#define VL53L0X_REG_ALGO_PART_TO_PART_RANGE_OFFSET_MM 0x0028 + +#define VL53L0X_REG_I2C_SLAVE_DEVICE_ADDRESS 0x008a + +/* Check Limit registers */ +#define VL53L0X_REG_MSRC_CONFIG_CONTROL 0x0060 + +#define VL53L0X_REG_PRE_RANGE_CONFIG_MIN_SNR 0X0027 +#define VL53L0X_REG_PRE_RANGE_CONFIG_VALID_PHASE_LOW 0x0056 +#define VL53L0X_REG_PRE_RANGE_CONFIG_VALID_PHASE_HIGH 0x0057 +#define VL53L0X_REG_PRE_RANGE_MIN_COUNT_RATE_RTN_LIMIT 0x0064 + +#define VL53L0X_REG_FINAL_RANGE_CONFIG_MIN_SNR 0X0067 +#define VL53L0X_REG_FINAL_RANGE_CONFIG_VALID_PHASE_LOW 0x0047 +#define VL53L0X_REG_FINAL_RANGE_CONFIG_VALID_PHASE_HIGH 0x0048 +#define VL53L0X_REG_FINAL_RANGE_CONFIG_MIN_COUNT_RATE_RTN_LIMIT 0x0044 + + +#define VL53L0X_REG_PRE_RANGE_CONFIG_SIGMA_THRESH_HI 0X0061 +#define VL53L0X_REG_PRE_RANGE_CONFIG_SIGMA_THRESH_LO 0X0062 + +/* PRE RANGE registers */ +#define VL53L0X_REG_PRE_RANGE_CONFIG_VCSEL_PERIOD 0x0050 +#define VL53L0X_REG_PRE_RANGE_CONFIG_TIMEOUT_MACROP_HI 0x0051 +#define VL53L0X_REG_PRE_RANGE_CONFIG_TIMEOUT_MACROP_LO 0x0052 + +#define VL53L0X_REG_SYSTEM_HISTOGRAM_BIN 0x0081 +#define VL53L0X_REG_HISTOGRAM_CONFIG_INITIAL_PHASE_SELECT 0x0033 +#define VL53L0X_REG_HISTOGRAM_CONFIG_READOUT_CTRL 0x0055 + +#define VL53L0X_REG_FINAL_RANGE_CONFIG_VCSEL_PERIOD 0x0070 +#define VL53L0X_REG_FINAL_RANGE_CONFIG_TIMEOUT_MACROP_HI 0x0071 +#define VL53L0X_REG_FINAL_RANGE_CONFIG_TIMEOUT_MACROP_LO 0x0072 +#define VL53L0X_REG_CROSSTALK_COMPENSATION_PEAK_RATE_MCPS 0x0020 + +#define VL53L0X_REG_MSRC_CONFIG_TIMEOUT_MACROP 0x0046 + + +#define VL53L0X_REG_SOFT_RESET_GO2_SOFT_RESET_N 0x00bf +#define VL53L0X_REG_IDENTIFICATION_MODEL_ID 0x00c0 +#define VL53L0X_REG_IDENTIFICATION_REVISION_ID 0x00c2 + +#define VL53L0X_REG_OSC_CALIBRATE_VAL 0x00f8 + + +#define VL53L0X_SIGMA_ESTIMATE_MAX_VALUE 65535 +/* equivalent to a range sigma of 655.35mm */ + +#define VL53L0X_REG_GLOBAL_CONFIG_VCSEL_WIDTH 0x032 +#define VL53L0X_REG_GLOBAL_CONFIG_SPAD_ENABLES_REF_0 0x0B0 +#define VL53L0X_REG_GLOBAL_CONFIG_SPAD_ENABLES_REF_1 0x0B1 +#define VL53L0X_REG_GLOBAL_CONFIG_SPAD_ENABLES_REF_2 0x0B2 +#define VL53L0X_REG_GLOBAL_CONFIG_SPAD_ENABLES_REF_3 0x0B3 +#define VL53L0X_REG_GLOBAL_CONFIG_SPAD_ENABLES_REF_4 0x0B4 +#define VL53L0X_REG_GLOBAL_CONFIG_SPAD_ENABLES_REF_5 0x0B5 + +#define VL53L0X_REG_GLOBAL_CONFIG_REF_EN_START_SELECT 0xB6 +#define VL53L0X_REG_DYNAMIC_SPAD_NUM_REQUESTED_REF_SPAD 0x4E /* 0x14E */ +#define VL53L0X_REG_DYNAMIC_SPAD_REF_EN_START_OFFSET 0x4F /* 0x14F */ +#define VL53L0X_REG_POWER_MANAGEMENT_GO1_POWER_FORCE 0x80 + +/* + * Speed of light in um per 1E-10 Seconds + */ + +#define VL53L0X_SPEED_OF_LIGHT_IN_AIR 2997 + +#define VL53L0X_REG_VHV_CONFIG_PAD_SCL_SDA__EXTSUP_HV 0x0089 + +#define VL53L0X_REG_ALGO_PHASECAL_LIM 0x0030 /* 0x130 */ +#define VL53L0X_REG_ALGO_PHASECAL_CONFIG_TIMEOUT 0x0030 + +/** @} VL53L0X_DefineRegisters_group */ + +/** @} VL53L0X_DevSpecDefines_group */ + + +#endif + +/* _VL53L0X_DEVICE_H_ */ + + diff --git a/modules/VL53L0X/inc/vl53l0x_gen.h b/modules/VL53L0X/inc/vl53l0x_gen.h new file mode 100644 index 0000000000000000000000000000000000000000..d28669b08c1e2aa675dcfaa1af74fb2479318054 --- /dev/null +++ b/modules/VL53L0X/inc/vl53l0x_gen.h @@ -0,0 +1,16 @@ +#ifndef __VL53L0X_GEN_H +#define __VL53L0X_GEN_H + +#include "bsp_vl53l0x.h" + + +extern VL53L0X_RangingMeasurementData_t vl53l0x_data; + +VL53L0X_Error vl53l0x_set_mode(VL53L0X_Dev_t *dev,u8 mode); +void vl53l0x_general_test(VL53L0X_Dev_t *dev); + +//ͨ +void vl53l0x_general_start(VL53L0X_Dev_t *dev,u8 mode); +#endif + + diff --git a/modules/VL53L0X/inc/vl53l0x_i2c.h b/modules/VL53L0X/inc/vl53l0x_i2c.h new file mode 100644 index 0000000000000000000000000000000000000000..1f0cbd91c8e0aa7a9dce859c2bece1a58827f47e --- /dev/null +++ b/modules/VL53L0X/inc/vl53l0x_i2c.h @@ -0,0 +1,67 @@ +#ifndef __VL53L0_I2C_H +#define __VL53L0_I2C_H + +#include "stm32f4xx.h" +#include "my_vl53l0.h" +#ifndef u8 +#define u8 uint8_t +#endif +#ifndef u16 +#define u16 uint16_t +#endif +#ifndef u32 +#define u32 uint32_t +#endif + +//˿ֲ +//#define RCC_VL53L0x RCC_AHB1Periph_GPIOB + + +// SDA Ϊģʽ +#define SDA_OUT() { \ + GPIO_InitTypeDef GPIO_InitStruct = {0}; \ + GPIO_InitStruct.Pin = GPIO_SDA; \ + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; \ + GPIO_InitStruct.Pull = GPIO_NOPULL; \ + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; \ + HAL_GPIO_Init(PORT_VL53L0x, &GPIO_InitStruct); \ +} + +// SDA Ϊģʽ +#define SDA_IN() { \ + GPIO_InitTypeDef GPIO_InitStruct = {0}; \ + GPIO_InitStruct.Pin = GPIO_SDA; \ + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; \ + GPIO_InitStruct.Pull = GPIO_NOPULL; \ + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; \ + HAL_GPIO_Init(PORT_VL53L0x, &GPIO_InitStruct); \ +} + +// ȡ SDA ŵƽ +#define SDA_GET() HAL_GPIO_ReadPin(PORT_VL53L0x, GPIO_SDA) + +// SDA / SCL ƽx Ϊ 1 øߣ0 õͣ +#define SDA(x) HAL_GPIO_WritePin(PORT_VL53L0x, GPIO_SDA, (x) ? GPIO_PIN_SET : GPIO_PIN_RESET) +#define SCL(x) HAL_GPIO_WritePin(PORT_VL53L0x, GPIO_SCL, (x) ? GPIO_PIN_SET : GPIO_PIN_RESET) + +//״̬ +#define STATUS_OK 0x00 +#define STATUS_FAIL 0x01 + +//IIC +//void VL53L0X_i2c_init(void);//ʼIICIO + +u8 VL53L0X_write_byte(u8 address,u8 index,u8 data); //IICдһ8λ +u8 VL53L0X_write_word(u8 address,u8 index,u16 data); //IICдһ16λ +u8 VL53L0X_write_dword(u8 address,u8 index,u32 data); //IICдһ32λ +u8 VL53L0X_write_multi(u8 address, u8 index,u8 *pdata,u16 count);//IICд + +u8 VL53L0X_read_byte(u8 address,u8 index,u8 *pdata); //IICһ8λ +u8 VL53L0X_read_word(u8 address,u8 index,u16 *pdata); //IICһ16λ +u8 VL53L0X_read_dword(u8 address,u8 index,u32 *pdata); //IICһ32λ +u8 VL53L0X_read_multi(u8 address,u8 index,u8 *pdata,u16 count); //IIC + + +#endif + + diff --git a/modules/VL53L0X/inc/vl53l0x_interrupt_threshold_settings.h b/modules/VL53L0X/inc/vl53l0x_interrupt_threshold_settings.h new file mode 100644 index 0000000000000000000000000000000000000000..41677f1579a5606cd8c1ee1c8e7a547900579b9d --- /dev/null +++ b/modules/VL53L0X/inc/vl53l0x_interrupt_threshold_settings.h @@ -0,0 +1,194 @@ +/******************************************************************************* +Copyright 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 _VL53L0X_INTERRUPT_THRESHOLD_SETTINGS_H_ +#define _VL53L0X_INTERRUPT_THRESHOLD_SETTINGS_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + + +uint8_t InterruptThresholdSettings[] = { + + /* Start of Interrupt Threshold Settings */ + 0x1, 0xff, 0x00, + 0x1, 0x80, 0x01, + 0x1, 0xff, 0x01, + 0x1, 0x00, 0x00, + 0x1, 0xff, 0x01, + 0x1, 0x4f, 0x02, + 0x1, 0xFF, 0x0E, + 0x1, 0x00, 0x03, + 0x1, 0x01, 0x84, + 0x1, 0x02, 0x0A, + 0x1, 0x03, 0x03, + 0x1, 0x04, 0x08, + 0x1, 0x05, 0xC8, + 0x1, 0x06, 0x03, + 0x1, 0x07, 0x8D, + 0x1, 0x08, 0x08, + 0x1, 0x09, 0xC6, + 0x1, 0x0A, 0x01, + 0x1, 0x0B, 0x02, + 0x1, 0x0C, 0x00, + 0x1, 0x0D, 0xD5, + 0x1, 0x0E, 0x18, + 0x1, 0x0F, 0x12, + 0x1, 0x10, 0x01, + 0x1, 0x11, 0x82, + 0x1, 0x12, 0x00, + 0x1, 0x13, 0xD5, + 0x1, 0x14, 0x18, + 0x1, 0x15, 0x13, + 0x1, 0x16, 0x03, + 0x1, 0x17, 0x86, + 0x1, 0x18, 0x0A, + 0x1, 0x19, 0x09, + 0x1, 0x1A, 0x08, + 0x1, 0x1B, 0xC2, + 0x1, 0x1C, 0x03, + 0x1, 0x1D, 0x8F, + 0x1, 0x1E, 0x0A, + 0x1, 0x1F, 0x06, + 0x1, 0x20, 0x01, + 0x1, 0x21, 0x02, + 0x1, 0x22, 0x00, + 0x1, 0x23, 0xD5, + 0x1, 0x24, 0x18, + 0x1, 0x25, 0x22, + 0x1, 0x26, 0x01, + 0x1, 0x27, 0x82, + 0x1, 0x28, 0x00, + 0x1, 0x29, 0xD5, + 0x1, 0x2A, 0x18, + 0x1, 0x2B, 0x0B, + 0x1, 0x2C, 0x28, + 0x1, 0x2D, 0x78, + 0x1, 0x2E, 0x28, + 0x1, 0x2F, 0x91, + 0x1, 0x30, 0x00, + 0x1, 0x31, 0x0B, + 0x1, 0x32, 0x00, + 0x1, 0x33, 0x0B, + 0x1, 0x34, 0x00, + 0x1, 0x35, 0xA1, + 0x1, 0x36, 0x00, + 0x1, 0x37, 0xA0, + 0x1, 0x38, 0x00, + 0x1, 0x39, 0x04, + 0x1, 0x3A, 0x28, + 0x1, 0x3B, 0x30, + 0x1, 0x3C, 0x0C, + 0x1, 0x3D, 0x04, + 0x1, 0x3E, 0x0F, + 0x1, 0x3F, 0x79, + 0x1, 0x40, 0x28, + 0x1, 0x41, 0x1E, + 0x1, 0x42, 0x2F, + 0x1, 0x43, 0x87, + 0x1, 0x44, 0x00, + 0x1, 0x45, 0x0B, + 0x1, 0x46, 0x00, + 0x1, 0x47, 0x0B, + 0x1, 0x48, 0x00, + 0x1, 0x49, 0xA7, + 0x1, 0x4A, 0x00, + 0x1, 0x4B, 0xA6, + 0x1, 0x4C, 0x00, + 0x1, 0x4D, 0x04, + 0x1, 0x4E, 0x01, + 0x1, 0x4F, 0x00, + 0x1, 0x50, 0x00, + 0x1, 0x51, 0x80, + 0x1, 0x52, 0x09, + 0x1, 0x53, 0x08, + 0x1, 0x54, 0x01, + 0x1, 0x55, 0x00, + 0x1, 0x56, 0x0F, + 0x1, 0x57, 0x79, + 0x1, 0x58, 0x09, + 0x1, 0x59, 0x05, + 0x1, 0x5A, 0x00, + 0x1, 0x5B, 0x60, + 0x1, 0x5C, 0x05, + 0x1, 0x5D, 0xD1, + 0x1, 0x5E, 0x0C, + 0x1, 0x5F, 0x3C, + 0x1, 0x60, 0x00, + 0x1, 0x61, 0xD0, + 0x1, 0x62, 0x0B, + 0x1, 0x63, 0x03, + 0x1, 0x64, 0x28, + 0x1, 0x65, 0x10, + 0x1, 0x66, 0x2A, + 0x1, 0x67, 0x39, + 0x1, 0x68, 0x0B, + 0x1, 0x69, 0x02, + 0x1, 0x6A, 0x28, + 0x1, 0x6B, 0x10, + 0x1, 0x6C, 0x2A, + 0x1, 0x6D, 0x61, + 0x1, 0x6E, 0x0C, + 0x1, 0x6F, 0x00, + 0x1, 0x70, 0x0F, + 0x1, 0x71, 0x79, + 0x1, 0x72, 0x00, + 0x1, 0x73, 0x0B, + 0x1, 0x74, 0x00, + 0x1, 0x75, 0x0B, + 0x1, 0x76, 0x00, + 0x1, 0x77, 0xA1, + 0x1, 0x78, 0x00, + 0x1, 0x79, 0xA0, + 0x1, 0x7A, 0x00, + 0x1, 0x7B, 0x04, + 0x1, 0xFF, 0x04, + 0x1, 0x79, 0x1D, + 0x1, 0x7B, 0x27, + 0x1, 0x96, 0x0E, + 0x1, 0x97, 0xFE, + 0x1, 0x98, 0x03, + 0x1, 0x99, 0xEF, + 0x1, 0x9A, 0x02, + 0x1, 0x9B, 0x44, + 0x1, 0x73, 0x07, + 0x1, 0x70, 0x01, + 0x1, 0xff, 0x01, + 0x1, 0x00, 0x01, + 0x1, 0xff, 0x00, + 0x00, 0x00, 0x00 +}; + +#ifdef __cplusplus +} +#endif + +#endif /* _VL53L0X_INTERRUPT_THRESHOLD_SETTINGS_H_ */ diff --git a/modules/VL53L0X/inc/vl53l0x_it.h b/modules/VL53L0X/inc/vl53l0x_it.h new file mode 100644 index 0000000000000000000000000000000000000000..c4f8c35826f3f8bc82ee1b45a80078e25596a28b --- /dev/null +++ b/modules/VL53L0X/inc/vl53l0x_it.h @@ -0,0 +1,9 @@ +#ifndef __ALARM_H +#define __ALARM_H + +#include "bsp_vl53l0x.h" + +void vl53l0x_interrupt_test(VL53L0X_Dev_t *dev); + + +#endif diff --git a/modules/VL53L0X/inc/vl53l0x_platform.h b/modules/VL53L0X/inc/vl53l0x_platform.h new file mode 100644 index 0000000000000000000000000000000000000000..9149869e9db6babd3b25969269fff7657be3905b --- /dev/null +++ b/modules/VL53L0X/inc/vl53l0x_platform.h @@ -0,0 +1,40 @@ +#ifndef __VL53L0X_PLATFORM_H +#define __VL53L0X_PLATFORM_H + +#include "vl53l0x_def.h" +#include "vl53l0x_i2c.h" +#include "vl53l0x_platform_log.h" + + +//vl53l0x豸I2CϢ +typedef struct { + VL53L0X_DevData_t Data; /*!< embed ST Ewok Dev data as "Data"*/ + /*!< user specific field */ + uint8_t I2cDevAddr; /*!< i2c device address user specific field */ + uint8_t comms_type; /*!< Type of comms : VL53L0X_COMMS_I2C or VL53L0X_COMMS_SPI */ + uint16_t comms_speed_khz; /*!< Comms speed [kHz] : typically 400kHz for I2C */ + +} VL53L0X_Dev_t; + + +typedef VL53L0X_Dev_t* VL53L0X_DEV; + +#define VL53L0X_MAX_I2C_XFER_SIZE 64 //I2Cдֽ +#define PALDevDataGet(Dev, field) (Dev->Data.field) +#define PALDevDataSet(Dev, field, data) (Dev->Data.field)=(data) + + +VL53L0X_Error VL53L0X_WriteMulti(VL53L0X_DEV Dev, uint8_t index, uint8_t *pdata,uint32_t count); +VL53L0X_Error VL53L0X_ReadMulti(VL53L0X_DEV Dev, uint8_t index, uint8_t *pdata,uint32_t count); +VL53L0X_Error VL53L0X_WrByte(VL53L0X_DEV Dev, uint8_t index, uint8_t data); +VL53L0X_Error VL53L0X_WrWord(VL53L0X_DEV Dev, uint8_t index, uint16_t data); +VL53L0X_Error VL53L0X_WrDWord(VL53L0X_DEV Dev, uint8_t index, uint32_t data); +VL53L0X_Error VL53L0X_UpdateByte(VL53L0X_DEV Dev, uint8_t index, uint8_t AndData, uint8_t OrData); +VL53L0X_Error VL53L0X_RdByte(VL53L0X_DEV Dev, uint8_t index, uint8_t *data); +VL53L0X_Error VL53L0X_RdWord(VL53L0X_DEV Dev, uint8_t index, uint16_t *data); +VL53L0X_Error VL53L0X_RdDWord(VL53L0X_DEV Dev, uint8_t index, uint32_t *data); +VL53L0X_Error VL53L0X_PollingDelay(VL53L0X_DEV Dev); + + +#endif + diff --git a/modules/VL53L0X/inc/vl53l0x_platform_log.h b/modules/VL53L0X/inc/vl53l0x_platform_log.h new file mode 100644 index 0000000000000000000000000000000000000000..3cb21467c588237881e7e7251d8e69a4ef48fe24 --- /dev/null +++ b/modules/VL53L0X/inc/vl53l0x_platform_log.h @@ -0,0 +1,157 @@ +///******************************************************************************* +//Copyright 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. +//********************************************************************************/ + + +//#ifndef _VL53L0X_PLATFORM_LOG_H_ +//#define _VL53L0X_PLATFORM_LOG_H_ + +//#include +//#include +///* LOG Functions */ + +//#ifdef __cplusplus +//extern "C" { +//#endif + + +///** +// * @file vl53l0x_platform_log.h +// * +// * @brief platform log function definition +// */ + +////#define VL53L0X_LOG_ENABLE 0 + +//enum { +// TRACE_LEVEL_NONE, +// TRACE_LEVEL_ERRORS, +// TRACE_LEVEL_WARNING, +// TRACE_LEVEL_INFO, +// TRACE_LEVEL_DEBUG, +// TRACE_LEVEL_ALL, +// TRACE_LEVEL_IGNORE +//}; + +//enum { +// TRACE_FUNCTION_NONE = 0, +// TRACE_FUNCTION_I2C = 1, +// TRACE_FUNCTION_ALL = 0x7fffffff //all bits except sign +//}; + +//enum { +// TRACE_MODULE_NONE = 0x0, +// TRACE_MODULE_API = 0x1, +// TRACE_MODULE_PLATFORM = 0x2, +// TRACE_MODULE_ALL = 0x7fffffff //all bits except sign +//}; + + +//#if defined(VL53L0X_LOG_ENABLE) && (TRACE_UART==1) + +//#include +//extern int uart_printf(const char *msg, ...); +//extern int uart_vprintf(const char *msg, va_list ap); + +//#define trace_printf uart_printf +//#define trace_vprintf uart_vprintf + + +//extern uint32_t _trace_level; + + + +//int32_t VL53L0X_trace_config(char *filename, uint32_t modules, uint32_t level, uint32_t functions); +//void trace_print_module_function(uint32_t module, uint32_t level, uint32_t function, const char *format, ...); + + +////extern FILE * log_file; + +//#define LOG_GET_TIME() (int)HAL_GetTick() + +//#define _LOG_FUNCTION_START(module, fmt, ... ) \ +// trace_print_module_function(module, _trace_level, TRACE_FUNCTION_ALL, "%ld %s "fmt"\n", LOG_GET_TIME(), __FUNCTION__, ##__VA_ARGS__); + +//#define _LOG_FUNCTION_END(module, status, ... )\ +// trace_print_module_function(module, _trace_level, TRACE_FUNCTION_ALL, "%d %s %d\n", LOG_GET_TIME(), __FUNCTION__, (int)status, ##__VA_ARGS__) + +//#define _LOG_FUNCTION_END_FMT(module, status, fmt, ... )\ +// trace_print_module_function(module, _trace_level, TRACE_FUNCTION_ALL, "%d %s %d "fmt"\n", LOG_GET_TIME(), __FUNCTION__, (int)status,##__VA_ARGS__) + + +//#else /* VL53L0X_LOG_ENABLE no logging or no TRACE_UART */ +// #define VL53L0X_ErrLog(...) (void)0 +// #define _LOG_FUNCTION_START(module, fmt, ... ) (void)0 +// #define _LOG_FUNCTION_END(module, status, ... ) (void)0 +// #define _LOG_FUNCTION_END_FMT(module, status, fmt, ... ) (void)0 +// #define trace_vprintf(...) (void)0 +// #define VL53L0X_trace_config(...) (void)0 + +//#endif /* else */ + +//#define VL53L0_COPYSTRING(str, ...) strcpy(str, ##__VA_ARGS__) + +//#endif /* _VL53L0X_PLATFORM_LOG_H_ */ + + +#ifndef _VL53L0X_PLATFORM_LOG_H_ +#define _VL53L0X_PLATFORM_LOG_H_ + +#include +#include + +enum { + TRACE_LEVEL_NONE, + TRACE_LEVEL_ERRORS, + TRACE_LEVEL_WARNING, + TRACE_LEVEL_INFO, + TRACE_LEVEL_DEBUG, + TRACE_LEVEL_ALL, + TRACE_LEVEL_IGNORE +}; + +enum { + TRACE_FUNCTION_NONE = 0, + TRACE_FUNCTION_I2C = 1, + TRACE_FUNCTION_ALL = 0x7fffffff //all bits except sign +}; + +enum { + TRACE_MODULE_NONE = 0x0, + TRACE_MODULE_API = 0x1, + TRACE_MODULE_PLATFORM = 0x2, + TRACE_MODULE_ALL = 0x7fffffff //all bits except sign +}; + + +#define VL53L0X_ErrLog(...) (void)0 +#define _LOG_FUNCTION_START(module, fmt, ... ) (void)0 +#define _LOG_FUNCTION_END(module, status, ... ) (void)0 +#define _LOG_FUNCTION_END_FMT(module, status, fmt, ... ) (void)0 +#define VL53L0X_COPYSTRING(str, ...) strcpy(str, __VA_ARGS__) + +#endif /* _VL53L0X_PLATFORM_LOG_H_ */ diff --git a/modules/VL53L0X/inc/vl53l0x_tuning.h b/modules/VL53L0X/inc/vl53l0x_tuning.h new file mode 100644 index 0000000000000000000000000000000000000000..a7ad71bba55cd98c88273df69aa7ae18aa104642 --- /dev/null +++ b/modules/VL53L0X/inc/vl53l0x_tuning.h @@ -0,0 +1,146 @@ +/******************************************************************************* +Copyright 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 _VL53L0X_TUNING_H_ +#define _VL53L0X_TUNING_H_ + +#include "vl53l0x_def.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +uint8_t DefaultTuningSettings[] = { + + /* update 02/11/2015_v36 */ + 0x01, 0xFF, 0x01, + 0x01, 0x00, 0x00, + + 0x01, 0xFF, 0x00, + 0x01, 0x09, 0x00, + 0x01, 0x10, 0x00, + 0x01, 0x11, 0x00, + + 0x01, 0x24, 0x01, + 0x01, 0x25, 0xff, + 0x01, 0x75, 0x00, + + 0x01, 0xFF, 0x01, + 0x01, 0x4e, 0x2c, + 0x01, 0x48, 0x00, + 0x01, 0x30, 0x20, + + 0x01, 0xFF, 0x00, + 0x01, 0x30, 0x09, /* mja changed from 0x64. */ + 0x01, 0x54, 0x00, + 0x01, 0x31, 0x04, + 0x01, 0x32, 0x03, + 0x01, 0x40, 0x83, + 0x01, 0x46, 0x25, + 0x01, 0x60, 0x00, + 0x01, 0x27, 0x00, + 0x01, 0x50, 0x06, + 0x01, 0x51, 0x00, + 0x01, 0x52, 0x96, + 0x01, 0x56, 0x08, + 0x01, 0x57, 0x30, + 0x01, 0x61, 0x00, + 0x01, 0x62, 0x00, + 0x01, 0x64, 0x00, + 0x01, 0x65, 0x00, + 0x01, 0x66, 0xa0, + + 0x01, 0xFF, 0x01, + 0x01, 0x22, 0x32, + 0x01, 0x47, 0x14, + 0x01, 0x49, 0xff, + 0x01, 0x4a, 0x00, + + 0x01, 0xFF, 0x00, + 0x01, 0x7a, 0x0a, + 0x01, 0x7b, 0x00, + 0x01, 0x78, 0x21, + + 0x01, 0xFF, 0x01, + 0x01, 0x23, 0x34, + 0x01, 0x42, 0x00, + 0x01, 0x44, 0xff, + 0x01, 0x45, 0x26, + 0x01, 0x46, 0x05, + 0x01, 0x40, 0x40, + 0x01, 0x0E, 0x06, + 0x01, 0x20, 0x1a, + 0x01, 0x43, 0x40, + + 0x01, 0xFF, 0x00, + 0x01, 0x34, 0x03, + 0x01, 0x35, 0x44, + + 0x01, 0xFF, 0x01, + 0x01, 0x31, 0x04, + 0x01, 0x4b, 0x09, + 0x01, 0x4c, 0x05, + 0x01, 0x4d, 0x04, + + + 0x01, 0xFF, 0x00, + 0x01, 0x44, 0x00, + 0x01, 0x45, 0x20, + 0x01, 0x47, 0x08, + 0x01, 0x48, 0x28, + 0x01, 0x67, 0x00, + 0x01, 0x70, 0x04, + 0x01, 0x71, 0x01, + 0x01, 0x72, 0xfe, + 0x01, 0x76, 0x00, + 0x01, 0x77, 0x00, + + 0x01, 0xFF, 0x01, + 0x01, 0x0d, 0x01, + + 0x01, 0xFF, 0x00, + 0x01, 0x80, 0x01, + 0x01, 0x01, 0xF8, + + 0x01, 0xFF, 0x01, + 0x01, 0x8e, 0x01, + 0x01, 0x00, 0x01, + 0x01, 0xFF, 0x00, + 0x01, 0x80, 0x00, + + 0x00, 0x00, 0x00 +}; + +#ifdef __cplusplus +} +#endif + +#endif /* _VL53L0X_TUNING_H_ */ diff --git a/modules/VL53L0X/inc/vl53l0x_types.h b/modules/VL53L0X/inc/vl53l0x_types.h new file mode 100644 index 0000000000000000000000000000000000000000..db9e81d5fc38cf0391210dfdbc0036ec48da8ad2 --- /dev/null +++ b/modules/VL53L0X/inc/vl53l0x_types.h @@ -0,0 +1,112 @@ +/******************************************************************************* +Copyright ?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 vl53l0_types.h + * @brief VL53L0 types definition + */ + +#ifndef VL53L0X_TYPES_H_ +#define VL53L0X_TYPES_H_ + +/** @defgroup porting_type Basic type definition + * @ingroup VL53L0X_platform_group + * + * @brief file vl53l0_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 +#include +#include "stm32f4xx.h" + +#ifndef NULL +#error "Error NULL definition should be done. Please add required include " +#endif + + +#if ! defined(STDINT_H) && !defined(_GCC_STDINT_H) &&!defined(__STDINT_DECLS) && !defined(_GCC_WRAP_STDINT_H) + + #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 VL53L0X_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 /* VL53L0X_TYPES_H_ */ diff --git a/modules/VL53L0X/my_vl53l0.h b/modules/VL53L0X/my_vl53l0.h new file mode 100644 index 0000000000000000000000000000000000000000..745a3719bc8beba8dc23b413487bae6e50662024 --- /dev/null +++ b/modules/VL53L0X/my_vl53l0.h @@ -0,0 +1,9 @@ +#ifndef __my_vl53l0_H +#define __my_vl53l0_H +#include "stm32f4xx_hal.h" + +#define VL53L0X_Xshut PDout(5) +#define PORT_VL53L0x GPIOD +#define GPIO_SDA GPIO_PIN_6 +#define GPIO_SCL GPIO_PIN_7 +#endif diff --git a/modules/VL53L0X/src/bsp_VL53L0X.c b/modules/VL53L0X/src/bsp_VL53L0X.c new file mode 100644 index 0000000000000000000000000000000000000000..25f772e29bcd7b7a050854bdf7ebe9a14afb3db6 --- /dev/null +++ b/modules/VL53L0X/src/bsp_VL53L0X.c @@ -0,0 +1,170 @@ +#include "bsp_vl53l0x.h" +#include "my_vl53l0.h" +#include "delay.h" + +VL53L0X_Dev_t vl53l0x_dev;//豸I2Cݲ +VL53L0X_DeviceInfo_t vl53l0x_dev_info;//豸ID汾Ϣ +uint8_t AjustOK=0;//У׼־λ + +//VL53L0Xģʽ +//0Ĭ;1:߾;2:;3: +mode_data Mode_data[]= +{ + {(FixPoint1616_t)(0.25*65536), + (FixPoint1616_t)(18*65536), + 33000, + 14, + 10},//Ĭ + + {(FixPoint1616_t)(0.25*65536) , + (FixPoint1616_t)(18*65536), + 200000, + 14, + 10},//߾ + + {(FixPoint1616_t)(0.1*65536) , + (FixPoint1616_t)(60*65536), + 33000, + 18, + 14},// + + {(FixPoint1616_t)(0.25*65536) , + (FixPoint1616_t)(32*65536), + 20000, + 14, + 10},// + +}; + +//APIϢӡ +//Status鿴VL53L0X_ErrorĶ +void print_pal_error(VL53L0X_Error Status) +{ + + char buf[VL53L0X_MAX_STRING_LENGTH]; + + VL53L0X_GetPalErrorString(Status,buf);//Status״̬ȡϢַ + + printf("API Status: %i : %s\r\n",Status, buf);//ӡ״̬ʹϢ +} + + +//VL53L0X豸I2Cַ +//dev:豸I2Cṹ +//newaddr:豸I2Cַ +VL53L0X_Error vl53l0x_Addr_set(VL53L0X_Dev_t *dev,uint8_t newaddr) +{ + uint16_t Id; + uint8_t FinalAddress; + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + u8 sta=0x00; + + FinalAddress = newaddr; + + if(FinalAddress==dev->I2cDevAddr)//豸I2Cַɵַһ,ֱ˳ + return VL53L0X_ERROR_NONE; + //ڽеһĴ֮ǰI2C׼ģʽ(400Khz) + Status = VL53L0X_WrByte(dev,0x88,0x00); + if(Status!=VL53L0X_ERROR_NONE) + { + sta=0x01;//I2C׼ģʽ + goto set_error; + } + //ʹĬϵ0x52ַȡһĴ + Status = VL53L0X_RdWord(dev, VL53L0X_REG_IDENTIFICATION_MODEL_ID, &Id); + if(Status!=VL53L0X_ERROR_NONE) + { + sta=0x02;//ȡĴ + goto set_error; + } + if(Id == 0xEEAA) + { + //豸µI2Cַ + Status = VL53L0X_SetDeviceAddress(dev,FinalAddress); + if(Status!=VL53L0X_ERROR_NONE) + { + sta=0x03;//I2Cַ + goto set_error; + } + //޸IJṹI2Cַ + dev->I2cDevAddr = FinalAddress; + //µI2CַдǷ + Status = VL53L0X_RdWord(dev, VL53L0X_REG_IDENTIFICATION_MODEL_ID, &Id); + if(Status!=VL53L0X_ERROR_NONE) + { + sta=0x04;//I2Cַд + goto set_error; + } + } + set_error: + if(Status!=VL53L0X_ERROR_NONE) + { + print_pal_error(Status);//ӡϢ + } + if(sta!=0) + printf("sta:0x%x\r\n",sta); + return Status; +} + +//vl53l0xλ +//dev:豸I2Cṹ +void vl53l0x_reset(VL53L0X_Dev_t *dev) +{ + uint8_t addr; + addr = dev->I2cDevAddr;//豸ԭI2Cַ + VL53L0X_Xshut=0;//ʧVL53L0X + delay_ms(30); + VL53L0X_Xshut=1;//ʹVL53L0X,ôڹ(I2CַָĬ0X52) + delay_ms(30); + dev->I2cDevAddr=0x52; + vl53l0x_Addr_set(dev,addr);//VL53L0XԭϵǰԭI2Cַ + VL53L0X_DataInit(dev); +} + +//ʼvl53l0x +//dev:豸I2Cṹ +VL53L0X_Error vl53l0x_init(VL53L0X_Dev_t *dev) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + VL53L0X_Dev_t *pMyDevice = dev; + +// RCC_AHB1PeriphClockCmd(RCC_VL53L0x, ENABLE); // ʹGPIOʱ +// +// GPIO_InitTypeDef GPIO_InitStructure; + +// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; +// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; +// GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; +// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; +// GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; +// GPIO_Init(PORT_VL53L0x, &GPIO_InitStructure); + + + pMyDevice->I2cDevAddr = VL53L0X_Addr;//I2Cַ(ϵĬ0x52) + pMyDevice->comms_type = 1; //I2Cͨģʽ + pMyDevice->comms_speed_khz = 400; //I2Cͨ + + //VL53L0X_i2c_init();//ʼIIC + + VL53L0X_Xshut=0;//ʧVL53L0X + delay_ms(50); + VL53L0X_Xshut=1;//ʹVL53L0X,ôڹ + delay_ms(50); + + vl53l0x_Addr_set(pMyDevice,0x54);//VL53L0XI2Cַ + if(Status!=VL53L0X_ERROR_NONE) goto error; + Status = VL53L0X_DataInit(pMyDevice);//豸ʼ + if(Status!=VL53L0X_ERROR_NONE) goto error; + delay_ms(2); + Status = VL53L0X_GetDeviceInfo(pMyDevice,&vl53l0x_dev_info);//ȡ豸IDϢ + if(Status!=VL53L0X_ERROR_NONE) goto error; + + error: + if(Status!=VL53L0X_ERROR_NONE) + { + print_pal_error(Status);//ӡϢ + return Status; + } + + return Status; +} diff --git a/modules/VL53L0X/src/vl53l0x_api.c b/modules/VL53L0X/src/vl53l0x_api.c new file mode 100644 index 0000000000000000000000000000000000000000..0163f7396c2a520a4540059f44b5d8998fcadff9 --- /dev/null +++ b/modules/VL53L0X/src/vl53l0x_api.c @@ -0,0 +1,3035 @@ +/******************************************************************************* + Copyright 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. + ******************************************************************************/ + +#include "vl53l0x_api.h" +#include "vl53l0x_tuning.h" +#include "vl53l0x_interrupt_threshold_settings.h" +#include "vl53l0x_api_core.h" +#include "vl53l0x_api_calibration.h" +#include "vl53l0x_api_strings.h" + +#ifndef __KERNEL__ +#include +#endif +#define LOG_FUNCTION_START(fmt, ...) \ + _LOG_FUNCTION_START(TRACE_MODULE_API, fmt, ##__VA_ARGS__) +#define LOG_FUNCTION_END(status, ...) \ + _LOG_FUNCTION_END(TRACE_MODULE_API, status, ##__VA_ARGS__) +#define LOG_FUNCTION_END_FMT(status, fmt, ...) \ + _LOG_FUNCTION_END_FMT(TRACE_MODULE_API, status, fmt, ##__VA_ARGS__) + +#ifdef VL53L0X_LOG_ENABLE +#define trace_print(level, ...) trace_print_module_function(TRACE_MODULE_API, \ + level, TRACE_FUNCTION_NONE, ##__VA_ARGS__) +#endif + +/* Group PAL General Functions */ + +VL53L0X_Error VL53L0X_GetVersion(VL53L0X_Version_t *pVersion) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + LOG_FUNCTION_START(""); + + pVersion->major = VL53L0X_IMPLEMENTATION_VER_MAJOR; + pVersion->minor = VL53L0X_IMPLEMENTATION_VER_MINOR; + pVersion->build = VL53L0X_IMPLEMENTATION_VER_SUB; + + pVersion->revision = VL53L0X_IMPLEMENTATION_VER_REVISION; + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_GetPalSpecVersion(VL53L0X_Version_t *pPalSpecVersion) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + + LOG_FUNCTION_START(""); + + pPalSpecVersion->major = VL53L0X_SPECIFICATION_VER_MAJOR; + pPalSpecVersion->minor = VL53L0X_SPECIFICATION_VER_MINOR; + pPalSpecVersion->build = VL53L0X_SPECIFICATION_VER_SUB; + + pPalSpecVersion->revision = VL53L0X_SPECIFICATION_VER_REVISION; + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_GetProductRevision(VL53L0X_DEV Dev, + uint8_t *pProductRevisionMajor, uint8_t *pProductRevisionMinor) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + uint8_t revision_id; + + LOG_FUNCTION_START(""); + + Status = VL53L0X_RdByte(Dev, VL53L0X_REG_IDENTIFICATION_REVISION_ID, + &revision_id); + *pProductRevisionMajor = 1; + *pProductRevisionMinor = (revision_id & 0xF0) >> 4; + + LOG_FUNCTION_END(Status); + return Status; + +} + +VL53L0X_Error VL53L0X_GetDeviceInfo(VL53L0X_DEV Dev, + VL53L0X_DeviceInfo_t *pVL53L0X_DeviceInfo) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + LOG_FUNCTION_START(""); + + Status = VL53L0X_get_device_info(Dev, pVL53L0X_DeviceInfo); + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_GetDeviceErrorStatus(VL53L0X_DEV Dev, + VL53L0X_DeviceError *pDeviceErrorStatus) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + uint8_t RangeStatus; + + LOG_FUNCTION_START(""); + + Status = VL53L0X_RdByte(Dev, VL53L0X_REG_RESULT_RANGE_STATUS, + &RangeStatus); + + *pDeviceErrorStatus = (VL53L0X_DeviceError)((RangeStatus & 0x78) >> 3); + + LOG_FUNCTION_END(Status); + return Status; +} + + +VL53L0X_Error VL53L0X_GetDeviceErrorString(VL53L0X_DeviceError ErrorCode, + char *pDeviceErrorString) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + + LOG_FUNCTION_START(""); + + Status = VL53L0X_get_device_error_string(ErrorCode, pDeviceErrorString); + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_GetRangeStatusString(uint8_t RangeStatus, + char *pRangeStatusString) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + LOG_FUNCTION_START(""); + + Status = VL53L0X_get_range_status_string(RangeStatus, + pRangeStatusString); + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_GetPalErrorString(VL53L0X_Error PalErrorCode, + char *pPalErrorString) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + LOG_FUNCTION_START(""); + + Status = VL53L0X_get_pal_error_string(PalErrorCode, pPalErrorString); + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_GetPalStateString(VL53L0X_State PalStateCode, + char *pPalStateString) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + LOG_FUNCTION_START(""); + + Status = VL53L0X_get_pal_state_string(PalStateCode, pPalStateString); + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_GetPalState(VL53L0X_DEV Dev, VL53L0X_State *pPalState) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + LOG_FUNCTION_START(""); + + *pPalState = PALDevDataGet(Dev, PalState); + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_SetPowerMode(VL53L0X_DEV Dev, VL53L0X_PowerModes PowerMode) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + LOG_FUNCTION_START(""); + + /* Only level1 of Power mode exists */ + if ((PowerMode != VL53L0X_POWERMODE_STANDBY_LEVEL1) + && (PowerMode != VL53L0X_POWERMODE_IDLE_LEVEL1)) { + Status = VL53L0X_ERROR_MODE_NOT_SUPPORTED; + } else if (PowerMode == VL53L0X_POWERMODE_STANDBY_LEVEL1) { + /* set the standby level1 of power mode */ + Status = VL53L0X_WrByte(Dev, 0x80, 0x00); + if (Status == VL53L0X_ERROR_NONE) { + /* Set PAL State to standby */ + PALDevDataSet(Dev, PalState, VL53L0X_STATE_STANDBY); + PALDevDataSet(Dev, PowerMode, + VL53L0X_POWERMODE_STANDBY_LEVEL1); + } + + } else { + /* VL53L0X_POWERMODE_IDLE_LEVEL1 */ + Status = VL53L0X_WrByte(Dev, 0x80, 0x00); + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_StaticInit(Dev); + + if (Status == VL53L0X_ERROR_NONE) + PALDevDataSet(Dev, PowerMode, + VL53L0X_POWERMODE_IDLE_LEVEL1); + + } + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_GetPowerMode(VL53L0X_DEV Dev, VL53L0X_PowerModes *pPowerMode) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + uint8_t Byte; + LOG_FUNCTION_START(""); + + /* Only level1 of Power mode exists */ + Status = VL53L0X_RdByte(Dev, 0x80, &Byte); + + if (Status == VL53L0X_ERROR_NONE) { + if (Byte == 1) { + PALDevDataSet(Dev, PowerMode, + VL53L0X_POWERMODE_IDLE_LEVEL1); + } else { + PALDevDataSet(Dev, PowerMode, + VL53L0X_POWERMODE_STANDBY_LEVEL1); + } + } + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_SetOffsetCalibrationDataMicroMeter(VL53L0X_DEV Dev, + int32_t OffsetCalibrationDataMicroMeter) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + LOG_FUNCTION_START(""); + + Status = VL53L0X_set_offset_calibration_data_micro_meter(Dev, + OffsetCalibrationDataMicroMeter); + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_GetOffsetCalibrationDataMicroMeter(VL53L0X_DEV Dev, + int32_t *pOffsetCalibrationDataMicroMeter) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + LOG_FUNCTION_START(""); + + Status = VL53L0X_get_offset_calibration_data_micro_meter(Dev, + pOffsetCalibrationDataMicroMeter); + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_SetLinearityCorrectiveGain(VL53L0X_DEV Dev, + int16_t LinearityCorrectiveGain) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + LOG_FUNCTION_START(""); + + if ((LinearityCorrectiveGain < 0) || (LinearityCorrectiveGain > 1000)) + Status = VL53L0X_ERROR_INVALID_PARAMS; + else { + PALDevDataSet(Dev, LinearityCorrectiveGain, + LinearityCorrectiveGain); + + if (LinearityCorrectiveGain != 1000) { + /* Disable FW Xtalk */ + Status = VL53L0X_WrWord(Dev, + VL53L0X_REG_CROSSTALK_COMPENSATION_PEAK_RATE_MCPS, 0); + } + } + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_GetLinearityCorrectiveGain(VL53L0X_DEV Dev, + uint16_t *pLinearityCorrectiveGain) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + LOG_FUNCTION_START(""); + + *pLinearityCorrectiveGain = PALDevDataGet(Dev, LinearityCorrectiveGain); + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_SetGroupParamHold(VL53L0X_DEV Dev, uint8_t GroupParamHold) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NOT_IMPLEMENTED; + LOG_FUNCTION_START(""); + + /* not implemented on VL53L0X */ + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_GetUpperLimitMilliMeter(VL53L0X_DEV Dev, + uint16_t *pUpperLimitMilliMeter) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NOT_IMPLEMENTED; + LOG_FUNCTION_START(""); + + /* not implemented on VL53L0X */ + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_GetTotalSignalRate(VL53L0X_DEV Dev, + FixPoint1616_t *pTotalSignalRate) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + VL53L0X_RangingMeasurementData_t LastRangeDataBuffer; + + LOG_FUNCTION_START(""); + + LastRangeDataBuffer = PALDevDataGet(Dev, LastRangeMeasure); + + Status = VL53L0X_get_total_signal_rate( + Dev, &LastRangeDataBuffer, pTotalSignalRate); + + LOG_FUNCTION_END(Status); + return Status; +} + +/* End Group PAL General Functions */ + +/* Group PAL Init Functions */ +VL53L0X_Error VL53L0X_SetDeviceAddress(VL53L0X_DEV Dev, uint8_t DeviceAddress) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + LOG_FUNCTION_START(""); + + Status = VL53L0X_WrByte(Dev, VL53L0X_REG_I2C_SLAVE_DEVICE_ADDRESS, + DeviceAddress / 2); + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_DataInit(VL53L0X_DEV Dev) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + VL53L0X_DeviceParameters_t CurrentParameters; + int i; + uint8_t StopVariable; + + LOG_FUNCTION_START(""); + + /* by default the I2C is running at 1V8 if you want to change it you + * need to include this define at compilation level. */ +#ifdef USE_I2C_2V8 + Status = VL53L0X_UpdateByte(Dev, + VL53L0X_REG_VHV_CONFIG_PAD_SCL_SDA__EXTSUP_HV, + 0xFE, + 0x01); +#endif + + /* Set I2C standard mode */ + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_WrByte(Dev, 0x88, 0x00); + + VL53L0X_SETDEVICESPECIFICPARAMETER(Dev, ReadDataFromDeviceDone, 0); + +#ifdef USE_IQC_STATION + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_apply_offset_adjustment(Dev); +#endif + + /* Default value is 1000 for Linearity Corrective Gain */ + PALDevDataSet(Dev, LinearityCorrectiveGain, 1000); + + /* Dmax default Parameter */ + PALDevDataSet(Dev, DmaxCalRangeMilliMeter, 400); + PALDevDataSet(Dev, DmaxCalSignalRateRtnMegaCps, + (FixPoint1616_t)((0x00016B85))); /* 1.42 No Cover Glass*/ + + /* Set Default static parameters + *set first temporary values 9.44MHz * 65536 = 618660 */ + VL53L0X_SETDEVICESPECIFICPARAMETER(Dev, OscFrequencyMHz, 618660); + + /* Set Default XTalkCompensationRateMegaCps to 0 */ + VL53L0X_SETPARAMETERFIELD(Dev, XTalkCompensationRateMegaCps, 0); + + /* Get default parameters */ + Status = VL53L0X_GetDeviceParameters(Dev, &CurrentParameters); + if (Status == VL53L0X_ERROR_NONE) { + /* initialize PAL values */ + CurrentParameters.DeviceMode = VL53L0X_DEVICEMODE_SINGLE_RANGING; + CurrentParameters.HistogramMode = VL53L0X_HISTOGRAMMODE_DISABLED; + PALDevDataSet(Dev, CurrentParameters, CurrentParameters); + } + + /* Sigma estimator variable */ + PALDevDataSet(Dev, SigmaEstRefArray, 100); + PALDevDataSet(Dev, SigmaEstEffPulseWidth, 900); + PALDevDataSet(Dev, SigmaEstEffAmbWidth, 500); + PALDevDataSet(Dev, targetRefRate, 0x0A00); /* 20 MCPS in 9:7 format */ + + /* Use internal default settings */ + PALDevDataSet(Dev, UseInternalTuningSettings, 1); + + Status |= VL53L0X_WrByte(Dev, 0x80, 0x01); + Status |= VL53L0X_WrByte(Dev, 0xFF, 0x01); + Status |= VL53L0X_WrByte(Dev, 0x00, 0x00); + Status |= VL53L0X_RdByte(Dev, 0x91, &StopVariable); + PALDevDataSet(Dev, StopVariable, StopVariable); + Status |= VL53L0X_WrByte(Dev, 0x00, 0x01); + Status |= VL53L0X_WrByte(Dev, 0xFF, 0x00); + Status |= VL53L0X_WrByte(Dev, 0x80, 0x00); + + /* Enable all check */ + for (i = 0; i < VL53L0X_CHECKENABLE_NUMBER_OF_CHECKS; i++) { + if (Status == VL53L0X_ERROR_NONE) + Status |= VL53L0X_SetLimitCheckEnable(Dev, i, 1); + else + break; + + } + + /* Disable the following checks */ + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_SetLimitCheckEnable(Dev, + VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP, 0); + + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_SetLimitCheckEnable(Dev, + VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD, 0); + + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_SetLimitCheckEnable(Dev, + VL53L0X_CHECKENABLE_SIGNAL_RATE_MSRC, 0); + + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_SetLimitCheckEnable(Dev, + VL53L0X_CHECKENABLE_SIGNAL_RATE_PRE_RANGE, 0); + + /* Limit default values */ + if (Status == VL53L0X_ERROR_NONE) { + Status = VL53L0X_SetLimitCheckValue(Dev, + VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE, + (FixPoint1616_t)(18 * 65536)); + } + if (Status == VL53L0X_ERROR_NONE) { + Status = VL53L0X_SetLimitCheckValue(Dev, + VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE, + (FixPoint1616_t)(25 * 65536 / 100)); + /* 0.25 * 65536 */ + } + + if (Status == VL53L0X_ERROR_NONE) { + Status = VL53L0X_SetLimitCheckValue(Dev, + VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP, + (FixPoint1616_t)(35 * 65536)); + } + + if (Status == VL53L0X_ERROR_NONE) { + Status = VL53L0X_SetLimitCheckValue(Dev, + VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD, + (FixPoint1616_t)(0 * 65536)); + } + + if (Status == VL53L0X_ERROR_NONE) { + + PALDevDataSet(Dev, SequenceConfig, 0xFF); + Status = VL53L0X_WrByte(Dev, VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG, + 0xFF); + + /* Set PAL state to tell that we are waiting for call to + * VL53L0X_StaticInit */ + PALDevDataSet(Dev, PalState, VL53L0X_STATE_WAIT_STATICINIT); + } + + if (Status == VL53L0X_ERROR_NONE) + VL53L0X_SETDEVICESPECIFICPARAMETER(Dev, RefSpadsInitialised, 0); + + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_SetTuningSettingBuffer(VL53L0X_DEV Dev, + uint8_t *pTuningSettingBuffer, uint8_t UseInternalTuningSettings) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + + LOG_FUNCTION_START(""); + + if (UseInternalTuningSettings == 1) { + /* Force use internal settings */ + PALDevDataSet(Dev, UseInternalTuningSettings, 1); + } else { + + /* check that the first byte is not 0 */ + if (*pTuningSettingBuffer != 0) { + PALDevDataSet(Dev, pTuningSettingsPointer, + pTuningSettingBuffer); + PALDevDataSet(Dev, UseInternalTuningSettings, 0); + + } else { + Status = VL53L0X_ERROR_INVALID_PARAMS; + } + } + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_GetTuningSettingBuffer(VL53L0X_DEV Dev, + uint8_t **ppTuningSettingBuffer, uint8_t *pUseInternalTuningSettings) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + + LOG_FUNCTION_START(""); + + *ppTuningSettingBuffer = PALDevDataGet(Dev, pTuningSettingsPointer); + *pUseInternalTuningSettings = PALDevDataGet(Dev, + UseInternalTuningSettings); + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_StaticInit(VL53L0X_DEV Dev) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + VL53L0X_DeviceParameters_t CurrentParameters = {0}; + uint8_t *pTuningSettingBuffer; + uint16_t tempword = 0; + uint8_t tempbyte = 0; + uint8_t UseInternalTuningSettings = 0; + uint32_t count = 0; + uint8_t isApertureSpads = 0; + uint32_t refSpadCount = 0; + uint8_t ApertureSpads = 0; + uint8_t vcselPulsePeriodPCLK; + uint32_t seqTimeoutMicroSecs; + + LOG_FUNCTION_START(""); + + Status = VL53L0X_get_info_from_device(Dev, 1); + + /* set the ref spad from NVM */ + count = (uint32_t)VL53L0X_GETDEVICESPECIFICPARAMETER(Dev, + ReferenceSpadCount); + ApertureSpads = VL53L0X_GETDEVICESPECIFICPARAMETER(Dev, + ReferenceSpadType); + + /* NVM value invalid */ + if ((ApertureSpads > 1) || + ((ApertureSpads == 1) && (count > 32)) || + ((ApertureSpads == 0) && (count > 12))) + Status = VL53L0X_perform_ref_spad_management(Dev, &refSpadCount, + &isApertureSpads); + else + Status = VL53L0X_set_reference_spads(Dev, count, ApertureSpads); + + + /* Initialize tuning settings buffer to prevent compiler warning. */ + pTuningSettingBuffer = DefaultTuningSettings; + + if (Status == VL53L0X_ERROR_NONE) { + UseInternalTuningSettings = PALDevDataGet(Dev, + UseInternalTuningSettings); + + if (UseInternalTuningSettings == 0) + pTuningSettingBuffer = PALDevDataGet(Dev, + pTuningSettingsPointer); + else + pTuningSettingBuffer = DefaultTuningSettings; + + } + + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_load_tuning_settings(Dev, pTuningSettingBuffer); + + + /* Set interrupt config to new sample ready */ + if (Status == VL53L0X_ERROR_NONE) { + Status = VL53L0X_SetGpioConfig(Dev, 0, 0, + VL53L0X_REG_SYSTEM_INTERRUPT_GPIO_NEW_SAMPLE_READY, + VL53L0X_INTERRUPTPOLARITY_LOW); + } + + if (Status == VL53L0X_ERROR_NONE) { + Status = VL53L0X_WrByte(Dev, 0xFF, 0x01); + Status |= VL53L0X_RdWord(Dev, 0x84, &tempword); + Status |= VL53L0X_WrByte(Dev, 0xFF, 0x00); + } + + if (Status == VL53L0X_ERROR_NONE) { + VL53L0X_SETDEVICESPECIFICPARAMETER(Dev, OscFrequencyMHz, + VL53L0X_FIXPOINT412TOFIXPOINT1616(tempword)); + } + + /* After static init, some device parameters may be changed, + * so update them */ + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_GetDeviceParameters(Dev, &CurrentParameters); + + + if (Status == VL53L0X_ERROR_NONE) { + Status = VL53L0X_GetFractionEnable(Dev, &tempbyte); + if (Status == VL53L0X_ERROR_NONE) + PALDevDataSet(Dev, RangeFractionalEnable, tempbyte); + + } + + if (Status == VL53L0X_ERROR_NONE) + PALDevDataSet(Dev, CurrentParameters, CurrentParameters); + + + /* read the sequence config and save it */ + if (Status == VL53L0X_ERROR_NONE) { + Status = VL53L0X_RdByte(Dev, + VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG, &tempbyte); + if (Status == VL53L0X_ERROR_NONE) + PALDevDataSet(Dev, SequenceConfig, tempbyte); + + } + + /* Disable MSRC and TCC by default */ + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_SetSequenceStepEnable(Dev, + VL53L0X_SEQUENCESTEP_TCC, 0); + + + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_SetSequenceStepEnable(Dev, + VL53L0X_SEQUENCESTEP_MSRC, 0); + + + /* Set PAL State to standby */ + if (Status == VL53L0X_ERROR_NONE) + PALDevDataSet(Dev, PalState, VL53L0X_STATE_IDLE); + + + + /* Store pre-range vcsel period */ + if (Status == VL53L0X_ERROR_NONE) { + Status = VL53L0X_GetVcselPulsePeriod( + Dev, + VL53L0X_VCSEL_PERIOD_PRE_RANGE, + &vcselPulsePeriodPCLK); + } + + if (Status == VL53L0X_ERROR_NONE) { + VL53L0X_SETDEVICESPECIFICPARAMETER( + Dev, + PreRangeVcselPulsePeriod, + vcselPulsePeriodPCLK); + } + + /* Store final-range vcsel period */ + if (Status == VL53L0X_ERROR_NONE) { + Status = VL53L0X_GetVcselPulsePeriod( + Dev, + VL53L0X_VCSEL_PERIOD_FINAL_RANGE, + &vcselPulsePeriodPCLK); + } + + if (Status == VL53L0X_ERROR_NONE) { + VL53L0X_SETDEVICESPECIFICPARAMETER( + Dev, + FinalRangeVcselPulsePeriod, + vcselPulsePeriodPCLK); + } + + /* Store pre-range timeout */ + if (Status == VL53L0X_ERROR_NONE) { + Status = get_sequence_step_timeout( + Dev, + VL53L0X_SEQUENCESTEP_PRE_RANGE, + &seqTimeoutMicroSecs); + } + + if (Status == VL53L0X_ERROR_NONE) { + VL53L0X_SETDEVICESPECIFICPARAMETER( + Dev, + PreRangeTimeoutMicroSecs, + seqTimeoutMicroSecs); + } + + /* Store final-range timeout */ + if (Status == VL53L0X_ERROR_NONE) { + Status = get_sequence_step_timeout( + Dev, + VL53L0X_SEQUENCESTEP_FINAL_RANGE, + &seqTimeoutMicroSecs); + } + + if (Status == VL53L0X_ERROR_NONE) { + VL53L0X_SETDEVICESPECIFICPARAMETER( + Dev, + FinalRangeTimeoutMicroSecs, + seqTimeoutMicroSecs); + } + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_WaitDeviceBooted(VL53L0X_DEV Dev) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NOT_IMPLEMENTED; + LOG_FUNCTION_START(""); + + /* not implemented on VL53L0X */ + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_ResetDevice(VL53L0X_DEV Dev) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + uint8_t Byte; + LOG_FUNCTION_START(""); + + /* Set reset bit */ + Status = VL53L0X_WrByte(Dev, VL53L0X_REG_SOFT_RESET_GO2_SOFT_RESET_N, + 0x00); + + /* Wait for some time */ + if (Status == VL53L0X_ERROR_NONE) { + do { + Status = VL53L0X_RdByte(Dev, + VL53L0X_REG_IDENTIFICATION_MODEL_ID, &Byte); + } while (Byte != 0x00); + } + + VL53L0X_PollingDelay(Dev); + + /* Release reset */ + Status = VL53L0X_WrByte(Dev, VL53L0X_REG_SOFT_RESET_GO2_SOFT_RESET_N, + 0x01); + + /* Wait until correct boot-up of the device */ + if (Status == VL53L0X_ERROR_NONE) { + do { + Status = VL53L0X_RdByte(Dev, + VL53L0X_REG_IDENTIFICATION_MODEL_ID, &Byte); + } while (Byte == 0x00); + } + + VL53L0X_PollingDelay(Dev); + + /* Set PAL State to VL53L0X_STATE_POWERDOWN */ + if (Status == VL53L0X_ERROR_NONE) + PALDevDataSet(Dev, PalState, VL53L0X_STATE_POWERDOWN); + + + LOG_FUNCTION_END(Status); + return Status; +} +/* End Group PAL Init Functions */ + +/* Group PAL Parameters Functions */ +VL53L0X_Error VL53L0X_SetDeviceParameters(VL53L0X_DEV Dev, + const VL53L0X_DeviceParameters_t *pDeviceParameters) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + int i; + LOG_FUNCTION_START(""); + Status = VL53L0X_SetDeviceMode(Dev, pDeviceParameters->DeviceMode); + + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_SetInterMeasurementPeriodMilliSeconds(Dev, + pDeviceParameters->InterMeasurementPeriodMilliSeconds); + + + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_SetXTalkCompensationRateMegaCps(Dev, + pDeviceParameters->XTalkCompensationRateMegaCps); + + + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_SetOffsetCalibrationDataMicroMeter(Dev, + pDeviceParameters->RangeOffsetMicroMeters); + + + for (i = 0; i < VL53L0X_CHECKENABLE_NUMBER_OF_CHECKS; i++) { + if (Status == VL53L0X_ERROR_NONE) + Status |= VL53L0X_SetLimitCheckEnable(Dev, i, + pDeviceParameters->LimitChecksEnable[i]); + else + break; + + if (Status == VL53L0X_ERROR_NONE) + Status |= VL53L0X_SetLimitCheckValue(Dev, i, + pDeviceParameters->LimitChecksValue[i]); + else + break; + + } + + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_SetWrapAroundCheckEnable(Dev, + pDeviceParameters->WrapAroundCheckEnable); + + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_SetMeasurementTimingBudgetMicroSeconds(Dev, + pDeviceParameters->MeasurementTimingBudgetMicroSeconds); + + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_GetDeviceParameters(VL53L0X_DEV Dev, + VL53L0X_DeviceParameters_t *pDeviceParameters) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + int i; + + LOG_FUNCTION_START(""); + + Status = VL53L0X_GetDeviceMode(Dev, &(pDeviceParameters->DeviceMode)); + + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_GetInterMeasurementPeriodMilliSeconds(Dev, + &(pDeviceParameters->InterMeasurementPeriodMilliSeconds)); + + + if (Status == VL53L0X_ERROR_NONE) + pDeviceParameters->XTalkCompensationEnable = 0; + + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_GetXTalkCompensationRateMegaCps(Dev, + &(pDeviceParameters->XTalkCompensationRateMegaCps)); + + + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_GetOffsetCalibrationDataMicroMeter(Dev, + &(pDeviceParameters->RangeOffsetMicroMeters)); + + + if (Status == VL53L0X_ERROR_NONE) { + for (i = 0; i < VL53L0X_CHECKENABLE_NUMBER_OF_CHECKS; i++) { + /* get first the values, then the enables. + * VL53L0X_GetLimitCheckValue will modify the enable + * flags + */ + if (Status == VL53L0X_ERROR_NONE) { + Status |= VL53L0X_GetLimitCheckValue(Dev, i, + &(pDeviceParameters->LimitChecksValue[i])); + } else { + break; + } + if (Status == VL53L0X_ERROR_NONE) { + Status |= VL53L0X_GetLimitCheckEnable(Dev, i, + &(pDeviceParameters->LimitChecksEnable[i])); + } else { + break; + } + } + } + + if (Status == VL53L0X_ERROR_NONE) { + Status = VL53L0X_GetWrapAroundCheckEnable(Dev, + &(pDeviceParameters->WrapAroundCheckEnable)); + } + + /* Need to be done at the end as it uses VCSELPulsePeriod */ + if (Status == VL53L0X_ERROR_NONE) { + Status = VL53L0X_GetMeasurementTimingBudgetMicroSeconds(Dev, + &(pDeviceParameters->MeasurementTimingBudgetMicroSeconds)); + } + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_SetDeviceMode(VL53L0X_DEV Dev, VL53L0X_DeviceModes DeviceMode) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + + LOG_FUNCTION_START("%d", (int)DeviceMode); + + switch (DeviceMode) { + case VL53L0X_DEVICEMODE_SINGLE_RANGING: + case VL53L0X_DEVICEMODE_CONTINUOUS_RANGING: + case VL53L0X_DEVICEMODE_CONTINUOUS_TIMED_RANGING: + case VL53L0X_DEVICEMODE_GPIO_DRIVE: + case VL53L0X_DEVICEMODE_GPIO_OSC: + /* Supported modes */ + VL53L0X_SETPARAMETERFIELD(Dev, DeviceMode, DeviceMode); + break; + default: + /* Unsupported mode */ + Status = VL53L0X_ERROR_MODE_NOT_SUPPORTED; + } + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_GetDeviceMode(VL53L0X_DEV Dev, + VL53L0X_DeviceModes *pDeviceMode) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + LOG_FUNCTION_START(""); + + VL53L0X_GETPARAMETERFIELD(Dev, DeviceMode, *pDeviceMode); + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_SetRangeFractionEnable(VL53L0X_DEV Dev, uint8_t Enable) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + + LOG_FUNCTION_START("%d", (int)Enable); + + Status = VL53L0X_WrByte(Dev, VL53L0X_REG_SYSTEM_RANGE_CONFIG, Enable); + + if (Status == VL53L0X_ERROR_NONE) + PALDevDataSet(Dev, RangeFractionalEnable, Enable); + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_GetFractionEnable(VL53L0X_DEV Dev, uint8_t *pEnabled) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + LOG_FUNCTION_START(""); + + Status = VL53L0X_RdByte(Dev, VL53L0X_REG_SYSTEM_RANGE_CONFIG, pEnabled); + + if (Status == VL53L0X_ERROR_NONE) + *pEnabled = (*pEnabled & 1); + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_SetHistogramMode(VL53L0X_DEV Dev, + VL53L0X_HistogramModes HistogramMode) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NOT_IMPLEMENTED; + LOG_FUNCTION_START(""); + + /* not implemented on VL53L0X */ + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_GetHistogramMode(VL53L0X_DEV Dev, + VL53L0X_HistogramModes *pHistogramMode) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NOT_IMPLEMENTED; + LOG_FUNCTION_START(""); + + /* not implemented on VL53L0X */ + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_SetMeasurementTimingBudgetMicroSeconds(VL53L0X_DEV Dev, + uint32_t MeasurementTimingBudgetMicroSeconds) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + LOG_FUNCTION_START(""); + + Status = VL53L0X_set_measurement_timing_budget_micro_seconds(Dev, + MeasurementTimingBudgetMicroSeconds); + + LOG_FUNCTION_END(Status); + + return Status; +} + +VL53L0X_Error VL53L0X_GetMeasurementTimingBudgetMicroSeconds(VL53L0X_DEV Dev, + uint32_t *pMeasurementTimingBudgetMicroSeconds) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + LOG_FUNCTION_START(""); + + Status = VL53L0X_get_measurement_timing_budget_micro_seconds(Dev, + pMeasurementTimingBudgetMicroSeconds); + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_SetVcselPulsePeriod(VL53L0X_DEV Dev, + VL53L0X_VcselPeriod VcselPeriodType, uint8_t VCSELPulsePeriodPCLK) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + LOG_FUNCTION_START(""); + + Status = VL53L0X_set_vcsel_pulse_period(Dev, VcselPeriodType, + VCSELPulsePeriodPCLK); + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_GetVcselPulsePeriod(VL53L0X_DEV Dev, + VL53L0X_VcselPeriod VcselPeriodType, uint8_t *pVCSELPulsePeriodPCLK) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + LOG_FUNCTION_START(""); + + Status = VL53L0X_get_vcsel_pulse_period(Dev, VcselPeriodType, + pVCSELPulsePeriodPCLK); + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_SetSequenceStepEnable(VL53L0X_DEV Dev, + VL53L0X_SequenceStepId SequenceStepId, uint8_t SequenceStepEnabled) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + uint8_t SequenceConfig = 0; + uint8_t SequenceConfigNew = 0; + uint32_t MeasurementTimingBudgetMicroSeconds; + LOG_FUNCTION_START(""); + + Status = VL53L0X_RdByte(Dev, VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG, + &SequenceConfig); + + SequenceConfigNew = SequenceConfig; + + if (Status == VL53L0X_ERROR_NONE) { + if (SequenceStepEnabled == 1) { + + /* Enable requested sequence step + */ + switch (SequenceStepId) { + case VL53L0X_SEQUENCESTEP_TCC: + SequenceConfigNew |= 0x10; + break; + case VL53L0X_SEQUENCESTEP_DSS: + SequenceConfigNew |= 0x28; + break; + case VL53L0X_SEQUENCESTEP_MSRC: + SequenceConfigNew |= 0x04; + break; + case VL53L0X_SEQUENCESTEP_PRE_RANGE: + SequenceConfigNew |= 0x40; + break; + case VL53L0X_SEQUENCESTEP_FINAL_RANGE: + SequenceConfigNew |= 0x80; + break; + default: + Status = VL53L0X_ERROR_INVALID_PARAMS; + } + } else { + /* Disable requested sequence step + */ + switch (SequenceStepId) { + case VL53L0X_SEQUENCESTEP_TCC: + SequenceConfigNew &= 0xef; + break; + case VL53L0X_SEQUENCESTEP_DSS: + SequenceConfigNew &= 0xd7; + break; + case VL53L0X_SEQUENCESTEP_MSRC: + SequenceConfigNew &= 0xfb; + break; + case VL53L0X_SEQUENCESTEP_PRE_RANGE: + SequenceConfigNew &= 0xbf; + break; + case VL53L0X_SEQUENCESTEP_FINAL_RANGE: + SequenceConfigNew &= 0x7f; + break; + default: + Status = VL53L0X_ERROR_INVALID_PARAMS; + } + } + } + + if (SequenceConfigNew != SequenceConfig) { + /* Apply New Setting */ + if (Status == VL53L0X_ERROR_NONE) { + Status = VL53L0X_WrByte(Dev, + VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG, SequenceConfigNew); + } + if (Status == VL53L0X_ERROR_NONE) + PALDevDataSet(Dev, SequenceConfig, SequenceConfigNew); + + + /* Recalculate timing budget */ + if (Status == VL53L0X_ERROR_NONE) { + VL53L0X_GETPARAMETERFIELD(Dev, + MeasurementTimingBudgetMicroSeconds, + MeasurementTimingBudgetMicroSeconds); + + VL53L0X_SetMeasurementTimingBudgetMicroSeconds(Dev, + MeasurementTimingBudgetMicroSeconds); + } + } + + LOG_FUNCTION_END(Status); + + return Status; +} + +VL53L0X_Error sequence_step_enabled(VL53L0X_DEV Dev, + VL53L0X_SequenceStepId SequenceStepId, uint8_t SequenceConfig, + uint8_t *pSequenceStepEnabled) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + *pSequenceStepEnabled = 0; + LOG_FUNCTION_START(""); + + switch (SequenceStepId) { + case VL53L0X_SEQUENCESTEP_TCC: + *pSequenceStepEnabled = (SequenceConfig & 0x10) >> 4; + break; + case VL53L0X_SEQUENCESTEP_DSS: + *pSequenceStepEnabled = (SequenceConfig & 0x08) >> 3; + break; + case VL53L0X_SEQUENCESTEP_MSRC: + *pSequenceStepEnabled = (SequenceConfig & 0x04) >> 2; + break; + case VL53L0X_SEQUENCESTEP_PRE_RANGE: + *pSequenceStepEnabled = (SequenceConfig & 0x40) >> 6; + break; + case VL53L0X_SEQUENCESTEP_FINAL_RANGE: + *pSequenceStepEnabled = (SequenceConfig & 0x80) >> 7; + break; + default: + Status = VL53L0X_ERROR_INVALID_PARAMS; + } + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_GetSequenceStepEnable(VL53L0X_DEV Dev, + VL53L0X_SequenceStepId SequenceStepId, uint8_t *pSequenceStepEnabled) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + uint8_t SequenceConfig = 0; + LOG_FUNCTION_START(""); + + Status = VL53L0X_RdByte(Dev, VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG, + &SequenceConfig); + + if (Status == VL53L0X_ERROR_NONE) { + Status = sequence_step_enabled(Dev, SequenceStepId, + SequenceConfig, pSequenceStepEnabled); + } + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_GetSequenceStepEnables(VL53L0X_DEV Dev, + VL53L0X_SchedulerSequenceSteps_t *pSchedulerSequenceSteps) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + uint8_t SequenceConfig = 0; + LOG_FUNCTION_START(""); + + Status = VL53L0X_RdByte(Dev, VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG, + &SequenceConfig); + + if (Status == VL53L0X_ERROR_NONE) { + Status = sequence_step_enabled(Dev, + VL53L0X_SEQUENCESTEP_TCC, SequenceConfig, + &pSchedulerSequenceSteps->TccOn); + } + if (Status == VL53L0X_ERROR_NONE) { + Status = sequence_step_enabled(Dev, + VL53L0X_SEQUENCESTEP_DSS, SequenceConfig, + &pSchedulerSequenceSteps->DssOn); + } + if (Status == VL53L0X_ERROR_NONE) { + Status = sequence_step_enabled(Dev, + VL53L0X_SEQUENCESTEP_MSRC, SequenceConfig, + &pSchedulerSequenceSteps->MsrcOn); + } + if (Status == VL53L0X_ERROR_NONE) { + Status = sequence_step_enabled(Dev, + VL53L0X_SEQUENCESTEP_PRE_RANGE, SequenceConfig, + &pSchedulerSequenceSteps->PreRangeOn); + } + if (Status == VL53L0X_ERROR_NONE) { + Status = sequence_step_enabled(Dev, + VL53L0X_SEQUENCESTEP_FINAL_RANGE, SequenceConfig, + &pSchedulerSequenceSteps->FinalRangeOn); + } + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_GetNumberOfSequenceSteps(VL53L0X_DEV Dev, + uint8_t *pNumberOfSequenceSteps) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + LOG_FUNCTION_START(""); + + *pNumberOfSequenceSteps = VL53L0X_SEQUENCESTEP_NUMBER_OF_CHECKS; + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_GetSequenceStepsInfo(VL53L0X_SequenceStepId SequenceStepId, + char *pSequenceStepsString) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + LOG_FUNCTION_START(""); + + Status = VL53L0X_get_sequence_steps_info( + SequenceStepId, + pSequenceStepsString); + + LOG_FUNCTION_END(Status); + + return Status; +} + +VL53L0X_Error VL53L0X_SetSequenceStepTimeout(VL53L0X_DEV Dev, + VL53L0X_SequenceStepId SequenceStepId, FixPoint1616_t TimeOutMilliSecs) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + VL53L0X_Error Status1 = VL53L0X_ERROR_NONE; + uint32_t TimeoutMicroSeconds = ((TimeOutMilliSecs * 1000) + 0x8000) + >> 16; + uint32_t MeasurementTimingBudgetMicroSeconds; + FixPoint1616_t OldTimeOutMicroSeconds; + + LOG_FUNCTION_START(""); + + /* Read back the current value in case we need to revert back to this. + */ + Status = get_sequence_step_timeout(Dev, SequenceStepId, + &OldTimeOutMicroSeconds); + + if (Status == VL53L0X_ERROR_NONE) { + Status = set_sequence_step_timeout(Dev, SequenceStepId, + TimeoutMicroSeconds); + } + + if (Status == VL53L0X_ERROR_NONE) { + VL53L0X_GETPARAMETERFIELD(Dev, + MeasurementTimingBudgetMicroSeconds, + MeasurementTimingBudgetMicroSeconds); + + /* At this point we don't know if the requested value is valid, + therefore proceed to update the entire timing budget and + if this fails, revert back to the previous value. + */ + Status = VL53L0X_SetMeasurementTimingBudgetMicroSeconds(Dev, + MeasurementTimingBudgetMicroSeconds); + + if (Status != VL53L0X_ERROR_NONE) { + Status1 = set_sequence_step_timeout(Dev, SequenceStepId, + OldTimeOutMicroSeconds); + + if (Status1 == VL53L0X_ERROR_NONE) { + Status1 = + VL53L0X_SetMeasurementTimingBudgetMicroSeconds( + Dev, + MeasurementTimingBudgetMicroSeconds); + } + + Status = Status1; + } + } + + LOG_FUNCTION_END(Status); + + return Status; +} + +VL53L0X_Error VL53L0X_GetSequenceStepTimeout(VL53L0X_DEV Dev, + VL53L0X_SequenceStepId SequenceStepId, FixPoint1616_t *pTimeOutMilliSecs) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + uint32_t TimeoutMicroSeconds; + LOG_FUNCTION_START(""); + + Status = get_sequence_step_timeout(Dev, SequenceStepId, + &TimeoutMicroSeconds); + if (Status == VL53L0X_ERROR_NONE) { + TimeoutMicroSeconds <<= 8; + *pTimeOutMilliSecs = (TimeoutMicroSeconds + 500)/1000; + *pTimeOutMilliSecs <<= 8; + } + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_SetInterMeasurementPeriodMilliSeconds(VL53L0X_DEV Dev, + uint32_t InterMeasurementPeriodMilliSeconds) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + uint16_t osc_calibrate_val; + uint32_t IMPeriodMilliSeconds; + + LOG_FUNCTION_START(""); + + Status = VL53L0X_RdWord(Dev, VL53L0X_REG_OSC_CALIBRATE_VAL, + &osc_calibrate_val); + + if (Status == VL53L0X_ERROR_NONE) { + if (osc_calibrate_val != 0) { + IMPeriodMilliSeconds = + InterMeasurementPeriodMilliSeconds + * osc_calibrate_val; + } else { + IMPeriodMilliSeconds = + InterMeasurementPeriodMilliSeconds; + } + Status = VL53L0X_WrDWord(Dev, + VL53L0X_REG_SYSTEM_INTERMEASUREMENT_PERIOD, + IMPeriodMilliSeconds); + } + + if (Status == VL53L0X_ERROR_NONE) { + VL53L0X_SETPARAMETERFIELD(Dev, + InterMeasurementPeriodMilliSeconds, + InterMeasurementPeriodMilliSeconds); + } + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_GetInterMeasurementPeriodMilliSeconds(VL53L0X_DEV Dev, + uint32_t *pInterMeasurementPeriodMilliSeconds) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + uint16_t osc_calibrate_val; + uint32_t IMPeriodMilliSeconds; + + LOG_FUNCTION_START(""); + + Status = VL53L0X_RdWord(Dev, VL53L0X_REG_OSC_CALIBRATE_VAL, + &osc_calibrate_val); + + if (Status == VL53L0X_ERROR_NONE) { + Status = VL53L0X_RdDWord(Dev, + VL53L0X_REG_SYSTEM_INTERMEASUREMENT_PERIOD, + &IMPeriodMilliSeconds); + } + + if (Status == VL53L0X_ERROR_NONE) { + if (osc_calibrate_val != 0) { + *pInterMeasurementPeriodMilliSeconds = + IMPeriodMilliSeconds / osc_calibrate_val; + } + VL53L0X_SETPARAMETERFIELD(Dev, + InterMeasurementPeriodMilliSeconds, + *pInterMeasurementPeriodMilliSeconds); + } + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_SetXTalkCompensationEnable(VL53L0X_DEV Dev, + uint8_t XTalkCompensationEnable) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + FixPoint1616_t TempFix1616; + uint16_t LinearityCorrectiveGain; + + LOG_FUNCTION_START(""); + + LinearityCorrectiveGain = PALDevDataGet(Dev, LinearityCorrectiveGain); + + if ((XTalkCompensationEnable == 0) + || (LinearityCorrectiveGain != 1000)) { + TempFix1616 = 0; + } else { + VL53L0X_GETPARAMETERFIELD(Dev, XTalkCompensationRateMegaCps, + TempFix1616); + } + + /* the following register has a format 3.13 */ + Status = VL53L0X_WrWord(Dev, + VL53L0X_REG_CROSSTALK_COMPENSATION_PEAK_RATE_MCPS, + VL53L0X_FIXPOINT1616TOFIXPOINT313(TempFix1616)); + + if (Status == VL53L0X_ERROR_NONE) { + if (XTalkCompensationEnable == 0) { + VL53L0X_SETPARAMETERFIELD(Dev, XTalkCompensationEnable, + 0); + } else { + VL53L0X_SETPARAMETERFIELD(Dev, XTalkCompensationEnable, + 1); + } + } + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_GetXTalkCompensationEnable(VL53L0X_DEV Dev, + uint8_t *pXTalkCompensationEnable) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + uint8_t Temp8; + LOG_FUNCTION_START(""); + + VL53L0X_GETPARAMETERFIELD(Dev, XTalkCompensationEnable, Temp8); + *pXTalkCompensationEnable = Temp8; + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_SetXTalkCompensationRateMegaCps(VL53L0X_DEV Dev, + FixPoint1616_t XTalkCompensationRateMegaCps) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + uint8_t Temp8; + uint16_t LinearityCorrectiveGain; + uint16_t data; + LOG_FUNCTION_START(""); + + VL53L0X_GETPARAMETERFIELD(Dev, XTalkCompensationEnable, Temp8); + LinearityCorrectiveGain = PALDevDataGet(Dev, LinearityCorrectiveGain); + + if (Temp8 == 0) { /* disabled write only internal value */ + VL53L0X_SETPARAMETERFIELD(Dev, XTalkCompensationRateMegaCps, + XTalkCompensationRateMegaCps); + } else { + /* the following register has a format 3.13 */ + if (LinearityCorrectiveGain == 1000) { + data = VL53L0X_FIXPOINT1616TOFIXPOINT313( + XTalkCompensationRateMegaCps); + } else { + data = 0; + } + + Status = VL53L0X_WrWord(Dev, + VL53L0X_REG_CROSSTALK_COMPENSATION_PEAK_RATE_MCPS, data); + + if (Status == VL53L0X_ERROR_NONE) { + VL53L0X_SETPARAMETERFIELD(Dev, + XTalkCompensationRateMegaCps, + XTalkCompensationRateMegaCps); + } + } + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_GetXTalkCompensationRateMegaCps(VL53L0X_DEV Dev, + FixPoint1616_t *pXTalkCompensationRateMegaCps) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + uint16_t Value; + FixPoint1616_t TempFix1616; + + LOG_FUNCTION_START(""); + + Status = VL53L0X_RdWord(Dev, + VL53L0X_REG_CROSSTALK_COMPENSATION_PEAK_RATE_MCPS, (uint16_t *)&Value); + if (Status == VL53L0X_ERROR_NONE) { + if (Value == 0) { + /* the Xtalk is disabled return value from memory */ + VL53L0X_GETPARAMETERFIELD(Dev, + XTalkCompensationRateMegaCps, TempFix1616); + *pXTalkCompensationRateMegaCps = TempFix1616; + VL53L0X_SETPARAMETERFIELD(Dev, XTalkCompensationEnable, + 0); + } else { + TempFix1616 = VL53L0X_FIXPOINT313TOFIXPOINT1616(Value); + *pXTalkCompensationRateMegaCps = TempFix1616; + VL53L0X_SETPARAMETERFIELD(Dev, + XTalkCompensationRateMegaCps, TempFix1616); + VL53L0X_SETPARAMETERFIELD(Dev, XTalkCompensationEnable, + 1); + } + } + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_SetRefCalibration(VL53L0X_DEV Dev, uint8_t VhvSettings, + uint8_t PhaseCal) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + LOG_FUNCTION_START(""); + + Status = VL53L0X_set_ref_calibration(Dev, VhvSettings, PhaseCal); + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_GetRefCalibration(VL53L0X_DEV Dev, uint8_t *pVhvSettings, + uint8_t *pPhaseCal) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + LOG_FUNCTION_START(""); + + Status = VL53L0X_get_ref_calibration(Dev, pVhvSettings, pPhaseCal); + + LOG_FUNCTION_END(Status); + return Status; +} + +/* + * CHECK LIMIT FUNCTIONS + */ + +VL53L0X_Error VL53L0X_GetNumberOfLimitCheck(uint16_t *pNumberOfLimitCheck) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + LOG_FUNCTION_START(""); + + *pNumberOfLimitCheck = VL53L0X_CHECKENABLE_NUMBER_OF_CHECKS; + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_GetLimitCheckInfo(VL53L0X_DEV Dev, uint16_t LimitCheckId, + char *pLimitCheckString) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + + LOG_FUNCTION_START(""); + + Status = VL53L0X_get_limit_check_info(Dev, LimitCheckId, + pLimitCheckString); + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_GetLimitCheckStatus(VL53L0X_DEV Dev, uint16_t LimitCheckId, + uint8_t *pLimitCheckStatus) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + uint8_t Temp8; + + LOG_FUNCTION_START(""); + + if (LimitCheckId >= VL53L0X_CHECKENABLE_NUMBER_OF_CHECKS) { + Status = VL53L0X_ERROR_INVALID_PARAMS; + } else { + + VL53L0X_GETARRAYPARAMETERFIELD(Dev, LimitChecksStatus, + LimitCheckId, Temp8); + + *pLimitCheckStatus = Temp8; + + } + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_SetLimitCheckEnable(VL53L0X_DEV Dev, uint16_t LimitCheckId, + uint8_t LimitCheckEnable) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + FixPoint1616_t TempFix1616 = 0; + uint8_t LimitCheckEnableInt = 0; + uint8_t LimitCheckDisable = 0; + uint8_t Temp8; + + LOG_FUNCTION_START(""); + + if (LimitCheckId >= VL53L0X_CHECKENABLE_NUMBER_OF_CHECKS) { + Status = VL53L0X_ERROR_INVALID_PARAMS; + } else { + if (LimitCheckEnable == 0) { + TempFix1616 = 0; + LimitCheckEnableInt = 0; + LimitCheckDisable = 1; + + } else { + VL53L0X_GETARRAYPARAMETERFIELD(Dev, LimitChecksValue, + LimitCheckId, TempFix1616); + LimitCheckDisable = 0; + /* this to be sure to have either 0 or 1 */ + LimitCheckEnableInt = 1; + } + + switch (LimitCheckId) { + + case VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE: + /* internal computation: */ + VL53L0X_SETARRAYPARAMETERFIELD(Dev, LimitChecksEnable, + VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE, + LimitCheckEnableInt); + + break; + + case VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE: + + Status = VL53L0X_WrWord(Dev, + VL53L0X_REG_FINAL_RANGE_CONFIG_MIN_COUNT_RATE_RTN_LIMIT, + VL53L0X_FIXPOINT1616TOFIXPOINT97(TempFix1616)); + + break; + + case VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP: + + /* internal computation: */ + VL53L0X_SETARRAYPARAMETERFIELD(Dev, LimitChecksEnable, + VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP, + LimitCheckEnableInt); + + break; + + case VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD: + + /* internal computation: */ + VL53L0X_SETARRAYPARAMETERFIELD(Dev, LimitChecksEnable, + VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD, + LimitCheckEnableInt); + + break; + + case VL53L0X_CHECKENABLE_SIGNAL_RATE_MSRC: + + Temp8 = (uint8_t)(LimitCheckDisable << 1); + Status = VL53L0X_UpdateByte(Dev, + VL53L0X_REG_MSRC_CONFIG_CONTROL, + 0xFE, Temp8); + + break; + + case VL53L0X_CHECKENABLE_SIGNAL_RATE_PRE_RANGE: + + Temp8 = (uint8_t)(LimitCheckDisable << 4); + Status = VL53L0X_UpdateByte(Dev, + VL53L0X_REG_MSRC_CONFIG_CONTROL, + 0xEF, Temp8); + + break; + + + default: + Status = VL53L0X_ERROR_INVALID_PARAMS; + + } + + } + + if (Status == VL53L0X_ERROR_NONE) { + if (LimitCheckEnable == 0) { + VL53L0X_SETARRAYPARAMETERFIELD(Dev, LimitChecksEnable, + LimitCheckId, 0); + } else { + VL53L0X_SETARRAYPARAMETERFIELD(Dev, LimitChecksEnable, + LimitCheckId, 1); + } + } + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_GetLimitCheckEnable(VL53L0X_DEV Dev, uint16_t LimitCheckId, + uint8_t *pLimitCheckEnable) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + uint8_t Temp8; + + LOG_FUNCTION_START(""); + + if (LimitCheckId >= VL53L0X_CHECKENABLE_NUMBER_OF_CHECKS) { + Status = VL53L0X_ERROR_INVALID_PARAMS; + *pLimitCheckEnable = 0; + } else { + VL53L0X_GETARRAYPARAMETERFIELD(Dev, LimitChecksEnable, + LimitCheckId, Temp8); + *pLimitCheckEnable = Temp8; + } + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_SetLimitCheckValue(VL53L0X_DEV Dev, uint16_t LimitCheckId, + FixPoint1616_t LimitCheckValue) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + uint8_t Temp8; + + LOG_FUNCTION_START(""); + + VL53L0X_GETARRAYPARAMETERFIELD(Dev, LimitChecksEnable, LimitCheckId, + Temp8); + + if (Temp8 == 0) { /* disabled write only internal value */ + VL53L0X_SETARRAYPARAMETERFIELD(Dev, LimitChecksValue, + LimitCheckId, LimitCheckValue); + } else { + + switch (LimitCheckId) { + + case VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE: + /* internal computation: */ + VL53L0X_SETARRAYPARAMETERFIELD(Dev, LimitChecksValue, + VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE, + LimitCheckValue); + break; + + case VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE: + + Status = VL53L0X_WrWord(Dev, + VL53L0X_REG_FINAL_RANGE_CONFIG_MIN_COUNT_RATE_RTN_LIMIT, + VL53L0X_FIXPOINT1616TOFIXPOINT97( + LimitCheckValue)); + + break; + + case VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP: + + /* internal computation: */ + VL53L0X_SETARRAYPARAMETERFIELD(Dev, LimitChecksValue, + VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP, + LimitCheckValue); + + break; + + case VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD: + + /* internal computation: */ + VL53L0X_SETARRAYPARAMETERFIELD(Dev, LimitChecksValue, + VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD, + LimitCheckValue); + + break; + + case VL53L0X_CHECKENABLE_SIGNAL_RATE_MSRC: + case VL53L0X_CHECKENABLE_SIGNAL_RATE_PRE_RANGE: + + Status = VL53L0X_WrWord(Dev, + VL53L0X_REG_PRE_RANGE_MIN_COUNT_RATE_RTN_LIMIT, + VL53L0X_FIXPOINT1616TOFIXPOINT97( + LimitCheckValue)); + + break; + + default: + Status = VL53L0X_ERROR_INVALID_PARAMS; + + } + + if (Status == VL53L0X_ERROR_NONE) { + VL53L0X_SETARRAYPARAMETERFIELD(Dev, LimitChecksValue, + LimitCheckId, LimitCheckValue); + } + } + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_GetLimitCheckValue(VL53L0X_DEV Dev, uint16_t LimitCheckId, + FixPoint1616_t *pLimitCheckValue) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + uint8_t EnableZeroValue = 0; + uint16_t Temp16; + FixPoint1616_t TempFix1616; + + LOG_FUNCTION_START(""); + + switch (LimitCheckId) { + + case VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE: + /* internal computation: */ + VL53L0X_GETARRAYPARAMETERFIELD(Dev, LimitChecksValue, + VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE, TempFix1616); + EnableZeroValue = 0; + break; + + case VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE: + Status = VL53L0X_RdWord(Dev, + VL53L0X_REG_FINAL_RANGE_CONFIG_MIN_COUNT_RATE_RTN_LIMIT, + &Temp16); + if (Status == VL53L0X_ERROR_NONE) + TempFix1616 = VL53L0X_FIXPOINT97TOFIXPOINT1616(Temp16); + + + EnableZeroValue = 1; + break; + + case VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP: + /* internal computation: */ + VL53L0X_GETARRAYPARAMETERFIELD(Dev, LimitChecksValue, + VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP, TempFix1616); + EnableZeroValue = 0; + break; + + case VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD: + /* internal computation: */ + VL53L0X_GETARRAYPARAMETERFIELD(Dev, LimitChecksValue, + VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD, TempFix1616); + EnableZeroValue = 0; + break; + + case VL53L0X_CHECKENABLE_SIGNAL_RATE_MSRC: + case VL53L0X_CHECKENABLE_SIGNAL_RATE_PRE_RANGE: + Status = VL53L0X_RdWord(Dev, + VL53L0X_REG_PRE_RANGE_MIN_COUNT_RATE_RTN_LIMIT, + &Temp16); + if (Status == VL53L0X_ERROR_NONE) + TempFix1616 = VL53L0X_FIXPOINT97TOFIXPOINT1616(Temp16); + + + EnableZeroValue = 0; + break; + + default: + Status = VL53L0X_ERROR_INVALID_PARAMS; + + } + + if (Status == VL53L0X_ERROR_NONE) { + + if (EnableZeroValue == 1) { + + if (TempFix1616 == 0) { + /* disabled: return value from memory */ + VL53L0X_GETARRAYPARAMETERFIELD(Dev, + LimitChecksValue, LimitCheckId, + TempFix1616); + *pLimitCheckValue = TempFix1616; + VL53L0X_SETARRAYPARAMETERFIELD(Dev, + LimitChecksEnable, LimitCheckId, 0); + } else { + *pLimitCheckValue = TempFix1616; + VL53L0X_SETARRAYPARAMETERFIELD(Dev, + LimitChecksValue, LimitCheckId, + TempFix1616); + VL53L0X_SETARRAYPARAMETERFIELD(Dev, + LimitChecksEnable, LimitCheckId, 1); + } + } else { + *pLimitCheckValue = TempFix1616; + } + } + + LOG_FUNCTION_END(Status); + return Status; + +} + +VL53L0X_Error VL53L0X_GetLimitCheckCurrent(VL53L0X_DEV Dev, uint16_t LimitCheckId, + FixPoint1616_t *pLimitCheckCurrent) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + VL53L0X_RangingMeasurementData_t LastRangeDataBuffer; + + LOG_FUNCTION_START(""); + + if (LimitCheckId >= VL53L0X_CHECKENABLE_NUMBER_OF_CHECKS) { + Status = VL53L0X_ERROR_INVALID_PARAMS; + } else { + switch (LimitCheckId) { + case VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE: + /* Need to run a ranging to have the latest values */ + *pLimitCheckCurrent = PALDevDataGet(Dev, SigmaEstimate); + + break; + + case VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE: + /* Need to run a ranging to have the latest values */ + LastRangeDataBuffer = PALDevDataGet(Dev, + LastRangeMeasure); + *pLimitCheckCurrent = + LastRangeDataBuffer.SignalRateRtnMegaCps; + + break; + + case VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP: + /* Need to run a ranging to have the latest values */ + *pLimitCheckCurrent = PALDevDataGet(Dev, + LastSignalRefMcps); + + break; + + case VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD: + /* Need to run a ranging to have the latest values */ + LastRangeDataBuffer = PALDevDataGet(Dev, + LastRangeMeasure); + *pLimitCheckCurrent = + LastRangeDataBuffer.SignalRateRtnMegaCps; + + break; + + case VL53L0X_CHECKENABLE_SIGNAL_RATE_MSRC: + /* Need to run a ranging to have the latest values */ + LastRangeDataBuffer = PALDevDataGet(Dev, + LastRangeMeasure); + *pLimitCheckCurrent = + LastRangeDataBuffer.SignalRateRtnMegaCps; + + break; + + case VL53L0X_CHECKENABLE_SIGNAL_RATE_PRE_RANGE: + /* Need to run a ranging to have the latest values */ + LastRangeDataBuffer = PALDevDataGet(Dev, + LastRangeMeasure); + *pLimitCheckCurrent = + LastRangeDataBuffer.SignalRateRtnMegaCps; + + break; + + default: + Status = VL53L0X_ERROR_INVALID_PARAMS; + } + } + + LOG_FUNCTION_END(Status); + return Status; + +} + +/* + * WRAPAROUND Check + */ +VL53L0X_Error VL53L0X_SetWrapAroundCheckEnable(VL53L0X_DEV Dev, + uint8_t WrapAroundCheckEnable) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + uint8_t Byte; + uint8_t WrapAroundCheckEnableInt; + + LOG_FUNCTION_START(""); + + Status = VL53L0X_RdByte(Dev, VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG, &Byte); + if (WrapAroundCheckEnable == 0) { + /* Disable wraparound */ + Byte = Byte & 0x7F; + WrapAroundCheckEnableInt = 0; + } else { + /*Enable wraparound */ + Byte = Byte | 0x80; + WrapAroundCheckEnableInt = 1; + } + + Status = VL53L0X_WrByte(Dev, VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG, Byte); + + if (Status == VL53L0X_ERROR_NONE) { + PALDevDataSet(Dev, SequenceConfig, Byte); + VL53L0X_SETPARAMETERFIELD(Dev, WrapAroundCheckEnable, + WrapAroundCheckEnableInt); + } + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_GetWrapAroundCheckEnable(VL53L0X_DEV Dev, + uint8_t *pWrapAroundCheckEnable) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + uint8_t data; + + LOG_FUNCTION_START(""); + + Status = VL53L0X_RdByte(Dev, VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG, &data); + if (Status == VL53L0X_ERROR_NONE) { + PALDevDataSet(Dev, SequenceConfig, data); + if (data & (0x01 << 7)) + *pWrapAroundCheckEnable = 0x01; + else + *pWrapAroundCheckEnable = 0x00; + } + if (Status == VL53L0X_ERROR_NONE) { + VL53L0X_SETPARAMETERFIELD(Dev, WrapAroundCheckEnable, + *pWrapAroundCheckEnable); + } + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_SetDmaxCalParameters(VL53L0X_DEV Dev, + uint16_t RangeMilliMeter, FixPoint1616_t SignalRateRtnMegaCps) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + FixPoint1616_t SignalRateRtnMegaCpsTemp = 0; + + LOG_FUNCTION_START(""); + + /* Check if one of input parameter is zero, in that case the + * value are get from NVM */ + if ((RangeMilliMeter == 0) || (SignalRateRtnMegaCps == 0)) { + /* NVM parameters */ + /* Run VL53L0X_get_info_from_device wit option 4 to get + * signal rate at 400 mm if the value have been already + * get this function will return with no access to device */ + VL53L0X_get_info_from_device(Dev, 4); + + SignalRateRtnMegaCpsTemp = VL53L0X_GETDEVICESPECIFICPARAMETER( + Dev, SignalRateMeasFixed400mm); + + PALDevDataSet(Dev, DmaxCalRangeMilliMeter, 400); + PALDevDataSet(Dev, DmaxCalSignalRateRtnMegaCps, + SignalRateRtnMegaCpsTemp); + } else { + /* User parameters */ + PALDevDataSet(Dev, DmaxCalRangeMilliMeter, RangeMilliMeter); + PALDevDataSet(Dev, DmaxCalSignalRateRtnMegaCps, + SignalRateRtnMegaCps); + } + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_GetDmaxCalParameters(VL53L0X_DEV Dev, + uint16_t *pRangeMilliMeter, FixPoint1616_t *pSignalRateRtnMegaCps) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + + LOG_FUNCTION_START(""); + + *pRangeMilliMeter = PALDevDataGet(Dev, DmaxCalRangeMilliMeter); + *pSignalRateRtnMegaCps = PALDevDataGet(Dev, + DmaxCalSignalRateRtnMegaCps); + + LOG_FUNCTION_END(Status); + return Status; +} + +/* End Group PAL Parameters Functions */ + +/* Group PAL Measurement Functions */ +VL53L0X_Error VL53L0X_PerformSingleMeasurement(VL53L0X_DEV Dev) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + VL53L0X_DeviceModes DeviceMode; + + LOG_FUNCTION_START(""); + + /* Get Current DeviceMode */ + Status = VL53L0X_GetDeviceMode(Dev, &DeviceMode); + + /* Start immediately to run a single ranging measurement in case of + * single ranging or single histogram */ + if (Status == VL53L0X_ERROR_NONE + && DeviceMode == VL53L0X_DEVICEMODE_SINGLE_RANGING) + Status = VL53L0X_StartMeasurement(Dev); + + + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_measurement_poll_for_completion(Dev); + + + /* Change PAL State in case of single ranging or single histogram */ + if (Status == VL53L0X_ERROR_NONE + && DeviceMode == VL53L0X_DEVICEMODE_SINGLE_RANGING) + PALDevDataSet(Dev, PalState, VL53L0X_STATE_IDLE); + + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_PerformSingleHistogramMeasurement(VL53L0X_DEV Dev, + VL53L0X_HistogramMeasurementData_t *pHistogramMeasurementData) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NOT_IMPLEMENTED; + LOG_FUNCTION_START(""); + + /* not implemented on VL53L0X */ + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_PerformRefCalibration(VL53L0X_DEV Dev, uint8_t *pVhvSettings, + uint8_t *pPhaseCal) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + LOG_FUNCTION_START(""); + + Status = VL53L0X_perform_ref_calibration(Dev, pVhvSettings, + pPhaseCal, 1); + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_PerformXTalkMeasurement(VL53L0X_DEV Dev, + uint32_t TimeoutMs, FixPoint1616_t *pXtalkPerSpad, + uint8_t *pAmbientTooHigh) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NOT_IMPLEMENTED; + LOG_FUNCTION_START(""); + + /* not implemented on VL53L0X */ + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_PerformXTalkCalibration(VL53L0X_DEV Dev, + FixPoint1616_t XTalkCalDistance, + FixPoint1616_t *pXTalkCompensationRateMegaCps) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + LOG_FUNCTION_START(""); + + Status = VL53L0X_perform_xtalk_calibration(Dev, XTalkCalDistance, + pXTalkCompensationRateMegaCps); + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_PerformOffsetCalibration(VL53L0X_DEV Dev, + FixPoint1616_t CalDistanceMilliMeter, int32_t *pOffsetMicroMeter) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + LOG_FUNCTION_START(""); + + Status = VL53L0X_perform_offset_calibration(Dev, CalDistanceMilliMeter, + pOffsetMicroMeter); + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_CheckAndLoadInterruptSettings(VL53L0X_DEV Dev, + uint8_t StartNotStopFlag) +{ + uint8_t InterruptConfig; + FixPoint1616_t ThresholdLow; + FixPoint1616_t ThresholdHigh; + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + + InterruptConfig = VL53L0X_GETDEVICESPECIFICPARAMETER(Dev, + Pin0GpioFunctionality); + + if ((InterruptConfig == + VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_LOW) || + (InterruptConfig == + VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_HIGH) || + (InterruptConfig == + VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_OUT)) { + + Status = VL53L0X_GetInterruptThresholds(Dev, + VL53L0X_DEVICEMODE_CONTINUOUS_RANGING, + &ThresholdLow, &ThresholdHigh); + + if (((ThresholdLow > 255*65536) || + (ThresholdHigh > 255*65536)) && + (Status == VL53L0X_ERROR_NONE)) { + + if (StartNotStopFlag != 0) { + Status = VL53L0X_load_tuning_settings(Dev, + InterruptThresholdSettings); + } else { + Status |= VL53L0X_WrByte(Dev, 0xFF, 0x04); + Status |= VL53L0X_WrByte(Dev, 0x70, 0x00); + Status |= VL53L0X_WrByte(Dev, 0xFF, 0x00); + Status |= VL53L0X_WrByte(Dev, 0x80, 0x00); + } + + } + + + } + + return Status; + +} + + +VL53L0X_Error VL53L0X_StartMeasurement(VL53L0X_DEV Dev) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + VL53L0X_DeviceModes DeviceMode; + uint8_t Byte; + uint8_t StartStopByte = VL53L0X_REG_SYSRANGE_MODE_START_STOP; + uint32_t LoopNb; + LOG_FUNCTION_START(""); + + /* Get Current DeviceMode */ + VL53L0X_GetDeviceMode(Dev, &DeviceMode); + + Status = VL53L0X_WrByte(Dev, 0x80, 0x01); + Status = VL53L0X_WrByte(Dev, 0xFF, 0x01); + Status = VL53L0X_WrByte(Dev, 0x00, 0x00); + Status = VL53L0X_WrByte(Dev, 0x91, PALDevDataGet(Dev, StopVariable)); + Status = VL53L0X_WrByte(Dev, 0x00, 0x01); + Status = VL53L0X_WrByte(Dev, 0xFF, 0x00); + Status = VL53L0X_WrByte(Dev, 0x80, 0x00); + + switch (DeviceMode) { + case VL53L0X_DEVICEMODE_SINGLE_RANGING: + Status = VL53L0X_WrByte(Dev, VL53L0X_REG_SYSRANGE_START, 0x01); + + Byte = StartStopByte; + if (Status == VL53L0X_ERROR_NONE) { + /* Wait until start bit has been cleared */ + LoopNb = 0; + do { + if (LoopNb > 0) + Status = VL53L0X_RdByte(Dev, + VL53L0X_REG_SYSRANGE_START, &Byte); + LoopNb = LoopNb + 1; + } while (((Byte & StartStopByte) == StartStopByte) + && (Status == VL53L0X_ERROR_NONE) + && (LoopNb < VL53L0X_DEFAULT_MAX_LOOP)); + + if (LoopNb >= VL53L0X_DEFAULT_MAX_LOOP) + Status = VL53L0X_ERROR_TIME_OUT; + + } + + break; + case VL53L0X_DEVICEMODE_CONTINUOUS_RANGING: + /* Back-to-back mode */ + + /* Check if need to apply interrupt settings */ + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_CheckAndLoadInterruptSettings(Dev, 1); + + Status = VL53L0X_WrByte(Dev, + VL53L0X_REG_SYSRANGE_START, + VL53L0X_REG_SYSRANGE_MODE_BACKTOBACK); + if (Status == VL53L0X_ERROR_NONE) { + /* Set PAL State to Running */ + PALDevDataSet(Dev, PalState, VL53L0X_STATE_RUNNING); + } + break; + case VL53L0X_DEVICEMODE_CONTINUOUS_TIMED_RANGING: + /* Continuous mode */ + /* Check if need to apply interrupt settings */ + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_CheckAndLoadInterruptSettings(Dev, 1); + + Status = VL53L0X_WrByte(Dev, + VL53L0X_REG_SYSRANGE_START, + VL53L0X_REG_SYSRANGE_MODE_TIMED); + + if (Status == VL53L0X_ERROR_NONE) { + /* Set PAL State to Running */ + PALDevDataSet(Dev, PalState, VL53L0X_STATE_RUNNING); + } + break; + default: + /* Selected mode not supported */ + Status = VL53L0X_ERROR_MODE_NOT_SUPPORTED; + } + + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_StopMeasurement(VL53L0X_DEV Dev) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + LOG_FUNCTION_START(""); + + Status = VL53L0X_WrByte(Dev, VL53L0X_REG_SYSRANGE_START, + VL53L0X_REG_SYSRANGE_MODE_SINGLESHOT); + + Status = VL53L0X_WrByte(Dev, 0xFF, 0x01); + Status = VL53L0X_WrByte(Dev, 0x00, 0x00); + Status = VL53L0X_WrByte(Dev, 0x91, 0x00); + Status = VL53L0X_WrByte(Dev, 0x00, 0x01); + Status = VL53L0X_WrByte(Dev, 0xFF, 0x00); + + if (Status == VL53L0X_ERROR_NONE) { + /* Set PAL State to Idle */ + PALDevDataSet(Dev, PalState, VL53L0X_STATE_IDLE); + } + + /* Check if need to apply interrupt settings */ + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_CheckAndLoadInterruptSettings(Dev, 0); + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_GetMeasurementDataReady(VL53L0X_DEV Dev, + uint8_t *pMeasurementDataReady) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + uint8_t SysRangeStatusRegister; + uint8_t InterruptConfig; + uint32_t InterruptMask; + LOG_FUNCTION_START(""); + + InterruptConfig = VL53L0X_GETDEVICESPECIFICPARAMETER(Dev, + Pin0GpioFunctionality); + + if (InterruptConfig == + VL53L0X_REG_SYSTEM_INTERRUPT_GPIO_NEW_SAMPLE_READY) { + Status = VL53L0X_GetInterruptMaskStatus(Dev, &InterruptMask); + if (InterruptMask == + VL53L0X_REG_SYSTEM_INTERRUPT_GPIO_NEW_SAMPLE_READY) + *pMeasurementDataReady = 1; + else + *pMeasurementDataReady = 0; + } else { + Status = VL53L0X_RdByte(Dev, VL53L0X_REG_RESULT_RANGE_STATUS, + &SysRangeStatusRegister); + if (Status == VL53L0X_ERROR_NONE) { + if (SysRangeStatusRegister & 0x01) + *pMeasurementDataReady = 1; + else + *pMeasurementDataReady = 0; + } + } + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_WaitDeviceReadyForNewMeasurement(VL53L0X_DEV Dev, + uint32_t MaxLoop) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NOT_IMPLEMENTED; + LOG_FUNCTION_START(""); + + /* not implemented for VL53L0X */ + + LOG_FUNCTION_END(Status); + return Status; +} + + +VL53L0X_Error VL53L0X_GetRangingMeasurementData(VL53L0X_DEV Dev, + VL53L0X_RangingMeasurementData_t *pRangingMeasurementData) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + uint8_t DeviceRangeStatus; + uint8_t RangeFractionalEnable; + uint8_t PalRangeStatus; + uint8_t XTalkCompensationEnable; + uint16_t AmbientRate; + FixPoint1616_t SignalRate; + uint16_t XTalkCompensationRateMegaCps; + uint16_t EffectiveSpadRtnCount; + uint16_t tmpuint16; + uint16_t XtalkRangeMilliMeter; + uint16_t LinearityCorrectiveGain; + uint8_t localBuffer[12]; + VL53L0X_RangingMeasurementData_t LastRangeDataBuffer; + + LOG_FUNCTION_START(""); + + /* + * use multi read even if some registers are not useful, result will + * be more efficient + * start reading at 0x14 dec20 + * end reading at 0x21 dec33 total 14 bytes to read + */ + Status = VL53L0X_ReadMulti(Dev, 0x14, localBuffer, 12); + + if (Status == VL53L0X_ERROR_NONE) { + + pRangingMeasurementData->ZoneId = 0; /* Only one zone */ + pRangingMeasurementData->TimeStamp = 0; /* Not Implemented */ + + tmpuint16 = VL53L0X_MAKEUINT16(localBuffer[11], localBuffer[10]); + /* cut1.1 if SYSTEM__RANGE_CONFIG if 1 range is 2bits fractional + *(format 11.2) else no fractional + */ + + pRangingMeasurementData->MeasurementTimeUsec = 0; + + SignalRate = VL53L0X_FIXPOINT97TOFIXPOINT1616( + VL53L0X_MAKEUINT16(localBuffer[7], localBuffer[6])); + /* peak_signal_count_rate_rtn_mcps */ + pRangingMeasurementData->SignalRateRtnMegaCps = SignalRate; + + AmbientRate = VL53L0X_MAKEUINT16(localBuffer[9], localBuffer[8]); + pRangingMeasurementData->AmbientRateRtnMegaCps = + VL53L0X_FIXPOINT97TOFIXPOINT1616(AmbientRate); + + EffectiveSpadRtnCount = VL53L0X_MAKEUINT16(localBuffer[3], + localBuffer[2]); + /* EffectiveSpadRtnCount is 8.8 format */ + pRangingMeasurementData->EffectiveSpadRtnCount = + EffectiveSpadRtnCount; + + DeviceRangeStatus = localBuffer[0]; + + /* Get Linearity Corrective Gain */ + LinearityCorrectiveGain = PALDevDataGet(Dev, + LinearityCorrectiveGain); + + /* Get ranging configuration */ + RangeFractionalEnable = PALDevDataGet(Dev, + RangeFractionalEnable); + + if (LinearityCorrectiveGain != 1000) { + + tmpuint16 = (uint16_t)((LinearityCorrectiveGain + * tmpuint16 + 500) / 1000); + + /* Implement Xtalk */ + VL53L0X_GETPARAMETERFIELD(Dev, + XTalkCompensationRateMegaCps, + XTalkCompensationRateMegaCps); + VL53L0X_GETPARAMETERFIELD(Dev, XTalkCompensationEnable, + XTalkCompensationEnable); + + if (XTalkCompensationEnable) { + + if ((SignalRate + - ((XTalkCompensationRateMegaCps + * EffectiveSpadRtnCount) >> 8)) + <= 0) { + if (RangeFractionalEnable) + XtalkRangeMilliMeter = 8888; + else + XtalkRangeMilliMeter = 8888 + << 2; + } else { + XtalkRangeMilliMeter = + (tmpuint16 * SignalRate) + / (SignalRate + - ((XTalkCompensationRateMegaCps + * EffectiveSpadRtnCount) + >> 8)); + } + + tmpuint16 = XtalkRangeMilliMeter; + } + + } + + if (RangeFractionalEnable) { + pRangingMeasurementData->RangeMilliMeter = + (uint16_t)((tmpuint16) >> 2); + pRangingMeasurementData->RangeFractionalPart = + (uint8_t)((tmpuint16 & 0x03) << 6); + } else { + pRangingMeasurementData->RangeMilliMeter = tmpuint16; + pRangingMeasurementData->RangeFractionalPart = 0; + } + + /* + * For a standard definition of RangeStatus, this should + * return 0 in case of good result after a ranging + * The range status depends on the device so call a device + * specific function to obtain the right Status. + */ + Status |= VL53L0X_get_pal_range_status(Dev, DeviceRangeStatus, + SignalRate, EffectiveSpadRtnCount, + pRangingMeasurementData, &PalRangeStatus); + + if (Status == VL53L0X_ERROR_NONE) + pRangingMeasurementData->RangeStatus = PalRangeStatus; + + } + + if (Status == VL53L0X_ERROR_NONE) { + /* Copy last read data into Dev buffer */ + LastRangeDataBuffer = PALDevDataGet(Dev, LastRangeMeasure); + + LastRangeDataBuffer.RangeMilliMeter = + pRangingMeasurementData->RangeMilliMeter; + LastRangeDataBuffer.RangeFractionalPart = + pRangingMeasurementData->RangeFractionalPart; + LastRangeDataBuffer.RangeDMaxMilliMeter = + pRangingMeasurementData->RangeDMaxMilliMeter; + LastRangeDataBuffer.MeasurementTimeUsec = + pRangingMeasurementData->MeasurementTimeUsec; + LastRangeDataBuffer.SignalRateRtnMegaCps = + pRangingMeasurementData->SignalRateRtnMegaCps; + LastRangeDataBuffer.AmbientRateRtnMegaCps = + pRangingMeasurementData->AmbientRateRtnMegaCps; + LastRangeDataBuffer.EffectiveSpadRtnCount = + pRangingMeasurementData->EffectiveSpadRtnCount; + LastRangeDataBuffer.RangeStatus = + pRangingMeasurementData->RangeStatus; + + PALDevDataSet(Dev, LastRangeMeasure, LastRangeDataBuffer); + } + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_GetMeasurementRefSignal(VL53L0X_DEV Dev, + FixPoint1616_t *pMeasurementRefSignal) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + uint8_t SignalRefClipLimitCheckEnable = 0; + LOG_FUNCTION_START(""); + + Status = VL53L0X_GetLimitCheckEnable(Dev, + VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP, + &SignalRefClipLimitCheckEnable); + if (SignalRefClipLimitCheckEnable != 0) { + *pMeasurementRefSignal = PALDevDataGet(Dev, LastSignalRefMcps); + } else { + Status = VL53L0X_ERROR_INVALID_COMMAND; + } + LOG_FUNCTION_END(Status); + + return Status; +} + +VL53L0X_Error VL53L0X_GetHistogramMeasurementData(VL53L0X_DEV Dev, + VL53L0X_HistogramMeasurementData_t *pHistogramMeasurementData) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NOT_IMPLEMENTED; + LOG_FUNCTION_START(""); + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_PerformSingleRangingMeasurement(VL53L0X_DEV Dev, + VL53L0X_RangingMeasurementData_t *pRangingMeasurementData) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + + LOG_FUNCTION_START(""); + + /* This function will do a complete single ranging + * Here we fix the mode! */ + Status = VL53L0X_SetDeviceMode(Dev, VL53L0X_DEVICEMODE_SINGLE_RANGING); + + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_PerformSingleMeasurement(Dev); + + + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_GetRangingMeasurementData(Dev, + pRangingMeasurementData); + + + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_ClearInterruptMask(Dev, 0); + + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_SetNumberOfROIZones(VL53L0X_DEV Dev, + uint8_t NumberOfROIZones) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + + LOG_FUNCTION_START(""); + + if (NumberOfROIZones != 1) + Status = VL53L0X_ERROR_INVALID_PARAMS; + + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_GetNumberOfROIZones(VL53L0X_DEV Dev, + uint8_t *pNumberOfROIZones) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + + LOG_FUNCTION_START(""); + + *pNumberOfROIZones = 1; + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_GetMaxNumberOfROIZones(VL53L0X_DEV Dev, + uint8_t *pMaxNumberOfROIZones) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + + LOG_FUNCTION_START(""); + + *pMaxNumberOfROIZones = 1; + + LOG_FUNCTION_END(Status); + return Status; +} + +/* End Group PAL Measurement Functions */ + +VL53L0X_Error VL53L0X_SetGpioConfig(VL53L0X_DEV Dev, uint8_t Pin, + VL53L0X_DeviceModes DeviceMode, VL53L0X_GpioFunctionality Functionality, + VL53L0X_InterruptPolarity Polarity) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + uint8_t data; + + LOG_FUNCTION_START(""); + + if (Pin != 0) { + Status = VL53L0X_ERROR_GPIO_NOT_EXISTING; + } else if (DeviceMode == VL53L0X_DEVICEMODE_GPIO_DRIVE) { + if (Polarity == VL53L0X_INTERRUPTPOLARITY_LOW) + data = 0x10; + else + data = 1; + + Status = VL53L0X_WrByte(Dev, + VL53L0X_REG_GPIO_HV_MUX_ACTIVE_HIGH, data); + + } else if (DeviceMode == VL53L0X_DEVICEMODE_GPIO_OSC) { + + Status |= VL53L0X_WrByte(Dev, 0xff, 0x01); + Status |= VL53L0X_WrByte(Dev, 0x00, 0x00); + + Status |= VL53L0X_WrByte(Dev, 0xff, 0x00); + Status |= VL53L0X_WrByte(Dev, 0x80, 0x01); + Status |= VL53L0X_WrByte(Dev, 0x85, 0x02); + + Status |= VL53L0X_WrByte(Dev, 0xff, 0x04); + Status |= VL53L0X_WrByte(Dev, 0xcd, 0x00); + Status |= VL53L0X_WrByte(Dev, 0xcc, 0x11); + + Status |= VL53L0X_WrByte(Dev, 0xff, 0x07); + Status |= VL53L0X_WrByte(Dev, 0xbe, 0x00); + + Status |= VL53L0X_WrByte(Dev, 0xff, 0x06); + Status |= VL53L0X_WrByte(Dev, 0xcc, 0x09); + + Status |= VL53L0X_WrByte(Dev, 0xff, 0x00); + Status |= VL53L0X_WrByte(Dev, 0xff, 0x01); + Status |= VL53L0X_WrByte(Dev, 0x00, 0x00); + + } else { + + if (Status == VL53L0X_ERROR_NONE) { + switch (Functionality) { + case VL53L0X_GPIOFUNCTIONALITY_OFF: + data = 0x00; + break; + case VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_LOW: + data = 0x01; + break; + case VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_HIGH: + data = 0x02; + break; + case VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_OUT: + data = 0x03; + break; + case VL53L0X_GPIOFUNCTIONALITY_NEW_MEASURE_READY: + data = 0x04; + break; + default: + Status = + VL53L0X_ERROR_GPIO_FUNCTIONALITY_NOT_SUPPORTED; + } + } + + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_WrByte(Dev, + VL53L0X_REG_SYSTEM_INTERRUPT_CONFIG_GPIO, data); + + if (Status == VL53L0X_ERROR_NONE) { + if (Polarity == VL53L0X_INTERRUPTPOLARITY_LOW) + data = 0; + else + data = (uint8_t)(1 << 4); + + Status = VL53L0X_UpdateByte(Dev, + VL53L0X_REG_GPIO_HV_MUX_ACTIVE_HIGH, 0xEF, data); + } + + if (Status == VL53L0X_ERROR_NONE) + VL53L0X_SETDEVICESPECIFICPARAMETER(Dev, + Pin0GpioFunctionality, Functionality); + + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_ClearInterruptMask(Dev, 0); + + } + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_GetGpioConfig(VL53L0X_DEV Dev, uint8_t Pin, + VL53L0X_DeviceModes *pDeviceMode, + VL53L0X_GpioFunctionality *pFunctionality, + VL53L0X_InterruptPolarity *pPolarity) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + VL53L0X_GpioFunctionality GpioFunctionality; + uint8_t data; + + LOG_FUNCTION_START(""); + + /* pDeviceMode not managed by Ewok it return the current mode */ + + Status = VL53L0X_GetDeviceMode(Dev, pDeviceMode); + + if (Status == VL53L0X_ERROR_NONE) { + if (Pin != 0) { + Status = VL53L0X_ERROR_GPIO_NOT_EXISTING; + } else { + Status = VL53L0X_RdByte(Dev, + VL53L0X_REG_SYSTEM_INTERRUPT_CONFIG_GPIO, &data); + } + } + + if (Status == VL53L0X_ERROR_NONE) { + switch (data & 0x07) { + case 0x00: + GpioFunctionality = VL53L0X_GPIOFUNCTIONALITY_OFF; + break; + case 0x01: + GpioFunctionality = + VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_LOW; + break; + case 0x02: + GpioFunctionality = + VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_HIGH; + break; + case 0x03: + GpioFunctionality = + VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_OUT; + break; + case 0x04: + GpioFunctionality = + VL53L0X_GPIOFUNCTIONALITY_NEW_MEASURE_READY; + break; + default: + Status = VL53L0X_ERROR_GPIO_FUNCTIONALITY_NOT_SUPPORTED; + } + } + + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_RdByte(Dev, VL53L0X_REG_GPIO_HV_MUX_ACTIVE_HIGH, + &data); + + if (Status == VL53L0X_ERROR_NONE) { + if ((data & (uint8_t)(1 << 4)) == 0) + *pPolarity = VL53L0X_INTERRUPTPOLARITY_LOW; + else + *pPolarity = VL53L0X_INTERRUPTPOLARITY_HIGH; + } + + if (Status == VL53L0X_ERROR_NONE) { + *pFunctionality = GpioFunctionality; + VL53L0X_SETDEVICESPECIFICPARAMETER(Dev, Pin0GpioFunctionality, + GpioFunctionality); + } + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_SetInterruptThresholds(VL53L0X_DEV Dev, + VL53L0X_DeviceModes DeviceMode, FixPoint1616_t ThresholdLow, + FixPoint1616_t ThresholdHigh) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + uint16_t Threshold16; + LOG_FUNCTION_START(""); + + /* no dependency on DeviceMode for Ewok */ + /* Need to divide by 2 because the FW will apply a x2 */ + Threshold16 = (uint16_t)((ThresholdLow >> 17) & 0x00fff); + Status = VL53L0X_WrWord(Dev, VL53L0X_REG_SYSTEM_THRESH_LOW, Threshold16); + + if (Status == VL53L0X_ERROR_NONE) { + /* Need to divide by 2 because the FW will apply a x2 */ + Threshold16 = (uint16_t)((ThresholdHigh >> 17) & 0x00fff); + Status = VL53L0X_WrWord(Dev, VL53L0X_REG_SYSTEM_THRESH_HIGH, + Threshold16); + } + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_GetInterruptThresholds(VL53L0X_DEV Dev, + VL53L0X_DeviceModes DeviceMode, FixPoint1616_t *pThresholdLow, + FixPoint1616_t *pThresholdHigh) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + uint16_t Threshold16; + LOG_FUNCTION_START(""); + + /* no dependency on DeviceMode for Ewok */ + + Status = VL53L0X_RdWord(Dev, VL53L0X_REG_SYSTEM_THRESH_LOW, &Threshold16); + /* Need to multiply by 2 because the FW will apply a x2 */ + *pThresholdLow = (FixPoint1616_t)((0x00fff & Threshold16) << 17); + + if (Status == VL53L0X_ERROR_NONE) { + Status = VL53L0X_RdWord(Dev, VL53L0X_REG_SYSTEM_THRESH_HIGH, + &Threshold16); + /* Need to multiply by 2 because the FW will apply a x2 */ + *pThresholdHigh = + (FixPoint1616_t)((0x00fff & Threshold16) << 17); + } + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_GetStopCompletedStatus(VL53L0X_DEV Dev, + uint32_t *pStopStatus) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + uint8_t Byte = 0; + LOG_FUNCTION_START(""); + + Status = VL53L0X_WrByte(Dev, 0xFF, 0x01); + + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_RdByte(Dev, 0x04, &Byte); + + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_WrByte(Dev, 0xFF, 0x0); + + *pStopStatus = Byte; + + if (Byte == 0) { + Status = VL53L0X_WrByte(Dev, 0x80, 0x01); + Status = VL53L0X_WrByte(Dev, 0xFF, 0x01); + Status = VL53L0X_WrByte(Dev, 0x00, 0x00); + Status = VL53L0X_WrByte(Dev, 0x91, + PALDevDataGet(Dev, StopVariable)); + Status = VL53L0X_WrByte(Dev, 0x00, 0x01); + Status = VL53L0X_WrByte(Dev, 0xFF, 0x00); + Status = VL53L0X_WrByte(Dev, 0x80, 0x00); + } + + LOG_FUNCTION_END(Status); + return Status; +} + +/* Group PAL Interrupt Functions */ +VL53L0X_Error VL53L0X_ClearInterruptMask(VL53L0X_DEV Dev, uint32_t InterruptMask) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + uint8_t LoopCount; + uint8_t Byte; + LOG_FUNCTION_START(""); + + /* clear bit 0 range interrupt, bit 1 error interrupt */ + LoopCount = 0; + do { + Status = VL53L0X_WrByte(Dev, + VL53L0X_REG_SYSTEM_INTERRUPT_CLEAR, 0x01); + Status |= VL53L0X_WrByte(Dev, + VL53L0X_REG_SYSTEM_INTERRUPT_CLEAR, 0x00); + Status |= VL53L0X_RdByte(Dev, + VL53L0X_REG_RESULT_INTERRUPT_STATUS, &Byte); + LoopCount++; + } while (((Byte & 0x07) != 0x00) + && (LoopCount < 3) + && (Status == VL53L0X_ERROR_NONE)); + + + if (LoopCount >= 3) + Status = VL53L0X_ERROR_INTERRUPT_NOT_CLEARED; + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_GetInterruptMaskStatus(VL53L0X_DEV Dev, + uint32_t *pInterruptMaskStatus) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + uint8_t Byte; + LOG_FUNCTION_START(""); + + Status = VL53L0X_RdByte(Dev, VL53L0X_REG_RESULT_INTERRUPT_STATUS, &Byte); + *pInterruptMaskStatus = Byte & 0x07; + + if (Byte & 0x18) + Status = VL53L0X_ERROR_RANGE_ERROR; + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_EnableInterruptMask(VL53L0X_DEV Dev, uint32_t InterruptMask) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NOT_IMPLEMENTED; + LOG_FUNCTION_START(""); + + /* not implemented for VL53L0X */ + + LOG_FUNCTION_END(Status); + return Status; +} + +/* End Group PAL Interrupt Functions */ + +/* Group SPAD functions */ + +VL53L0X_Error VL53L0X_SetSpadAmbientDamperThreshold(VL53L0X_DEV Dev, + uint16_t SpadAmbientDamperThreshold) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + LOG_FUNCTION_START(""); + + Status = VL53L0X_WrByte(Dev, 0xFF, 0x01); + Status |= VL53L0X_WrWord(Dev, 0x40, SpadAmbientDamperThreshold); + Status |= VL53L0X_WrByte(Dev, 0xFF, 0x00); + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_GetSpadAmbientDamperThreshold(VL53L0X_DEV Dev, + uint16_t *pSpadAmbientDamperThreshold) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + LOG_FUNCTION_START(""); + + Status = VL53L0X_WrByte(Dev, 0xFF, 0x01); + Status |= VL53L0X_RdWord(Dev, 0x40, pSpadAmbientDamperThreshold); + Status |= VL53L0X_WrByte(Dev, 0xFF, 0x00); + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_SetSpadAmbientDamperFactor(VL53L0X_DEV Dev, + uint16_t SpadAmbientDamperFactor) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + uint8_t Byte; + LOG_FUNCTION_START(""); + + Byte = (uint8_t)(SpadAmbientDamperFactor & 0x00FF); + + Status = VL53L0X_WrByte(Dev, 0xFF, 0x01); + Status |= VL53L0X_WrByte(Dev, 0x42, Byte); + Status |= VL53L0X_WrByte(Dev, 0xFF, 0x00); + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_GetSpadAmbientDamperFactor(VL53L0X_DEV Dev, + uint16_t *pSpadAmbientDamperFactor) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + uint8_t Byte; + LOG_FUNCTION_START(""); + + Status = VL53L0X_WrByte(Dev, 0xFF, 0x01); + Status |= VL53L0X_RdByte(Dev, 0x42, &Byte); + Status |= VL53L0X_WrByte(Dev, 0xFF, 0x00); + *pSpadAmbientDamperFactor = (uint16_t)Byte; + + LOG_FUNCTION_END(Status); + return Status; +} + +/* END Group SPAD functions */ + +/***************************************************************************** + * Internal functions + *****************************************************************************/ + +VL53L0X_Error VL53L0X_SetReferenceSpads(VL53L0X_DEV Dev, uint32_t count, + uint8_t isApertureSpads) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + LOG_FUNCTION_START(""); + + Status = VL53L0X_set_reference_spads(Dev, count, isApertureSpads); + + LOG_FUNCTION_END(Status); + + return Status; +} + +VL53L0X_Error VL53L0X_GetReferenceSpads(VL53L0X_DEV Dev, uint32_t *pSpadCount, + uint8_t *pIsApertureSpads) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + LOG_FUNCTION_START(""); + + Status = VL53L0X_get_reference_spads(Dev, pSpadCount, pIsApertureSpads); + + LOG_FUNCTION_END(Status); + + return Status; +} + +VL53L0X_Error VL53L0X_PerformRefSpadManagement(VL53L0X_DEV Dev, + uint32_t *refSpadCount, uint8_t *isApertureSpads) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + LOG_FUNCTION_START(""); + + Status = VL53L0X_perform_ref_spad_management(Dev, refSpadCount, + isApertureSpads); + + LOG_FUNCTION_END(Status); + + return Status; +} diff --git a/modules/VL53L0X/src/vl53l0x_api_calibration.c b/modules/VL53L0X/src/vl53l0x_api_calibration.c new file mode 100644 index 0000000000000000000000000000000000000000..2995897a5668a24951a59d278351c13d6264979b --- /dev/null +++ b/modules/VL53L0X/src/vl53l0x_api_calibration.c @@ -0,0 +1,1276 @@ +/******************************************************************************* + Copyright 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. + ******************************************************************************/ + +#include "vl53l0x_api.h" +#include "vl53l0x_api_core.h" +#include "vl53l0x_api_calibration.h" + +#ifndef __KERNEL__ +#include +#endif + +#define LOG_FUNCTION_START(fmt, ...) \ + _LOG_FUNCTION_START(TRACE_MODULE_API, fmt, ##__VA_ARGS__) +#define LOG_FUNCTION_END(status, ...) \ + _LOG_FUNCTION_END(TRACE_MODULE_API, status, ##__VA_ARGS__) +#define LOG_FUNCTION_END_FMT(status, fmt, ...) \ + _LOG_FUNCTION_END_FMT(TRACE_MODULE_API, status, fmt, ##__VA_ARGS__) + +#define REF_ARRAY_SPAD_0 0 +#define REF_ARRAY_SPAD_5 5 +#define REF_ARRAY_SPAD_10 10 + +uint32_t refArrayQuadrants[4] = {REF_ARRAY_SPAD_10, REF_ARRAY_SPAD_5, + REF_ARRAY_SPAD_0, REF_ARRAY_SPAD_5 }; + +VL53L0X_Error VL53L0X_perform_xtalk_calibration(VL53L0X_DEV Dev, + FixPoint1616_t XTalkCalDistance, + FixPoint1616_t *pXTalkCompensationRateMegaCps) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + uint16_t sum_ranging = 0; + uint16_t sum_spads = 0; + FixPoint1616_t sum_signalRate = 0; + FixPoint1616_t total_count = 0; + uint8_t xtalk_meas = 0; + VL53L0X_RangingMeasurementData_t RangingMeasurementData; + FixPoint1616_t xTalkStoredMeanSignalRate; + FixPoint1616_t xTalkStoredMeanRange; + FixPoint1616_t xTalkStoredMeanRtnSpads; + uint32_t signalXTalkTotalPerSpad; + uint32_t xTalkStoredMeanRtnSpadsAsInt; + uint32_t xTalkCalDistanceAsInt; + FixPoint1616_t XTalkCompensationRateMegaCps; + + if (XTalkCalDistance <= 0) + Status = VL53L0X_ERROR_INVALID_PARAMS; + + /* Disable the XTalk compensation */ + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_SetXTalkCompensationEnable(Dev, 0); + + /* Disable the RIT */ + if (Status == VL53L0X_ERROR_NONE) { + Status = VL53L0X_SetLimitCheckEnable(Dev, + VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD, 0); + } + + /* Perform 50 measurements and compute the averages */ + if (Status == VL53L0X_ERROR_NONE) { + sum_ranging = 0; + sum_spads = 0; + sum_signalRate = 0; + total_count = 0; + for (xtalk_meas = 0; xtalk_meas < 50; xtalk_meas++) { + Status = VL53L0X_PerformSingleRangingMeasurement(Dev, + &RangingMeasurementData); + + if (Status != VL53L0X_ERROR_NONE) + break; + + /* The range is valid when RangeStatus = 0 */ + if (RangingMeasurementData.RangeStatus == 0) { + sum_ranging = sum_ranging + + RangingMeasurementData.RangeMilliMeter; + sum_signalRate = sum_signalRate + + RangingMeasurementData.SignalRateRtnMegaCps; + sum_spads = sum_spads + + RangingMeasurementData.EffectiveSpadRtnCount + / 256; + total_count = total_count + 1; + } + } + + /* no valid values found */ + if (total_count == 0) + Status = VL53L0X_ERROR_RANGE_ERROR; + + } + + + if (Status == VL53L0X_ERROR_NONE) { + /* FixPoint1616_t / uint16_t = FixPoint1616_t */ + xTalkStoredMeanSignalRate = sum_signalRate / total_count; + xTalkStoredMeanRange = (FixPoint1616_t)((uint32_t)( + sum_ranging << 16) / total_count); + xTalkStoredMeanRtnSpads = (FixPoint1616_t)((uint32_t)( + sum_spads << 16) / total_count); + + /* Round Mean Spads to Whole Number. + * Typically the calculated mean SPAD count is a whole number + * or very close to a whole + * number, therefore any truncation will not result in a + * significant loss in accuracy. + * Also, for a grey target at a typical distance of around + * 400mm, around 220 SPADs will + * be enabled, therefore, any truncation will result in a loss + * of accuracy of less than + * 0.5%. + */ + xTalkStoredMeanRtnSpadsAsInt = (xTalkStoredMeanRtnSpads + + 0x8000) >> 16; + + /* Round Cal Distance to Whole Number. + * Note that the cal distance is in mm, therefore no resolution + * is lost.*/ + xTalkCalDistanceAsInt = (XTalkCalDistance + 0x8000) >> 16; + + if (xTalkStoredMeanRtnSpadsAsInt == 0 || + xTalkCalDistanceAsInt == 0 || + xTalkStoredMeanRange >= XTalkCalDistance) { + XTalkCompensationRateMegaCps = 0; + } else { + /* Round Cal Distance to Whole Number. + Note that the cal distance is in mm, therefore no + resolution is lost.*/ + xTalkCalDistanceAsInt = (XTalkCalDistance + + 0x8000) >> 16; + + /* Apply division by mean spad count early in the + * calculation to keep the numbers small. + * This ensures we can maintain a 32bit calculation. + * Fixed1616 / int := Fixed1616 */ + signalXTalkTotalPerSpad = (xTalkStoredMeanSignalRate) / + xTalkStoredMeanRtnSpadsAsInt; + + /* Complete the calculation for total Signal XTalk per + * SPAD + * Fixed1616 * (Fixed1616 - Fixed1616/int) := + * (2^16 * Fixed1616) + */ + signalXTalkTotalPerSpad *= ((1 << 16) - + (xTalkStoredMeanRange / xTalkCalDistanceAsInt)); + + /* Round from 2^16 * Fixed1616, to Fixed1616. */ + XTalkCompensationRateMegaCps = (signalXTalkTotalPerSpad + + 0x8000) >> 16; + } + + *pXTalkCompensationRateMegaCps = XTalkCompensationRateMegaCps; + + /* Enable the XTalk compensation */ + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_SetXTalkCompensationEnable(Dev, 1); + + /* Enable the XTalk compensation */ + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_SetXTalkCompensationRateMegaCps(Dev, + XTalkCompensationRateMegaCps); + + } + + return Status; +} + +VL53L0X_Error VL53L0X_perform_offset_calibration(VL53L0X_DEV Dev, + FixPoint1616_t CalDistanceMilliMeter, + int32_t *pOffsetMicroMeter) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + uint16_t sum_ranging = 0; + FixPoint1616_t total_count = 0; + VL53L0X_RangingMeasurementData_t RangingMeasurementData; + FixPoint1616_t StoredMeanRange; + uint32_t StoredMeanRangeAsInt; + uint32_t CalDistanceAsInt_mm; + uint8_t SequenceStepEnabled; + int meas = 0; + + if (CalDistanceMilliMeter <= 0) + Status = VL53L0X_ERROR_INVALID_PARAMS; + + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_SetOffsetCalibrationDataMicroMeter(Dev, 0); + + + /* Get the value of the TCC */ + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_GetSequenceStepEnable(Dev, + VL53L0X_SEQUENCESTEP_TCC, &SequenceStepEnabled); + + + /* Disable the TCC */ + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_SetSequenceStepEnable(Dev, + VL53L0X_SEQUENCESTEP_TCC, 0); + + + /* Disable the RIT */ + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_SetLimitCheckEnable(Dev, + VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD, 0); + + /* Perform 50 measurements and compute the averages */ + if (Status == VL53L0X_ERROR_NONE) { + sum_ranging = 0; + total_count = 0; + for (meas = 0; meas < 50; meas++) { + Status = VL53L0X_PerformSingleRangingMeasurement(Dev, + &RangingMeasurementData); + + if (Status != VL53L0X_ERROR_NONE) + break; + + /* The range is valid when RangeStatus = 0 */ + if (RangingMeasurementData.RangeStatus == 0) { + sum_ranging = sum_ranging + + RangingMeasurementData.RangeMilliMeter; + total_count = total_count + 1; + } + } + + /* no valid values found */ + if (total_count == 0) + Status = VL53L0X_ERROR_RANGE_ERROR; + } + + + if (Status == VL53L0X_ERROR_NONE) { + /* FixPoint1616_t / uint16_t = FixPoint1616_t */ + StoredMeanRange = (FixPoint1616_t)((uint32_t)(sum_ranging << 16) + / total_count); + + StoredMeanRangeAsInt = (StoredMeanRange + 0x8000) >> 16; + + /* Round Cal Distance to Whole Number. + * Note that the cal distance is in mm, therefore no resolution + * is lost.*/ + CalDistanceAsInt_mm = (CalDistanceMilliMeter + 0x8000) >> 16; + + *pOffsetMicroMeter = (CalDistanceAsInt_mm - + StoredMeanRangeAsInt) * 1000; + + /* Apply the calculated offset */ + if (Status == VL53L0X_ERROR_NONE) { + VL53L0X_SETPARAMETERFIELD(Dev, RangeOffsetMicroMeters, + *pOffsetMicroMeter); + Status = VL53L0X_SetOffsetCalibrationDataMicroMeter(Dev, + *pOffsetMicroMeter); + } + + } + + /* Restore the TCC */ + if (Status == VL53L0X_ERROR_NONE) { + if (SequenceStepEnabled != 0) + Status = VL53L0X_SetSequenceStepEnable(Dev, + VL53L0X_SEQUENCESTEP_TCC, 1); + } + + return Status; +} + + +VL53L0X_Error VL53L0X_set_offset_calibration_data_micro_meter(VL53L0X_DEV Dev, + int32_t OffsetCalibrationDataMicroMeter) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + int32_t cMaxOffsetMicroMeter = 511000; + int32_t cMinOffsetMicroMeter = -512000; + int16_t cOffsetRange = 4096; + uint32_t encodedOffsetVal; + + LOG_FUNCTION_START(""); + + if (OffsetCalibrationDataMicroMeter > cMaxOffsetMicroMeter) + OffsetCalibrationDataMicroMeter = cMaxOffsetMicroMeter; + else if (OffsetCalibrationDataMicroMeter < cMinOffsetMicroMeter) + OffsetCalibrationDataMicroMeter = cMinOffsetMicroMeter; + + /* The offset register is 10.2 format and units are mm + * therefore conversion is applied by a division of + * 250. + */ + if (OffsetCalibrationDataMicroMeter >= 0) { + encodedOffsetVal = + OffsetCalibrationDataMicroMeter/250; + } else { + encodedOffsetVal = + cOffsetRange + + OffsetCalibrationDataMicroMeter/250; + } + + Status = VL53L0X_WrWord(Dev, + VL53L0X_REG_ALGO_PART_TO_PART_RANGE_OFFSET_MM, + encodedOffsetVal); + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_get_offset_calibration_data_micro_meter(VL53L0X_DEV Dev, + int32_t *pOffsetCalibrationDataMicroMeter) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + uint16_t RangeOffsetRegister; + int16_t cMaxOffset = 2047; + int16_t cOffsetRange = 4096; + + /* Note that offset has 10.2 format */ + + Status = VL53L0X_RdWord(Dev, + VL53L0X_REG_ALGO_PART_TO_PART_RANGE_OFFSET_MM, + &RangeOffsetRegister); + + if (Status == VL53L0X_ERROR_NONE) { + RangeOffsetRegister = (RangeOffsetRegister & 0x0fff); + + /* Apply 12 bit 2's compliment conversion */ + if (RangeOffsetRegister > cMaxOffset) + *pOffsetCalibrationDataMicroMeter = + (int16_t)(RangeOffsetRegister - cOffsetRange) + * 250; + else + *pOffsetCalibrationDataMicroMeter = + (int16_t)RangeOffsetRegister * 250; + + } + + return Status; +} + + +VL53L0X_Error VL53L0X_apply_offset_adjustment(VL53L0X_DEV Dev) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + int32_t CorrectedOffsetMicroMeters; + int32_t CurrentOffsetMicroMeters; + + /* if we run on this function we can read all the NVM info + * used by the API */ + Status = VL53L0X_get_info_from_device(Dev, 7); + + /* Read back current device offset */ + if (Status == VL53L0X_ERROR_NONE) { + Status = VL53L0X_GetOffsetCalibrationDataMicroMeter(Dev, + &CurrentOffsetMicroMeters); + } + + /* Apply Offset Adjustment derived from 400mm measurements */ + if (Status == VL53L0X_ERROR_NONE) { + + /* Store initial device offset */ + PALDevDataSet(Dev, Part2PartOffsetNVMMicroMeter, + CurrentOffsetMicroMeters); + + CorrectedOffsetMicroMeters = CurrentOffsetMicroMeters + + (int32_t)PALDevDataGet(Dev, + Part2PartOffsetAdjustmentNVMMicroMeter); + + Status = VL53L0X_SetOffsetCalibrationDataMicroMeter(Dev, + CorrectedOffsetMicroMeters); + + /* store current, adjusted offset */ + if (Status == VL53L0X_ERROR_NONE) { + VL53L0X_SETPARAMETERFIELD(Dev, RangeOffsetMicroMeters, + CorrectedOffsetMicroMeters); + } + } + + return Status; +} + +void get_next_good_spad(uint8_t goodSpadArray[], uint32_t size, + uint32_t curr, int32_t *next) +{ + uint32_t startIndex; + uint32_t fineOffset; + uint32_t cSpadsPerByte = 8; + uint32_t coarseIndex; + uint32_t fineIndex; + uint8_t dataByte; + uint8_t success = 0; + + /* + * Starting with the current good spad, loop through the array to find + * the next. i.e. the next bit set in the sequence. + * + * The coarse index is the byte index of the array and the fine index is + * the index of the bit within each byte. + */ + + *next = -1; + + startIndex = curr / cSpadsPerByte; + fineOffset = curr % cSpadsPerByte; + + for (coarseIndex = startIndex; ((coarseIndex < size) && !success); + coarseIndex++) { + fineIndex = 0; + dataByte = goodSpadArray[coarseIndex]; + + if (coarseIndex == startIndex) { + /* locate the bit position of the provided current + * spad bit before iterating */ + dataByte >>= fineOffset; + fineIndex = fineOffset; + } + + while (fineIndex < cSpadsPerByte) { + if ((dataByte & 0x1) == 1) { + success = 1; + *next = coarseIndex * cSpadsPerByte + fineIndex; + break; + } + dataByte >>= 1; + fineIndex++; + } + } +} + + +uint8_t is_aperture(uint32_t spadIndex) +{ + /* + * This function reports if a given spad index is an aperture SPAD by + * deriving the quadrant. + */ + uint32_t quadrant; + uint8_t isAperture = 1; + quadrant = spadIndex >> 6; + if (refArrayQuadrants[quadrant] == REF_ARRAY_SPAD_0) + isAperture = 0; + + return isAperture; +} + + +VL53L0X_Error enable_spad_bit(uint8_t spadArray[], uint32_t size, + uint32_t spadIndex) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + uint32_t cSpadsPerByte = 8; + uint32_t coarseIndex; + uint32_t fineIndex; + + coarseIndex = spadIndex / cSpadsPerByte; + fineIndex = spadIndex % cSpadsPerByte; + if (coarseIndex >= size) + status = VL53L0X_ERROR_REF_SPAD_INIT; + else + spadArray[coarseIndex] |= (1 << fineIndex); + + return status; +} + +VL53L0X_Error count_enabled_spads(uint8_t spadArray[], + uint32_t byteCount, uint32_t maxSpads, + uint32_t *pTotalSpadsEnabled, uint8_t *pIsAperture) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + uint32_t cSpadsPerByte = 8; + uint32_t lastByte; + uint32_t lastBit; + uint32_t byteIndex = 0; + uint32_t bitIndex = 0; + uint8_t tempByte; + uint8_t spadTypeIdentified = 0; + + /* The entire array will not be used for spads, therefore the last + * byte and last bit is determined from the max spads value. + */ + + lastByte = maxSpads / cSpadsPerByte; + lastBit = maxSpads % cSpadsPerByte; + + /* Check that the max spads value does not exceed the array bounds. */ + if (lastByte >= byteCount) + status = VL53L0X_ERROR_REF_SPAD_INIT; + + *pTotalSpadsEnabled = 0; + + /* Count the bits enabled in the whole bytes */ + for (byteIndex = 0; byteIndex <= (lastByte - 1); byteIndex++) { + tempByte = spadArray[byteIndex]; + + for (bitIndex = 0; bitIndex <= cSpadsPerByte; bitIndex++) { + if ((tempByte & 0x01) == 1) { + (*pTotalSpadsEnabled)++; + + if (!spadTypeIdentified) { + *pIsAperture = 1; + if ((byteIndex < 2) && (bitIndex < 4)) + *pIsAperture = 0; + spadTypeIdentified = 1; + } + } + tempByte >>= 1; + } + } + + /* Count the number of bits enabled in the last byte accounting + * for the fact that not all bits in the byte may be used. + */ + tempByte = spadArray[lastByte]; + + for (bitIndex = 0; bitIndex <= lastBit; bitIndex++) { + if ((tempByte & 0x01) == 1) + (*pTotalSpadsEnabled)++; + } + + return status; +} + +VL53L0X_Error set_ref_spad_map(VL53L0X_DEV Dev, uint8_t *refSpadArray) +{ + VL53L0X_Error status = VL53L0X_WriteMulti(Dev, + VL53L0X_REG_GLOBAL_CONFIG_SPAD_ENABLES_REF_0, + refSpadArray, 6); + return status; +} + +VL53L0X_Error get_ref_spad_map(VL53L0X_DEV Dev, uint8_t *refSpadArray) +{ + VL53L0X_Error status = VL53L0X_ReadMulti(Dev, + VL53L0X_REG_GLOBAL_CONFIG_SPAD_ENABLES_REF_0, + refSpadArray, + 6); + return status; +} + +VL53L0X_Error enable_ref_spads(VL53L0X_DEV Dev, + uint8_t apertureSpads, + uint8_t goodSpadArray[], + uint8_t spadArray[], + uint32_t size, + uint32_t start, + uint32_t offset, + uint32_t spadCount, + uint32_t *lastSpad) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + uint32_t index; + uint32_t i; + int32_t nextGoodSpad = offset; + uint32_t currentSpad; + uint8_t checkSpadArray[6]; + + /* + * This function takes in a spad array which may or may not have SPADS + * already enabled and appends from a given offset a requested number + * of new SPAD enables. The 'good spad map' is applied to + * determine the next SPADs to enable. + * + * This function applies to only aperture or only non-aperture spads. + * Checks are performed to ensure this. + */ + + currentSpad = offset; + for (index = 0; index < spadCount; index++) { + get_next_good_spad(goodSpadArray, size, currentSpad, + &nextGoodSpad); + + if (nextGoodSpad == -1) { + status = VL53L0X_ERROR_REF_SPAD_INIT; + break; + } + + /* Confirm that the next good SPAD is non-aperture */ + if (is_aperture(start + nextGoodSpad) != apertureSpads) { + /* if we can't get the required number of good aperture + * spads from the current quadrant then this is an error + */ + status = VL53L0X_ERROR_REF_SPAD_INIT; + break; + } + currentSpad = (uint32_t)nextGoodSpad; + enable_spad_bit(spadArray, size, currentSpad); + currentSpad++; + } + *lastSpad = currentSpad; + + if (status == VL53L0X_ERROR_NONE) + status = set_ref_spad_map(Dev, spadArray); + + + if (status == VL53L0X_ERROR_NONE) { + status = get_ref_spad_map(Dev, checkSpadArray); + + i = 0; + + /* Compare spad maps. If not equal report error. */ + while (i < size) { + if (spadArray[i] != checkSpadArray[i]) { + status = VL53L0X_ERROR_REF_SPAD_INIT; + break; + } + i++; + } + } + return status; +} + + +VL53L0X_Error perform_ref_signal_measurement(VL53L0X_DEV Dev, + uint16_t *refSignalRate) +{ + VL53L0X_Error status = VL53L0X_ERROR_NONE; + VL53L0X_RangingMeasurementData_t rangingMeasurementData; + + uint8_t SequenceConfig = 0; + + /* store the value of the sequence config, + * this will be reset before the end of the function + */ + + SequenceConfig = PALDevDataGet(Dev, SequenceConfig); + + /* + * This function performs a reference signal rate measurement. + */ + if (status == VL53L0X_ERROR_NONE) + status = VL53L0X_WrByte(Dev, + VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG, 0xC0); + + if (status == VL53L0X_ERROR_NONE) + status = VL53L0X_PerformSingleRangingMeasurement(Dev, + &rangingMeasurementData); + + if (status == VL53L0X_ERROR_NONE) + status = VL53L0X_WrByte(Dev, 0xFF, 0x01); + + if (status == VL53L0X_ERROR_NONE) + status = VL53L0X_RdWord(Dev, + VL53L0X_REG_RESULT_PEAK_SIGNAL_RATE_REF, + refSignalRate); + + if (status == VL53L0X_ERROR_NONE) + status = VL53L0X_WrByte(Dev, 0xFF, 0x00); + + if (status == VL53L0X_ERROR_NONE) { + /* restore the previous Sequence Config */ + status = VL53L0X_WrByte(Dev, VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG, + SequenceConfig); + if (status == VL53L0X_ERROR_NONE) + PALDevDataSet(Dev, SequenceConfig, SequenceConfig); + } + + return status; +} + +VL53L0X_Error VL53L0X_perform_ref_spad_management(VL53L0X_DEV Dev, + uint32_t *refSpadCount, + uint8_t *isApertureSpads) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + uint8_t lastSpadArray[6]; + uint8_t startSelect = 0xB4; + uint32_t minimumSpadCount = 3; + uint32_t maxSpadCount = 44; + uint32_t currentSpadIndex = 0; + uint32_t lastSpadIndex = 0; + int32_t nextGoodSpad = 0; + uint16_t targetRefRate = 0x0A00; /* 20 MCPS in 9:7 format */ + uint16_t peakSignalRateRef; + uint32_t needAptSpads = 0; + uint32_t index = 0; + uint32_t spadArraySize = 6; + uint32_t signalRateDiff = 0; + uint32_t lastSignalRateDiff = 0; + uint8_t complete = 0; + uint8_t VhvSettings = 0; + uint8_t PhaseCal = 0; + uint32_t refSpadCount_int = 0; + uint8_t isApertureSpads_int = 0; + + /* + * The reference SPAD initialization procedure determines the minimum + * amount of reference spads to be enables to achieve a target reference + * signal rate and should be performed once during initialization. + * + * Either aperture or non-aperture spads are applied but never both. + * Firstly non-aperture spads are set, begining with 5 spads, and + * increased one spad at a time until the closest measurement to the + * target rate is achieved. + * + * If the target rate is exceeded when 5 non-aperture spads are enabled, + * initialization is performed instead with aperture spads. + * + * When setting spads, a 'Good Spad Map' is applied. + * + * This procedure operates within a SPAD window of interest of a maximum + * 44 spads. + * The start point is currently fixed to 180, which lies towards the end + * of the non-aperture quadrant and runs in to the adjacent aperture + * quadrant. + */ + + + targetRefRate = PALDevDataGet(Dev, targetRefRate); + + /* + * Initialize Spad arrays. + * Currently the good spad map is initialised to 'All good'. + * This is a short term implementation. The good spad map will be + * provided as an input. + * Note that there are 6 bytes. Only the first 44 bits will be used to + * represent spads. + */ + for (index = 0; index < spadArraySize; index++) + Dev->Data.SpadData.RefSpadEnables[index] = 0; + + + Status = VL53L0X_WrByte(Dev, 0xFF, 0x01); + + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_WrByte(Dev, + VL53L0X_REG_DYNAMIC_SPAD_REF_EN_START_OFFSET, 0x00); + + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_WrByte(Dev, + VL53L0X_REG_DYNAMIC_SPAD_NUM_REQUESTED_REF_SPAD, 0x2C); + + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_WrByte(Dev, 0xFF, 0x00); + + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_WrByte(Dev, + VL53L0X_REG_GLOBAL_CONFIG_REF_EN_START_SELECT, + startSelect); + + + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_WrByte(Dev, + VL53L0X_REG_POWER_MANAGEMENT_GO1_POWER_FORCE, 0); + + /* Perform ref calibration */ + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_perform_ref_calibration(Dev, &VhvSettings, + &PhaseCal, 0); + + if (Status == VL53L0X_ERROR_NONE) { + /* Enable Minimum NON-APERTURE Spads */ + currentSpadIndex = 0; + lastSpadIndex = currentSpadIndex; + needAptSpads = 0; + Status = enable_ref_spads(Dev, + needAptSpads, + Dev->Data.SpadData.RefGoodSpadMap, + Dev->Data.SpadData.RefSpadEnables, + spadArraySize, + startSelect, + currentSpadIndex, + minimumSpadCount, + &lastSpadIndex); + } + + if (Status == VL53L0X_ERROR_NONE) { + currentSpadIndex = lastSpadIndex; + + Status = perform_ref_signal_measurement(Dev, + &peakSignalRateRef); + if ((Status == VL53L0X_ERROR_NONE) && + (peakSignalRateRef > targetRefRate)) { + /* Signal rate measurement too high, + * switch to APERTURE SPADs */ + + for (index = 0; index < spadArraySize; index++) + Dev->Data.SpadData.RefSpadEnables[index] = 0; + + + /* Increment to the first APERTURE spad */ + while ((is_aperture(startSelect + currentSpadIndex) + == 0) && (currentSpadIndex < maxSpadCount)) { + currentSpadIndex++; + } + + needAptSpads = 1; + + Status = enable_ref_spads(Dev, + needAptSpads, + Dev->Data.SpadData.RefGoodSpadMap, + Dev->Data.SpadData.RefSpadEnables, + spadArraySize, + startSelect, + currentSpadIndex, + minimumSpadCount, + &lastSpadIndex); + + if (Status == VL53L0X_ERROR_NONE) { + currentSpadIndex = lastSpadIndex; + Status = perform_ref_signal_measurement(Dev, + &peakSignalRateRef); + + if ((Status == VL53L0X_ERROR_NONE) && + (peakSignalRateRef > targetRefRate)) { + /* Signal rate still too high after + * setting the minimum number of + * APERTURE spads. Can do no more + * therefore set the min number of + * aperture spads as the result. + */ + isApertureSpads_int = 1; + refSpadCount_int = minimumSpadCount; + } + } + } else { + needAptSpads = 0; + } + } + + if ((Status == VL53L0X_ERROR_NONE) && + (peakSignalRateRef < targetRefRate)) { + /* At this point, the minimum number of either aperture + * or non-aperture spads have been set. Proceed to add + * spads and perform measurements until the target + * reference is reached. + */ + isApertureSpads_int = needAptSpads; + refSpadCount_int = minimumSpadCount; + + memcpy(lastSpadArray, Dev->Data.SpadData.RefSpadEnables, + spadArraySize); + lastSignalRateDiff = abs(peakSignalRateRef - + targetRefRate); + complete = 0; + + while (!complete) { + get_next_good_spad( + Dev->Data.SpadData.RefGoodSpadMap, + spadArraySize, currentSpadIndex, + &nextGoodSpad); + + if (nextGoodSpad == -1) { + Status = VL53L0X_ERROR_REF_SPAD_INIT; + break; + } + + /* Cannot combine Aperture and Non-Aperture spads, so + * ensure the current spad is of the correct type. + */ + if (is_aperture((uint32_t)startSelect + nextGoodSpad) != + needAptSpads) { + /* At this point we have enabled the maximum + * number of Aperture spads. + */ + complete = 1; + break; + } + + (refSpadCount_int)++; + + currentSpadIndex = nextGoodSpad; + Status = enable_spad_bit( + Dev->Data.SpadData.RefSpadEnables, + spadArraySize, currentSpadIndex); + + if (Status == VL53L0X_ERROR_NONE) { + currentSpadIndex++; + /* Proceed to apply the additional spad and + * perform measurement. */ + Status = set_ref_spad_map(Dev, + Dev->Data.SpadData.RefSpadEnables); + } + + if (Status != VL53L0X_ERROR_NONE) + break; + + Status = perform_ref_signal_measurement(Dev, + &peakSignalRateRef); + + if (Status != VL53L0X_ERROR_NONE) + break; + + signalRateDiff = abs(peakSignalRateRef - targetRefRate); + + if (peakSignalRateRef > targetRefRate) { + /* Select the spad map that provides the + * measurement closest to the target rate, + * either above or below it. + */ + if (signalRateDiff > lastSignalRateDiff) { + /* Previous spad map produced a closer + * measurement, so choose this. */ + Status = set_ref_spad_map(Dev, + lastSpadArray); + memcpy( + Dev->Data.SpadData.RefSpadEnables, + lastSpadArray, spadArraySize); + + (refSpadCount_int)--; + } + complete = 1; + } else { + /* Continue to add spads */ + lastSignalRateDiff = signalRateDiff; + memcpy(lastSpadArray, + Dev->Data.SpadData.RefSpadEnables, + spadArraySize); + } + + } /* while */ + } + + if (Status == VL53L0X_ERROR_NONE) { + *refSpadCount = refSpadCount_int; + *isApertureSpads = isApertureSpads_int; + + VL53L0X_SETDEVICESPECIFICPARAMETER(Dev, RefSpadsInitialised, 1); + VL53L0X_SETDEVICESPECIFICPARAMETER(Dev, + ReferenceSpadCount, (uint8_t)(*refSpadCount)); + VL53L0X_SETDEVICESPECIFICPARAMETER(Dev, + ReferenceSpadType, *isApertureSpads); + } + + return Status; +} + +VL53L0X_Error VL53L0X_set_reference_spads(VL53L0X_DEV Dev, + uint32_t count, uint8_t isApertureSpads) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + uint32_t currentSpadIndex = 0; + uint8_t startSelect = 0xB4; + uint32_t spadArraySize = 6; + uint32_t maxSpadCount = 44; + uint32_t lastSpadIndex; + uint32_t index; + + /* + * This function applies a requested number of reference spads, either + * aperture or + * non-aperture, as requested. + * The good spad map will be applied. + */ + + Status = VL53L0X_WrByte(Dev, 0xFF, 0x01); + + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_WrByte(Dev, + VL53L0X_REG_DYNAMIC_SPAD_REF_EN_START_OFFSET, 0x00); + + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_WrByte(Dev, + VL53L0X_REG_DYNAMIC_SPAD_NUM_REQUESTED_REF_SPAD, 0x2C); + + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_WrByte(Dev, 0xFF, 0x00); + + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_WrByte(Dev, + VL53L0X_REG_GLOBAL_CONFIG_REF_EN_START_SELECT, + startSelect); + + for (index = 0; index < spadArraySize; index++) + Dev->Data.SpadData.RefSpadEnables[index] = 0; + + if (isApertureSpads) { + /* Increment to the first APERTURE spad */ + while ((is_aperture(startSelect + currentSpadIndex) == 0) && + (currentSpadIndex < maxSpadCount)) { + currentSpadIndex++; + } + } + Status = enable_ref_spads(Dev, + isApertureSpads, + Dev->Data.SpadData.RefGoodSpadMap, + Dev->Data.SpadData.RefSpadEnables, + spadArraySize, + startSelect, + currentSpadIndex, + count, + &lastSpadIndex); + + if (Status == VL53L0X_ERROR_NONE) { + VL53L0X_SETDEVICESPECIFICPARAMETER(Dev, RefSpadsInitialised, 1); + VL53L0X_SETDEVICESPECIFICPARAMETER(Dev, + ReferenceSpadCount, (uint8_t)(count)); + VL53L0X_SETDEVICESPECIFICPARAMETER(Dev, + ReferenceSpadType, isApertureSpads); + } + + return Status; +} + +VL53L0X_Error VL53L0X_get_reference_spads(VL53L0X_DEV Dev, + uint32_t *pSpadCount, uint8_t *pIsApertureSpads) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + uint8_t refSpadsInitialised; + uint8_t refSpadArray[6]; + uint32_t cMaxSpadCount = 44; + uint32_t cSpadArraySize = 6; + uint32_t spadsEnabled; + uint8_t isApertureSpads = 0; + + refSpadsInitialised = VL53L0X_GETDEVICESPECIFICPARAMETER(Dev, + RefSpadsInitialised); + + if (refSpadsInitialised == 1) { + + *pSpadCount = (uint32_t)VL53L0X_GETDEVICESPECIFICPARAMETER(Dev, + ReferenceSpadCount); + *pIsApertureSpads = VL53L0X_GETDEVICESPECIFICPARAMETER(Dev, + ReferenceSpadType); + } else { + + /* obtain spad info from device.*/ + Status = get_ref_spad_map(Dev, refSpadArray); + + if (Status == VL53L0X_ERROR_NONE) { + /* count enabled spads within spad map array and + * determine if Aperture or Non-Aperture. + */ + Status = count_enabled_spads(refSpadArray, + cSpadArraySize, + cMaxSpadCount, + &spadsEnabled, + &isApertureSpads); + + if (Status == VL53L0X_ERROR_NONE) { + + *pSpadCount = spadsEnabled; + *pIsApertureSpads = isApertureSpads; + + VL53L0X_SETDEVICESPECIFICPARAMETER(Dev, + RefSpadsInitialised, 1); + VL53L0X_SETDEVICESPECIFICPARAMETER(Dev, + ReferenceSpadCount, + (uint8_t)spadsEnabled); + VL53L0X_SETDEVICESPECIFICPARAMETER(Dev, + ReferenceSpadType, isApertureSpads); + } + } + } + + return Status; +} + + +VL53L0X_Error VL53L0X_perform_single_ref_calibration(VL53L0X_DEV Dev, + uint8_t vhv_init_byte) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_WrByte(Dev, VL53L0X_REG_SYSRANGE_START, + VL53L0X_REG_SYSRANGE_MODE_START_STOP | + vhv_init_byte); + + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_measurement_poll_for_completion(Dev); + + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_ClearInterruptMask(Dev, 0); + + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_WrByte(Dev, VL53L0X_REG_SYSRANGE_START, 0x00); + + return Status; +} + + +VL53L0X_Error VL53L0X_ref_calibration_io(VL53L0X_DEV Dev, uint8_t read_not_write, + uint8_t VhvSettings, uint8_t PhaseCal, + uint8_t *pVhvSettings, uint8_t *pPhaseCal, + const uint8_t vhv_enable, const uint8_t phase_enable) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + uint8_t PhaseCalint = 0; + + /* Read VHV from device */ + Status |= VL53L0X_WrByte(Dev, 0xFF, 0x01); + Status |= VL53L0X_WrByte(Dev, 0x00, 0x00); + Status |= VL53L0X_WrByte(Dev, 0xFF, 0x00); + + if (read_not_write) { + if (vhv_enable) + Status |= VL53L0X_RdByte(Dev, 0xCB, pVhvSettings); + if (phase_enable) + Status |= VL53L0X_RdByte(Dev, 0xEE, &PhaseCalint); + } else { + if (vhv_enable) + Status |= VL53L0X_WrByte(Dev, 0xCB, VhvSettings); + if (phase_enable) + Status |= VL53L0X_UpdateByte(Dev, 0xEE, 0x80, PhaseCal); + } + + Status |= VL53L0X_WrByte(Dev, 0xFF, 0x01); + Status |= VL53L0X_WrByte(Dev, 0x00, 0x01); + Status |= VL53L0X_WrByte(Dev, 0xFF, 0x00); + + *pPhaseCal = (uint8_t)(PhaseCalint&0xEF); + + return Status; +} + + +VL53L0X_Error VL53L0X_perform_vhv_calibration(VL53L0X_DEV Dev, + uint8_t *pVhvSettings, const uint8_t get_data_enable, + const uint8_t restore_config) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + uint8_t SequenceConfig = 0; + uint8_t VhvSettings = 0; + uint8_t PhaseCal = 0; + uint8_t PhaseCalInt = 0; + + /* store the value of the sequence config, + * this will be reset before the end of the function + */ + + if (restore_config) + SequenceConfig = PALDevDataGet(Dev, SequenceConfig); + + /* Run VHV */ + Status = VL53L0X_WrByte(Dev, VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG, 0x01); + + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_perform_single_ref_calibration(Dev, 0x40); + + /* Read VHV from device */ + if ((Status == VL53L0X_ERROR_NONE) && (get_data_enable == 1)) { + Status = VL53L0X_ref_calibration_io(Dev, 1, + VhvSettings, PhaseCal, /* Not used here */ + pVhvSettings, &PhaseCalInt, + 1, 0); + } else + *pVhvSettings = 0; + + + if ((Status == VL53L0X_ERROR_NONE) && restore_config) { + /* restore the previous Sequence Config */ + Status = VL53L0X_WrByte(Dev, VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG, + SequenceConfig); + if (Status == VL53L0X_ERROR_NONE) + PALDevDataSet(Dev, SequenceConfig, SequenceConfig); + + } + + return Status; +} + +VL53L0X_Error VL53L0X_perform_phase_calibration(VL53L0X_DEV Dev, + uint8_t *pPhaseCal, const uint8_t get_data_enable, + const uint8_t restore_config) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + uint8_t SequenceConfig = 0; + uint8_t VhvSettings = 0; + uint8_t PhaseCal = 0; + uint8_t VhvSettingsint; + + /* store the value of the sequence config, + * this will be reset before the end of the function + */ + + if (restore_config) + SequenceConfig = PALDevDataGet(Dev, SequenceConfig); + + /* Run PhaseCal */ + Status = VL53L0X_WrByte(Dev, VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG, 0x02); + + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_perform_single_ref_calibration(Dev, 0x0); + + /* Read PhaseCal from device */ + if ((Status == VL53L0X_ERROR_NONE) && (get_data_enable == 1)) { + Status = VL53L0X_ref_calibration_io(Dev, 1, + VhvSettings, PhaseCal, /* Not used here */ + &VhvSettingsint, pPhaseCal, + 0, 1); + } else + *pPhaseCal = 0; + + + if ((Status == VL53L0X_ERROR_NONE) && restore_config) { + /* restore the previous Sequence Config */ + Status = VL53L0X_WrByte(Dev, VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG, + SequenceConfig); + if (Status == VL53L0X_ERROR_NONE) + PALDevDataSet(Dev, SequenceConfig, SequenceConfig); + + } + + return Status; +} + +VL53L0X_Error VL53L0X_perform_ref_calibration(VL53L0X_DEV Dev, + uint8_t *pVhvSettings, uint8_t *pPhaseCal, uint8_t get_data_enable) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + uint8_t SequenceConfig = 0; + + /* store the value of the sequence config, + * this will be reset before the end of the function + */ + + SequenceConfig = PALDevDataGet(Dev, SequenceConfig); + + /* In the following function we don't save the config to optimize + * writes on device. Config is saved and restored only once. */ + Status = VL53L0X_perform_vhv_calibration( + Dev, pVhvSettings, get_data_enable, 0); + + + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_perform_phase_calibration( + Dev, pPhaseCal, get_data_enable, 0); + + + if (Status == VL53L0X_ERROR_NONE) { + /* restore the previous Sequence Config */ + Status = VL53L0X_WrByte(Dev, VL53L0X_REG_SYSTEM_SEQUENCE_CONFIG, + SequenceConfig); + if (Status == VL53L0X_ERROR_NONE) + PALDevDataSet(Dev, SequenceConfig, SequenceConfig); + + } + + return Status; +} + +VL53L0X_Error VL53L0X_set_ref_calibration(VL53L0X_DEV Dev, + uint8_t VhvSettings, uint8_t PhaseCal) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + uint8_t pVhvSettings; + uint8_t pPhaseCal; + + Status = VL53L0X_ref_calibration_io(Dev, 0, + VhvSettings, PhaseCal, + &pVhvSettings, &pPhaseCal, + 1, 1); + + return Status; +} + +VL53L0X_Error VL53L0X_get_ref_calibration(VL53L0X_DEV Dev, + uint8_t *pVhvSettings, uint8_t *pPhaseCal) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + uint8_t VhvSettings = 0; + uint8_t PhaseCal = 0; + + Status = VL53L0X_ref_calibration_io(Dev, 1, + VhvSettings, PhaseCal, + pVhvSettings, pPhaseCal, + 1, 1); + + return Status; +} diff --git a/modules/VL53L0X/src/vl53l0x_api_core.c b/modules/VL53L0X/src/vl53l0x_api_core.c new file mode 100644 index 0000000000000000000000000000000000000000..8f0632a1c082536df34f5710b4edd4a90449f4f8 --- /dev/null +++ b/modules/VL53L0X/src/vl53l0x_api_core.c @@ -0,0 +1,2239 @@ +/******************************************************************************* + Copyright 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. + ******************************************************************************/ + +#include "vl53l0x_api.h" +#include "vl53l0x_api_core.h" +#include "vl53l0x_api_calibration.h" + + +#ifndef __KERNEL__ +#include +#endif +#define LOG_FUNCTION_START(fmt, ...) \ + _LOG_FUNCTION_START(TRACE_MODULE_API, fmt, ##__VA_ARGS__) +#define LOG_FUNCTION_END(status, ...) \ + _LOG_FUNCTION_END(TRACE_MODULE_API, status, ##__VA_ARGS__) +#define LOG_FUNCTION_END_FMT(status, fmt, ...) \ + _LOG_FUNCTION_END_FMT(TRACE_MODULE_API, status, fmt, ##__VA_ARGS__) + +VL53L0X_Error VL53L0X_reverse_bytes(uint8_t *data, uint32_t size) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + uint8_t tempData; + uint32_t mirrorIndex; + uint32_t middle = size/2; + uint32_t index; + + for (index = 0; index < middle; index++) { + mirrorIndex = size - index - 1; + tempData = data[index]; + data[index] = data[mirrorIndex]; + data[mirrorIndex] = tempData; + } + return Status; +} + +VL53L0X_Error VL53L0X_measurement_poll_for_completion(VL53L0X_DEV Dev) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + uint8_t NewDataReady = 0; + uint32_t LoopNb; + + LOG_FUNCTION_START(""); + + LoopNb = 0; + + do { + Status = VL53L0X_GetMeasurementDataReady(Dev, &NewDataReady); + if (Status != 0) + break; /* the error is set */ + + if (NewDataReady == 1) + break; /* done note that status == 0 */ + + LoopNb++; + if (LoopNb >= VL53L0X_DEFAULT_MAX_LOOP) { + Status = VL53L0X_ERROR_TIME_OUT; + break; + } + + VL53L0X_PollingDelay(Dev); + } while (1); + + LOG_FUNCTION_END(Status); + + return Status; +} + + +uint8_t VL53L0X_decode_vcsel_period(uint8_t vcsel_period_reg) +{ + /*! + * Converts the encoded VCSEL period register value into the real + * period in PLL clocks + */ + + uint8_t vcsel_period_pclks = 0; + + vcsel_period_pclks = (vcsel_period_reg + 1) << 1; + + return vcsel_period_pclks; +} + +uint8_t VL53L0X_encode_vcsel_period(uint8_t vcsel_period_pclks) +{ + /*! + * Converts the encoded VCSEL period register value into the real period + * in PLL clocks + */ + + uint8_t vcsel_period_reg = 0; + + vcsel_period_reg = (vcsel_period_pclks >> 1) - 1; + + return vcsel_period_reg; +} + + +uint32_t VL53L0X_isqrt(uint32_t num) +{ + /* + * Implements an integer square root + * + * From: http://en.wikipedia.org/wiki/Methods_of_computing_square_roots + */ + + uint32_t res = 0; + uint32_t bit = 1 << 30; + /* The second-to-top bit is set: + * 1 << 14 for 16-bits, 1 << 30 for 32 bits */ + + /* "bit" starts at the highest power of four <= the argument. */ + while (bit > num) + bit >>= 2; + + + while (bit != 0) { + if (num >= res + bit) { + num -= res + bit; + res = (res >> 1) + bit; + } else + res >>= 1; + + bit >>= 2; + } + + return res; +} + + +uint32_t VL53L0X_quadrature_sum(uint32_t a, uint32_t b) +{ + /* + * Implements a quadrature sum + * + * rea = sqrt(a^2 + b^2) + * + * Trap overflow case max input value is 65535 (16-bit value) + * as internal calc are 32-bit wide + * + * If overflow then seta output to maximum + */ + uint32_t res = 0; + + if (a > 65535 || b > 65535) + res = 65535; + else + res = VL53L0X_isqrt(a * a + b * b); + + return res; +} + + +VL53L0X_Error VL53L0X_device_read_strobe(VL53L0X_DEV Dev) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + uint8_t strobe; + uint32_t LoopNb; + LOG_FUNCTION_START(""); + + Status |= VL53L0X_WrByte(Dev, 0x83, 0x00); + + /* polling + * use timeout to avoid deadlock*/ + if (Status == VL53L0X_ERROR_NONE) { + LoopNb = 0; + do { + Status = VL53L0X_RdByte(Dev, 0x83, &strobe); + if ((strobe != 0x00) || Status != VL53L0X_ERROR_NONE) + break; + + LoopNb = LoopNb + 1; + } while (LoopNb < VL53L0X_DEFAULT_MAX_LOOP); + + if (LoopNb >= VL53L0X_DEFAULT_MAX_LOOP) + Status = VL53L0X_ERROR_TIME_OUT; + + } + + Status |= VL53L0X_WrByte(Dev, 0x83, 0x01); + + LOG_FUNCTION_END(Status); + return Status; + +} + +VL53L0X_Error VL53L0X_get_info_from_device(VL53L0X_DEV Dev, uint8_t option) +{ + + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + uint8_t byte; + uint32_t TmpDWord; + uint8_t ModuleId; + uint8_t Revision; + uint8_t ReferenceSpadCount = 0; + uint8_t ReferenceSpadType = 0; + uint32_t PartUIDUpper = 0; + uint32_t PartUIDLower = 0; + uint32_t OffsetFixed1104_mm = 0; + int16_t OffsetMicroMeters = 0; + uint32_t DistMeasTgtFixed1104_mm = 400 << 4; + uint32_t DistMeasFixed1104_400_mm = 0; + uint32_t SignalRateMeasFixed1104_400_mm = 0; + char ProductId[19]; + char *ProductId_tmp; + uint8_t ReadDataFromDeviceDone; + FixPoint1616_t SignalRateMeasFixed400mmFix = 0; + uint8_t NvmRefGoodSpadMap[VL53L0X_REF_SPAD_BUFFER_SIZE]; + int i; + + + LOG_FUNCTION_START(""); + + ReadDataFromDeviceDone = VL53L0X_GETDEVICESPECIFICPARAMETER(Dev, + ReadDataFromDeviceDone); + + /* This access is done only once after that a GetDeviceInfo or + * datainit is done*/ + if (ReadDataFromDeviceDone != 7) { + + Status |= VL53L0X_WrByte(Dev, 0x80, 0x01); + Status |= VL53L0X_WrByte(Dev, 0xFF, 0x01); + Status |= VL53L0X_WrByte(Dev, 0x00, 0x00); + + Status |= VL53L0X_WrByte(Dev, 0xFF, 0x06); + Status |= VL53L0X_RdByte(Dev, 0x83, &byte); + Status |= VL53L0X_WrByte(Dev, 0x83, byte|4); + Status |= VL53L0X_WrByte(Dev, 0xFF, 0x07); + Status |= VL53L0X_WrByte(Dev, 0x81, 0x01); + + Status |= VL53L0X_PollingDelay(Dev); + + Status |= VL53L0X_WrByte(Dev, 0x80, 0x01); + + if (((option & 1) == 1) && + ((ReadDataFromDeviceDone & 1) == 0)) { + Status |= VL53L0X_WrByte(Dev, 0x94, 0x6b); + Status |= VL53L0X_device_read_strobe(Dev); + Status |= VL53L0X_RdDWord(Dev, 0x90, &TmpDWord); + + ReferenceSpadCount = (uint8_t)((TmpDWord >> 8) & 0x07f); + ReferenceSpadType = (uint8_t)((TmpDWord >> 15) & 0x01); + + Status |= VL53L0X_WrByte(Dev, 0x94, 0x24); + Status |= VL53L0X_device_read_strobe(Dev); + Status |= VL53L0X_RdDWord(Dev, 0x90, &TmpDWord); + + + NvmRefGoodSpadMap[0] = (uint8_t)((TmpDWord >> 24) + & 0xff); + NvmRefGoodSpadMap[1] = (uint8_t)((TmpDWord >> 16) + & 0xff); + NvmRefGoodSpadMap[2] = (uint8_t)((TmpDWord >> 8) + & 0xff); + NvmRefGoodSpadMap[3] = (uint8_t)(TmpDWord & 0xff); + + Status |= VL53L0X_WrByte(Dev, 0x94, 0x25); + Status |= VL53L0X_device_read_strobe(Dev); + Status |= VL53L0X_RdDWord(Dev, 0x90, &TmpDWord); + + NvmRefGoodSpadMap[4] = (uint8_t)((TmpDWord >> 24) + & 0xff); + NvmRefGoodSpadMap[5] = (uint8_t)((TmpDWord >> 16) + & 0xff); + } + + if (((option & 2) == 2) && + ((ReadDataFromDeviceDone & 2) == 0)) { + + Status |= VL53L0X_WrByte(Dev, 0x94, 0x02); + Status |= VL53L0X_device_read_strobe(Dev); + Status |= VL53L0X_RdByte(Dev, 0x90, &ModuleId); + + Status |= VL53L0X_WrByte(Dev, 0x94, 0x7B); + Status |= VL53L0X_device_read_strobe(Dev); + Status |= VL53L0X_RdByte(Dev, 0x90, &Revision); + + Status |= VL53L0X_WrByte(Dev, 0x94, 0x77); + Status |= VL53L0X_device_read_strobe(Dev); + Status |= VL53L0X_RdDWord(Dev, 0x90, &TmpDWord); + + ProductId[0] = (char)((TmpDWord >> 25) & 0x07f); + ProductId[1] = (char)((TmpDWord >> 18) & 0x07f); + ProductId[2] = (char)((TmpDWord >> 11) & 0x07f); + ProductId[3] = (char)((TmpDWord >> 4) & 0x07f); + + byte = (uint8_t)((TmpDWord & 0x00f) << 3); + + Status |= VL53L0X_WrByte(Dev, 0x94, 0x78); + Status |= VL53L0X_device_read_strobe(Dev); + Status |= VL53L0X_RdDWord(Dev, 0x90, &TmpDWord); + + ProductId[4] = (char)(byte + + ((TmpDWord >> 29) & 0x07f)); + ProductId[5] = (char)((TmpDWord >> 22) & 0x07f); + ProductId[6] = (char)((TmpDWord >> 15) & 0x07f); + ProductId[7] = (char)((TmpDWord >> 8) & 0x07f); + ProductId[8] = (char)((TmpDWord >> 1) & 0x07f); + + byte = (uint8_t)((TmpDWord & 0x001) << 6); + + Status |= VL53L0X_WrByte(Dev, 0x94, 0x79); + + Status |= VL53L0X_device_read_strobe(Dev); + + Status |= VL53L0X_RdDWord(Dev, 0x90, &TmpDWord); + + ProductId[9] = (char)(byte + + ((TmpDWord >> 26) & 0x07f)); + ProductId[10] = (char)((TmpDWord >> 19) & 0x07f); + ProductId[11] = (char)((TmpDWord >> 12) & 0x07f); + ProductId[12] = (char)((TmpDWord >> 5) & 0x07f); + + byte = (uint8_t)((TmpDWord & 0x01f) << 2); + + Status |= VL53L0X_WrByte(Dev, 0x94, 0x7A); + + Status |= VL53L0X_device_read_strobe(Dev); + + Status |= VL53L0X_RdDWord(Dev, 0x90, &TmpDWord); + + ProductId[13] = (char)(byte + + ((TmpDWord >> 30) & 0x07f)); + ProductId[14] = (char)((TmpDWord >> 23) & 0x07f); + ProductId[15] = (char)((TmpDWord >> 16) & 0x07f); + ProductId[16] = (char)((TmpDWord >> 9) & 0x07f); + ProductId[17] = (char)((TmpDWord >> 2) & 0x07f); + ProductId[18] = '\0'; + + } + + if (((option & 4) == 4) && + ((ReadDataFromDeviceDone & 4) == 0)) { + + Status |= VL53L0X_WrByte(Dev, 0x94, 0x7B); + Status |= VL53L0X_device_read_strobe(Dev); + Status |= VL53L0X_RdDWord(Dev, 0x90, &PartUIDUpper); + + Status |= VL53L0X_WrByte(Dev, 0x94, 0x7C); + Status |= VL53L0X_device_read_strobe(Dev); + Status |= VL53L0X_RdDWord(Dev, 0x90, &PartUIDLower); + + Status |= VL53L0X_WrByte(Dev, 0x94, 0x73); + Status |= VL53L0X_device_read_strobe(Dev); + Status |= VL53L0X_RdDWord(Dev, 0x90, &TmpDWord); + + SignalRateMeasFixed1104_400_mm = (TmpDWord & + 0x0000000ff) << 8; + + Status |= VL53L0X_WrByte(Dev, 0x94, 0x74); + Status |= VL53L0X_device_read_strobe(Dev); + Status |= VL53L0X_RdDWord(Dev, 0x90, &TmpDWord); + + SignalRateMeasFixed1104_400_mm |= ((TmpDWord & + 0xff000000) >> 24); + + Status |= VL53L0X_WrByte(Dev, 0x94, 0x75); + Status |= VL53L0X_device_read_strobe(Dev); + Status |= VL53L0X_RdDWord(Dev, 0x90, &TmpDWord); + + DistMeasFixed1104_400_mm = (TmpDWord & 0x0000000ff) + << 8; + + Status |= VL53L0X_WrByte(Dev, 0x94, 0x76); + Status |= VL53L0X_device_read_strobe(Dev); + Status |= VL53L0X_RdDWord(Dev, 0x90, &TmpDWord); + + DistMeasFixed1104_400_mm |= ((TmpDWord & 0xff000000) + >> 24); + } + + Status |= VL53L0X_WrByte(Dev, 0x81, 0x00); + Status |= VL53L0X_WrByte(Dev, 0xFF, 0x06); + Status |= VL53L0X_RdByte(Dev, 0x83, &byte); + Status |= VL53L0X_WrByte(Dev, 0x83, byte&0xfb); + Status |= VL53L0X_WrByte(Dev, 0xFF, 0x01); + Status |= VL53L0X_WrByte(Dev, 0x00, 0x01); + + Status |= VL53L0X_WrByte(Dev, 0xFF, 0x00); + Status |= VL53L0X_WrByte(Dev, 0x80, 0x00); + } + + if ((Status == VL53L0X_ERROR_NONE) && + (ReadDataFromDeviceDone != 7)) { + /* Assign to variable if status is ok */ + if (((option & 1) == 1) && + ((ReadDataFromDeviceDone & 1) == 0)) { + VL53L0X_SETDEVICESPECIFICPARAMETER(Dev, + ReferenceSpadCount, ReferenceSpadCount); + + VL53L0X_SETDEVICESPECIFICPARAMETER(Dev, + ReferenceSpadType, ReferenceSpadType); + + for (i = 0; i < VL53L0X_REF_SPAD_BUFFER_SIZE; i++) { + Dev->Data.SpadData.RefGoodSpadMap[i] = + NvmRefGoodSpadMap[i]; + } + } + + if (((option & 2) == 2) && + ((ReadDataFromDeviceDone & 2) == 0)) { + VL53L0X_SETDEVICESPECIFICPARAMETER(Dev, + ModuleId, ModuleId); + + VL53L0X_SETDEVICESPECIFICPARAMETER(Dev, + Revision, Revision); + + ProductId_tmp = VL53L0X_GETDEVICESPECIFICPARAMETER(Dev, + ProductId); + VL53L0X_COPYSTRING(ProductId_tmp, ProductId); + + } + + if (((option & 4) == 4) && + ((ReadDataFromDeviceDone & 4) == 0)) { + VL53L0X_SETDEVICESPECIFICPARAMETER(Dev, + PartUIDUpper, PartUIDUpper); + + VL53L0X_SETDEVICESPECIFICPARAMETER(Dev, + PartUIDLower, PartUIDLower); + + SignalRateMeasFixed400mmFix = + VL53L0X_FIXPOINT97TOFIXPOINT1616( + SignalRateMeasFixed1104_400_mm); + + VL53L0X_SETDEVICESPECIFICPARAMETER(Dev, + SignalRateMeasFixed400mm, + SignalRateMeasFixed400mmFix); + + OffsetMicroMeters = 0; + if (DistMeasFixed1104_400_mm != 0) { + OffsetFixed1104_mm = + DistMeasFixed1104_400_mm - + DistMeasTgtFixed1104_mm; + OffsetMicroMeters = (OffsetFixed1104_mm + * 1000) >> 4; + OffsetMicroMeters *= -1; + } + + PALDevDataSet(Dev, + Part2PartOffsetAdjustmentNVMMicroMeter, + OffsetMicroMeters); + } + byte = (uint8_t)(ReadDataFromDeviceDone|option); + VL53L0X_SETDEVICESPECIFICPARAMETER(Dev, ReadDataFromDeviceDone, + byte); + } + + LOG_FUNCTION_END(Status); + return Status; +} + + +uint32_t VL53L0X_calc_macro_period_ps(VL53L0X_DEV Dev, uint8_t vcsel_period_pclks) +{ + uint64_t PLL_period_ps; + uint32_t macro_period_vclks; + uint32_t macro_period_ps; + + LOG_FUNCTION_START(""); + + /* The above calculation will produce rounding errors, + therefore set fixed value + */ + PLL_period_ps = 1655; + + macro_period_vclks = 2304; + macro_period_ps = (uint32_t)(macro_period_vclks + * vcsel_period_pclks * PLL_period_ps); + + LOG_FUNCTION_END(""); + return macro_period_ps; +} + +uint16_t VL53L0X_encode_timeout(uint32_t timeout_macro_clks) +{ + /*! + * Encode timeout in macro periods in (LSByte * 2^MSByte) + 1 format + */ + + uint16_t encoded_timeout = 0; + uint32_t ls_byte = 0; + uint16_t ms_byte = 0; + + if (timeout_macro_clks > 0) { + ls_byte = timeout_macro_clks - 1; + + while ((ls_byte & 0xFFFFFF00) > 0) { + ls_byte = ls_byte >> 1; + ms_byte++; + } + + encoded_timeout = (ms_byte << 8) + + (uint16_t) (ls_byte & 0x000000FF); + } + + return encoded_timeout; + +} + +uint32_t VL53L0X_decode_timeout(uint16_t encoded_timeout) +{ + /*! + * Decode 16-bit timeout register value - format (LSByte * 2^MSByte) + 1 + */ + + uint32_t timeout_macro_clks = 0; + + timeout_macro_clks = ((uint32_t) (encoded_timeout & 0x00FF) + << (uint32_t) ((encoded_timeout & 0xFF00) >> 8)) + 1; + + return timeout_macro_clks; +} + + +/* To convert ms into register value */ +uint32_t VL53L0X_calc_timeout_mclks(VL53L0X_DEV Dev, + uint32_t timeout_period_us, + uint8_t vcsel_period_pclks) +{ + uint32_t macro_period_ps; + uint32_t macro_period_ns; + uint32_t timeout_period_mclks = 0; + + macro_period_ps = VL53L0X_calc_macro_period_ps(Dev, vcsel_period_pclks); + macro_period_ns = (macro_period_ps + 500) / 1000; + + timeout_period_mclks = + (uint32_t) (((timeout_period_us * 1000) + + (macro_period_ns / 2)) / macro_period_ns); + + return timeout_period_mclks; +} + +/* To convert register value into us */ +uint32_t VL53L0X_calc_timeout_us(VL53L0X_DEV Dev, + uint16_t timeout_period_mclks, + uint8_t vcsel_period_pclks) +{ + uint32_t macro_period_ps; + uint32_t macro_period_ns; + uint32_t actual_timeout_period_us = 0; + + macro_period_ps = VL53L0X_calc_macro_period_ps(Dev, vcsel_period_pclks); + macro_period_ns = (macro_period_ps + 500) / 1000; + + actual_timeout_period_us = + ((timeout_period_mclks * macro_period_ns) + 500) / 1000; + + return actual_timeout_period_us; +} + + +VL53L0X_Error get_sequence_step_timeout(VL53L0X_DEV Dev, + VL53L0X_SequenceStepId SequenceStepId, + uint32_t *pTimeOutMicroSecs) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + uint8_t CurrentVCSELPulsePeriodPClk; + uint8_t EncodedTimeOutByte = 0; + uint32_t TimeoutMicroSeconds = 0; + uint16_t PreRangeEncodedTimeOut = 0; + uint16_t MsrcTimeOutMClks; + uint16_t PreRangeTimeOutMClks; + uint16_t FinalRangeTimeOutMClks = 0; + uint16_t FinalRangeEncodedTimeOut; + VL53L0X_SchedulerSequenceSteps_t SchedulerSequenceSteps; + + if ((SequenceStepId == VL53L0X_SEQUENCESTEP_TCC) || + (SequenceStepId == VL53L0X_SEQUENCESTEP_DSS) || + (SequenceStepId == VL53L0X_SEQUENCESTEP_MSRC)) { + + Status = VL53L0X_GetVcselPulsePeriod(Dev, + VL53L0X_VCSEL_PERIOD_PRE_RANGE, + &CurrentVCSELPulsePeriodPClk); + if (Status == VL53L0X_ERROR_NONE) { + Status = VL53L0X_RdByte(Dev, + VL53L0X_REG_MSRC_CONFIG_TIMEOUT_MACROP, + &EncodedTimeOutByte); + } + MsrcTimeOutMClks = VL53L0X_decode_timeout(EncodedTimeOutByte); + + TimeoutMicroSeconds = VL53L0X_calc_timeout_us(Dev, + MsrcTimeOutMClks, + CurrentVCSELPulsePeriodPClk); + } else if (SequenceStepId == VL53L0X_SEQUENCESTEP_PRE_RANGE) { + /* Retrieve PRE-RANGE VCSEL Period */ + Status = VL53L0X_GetVcselPulsePeriod(Dev, + VL53L0X_VCSEL_PERIOD_PRE_RANGE, + &CurrentVCSELPulsePeriodPClk); + + /* Retrieve PRE-RANGE Timeout in Macro periods (MCLKS) */ + if (Status == VL53L0X_ERROR_NONE) { + + /* Retrieve PRE-RANGE VCSEL Period */ + Status = VL53L0X_GetVcselPulsePeriod(Dev, + VL53L0X_VCSEL_PERIOD_PRE_RANGE, + &CurrentVCSELPulsePeriodPClk); + + if (Status == VL53L0X_ERROR_NONE) { + Status = VL53L0X_RdWord(Dev, + VL53L0X_REG_PRE_RANGE_CONFIG_TIMEOUT_MACROP_HI, + &PreRangeEncodedTimeOut); + } + + PreRangeTimeOutMClks = VL53L0X_decode_timeout( + PreRangeEncodedTimeOut); + + TimeoutMicroSeconds = VL53L0X_calc_timeout_us(Dev, + PreRangeTimeOutMClks, + CurrentVCSELPulsePeriodPClk); + } + } else if (SequenceStepId == VL53L0X_SEQUENCESTEP_FINAL_RANGE) { + + VL53L0X_GetSequenceStepEnables(Dev, &SchedulerSequenceSteps); + PreRangeTimeOutMClks = 0; + + if (SchedulerSequenceSteps.PreRangeOn) { + /* Retrieve PRE-RANGE VCSEL Period */ + Status = VL53L0X_GetVcselPulsePeriod(Dev, + VL53L0X_VCSEL_PERIOD_PRE_RANGE, + &CurrentVCSELPulsePeriodPClk); + + /* Retrieve PRE-RANGE Timeout in Macro periods + * (MCLKS) */ + if (Status == VL53L0X_ERROR_NONE) { + Status = VL53L0X_RdWord(Dev, + VL53L0X_REG_PRE_RANGE_CONFIG_TIMEOUT_MACROP_HI, + &PreRangeEncodedTimeOut); + PreRangeTimeOutMClks = VL53L0X_decode_timeout( + PreRangeEncodedTimeOut); + } + } + + if (Status == VL53L0X_ERROR_NONE) { + /* Retrieve FINAL-RANGE VCSEL Period */ + Status = VL53L0X_GetVcselPulsePeriod(Dev, + VL53L0X_VCSEL_PERIOD_FINAL_RANGE, + &CurrentVCSELPulsePeriodPClk); + } + + /* Retrieve FINAL-RANGE Timeout in Macro periods (MCLKS) */ + if (Status == VL53L0X_ERROR_NONE) { + Status = VL53L0X_RdWord(Dev, + VL53L0X_REG_FINAL_RANGE_CONFIG_TIMEOUT_MACROP_HI, + &FinalRangeEncodedTimeOut); + FinalRangeTimeOutMClks = VL53L0X_decode_timeout( + FinalRangeEncodedTimeOut); + } + + FinalRangeTimeOutMClks -= PreRangeTimeOutMClks; + TimeoutMicroSeconds = VL53L0X_calc_timeout_us(Dev, + FinalRangeTimeOutMClks, + CurrentVCSELPulsePeriodPClk); + } + + *pTimeOutMicroSecs = TimeoutMicroSeconds; + + return Status; +} + + +VL53L0X_Error set_sequence_step_timeout(VL53L0X_DEV Dev, + VL53L0X_SequenceStepId SequenceStepId, + uint32_t TimeOutMicroSecs) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + uint8_t CurrentVCSELPulsePeriodPClk; + uint8_t MsrcEncodedTimeOut; + uint16_t PreRangeEncodedTimeOut; + uint16_t PreRangeTimeOutMClks; + uint16_t MsrcRangeTimeOutMClks; + uint32_t FinalRangeTimeOutMClks; + uint16_t FinalRangeEncodedTimeOut; + VL53L0X_SchedulerSequenceSteps_t SchedulerSequenceSteps; + + if ((SequenceStepId == VL53L0X_SEQUENCESTEP_TCC) || + (SequenceStepId == VL53L0X_SEQUENCESTEP_DSS) || + (SequenceStepId == VL53L0X_SEQUENCESTEP_MSRC)) { + + Status = VL53L0X_GetVcselPulsePeriod(Dev, + VL53L0X_VCSEL_PERIOD_PRE_RANGE, + &CurrentVCSELPulsePeriodPClk); + + if (Status == VL53L0X_ERROR_NONE) { + MsrcRangeTimeOutMClks = VL53L0X_calc_timeout_mclks(Dev, + TimeOutMicroSecs, + (uint8_t)CurrentVCSELPulsePeriodPClk); + + if (MsrcRangeTimeOutMClks > 256) + MsrcEncodedTimeOut = 255; + else + MsrcEncodedTimeOut = + (uint8_t)MsrcRangeTimeOutMClks - 1; + + VL53L0X_SETDEVICESPECIFICPARAMETER(Dev, + LastEncodedTimeout, + MsrcEncodedTimeOut); + } + + if (Status == VL53L0X_ERROR_NONE) { + Status = VL53L0X_WrByte(Dev, + VL53L0X_REG_MSRC_CONFIG_TIMEOUT_MACROP, + MsrcEncodedTimeOut); + } + } else { + + if (SequenceStepId == VL53L0X_SEQUENCESTEP_PRE_RANGE) { + + if (Status == VL53L0X_ERROR_NONE) { + Status = VL53L0X_GetVcselPulsePeriod(Dev, + VL53L0X_VCSEL_PERIOD_PRE_RANGE, + &CurrentVCSELPulsePeriodPClk); + PreRangeTimeOutMClks = + VL53L0X_calc_timeout_mclks(Dev, + TimeOutMicroSecs, + (uint8_t)CurrentVCSELPulsePeriodPClk); + PreRangeEncodedTimeOut = VL53L0X_encode_timeout( + PreRangeTimeOutMClks); + + VL53L0X_SETDEVICESPECIFICPARAMETER(Dev, + LastEncodedTimeout, + PreRangeEncodedTimeOut); + } + + if (Status == VL53L0X_ERROR_NONE) { + Status = VL53L0X_WrWord(Dev, + VL53L0X_REG_PRE_RANGE_CONFIG_TIMEOUT_MACROP_HI, + PreRangeEncodedTimeOut); + } + + if (Status == VL53L0X_ERROR_NONE) { + VL53L0X_SETDEVICESPECIFICPARAMETER( + Dev, + PreRangeTimeoutMicroSecs, + TimeOutMicroSecs); + } + } else if (SequenceStepId == VL53L0X_SEQUENCESTEP_FINAL_RANGE) { + + /* For the final range timeout, the pre-range timeout + * must be added. To do this both final and pre-range + * timeouts must be expressed in macro periods MClks + * because they have different vcsel periods. + */ + + VL53L0X_GetSequenceStepEnables(Dev, + &SchedulerSequenceSteps); + PreRangeTimeOutMClks = 0; + if (SchedulerSequenceSteps.PreRangeOn) { + + /* Retrieve PRE-RANGE VCSEL Period */ + Status = VL53L0X_GetVcselPulsePeriod(Dev, + VL53L0X_VCSEL_PERIOD_PRE_RANGE, + &CurrentVCSELPulsePeriodPClk); + + /* Retrieve PRE-RANGE Timeout in Macro periods + * (MCLKS) */ + if (Status == VL53L0X_ERROR_NONE) { + Status = VL53L0X_RdWord(Dev, 0x51, + &PreRangeEncodedTimeOut); + PreRangeTimeOutMClks = + VL53L0X_decode_timeout( + PreRangeEncodedTimeOut); + } + } + + /* Calculate FINAL RANGE Timeout in Macro Periods + * (MCLKS) and add PRE-RANGE value + */ + if (Status == VL53L0X_ERROR_NONE) { + + Status = VL53L0X_GetVcselPulsePeriod(Dev, + VL53L0X_VCSEL_PERIOD_FINAL_RANGE, + &CurrentVCSELPulsePeriodPClk); + } + if (Status == VL53L0X_ERROR_NONE) { + + FinalRangeTimeOutMClks = + VL53L0X_calc_timeout_mclks(Dev, + TimeOutMicroSecs, + (uint8_t) CurrentVCSELPulsePeriodPClk); + + FinalRangeTimeOutMClks += PreRangeTimeOutMClks; + + FinalRangeEncodedTimeOut = + VL53L0X_encode_timeout(FinalRangeTimeOutMClks); + + if (Status == VL53L0X_ERROR_NONE) { + Status = VL53L0X_WrWord(Dev, 0x71, + FinalRangeEncodedTimeOut); + } + + if (Status == VL53L0X_ERROR_NONE) { + VL53L0X_SETDEVICESPECIFICPARAMETER( + Dev, + FinalRangeTimeoutMicroSecs, + TimeOutMicroSecs); + } + } + } else + Status = VL53L0X_ERROR_INVALID_PARAMS; + + } + return Status; +} + +VL53L0X_Error VL53L0X_set_vcsel_pulse_period(VL53L0X_DEV Dev, + VL53L0X_VcselPeriod VcselPeriodType, uint8_t VCSELPulsePeriodPCLK) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + uint8_t vcsel_period_reg; + uint8_t MinPreVcselPeriodPCLK = 12; + uint8_t MaxPreVcselPeriodPCLK = 18; + uint8_t MinFinalVcselPeriodPCLK = 8; + uint8_t MaxFinalVcselPeriodPCLK = 14; + uint32_t MeasurementTimingBudgetMicroSeconds; + uint32_t FinalRangeTimeoutMicroSeconds; + uint32_t PreRangeTimeoutMicroSeconds; + uint32_t MsrcTimeoutMicroSeconds; + uint8_t PhaseCalInt = 0; + + /* Check if valid clock period requested */ + + if ((VCSELPulsePeriodPCLK % 2) != 0) { + /* Value must be an even number */ + Status = VL53L0X_ERROR_INVALID_PARAMS; + } else if (VcselPeriodType == VL53L0X_VCSEL_PERIOD_PRE_RANGE && + (VCSELPulsePeriodPCLK < MinPreVcselPeriodPCLK || + VCSELPulsePeriodPCLK > MaxPreVcselPeriodPCLK)) { + Status = VL53L0X_ERROR_INVALID_PARAMS; + } else if (VcselPeriodType == VL53L0X_VCSEL_PERIOD_FINAL_RANGE && + (VCSELPulsePeriodPCLK < MinFinalVcselPeriodPCLK || + VCSELPulsePeriodPCLK > MaxFinalVcselPeriodPCLK)) { + + Status = VL53L0X_ERROR_INVALID_PARAMS; + } + + /* Apply specific settings for the requested clock period */ + + if (Status != VL53L0X_ERROR_NONE) + return Status; + + + if (VcselPeriodType == VL53L0X_VCSEL_PERIOD_PRE_RANGE) { + + /* Set phase check limits */ + if (VCSELPulsePeriodPCLK == 12) { + + Status = VL53L0X_WrByte(Dev, + VL53L0X_REG_PRE_RANGE_CONFIG_VALID_PHASE_HIGH, + 0x18); + Status = VL53L0X_WrByte(Dev, + VL53L0X_REG_PRE_RANGE_CONFIG_VALID_PHASE_LOW, + 0x08); + } else if (VCSELPulsePeriodPCLK == 14) { + + Status = VL53L0X_WrByte(Dev, + VL53L0X_REG_PRE_RANGE_CONFIG_VALID_PHASE_HIGH, + 0x30); + Status = VL53L0X_WrByte(Dev, + VL53L0X_REG_PRE_RANGE_CONFIG_VALID_PHASE_LOW, + 0x08); + } else if (VCSELPulsePeriodPCLK == 16) { + + Status = VL53L0X_WrByte(Dev, + VL53L0X_REG_PRE_RANGE_CONFIG_VALID_PHASE_HIGH, + 0x40); + Status = VL53L0X_WrByte(Dev, + VL53L0X_REG_PRE_RANGE_CONFIG_VALID_PHASE_LOW, + 0x08); + } else if (VCSELPulsePeriodPCLK == 18) { + + Status = VL53L0X_WrByte(Dev, + VL53L0X_REG_PRE_RANGE_CONFIG_VALID_PHASE_HIGH, + 0x50); + Status = VL53L0X_WrByte(Dev, + VL53L0X_REG_PRE_RANGE_CONFIG_VALID_PHASE_LOW, + 0x08); + } + } else if (VcselPeriodType == VL53L0X_VCSEL_PERIOD_FINAL_RANGE) { + + if (VCSELPulsePeriodPCLK == 8) { + + Status = VL53L0X_WrByte(Dev, + VL53L0X_REG_FINAL_RANGE_CONFIG_VALID_PHASE_HIGH, + 0x10); + Status = VL53L0X_WrByte(Dev, + VL53L0X_REG_FINAL_RANGE_CONFIG_VALID_PHASE_LOW, + 0x08); + + Status |= VL53L0X_WrByte(Dev, + VL53L0X_REG_GLOBAL_CONFIG_VCSEL_WIDTH, 0x02); + Status |= VL53L0X_WrByte(Dev, + VL53L0X_REG_ALGO_PHASECAL_CONFIG_TIMEOUT, 0x0C); + + Status |= VL53L0X_WrByte(Dev, 0xff, 0x01); + Status |= VL53L0X_WrByte(Dev, + VL53L0X_REG_ALGO_PHASECAL_LIM, + 0x30); + Status |= VL53L0X_WrByte(Dev, 0xff, 0x00); + } else if (VCSELPulsePeriodPCLK == 10) { + + Status = VL53L0X_WrByte(Dev, + VL53L0X_REG_FINAL_RANGE_CONFIG_VALID_PHASE_HIGH, + 0x28); + Status = VL53L0X_WrByte(Dev, + VL53L0X_REG_FINAL_RANGE_CONFIG_VALID_PHASE_LOW, + 0x08); + + Status |= VL53L0X_WrByte(Dev, + VL53L0X_REG_GLOBAL_CONFIG_VCSEL_WIDTH, 0x03); + Status |= VL53L0X_WrByte(Dev, + VL53L0X_REG_ALGO_PHASECAL_CONFIG_TIMEOUT, 0x09); + + Status |= VL53L0X_WrByte(Dev, 0xff, 0x01); + Status |= VL53L0X_WrByte(Dev, + VL53L0X_REG_ALGO_PHASECAL_LIM, + 0x20); + Status |= VL53L0X_WrByte(Dev, 0xff, 0x00); + } else if (VCSELPulsePeriodPCLK == 12) { + + Status = VL53L0X_WrByte(Dev, + VL53L0X_REG_FINAL_RANGE_CONFIG_VALID_PHASE_HIGH, + 0x38); + Status = VL53L0X_WrByte(Dev, + VL53L0X_REG_FINAL_RANGE_CONFIG_VALID_PHASE_LOW, + 0x08); + + Status |= VL53L0X_WrByte(Dev, + VL53L0X_REG_GLOBAL_CONFIG_VCSEL_WIDTH, 0x03); + Status |= VL53L0X_WrByte(Dev, + VL53L0X_REG_ALGO_PHASECAL_CONFIG_TIMEOUT, 0x08); + + Status |= VL53L0X_WrByte(Dev, 0xff, 0x01); + Status |= VL53L0X_WrByte(Dev, + VL53L0X_REG_ALGO_PHASECAL_LIM, + 0x20); + Status |= VL53L0X_WrByte(Dev, 0xff, 0x00); + } else if (VCSELPulsePeriodPCLK == 14) { + + Status = VL53L0X_WrByte(Dev, + VL53L0X_REG_FINAL_RANGE_CONFIG_VALID_PHASE_HIGH, + 0x048); + Status = VL53L0X_WrByte(Dev, + VL53L0X_REG_FINAL_RANGE_CONFIG_VALID_PHASE_LOW, + 0x08); + + Status |= VL53L0X_WrByte(Dev, + VL53L0X_REG_GLOBAL_CONFIG_VCSEL_WIDTH, 0x03); + Status |= VL53L0X_WrByte(Dev, + VL53L0X_REG_ALGO_PHASECAL_CONFIG_TIMEOUT, 0x07); + + Status |= VL53L0X_WrByte(Dev, 0xff, 0x01); + Status |= VL53L0X_WrByte(Dev, + VL53L0X_REG_ALGO_PHASECAL_LIM, + 0x20); + Status |= VL53L0X_WrByte(Dev, 0xff, 0x00); + } + } + + + /* Re-calculate and apply timeouts, in macro periods */ + + if (Status == VL53L0X_ERROR_NONE) { + vcsel_period_reg = VL53L0X_encode_vcsel_period((uint8_t) + VCSELPulsePeriodPCLK); + + /* When the VCSEL period for the pre or final range is changed, + * the corresponding timeout must be read from the device using + * the current VCSEL period, then the new VCSEL period can be + * applied. The timeout then must be written back to the device + * using the new VCSEL period. + * + * For the MSRC timeout, the same applies - this timeout being + * dependant on the pre-range vcsel period. + */ + switch (VcselPeriodType) { + case VL53L0X_VCSEL_PERIOD_PRE_RANGE: + Status = get_sequence_step_timeout(Dev, + VL53L0X_SEQUENCESTEP_PRE_RANGE, + &PreRangeTimeoutMicroSeconds); + + if (Status == VL53L0X_ERROR_NONE) + Status = get_sequence_step_timeout(Dev, + VL53L0X_SEQUENCESTEP_MSRC, + &MsrcTimeoutMicroSeconds); + + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_WrByte(Dev, + VL53L0X_REG_PRE_RANGE_CONFIG_VCSEL_PERIOD, + vcsel_period_reg); + + + if (Status == VL53L0X_ERROR_NONE) + Status = set_sequence_step_timeout(Dev, + VL53L0X_SEQUENCESTEP_PRE_RANGE, + PreRangeTimeoutMicroSeconds); + + + if (Status == VL53L0X_ERROR_NONE) + Status = set_sequence_step_timeout(Dev, + VL53L0X_SEQUENCESTEP_MSRC, + MsrcTimeoutMicroSeconds); + + VL53L0X_SETDEVICESPECIFICPARAMETER( + Dev, + PreRangeVcselPulsePeriod, + VCSELPulsePeriodPCLK); + break; + case VL53L0X_VCSEL_PERIOD_FINAL_RANGE: + Status = get_sequence_step_timeout(Dev, + VL53L0X_SEQUENCESTEP_FINAL_RANGE, + &FinalRangeTimeoutMicroSeconds); + + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_WrByte(Dev, + VL53L0X_REG_FINAL_RANGE_CONFIG_VCSEL_PERIOD, + vcsel_period_reg); + + + if (Status == VL53L0X_ERROR_NONE) + Status = set_sequence_step_timeout(Dev, + VL53L0X_SEQUENCESTEP_FINAL_RANGE, + FinalRangeTimeoutMicroSeconds); + + VL53L0X_SETDEVICESPECIFICPARAMETER( + Dev, + FinalRangeVcselPulsePeriod, + VCSELPulsePeriodPCLK); + break; + default: + Status = VL53L0X_ERROR_INVALID_PARAMS; + } + } + + /* Finally, the timing budget must be re-applied */ + if (Status == VL53L0X_ERROR_NONE) { + VL53L0X_GETPARAMETERFIELD(Dev, + MeasurementTimingBudgetMicroSeconds, + MeasurementTimingBudgetMicroSeconds); + + Status = VL53L0X_SetMeasurementTimingBudgetMicroSeconds(Dev, + MeasurementTimingBudgetMicroSeconds); + } + + /* Perform the phase calibration. This is needed after changing on + * vcsel period. + * get_data_enable = 0, restore_config = 1 */ + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_perform_phase_calibration( + Dev, &PhaseCalInt, 0, 1); + + return Status; +} + +VL53L0X_Error VL53L0X_get_vcsel_pulse_period(VL53L0X_DEV Dev, + VL53L0X_VcselPeriod VcselPeriodType, uint8_t *pVCSELPulsePeriodPCLK) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + uint8_t vcsel_period_reg; + + switch (VcselPeriodType) { + case VL53L0X_VCSEL_PERIOD_PRE_RANGE: + Status = VL53L0X_RdByte(Dev, + VL53L0X_REG_PRE_RANGE_CONFIG_VCSEL_PERIOD, + &vcsel_period_reg); + break; + case VL53L0X_VCSEL_PERIOD_FINAL_RANGE: + Status = VL53L0X_RdByte(Dev, + VL53L0X_REG_FINAL_RANGE_CONFIG_VCSEL_PERIOD, + &vcsel_period_reg); + break; + default: + Status = VL53L0X_ERROR_INVALID_PARAMS; + } + + if (Status == VL53L0X_ERROR_NONE) + *pVCSELPulsePeriodPCLK = + VL53L0X_decode_vcsel_period(vcsel_period_reg); + + return Status; +} + + + +VL53L0X_Error VL53L0X_set_measurement_timing_budget_micro_seconds(VL53L0X_DEV Dev, + uint32_t MeasurementTimingBudgetMicroSeconds) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + uint32_t FinalRangeTimingBudgetMicroSeconds; + VL53L0X_SchedulerSequenceSteps_t SchedulerSequenceSteps; + uint32_t MsrcDccTccTimeoutMicroSeconds = 2000; + uint32_t StartOverheadMicroSeconds = 1910; + uint32_t EndOverheadMicroSeconds = 960; + uint32_t MsrcOverheadMicroSeconds = 660; + uint32_t TccOverheadMicroSeconds = 590; + uint32_t DssOverheadMicroSeconds = 690; + uint32_t PreRangeOverheadMicroSeconds = 660; + uint32_t FinalRangeOverheadMicroSeconds = 550; + uint32_t PreRangeTimeoutMicroSeconds = 0; + uint32_t cMinTimingBudgetMicroSeconds = 20000; + uint32_t SubTimeout = 0; + + LOG_FUNCTION_START(""); + + if (MeasurementTimingBudgetMicroSeconds + < cMinTimingBudgetMicroSeconds) { + Status = VL53L0X_ERROR_INVALID_PARAMS; + return Status; + } + + FinalRangeTimingBudgetMicroSeconds = + MeasurementTimingBudgetMicroSeconds - + (StartOverheadMicroSeconds + EndOverheadMicroSeconds); + + Status = VL53L0X_GetSequenceStepEnables(Dev, &SchedulerSequenceSteps); + + if (Status == VL53L0X_ERROR_NONE && + (SchedulerSequenceSteps.TccOn || + SchedulerSequenceSteps.MsrcOn || + SchedulerSequenceSteps.DssOn)) { + + /* TCC, MSRC and DSS all share the same timeout */ + Status = get_sequence_step_timeout(Dev, + VL53L0X_SEQUENCESTEP_MSRC, + &MsrcDccTccTimeoutMicroSeconds); + + /* Subtract the TCC, MSRC and DSS timeouts if they are + * enabled. */ + + if (Status != VL53L0X_ERROR_NONE) + return Status; + + /* TCC */ + if (SchedulerSequenceSteps.TccOn) { + + SubTimeout = MsrcDccTccTimeoutMicroSeconds + + TccOverheadMicroSeconds; + + if (SubTimeout < + FinalRangeTimingBudgetMicroSeconds) { + FinalRangeTimingBudgetMicroSeconds -= + SubTimeout; + } else { + /* Requested timeout too big. */ + Status = VL53L0X_ERROR_INVALID_PARAMS; + } + } + + if (Status != VL53L0X_ERROR_NONE) { + LOG_FUNCTION_END(Status); + return Status; + } + + /* DSS */ + if (SchedulerSequenceSteps.DssOn) { + + SubTimeout = 2 * (MsrcDccTccTimeoutMicroSeconds + + DssOverheadMicroSeconds); + + if (SubTimeout < FinalRangeTimingBudgetMicroSeconds) { + FinalRangeTimingBudgetMicroSeconds + -= SubTimeout; + } else { + /* Requested timeout too big. */ + Status = VL53L0X_ERROR_INVALID_PARAMS; + } + } else if (SchedulerSequenceSteps.MsrcOn) { + /* MSRC */ + SubTimeout = MsrcDccTccTimeoutMicroSeconds + + MsrcOverheadMicroSeconds; + + if (SubTimeout < FinalRangeTimingBudgetMicroSeconds) { + FinalRangeTimingBudgetMicroSeconds + -= SubTimeout; + } else { + /* Requested timeout too big. */ + Status = VL53L0X_ERROR_INVALID_PARAMS; + } + } + + } + + if (Status != VL53L0X_ERROR_NONE) { + LOG_FUNCTION_END(Status); + return Status; + } + + if (SchedulerSequenceSteps.PreRangeOn) { + + /* Subtract the Pre-range timeout if enabled. */ + + Status = get_sequence_step_timeout(Dev, + VL53L0X_SEQUENCESTEP_PRE_RANGE, + &PreRangeTimeoutMicroSeconds); + + SubTimeout = PreRangeTimeoutMicroSeconds + + PreRangeOverheadMicroSeconds; + + if (SubTimeout < FinalRangeTimingBudgetMicroSeconds) { + FinalRangeTimingBudgetMicroSeconds -= SubTimeout; + } else { + /* Requested timeout too big. */ + Status = VL53L0X_ERROR_INVALID_PARAMS; + } + } + + + if (Status == VL53L0X_ERROR_NONE && + SchedulerSequenceSteps.FinalRangeOn) { + + FinalRangeTimingBudgetMicroSeconds -= + FinalRangeOverheadMicroSeconds; + + /* Final Range Timeout + * Note that the final range timeout is determined by the timing + * budget and the sum of all other timeouts within the sequence. + * If there is no room for the final range timeout, then an error + * will be set. Otherwise the remaining time will be applied to + * the final range. + */ + Status = set_sequence_step_timeout(Dev, + VL53L0X_SEQUENCESTEP_FINAL_RANGE, + FinalRangeTimingBudgetMicroSeconds); + + VL53L0X_SETPARAMETERFIELD(Dev, + MeasurementTimingBudgetMicroSeconds, + MeasurementTimingBudgetMicroSeconds); + } + + LOG_FUNCTION_END(Status); + + return Status; +} + +VL53L0X_Error VL53L0X_get_measurement_timing_budget_micro_seconds(VL53L0X_DEV Dev, + uint32_t *pMeasurementTimingBudgetMicroSeconds) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + VL53L0X_SchedulerSequenceSteps_t SchedulerSequenceSteps; + uint32_t FinalRangeTimeoutMicroSeconds; + uint32_t MsrcDccTccTimeoutMicroSeconds = 2000; + uint32_t StartOverheadMicroSeconds = 1910; + uint32_t EndOverheadMicroSeconds = 960; + uint32_t MsrcOverheadMicroSeconds = 660; + uint32_t TccOverheadMicroSeconds = 590; + uint32_t DssOverheadMicroSeconds = 690; + uint32_t PreRangeOverheadMicroSeconds = 660; + uint32_t FinalRangeOverheadMicroSeconds = 550; + uint32_t PreRangeTimeoutMicroSeconds = 0; + + LOG_FUNCTION_START(""); + + /* Start and end overhead times always present */ + *pMeasurementTimingBudgetMicroSeconds + = StartOverheadMicroSeconds + EndOverheadMicroSeconds; + + Status = VL53L0X_GetSequenceStepEnables(Dev, &SchedulerSequenceSteps); + + if (Status != VL53L0X_ERROR_NONE) { + LOG_FUNCTION_END(Status); + return Status; + } + + + if (SchedulerSequenceSteps.TccOn || + SchedulerSequenceSteps.MsrcOn || + SchedulerSequenceSteps.DssOn) { + + Status = get_sequence_step_timeout(Dev, + VL53L0X_SEQUENCESTEP_MSRC, + &MsrcDccTccTimeoutMicroSeconds); + + if (Status == VL53L0X_ERROR_NONE) { + if (SchedulerSequenceSteps.TccOn) { + *pMeasurementTimingBudgetMicroSeconds += + MsrcDccTccTimeoutMicroSeconds + + TccOverheadMicroSeconds; + } + + if (SchedulerSequenceSteps.DssOn) { + *pMeasurementTimingBudgetMicroSeconds += + 2 * (MsrcDccTccTimeoutMicroSeconds + + DssOverheadMicroSeconds); + } else if (SchedulerSequenceSteps.MsrcOn) { + *pMeasurementTimingBudgetMicroSeconds += + MsrcDccTccTimeoutMicroSeconds + + MsrcOverheadMicroSeconds; + } + } + } + + if (Status == VL53L0X_ERROR_NONE) { + if (SchedulerSequenceSteps.PreRangeOn) { + Status = get_sequence_step_timeout(Dev, + VL53L0X_SEQUENCESTEP_PRE_RANGE, + &PreRangeTimeoutMicroSeconds); + *pMeasurementTimingBudgetMicroSeconds += + PreRangeTimeoutMicroSeconds + + PreRangeOverheadMicroSeconds; + } + } + + if (Status == VL53L0X_ERROR_NONE) { + if (SchedulerSequenceSteps.FinalRangeOn) { + Status = get_sequence_step_timeout(Dev, + VL53L0X_SEQUENCESTEP_FINAL_RANGE, + &FinalRangeTimeoutMicroSeconds); + *pMeasurementTimingBudgetMicroSeconds += + (FinalRangeTimeoutMicroSeconds + + FinalRangeOverheadMicroSeconds); + } + } + + if (Status == VL53L0X_ERROR_NONE) { + VL53L0X_SETPARAMETERFIELD(Dev, + MeasurementTimingBudgetMicroSeconds, + *pMeasurementTimingBudgetMicroSeconds); + } + + LOG_FUNCTION_END(Status); + return Status; +} + + + +VL53L0X_Error VL53L0X_load_tuning_settings(VL53L0X_DEV Dev, + uint8_t *pTuningSettingBuffer) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + int i; + int Index; + uint8_t msb; + uint8_t lsb; + uint8_t SelectParam; + uint8_t NumberOfWrites; + uint8_t Address; + uint8_t localBuffer[4]; /* max */ + uint16_t Temp16; + + LOG_FUNCTION_START(""); + + Index = 0; + + while ((*(pTuningSettingBuffer + Index) != 0) && + (Status == VL53L0X_ERROR_NONE)) { + NumberOfWrites = *(pTuningSettingBuffer + Index); + Index++; + if (NumberOfWrites == 0xFF) { + /* internal parameters */ + SelectParam = *(pTuningSettingBuffer + Index); + Index++; + switch (SelectParam) { + case 0: /* uint16_t SigmaEstRefArray -> 2 bytes */ + msb = *(pTuningSettingBuffer + Index); + Index++; + lsb = *(pTuningSettingBuffer + Index); + Index++; + Temp16 = VL53L0X_MAKEUINT16(lsb, msb); + PALDevDataSet(Dev, SigmaEstRefArray, Temp16); + break; + case 1: /* uint16_t SigmaEstEffPulseWidth -> 2 bytes */ + msb = *(pTuningSettingBuffer + Index); + Index++; + lsb = *(pTuningSettingBuffer + Index); + Index++; + Temp16 = VL53L0X_MAKEUINT16(lsb, msb); + PALDevDataSet(Dev, SigmaEstEffPulseWidth, + Temp16); + break; + case 2: /* uint16_t SigmaEstEffAmbWidth -> 2 bytes */ + msb = *(pTuningSettingBuffer + Index); + Index++; + lsb = *(pTuningSettingBuffer + Index); + Index++; + Temp16 = VL53L0X_MAKEUINT16(lsb, msb); + PALDevDataSet(Dev, SigmaEstEffAmbWidth, Temp16); + break; + case 3: /* uint16_t targetRefRate -> 2 bytes */ + msb = *(pTuningSettingBuffer + Index); + Index++; + lsb = *(pTuningSettingBuffer + Index); + Index++; + Temp16 = VL53L0X_MAKEUINT16(lsb, msb); + PALDevDataSet(Dev, targetRefRate, Temp16); + break; + default: /* invalid parameter */ + Status = VL53L0X_ERROR_INVALID_PARAMS; + } + + } else if (NumberOfWrites <= 4) { + Address = *(pTuningSettingBuffer + Index); + Index++; + + for (i = 0; i < NumberOfWrites; i++) { + localBuffer[i] = *(pTuningSettingBuffer + + Index); + Index++; + } + + Status = VL53L0X_WriteMulti(Dev, Address, localBuffer, + NumberOfWrites); + + } else { + Status = VL53L0X_ERROR_INVALID_PARAMS; + } + } + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_get_total_xtalk_rate(VL53L0X_DEV Dev, + VL53L0X_RangingMeasurementData_t *pRangingMeasurementData, + FixPoint1616_t *ptotal_xtalk_rate_mcps) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + + uint8_t xtalkCompEnable; + FixPoint1616_t totalXtalkMegaCps; + FixPoint1616_t xtalkPerSpadMegaCps; + + *ptotal_xtalk_rate_mcps = 0; + + Status = VL53L0X_GetXTalkCompensationEnable(Dev, &xtalkCompEnable); + if (Status == VL53L0X_ERROR_NONE) { + + if (xtalkCompEnable) { + + VL53L0X_GETPARAMETERFIELD( + Dev, + XTalkCompensationRateMegaCps, + xtalkPerSpadMegaCps); + + /* FixPoint1616 * FixPoint 8:8 = FixPoint0824 */ + totalXtalkMegaCps = + pRangingMeasurementData->EffectiveSpadRtnCount * + xtalkPerSpadMegaCps; + + /* FixPoint0824 >> 8 = FixPoint1616 */ + *ptotal_xtalk_rate_mcps = + (totalXtalkMegaCps + 0x80) >> 8; + } + } + + return Status; +} + +VL53L0X_Error VL53L0X_get_total_signal_rate(VL53L0X_DEV Dev, + VL53L0X_RangingMeasurementData_t *pRangingMeasurementData, + FixPoint1616_t *ptotal_signal_rate_mcps) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + FixPoint1616_t totalXtalkMegaCps; + + LOG_FUNCTION_START(""); + + *ptotal_signal_rate_mcps = + pRangingMeasurementData->SignalRateRtnMegaCps; + + Status = VL53L0X_get_total_xtalk_rate( + Dev, pRangingMeasurementData, &totalXtalkMegaCps); + + if (Status == VL53L0X_ERROR_NONE) + *ptotal_signal_rate_mcps += totalXtalkMegaCps; + + return Status; +} + +VL53L0X_Error VL53L0X_calc_dmax( + VL53L0X_DEV Dev, + FixPoint1616_t totalSignalRate_mcps, + FixPoint1616_t totalCorrSignalRate_mcps, + FixPoint1616_t pwMult, + uint32_t sigmaEstimateP1, + FixPoint1616_t sigmaEstimateP2, + uint32_t peakVcselDuration_us, + uint32_t *pdmax_mm) +{ + const uint32_t cSigmaLimit = 18; + const FixPoint1616_t cSignalLimit = 0x4000; /* 0.25 */ + const FixPoint1616_t cSigmaEstRef = 0x00000042; /* 0.001 */ + const uint32_t cAmbEffWidthSigmaEst_ns = 6; + const uint32_t cAmbEffWidthDMax_ns = 7; + uint32_t dmaxCalRange_mm; + FixPoint1616_t dmaxCalSignalRateRtn_mcps; + FixPoint1616_t minSignalNeeded; + FixPoint1616_t minSignalNeeded_p1; + FixPoint1616_t minSignalNeeded_p2; + FixPoint1616_t minSignalNeeded_p3; + FixPoint1616_t minSignalNeeded_p4; + FixPoint1616_t sigmaLimitTmp; + FixPoint1616_t sigmaEstSqTmp; + FixPoint1616_t signalLimitTmp; + FixPoint1616_t SignalAt0mm; + FixPoint1616_t dmaxDark; + FixPoint1616_t dmaxAmbient; + FixPoint1616_t dmaxDarkTmp; + FixPoint1616_t sigmaEstP2Tmp; + uint32_t signalRateTemp_mcps; + + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + + LOG_FUNCTION_START(""); + + dmaxCalRange_mm = + PALDevDataGet(Dev, DmaxCalRangeMilliMeter); + + dmaxCalSignalRateRtn_mcps = + PALDevDataGet(Dev, DmaxCalSignalRateRtnMegaCps); + + /* uint32 * FixPoint1616 = FixPoint1616 */ + SignalAt0mm = dmaxCalRange_mm * dmaxCalSignalRateRtn_mcps; + + /* FixPoint1616 >> 8 = FixPoint2408 */ + SignalAt0mm = (SignalAt0mm + 0x80) >> 8; + SignalAt0mm *= dmaxCalRange_mm; + + minSignalNeeded_p1 = 0; + if (totalCorrSignalRate_mcps > 0) { + + /* Shift by 10 bits to increase resolution prior to the + * division */ + signalRateTemp_mcps = totalSignalRate_mcps << 10; + + /* Add rounding value prior to division */ + minSignalNeeded_p1 = signalRateTemp_mcps + + (totalCorrSignalRate_mcps/2); + + /* FixPoint0626/FixPoint1616 = FixPoint2210 */ + minSignalNeeded_p1 /= totalCorrSignalRate_mcps; + + /* Apply a factored version of the speed of light. + Correction to be applied at the end */ + minSignalNeeded_p1 *= 3; + + /* FixPoint2210 * FixPoint2210 = FixPoint1220 */ + minSignalNeeded_p1 *= minSignalNeeded_p1; + + /* FixPoint1220 >> 16 = FixPoint2804 */ + minSignalNeeded_p1 = (minSignalNeeded_p1 + 0x8000) >> 16; + } + + minSignalNeeded_p2 = pwMult * sigmaEstimateP1; + + /* FixPoint1616 >> 16 = uint32 */ + minSignalNeeded_p2 = (minSignalNeeded_p2 + 0x8000) >> 16; + + /* uint32 * uint32 = uint32 */ + minSignalNeeded_p2 *= minSignalNeeded_p2; + + /* Check sigmaEstimateP2 + * If this value is too high there is not enough signal rate + * to calculate dmax value so set a suitable value to ensure + * a very small dmax. + */ + sigmaEstP2Tmp = (sigmaEstimateP2 + 0x8000) >> 16; + sigmaEstP2Tmp = (sigmaEstP2Tmp + cAmbEffWidthSigmaEst_ns/2)/ + cAmbEffWidthSigmaEst_ns; + sigmaEstP2Tmp *= cAmbEffWidthDMax_ns; + + if (sigmaEstP2Tmp > 0xffff) { + minSignalNeeded_p3 = 0xfff00000; + } else { + + /* DMAX uses a different ambient width from sigma, so apply + * correction. + * Perform division before multiplication to prevent overflow. + */ + sigmaEstimateP2 = (sigmaEstimateP2 + cAmbEffWidthSigmaEst_ns/2)/ + cAmbEffWidthSigmaEst_ns; + sigmaEstimateP2 *= cAmbEffWidthDMax_ns; + + /* FixPoint1616 >> 16 = uint32 */ + minSignalNeeded_p3 = (sigmaEstimateP2 + 0x8000) >> 16; + + minSignalNeeded_p3 *= minSignalNeeded_p3; + + } + + /* FixPoint1814 / uint32 = FixPoint1814 */ + sigmaLimitTmp = ((cSigmaLimit << 14) + 500) / 1000; + + /* FixPoint1814 * FixPoint1814 = FixPoint3628 := FixPoint0428 */ + sigmaLimitTmp *= sigmaLimitTmp; + + /* FixPoint1616 * FixPoint1616 = FixPoint3232 */ + sigmaEstSqTmp = cSigmaEstRef * cSigmaEstRef; + + /* FixPoint3232 >> 4 = FixPoint0428 */ + sigmaEstSqTmp = (sigmaEstSqTmp + 0x08) >> 4; + + /* FixPoint0428 - FixPoint0428 = FixPoint0428 */ + sigmaLimitTmp -= sigmaEstSqTmp; + + /* uint32_t * FixPoint0428 = FixPoint0428 */ + minSignalNeeded_p4 = 4 * 12 * sigmaLimitTmp; + + /* FixPoint0428 >> 14 = FixPoint1814 */ + minSignalNeeded_p4 = (minSignalNeeded_p4 + 0x2000) >> 14; + + /* uint32 + uint32 = uint32 */ + minSignalNeeded = (minSignalNeeded_p2 + minSignalNeeded_p3); + + /* uint32 / uint32 = uint32 */ + minSignalNeeded += (peakVcselDuration_us/2); + minSignalNeeded /= peakVcselDuration_us; + + /* uint32 << 14 = FixPoint1814 */ + minSignalNeeded <<= 14; + + /* FixPoint1814 / FixPoint1814 = uint32 */ + minSignalNeeded += (minSignalNeeded_p4/2); + minSignalNeeded /= minSignalNeeded_p4; + + /* FixPoint3200 * FixPoint2804 := FixPoint2804*/ + minSignalNeeded *= minSignalNeeded_p1; + + /* Apply correction by dividing by 1000000. + * This assumes 10E16 on the numerator of the equation + * and 10E-22 on the denominator. + * We do this because 32bit fix point calculation can't + * handle the larger and smaller elements of this equation, + * i.e. speed of light and pulse widths. + */ + minSignalNeeded = (minSignalNeeded + 500) / 1000; + minSignalNeeded <<= 4; + + minSignalNeeded = (minSignalNeeded + 500) / 1000; + + /* FixPoint1616 >> 8 = FixPoint2408 */ + signalLimitTmp = (cSignalLimit + 0x80) >> 8; + + /* FixPoint2408/FixPoint2408 = uint32 */ + if (signalLimitTmp != 0) + dmaxDarkTmp = (SignalAt0mm + (signalLimitTmp / 2)) + / signalLimitTmp; + else + dmaxDarkTmp = 0; + + dmaxDark = VL53L0X_isqrt(dmaxDarkTmp); + + /* FixPoint2408/FixPoint2408 = uint32 */ + if (minSignalNeeded != 0) + dmaxAmbient = (SignalAt0mm + minSignalNeeded/2) + / minSignalNeeded; + else + dmaxAmbient = 0; + + dmaxAmbient = VL53L0X_isqrt(dmaxAmbient); + + *pdmax_mm = dmaxDark; + if (dmaxDark > dmaxAmbient) + *pdmax_mm = dmaxAmbient; + + LOG_FUNCTION_END(Status); + + return Status; +} + + +VL53L0X_Error VL53L0X_calc_sigma_estimate(VL53L0X_DEV Dev, + VL53L0X_RangingMeasurementData_t *pRangingMeasurementData, + FixPoint1616_t *pSigmaEstimate, + uint32_t *pDmax_mm) +{ + /* Expressed in 100ths of a ns, i.e. centi-ns */ + const uint32_t cPulseEffectiveWidth_centi_ns = 800; + /* Expressed in 100ths of a ns, i.e. centi-ns */ + const uint32_t cAmbientEffectiveWidth_centi_ns = 600; + const FixPoint1616_t cDfltFinalRangeIntegrationTimeMilliSecs = 0x00190000; /* 25ms */ + const uint32_t cVcselPulseWidth_ps = 4700; /* pico secs */ + const FixPoint1616_t cSigmaEstMax = 0x028F87AE; + const FixPoint1616_t cSigmaEstRtnMax = 0xF000; + const FixPoint1616_t cAmbToSignalRatioMax = 0xF0000000/ + cAmbientEffectiveWidth_centi_ns; + /* Time Of Flight per mm (6.6 pico secs) */ + const FixPoint1616_t cTOF_per_mm_ps = 0x0006999A; + const uint32_t c16BitRoundingParam = 0x00008000; + const FixPoint1616_t cMaxXTalk_kcps = 0x00320000; + const uint32_t cPllPeriod_ps = 1655; + + uint32_t vcselTotalEventsRtn; + uint32_t finalRangeTimeoutMicroSecs; + uint32_t preRangeTimeoutMicroSecs; + uint32_t finalRangeIntegrationTimeMilliSecs; + FixPoint1616_t sigmaEstimateP1; + FixPoint1616_t sigmaEstimateP2; + FixPoint1616_t sigmaEstimateP3; + FixPoint1616_t deltaT_ps; + FixPoint1616_t pwMult; + FixPoint1616_t sigmaEstRtn; + FixPoint1616_t sigmaEstimate; + FixPoint1616_t xTalkCorrection; + FixPoint1616_t ambientRate_kcps; + FixPoint1616_t peakSignalRate_kcps; + FixPoint1616_t xTalkCompRate_mcps; + uint32_t xTalkCompRate_kcps; + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + FixPoint1616_t diff1_mcps; + FixPoint1616_t diff2_mcps; + FixPoint1616_t sqr1; + FixPoint1616_t sqr2; + FixPoint1616_t sqrSum; + FixPoint1616_t sqrtResult_centi_ns; + FixPoint1616_t sqrtResult; + FixPoint1616_t totalSignalRate_mcps; + FixPoint1616_t correctedSignalRate_mcps; + FixPoint1616_t sigmaEstRef; + uint32_t vcselWidth; + uint32_t finalRangeMacroPCLKS; + uint32_t preRangeMacroPCLKS; + uint32_t peakVcselDuration_us; + uint8_t finalRangeVcselPCLKS; + uint8_t preRangeVcselPCLKS; + /*! \addtogroup calc_sigma_estimate + * @{ + * + * Estimates the range sigma + */ + + LOG_FUNCTION_START(""); + + VL53L0X_GETPARAMETERFIELD(Dev, XTalkCompensationRateMegaCps, + xTalkCompRate_mcps); + + /* + * We work in kcps rather than mcps as this helps keep within the + * confines of the 32 Fix1616 type. + */ + + ambientRate_kcps = + (pRangingMeasurementData->AmbientRateRtnMegaCps * 1000) >> 16; + + correctedSignalRate_mcps = + pRangingMeasurementData->SignalRateRtnMegaCps; + + + Status = VL53L0X_get_total_signal_rate( + Dev, pRangingMeasurementData, &totalSignalRate_mcps); + Status = VL53L0X_get_total_xtalk_rate( + Dev, pRangingMeasurementData, &xTalkCompRate_mcps); + + + /* Signal rate measurement provided by device is the + * peak signal rate, not average. + */ + peakSignalRate_kcps = (totalSignalRate_mcps * 1000); + peakSignalRate_kcps = (peakSignalRate_kcps + 0x8000) >> 16; + + xTalkCompRate_kcps = xTalkCompRate_mcps * 1000; + + if (xTalkCompRate_kcps > cMaxXTalk_kcps) + xTalkCompRate_kcps = cMaxXTalk_kcps; + + if (Status == VL53L0X_ERROR_NONE) { + + /* Calculate final range macro periods */ + finalRangeTimeoutMicroSecs = VL53L0X_GETDEVICESPECIFICPARAMETER( + Dev, FinalRangeTimeoutMicroSecs); + + finalRangeVcselPCLKS = VL53L0X_GETDEVICESPECIFICPARAMETER( + Dev, FinalRangeVcselPulsePeriod); + + finalRangeMacroPCLKS = VL53L0X_calc_timeout_mclks( + Dev, finalRangeTimeoutMicroSecs, finalRangeVcselPCLKS); + + /* Calculate pre-range macro periods */ + preRangeTimeoutMicroSecs = VL53L0X_GETDEVICESPECIFICPARAMETER( + Dev, PreRangeTimeoutMicroSecs); + + preRangeVcselPCLKS = VL53L0X_GETDEVICESPECIFICPARAMETER( + Dev, PreRangeVcselPulsePeriod); + + preRangeMacroPCLKS = VL53L0X_calc_timeout_mclks( + Dev, preRangeTimeoutMicroSecs, preRangeVcselPCLKS); + + vcselWidth = 3; + if (finalRangeVcselPCLKS == 8) + vcselWidth = 2; + + + peakVcselDuration_us = vcselWidth * 2048 * + (preRangeMacroPCLKS + finalRangeMacroPCLKS); + peakVcselDuration_us = (peakVcselDuration_us + 500)/1000; + peakVcselDuration_us *= cPllPeriod_ps; + peakVcselDuration_us = (peakVcselDuration_us + 500)/1000; + + /* Fix1616 >> 8 = Fix2408 */ + totalSignalRate_mcps = (totalSignalRate_mcps + 0x80) >> 8; + + /* Fix2408 * uint32 = Fix2408 */ + vcselTotalEventsRtn = totalSignalRate_mcps * + peakVcselDuration_us; + + /* Fix2408 >> 8 = uint32 */ + vcselTotalEventsRtn = (vcselTotalEventsRtn + 0x80) >> 8; + + /* Fix2408 << 8 = Fix1616 = */ + totalSignalRate_mcps <<= 8; + } + + if (Status != VL53L0X_ERROR_NONE) { + LOG_FUNCTION_END(Status); + return Status; + } + + if (peakSignalRate_kcps == 0) { + *pSigmaEstimate = cSigmaEstMax; + PALDevDataSet(Dev, SigmaEstimate, cSigmaEstMax); + *pDmax_mm = 0; + } else { + if (vcselTotalEventsRtn < 1) + vcselTotalEventsRtn = 1; + + sigmaEstimateP1 = cPulseEffectiveWidth_centi_ns; + + /* ((FixPoint1616 << 16)* uint32)/uint32 = FixPoint1616 */ + sigmaEstimateP2 = (ambientRate_kcps << 16)/peakSignalRate_kcps; + if (sigmaEstimateP2 > cAmbToSignalRatioMax) { + /* Clip to prevent overflow. Will ensure safe + * max result. */ + sigmaEstimateP2 = cAmbToSignalRatioMax; + } + sigmaEstimateP2 *= cAmbientEffectiveWidth_centi_ns; + + sigmaEstimateP3 = 2 * VL53L0X_isqrt(vcselTotalEventsRtn * 12); + + /* uint32 * FixPoint1616 = FixPoint1616 */ + deltaT_ps = pRangingMeasurementData->RangeMilliMeter * + cTOF_per_mm_ps; + + /* + * vcselRate - xtalkCompRate + * (uint32 << 16) - FixPoint1616 = FixPoint1616. + * Divide result by 1000 to convert to mcps. + * 500 is added to ensure rounding when integer division + * truncates. + */ + diff1_mcps = (((peakSignalRate_kcps << 16) - + 2 * xTalkCompRate_kcps) + 500)/1000; + + /* vcselRate + xtalkCompRate */ + diff2_mcps = ((peakSignalRate_kcps << 16) + 500)/1000; + + /* Shift by 8 bits to increase resolution prior to the + * division */ + diff1_mcps <<= 8; + + /* FixPoint0824/FixPoint1616 = FixPoint2408 */ + xTalkCorrection = abs(diff1_mcps/diff2_mcps); + + /* FixPoint2408 << 8 = FixPoint1616 */ + xTalkCorrection <<= 8; + + if(pRangingMeasurementData->RangeStatus != 0){ + pwMult = 1 << 16; + } else { + /* FixPoint1616/uint32 = FixPoint1616 */ + pwMult = deltaT_ps/cVcselPulseWidth_ps; /* smaller than 1.0f */ + + /* + * FixPoint1616 * FixPoint1616 = FixPoint3232, however both + * values are small enough such that32 bits will not be + * exceeded. + */ + pwMult *= ((1 << 16) - xTalkCorrection); + + /* (FixPoint3232 >> 16) = FixPoint1616 */ + pwMult = (pwMult + c16BitRoundingParam) >> 16; + + /* FixPoint1616 + FixPoint1616 = FixPoint1616 */ + pwMult += (1 << 16); + + /* + * At this point the value will be 1.xx, therefore if we square + * the value this will exceed 32 bits. To address this perform + * a single shift to the right before the multiplication. + */ + pwMult >>= 1; + /* FixPoint1715 * FixPoint1715 = FixPoint3430 */ + pwMult = pwMult * pwMult; + + /* (FixPoint3430 >> 14) = Fix1616 */ + pwMult >>= 14; + } + + /* FixPoint1616 * uint32 = FixPoint1616 */ + sqr1 = pwMult * sigmaEstimateP1; + + /* (FixPoint1616 >> 16) = FixPoint3200 */ + sqr1 = (sqr1 + 0x8000) >> 16; + + /* FixPoint3200 * FixPoint3200 = FixPoint6400 */ + sqr1 *= sqr1; + + sqr2 = sigmaEstimateP2; + + /* (FixPoint1616 >> 16) = FixPoint3200 */ + sqr2 = (sqr2 + 0x8000) >> 16; + + /* FixPoint3200 * FixPoint3200 = FixPoint6400 */ + sqr2 *= sqr2; + + /* FixPoint64000 + FixPoint6400 = FixPoint6400 */ + sqrSum = sqr1 + sqr2; + + /* SQRT(FixPoin6400) = FixPoint3200 */ + sqrtResult_centi_ns = VL53L0X_isqrt(sqrSum); + + /* (FixPoint3200 << 16) = FixPoint1616 */ + sqrtResult_centi_ns <<= 16; + + /* + * Note that the Speed Of Light is expressed in um per 1E-10 + * seconds (2997) Therefore to get mm/ns we have to divide by + * 10000 + */ + sigmaEstRtn = (((sqrtResult_centi_ns+50)/100) / + sigmaEstimateP3); + sigmaEstRtn *= VL53L0X_SPEED_OF_LIGHT_IN_AIR; + + /* Add 5000 before dividing by 10000 to ensure rounding. */ + sigmaEstRtn += 5000; + sigmaEstRtn /= 10000; + + if (sigmaEstRtn > cSigmaEstRtnMax) { + /* Clip to prevent overflow. Will ensure safe + * max result. */ + sigmaEstRtn = cSigmaEstRtnMax; + } + finalRangeIntegrationTimeMilliSecs = + (finalRangeTimeoutMicroSecs + preRangeTimeoutMicroSecs + 500)/1000; + + /* sigmaEstRef = 1mm * 25ms/final range integration time (inc pre-range) + * sqrt(FixPoint1616/int) = FixPoint2408) + */ + sigmaEstRef = + VL53L0X_isqrt((cDfltFinalRangeIntegrationTimeMilliSecs + + finalRangeIntegrationTimeMilliSecs/2)/ + finalRangeIntegrationTimeMilliSecs); + + /* FixPoint2408 << 8 = FixPoint1616 */ + sigmaEstRef <<= 8; + sigmaEstRef = (sigmaEstRef + 500)/1000; + + /* FixPoint1616 * FixPoint1616 = FixPoint3232 */ + sqr1 = sigmaEstRtn * sigmaEstRtn; + /* FixPoint1616 * FixPoint1616 = FixPoint3232 */ + sqr2 = sigmaEstRef * sigmaEstRef; + + /* sqrt(FixPoint3232) = FixPoint1616 */ + sqrtResult = VL53L0X_isqrt((sqr1 + sqr2)); + /* + * Note that the Shift by 4 bits increases resolution prior to + * the sqrt, therefore the result must be shifted by 2 bits to + * the right to revert back to the FixPoint1616 format. + */ + + sigmaEstimate = 1000 * sqrtResult; + + if ((peakSignalRate_kcps < 1) || (vcselTotalEventsRtn < 1) || + (sigmaEstimate > cSigmaEstMax)) { + sigmaEstimate = cSigmaEstMax; + } + + *pSigmaEstimate = (uint32_t)(sigmaEstimate); + PALDevDataSet(Dev, SigmaEstimate, *pSigmaEstimate); + Status = VL53L0X_calc_dmax( + Dev, + totalSignalRate_mcps, + correctedSignalRate_mcps, + pwMult, + sigmaEstimateP1, + sigmaEstimateP2, + peakVcselDuration_us, + pDmax_mm); + } + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_get_pal_range_status(VL53L0X_DEV Dev, + uint8_t DeviceRangeStatus, + FixPoint1616_t SignalRate, + uint16_t EffectiveSpadRtnCount, + VL53L0X_RangingMeasurementData_t *pRangingMeasurementData, + uint8_t *pPalRangeStatus) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + uint8_t NoneFlag; + uint8_t SigmaLimitflag = 0; + uint8_t SignalRefClipflag = 0; + uint8_t RangeIgnoreThresholdflag = 0; + uint8_t SigmaLimitCheckEnable = 0; + uint8_t SignalRateFinalRangeLimitCheckEnable = 0; + uint8_t SignalRefClipLimitCheckEnable = 0; + uint8_t RangeIgnoreThresholdLimitCheckEnable = 0; + FixPoint1616_t SigmaEstimate; + FixPoint1616_t SigmaLimitValue; + FixPoint1616_t SignalRefClipValue; + FixPoint1616_t RangeIgnoreThresholdValue; + FixPoint1616_t SignalRatePerSpad; + uint8_t DeviceRangeStatusInternal = 0; + uint16_t tmpWord = 0; + uint8_t Temp8; + uint32_t Dmax_mm = 0; + FixPoint1616_t LastSignalRefMcps; + + LOG_FUNCTION_START(""); + + + /* + * VL53L0X has a good ranging when the value of the + * DeviceRangeStatus = 11. This function will replace the value 0 with + * the value 11 in the DeviceRangeStatus. + * In addition, the SigmaEstimator is not included in the VL53L0X + * DeviceRangeStatus, this will be added in the PalRangeStatus. + */ + + DeviceRangeStatusInternal = ((DeviceRangeStatus & 0x78) >> 3); + + if (DeviceRangeStatusInternal == 0 || + DeviceRangeStatusInternal == 5 || + DeviceRangeStatusInternal == 7 || + DeviceRangeStatusInternal == 12 || + DeviceRangeStatusInternal == 13 || + DeviceRangeStatusInternal == 14 || + DeviceRangeStatusInternal == 15 + ) { + NoneFlag = 1; + } else { + NoneFlag = 0; + } + + /* + * Check if Sigma limit is enabled, if yes then do comparison with limit + * value and put the result back into pPalRangeStatus. + */ + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_GetLimitCheckEnable(Dev, + VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE, + &SigmaLimitCheckEnable); + + if ((SigmaLimitCheckEnable != 0) && (Status == VL53L0X_ERROR_NONE)) { + /* + * compute the Sigma and check with limit + */ + Status = VL53L0X_calc_sigma_estimate( + Dev, + pRangingMeasurementData, + &SigmaEstimate, + &Dmax_mm); + if (Status == VL53L0X_ERROR_NONE) + pRangingMeasurementData->RangeDMaxMilliMeter = Dmax_mm; + + if (Status == VL53L0X_ERROR_NONE) { + Status = VL53L0X_GetLimitCheckValue(Dev, + VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE, + &SigmaLimitValue); + + if ((SigmaLimitValue > 0) && + (SigmaEstimate > SigmaLimitValue)) + /* Limit Fail */ + SigmaLimitflag = 1; + } + } + + /* + * Check if Signal ref clip limit is enabled, if yes then do comparison + * with limit value and put the result back into pPalRangeStatus. + */ + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_GetLimitCheckEnable(Dev, + VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP, + &SignalRefClipLimitCheckEnable); + + if ((SignalRefClipLimitCheckEnable != 0) && + (Status == VL53L0X_ERROR_NONE)) { + + Status = VL53L0X_GetLimitCheckValue(Dev, + VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP, + &SignalRefClipValue); + + /* Read LastSignalRefMcps from device */ + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_WrByte(Dev, 0xFF, 0x01); + + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_RdWord(Dev, + VL53L0X_REG_RESULT_PEAK_SIGNAL_RATE_REF, + &tmpWord); + + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_WrByte(Dev, 0xFF, 0x00); + + LastSignalRefMcps = VL53L0X_FIXPOINT97TOFIXPOINT1616(tmpWord); + PALDevDataSet(Dev, LastSignalRefMcps, LastSignalRefMcps); + + if ((SignalRefClipValue > 0) && + (LastSignalRefMcps > SignalRefClipValue)) { + /* Limit Fail */ + SignalRefClipflag = 1; + } + } + + /* + * Check if Signal ref clip limit is enabled, if yes then do comparison + * with limit value and put the result back into pPalRangeStatus. + * EffectiveSpadRtnCount has a format 8.8 + * If (Return signal rate < (1.5 x Xtalk x number of Spads)) : FAIL + */ + if (Status == VL53L0X_ERROR_NONE) + Status = VL53L0X_GetLimitCheckEnable(Dev, + VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD, + &RangeIgnoreThresholdLimitCheckEnable); + + if ((RangeIgnoreThresholdLimitCheckEnable != 0) && + (Status == VL53L0X_ERROR_NONE)) { + + /* Compute the signal rate per spad */ + if (EffectiveSpadRtnCount == 0) { + SignalRatePerSpad = 0; + } else { + SignalRatePerSpad = (FixPoint1616_t)((256 * SignalRate) + / EffectiveSpadRtnCount); + } + + Status = VL53L0X_GetLimitCheckValue(Dev, + VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD, + &RangeIgnoreThresholdValue); + + if ((RangeIgnoreThresholdValue > 0) && + (SignalRatePerSpad < RangeIgnoreThresholdValue)) { + /* Limit Fail add 2^6 to range status */ + RangeIgnoreThresholdflag = 1; + } + } + + if (Status == VL53L0X_ERROR_NONE) { + if (NoneFlag == 1) { + *pPalRangeStatus = 255; /* NONE */ + } else if (DeviceRangeStatusInternal == 1 || + DeviceRangeStatusInternal == 2 || + DeviceRangeStatusInternal == 3) { + *pPalRangeStatus = 5; /* HW fail */ + } else if (DeviceRangeStatusInternal == 6 || + DeviceRangeStatusInternal == 9) { + *pPalRangeStatus = 4; /* Phase fail */ + } else if (DeviceRangeStatusInternal == 8 || + DeviceRangeStatusInternal == 10 || + SignalRefClipflag == 1) { + *pPalRangeStatus = 3; /* Min range */ + } else if (DeviceRangeStatusInternal == 4 || + RangeIgnoreThresholdflag == 1) { + *pPalRangeStatus = 2; /* Signal Fail */ + } else if (SigmaLimitflag == 1) { + *pPalRangeStatus = 1; /* Sigma Fail */ + } else { + *pPalRangeStatus = 0; /* Range Valid */ + } + } + + /* DMAX only relevant during range error */ + if (*pPalRangeStatus == 0) + pRangingMeasurementData->RangeDMaxMilliMeter = 0; + + /* fill the Limit Check Status */ + + Status = VL53L0X_GetLimitCheckEnable(Dev, + VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE, + &SignalRateFinalRangeLimitCheckEnable); + + if (Status == VL53L0X_ERROR_NONE) { + if ((SigmaLimitCheckEnable == 0) || (SigmaLimitflag == 1)) + Temp8 = 1; + else + Temp8 = 0; + VL53L0X_SETARRAYPARAMETERFIELD(Dev, LimitChecksStatus, + VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE, Temp8); + + if ((DeviceRangeStatusInternal == 4) || + (SignalRateFinalRangeLimitCheckEnable == 0)) + Temp8 = 1; + else + Temp8 = 0; + VL53L0X_SETARRAYPARAMETERFIELD(Dev, LimitChecksStatus, + VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE, + Temp8); + + if ((SignalRefClipLimitCheckEnable == 0) || + (SignalRefClipflag == 1)) + Temp8 = 1; + else + Temp8 = 0; + + VL53L0X_SETARRAYPARAMETERFIELD(Dev, LimitChecksStatus, + VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP, Temp8); + + if ((RangeIgnoreThresholdLimitCheckEnable == 0) || + (RangeIgnoreThresholdflag == 1)) + Temp8 = 1; + else + Temp8 = 0; + + VL53L0X_SETARRAYPARAMETERFIELD(Dev, LimitChecksStatus, + VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD, + Temp8); + } + + LOG_FUNCTION_END(Status); + return Status; + +} diff --git a/modules/VL53L0X/src/vl53l0x_api_ranging.c b/modules/VL53L0X/src/vl53l0x_api_ranging.c new file mode 100644 index 0000000000000000000000000000000000000000..f07283f224becece3d479bad4f1c9c0aeb4eeda4 --- /dev/null +++ b/modules/VL53L0X/src/vl53l0x_api_ranging.c @@ -0,0 +1,42 @@ +/******************************************************************************* + Copyright 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. + ******************************************************************************/ + +#include "vl53l0x_api.h" +#include "vl53l0x_api_core.h" + + +#ifndef __KERNEL__ +#include +#endif +#define LOG_FUNCTION_START(fmt, ...) \ + _LOG_FUNCTION_START(TRACE_MODULE_API, fmt, ##__VA_ARGS__) +#define LOG_FUNCTION_END(status, ...) \ + _LOG_FUNCTION_END(TRACE_MODULE_API, status, ##__VA_ARGS__) +#define LOG_FUNCTION_END_FMT(status, fmt, ...) \ + _LOG_FUNCTION_END_FMT(TRACE_MODULE_API, status, fmt, ##__VA_ARGS__) + diff --git a/modules/VL53L0X/src/vl53l0x_api_strings.c b/modules/VL53L0X/src/vl53l0x_api_strings.c new file mode 100644 index 0000000000000000000000000000000000000000..bc2bd30e39f18a154f66cb7325dcb5db3c55d702 --- /dev/null +++ b/modules/VL53L0X/src/vl53l0x_api_strings.c @@ -0,0 +1,462 @@ +/******************************************************************************* + Copyright 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. + ******************************************************************************/ + +#include "vl53l0x_api.h" +#include "vl53l0x_api_core.h" +#include "vl53l0x_api_strings.h" + +#ifndef __KERNEL__ +#include +#endif + +#define LOG_FUNCTION_START(fmt, ...) \ + _LOG_FUNCTION_START(TRACE_MODULE_API, fmt, ##__VA_ARGS__) +#define LOG_FUNCTION_END(status, ...) \ + _LOG_FUNCTION_END(TRACE_MODULE_API, status, ##__VA_ARGS__) +#define LOG_FUNCTION_END_FMT(status, fmt, ...) \ + _LOG_FUNCTION_END_FMT(TRACE_MODULE_API, status, fmt, ##__VA_ARGS__) + + +VL53L0X_Error VL53L0X_check_part_used(VL53L0X_DEV Dev, + uint8_t *Revision, + VL53L0X_DeviceInfo_t *pVL53L0X_DeviceInfo) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + uint8_t ModuleIdInt; + char *ProductId_tmp; + + LOG_FUNCTION_START(""); + + Status = VL53L0X_get_info_from_device(Dev, 2); + + if (Status == VL53L0X_ERROR_NONE) { + ModuleIdInt = VL53L0X_GETDEVICESPECIFICPARAMETER(Dev, ModuleId); + + if (ModuleIdInt == 0) { + *Revision = 0; + VL53L0X_COPYSTRING(pVL53L0X_DeviceInfo->ProductId, ""); + } else { + *Revision = VL53L0X_GETDEVICESPECIFICPARAMETER(Dev, Revision); + ProductId_tmp = VL53L0X_GETDEVICESPECIFICPARAMETER(Dev, + ProductId); + VL53L0X_COPYSTRING(pVL53L0X_DeviceInfo->ProductId, ProductId_tmp); + } + } + + LOG_FUNCTION_END(Status); + return Status; +} + + +VL53L0X_Error VL53L0X_get_device_info(VL53L0X_DEV Dev, + VL53L0X_DeviceInfo_t *pVL53L0X_DeviceInfo) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + uint8_t revision_id; + uint8_t Revision; + + Status = VL53L0X_check_part_used(Dev, &Revision, pVL53L0X_DeviceInfo); + + if (Status == VL53L0X_ERROR_NONE) { + if (Revision == 0) { + VL53L0X_COPYSTRING(pVL53L0X_DeviceInfo->Name, + VL53L0X_STRING_DEVICE_INFO_NAME_TS0); + } else if ((Revision <= 34) && (Revision != 32)) { + VL53L0X_COPYSTRING(pVL53L0X_DeviceInfo->Name, + VL53L0X_STRING_DEVICE_INFO_NAME_TS1); + } else if (Revision < 39) { + VL53L0X_COPYSTRING(pVL53L0X_DeviceInfo->Name, + VL53L0X_STRING_DEVICE_INFO_NAME_TS2); + } else { + VL53L0X_COPYSTRING(pVL53L0X_DeviceInfo->Name, + VL53L0X_STRING_DEVICE_INFO_NAME_ES1); + } + + VL53L0X_COPYSTRING(pVL53L0X_DeviceInfo->Type, + VL53L0X_STRING_DEVICE_INFO_TYPE); + + } + + if (Status == VL53L0X_ERROR_NONE) { + Status = VL53L0X_RdByte(Dev, VL53L0X_REG_IDENTIFICATION_MODEL_ID, + &pVL53L0X_DeviceInfo->ProductType); + } + + if (Status == VL53L0X_ERROR_NONE) { + Status = VL53L0X_RdByte(Dev, + VL53L0X_REG_IDENTIFICATION_REVISION_ID, + &revision_id); + pVL53L0X_DeviceInfo->ProductRevisionMajor = 1; + pVL53L0X_DeviceInfo->ProductRevisionMinor = + (revision_id & 0xF0) >> 4; + } + + return Status; +} + + +VL53L0X_Error VL53L0X_get_device_error_string(VL53L0X_DeviceError ErrorCode, + char *pDeviceErrorString) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + + LOG_FUNCTION_START(""); + + switch (ErrorCode) { + case VL53L0X_DEVICEERROR_NONE: + VL53L0X_COPYSTRING(pDeviceErrorString, + VL53L0X_STRING_DEVICEERROR_NONE); + break; + case VL53L0X_DEVICEERROR_VCSELCONTINUITYTESTFAILURE: + VL53L0X_COPYSTRING(pDeviceErrorString, + VL53L0X_STRING_DEVICEERROR_VCSELCONTINUITYTESTFAILURE); + break; + case VL53L0X_DEVICEERROR_VCSELWATCHDOGTESTFAILURE: + VL53L0X_COPYSTRING(pDeviceErrorString, + VL53L0X_STRING_DEVICEERROR_VCSELWATCHDOGTESTFAILURE); + break; + case VL53L0X_DEVICEERROR_NOVHVVALUEFOUND: + VL53L0X_COPYSTRING(pDeviceErrorString, + VL53L0X_STRING_DEVICEERROR_NOVHVVALUEFOUND); + break; + case VL53L0X_DEVICEERROR_MSRCNOTARGET: + VL53L0X_COPYSTRING(pDeviceErrorString, + VL53L0X_STRING_DEVICEERROR_MSRCNOTARGET); + break; + case VL53L0X_DEVICEERROR_SNRCHECK: + VL53L0X_COPYSTRING(pDeviceErrorString, + VL53L0X_STRING_DEVICEERROR_SNRCHECK); + break; + case VL53L0X_DEVICEERROR_RANGEPHASECHECK: + VL53L0X_COPYSTRING(pDeviceErrorString, + VL53L0X_STRING_DEVICEERROR_RANGEPHASECHECK); + break; + case VL53L0X_DEVICEERROR_SIGMATHRESHOLDCHECK: + VL53L0X_COPYSTRING(pDeviceErrorString, + VL53L0X_STRING_DEVICEERROR_SIGMATHRESHOLDCHECK); + break; + case VL53L0X_DEVICEERROR_TCC: + VL53L0X_COPYSTRING(pDeviceErrorString, + VL53L0X_STRING_DEVICEERROR_TCC); + break; + case VL53L0X_DEVICEERROR_PHASECONSISTENCY: + VL53L0X_COPYSTRING(pDeviceErrorString, + VL53L0X_STRING_DEVICEERROR_PHASECONSISTENCY); + break; + case VL53L0X_DEVICEERROR_MINCLIP: + VL53L0X_COPYSTRING(pDeviceErrorString, + VL53L0X_STRING_DEVICEERROR_MINCLIP); + break; + case VL53L0X_DEVICEERROR_RANGECOMPLETE: + VL53L0X_COPYSTRING(pDeviceErrorString, + VL53L0X_STRING_DEVICEERROR_RANGECOMPLETE); + break; + case VL53L0X_DEVICEERROR_ALGOUNDERFLOW: + VL53L0X_COPYSTRING(pDeviceErrorString, + VL53L0X_STRING_DEVICEERROR_ALGOUNDERFLOW); + break; + case VL53L0X_DEVICEERROR_ALGOOVERFLOW: + VL53L0X_COPYSTRING(pDeviceErrorString, + VL53L0X_STRING_DEVICEERROR_ALGOOVERFLOW); + break; + case VL53L0X_DEVICEERROR_RANGEIGNORETHRESHOLD: + VL53L0X_COPYSTRING(pDeviceErrorString, + VL53L0X_STRING_DEVICEERROR_RANGEIGNORETHRESHOLD); + break; + + default: + VL53L0X_COPYSTRING(pDeviceErrorString, + VL53L0X_STRING_UNKNOW_ERROR_CODE); + + } + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_get_range_status_string(uint8_t RangeStatus, + char *pRangeStatusString) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + + LOG_FUNCTION_START(""); + + switch (RangeStatus) { + case 0: + VL53L0X_COPYSTRING(pRangeStatusString, + VL53L0X_STRING_RANGESTATUS_RANGEVALID); + break; + case 1: + VL53L0X_COPYSTRING(pRangeStatusString, + VL53L0X_STRING_RANGESTATUS_SIGMA); + break; + case 2: + VL53L0X_COPYSTRING(pRangeStatusString, + VL53L0X_STRING_RANGESTATUS_SIGNAL); + break; + case 3: + VL53L0X_COPYSTRING(pRangeStatusString, + VL53L0X_STRING_RANGESTATUS_MINRANGE); + break; + case 4: + VL53L0X_COPYSTRING(pRangeStatusString, + VL53L0X_STRING_RANGESTATUS_PHASE); + break; + case 5: + VL53L0X_COPYSTRING(pRangeStatusString, + VL53L0X_STRING_RANGESTATUS_HW); + break; + + default: /**/ + VL53L0X_COPYSTRING(pRangeStatusString, + VL53L0X_STRING_RANGESTATUS_NONE); + } + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_get_pal_error_string(VL53L0X_Error PalErrorCode, + char *pPalErrorString) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + + LOG_FUNCTION_START(""); + + switch (PalErrorCode) { + case VL53L0X_ERROR_NONE: + VL53L0X_COPYSTRING(pPalErrorString, + VL53L0X_STRING_ERROR_NONE); + break; + case VL53L0X_ERROR_CALIBRATION_WARNING: + VL53L0X_COPYSTRING(pPalErrorString, + VL53L0X_STRING_ERROR_CALIBRATION_WARNING); + break; + case VL53L0X_ERROR_MIN_CLIPPED: + VL53L0X_COPYSTRING(pPalErrorString, + VL53L0X_STRING_ERROR_MIN_CLIPPED); + break; + case VL53L0X_ERROR_UNDEFINED: + VL53L0X_COPYSTRING(pPalErrorString, + VL53L0X_STRING_ERROR_UNDEFINED); + break; + case VL53L0X_ERROR_INVALID_PARAMS: + VL53L0X_COPYSTRING(pPalErrorString, + VL53L0X_STRING_ERROR_INVALID_PARAMS); + break; + case VL53L0X_ERROR_NOT_SUPPORTED: + VL53L0X_COPYSTRING(pPalErrorString, + VL53L0X_STRING_ERROR_NOT_SUPPORTED); + break; + case VL53L0X_ERROR_INTERRUPT_NOT_CLEARED: + VL53L0X_COPYSTRING(pPalErrorString, + VL53L0X_STRING_ERROR_INTERRUPT_NOT_CLEARED); + break; + case VL53L0X_ERROR_RANGE_ERROR: + VL53L0X_COPYSTRING(pPalErrorString, + VL53L0X_STRING_ERROR_RANGE_ERROR); + break; + case VL53L0X_ERROR_TIME_OUT: + VL53L0X_COPYSTRING(pPalErrorString, + VL53L0X_STRING_ERROR_TIME_OUT); + break; + case VL53L0X_ERROR_MODE_NOT_SUPPORTED: + VL53L0X_COPYSTRING(pPalErrorString, + VL53L0X_STRING_ERROR_MODE_NOT_SUPPORTED); + break; + case VL53L0X_ERROR_BUFFER_TOO_SMALL: + VL53L0X_COPYSTRING(pPalErrorString, + VL53L0X_STRING_ERROR_BUFFER_TOO_SMALL); + break; + case VL53L0X_ERROR_GPIO_NOT_EXISTING: + VL53L0X_COPYSTRING(pPalErrorString, + VL53L0X_STRING_ERROR_GPIO_NOT_EXISTING); + break; + case VL53L0X_ERROR_GPIO_FUNCTIONALITY_NOT_SUPPORTED: + VL53L0X_COPYSTRING(pPalErrorString, + VL53L0X_STRING_ERROR_GPIO_FUNCTIONALITY_NOT_SUPPORTED); + break; + case VL53L0X_ERROR_CONTROL_INTERFACE: + VL53L0X_COPYSTRING(pPalErrorString, + VL53L0X_STRING_ERROR_CONTROL_INTERFACE); + break; + case VL53L0X_ERROR_INVALID_COMMAND: + VL53L0X_COPYSTRING(pPalErrorString, + VL53L0X_STRING_ERROR_INVALID_COMMAND); + break; + case VL53L0X_ERROR_DIVISION_BY_ZERO: + VL53L0X_COPYSTRING(pPalErrorString, + VL53L0X_STRING_ERROR_DIVISION_BY_ZERO); + break; + case VL53L0X_ERROR_REF_SPAD_INIT: + VL53L0X_COPYSTRING(pPalErrorString, + VL53L0X_STRING_ERROR_REF_SPAD_INIT); + break; + case VL53L0X_ERROR_NOT_IMPLEMENTED: + VL53L0X_COPYSTRING(pPalErrorString, + VL53L0X_STRING_ERROR_NOT_IMPLEMENTED); + break; + + default: + VL53L0X_COPYSTRING(pPalErrorString, + VL53L0X_STRING_UNKNOW_ERROR_CODE); + } + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_get_pal_state_string(VL53L0X_State PalStateCode, + char *pPalStateString) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + + LOG_FUNCTION_START(""); + + switch (PalStateCode) { + case VL53L0X_STATE_POWERDOWN: + VL53L0X_COPYSTRING(pPalStateString, + VL53L0X_STRING_STATE_POWERDOWN); + break; + case VL53L0X_STATE_WAIT_STATICINIT: + VL53L0X_COPYSTRING(pPalStateString, + VL53L0X_STRING_STATE_WAIT_STATICINIT); + break; + case VL53L0X_STATE_STANDBY: + VL53L0X_COPYSTRING(pPalStateString, + VL53L0X_STRING_STATE_STANDBY); + break; + case VL53L0X_STATE_IDLE: + VL53L0X_COPYSTRING(pPalStateString, + VL53L0X_STRING_STATE_IDLE); + break; + case VL53L0X_STATE_RUNNING: + VL53L0X_COPYSTRING(pPalStateString, + VL53L0X_STRING_STATE_RUNNING); + break; + case VL53L0X_STATE_UNKNOWN: + VL53L0X_COPYSTRING(pPalStateString, + VL53L0X_STRING_STATE_UNKNOWN); + break; + case VL53L0X_STATE_ERROR: + VL53L0X_COPYSTRING(pPalStateString, + VL53L0X_STRING_STATE_ERROR); + break; + + default: + VL53L0X_COPYSTRING(pPalStateString, + VL53L0X_STRING_STATE_UNKNOWN); + } + + LOG_FUNCTION_END(Status); + return Status; +} + +VL53L0X_Error VL53L0X_get_sequence_steps_info( + VL53L0X_SequenceStepId SequenceStepId, + char *pSequenceStepsString) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + LOG_FUNCTION_START(""); + + switch (SequenceStepId) { + case VL53L0X_SEQUENCESTEP_TCC: + VL53L0X_COPYSTRING(pSequenceStepsString, + VL53L0X_STRING_SEQUENCESTEP_TCC); + break; + case VL53L0X_SEQUENCESTEP_DSS: + VL53L0X_COPYSTRING(pSequenceStepsString, + VL53L0X_STRING_SEQUENCESTEP_DSS); + break; + case VL53L0X_SEQUENCESTEP_MSRC: + VL53L0X_COPYSTRING(pSequenceStepsString, + VL53L0X_STRING_SEQUENCESTEP_MSRC); + break; + case VL53L0X_SEQUENCESTEP_PRE_RANGE: + VL53L0X_COPYSTRING(pSequenceStepsString, + VL53L0X_STRING_SEQUENCESTEP_PRE_RANGE); + break; + case VL53L0X_SEQUENCESTEP_FINAL_RANGE: + VL53L0X_COPYSTRING(pSequenceStepsString, + VL53L0X_STRING_SEQUENCESTEP_FINAL_RANGE); + break; + + default: + Status = VL53L0X_ERROR_INVALID_PARAMS; + } + + LOG_FUNCTION_END(Status); + + return Status; +} + + +VL53L0X_Error VL53L0X_get_limit_check_info(VL53L0X_DEV Dev, uint16_t LimitCheckId, + char *pLimitCheckString) +{ + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + + LOG_FUNCTION_START(""); + + switch (LimitCheckId) { + case VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE: + VL53L0X_COPYSTRING(pLimitCheckString, + VL53L0X_STRING_CHECKENABLE_SIGMA_FINAL_RANGE); + break; + case VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE: + VL53L0X_COPYSTRING(pLimitCheckString, + VL53L0X_STRING_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE); + break; + case VL53L0X_CHECKENABLE_SIGNAL_REF_CLIP: + VL53L0X_COPYSTRING(pLimitCheckString, + VL53L0X_STRING_CHECKENABLE_SIGNAL_REF_CLIP); + break; + case VL53L0X_CHECKENABLE_RANGE_IGNORE_THRESHOLD: + VL53L0X_COPYSTRING(pLimitCheckString, + VL53L0X_STRING_CHECKENABLE_RANGE_IGNORE_THRESHOLD); + break; + + case VL53L0X_CHECKENABLE_SIGNAL_RATE_MSRC: + VL53L0X_COPYSTRING(pLimitCheckString, + VL53L0X_STRING_CHECKENABLE_SIGNAL_RATE_MSRC); + break; + + case VL53L0X_CHECKENABLE_SIGNAL_RATE_PRE_RANGE: + VL53L0X_COPYSTRING(pLimitCheckString, + VL53L0X_STRING_CHECKENABLE_SIGNAL_RATE_PRE_RANGE); + break; + + default: + VL53L0X_COPYSTRING(pLimitCheckString, + VL53L0X_STRING_UNKNOW_ERROR_CODE); + + } + + LOG_FUNCTION_END(Status); + return Status; +} diff --git a/modules/VL53L0X/src/vl53l0x_cali.c b/modules/VL53L0X/src/vl53l0x_cali.c new file mode 100644 index 0000000000000000000000000000000000000000..288589114eafa76729801397debb6fd73bfbf364 --- /dev/null +++ b/modules/VL53L0X/src/vl53l0x_cali.c @@ -0,0 +1,180 @@ +#include "vl53l0x_cali.h" +#include "delay.h" + +_vl53l0x_adjust Vl53l0x_adjust; //校准数据24c02写缓存区(用于在校准模式校准数据写入24c02) +_vl53l0x_adjust Vl53l0x_data; //校准数据24c02读缓存区(用于系统初始化时向24C02读取数据) + +#define adjust_num 5//校准错误次数 + +//VL53L0X校准函数 +//dev:设备I2C参数结构体 +VL53L0X_Error vl53l0x_adjust(VL53L0X_Dev_t *dev) +{ + + VL53L0X_DeviceError Status = VL53L0X_ERROR_NONE; + uint32_t refSpadCount = 7; + uint8_t isApertureSpads = 0; + uint32_t XTalkCalDistance = 100; + uint32_t XTalkCompensationRateMegaCps; + uint32_t CalDistanceMilliMeter = 100<<16; + int32_t OffsetMicroMeter = 30000; + uint8_t VhvSettings = 23; + uint8_t PhaseCal = 1; + u8 i=0; + + VL53L0X_StaticInit(dev);//数值恢复默认,传感器处于空闲状态 +// LED1=0; + //SPADS校准---------------------------- + spads: + delay_ms(10); + printf("The SPADS Calibration Start...\r\n"); + Status = VL53L0X_PerformRefSpadManagement(dev,&refSpadCount,&isApertureSpads);//执行参考Spad管理 + if(Status == VL53L0X_ERROR_NONE) + { + printf("refSpadCount = %d\r\n",refSpadCount); + Vl53l0x_adjust.refSpadCount = refSpadCount; + printf("isApertureSpads = %d\r\n",isApertureSpads); + Vl53l0x_adjust.isApertureSpads = isApertureSpads; + printf("The SPADS Calibration Finish...\r\n\r\n"); + i=0; + } + else + { + i++; + if(i==adjust_num) return Status; + printf("SPADS Calibration Error,Restart this step\r\n"); + goto spads; + } + //设备参考校准--------------------------------------------------- + ref: + delay_ms(10); + printf("The Ref Calibration Start...\r\n"); + Status = VL53L0X_PerformRefCalibration(dev,&VhvSettings,&PhaseCal);//Ref参考校准 + if(Status == VL53L0X_ERROR_NONE) + { + printf("VhvSettings = %d\r\n",VhvSettings); + Vl53l0x_adjust.VhvSettings = VhvSettings; + printf("PhaseCal = %d\r\n",PhaseCal); + Vl53l0x_adjust.PhaseCal = PhaseCal; + printf("The Ref Calibration Finish...\r\n\r\n"); + i=0; + } + else + { + i++; + if(i==adjust_num) return Status; + printf("Ref Calibration Error,Restart this step\r\n"); + goto ref; + } + //偏移校准------------------------------------------------ + offset: + delay_ms(10); + printf("Offset Calibration:need a white target,in black space,and the distance keep 100mm!\r\n"); + printf("The Offset Calibration Start...\r\n"); + + Status = VL53L0X_PerformOffsetCalibration(dev,CalDistanceMilliMeter,&OffsetMicroMeter);//偏移校准 + if(Status == VL53L0X_ERROR_NONE) + { + printf("CalDistanceMilliMeter = %d mm\r\n",CalDistanceMilliMeter); + Vl53l0x_adjust.CalDistanceMilliMeter = CalDistanceMilliMeter; + printf("OffsetMicroMeter = %d mm\r\n",OffsetMicroMeter); + Vl53l0x_adjust.OffsetMicroMeter = OffsetMicroMeter; + printf("The Offset Calibration Finish...\r\n\r\n"); + i=0; + } + else + { + i++; + if(i==adjust_num) return Status; + printf("Offset Calibration Error,Restart this step\r\n"); + goto offset; + } + //串扰校准----------------------------------------------------- + xtalk: + delay_ms(20); + printf("Cross Talk Calibration:need a grey target\r\n"); + printf("The Cross Talk Calibration Start...\r\n"); + Status = VL53L0X_PerformXTalkCalibration(dev,XTalkCalDistance,&XTalkCompensationRateMegaCps);//串扰校准 + if(Status == VL53L0X_ERROR_NONE) + { + printf("XTalkCalDistance = %d mm\r\n",XTalkCalDistance); + Vl53l0x_adjust.XTalkCalDistance = XTalkCalDistance; + printf("XTalkCompensationRateMegaCps = %d\r\n",XTalkCompensationRateMegaCps); + Vl53l0x_adjust.XTalkCompensationRateMegaCps = XTalkCompensationRateMegaCps; + printf("The Cross Talk Calibration Finish...\r\n\r\n"); + i=0; + } + else + { + i++; + if(i==adjust_num) return Status; + printf("Cross Talk Calibration Error,Restart this step\r\n"); + goto xtalk; + } +// LED1=1; + printf("All the Calibration has Finished!\r\n"); + printf("Calibration is successful!!\r\n"); + + Vl53l0x_adjust.adjustok = 0xAA;//校准成功 +// AT24CXX_Write(0,(u8*)&Vl53l0x_adjust,sizeof(_vl53l0x_adjust));//将校准数据保存到24c02 + memcpy(&Vl53l0x_data,&Vl53l0x_adjust,sizeof(_vl53l0x_adjust)); + return Status; +} + +////vl53l0x校准测试 +////dev:设备I2C参数结构体 +//void vl53l0x_calibration_test(VL53L0X_Dev_t *dev) +//{ +// VL53L0X_Error status = VL53L0X_ERROR_NONE; +// u8 key=0; +// u8 i=0; +// +//// LCD_Fill(30,170,320,300,WHITE); +//// POINT_COLOR=RED;//设置字体为红色 +//// LCD_ShowString(30,170,300,16,16,"need a white target,and "); +//// LCD_ShowString(30,190,250,16,16,"the distance keep 100mm."); +//// POINT_COLOR=BLUE;//设置字体为蓝色 +//// LCD_ShowString(30,220,200,16,16,"KEY_UP: Return menu"); +//// LCD_ShowString(30,240,200,16,16,"KEY1: Calibration"); +// printf("need a white target,and the distance keep 100mm.\n\r"); +// printf("KEY_UP: Return menu\n\r"); +// printf("KEY1 : Calibration\n\r"); +// while(1) +// { +////// key = KEY_Scan(0); +////// if(key==KEY1_PRES) +////// { +////// POINT_COLOR=RED;//设置字体为红色 +////// LCD_ShowString(30,260,200,16,16,"Start calibration..."); +//// status = vl53l0x_adjust(dev);//进入校准 +//// if(status!=VL53L0X_ERROR_NONE)//校准失败 +//// { +//// printf("Calibration is error!!\r\n"); +//// i=3; +//// while(i--) +//// { +//// delay_1ms(500); +////// LCD_ShowString(30,260,200,16,16," "); +////// delay_1ms(500); +////// LCD_ShowString(30,260,200,16,16,"Calibration is error"); +//// } +//// } +//// else +////// LCD_ShowString(30,260,200,16,16,"Calibration is complete!"); +//// delay_1ms(500); + +//// break; +//// +//// } +//// else if(key==WKUP_PRES) +//// { +//// LED1=1; +//// break;//返回上一菜单 +//// } +// printf("%s\r\n",__FILE__); +// delay_1ms(200); +//// LED0=!LED0; +// +// } +// +//} diff --git a/modules/VL53L0X/src/vl53l0x_gen.c b/modules/VL53L0X/src/vl53l0x_gen.c new file mode 100644 index 0000000000000000000000000000000000000000..df9ffaba2cbe6a1737d899a31f0f2f769de3f1bc --- /dev/null +++ b/modules/VL53L0X/src/vl53l0x_gen.c @@ -0,0 +1,81 @@ +#include "vl53l0x_gen.h" +#include "delay.h" + +#ifndef vu16 +#define vu16 uint16_t +#endif + +VL53L0X_RangingMeasurementData_t vl53l0x_data;//ṹ +vu16 Distance_data=0;// + +//VL53L0X ģʽ +//dev:豸I2Cṹ +//mode: 0:Ĭ;1:߾;2: +VL53L0X_Error vl53l0x_set_mode(VL53L0X_Dev_t *dev,u8 mode) +{ + + VL53L0X_Error status = VL53L0X_ERROR_NONE; + uint8_t VhvSettings; + uint8_t PhaseCal; + uint32_t refSpadCount; + uint8_t isApertureSpads; + + vl53l0x_reset(dev);//λvl53l0x(Ƶлģʽ׵²ɼݲ׼һ) + status = VL53L0X_StaticInit(dev); + + if(AjustOK!=0)//У׼,дУ׼ֵ + { + status= VL53L0X_SetReferenceSpads(dev,Vl53l0x_data.refSpadCount,Vl53l0x_data.isApertureSpads);//趨SpadsУ׼ֵ + if(status!=VL53L0X_ERROR_NONE) goto error; + delay_ms(2); + status= VL53L0X_SetRefCalibration(dev,Vl53l0x_data.VhvSettings,Vl53l0x_data.PhaseCal);//趨RefУ׼ֵ + if(status!=VL53L0X_ERROR_NONE) goto error; + delay_ms(2); + status=VL53L0X_SetOffsetCalibrationDataMicroMeter(dev,Vl53l0x_data.OffsetMicroMeter);//趨ƫУ׼ֵ + if(status!=VL53L0X_ERROR_NONE) goto error; + delay_ms(2); + status=VL53L0X_SetXTalkCompensationRateMegaCps(dev,Vl53l0x_data.XTalkCompensationRateMegaCps);//趨У׼ֵ + if(status!=VL53L0X_ERROR_NONE) goto error; + delay_ms(2); + } + else + { + status = VL53L0X_PerformRefCalibration(dev, &VhvSettings, &PhaseCal);//RefοУ׼ + if(status!=VL53L0X_ERROR_NONE) goto error; + delay_ms(2); + status = VL53L0X_PerformRefSpadManagement(dev, &refSpadCount, &isApertureSpads);//ִвοSPAD + if(status!=VL53L0X_ERROR_NONE) goto error; + delay_ms(2); + } + status = VL53L0X_SetDeviceMode(dev,VL53L0X_DEVICEMODE_SINGLE_RANGING);//ʹܵβģʽ + if(status!=VL53L0X_ERROR_NONE) goto error; + delay_ms(2); + status = VL53L0X_SetLimitCheckEnable(dev,VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE,1);//ʹSIGMAΧ + if(status!=VL53L0X_ERROR_NONE) goto error; + delay_ms(2); + status = VL53L0X_SetLimitCheckEnable(dev,VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE,1);//ʹźʷΧ + if(status!=VL53L0X_ERROR_NONE) goto error; + delay_ms(2); + status = VL53L0X_SetLimitCheckValue(dev,VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE,Mode_data[mode].sigmaLimit);//趨SIGMAΧ + if(status!=VL53L0X_ERROR_NONE) goto error; + delay_ms(2); + status = VL53L0X_SetLimitCheckValue(dev,VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE,Mode_data[mode].signalLimit);//趨źʷΧΧ + if(status!=VL53L0X_ERROR_NONE) goto error; + delay_ms(2); + status = VL53L0X_SetMeasurementTimingBudgetMicroSeconds(dev,Mode_data[mode].timingBudget);//趨ʱ + if(status!=VL53L0X_ERROR_NONE) goto error; + delay_ms(2); + status = VL53L0X_SetVcselPulsePeriod(dev, VL53L0X_VCSEL_PERIOD_PRE_RANGE, Mode_data[mode].preRangeVcselPeriod);//趨VCSEL + if(status!=VL53L0X_ERROR_NONE) goto error; + delay_ms(2); + status = VL53L0X_SetVcselPulsePeriod(dev, VL53L0X_VCSEL_PERIOD_FINAL_RANGE, Mode_data[mode].finalRangeVcselPeriod);//趨VCSELڷΧ + + error://Ϣ + if(status!=VL53L0X_ERROR_NONE) + { + print_pal_error(status); + return status; + } + return status; + +} diff --git a/modules/VL53L0X/src/vl53l0x_i2c.c b/modules/VL53L0X/src/vl53l0x_i2c.c new file mode 100644 index 0000000000000000000000000000000000000000..c2de6329dca3c7ab50827f8db105db8a1a15a7a8 --- /dev/null +++ b/modules/VL53L0X/src/vl53l0x_i2c.c @@ -0,0 +1,428 @@ +#include "vl53l0x_i2c.h" +#include "delay.h" + + + +//VL53L0X I2Cʼ +//void VL53L0X_i2c_init(void) +//{ +// RCC_AHB1PeriphClockCmd(RCC_VL53L0x, ENABLE); // ʹGPIOʱ +// +// GPIO_InitTypeDef GPIO_InitStructure; + +// GPIO_InitStructure.GPIO_Pin = GPIO_SDA|GPIO_SCL; +// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; +// GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; +// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; +// GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; +// GPIO_Init(PORT_VL53L0x, &GPIO_InitStructure); + +//} + +/****************************************************************** + * ƣIIC_Start + * ˵ IICʼʱ + * Σ + * أ + * ߣLC + * ע +******************************************************************/ +void IIC_Start(void) +{ + SDA_OUT(); + + SDA(1); + delay_us(5); + SCL(1); + delay_us(5); + + SDA(0); + delay_us(5); + SCL(0); + delay_us(5); + +} +/****************************************************************** + * ƣIIC_Stop + * ˵ IICֹͣź + * Σ + * أ + * ߣLC + * ע +******************************************************************/ +void IIC_Stop(void) +{ + SDA_OUT(); + SCL(0); + SDA(0); + + SCL(1); + delay_us(5); + SDA(1); + delay_us(5); + +} + +/****************************************************************** + * ƣIIC_Send_Ack + * ˵ Ӧ߷Ӧź + * Σ0Ӧ 1ͷӦ + * أ + * ߣLC + * ע +******************************************************************/ +void IIC_Send_Ack(unsigned char ack) +{ + SDA_OUT(); + SCL(0); + SDA(0); + delay_us(5); + if(!ack) SDA(0); + else SDA(1); + SCL(1); + delay_us(5); + SCL(0); + SDA(1); +} + + +/****************************************************************** + * ƣI2C_WaitAck + * ˵ ȴӻӦ + * Σ + * أ0Ӧ 1ʱӦ + * ߣLC + * ע +******************************************************************/ +unsigned char I2C_WaitAck(void) +{ + + char ack = 0; + unsigned char ack_flag = 10; + SCL(0); + SDA(1); + SDA_IN(); + delay_us(5); + SCL(1); + delay_us(5); + + while( (SDA_GET()==1) && ( ack_flag ) ) + { + ack_flag--; + delay_us(5); + } + + if( ack_flag <= 0 ) + { + IIC_Stop(); + return 1; + } + else + { + SCL(0); + SDA_OUT(); + } + return ack; +} + +/****************************************************************** + * ƣSend_Byte + * ˵ дһֽ + * ΣdatҪд˵ + * أ + * ߣLC + * ע +******************************************************************/ +void Send_Byte(uint8_t dat) +{ + int i = 0; + SDA_OUT(); + SCL(0);//ʱӿʼݴ + + for( i = 0; i < 8; i++ ) + { + SDA( (dat & 0x80) >> 7 ); + delay_us(1); + SCL(1); + delay_us(5); + SCL(0); + delay_us(5); + dat<<=1; + } +} + +/****************************************************************** + * ƣRead_Byte + * ˵ IICʱ + * Σack=1ʱACKack=0nACK + * أ + * ߣLC + * ע +******************************************************************/ +unsigned char Read_Byte(unsigned char ack) +{ + unsigned char i,receive=0; + SDA_IN();//SDAΪ + for(i=0;i<8;i++ ) + { + SCL(0); + delay_us(4); + SCL(1); + receive<<=1; + if( SDA_GET() )receive++; + delay_us(4); //1 + } + if (!ack) + IIC_Send_Ack(1);//nACK + else + IIC_Send_Ack(0); //ACK + return receive; +} + + +//IICдһֽ +u8 VL_IIC_Write_1Byte(u8 SlaveAddress, u8 REG_Address,u8 REG_data) +{ + IIC_Start(); + Send_Byte(SlaveAddress); + if(I2C_WaitAck()) + { + IIC_Stop();//ͷ + return 1;//ûӦ˳ + + } + Send_Byte(REG_Address); + I2C_WaitAck(); + Send_Byte(REG_data); + I2C_WaitAck(); + IIC_Stop(); + + return 0; +} + +//IICһֽ +u8 VL_IIC_Read_1Byte(u8 SlaveAddress, u8 REG_Address,u8 *REG_data) +{ + IIC_Start(); + Send_Byte(SlaveAddress);//д + if(I2C_WaitAck()) + { + IIC_Stop();//ͷ + return 1;//ûӦ˳ + } + Send_Byte(REG_Address); + I2C_WaitAck(); + IIC_Start(); + Send_Byte(SlaveAddress|0x01);// + I2C_WaitAck(); + *REG_data = Read_Byte(0); + IIC_Stop(); + + return 0; +} + +//IICдnֽ +u8 VL_IIC_Write_nByte(u8 SlaveAddress, u8 REG_Address,u16 len, u8 *buf) +{ + IIC_Start(); + Send_Byte(SlaveAddress);//д + if(I2C_WaitAck()) + { + IIC_Stop();//ͷ + return 1;//ûӦ˳ + } + Send_Byte(REG_Address); + I2C_WaitAck(); + while(len--) + { + Send_Byte(*buf++);//buff + I2C_WaitAck(); + } + IIC_Stop();//ͷ + + return 0; + +} + +//IICnֽ +u8 VL_IIC_Read_nByte(u8 SlaveAddress, u8 REG_Address,u16 len,u8 *buf) +{ + IIC_Start(); + Send_Byte(SlaveAddress);//д + if(I2C_WaitAck()) + { + IIC_Stop();//ͷ + return 1;//ûӦ˳ + } + Send_Byte(REG_Address); + I2C_WaitAck(); + + IIC_Start(); + Send_Byte(SlaveAddress|0x01);// + I2C_WaitAck(); + while(len) + { + if(len==1) + { + *buf = Read_Byte(0); + } + else + { + *buf = Read_Byte(1); + } + buf++; + len--; + } + IIC_Stop();//ͷ + + return 0; + +} + +//VL53L0X д +//address:ַ +//index:ƫƵַ +//pdata:ָ +//count: 65535 +u8 VL53L0X_write_multi(u8 address, u8 index,u8 *pdata,u16 count) +{ + u8 status = STATUS_OK; + + if(VL_IIC_Write_nByte(address,index,count,pdata)) + { + status = STATUS_FAIL; + } + return status; +} + + +//VL53L0X +//address:ַ +//index:ƫƵַ +//pdata:ָ +//count: 65535 +u8 VL53L0X_read_multi(u8 address,u8 index,u8 *pdata,u16 count) +{ + u8 status = STATUS_OK; + + if(VL_IIC_Read_nByte(address,index,count,pdata)) + { + status = STATUS_FAIL; + } + + return status; +} + +//VL53L0X д1(ֽ) +//address:ַ +//index:ƫƵַ +//data:(8λ) +u8 VL53L0X_write_byte(u8 address,u8 index,u8 data) +{ + u8 status = STATUS_OK; + + status = VL53L0X_write_multi(address,index,&data,1); + + return status; +} + +//VL53L0X д1(˫ֽ) +//address:ַ +//index:ƫƵַ +//data:(16λ) +u8 VL53L0X_write_word(u8 address,u8 index,u16 data) +{ + u8 status = STATUS_OK; + + u8 buffer[2]; + + //16λݲֳ8λ + buffer[0] = (u8)(data>>8);//߰λ + buffer[1] = (u8)(data&0xff);//Ͱλ + + if(index%2==1) + { + //ͨŲܴԷ2ֽڶĴֽ + status = VL53L0X_write_multi(address,index,&buffer[0],1); + status = VL53L0X_write_multi(address,index,&buffer[0],1); + }else + { + status = VL53L0X_write_multi(address,index,buffer,2); + } + + return status; +} + +//VL53L0X д1(ֽ) +//address:ַ +//index:ƫƵַ +//data:(32λ) +u8 VL53L0X_write_dword(u8 address,u8 index,u32 data) +{ + + u8 status = STATUS_OK; + + u8 buffer[4]; + + //32λݲֳ8λ + buffer[0] = (u8)(data>>24); + buffer[1] = (u8)((data&0xff0000)>>16); + buffer[2] = (u8)((data&0xff00)>>8); + buffer[3] = (u8)(data&0xff); + + status = VL53L0X_write_multi(address,index,buffer,4); + + return status; + +} + + +//VL53L0X 1(ֽ) +//address:ַ +//index:ƫƵַ +//data:(8λ) +u8 VL53L0X_read_byte(u8 address,u8 index,u8 *pdata) +{ + u8 status = STATUS_OK; + + status = VL53L0X_read_multi(address,index,pdata,1); + + return status; + +} + +//VL53L0X (˫ֽ) +//address:ַ +//index:ƫƵַ +//data:(16λ) +u8 VL53L0X_read_word(u8 address,u8 index,u16 *pdata) +{ + u8 status = STATUS_OK; + + u8 buffer[2]; + + status = VL53L0X_read_multi(address,index,buffer,2); + + *pdata = ((u16)buffer[0]<<8)+(u16)buffer[1]; + + return status; + +} + +//VL53L0X 1(ֽ) +//address:ַ +//index:ƫƵַ +//data:(32λ) +u8 VL53L0X_read_dword(u8 address,u8 index,u32 *pdata) +{ + u8 status = STATUS_OK; + + u8 buffer[4]; + + status = VL53L0X_read_multi(address,index,buffer,4); + + *pdata = ((u32)buffer[0]<<24)+((u32)buffer[1]<<16)+((u32)buffer[2]<<8)+((u32)buffer[3]); + + return status; + +} diff --git a/modules/VL53L0X/src/vl53l0x_it.c b/modules/VL53L0X/src/vl53l0x_it.c new file mode 100644 index 0000000000000000000000000000000000000000..ecc60321b54e35c11e443c48c375aa678e94bd24 --- /dev/null +++ b/modules/VL53L0X/src/vl53l0x_it.c @@ -0,0 +1,262 @@ +#include "vl53l0x_it.h" + +/* +//޾ֵ λ:mm +#define Thresh_Low 60 +#define Thresh_High 150 + +//жģʽṹ +typedef struct +{ + const int VL53L0X_Mode;//ģʽ + uint32_t ThreshLow; //ֵ + uint32_t ThreshHigh; //ֵ +}AlrmMode_t; + +AlrmMode_t AlarmModes ={ + + VL53L0X_GPIOFUNCTIONALITY_THRESHOLD_CROSSED_OUT,// value < thresh_low OR value > thresh_high + Thresh_Low<<16, + Thresh_High<<16 +}; + +//жóʼ +static void exti1_init(void) +{ +// GPIO_InitTypeDef GPIO_InitStructure; +// EXTI_InitTypeDef EXTI_InitStructure; +// NVIC_InitTypeDef NVIC_InitStructure; +// +// RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);//ʹGPIOFʱ +// RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);//ʹSYSCFGʱ +// +// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; +// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//ͨģʽ +// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz +// GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;// +// GPIO_Init(GPIOF, &GPIO_InitStructure);//ʼ + +// SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOF, EXTI_PinSource6);//PF6 ӵж6 +// +// EXTI_InitStructure.EXTI_Line = EXTI_Line6;//LINE6 +// EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//ж¼ +// EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //½ش +// EXTI_InitStructure.EXTI_LineCmd = ENABLE;//ʹLINE6 +// EXTI_Init(&EXTI_InitStructure);// +// +// NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;//ⲿж6 +// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x03;//ռȼ3 +// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;//ȼ2 +// NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//ʹⲿжͨ +// NVIC_Init(&NVIC_InitStructure); + +} + +//־λ alarm_flag +//1:о +//0 +u8 alarm_flag=0; + +//ⲿжϷ +void EXTI9_5_IRQHandler(void) +{ + alarm_flag=1;//־ +// EXTI_ClearITPendingBit(EXTI_Line6); //LINE6ϵжϱ־λ +} + +extern uint8_t AjustOK; +extern mode_data Mode_data[]; + +//vl53l0xжϲģʽ +//dev:豸I2Cṹ +//mode: 0:Ĭ;1:߾;2:;3: +void vl53l0x_interrupt_start(VL53L0X_Dev_t *dev,uint8_t mode) +{ +// uint8_t VhvSettings; +// uint8_t PhaseCal; +// uint32_t refSpadCount; +// uint8_t isApertureSpads; +// VL53L0X_RangingMeasurementData_t RangingMeasurementData; +// static char buf[VL53L0X_MAX_STRING_LENGTH];//ģʽַַ +// VL53L0X_Error status=VL53L0X_ERROR_NONE;//״̬ +// u8 key; + +// exti_init();//жϳʼ +// LED0=1; +// mode_string(mode,buf);//ʾǰõģʽ +// LCD_Fill(30,170,300,300,WHITE); +// POINT_COLOR=RED; //Ϊɫ +// LCD_ShowString(30,140+30,300,16,16,"Interrupt Mode "); +// POINT_COLOR=BLUE; //Ϊɫ +// LCD_ShowString(30,140+50,200,16,16,"KEY_UP: Exit the test "); +// LCD_ShowString(30,140+70,200,16,16,"Mode: "); +// LCD_ShowString(80,140+70,200,16,16,(u8*)buf); +// sprintf((char*)buf,"Thresh Low: %d mm ",Thresh_Low); +// printf("Thresh Low: %d mm \n\r",Thresh_Low); +// LCD_ShowString(30,140+90,300,16,16,(u8*)buf); +// sprintf((char*)buf,"Thresh High: %d mm",Thresh_High); +// printf("Thresh High: %d mm \n\r",Thresh_High); +// LCD_ShowString(30,140+110,300,16,16,(u8*)buf); +// LCD_ShowString(30,140+130,300,16,16,"Now value: mm"); +// +// vl53l0x_reset(dev);//λvl53l0x(Ƶлģʽ׵²ɼݲ׼һ) +// status = VL53L0X_StaticInit(dev); +// if(status!=VL53L0X_ERROR_NONE) goto error; + +// if(AjustOK!=0)//У׼,дУ׼ֵ +// { +// status= VL53L0X_SetReferenceSpads(dev,Vl53l0x_data.refSpadCount,Vl53l0x_data.isApertureSpads);//趨SpadsУ׼ֵ +// if(status!=VL53L0X_ERROR_NONE) goto error; +// delay_ms(2); +// status= VL53L0X_SetRefCalibration(dev,Vl53l0x_data.VhvSettings,Vl53l0x_data.PhaseCal);//趨RefУ׼ֵ +// if(status!=VL53L0X_ERROR_NONE) goto error; +// delay_ms(2); +// status=VL53L0X_SetOffsetCalibrationDataMicroMeter(dev,Vl53l0x_data.OffsetMicroMeter);//趨ƫУ׼ֵ +// if(status!=VL53L0X_ERROR_NONE) goto error; +// delay_ms(2); +// status=VL53L0X_SetXTalkCompensationRateMegaCps(dev,Vl53l0x_data.XTalkCompensationRateMegaCps);//趨У׼ֵ +// if(status!=VL53L0X_ERROR_NONE) goto error; +// }else +// { +// status = VL53L0X_PerformRefCalibration(dev, &VhvSettings, &PhaseCal);//RefοУ׼ +// if(status!=VL53L0X_ERROR_NONE) goto error; +// delay_ms(2); +// status = VL53L0X_PerformRefSpadManagement(dev, &refSpadCount, &isApertureSpads);//ִвοSPAD +// if(status!=VL53L0X_ERROR_NONE) goto error; +// delay_ms(2); +// } +// status = VL53L0X_SetDeviceMode(dev,VL53L0X_DEVICEMODE_CONTINUOUS_RANGING);//ʹģʽ +// if(status!=VL53L0X_ERROR_NONE) goto error; +// delay_ms(2); +// status = VL53L0X_SetInterMeasurementPeriodMilliSeconds(dev,Mode_data[mode].timingBudget);//ڲڲʱ +// if(status!=VL53L0X_ERROR_NONE) goto error; +// delay_ms(2); +// status = VL53L0X_SetLimitCheckEnable(dev,VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE,1);//ʹSIGMAΧ +// if(status!=VL53L0X_ERROR_NONE) goto error; +// delay_ms(2); +// status = VL53L0X_SetLimitCheckEnable(dev,VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE,1);//ʹźʷΧ +// if(status!=VL53L0X_ERROR_NONE) goto error; +// delay_ms(2); +// status = VL53L0X_SetLimitCheckValue(dev,VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE,Mode_data[mode].sigmaLimit);//趨SIGMAΧ +// if(status!=VL53L0X_ERROR_NONE) goto error; +// delay_ms(2); +// status = VL53L0X_SetLimitCheckValue(dev,VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE,Mode_data[mode].signalLimit);//趨źʷΧΧ +// if(status!=VL53L0X_ERROR_NONE) goto error; +// delay_ms(2); +// status = VL53L0X_SetMeasurementTimingBudgetMicroSeconds(dev,Mode_data[mode].timingBudget);//趨ʱ +// if(status!=VL53L0X_ERROR_NONE) goto error; +// delay_ms(2); +// status = VL53L0X_SetVcselPulsePeriod(dev, VL53L0X_VCSEL_PERIOD_PRE_RANGE, Mode_data[mode].preRangeVcselPeriod);//趨VCSEL +// if(status!=VL53L0X_ERROR_NONE) goto error; +// delay_ms(2); +// status = VL53L0X_SetVcselPulsePeriod(dev, VL53L0X_VCSEL_PERIOD_FINAL_RANGE, Mode_data[mode].finalRangeVcselPeriod);//趨VCSELڷΧ +// if(status!=VL53L0X_ERROR_NONE) goto error; +// delay_ms(2); +// status = VL53L0X_StopMeasurement(dev);//ֹͣ +// if(status!=VL53L0X_ERROR_NONE) goto error; +// delay_ms(2); +// status = VL53L0X_SetInterruptThresholds(dev,VL53L0X_DEVICEMODE_CONTINUOUS_RANGING,AlarmModes.ThreshLow, AlarmModes.ThreshHigh);//趨жϡֵ +// if(status!=VL53L0X_ERROR_NONE) goto error; +// delay_ms(2); +// status = VL53L0X_SetGpioConfig(dev,0,VL53L0X_DEVICEMODE_CONTINUOUS_RANGING,AlarmModes.VL53L0X_Mode,VL53L0X_INTERRUPTPOLARITY_LOW);//趨жģʽ ½ +// if(status!=VL53L0X_ERROR_NONE) goto error; +// delay_ms(2); +// status = VL53L0X_ClearInterruptMask(dev,0);//VL53L0Xжϱ־λ +// +// error://Ϣ +// if(status!=VL53L0X_ERROR_NONE) +// { +// print_pal_error(status); +// return ; +// } + +// alarm_flag = 0; +// VL53L0X_StartMeasurement(dev);// +// while(1) +// { +// key = KEY_Scan(0); +// if(key==WKUP_PRES) +// { +// VL53L0X_ClearInterruptMask(dev,0);//VL53L0Xжϱ־λ +// status = VL53L0X_StopMeasurement(dev); //ֹͣ +// LED1=1; +// break;//һ˵ +// } +// if(alarm_flag==1)//ж +// { +// alarm_flag=0; +// VL53L0X_GetRangingMeasurementData(dev,&RangingMeasurementData);//ȡ,ʾ +// printf("d: %3d mm\r\n",RangingMeasurementData.RangeMilliMeter); +// LCD_ShowxNum(110,140+130,RangingMeasurementData.RangeMilliMeter,4,16,0); +// delay_ms(70); +// VL53L0X_ClearInterruptMask(dev,0);//VL53L0Xжϱ־λ +// +// } +// delay_ms(30); +// LED1=!LED1; + +// } + +} + +//vl53l0xжϲģʽUI +void interrupt_ui(void) +{ +// LCD_Fill(30,140+20,300,300,WHITE); +// POINT_COLOR=RED; //Ϊɫ +// LCD_ShowString(30,140+30,300,16,16,"Interrupt Mode "); +// LCD_ShowString(30,140+55,300,16,16,"KEY1: Switch working mode "); +// POINT_COLOR=BLUE; //Ϊɫ +// LCD_ShowString(30,140+75,300,16,16, "KEY_UP: Return menu "); +// LCD_ShowString(30,140+95,300,16,16, "KEY0: Default "); +// printf("interrupt_test \n\r"); +// printf("WK_UP: Return menu \n\r"); +// printf("KEY1 : Switch working mode \n\r"); +// printf("KEY0 : START! \n\r"); +} + +//vl53l0xжϲģʽ +//dev:豸I2Cṹ +void vl53l0x_interrupt_test(VL53L0X_Dev_t *dev) +{ +// u8 key=0; +// u8 i=0; +// u8 mode=0; +// LED1=1; +// interrupt_ui();//ʾжϲģʽUI +// +// while(1) +// { +// key = KEY_Scan(0); +// +// if(key==WKUP_PRES) break;//˵ +// +// else if(key==KEY1_PRES)//ѡģʽ +// { +// mode++; +// if(mode==4) mode=0; +// +// switch(mode) +// { +// case Default_Mode: LCD_ShowString(95,140+95,300,16,16, "Default "); printf("Default \n\r"); break;//Ĭ +// case HIGH_ACCURACY: LCD_ShowString(95,140+95,300,16,16, "High Accuracy "); printf("High Accuracy \n\r"); break;//߾ +// case LONG_RANGE: LCD_ShowString(95,140+95,300,16,16, "Long Range "); printf("Long Range \n\r"); break;// +// case HIGH_SPEED: LCD_ShowString(95,140+95,300,16,16, "High Speed "); printf("High Speed \n\r"); break;// +// } +// } +// else if(key==KEY0_PRES)// +// { +// vl53l0x_interrupt_start(dev,mode); +// interrupt_ui(); +// mode=0; +// } +// i++; +// if(i==5) +// { +// i=0; +// LED0=!LED0; +// } +// delay_ms(50); +// } + +}*/ diff --git a/modules/VL53L0X/src/vl53l0x_platform.c b/modules/VL53L0X/src/vl53l0x_platform.c new file mode 100644 index 0000000000000000000000000000000000000000..fefd91d1ab4002ac618792c5002766455a29a366 --- /dev/null +++ b/modules/VL53L0X/src/vl53l0x_platform.c @@ -0,0 +1,271 @@ +#include "vl53l0x_platform.h" + +//VL53L0Xд +//Dev:豸I2Cṹ +//index:ƫƵַ +//pdata:ָ +//count: +//ֵ: 0:ɹ +// : +VL53L0X_Error VL53L0X_WriteMulti(VL53L0X_DEV Dev, uint8_t index, uint8_t *pdata,uint32_t count) +{ + + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + + int32_t status_int = 0; + + uint8_t deviceAddress; + + if(count >=VL53L0X_MAX_I2C_XFER_SIZE) + { + Status = VL53L0X_ERROR_INVALID_PARAMS; + } + + deviceAddress = Dev->I2cDevAddr; + + status_int = VL53L0X_write_multi(deviceAddress, index, pdata, count); + + if(status_int !=0) + Status = VL53L0X_ERROR_CONTROL_INTERFACE; + + return Status; + +} + +//VL53L0X +//Dev:豸I2Cṹ +//index:ƫƵַ +//pdata:ָ +//count: +//ֵ: 0:ɹ +// : +VL53L0X_Error VL53L0X_ReadMulti(VL53L0X_DEV Dev, uint8_t index, uint8_t *pdata,uint32_t count) +{ + + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + + int32_t status_int; + + uint8_t deviceAddress; + + if(count >=VL53L0X_MAX_I2C_XFER_SIZE) + { + Status = VL53L0X_ERROR_INVALID_PARAMS; + } + + deviceAddress = Dev->I2cDevAddr; + + status_int = VL53L0X_read_multi(deviceAddress, index, pdata, count); + + if(status_int!=0) + Status = VL53L0X_ERROR_CONTROL_INTERFACE; + + return Status; + +} + +//VL53L0X дֽڼĴ +//Dev:豸I2Cṹ +//index:ƫƵַ +//pdata:ָ +//count: +//ֵ: 0:ɹ +// :ʧ +VL53L0X_Error VL53L0X_WrByte(VL53L0X_DEV Dev, uint8_t index, uint8_t data) +{ + + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + int32_t status_int; + uint8_t deviceAddress; + + deviceAddress = Dev->I2cDevAddr; + + status_int = VL53L0X_write_byte(deviceAddress,index,data); + + if(status_int!=0) + Status = VL53L0X_ERROR_CONTROL_INTERFACE; + + return Status; + +} + +//VL53L0X д֣2ֽڣĴ +//Dev:豸I2Cṹ +//index:ƫƵַ +//pdata:ָ +//count: +//ֵ: 0:ɹ +// :ʧ +VL53L0X_Error VL53L0X_WrWord(VL53L0X_DEV Dev, uint8_t index, uint16_t data) +{ + + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + int32_t status_int; + uint8_t deviceAddress; + + deviceAddress = Dev->I2cDevAddr; + + status_int = VL53L0X_write_word(deviceAddress,index,data); + + if(status_int!=0) + Status = VL53L0X_ERROR_CONTROL_INTERFACE; + + return Status; + +} + +//VL53L0X д˫֣4ֽڣĴ +//Dev:豸I2Cṹ +//index:ƫƵַ +//pdata:ָ +//count: +//ֵ: 0:ɹ +// :ʧ +VL53L0X_Error VL53L0X_WrDWord(VL53L0X_DEV Dev, uint8_t index, uint32_t data) +{ + + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + int32_t status_int; + uint8_t deviceAddress; + + deviceAddress = Dev->I2cDevAddr; + + status_int = VL53L0X_write_dword(deviceAddress, index, data); + + if (status_int != 0) + Status = VL53L0X_ERROR_CONTROL_INTERFACE; + + return Status; + +} + +//VL53L0X вȫ(/޸/д)ֽڼĴ +//Dev:豸I2Cṹ +//index:ƫƵַ +//AndData:8λ +//OrData:8λ +//ֵ: 0:ɹ +// : +VL53L0X_Error VL53L0X_UpdateByte(VL53L0X_DEV Dev, uint8_t index, uint8_t AndData, uint8_t OrData) +{ + + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + int32_t status_int; + uint8_t deviceAddress; + uint8_t data; + + deviceAddress = Dev->I2cDevAddr; + + status_int = VL53L0X_read_byte(deviceAddress,index,&data); + + if(status_int!=0) + Status = VL53L0X_ERROR_CONTROL_INTERFACE; + + if(Status == VL53L0X_ERROR_NONE) + { + data = (data & AndData) | OrData; + status_int = VL53L0X_write_byte(deviceAddress, index,data); + + + if(status_int !=0) + Status = VL53L0X_ERROR_CONTROL_INTERFACE; + + } + + return Status; + +} + +//VL53L0X ֽڼĴ +//Dev:豸I2Cṹ +//index:ƫƵַ +//pdata:ָ +//count: +//ֵ: 0:ɹ +// : +VL53L0X_Error VL53L0X_RdByte(VL53L0X_DEV Dev, uint8_t index, uint8_t *data) +{ + + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + int32_t status_int; + uint8_t deviceAddress; + + deviceAddress = Dev->I2cDevAddr; + + status_int = VL53L0X_read_byte(deviceAddress, index, data); + + if(status_int !=0) + Status = VL53L0X_ERROR_CONTROL_INTERFACE; + + return Status; + +} + +//VL53L0X ֣2ֽڣĴ +//Dev:豸I2Cṹ +//index:ƫƵַ +//pdata:ָ +//count: +//ֵ: 0:ɹ +// : +VL53L0X_Error VL53L0X_RdWord(VL53L0X_DEV Dev, uint8_t index, uint16_t *data) +{ + + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + int32_t status_int; + uint8_t deviceAddress; + + deviceAddress = Dev->I2cDevAddr; + + status_int = VL53L0X_read_word(deviceAddress, index, data); + + if(status_int !=0) + Status = VL53L0X_ERROR_CONTROL_INTERFACE; + + return Status; + +} + +//VL53L0X ˫֣4ֽڣĴ +//Dev:豸I2Cṹ +//index:ƫƵַ +//pdata:ָ +//count: +//ֵ: 0:ɹ +// : +VL53L0X_Error VL53L0X_RdDWord(VL53L0X_DEV Dev, uint8_t index, uint32_t *data) +{ + + VL53L0X_Error Status = VL53L0X_ERROR_NONE; + int32_t status_int; + uint8_t deviceAddress; + + deviceAddress = Dev->I2cDevAddr; + + status_int = VL53L0X_read_dword(deviceAddress, index, data); + + if (status_int != 0) + Status = VL53L0X_ERROR_CONTROL_INTERFACE; + + return Status; +} + +//VL53L0X ײʱ +//Dev:豸I2Cṹ +//ֵ: 0:ɹ +// : +#define VL53L0X_POLLINGDELAY_LOOPNB 250 +VL53L0X_Error VL53L0X_PollingDelay(VL53L0X_DEV Dev) +{ + + VL53L0X_Error status = VL53L0X_ERROR_NONE; + volatile uint32_t i; + + for(i=0;i> 4)); + OLED_Write_Cmd(0x00 | (column & 0x0F)); } -void HW_OLED_FullyFill(uint8_t fillData) { - for(uint16_t m = 0; m < displayHeight/8; m++) { - for(uint16_t n = 0; n < displayWidth; n++) { - OLED_RAM[m][n] = fillData; - } +static void OLED_Write_Batch(uint8_t page, uint8_t startCol, const uint8_t *data, uint8_t dataLen) +{ + OLED_Set_Cursor(page, startCol); + for (uint8_t i = 0; i < dataLen; ++i) + { + OLED_Write_Data(data[i]); } - HW_OLED_RefreshRAM(); } -void HW_OLED_FullyClear(void) { - HW_OLED_FullyFill(RESET_PIXEL); -} - -void HW_OLED_SetPixel(int16_t x, int16_t y, uint8_t setPixel) { - if (x >= 0 && x < displayWidth && y >= 0 && y < displayHeight) { - if (setPixel) { - OLED_RAM[y/8][x] |= (0x01 << (y%8)); - } else { - OLED_RAM[y/8][x] &= ~(0x01 << (y%8)); - } - } -} - -PixelStatus HW_OLED_GetPixel(int16_t x, int16_t y) { - if (OLED_RAM[y/8][x] >> (y%8) & 0x01) - return SET_PIXEL; - return RESET_PIXEL; -} - -// 修正形参命名:ch → str,TextSize → textSize -void HW_OLED_ShowStr(int16_t x, int16_t y, uint8_t str[], uint8_t textSize) { - if (x >= 0 && x < displayWidth && y >= 0 && y < displayHeight) { - int32_t c = 0; - uint8_t j = 0; - switch (textSize) { - case 1: { - while (str[j] != '\0') { - c = str[j] - 32; - if (c < 0) - break; - - if (x >= 125 || (127 - x < 6)) { - x = 0; - y += 8; - if (63 - y < 8) - break; - } - for (uint8_t m = 0; m < 6; m++) { - for (uint8_t n = 0; n < 8; n++) { - HW_OLED_SetPixel(x + m, y + n, (F6x8[c][m] >> n) & 0x01); - } - } - x += 6; - j++; - } - } break; - case 2: { - while (str[j] != '\0') { - c = str[j] - 32; - if (c < 0) - break; - - if (x >= 127 || (127 - x < 8)) { - x = 0; - y += 16; - if (63 - y < 16) - break; - } - for (uint8_t m = 0; m < 2; m++) { - for (uint8_t n = 0; n < 8; n++) { - for (uint8_t i = 0; i < 8; i++) { - HW_OLED_SetPixel(x + n, y + i + m*8, (F8X16[c][n + m*8] >> i) & 0x01); - } - } - } - x += 8; - j++; - } - } break; - } - } - HW_OLED_RefreshRAM(); -} - -void HW_OLED_ShowCN(int16_t x, int16_t y, uint8_t* str) { - if (x >= 0 && x < displayWidth && y >= 0 && y < displayHeight) { - int32_t len = 0, offset = sizeof(F16x16_CN[0].index); - - while (str[len] != '\0') { - if (x >= 127 || (127 - x < 16)) { - x = 0; - y += 16; - if (63 - y < 16) - break; - } - for (uint8_t i = 0; i < sizeof(F16x16_CN)/sizeof(GB2312_CN); i++) { - if (((F16x16_CN[i].index[0] == str[len]) && (F16x16_CN[i].index[1] == str[len+1]))) { - for (uint8_t m = 0; m < 2; m++) { - for (uint8_t n = 0; n < 16; n++) { - for (uint8_t j = 0; j < 8; j++) { - HW_OLED_SetPixel(x + n, y + j + m*8, (F16x16_CN[i].encoder[n + m*16] >> j) & 0x01); - } - } - } - x += 16; - len += offset; - break; - } - else if (F16x16_CN[i].index[0] == str[len] && str[len] == 0x20) { - for (uint8_t m = 0; m < 2; m++) { - for (uint8_t n = 0; n < 16; n++) { - for (uint8_t j = 0; j < 8; j++) { - HW_OLED_SetPixel(x + n, y + j + m*8, (F16x16_CN[i].encoder[n + m*16] >> j) & 0x01); - } - } - } - x += 16; - len++; - break; - } - } - } +static void OLED_Write_Page(uint8_t page, uint8_t fillValue) +{ + OLED_Set_Cursor(page, 0); + for (uint8_t i = 0; i < 128; ++i) + { + OLED_Write_Data(fillValue); } - HW_OLED_RefreshRAM(); } -void HW_OLED_ShowMixedCH(int16_t x, int16_t y, uint8_t* str) { - if (x >= 0 && x < displayWidth && y >= 0 && y < displayHeight) { - int32_t len = 0, c, offset = sizeof(F16x16_CN[0].index); - - while (str[len] != '\0') { - if (str[len] >= 0xa1) { - for (uint8_t i = 0; i < sizeof(F16x16_CN)/sizeof(GB2312_CN); i++) { - if (((F16x16_CN[i].index[0] == str[len]) && (F16x16_CN[i].index[1] == str[len+1]))) { - if (x >= 127 || (127 - x < 16)) { - x = 0; - y += 16; - if (63 - y < 16) - break; - } - for (uint8_t m = 0; m < 2; m++) { - for (uint8_t n = 0; n < 16; n++) { - for (uint8_t j = 0; j < 8; j++) { - HW_OLED_SetPixel(x + n, y + j + m*8, (F16x16_CN[i].encoder[n + m*16] >> j) & 0x01); - } - } - } - x += 16; - len += offset; - break; - } - } - } - else if (str[len] <= 127) { - c = str[len] - 32; - if (c < 0) - break; - if (x >= 127 || (127 - x < 8)) { - x = 0; - y += 16; - if (63 - y < 16) - break; - } - for (uint8_t m = 0; m < 2; m++) { - for (uint8_t n = 0; n < 8; n++) { - for (uint8_t i = 0; i < 8; i++) { - HW_OLED_SetPixel(x + n, y + i + m*8, (F8X16[c][n + m*8] >> i) & 0x01); - } - } - } - x += 8; - len++; - } - } +// 公共API +void HW_OLED_Init(void) +{ + gI2cHandle = &hi2c1; // 假设使用 hi2c1,根据实际修改 + HAL_Delay(100); + + // 初始化命令序列 + OLED_Write_Cmd(0xAE); // 关闭显示 + OLED_Write_Cmd(0xD5); OLED_Write_Cmd(0x80); + OLED_Write_Cmd(0xA8); OLED_Write_Cmd(0x3F); + OLED_Write_Cmd(0xD3); OLED_Write_Cmd(0x00); + OLED_Write_Cmd(0x40); // 起始行 + OLED_Write_Cmd(0xA1); // 左右反置 + OLED_Write_Cmd(0xC8); // 上下反置 + OLED_Write_Cmd(0xDA); OLED_Write_Cmd(0x12); + OLED_Write_Cmd(0x81); OLED_Write_Cmd(0xCF); + OLED_Write_Cmd(0xD9); OLED_Write_Cmd(0xF1); + OLED_Write_Cmd(0xDB); OLED_Write_Cmd(0x30); + OLED_Write_Cmd(0xA4); // 全局显示开启 + OLED_Write_Cmd(0xA6); // 正常显示 + OLED_Write_Cmd(0x8D); OLED_Write_Cmd(0x14); // 电荷泵使能 + OLED_Write_Cmd(0xAF); // 开启显示 + + HW_OLED_Clear(); +} + +void HW_OLED_Clear(void) +{ + for (uint8_t page = 0; page < 8; ++page) + { + OLED_Write_Page(page, 0x00); } - HW_OLED_RefreshRAM(); } -// 修正形参命名:L → width,H → height,BMP → bmpData -void HW_OLED_DrawBMP(int16_t x0, int16_t y0, int16_t width, int16_t height, const uint8_t bmpData[]) { - if (x0 >= 0 && x0 < displayWidth && x0 + width <= displayWidth && - y0 >= 0 && y0 < displayHeight && y0 + height <= displayHeight) { - uint8_t *p = (uint8_t *)bmpData; - for(int16_t y = y0; y < y0 + height; y +=8) { - for(int16_t x = x0; x < x0 + width; x++) { - for(int16_t i = 0; i < 8; i++) { - HW_OLED_SetPixel(x, y + i, ((*p) >> i) & 0x01); - } - p++; - } - } +void HW_OLED_Fill(void) +{ + for (uint8_t page = 0; page < 8; ++page) + { + OLED_Write_Page(page, 0xFF); } - HW_OLED_RefreshRAM(); } - -// 修正形参命名:L → width,H → height -void OLED_AreaFill(int16_t x0, int16_t y0, int16_t width, int16_t height, uint8_t fillData) { - if (x0 >= 0 && x0 < displayWidth && x0 + width <= displayWidth && - y0 >= 0 && y0 < displayHeight && y0 + height <= displayHeight) { - for(int16_t y = y0; y < y0 + height; y++) { - for(int16_t x = x0; x < x0 + width; x++) { - for(int16_t i = 0; i < 8; i++) { - HW_OLED_SetPixel(x, y + i, (fillData >> i) & SET_PIXEL); - } - } - } - HW_OLED_RefreshRAM(); - } -} - -// 修正形参命名:L → width,H → height -void OLED_AreaClear(int16_t x0, int16_t y0, int16_t width, int16_t height) { - if (x0 >= 0 && x0 < displayWidth && x0 + width <= displayWidth && - y0 >= 0 && y0 < displayHeight && y0 + height <= displayHeight) { - for(int16_t y = y0; y < y0 + height; y +=8) { - for(int16_t x = x0; x < x0 + width; x++) { - for(int16_t i = 0; i < 8; i++) { - HW_OLED_SetPixel(x, y + i, RESET_PIXEL); - } - } - } - HW_OLED_RefreshRAM(); - } -} - -void HW_OLED_FullyToggle(void) { - for(uint16_t m = 0; m < displayHeight/8; m++) { - for(uint16_t n = 0; n < displayWidth; n++) { - OLED_RAM[m][n] = ~OLED_RAM[m][n]; - } - } - HW_OLED_RefreshRAM(); -} - -// 修正形参命名:L → width,H → height -void HW_OLED_AreaToggle(int16_t x0, int16_t y0, int16_t width, int16_t height) { - if (x0 >= 0 && x0 < displayWidth && x0 + width <= displayWidth && - y0 >= 0 && y0 < displayHeight && y0 + height <= displayHeight) { - for(int16_t y = y0; y < y0 + height; y +=8) { - for(int16_t x = x0; x < x0 + width; x++) { - for(int16_t i = 0; i < 8; i++) { - HW_OLED_SetPixel(x, y + i, !HW_OLED_GetPixel(x, y + i)); - } - } - } - HW_OLED_RefreshRAM(); - } -} - -void HW_OLED_VerticalShift(void) { - for(uint8_t i = 0; i < displayHeight; i++) { - HW_OLED_WriteCmd(0xd3); - HW_OLED_WriteCmd(i); - HAL_Delay(40); - } -} - -void HW_OLED_HorizontalShift(uint8_t direction) { - HW_OLED_WriteCmd(direction); - HW_OLED_WriteCmd(0x00); - HW_OLED_WriteCmd(0x00); - HW_OLED_WriteCmd(0x05); - HW_OLED_WriteCmd(0x07); - HW_OLED_WriteCmd(0x00); - HW_OLED_WriteCmd(0xff); - HW_OLED_WriteCmd(0x2f); -} - -void HW_OLED_VerticalAndHorizontalShift(uint8_t direction) { - HW_OLED_WriteCmd(direction); - HW_OLED_WriteCmd(0x00); - HW_OLED_WriteCmd(0x00); - HW_OLED_WriteCmd(0x05); - HW_OLED_WriteCmd(0x07); - HW_OLED_WriteCmd(0x01); - HW_OLED_WriteCmd(0x2f); -} - -void HW_OLED_DisplayMode(uint8_t mode) { - HW_OLED_WriteCmd(mode); -} - -void HW_OLED_IntensityControl(uint8_t intensity) { - HW_OLED_WriteCmd(0x81); - HW_OLED_WriteCmd(intensity); -} - diff --git a/modules/oled/HW_OLED.h b/modules/oled/HW_OLED.h index 57ac6b3ea71e937f90c0a3c822a3966048b2aa10..a2bb3db2f5806c295f7e472c3706c048eaa8f51e 100644 --- a/modules/oled/HW_OLED.h +++ b/modules/oled/HW_OLED.h @@ -1,220 +1,67 @@ -#ifndef OLED_H__ -#define OLED_H__ +#ifndef HW_OLED_H +#define HW_OLED_H -#include "stm32f1xx_hal.h" // 包含HAL库 +#include "i2c.h" +#include "Base_I2C.h" -/* BMP图片说明 - 图片格式为位映射,索引分别对应图片的宽和高, - BMP_xx[H/8][L]; -*/ -extern const uint8_t BMP_Picture[64/8][64]; +// OLED控制命令宏定义 +#define OLED_CMD_LEFT 0x27 // 左移命令 +#define OLED_CMD_RIGHT 0x26 // 右移命令 +#define OLED_CMD_UP 0x29 // 上移命令 +#define OLED_CMD_DOWN 0x2A // 下移命令 +#define OLED_CMD_ON 0xA7 // 显示开启/点亮命令 +#define OLED_CMD_OFF 0xA6 // 显示关闭/熄灭命令 -/* 像素状态枚举 */ -typedef enum -{ - SET_PIXEL = 0x01, - RESET_PIXEL = 0x00, -} PixelStatus; +#define OLED_I2C_ADDR 0x78 // OLED I2C设备地址 -/** - * @brief 通过I2C写入一个字节数据 - * @param regAddr: 要写入数据的地址,取值范围为0x00 - 0xFF - * @param data: 要写入的字节数据,取值范围为0x00 - 0xFF - * @retval 无 - */ -void HW_OLED_WriteByte(uint8_t regAddr, uint8_t data); +//OLED屏幕参数 +#define OLED_WIDTH 128 // OLED宽度:128 +#define OLED_HEIGHT 64 // OLED高度:64 -/** - * @brief 写命令 - * @param iicCommand: 要写入的IIC命令,取值范围为0x00 - 0xFF - * @retval 无 - */ -void HW_OLED_WriteCmd(uint8_t iicCommand); - -/** - * @brief 写数据 - * @param iicData: 要写入的IIC数据,取值范围为0x00 - 0xFF - * @retval 无 - */ -void HW_OLED_WriteDat(uint8_t iicData); +//屏幕操作函数 /** - * @brief 初始化OLED模块 - * @param 无 - * @retval 无 + * @brief OLED初始化(上电必须调用) */ void HW_OLED_Init(void); /** - * @brief 打开OLED显示 - * @param 无 - * @retval 无 + * @brief OLED清屏(全黑) */ -void HW_OLED_On(void); +void HW_OLED_Clear(void); /** - * @brief 关闭OLED显示 -- 睡眠模式下,OLED功耗小于10uA - * @param 无 - * @retval 无 + * @brief OLED满屏点亮(全白) */ -void HW_OLED_Off(void); +void HW_OLED_Fill(void); /** - * @brief 全量刷新 - * @param 无 - * @retval 无 + * @brief 设置光标位置并连续写入多个字节数据(适用于非重复数据) + * @param page 页地址(0~7,对应 Y 坐标每 8 像素一页) + * @param column 列起始地址(0~127,对应 X 坐标) + * @param data 待写入的数据缓冲区指针 + * @param dataLen 要写入的字节数 */ -void HW_OLED_RefreshRAM(void); +static void HW_OLED_SetCursorAndWriteData(uint8_t page, uint8_t column, + const uint8_t *data, uint8_t dataLen); /** - * @brief 清空数据缓存 - * @param 无 - * @retval 无 + * @brief 将整页(128 列)填充为指定值 + * @param page 页地址(0~7) + * @param fillValue 填充值(0x00 清空,0xFF 全亮) */ -void HW_OLED_ClearRAM(void); +static void HW_OLED_WritePage(uint8_t page, uint8_t fillValue); /** - * @brief 全屏填充 0x00~0xff - * @param fillData: 填充数据(1字节),取值范围为0x00 - 0xFF - * @retval 无 + * @brief 向 OLED 写入命令字节 + * @param cmd 命令字节(如 0xAE 关闭显示) */ -void HW_OLED_FullyFill(uint8_t fillData); +static void HW_OLED_WriteCommand(uint8_t cmd); /** - * @brief 全屏清空 - * @param 无 - * @retval 无 + * @brief 向 OLED 写入数据字节(显示内容) + * @param data 要显示的数据字节(一列 8 像素点) */ -void HW_OLED_FullyClear(void); - -/** - * @brief 设置指定像素点的状态 - * @param x: 起始横坐标,取值范围为0 - 127 - * @param y: 起始纵坐标,取值范围为0 - 63 - * @param setPixel: 设置像素状态,取值为SET_PIXEL(点亮像素)或RESET_PIXEL(熄灭像素) - * @retval 无 - */ -void HW_OLED_SetPixel(int16_t x, int16_t y, uint8_t setPixel); - -/** - * @brief 获取指定像素点的状态 - * @param x: 起始横坐标,取值范围为0 - 127 - * @param y: 起始纵坐标,取值范围为0 - 63 - * @retval PixelStatus: 返回像素的状态,SET_PIXEL(像素点亮)或RESET_PIXEL(像素熄灭) - */ -PixelStatus HW_OLED_GetPixel(int16_t x, int16_t y); - -/** - * @brief 显示codetab.h中的ASCII字符,有6*8和8*16可选 - * @param x: 起始横坐标,取值范围为0 - 127 - * @param y: 起始纵坐标,取值范围为0 - 63 - * @param str[]: 要显示的字符串 - * @param textSize: 字体大小,取值为1(6*8字体)或2(8*16字体) - * @retval 无 - */ -void HW_OLED_ShowStr(int16_t x, int16_t y, uint8_t str[], uint8_t textSize); - -/** - * @brief 显示codetab.h中的汉字,16*16点阵 - * @param x: 起始横坐标,取值范围为0 - 127 - * @param y: 起始纵坐标,取值范围为0 - 7 - * @param str: 对应codetab.h中的汉字 - * @retval 无 - */ -void HW_OLED_ShowCN(int16_t x, int16_t y, uint8_t* str); - -/** - * @brief 显示codetab.h中的汉字,16*16点阵,英文,8*16点阵 - * @param x: 起始横坐标,取值范围为0 - 127 - * @param y: 起始纵坐标,取值范围为0 - 7 - * @param str: 对应codetab.h中的汉字和英文 - * @retval 无 - */ -void HW_OLED_ShowMixedCH(int16_t x, int16_t y, uint8_t* str); - -/** - * @brief 图片显示函数,显示BMP位图,格式使用二维数组存储 - * @param x0: 起始横坐标,取值范围为0 - 127 - * @param y0: 起始纵坐标,取值范围为0 - 63 - * @param width: 图片长度,取值需保证图片不会超出屏幕范围 - * @param height: 图片高度,取值需保证图片不会超出屏幕范围 - * @param bmpData: 位图数据 - * @retval 无 - */ -void HW_OLED_DrawBMP(int16_t x0, int16_t y0, int16_t width, int16_t height, const uint8_t bmpData[]); - -/** - * @brief 区域填充 - * @param x0: 起始横坐标,取值范围为0 - 127 - * @param y0: 起始纵坐标,取值范围为0 - 63 - * @param width: 填充区域长度,取值需保证区域不会超出屏幕范围 - * @param height: 填充区域高度,取值需保证区域不会超出屏幕范围 - * @param fillData: 填充数据,取值范围为0x00 - 0xFF - * @retval 无 - */ -void HW_OLED_AreaFill(int16_t x0, int16_t y0, int16_t width, int16_t height, uint8_t fillData); - -/** - * @brief 区域清空 - * @param x0: 起始横坐标,取值范围为0 - 127 - * @param y0: 起始纵坐标,取值范围为0 - 63 - * @param width: 清空区域长度,取值需保证区域不会超出屏幕范围 - * @param height: 清空区域高度,取值需保证区域不会超出屏幕范围 - * @retval 无 - */ -void HW_OLED_AreaClear(int16_t x0, int16_t y0, int16_t width, int16_t height); - -/** - * @brief 全屏反色显示 - * @param 无 - * @retval 无 - */ -void HW_OLED_FullyToggle(void); - -/** - * @brief 区域反色显示 - * @param x0: 起始横坐标,取值范围为0 - 127 - * @param y0: 起始纵坐标,取值范围为0 - 63 - * @param width: 反色区域长度,取值需保证区域不会超出屏幕范围 - * @param height: 反色区域高度,取值需保证区域不会超出屏幕范围 - * @retval 无 - */ -void HW_OLED_AreaToggle(int16_t x0, int16_t y0, int16_t width, int16_t height); - -/** - * @brief 全屏垂直滚动显示 - * @param 无 - * @retval 无 - */ -void HW_OLED_VerticalShift(void); - -/** - * @brief 全屏水平滚动显示 - * @param direction: 滚动方向,具体取值含义需根据实际实现确定 - * @retval 无 - */ -void HW_OLED_HorizontalShift(uint8_t direction); - -/** - * @brief 全屏同时垂直和水平滚动显示 - * @param direction: 滚动方向,具体取值含义需根据实际实现确定 - * @retval 无 - */ -void HW_OLED_VerticalAndHorizontalShift(uint8_t direction); - -/** - * @brief 屏幕显示模式选择 - * @param mode: 显示模式,具体取值含义需根据实际实现确定 - * @retval 无 - */ -void HW_OLED_DisplayMode(uint8_t mode); - -/** - * @brief 屏幕亮度控制 - * @param intensity: 亮度值,取值范围需根据实际硬件确定 - * @retval 无 - */ -void HW_OLED_IntensityControl(uint8_t intensity); +static void HW_OLED_WriteData(uint8_t data); #endif - diff --git a/modules/oled/HW_OLED_Font.h b/modules/oled/HW_OLED_Font.h deleted file mode 100644 index ee300e1deb82a03fd53d12a568104f22855e5b65..0000000000000000000000000000000000000000 --- a/modules/oled/HW_OLED_Font.h +++ /dev/null @@ -1,262 +0,0 @@ -#ifndef OLED_FONT_H__ -#define OLED_FONT_H__ -#ifdef __cplusplus - extern "C" { -#endif - -#include "stm32f1xx_hal.h" - -const uint8_t F6x8[][6] = -{ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,// sp - 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00,// ! - 0x00, 0x00, 0x07, 0x00, 0x07, 0x00,// " - 0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14,// # - 0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12,// $ - 0x00, 0x62, 0x64, 0x08, 0x13, 0x23,// % - 0x00, 0x36, 0x49, 0x55, 0x22, 0x50,// & - 0x00, 0x00, 0x05, 0x03, 0x00, 0x00,// ' - 0x00, 0x00, 0x1c, 0x22, 0x41, 0x00,// ( - 0x00, 0x00, 0x41, 0x22, 0x1c, 0x00,// ) - 0x00, 0x14, 0x08, 0x3E, 0x08, 0x14,// * - 0x00, 0x08, 0x08, 0x3E, 0x08, 0x08,// + - 0x00, 0x00, 0x00, 0xA0, 0x60, 0x00,// , - 0x00, 0x08, 0x08, 0x08, 0x08, 0x08,// - - 0x00, 0x00, 0x60, 0x60, 0x00, 0x00,// . - 0x00, 0x20, 0x10, 0x08, 0x04, 0x02,// / - 0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E,// 0 - 0x00, 0x00, 0x42, 0x7F, 0x40, 0x00,// 1 - 0x00, 0x42, 0x61, 0x51, 0x49, 0x46,// 2 - 0x00, 0x21, 0x41, 0x45, 0x4B, 0x31,// 3 - 0x00, 0x18, 0x14, 0x12, 0x7F, 0x10,// 4 - 0x00, 0x27, 0x45, 0x45, 0x45, 0x39,// 5 - 0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30,// 6 - 0x00, 0x01, 0x71, 0x09, 0x05, 0x03,// 7 - 0x00, 0x36, 0x49, 0x49, 0x49, 0x36,// 8 - 0x00, 0x06, 0x49, 0x49, 0x29, 0x1E,// 9 - 0x00, 0x00, 0x36, 0x36, 0x00, 0x00,// : - 0x00, 0x00, 0x56, 0x36, 0x00, 0x00,// ; - 0x00, 0x08, 0x14, 0x22, 0x41, 0x00,// < - 0x00, 0x14, 0x14, 0x14, 0x14, 0x14,// = - 0x00, 0x00, 0x41, 0x22, 0x14, 0x08,// > - 0x00, 0x02, 0x01, 0x51, 0x09, 0x06,// ? - 0x00, 0x32, 0x49, 0x59, 0x51, 0x3E,// @ - 0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C,// A - 0x00, 0x7F, 0x49, 0x49, 0x49, 0x36,// B - 0x00, 0x3E, 0x41, 0x41, 0x41, 0x22,// C - 0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C,// D - 0x00, 0x7F, 0x49, 0x49, 0x49, 0x41,// E - 0x00, 0x7F, 0x09, 0x09, 0x09, 0x01,// F - 0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A,// G - 0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F,// H - 0x00, 0x00, 0x41, 0x7F, 0x41, 0x00,// I - 0x00, 0x20, 0x40, 0x41, 0x3F, 0x01,// J - 0x00, 0x7F, 0x08, 0x14, 0x22, 0x41,// K - 0x00, 0x7F, 0x40, 0x40, 0x40, 0x40,// L - 0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F,// M - 0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F,// N - 0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E,// O - 0x00, 0x7F, 0x09, 0x09, 0x09, 0x06,// P - 0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E,// Q - 0x00, 0x7F, 0x09, 0x19, 0x29, 0x46,// R - 0x00, 0x46, 0x49, 0x49, 0x49, 0x31,// S - 0x00, 0x01, 0x01, 0x7F, 0x01, 0x01,// T - 0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F,// U - 0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F,// V - 0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F,// W - 0x00, 0x63, 0x14, 0x08, 0x14, 0x63,// X - 0x00, 0x07, 0x08, 0x70, 0x08, 0x07,// Y - 0x00, 0x61, 0x51, 0x49, 0x45, 0x43,// Z - 0x00, 0x00, 0x7F, 0x41, 0x41, 0x00,// [ - 0x00, 0x55, 0x2A, 0x55, 0x2A, 0x55,// 55 - 0x00, 0x00, 0x41, 0x41, 0x7F, 0x00,// ] - 0x00, 0x04, 0x02, 0x01, 0x02, 0x04,// ^ - 0x00, 0x40, 0x40, 0x40, 0x40, 0x40,// _ - 0x00, 0x00, 0x01, 0x02, 0x04, 0x00,// ' - 0x00, 0x20, 0x54, 0x54, 0x54, 0x78,// a - 0x00, 0x7F, 0x48, 0x44, 0x44, 0x38,// b - 0x00, 0x38, 0x44, 0x44, 0x44, 0x20,// c - 0x00, 0x38, 0x44, 0x44, 0x48, 0x7F,// d - 0x00, 0x38, 0x54, 0x54, 0x54, 0x18,// e - 0x00, 0x08, 0x7E, 0x09, 0x01, 0x02,// f - 0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C,// g - 0x00, 0x7F, 0x08, 0x04, 0x04, 0x78,// h - 0x00, 0x00, 0x44, 0x7D, 0x40, 0x00,// i - 0x00, 0x40, 0x80, 0x84, 0x7D, 0x00,// j - 0x00, 0x7F, 0x10, 0x28, 0x44, 0x00,// k - 0x00, 0x00, 0x41, 0x7F, 0x40, 0x00,// l - 0x00, 0x7C, 0x04, 0x18, 0x04, 0x78,// m - 0x00, 0x7C, 0x08, 0x04, 0x04, 0x78,// n - 0x00, 0x38, 0x44, 0x44, 0x44, 0x38,// o - 0x00, 0xFC, 0x24, 0x24, 0x24, 0x18,// p - 0x00, 0x18, 0x24, 0x24, 0x18, 0xFC,// q - 0x00, 0x7C, 0x08, 0x04, 0x04, 0x08,// r - 0x00, 0x48, 0x54, 0x54, 0x54, 0x20,// s - 0x00, 0x04, 0x3F, 0x44, 0x40, 0x20,// t - 0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C,// u - 0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C,// v - 0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C,// w - 0x00, 0x44, 0x28, 0x10, 0x28, 0x44,// x - 0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C,// y - 0x00, 0x44, 0x64, 0x54, 0x4C, 0x44,// z - 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,// horiz lines -}; -/****************************************8*16的点阵************************************/ -const uint8_t F8X16[][16]= -{ - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// 0 - 0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x30,0x00,0x00,0x00,//! 1 - 0x00,0x10,0x0C,0x06,0x10,0x0C,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//" 2 - 0x40,0xC0,0x78,0x40,0xC0,0x78,0x40,0x00,0x04,0x3F,0x04,0x04,0x3F,0x04,0x04,0x00,//# 3 - 0x00,0x70,0x88,0xFC,0x08,0x30,0x00,0x00,0x00,0x18,0x20,0xFF,0x21,0x1E,0x00,0x00,//$ 4 - 0xF0,0x08,0xF0,0x00,0xE0,0x18,0x00,0x00,0x00,0x21,0x1C,0x03,0x1E,0x21,0x1E,0x00,//% 5 - 0x00,0xF0,0x08,0x88,0x70,0x00,0x00,0x00,0x1E,0x21,0x23,0x24,0x19,0x27,0x21,0x10,//& 6 - 0x10,0x16,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//' 7 - 0x00,0x00,0x00,0xE0,0x18,0x04,0x02,0x00,0x00,0x00,0x00,0x07,0x18,0x20,0x40,0x00,//( 8 - 0x00,0x02,0x04,0x18,0xE0,0x00,0x00,0x00,0x00,0x40,0x20,0x18,0x07,0x00,0x00,0x00,//) 9 - 0x40,0x40,0x80,0xF0,0x80,0x40,0x40,0x00,0x02,0x02,0x01,0x0F,0x01,0x02,0x02,0x00,//* 10 - 0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x1F,0x01,0x01,0x01,0x00,//+ 11 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xB0,0x70,0x00,0x00,0x00,0x00,0x00,//, 12 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,//- 13 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00,//. 14 - 0x00,0x00,0x00,0x00,0x80,0x60,0x18,0x04,0x00,0x60,0x18,0x06,0x01,0x00,0x00,0x00,/// 15 - 0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,//0 16 - 0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//1 17 - 0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00,//2 18 - 0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00,//3 19 - 0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00,//4 20 - 0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00,//5 21 - 0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00,//6 22 - 0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,//7 23 - 0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00,//8 24 - 0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00,//9 25 - 0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,//: 26 - 0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x60,0x00,0x00,0x00,0x00,//; 27 - 0x00,0x00,0x80,0x40,0x20,0x10,0x08,0x00,0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x00,//< 28 - 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00,//= 29 - 0x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x20,0x10,0x08,0x04,0x02,0x01,0x00,//> 30 - 0x00,0x70,0x48,0x08,0x08,0x08,0xF0,0x00,0x00,0x00,0x00,0x30,0x36,0x01,0x00,0x00,//? 31 - 0xC0,0x30,0xC8,0x28,0xE8,0x10,0xE0,0x00,0x07,0x18,0x27,0x24,0x23,0x14,0x0B,0x00,//@ 32 - 0x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00,0x20,0x3C,0x23,0x02,0x02,0x27,0x38,0x20,//A 33 - 0x08,0xF8,0x88,0x88,0x88,0x70,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x11,0x0E,0x00,//B 34 - 0xC0,0x30,0x08,0x08,0x08,0x08,0x38,0x00,0x07,0x18,0x20,0x20,0x20,0x10,0x08,0x00,//C 35 - 0x08,0xF8,0x08,0x08,0x08,0x10,0xE0,0x00,0x20,0x3F,0x20,0x20,0x20,0x10,0x0F,0x00,//D 36 - 0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x20,0x23,0x20,0x18,0x00,//E 37 - 0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x00,0x03,0x00,0x00,0x00,//F 38 - 0xC0,0x30,0x08,0x08,0x08,0x38,0x00,0x00,0x07,0x18,0x20,0x20,0x22,0x1E,0x02,0x00,//G 39 - 0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x20,0x3F,0x21,0x01,0x01,0x21,0x3F,0x20,//H 40 - 0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//I 41 - 0x00,0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,0x00,//J 42 - 0x08,0xF8,0x88,0xC0,0x28,0x18,0x08,0x00,0x20,0x3F,0x20,0x01,0x26,0x38,0x20,0x00,//K 43 - 0x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x20,0x30,0x00,//L 44 - 0x08,0xF8,0xF8,0x00,0xF8,0xF8,0x08,0x00,0x20,0x3F,0x00,0x3F,0x00,0x3F,0x20,0x00,//M 45 - 0x08,0xF8,0x30,0xC0,0x00,0x08,0xF8,0x08,0x20,0x3F,0x20,0x00,0x07,0x18,0x3F,0x00,//N 46 - 0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x10,0x20,0x20,0x20,0x10,0x0F,0x00,//O 47 - 0x08,0xF8,0x08,0x08,0x08,0x08,0xF0,0x00,0x20,0x3F,0x21,0x01,0x01,0x01,0x00,0x00,//P 48 - 0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x18,0x24,0x24,0x38,0x50,0x4F,0x00,//Q 49 - 0x08,0xF8,0x88,0x88,0x88,0x88,0x70,0x00,0x20,0x3F,0x20,0x00,0x03,0x0C,0x30,0x20,//R 50 - 0x00,0x70,0x88,0x08,0x08,0x08,0x38,0x00,0x00,0x38,0x20,0x21,0x21,0x22,0x1C,0x00,//S 51 - 0x18,0x08,0x08,0xF8,0x08,0x08,0x18,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,//T 52 - 0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,//U 53 - 0x08,0x78,0x88,0x00,0x00,0xC8,0x38,0x08,0x00,0x00,0x07,0x38,0x0E,0x01,0x00,0x00,//V 54 - 0xF8,0x08,0x00,0xF8,0x00,0x08,0xF8,0x00,0x03,0x3C,0x07,0x00,0x07,0x3C,0x03,0x00,//W 55 - 0x08,0x18,0x68,0x80,0x80,0x68,0x18,0x08,0x20,0x30,0x2C,0x03,0x03,0x2C,0x30,0x20,//X 56 - 0x08,0x38,0xC8,0x00,0xC8,0x38,0x08,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,//Y 57 - 0x10,0x08,0x08,0x08,0xC8,0x38,0x08,0x00,0x20,0x38,0x26,0x21,0x20,0x20,0x18,0x00,//Z 58 - 0x00,0x00,0x00,0xFE,0x02,0x02,0x02,0x00,0x00,0x00,0x00,0x7F,0x40,0x40,0x40,0x00,//[ 59 - 0x00,0x0C,0x30,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x06,0x38,0xC0,0x00,//\ 60 - 0x00,0x02,0x02,0x02,0xFE,0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x7F,0x00,0x00,0x00,//] 61 - 0x00,0x00,0x04,0x02,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//^ 62 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,//_ 63 - 0x00,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//` 64 - 0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x19,0x24,0x22,0x22,0x22,0x3F,0x20,//a 65 - 0x08,0xF8,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x3F,0x11,0x20,0x20,0x11,0x0E,0x00,//b 66 - 0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00,0x00,0x0E,0x11,0x20,0x20,0x20,0x11,0x00,//c 67 - 0x00,0x00,0x00,0x80,0x80,0x88,0xF8,0x00,0x00,0x0E,0x11,0x20,0x20,0x10,0x3F,0x20,//d 68 - 0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x22,0x22,0x22,0x22,0x13,0x00,//e 69 - 0x00,0x80,0x80,0xF0,0x88,0x88,0x88,0x18,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//f 70 - 0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x6B,0x94,0x94,0x94,0x93,0x60,0x00,//g 71 - 0x08,0xF8,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,//h 72 - 0x00,0x80,0x98,0x98,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//i 73 - 0x00,0x00,0x00,0x80,0x98,0x98,0x00,0x00,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,//j 74 - 0x08,0xF8,0x00,0x00,0x80,0x80,0x80,0x00,0x20,0x3F,0x24,0x02,0x2D,0x30,0x20,0x00,//k 75 - 0x00,0x08,0x08,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//l 76 - 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x20,0x3F,0x20,0x00,0x3F,0x20,0x00,0x3F,//m 77 - 0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,//n 78 - 0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,//o 79 - 0x80,0x80,0x00,0x80,0x80,0x00,0x00,0x00,0x80,0xFF,0xA1,0x20,0x20,0x11,0x0E,0x00,//p 80 - 0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x0E,0x11,0x20,0x20,0xA0,0xFF,0x80,//q 81 - 0x80,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x20,0x20,0x3F,0x21,0x20,0x00,0x01,0x00,//r 82 - 0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x33,0x24,0x24,0x24,0x24,0x19,0x00,//s 83 - 0x00,0x80,0x80,0xE0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x1F,0x20,0x20,0x00,0x00,//t 84 - 0x80,0x80,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x1F,0x20,0x20,0x20,0x10,0x3F,0x20,//u 85 - 0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x00,0x01,0x0E,0x30,0x08,0x06,0x01,0x00,//v 86 - 0x80,0x80,0x00,0x80,0x00,0x80,0x80,0x80,0x0F,0x30,0x0C,0x03,0x0C,0x30,0x0F,0x00,//w 87 - 0x00,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x31,0x2E,0x0E,0x31,0x20,0x00,//x 88 - 0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x80,0x81,0x8E,0x70,0x18,0x06,0x01,0x00,//y 89 - 0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x21,0x30,0x2C,0x22,0x21,0x30,0x00,//z 90 - 0x00,0x00,0x00,0x00,0x80,0x7C,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x3F,0x40,0x40,//{ 91 - 0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,//| 92 - 0x00,0x02,0x02,0x7C,0x80,0x00,0x00,0x00,0x00,0x40,0x40,0x3F,0x00,0x00,0x00,0x00,//} 93 - 0x00,0x06,0x01,0x01,0x02,0x02,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//~ 94 -}; - -typedef struct { - char index[2]; - uint8_t encoder[32]; -}GB2312_CN; - -const GB2312_CN F16x16_CN[] = { - {"温", - 0x10,0x60,0x02,0x8C,0x00,0x00,0xFE,0x92,0x92,0x92,0x92,0x92,0xFE,0x00,0x00,0x00,0x04,0x04,0x7E,0x01,0x40,0x7E,0x42,0x42,0x7E,0x42,0x7E,0x42,0x42,0x7E,0x40,0x00,/*"温"*/ - }, - {"度", - 0x00,0x00,0xFC,0x24,0x24,0x24,0xFC,0x25,0x26,0x24,0xFC,0x24,0x24,0x24,0x04,0x00,0x40,0x30,0x8F,0x80,0x84,0x4C,0x55,0x25,0x25,0x25,0x55,0x4C,0x80,0x80,0x80,0x00,/*"度"*/ - } -}; - -const uint8_t BMP_Picture[64/8][64] = { -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80, -0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0x30,0x1E, -0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x3C,0x40,0x60,0x20,0x20,0x20,0x20, -0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x60,0xC0,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x30,0x10,0x10,0x08,0x04,0x04,0x02,0xFD,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x10,0x10,0x0C,0x06,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE, -0x00,0x30,0x10,0x10,0x10,0x10,0x10,0x08,0x08,0x04,0x07,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFB,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0x30,0x00,0x00,0x00,0x00,0x03, -0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x50,0x80,0x00,0x00,0x80, -0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x3F,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x70,0xF0,0x0F, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -}; - - - -#ifdef __cplusplus -} -#endif -#endif - - - - diff --git a/modules/oled/OLED_FONT_8X16_ENGLISH.h b/modules/oled/OLED_FONT_8X16_ENGLISH.h new file mode 100644 index 0000000000000000000000000000000000000000..9039df5c0d064c304c1089dc3652d88ddb94294a --- /dev/null +++ b/modules/oled/OLED_FONT_8X16_ENGLISH.h @@ -0,0 +1,199 @@ +#ifndef OLED_FONT_8X16_ENGLISH_H +#define OLED_FONT_8X16_ENGLISH_H + +#include + +static const uint8_t OLED_F8x16[][16]= +{ + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},// 0 + + {0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x30,0x00,0x00,0x00},//! 1 + + {0x00,0x10,0x0C,0x06,0x10,0x0C,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},//" 2 + + {0x40,0xC0,0x78,0x40,0xC0,0x78,0x40,0x00,0x04,0x3F,0x04,0x04,0x3F,0x04,0x04,0x00},//# 3 + + {0x00,0x70,0x88,0xFC,0x08,0x30,0x00,0x00,0x00,0x18,0x20,0xFF,0x21,0x1E,0x00,0x00},//$ 4 + + {0xF0,0x08,0xF0,0x00,0xE0,0x18,0x00,0x00,0x00,0x21,0x1C,0x03,0x1E,0x21,0x1E,0x00},//% 5 + + {0x00,0xF0,0x08,0x88,0x70,0x00,0x00,0x00,0x1E,0x21,0x23,0x24,0x19,0x27,0x21,0x10},//& 6 + + {0x10,0x16,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},//' 7 + + {0x00,0x00,0x00,0xE0,0x18,0x04,0x02,0x00,0x00,0x00,0x00,0x07,0x18,0x20,0x40,0x00},//( 8 + + {0x00,0x02,0x04,0x18,0xE0,0x00,0x00,0x00,0x00,0x40,0x20,0x18,0x07,0x00,0x00,0x00},//) 9 + + {0x40,0x40,0x80,0xF0,0x80,0x40,0x40,0x00,0x02,0x02,0x01,0x0F,0x01,0x02,0x02,0x00},//* 10 + + {0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x1F,0x01,0x01,0x01,0x00},//+ 11 + + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xB0,0x70,0x00,0x00,0x00,0x00,0x00},//, 12 + + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01},//- 13 + + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00},//. 14 + + {0x00,0x00,0x00,0x00,0x80,0x60,0x18,0x04,0x00,0x60,0x18,0x06,0x01,0x00,0x00,0x00},/// 15 + + {0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00},//0 16 + + {0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00},//1 17 + + {0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00},//2 18 + + {0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00},//3 19 + + {0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00},//4 20 + + {0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00},//5 21 + + {0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00},//6 22 + + {0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00},//7 23 + + {0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00},//8 24 + + {0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00},//9 25 + + {0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00},//: 26 + + {0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x60,0x00,0x00,0x00,0x00},//; 27 + + {0x00,0x00,0x80,0x40,0x20,0x10,0x08,0x00,0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x00},//< 28 + + {0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00},//= 29 + + {0x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x20,0x10,0x08,0x04,0x02,0x01,0x00},//> 30 + + {0x00,0x70,0x48,0x08,0x08,0x08,0xF0,0x00,0x00,0x00,0x00,0x30,0x36,0x01,0x00,0x00},//? 31 + + {0xC0,0x30,0xC8,0x28,0xE8,0x10,0xE0,0x00,0x07,0x18,0x27,0x24,0x23,0x14,0x0B,0x00},//@ 32 + + {0x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00,0x20,0x3C,0x23,0x02,0x02,0x27,0x38,0x20},//A 33 + + {0x08,0xF8,0x88,0x88,0x88,0x70,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x11,0x0E,0x00},//B 34 + + {0xC0,0x30,0x08,0x08,0x08,0x08,0x38,0x00,0x07,0x18,0x20,0x20,0x20,0x10,0x08,0x00},//C 35 + + {0x08,0xF8,0x08,0x08,0x08,0x10,0xE0,0x00,0x20,0x3F,0x20,0x20,0x20,0x10,0x0F,0x00},//D 36 + + {0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x20,0x23,0x20,0x18,0x00},//E 37 + + {0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x00,0x03,0x00,0x00,0x00},//F 38 + + {0xC0,0x30,0x08,0x08,0x08,0x38,0x00,0x00,0x07,0x18,0x20,0x20,0x22,0x1E,0x02,0x00},//G 39 + + {0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x20,0x3F,0x21,0x01,0x01,0x21,0x3F,0x20},//H 40 + + {0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00},//I 41 + + {0x00,0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,0x00},//J 42 + + {0x08,0xF8,0x88,0xC0,0x28,0x18,0x08,0x00,0x20,0x3F,0x20,0x01,0x26,0x38,0x20,0x00},//K 43 + + {0x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x20,0x30,0x00},//L 44 + + {0x08,0xF8,0xF8,0x00,0xF8,0xF8,0x08,0x00,0x20,0x3F,0x00,0x3F,0x00,0x3F,0x20,0x00},//M 45 + + {0x08,0xF8,0x30,0xC0,0x00,0x08,0xF8,0x08,0x20,0x3F,0x20,0x00,0x07,0x18,0x3F,0x00},//N 46 + + {0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x10,0x20,0x20,0x20,0x10,0x0F,0x00},//O 47 + + {0x08,0xF8,0x08,0x08,0x08,0x08,0xF0,0x00,0x20,0x3F,0x21,0x01,0x01,0x01,0x00,0x00},//P 48 + + {0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x18,0x24,0x24,0x38,0x50,0x4F,0x00},//Q 49 + + {0x08,0xF8,0x88,0x88,0x88,0x88,0x70,0x00,0x20,0x3F,0x20,0x00,0x03,0x0C,0x30,0x20},//R 50 + + {0x00,0x70,0x88,0x08,0x08,0x08,0x38,0x00,0x00,0x38,0x20,0x21,0x21,0x22,0x1C,0x00},//S 51 + + {0x18,0x08,0x08,0xF8,0x08,0x08,0x18,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00},//T 52 + + {0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00},//U 53 + + {0x08,0x78,0x88,0x00,0x00,0xC8,0x38,0x08,0x00,0x00,0x07,0x38,0x0E,0x01,0x00,0x00},//V 54 + + {0xF8,0x08,0x00,0xF8,0x00,0x08,0xF8,0x00,0x03,0x3C,0x07,0x00,0x07,0x3C,0x03,0x00},//W 55 + + {0x08,0x18,0x68,0x80,0x80,0x68,0x18,0x08,0x20,0x30,0x2C,0x03,0x03,0x2C,0x30,0x20},//X 56 + + {0x08,0x38,0xC8,0x00,0xC8,0x38,0x08,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00},//Y 57 + + {0x10,0x08,0x08,0x08,0xC8,0x38,0x08,0x00,0x20,0x38,0x26,0x21,0x20,0x20,0x18,0x00},//Z 58 + + {0x00,0x00,0x00,0xFE,0x02,0x02,0x02,0x00,0x00,0x00,0x00,0x7F,0x40,0x40,0x40,0x00},//[ 59 + + {0x00,0x0C,0x30,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x06,0x38,0xC0,0x00},//\ 60 + + {0x00,0x02,0x02,0x02,0xFE,0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x7F,0x00,0x00,0x00},//] 61 + + {0x00,0x00,0x04,0x02,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},//^ 62 + + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80},//_ 63 + + {0x00,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},//` 64 + + {0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x19,0x24,0x22,0x22,0x22,0x3F,0x20},//a 65 + + {0x08,0xF8,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x3F,0x11,0x20,0x20,0x11,0x0E,0x00},//b 66 + + {0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00,0x00,0x0E,0x11,0x20,0x20,0x20,0x11,0x00},//c 67 + + {0x00,0x00,0x00,0x80,0x80,0x88,0xF8,0x00,0x00,0x0E,0x11,0x20,0x20,0x10,0x3F,0x20},//d 68 + + {0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x22,0x22,0x22,0x22,0x13,0x00},//e 69 + + {0x00,0x80,0x80,0xF0,0x88,0x88,0x88,0x18,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00},//f 70 + + {0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x6B,0x94,0x94,0x94,0x93,0x60,0x00},//g 71 + + {0x08,0xF8,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20},//h 72 + + {0x00,0x80,0x98,0x98,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00},//i 73 + + {0x00,0x00,0x00,0x80,0x98,0x98,0x00,0x00,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00},//j 74 + + {0x08,0xF8,0x00,0x00,0x80,0x80,0x80,0x00,0x20,0x3F,0x24,0x02,0x2D,0x30,0x20,0x00},//k 75 + + {0x00,0x08,0x08,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00},//l 76 + + {0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x20,0x3F,0x20,0x00,0x3F,0x20,0x00,0x3F},//m 77 + + {0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20},//n 78 + + {0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00},//o 79 + + {0x80,0x80,0x00,0x80,0x80,0x00,0x00,0x00,0x80,0xFF,0xA1,0x20,0x20,0x11,0x0E,0x00},//p 80 + + {0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x0E,0x11,0x20,0x20,0xA0,0xFF,0x80},//q 81 + + {0x80,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x20,0x20,0x3F,0x21,0x20,0x00,0x01,0x00},//r 82 + + {0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x33,0x24,0x24,0x24,0x24,0x19,0x00},//s 83 + + {0x00,0x80,0x80,0xE0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x1F,0x20,0x20,0x00,0x00},//t 84 + + {0x80,0x80,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x1F,0x20,0x20,0x20,0x10,0x3F,0x20},//u 85 + + {0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x00,0x01,0x0E,0x30,0x08,0x06,0x01,0x00},//v 86 + + {0x80,0x80,0x00,0x80,0x00,0x80,0x80,0x80,0x0F,0x30,0x0C,0x03,0x0C,0x30,0x0F,0x00},//w 87 + + {0x00,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x31,0x2E,0x0E,0x31,0x20,0x00},//x 88 + + {0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x80,0x81,0x8E,0x70,0x18,0x06,0x01,0x00},//y 89 + + {0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x21,0x30,0x2C,0x22,0x21,0x30,0x00},//z 90 + + {0x00,0x00,0x00,0x00,0x80,0x7C,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x3F,0x40,0x40},//{ 91 + + {0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00},//| 92 + + {0x00,0x02,0x02,0x7C,0x80,0x00,0x00,0x00,0x00,0x40,0x40,0x3F,0x00,0x00,0x00,0x00},//} 93 + + {0x00,0x06,0x01,0x01,0x02,0x02,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}//~ 94 +}; + +#endif diff --git a/modules/oled/OLED_FONT_MANAGE.h b/modules/oled/OLED_FONT_MANAGE.h new file mode 100644 index 0000000000000000000000000000000000000000..aa8a781fbe1a53e0b4ed783b5577b2828013b879 --- /dev/null +++ b/modules/oled/OLED_FONT_MANAGE.h @@ -0,0 +1,23 @@ +#ifndef OLED_FONT_MANAGE_H +#define OLED_FONT_MANAGE_H + +#include +#include "HW_OLED.h" + +// 宏定义:选择当前使用的OLED字库(仅开启一个即可) +#define OLED_FONT_8X16_ENGLISH // 8x16英文字库(默认开启) +//#define OLED_FONT_16X16_CHINESE // 16x16中文字库 +//#define OLED_FONT_8X16_NUMBER // 8x16数字字库 + +#ifdef OLED_FONT_8X16_ENGLISH + #include "OLED_FONT_8X16_ENGLISH.h" +#elif defined(OLED_FONT_16X16_CHINESE) + #include "OLED_FONT_16X16_CHINESE.h" +#elif defined(OLED_FONT_8X16_NUMBER) + #include "OLED_FONT_8X16_NUMBER.h" +#else + + #include "OLED_FONT_8X16_ENGLISH.h" // 无任何字库定义时,默认加载标准英文字库 +#endif + +#endif