Contains Ayoub's Ranging and Custom interfaces for the VL53L3CX

Committer:
charlesmn
Date:
Wed Jul 21 14:19:31 2021 +0000
Revision:
0:c1910e04fc6c
Child:
1:dae4cb24beec
Change from directory to lib

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