charles macneill / Vl6180_Lib
Committer:
charlesmn
Date:
Wed Oct 28 16:06:15 2020 +0000
Revision:
1:b4bdb0356af0
Parent:
0:1da5e4bcb8e5
fix compiler error. Replace #ifdef 0 with #if 0

Who changed what in which revision?

UserRevisionLine numberNew contents of line
charlesmn 0:1da5e4bcb8e5 1 /*******************************************************************************
charlesmn 0:1da5e4bcb8e5 2 Copyright � 2019, STMicroelectronics International N.V.
charlesmn 0:1da5e4bcb8e5 3 All rights reserved.
charlesmn 0:1da5e4bcb8e5 4
charlesmn 0:1da5e4bcb8e5 5 Redistribution and use in source and binary forms, with or without
charlesmn 0:1da5e4bcb8e5 6 modification, are permitted provided that the following conditions are met:
charlesmn 0:1da5e4bcb8e5 7 * Redistributions of source code must retain the above copyright
charlesmn 0:1da5e4bcb8e5 8 notice, this list of conditions and the following disclaimer.
charlesmn 0:1da5e4bcb8e5 9 * Redistributions in binary form must reproduce the above copyright
charlesmn 0:1da5e4bcb8e5 10 notice, this list of conditions and the following disclaimer in the
charlesmn 0:1da5e4bcb8e5 11 documentation and/or other materials provided with the distribution.
charlesmn 0:1da5e4bcb8e5 12 * Neither the name of STMicroelectronics nor the
charlesmn 0:1da5e4bcb8e5 13 names of its contributors may be used to endorse or promote products
charlesmn 0:1da5e4bcb8e5 14 derived from this software without specific prior written permission.
charlesmn 0:1da5e4bcb8e5 15
charlesmn 0:1da5e4bcb8e5 16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
charlesmn 0:1da5e4bcb8e5 17 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
charlesmn 0:1da5e4bcb8e5 18 WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
charlesmn 0:1da5e4bcb8e5 19 NON-INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS ARE DISCLAIMED.
charlesmn 0:1da5e4bcb8e5 20 IN NO EVENT SHALL STMICROELECTRONICS INTERNATIONAL N.V. BE LIABLE FOR ANY
charlesmn 0:1da5e4bcb8e5 21 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
charlesmn 0:1da5e4bcb8e5 22 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
charlesmn 0:1da5e4bcb8e5 23 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
charlesmn 0:1da5e4bcb8e5 24 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
charlesmn 0:1da5e4bcb8e5 25 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
charlesmn 0:1da5e4bcb8e5 26 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
charlesmn 0:1da5e4bcb8e5 27 ********************************************************************************/
charlesmn 0:1da5e4bcb8e5 28 #include "stdio.h"
charlesmn 0:1da5e4bcb8e5 29 #include "vl6180_api.h"
charlesmn 0:1da5e4bcb8e5 30
charlesmn 0:1da5e4bcb8e5 31 #define VL6180_9to7Conv(x) (x)
charlesmn 0:1da5e4bcb8e5 32
charlesmn 0:1da5e4bcb8e5 33 /* TODO when set all "cached" value with "default init" are updated after init from register read back */
charlesmn 0:1da5e4bcb8e5 34 #define REFRESH_CACHED_DATA_AFTER_INIT 1
charlesmn 0:1da5e4bcb8e5 35
charlesmn 0:1da5e4bcb8e5 36
charlesmn 0:1da5e4bcb8e5 37 #define IsValidGPIOFunction(x) ((x) == GPIOx_SELECT_GPIO_INTERRUPT_OUTPUT || (x) == GPIOx_SELECT_OFF)
charlesmn 0:1da5e4bcb8e5 38
charlesmn 0:1da5e4bcb8e5 39
charlesmn 0:1da5e4bcb8e5 40 /** default value ECE factor Molecular */
charlesmn 0:1da5e4bcb8e5 41 #define DEF_ECE_FACTOR_M 85
charlesmn 0:1da5e4bcb8e5 42 /** default value ECE factor Denominator */
charlesmn 0:1da5e4bcb8e5 43 #define DEF_ECE_FACTOR_D 100
charlesmn 0:1da5e4bcb8e5 44 /** default value for DMAX Enable */
charlesmn 0:1da5e4bcb8e5 45 #define DEF_DMAX_ENABLE 1
charlesmn 0:1da5e4bcb8e5 46 /** default ambient tuning factor %x1000 */
charlesmn 0:1da5e4bcb8e5 47 #define DEF_AMBIENT_TUNING 80
charlesmn 0:1da5e4bcb8e5 48
charlesmn 0:1da5e4bcb8e5 49 #define DEF_CROSS_TALK_VALID_HEIGHT_VALUE 20
charlesmn 0:1da5e4bcb8e5 50
charlesmn 0:1da5e4bcb8e5 51
charlesmn 0:1da5e4bcb8e5 52 #if VL6180_SINGLE_DEVICE_DRIVER
charlesmn 0:1da5e4bcb8e5 53 extern struct VL6180DevData_t SingleVL6180DevData;
charlesmn 0:1da5e4bcb8e5 54 #define VL6180DevDataGet(dev, field) (SingleVL6180DevData.field)
charlesmn 0:1da5e4bcb8e5 55 #define VL6180DevDataSet(dev, field, data) SingleVL6180DevData.field = (data)
charlesmn 0:1da5e4bcb8e5 56 #endif
charlesmn 0:1da5e4bcb8e5 57
charlesmn 0:1da5e4bcb8e5 58 #define LUXRES_FIX_PREC 8
charlesmn 0:1da5e4bcb8e5 59 #define GAIN_FIX_PREC 8 /* ! if not sme as LUX_PREC then :( adjust GetLux */
charlesmn 0:1da5e4bcb8e5 60 #define AN_GAIN_MULT (1 << GAIN_FIX_PREC)
charlesmn 0:1da5e4bcb8e5 61
charlesmn 0:1da5e4bcb8e5 62
charlesmn 0:1da5e4bcb8e5 63 static int32_t _GetAveTotalTime(VL6180Dev_t dev);
charlesmn 0:1da5e4bcb8e5 64 static int VL6180_RangeSetEarlyConvergenceEestimateThreshold(VL6180Dev_t dev);
charlesmn 0:1da5e4bcb8e5 65
charlesmn 0:1da5e4bcb8e5 66 /**
charlesmn 0:1da5e4bcb8e5 67 * ScalerLookUP scaling factor-1 to register #RANGE_SCALER lookup
charlesmn 0:1da5e4bcb8e5 68 */
charlesmn 0:1da5e4bcb8e5 69 static const uint16_t ScalerLookUP[] ROMABLE_DATA = {253, 127, 84}; /* lookup table for scaling->scalar 1x2x 3x */
charlesmn 0:1da5e4bcb8e5 70 /**
charlesmn 0:1da5e4bcb8e5 71 * scaling factor to Upper limit look up
charlesmn 0:1da5e4bcb8e5 72 */
charlesmn 0:1da5e4bcb8e5 73 static const uint16_t UpperLimitLookUP[] ROMABLE_DATA = {185, 370, 580}; /* lookup table for scaling->limit 1x2x3x */
charlesmn 0:1da5e4bcb8e5 74
charlesmn 0:1da5e4bcb8e5 75
charlesmn 0:1da5e4bcb8e5 76 #if VL6180_RANGE_STATUS_ERRSTRING
charlesmn 0:1da5e4bcb8e5 77 const char *ROMABLE_DATA VL6180_RangeStatusErrString[] = {
charlesmn 0:1da5e4bcb8e5 78 "No Error",
charlesmn 0:1da5e4bcb8e5 79 "VCSEL Continuity Test",
charlesmn 0:1da5e4bcb8e5 80 "VCSEL Watchdog Test",
charlesmn 0:1da5e4bcb8e5 81 "VCSEL Watchdog",
charlesmn 0:1da5e4bcb8e5 82 "PLL1 Lock",
charlesmn 0:1da5e4bcb8e5 83 "PLL2 Lock",
charlesmn 0:1da5e4bcb8e5 84 "Early Convergence Estimate",
charlesmn 0:1da5e4bcb8e5 85 "Max Convergence",
charlesmn 0:1da5e4bcb8e5 86 "No Target Ignore",
charlesmn 0:1da5e4bcb8e5 87 "Not used 9",
charlesmn 0:1da5e4bcb8e5 88 "Not used 10",
charlesmn 0:1da5e4bcb8e5 89 "Max Signal To Noise Ratio",
charlesmn 0:1da5e4bcb8e5 90 "Raw Ranging Algo Underflow",
charlesmn 0:1da5e4bcb8e5 91 "Raw Ranging Algo Overflow",
charlesmn 0:1da5e4bcb8e5 92 "Ranging Algo Underflow",
charlesmn 0:1da5e4bcb8e5 93 "Ranging Algo Overflow",
charlesmn 0:1da5e4bcb8e5 94
charlesmn 0:1da5e4bcb8e5 95 "Filtered by post processing (WAF)",
charlesmn 0:1da5e4bcb8e5 96 "Ranging filtering (WAF) on-going",
charlesmn 0:1da5e4bcb8e5 97 "Data not ready",
charlesmn 0:1da5e4bcb8e5 98 };
charlesmn 0:1da5e4bcb8e5 99
charlesmn 0:1da5e4bcb8e5 100 const char *VL6180_RangeGetStatusErrString(uint8_t RangeErrCode)
charlesmn 0:1da5e4bcb8e5 101 {
charlesmn 0:1da5e4bcb8e5 102 if (RangeErrCode > sizeof(VL6180_RangeStatusErrString) / sizeof(VL6180_RangeStatusErrString[0]))
charlesmn 0:1da5e4bcb8e5 103 return NULL;
charlesmn 0:1da5e4bcb8e5 104 return VL6180_RangeStatusErrString[RangeErrCode];
charlesmn 0:1da5e4bcb8e5 105 }
charlesmn 0:1da5e4bcb8e5 106 #endif
charlesmn 0:1da5e4bcb8e5 107
charlesmn 0:1da5e4bcb8e5 108 #if VL6180_UPSCALE_SUPPORT == 1
charlesmn 0:1da5e4bcb8e5 109 #define _GetUpscale(dev, ...) 1
charlesmn 0:1da5e4bcb8e5 110 #define _SetUpscale(...) -1
charlesmn 0:1da5e4bcb8e5 111 #define DEF_UPSCALE 1
charlesmn 0:1da5e4bcb8e5 112 #elif VL6180_UPSCALE_SUPPORT == 2
charlesmn 0:1da5e4bcb8e5 113 #define _GetUpscale(dev, ...) 2
charlesmn 0:1da5e4bcb8e5 114 #define _SetUpscale(...)
charlesmn 0:1da5e4bcb8e5 115 #define DEF_UPSCALE 2
charlesmn 0:1da5e4bcb8e5 116 #elif VL6180_UPSCALE_SUPPORT == 3
charlesmn 0:1da5e4bcb8e5 117 #define _GetUpscale(dev, ...) 3
charlesmn 0:1da5e4bcb8e5 118 #define _SetUpscale(...)
charlesmn 0:1da5e4bcb8e5 119 #define DEF_UPSCALE 3
charlesmn 0:1da5e4bcb8e5 120 #else
charlesmn 0:1da5e4bcb8e5 121 #define DEF_UPSCALE (-(VL6180_UPSCALE_SUPPORT))
charlesmn 0:1da5e4bcb8e5 122 #define _GetUpscale(dev, ...) VL6180DevDataGet(dev, UpscaleFactor)
charlesmn 0:1da5e4bcb8e5 123 #define _SetUpscale(dev, Scaling) VL6180DevDataSet(dev, UpscaleFactor, Scaling)
charlesmn 0:1da5e4bcb8e5 124 #endif
charlesmn 0:1da5e4bcb8e5 125
charlesmn 0:1da5e4bcb8e5 126
charlesmn 0:1da5e4bcb8e5 127 #if VL6180_SINGLE_DEVICE_DRIVER
charlesmn 0:1da5e4bcb8e5 128 /**
charlesmn 0:1da5e4bcb8e5 129 * the unique driver data When single device driver is active
charlesmn 0:1da5e4bcb8e5 130 */
charlesmn 0:1da5e4bcb8e5 131 struct VL6180DevData_t VL6180_DEV_DATA_ATTR SingleVL6180DevData = {
charlesmn 0:1da5e4bcb8e5 132 .EceFactorM = DEF_ECE_FACTOR_M,
charlesmn 0:1da5e4bcb8e5 133 .EceFactorD = DEF_ECE_FACTOR_D,
charlesmn 0:1da5e4bcb8e5 134 #ifdef VL6180_HAVE_UPSCALE_DATA
charlesmn 0:1da5e4bcb8e5 135 .UpscaleFactor = DEF_UPSCALE,
charlesmn 0:1da5e4bcb8e5 136 #endif
charlesmn 0:1da5e4bcb8e5 137 #ifdef VL6180_HAVE_DMAX_RANGING
charlesmn 0:1da5e4bcb8e5 138 .DMaxEnable = DEF_DMAX_ENABLE,
charlesmn 0:1da5e4bcb8e5 139 #endif
charlesmn 0:1da5e4bcb8e5 140 };
charlesmn 0:1da5e4bcb8e5 141 #endif /* VL6180_SINGLE_DEVICE_DRIVER */
charlesmn 0:1da5e4bcb8e5 142
charlesmn 0:1da5e4bcb8e5 143
charlesmn 0:1da5e4bcb8e5 144
charlesmn 0:1da5e4bcb8e5 145 #define Fix7_2_KCPs(x) ((((uint32_t)(x))*1000)>>7)
charlesmn 0:1da5e4bcb8e5 146
charlesmn 0:1da5e4bcb8e5 147
charlesmn 0:1da5e4bcb8e5 148 #if VL6180_WRAP_AROUND_FILTER_SUPPORT || VL6180_HAVE_DMAX_RANGING
charlesmn 0:1da5e4bcb8e5 149 static int _GetRateResult(VL6180Dev_t dev, VL6180_RangeData_t *pRangeData);
charlesmn 0:1da5e4bcb8e5 150 #endif
charlesmn 0:1da5e4bcb8e5 151
charlesmn 0:1da5e4bcb8e5 152 #if VL6180_WRAP_AROUND_FILTER_SUPPORT
charlesmn 0:1da5e4bcb8e5 153 static int _filter_Init(VL6180Dev_t dev);
charlesmn 0:1da5e4bcb8e5 154 static int _filter_GetResult(VL6180Dev_t dev, VL6180_RangeData_t *pData);
charlesmn 0:1da5e4bcb8e5 155 #define _IsWrapArroundActive(dev) VL6180DevDataGet(dev, WrapAroundFilterActive)
charlesmn 0:1da5e4bcb8e5 156 #else
charlesmn 0:1da5e4bcb8e5 157 #define _IsWrapArroundActive(dev) 0
charlesmn 0:1da5e4bcb8e5 158 #endif
charlesmn 0:1da5e4bcb8e5 159
charlesmn 0:1da5e4bcb8e5 160
charlesmn 0:1da5e4bcb8e5 161 #if VL6180_HAVE_DMAX_RANGING
charlesmn 0:1da5e4bcb8e5 162 void _DMax_OneTimeInit(VL6180Dev_t dev);
charlesmn 0:1da5e4bcb8e5 163 static int _DMax_InitData(VL6180Dev_t dev);
charlesmn 0:1da5e4bcb8e5 164 static int _DMax_Compute(VL6180Dev_t dev, VL6180_RangeData_t *pRange);
charlesmn 0:1da5e4bcb8e5 165 #define _IsDMaxActive(dev) VL6180DevDataGet(dev, DMaxEnable)
charlesmn 0:1da5e4bcb8e5 166 #else
charlesmn 0:1da5e4bcb8e5 167 #define _DMax_InitData(...) 0 /* success */
charlesmn 0:1da5e4bcb8e5 168 #define _DMax_OneTimeInit(...) (void)0
charlesmn 0:1da5e4bcb8e5 169 #define _IsDMaxActive(...) 0
charlesmn 0:1da5e4bcb8e5 170 #endif
charlesmn 0:1da5e4bcb8e5 171
charlesmn 0:1da5e4bcb8e5 172 static int VL6180_RangeStaticInit(VL6180Dev_t dev);
charlesmn 0:1da5e4bcb8e5 173 static int VL6180_UpscaleStaticInit(VL6180Dev_t dev);
charlesmn 0:1da5e4bcb8e5 174
charlesmn 0:1da5e4bcb8e5 175 int VL6180_WaitDeviceBooted(VL6180Dev_t dev)
charlesmn 0:1da5e4bcb8e5 176 {
charlesmn 0:1da5e4bcb8e5 177 uint8_t FreshOutReset;
charlesmn 0:1da5e4bcb8e5 178 int status;
charlesmn 0:1da5e4bcb8e5 179 LOG_FUNCTION_START("");
charlesmn 0:1da5e4bcb8e5 180 do {
charlesmn 0:1da5e4bcb8e5 181 status = VL6180_RdByte(dev, SYSTEM_FRESH_OUT_OF_RESET, &FreshOutReset);
charlesmn 0:1da5e4bcb8e5 182 } while (FreshOutReset != 1 && status == 0);
charlesmn 0:1da5e4bcb8e5 183 LOG_FUNCTION_END(status);
charlesmn 0:1da5e4bcb8e5 184 return status;
charlesmn 0:1da5e4bcb8e5 185 }
charlesmn 0:1da5e4bcb8e5 186
charlesmn 0:1da5e4bcb8e5 187 int VL6180_InitData(VL6180Dev_t dev)
charlesmn 0:1da5e4bcb8e5 188 {
charlesmn 0:1da5e4bcb8e5 189 int status, dmax_status ;
charlesmn 0:1da5e4bcb8e5 190 int8_t offset;
charlesmn 0:1da5e4bcb8e5 191 uint8_t FreshOutReset;
charlesmn 0:1da5e4bcb8e5 192 uint32_t CalValue;
charlesmn 0:1da5e4bcb8e5 193 uint16_t u16;
charlesmn 0:1da5e4bcb8e5 194 uint32_t XTalkCompRate_KCps;
charlesmn 0:1da5e4bcb8e5 195
charlesmn 0:1da5e4bcb8e5 196 LOG_FUNCTION_START("");
charlesmn 0:1da5e4bcb8e5 197
charlesmn 0:1da5e4bcb8e5 198 VL6180DevDataSet(dev, EceFactorM, DEF_ECE_FACTOR_M);
charlesmn 0:1da5e4bcb8e5 199 VL6180DevDataSet(dev, EceFactorD, DEF_ECE_FACTOR_D);
charlesmn 0:1da5e4bcb8e5 200
charlesmn 0:1da5e4bcb8e5 201 VL6180DevDataSet(dev, RangeIgnore.Enabled, 0);
charlesmn 0:1da5e4bcb8e5 202
charlesmn 0:1da5e4bcb8e5 203 #ifdef VL6180_HAVE_UPSCALE_DATA
charlesmn 0:1da5e4bcb8e5 204 VL6180DevDataSet(dev, UpscaleFactor, DEF_UPSCALE);
charlesmn 0:1da5e4bcb8e5 205 #endif
charlesmn 0:1da5e4bcb8e5 206
charlesmn 0:1da5e4bcb8e5 207 #ifdef VL6180_HAVE_WRAP_AROUND_DATA
charlesmn 0:1da5e4bcb8e5 208 VL6180DevDataSet(dev, WrapAroundFilterActive, (VL6180_WRAP_AROUND_FILTER_SUPPORT > 0));
charlesmn 0:1da5e4bcb8e5 209 VL6180DevDataSet(dev, DMaxEnable, DEF_DMAX_ENABLE);
charlesmn 0:1da5e4bcb8e5 210 #endif
charlesmn 0:1da5e4bcb8e5 211
charlesmn 0:1da5e4bcb8e5 212 _DMax_OneTimeInit(dev);
charlesmn 0:1da5e4bcb8e5 213 do {
charlesmn 0:1da5e4bcb8e5 214
charlesmn 0:1da5e4bcb8e5 215 /* backup offset initial value from nvm these must be done prior any over call that use offset */
charlesmn 0:1da5e4bcb8e5 216 status = VL6180_RdByte(dev, SYSRANGE_PART_TO_PART_RANGE_OFFSET, (uint8_t *)&offset);
charlesmn 0:1da5e4bcb8e5 217 if (status) {
charlesmn 0:1da5e4bcb8e5 218 VL6180_ErrLog("SYSRANGE_PART_TO_PART_RANGE_OFFSET rd fail");
charlesmn 0:1da5e4bcb8e5 219 break;
charlesmn 0:1da5e4bcb8e5 220 }
charlesmn 0:1da5e4bcb8e5 221 VL6180DevDataSet(dev, Part2PartOffsetNVM, offset);
charlesmn 0:1da5e4bcb8e5 222
charlesmn 0:1da5e4bcb8e5 223 status = VL6180_RdDWord(dev, SYSRANGE_RANGE_IGNORE_THRESHOLD, &CalValue);
charlesmn 0:1da5e4bcb8e5 224 if (status) {
charlesmn 0:1da5e4bcb8e5 225 VL6180_ErrLog("Part2PartAmbNVM rd fail");
charlesmn 0:1da5e4bcb8e5 226 break;
charlesmn 0:1da5e4bcb8e5 227 }
charlesmn 0:1da5e4bcb8e5 228 if ((CalValue&0xFFFF0000) == 0) {
charlesmn 0:1da5e4bcb8e5 229 CalValue = 0x00CE03F8;
charlesmn 0:1da5e4bcb8e5 230 }
charlesmn 0:1da5e4bcb8e5 231 VL6180DevDataSet(dev, Part2PartAmbNVM, CalValue);
charlesmn 0:1da5e4bcb8e5 232
charlesmn 0:1da5e4bcb8e5 233 status = VL6180_RdWord(dev, SYSRANGE_CROSSTALK_COMPENSATION_RATE , &u16);
charlesmn 0:1da5e4bcb8e5 234 if (status) {
charlesmn 0:1da5e4bcb8e5 235 VL6180_ErrLog("SYSRANGE_CROSSTALK_COMPENSATION_RATE rd fail ");
charlesmn 0:1da5e4bcb8e5 236 break;
charlesmn 0:1da5e4bcb8e5 237 }
charlesmn 0:1da5e4bcb8e5 238 XTalkCompRate_KCps = Fix7_2_KCPs(u16);
charlesmn 0:1da5e4bcb8e5 239 VL6180DevDataSet(dev, XTalkCompRate_KCps, XTalkCompRate_KCps);
charlesmn 0:1da5e4bcb8e5 240
charlesmn 0:1da5e4bcb8e5 241 dmax_status = _DMax_InitData(dev);
charlesmn 0:1da5e4bcb8e5 242 if (dmax_status < 0) {
charlesmn 0:1da5e4bcb8e5 243 VL6180_ErrLog("DMax init failure");
charlesmn 0:1da5e4bcb8e5 244 break;
charlesmn 0:1da5e4bcb8e5 245 }
charlesmn 0:1da5e4bcb8e5 246
charlesmn 0:1da5e4bcb8e5 247 /* Read or wait for fresh out of reset */
charlesmn 0:1da5e4bcb8e5 248 status = VL6180_RdByte(dev, SYSTEM_FRESH_OUT_OF_RESET, &FreshOutReset);
charlesmn 0:1da5e4bcb8e5 249 if (status) {
charlesmn 0:1da5e4bcb8e5 250 VL6180_ErrLog("SYSTEM_FRESH_OUT_OF_RESET rd fail");
charlesmn 0:1da5e4bcb8e5 251 break;
charlesmn 0:1da5e4bcb8e5 252 }
charlesmn 0:1da5e4bcb8e5 253 if (FreshOutReset != 1 || dmax_status)
charlesmn 0:1da5e4bcb8e5 254 status = CALIBRATION_WARNING;
charlesmn 0:1da5e4bcb8e5 255
charlesmn 0:1da5e4bcb8e5 256 } while (0);
charlesmn 0:1da5e4bcb8e5 257
charlesmn 0:1da5e4bcb8e5 258 LOG_FUNCTION_END(status);
charlesmn 0:1da5e4bcb8e5 259 return status;
charlesmn 0:1da5e4bcb8e5 260 }
charlesmn 0:1da5e4bcb8e5 261
charlesmn 0:1da5e4bcb8e5 262 int8_t VL6180_GetOffsetCalibrationData(VL6180Dev_t dev)
charlesmn 0:1da5e4bcb8e5 263 {
charlesmn 0:1da5e4bcb8e5 264 int8_t offset;
charlesmn 0:1da5e4bcb8e5 265 LOG_FUNCTION_START("");
charlesmn 0:1da5e4bcb8e5 266 offset = VL6180DevDataGet(dev, Part2PartOffsetNVM);
charlesmn 0:1da5e4bcb8e5 267 LOG_FUNCTION_END(offset);
charlesmn 0:1da5e4bcb8e5 268 return offset;
charlesmn 0:1da5e4bcb8e5 269 }
charlesmn 0:1da5e4bcb8e5 270
charlesmn 0:1da5e4bcb8e5 271 int VL6180_SetOffsetCalibrationData(VL6180Dev_t dev, int8_t offset)
charlesmn 0:1da5e4bcb8e5 272 {
charlesmn 0:1da5e4bcb8e5 273 int status;
charlesmn 0:1da5e4bcb8e5 274 LOG_FUNCTION_START("%d", offset);
charlesmn 0:1da5e4bcb8e5 275 VL6180DevDataSet(dev, Part2PartOffsetNVM, offset);
charlesmn 0:1da5e4bcb8e5 276 offset /= _GetUpscale(dev);
charlesmn 0:1da5e4bcb8e5 277 status = VL6180_WrByte(dev, SYSRANGE_PART_TO_PART_RANGE_OFFSET, offset);
charlesmn 0:1da5e4bcb8e5 278 LOG_FUNCTION_END(status);
charlesmn 0:1da5e4bcb8e5 279 return status;
charlesmn 0:1da5e4bcb8e5 280 }
charlesmn 0:1da5e4bcb8e5 281
charlesmn 0:1da5e4bcb8e5 282 int VL6180_SetXTalkCompensationRate(VL6180Dev_t dev, FixPoint97_t Rate)
charlesmn 0:1da5e4bcb8e5 283 {
charlesmn 0:1da5e4bcb8e5 284 int status;
charlesmn 0:1da5e4bcb8e5 285 LOG_FUNCTION_START("%d", Rate);
charlesmn 0:1da5e4bcb8e5 286 status = VL6180_WrWord(dev, SYSRANGE_CROSSTALK_COMPENSATION_RATE, Rate);
charlesmn 0:1da5e4bcb8e5 287 if (status == 0) {
charlesmn 0:1da5e4bcb8e5 288 uint32_t XTalkCompRate_KCps;
charlesmn 0:1da5e4bcb8e5 289 XTalkCompRate_KCps = Fix7_2_KCPs(Rate);
charlesmn 0:1da5e4bcb8e5 290 VL6180DevDataSet(dev, XTalkCompRate_KCps, XTalkCompRate_KCps);
charlesmn 0:1da5e4bcb8e5 291 /* update dmax whenever xtalk rate changes */
charlesmn 0:1da5e4bcb8e5 292 status = _DMax_InitData(dev);
charlesmn 0:1da5e4bcb8e5 293 }
charlesmn 0:1da5e4bcb8e5 294 LOG_FUNCTION_END(status);
charlesmn 0:1da5e4bcb8e5 295 return status;
charlesmn 0:1da5e4bcb8e5 296 }
charlesmn 0:1da5e4bcb8e5 297
charlesmn 0:1da5e4bcb8e5 298 int VL6180_SetI2CAddress(VL6180Dev_t dev, uint8_t NewAddress)
charlesmn 0:1da5e4bcb8e5 299 {
charlesmn 0:1da5e4bcb8e5 300 int status;
charlesmn 0:1da5e4bcb8e5 301 LOG_FUNCTION_START("");
charlesmn 0:1da5e4bcb8e5 302
charlesmn 0:1da5e4bcb8e5 303 status = VL6180_WrByte(dev, I2C_SLAVE_DEVICE_ADDRESS, NewAddress / 2);
charlesmn 0:1da5e4bcb8e5 304 if (status) {
charlesmn 0:1da5e4bcb8e5 305 VL6180_ErrLog("new i2c addr Wr fail");
charlesmn 0:1da5e4bcb8e5 306 }
charlesmn 0:1da5e4bcb8e5 307 LOG_FUNCTION_END(status);
charlesmn 0:1da5e4bcb8e5 308 return status;
charlesmn 0:1da5e4bcb8e5 309 }
charlesmn 0:1da5e4bcb8e5 310
charlesmn 0:1da5e4bcb8e5 311 uint16_t VL6180_GetUpperLimit(VL6180Dev_t dev)
charlesmn 0:1da5e4bcb8e5 312 {
charlesmn 0:1da5e4bcb8e5 313 uint16_t limit;
charlesmn 0:1da5e4bcb8e5 314 int scaling;
charlesmn 0:1da5e4bcb8e5 315
charlesmn 0:1da5e4bcb8e5 316 LOG_FUNCTION_START("");
charlesmn 0:1da5e4bcb8e5 317
charlesmn 0:1da5e4bcb8e5 318 scaling = _GetUpscale(dev);
charlesmn 0:1da5e4bcb8e5 319 /* FIXME we do assume here _GetUpscale is valid if user call us prior to init we may overflow the LUT mem area */
charlesmn 0:1da5e4bcb8e5 320 limit = UpperLimitLookUP[scaling - 1];
charlesmn 0:1da5e4bcb8e5 321
charlesmn 0:1da5e4bcb8e5 322 LOG_FUNCTION_END((int)limit);
charlesmn 0:1da5e4bcb8e5 323 return limit;
charlesmn 0:1da5e4bcb8e5 324 }
charlesmn 0:1da5e4bcb8e5 325
charlesmn 0:1da5e4bcb8e5 326
charlesmn 0:1da5e4bcb8e5 327
charlesmn 0:1da5e4bcb8e5 328 int VL6180_StaticInit(VL6180Dev_t dev)
charlesmn 0:1da5e4bcb8e5 329 {
charlesmn 0:1da5e4bcb8e5 330 int status = 0, init_status;
charlesmn 0:1da5e4bcb8e5 331 LOG_FUNCTION_START("");
charlesmn 0:1da5e4bcb8e5 332
charlesmn 0:1da5e4bcb8e5 333 /* TODO doc When using configurable scaling but using 1x as start condition
charlesmn 0:1da5e4bcb8e5 334 * load tunning upscale or not ??? */
charlesmn 0:1da5e4bcb8e5 335 if (_GetUpscale(dev) == 1 && !(VL6180_UPSCALE_SUPPORT < 0))
charlesmn 0:1da5e4bcb8e5 336 {
charlesmn 0:1da5e4bcb8e5 337 init_status = VL6180_RangeStaticInit(dev);
charlesmn 0:1da5e4bcb8e5 338 }
charlesmn 0:1da5e4bcb8e5 339 else
charlesmn 0:1da5e4bcb8e5 340 {
charlesmn 0:1da5e4bcb8e5 341 init_status = VL6180_UpscaleStaticInit(dev);
charlesmn 0:1da5e4bcb8e5 342 }
charlesmn 0:1da5e4bcb8e5 343
charlesmn 0:1da5e4bcb8e5 344 if (init_status < 0) {
charlesmn 0:1da5e4bcb8e5 345 VL6180_ErrLog("StaticInit fail");
charlesmn 0:1da5e4bcb8e5 346 goto error;
charlesmn 0:1da5e4bcb8e5 347 } else if (init_status > 0) {
charlesmn 0:1da5e4bcb8e5 348 VL6180_ErrLog("StaticInit warning");
charlesmn 0:1da5e4bcb8e5 349 }
charlesmn 0:1da5e4bcb8e5 350
charlesmn 0:1da5e4bcb8e5 351 if (status < 0) {
charlesmn 0:1da5e4bcb8e5 352 VL6180_ErrLog("StaticInit fail");
charlesmn 0:1da5e4bcb8e5 353 }
charlesmn 0:1da5e4bcb8e5 354 if (!status && init_status) {
charlesmn 0:1da5e4bcb8e5 355 status = init_status;
charlesmn 0:1da5e4bcb8e5 356 }
charlesmn 0:1da5e4bcb8e5 357 error:
charlesmn 0:1da5e4bcb8e5 358 LOG_FUNCTION_END(status);
charlesmn 0:1da5e4bcb8e5 359 return status;
charlesmn 0:1da5e4bcb8e5 360 }
charlesmn 0:1da5e4bcb8e5 361
charlesmn 0:1da5e4bcb8e5 362
charlesmn 0:1da5e4bcb8e5 363 int VL6180_SetGroupParamHold(VL6180Dev_t dev, int Hold)
charlesmn 0:1da5e4bcb8e5 364 {
charlesmn 0:1da5e4bcb8e5 365 int status;
charlesmn 0:1da5e4bcb8e5 366 uint8_t value;
charlesmn 0:1da5e4bcb8e5 367
charlesmn 0:1da5e4bcb8e5 368 LOG_FUNCTION_START("%d", Hold);
charlesmn 0:1da5e4bcb8e5 369 if (Hold)
charlesmn 0:1da5e4bcb8e5 370 value = 1;
charlesmn 0:1da5e4bcb8e5 371 else
charlesmn 0:1da5e4bcb8e5 372 value = 0;
charlesmn 0:1da5e4bcb8e5 373 status = VL6180_WrByte(dev, SYSTEM_GROUPED_PARAMETER_HOLD, value);
charlesmn 0:1da5e4bcb8e5 374
charlesmn 0:1da5e4bcb8e5 375 LOG_FUNCTION_END(status);
charlesmn 0:1da5e4bcb8e5 376 return status;
charlesmn 0:1da5e4bcb8e5 377
charlesmn 0:1da5e4bcb8e5 378 }
charlesmn 0:1da5e4bcb8e5 379
charlesmn 0:1da5e4bcb8e5 380 int VL6180_Prepare(VL6180Dev_t dev)
charlesmn 0:1da5e4bcb8e5 381 {
charlesmn 0:1da5e4bcb8e5 382 int status;
charlesmn 0:1da5e4bcb8e5 383 LOG_FUNCTION_START("");
charlesmn 0:1da5e4bcb8e5 384
charlesmn 0:1da5e4bcb8e5 385 do {
charlesmn 0:1da5e4bcb8e5 386 status = VL6180_StaticInit(dev);
charlesmn 0:1da5e4bcb8e5 387 if (status < 0)
charlesmn 0:1da5e4bcb8e5 388 break;
charlesmn 0:1da5e4bcb8e5 389
charlesmn 0:1da5e4bcb8e5 390 /* set range InterruptMode to new sample */
charlesmn 0:1da5e4bcb8e5 391 status = VL6180_RangeConfigInterrupt(dev, CONFIG_GPIO_INTERRUPT_NEW_SAMPLE_READY);
charlesmn 0:1da5e4bcb8e5 392 if (status)
charlesmn 0:1da5e4bcb8e5 393 break;
charlesmn 0:1da5e4bcb8e5 394
charlesmn 0:1da5e4bcb8e5 395 /* set default threshold */
charlesmn 0:1da5e4bcb8e5 396 status = VL6180_RangeSetRawThresholds(dev, 10, 200);
charlesmn 0:1da5e4bcb8e5 397 if (status) {
charlesmn 0:1da5e4bcb8e5 398 VL6180_ErrLog("VL6180_RangeSetRawThresholds fail");
charlesmn 0:1da5e4bcb8e5 399 break;
charlesmn 0:1da5e4bcb8e5 400 }
charlesmn 0:1da5e4bcb8e5 401 #if VL6180_WRAP_AROUND_FILTER_SUPPORT
charlesmn 0:1da5e4bcb8e5 402 _filter_Init(dev);
charlesmn 0:1da5e4bcb8e5 403 #endif
charlesmn 0:1da5e4bcb8e5 404 /* make sure to reset any left previous condition that can hangs first poll */
charlesmn 0:1da5e4bcb8e5 405
charlesmn 0:1da5e4bcb8e5 406 status = VL6180_ClearAllInterrupt(dev);
charlesmn 0:1da5e4bcb8e5 407 } while (0);
charlesmn 0:1da5e4bcb8e5 408 LOG_FUNCTION_END(status);
charlesmn 0:1da5e4bcb8e5 409
charlesmn 0:1da5e4bcb8e5 410 return status;
charlesmn 0:1da5e4bcb8e5 411 }
charlesmn 0:1da5e4bcb8e5 412
charlesmn 0:1da5e4bcb8e5 413
charlesmn 0:1da5e4bcb8e5 414 int VL6180_RangePollMeasurement(VL6180Dev_t dev, VL6180_RangeData_t *pRangeData)
charlesmn 0:1da5e4bcb8e5 415 {
charlesmn 0:1da5e4bcb8e5 416 int status;
charlesmn 0:1da5e4bcb8e5 417 int ClrStatus;
charlesmn 0:1da5e4bcb8e5 418 IntrStatus_t IntStatus;
charlesmn 0:1da5e4bcb8e5 419
charlesmn 0:1da5e4bcb8e5 420 LOG_FUNCTION_START("");
charlesmn 0:1da5e4bcb8e5 421 /* start single range measurement */
charlesmn 0:1da5e4bcb8e5 422
charlesmn 0:1da5e4bcb8e5 423
charlesmn 0:1da5e4bcb8e5 424 #if VL6180_SAFE_POLLING_ENTER
charlesmn 0:1da5e4bcb8e5 425 /* if device get stopped with left interrupt uncleared , it is required to clear them now or poll for new condition will never occur*/
charlesmn 0:1da5e4bcb8e5 426 status = VL6180_RangeClearInterrupt(dev);
charlesmn 0:1da5e4bcb8e5 427 if (status) {
charlesmn 0:1da5e4bcb8e5 428 VL6180_ErrLog("VL6180_RangeClearInterrupt fail");
charlesmn 0:1da5e4bcb8e5 429 goto done;
charlesmn 0:1da5e4bcb8e5 430 }
charlesmn 0:1da5e4bcb8e5 431 #endif
charlesmn 0:1da5e4bcb8e5 432 /* //![single_shot_snipet] */
charlesmn 0:1da5e4bcb8e5 433 status = VL6180_RangeSetSystemMode(dev, MODE_START_STOP | MODE_SINGLESHOT);
charlesmn 0:1da5e4bcb8e5 434 if (status) {
charlesmn 0:1da5e4bcb8e5 435 VL6180_ErrLog("VL6180_RangeSetSystemMode fail");
charlesmn 0:1da5e4bcb8e5 436 goto done;
charlesmn 0:1da5e4bcb8e5 437 }
charlesmn 0:1da5e4bcb8e5 438
charlesmn 0:1da5e4bcb8e5 439
charlesmn 0:1da5e4bcb8e5 440 /* poll for new sample ready */
charlesmn 0:1da5e4bcb8e5 441 while (1) {
charlesmn 0:1da5e4bcb8e5 442 status = VL6180_RangeGetInterruptStatus(dev, &IntStatus.val);
charlesmn 0:1da5e4bcb8e5 443 if (status) {
charlesmn 0:1da5e4bcb8e5 444 break;
charlesmn 0:1da5e4bcb8e5 445 }
charlesmn 0:1da5e4bcb8e5 446 if (IntStatus.status.Range == RES_INT_STAT_GPIO_NEW_SAMPLE_READY || IntStatus.status.Error != 0) {
charlesmn 0:1da5e4bcb8e5 447 break;
charlesmn 0:1da5e4bcb8e5 448 }
charlesmn 0:1da5e4bcb8e5 449
charlesmn 0:1da5e4bcb8e5 450 VL6180_PollDelay(dev);
charlesmn 0:1da5e4bcb8e5 451 }
charlesmn 0:1da5e4bcb8e5 452 /* //![single_shot_snipet] */
charlesmn 0:1da5e4bcb8e5 453
charlesmn 0:1da5e4bcb8e5 454 if (!status) {
charlesmn 0:1da5e4bcb8e5 455 status = VL6180_RangeGetMeasurement(dev, pRangeData);
charlesmn 0:1da5e4bcb8e5 456 }
charlesmn 0:1da5e4bcb8e5 457
charlesmn 0:1da5e4bcb8e5 458 /* clear range interrupt source */
charlesmn 0:1da5e4bcb8e5 459 ClrStatus = VL6180_RangeClearInterrupt(dev);
charlesmn 0:1da5e4bcb8e5 460
charlesmn 0:1da5e4bcb8e5 461 if (ClrStatus) {
charlesmn 0:1da5e4bcb8e5 462 VL6180_ErrLog("VL6180_RangeClearInterrupt fail");
charlesmn 0:1da5e4bcb8e5 463 /* leave initial status if already in error */
charlesmn 0:1da5e4bcb8e5 464 if (!status) {
charlesmn 0:1da5e4bcb8e5 465 status = ClrStatus;
charlesmn 0:1da5e4bcb8e5 466 }
charlesmn 0:1da5e4bcb8e5 467 }
charlesmn 0:1da5e4bcb8e5 468 done:
charlesmn 0:1da5e4bcb8e5 469 VL6180_ErrLog("VL6180_RangeClearInterrupt end");
charlesmn 0:1da5e4bcb8e5 470 LOG_FUNCTION_END(status);
charlesmn 0:1da5e4bcb8e5 471 return status;
charlesmn 0:1da5e4bcb8e5 472 }
charlesmn 0:1da5e4bcb8e5 473
charlesmn 0:1da5e4bcb8e5 474
charlesmn 0:1da5e4bcb8e5 475 #if VL6180_CACHED_REG
charlesmn 0:1da5e4bcb8e5 476
charlesmn 0:1da5e4bcb8e5 477 int VL6180_GetCachedDWord(VL6180Dev_t dev, uint16_t index, uint32_t *pValue)
charlesmn 0:1da5e4bcb8e5 478 {
charlesmn 0:1da5e4bcb8e5 479 int status;
charlesmn 0:1da5e4bcb8e5 480 uint32_t Value;
charlesmn 0:1da5e4bcb8e5 481 if (VL6180DevDataGet(dev, CacheFilled) != 0 &&
charlesmn 0:1da5e4bcb8e5 482 index >= VL6180_FIRST_CACHED_INDEX &&
charlesmn 0:1da5e4bcb8e5 483 index <= (VL6180_LAST_CACHED_INDEX - 3)) {
charlesmn 0:1da5e4bcb8e5 484 uint8_t *pBytes = &VL6180DevDataGet(dev, CachedRegs[index - VL6180_FIRST_CACHED_INDEX]);
charlesmn 0:1da5e4bcb8e5 485 Value = ((uint32_t)pBytes[0] << 24) |
charlesmn 0:1da5e4bcb8e5 486 ((uint32_t)pBytes[1] << 16) |
charlesmn 0:1da5e4bcb8e5 487 ((uint32_t)pBytes[2] << 8) |
charlesmn 0:1da5e4bcb8e5 488 (uint32_t)pBytes[3];
charlesmn 0:1da5e4bcb8e5 489 *pValue = Value;
charlesmn 0:1da5e4bcb8e5 490 status = 0;
charlesmn 0:1da5e4bcb8e5 491 } else {
charlesmn 0:1da5e4bcb8e5 492 status = VL6180_RdDWord(dev, index, pValue);
charlesmn 0:1da5e4bcb8e5 493 }
charlesmn 0:1da5e4bcb8e5 494 return status;
charlesmn 0:1da5e4bcb8e5 495 }
charlesmn 0:1da5e4bcb8e5 496
charlesmn 0:1da5e4bcb8e5 497 int VL6180_GetCachedWord(VL6180Dev_t dev, uint16_t index, uint16_t *pValue)
charlesmn 0:1da5e4bcb8e5 498 {
charlesmn 0:1da5e4bcb8e5 499 int status;
charlesmn 0:1da5e4bcb8e5 500 uint32_t Value;
charlesmn 0:1da5e4bcb8e5 501 if (VL6180DevDataGet(dev, CacheFilled) != 0 &&
charlesmn 0:1da5e4bcb8e5 502 index >= VL6180_FIRST_CACHED_INDEX &&
charlesmn 0:1da5e4bcb8e5 503 index <= (VL6180_LAST_CACHED_INDEX - 1)) {
charlesmn 0:1da5e4bcb8e5 504 uint8_t *pBytes = &VL6180DevDataGet(dev, CachedRegs[index - VL6180_FIRST_CACHED_INDEX]);
charlesmn 0:1da5e4bcb8e5 505 Value = ((uint32_t)pBytes[0] << 8) | (uint32_t)pBytes[1];
charlesmn 0:1da5e4bcb8e5 506 *pValue = Value;
charlesmn 0:1da5e4bcb8e5 507 status = 0;
charlesmn 0:1da5e4bcb8e5 508 } else {
charlesmn 0:1da5e4bcb8e5 509 status = VL6180_RdWord(dev, index, pValue);
charlesmn 0:1da5e4bcb8e5 510 }
charlesmn 0:1da5e4bcb8e5 511 return status;
charlesmn 0:1da5e4bcb8e5 512 }
charlesmn 0:1da5e4bcb8e5 513
charlesmn 0:1da5e4bcb8e5 514 int VL6180_GetCachedByte(VL6180Dev_t dev, uint16_t index, uint8_t *pValue)
charlesmn 0:1da5e4bcb8e5 515 {
charlesmn 0:1da5e4bcb8e5 516 int status;
charlesmn 0:1da5e4bcb8e5 517 uint8_t Value;
charlesmn 0:1da5e4bcb8e5 518 if (VL6180DevDataGet(dev, CacheFilled) != 0 &&
charlesmn 0:1da5e4bcb8e5 519 index >= VL6180_FIRST_CACHED_INDEX &&
charlesmn 0:1da5e4bcb8e5 520 index <= VL6180_LAST_CACHED_INDEX) {
charlesmn 0:1da5e4bcb8e5 521 Value = VL6180DevDataGet(dev, CachedRegs[index - VL6180_FIRST_CACHED_INDEX]);
charlesmn 0:1da5e4bcb8e5 522 *pValue = Value;
charlesmn 0:1da5e4bcb8e5 523 status = 0;
charlesmn 0:1da5e4bcb8e5 524 } else {
charlesmn 0:1da5e4bcb8e5 525 status = VL6180_RdByte(dev, index, pValue);
charlesmn 0:1da5e4bcb8e5 526 }
charlesmn 0:1da5e4bcb8e5 527 return status;
charlesmn 0:1da5e4bcb8e5 528 }
charlesmn 0:1da5e4bcb8e5 529
charlesmn 0:1da5e4bcb8e5 530
charlesmn 0:1da5e4bcb8e5 531 int _CachedRegs_Fetch(VL6180Dev_t dev)
charlesmn 0:1da5e4bcb8e5 532 {
charlesmn 0:1da5e4bcb8e5 533 int status;
charlesmn 0:1da5e4bcb8e5 534 uint8_t *Buffer;
charlesmn 0:1da5e4bcb8e5 535 if (VL6180DevDataGet(dev, CacheFilled) == 0) {
charlesmn 0:1da5e4bcb8e5 536 VL6180DevDataSet(dev, CacheFilled, 1);
charlesmn 0:1da5e4bcb8e5 537 Buffer = &VL6180DevDataGet(dev, CachedRegs[0]);
charlesmn 0:1da5e4bcb8e5 538 status = VL6180_RdMulti(dev, VL6180_FIRST_CACHED_INDEX, Buffer, VL6180_CACHED_REG_CNT);
charlesmn 0:1da5e4bcb8e5 539 } else {
charlesmn 0:1da5e4bcb8e5 540 status = 0 ;
charlesmn 0:1da5e4bcb8e5 541 }
charlesmn 0:1da5e4bcb8e5 542 return status;
charlesmn 0:1da5e4bcb8e5 543 }
charlesmn 0:1da5e4bcb8e5 544
charlesmn 0:1da5e4bcb8e5 545 void _CachedRegs_Flush(VL6180Dev_t dev)
charlesmn 0:1da5e4bcb8e5 546 {
charlesmn 0:1da5e4bcb8e5 547 VL6180DevDataSet(dev, CacheFilled, 0);
charlesmn 0:1da5e4bcb8e5 548 }
charlesmn 0:1da5e4bcb8e5 549
charlesmn 0:1da5e4bcb8e5 550 #else
charlesmn 0:1da5e4bcb8e5 551 # define _CachedRegs_Fetch(...) 0
charlesmn 0:1da5e4bcb8e5 552 # define _CachedRegs_Flush(...) (void)0
charlesmn 0:1da5e4bcb8e5 553 # define _Fetch_CachedRegs(...) 0
charlesmn 0:1da5e4bcb8e5 554 # define VL6180_GetCachedByte(dev, index, pValue) VL6180_RdByte(dev, index, pValue)
charlesmn 0:1da5e4bcb8e5 555 # define VL6180_GetCachedWord(dev, index, pValue) VL6180_RdWord(dev, index, pValue)
charlesmn 0:1da5e4bcb8e5 556 # define VL6180_GetCachedDWord(dev, index, pValue) VL6180_RdDWord(dev, index, pValue)
charlesmn 0:1da5e4bcb8e5 557 #endif /* VL6180_CACHED_REG */
charlesmn 0:1da5e4bcb8e5 558
charlesmn 0:1da5e4bcb8e5 559
charlesmn 0:1da5e4bcb8e5 560
charlesmn 0:1da5e4bcb8e5 561 int VL6180_RangeGetMeasurement(VL6180Dev_t dev, VL6180_RangeData_t *pRangeData)
charlesmn 0:1da5e4bcb8e5 562 {
charlesmn 0:1da5e4bcb8e5 563 int status;
charlesmn 0:1da5e4bcb8e5 564 uint16_t RawRate;
charlesmn 0:1da5e4bcb8e5 565 uint8_t RawStatus;
charlesmn 0:1da5e4bcb8e5 566
charlesmn 0:1da5e4bcb8e5 567 LOG_FUNCTION_START("");
charlesmn 0:1da5e4bcb8e5 568
charlesmn 0:1da5e4bcb8e5 569 status = _CachedRegs_Fetch(dev);
charlesmn 0:1da5e4bcb8e5 570 if (status) {
charlesmn 0:1da5e4bcb8e5 571 VL6180_ErrLog("Cache register read fail");
charlesmn 0:1da5e4bcb8e5 572 goto error;
charlesmn 0:1da5e4bcb8e5 573 }
charlesmn 0:1da5e4bcb8e5 574 status = VL6180_RangeGetResult(dev, &pRangeData->range_mm);
charlesmn 0:1da5e4bcb8e5 575 if (!status) {
charlesmn 0:1da5e4bcb8e5 576 status = VL6180_GetCachedWord(dev, RESULT_RANGE_SIGNAL_RATE, &RawRate);
charlesmn 0:1da5e4bcb8e5 577 if (!status) {
charlesmn 0:1da5e4bcb8e5 578 pRangeData->signalRate_mcps = VL6180_9to7Conv(RawRate);
charlesmn 0:1da5e4bcb8e5 579 status = VL6180_GetCachedByte(dev, RESULT_RANGE_STATUS, &RawStatus);
charlesmn 0:1da5e4bcb8e5 580 if (!status) {
charlesmn 0:1da5e4bcb8e5 581 pRangeData->errorStatus = RawStatus >> 4;
charlesmn 0:1da5e4bcb8e5 582 } else {
charlesmn 0:1da5e4bcb8e5 583 VL6180_ErrLog("Rd RESULT_RANGE_STATUS fail");
charlesmn 0:1da5e4bcb8e5 584 }
charlesmn 0:1da5e4bcb8e5 585 #if VL6180_WRAP_AROUND_FILTER_SUPPORT || VL6180_HAVE_DMAX_RANGING
charlesmn 0:1da5e4bcb8e5 586 status = _GetRateResult(dev, pRangeData);
charlesmn 0:1da5e4bcb8e5 587 if (status)
charlesmn 0:1da5e4bcb8e5 588 goto error;
charlesmn 0:1da5e4bcb8e5 589 #endif
charlesmn 0:1da5e4bcb8e5 590 #if VL6180_WRAP_AROUND_FILTER_SUPPORT
charlesmn 0:1da5e4bcb8e5 591 /* if enabled run filter */
charlesmn 0:1da5e4bcb8e5 592 if (_IsWrapArroundActive(dev)) {
charlesmn 0:1da5e4bcb8e5 593 status = _filter_GetResult(dev, pRangeData);
charlesmn 0:1da5e4bcb8e5 594 if (!status) {
charlesmn 0:1da5e4bcb8e5 595 /* patch the range status and measure if it is filtered */
charlesmn 0:1da5e4bcb8e5 596 if(pRangeData->FilteredData.filterError != NoError) {
charlesmn 0:1da5e4bcb8e5 597 pRangeData->errorStatus = pRangeData->FilteredData.filterError;
charlesmn 0:1da5e4bcb8e5 598 pRangeData->range_mm = pRangeData->FilteredData.range_mm;
charlesmn 0:1da5e4bcb8e5 599 }
charlesmn 0:1da5e4bcb8e5 600 }
charlesmn 0:1da5e4bcb8e5 601 }
charlesmn 0:1da5e4bcb8e5 602 #endif
charlesmn 0:1da5e4bcb8e5 603
charlesmn 0:1da5e4bcb8e5 604 #if VL6180_HAVE_DMAX_RANGING
charlesmn 0:1da5e4bcb8e5 605 if (_IsDMaxActive(dev)) {
charlesmn 0:1da5e4bcb8e5 606 _DMax_Compute(dev, pRangeData);
charlesmn 0:1da5e4bcb8e5 607 }
charlesmn 0:1da5e4bcb8e5 608 #endif
charlesmn 0:1da5e4bcb8e5 609 } else {
charlesmn 0:1da5e4bcb8e5 610 VL6180_ErrLog("Rd RESULT_RANGE_SIGNAL_RATE fail");
charlesmn 0:1da5e4bcb8e5 611 }
charlesmn 0:1da5e4bcb8e5 612 } else {
charlesmn 0:1da5e4bcb8e5 613 VL6180_ErrLog("VL6180_GetRangeResult fail");
charlesmn 0:1da5e4bcb8e5 614 }
charlesmn 0:1da5e4bcb8e5 615 error:
charlesmn 0:1da5e4bcb8e5 616 _CachedRegs_Flush(dev);
charlesmn 0:1da5e4bcb8e5 617 LOG_FUNCTION_END_FMT(status, "%d %d %d", (int)pRangeData->range_mm, (int)pRangeData->signalRate_mcps, (int)pRangeData->errorStatus) ;
charlesmn 0:1da5e4bcb8e5 618 return status;
charlesmn 0:1da5e4bcb8e5 619 }
charlesmn 0:1da5e4bcb8e5 620
charlesmn 0:1da5e4bcb8e5 621
charlesmn 0:1da5e4bcb8e5 622 int VL6180_RangeGetMeasurementIfReady(VL6180Dev_t dev, VL6180_RangeData_t *pRangeData)
charlesmn 0:1da5e4bcb8e5 623 {
charlesmn 0:1da5e4bcb8e5 624 int status;
charlesmn 0:1da5e4bcb8e5 625 IntrStatus_t IntStatus;
charlesmn 0:1da5e4bcb8e5 626
charlesmn 0:1da5e4bcb8e5 627 LOG_FUNCTION_START();
charlesmn 0:1da5e4bcb8e5 628 status = VL6180_RangeGetInterruptStatus(dev, &IntStatus.val);
charlesmn 0:1da5e4bcb8e5 629 if (status == 0) {
charlesmn 0:1da5e4bcb8e5 630 if (IntStatus.status.Range == RES_INT_STAT_GPIO_NEW_SAMPLE_READY ||
charlesmn 0:1da5e4bcb8e5 631 IntStatus.status.Error != 0) {
charlesmn 0:1da5e4bcb8e5 632 status = VL6180_RangeGetMeasurement(dev, pRangeData);
charlesmn 0:1da5e4bcb8e5 633 if (status == 0) {
charlesmn 0:1da5e4bcb8e5 634 /* clear range interrupt source */
charlesmn 0:1da5e4bcb8e5 635 status = VL6180_RangeClearInterrupt(dev);
charlesmn 0:1da5e4bcb8e5 636 if (status) {
charlesmn 0:1da5e4bcb8e5 637 VL6180_ErrLog("VL6180_RangeClearInterrupt fail");
charlesmn 0:1da5e4bcb8e5 638 }
charlesmn 0:1da5e4bcb8e5 639 }
charlesmn 0:1da5e4bcb8e5 640 } else {
charlesmn 0:1da5e4bcb8e5 641 pRangeData->errorStatus = DataNotReady;
charlesmn 0:1da5e4bcb8e5 642 }
charlesmn 0:1da5e4bcb8e5 643 } else {
charlesmn 0:1da5e4bcb8e5 644 VL6180_ErrLog("fail to get interrupt status");
charlesmn 0:1da5e4bcb8e5 645 }
charlesmn 0:1da5e4bcb8e5 646 LOG_FUNCTION_END(status) ;
charlesmn 0:1da5e4bcb8e5 647 return status;
charlesmn 0:1da5e4bcb8e5 648 }
charlesmn 0:1da5e4bcb8e5 649
charlesmn 0:1da5e4bcb8e5 650 int VL6180_FilterSetState(VL6180Dev_t dev, int state)
charlesmn 0:1da5e4bcb8e5 651 {
charlesmn 0:1da5e4bcb8e5 652 int status;
charlesmn 0:1da5e4bcb8e5 653 LOG_FUNCTION_START("%d", state);
charlesmn 0:1da5e4bcb8e5 654 #if VL6180_WRAP_AROUND_FILTER_SUPPORT
charlesmn 0:1da5e4bcb8e5 655 VL6180DevDataSet(dev, WrapAroundFilterActive, state);
charlesmn 0:1da5e4bcb8e5 656 status = 0;
charlesmn 0:1da5e4bcb8e5 657 #else
charlesmn 0:1da5e4bcb8e5 658 status = NOT_SUPPORTED;
charlesmn 0:1da5e4bcb8e5 659 #endif
charlesmn 0:1da5e4bcb8e5 660 LOG_FUNCTION_END(status);
charlesmn 0:1da5e4bcb8e5 661 return status;
charlesmn 0:1da5e4bcb8e5 662 }
charlesmn 0:1da5e4bcb8e5 663
charlesmn 0:1da5e4bcb8e5 664 int VL6180_FilterGetState(VL6180Dev_t dev)
charlesmn 0:1da5e4bcb8e5 665 {
charlesmn 0:1da5e4bcb8e5 666 int status;
charlesmn 0:1da5e4bcb8e5 667 LOG_FUNCTION_START("");
charlesmn 0:1da5e4bcb8e5 668 #if VL6180_WRAP_AROUND_FILTER_SUPPORT
charlesmn 0:1da5e4bcb8e5 669 status = VL6180DevDataGet(dev, WrapAroundFilterActive);
charlesmn 0:1da5e4bcb8e5 670 #else
charlesmn 0:1da5e4bcb8e5 671 status = 0;
charlesmn 0:1da5e4bcb8e5 672 #endif
charlesmn 0:1da5e4bcb8e5 673 LOG_FUNCTION_END(status);
charlesmn 0:1da5e4bcb8e5 674 return status;
charlesmn 0:1da5e4bcb8e5 675 }
charlesmn 0:1da5e4bcb8e5 676
charlesmn 0:1da5e4bcb8e5 677 int VL6180_RangeGetResult(VL6180Dev_t dev, int32_t *pRange_mm)
charlesmn 0:1da5e4bcb8e5 678 {
charlesmn 0:1da5e4bcb8e5 679 int status;
charlesmn 0:1da5e4bcb8e5 680 uint8_t RawRange;
charlesmn 0:1da5e4bcb8e5 681 int32_t Upscale;
charlesmn 0:1da5e4bcb8e5 682
charlesmn 0:1da5e4bcb8e5 683 LOG_FUNCTION_START("%p", pRange_mm);
charlesmn 0:1da5e4bcb8e5 684
charlesmn 0:1da5e4bcb8e5 685 status = VL6180_GetCachedByte(dev, RESULT_RANGE_VAL, &RawRange);
charlesmn 0:1da5e4bcb8e5 686 if (!status) {
charlesmn 0:1da5e4bcb8e5 687 Upscale = _GetUpscale(dev);
charlesmn 0:1da5e4bcb8e5 688 *pRange_mm = Upscale * (int32_t)RawRange;
charlesmn 0:1da5e4bcb8e5 689 }
charlesmn 0:1da5e4bcb8e5 690 LOG_FUNCTION_END_FMT(status, "%d", (int)*pRange_mm);
charlesmn 0:1da5e4bcb8e5 691 return status;
charlesmn 0:1da5e4bcb8e5 692 }
charlesmn 0:1da5e4bcb8e5 693
charlesmn 0:1da5e4bcb8e5 694 int VL6180_RangeSetRawThresholds(VL6180Dev_t dev, uint8_t low, uint8_t high)
charlesmn 0:1da5e4bcb8e5 695 {
charlesmn 0:1da5e4bcb8e5 696 int status;
charlesmn 0:1da5e4bcb8e5 697 LOG_FUNCTION_START("%d %d", (int) low, (int)high);
charlesmn 0:1da5e4bcb8e5 698 /* TODO we can optimize here grouping high/low in a word but that's cpu endianness dependent */
charlesmn 0:1da5e4bcb8e5 699 status = VL6180_WrByte(dev, SYSRANGE_THRESH_HIGH, high);
charlesmn 0:1da5e4bcb8e5 700 if (!status) {
charlesmn 0:1da5e4bcb8e5 701 status = VL6180_WrByte(dev, SYSRANGE_THRESH_LOW, low);
charlesmn 0:1da5e4bcb8e5 702 }
charlesmn 0:1da5e4bcb8e5 703
charlesmn 0:1da5e4bcb8e5 704 LOG_FUNCTION_END(status);
charlesmn 0:1da5e4bcb8e5 705 return status;
charlesmn 0:1da5e4bcb8e5 706 }
charlesmn 0:1da5e4bcb8e5 707
charlesmn 0:1da5e4bcb8e5 708 int VL6180_RangeSetThresholds(VL6180Dev_t dev, uint16_t low, uint16_t high, int UseSafeParamHold)
charlesmn 0:1da5e4bcb8e5 709 {
charlesmn 0:1da5e4bcb8e5 710 int status;
charlesmn 0:1da5e4bcb8e5 711 int scale;
charlesmn 0:1da5e4bcb8e5 712 LOG_FUNCTION_START("%d %d", (int) low, (int)high);
charlesmn 0:1da5e4bcb8e5 713 scale = _GetUpscale(dev, UpscaleFactor);
charlesmn 0:1da5e4bcb8e5 714 if (low > scale * 255 || high > scale * 255) {
charlesmn 0:1da5e4bcb8e5 715 status = INVALID_PARAMS;
charlesmn 0:1da5e4bcb8e5 716 } else {
charlesmn 0:1da5e4bcb8e5 717 do {
charlesmn 0:1da5e4bcb8e5 718 if (UseSafeParamHold) {
charlesmn 0:1da5e4bcb8e5 719 status = VL6180_SetGroupParamHold(dev, 1);
charlesmn 0:1da5e4bcb8e5 720 if (status)
charlesmn 0:1da5e4bcb8e5 721 break;
charlesmn 0:1da5e4bcb8e5 722 }
charlesmn 0:1da5e4bcb8e5 723 status = VL6180_RangeSetRawThresholds(dev, (uint8_t)(low / scale), (uint8_t)(high / scale));
charlesmn 0:1da5e4bcb8e5 724 if (status) {
charlesmn 0:1da5e4bcb8e5 725 VL6180_ErrLog("VL6180_RangeSetRawThresholds fail");
charlesmn 0:1da5e4bcb8e5 726 }
charlesmn 0:1da5e4bcb8e5 727 if (UseSafeParamHold) {
charlesmn 0:1da5e4bcb8e5 728 int HoldStatus;
charlesmn 0:1da5e4bcb8e5 729 /* tryt to unset param hold vene if previous fail */
charlesmn 0:1da5e4bcb8e5 730 HoldStatus = VL6180_SetGroupParamHold(dev, 0);
charlesmn 0:1da5e4bcb8e5 731 if (!status)
charlesmn 0:1da5e4bcb8e5 732 status = HoldStatus;
charlesmn 0:1da5e4bcb8e5 733 }
charlesmn 0:1da5e4bcb8e5 734 } while (0);
charlesmn 0:1da5e4bcb8e5 735 }
charlesmn 0:1da5e4bcb8e5 736
charlesmn 0:1da5e4bcb8e5 737 LOG_FUNCTION_END(status);
charlesmn 0:1da5e4bcb8e5 738 return status;
charlesmn 0:1da5e4bcb8e5 739 }
charlesmn 0:1da5e4bcb8e5 740
charlesmn 0:1da5e4bcb8e5 741
charlesmn 0:1da5e4bcb8e5 742 int VL6180_RangeGetThresholds(VL6180Dev_t dev, uint16_t *low, uint16_t *high)
charlesmn 0:1da5e4bcb8e5 743 {
charlesmn 0:1da5e4bcb8e5 744 int status = 0;
charlesmn 0:1da5e4bcb8e5 745 uint8_t RawLow, RawHigh;
charlesmn 0:1da5e4bcb8e5 746 int scale;
charlesmn 0:1da5e4bcb8e5 747
charlesmn 0:1da5e4bcb8e5 748 LOG_FUNCTION_START("%p %p", low , high);
charlesmn 0:1da5e4bcb8e5 749
charlesmn 0:1da5e4bcb8e5 750 scale = _GetUpscale(dev, UpscaleFactor);
charlesmn 0:1da5e4bcb8e5 751 do {
charlesmn 0:1da5e4bcb8e5 752 if (high != NULL) {
charlesmn 0:1da5e4bcb8e5 753 status = VL6180_RdByte(dev, SYSRANGE_THRESH_HIGH, &RawHigh);
charlesmn 0:1da5e4bcb8e5 754 if (status) {
charlesmn 0:1da5e4bcb8e5 755 VL6180_ErrLog("rd SYSRANGE_THRESH_HIGH fail");
charlesmn 0:1da5e4bcb8e5 756 break;
charlesmn 0:1da5e4bcb8e5 757 }
charlesmn 0:1da5e4bcb8e5 758 *high = (uint16_t)RawHigh * scale;
charlesmn 0:1da5e4bcb8e5 759 }
charlesmn 0:1da5e4bcb8e5 760 if (low != NULL) {
charlesmn 0:1da5e4bcb8e5 761 status = VL6180_RdByte(dev, SYSRANGE_THRESH_LOW, &RawLow);
charlesmn 0:1da5e4bcb8e5 762 if (status) {
charlesmn 0:1da5e4bcb8e5 763 VL6180_ErrLog("rd SYSRANGE_THRESH_LOW fail");
charlesmn 0:1da5e4bcb8e5 764 break;
charlesmn 0:1da5e4bcb8e5 765 }
charlesmn 0:1da5e4bcb8e5 766 *low = (uint16_t)RawLow * scale;
charlesmn 0:1da5e4bcb8e5 767 }
charlesmn 0:1da5e4bcb8e5 768 } while (0);
charlesmn 0:1da5e4bcb8e5 769 LOG_FUNCTION_END_FMT(status, "%d %d", (int)*low , (int)*high);
charlesmn 0:1da5e4bcb8e5 770 return status;
charlesmn 0:1da5e4bcb8e5 771 }
charlesmn 0:1da5e4bcb8e5 772
charlesmn 0:1da5e4bcb8e5 773
charlesmn 0:1da5e4bcb8e5 774 int VL6180_RangeGetInterruptStatus(VL6180Dev_t dev, uint8_t *pIntStatus)
charlesmn 0:1da5e4bcb8e5 775 {
charlesmn 0:1da5e4bcb8e5 776 int status;
charlesmn 0:1da5e4bcb8e5 777 uint8_t IntStatus;
charlesmn 0:1da5e4bcb8e5 778 LOG_FUNCTION_START("%p", pIntStatus);
charlesmn 0:1da5e4bcb8e5 779 /* FIXME we are grouping "error" with over status the user must check implicitly for it
charlesmn 0:1da5e4bcb8e5 780 * not just new sample or over status , that will nevr show up in case of error*/
charlesmn 0:1da5e4bcb8e5 781 status = VL6180_GetCachedByte(dev, RESULT_INTERRUPT_STATUS_GPIO, &IntStatus);
charlesmn 0:1da5e4bcb8e5 782 *pIntStatus = IntStatus & 0xC7;
charlesmn 0:1da5e4bcb8e5 783
charlesmn 0:1da5e4bcb8e5 784 LOG_FUNCTION_END_FMT(status, "%d", (int)*pIntStatus);
charlesmn 0:1da5e4bcb8e5 785 return status;
charlesmn 0:1da5e4bcb8e5 786 }
charlesmn 0:1da5e4bcb8e5 787
charlesmn 0:1da5e4bcb8e5 788
charlesmn 0:1da5e4bcb8e5 789 int VL6180_GetInterruptStatus(VL6180Dev_t dev, uint8_t *IntStatus)
charlesmn 0:1da5e4bcb8e5 790 {
charlesmn 0:1da5e4bcb8e5 791 int status;
charlesmn 0:1da5e4bcb8e5 792 LOG_FUNCTION_START("%p" , IntStatus);
charlesmn 0:1da5e4bcb8e5 793 status = VL6180_RdByte(dev, RESULT_INTERRUPT_STATUS_GPIO, IntStatus);
charlesmn 0:1da5e4bcb8e5 794 LOG_FUNCTION_END_FMT(status, "%d", (int)*IntStatus);
charlesmn 0:1da5e4bcb8e5 795 return status;
charlesmn 0:1da5e4bcb8e5 796 }
charlesmn 0:1da5e4bcb8e5 797
charlesmn 0:1da5e4bcb8e5 798 int VL6180_ClearInterrupt(VL6180Dev_t dev, uint8_t IntClear)
charlesmn 0:1da5e4bcb8e5 799 {
charlesmn 0:1da5e4bcb8e5 800 int status;
charlesmn 0:1da5e4bcb8e5 801 LOG_FUNCTION_START("%d", (int)IntClear);
charlesmn 0:1da5e4bcb8e5 802 if (IntClear <= 7) {
charlesmn 0:1da5e4bcb8e5 803 status = VL6180_WrByte(dev, SYSTEM_INTERRUPT_CLEAR, IntClear);
charlesmn 0:1da5e4bcb8e5 804 } else {
charlesmn 0:1da5e4bcb8e5 805 status = INVALID_PARAMS;
charlesmn 0:1da5e4bcb8e5 806 }
charlesmn 0:1da5e4bcb8e5 807 LOG_FUNCTION_END(status);
charlesmn 0:1da5e4bcb8e5 808 return status;
charlesmn 0:1da5e4bcb8e5 809 }
charlesmn 0:1da5e4bcb8e5 810
charlesmn 0:1da5e4bcb8e5 811
charlesmn 0:1da5e4bcb8e5 812 static int VL6180_RangeStaticInit(VL6180Dev_t dev)
charlesmn 0:1da5e4bcb8e5 813 {
charlesmn 0:1da5e4bcb8e5 814 int status;
charlesmn 0:1da5e4bcb8e5 815 LOG_FUNCTION_START("");
charlesmn 0:1da5e4bcb8e5 816 printf("VL6180_RangeStaticInit start \n");
charlesmn 0:1da5e4bcb8e5 817 /* REGISTER_TUNING_SR03_270514_CustomerView.txt */
charlesmn 0:1da5e4bcb8e5 818 VL6180_WrByte(dev, 0x0207, 0x01);
charlesmn 0:1da5e4bcb8e5 819 VL6180_WrByte(dev, 0x0208, 0x01);
charlesmn 0:1da5e4bcb8e5 820 VL6180_WrByte(dev, 0x0096, 0x00);
charlesmn 0:1da5e4bcb8e5 821 VL6180_WrByte(dev, 0x0097, 0xfd);
charlesmn 0:1da5e4bcb8e5 822 VL6180_WrByte(dev, 0x00e3, 0x00);
charlesmn 0:1da5e4bcb8e5 823 VL6180_WrByte(dev, 0x00e4, 0x04);
charlesmn 0:1da5e4bcb8e5 824 VL6180_WrByte(dev, 0x00e5, 0x02);
charlesmn 0:1da5e4bcb8e5 825 VL6180_WrByte(dev, 0x00e6, 0x01);
charlesmn 0:1da5e4bcb8e5 826 VL6180_WrByte(dev, 0x00e7, 0x03);
charlesmn 0:1da5e4bcb8e5 827 VL6180_WrByte(dev, 0x00f5, 0x02);
charlesmn 0:1da5e4bcb8e5 828 VL6180_WrByte(dev, 0x00d9, 0x05);
charlesmn 0:1da5e4bcb8e5 829 VL6180_WrByte(dev, 0x00db, 0xce);
charlesmn 0:1da5e4bcb8e5 830 VL6180_WrByte(dev, 0x00dc, 0x03);
charlesmn 0:1da5e4bcb8e5 831 VL6180_WrByte(dev, 0x00dd, 0xf8);
charlesmn 0:1da5e4bcb8e5 832 VL6180_WrByte(dev, 0x009f, 0x00);
charlesmn 0:1da5e4bcb8e5 833 VL6180_WrByte(dev, 0x00a3, 0x3c);
charlesmn 0:1da5e4bcb8e5 834 VL6180_WrByte(dev, 0x00b7, 0x00);
charlesmn 0:1da5e4bcb8e5 835 VL6180_WrByte(dev, 0x00bb, 0x3c);
charlesmn 0:1da5e4bcb8e5 836 VL6180_WrByte(dev, 0x00b2, 0x09);
charlesmn 0:1da5e4bcb8e5 837 VL6180_WrByte(dev, 0x00ca, 0x09);
charlesmn 0:1da5e4bcb8e5 838 VL6180_WrByte(dev, 0x0198, 0x01);
charlesmn 0:1da5e4bcb8e5 839 VL6180_WrByte(dev, 0x01b0, 0x17);
charlesmn 0:1da5e4bcb8e5 840 VL6180_WrByte(dev, 0x01ad, 0x00);
charlesmn 0:1da5e4bcb8e5 841 VL6180_WrByte(dev, 0x00ff, 0x05);
charlesmn 0:1da5e4bcb8e5 842 VL6180_WrByte(dev, 0x0100, 0x05);
charlesmn 0:1da5e4bcb8e5 843 VL6180_WrByte(dev, 0x0199, 0x05);
charlesmn 0:1da5e4bcb8e5 844 VL6180_WrByte(dev, 0x01a6, 0x1b);
charlesmn 0:1da5e4bcb8e5 845 VL6180_WrByte(dev, 0x01ac, 0x3e);
charlesmn 0:1da5e4bcb8e5 846 VL6180_WrByte(dev, 0x01a7, 0x1f);
charlesmn 0:1da5e4bcb8e5 847 VL6180_WrByte(dev, 0x0030, 0x00);
charlesmn 0:1da5e4bcb8e5 848
charlesmn 0:1da5e4bcb8e5 849 /* Recommended : Public registers - See data sheet for more detail */
charlesmn 0:1da5e4bcb8e5 850 VL6180_WrByte(dev, 0x0011, 0x10); /* Enables polling for New Sample ready when measurement completes */
charlesmn 0:1da5e4bcb8e5 851 VL6180_WrByte(dev, 0x010a, 0x30); /* Set the averaging sample period (compromise between lower noise and increased execution time) */
charlesmn 0:1da5e4bcb8e5 852 VL6180_WrByte(dev, 0x003f, 0x46); /* Sets the light and dark gain (upper nibble). Dark gain should not be changed.*/
charlesmn 0:1da5e4bcb8e5 853 VL6180_WrByte(dev, 0x0031, 0xFF); /* sets the # of range measurements after which auto calibration of system is performed */
charlesmn 0:1da5e4bcb8e5 854 VL6180_WrByte(dev, 0x002e, 0x01); /* perform a single temperature calibration of the ranging sensor */
charlesmn 0:1da5e4bcb8e5 855
charlesmn 0:1da5e4bcb8e5 856 /* Optional: Public registers - See data sheet for more detail */
charlesmn 0:1da5e4bcb8e5 857 VL6180_WrByte(dev, 0x001b, 0x09); /* Set default ranging inter-measurement period to 100ms */
charlesmn 0:1da5e4bcb8e5 858 VL6180_WrByte(dev, 0x0014, 0x24); /* Configures interrupt on New sample ready */
charlesmn 0:1da5e4bcb8e5 859
charlesmn 0:1da5e4bcb8e5 860 printf("VL6180_RangeSetMaxConvergenceTime \n");
charlesmn 0:1da5e4bcb8e5 861 status = VL6180_RangeSetMaxConvergenceTime(dev, 50); /* Calculate ece value on initialization (use max conv) */
charlesmn 0:1da5e4bcb8e5 862 LOG_FUNCTION_END(status);
charlesmn 0:1da5e4bcb8e5 863
charlesmn 0:1da5e4bcb8e5 864 return status;
charlesmn 0:1da5e4bcb8e5 865 }
charlesmn 0:1da5e4bcb8e5 866
charlesmn 0:1da5e4bcb8e5 867 #if VL6180_UPSCALE_SUPPORT != 1
charlesmn 0:1da5e4bcb8e5 868
charlesmn 0:1da5e4bcb8e5 869 static int _UpscaleInitPatch0(VL6180Dev_t dev)
charlesmn 0:1da5e4bcb8e5 870 {
charlesmn 0:1da5e4bcb8e5 871 int status;
charlesmn 0:1da5e4bcb8e5 872 uint32_t CalValue = 0;
charlesmn 0:1da5e4bcb8e5 873 CalValue = VL6180DevDataGet(dev, Part2PartAmbNVM);
charlesmn 0:1da5e4bcb8e5 874 status = VL6180_WrDWord(dev, 0xDA, CalValue);
charlesmn 0:1da5e4bcb8e5 875 return status;
charlesmn 0:1da5e4bcb8e5 876 }
charlesmn 0:1da5e4bcb8e5 877
charlesmn 0:1da5e4bcb8e5 878 /* only include up-scaling register setting when up-scale support is configured in */
charlesmn 0:1da5e4bcb8e5 879 int VL6180_UpscaleRegInit(VL6180Dev_t dev)
charlesmn 0:1da5e4bcb8e5 880 {
charlesmn 0:1da5e4bcb8e5 881
charlesmn 0:1da5e4bcb8e5 882 /* apply REGISTER_TUNING_ER02_100614_CustomerView.txt */
charlesmn 0:1da5e4bcb8e5 883 VL6180_WrByte(dev, 0x0207, 0x01);
charlesmn 0:1da5e4bcb8e5 884 VL6180_WrByte(dev, 0x0208, 0x01);
charlesmn 0:1da5e4bcb8e5 885 VL6180_WrByte(dev, 0x0096, 0x00);
charlesmn 0:1da5e4bcb8e5 886 VL6180_WrByte(dev, 0x0097, 0x54);
charlesmn 0:1da5e4bcb8e5 887 VL6180_WrByte(dev, 0x00e3, 0x00);
charlesmn 0:1da5e4bcb8e5 888 VL6180_WrByte(dev, 0x00e4, 0x04);
charlesmn 0:1da5e4bcb8e5 889 VL6180_WrByte(dev, 0x00e5, 0x02);
charlesmn 0:1da5e4bcb8e5 890 VL6180_WrByte(dev, 0x00e6, 0x01);
charlesmn 0:1da5e4bcb8e5 891 VL6180_WrByte(dev, 0x00e7, 0x03);
charlesmn 0:1da5e4bcb8e5 892 VL6180_WrByte(dev, 0x00f5, 0x02);
charlesmn 0:1da5e4bcb8e5 893 VL6180_WrByte(dev, 0x00d9, 0x05);
charlesmn 0:1da5e4bcb8e5 894
charlesmn 0:1da5e4bcb8e5 895 _UpscaleInitPatch0(dev);
charlesmn 0:1da5e4bcb8e5 896
charlesmn 0:1da5e4bcb8e5 897
charlesmn 0:1da5e4bcb8e5 898 VL6180_WrByte(dev, 0x009f, 0x00);
charlesmn 0:1da5e4bcb8e5 899 VL6180_WrByte(dev, 0x00a3, 0x28);
charlesmn 0:1da5e4bcb8e5 900 VL6180_WrByte(dev, 0x00b7, 0x00);
charlesmn 0:1da5e4bcb8e5 901 VL6180_WrByte(dev, 0x00bb, 0x28);
charlesmn 0:1da5e4bcb8e5 902 VL6180_WrByte(dev, 0x00b2, 0x09);
charlesmn 0:1da5e4bcb8e5 903 VL6180_WrByte(dev, 0x00ca, 0x09);
charlesmn 0:1da5e4bcb8e5 904 VL6180_WrByte(dev, 0x0198, 0x01);
charlesmn 0:1da5e4bcb8e5 905 VL6180_WrByte(dev, 0x01b0, 0x17);
charlesmn 0:1da5e4bcb8e5 906 VL6180_WrByte(dev, 0x01ad, 0x00);
charlesmn 0:1da5e4bcb8e5 907 VL6180_WrByte(dev, 0x00ff, 0x05);
charlesmn 0:1da5e4bcb8e5 908 VL6180_WrByte(dev, 0x0100, 0x05);
charlesmn 0:1da5e4bcb8e5 909 VL6180_WrByte(dev, 0x0199, 0x05);
charlesmn 0:1da5e4bcb8e5 910 VL6180_WrByte(dev, 0x01a6, 0x1b);
charlesmn 0:1da5e4bcb8e5 911 VL6180_WrByte(dev, 0x01ac, 0x3e);
charlesmn 0:1da5e4bcb8e5 912 VL6180_WrByte(dev, 0x01a7, 0x1f);
charlesmn 0:1da5e4bcb8e5 913 VL6180_WrByte(dev, 0x0030, 0x00);
charlesmn 0:1da5e4bcb8e5 914 VL6180_WrByte(dev, 0x0011, 0x10);
charlesmn 0:1da5e4bcb8e5 915 VL6180_WrByte(dev, 0x010a, 0x30);
charlesmn 0:1da5e4bcb8e5 916 VL6180_WrByte(dev, 0x003f, 0x46);
charlesmn 0:1da5e4bcb8e5 917 VL6180_WrByte(dev, 0x0031, 0xFF);
charlesmn 0:1da5e4bcb8e5 918 VL6180_WrByte(dev, 0x0040, 0x63);
charlesmn 0:1da5e4bcb8e5 919 VL6180_WrByte(dev, 0x002e, 0x01);
charlesmn 0:1da5e4bcb8e5 920 VL6180_WrByte(dev, 0x002c, 0xff);
charlesmn 0:1da5e4bcb8e5 921 VL6180_WrByte(dev, 0x001b, 0x09);
charlesmn 0:1da5e4bcb8e5 922 VL6180_WrByte(dev, 0x003e, 0x31);
charlesmn 0:1da5e4bcb8e5 923 VL6180_WrByte(dev, 0x0014, 0x24);
charlesmn 0:1da5e4bcb8e5 924 #if VL6180_EXTENDED_RANGE
charlesmn 0:1da5e4bcb8e5 925 VL6180_RangeSetMaxConvergenceTime(dev, 63);
charlesmn 0:1da5e4bcb8e5 926 #else
charlesmn 0:1da5e4bcb8e5 927 VL6180_RangeSetMaxConvergenceTime(dev, 50);
charlesmn 0:1da5e4bcb8e5 928 #endif
charlesmn 0:1da5e4bcb8e5 929
charlesmn 0:1da5e4bcb8e5 930 return 0;
charlesmn 0:1da5e4bcb8e5 931 }
charlesmn 0:1da5e4bcb8e5 932 #else
charlesmn 0:1da5e4bcb8e5 933 #define VL6180_UpscaleRegInit(...) -1
charlesmn 0:1da5e4bcb8e5 934 #endif
charlesmn 0:1da5e4bcb8e5 935
charlesmn 0:1da5e4bcb8e5 936 int VL6180_UpscaleSetScaling(VL6180Dev_t dev, uint8_t scaling)
charlesmn 0:1da5e4bcb8e5 937 {
charlesmn 0:1da5e4bcb8e5 938 int status;
charlesmn 0:1da5e4bcb8e5 939 uint16_t Scaler;
charlesmn 0:1da5e4bcb8e5 940 uint16_t ValidHeight;
charlesmn 0:1da5e4bcb8e5 941 int8_t Offset;
charlesmn 0:1da5e4bcb8e5 942
charlesmn 0:1da5e4bcb8e5 943 LOG_FUNCTION_START("%d", (int)scaling);
charlesmn 0:1da5e4bcb8e5 944
charlesmn 0:1da5e4bcb8e5 945 #ifdef VL6180_HAVE_UPSCALE_DATA
charlesmn 0:1da5e4bcb8e5 946 #define min_scaling 1
charlesmn 0:1da5e4bcb8e5 947 #define max_scaling (sizeof(ScalerLookUP) / sizeof(ScalerLookUP[0]))
charlesmn 0:1da5e4bcb8e5 948 #else
charlesmn 0:1da5e4bcb8e5 949 /* we are in fixed config so only allow configured factor */
charlesmn 0:1da5e4bcb8e5 950 #define min_scaling VL6180_UPSCALE_SUPPORT
charlesmn 0:1da5e4bcb8e5 951 #define max_scaling VL6180_UPSCALE_SUPPORT
charlesmn 0:1da5e4bcb8e5 952 #endif
charlesmn 0:1da5e4bcb8e5 953
charlesmn 0:1da5e4bcb8e5 954 if (scaling >= min_scaling && scaling <= max_scaling) {
charlesmn 0:1da5e4bcb8e5 955
charlesmn 0:1da5e4bcb8e5 956 Scaler = ScalerLookUP[scaling - 1];
charlesmn 0:1da5e4bcb8e5 957 status = VL6180_WrWord(dev, RANGE_SCALER, Scaler);
charlesmn 0:1da5e4bcb8e5 958 _SetUpscale(dev, scaling);
charlesmn 0:1da5e4bcb8e5 959
charlesmn 0:1da5e4bcb8e5 960 /* Apply scaling on part-2-part offset */
charlesmn 0:1da5e4bcb8e5 961 Offset = VL6180DevDataGet(dev, Part2PartOffsetNVM) / scaling;
charlesmn 0:1da5e4bcb8e5 962 status = VL6180_WrByte(dev, SYSRANGE_PART_TO_PART_RANGE_OFFSET, Offset);
charlesmn 0:1da5e4bcb8e5 963
charlesmn 0:1da5e4bcb8e5 964 /* Apply scaling on CrossTalkValidHeight */
charlesmn 0:1da5e4bcb8e5 965 if (status == 0) {
charlesmn 0:1da5e4bcb8e5 966 status = VL6180_WrByte(dev, SYSRANGE_CROSSTALK_VALID_HEIGHT,
charlesmn 0:1da5e4bcb8e5 967 DEF_CROSS_TALK_VALID_HEIGHT_VALUE / scaling);
charlesmn 0:1da5e4bcb8e5 968 }
charlesmn 0:1da5e4bcb8e5 969 /* Apply scaling on RangeIgnore ValidHeight if enabled */
charlesmn 0:1da5e4bcb8e5 970 if( status == 0){
charlesmn 0:1da5e4bcb8e5 971 if( VL6180DevDataGet(dev, RangeIgnore.Enabled) !=0 ){
charlesmn 0:1da5e4bcb8e5 972 ValidHeight = VL6180DevDataGet(dev, RangeIgnore.ValidHeight);
charlesmn 0:1da5e4bcb8e5 973 ValidHeight /= _GetUpscale(dev);
charlesmn 0:1da5e4bcb8e5 974 if( ValidHeight > 255 )
charlesmn 0:1da5e4bcb8e5 975 ValidHeight = 255;
charlesmn 0:1da5e4bcb8e5 976
charlesmn 0:1da5e4bcb8e5 977 status = VL6180_WrByte(dev, SYSRANGE_RANGE_IGNORE_VALID_HEIGHT,
charlesmn 0:1da5e4bcb8e5 978 (uint8_t)(ValidHeight & 0xFF) );
charlesmn 0:1da5e4bcb8e5 979 }
charlesmn 0:1da5e4bcb8e5 980 }
charlesmn 0:1da5e4bcb8e5 981
charlesmn 0:1da5e4bcb8e5 982 #if !VL6180_EXTENDED_RANGE
charlesmn 0:1da5e4bcb8e5 983 if (status == 0) {
charlesmn 0:1da5e4bcb8e5 984 status = VL6180_RangeSetEceState(dev, scaling == 1); /* enable ece only at 1x scaling */
charlesmn 0:1da5e4bcb8e5 985 }
charlesmn 0:1da5e4bcb8e5 986 if (status == 0 && !VL6180_EXTENDED_RANGE && scaling != 1) {
charlesmn 0:1da5e4bcb8e5 987 status = NOT_GUARANTEED ;
charlesmn 0:1da5e4bcb8e5 988 }
charlesmn 0:1da5e4bcb8e5 989 #endif
charlesmn 0:1da5e4bcb8e5 990 } else {
charlesmn 0:1da5e4bcb8e5 991 status = INVALID_PARAMS;
charlesmn 0:1da5e4bcb8e5 992 }
charlesmn 0:1da5e4bcb8e5 993 #undef min_scaling
charlesmn 0:1da5e4bcb8e5 994 #undef max_scaling
charlesmn 0:1da5e4bcb8e5 995 LOG_FUNCTION_END(status);
charlesmn 0:1da5e4bcb8e5 996 return status;
charlesmn 0:1da5e4bcb8e5 997 }
charlesmn 0:1da5e4bcb8e5 998
charlesmn 0:1da5e4bcb8e5 999
charlesmn 0:1da5e4bcb8e5 1000 int VL6180_UpscaleGetScaling(VL6180Dev_t dev)
charlesmn 0:1da5e4bcb8e5 1001 {
charlesmn 0:1da5e4bcb8e5 1002 int status;
charlesmn 0:1da5e4bcb8e5 1003 LOG_FUNCTION_START("");
charlesmn 0:1da5e4bcb8e5 1004 status = _GetUpscale(dev);
charlesmn 0:1da5e4bcb8e5 1005 LOG_FUNCTION_END(status);
charlesmn 0:1da5e4bcb8e5 1006
charlesmn 0:1da5e4bcb8e5 1007 return status;
charlesmn 0:1da5e4bcb8e5 1008 }
charlesmn 0:1da5e4bcb8e5 1009
charlesmn 0:1da5e4bcb8e5 1010
charlesmn 0:1da5e4bcb8e5 1011 static int VL6180_UpscaleStaticInit(VL6180Dev_t dev)
charlesmn 0:1da5e4bcb8e5 1012 {
charlesmn 0:1da5e4bcb8e5 1013 /* todo make these a fail macro in case only 1x is suppoted */
charlesmn 0:1da5e4bcb8e5 1014 int status;
charlesmn 0:1da5e4bcb8e5 1015
charlesmn 0:1da5e4bcb8e5 1016 LOG_FUNCTION_START("");
charlesmn 0:1da5e4bcb8e5 1017 do {
charlesmn 0:1da5e4bcb8e5 1018 status = VL6180_UpscaleRegInit(dev);
charlesmn 0:1da5e4bcb8e5 1019 if (status) {
charlesmn 0:1da5e4bcb8e5 1020 VL6180_ErrLog("regInit fail");
charlesmn 0:1da5e4bcb8e5 1021 break;
charlesmn 0:1da5e4bcb8e5 1022 }
charlesmn 0:1da5e4bcb8e5 1023 #if VL6180_EXTENDED_RANGE
charlesmn 0:1da5e4bcb8e5 1024 status = VL6180_RangeSetEceState(dev, 0);
charlesmn 0:1da5e4bcb8e5 1025 if (status) {
charlesmn 0:1da5e4bcb8e5 1026 VL6180_ErrLog("VL6180_RangeSetEceState fail");
charlesmn 0:1da5e4bcb8e5 1027 break;
charlesmn 0:1da5e4bcb8e5 1028 }
charlesmn 0:1da5e4bcb8e5 1029 #endif
charlesmn 0:1da5e4bcb8e5 1030 } while (0);
charlesmn 0:1da5e4bcb8e5 1031 if (!status) {
charlesmn 0:1da5e4bcb8e5 1032 /* must write the scaler at least once to the device to ensure the scaler is in a known state. */
charlesmn 0:1da5e4bcb8e5 1033 status = VL6180_UpscaleSetScaling(dev, _GetUpscale(dev));
charlesmn 0:1da5e4bcb8e5 1034 VL6180_WrByte(dev, 0x016, 0x00); /* change fresh out of set status to 0 */
charlesmn 0:1da5e4bcb8e5 1035 }
charlesmn 0:1da5e4bcb8e5 1036 LOG_FUNCTION_END(status);
charlesmn 0:1da5e4bcb8e5 1037 return status;
charlesmn 0:1da5e4bcb8e5 1038 }
charlesmn 0:1da5e4bcb8e5 1039
charlesmn 0:1da5e4bcb8e5 1040
charlesmn 0:1da5e4bcb8e5 1041 int VL6180_SetGPIOxPolarity(VL6180Dev_t dev, int pin, int active_high)
charlesmn 0:1da5e4bcb8e5 1042 {
charlesmn 0:1da5e4bcb8e5 1043 int status;
charlesmn 0:1da5e4bcb8e5 1044 LOG_FUNCTION_START("%d %d", (int) pin, (int)active_high);
charlesmn 0:1da5e4bcb8e5 1045
charlesmn 0:1da5e4bcb8e5 1046 if (pin == 0 || pin == 1) {
charlesmn 0:1da5e4bcb8e5 1047 uint16_t RegIndex;
charlesmn 0:1da5e4bcb8e5 1048 uint8_t DataSet;
charlesmn 0:1da5e4bcb8e5 1049 if (pin == 0)
charlesmn 0:1da5e4bcb8e5 1050 RegIndex = SYSTEM_MODE_GPIO0;
charlesmn 0:1da5e4bcb8e5 1051 else
charlesmn 0:1da5e4bcb8e5 1052 RegIndex = SYSTEM_MODE_GPIO1;
charlesmn 0:1da5e4bcb8e5 1053
charlesmn 0:1da5e4bcb8e5 1054 if (active_high)
charlesmn 0:1da5e4bcb8e5 1055 DataSet = GPIOx_POLARITY_SELECT_MASK;
charlesmn 0:1da5e4bcb8e5 1056 else
charlesmn 0:1da5e4bcb8e5 1057 DataSet = 0;
charlesmn 0:1da5e4bcb8e5 1058
charlesmn 0:1da5e4bcb8e5 1059 status = VL6180_UpdateByte(dev, RegIndex, (uint8_t)~GPIOx_POLARITY_SELECT_MASK, DataSet);
charlesmn 0:1da5e4bcb8e5 1060 } else {
charlesmn 0:1da5e4bcb8e5 1061 VL6180_ErrLog("Invalid pin param %d", (int)pin);
charlesmn 0:1da5e4bcb8e5 1062 status = INVALID_PARAMS;
charlesmn 0:1da5e4bcb8e5 1063 }
charlesmn 0:1da5e4bcb8e5 1064
charlesmn 0:1da5e4bcb8e5 1065 LOG_FUNCTION_END(status);
charlesmn 0:1da5e4bcb8e5 1066
charlesmn 0:1da5e4bcb8e5 1067 return status;
charlesmn 0:1da5e4bcb8e5 1068 }
charlesmn 0:1da5e4bcb8e5 1069
charlesmn 0:1da5e4bcb8e5 1070 int VL6180_SetGPIOxFunctionality(VL6180Dev_t dev, int pin, uint8_t functionality)
charlesmn 0:1da5e4bcb8e5 1071 {
charlesmn 0:1da5e4bcb8e5 1072 int status;
charlesmn 0:1da5e4bcb8e5 1073
charlesmn 0:1da5e4bcb8e5 1074 LOG_FUNCTION_START("%d %d", (int) pin, (int)functionality);
charlesmn 0:1da5e4bcb8e5 1075
charlesmn 0:1da5e4bcb8e5 1076 if (((pin == 0) || (pin == 1)) && IsValidGPIOFunction(functionality)) {
charlesmn 0:1da5e4bcb8e5 1077 uint16_t RegIndex;
charlesmn 0:1da5e4bcb8e5 1078
charlesmn 0:1da5e4bcb8e5 1079 if (pin == 0)
charlesmn 0:1da5e4bcb8e5 1080 RegIndex = SYSTEM_MODE_GPIO0;
charlesmn 0:1da5e4bcb8e5 1081 else
charlesmn 0:1da5e4bcb8e5 1082 RegIndex = SYSTEM_MODE_GPIO1;
charlesmn 0:1da5e4bcb8e5 1083
charlesmn 0:1da5e4bcb8e5 1084 status = VL6180_UpdateByte(dev, RegIndex, (uint8_t)~GPIOx_FUNCTIONALITY_SELECT_MASK,
charlesmn 0:1da5e4bcb8e5 1085 functionality << GPIOx_FUNCTIONALITY_SELECT_SHIFT);
charlesmn 0:1da5e4bcb8e5 1086 if (status) {
charlesmn 0:1da5e4bcb8e5 1087 VL6180_ErrLog("Update SYSTEM_MODE_GPIO%d fail", (int)pin);
charlesmn 0:1da5e4bcb8e5 1088 }
charlesmn 0:1da5e4bcb8e5 1089 } else {
charlesmn 0:1da5e4bcb8e5 1090 VL6180_ErrLog("Invalid pin %d or function %d", (int)pin, (int)functionality);
charlesmn 0:1da5e4bcb8e5 1091 status = INVALID_PARAMS;
charlesmn 0:1da5e4bcb8e5 1092 }
charlesmn 0:1da5e4bcb8e5 1093
charlesmn 0:1da5e4bcb8e5 1094 LOG_FUNCTION_END(status);
charlesmn 0:1da5e4bcb8e5 1095 return status;
charlesmn 0:1da5e4bcb8e5 1096 }
charlesmn 0:1da5e4bcb8e5 1097
charlesmn 0:1da5e4bcb8e5 1098
charlesmn 0:1da5e4bcb8e5 1099 int VL6180_SetupGPIOx(VL6180Dev_t dev, int pin, uint8_t IntFunction, int ActiveHigh)
charlesmn 0:1da5e4bcb8e5 1100 {
charlesmn 0:1da5e4bcb8e5 1101 int status;
charlesmn 0:1da5e4bcb8e5 1102
charlesmn 0:1da5e4bcb8e5 1103 LOG_FUNCTION_START("%d %d", (int) pin, (int)IntFunction);
charlesmn 0:1da5e4bcb8e5 1104
charlesmn 0:1da5e4bcb8e5 1105 if (((pin == 0) || (pin == 1)) && IsValidGPIOFunction(IntFunction)) {
charlesmn 0:1da5e4bcb8e5 1106 uint16_t RegIndex;
charlesmn 0:1da5e4bcb8e5 1107 uint8_t value = 0;
charlesmn 0:1da5e4bcb8e5 1108
charlesmn 0:1da5e4bcb8e5 1109 if (pin == 0)
charlesmn 0:1da5e4bcb8e5 1110 RegIndex = SYSTEM_MODE_GPIO0;
charlesmn 0:1da5e4bcb8e5 1111 else
charlesmn 0:1da5e4bcb8e5 1112 RegIndex = SYSTEM_MODE_GPIO1;
charlesmn 0:1da5e4bcb8e5 1113
charlesmn 0:1da5e4bcb8e5 1114 if (ActiveHigh)
charlesmn 0:1da5e4bcb8e5 1115 value |= GPIOx_POLARITY_SELECT_MASK;
charlesmn 0:1da5e4bcb8e5 1116
charlesmn 0:1da5e4bcb8e5 1117 value |= IntFunction << GPIOx_FUNCTIONALITY_SELECT_SHIFT;
charlesmn 0:1da5e4bcb8e5 1118 status = VL6180_WrByte(dev, RegIndex, value);
charlesmn 0:1da5e4bcb8e5 1119 if (status) {
charlesmn 0:1da5e4bcb8e5 1120 VL6180_ErrLog("SYSTEM_MODE_GPIO%d wr fail", (int)pin-SYSTEM_MODE_GPIO0);
charlesmn 0:1da5e4bcb8e5 1121 }
charlesmn 0:1da5e4bcb8e5 1122 } else {
charlesmn 0:1da5e4bcb8e5 1123 VL6180_ErrLog("Invalid pin %d or function %d", (int)pin, (int) IntFunction);
charlesmn 0:1da5e4bcb8e5 1124 status = INVALID_PARAMS;
charlesmn 0:1da5e4bcb8e5 1125 }
charlesmn 0:1da5e4bcb8e5 1126
charlesmn 0:1da5e4bcb8e5 1127 LOG_FUNCTION_END(status);
charlesmn 0:1da5e4bcb8e5 1128 return status;
charlesmn 0:1da5e4bcb8e5 1129 }
charlesmn 0:1da5e4bcb8e5 1130
charlesmn 0:1da5e4bcb8e5 1131
charlesmn 0:1da5e4bcb8e5 1132 int VL6180_DisableGPIOxOut(VL6180Dev_t dev, int pin)
charlesmn 0:1da5e4bcb8e5 1133 {
charlesmn 0:1da5e4bcb8e5 1134 int status;
charlesmn 0:1da5e4bcb8e5 1135
charlesmn 0:1da5e4bcb8e5 1136 LOG_FUNCTION_START("%d", (int)pin);
charlesmn 0:1da5e4bcb8e5 1137
charlesmn 0:1da5e4bcb8e5 1138 status = VL6180_SetGPIOxFunctionality(dev, pin, GPIOx_SELECT_OFF);
charlesmn 0:1da5e4bcb8e5 1139
charlesmn 0:1da5e4bcb8e5 1140 LOG_FUNCTION_END(status);
charlesmn 0:1da5e4bcb8e5 1141 return status;
charlesmn 0:1da5e4bcb8e5 1142 }
charlesmn 0:1da5e4bcb8e5 1143
charlesmn 0:1da5e4bcb8e5 1144
charlesmn 0:1da5e4bcb8e5 1145 int VL6180_SetupGPIO1(VL6180Dev_t dev, uint8_t IntFunction, int ActiveHigh)
charlesmn 0:1da5e4bcb8e5 1146 {
charlesmn 0:1da5e4bcb8e5 1147 int status;
charlesmn 0:1da5e4bcb8e5 1148 LOG_FUNCTION_START("%d %d", (int)IntFunction, (int)ActiveHigh);
charlesmn 0:1da5e4bcb8e5 1149 status = VL6180_SetupGPIOx(dev, 1, IntFunction, ActiveHigh);
charlesmn 0:1da5e4bcb8e5 1150 LOG_FUNCTION_END(status);
charlesmn 0:1da5e4bcb8e5 1151 return status;
charlesmn 0:1da5e4bcb8e5 1152 }
charlesmn 0:1da5e4bcb8e5 1153
charlesmn 0:1da5e4bcb8e5 1154 int VL6180_RangeConfigInterrupt(VL6180Dev_t dev, uint8_t ConfigGpioInt)
charlesmn 0:1da5e4bcb8e5 1155 {
charlesmn 0:1da5e4bcb8e5 1156 int status;
charlesmn 0:1da5e4bcb8e5 1157
charlesmn 0:1da5e4bcb8e5 1158 if (ConfigGpioInt <= CONFIG_GPIO_INTERRUPT_NEW_SAMPLE_READY) {
charlesmn 0:1da5e4bcb8e5 1159 status = VL6180_UpdateByte(dev, SYSTEM_INTERRUPT_CONFIG_GPIO,
charlesmn 0:1da5e4bcb8e5 1160 (uint8_t)(~CONFIG_GPIO_RANGE_MASK),
charlesmn 0:1da5e4bcb8e5 1161 ConfigGpioInt);
charlesmn 0:1da5e4bcb8e5 1162 } else {
charlesmn 0:1da5e4bcb8e5 1163 VL6180_ErrLog("Invalid config mode param %d", (int)ConfigGpioInt);
charlesmn 0:1da5e4bcb8e5 1164 status = INVALID_PARAMS;
charlesmn 0:1da5e4bcb8e5 1165 }
charlesmn 0:1da5e4bcb8e5 1166 LOG_FUNCTION_END(status);
charlesmn 0:1da5e4bcb8e5 1167 return status;
charlesmn 0:1da5e4bcb8e5 1168 }
charlesmn 0:1da5e4bcb8e5 1169
charlesmn 0:1da5e4bcb8e5 1170
charlesmn 0:1da5e4bcb8e5 1171 int VL6180_RangeSetEceFactor(VL6180Dev_t dev, uint16_t FactorM, uint16_t FactorD)
charlesmn 0:1da5e4bcb8e5 1172 {
charlesmn 0:1da5e4bcb8e5 1173 int status;
charlesmn 0:1da5e4bcb8e5 1174 uint8_t u8;
charlesmn 0:1da5e4bcb8e5 1175
charlesmn 0:1da5e4bcb8e5 1176 LOG_FUNCTION_START("%d %d", (int)FactorM, (int)FactorD);
charlesmn 0:1da5e4bcb8e5 1177 do {
charlesmn 0:1da5e4bcb8e5 1178 /* D cannot be 0 M must be <=D and >= 0 */
charlesmn 0:1da5e4bcb8e5 1179 if (FactorM <= FactorD && FactorD > 0) {
charlesmn 0:1da5e4bcb8e5 1180 VL6180DevDataSet(dev, EceFactorM, FactorM);
charlesmn 0:1da5e4bcb8e5 1181 VL6180DevDataSet(dev, EceFactorD, FactorD);
charlesmn 0:1da5e4bcb8e5 1182 /* read and re-apply max conv time to get new ece factor set */
charlesmn 0:1da5e4bcb8e5 1183 status = VL6180_RdByte(dev, SYSRANGE_MAX_CONVERGENCE_TIME, &u8);
charlesmn 0:1da5e4bcb8e5 1184 if (status) {
charlesmn 0:1da5e4bcb8e5 1185 VL6180_ErrLog("SYSRANGE_MAX_CONVERGENCE_TIME rd fail ");
charlesmn 0:1da5e4bcb8e5 1186 break;
charlesmn 0:1da5e4bcb8e5 1187 }
charlesmn 0:1da5e4bcb8e5 1188 status = VL6180_RangeSetMaxConvergenceTime(dev, u8);
charlesmn 0:1da5e4bcb8e5 1189 if (status < 0) {
charlesmn 0:1da5e4bcb8e5 1190 VL6180_ErrLog("fail to apply time after ece m/d change");
charlesmn 0:1da5e4bcb8e5 1191 break;
charlesmn 0:1da5e4bcb8e5 1192 }
charlesmn 0:1da5e4bcb8e5 1193 } else {
charlesmn 0:1da5e4bcb8e5 1194 VL6180_ErrLog("invalid factor %d/%d", (int)FactorM, (int)FactorD);
charlesmn 0:1da5e4bcb8e5 1195 status = INVALID_PARAMS;
charlesmn 0:1da5e4bcb8e5 1196 }
charlesmn 0:1da5e4bcb8e5 1197 } while (0);
charlesmn 0:1da5e4bcb8e5 1198 LOG_FUNCTION_END(status);
charlesmn 0:1da5e4bcb8e5 1199 return status;
charlesmn 0:1da5e4bcb8e5 1200 }
charlesmn 0:1da5e4bcb8e5 1201
charlesmn 0:1da5e4bcb8e5 1202 int VL6180_RangeSetEceState(VL6180Dev_t dev, int enable)
charlesmn 0:1da5e4bcb8e5 1203 {
charlesmn 0:1da5e4bcb8e5 1204 int status;
charlesmn 0:1da5e4bcb8e5 1205 uint8_t or_mask;
charlesmn 0:1da5e4bcb8e5 1206
charlesmn 0:1da5e4bcb8e5 1207 LOG_FUNCTION_START("%d", (int)enable);
charlesmn 0:1da5e4bcb8e5 1208 if (enable)
charlesmn 0:1da5e4bcb8e5 1209 or_mask = RANGE_CHECK_ECE_ENABLE_MASK;
charlesmn 0:1da5e4bcb8e5 1210 else
charlesmn 0:1da5e4bcb8e5 1211 or_mask = 0;
charlesmn 0:1da5e4bcb8e5 1212
charlesmn 0:1da5e4bcb8e5 1213 status = VL6180_UpdateByte(dev, SYSRANGE_RANGE_CHECK_ENABLES, ~RANGE_CHECK_ECE_ENABLE_MASK, or_mask);
charlesmn 0:1da5e4bcb8e5 1214 LOG_FUNCTION_END(status);
charlesmn 0:1da5e4bcb8e5 1215 return status;
charlesmn 0:1da5e4bcb8e5 1216 }
charlesmn 0:1da5e4bcb8e5 1217
charlesmn 0:1da5e4bcb8e5 1218
charlesmn 0:1da5e4bcb8e5 1219 int VL6180_RangeSetMaxConvergenceTime(VL6180Dev_t dev, uint8_t MaxConTime_msec)
charlesmn 0:1da5e4bcb8e5 1220 {
charlesmn 0:1da5e4bcb8e5 1221 int status = 0;
charlesmn 0:1da5e4bcb8e5 1222 LOG_FUNCTION_START("%d", (int)MaxConTime_msec);
charlesmn 0:1da5e4bcb8e5 1223 do {
charlesmn 0:1da5e4bcb8e5 1224 status = VL6180_WrByte(dev, SYSRANGE_MAX_CONVERGENCE_TIME, MaxConTime_msec);
charlesmn 0:1da5e4bcb8e5 1225 if (status) {
charlesmn 0:1da5e4bcb8e5 1226 break;
charlesmn 0:1da5e4bcb8e5 1227 }
charlesmn 0:1da5e4bcb8e5 1228 status = VL6180_RangeSetEarlyConvergenceEestimateThreshold(dev);
charlesmn 0:1da5e4bcb8e5 1229 if (status) {
charlesmn 0:1da5e4bcb8e5 1230 break;
charlesmn 0:1da5e4bcb8e5 1231 }
charlesmn 0:1da5e4bcb8e5 1232 status = _DMax_InitData(dev);
charlesmn 0:1da5e4bcb8e5 1233 } while (0);
charlesmn 0:1da5e4bcb8e5 1234 LOG_FUNCTION_END(status);
charlesmn 0:1da5e4bcb8e5 1235 return status;
charlesmn 0:1da5e4bcb8e5 1236 }
charlesmn 0:1da5e4bcb8e5 1237
charlesmn 0:1da5e4bcb8e5 1238 int VL6180_RangeSetInterMeasPeriod(VL6180Dev_t dev, uint32_t InterMeasTime_msec)
charlesmn 0:1da5e4bcb8e5 1239 {
charlesmn 0:1da5e4bcb8e5 1240 uint8_t SetTime;
charlesmn 0:1da5e4bcb8e5 1241 int status;
charlesmn 0:1da5e4bcb8e5 1242
charlesmn 0:1da5e4bcb8e5 1243 LOG_FUNCTION_START("%d", (int)InterMeasTime_msec);
charlesmn 0:1da5e4bcb8e5 1244 do {
charlesmn 0:1da5e4bcb8e5 1245 if (InterMeasTime_msec > 2550) {
charlesmn 0:1da5e4bcb8e5 1246 status = INVALID_PARAMS;
charlesmn 0:1da5e4bcb8e5 1247 break;
charlesmn 0:1da5e4bcb8e5 1248 }
charlesmn 0:1da5e4bcb8e5 1249 /* doc in not 100% clear and confusing about the limit practically all value are OK but 0
charlesmn 0:1da5e4bcb8e5 1250 * that can hang device in continuous mode */
charlesmn 0:1da5e4bcb8e5 1251 if (InterMeasTime_msec < 10) {
charlesmn 0:1da5e4bcb8e5 1252 InterMeasTime_msec = 10;
charlesmn 0:1da5e4bcb8e5 1253 }
charlesmn 0:1da5e4bcb8e5 1254 SetTime = (uint8_t)(InterMeasTime_msec / 10);
charlesmn 0:1da5e4bcb8e5 1255 status = VL6180_WrByte(dev, SYSRANGE_INTERMEASUREMENT_PERIOD, SetTime);
charlesmn 0:1da5e4bcb8e5 1256 if (status) {
charlesmn 0:1da5e4bcb8e5 1257 VL6180_ErrLog("SYSRANGE_INTERMEASUREMENT_PERIOD wr fail");
charlesmn 0:1da5e4bcb8e5 1258 } else if (SetTime != InterMeasTime_msec / 10) {
charlesmn 0:1da5e4bcb8e5 1259 status = MIN_CLIPED; /* on success change status to clip if it did */
charlesmn 0:1da5e4bcb8e5 1260 }
charlesmn 0:1da5e4bcb8e5 1261 } while (0);
charlesmn 0:1da5e4bcb8e5 1262 LOG_FUNCTION_END(status);
charlesmn 0:1da5e4bcb8e5 1263 return status;
charlesmn 0:1da5e4bcb8e5 1264 }
charlesmn 0:1da5e4bcb8e5 1265
charlesmn 0:1da5e4bcb8e5 1266
charlesmn 0:1da5e4bcb8e5 1267 int VL6180_RangeGetDeviceReady(VL6180Dev_t dev, int *Ready)
charlesmn 0:1da5e4bcb8e5 1268 {
charlesmn 0:1da5e4bcb8e5 1269 int status;
charlesmn 0:1da5e4bcb8e5 1270 uint8_t u8;
charlesmn 0:1da5e4bcb8e5 1271 LOG_FUNCTION_START("%p", (int)Ready);
charlesmn 0:1da5e4bcb8e5 1272 status = VL6180_RdByte(dev, RESULT_RANGE_STATUS, &u8);
charlesmn 0:1da5e4bcb8e5 1273 if (!status)
charlesmn 0:1da5e4bcb8e5 1274 *Ready = u8&RANGE_DEVICE_READY_MASK;
charlesmn 0:1da5e4bcb8e5 1275 LOG_FUNCTION_END_FMT(status, "%d", *Ready);
charlesmn 0:1da5e4bcb8e5 1276 return status;
charlesmn 0:1da5e4bcb8e5 1277 }
charlesmn 0:1da5e4bcb8e5 1278
charlesmn 0:1da5e4bcb8e5 1279
charlesmn 0:1da5e4bcb8e5 1280 int VL6180_RangeWaitDeviceReady(VL6180Dev_t dev, int MaxLoop)
charlesmn 0:1da5e4bcb8e5 1281 {
charlesmn 0:1da5e4bcb8e5 1282 int status = 0; /* if user specify an invalid <=0 loop count we'll return error */
charlesmn 0:1da5e4bcb8e5 1283 int n;
charlesmn 0:1da5e4bcb8e5 1284 uint8_t u8;
charlesmn 0:1da5e4bcb8e5 1285 LOG_FUNCTION_START("%d", (int)MaxLoop);
charlesmn 0:1da5e4bcb8e5 1286 if (MaxLoop < 1) {
charlesmn 0:1da5e4bcb8e5 1287 status = INVALID_PARAMS;
charlesmn 0:1da5e4bcb8e5 1288 } else {
charlesmn 0:1da5e4bcb8e5 1289 for (n = 0; n < MaxLoop ; n++) {
charlesmn 0:1da5e4bcb8e5 1290 status = VL6180_RdByte(dev, RESULT_RANGE_STATUS, &u8);
charlesmn 0:1da5e4bcb8e5 1291 if (status)
charlesmn 0:1da5e4bcb8e5 1292 break;
charlesmn 0:1da5e4bcb8e5 1293 u8 = u8 & RANGE_DEVICE_READY_MASK;
charlesmn 0:1da5e4bcb8e5 1294 if (u8)
charlesmn 0:1da5e4bcb8e5 1295 break;
charlesmn 0:1da5e4bcb8e5 1296
charlesmn 0:1da5e4bcb8e5 1297 }
charlesmn 0:1da5e4bcb8e5 1298 if (!status && !u8) {
charlesmn 0:1da5e4bcb8e5 1299 status = TIME_OUT;
charlesmn 0:1da5e4bcb8e5 1300 }
charlesmn 0:1da5e4bcb8e5 1301 }
charlesmn 0:1da5e4bcb8e5 1302 LOG_FUNCTION_END(status);
charlesmn 0:1da5e4bcb8e5 1303 return status;
charlesmn 0:1da5e4bcb8e5 1304 }
charlesmn 0:1da5e4bcb8e5 1305
charlesmn 0:1da5e4bcb8e5 1306 int VL6180_RangeSetSystemMode(VL6180Dev_t dev, uint8_t mode)
charlesmn 0:1da5e4bcb8e5 1307 {
charlesmn 0:1da5e4bcb8e5 1308 int status;
charlesmn 0:1da5e4bcb8e5 1309 LOG_FUNCTION_START("%d", (int)mode);
charlesmn 0:1da5e4bcb8e5 1310 /* FIXME we are not checking device is ready via @a VL6180_RangeWaitDeviceReady
charlesmn 0:1da5e4bcb8e5 1311 * so if called back to back real fast we are not checking
charlesmn 0:1da5e4bcb8e5 1312 * if previous mode "set" got absorbed => bit 0 must be 0 so that it work
charlesmn 0:1da5e4bcb8e5 1313 */
charlesmn 0:1da5e4bcb8e5 1314 if (mode <= 3) {
charlesmn 0:1da5e4bcb8e5 1315 status = VL6180_WrByte(dev, SYSRANGE_START, mode);
charlesmn 0:1da5e4bcb8e5 1316 if (status) {
charlesmn 0:1da5e4bcb8e5 1317 VL6180_ErrLog("SYSRANGE_START wr fail");
charlesmn 0:1da5e4bcb8e5 1318 }
charlesmn 0:1da5e4bcb8e5 1319 } else {
charlesmn 0:1da5e4bcb8e5 1320 status = INVALID_PARAMS;
charlesmn 0:1da5e4bcb8e5 1321 }
charlesmn 0:1da5e4bcb8e5 1322
charlesmn 0:1da5e4bcb8e5 1323 LOG_FUNCTION_END(status);
charlesmn 0:1da5e4bcb8e5 1324 return status;
charlesmn 0:1da5e4bcb8e5 1325 }
charlesmn 0:1da5e4bcb8e5 1326
charlesmn 0:1da5e4bcb8e5 1327
charlesmn 0:1da5e4bcb8e5 1328 int VL6180_RangeStartContinuousMode(VL6180Dev_t dev)
charlesmn 0:1da5e4bcb8e5 1329 {
charlesmn 0:1da5e4bcb8e5 1330 int status;
charlesmn 0:1da5e4bcb8e5 1331 LOG_FUNCTION_START("");
charlesmn 0:1da5e4bcb8e5 1332 status = VL6180_RangeSetSystemMode(dev, MODE_START_STOP | MODE_CONTINUOUS);
charlesmn 0:1da5e4bcb8e5 1333 LOG_FUNCTION_END(status);
charlesmn 0:1da5e4bcb8e5 1334 return status;
charlesmn 0:1da5e4bcb8e5 1335 }
charlesmn 0:1da5e4bcb8e5 1336
charlesmn 0:1da5e4bcb8e5 1337 int VL6180_RangeStartSingleShot(VL6180Dev_t dev)
charlesmn 0:1da5e4bcb8e5 1338 {
charlesmn 0:1da5e4bcb8e5 1339 int status;
charlesmn 0:1da5e4bcb8e5 1340 LOG_FUNCTION_START("");
charlesmn 0:1da5e4bcb8e5 1341 status = VL6180_RangeSetSystemMode(dev, MODE_START_STOP | MODE_SINGLESHOT);
charlesmn 0:1da5e4bcb8e5 1342 LOG_FUNCTION_END(status);
charlesmn 0:1da5e4bcb8e5 1343 return status;
charlesmn 0:1da5e4bcb8e5 1344 }
charlesmn 0:1da5e4bcb8e5 1345
charlesmn 0:1da5e4bcb8e5 1346
charlesmn 0:1da5e4bcb8e5 1347 static int VL6180_RangeSetEarlyConvergenceEestimateThreshold(VL6180Dev_t dev)
charlesmn 0:1da5e4bcb8e5 1348 {
charlesmn 0:1da5e4bcb8e5 1349 int status;
charlesmn 0:1da5e4bcb8e5 1350
charlesmn 0:1da5e4bcb8e5 1351 const uint32_t cMicroSecPerMilliSec = 1000;
charlesmn 0:1da5e4bcb8e5 1352 const uint32_t cEceSampleTime_us = 500;
charlesmn 0:1da5e4bcb8e5 1353 uint32_t ece_factor_m = VL6180DevDataGet(dev, EceFactorM);
charlesmn 0:1da5e4bcb8e5 1354 uint32_t ece_factor_d = VL6180DevDataGet(dev, EceFactorD);
charlesmn 0:1da5e4bcb8e5 1355 uint32_t convergTime_us;
charlesmn 0:1da5e4bcb8e5 1356 uint32_t fineThresh;
charlesmn 0:1da5e4bcb8e5 1357 uint32_t eceThresh;
charlesmn 0:1da5e4bcb8e5 1358 uint8_t u8;
charlesmn 0:1da5e4bcb8e5 1359 uint32_t maxConv_ms;
charlesmn 0:1da5e4bcb8e5 1360 int32_t AveTime;
charlesmn 0:1da5e4bcb8e5 1361
charlesmn 0:1da5e4bcb8e5 1362 LOG_FUNCTION_START("");
charlesmn 0:1da5e4bcb8e5 1363
charlesmn 0:1da5e4bcb8e5 1364 do {
charlesmn 0:1da5e4bcb8e5 1365 status = VL6180_RdByte(dev, SYSRANGE_MAX_CONVERGENCE_TIME, &u8);
charlesmn 0:1da5e4bcb8e5 1366 if (status) {
charlesmn 0:1da5e4bcb8e5 1367 VL6180_ErrLog("SYSRANGE_MAX_CONVERGENCE_TIME rd fail");
charlesmn 0:1da5e4bcb8e5 1368 break;
charlesmn 0:1da5e4bcb8e5 1369 }
charlesmn 0:1da5e4bcb8e5 1370 maxConv_ms = u8;
charlesmn 0:1da5e4bcb8e5 1371 AveTime = _GetAveTotalTime(dev);
charlesmn 0:1da5e4bcb8e5 1372 if (AveTime < 0) {
charlesmn 0:1da5e4bcb8e5 1373 status = -1;
charlesmn 0:1da5e4bcb8e5 1374 break;
charlesmn 0:1da5e4bcb8e5 1375 }
charlesmn 0:1da5e4bcb8e5 1376
charlesmn 0:1da5e4bcb8e5 1377 convergTime_us = maxConv_ms * cMicroSecPerMilliSec - AveTime;
charlesmn 0:1da5e4bcb8e5 1378 status = VL6180_RdDWord(dev, 0xB8, &fineThresh);
charlesmn 0:1da5e4bcb8e5 1379 if (status) {
charlesmn 0:1da5e4bcb8e5 1380 VL6180_ErrLog("reg 0xB8 rd fail");
charlesmn 0:1da5e4bcb8e5 1381 break;
charlesmn 0:1da5e4bcb8e5 1382 }
charlesmn 0:1da5e4bcb8e5 1383 fineThresh *= 256;
charlesmn 0:1da5e4bcb8e5 1384 eceThresh = ece_factor_m * cEceSampleTime_us * fineThresh / (convergTime_us * ece_factor_d);
charlesmn 0:1da5e4bcb8e5 1385
charlesmn 0:1da5e4bcb8e5 1386 status = VL6180_WrWord(dev, SYSRANGE_EARLY_CONVERGENCE_ESTIMATE, (uint16_t)eceThresh);
charlesmn 0:1da5e4bcb8e5 1387 } while (0);
charlesmn 0:1da5e4bcb8e5 1388
charlesmn 0:1da5e4bcb8e5 1389 LOG_FUNCTION_END(status);
charlesmn 0:1da5e4bcb8e5 1390 return status;
charlesmn 0:1da5e4bcb8e5 1391 }
charlesmn 0:1da5e4bcb8e5 1392
charlesmn 0:1da5e4bcb8e5 1393
charlesmn 0:1da5e4bcb8e5 1394 static int _RangeIgnore_UpdateDevice(VL6180Dev_t dev){
charlesmn 0:1da5e4bcb8e5 1395 int status;
charlesmn 0:1da5e4bcb8e5 1396 int enable;
charlesmn 0:1da5e4bcb8e5 1397 int threshold;
charlesmn 0:1da5e4bcb8e5 1398 int range;
charlesmn 0:1da5e4bcb8e5 1399 int or_mask;
charlesmn 0:1da5e4bcb8e5 1400 enable= VL6180DevDataGet(dev, RangeIgnore.Enabled);
charlesmn 0:1da5e4bcb8e5 1401 if( enable ){
charlesmn 0:1da5e4bcb8e5 1402 // if to be nabled program first range value and threshold
charlesmn 0:1da5e4bcb8e5 1403 range = VL6180DevDataGet(dev, RangeIgnore.ValidHeight);
charlesmn 0:1da5e4bcb8e5 1404 range /= _GetUpscale(dev);
charlesmn 0:1da5e4bcb8e5 1405 if( range > 255 )
charlesmn 0:1da5e4bcb8e5 1406 range = 255;
charlesmn 0:1da5e4bcb8e5 1407
charlesmn 0:1da5e4bcb8e5 1408 status = VL6180_WrByte(dev, SYSRANGE_RANGE_IGNORE_VALID_HEIGHT, range);
charlesmn 0:1da5e4bcb8e5 1409 if( status ){
charlesmn 0:1da5e4bcb8e5 1410 goto done;
charlesmn 0:1da5e4bcb8e5 1411 }
charlesmn 0:1da5e4bcb8e5 1412
charlesmn 0:1da5e4bcb8e5 1413 threshold = VL6180DevDataGet(dev, RangeIgnore.IgnoreThreshold);
charlesmn 0:1da5e4bcb8e5 1414 status = VL6180_WrWord(dev, SYSRANGE_RANGE_IGNORE_THRESHOLD, threshold);
charlesmn 0:1da5e4bcb8e5 1415 if( status ){
charlesmn 0:1da5e4bcb8e5 1416 goto done;
charlesmn 0:1da5e4bcb8e5 1417 }
charlesmn 0:1da5e4bcb8e5 1418 or_mask = RANGE_CHECK_RANGE_ENABLE_MASK;
charlesmn 0:1da5e4bcb8e5 1419 }
charlesmn 0:1da5e4bcb8e5 1420 else{
charlesmn 0:1da5e4bcb8e5 1421 or_mask = 0;
charlesmn 0:1da5e4bcb8e5 1422 }
charlesmn 0:1da5e4bcb8e5 1423 status = VL6180_UpdateByte(dev, SYSRANGE_RANGE_CHECK_ENABLES, ~RANGE_CHECK_RANGE_ENABLE_MASK, or_mask);
charlesmn 0:1da5e4bcb8e5 1424 _DMax_InitData(dev);
charlesmn 0:1da5e4bcb8e5 1425 done:
charlesmn 0:1da5e4bcb8e5 1426 return status;
charlesmn 0:1da5e4bcb8e5 1427 }
charlesmn 0:1da5e4bcb8e5 1428
charlesmn 0:1da5e4bcb8e5 1429 int VL6180_RangeIgnoreSetEnable(VL6180Dev_t dev, int EnableState){
charlesmn 0:1da5e4bcb8e5 1430 int CurEnable;
charlesmn 0:1da5e4bcb8e5 1431 int status=0;
charlesmn 0:1da5e4bcb8e5 1432 LOG_FUNCTION_START("enable %d", EnableState);
charlesmn 0:1da5e4bcb8e5 1433
charlesmn 0:1da5e4bcb8e5 1434 if( EnableState )
charlesmn 0:1da5e4bcb8e5 1435 EnableState = 1;
charlesmn 0:1da5e4bcb8e5 1436
charlesmn 0:1da5e4bcb8e5 1437 CurEnable = VL6180DevDataGet(dev, RangeIgnore.Enabled);
charlesmn 0:1da5e4bcb8e5 1438 if( EnableState != CurEnable ){
charlesmn 0:1da5e4bcb8e5 1439 VL6180DevDataSet(dev, RangeIgnore.Enabled, EnableState);
charlesmn 0:1da5e4bcb8e5 1440 status = _RangeIgnore_UpdateDevice(dev);
charlesmn 0:1da5e4bcb8e5 1441 }
charlesmn 0:1da5e4bcb8e5 1442 LOG_FUNCTION_END(status);
charlesmn 0:1da5e4bcb8e5 1443 return status;
charlesmn 0:1da5e4bcb8e5 1444 }
charlesmn 0:1da5e4bcb8e5 1445
charlesmn 0:1da5e4bcb8e5 1446 int VL6180_RangeIgnoreConfigure(VL6180Dev_t dev, uint16_t ValidHeight_mm, uint16_t IgnoreThreshold){
charlesmn 0:1da5e4bcb8e5 1447 int status;
charlesmn 0:1da5e4bcb8e5 1448 int enabled;
charlesmn 0:1da5e4bcb8e5 1449
charlesmn 0:1da5e4bcb8e5 1450 LOG_FUNCTION_START("height= %d Threshold=%d", (int)ValidHeight_mm, (int)Threshold);
charlesmn 0:1da5e4bcb8e5 1451
charlesmn 0:1da5e4bcb8e5 1452 enabled = VL6180DevDataGet(dev, RangeIgnore.Enabled);
charlesmn 0:1da5e4bcb8e5 1453 VL6180DevDataSet(dev, RangeIgnore.ValidHeight, ValidHeight_mm);
charlesmn 0:1da5e4bcb8e5 1454 VL6180DevDataSet(dev, RangeIgnore.IgnoreThreshold, IgnoreThreshold);
charlesmn 0:1da5e4bcb8e5 1455 if( enabled ){
charlesmn 0:1da5e4bcb8e5 1456 status = _RangeIgnore_UpdateDevice(dev);
charlesmn 0:1da5e4bcb8e5 1457 }
charlesmn 0:1da5e4bcb8e5 1458 else{
charlesmn 0:1da5e4bcb8e5 1459 status = 0;
charlesmn 0:1da5e4bcb8e5 1460 }
charlesmn 0:1da5e4bcb8e5 1461 LOG_FUNCTION_END(status);
charlesmn 0:1da5e4bcb8e5 1462 return status;
charlesmn 0:1da5e4bcb8e5 1463 }
charlesmn 0:1da5e4bcb8e5 1464
charlesmn 0:1da5e4bcb8e5 1465 /*
charlesmn 0:1da5e4bcb8e5 1466 * Return >0 = time
charlesmn 0:1da5e4bcb8e5 1467 * <0 1 if fail to get read data from device to compute time
charlesmn 0:1da5e4bcb8e5 1468 */
charlesmn 0:1da5e4bcb8e5 1469 static int32_t _GetAveTotalTime(VL6180Dev_t dev)
charlesmn 0:1da5e4bcb8e5 1470 {
charlesmn 0:1da5e4bcb8e5 1471 uint32_t cFwOverhead_us = 24;
charlesmn 0:1da5e4bcb8e5 1472 uint32_t cVcpSetupTime_us = 70;
charlesmn 0:1da5e4bcb8e5 1473 uint32_t cPLL2_StartupDelay_us = 200;
charlesmn 0:1da5e4bcb8e5 1474 uint8_t cMeasMask = 0x07;
charlesmn 0:1da5e4bcb8e5 1475 uint32_t Samples;
charlesmn 0:1da5e4bcb8e5 1476 uint32_t SamplePeriod;
charlesmn 0:1da5e4bcb8e5 1477 uint32_t SingleTime_us;
charlesmn 0:1da5e4bcb8e5 1478 int32_t TotalAveTime_us;
charlesmn 0:1da5e4bcb8e5 1479 uint8_t u8;
charlesmn 0:1da5e4bcb8e5 1480 int status;
charlesmn 0:1da5e4bcb8e5 1481
charlesmn 0:1da5e4bcb8e5 1482 LOG_FUNCTION_START("");
charlesmn 0:1da5e4bcb8e5 1483
charlesmn 0:1da5e4bcb8e5 1484 status = VL6180_RdByte(dev, 0x109, &u8);
charlesmn 0:1da5e4bcb8e5 1485 if (status) {
charlesmn 0:1da5e4bcb8e5 1486 VL6180_ErrLog("rd 0x109 fail");
charlesmn 0:1da5e4bcb8e5 1487 return -1;
charlesmn 0:1da5e4bcb8e5 1488 }
charlesmn 0:1da5e4bcb8e5 1489 Samples = u8 & cMeasMask;
charlesmn 0:1da5e4bcb8e5 1490 status = VL6180_RdByte(dev, READOUT_AVERAGING_SAMPLE_PERIOD, &u8);
charlesmn 0:1da5e4bcb8e5 1491 if (status) {
charlesmn 0:1da5e4bcb8e5 1492 VL6180_ErrLog("i2c READOUT_AVERAGING_SAMPLE_PERIOD fail");
charlesmn 0:1da5e4bcb8e5 1493 return -1;
charlesmn 0:1da5e4bcb8e5 1494 }
charlesmn 0:1da5e4bcb8e5 1495 SamplePeriod = u8;
charlesmn 0:1da5e4bcb8e5 1496 SingleTime_us = cFwOverhead_us + cVcpSetupTime_us + (SamplePeriod * 10);
charlesmn 0:1da5e4bcb8e5 1497 TotalAveTime_us = (Samples + 1) * SingleTime_us + cPLL2_StartupDelay_us;
charlesmn 0:1da5e4bcb8e5 1498
charlesmn 0:1da5e4bcb8e5 1499 LOG_FUNCTION_END(TotalAveTime_us);
charlesmn 0:1da5e4bcb8e5 1500 return TotalAveTime_us;
charlesmn 0:1da5e4bcb8e5 1501 }
charlesmn 0:1da5e4bcb8e5 1502
charlesmn 0:1da5e4bcb8e5 1503 #if VL6180_HAVE_DMAX_RANGING
charlesmn 0:1da5e4bcb8e5 1504 #define _GetDMaxDataRetSignalAt400mm(dev) VL6180DevDataGet(dev, DMaxData.retSignalAt400mm)
charlesmn 0:1da5e4bcb8e5 1505 #else
charlesmn 0:1da5e4bcb8e5 1506 #define _GetDMaxDataRetSignalAt400mm(dev) 375 /* Use a default high value */
charlesmn 0:1da5e4bcb8e5 1507 #endif
charlesmn 0:1da5e4bcb8e5 1508
charlesmn 0:1da5e4bcb8e5 1509
charlesmn 0:1da5e4bcb8e5 1510 #if VL6180_WRAP_AROUND_FILTER_SUPPORT
charlesmn 0:1da5e4bcb8e5 1511
charlesmn 0:1da5e4bcb8e5 1512 #define PRESERVE_DEVICE_ERROR_CODE /* If uncommented, device error code will be preserved on top of wraparound error code, but this may lead to some error code instability like overflow error <==> RangingFilteringOnGoing error oscillations */
charlesmn 0:1da5e4bcb8e5 1513 #define SENSITIVE_FILTERING_ON_GOING /* If uncommented, filter will go back to RangingFilteringOnGoing if it must go through the std dev testing */
charlesmn 0:1da5e4bcb8e5 1514
charlesmn 0:1da5e4bcb8e5 1515 #define FILTER_STDDEV_SAMPLES 6
charlesmn 0:1da5e4bcb8e5 1516 #define MIN_FILTER_STDDEV_SAMPLES 3
charlesmn 0:1da5e4bcb8e5 1517 #define MIN_FILTER_STDDEV_SAMPLES_AFTER_FLUSH_OR_BYPASS 5
charlesmn 0:1da5e4bcb8e5 1518 #define STDDEV_BASE_VALUE 150
charlesmn 0:1da5e4bcb8e5 1519
charlesmn 0:1da5e4bcb8e5 1520 #define FILTER_INVALID_DISTANCE 65535
charlesmn 0:1da5e4bcb8e5 1521
charlesmn 0:1da5e4bcb8e5 1522 #define _FilterData(field) VL6180DevDataGet(dev, FilterData.field)
charlesmn 0:1da5e4bcb8e5 1523 /*
charlesmn 0:1da5e4bcb8e5 1524 * One time init
charlesmn 0:1da5e4bcb8e5 1525 */
charlesmn 0:1da5e4bcb8e5 1526 int _filter_Init(VL6180Dev_t dev)
charlesmn 0:1da5e4bcb8e5 1527 {
charlesmn 0:1da5e4bcb8e5 1528 int i;
charlesmn 0:1da5e4bcb8e5 1529 _FilterData(MeasurementIndex) = 0;
charlesmn 0:1da5e4bcb8e5 1530
charlesmn 0:1da5e4bcb8e5 1531 _FilterData(Default_ZeroVal) = 0;
charlesmn 0:1da5e4bcb8e5 1532 _FilterData(Default_VAVGVal) = 0;
charlesmn 0:1da5e4bcb8e5 1533 _FilterData(NoDelay_ZeroVal) = 0;
charlesmn 0:1da5e4bcb8e5 1534 _FilterData(NoDelay_VAVGVal) = 0;
charlesmn 0:1da5e4bcb8e5 1535 _FilterData(Previous_VAVGDiff) = 0;
charlesmn 0:1da5e4bcb8e5 1536
charlesmn 0:1da5e4bcb8e5 1537 _FilterData(StdFilteredReads) = 0;
charlesmn 0:1da5e4bcb8e5 1538 _FilterData(FilteringOnGoingConsecutiveStates) = 0;
charlesmn 0:1da5e4bcb8e5 1539
charlesmn 0:1da5e4bcb8e5 1540 for (i = 0; i < FILTER_NBOF_SAMPLES; i++) {
charlesmn 0:1da5e4bcb8e5 1541 _FilterData(LastTrueRange)[i] = FILTER_INVALID_DISTANCE;
charlesmn 0:1da5e4bcb8e5 1542 _FilterData(LastReturnRates)[i] = 0;
charlesmn 0:1da5e4bcb8e5 1543 }
charlesmn 0:1da5e4bcb8e5 1544 _FilterData(MeasurementsSinceLastFlush)=0;
charlesmn 0:1da5e4bcb8e5 1545 return 0;
charlesmn 0:1da5e4bcb8e5 1546 }
charlesmn 0:1da5e4bcb8e5 1547
charlesmn 0:1da5e4bcb8e5 1548
charlesmn 0:1da5e4bcb8e5 1549 static uint32_t _filter_StdDevDamper(uint32_t AmbientRate,
charlesmn 0:1da5e4bcb8e5 1550 uint32_t SignalRate,
charlesmn 0:1da5e4bcb8e5 1551 const uint32_t StdDevLimitLowLight,
charlesmn 0:1da5e4bcb8e5 1552 const uint32_t StdDevLimitLowLightSNR,
charlesmn 0:1da5e4bcb8e5 1553 const uint32_t StdDevLimitHighLight,
charlesmn 0:1da5e4bcb8e5 1554 const uint32_t StdDevLimitHighLightSNR)
charlesmn 0:1da5e4bcb8e5 1555 {
charlesmn 0:1da5e4bcb8e5 1556 uint32_t newStdDev;
charlesmn 0:1da5e4bcb8e5 1557 uint16_t SNR;
charlesmn 0:1da5e4bcb8e5 1558
charlesmn 0:1da5e4bcb8e5 1559 if (AmbientRate > 0)
charlesmn 0:1da5e4bcb8e5 1560 SNR = (uint16_t) ((100 * SignalRate) / AmbientRate);
charlesmn 0:1da5e4bcb8e5 1561 else
charlesmn 0:1da5e4bcb8e5 1562 SNR = 9999;
charlesmn 0:1da5e4bcb8e5 1563
charlesmn 0:1da5e4bcb8e5 1564 if (SNR >= StdDevLimitLowLightSNR) {
charlesmn 0:1da5e4bcb8e5 1565 newStdDev = StdDevLimitLowLight;
charlesmn 0:1da5e4bcb8e5 1566 } else {
charlesmn 0:1da5e4bcb8e5 1567 if (SNR <= StdDevLimitHighLightSNR)
charlesmn 0:1da5e4bcb8e5 1568 newStdDev = StdDevLimitHighLight;
charlesmn 0:1da5e4bcb8e5 1569 else {
charlesmn 0:1da5e4bcb8e5 1570 newStdDev = (uint32_t)(StdDevLimitHighLight -
charlesmn 0:1da5e4bcb8e5 1571 (SNR - StdDevLimitHighLightSNR) *
charlesmn 0:1da5e4bcb8e5 1572 (StdDevLimitHighLight - StdDevLimitLowLight) /
charlesmn 0:1da5e4bcb8e5 1573 (StdDevLimitLowLightSNR - StdDevLimitHighLightSNR));
charlesmn 0:1da5e4bcb8e5 1574 }
charlesmn 0:1da5e4bcb8e5 1575 }
charlesmn 0:1da5e4bcb8e5 1576
charlesmn 0:1da5e4bcb8e5 1577 return newStdDev;
charlesmn 0:1da5e4bcb8e5 1578 }
charlesmn 0:1da5e4bcb8e5 1579
charlesmn 0:1da5e4bcb8e5 1580
charlesmn 0:1da5e4bcb8e5 1581 /*
charlesmn 0:1da5e4bcb8e5 1582 * Return <0 on error
charlesmn 0:1da5e4bcb8e5 1583 */
charlesmn 0:1da5e4bcb8e5 1584 static int32_t _filter_Start(VL6180Dev_t dev,
charlesmn 0:1da5e4bcb8e5 1585 uint16_t m_trueRange_mm,
charlesmn 0:1da5e4bcb8e5 1586 uint16_t m_rawRange_mm,
charlesmn 0:1da5e4bcb8e5 1587 uint32_t m_rtnSignalRate,
charlesmn 0:1da5e4bcb8e5 1588 uint32_t m_rtnAmbientRate,
charlesmn 0:1da5e4bcb8e5 1589 uint16_t errorCode)
charlesmn 0:1da5e4bcb8e5 1590 {
charlesmn 0:1da5e4bcb8e5 1591 int status;
charlesmn 0:1da5e4bcb8e5 1592 uint16_t m_newTrueRange_mm = 0;
charlesmn 0:1da5e4bcb8e5 1593 #if VL6180_HAVE_MULTI_READ
charlesmn 0:1da5e4bcb8e5 1594 uint8_t MultiReadBuf[8];
charlesmn 0:1da5e4bcb8e5 1595 #endif
charlesmn 0:1da5e4bcb8e5 1596 uint16_t i;
charlesmn 0:1da5e4bcb8e5 1597 uint16_t bypassFilter = 0;
charlesmn 0:1da5e4bcb8e5 1598 uint16_t resetVAVGData = 1;
charlesmn 0:1da5e4bcb8e5 1599
charlesmn 0:1da5e4bcb8e5 1600 uint16_t filterErrorCode = NoError;
charlesmn 0:1da5e4bcb8e5 1601 uint16_t filterErrorCodeOnRangingErrorCode = NoError;
charlesmn 0:1da5e4bcb8e5 1602
charlesmn 0:1da5e4bcb8e5 1603 uint16_t registerValue;
charlesmn 0:1da5e4bcb8e5 1604
charlesmn 0:1da5e4bcb8e5 1605 uint32_t register32BitsValue1;
charlesmn 0:1da5e4bcb8e5 1606 uint32_t register32BitsValue2;
charlesmn 0:1da5e4bcb8e5 1607
charlesmn 0:1da5e4bcb8e5 1608 uint16_t ValidDistance = 0;
charlesmn 0:1da5e4bcb8e5 1609 uint16_t SuspicuousRangingZone = 0;
charlesmn 0:1da5e4bcb8e5 1610
charlesmn 0:1da5e4bcb8e5 1611 uint16_t WrapAroundFlag = 0;
charlesmn 0:1da5e4bcb8e5 1612 uint16_t NoWrapAroundFlag = 0;
charlesmn 0:1da5e4bcb8e5 1613 uint16_t NoWrapAroundHighConfidenceFlag = 0;
charlesmn 0:1da5e4bcb8e5 1614
charlesmn 0:1da5e4bcb8e5 1615 uint16_t FlushFilter = 0;
charlesmn 0:1da5e4bcb8e5 1616 uint32_t RateChange = 0;
charlesmn 0:1da5e4bcb8e5 1617
charlesmn 0:1da5e4bcb8e5 1618 uint16_t StdDevSamplesMinNeeded = 0;
charlesmn 0:1da5e4bcb8e5 1619 uint16_t StdDevSamples = 0;
charlesmn 0:1da5e4bcb8e5 1620 uint32_t StdDevDistanceSum = 0;
charlesmn 0:1da5e4bcb8e5 1621 uint32_t StdDevDistanceMean = 0;
charlesmn 0:1da5e4bcb8e5 1622 uint32_t StdDevDistance = 0;
charlesmn 0:1da5e4bcb8e5 1623 uint32_t StdDevRateSum = 0;
charlesmn 0:1da5e4bcb8e5 1624 uint32_t StdDevRateMean = 0;
charlesmn 0:1da5e4bcb8e5 1625 uint32_t StdDevRate = 0;
charlesmn 0:1da5e4bcb8e5 1626 uint32_t StdDevLimitWithTargetMove = 0;
charlesmn 0:1da5e4bcb8e5 1627
charlesmn 0:1da5e4bcb8e5 1628 uint32_t VAVGDiff;
charlesmn 0:1da5e4bcb8e5 1629 uint32_t IdealVAVGDiff;
charlesmn 0:1da5e4bcb8e5 1630 uint32_t MinVAVGDiff;
charlesmn 0:1da5e4bcb8e5 1631 uint32_t MaxVAVGDiff;
charlesmn 0:1da5e4bcb8e5 1632
charlesmn 0:1da5e4bcb8e5 1633 /* Filter Parameters */
charlesmn 0:1da5e4bcb8e5 1634 static const uint16_t ROMABLE_DATA WrapAroundLowRawRangeLimit = 60;
charlesmn 0:1da5e4bcb8e5 1635 static const uint32_t ROMABLE_DATA WrapAroundLowReturnRateLimit_ROM = 800;
charlesmn 0:1da5e4bcb8e5 1636 /* Shall be adapted depending on crossTalk */
charlesmn 0:1da5e4bcb8e5 1637 static const uint16_t ROMABLE_DATA WrapAroundLowRawRangeLimit2 = 165;
charlesmn 0:1da5e4bcb8e5 1638 static const uint32_t ROMABLE_DATA WrapAroundLowReturnRateLimit2_ROM = 180;
charlesmn 0:1da5e4bcb8e5 1639 /* Shall be adapted depending on crossTalk and device sensitivity*/
charlesmn 0:1da5e4bcb8e5 1640 static const uint32_t ROMABLE_DATA WrapAroundLowRawRangeLimit2SuspicuousAddedSignalRate = 150;
charlesmn 0:1da5e4bcb8e5 1641
charlesmn 0:1da5e4bcb8e5 1642
charlesmn 0:1da5e4bcb8e5 1643 static const uint32_t ROMABLE_DATA WrapAroundLowReturnRateFilterLimit_ROM = 850;
charlesmn 0:1da5e4bcb8e5 1644 /* Shall be adapted depending on crossTalk and device sensitivity*/
charlesmn 0:1da5e4bcb8e5 1645 static const uint16_t ROMABLE_DATA WrapAroundHighRawRangeFilterLimit = 350;
charlesmn 0:1da5e4bcb8e5 1646 static const uint32_t ROMABLE_DATA WrapAroundHighReturnRateFilterLimit_ROM = 1400;
charlesmn 0:1da5e4bcb8e5 1647 /* Shall be adapted depending on crossTalk and device sensitivity*/
charlesmn 0:1da5e4bcb8e5 1648
charlesmn 0:1da5e4bcb8e5 1649 static const uint32_t ROMABLE_DATA WrapAroundMaximumAmbientRateFilterLimit = 15000;
charlesmn 0:1da5e4bcb8e5 1650
charlesmn 0:1da5e4bcb8e5 1651 /* Temporal filter data and flush values */
charlesmn 0:1da5e4bcb8e5 1652 static const uint32_t ROMABLE_DATA MinReturnRateFilterFlush = 75;
charlesmn 0:1da5e4bcb8e5 1653 static const uint32_t ROMABLE_DATA MaxReturnRateChangeFilterFlush = 50;
charlesmn 0:1da5e4bcb8e5 1654
charlesmn 0:1da5e4bcb8e5 1655 /* STDDEV values and damper values */
charlesmn 0:1da5e4bcb8e5 1656 static const uint32_t ROMABLE_DATA StdDevLimitLowLight = STDDEV_BASE_VALUE;
charlesmn 0:1da5e4bcb8e5 1657 static const uint32_t ROMABLE_DATA StdDevLimitLowLightSNR = 30; /* 0.3 */
charlesmn 0:1da5e4bcb8e5 1658 static const uint32_t ROMABLE_DATA StdDevLimitHighLight = STDDEV_BASE_VALUE*6;
charlesmn 0:1da5e4bcb8e5 1659 static const uint32_t ROMABLE_DATA StdDevLimitHighLightSNR = 5; /* 0.05 */
charlesmn 0:1da5e4bcb8e5 1660
charlesmn 0:1da5e4bcb8e5 1661 static const uint32_t ROMABLE_DATA StdDevHighConfidenceSNRLimit = 8;
charlesmn 0:1da5e4bcb8e5 1662 static const uint32_t ROMABLE_DATA StdDevNoWrapDetectedMultiplier = 4;
charlesmn 0:1da5e4bcb8e5 1663
charlesmn 0:1da5e4bcb8e5 1664 static const uint32_t ROMABLE_DATA StdDevMovingTargetStdDevLimit = 90000;
charlesmn 0:1da5e4bcb8e5 1665
charlesmn 0:1da5e4bcb8e5 1666 static const uint32_t ROMABLE_DATA StdDevMovingTargetReturnRateLimit = 3500;
charlesmn 0:1da5e4bcb8e5 1667 static const uint32_t ROMABLE_DATA StdDevMovingTargetStdDevForReturnRateLimit = STDDEV_BASE_VALUE*25;
charlesmn 0:1da5e4bcb8e5 1668
charlesmn 0:1da5e4bcb8e5 1669 static const uint32_t ROMABLE_DATA MAX_VAVGDiff_ROM = 1800;
charlesmn 0:1da5e4bcb8e5 1670 static const uint32_t ROMABLE_DATA SuspicuousMAX_VAVGDiffRatio = 2;
charlesmn 0:1da5e4bcb8e5 1671
charlesmn 0:1da5e4bcb8e5 1672 /* WrapAroundDetection variables */
charlesmn 0:1da5e4bcb8e5 1673 static const uint16_t ROMABLE_DATA WrapAroundNoDelayCheckPeriod = 2;
charlesmn 0:1da5e4bcb8e5 1674 static const uint16_t ROMABLE_DATA StdFilteredReadsIncrement = 2;
charlesmn 0:1da5e4bcb8e5 1675 static const uint16_t ROMABLE_DATA StdFilteredReadsDecrement = 1;
charlesmn 0:1da5e4bcb8e5 1676 static const uint16_t ROMABLE_DATA StdMaxFilteredReads = 4;
charlesmn 0:1da5e4bcb8e5 1677
charlesmn 0:1da5e4bcb8e5 1678 uint32_t SignalRateDMax;
charlesmn 0:1da5e4bcb8e5 1679 uint32_t WrapAroundLowReturnRateLimit;
charlesmn 0:1da5e4bcb8e5 1680 uint32_t WrapAroundLowReturnRateLimit2;
charlesmn 0:1da5e4bcb8e5 1681 uint32_t WrapAroundLowReturnRateFilterLimit;
charlesmn 0:1da5e4bcb8e5 1682 uint32_t WrapAroundHighReturnRateFilterLimit;
charlesmn 0:1da5e4bcb8e5 1683
charlesmn 0:1da5e4bcb8e5 1684 uint32_t MAX_VAVGDiff = 1800;
charlesmn 0:1da5e4bcb8e5 1685
charlesmn 0:1da5e4bcb8e5 1686 uint8_t u8;//, u8_2;
charlesmn 0:1da5e4bcb8e5 1687 uint32_t XTalkCompRate_KCps;
charlesmn 0:1da5e4bcb8e5 1688 uint32_t StdDevLimit = 300;
charlesmn 0:1da5e4bcb8e5 1689 uint32_t MaxOrInvalidDistance = 255*_GetUpscale(dev);
charlesmn 0:1da5e4bcb8e5 1690 /* #define MaxOrInvalidDistance (uint16_t) (255 * 3) */
charlesmn 0:1da5e4bcb8e5 1691
charlesmn 0:1da5e4bcb8e5 1692 /* Check if distance is Valid or not */
charlesmn 0:1da5e4bcb8e5 1693 switch (errorCode) {
charlesmn 0:1da5e4bcb8e5 1694 case Raw_Ranging_Algo_Underflow:
charlesmn 0:1da5e4bcb8e5 1695 case Ranging_Algo_Underflow:
charlesmn 0:1da5e4bcb8e5 1696 filterErrorCodeOnRangingErrorCode = RangingFiltered; /* If we have to go through filter, mean we have here a wraparound case */
charlesmn 0:1da5e4bcb8e5 1697 ValidDistance = 0;
charlesmn 0:1da5e4bcb8e5 1698 break;
charlesmn 0:1da5e4bcb8e5 1699 case Raw_Ranging_Algo_Overflow:
charlesmn 0:1da5e4bcb8e5 1700 case Ranging_Algo_Overflow:
charlesmn 0:1da5e4bcb8e5 1701 filterErrorCodeOnRangingErrorCode = RangingFiltered; /* If we have to go through filter, mean we have here a wraparound case */
charlesmn 0:1da5e4bcb8e5 1702 //m_trueRange_mm = MaxOrInvalidDistance;
charlesmn 0:1da5e4bcb8e5 1703 m_trueRange_mm = 200*_GetUpscale(dev);
charlesmn 0:1da5e4bcb8e5 1704 ValidDistance = 1;
charlesmn 0:1da5e4bcb8e5 1705 break;
charlesmn 0:1da5e4bcb8e5 1706 default:
charlesmn 0:1da5e4bcb8e5 1707 if (m_rawRange_mm >= MaxOrInvalidDistance) {
charlesmn 0:1da5e4bcb8e5 1708 ValidDistance = 0;
charlesmn 0:1da5e4bcb8e5 1709 bypassFilter = 1; /* Bypass the filter in this case as produced distance is not usable (and also the VAVGVal and ZeroVal values) */
charlesmn 0:1da5e4bcb8e5 1710 } else {
charlesmn 0:1da5e4bcb8e5 1711 ValidDistance = 1;
charlesmn 0:1da5e4bcb8e5 1712 }
charlesmn 0:1da5e4bcb8e5 1713 break;
charlesmn 0:1da5e4bcb8e5 1714 }
charlesmn 0:1da5e4bcb8e5 1715 m_newTrueRange_mm = m_trueRange_mm;
charlesmn 0:1da5e4bcb8e5 1716
charlesmn 0:1da5e4bcb8e5 1717 XTalkCompRate_KCps = VL6180DevDataGet(dev, XTalkCompRate_KCps);
charlesmn 0:1da5e4bcb8e5 1718
charlesmn 0:1da5e4bcb8e5 1719 /* Update signal rate limits depending on crosstalk */
charlesmn 0:1da5e4bcb8e5 1720 SignalRateDMax = (uint32_t)_GetDMaxDataRetSignalAt400mm(dev) ;
charlesmn 0:1da5e4bcb8e5 1721 WrapAroundLowReturnRateLimit = WrapAroundLowReturnRateLimit_ROM + XTalkCompRate_KCps;
charlesmn 0:1da5e4bcb8e5 1722 WrapAroundLowReturnRateLimit2 = ((WrapAroundLowReturnRateLimit2_ROM *
charlesmn 0:1da5e4bcb8e5 1723 SignalRateDMax) / 312) +
charlesmn 0:1da5e4bcb8e5 1724 XTalkCompRate_KCps;
charlesmn 0:1da5e4bcb8e5 1725 WrapAroundLowReturnRateFilterLimit = ((WrapAroundLowReturnRateFilterLimit_ROM *
charlesmn 0:1da5e4bcb8e5 1726 SignalRateDMax) / 312) + XTalkCompRate_KCps;
charlesmn 0:1da5e4bcb8e5 1727 WrapAroundHighReturnRateFilterLimit = ((WrapAroundHighReturnRateFilterLimit_ROM *
charlesmn 0:1da5e4bcb8e5 1728 SignalRateDMax) / 312) + XTalkCompRate_KCps;
charlesmn 0:1da5e4bcb8e5 1729
charlesmn 0:1da5e4bcb8e5 1730
charlesmn 0:1da5e4bcb8e5 1731 /* Checks on low range data */
charlesmn 0:1da5e4bcb8e5 1732 if ((m_rawRange_mm < WrapAroundLowRawRangeLimit) && (m_rtnSignalRate < WrapAroundLowReturnRateLimit)) {
charlesmn 0:1da5e4bcb8e5 1733 filterErrorCode = RangingFiltered; /* On this condition, wraparound case is ensured */
charlesmn 0:1da5e4bcb8e5 1734 bypassFilter = 1;
charlesmn 0:1da5e4bcb8e5 1735 }
charlesmn 0:1da5e4bcb8e5 1736 if ((m_rawRange_mm < WrapAroundLowRawRangeLimit2) && (m_rtnSignalRate < WrapAroundLowReturnRateLimit2)) {
charlesmn 0:1da5e4bcb8e5 1737 filterErrorCode = RangingFiltered; /* On this condition, wraparound case is ensured */
charlesmn 0:1da5e4bcb8e5 1738 bypassFilter = 1;
charlesmn 0:1da5e4bcb8e5 1739 }
charlesmn 0:1da5e4bcb8e5 1740 if ((m_rawRange_mm < WrapAroundLowRawRangeLimit2) && (m_rtnSignalRate < (WrapAroundLowReturnRateLimit2 + WrapAroundLowRawRangeLimit2SuspicuousAddedSignalRate))) {
charlesmn 0:1da5e4bcb8e5 1741 SuspicuousRangingZone = 1; /* On this area, we are in an highly suspicuous wraparound ares, filter parameter will be stengthen */
charlesmn 0:1da5e4bcb8e5 1742 }
charlesmn 0:1da5e4bcb8e5 1743
charlesmn 0:1da5e4bcb8e5 1744
charlesmn 0:1da5e4bcb8e5 1745 /* Checks on Ambient rate level */
charlesmn 0:1da5e4bcb8e5 1746 if (m_rtnAmbientRate > WrapAroundMaximumAmbientRateFilterLimit) {
charlesmn 0:1da5e4bcb8e5 1747 /* Too high ambient rate */
charlesmn 0:1da5e4bcb8e5 1748 FlushFilter = 1;
charlesmn 0:1da5e4bcb8e5 1749 bypassFilter = 1;
charlesmn 0:1da5e4bcb8e5 1750 }
charlesmn 0:1da5e4bcb8e5 1751
charlesmn 0:1da5e4bcb8e5 1752 /* Checks on Filter flush */
charlesmn 0:1da5e4bcb8e5 1753 if (m_rtnSignalRate < MinReturnRateFilterFlush) {
charlesmn 0:1da5e4bcb8e5 1754 /* Completely lost target, so flush the filter */
charlesmn 0:1da5e4bcb8e5 1755 FlushFilter = 1;
charlesmn 0:1da5e4bcb8e5 1756 bypassFilter = 1;
charlesmn 0:1da5e4bcb8e5 1757 }
charlesmn 0:1da5e4bcb8e5 1758 if (_FilterData(LastReturnRates)[0] != 0) {
charlesmn 0:1da5e4bcb8e5 1759 if (m_rtnSignalRate > _FilterData(LastReturnRates)[0])
charlesmn 0:1da5e4bcb8e5 1760 RateChange = (100 *
charlesmn 0:1da5e4bcb8e5 1761 (m_rtnSignalRate - _FilterData(LastReturnRates)[0])) /
charlesmn 0:1da5e4bcb8e5 1762 _FilterData(LastReturnRates)[0];
charlesmn 0:1da5e4bcb8e5 1763 else
charlesmn 0:1da5e4bcb8e5 1764 RateChange = (100 *
charlesmn 0:1da5e4bcb8e5 1765 (_FilterData(LastReturnRates)[0] - m_rtnSignalRate)) /
charlesmn 0:1da5e4bcb8e5 1766 _FilterData(LastReturnRates)[0];
charlesmn 0:1da5e4bcb8e5 1767 } else
charlesmn 0:1da5e4bcb8e5 1768 RateChange = 0;
charlesmn 0:1da5e4bcb8e5 1769 if (RateChange > MaxReturnRateChangeFilterFlush) {
charlesmn 0:1da5e4bcb8e5 1770 FlushFilter = 1;
charlesmn 0:1da5e4bcb8e5 1771 }
charlesmn 0:1da5e4bcb8e5 1772 /* TODO optimize filter using circular buffer */
charlesmn 0:1da5e4bcb8e5 1773 if (FlushFilter == 1) {
charlesmn 0:1da5e4bcb8e5 1774 _FilterData(MeasurementIndex) = 0;
charlesmn 0:1da5e4bcb8e5 1775 for (i = 0; i < FILTER_NBOF_SAMPLES; i++) {
charlesmn 0:1da5e4bcb8e5 1776 _FilterData(LastTrueRange)[i] = FILTER_INVALID_DISTANCE;
charlesmn 0:1da5e4bcb8e5 1777 _FilterData(LastReturnRates)[i] = 0;
charlesmn 0:1da5e4bcb8e5 1778 }
charlesmn 0:1da5e4bcb8e5 1779 _FilterData(MeasurementsSinceLastFlush)=0;
charlesmn 0:1da5e4bcb8e5 1780 } else {
charlesmn 0:1da5e4bcb8e5 1781 for (i = (uint16_t) (FILTER_NBOF_SAMPLES - 1); i > 0; i--) {
charlesmn 0:1da5e4bcb8e5 1782 _FilterData(LastTrueRange)[i] = _FilterData(LastTrueRange)[i - 1];
charlesmn 0:1da5e4bcb8e5 1783 _FilterData(LastReturnRates)[i] = _FilterData(LastReturnRates)[i - 1];
charlesmn 0:1da5e4bcb8e5 1784 }
charlesmn 0:1da5e4bcb8e5 1785 }
charlesmn 0:1da5e4bcb8e5 1786
charlesmn 0:1da5e4bcb8e5 1787 if (ValidDistance == 1)
charlesmn 0:1da5e4bcb8e5 1788 _FilterData(LastTrueRange)[0] = m_trueRange_mm;
charlesmn 0:1da5e4bcb8e5 1789 else
charlesmn 0:1da5e4bcb8e5 1790 _FilterData(LastTrueRange)[0] = FILTER_INVALID_DISTANCE;
charlesmn 0:1da5e4bcb8e5 1791 _FilterData(LastReturnRates)[0] = m_rtnSignalRate;
charlesmn 0:1da5e4bcb8e5 1792 _FilterData(MeasurementsSinceLastFlush)++;
charlesmn 0:1da5e4bcb8e5 1793
charlesmn 0:1da5e4bcb8e5 1794 /* Check if we need to go through the filter or not */
charlesmn 0:1da5e4bcb8e5 1795 if (!(((m_rawRange_mm < WrapAroundHighRawRangeFilterLimit) &&
charlesmn 0:1da5e4bcb8e5 1796 (m_rtnSignalRate < WrapAroundLowReturnRateFilterLimit)) ||
charlesmn 0:1da5e4bcb8e5 1797 ((m_rawRange_mm >= WrapAroundHighRawRangeFilterLimit) &&
charlesmn 0:1da5e4bcb8e5 1798 (m_rtnSignalRate < WrapAroundHighReturnRateFilterLimit))))
charlesmn 0:1da5e4bcb8e5 1799 bypassFilter = 1;
charlesmn 0:1da5e4bcb8e5 1800 else {
charlesmn 0:1da5e4bcb8e5 1801 /* if some wraparound filtering due to some ranging error code has been detected, update the filter status and bypass the filter */
charlesmn 0:1da5e4bcb8e5 1802 if(filterErrorCodeOnRangingErrorCode!=NoError){
charlesmn 0:1da5e4bcb8e5 1803 #ifndef PRESERVE_DEVICE_ERROR_CODE
charlesmn 0:1da5e4bcb8e5 1804 filterErrorCode = filterErrorCodeOnRangingErrorCode;
charlesmn 0:1da5e4bcb8e5 1805 #else
charlesmn 0:1da5e4bcb8e5 1806 if((errorCode==Raw_Ranging_Algo_Underflow) || (errorCode==Ranging_Algo_Underflow)) {
charlesmn 0:1da5e4bcb8e5 1807 /* Preserves the error codes except for Raw_Ranging_Algo_Underflow and Ranging_Algo_Underflow */
charlesmn 0:1da5e4bcb8e5 1808 filterErrorCode = filterErrorCodeOnRangingErrorCode;
charlesmn 0:1da5e4bcb8e5 1809 }
charlesmn 0:1da5e4bcb8e5 1810 #endif
charlesmn 0:1da5e4bcb8e5 1811 bypassFilter = 1;
charlesmn 0:1da5e4bcb8e5 1812 resetVAVGData = 0;
charlesmn 0:1da5e4bcb8e5 1813 }
charlesmn 0:1da5e4bcb8e5 1814 }
charlesmn 0:1da5e4bcb8e5 1815
charlesmn 0:1da5e4bcb8e5 1816 /* Check which kind of measurement has been made */
charlesmn 0:1da5e4bcb8e5 1817 status = VL6180_RdByte(dev, 0x01AC, &u8);
charlesmn 0:1da5e4bcb8e5 1818 if (status) {
charlesmn 0:1da5e4bcb8e5 1819 VL6180_ErrLog("0x01AC rd fail");
charlesmn 0:1da5e4bcb8e5 1820 goto done_err;
charlesmn 0:1da5e4bcb8e5 1821 }
charlesmn 0:1da5e4bcb8e5 1822 registerValue = u8;
charlesmn 0:1da5e4bcb8e5 1823
charlesmn 0:1da5e4bcb8e5 1824 /* Read data for filtering */
charlesmn 0:1da5e4bcb8e5 1825 #if VL6180_HAVE_MULTI_READ
charlesmn 0:1da5e4bcb8e5 1826 status = VL6180_RdMulti(dev, 0x10C, MultiReadBuf, 8); /* read only 8 lsb bits */
charlesmn 0:1da5e4bcb8e5 1827 if (status) {
charlesmn 0:1da5e4bcb8e5 1828 VL6180_ErrLog("0x10C multi rd fail");
charlesmn 0:1da5e4bcb8e5 1829 goto done_err;
charlesmn 0:1da5e4bcb8e5 1830 }
charlesmn 0:1da5e4bcb8e5 1831 register32BitsValue1 = ((uint32_t) MultiReadBuf[0] << 24)
charlesmn 0:1da5e4bcb8e5 1832 + ((uint32_t) MultiReadBuf[1] << 16)
charlesmn 0:1da5e4bcb8e5 1833 + ((uint32_t) MultiReadBuf[2] << 8)
charlesmn 0:1da5e4bcb8e5 1834 + ((uint32_t) MultiReadBuf[3] << 0);
charlesmn 0:1da5e4bcb8e5 1835 register32BitsValue2 = ((uint32_t) MultiReadBuf[4] << 24)
charlesmn 0:1da5e4bcb8e5 1836 + ((uint32_t) MultiReadBuf[5] << 16)
charlesmn 0:1da5e4bcb8e5 1837 + ((uint32_t) MultiReadBuf[6] << 8)
charlesmn 0:1da5e4bcb8e5 1838 + ((uint32_t) MultiReadBuf[7] << 0);
charlesmn 0:1da5e4bcb8e5 1839 #else
charlesmn 0:1da5e4bcb8e5 1840 status = VL6180_RdDWord(dev, 0x10C, &register32BitsValue1); /* read 32 bits, lower 17 bits are the one useful */
charlesmn 0:1da5e4bcb8e5 1841 if (status) {
charlesmn 0:1da5e4bcb8e5 1842 VL6180_ErrLog("0x010C rd fail");
charlesmn 0:1da5e4bcb8e5 1843 goto done_err;
charlesmn 0:1da5e4bcb8e5 1844 }
charlesmn 0:1da5e4bcb8e5 1845 status = VL6180_RdDWord(dev, 0x0110, & register32BitsValue2); /* read 32 bits, lower 17 bits are the one useful */
charlesmn 0:1da5e4bcb8e5 1846 if (status) {
charlesmn 0:1da5e4bcb8e5 1847 VL6180_ErrLog("0x0110 rd fail");
charlesmn 0:1da5e4bcb8e5 1848 goto done_err;
charlesmn 0:1da5e4bcb8e5 1849 }
charlesmn 0:1da5e4bcb8e5 1850 #endif
charlesmn 0:1da5e4bcb8e5 1851
charlesmn 0:1da5e4bcb8e5 1852
charlesmn 0:1da5e4bcb8e5 1853 if ((FlushFilter == 1) || ((bypassFilter == 1) && (resetVAVGData == 1))) {
charlesmn 0:1da5e4bcb8e5 1854 if (registerValue != 0x3E) {
charlesmn 0:1da5e4bcb8e5 1855 status = VL6180_WrByte(dev, 0x1AC, 0x3E);
charlesmn 0:1da5e4bcb8e5 1856 if (status) {
charlesmn 0:1da5e4bcb8e5 1857 VL6180_ErrLog("0x01AC bypass wr fail");
charlesmn 0:1da5e4bcb8e5 1858 goto done_err;
charlesmn 0:1da5e4bcb8e5 1859 }
charlesmn 0:1da5e4bcb8e5 1860 //status = VL6180_WrByte(dev, 0x0F2, 0x01);
charlesmn 0:1da5e4bcb8e5 1861 //if (status) {
charlesmn 0:1da5e4bcb8e5 1862 // VL6180_ErrLog("0x0F2 bypass wr fail");
charlesmn 0:1da5e4bcb8e5 1863 // goto done_err;
charlesmn 0:1da5e4bcb8e5 1864 //}
charlesmn 0:1da5e4bcb8e5 1865 }
charlesmn 0:1da5e4bcb8e5 1866 /* Set both Default and NoDelay To same value */
charlesmn 0:1da5e4bcb8e5 1867 _FilterData(Default_ZeroVal) = register32BitsValue1;
charlesmn 0:1da5e4bcb8e5 1868 _FilterData(Default_VAVGVal) = register32BitsValue2;
charlesmn 0:1da5e4bcb8e5 1869 _FilterData(NoDelay_ZeroVal) = register32BitsValue1;
charlesmn 0:1da5e4bcb8e5 1870 _FilterData(NoDelay_VAVGVal) = register32BitsValue2;
charlesmn 0:1da5e4bcb8e5 1871
charlesmn 0:1da5e4bcb8e5 1872 _FilterData(MeasurementIndex) = 0;
charlesmn 0:1da5e4bcb8e5 1873 } else {
charlesmn 0:1da5e4bcb8e5 1874 if (registerValue == 0x3E) {
charlesmn 0:1da5e4bcb8e5 1875 _FilterData(Default_ZeroVal) = register32BitsValue1;
charlesmn 0:1da5e4bcb8e5 1876 _FilterData(Default_VAVGVal) = register32BitsValue2;
charlesmn 0:1da5e4bcb8e5 1877 } else {
charlesmn 0:1da5e4bcb8e5 1878 _FilterData(NoDelay_ZeroVal) = register32BitsValue1;
charlesmn 0:1da5e4bcb8e5 1879 _FilterData(NoDelay_VAVGVal) = register32BitsValue2;
charlesmn 0:1da5e4bcb8e5 1880 }
charlesmn 0:1da5e4bcb8e5 1881
charlesmn 0:1da5e4bcb8e5 1882 if (_FilterData(MeasurementIndex) % WrapAroundNoDelayCheckPeriod == 0) {
charlesmn 0:1da5e4bcb8e5 1883 u8 = 0x3C;
charlesmn 0:1da5e4bcb8e5 1884 //u8_2 = 0x05;
charlesmn 0:1da5e4bcb8e5 1885 } else {
charlesmn 0:1da5e4bcb8e5 1886 u8 = 0x3E;
charlesmn 0:1da5e4bcb8e5 1887 //u8_2 = 0x01;
charlesmn 0:1da5e4bcb8e5 1888 }
charlesmn 0:1da5e4bcb8e5 1889 status = VL6180_WrByte(dev, 0x01AC, u8);
charlesmn 0:1da5e4bcb8e5 1890 if (status) {
charlesmn 0:1da5e4bcb8e5 1891 VL6180_ErrLog("0x01AC wr fail");
charlesmn 0:1da5e4bcb8e5 1892 goto done_err;
charlesmn 0:1da5e4bcb8e5 1893 }
charlesmn 0:1da5e4bcb8e5 1894 //status = VL6180_WrByte(dev, 0x0F2, u8_2);
charlesmn 0:1da5e4bcb8e5 1895 //if (status) {
charlesmn 0:1da5e4bcb8e5 1896 // VL6180_ErrLog("0x0F2 wr fail");
charlesmn 0:1da5e4bcb8e5 1897 // goto done_err;
charlesmn 0:1da5e4bcb8e5 1898 //}
charlesmn 0:1da5e4bcb8e5 1899 _FilterData(MeasurementIndex)++;
charlesmn 0:1da5e4bcb8e5 1900 }
charlesmn 0:1da5e4bcb8e5 1901
charlesmn 0:1da5e4bcb8e5 1902 if (bypassFilter == 1) {
charlesmn 0:1da5e4bcb8e5 1903 /* Do not go through the filter */
charlesmn 0:1da5e4bcb8e5 1904
charlesmn 0:1da5e4bcb8e5 1905 /* Update filter error code */
charlesmn 0:1da5e4bcb8e5 1906 _FilterData(filterError) = filterErrorCode;
charlesmn 0:1da5e4bcb8e5 1907
charlesmn 0:1da5e4bcb8e5 1908 /* Update reported range */
charlesmn 0:1da5e4bcb8e5 1909 if(filterErrorCode==RangingFiltered)
charlesmn 0:1da5e4bcb8e5 1910 m_newTrueRange_mm = MaxOrInvalidDistance; /* Set to invalid distance */
charlesmn 0:1da5e4bcb8e5 1911
charlesmn 0:1da5e4bcb8e5 1912 return m_newTrueRange_mm;
charlesmn 0:1da5e4bcb8e5 1913 }
charlesmn 0:1da5e4bcb8e5 1914
charlesmn 0:1da5e4bcb8e5 1915 /* Computes current VAVGDiff */
charlesmn 0:1da5e4bcb8e5 1916 if (_FilterData(Default_VAVGVal) > _FilterData(NoDelay_VAVGVal))
charlesmn 0:1da5e4bcb8e5 1917 VAVGDiff = _FilterData(Default_VAVGVal) - _FilterData(NoDelay_VAVGVal);
charlesmn 0:1da5e4bcb8e5 1918 else
charlesmn 0:1da5e4bcb8e5 1919 VAVGDiff = 0;
charlesmn 0:1da5e4bcb8e5 1920 _FilterData(Previous_VAVGDiff) = VAVGDiff;
charlesmn 0:1da5e4bcb8e5 1921
charlesmn 0:1da5e4bcb8e5 1922 if(SuspicuousRangingZone==0)
charlesmn 0:1da5e4bcb8e5 1923 MAX_VAVGDiff = MAX_VAVGDiff_ROM;
charlesmn 0:1da5e4bcb8e5 1924 else
charlesmn 0:1da5e4bcb8e5 1925 /* In suspicuous area, strengthen the filter */
charlesmn 0:1da5e4bcb8e5 1926 MAX_VAVGDiff = MAX_VAVGDiff_ROM / SuspicuousMAX_VAVGDiffRatio;
charlesmn 0:1da5e4bcb8e5 1927
charlesmn 0:1da5e4bcb8e5 1928 /* Check the VAVGDiff */
charlesmn 0:1da5e4bcb8e5 1929 if (_FilterData(Default_ZeroVal) > _FilterData(NoDelay_ZeroVal))
charlesmn 0:1da5e4bcb8e5 1930 IdealVAVGDiff = _FilterData(Default_ZeroVal) - _FilterData(NoDelay_ZeroVal);
charlesmn 0:1da5e4bcb8e5 1931 else
charlesmn 0:1da5e4bcb8e5 1932 IdealVAVGDiff = _FilterData(NoDelay_ZeroVal) - _FilterData(Default_ZeroVal);
charlesmn 0:1da5e4bcb8e5 1933 if (IdealVAVGDiff > MAX_VAVGDiff)
charlesmn 0:1da5e4bcb8e5 1934 MinVAVGDiff = IdealVAVGDiff - MAX_VAVGDiff;
charlesmn 0:1da5e4bcb8e5 1935 else
charlesmn 0:1da5e4bcb8e5 1936 MinVAVGDiff = 0;
charlesmn 0:1da5e4bcb8e5 1937 MaxVAVGDiff = IdealVAVGDiff + MAX_VAVGDiff;
charlesmn 0:1da5e4bcb8e5 1938 if (VAVGDiff < MinVAVGDiff || VAVGDiff > MaxVAVGDiff) {
charlesmn 0:1da5e4bcb8e5 1939 WrapAroundFlag = 1;
charlesmn 0:1da5e4bcb8e5 1940 filterErrorCode = RangingFiltered;
charlesmn 0:1da5e4bcb8e5 1941 } else {
charlesmn 0:1da5e4bcb8e5 1942 /* Go through filtering check */
charlesmn 0:1da5e4bcb8e5 1943
charlesmn 0:1da5e4bcb8e5 1944 if(_FilterData(MeasurementIndex)<=1)
charlesmn 0:1da5e4bcb8e5 1945 /* On measurement after a bypass, uses an increase number of samples */
charlesmn 0:1da5e4bcb8e5 1946 StdDevSamplesMinNeeded = MIN_FILTER_STDDEV_SAMPLES_AFTER_FLUSH_OR_BYPASS;
charlesmn 0:1da5e4bcb8e5 1947 else
charlesmn 0:1da5e4bcb8e5 1948 StdDevSamplesMinNeeded = MIN_FILTER_STDDEV_SAMPLES;
charlesmn 0:1da5e4bcb8e5 1949
charlesmn 0:1da5e4bcb8e5 1950 /* StdDevLimit Damper on SNR */
charlesmn 0:1da5e4bcb8e5 1951 StdDevLimit = _filter_StdDevDamper(m_rtnAmbientRate, m_rtnSignalRate, StdDevLimitLowLight, StdDevLimitLowLightSNR, StdDevLimitHighLight, StdDevLimitHighLightSNR);
charlesmn 0:1da5e4bcb8e5 1952
charlesmn 0:1da5e4bcb8e5 1953 /* Standard deviations computations */
charlesmn 0:1da5e4bcb8e5 1954 StdDevSamples = 0;
charlesmn 0:1da5e4bcb8e5 1955 StdDevDistanceSum = 0;
charlesmn 0:1da5e4bcb8e5 1956 StdDevDistanceMean = 0;
charlesmn 0:1da5e4bcb8e5 1957 StdDevDistance = 0;
charlesmn 0:1da5e4bcb8e5 1958 StdDevRateSum = 0;
charlesmn 0:1da5e4bcb8e5 1959 StdDevRateMean = 0;
charlesmn 0:1da5e4bcb8e5 1960 StdDevRate = 0;
charlesmn 0:1da5e4bcb8e5 1961 for (i = 0; (i < FILTER_NBOF_SAMPLES) && (StdDevSamples < FILTER_STDDEV_SAMPLES); i++) {
charlesmn 0:1da5e4bcb8e5 1962 if (_FilterData(LastTrueRange)[i] != FILTER_INVALID_DISTANCE) {
charlesmn 0:1da5e4bcb8e5 1963 StdDevSamples = (uint16_t) (StdDevSamples + 1);
charlesmn 0:1da5e4bcb8e5 1964 StdDevDistanceSum = (uint32_t) (StdDevDistanceSum + _FilterData(LastTrueRange)[i]);
charlesmn 0:1da5e4bcb8e5 1965 StdDevRateSum = (uint32_t) (StdDevRateSum + _FilterData(LastReturnRates)[i]);
charlesmn 0:1da5e4bcb8e5 1966 }
charlesmn 0:1da5e4bcb8e5 1967 }
charlesmn 0:1da5e4bcb8e5 1968 if (StdDevSamples > 0) {
charlesmn 0:1da5e4bcb8e5 1969 StdDevDistanceMean = (uint32_t) (StdDevDistanceSum / StdDevSamples);
charlesmn 0:1da5e4bcb8e5 1970 StdDevRateMean = (uint32_t) (StdDevRateSum / StdDevSamples);
charlesmn 0:1da5e4bcb8e5 1971 }
charlesmn 0:1da5e4bcb8e5 1972 /* TODO optimize shorten Std dev in aisngle loop computation using sum of x2 - (sum of x)2 */
charlesmn 0:1da5e4bcb8e5 1973 StdDevSamples = 0;
charlesmn 0:1da5e4bcb8e5 1974 StdDevDistanceSum = 0;
charlesmn 0:1da5e4bcb8e5 1975 StdDevRateSum = 0;
charlesmn 0:1da5e4bcb8e5 1976 for (i = 0; (i < FILTER_NBOF_SAMPLES) && (StdDevSamples < FILTER_STDDEV_SAMPLES); i++) {
charlesmn 0:1da5e4bcb8e5 1977 if (_FilterData(LastTrueRange)[i] != FILTER_INVALID_DISTANCE) {
charlesmn 0:1da5e4bcb8e5 1978 StdDevSamples = (uint16_t) (StdDevSamples + 1);
charlesmn 0:1da5e4bcb8e5 1979 StdDevDistanceSum = (uint32_t) (StdDevDistanceSum +
charlesmn 0:1da5e4bcb8e5 1980 (int)(_FilterData(LastTrueRange)[i] -
charlesmn 0:1da5e4bcb8e5 1981 StdDevDistanceMean) *
charlesmn 0:1da5e4bcb8e5 1982 (int) (_FilterData(LastTrueRange)[i] -
charlesmn 0:1da5e4bcb8e5 1983 StdDevDistanceMean));
charlesmn 0:1da5e4bcb8e5 1984 StdDevRateSum = (uint32_t) (StdDevRateSum +
charlesmn 0:1da5e4bcb8e5 1985 (int) (_FilterData(LastReturnRates)[i] -
charlesmn 0:1da5e4bcb8e5 1986 StdDevRateMean) *
charlesmn 0:1da5e4bcb8e5 1987 (int) (_FilterData(LastReturnRates)[i] -
charlesmn 0:1da5e4bcb8e5 1988 StdDevRateMean));
charlesmn 0:1da5e4bcb8e5 1989 }
charlesmn 0:1da5e4bcb8e5 1990 }
charlesmn 0:1da5e4bcb8e5 1991 if (StdDevSamples >= StdDevSamplesMinNeeded) {
charlesmn 0:1da5e4bcb8e5 1992 StdDevDistance = (uint16_t) (StdDevDistanceSum / StdDevSamples);
charlesmn 0:1da5e4bcb8e5 1993 StdDevRate = (uint16_t) (StdDevRateSum / StdDevSamples);
charlesmn 0:1da5e4bcb8e5 1994 } else {
charlesmn 0:1da5e4bcb8e5 1995 StdDevDistance = 0;
charlesmn 0:1da5e4bcb8e5 1996 StdDevRate = 0;
charlesmn 0:1da5e4bcb8e5 1997 }
charlesmn 0:1da5e4bcb8e5 1998
charlesmn 0:1da5e4bcb8e5 1999 /* Check Return rate standard deviation */
charlesmn 0:1da5e4bcb8e5 2000 if (StdDevRate < StdDevMovingTargetStdDevLimit) {
charlesmn 0:1da5e4bcb8e5 2001 if (StdDevSamples < StdDevSamplesMinNeeded) {
charlesmn 0:1da5e4bcb8e5 2002 //m_newTrueRange_mm = MaxOrInvalidDistance;
charlesmn 0:1da5e4bcb8e5 2003 filterErrorCode = RangingFiltered;
charlesmn 0:1da5e4bcb8e5 2004 } else {
charlesmn 0:1da5e4bcb8e5 2005 /* Check distance standard deviation */
charlesmn 0:1da5e4bcb8e5 2006 if (StdDevRate < StdDevMovingTargetReturnRateLimit)
charlesmn 0:1da5e4bcb8e5 2007 StdDevLimitWithTargetMove = StdDevLimit +
charlesmn 0:1da5e4bcb8e5 2008 (((StdDevMovingTargetStdDevForReturnRateLimit -
charlesmn 0:1da5e4bcb8e5 2009 StdDevLimit) * StdDevRate) /
charlesmn 0:1da5e4bcb8e5 2010 StdDevMovingTargetReturnRateLimit);
charlesmn 0:1da5e4bcb8e5 2011 else
charlesmn 0:1da5e4bcb8e5 2012 StdDevLimitWithTargetMove = StdDevMovingTargetStdDevForReturnRateLimit;
charlesmn 0:1da5e4bcb8e5 2013
charlesmn 0:1da5e4bcb8e5 2014 if(_FilterData(filterError)==NoError){
charlesmn 0:1da5e4bcb8e5 2015 /* No wrapAround detected yet, so relax constraints on the std dev */
charlesmn 0:1da5e4bcb8e5 2016 StdDevLimitWithTargetMove = StdDevLimitWithTargetMove * StdDevNoWrapDetectedMultiplier;
charlesmn 0:1da5e4bcb8e5 2017 }
charlesmn 0:1da5e4bcb8e5 2018
charlesmn 0:1da5e4bcb8e5 2019 if (((StdDevDistance * StdDevHighConfidenceSNRLimit) < StdDevLimit) && (StdDevSamples>=FILTER_STDDEV_SAMPLES)) {
charlesmn 0:1da5e4bcb8e5 2020 NoWrapAroundHighConfidenceFlag = 1;
charlesmn 0:1da5e4bcb8e5 2021 } else {
charlesmn 0:1da5e4bcb8e5 2022 if (StdDevDistance < StdDevLimitWithTargetMove) {
charlesmn 0:1da5e4bcb8e5 2023 NoWrapAroundFlag = 1;
charlesmn 0:1da5e4bcb8e5 2024 } else {
charlesmn 0:1da5e4bcb8e5 2025 WrapAroundFlag = 1;
charlesmn 0:1da5e4bcb8e5 2026 filterErrorCode = RangingFiltered;
charlesmn 0:1da5e4bcb8e5 2027 }
charlesmn 0:1da5e4bcb8e5 2028 }
charlesmn 0:1da5e4bcb8e5 2029 }
charlesmn 0:1da5e4bcb8e5 2030 } else {
charlesmn 0:1da5e4bcb8e5 2031 /* Target moving too fast */
charlesmn 0:1da5e4bcb8e5 2032 WrapAroundFlag = 1;
charlesmn 0:1da5e4bcb8e5 2033 filterErrorCode = RangingFiltered;
charlesmn 0:1da5e4bcb8e5 2034 }
charlesmn 0:1da5e4bcb8e5 2035 }
charlesmn 0:1da5e4bcb8e5 2036
charlesmn 0:1da5e4bcb8e5 2037 if (ValidDistance == 0) {
charlesmn 0:1da5e4bcb8e5 2038 /* In case of invalid distance */
charlesmn 0:1da5e4bcb8e5 2039 if (_FilterData(StdFilteredReads) > 0)
charlesmn 0:1da5e4bcb8e5 2040 _FilterData(StdFilteredReads) = (uint16_t) (_FilterData(StdFilteredReads) - 1);
charlesmn 0:1da5e4bcb8e5 2041 } else {
charlesmn 0:1da5e4bcb8e5 2042 if (WrapAroundFlag == 1) {
charlesmn 0:1da5e4bcb8e5 2043 _FilterData(StdFilteredReads) = (uint16_t) (_FilterData(StdFilteredReads) +
charlesmn 0:1da5e4bcb8e5 2044 StdFilteredReadsIncrement);
charlesmn 0:1da5e4bcb8e5 2045 if (_FilterData(StdFilteredReads) > StdMaxFilteredReads)
charlesmn 0:1da5e4bcb8e5 2046 _FilterData(StdFilteredReads) = StdMaxFilteredReads;
charlesmn 0:1da5e4bcb8e5 2047 } else {
charlesmn 0:1da5e4bcb8e5 2048 if (NoWrapAroundFlag == 1) {
charlesmn 0:1da5e4bcb8e5 2049 if (_FilterData(StdFilteredReads) > 0) {
charlesmn 0:1da5e4bcb8e5 2050 filterErrorCode = RangingFiltered;
charlesmn 0:1da5e4bcb8e5 2051 if (_FilterData(StdFilteredReads) > StdFilteredReadsDecrement)
charlesmn 0:1da5e4bcb8e5 2052 _FilterData(StdFilteredReads) = (uint16_t) (_FilterData(StdFilteredReads) -
charlesmn 0:1da5e4bcb8e5 2053 StdFilteredReadsDecrement);
charlesmn 0:1da5e4bcb8e5 2054 else
charlesmn 0:1da5e4bcb8e5 2055 _FilterData(StdFilteredReads) = 0;
charlesmn 0:1da5e4bcb8e5 2056 }
charlesmn 0:1da5e4bcb8e5 2057 } else {
charlesmn 0:1da5e4bcb8e5 2058 if (NoWrapAroundHighConfidenceFlag == 1) {
charlesmn 0:1da5e4bcb8e5 2059 _FilterData(StdFilteredReads) = 0;
charlesmn 0:1da5e4bcb8e5 2060 }
charlesmn 0:1da5e4bcb8e5 2061 }
charlesmn 0:1da5e4bcb8e5 2062 }
charlesmn 0:1da5e4bcb8e5 2063 }
charlesmn 0:1da5e4bcb8e5 2064
charlesmn 0:1da5e4bcb8e5 2065 /* If we detect a change from no Error to RangingFilteringOnGoing, then it means that
charlesmn 0:1da5e4bcb8e5 2066 * the filter detected a change in te scene, so discard all previous measurements.
charlesmn 0:1da5e4bcb8e5 2067 */
charlesmn 0:1da5e4bcb8e5 2068 if((_FilterData(filterError) == NoError) && (filterErrorCode!=NoError)) {
charlesmn 0:1da5e4bcb8e5 2069 for (i = 1; i < FILTER_NBOF_SAMPLES; i++) {
charlesmn 0:1da5e4bcb8e5 2070 _FilterData(LastTrueRange)[i] = FILTER_INVALID_DISTANCE;
charlesmn 0:1da5e4bcb8e5 2071 _FilterData(LastReturnRates)[i] = 0;
charlesmn 0:1da5e4bcb8e5 2072 }
charlesmn 0:1da5e4bcb8e5 2073 }
charlesmn 0:1da5e4bcb8e5 2074
charlesmn 0:1da5e4bcb8e5 2075 /* Update filter error code */
charlesmn 0:1da5e4bcb8e5 2076 _FilterData(filterError) = filterErrorCode;
charlesmn 0:1da5e4bcb8e5 2077
charlesmn 0:1da5e4bcb8e5 2078 /* Update reported range */
charlesmn 0:1da5e4bcb8e5 2079 if(filterErrorCode==RangingFiltered)
charlesmn 0:1da5e4bcb8e5 2080 m_newTrueRange_mm = MaxOrInvalidDistance; /* Set to invalid distance */
charlesmn 0:1da5e4bcb8e5 2081
charlesmn 0:1da5e4bcb8e5 2082 return m_newTrueRange_mm;
charlesmn 0:1da5e4bcb8e5 2083 done_err:
charlesmn 0:1da5e4bcb8e5 2084 return -1;
charlesmn 0:1da5e4bcb8e5 2085
charlesmn 0:1da5e4bcb8e5 2086 #undef MaxOrInvalidDistance
charlesmn 0:1da5e4bcb8e5 2087 }
charlesmn 0:1da5e4bcb8e5 2088
charlesmn 0:1da5e4bcb8e5 2089
charlesmn 0:1da5e4bcb8e5 2090 static int _filter_GetResult(VL6180Dev_t dev, VL6180_RangeData_t *pRangeData)
charlesmn 0:1da5e4bcb8e5 2091 {
charlesmn 0:1da5e4bcb8e5 2092 uint32_t m_rawRange_mm = 0;
charlesmn 0:1da5e4bcb8e5 2093 int32_t FilteredRange;
charlesmn 0:1da5e4bcb8e5 2094 const uint8_t scaler = _GetUpscale(dev);
charlesmn 0:1da5e4bcb8e5 2095 uint8_t u8;
charlesmn 0:1da5e4bcb8e5 2096 int status;
charlesmn 0:1da5e4bcb8e5 2097
charlesmn 0:1da5e4bcb8e5 2098 do {
charlesmn 0:1da5e4bcb8e5 2099 status = VL6180_GetCachedByte(dev, RESULT_RANGE_RAW, &u8);
charlesmn 0:1da5e4bcb8e5 2100 if (status) {
charlesmn 0:1da5e4bcb8e5 2101 VL6180_ErrLog("RESULT_RANGE_RAW rd fail");
charlesmn 0:1da5e4bcb8e5 2102 break;
charlesmn 0:1da5e4bcb8e5 2103 }
charlesmn 0:1da5e4bcb8e5 2104 m_rawRange_mm = u8;
charlesmn 0:1da5e4bcb8e5 2105
charlesmn 0:1da5e4bcb8e5 2106 FilteredRange = _filter_Start(dev, pRangeData->range_mm, (m_rawRange_mm * scaler), pRangeData->rtnRate, pRangeData->rtnAmbRate, pRangeData->errorStatus);
charlesmn 0:1da5e4bcb8e5 2107 if (FilteredRange < 0) {
charlesmn 0:1da5e4bcb8e5 2108 status = -1;
charlesmn 0:1da5e4bcb8e5 2109 break;
charlesmn 0:1da5e4bcb8e5 2110 }
charlesmn 0:1da5e4bcb8e5 2111 pRangeData->FilteredData.range_mm = FilteredRange;
charlesmn 0:1da5e4bcb8e5 2112 pRangeData->FilteredData.rawRange_mm = m_rawRange_mm * scaler;
charlesmn 0:1da5e4bcb8e5 2113 pRangeData->FilteredData.filterError= _FilterData(filterError);
charlesmn 0:1da5e4bcb8e5 2114 } while (0);
charlesmn 0:1da5e4bcb8e5 2115 return status;
charlesmn 0:1da5e4bcb8e5 2116 }
charlesmn 0:1da5e4bcb8e5 2117
charlesmn 0:1da5e4bcb8e5 2118 #undef _FilterData
charlesmn 0:1da5e4bcb8e5 2119 #ifdef PRESERVE_DEVICE_ERROR_CODE
charlesmn 0:1da5e4bcb8e5 2120 #undef PRESERVE_DEVICE_ERROR_CODE
charlesmn 0:1da5e4bcb8e5 2121 #endif
charlesmn 0:1da5e4bcb8e5 2122 #ifdef SENSITIVE_FILTERING_ON_GOING
charlesmn 0:1da5e4bcb8e5 2123 #undef SENSITIVE_FILTERING_ON_GOING
charlesmn 0:1da5e4bcb8e5 2124 #endif
charlesmn 0:1da5e4bcb8e5 2125 #undef FILTER_STDDEV_SAMPLES
charlesmn 0:1da5e4bcb8e5 2126 #undef MIN_FILTER_STDDEV_SAMPLES
charlesmn 0:1da5e4bcb8e5 2127 #undef MIN_FILTER_STDDEV_SAMPLES_AFTER_FLUSH_OR_BYPASS
charlesmn 0:1da5e4bcb8e5 2128 #undef STDDEV_BASE_VALUE
charlesmn 0:1da5e4bcb8e5 2129 #undef FILTER_INVALID_DISTANCE
charlesmn 0:1da5e4bcb8e5 2130
charlesmn 0:1da5e4bcb8e5 2131 #endif /* VL6180_WRAP_AROUND_FILTER_SUPPORT */
charlesmn 0:1da5e4bcb8e5 2132
charlesmn 0:1da5e4bcb8e5 2133 #ifdef VL6180_HAVE_RATE_DATA
charlesmn 0:1da5e4bcb8e5 2134
charlesmn 0:1da5e4bcb8e5 2135 static int _GetRateResult(VL6180Dev_t dev, VL6180_RangeData_t *pRangeData)
charlesmn 0:1da5e4bcb8e5 2136 {
charlesmn 0:1da5e4bcb8e5 2137 uint32_t m_rtnConvTime = 0;
charlesmn 0:1da5e4bcb8e5 2138 uint32_t m_rtnSignalRate = 0;
charlesmn 0:1da5e4bcb8e5 2139 uint32_t m_rtnAmbientRate = 0;
charlesmn 0:1da5e4bcb8e5 2140 uint32_t m_rtnSignalCount = 0;
charlesmn 0:1da5e4bcb8e5 2141 uint32_t m_rtnAmbientCount = 0;
charlesmn 0:1da5e4bcb8e5 2142 uint32_t m_refConvTime = 0;
charlesmn 0:1da5e4bcb8e5 2143 uint32_t cRtnSignalCountMax = 0x7FFFFFFF;
charlesmn 0:1da5e4bcb8e5 2144 uint32_t cDllPeriods = 6;
charlesmn 0:1da5e4bcb8e5 2145 uint32_t calcConvTime = 0;
charlesmn 0:1da5e4bcb8e5 2146
charlesmn 0:1da5e4bcb8e5 2147 int status;
charlesmn 0:1da5e4bcb8e5 2148
charlesmn 0:1da5e4bcb8e5 2149 do {
charlesmn 0:1da5e4bcb8e5 2150 status = VL6180_GetCachedDWord(dev, RESULT_RANGE_RETURN_SIGNAL_COUNT, &m_rtnSignalCount);
charlesmn 0:1da5e4bcb8e5 2151 if (status) {
charlesmn 0:1da5e4bcb8e5 2152 VL6180_ErrLog("RESULT_RANGE_RETURN_SIGNAL_COUNT rd fail");
charlesmn 0:1da5e4bcb8e5 2153 break;
charlesmn 0:1da5e4bcb8e5 2154 }
charlesmn 0:1da5e4bcb8e5 2155 if (m_rtnSignalCount > cRtnSignalCountMax) {
charlesmn 0:1da5e4bcb8e5 2156 m_rtnSignalCount = 0;
charlesmn 0:1da5e4bcb8e5 2157 }
charlesmn 0:1da5e4bcb8e5 2158
charlesmn 0:1da5e4bcb8e5 2159 status = VL6180_GetCachedDWord(dev, RESULT_RANGE_RETURN_AMB_COUNT, &m_rtnAmbientCount);
charlesmn 0:1da5e4bcb8e5 2160 if (status) {
charlesmn 0:1da5e4bcb8e5 2161 VL6180_ErrLog("RESULT_RANGE_RETURN_AMB_COUNTrd fail");
charlesmn 0:1da5e4bcb8e5 2162 break;
charlesmn 0:1da5e4bcb8e5 2163 }
charlesmn 0:1da5e4bcb8e5 2164
charlesmn 0:1da5e4bcb8e5 2165
charlesmn 0:1da5e4bcb8e5 2166 status = VL6180_GetCachedDWord(dev, RESULT_RANGE_RETURN_CONV_TIME, &m_rtnConvTime);
charlesmn 0:1da5e4bcb8e5 2167 if (status) {
charlesmn 0:1da5e4bcb8e5 2168 VL6180_ErrLog("RESULT_RANGE_RETURN_CONV_TIME rd fail");
charlesmn 0:1da5e4bcb8e5 2169 break;
charlesmn 0:1da5e4bcb8e5 2170 }
charlesmn 0:1da5e4bcb8e5 2171
charlesmn 0:1da5e4bcb8e5 2172 status = VL6180_GetCachedDWord(dev, RESULT_RANGE_REFERENCE_CONV_TIME, &m_refConvTime);
charlesmn 0:1da5e4bcb8e5 2173 if (status) {
charlesmn 0:1da5e4bcb8e5 2174 VL6180_ErrLog("RESULT_RANGE_REFERENCE_CONV_TIME rd fail");
charlesmn 0:1da5e4bcb8e5 2175 break;
charlesmn 0:1da5e4bcb8e5 2176 }
charlesmn 0:1da5e4bcb8e5 2177
charlesmn 0:1da5e4bcb8e5 2178 pRangeData->rtnConvTime = m_rtnConvTime;
charlesmn 0:1da5e4bcb8e5 2179 pRangeData->refConvTime = m_refConvTime;
charlesmn 0:1da5e4bcb8e5 2180
charlesmn 0:1da5e4bcb8e5 2181 calcConvTime = m_refConvTime;
charlesmn 0:1da5e4bcb8e5 2182 if (m_rtnConvTime > m_refConvTime) {
charlesmn 0:1da5e4bcb8e5 2183 calcConvTime = m_rtnConvTime;
charlesmn 0:1da5e4bcb8e5 2184 }
charlesmn 0:1da5e4bcb8e5 2185 if (calcConvTime == 0)
charlesmn 0:1da5e4bcb8e5 2186 calcConvTime = 63000;
charlesmn 0:1da5e4bcb8e5 2187
charlesmn 0:1da5e4bcb8e5 2188 m_rtnSignalRate = (m_rtnSignalCount * 1000) / calcConvTime;
charlesmn 0:1da5e4bcb8e5 2189 m_rtnAmbientRate = (m_rtnAmbientCount * cDllPeriods * 1000) / calcConvTime;
charlesmn 0:1da5e4bcb8e5 2190
charlesmn 0:1da5e4bcb8e5 2191 pRangeData->rtnRate = m_rtnSignalRate;
charlesmn 0:1da5e4bcb8e5 2192 pRangeData->rtnAmbRate = m_rtnAmbientRate;
charlesmn 0:1da5e4bcb8e5 2193
charlesmn 0:1da5e4bcb8e5 2194
charlesmn 0:1da5e4bcb8e5 2195 } while (0);
charlesmn 0:1da5e4bcb8e5 2196 return status;
charlesmn 0:1da5e4bcb8e5 2197 }
charlesmn 0:1da5e4bcb8e5 2198 #endif /* VL6180_HAVE_RATE_DATA */
charlesmn 0:1da5e4bcb8e5 2199
charlesmn 0:1da5e4bcb8e5 2200
charlesmn 0:1da5e4bcb8e5 2201 int VL6180_DMaxSetState(VL6180Dev_t dev, int state)
charlesmn 0:1da5e4bcb8e5 2202 {
charlesmn 0:1da5e4bcb8e5 2203 int status;
charlesmn 0:1da5e4bcb8e5 2204 LOG_FUNCTION_START("%d", state);
charlesmn 0:1da5e4bcb8e5 2205 #if VL6180_HAVE_DMAX_RANGING
charlesmn 0:1da5e4bcb8e5 2206 VL6180DevDataSet(dev, DMaxEnable, state);
charlesmn 0:1da5e4bcb8e5 2207 if (state) {
charlesmn 0:1da5e4bcb8e5 2208 status = _DMax_InitData(dev);
charlesmn 0:1da5e4bcb8e5 2209 } else {
charlesmn 0:1da5e4bcb8e5 2210 status = 0;
charlesmn 0:1da5e4bcb8e5 2211 }
charlesmn 0:1da5e4bcb8e5 2212 #else
charlesmn 0:1da5e4bcb8e5 2213 status = NOT_SUPPORTED;
charlesmn 0:1da5e4bcb8e5 2214 #endif
charlesmn 0:1da5e4bcb8e5 2215 LOG_FUNCTION_END(status);
charlesmn 0:1da5e4bcb8e5 2216 return status;
charlesmn 0:1da5e4bcb8e5 2217 }
charlesmn 0:1da5e4bcb8e5 2218
charlesmn 0:1da5e4bcb8e5 2219 int VL6180_DMaxGetState(VL6180Dev_t dev)
charlesmn 0:1da5e4bcb8e5 2220 {
charlesmn 0:1da5e4bcb8e5 2221 int status;
charlesmn 0:1da5e4bcb8e5 2222 LOG_FUNCTION_START("");
charlesmn 0:1da5e4bcb8e5 2223 #if VL6180_HAVE_DMAX_RANGING
charlesmn 0:1da5e4bcb8e5 2224 status = VL6180DevDataGet(dev, DMaxEnable);
charlesmn 0:1da5e4bcb8e5 2225 #else
charlesmn 0:1da5e4bcb8e5 2226 status = 0;
charlesmn 0:1da5e4bcb8e5 2227 #endif
charlesmn 0:1da5e4bcb8e5 2228 LOG_FUNCTION_END(status);
charlesmn 0:1da5e4bcb8e5 2229 return status;
charlesmn 0:1da5e4bcb8e5 2230 }
charlesmn 0:1da5e4bcb8e5 2231
charlesmn 0:1da5e4bcb8e5 2232
charlesmn 0:1da5e4bcb8e5 2233 #if VL6180_HAVE_DMAX_RANGING
charlesmn 0:1da5e4bcb8e5 2234
charlesmn 0:1da5e4bcb8e5 2235 #define _DMaxData(field) VL6180DevDataGet(dev, DMaxData.field)
charlesmn 0:1da5e4bcb8e5 2236 /*
charlesmn 0:1da5e4bcb8e5 2237 * Convert fix point x.7 to KCpount per sec
charlesmn 0:1da5e4bcb8e5 2238 */
charlesmn 0:1da5e4bcb8e5 2239
charlesmn 0:1da5e4bcb8e5 2240 #ifndef VL6180_PLATFORM_PROVIDE_SQRT
charlesmn 0:1da5e4bcb8e5 2241
charlesmn 0:1da5e4bcb8e5 2242 /*
charlesmn 0:1da5e4bcb8e5 2243 * 32 bit integer square root with not so bad precision (integer result) and is quite fast
charlesmn 0:1da5e4bcb8e5 2244 * see http://en.wikipedia.org/wiki/Methods_of_computing_square_roots
charlesmn 0:1da5e4bcb8e5 2245 */
charlesmn 0:1da5e4bcb8e5 2246 uint32_t VL6180_SqrtUint32(uint32_t num)
charlesmn 0:1da5e4bcb8e5 2247 {
charlesmn 0:1da5e4bcb8e5 2248 uint32_t res = 0;
charlesmn 0:1da5e4bcb8e5 2249 uint32_t bit = 1 << 30; /* The second-to-top bit is set: 1 << 30 for 32 bits */
charlesmn 0:1da5e4bcb8e5 2250
charlesmn 0:1da5e4bcb8e5 2251 /* "bit" starts at the highest power of four <= the argument. */
charlesmn 0:1da5e4bcb8e5 2252 while (bit > num)
charlesmn 0:1da5e4bcb8e5 2253 bit >>= 2;
charlesmn 0:1da5e4bcb8e5 2254
charlesmn 0:1da5e4bcb8e5 2255 while (bit != 0) {
charlesmn 0:1da5e4bcb8e5 2256 if (num >= res + bit) {
charlesmn 0:1da5e4bcb8e5 2257 num -= res + bit;
charlesmn 0:1da5e4bcb8e5 2258 res = (res >> 1) + bit;
charlesmn 0:1da5e4bcb8e5 2259 } else
charlesmn 0:1da5e4bcb8e5 2260 res >>= 1;
charlesmn 0:1da5e4bcb8e5 2261 bit >>= 2;
charlesmn 0:1da5e4bcb8e5 2262 }
charlesmn 0:1da5e4bcb8e5 2263 return res;
charlesmn 0:1da5e4bcb8e5 2264 }
charlesmn 0:1da5e4bcb8e5 2265 #endif
charlesmn 0:1da5e4bcb8e5 2266
charlesmn 0:1da5e4bcb8e5 2267
charlesmn 0:1da5e4bcb8e5 2268 /* DMax one time init */
charlesmn 0:1da5e4bcb8e5 2269 void _DMax_OneTimeInit(VL6180Dev_t dev)
charlesmn 0:1da5e4bcb8e5 2270 {
charlesmn 0:1da5e4bcb8e5 2271 _DMaxData(ambTuningWindowFactor_K) = DEF_AMBIENT_TUNING;
charlesmn 0:1da5e4bcb8e5 2272 }
charlesmn 0:1da5e4bcb8e5 2273
charlesmn 0:1da5e4bcb8e5 2274
charlesmn 0:1da5e4bcb8e5 2275 static uint32_t _DMax_RawValueAtRateKCps(VL6180Dev_t dev, int32_t rate)
charlesmn 0:1da5e4bcb8e5 2276 {
charlesmn 0:1da5e4bcb8e5 2277 uint32_t snrLimit_K;
charlesmn 0:1da5e4bcb8e5 2278 int32_t DMaxSq;
charlesmn 0:1da5e4bcb8e5 2279 uint32_t RawDMax;
charlesmn 0:1da5e4bcb8e5 2280 DMaxFix_t retSignalAt400mm;
charlesmn 0:1da5e4bcb8e5 2281 uint32_t ambTuningWindowFactor_K;
charlesmn 0:1da5e4bcb8e5 2282
charlesmn 0:1da5e4bcb8e5 2283
charlesmn 0:1da5e4bcb8e5 2284 ambTuningWindowFactor_K = _DMaxData(ambTuningWindowFactor_K);
charlesmn 0:1da5e4bcb8e5 2285 snrLimit_K = _DMaxData(snrLimit_K);
charlesmn 0:1da5e4bcb8e5 2286 retSignalAt400mm = _DMaxData(retSignalAt400mm);
charlesmn 0:1da5e4bcb8e5 2287 /* 12 to 18 bits Kcps */
charlesmn 0:1da5e4bcb8e5 2288 if (rate > 0) {
charlesmn 0:1da5e4bcb8e5 2289 DMaxSq = 400 * 400 * 1000 / rate - (400 * 400 / 330);
charlesmn 0:1da5e4bcb8e5 2290 /* K of (1/RtnAmb -1/330 )=> 30bit- (12-18)bit => 12-18 bits*/
charlesmn 0:1da5e4bcb8e5 2291 if (DMaxSq <= 0) {
charlesmn 0:1da5e4bcb8e5 2292 RawDMax = 0;
charlesmn 0:1da5e4bcb8e5 2293 } else {
charlesmn 0:1da5e4bcb8e5 2294 /* value can be more 32 bit so base on raneg apply
charlesmn 0:1da5e4bcb8e5 2295 * retSignalAt400mm before or after division to presevr accuracy */
charlesmn 0:1da5e4bcb8e5 2296 if (DMaxSq < (2 << 12)) {
charlesmn 0:1da5e4bcb8e5 2297 DMaxSq = DMaxSq * retSignalAt400mm /
charlesmn 0:1da5e4bcb8e5 2298 (snrLimit_K + ambTuningWindowFactor_K);
charlesmn 0:1da5e4bcb8e5 2299 /* max 12 + 12 to 18 -10 => 12-26 bit */
charlesmn 0:1da5e4bcb8e5 2300 } else {
charlesmn 0:1da5e4bcb8e5 2301 DMaxSq = DMaxSq / (snrLimit_K + ambTuningWindowFactor_K) * retSignalAt400mm;
charlesmn 0:1da5e4bcb8e5 2302 /* 12 to 18 -10 + 12 to 18 *=> 12-26 bit */
charlesmn 0:1da5e4bcb8e5 2303 }
charlesmn 0:1da5e4bcb8e5 2304 RawDMax = VL6180_SqrtUint32(DMaxSq);
charlesmn 0:1da5e4bcb8e5 2305 }
charlesmn 0:1da5e4bcb8e5 2306 } else {
charlesmn 0:1da5e4bcb8e5 2307 RawDMax = 0x7FFFFFFF; /* bigest possibmle 32bit signed value */
charlesmn 0:1da5e4bcb8e5 2308 }
charlesmn 0:1da5e4bcb8e5 2309 return RawDMax;
charlesmn 0:1da5e4bcb8e5 2310 }
charlesmn 0:1da5e4bcb8e5 2311
charlesmn 0:1da5e4bcb8e5 2312 /*
charlesmn 0:1da5e4bcb8e5 2313 * fetch static data from register to avoid re-read
charlesmn 0:1da5e4bcb8e5 2314 * precompute all intermediate constant and cliipings
charlesmn 0:1da5e4bcb8e5 2315 *
charlesmn 0:1da5e4bcb8e5 2316 * to be re-used/call on changes of :
charlesmn 0:1da5e4bcb8e5 2317 * 0x2A
charlesmn 0:1da5e4bcb8e5 2318 * SYSRANGE_MAX_AMBIENT_LEVEL_MULT
charlesmn 0:1da5e4bcb8e5 2319 * Dev Data XtalkComRate_KCPs
charlesmn 0:1da5e4bcb8e5 2320 * SYSRANGE_MAX_CONVERGENCE_TIME
charlesmn 0:1da5e4bcb8e5 2321 * SYSRANGE_RANGE_CHECK_ENABLES mask RANGE_CHECK_RANGE_ENABLE_MASK
charlesmn 0:1da5e4bcb8e5 2322 * range 0xb8-0xbb (0xbb)
charlesmn 0:1da5e4bcb8e5 2323 */
charlesmn 0:1da5e4bcb8e5 2324 static int _DMax_InitData(VL6180Dev_t dev)
charlesmn 0:1da5e4bcb8e5 2325 {
charlesmn 0:1da5e4bcb8e5 2326 int status, warning;
charlesmn 0:1da5e4bcb8e5 2327 uint8_t u8;
charlesmn 0:1da5e4bcb8e5 2328 uint16_t u16;
charlesmn 0:1da5e4bcb8e5 2329 uint32_t u32;
charlesmn 0:1da5e4bcb8e5 2330 uint32_t Reg2A_KCps;
charlesmn 0:1da5e4bcb8e5 2331 uint32_t RegB8;
charlesmn 0:1da5e4bcb8e5 2332 uint8_t MaxConvTime;
charlesmn 0:1da5e4bcb8e5 2333 uint32_t XTalkCompRate_KCps;
charlesmn 0:1da5e4bcb8e5 2334 uint32_t RangeIgnoreThreshold;
charlesmn 0:1da5e4bcb8e5 2335 int32_t minSignalNeeded;
charlesmn 0:1da5e4bcb8e5 2336 uint8_t SysRangeCheckEn;
charlesmn 0:1da5e4bcb8e5 2337 uint8_t snrLimit;
charlesmn 0:1da5e4bcb8e5 2338 static const int ROMABLE_DATA MaxConvTimeAdjust = -4;
charlesmn 0:1da5e4bcb8e5 2339
charlesmn 0:1da5e4bcb8e5 2340 warning = 0;
charlesmn 0:1da5e4bcb8e5 2341
charlesmn 0:1da5e4bcb8e5 2342 LOG_FUNCTION_START("");
charlesmn 0:1da5e4bcb8e5 2343 do {
charlesmn 0:1da5e4bcb8e5 2344 status = VL6180_RdByte(dev, 0x02A, &u8);
charlesmn 0:1da5e4bcb8e5 2345 if (status) {
charlesmn 0:1da5e4bcb8e5 2346 VL6180_ErrLog("Reg 0x02A rd fail");
charlesmn 0:1da5e4bcb8e5 2347 break;
charlesmn 0:1da5e4bcb8e5 2348 }
charlesmn 0:1da5e4bcb8e5 2349
charlesmn 0:1da5e4bcb8e5 2350 if (u8 == 0) {
charlesmn 0:1da5e4bcb8e5 2351 warning = CALIBRATION_WARNING;
charlesmn 0:1da5e4bcb8e5 2352 u8 = 40; /* use a default average value */
charlesmn 0:1da5e4bcb8e5 2353 }
charlesmn 0:1da5e4bcb8e5 2354 Reg2A_KCps = Fix7_2_KCPs(u8); /* convert to KCPs */
charlesmn 0:1da5e4bcb8e5 2355
charlesmn 0:1da5e4bcb8e5 2356 status = VL6180_RdByte(dev, SYSRANGE_RANGE_CHECK_ENABLES, &SysRangeCheckEn);
charlesmn 0:1da5e4bcb8e5 2357 if (status) {
charlesmn 0:1da5e4bcb8e5 2358 VL6180_ErrLog("SYSRANGE_RANGE_CHECK_ENABLES rd fail ");
charlesmn 0:1da5e4bcb8e5 2359 break;
charlesmn 0:1da5e4bcb8e5 2360 }
charlesmn 0:1da5e4bcb8e5 2361
charlesmn 0:1da5e4bcb8e5 2362 status = VL6180_RdByte(dev, SYSRANGE_MAX_CONVERGENCE_TIME, &MaxConvTime);
charlesmn 0:1da5e4bcb8e5 2363 if (status) {
charlesmn 0:1da5e4bcb8e5 2364 VL6180_ErrLog("SYSRANGE_MAX_CONVERGENCE_TIME rd fail ");
charlesmn 0:1da5e4bcb8e5 2365 break;
charlesmn 0:1da5e4bcb8e5 2366 }
charlesmn 0:1da5e4bcb8e5 2367
charlesmn 0:1da5e4bcb8e5 2368 status = VL6180_RdDWord(dev, 0x0B8, &RegB8);
charlesmn 0:1da5e4bcb8e5 2369 if (status) {
charlesmn 0:1da5e4bcb8e5 2370 VL6180_ErrLog("reg 0x0B8 rd fail ");
charlesmn 0:1da5e4bcb8e5 2371 break;
charlesmn 0:1da5e4bcb8e5 2372 }
charlesmn 0:1da5e4bcb8e5 2373
charlesmn 0:1da5e4bcb8e5 2374 status = VL6180_RdByte(dev, SYSRANGE_MAX_AMBIENT_LEVEL_MULT, &snrLimit);
charlesmn 0:1da5e4bcb8e5 2375 if (status) {
charlesmn 0:1da5e4bcb8e5 2376 VL6180_ErrLog("SYSRANGE_MAX_AMBIENT_LEVEL_MULT rd fail ");
charlesmn 0:1da5e4bcb8e5 2377 break;
charlesmn 0:1da5e4bcb8e5 2378 }
charlesmn 0:1da5e4bcb8e5 2379 _DMaxData(snrLimit_K) = (int32_t)16 * 1000 / snrLimit;
charlesmn 0:1da5e4bcb8e5 2380 XTalkCompRate_KCps = VL6180DevDataGet(dev, XTalkCompRate_KCps);
charlesmn 0:1da5e4bcb8e5 2381
charlesmn 0:1da5e4bcb8e5 2382 if (Reg2A_KCps >= XTalkCompRate_KCps) {
charlesmn 0:1da5e4bcb8e5 2383 _DMaxData(retSignalAt400mm) = Reg2A_KCps;
charlesmn 0:1da5e4bcb8e5 2384 } else{
charlesmn 0:1da5e4bcb8e5 2385 _DMaxData(retSignalAt400mm) = 0;
charlesmn 0:1da5e4bcb8e5 2386 /* Reg2A_K - XTalkCompRate_KCp <0 is invalid */
charlesmn 0:1da5e4bcb8e5 2387 }
charlesmn 0:1da5e4bcb8e5 2388
charlesmn 0:1da5e4bcb8e5 2389 /* if xtalk range check is off omit it in snr clipping */
charlesmn 0:1da5e4bcb8e5 2390 if (SysRangeCheckEn&RANGE_CHECK_RANGE_ENABLE_MASK) {
charlesmn 0:1da5e4bcb8e5 2391 status = VL6180_RdWord(dev, SYSRANGE_RANGE_IGNORE_THRESHOLD, &u16);
charlesmn 0:1da5e4bcb8e5 2392 if (status) {
charlesmn 0:1da5e4bcb8e5 2393 VL6180_ErrLog("SYSRANGE_RANGE_IGNORE_THRESHOLD rd fail ");
charlesmn 0:1da5e4bcb8e5 2394 break;
charlesmn 0:1da5e4bcb8e5 2395 }
charlesmn 0:1da5e4bcb8e5 2396 RangeIgnoreThreshold = Fix7_2_KCPs(u16);
charlesmn 0:1da5e4bcb8e5 2397 } else{
charlesmn 0:1da5e4bcb8e5 2398 RangeIgnoreThreshold = 0;
charlesmn 0:1da5e4bcb8e5 2399 }
charlesmn 0:1da5e4bcb8e5 2400
charlesmn 0:1da5e4bcb8e5 2401 minSignalNeeded = (RegB8 * 256) / ((int32_t)MaxConvTime + (int32_t)MaxConvTimeAdjust);
charlesmn 0:1da5e4bcb8e5 2402 /* KCps 8+8 bit -(1 to 6 bit) => 15-10 bit */
charlesmn 0:1da5e4bcb8e5 2403 /* minSignalNeeded = max ( minSignalNeeded, RangeIgnoreThreshold - XTalkCompRate_KCps) */
charlesmn 0:1da5e4bcb8e5 2404 if (minSignalNeeded <= (int32_t)RangeIgnoreThreshold - (int32_t)XTalkCompRate_KCps)
charlesmn 0:1da5e4bcb8e5 2405 minSignalNeeded = RangeIgnoreThreshold - XTalkCompRate_KCps;
charlesmn 0:1da5e4bcb8e5 2406
charlesmn 0:1da5e4bcb8e5 2407 u32 = (minSignalNeeded*(uint32_t)snrLimit) / 16;
charlesmn 0:1da5e4bcb8e5 2408 _DMaxData(ClipSnrLimit) = _DMax_RawValueAtRateKCps(dev, u32);
charlesmn 0:1da5e4bcb8e5 2409 /* clip to dmax to min signal snr limit rate*/
charlesmn 0:1da5e4bcb8e5 2410 } while (0);
charlesmn 0:1da5e4bcb8e5 2411 if (!status)
charlesmn 0:1da5e4bcb8e5 2412 status = warning;
charlesmn 0:1da5e4bcb8e5 2413 LOG_FUNCTION_END(status);
charlesmn 0:1da5e4bcb8e5 2414 return status;
charlesmn 0:1da5e4bcb8e5 2415 }
charlesmn 0:1da5e4bcb8e5 2416
charlesmn 0:1da5e4bcb8e5 2417 static int _DMax_Compute(VL6180Dev_t dev, VL6180_RangeData_t *pRange)
charlesmn 0:1da5e4bcb8e5 2418 {
charlesmn 0:1da5e4bcb8e5 2419 uint32_t rtnAmbRate;
charlesmn 0:1da5e4bcb8e5 2420 int32_t DMax;
charlesmn 0:1da5e4bcb8e5 2421 int scaling;
charlesmn 0:1da5e4bcb8e5 2422 uint16_t HwLimitAtScale;
charlesmn 0:1da5e4bcb8e5 2423 static const int ROMABLE_DATA rtnAmbLowLimit_KCps = 330 * 1000;
charlesmn 0:1da5e4bcb8e5 2424
charlesmn 0:1da5e4bcb8e5 2425 rtnAmbRate = pRange->rtnAmbRate;
charlesmn 0:1da5e4bcb8e5 2426 if (rtnAmbRate < rtnAmbLowLimit_KCps) {
charlesmn 0:1da5e4bcb8e5 2427 DMax = _DMax_RawValueAtRateKCps(dev, rtnAmbRate);
charlesmn 0:1da5e4bcb8e5 2428 scaling = _GetUpscale(dev);
charlesmn 0:1da5e4bcb8e5 2429 HwLimitAtScale = UpperLimitLookUP[scaling - 1];
charlesmn 0:1da5e4bcb8e5 2430
charlesmn 0:1da5e4bcb8e5 2431 if (DMax > _DMaxData(ClipSnrLimit)) {
charlesmn 0:1da5e4bcb8e5 2432 DMax = _DMaxData(ClipSnrLimit);
charlesmn 0:1da5e4bcb8e5 2433 }
charlesmn 0:1da5e4bcb8e5 2434 if (DMax > HwLimitAtScale) {
charlesmn 0:1da5e4bcb8e5 2435 DMax = HwLimitAtScale;
charlesmn 0:1da5e4bcb8e5 2436 }
charlesmn 0:1da5e4bcb8e5 2437 pRange->DMax = DMax;
charlesmn 0:1da5e4bcb8e5 2438 } else {
charlesmn 0:1da5e4bcb8e5 2439 pRange->DMax = 0;
charlesmn 0:1da5e4bcb8e5 2440 }
charlesmn 0:1da5e4bcb8e5 2441 return 0;
charlesmn 0:1da5e4bcb8e5 2442 }
charlesmn 0:1da5e4bcb8e5 2443
charlesmn 0:1da5e4bcb8e5 2444 #undef _DMaxData
charlesmn 0:1da5e4bcb8e5 2445 #undef Fix7_2_KCPs
charlesmn 0:1da5e4bcb8e5 2446
charlesmn 0:1da5e4bcb8e5 2447 #endif /* VL6180_HAVE_DMAX_RANGING */
charlesmn 0:1da5e4bcb8e5 2448
charlesmn 0:1da5e4bcb8e5 2449
charlesmn 0:1da5e4bcb8e5 2450
charlesmn 0:1da5e4bcb8e5 2451