Contains Ayoub's Ranging and Custom interfaces for the VL53L3CX

Committer:
charlesmn
Date:
Wed Jul 21 14:47:53 2021 +0000
Revision:
1:dae4cb24beec
Parent:
0:c1910e04fc6c
strip out commented out code

Who changed what in which revision?

UserRevisionLine numberNew contents of line
charlesmn 0:c1910e04fc6c 1 /**
charlesmn 0:c1910e04fc6c 2 ******************************************************************************
charlesmn 0:c1910e04fc6c 3 * @file vl53l3cx.c
charlesmn 0:c1910e04fc6c 4 * @author IMG SW Application Team
charlesmn 0:c1910e04fc6c 5 * @brief This file provides the VL53L3CX ranging sensor component driver
charlesmn 0:c1910e04fc6c 6 ******************************************************************************
charlesmn 0:c1910e04fc6c 7 * @attention
charlesmn 0:c1910e04fc6c 8 *
charlesmn 0:c1910e04fc6c 9 * <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
charlesmn 0:c1910e04fc6c 10 * All rights reserved.</center></h2>
charlesmn 0:c1910e04fc6c 11 *
charlesmn 0:c1910e04fc6c 12 * This software component is licensed by ST under BSD 3-Clause license,
charlesmn 0:c1910e04fc6c 13 * the "License"; You may not use this file except in compliance with the
charlesmn 0:c1910e04fc6c 14 * License. You may obtain a copy of the License at:
charlesmn 0:c1910e04fc6c 15 * opensource.org/licenses/BSD-3-Clause
charlesmn 0:c1910e04fc6c 16 *
charlesmn 0:c1910e04fc6c 17 ******************************************************************************
charlesmn 0:c1910e04fc6c 18 */
charlesmn 0:c1910e04fc6c 19
charlesmn 0:c1910e04fc6c 20 /* Includes ------------------------------------------------------------------*/
charlesmn 0:c1910e04fc6c 21 #include "vl53l3cx.h"
charlesmn 0:c1910e04fc6c 22 #include "vl53lx_platform.h"
charlesmn 0:c1910e04fc6c 23 #include "vl53lx_api.h"
charlesmn 0:c1910e04fc6c 24 #include "spi_interface.h"
charlesmn 0:c1910e04fc6c 25
charlesmn 0:c1910e04fc6c 26 /** @addtogroup BSP
charlesmn 0:c1910e04fc6c 27 * @{
charlesmn 0:c1910e04fc6c 28 */
charlesmn 0:c1910e04fc6c 29
charlesmn 0:c1910e04fc6c 30 /** @addtogroup Components
charlesmn 0:c1910e04fc6c 31 * @{
charlesmn 0:c1910e04fc6c 32 */
charlesmn 0:c1910e04fc6c 33
charlesmn 0:c1910e04fc6c 34 /** @addtogroup VL53L3CX
charlesmn 0:c1910e04fc6c 35 * @brief This file provides a set of functions needed to drive the
charlesmn 0:c1910e04fc6c 36 * VL53L3CX ranging sensor.
charlesmn 0:c1910e04fc6c 37 * @{
charlesmn 0:c1910e04fc6c 38 */
charlesmn 0:c1910e04fc6c 39
charlesmn 0:c1910e04fc6c 40 /** @defgroup VL53L3CX_Private_TypesDefinitions Private Types Definitions
charlesmn 0:c1910e04fc6c 41 * @{
charlesmn 0:c1910e04fc6c 42 */
charlesmn 0:c1910e04fc6c 43
charlesmn 0:c1910e04fc6c 44 #define V53L3CX_POLL_TIMEOUT (0xFFFFU)
charlesmn 0:c1910e04fc6c 45
charlesmn 0:c1910e04fc6c 46 /**
charlesmn 0:c1910e04fc6c 47 * @}
charlesmn 0:c1910e04fc6c 48 */
charlesmn 0:c1910e04fc6c 49 /** @defgroup VL53L3CX_Private_Variables Private Variables
charlesmn 0:c1910e04fc6c 50 * @{
charlesmn 0:c1910e04fc6c 51 */
charlesmn 0:c1910e04fc6c 52
charlesmn 0:c1910e04fc6c 53 VL53L3CX_RANGING_SENSOR_Drv_t VL53L3CX_RANGING_SENSOR_Driver =
charlesmn 0:c1910e04fc6c 54 {
charlesmn 0:c1910e04fc6c 55 VL53L3CX_Init,
charlesmn 0:c1910e04fc6c 56 VL53L3CX_DeInit,
charlesmn 0:c1910e04fc6c 57 VL53L3CX_ReadID,
charlesmn 0:c1910e04fc6c 58 VL53L3CX_GetCapabilities,
charlesmn 0:c1910e04fc6c 59 VL53L3CX_ConfigProfile,
charlesmn 0:c1910e04fc6c 60 VL53L3CX_ConfigROI,
charlesmn 0:c1910e04fc6c 61 VL53L3CX_ConfigIT,
charlesmn 0:c1910e04fc6c 62 VL53L3CX_GetDistance,
charlesmn 0:c1910e04fc6c 63 VL53L3CX_Start,
charlesmn 0:c1910e04fc6c 64 VL53L3CX_Stop,
charlesmn 0:c1910e04fc6c 65 VL53L3CX_SetAddress,
charlesmn 0:c1910e04fc6c 66 VL53L3CX_GetAddress,
charlesmn 0:c1910e04fc6c 67 VL53L3CX_SetPowerMode,
charlesmn 0:c1910e04fc6c 68 VL53L3CX_GetPowerMode
charlesmn 0:c1910e04fc6c 69 };
charlesmn 0:c1910e04fc6c 70
charlesmn 0:c1910e04fc6c 71 /**
charlesmn 0:c1910e04fc6c 72 * @}
charlesmn 0:c1910e04fc6c 73 */
charlesmn 0:c1910e04fc6c 74
charlesmn 0:c1910e04fc6c 75
charlesmn 0:c1910e04fc6c 76 /** @defgroup VL53L3CX_Private_Functions_Prototypes Private Functions Prototypes
charlesmn 0:c1910e04fc6c 77 * @{
charlesmn 0:c1910e04fc6c 78 */
charlesmn 0:c1910e04fc6c 79 static int32_t vl53l3cx_poll_for_measurement(VL53L3CX_Object_t *pObj, uint32_t Timeout);
charlesmn 0:c1910e04fc6c 80 static int32_t vl53l3cx_get_result(VL53L3CX_Object_t *pObj, VL53L3CX_Result_t *pResult);
charlesmn 0:c1910e04fc6c 81
charlesmn 0:c1910e04fc6c 82 /**
charlesmn 0:c1910e04fc6c 83 * @}
charlesmn 0:c1910e04fc6c 84 */
charlesmn 0:c1910e04fc6c 85
charlesmn 0:c1910e04fc6c 86 /**
charlesmn 0:c1910e04fc6c 87 * @brief Initializes the vl53l3cx context object.
charlesmn 0:c1910e04fc6c 88 * @param pObj vl53l3cx context object.
charlesmn 0:c1910e04fc6c 89 * @param pIO BSP IO struct.
charlesmn 0:c1910e04fc6c 90 * @retval VL53L3CX status
charlesmn 0:c1910e04fc6c 91 */
charlesmn 0:c1910e04fc6c 92 int32_t VL53L3CX_RegisterBusIO(VL53L3CX_Object_t *pObj, VL53L3CX_IO_t *pIO)
charlesmn 0:c1910e04fc6c 93 {
charlesmn 0:c1910e04fc6c 94 int32_t ret = 0;
charlesmn 0:c1910e04fc6c 95
charlesmn 0:c1910e04fc6c 96 if (pObj == NULL)
charlesmn 0:c1910e04fc6c 97 {
charlesmn 0:c1910e04fc6c 98 ret = VL53L3CX_INVALID_PARAM;
charlesmn 0:c1910e04fc6c 99 }
charlesmn 0:c1910e04fc6c 100 else
charlesmn 0:c1910e04fc6c 101 {
charlesmn 0:c1910e04fc6c 102 pObj->IO.Address = pIO->Address;
charlesmn 0:c1910e04fc6c 103 pObj->IO.GetTick = pIO->GetTick;
charlesmn 0:c1910e04fc6c 104 }
charlesmn 0:c1910e04fc6c 105
charlesmn 0:c1910e04fc6c 106
charlesmn 0:c1910e04fc6c 107
charlesmn 0:c1910e04fc6c 108
charlesmn 0:c1910e04fc6c 109 return ret;
charlesmn 0:c1910e04fc6c 110 }
charlesmn 0:c1910e04fc6c 111
charlesmn 0:c1910e04fc6c 112 /**
charlesmn 0:c1910e04fc6c 113 * @brief Initializes the vl53l3cx.
charlesmn 0:c1910e04fc6c 114 * @param pObj vl53l3cx context object.
charlesmn 0:c1910e04fc6c 115 * @retval VL53L3CX status
charlesmn 0:c1910e04fc6c 116 */
charlesmn 0:c1910e04fc6c 117 int32_t VL53L3CX_Init(VL53L3CX_Object_t *pObj)
charlesmn 0:c1910e04fc6c 118 {
charlesmn 0:c1910e04fc6c 119 int32_t ret;
charlesmn 0:c1910e04fc6c 120
charlesmn 0:c1910e04fc6c 121 if (pObj->IsInitialized != 0U)
charlesmn 0:c1910e04fc6c 122 {
charlesmn 0:c1910e04fc6c 123 ret = VL53L3CX_ERROR;
charlesmn 0:c1910e04fc6c 124 }
charlesmn 0:c1910e04fc6c 125 else if (VL53LX_WaitDeviceBooted(pObj) != VL53LX_ERROR_NONE)
charlesmn 0:c1910e04fc6c 126 {
charlesmn 0:c1910e04fc6c 127 ret = VL53L3CX_ERROR;
charlesmn 0:c1910e04fc6c 128 }
charlesmn 0:c1910e04fc6c 129 else if (VL53LX_DataInit(pObj) != VL53LX_ERROR_NONE)
charlesmn 0:c1910e04fc6c 130 {
charlesmn 0:c1910e04fc6c 131 ret = VL53L3CX_ERROR;
charlesmn 0:c1910e04fc6c 132 }
charlesmn 0:c1910e04fc6c 133 else if (VL53LX_PerformRefSpadManagement(pObj) != VL53LX_ERROR_NONE)
charlesmn 0:c1910e04fc6c 134 {
charlesmn 0:c1910e04fc6c 135 ret = VL53L3CX_ERROR;
charlesmn 0:c1910e04fc6c 136 }
charlesmn 0:c1910e04fc6c 137 else
charlesmn 0:c1910e04fc6c 138 {
charlesmn 0:c1910e04fc6c 139 pObj->IsRanging = 0;
charlesmn 0:c1910e04fc6c 140 pObj->IsBlocking = 0;
charlesmn 0:c1910e04fc6c 141 pObj->IsContinuous = 0;
charlesmn 0:c1910e04fc6c 142 pObj->IsAmbientEnabled = 0;
charlesmn 0:c1910e04fc6c 143 pObj->IsSignalEnabled = 0;
charlesmn 0:c1910e04fc6c 144 pObj->IsInitialized = 1;
charlesmn 0:c1910e04fc6c 145 ret = VL53L3CX_OK;
charlesmn 0:c1910e04fc6c 146 }
charlesmn 0:c1910e04fc6c 147
charlesmn 0:c1910e04fc6c 148 return ret;
charlesmn 0:c1910e04fc6c 149 }
charlesmn 0:c1910e04fc6c 150
charlesmn 0:c1910e04fc6c 151 /**
charlesmn 0:c1910e04fc6c 152 * @brief Deinitializes the vl53l3cx.
charlesmn 0:c1910e04fc6c 153 * @param pObj vl53l3cx context object.
charlesmn 0:c1910e04fc6c 154 * @retval VL53L3CX status
charlesmn 0:c1910e04fc6c 155 */
charlesmn 0:c1910e04fc6c 156 int32_t VL53L3CX_DeInit(VL53L3CX_Object_t *pObj)
charlesmn 0:c1910e04fc6c 157 {
charlesmn 0:c1910e04fc6c 158 int32_t ret = VL53L3CX_ERROR;
charlesmn 0:c1910e04fc6c 159
charlesmn 0:c1910e04fc6c 160 if (pObj->IsInitialized == 1U)
charlesmn 0:c1910e04fc6c 161 {
charlesmn 0:c1910e04fc6c 162 /* De-initialize the vl53l3cx interface */
charlesmn 0:c1910e04fc6c 163 if (pObj->IO.DeInit() != 0)
charlesmn 0:c1910e04fc6c 164 {
charlesmn 0:c1910e04fc6c 165 ret = VL53L3CX_ERROR;
charlesmn 0:c1910e04fc6c 166 }
charlesmn 0:c1910e04fc6c 167 else
charlesmn 0:c1910e04fc6c 168 {
charlesmn 0:c1910e04fc6c 169 ret = VL53L3CX_OK;
charlesmn 0:c1910e04fc6c 170 pObj->IsInitialized = 0;
charlesmn 0:c1910e04fc6c 171 }
charlesmn 0:c1910e04fc6c 172 }
charlesmn 0:c1910e04fc6c 173
charlesmn 0:c1910e04fc6c 174 return ret;
charlesmn 0:c1910e04fc6c 175 }
charlesmn 0:c1910e04fc6c 176
charlesmn 0:c1910e04fc6c 177 /**
charlesmn 0:c1910e04fc6c 178 * @brief Read the vl53l3cx device ID.
charlesmn 0:c1910e04fc6c 179 * @param pObj vl53l3cx context object.
charlesmn 0:c1910e04fc6c 180 * @param pId Pointer to the device ID.
charlesmn 0:c1910e04fc6c 181 * @retval VL53L3CX status
charlesmn 0:c1910e04fc6c 182 */
charlesmn 0:c1910e04fc6c 183 int32_t VL53L3CX_ReadID(VL53L3CX_Object_t *pObj, uint32_t *pId)
charlesmn 0:c1910e04fc6c 184 {
charlesmn 0:c1910e04fc6c 185 int32_t ret;
charlesmn 0:c1910e04fc6c 186
charlesmn 0:c1910e04fc6c 187 if ((pObj == NULL) || (pId == NULL))
charlesmn 0:c1910e04fc6c 188 {
charlesmn 0:c1910e04fc6c 189 ret = VL53L3CX_INVALID_PARAM;
charlesmn 0:c1910e04fc6c 190 }
charlesmn 0:c1910e04fc6c 191 else
charlesmn 0:c1910e04fc6c 192 {
charlesmn 0:c1910e04fc6c 193 printf("VL53L3CX_ReadID \n");
charlesmn 0:c1910e04fc6c 194 *pId = 0;
charlesmn 0:c1910e04fc6c 195 ret = VL53LX_RdWord(pObj, VL53L3CX_ID_REG, (uint16_t *) pId);
charlesmn 0:c1910e04fc6c 196 }
charlesmn 0:c1910e04fc6c 197
charlesmn 0:c1910e04fc6c 198 return ret;
charlesmn 0:c1910e04fc6c 199 }
charlesmn 0:c1910e04fc6c 200
charlesmn 0:c1910e04fc6c 201 /**
charlesmn 0:c1910e04fc6c 202 * @brief Get the vl53l3cx capabilities.
charlesmn 0:c1910e04fc6c 203 * @param pObj vl53l3cx context object.
charlesmn 0:c1910e04fc6c 204 * @param pCap Pointer to the vl53l3cx capabilities.
charlesmn 0:c1910e04fc6c 205 * @note This function should be called after the init.
charlesmn 0:c1910e04fc6c 206 * @retval VL53L3CX status
charlesmn 0:c1910e04fc6c 207 */
charlesmn 0:c1910e04fc6c 208 int32_t VL53L3CX_GetCapabilities(VL53L3CX_Object_t *pObj, VL53L3CX_Capabilities_t *pCap)
charlesmn 0:c1910e04fc6c 209 {
charlesmn 0:c1910e04fc6c 210 int32_t ret;
charlesmn 0:c1910e04fc6c 211
charlesmn 0:c1910e04fc6c 212 if ((pObj == NULL) || (pCap == NULL))
charlesmn 0:c1910e04fc6c 213 {
charlesmn 0:c1910e04fc6c 214 ret = VL53L3CX_INVALID_PARAM;
charlesmn 0:c1910e04fc6c 215 }
charlesmn 0:c1910e04fc6c 216 else
charlesmn 0:c1910e04fc6c 217 {
charlesmn 0:c1910e04fc6c 218 pCap->NumberOfZones = 1;
charlesmn 0:c1910e04fc6c 219 pCap->MaxNumberOfTargetsPerZone = VL53L3CX_NB_TARGET_PER_ZONE;
charlesmn 0:c1910e04fc6c 220 pCap->CustomROI = 1;
charlesmn 0:c1910e04fc6c 221 pCap->ThresholdDetection = 0;
charlesmn 0:c1910e04fc6c 222
charlesmn 0:c1910e04fc6c 223 ret = VL53L3CX_OK;
charlesmn 0:c1910e04fc6c 224 }
charlesmn 0:c1910e04fc6c 225
charlesmn 0:c1910e04fc6c 226 return ret;
charlesmn 0:c1910e04fc6c 227 }
charlesmn 0:c1910e04fc6c 228
charlesmn 0:c1910e04fc6c 229 /**
charlesmn 0:c1910e04fc6c 230 * @brief Set the ranging configuration profile.
charlesmn 0:c1910e04fc6c 231 * @param pObj vl53l3cx context object.
charlesmn 0:c1910e04fc6c 232 * @param pConfig Pointer to the new configuration profile to be applied.
charlesmn 0:c1910e04fc6c 233 * @note for VL53L3CX the profile corresponds to the distance modes.
charlesmn 0:c1910e04fc6c 234 * @retval VL53L3CX status
charlesmn 0:c1910e04fc6c 235 */
charlesmn 0:c1910e04fc6c 236 int32_t VL53L3CX_ConfigProfile(VL53L3CX_Object_t *pObj, VL53L3CX_ProfileConfig_t *pConfig)
charlesmn 0:c1910e04fc6c 237 {
charlesmn 0:c1910e04fc6c 238 int32_t ret;
charlesmn 0:c1910e04fc6c 239 uint8_t ranging_profile;
charlesmn 0:c1910e04fc6c 240
charlesmn 0:c1910e04fc6c 241 if ((pObj != NULL) && (pConfig != NULL))
charlesmn 0:c1910e04fc6c 242 {
charlesmn 0:c1910e04fc6c 243 ranging_profile = pConfig->RangingProfile;
charlesmn 0:c1910e04fc6c 244 }
charlesmn 0:c1910e04fc6c 245 else
charlesmn 0:c1910e04fc6c 246 {
charlesmn 0:c1910e04fc6c 247 printf("VL53L3CX_ConfigProfile pObj \n");
charlesmn 0:c1910e04fc6c 248 return VL53L3CX_INVALID_PARAM;
charlesmn 0:c1910e04fc6c 249 }
charlesmn 0:c1910e04fc6c 250
charlesmn 0:c1910e04fc6c 251 if ((ranging_profile != VL53L3CX_PROFILE_SHORT) &&
charlesmn 0:c1910e04fc6c 252 (ranging_profile != VL53L3CX_PROFILE_MEDIUM) &&
charlesmn 0:c1910e04fc6c 253 (ranging_profile != VL53L3CX_PROFILE_LONG))
charlesmn 0:c1910e04fc6c 254 {
charlesmn 0:c1910e04fc6c 255 printf("VL53L3CX_ConfigProfile ranging_profile \n");
charlesmn 0:c1910e04fc6c 256 ret = VL53L3CX_INVALID_PARAM;
charlesmn 0:c1910e04fc6c 257 }
charlesmn 0:c1910e04fc6c 258 else if (VL53LX_SetDistanceMode(pObj, ranging_profile) != VL53LX_ERROR_NONE)
charlesmn 0:c1910e04fc6c 259 {
charlesmn 0:c1910e04fc6c 260 ret = VL53L3CX_ERROR;
charlesmn 0:c1910e04fc6c 261 }
charlesmn 0:c1910e04fc6c 262 else if (VL53LX_SetMeasurementTimingBudgetMicroSeconds(
charlesmn 0:c1910e04fc6c 263 pObj, (1000U * pConfig->TimingBudget)) != VL53LX_ERROR_NONE)
charlesmn 0:c1910e04fc6c 264 {
charlesmn 0:c1910e04fc6c 265 ret = VL53L3CX_ERROR;
charlesmn 0:c1910e04fc6c 266 }
charlesmn 0:c1910e04fc6c 267 else
charlesmn 0:c1910e04fc6c 268 {
charlesmn 0:c1910e04fc6c 269 pObj->IsAmbientEnabled = (pConfig->EnableAmbient == 0U) ? 0U : 1U;
charlesmn 0:c1910e04fc6c 270 pObj->IsSignalEnabled = (pConfig->EnableSignal == 0U) ? 0U : 1U;
charlesmn 0:c1910e04fc6c 271 pObj->EnableInterrupt = pConfig->EnableInterrupt;
charlesmn 0:c1910e04fc6c 272 pObj->pin_gpio1 = pConfig->pin_gpio1;
charlesmn 0:c1910e04fc6c 273 pObj->Interrupt_Func = pConfig->Interrupt_Func;
charlesmn 0:c1910e04fc6c 274
charlesmn 0:c1910e04fc6c 275 delete_interrupt_measure_detection_irq(); // delete any existing interrupt
charlesmn 0:c1910e04fc6c 276 if ( pObj->EnableInterrupt == 1)
charlesmn 0:c1910e04fc6c 277 create_interrupt_measure_detection_irq(pObj->pin_gpio1);
charlesmn 0:c1910e04fc6c 278
charlesmn 0:c1910e04fc6c 279 ret = VL53L3CX_OK;
charlesmn 0:c1910e04fc6c 280 }
charlesmn 0:c1910e04fc6c 281 printf("VL53L3CX_ConfigProfile %d \n",ret);
charlesmn 0:c1910e04fc6c 282 return ret;
charlesmn 0:c1910e04fc6c 283 }
charlesmn 0:c1910e04fc6c 284
charlesmn 0:c1910e04fc6c 285 /**
charlesmn 0:c1910e04fc6c 286 * @brief Configure the Region of Interest of the vl53l3cx.
charlesmn 0:c1910e04fc6c 287 * @param pObj vl53l3cx context object.
charlesmn 0:c1910e04fc6c 288 * @param pROIConfig Pointer to the ROI configuration struct.
charlesmn 0:c1910e04fc6c 289 * @note Minimal ROI size is 4x4 spads.
charlesmn 0:c1910e04fc6c 290 * @retval VL53L3CX status
charlesmn 0:c1910e04fc6c 291 */
charlesmn 0:c1910e04fc6c 292 int32_t VL53L3CX_ConfigROI(VL53L3CX_Object_t *pObj, VL53L3CX_ROIConfig_t *pROIConfig)
charlesmn 0:c1910e04fc6c 293 {
charlesmn 0:c1910e04fc6c 294 int32_t ret;
charlesmn 0:c1910e04fc6c 295 VL53LX_UserRoi_t roi_settings;
charlesmn 0:c1910e04fc6c 296
charlesmn 0:c1910e04fc6c 297 if ((pObj == NULL) || (pROIConfig == NULL))
charlesmn 0:c1910e04fc6c 298 {
charlesmn 0:c1910e04fc6c 299 ret = VL53L3CX_INVALID_PARAM;
charlesmn 0:c1910e04fc6c 300 }
charlesmn 0:c1910e04fc6c 301 else
charlesmn 0:c1910e04fc6c 302 {
charlesmn 0:c1910e04fc6c 303 roi_settings.BotRightX = pROIConfig->BotRightX;
charlesmn 0:c1910e04fc6c 304 roi_settings.BotRightY = pROIConfig->BotRightY;
charlesmn 0:c1910e04fc6c 305 roi_settings.TopLeftX = pROIConfig->TopLeftX;
charlesmn 0:c1910e04fc6c 306 roi_settings.TopLeftY = pROIConfig->TopLeftY;
charlesmn 0:c1910e04fc6c 307
charlesmn 0:c1910e04fc6c 308 if (VL53LX_SetUserROI(pObj, &roi_settings) != VL53LX_ERROR_NONE)
charlesmn 0:c1910e04fc6c 309 {
charlesmn 0:c1910e04fc6c 310 ret = VL53L3CX_ERROR;
charlesmn 0:c1910e04fc6c 311 }
charlesmn 0:c1910e04fc6c 312 else
charlesmn 0:c1910e04fc6c 313 {
charlesmn 0:c1910e04fc6c 314 ret = VL53L3CX_OK;
charlesmn 0:c1910e04fc6c 315 }
charlesmn 0:c1910e04fc6c 316 }
charlesmn 0:c1910e04fc6c 317
charlesmn 0:c1910e04fc6c 318 return ret;
charlesmn 0:c1910e04fc6c 319 }
charlesmn 0:c1910e04fc6c 320
charlesmn 0:c1910e04fc6c 321 /**
charlesmn 0:c1910e04fc6c 322 * @brief Configure the IT event generation parameters.
charlesmn 0:c1910e04fc6c 323 * @param pObj vl53l3cx context object.
charlesmn 0:c1910e04fc6c 324 * @param pITConfig Pointer to the IT configuration struct.
charlesmn 0:c1910e04fc6c 325 * @note The threshold modes can be used only if supported by the device (check the capabilities)
charlesmn 0:c1910e04fc6c 326 * @warning This device does not support this feature.
charlesmn 0:c1910e04fc6c 327 * @retval VL53L3CX status
charlesmn 0:c1910e04fc6c 328 */
charlesmn 0:c1910e04fc6c 329 int32_t VL53L3CX_ConfigIT(VL53L3CX_Object_t *pObj, VL53L3CX_ITConfig_t *pITConfig)
charlesmn 0:c1910e04fc6c 330 {
charlesmn 0:c1910e04fc6c 331 UNUSED(pObj);
charlesmn 0:c1910e04fc6c 332 UNUSED(pITConfig);
charlesmn 0:c1910e04fc6c 333 return VL53L3CX_NOT_IMPLEMENTED;
charlesmn 0:c1910e04fc6c 334 }
charlesmn 0:c1910e04fc6c 335
charlesmn 0:c1910e04fc6c 336 /**
charlesmn 0:c1910e04fc6c 337 * @brief Get the last distance measurement information.
charlesmn 0:c1910e04fc6c 338 * @param pObj vl53l3cx context object.
charlesmn 0:c1910e04fc6c 339 * @param pResult Pointer to the result struct.
charlesmn 0:c1910e04fc6c 340 * @retval VL53L3CX status
charlesmn 0:c1910e04fc6c 341 */
charlesmn 0:c1910e04fc6c 342 int32_t VL53L3CX_GetDistance(VL53L3CX_Object_t *pObj, VL53L3CX_Result_t *pResult)
charlesmn 0:c1910e04fc6c 343 {
charlesmn 0:c1910e04fc6c 344 int32_t ret;
charlesmn 0:c1910e04fc6c 345
charlesmn 0:c1910e04fc6c 346 if ((pObj == NULL) || (pResult == NULL))
charlesmn 0:c1910e04fc6c 347 {
charlesmn 0:c1910e04fc6c 348 ret = VL53L3CX_INVALID_PARAM;
charlesmn 0:c1910e04fc6c 349 }
charlesmn 0:c1910e04fc6c 350 else if (pObj->IsRanging == 0U)
charlesmn 0:c1910e04fc6c 351 {
charlesmn 0:c1910e04fc6c 352 ret = VL53L3CX_ERROR;
charlesmn 0:c1910e04fc6c 353 }
charlesmn 0:c1910e04fc6c 354 else
charlesmn 0:c1910e04fc6c 355 {
charlesmn 0:c1910e04fc6c 356 if (pObj->IsBlocking == 1U)
charlesmn 0:c1910e04fc6c 357 {
charlesmn 0:c1910e04fc6c 358 ret = vl53l3cx_poll_for_measurement(pObj, V53L3CX_POLL_TIMEOUT);
charlesmn 0:c1910e04fc6c 359 }
charlesmn 0:c1910e04fc6c 360 else
charlesmn 0:c1910e04fc6c 361 {
charlesmn 0:c1910e04fc6c 362 ret = vl53l3cx_poll_for_measurement(pObj, 0U);
charlesmn 0:c1910e04fc6c 363 }
charlesmn 0:c1910e04fc6c 364 }
charlesmn 0:c1910e04fc6c 365
charlesmn 0:c1910e04fc6c 366 /* a new measure is available if no error is returned by the poll function */
charlesmn 0:c1910e04fc6c 367 if (ret == VL53L3CX_OK)
charlesmn 0:c1910e04fc6c 368 {
charlesmn 0:c1910e04fc6c 369 /* retrieve measurements and fill result structure */
charlesmn 0:c1910e04fc6c 370 if (vl53l3cx_get_result(pObj, pResult) != VL53L3CX_OK)
charlesmn 0:c1910e04fc6c 371 {
charlesmn 0:c1910e04fc6c 372 ret = VL53L3CX_ERROR;
charlesmn 0:c1910e04fc6c 373 }
charlesmn 0:c1910e04fc6c 374 else if (pObj->IsContinuous == 1U)
charlesmn 0:c1910e04fc6c 375 {
charlesmn 0:c1910e04fc6c 376 /* trigger new measurement if device configured in continuous mode */
charlesmn 0:c1910e04fc6c 377 ret = (int32_t)VL53LX_ClearInterruptAndStartMeasurement(pObj);
charlesmn 0:c1910e04fc6c 378 }
charlesmn 0:c1910e04fc6c 379 else
charlesmn 0:c1910e04fc6c 380 {
charlesmn 0:c1910e04fc6c 381 ret = VL53L3CX_OK;
charlesmn 0:c1910e04fc6c 382 }
charlesmn 0:c1910e04fc6c 383 }
charlesmn 0:c1910e04fc6c 384 return ret;
charlesmn 0:c1910e04fc6c 385 }
charlesmn 0:c1910e04fc6c 386
charlesmn 0:c1910e04fc6c 387 /**
charlesmn 0:c1910e04fc6c 388 * @brief Start ranging.
charlesmn 0:c1910e04fc6c 389 * @param pObj vl53l3cx context object.
charlesmn 0:c1910e04fc6c 390 * @param Mode The desired ranging mode.
charlesmn 0:c1910e04fc6c 391 * @retval VL53L3CX status
charlesmn 0:c1910e04fc6c 392 */
charlesmn 0:c1910e04fc6c 393 int32_t VL53L3CX_Start(VL53L3CX_Object_t *pObj, uint32_t Mode)
charlesmn 0:c1910e04fc6c 394 {
charlesmn 0:c1910e04fc6c 395 int32_t ret;
charlesmn 0:c1910e04fc6c 396
charlesmn 0:c1910e04fc6c 397 if (pObj == NULL)
charlesmn 0:c1910e04fc6c 398 {
charlesmn 0:c1910e04fc6c 399 printf("VL53L3CX_Start NULL \n");
charlesmn 0:c1910e04fc6c 400 ret = VL53L3CX_INVALID_PARAM;
charlesmn 0:c1910e04fc6c 401 }
charlesmn 0:c1910e04fc6c 402 else if (pObj->IsRanging == 1U)
charlesmn 0:c1910e04fc6c 403 {
charlesmn 0:c1910e04fc6c 404 printf("VL53L3CX_Start IsRanging \n");
charlesmn 0:c1910e04fc6c 405 ret = VL53L3CX_ERROR;
charlesmn 0:c1910e04fc6c 406 }
charlesmn 0:c1910e04fc6c 407 else if (VL53LX_StartMeasurement(pObj) == VL53LX_ERROR_NONE)
charlesmn 0:c1910e04fc6c 408 {
charlesmn 0:c1910e04fc6c 409 pObj->IsRanging = 1;
charlesmn 0:c1910e04fc6c 410 ret = VL53L3CX_OK;
charlesmn 0:c1910e04fc6c 411
charlesmn 0:c1910e04fc6c 412 switch (Mode)
charlesmn 0:c1910e04fc6c 413 {
charlesmn 0:c1910e04fc6c 414 case VL53L3CX_MODE_BLOCKING_CONTINUOUS:
charlesmn 0:c1910e04fc6c 415 pObj->IsContinuous = 1U;
charlesmn 0:c1910e04fc6c 416 pObj->IsBlocking = 1U;
charlesmn 0:c1910e04fc6c 417 break;
charlesmn 0:c1910e04fc6c 418
charlesmn 0:c1910e04fc6c 419 case VL53L3CX_MODE_BLOCKING_ONESHOT:
charlesmn 0:c1910e04fc6c 420 pObj->IsContinuous = 0U;
charlesmn 0:c1910e04fc6c 421 pObj->IsBlocking = 1U;
charlesmn 0:c1910e04fc6c 422 break;
charlesmn 0:c1910e04fc6c 423
charlesmn 0:c1910e04fc6c 424 case VL53L3CX_MODE_ASYNC_CONTINUOUS:
charlesmn 0:c1910e04fc6c 425 pObj->IsContinuous = 1U;
charlesmn 0:c1910e04fc6c 426 pObj->IsBlocking = 0U;
charlesmn 0:c1910e04fc6c 427 break;
charlesmn 0:c1910e04fc6c 428
charlesmn 0:c1910e04fc6c 429 case VL53L3CX_MODE_ASYNC_ONESHOT:
charlesmn 0:c1910e04fc6c 430 pObj->IsContinuous = 0U;
charlesmn 0:c1910e04fc6c 431 pObj->IsBlocking = 0U;
charlesmn 0:c1910e04fc6c 432 break;
charlesmn 0:c1910e04fc6c 433
charlesmn 0:c1910e04fc6c 434 default:
charlesmn 0:c1910e04fc6c 435 printf("VL53L3CX_Start default \n");
charlesmn 0:c1910e04fc6c 436 pObj->IsRanging = 0U;
charlesmn 0:c1910e04fc6c 437 ret = VL53L3CX_INVALID_PARAM;
charlesmn 0:c1910e04fc6c 438 break;
charlesmn 0:c1910e04fc6c 439 }
charlesmn 0:c1910e04fc6c 440 }
charlesmn 0:c1910e04fc6c 441 else
charlesmn 0:c1910e04fc6c 442 {
charlesmn 0:c1910e04fc6c 443 printf("VL53L3CX_Start end err \n");
charlesmn 0:c1910e04fc6c 444 ret = VL53L3CX_ERROR;
charlesmn 0:c1910e04fc6c 445 }
charlesmn 0:c1910e04fc6c 446 return ret;
charlesmn 0:c1910e04fc6c 447 }
charlesmn 0:c1910e04fc6c 448
charlesmn 0:c1910e04fc6c 449 /**
charlesmn 0:c1910e04fc6c 450 * @brief Stop ranging.
charlesmn 0:c1910e04fc6c 451 * @param pObj vl53l3cx context object.
charlesmn 0:c1910e04fc6c 452 * @retval VL53L3CX status
charlesmn 0:c1910e04fc6c 453 */
charlesmn 0:c1910e04fc6c 454 int32_t VL53L3CX_Stop(VL53L3CX_Object_t *pObj)
charlesmn 0:c1910e04fc6c 455 {
charlesmn 0:c1910e04fc6c 456 int32_t ret;
charlesmn 0:c1910e04fc6c 457
charlesmn 0:c1910e04fc6c 458 if (pObj == NULL)
charlesmn 0:c1910e04fc6c 459 {
charlesmn 0:c1910e04fc6c 460 ret = VL53L3CX_INVALID_PARAM;
charlesmn 0:c1910e04fc6c 461 }
charlesmn 0:c1910e04fc6c 462 else if (pObj->IsRanging == 0U)
charlesmn 0:c1910e04fc6c 463 {
charlesmn 0:c1910e04fc6c 464 /* ranging not started */
charlesmn 0:c1910e04fc6c 465 ret = VL53L3CX_ERROR;
charlesmn 0:c1910e04fc6c 466 }
charlesmn 0:c1910e04fc6c 467 else if (VL53LX_StopMeasurement(pObj) == VL53LX_ERROR_NONE)
charlesmn 0:c1910e04fc6c 468 {
charlesmn 0:c1910e04fc6c 469 pObj->IsRanging = 0U;
charlesmn 0:c1910e04fc6c 470 ret = VL53L3CX_OK;
charlesmn 0:c1910e04fc6c 471 }
charlesmn 0:c1910e04fc6c 472 else
charlesmn 0:c1910e04fc6c 473 {
charlesmn 0:c1910e04fc6c 474 ret = VL53L3CX_ERROR;
charlesmn 0:c1910e04fc6c 475 }
charlesmn 0:c1910e04fc6c 476
charlesmn 0:c1910e04fc6c 477 return ret;
charlesmn 0:c1910e04fc6c 478 }
charlesmn 0:c1910e04fc6c 479
charlesmn 0:c1910e04fc6c 480 /**
charlesmn 0:c1910e04fc6c 481 * @brief Set the I2C address of the device.
charlesmn 0:c1910e04fc6c 482 * @param pObj vl53l3cx context object.
charlesmn 0:c1910e04fc6c 483 * @param Address New I2C address.
charlesmn 0:c1910e04fc6c 484 * @retval VL53L3CX status
charlesmn 0:c1910e04fc6c 485 */
charlesmn 0:c1910e04fc6c 486 int32_t VL53L3CX_SetAddress(VL53L3CX_Object_t *pObj, uint32_t Address)
charlesmn 0:c1910e04fc6c 487 {
charlesmn 0:c1910e04fc6c 488 int32_t ret;
charlesmn 0:c1910e04fc6c 489
charlesmn 0:c1910e04fc6c 490 if (pObj == NULL)
charlesmn 0:c1910e04fc6c 491 {
charlesmn 0:c1910e04fc6c 492 ret = VL53L3CX_INVALID_PARAM;
charlesmn 0:c1910e04fc6c 493 }
charlesmn 0:c1910e04fc6c 494 else if (VL53LX_SetDeviceAddress(pObj, (uint8_t)Address) != VL53LX_ERROR_NONE)
charlesmn 0:c1910e04fc6c 495 {
charlesmn 0:c1910e04fc6c 496 ret = VL53L3CX_ERROR;
charlesmn 0:c1910e04fc6c 497 }
charlesmn 0:c1910e04fc6c 498 else
charlesmn 0:c1910e04fc6c 499 {
charlesmn 0:c1910e04fc6c 500 pObj->IO.Address = (uint16_t) Address;
charlesmn 0:c1910e04fc6c 501 ret = VL53L3CX_OK;
charlesmn 0:c1910e04fc6c 502 }
charlesmn 0:c1910e04fc6c 503
charlesmn 0:c1910e04fc6c 504 return ret;
charlesmn 0:c1910e04fc6c 505 }
charlesmn 0:c1910e04fc6c 506
charlesmn 0:c1910e04fc6c 507 /**
charlesmn 0:c1910e04fc6c 508 * @brief Get the current I2C address.
charlesmn 0:c1910e04fc6c 509 * @param pObj vl53l3cx context object.
charlesmn 0:c1910e04fc6c 510 * @param pAddress Pointer to the current I2C address.
charlesmn 0:c1910e04fc6c 511 * @retval VL53L3CX status
charlesmn 0:c1910e04fc6c 512 */
charlesmn 0:c1910e04fc6c 513 int32_t VL53L3CX_GetAddress(VL53L3CX_Object_t *pObj, uint32_t *pAddress)
charlesmn 0:c1910e04fc6c 514 {
charlesmn 0:c1910e04fc6c 515 int32_t ret;
charlesmn 0:c1910e04fc6c 516
charlesmn 0:c1910e04fc6c 517 if ((pObj == NULL) || (pAddress == NULL))
charlesmn 0:c1910e04fc6c 518 {
charlesmn 0:c1910e04fc6c 519 ret = VL53L3CX_INVALID_PARAM;
charlesmn 0:c1910e04fc6c 520 }
charlesmn 0:c1910e04fc6c 521 else
charlesmn 0:c1910e04fc6c 522 {
charlesmn 0:c1910e04fc6c 523 *pAddress = pObj->IO.Address;
charlesmn 0:c1910e04fc6c 524 ret = VL53L3CX_OK;
charlesmn 0:c1910e04fc6c 525 }
charlesmn 0:c1910e04fc6c 526
charlesmn 0:c1910e04fc6c 527 return ret;
charlesmn 0:c1910e04fc6c 528 }
charlesmn 0:c1910e04fc6c 529
charlesmn 0:c1910e04fc6c 530 /**
charlesmn 0:c1910e04fc6c 531 * @brief Set the power mode.
charlesmn 0:c1910e04fc6c 532 * @param pObj vl53l3cx context object.
charlesmn 0:c1910e04fc6c 533 * @param PowerMode New power mode to be entered.
charlesmn 0:c1910e04fc6c 534 * @note Not implemented for this device
charlesmn 0:c1910e04fc6c 535 * @retval VL53L3CX status
charlesmn 0:c1910e04fc6c 536 */
charlesmn 0:c1910e04fc6c 537 int32_t VL53L3CX_SetPowerMode(VL53L3CX_Object_t *pObj, uint32_t PowerMode)
charlesmn 0:c1910e04fc6c 538 {
charlesmn 0:c1910e04fc6c 539 UNUSED(pObj);
charlesmn 0:c1910e04fc6c 540 UNUSED(PowerMode);
charlesmn 0:c1910e04fc6c 541 return VL53L3CX_NOT_IMPLEMENTED;
charlesmn 0:c1910e04fc6c 542 }
charlesmn 0:c1910e04fc6c 543
charlesmn 0:c1910e04fc6c 544 /**
charlesmn 0:c1910e04fc6c 545 * @brief Get the power mode.
charlesmn 0:c1910e04fc6c 546 * @param pObj vl53l3cx context object.
charlesmn 0:c1910e04fc6c 547 * @param pPowerMode Pointer to the current power mode.
charlesmn 0:c1910e04fc6c 548 * @note Not implemented for this device
charlesmn 0:c1910e04fc6c 549 * @retval VL53L3CX status
charlesmn 0:c1910e04fc6c 550 */
charlesmn 0:c1910e04fc6c 551 int32_t VL53L3CX_GetPowerMode(VL53L3CX_Object_t *pObj, uint32_t *pPowerMode)
charlesmn 0:c1910e04fc6c 552 {
charlesmn 0:c1910e04fc6c 553 UNUSED(pObj);
charlesmn 0:c1910e04fc6c 554 UNUSED(pPowerMode);
charlesmn 0:c1910e04fc6c 555 return VL53L3CX_NOT_IMPLEMENTED;
charlesmn 0:c1910e04fc6c 556 }
charlesmn 0:c1910e04fc6c 557
charlesmn 0:c1910e04fc6c 558 /**
charlesmn 0:c1910e04fc6c 559 * @brief Perform an offset calibration.
charlesmn 0:c1910e04fc6c 560 * @param pObj vl53l3cx context object.
charlesmn 0:c1910e04fc6c 561 * @param CalDistance Calibration distance in mm.
charlesmn 0:c1910e04fc6c 562 * @retval VL53L3CX status
charlesmn 0:c1910e04fc6c 563 */
charlesmn 0:c1910e04fc6c 564 int32_t VL53L3CX_OffsetCalibration(VL53L3CX_Object_t *pObj, uint32_t CalDistance)
charlesmn 0:c1910e04fc6c 565 {
charlesmn 0:c1910e04fc6c 566 int32_t ret;
charlesmn 0:c1910e04fc6c 567
charlesmn 0:c1910e04fc6c 568 VL53LX_OffsetCorrectionModes Mode = VL53LX_OFFSETCORRECTIONMODE_STANDARD;
charlesmn 0:c1910e04fc6c 569
charlesmn 0:c1910e04fc6c 570 if (VL53LX_SetOffsetCorrectionMode(pObj, Mode) != VL53LX_ERROR_NONE)
charlesmn 0:c1910e04fc6c 571 {
charlesmn 0:c1910e04fc6c 572 ret = VL53L3CX_ERROR;
charlesmn 0:c1910e04fc6c 573 }
charlesmn 0:c1910e04fc6c 574 else if (VL53LX_PerformOffsetSimpleCalibration(pObj, (int32_t)CalDistance) != VL53LX_ERROR_NONE)
charlesmn 0:c1910e04fc6c 575 {
charlesmn 0:c1910e04fc6c 576 ret = VL53L3CX_ERROR;
charlesmn 0:c1910e04fc6c 577 }
charlesmn 0:c1910e04fc6c 578 else
charlesmn 0:c1910e04fc6c 579 {
charlesmn 0:c1910e04fc6c 580 ret = VL53L3CX_OK;
charlesmn 0:c1910e04fc6c 581 }
charlesmn 0:c1910e04fc6c 582
charlesmn 0:c1910e04fc6c 583 return ret;
charlesmn 0:c1910e04fc6c 584 }
charlesmn 0:c1910e04fc6c 585
charlesmn 0:c1910e04fc6c 586 /**
charlesmn 0:c1910e04fc6c 587 * @brief Perform a xtalk calibration.
charlesmn 0:c1910e04fc6c 588 * @param pObj vl53l3cx context object.
charlesmn 0:c1910e04fc6c 589 * @retval VL53L3CX status
charlesmn 0:c1910e04fc6c 590 */
charlesmn 0:c1910e04fc6c 591 int32_t VL53L3CX_XTalkCalibration(VL53L3CX_Object_t *pObj)
charlesmn 0:c1910e04fc6c 592 {
charlesmn 0:c1910e04fc6c 593 int32_t ret;
charlesmn 0:c1910e04fc6c 594
charlesmn 0:c1910e04fc6c 595 if (VL53LX_PerformXTalkCalibration(pObj) != VL53LX_ERROR_NONE)
charlesmn 0:c1910e04fc6c 596 {
charlesmn 0:c1910e04fc6c 597 ret = VL53L3CX_ERROR;
charlesmn 0:c1910e04fc6c 598 }
charlesmn 0:c1910e04fc6c 599 else
charlesmn 0:c1910e04fc6c 600 {
charlesmn 0:c1910e04fc6c 601 ret = VL53L3CX_OK;
charlesmn 0:c1910e04fc6c 602 }
charlesmn 0:c1910e04fc6c 603
charlesmn 0:c1910e04fc6c 604 return ret;
charlesmn 0:c1910e04fc6c 605 }
charlesmn 0:c1910e04fc6c 606
charlesmn 0:c1910e04fc6c 607 /** @defgroup VL53L3CX_Private_Functions Private Functions
charlesmn 0:c1910e04fc6c 608 * @{
charlesmn 0:c1910e04fc6c 609 */
charlesmn 0:c1910e04fc6c 610
charlesmn 0:c1910e04fc6c 611 static int32_t vl53l3cx_poll_for_measurement(VL53L3CX_Object_t *pObj, uint32_t Timeout)
charlesmn 0:c1910e04fc6c 612 {
charlesmn 0:c1910e04fc6c 613 uint32_t TickStart;
charlesmn 0:c1910e04fc6c 614 uint8_t NewDataReady = 0;
charlesmn 0:c1910e04fc6c 615
charlesmn 0:c1910e04fc6c 616 if (pObj == NULL)
charlesmn 0:c1910e04fc6c 617 {
charlesmn 0:c1910e04fc6c 618 return VL53L3CX_INVALID_PARAM;
charlesmn 0:c1910e04fc6c 619 }
charlesmn 0:c1910e04fc6c 620
charlesmn 0:c1910e04fc6c 621
charlesmn 0:c1910e04fc6c 622 TickStart = pObj->IO.GetTick();
charlesmn 0:c1910e04fc6c 623
charlesmn 0:c1910e04fc6c 624 do
charlesmn 0:c1910e04fc6c 625 {
charlesmn 0:c1910e04fc6c 626 (void)VL53LX_GetMeasurementDataReady(pObj, &NewDataReady);
charlesmn 0:c1910e04fc6c 627
charlesmn 0:c1910e04fc6c 628 if (NewDataReady == 1U)
charlesmn 0:c1910e04fc6c 629 {
charlesmn 0:c1910e04fc6c 630 return VL53L3CX_OK;
charlesmn 0:c1910e04fc6c 631 }
charlesmn 0:c1910e04fc6c 632 } while ((pObj->IO.GetTick() - TickStart) < Timeout);
charlesmn 0:c1910e04fc6c 633 return VL53L3CX_TIMEOUT;
charlesmn 0:c1910e04fc6c 634 }
charlesmn 0:c1910e04fc6c 635
charlesmn 0:c1910e04fc6c 636 static int32_t vl53l3cx_get_result(VL53L3CX_Object_t *pObj, VL53L3CX_Result_t *pResult)
charlesmn 0:c1910e04fc6c 637 {
charlesmn 0:c1910e04fc6c 638 int32_t ret;
charlesmn 0:c1910e04fc6c 639 uint8_t i, j;
charlesmn 0:c1910e04fc6c 640 uint16_t spad_count; /* number of active spads for the current measurement */
charlesmn 0:c1910e04fc6c 641 float_t ambient_temp, signal_temp; /* temporary variables used for computation */
charlesmn 0:c1910e04fc6c 642 VL53LX_MultiRangingData_t data;
charlesmn 0:c1910e04fc6c 643
charlesmn 0:c1910e04fc6c 644 if ((pObj == NULL) || (pResult == NULL))
charlesmn 0:c1910e04fc6c 645 {
charlesmn 0:c1910e04fc6c 646 ret = VL53L3CX_INVALID_PARAM;
charlesmn 0:c1910e04fc6c 647 }
charlesmn 0:c1910e04fc6c 648 else if (VL53LX_GetMultiRangingData(pObj, &data) != VL53LX_ERROR_NONE)
charlesmn 0:c1910e04fc6c 649 {
charlesmn 0:c1910e04fc6c 650 ret = VL53L3CX_ERROR;
charlesmn 0:c1910e04fc6c 651 }
charlesmn 0:c1910e04fc6c 652 else
charlesmn 0:c1910e04fc6c 653 {
charlesmn 0:c1910e04fc6c 654 for (i = 0; i < VL53L3CX_MAX_NB_ZONES; i++)
charlesmn 0:c1910e04fc6c 655 {
charlesmn 0:c1910e04fc6c 656 pResult->NumberOfZones = VL53L3CX_MAX_NB_ZONES;
charlesmn 0:c1910e04fc6c 657 /* number of detected targets by the device */
charlesmn 0:c1910e04fc6c 658 pResult->ZoneResult[i].NumberOfTargets = data.NumberOfObjectsFound;
charlesmn 0:c1910e04fc6c 659
charlesmn 0:c1910e04fc6c 660 for (j = 0; j < data.NumberOfObjectsFound; j++)
charlesmn 0:c1910e04fc6c 661 {
charlesmn 0:c1910e04fc6c 662 /* clip the value if negative */
charlesmn 0:c1910e04fc6c 663 if (data.RangeData[j].RangeMilliMeter < 0)
charlesmn 0:c1910e04fc6c 664 {
charlesmn 0:c1910e04fc6c 665 pResult->ZoneResult[i].Distance[j] = 0U;
charlesmn 0:c1910e04fc6c 666 }
charlesmn 0:c1910e04fc6c 667 else
charlesmn 0:c1910e04fc6c 668 {
charlesmn 0:c1910e04fc6c 669 pResult->ZoneResult[i].Distance[j] = (uint32_t)data.RangeData[j].RangeMilliMeter;
charlesmn 0:c1910e04fc6c 670 }
charlesmn 0:c1910e04fc6c 671
charlesmn 0:c1910e04fc6c 672 /* compute and return Ambient value if ambient rate output is enabled :
charlesmn 0:c1910e04fc6c 673 * - convert value from FixPoint1616 to Mcps by dividing by 65536
charlesmn 0:c1910e04fc6c 674 * - convert value from Mcps to Kcps by multiplying it by 1000
charlesmn 0:c1910e04fc6c 675 * - obtain number of active spads by dividing EffectiveSpadRtnCount by 256
charlesmn 0:c1910e04fc6c 676 * - convert ambient value from Kcps to Kcps/spad diving by the number of active spads
charlesmn 0:c1910e04fc6c 677 */
charlesmn 0:c1910e04fc6c 678 if (pObj->IsAmbientEnabled == 1U)
charlesmn 0:c1910e04fc6c 679 {
charlesmn 0:c1910e04fc6c 680 ambient_temp = (data.RangeData[j].AmbientRateRtnMegaCps / 65536.0f) * 1000.0f;
charlesmn 0:c1910e04fc6c 681 spad_count = data.EffectiveSpadRtnCount >> 8;
charlesmn 0:c1910e04fc6c 682 pResult->ZoneResult[i].Ambient[j] = ambient_temp / (float_t)spad_count;
charlesmn 0:c1910e04fc6c 683 }
charlesmn 0:c1910e04fc6c 684 else
charlesmn 0:c1910e04fc6c 685 {
charlesmn 0:c1910e04fc6c 686 pResult->ZoneResult[i].Ambient[j] = 0.0f;
charlesmn 0:c1910e04fc6c 687 }
charlesmn 0:c1910e04fc6c 688
charlesmn 0:c1910e04fc6c 689 /* compute and return Ambient value if signal rate output is enabled :
charlesmn 0:c1910e04fc6c 690 * - convert value from FixPoint1616 to Mcps by dividing by 65536
charlesmn 0:c1910e04fc6c 691 * - convert value from Mcps to Kcps by multiplying it by 1000
charlesmn 0:c1910e04fc6c 692 * - obtain number of active spads by dividing EffectiveSpadRtnCount by 256
charlesmn 0:c1910e04fc6c 693 * - convert ambient value from Kcps to Kcps/spad diving by the number of active spads
charlesmn 0:c1910e04fc6c 694 */
charlesmn 0:c1910e04fc6c 695 if (pObj->IsSignalEnabled == 1U)
charlesmn 0:c1910e04fc6c 696 {
charlesmn 0:c1910e04fc6c 697 signal_temp = (data.RangeData[j].SignalRateRtnMegaCps / 65536.0f) * 1000.0f;
charlesmn 0:c1910e04fc6c 698 spad_count = data.EffectiveSpadRtnCount >> 8;
charlesmn 0:c1910e04fc6c 699 pResult->ZoneResult[i].Signal[j] = signal_temp / (float_t)spad_count;
charlesmn 0:c1910e04fc6c 700 }
charlesmn 0:c1910e04fc6c 701 else
charlesmn 0:c1910e04fc6c 702 {
charlesmn 0:c1910e04fc6c 703 pResult->ZoneResult[i].Signal[j] = 0.0f;
charlesmn 0:c1910e04fc6c 704 }
charlesmn 0:c1910e04fc6c 705
charlesmn 0:c1910e04fc6c 706 pResult->ZoneResult[i].Status[j] = data.RangeData[j].RangeStatus;
charlesmn 0:c1910e04fc6c 707 }
charlesmn 0:c1910e04fc6c 708 }
charlesmn 0:c1910e04fc6c 709
charlesmn 0:c1910e04fc6c 710
charlesmn 0:c1910e04fc6c 711 ret = VL53L3CX_OK;
charlesmn 0:c1910e04fc6c 712 }
charlesmn 0:c1910e04fc6c 713
charlesmn 0:c1910e04fc6c 714 return ret;
charlesmn 0:c1910e04fc6c 715 }
charlesmn 0:c1910e04fc6c 716
charlesmn 0:c1910e04fc6c 717 /**
charlesmn 0:c1910e04fc6c 718 * @}
charlesmn 0:c1910e04fc6c 719 */
charlesmn 0:c1910e04fc6c 720
charlesmn 0:c1910e04fc6c 721 /**
charlesmn 0:c1910e04fc6c 722 * @}
charlesmn 0:c1910e04fc6c 723 */
charlesmn 0:c1910e04fc6c 724
charlesmn 0:c1910e04fc6c 725 /**
charlesmn 0:c1910e04fc6c 726 * @}
charlesmn 0:c1910e04fc6c 727 */
charlesmn 0:c1910e04fc6c 728
charlesmn 0:c1910e04fc6c 729 /**
charlesmn 0:c1910e04fc6c 730 * @}
charlesmn 0:c1910e04fc6c 731 */
charlesmn 0:c1910e04fc6c 732