Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
VL6160SRC/vl6180_api.c@1:b4bdb0356af0, 2020-10-28 (annotated)
- 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?
User | Revision | Line number | New 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, ®ister32BitsValue1); /* 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 |