Condensed Version of Public VL53L0X
VL53L0X.cpp@11:c6f95a42d4d7, 2019-04-08 (annotated)
- Committer:
- sepp_nepp
- Date:
- Mon Apr 08 16:26:19 2019 +0000
- Revision:
- 11:c6f95a42d4d7
- Parent:
- 10:cd251e0fc2fd
- Child:
- 12:aa177f0e4c10
Latest refactoring changes compile.; But now stuck with "Warning: L3912W: Option 'lecacyalign' is deprecated."
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
nikapov | 0:a1a69d32f310 | 1 | /** |
nikapov | 0:a1a69d32f310 | 2 | ****************************************************************************** |
sepp_nepp | 11:c6f95a42d4d7 | 3 | * @file Class.cpp |
nikapov | 0:a1a69d32f310 | 4 | * @author IMG |
nikapov | 0:a1a69d32f310 | 5 | * @version V0.0.1 |
nikapov | 0:a1a69d32f310 | 6 | * @date 28-June-2016 |
nikapov | 0:a1a69d32f310 | 7 | * @brief Implementation file for the VL53L0X driver class |
nikapov | 0:a1a69d32f310 | 8 | ****************************************************************************** |
nikapov | 0:a1a69d32f310 | 9 | * @attention |
nikapov | 0:a1a69d32f310 | 10 | * |
nikapov | 0:a1a69d32f310 | 11 | * <h2><center>© COPYRIGHT(c) 2016 STMicroelectronics</center></h2> |
nikapov | 0:a1a69d32f310 | 12 | * |
sepp_nepp | 7:41cbc431e1f4 | 13 | * Redistribution and use in source and binary forms,with or without modification, |
nikapov | 0:a1a69d32f310 | 14 | * are permitted provided that the following conditions are met: |
nikapov | 0:a1a69d32f310 | 15 | * 1. Redistributions of source code must retain the above copyright notice, |
nikapov | 0:a1a69d32f310 | 16 | * this list of conditions and the following disclaimer. |
nikapov | 0:a1a69d32f310 | 17 | * 2. Redistributions in binary form must reproduce the above copyright notice, |
nikapov | 0:a1a69d32f310 | 18 | * this list of conditions and the following disclaimer in the documentation |
nikapov | 0:a1a69d32f310 | 19 | * and/or other materials provided with the distribution. |
nikapov | 0:a1a69d32f310 | 20 | * 3. Neither the name of STMicroelectronics nor the names of its contributors |
nikapov | 0:a1a69d32f310 | 21 | * may be used to endorse or promote products derived from this software |
nikapov | 0:a1a69d32f310 | 22 | * without specific prior written permission. |
nikapov | 0:a1a69d32f310 | 23 | * |
nikapov | 0:a1a69d32f310 | 24 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
sepp_nepp | 7:41cbc431e1f4 | 25 | * AND ANY EXPRESS OR IMPLIED WARRANTIES,INCLUDING,BUT NOT LIMITED TO,THE |
nikapov | 0:a1a69d32f310 | 26 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
nikapov | 0:a1a69d32f310 | 27 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE |
sepp_nepp | 7:41cbc431e1f4 | 28 | * FOR ANY DIRECT,INDIRECT,INCIDENTAL,SPECIAL,EXEMPLARY,OR CONSEQUENTIAL |
sepp_nepp | 7:41cbc431e1f4 | 29 | * DAMAGES (INCLUDING,BUT NOT LIMITED TO,PROCUREMENT OF SUBSTITUTE GOODS OR |
sepp_nepp | 7:41cbc431e1f4 | 30 | * SERVICES; LOSS OF USE,DATA,OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
sepp_nepp | 7:41cbc431e1f4 | 31 | * CAUSED AND ON ANY THEORY OF LIABILITY,WHETHER IN CONTRACT,STRICT LIABILITY, |
nikapov | 0:a1a69d32f310 | 32 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
sepp_nepp | 7:41cbc431e1f4 | 33 | * OF THIS SOFTWARE,EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
nikapov | 0:a1a69d32f310 | 34 | * |
nikapov | 0:a1a69d32f310 | 35 | ****************************************************************************** |
nikapov | 0:a1a69d32f310 | 36 | */ |
nikapov | 0:a1a69d32f310 | 37 | |
sepp_nepp | 7:41cbc431e1f4 | 38 | // Some example regex that were used to replace useless macros |
sepp_nepp | 7:41cbc431e1f4 | 39 | // \QVL53L0X_SETARRAYPARAMETERFIELD(\E([A-Z\d]+)[[:punct:]](\s*)([A-Z\d_]+)[[:punct:]](\s*)([A-Z\d_]+)\Q);\E |
sepp_nepp | 11:c6f95a42d4d7 | 40 | // _device->CurrParams.\1[\3] = \5; |
sepp_nepp | 11:c6f95a42d4d7 | 41 | // to replace this "#define VL53L0X_SETARRAYPARAMETERFIELD(field, index, value)" by "_device->CurrParams.field[index] = value" |
sepp_nepp | 11:c6f95a42d4d7 | 42 | |
sepp_nepp | 11:c6f95a42d4d7 | 43 | // to replace "Read_Byte(0x90,&module_id);" by "module_id = Read_Byte(0x90);" search and replace |
sepp_nepp | 11:c6f95a42d4d7 | 44 | // \QRead_Byte(\E([A-Za-z_\d]+)[[:punct:]](\s*)\Q&\E([A-Za-z\d_]+)\Q);\E |
sepp_nepp | 11:c6f95a42d4d7 | 45 | // \3 = Read_Byte\(\1\); |
sepp_nepp | 7:41cbc431e1f4 | 46 | |
nikapov | 0:a1a69d32f310 | 47 | /* Includes */ |
nikapov | 0:a1a69d32f310 | 48 | #include <stdlib.h> |
nikapov | 0:a1a69d32f310 | 49 | #include "VL53L0X.h" |
sepp_nepp | 10:cd251e0fc2fd | 50 | #include "VL53L0X_tuning.h" |
sepp_nepp | 7:41cbc431e1f4 | 51 | |
sepp_nepp | 11:c6f95a42d4d7 | 52 | // Function Data_init and Init_Sensor is united into Start_Sensor |
sepp_nepp | 11:c6f95a42d4d7 | 53 | VL53L0X_Error VL53L0X::Start_Sensor(uint8_t new_addr) |
sepp_nepp | 11:c6f95a42d4d7 | 54 | { ErrState = VL53L0X_OK; |
sepp_nepp | 11:c6f95a42d4d7 | 55 | |
sepp_nepp | 11:c6f95a42d4d7 | 56 | if (_gpio0) { // Can the shutdown pin be controlled? |
sepp_nepp | 11:c6f95a42d4d7 | 57 | *_gpio0 = 0; wait_ms(1); // quick shutdown |
sepp_nepp | 11:c6f95a42d4d7 | 58 | *_gpio0 = 1; wait_ms(10); // and back ON again |
sepp_nepp | 11:c6f95a42d4d7 | 59 | } |
sepp_nepp | 11:c6f95a42d4d7 | 60 | |
sepp_nepp | 11:c6f95a42d4d7 | 61 | /* Setup the I2C bus. By default the I2C is running at 1V8 if you |
sepp_nepp | 11:c6f95a42d4d7 | 62 | * want to change it you need to include this define at compilation level. */ |
sepp_nepp | 11:c6f95a42d4d7 | 63 | #ifdef USE_I2C_2V8 |
sepp_nepp | 11:c6f95a42d4d7 | 64 | VL53L0X_UpdateByte(REG_VHV_CONFIG_PAD_SCL_SDA__EXTSUP_HV, 0xFE, 0x01); |
sepp_nepp | 11:c6f95a42d4d7 | 65 | #endif |
sepp_nepp | 11:c6f95a42d4d7 | 66 | /* Set I2C standard mode */ |
sepp_nepp | 11:c6f95a42d4d7 | 67 | Write_Byte(0x88,0x00); |
sepp_nepp | 11:c6f95a42d4d7 | 68 | |
sepp_nepp | 11:c6f95a42d4d7 | 69 | // read and check the device ID from the ID register |
sepp_nepp | 11:c6f95a42d4d7 | 70 | Device_Info.ProductType = Read_Byte(REG_IDENTIFICATION_MODEL_ID); |
sepp_nepp | 11:c6f95a42d4d7 | 71 | if ( (ErrState == VL53L0X_OK) && (Device_Info.ProductType != 0xEEAA) ) |
sepp_nepp | 11:c6f95a42d4d7 | 72 | {return VL53L0X_ERROR_I2C_WRONG_DEV_ID; } |
sepp_nepp | 11:c6f95a42d4d7 | 73 | |
sepp_nepp | 11:c6f95a42d4d7 | 74 | // reconfigure the address with a new address if requested |
sepp_nepp | 11:c6f95a42d4d7 | 75 | if ( (ErrState == VL53L0X_OK) && (new_addr != VL53L0X_DEFAULT_ADDRESS) ) |
sepp_nepp | 11:c6f95a42d4d7 | 76 | { Write_Byte(REG_I2C_SLAVE_DEVICE_ADDRESS, new_addr / 2); |
sepp_nepp | 11:c6f95a42d4d7 | 77 | I2cDevAddr = new_addr; |
sepp_nepp | 11:c6f95a42d4d7 | 78 | } |
sepp_nepp | 11:c6f95a42d4d7 | 79 | // quite if an error was raised |
sepp_nepp | 11:c6f95a42d4d7 | 80 | if (ErrState != VL53L0X_OK) {return ErrState; } |
sepp_nepp | 11:c6f95a42d4d7 | 81 | |
sepp_nepp | 11:c6f95a42d4d7 | 82 | /* Set Default static parameters |
sepp_nepp | 11:c6f95a42d4d7 | 83 | *set first temporary values 9.44MHz * 65536 = 618660 */ |
sepp_nepp | 11:c6f95a42d4d7 | 84 | DevSpecParams.OscFrequencyMHz = 618660; |
sepp_nepp | 11:c6f95a42d4d7 | 85 | DevSpecParams.RefSPADSInitialised = 0; |
sepp_nepp | 11:c6f95a42d4d7 | 86 | DevSpecParams.ReadDataFromDeviceDone = 0; |
sepp_nepp | 11:c6f95a42d4d7 | 87 | |
sepp_nepp | 11:c6f95a42d4d7 | 88 | #ifdef USE_IQC_STATION |
sepp_nepp | 11:c6f95a42d4d7 | 89 | VL53L0X_Apply_Offset_Cal(); |
sepp_nepp | 11:c6f95a42d4d7 | 90 | #endif |
sepp_nepp | 11:c6f95a42d4d7 | 91 | |
sepp_nepp | 11:c6f95a42d4d7 | 92 | /* Default value is 1000 for Linearity Corrective Gain */ |
sepp_nepp | 11:c6f95a42d4d7 | 93 | LinearityCorrectiveGain = 1000; |
sepp_nepp | 11:c6f95a42d4d7 | 94 | |
sepp_nepp | 11:c6f95a42d4d7 | 95 | /* Dmax default Parameter */ |
sepp_nepp | 11:c6f95a42d4d7 | 96 | DmaxCalRangeMilliMeter = 400; |
sepp_nepp | 11:c6f95a42d4d7 | 97 | DmaxCalSignalRateRtnMHz = (TFP1616)((0x00016B85)); /* 1.42 No Cover Glass*/ |
sepp_nepp | 11:c6f95a42d4d7 | 98 | |
sepp_nepp | 11:c6f95a42d4d7 | 99 | /* Get default parameters */ |
sepp_nepp | 11:c6f95a42d4d7 | 100 | CurrParams = Get_device_parameters(); |
sepp_nepp | 11:c6f95a42d4d7 | 101 | |
sepp_nepp | 11:c6f95a42d4d7 | 102 | /* Set Default Xtalk_CompRate_MHz to 0 */ |
sepp_nepp | 11:c6f95a42d4d7 | 103 | CurrParams.Xtalk_CompRate_MHz = 0; |
sepp_nepp | 11:c6f95a42d4d7 | 104 | |
sepp_nepp | 11:c6f95a42d4d7 | 105 | /* initialize CurrParams values */ |
sepp_nepp | 11:c6f95a42d4d7 | 106 | CurrParams.DeviceMode = VL53L0X_DEVICEMODE_SINGLE_RANGING; |
sepp_nepp | 11:c6f95a42d4d7 | 107 | CurrParams.HistogramMode = VL53L0X_HISTOGRAMMODE_DISABLED; |
sepp_nepp | 11:c6f95a42d4d7 | 108 | |
sepp_nepp | 11:c6f95a42d4d7 | 109 | /* Sigma estimator variable */ |
sepp_nepp | 11:c6f95a42d4d7 | 110 | SigmaEstRefArray = 100; |
sepp_nepp | 11:c6f95a42d4d7 | 111 | SigmaEstEffPulseWidth = 900; |
sepp_nepp | 11:c6f95a42d4d7 | 112 | SigmaEstEffAmbWidth = 500; |
sepp_nepp | 11:c6f95a42d4d7 | 113 | targetRefRate = 0x0A00; /* 20 MHz in 9:7 format */ |
sepp_nepp | 11:c6f95a42d4d7 | 114 | |
sepp_nepp | 11:c6f95a42d4d7 | 115 | /* Use internal default settings */ |
sepp_nepp | 11:c6f95a42d4d7 | 116 | UseInternalTuningSettings = 1; |
sepp_nepp | 11:c6f95a42d4d7 | 117 | Write_Byte(0x80,0x01); |
sepp_nepp | 11:c6f95a42d4d7 | 118 | Write_Byte(0xFF,0x01); |
sepp_nepp | 11:c6f95a42d4d7 | 119 | Write_Byte(0x00,0x00); |
sepp_nepp | 11:c6f95a42d4d7 | 120 | StopVariable = Read_Byte(0x91); |
sepp_nepp | 11:c6f95a42d4d7 | 121 | Write_Byte(0x00,0x01); |
sepp_nepp | 11:c6f95a42d4d7 | 122 | Write_Byte(0xFF,0x00); |
sepp_nepp | 11:c6f95a42d4d7 | 123 | Write_Byte(0x80,0x00); |
sepp_nepp | 11:c6f95a42d4d7 | 124 | |
sepp_nepp | 11:c6f95a42d4d7 | 125 | // quite if an error was raised |
sepp_nepp | 11:c6f95a42d4d7 | 126 | if (ErrState != VL53L0X_OK) {return ErrState; } |
sepp_nepp | 11:c6f95a42d4d7 | 127 | |
sepp_nepp | 11:c6f95a42d4d7 | 128 | /* Disable the following SW-internal checks plaus set some values */ |
sepp_nepp | 11:c6f95a42d4d7 | 129 | CurrParams.Limit_Chk_En [VL53L0X_CHECKEN_SIG_REF_CLIP] = 0; |
sepp_nepp | 11:c6f95a42d4d7 | 130 | CurrParams.Limit_Chk_Val[VL53L0X_CHECKEN_SIG_REF_CLIP] = (35 * 65536); |
sepp_nepp | 11:c6f95a42d4d7 | 131 | CurrParams.Limit_Chk_En [VL53L0X_CHECKEN_RANGE_IGNORE_THRESHOLD] = 0; |
sepp_nepp | 11:c6f95a42d4d7 | 132 | CurrParams.Limit_Chk_Val[VL53L0X_CHECKEN_RANGE_IGNORE_THRESHOLD] = 0; |
sepp_nepp | 11:c6f95a42d4d7 | 133 | |
sepp_nepp | 11:c6f95a42d4d7 | 134 | /* Disable the following Device-Internal Checks: */ |
sepp_nepp | 11:c6f95a42d4d7 | 135 | CurrParams.Limit_Chk_En[VL53L0X_CHECKEN_SIG_RATE_MSRC] = 0; |
sepp_nepp | 11:c6f95a42d4d7 | 136 | CurrParams.Limit_Chk_En[VL53L0X_CHECKEN_SIG_RATE_PRE_RANGE] = 0; |
sepp_nepp | 11:c6f95a42d4d7 | 137 | Register_BitMask(REG_MSRC_CONFIG_CONTROL,0xEE, 0); |
sepp_nepp | 11:c6f95a42d4d7 | 138 | |
sepp_nepp | 11:c6f95a42d4d7 | 139 | /* Only enable this internal Check : */ |
sepp_nepp | 11:c6f95a42d4d7 | 140 | CurrParams.Limit_Chk_En [VL53L0X_CHECKEN_SIGMA_FINAL_RANGE] = 1; |
sepp_nepp | 11:c6f95a42d4d7 | 141 | CurrParams.Limit_Chk_Val[VL53L0X_CHECKEN_SIGMA_FINAL_RANGE] = (18 * 65536); |
sepp_nepp | 11:c6f95a42d4d7 | 142 | |
sepp_nepp | 11:c6f95a42d4d7 | 143 | /* Plus Enable VL53L0X_CHECKEN_SIG_RATE_FINAL_RANGE check */ |
sepp_nepp | 11:c6f95a42d4d7 | 144 | Set_limit_chk_en(VL53L0X_CHECKEN_SIG_RATE_FINAL_RANGE,1); |
sepp_nepp | 11:c6f95a42d4d7 | 145 | |
sepp_nepp | 11:c6f95a42d4d7 | 146 | if (ErrState == VL53L0X_OK) { /* 0.25 in FP1616 notation 65536 */ |
sepp_nepp | 11:c6f95a42d4d7 | 147 | Set_limit_chk_val(VL53L0X_CHECKEN_SIG_RATE_FINAL_RANGE, |
sepp_nepp | 11:c6f95a42d4d7 | 148 | (TFP1616)(25 * 65536 / 100)); } |
sepp_nepp | 11:c6f95a42d4d7 | 149 | |
sepp_nepp | 11:c6f95a42d4d7 | 150 | // quit if an error was raised |
sepp_nepp | 11:c6f95a42d4d7 | 151 | if (ErrState != VL53L0X_OK) {return ErrState; } |
sepp_nepp | 11:c6f95a42d4d7 | 152 | |
sepp_nepp | 11:c6f95a42d4d7 | 153 | // Preset the Config States |
sepp_nepp | 11:c6f95a42d4d7 | 154 | SequenceConfig = 0xFF ; |
sepp_nepp | 11:c6f95a42d4d7 | 155 | |
sepp_nepp | 11:c6f95a42d4d7 | 156 | /* Set Device state to tell that we are waiting for call to VL53L0X_StaticInit */ |
sepp_nepp | 11:c6f95a42d4d7 | 157 | Current_State = VL53L0X_STATE_WAIT_STATICINIT ; |
sepp_nepp | 11:c6f95a42d4d7 | 158 | |
sepp_nepp | 11:c6f95a42d4d7 | 159 | Fill_device_info(); // Retrieve Silicon version, stored in Device_Info |
sepp_nepp | 11:c6f95a42d4d7 | 160 | |
sepp_nepp | 11:c6f95a42d4d7 | 161 | uint32_t ref_SPAD_count; |
sepp_nepp | 11:c6f95a42d4d7 | 162 | uint8_t is_aperture_SPADS; |
sepp_nepp | 11:c6f95a42d4d7 | 163 | uint8_t vhv_settings; |
sepp_nepp | 11:c6f95a42d4d7 | 164 | uint8_t phase_cal; |
sepp_nepp | 11:c6f95a42d4d7 | 165 | |
sepp_nepp | 11:c6f95a42d4d7 | 166 | if (ErrState == VL53L0X_OK) { Static_init(); } // Device Initialization |
sepp_nepp | 11:c6f95a42d4d7 | 167 | |
sepp_nepp | 11:c6f95a42d4d7 | 168 | if (ErrState == VL53L0X_OK) { // Device Calibration |
sepp_nepp | 11:c6f95a42d4d7 | 169 | Perf_Ref_calibration( &vhv_settings, &phase_cal, 1); } |
sepp_nepp | 11:c6f95a42d4d7 | 170 | |
sepp_nepp | 11:c6f95a42d4d7 | 171 | if (ErrState == VL53L0X_OK) { // SPAD Configuration |
sepp_nepp | 11:c6f95a42d4d7 | 172 | Perf_Ref_SPAD_management( &ref_SPAD_count, &is_aperture_SPADS); } |
sepp_nepp | 11:c6f95a42d4d7 | 173 | |
sepp_nepp | 11:c6f95a42d4d7 | 174 | return ErrState; |
sepp_nepp | 11:c6f95a42d4d7 | 175 | } |
sepp_nepp | 11:c6f95a42d4d7 | 176 | |
sepp_nepp | 11:c6f95a42d4d7 | 177 | void VL53L0X::Fill_device_info() |
sepp_nepp | 11:c6f95a42d4d7 | 178 | { uint8_t revision; |
sepp_nepp | 11:c6f95a42d4d7 | 179 | |
sepp_nepp | 11:c6f95a42d4d7 | 180 | Get_info_from_device(2); |
sepp_nepp | 11:c6f95a42d4d7 | 181 | |
sepp_nepp | 11:c6f95a42d4d7 | 182 | if (ErrState == VL53L0X_OK) |
sepp_nepp | 11:c6f95a42d4d7 | 183 | { if (DevSpecParams.ModuleId == 0) |
sepp_nepp | 11:c6f95a42d4d7 | 184 | { revision = 0; |
sepp_nepp | 11:c6f95a42d4d7 | 185 | strcpy(Device_Info.ProductId,""); } |
sepp_nepp | 11:c6f95a42d4d7 | 186 | else |
sepp_nepp | 11:c6f95a42d4d7 | 187 | { revision = DevSpecParams.Revision; |
sepp_nepp | 11:c6f95a42d4d7 | 188 | strcpy(Device_Info.ProductId,DevSpecParams.ProductId); |
sepp_nepp | 11:c6f95a42d4d7 | 189 | } |
sepp_nepp | 11:c6f95a42d4d7 | 190 | if (revision == 0) |
sepp_nepp | 11:c6f95a42d4d7 | 191 | { strcpy(Device_Info.Name,VL53L0X_STRING_DEVICE_INFO_NAME_TS0); } |
sepp_nepp | 11:c6f95a42d4d7 | 192 | else if ((revision <= 34) && (revision != 32)) |
sepp_nepp | 11:c6f95a42d4d7 | 193 | { strcpy(Device_Info.Name,VL53L0X_STRING_DEVICE_INFO_NAME_TS1); } |
sepp_nepp | 11:c6f95a42d4d7 | 194 | else if (revision < 39) |
sepp_nepp | 11:c6f95a42d4d7 | 195 | { strcpy(Device_Info.Name,VL53L0X_STRING_DEVICE_INFO_NAME_TS2); } |
sepp_nepp | 11:c6f95a42d4d7 | 196 | else { strcpy(Device_Info.Name,VL53L0X_STRING_DEVICE_INFO_NAME_ES1); } |
sepp_nepp | 11:c6f95a42d4d7 | 197 | strcpy(Device_Info.Type,VL53L0X_STRING_DEVICE_INFO_TYPE); |
sepp_nepp | 11:c6f95a42d4d7 | 198 | } |
sepp_nepp | 11:c6f95a42d4d7 | 199 | |
sepp_nepp | 11:c6f95a42d4d7 | 200 | Device_Info.ProductRevisionMajor = 1; |
sepp_nepp | 11:c6f95a42d4d7 | 201 | Device_Info.ProductRevisionMinor = |
sepp_nepp | 11:c6f95a42d4d7 | 202 | (Read_Byte(REG_IDENTIFICATION_REVISION_ID) & 0xF0) >> 4; |
nikapov | 0:a1a69d32f310 | 203 | } |
sepp_nepp | 11:c6f95a42d4d7 | 204 | |
sepp_nepp | 11:c6f95a42d4d7 | 205 | |
sepp_nepp | 11:c6f95a42d4d7 | 206 | uint32_t VL53L0X::Get_distance() |
sepp_nepp | 11:c6f95a42d4d7 | 207 | { ErrState = VL53L0X_OK; |
sepp_nepp | 11:c6f95a42d4d7 | 208 | TRangeResults p_ranging_results; |
sepp_nepp | 11:c6f95a42d4d7 | 209 | |
sepp_nepp | 11:c6f95a42d4d7 | 210 | Start_Measurement(op_single_shot_poll, NULL); |
sepp_nepp | 11:c6f95a42d4d7 | 211 | if (ErrState==VL53L0X_OK) |
sepp_nepp | 11:c6f95a42d4d7 | 212 | { p_ranging_results = Get_Measurement(op_single_shot_poll); } |
sepp_nepp | 11:c6f95a42d4d7 | 213 | |
sepp_nepp | 11:c6f95a42d4d7 | 214 | Stop_Measurement(op_single_shot_poll); |
sepp_nepp | 11:c6f95a42d4d7 | 215 | |
sepp_nepp | 11:c6f95a42d4d7 | 216 | if (p_ranging_results.RangeStatus == 0) // we have a valid range ? |
sepp_nepp | 11:c6f95a42d4d7 | 217 | { return p_ranging_results.RangeMilliMeter; } |
sepp_nepp | 11:c6f95a42d4d7 | 218 | else |
sepp_nepp | 11:c6f95a42d4d7 | 219 | { ErrState = VL53L0X_ERROR_RANGE_ERROR; return 0;} |
nikapov | 0:a1a69d32f310 | 220 | } |
nikapov | 0:a1a69d32f310 | 221 | |
sepp_nepp | 11:c6f95a42d4d7 | 222 | TRangeResults VL53L0X::Get_Measurement(TOperatingMode operating_mode) |
sepp_nepp | 11:c6f95a42d4d7 | 223 | { TRangeResults p_data; |
sepp_nepp | 11:c6f95a42d4d7 | 224 | |
sepp_nepp | 11:c6f95a42d4d7 | 225 | switch (operating_mode) { |
sepp_nepp | 11:c6f95a42d4d7 | 226 | case op_single_shot_poll: |
sepp_nepp | 11:c6f95a42d4d7 | 227 | Perf_single_ranging_measurement(&p_data); |
sepp_nepp | 11:c6f95a42d4d7 | 228 | break; |
sepp_nepp | 11:c6f95a42d4d7 | 229 | case op_poll: |
sepp_nepp | 11:c6f95a42d4d7 | 230 | Poll_Measure_Completion(); |
sepp_nepp | 11:c6f95a42d4d7 | 231 | Get_ranging_results(&p_data); |
sepp_nepp | 11:c6f95a42d4d7 | 232 | if (ErrState == VL53L0X_OK) { // Clear the interrupt |
sepp_nepp | 11:c6f95a42d4d7 | 233 | Clear_interrupt_mask(REG_SYSINT_GPIO_NEW_SAMPLE_READY); |
sepp_nepp | 11:c6f95a42d4d7 | 234 | Polling_delay(); |
sepp_nepp | 11:c6f95a42d4d7 | 235 | } |
sepp_nepp | 11:c6f95a42d4d7 | 236 | break; |
sepp_nepp | 11:c6f95a42d4d7 | 237 | case op_INT: |
sepp_nepp | 11:c6f95a42d4d7 | 238 | Get_ranging_results(&p_data); |
sepp_nepp | 11:c6f95a42d4d7 | 239 | Clear_interrupt_mask(REG_SYSINT_CLEAR | REG_RESULT_INTERRUPT_STATUS); |
sepp_nepp | 11:c6f95a42d4d7 | 240 | } // switch |
sepp_nepp | 11:c6f95a42d4d7 | 241 | return p_data; |
sepp_nepp | 11:c6f95a42d4d7 | 242 | } |
sepp_nepp | 11:c6f95a42d4d7 | 243 | |
sepp_nepp | 11:c6f95a42d4d7 | 244 | /** Get part to part calibration offset; Should only be used after a |
sepp_nepp | 11:c6f95a42d4d7 | 245 | successful call to @a VL53L0X_DataInit to backup device NVM value **/ |
sepp_nepp | 11:c6f95a42d4d7 | 246 | int32_t VL53L0X::Get_Offset_Cal_um() |
sepp_nepp | 11:c6f95a42d4d7 | 247 | { uint16_t range_offset_register; |
nikapov | 0:a1a69d32f310 | 248 | int16_t c_max_offset = 2047; |
nikapov | 0:a1a69d32f310 | 249 | int16_t c_offset_range = 4096; |
nikapov | 0:a1a69d32f310 | 250 | |
nikapov | 0:a1a69d32f310 | 251 | /* Note that offset has 10.2 format */ |
sepp_nepp | 11:c6f95a42d4d7 | 252 | range_offset_register = Read_Word(REG_ALGO_PART_TO_PART_RANGE_OFFSET_MM); |
sepp_nepp | 11:c6f95a42d4d7 | 253 | |
sepp_nepp | 11:c6f95a42d4d7 | 254 | if (ErrState == VL53L0X_OK) { |
nikapov | 0:a1a69d32f310 | 255 | range_offset_register = (range_offset_register & 0x0fff); |
nikapov | 0:a1a69d32f310 | 256 | |
sepp_nepp | 11:c6f95a42d4d7 | 257 | /* Apply 12 bit 2's complement conversion */ |
sepp_nepp | 11:c6f95a42d4d7 | 258 | if (range_offset_register > c_max_offset) |
sepp_nepp | 11:c6f95a42d4d7 | 259 | { return (int16_t)(range_offset_register - c_offset_range) * 250; } |
sepp_nepp | 11:c6f95a42d4d7 | 260 | else |
sepp_nepp | 11:c6f95a42d4d7 | 261 | { return (int16_t)range_offset_register * 250;} |
nikapov | 0:a1a69d32f310 | 262 | } |
sepp_nepp | 11:c6f95a42d4d7 | 263 | else return 0; |
nikapov | 0:a1a69d32f310 | 264 | } |
nikapov | 0:a1a69d32f310 | 265 | |
sepp_nepp | 11:c6f95a42d4d7 | 266 | void VL53L0X::Set_Offset_Cal_um(int32_t Offset_Cal_um) |
sepp_nepp | 11:c6f95a42d4d7 | 267 | { int32_t c_max_offset_um = 511000; |
sepp_nepp | 10:cd251e0fc2fd | 268 | int32_t c_min_offset_um = -512000; |
sepp_nepp | 11:c6f95a42d4d7 | 269 | int16_t c_offset_range = 4096; |
nikapov | 0:a1a69d32f310 | 270 | uint32_t encoded_offset_val; |
nikapov | 0:a1a69d32f310 | 271 | |
sepp_nepp | 11:c6f95a42d4d7 | 272 | if (Offset_Cal_um > c_max_offset_um) { Offset_Cal_um = c_max_offset_um; } |
sepp_nepp | 11:c6f95a42d4d7 | 273 | else |
sepp_nepp | 11:c6f95a42d4d7 | 274 | if (Offset_Cal_um < c_min_offset_um) { Offset_Cal_um = c_min_offset_um; } |
nikapov | 0:a1a69d32f310 | 275 | |
nikapov | 0:a1a69d32f310 | 276 | /* The offset register is 10.2 format and units are mm |
sepp_nepp | 10:cd251e0fc2fd | 277 | * therefore conversion is applied by a division of 250. */ |
sepp_nepp | 11:c6f95a42d4d7 | 278 | if (Offset_Cal_um >= 0) { encoded_offset_val = Offset_Cal_um / 250; } |
sepp_nepp | 11:c6f95a42d4d7 | 279 | else { encoded_offset_val = c_offset_range + Offset_Cal_um / 250; } |
sepp_nepp | 11:c6f95a42d4d7 | 280 | |
sepp_nepp | 11:c6f95a42d4d7 | 281 | Write_Word(REG_ALGO_PART_TO_PART_RANGE_OFFSET_MM, encoded_offset_val); |
nikapov | 0:a1a69d32f310 | 282 | } |
nikapov | 0:a1a69d32f310 | 283 | |
sepp_nepp | 11:c6f95a42d4d7 | 284 | void VL53L0X::VL53L0X_Apply_Offset_Cal() |
sepp_nepp | 11:c6f95a42d4d7 | 285 | { int32_t Summed_Offset_Cal_um; |
sepp_nepp | 11:c6f95a42d4d7 | 286 | |
sepp_nepp | 11:c6f95a42d4d7 | 287 | /* read all NVM info used by the API */ |
sepp_nepp | 11:c6f95a42d4d7 | 288 | Get_info_from_device(7); |
sepp_nepp | 11:c6f95a42d4d7 | 289 | |
sepp_nepp | 11:c6f95a42d4d7 | 290 | /* Read back current device offset, and remember in case later someone wants to use it */ |
sepp_nepp | 11:c6f95a42d4d7 | 291 | if (ErrState == VL53L0X_OK) { Last_Offset_Cal_um = Get_Offset_Cal_um(); } |
nikapov | 0:a1a69d32f310 | 292 | |
nikapov | 0:a1a69d32f310 | 293 | /* Apply Offset Adjustment derived from 400mm measurements */ |
sepp_nepp | 11:c6f95a42d4d7 | 294 | if (ErrState == VL53L0X_OK) |
sepp_nepp | 11:c6f95a42d4d7 | 295 | { Summed_Offset_Cal_um = Last_Offset_Cal_um + (int32_t) NVM_Offset_Cal_um; |
sepp_nepp | 11:c6f95a42d4d7 | 296 | Set_Offset_Cal_um(Summed_Offset_Cal_um); |
sepp_nepp | 11:c6f95a42d4d7 | 297 | /* remember current,adjusted offset */ |
sepp_nepp | 11:c6f95a42d4d7 | 298 | if (ErrState == VL53L0X_OK) { CurrParams.Offset_Cal_um = Summed_Offset_Cal_um; } |
sepp_nepp | 11:c6f95a42d4d7 | 299 | } |
sepp_nepp | 11:c6f95a42d4d7 | 300 | } |
sepp_nepp | 11:c6f95a42d4d7 | 301 | |
sepp_nepp | 11:c6f95a42d4d7 | 302 | void VL53L0X::Get_measure_period_ms(uint32_t *p_measure_period_ms) |
sepp_nepp | 11:c6f95a42d4d7 | 303 | { uint16_t osc_calibrate_val; |
sepp_nepp | 11:c6f95a42d4d7 | 304 | uint32_t im_period_ms; |
sepp_nepp | 11:c6f95a42d4d7 | 305 | |
sepp_nepp | 11:c6f95a42d4d7 | 306 | osc_calibrate_val = Read_Word(REG_OSC_CALIBRATE_VAL); |
sepp_nepp | 11:c6f95a42d4d7 | 307 | |
sepp_nepp | 11:c6f95a42d4d7 | 308 | if (ErrState == VL53L0X_OK) { im_period_ms = Read_DWord(REG_SYSTEM_MEASURE_PERIOD); } |
sepp_nepp | 11:c6f95a42d4d7 | 309 | |
sepp_nepp | 11:c6f95a42d4d7 | 310 | if (ErrState == VL53L0X_OK) { |
sepp_nepp | 11:c6f95a42d4d7 | 311 | if (osc_calibrate_val != 0) |
sepp_nepp | 11:c6f95a42d4d7 | 312 | {*p_measure_period_ms = im_period_ms / osc_calibrate_val; } |
sepp_nepp | 11:c6f95a42d4d7 | 313 | CurrParams.Measure_Period_ms = *p_measure_period_ms; |
sepp_nepp | 11:c6f95a42d4d7 | 314 | } |
sepp_nepp | 11:c6f95a42d4d7 | 315 | } |
sepp_nepp | 11:c6f95a42d4d7 | 316 | |
sepp_nepp | 11:c6f95a42d4d7 | 317 | void VL53L0X::Get_Xtalk_CompRate_MHz( TFP1616 *p_Xtalk_CompRate_MHz) |
sepp_nepp | 11:c6f95a42d4d7 | 318 | { uint16_t value; |
sepp_nepp | 11:c6f95a42d4d7 | 319 | TFP1616 temp_fix1616; |
sepp_nepp | 11:c6f95a42d4d7 | 320 | |
sepp_nepp | 11:c6f95a42d4d7 | 321 | value = Read_Word(REG_XTALK_COMPENS_RATE_MHz); |
sepp_nepp | 11:c6f95a42d4d7 | 322 | |
sepp_nepp | 11:c6f95a42d4d7 | 323 | if (ErrState == VL53L0X_OK) { |
sepp_nepp | 11:c6f95a42d4d7 | 324 | if (value == 0) { |
sepp_nepp | 11:c6f95a42d4d7 | 325 | /* the Xtalk is disabled return value from memory */ |
sepp_nepp | 11:c6f95a42d4d7 | 326 | temp_fix1616 = CurrParams.Xtalk_CompRate_MHz; |
sepp_nepp | 11:c6f95a42d4d7 | 327 | *p_Xtalk_CompRate_MHz = temp_fix1616; |
sepp_nepp | 11:c6f95a42d4d7 | 328 | CurrParams.XTalk_Compens_En = 0; |
sepp_nepp | 11:c6f95a42d4d7 | 329 | } else { |
sepp_nepp | 11:c6f95a42d4d7 | 330 | temp_fix1616 = FP313_TO_FP1616(value); |
sepp_nepp | 11:c6f95a42d4d7 | 331 | *p_Xtalk_CompRate_MHz = temp_fix1616; |
sepp_nepp | 11:c6f95a42d4d7 | 332 | CurrParams.Xtalk_CompRate_MHz = temp_fix1616; |
sepp_nepp | 11:c6f95a42d4d7 | 333 | CurrParams.XTalk_Compens_En = 1; |
nikapov | 0:a1a69d32f310 | 334 | } |
nikapov | 0:a1a69d32f310 | 335 | } |
nikapov | 0:a1a69d32f310 | 336 | } |
nikapov | 0:a1a69d32f310 | 337 | |
sepp_nepp | 11:c6f95a42d4d7 | 338 | TFP1616 VL53L0X::Get_limit_chk_val( uint16_t limit_check_id ) |
sepp_nepp | 11:c6f95a42d4d7 | 339 | { uint16_t temp16; |
sepp_nepp | 11:c6f95a42d4d7 | 340 | TFP1616 temp_fix1616; |
nikapov | 0:a1a69d32f310 | 341 | |
nikapov | 0:a1a69d32f310 | 342 | switch (limit_check_id) { |
sepp_nepp | 11:c6f95a42d4d7 | 343 | case VL53L0X_CHECKEN_SIGMA_FINAL_RANGE: /* only internal computations: */ |
sepp_nepp | 11:c6f95a42d4d7 | 344 | case VL53L0X_CHECKEN_SIG_REF_CLIP: |
sepp_nepp | 11:c6f95a42d4d7 | 345 | case VL53L0X_CHECKEN_RANGE_IGNORE_THRESHOLD: |
sepp_nepp | 11:c6f95a42d4d7 | 346 | return CurrParams.Limit_Chk_Val[limit_check_id];// need no more 'break'; |
sepp_nepp | 11:c6f95a42d4d7 | 347 | |
sepp_nepp | 11:c6f95a42d4d7 | 348 | case VL53L0X_CHECKEN_SIG_RATE_FINAL_RANGE: |
sepp_nepp | 11:c6f95a42d4d7 | 349 | temp16 = Read_Word(REG_FINAL_RANGE_CONFIG_MIN_COUNT_RATE_RTN_LIMIT); |
sepp_nepp | 11:c6f95a42d4d7 | 350 | temp_fix1616 = FP97_TO_FP1616(temp16); |
sepp_nepp | 11:c6f95a42d4d7 | 351 | if (temp_fix1616 == 0) /* disabled: return value from memory instead*/ |
sepp_nepp | 11:c6f95a42d4d7 | 352 | { temp_fix1616 = CurrParams.Limit_Chk_Val[limit_check_id]; |
sepp_nepp | 11:c6f95a42d4d7 | 353 | CurrParams.Limit_Chk_En[limit_check_id] = 0; } |
sepp_nepp | 11:c6f95a42d4d7 | 354 | else |
sepp_nepp | 11:c6f95a42d4d7 | 355 | { CurrParams.Limit_Chk_Val[limit_check_id] = temp_fix1616; |
sepp_nepp | 11:c6f95a42d4d7 | 356 | CurrParams.Limit_Chk_En[limit_check_id] = 1; } |
sepp_nepp | 11:c6f95a42d4d7 | 357 | return temp_fix1616; // need no more 'break'; |
sepp_nepp | 11:c6f95a42d4d7 | 358 | |
sepp_nepp | 11:c6f95a42d4d7 | 359 | case VL53L0X_CHECKEN_SIG_RATE_MSRC: |
sepp_nepp | 11:c6f95a42d4d7 | 360 | case VL53L0X_CHECKEN_SIG_RATE_PRE_RANGE: |
sepp_nepp | 11:c6f95a42d4d7 | 361 | temp16 = Read_Word(REG_PRE_RANGE_MIN_COUNT_RATE_RTN_LIMIT); |
sepp_nepp | 11:c6f95a42d4d7 | 362 | return FP97_TO_FP1616(temp16); // need no more break; |
nikapov | 0:a1a69d32f310 | 363 | |
nikapov | 0:a1a69d32f310 | 364 | default: |
sepp_nepp | 11:c6f95a42d4d7 | 365 | ErrState = VL53L0X_ERROR_INVALID_PARAMS; |
sepp_nepp | 11:c6f95a42d4d7 | 366 | return 0; |
nikapov | 0:a1a69d32f310 | 367 | } |
nikapov | 0:a1a69d32f310 | 368 | } |
nikapov | 0:a1a69d32f310 | 369 | |
sepp_nepp | 11:c6f95a42d4d7 | 370 | uint8_t VL53L0X::Get_limit_chk_en(uint16_t limit_check_id ) |
sepp_nepp | 11:c6f95a42d4d7 | 371 | { if (limit_check_id >= VL53L0X_CHECKEN_NUMBER_OF_CHECKS) |
sepp_nepp | 11:c6f95a42d4d7 | 372 | { ErrState = VL53L0X_ERROR_INVALID_PARAMS; |
sepp_nepp | 11:c6f95a42d4d7 | 373 | return 0; } |
sepp_nepp | 11:c6f95a42d4d7 | 374 | else { return CurrParams.Limit_Chk_En[limit_check_id]; } |
nikapov | 0:a1a69d32f310 | 375 | } |
nikapov | 0:a1a69d32f310 | 376 | |
sepp_nepp | 11:c6f95a42d4d7 | 377 | uint8_t VL53L0X::Get_Wrap_Around_Chk_En() |
sepp_nepp | 11:c6f95a42d4d7 | 378 | { /* Now using the private state field SequenceConfig instead of reading from device: |
sepp_nepp | 11:c6f95a42d4d7 | 379 | uint8_t SequenceConfig; |
sepp_nepp | 11:c6f95a42d4d7 | 380 | SequenceConfig = Read_Byte(REG_SYSTEM_SEQUENCE_CONFIG); |
sepp_nepp | 11:c6f95a42d4d7 | 381 | Set_SequenceConfig( SequenceConfig ); // checks for ErrState |
sepp_nepp | 5:b95f6951f7d5 | 382 | |
sepp_nepp | 11:c6f95a42d4d7 | 383 | if (ErrState == VL53L0X_OK) { |
sepp_nepp | 11:c6f95a42d4d7 | 384 | */ |
sepp_nepp | 11:c6f95a42d4d7 | 385 | CurrParams.Wrap_Around_Chk_En = (SequenceConfig >> 7) & 0x01; |
sepp_nepp | 11:c6f95a42d4d7 | 386 | return CurrParams.Wrap_Around_Chk_En; |
sepp_nepp | 11:c6f95a42d4d7 | 387 | // } else return 0; |
nikapov | 0:a1a69d32f310 | 388 | } |
nikapov | 0:a1a69d32f310 | 389 | |
sepp_nepp | 11:c6f95a42d4d7 | 390 | VL53L0X_Sequence_Steps_t VL53L0X::Get_sequence_step_enables() |
sepp_nepp | 11:c6f95a42d4d7 | 391 | { VL53L0X_Sequence_Steps_t p_sequence_steps; |
sepp_nepp | 11:c6f95a42d4d7 | 392 | /* Now using the private state field SequenceConfig instead of reading from device: |
sepp_nepp | 11:c6f95a42d4d7 | 393 | uint8_t SequenceConfig; |
sepp_nepp | 11:c6f95a42d4d7 | 394 | |
sepp_nepp | 11:c6f95a42d4d7 | 395 | SequenceConfig = Read_Byte(REG_SYSTEM_SEQUENCE_CONFIG); |
sepp_nepp | 11:c6f95a42d4d7 | 396 | |
sepp_nepp | 11:c6f95a42d4d7 | 397 | if (ErrState == VL53L0X_OK) { |
sepp_nepp | 11:c6f95a42d4d7 | 398 | */ |
sepp_nepp | 11:c6f95a42d4d7 | 399 | p_sequence_steps.TccOn = (SequenceConfig & 0x10) >> 4; |
sepp_nepp | 11:c6f95a42d4d7 | 400 | p_sequence_steps.DssOn = (SequenceConfig & 0x08) >> 3; |
sepp_nepp | 11:c6f95a42d4d7 | 401 | p_sequence_steps.MsrcOn = (SequenceConfig & 0x04) >> 2; |
sepp_nepp | 11:c6f95a42d4d7 | 402 | p_sequence_steps.PreRangeOn = (SequenceConfig & 0x40) >> 6; |
sepp_nepp | 11:c6f95a42d4d7 | 403 | p_sequence_steps.FinalRangeOn = (SequenceConfig & 0x80) >> 7; |
sepp_nepp | 11:c6f95a42d4d7 | 404 | // } |
sepp_nepp | 11:c6f95a42d4d7 | 405 | return p_sequence_steps; |
nikapov | 0:a1a69d32f310 | 406 | } |
nikapov | 0:a1a69d32f310 | 407 | |
sepp_nepp | 11:c6f95a42d4d7 | 408 | void VL53L0X::Set_vcsel_PPeriod(VL53L0X_Range_Phase Vcsel_Range_Phase, uint8_t vcsel_PPeriod_pclk) |
sepp_nepp | 11:c6f95a42d4d7 | 409 | { uint8_t vcsel_period_reg; |
nikapov | 0:a1a69d32f310 | 410 | uint8_t min_pre_vcsel_period_pclk = 12; |
nikapov | 0:a1a69d32f310 | 411 | uint8_t max_pre_vcsel_period_pclk = 18; |
nikapov | 0:a1a69d32f310 | 412 | uint8_t min_final_vcsel_period_pclk = 8; |
nikapov | 0:a1a69d32f310 | 413 | uint8_t max_final_vcsel_period_pclk = 14; |
sepp_nepp | 10:cd251e0fc2fd | 414 | uint32_t final_range_timeout_us; |
sepp_nepp | 10:cd251e0fc2fd | 415 | uint32_t pre_range_timeout_us; |
sepp_nepp | 10:cd251e0fc2fd | 416 | uint32_t msrc_timeout_us; |
nikapov | 0:a1a69d32f310 | 417 | uint8_t phase_cal_int = 0; |
nikapov | 0:a1a69d32f310 | 418 | |
nikapov | 0:a1a69d32f310 | 419 | /* Check if valid clock period requested */ |
sepp_nepp | 11:c6f95a42d4d7 | 420 | if ( ((vcsel_PPeriod_pclk % 2) != 0 ) /* Value must be an even number */ |
sepp_nepp | 11:c6f95a42d4d7 | 421 | || |
sepp_nepp | 11:c6f95a42d4d7 | 422 | ( Vcsel_Range_Phase == VL53L0X_VCSEL_PRE_RANGE && |
sepp_nepp | 11:c6f95a42d4d7 | 423 | ((vcsel_PPeriod_pclk < min_pre_vcsel_period_pclk)|| |
sepp_nepp | 11:c6f95a42d4d7 | 424 | (vcsel_PPeriod_pclk > max_pre_vcsel_period_pclk) ) ) |
sepp_nepp | 11:c6f95a42d4d7 | 425 | || |
sepp_nepp | 11:c6f95a42d4d7 | 426 | ( Vcsel_Range_Phase == VL53L0X_VCSEL_FINAL_RANGE && |
sepp_nepp | 11:c6f95a42d4d7 | 427 | (vcsel_PPeriod_pclk < min_final_vcsel_period_pclk || |
sepp_nepp | 11:c6f95a42d4d7 | 428 | vcsel_PPeriod_pclk > max_final_vcsel_period_pclk) ) ) |
sepp_nepp | 11:c6f95a42d4d7 | 429 | { ErrState = VL53L0X_ERROR_INVALID_PARAMS; |
sepp_nepp | 11:c6f95a42d4d7 | 430 | return;} |
nikapov | 0:a1a69d32f310 | 431 | |
nikapov | 0:a1a69d32f310 | 432 | /* Apply specific settings for the requested clock period */ |
sepp_nepp | 11:c6f95a42d4d7 | 433 | if (Vcsel_Range_Phase == VL53L0X_VCSEL_PRE_RANGE) { |
sepp_nepp | 11:c6f95a42d4d7 | 434 | /* Set phase check limits for pre-ranging*/ |
sepp_nepp | 11:c6f95a42d4d7 | 435 | if (vcsel_PPeriod_pclk == 12) { |
sepp_nepp | 11:c6f95a42d4d7 | 436 | Write_Byte(REG_PRE_RANGE_CONFIG_VALID_PHASE_HIGH,0x18); |
sepp_nepp | 11:c6f95a42d4d7 | 437 | Write_Byte(REG_PRE_RANGE_CONFIG_VALID_PHASE_LOW ,0x08); |
sepp_nepp | 11:c6f95a42d4d7 | 438 | } else if (vcsel_PPeriod_pclk == 14) { |
sepp_nepp | 11:c6f95a42d4d7 | 439 | Write_Byte(REG_PRE_RANGE_CONFIG_VALID_PHASE_HIGH,0x30); |
sepp_nepp | 11:c6f95a42d4d7 | 440 | Write_Byte(REG_PRE_RANGE_CONFIG_VALID_PHASE_LOW ,0x08); |
sepp_nepp | 11:c6f95a42d4d7 | 441 | } else if (vcsel_PPeriod_pclk == 16) { |
sepp_nepp | 11:c6f95a42d4d7 | 442 | Write_Byte(REG_PRE_RANGE_CONFIG_VALID_PHASE_HIGH,0x40); |
sepp_nepp | 11:c6f95a42d4d7 | 443 | Write_Byte(REG_PRE_RANGE_CONFIG_VALID_PHASE_LOW ,0x08); |
sepp_nepp | 11:c6f95a42d4d7 | 444 | } else if (vcsel_PPeriod_pclk == 18) { |
sepp_nepp | 11:c6f95a42d4d7 | 445 | Write_Byte(REG_PRE_RANGE_CONFIG_VALID_PHASE_HIGH,0x50); |
sepp_nepp | 11:c6f95a42d4d7 | 446 | Write_Byte(REG_PRE_RANGE_CONFIG_VALID_PHASE_LOW ,0x08); |
nikapov | 0:a1a69d32f310 | 447 | } |
sepp_nepp | 11:c6f95a42d4d7 | 448 | } else if (Vcsel_Range_Phase == VL53L0X_VCSEL_FINAL_RANGE) { |
sepp_nepp | 11:c6f95a42d4d7 | 449 | if (vcsel_PPeriod_pclk == 8) { |
sepp_nepp | 11:c6f95a42d4d7 | 450 | Write_Byte(REG_FINAL_RANGE_CONFIG_VALID_PHASE_HIGH,0x10); |
sepp_nepp | 11:c6f95a42d4d7 | 451 | Write_Byte(REG_FINAL_RANGE_CONFIG_VALID_PHASE_LOW ,0x08); |
sepp_nepp | 11:c6f95a42d4d7 | 452 | Write_Byte(REG_GLOBAL_CONFIG_VCSEL_WIDTH ,0x02); |
sepp_nepp | 11:c6f95a42d4d7 | 453 | Write_Byte(REG_ALGO_PHASECAL_CONFIG_TIMEOUT,0x0C); |
sepp_nepp | 11:c6f95a42d4d7 | 454 | Write_Byte(0xff,0x01); |
sepp_nepp | 11:c6f95a42d4d7 | 455 | Write_Byte(REG_ALGO_PHASECAL_LIM,0x30); |
sepp_nepp | 11:c6f95a42d4d7 | 456 | Write_Byte(0xff,0x00); |
sepp_nepp | 11:c6f95a42d4d7 | 457 | } else if (vcsel_PPeriod_pclk == 10) { |
sepp_nepp | 11:c6f95a42d4d7 | 458 | Write_Byte(REG_FINAL_RANGE_CONFIG_VALID_PHASE_HIGH,0x28); |
sepp_nepp | 11:c6f95a42d4d7 | 459 | Write_Byte(REG_FINAL_RANGE_CONFIG_VALID_PHASE_LOW,0x08); |
sepp_nepp | 11:c6f95a42d4d7 | 460 | Write_Byte(REG_GLOBAL_CONFIG_VCSEL_WIDTH,0x03); |
sepp_nepp | 11:c6f95a42d4d7 | 461 | Write_Byte(REG_ALGO_PHASECAL_CONFIG_TIMEOUT,0x09); |
sepp_nepp | 11:c6f95a42d4d7 | 462 | Write_Byte(0xff,0x01); |
sepp_nepp | 11:c6f95a42d4d7 | 463 | Write_Byte(REG_ALGO_PHASECAL_LIM,0x20); |
sepp_nepp | 11:c6f95a42d4d7 | 464 | Write_Byte(0xff,0x00); |
sepp_nepp | 11:c6f95a42d4d7 | 465 | } else if (vcsel_PPeriod_pclk == 12) { |
sepp_nepp | 11:c6f95a42d4d7 | 466 | Write_Byte(REG_FINAL_RANGE_CONFIG_VALID_PHASE_HIGH,0x38); |
sepp_nepp | 11:c6f95a42d4d7 | 467 | Write_Byte(REG_FINAL_RANGE_CONFIG_VALID_PHASE_LOW,0x08); |
sepp_nepp | 11:c6f95a42d4d7 | 468 | Write_Byte(REG_GLOBAL_CONFIG_VCSEL_WIDTH,0x03); |
sepp_nepp | 11:c6f95a42d4d7 | 469 | Write_Byte(REG_ALGO_PHASECAL_CONFIG_TIMEOUT,0x08); |
sepp_nepp | 11:c6f95a42d4d7 | 470 | Write_Byte(0xff,0x01); |
sepp_nepp | 11:c6f95a42d4d7 | 471 | Write_Byte(REG_ALGO_PHASECAL_LIM,0x20); |
sepp_nepp | 11:c6f95a42d4d7 | 472 | Write_Byte(0xff,0x00); |
sepp_nepp | 11:c6f95a42d4d7 | 473 | } else if (vcsel_PPeriod_pclk == 14) { |
sepp_nepp | 11:c6f95a42d4d7 | 474 | Write_Byte(REG_FINAL_RANGE_CONFIG_VALID_PHASE_HIGH,0x048); |
sepp_nepp | 11:c6f95a42d4d7 | 475 | Write_Byte(REG_FINAL_RANGE_CONFIG_VALID_PHASE_LOW,0x08); |
sepp_nepp | 11:c6f95a42d4d7 | 476 | Write_Byte(REG_GLOBAL_CONFIG_VCSEL_WIDTH,0x03); |
sepp_nepp | 11:c6f95a42d4d7 | 477 | Write_Byte(REG_ALGO_PHASECAL_CONFIG_TIMEOUT,0x07); |
sepp_nepp | 11:c6f95a42d4d7 | 478 | Write_Byte(0xff,0x01); |
sepp_nepp | 11:c6f95a42d4d7 | 479 | Write_Byte(REG_ALGO_PHASECAL_LIM, 0x20); |
sepp_nepp | 11:c6f95a42d4d7 | 480 | Write_Byte(0xff,0x00); |
nikapov | 0:a1a69d32f310 | 481 | } |
nikapov | 0:a1a69d32f310 | 482 | } |
nikapov | 0:a1a69d32f310 | 483 | |
sepp_nepp | 7:41cbc431e1f4 | 484 | /* Re-calculate and apply timeouts,in macro periods */ |
sepp_nepp | 11:c6f95a42d4d7 | 485 | if (ErrState == VL53L0X_OK) { |
sepp_nepp | 11:c6f95a42d4d7 | 486 | /* Converts the encoded VCSEL period register value into the real period in PLL clocks */ |
sepp_nepp | 11:c6f95a42d4d7 | 487 | /* Flattened from procedure called Encode_vcsel_period */ |
sepp_nepp | 11:c6f95a42d4d7 | 488 | vcsel_period_reg = (vcsel_PPeriod_pclk >> 1) - 1; |
sepp_nepp | 11:c6f95a42d4d7 | 489 | |
nikapov | 0:a1a69d32f310 | 490 | /* When the VCSEL period for the pre or final range is changed, |
nikapov | 0:a1a69d32f310 | 491 | * the corresponding timeout must be read from the device using |
sepp_nepp | 7:41cbc431e1f4 | 492 | * the current VCSEL period,then the new VCSEL period can be |
nikapov | 0:a1a69d32f310 | 493 | * applied. The timeout then must be written back to the device |
nikapov | 0:a1a69d32f310 | 494 | * using the new VCSEL period. |
sepp_nepp | 7:41cbc431e1f4 | 495 | * For the MSRC timeout,the same applies - this timeout being |
nikapov | 0:a1a69d32f310 | 496 | * dependant on the pre-range vcsel period. |
nikapov | 0:a1a69d32f310 | 497 | */ |
sepp_nepp | 11:c6f95a42d4d7 | 498 | switch (Vcsel_Range_Phase) { |
sepp_nepp | 11:c6f95a42d4d7 | 499 | case VL53L0X_VCSEL_PRE_RANGE: |
sepp_nepp | 11:c6f95a42d4d7 | 500 | Get_Sequence_Step_Timeout(VL53L0X_SEQUENCESTEP_PRE_RANGE,&pre_range_timeout_us); |
sepp_nepp | 11:c6f95a42d4d7 | 501 | |
sepp_nepp | 11:c6f95a42d4d7 | 502 | if (ErrState == VL53L0X_OK) |
sepp_nepp | 11:c6f95a42d4d7 | 503 | Get_Sequence_Step_Timeout(VL53L0X_SEQUENCESTEP_MSRC,&msrc_timeout_us); |
sepp_nepp | 11:c6f95a42d4d7 | 504 | |
sepp_nepp | 11:c6f95a42d4d7 | 505 | Write_Byte(REG_PRE_RANGE_CONFIG_VCSEL_PERIOD,vcsel_period_reg); |
sepp_nepp | 11:c6f95a42d4d7 | 506 | |
sepp_nepp | 11:c6f95a42d4d7 | 507 | if (ErrState == VL53L0X_OK) |
sepp_nepp | 11:c6f95a42d4d7 | 508 | Set_Sequence_Step_Timeout(VL53L0X_SEQUENCESTEP_PRE_RANGE,pre_range_timeout_us); |
sepp_nepp | 11:c6f95a42d4d7 | 509 | |
sepp_nepp | 11:c6f95a42d4d7 | 510 | if (ErrState == VL53L0X_OK) |
sepp_nepp | 11:c6f95a42d4d7 | 511 | Set_Sequence_Step_Timeout(VL53L0X_SEQUENCESTEP_MSRC,msrc_timeout_us); |
sepp_nepp | 11:c6f95a42d4d7 | 512 | |
sepp_nepp | 11:c6f95a42d4d7 | 513 | DevSpecParams.PreRangeVcselPPeriod = vcsel_PPeriod_pclk; |
sepp_nepp | 11:c6f95a42d4d7 | 514 | break; |
sepp_nepp | 11:c6f95a42d4d7 | 515 | |
sepp_nepp | 11:c6f95a42d4d7 | 516 | case VL53L0X_VCSEL_FINAL_RANGE: |
sepp_nepp | 11:c6f95a42d4d7 | 517 | Get_Sequence_Step_Timeout(VL53L0X_SEQUENCESTEP_FINAL_RANGE,&final_range_timeout_us); |
sepp_nepp | 11:c6f95a42d4d7 | 518 | |
sepp_nepp | 11:c6f95a42d4d7 | 519 | Write_Byte(REG_FINAL_RANGE_CONFIG_VCSEL_PERIOD,vcsel_period_reg); |
sepp_nepp | 11:c6f95a42d4d7 | 520 | |
sepp_nepp | 11:c6f95a42d4d7 | 521 | if (ErrState == VL53L0X_OK) |
sepp_nepp | 11:c6f95a42d4d7 | 522 | Set_Sequence_Step_Timeout(VL53L0X_SEQUENCESTEP_FINAL_RANGE,final_range_timeout_us); |
sepp_nepp | 11:c6f95a42d4d7 | 523 | |
sepp_nepp | 11:c6f95a42d4d7 | 524 | DevSpecParams.FinalRangeVcselPPeriod = vcsel_PPeriod_pclk; |
sepp_nepp | 11:c6f95a42d4d7 | 525 | break; |
sepp_nepp | 11:c6f95a42d4d7 | 526 | default: ErrState = VL53L0X_ERROR_INVALID_PARAMS; |
nikapov | 0:a1a69d32f310 | 527 | } |
nikapov | 0:a1a69d32f310 | 528 | } |
nikapov | 0:a1a69d32f310 | 529 | |
sepp_nepp | 11:c6f95a42d4d7 | 530 | /* Finally,the timing budget is re-applied */ |
sepp_nepp | 11:c6f95a42d4d7 | 531 | if (ErrState == VL53L0X_OK) |
sepp_nepp | 11:c6f95a42d4d7 | 532 | { Set_Measure_Time_Budget_us(CurrParams.Measure_Time_Budget_us); } |
sepp_nepp | 11:c6f95a42d4d7 | 533 | |
sepp_nepp | 11:c6f95a42d4d7 | 534 | /* Perform the phase calibration. This is needed after changing on vcsel period. |
sepp_nepp | 7:41cbc431e1f4 | 535 | * get_data_enable = 0,restore_config = 1 */ |
sepp_nepp | 11:c6f95a42d4d7 | 536 | Perf_phase_calibration(&phase_cal_int,0,1); |
nikapov | 0:a1a69d32f310 | 537 | } |
nikapov | 0:a1a69d32f310 | 538 | |
sepp_nepp | 11:c6f95a42d4d7 | 539 | #define VL53L0X_MACRO_PERIOD_NS 3813; // = ( VL53L0X_PLL_PERIOD_PS * VL53L0X_MACRO_PERIOD_VCLKS / 1000 ) |
nikapov | 0:a1a69d32f310 | 540 | |
nikapov | 0:a1a69d32f310 | 541 | /* To convert register value into us */ |
sepp_nepp | 11:c6f95a42d4d7 | 542 | uint32_t VL53L0X::Calc_timeout_us(uint16_t timeout_period_mclks, |
nikapov | 0:a1a69d32f310 | 543 | uint8_t vcsel_period_pclks) |
nikapov | 0:a1a69d32f310 | 544 | { |
nikapov | 0:a1a69d32f310 | 545 | uint32_t macro_period_ns; |
nikapov | 0:a1a69d32f310 | 546 | uint32_t actual_timeout_period_us = 0; |
nikapov | 0:a1a69d32f310 | 547 | |
sepp_nepp | 11:c6f95a42d4d7 | 548 | macro_period_ns = (uint32_t) (vcsel_period_pclks ) * VL53L0X_MACRO_PERIOD_NS; |
sepp_nepp | 11:c6f95a42d4d7 | 549 | |
sepp_nepp | 11:c6f95a42d4d7 | 550 | actual_timeout_period_us = ((timeout_period_mclks * macro_period_ns) + 500) / 1000; |
nikapov | 0:a1a69d32f310 | 551 | |
nikapov | 0:a1a69d32f310 | 552 | return actual_timeout_period_us; |
nikapov | 0:a1a69d32f310 | 553 | } |
nikapov | 0:a1a69d32f310 | 554 | |
sepp_nepp | 11:c6f95a42d4d7 | 555 | void VL53L0X::Get_Sequence_Step_Timeout(VL53L0X_SequenceStepId sequence_step_id, |
nikapov | 0:a1a69d32f310 | 556 | uint32_t *p_time_out_micro_secs) |
sepp_nepp | 11:c6f95a42d4d7 | 557 | { uint8_t current_vcsel_PPeriod_p_clk; |
nikapov | 0:a1a69d32f310 | 558 | uint8_t encoded_time_out_byte = 0; |
sepp_nepp | 10:cd251e0fc2fd | 559 | uint32_t timeout_us = 0; |
nikapov | 0:a1a69d32f310 | 560 | uint16_t pre_range_encoded_time_out = 0; |
nikapov | 0:a1a69d32f310 | 561 | uint16_t msrc_time_out_m_clks; |
nikapov | 0:a1a69d32f310 | 562 | uint16_t pre_range_time_out_m_clks; |
nikapov | 0:a1a69d32f310 | 563 | uint16_t final_range_time_out_m_clks = 0; |
nikapov | 0:a1a69d32f310 | 564 | uint16_t final_range_encoded_time_out; |
sepp_nepp | 11:c6f95a42d4d7 | 565 | VL53L0X_Sequence_Steps_t sequence_steps; |
sepp_nepp | 11:c6f95a42d4d7 | 566 | |
sepp_nepp | 11:c6f95a42d4d7 | 567 | if ((sequence_step_id == VL53L0X_SEQUENCESTEP_TCC ) || |
sepp_nepp | 11:c6f95a42d4d7 | 568 | (sequence_step_id == VL53L0X_SEQUENCESTEP_DSS ) || |
sepp_nepp | 11:c6f95a42d4d7 | 569 | (sequence_step_id == VL53L0X_SEQUENCESTEP_MSRC) ) { |
sepp_nepp | 11:c6f95a42d4d7 | 570 | |
sepp_nepp | 11:c6f95a42d4d7 | 571 | current_vcsel_PPeriod_p_clk = /* Gets and converts the VCSEL period register into actual clock periods */ |
sepp_nepp | 11:c6f95a42d4d7 | 572 | ( Read_Byte(REG_PRE_RANGE_CONFIG_VCSEL_PERIOD) + 1) << 1; |
sepp_nepp | 11:c6f95a42d4d7 | 573 | |
sepp_nepp | 11:c6f95a42d4d7 | 574 | if (ErrState == VL53L0X_OK) { |
sepp_nepp | 11:c6f95a42d4d7 | 575 | encoded_time_out_byte = Read_Byte(REG_MSRC_CONFIG_TIMEOUT_MACROP); |
nikapov | 0:a1a69d32f310 | 576 | } |
sepp_nepp | 11:c6f95a42d4d7 | 577 | msrc_time_out_m_clks = Decode_timeout(encoded_time_out_byte); |
sepp_nepp | 11:c6f95a42d4d7 | 578 | |
sepp_nepp | 11:c6f95a42d4d7 | 579 | timeout_us = Calc_timeout_us(msrc_time_out_m_clks, |
sepp_nepp | 11:c6f95a42d4d7 | 580 | current_vcsel_PPeriod_p_clk); |
nikapov | 0:a1a69d32f310 | 581 | } else if (sequence_step_id == VL53L0X_SEQUENCESTEP_PRE_RANGE) { |
sepp_nepp | 11:c6f95a42d4d7 | 582 | |
sepp_nepp | 11:c6f95a42d4d7 | 583 | current_vcsel_PPeriod_p_clk = /* Gets and converts the VCSEL period register into actual clock periods */ |
sepp_nepp | 11:c6f95a42d4d7 | 584 | ( Read_Byte(REG_PRE_RANGE_CONFIG_VCSEL_PERIOD) + 1) << 1; |
nikapov | 0:a1a69d32f310 | 585 | |
nikapov | 0:a1a69d32f310 | 586 | /* Retrieve PRE-RANGE Timeout in Macro periods (MCLKS) */ |
sepp_nepp | 11:c6f95a42d4d7 | 587 | if (ErrState == VL53L0X_OK) { |
sepp_nepp | 11:c6f95a42d4d7 | 588 | |
sepp_nepp | 11:c6f95a42d4d7 | 589 | pre_range_encoded_time_out = Read_Word(REG_PRE_RANGE_CONFIG_TIMEOUT_MACROP_HI); |
sepp_nepp | 11:c6f95a42d4d7 | 590 | |
sepp_nepp | 11:c6f95a42d4d7 | 591 | pre_range_time_out_m_clks = Decode_timeout(pre_range_encoded_time_out); |
sepp_nepp | 11:c6f95a42d4d7 | 592 | |
sepp_nepp | 11:c6f95a42d4d7 | 593 | timeout_us = Calc_timeout_us(pre_range_time_out_m_clks, |
sepp_nepp | 11:c6f95a42d4d7 | 594 | current_vcsel_PPeriod_p_clk); |
nikapov | 0:a1a69d32f310 | 595 | } |
nikapov | 0:a1a69d32f310 | 596 | } else if (sequence_step_id == VL53L0X_SEQUENCESTEP_FINAL_RANGE) { |
nikapov | 0:a1a69d32f310 | 597 | |
sepp_nepp | 11:c6f95a42d4d7 | 598 | sequence_steps = Get_sequence_step_enables(); |
nikapov | 0:a1a69d32f310 | 599 | pre_range_time_out_m_clks = 0; |
nikapov | 0:a1a69d32f310 | 600 | |
sepp_nepp | 11:c6f95a42d4d7 | 601 | if (sequence_steps.PreRangeOn) { |
sepp_nepp | 11:c6f95a42d4d7 | 602 | current_vcsel_PPeriod_p_clk = /* Gets and converts the VCSEL period register into actual clock periods */ |
sepp_nepp | 11:c6f95a42d4d7 | 603 | ( Read_Byte(REG_PRE_RANGE_CONFIG_VCSEL_PERIOD) + 1) << 1; |
sepp_nepp | 11:c6f95a42d4d7 | 604 | |
sepp_nepp | 11:c6f95a42d4d7 | 605 | /* Retrieve PRE-RANGE Timeout in Macro periods (MCLKS) */ |
sepp_nepp | 11:c6f95a42d4d7 | 606 | if (ErrState == VL53L0X_OK) { |
sepp_nepp | 11:c6f95a42d4d7 | 607 | pre_range_encoded_time_out = Read_Word(REG_PRE_RANGE_CONFIG_TIMEOUT_MACROP_HI); |
sepp_nepp | 11:c6f95a42d4d7 | 608 | pre_range_time_out_m_clks = Decode_timeout(pre_range_encoded_time_out); |
nikapov | 0:a1a69d32f310 | 609 | } |
nikapov | 0:a1a69d32f310 | 610 | } |
nikapov | 0:a1a69d32f310 | 611 | |
sepp_nepp | 11:c6f95a42d4d7 | 612 | if (ErrState == VL53L0X_OK) { |
sepp_nepp | 11:c6f95a42d4d7 | 613 | current_vcsel_PPeriod_p_clk = /* Get and converts the VCSEL period register into actual clock periods */ |
sepp_nepp | 11:c6f95a42d4d7 | 614 | ( Read_Byte(REG_FINAL_RANGE_CONFIG_VCSEL_PERIOD) + 1) << 1; |
sepp_nepp | 11:c6f95a42d4d7 | 615 | |
nikapov | 0:a1a69d32f310 | 616 | } |
nikapov | 0:a1a69d32f310 | 617 | |
nikapov | 0:a1a69d32f310 | 618 | /* Retrieve FINAL-RANGE Timeout in Macro periods (MCLKS) */ |
sepp_nepp | 11:c6f95a42d4d7 | 619 | if (ErrState == VL53L0X_OK) { |
sepp_nepp | 11:c6f95a42d4d7 | 620 | final_range_encoded_time_out = Read_Word(REG_FINAL_RANGE_CONFIG_TIMEOUT_MACROP_HI); |
sepp_nepp | 11:c6f95a42d4d7 | 621 | final_range_time_out_m_clks = Decode_timeout(final_range_encoded_time_out); |
nikapov | 0:a1a69d32f310 | 622 | } |
nikapov | 0:a1a69d32f310 | 623 | |
nikapov | 0:a1a69d32f310 | 624 | final_range_time_out_m_clks -= pre_range_time_out_m_clks; |
sepp_nepp | 11:c6f95a42d4d7 | 625 | timeout_us = Calc_timeout_us(final_range_time_out_m_clks,current_vcsel_PPeriod_p_clk); |
nikapov | 0:a1a69d32f310 | 626 | } |
nikapov | 0:a1a69d32f310 | 627 | |
sepp_nepp | 10:cd251e0fc2fd | 628 | *p_time_out_micro_secs = timeout_us; |
nikapov | 0:a1a69d32f310 | 629 | } |
nikapov | 0:a1a69d32f310 | 630 | |
sepp_nepp | 11:c6f95a42d4d7 | 631 | uint32_t VL53L0X::Get_Measure_Time_Budget_us() |
sepp_nepp | 11:c6f95a42d4d7 | 632 | { VL53L0X_Sequence_Steps_t sequence_steps; |
sepp_nepp | 11:c6f95a42d4d7 | 633 | uint32_t p_Measure_Time_Budget_us; |
sepp_nepp | 10:cd251e0fc2fd | 634 | uint32_t final_range_timeout_us; |
sepp_nepp | 11:c6f95a42d4d7 | 635 | uint32_t msrc_dcc_tcc_timeout_us= 2000; |
sepp_nepp | 10:cd251e0fc2fd | 636 | uint32_t start_overhead_us = 1910; |
sepp_nepp | 11:c6f95a42d4d7 | 637 | uint32_t end_overhead_us = 960; |
sepp_nepp | 10:cd251e0fc2fd | 638 | uint32_t msrc_overhead_us = 660; |
sepp_nepp | 11:c6f95a42d4d7 | 639 | uint32_t tcc_overhead_us = 590; |
sepp_nepp | 11:c6f95a42d4d7 | 640 | uint32_t dss_overhead_us = 690; |
sepp_nepp | 10:cd251e0fc2fd | 641 | uint32_t pre_range_overhead_us = 660; |
sepp_nepp | 11:c6f95a42d4d7 | 642 | uint32_t final_range_overhead_us= 550; |
sepp_nepp | 10:cd251e0fc2fd | 643 | uint32_t pre_range_timeout_us = 0; |
nikapov | 0:a1a69d32f310 | 644 | |
sepp_nepp | 11:c6f95a42d4d7 | 645 | if (ErrState != VL53L0X_OK) {return 0; } // do nothing while in Error State!!!! |
sepp_nepp | 11:c6f95a42d4d7 | 646 | |
nikapov | 0:a1a69d32f310 | 647 | /* Start and end overhead times always present */ |
sepp_nepp | 11:c6f95a42d4d7 | 648 | p_Measure_Time_Budget_us = start_overhead_us + end_overhead_us; |
sepp_nepp | 11:c6f95a42d4d7 | 649 | |
sepp_nepp | 11:c6f95a42d4d7 | 650 | sequence_steps = Get_sequence_step_enables(); |
sepp_nepp | 11:c6f95a42d4d7 | 651 | |
sepp_nepp | 11:c6f95a42d4d7 | 652 | if (sequence_steps.TccOn || sequence_steps.MsrcOn || sequence_steps.DssOn) |
sepp_nepp | 11:c6f95a42d4d7 | 653 | { Get_Sequence_Step_Timeout(VL53L0X_SEQUENCESTEP_MSRC, &msrc_dcc_tcc_timeout_us); |
sepp_nepp | 11:c6f95a42d4d7 | 654 | |
sepp_nepp | 11:c6f95a42d4d7 | 655 | if (ErrState == VL53L0X_OK) { |
sepp_nepp | 11:c6f95a42d4d7 | 656 | if (sequence_steps.TccOn) |
sepp_nepp | 11:c6f95a42d4d7 | 657 | { p_Measure_Time_Budget_us += msrc_dcc_tcc_timeout_us + tcc_overhead_us; } |
sepp_nepp | 11:c6f95a42d4d7 | 658 | |
sepp_nepp | 11:c6f95a42d4d7 | 659 | if (sequence_steps.DssOn) { |
sepp_nepp | 11:c6f95a42d4d7 | 660 | p_Measure_Time_Budget_us += 2 * (msrc_dcc_tcc_timeout_us + dss_overhead_us); |
sepp_nepp | 11:c6f95a42d4d7 | 661 | } else if (sequence_steps.MsrcOn) { |
sepp_nepp | 11:c6f95a42d4d7 | 662 | p_Measure_Time_Budget_us += msrc_dcc_tcc_timeout_us + msrc_overhead_us; |
nikapov | 0:a1a69d32f310 | 663 | } |
nikapov | 0:a1a69d32f310 | 664 | } |
nikapov | 0:a1a69d32f310 | 665 | } |
nikapov | 0:a1a69d32f310 | 666 | |
sepp_nepp | 11:c6f95a42d4d7 | 667 | if ( (ErrState == VL53L0X_OK) && sequence_steps.PreRangeOn) { |
sepp_nepp | 11:c6f95a42d4d7 | 668 | Get_Sequence_Step_Timeout(VL53L0X_SEQUENCESTEP_PRE_RANGE, &pre_range_timeout_us); |
sepp_nepp | 11:c6f95a42d4d7 | 669 | p_Measure_Time_Budget_us += pre_range_timeout_us + pre_range_overhead_us; |
sepp_nepp | 11:c6f95a42d4d7 | 670 | } |
sepp_nepp | 11:c6f95a42d4d7 | 671 | |
sepp_nepp | 11:c6f95a42d4d7 | 672 | if (ErrState == VL53L0X_OK) { |
sepp_nepp | 11:c6f95a42d4d7 | 673 | if (sequence_steps.FinalRangeOn) { |
sepp_nepp | 11:c6f95a42d4d7 | 674 | Get_Sequence_Step_Timeout(VL53L0X_SEQUENCESTEP_FINAL_RANGE, &final_range_timeout_us); |
sepp_nepp | 11:c6f95a42d4d7 | 675 | p_Measure_Time_Budget_us += (final_range_timeout_us + final_range_overhead_us); |
nikapov | 0:a1a69d32f310 | 676 | } |
nikapov | 0:a1a69d32f310 | 677 | } |
nikapov | 0:a1a69d32f310 | 678 | |
sepp_nepp | 11:c6f95a42d4d7 | 679 | if (ErrState == VL53L0X_OK) |
sepp_nepp | 11:c6f95a42d4d7 | 680 | { CurrParams.Measure_Time_Budget_us = p_Measure_Time_Budget_us; } |
sepp_nepp | 11:c6f95a42d4d7 | 681 | |
sepp_nepp | 11:c6f95a42d4d7 | 682 | return p_Measure_Time_Budget_us; |
nikapov | 0:a1a69d32f310 | 683 | } |
nikapov | 0:a1a69d32f310 | 684 | |
sepp_nepp | 11:c6f95a42d4d7 | 685 | VL53L0X_DeviceParams_t VL53L0X::Get_device_parameters() |
sepp_nepp | 11:c6f95a42d4d7 | 686 | { VL53L0X_DeviceParams_t device_params = {0}; |
sepp_nepp | 11:c6f95a42d4d7 | 687 | int i; |
sepp_nepp | 11:c6f95a42d4d7 | 688 | |
sepp_nepp | 11:c6f95a42d4d7 | 689 | if (ErrState != VL53L0X_OK) {return device_params; } // do nothing while in Error State!!!! |
sepp_nepp | 11:c6f95a42d4d7 | 690 | |
sepp_nepp | 11:c6f95a42d4d7 | 691 | device_params.DeviceMode = CurrParams.DeviceMode; |
sepp_nepp | 11:c6f95a42d4d7 | 692 | device_params.XTalk_Compens_En = 0; |
sepp_nepp | 11:c6f95a42d4d7 | 693 | device_params.Offset_Cal_um = Get_Offset_Cal_um(); |
sepp_nepp | 11:c6f95a42d4d7 | 694 | |
sepp_nepp | 11:c6f95a42d4d7 | 695 | Get_measure_period_ms(&(device_params.Measure_Period_ms)); |
sepp_nepp | 11:c6f95a42d4d7 | 696 | |
sepp_nepp | 11:c6f95a42d4d7 | 697 | if (ErrState == VL53L0X_OK) |
sepp_nepp | 11:c6f95a42d4d7 | 698 | Get_Xtalk_CompRate_MHz(&(device_params.Xtalk_CompRate_MHz)); |
sepp_nepp | 11:c6f95a42d4d7 | 699 | |
sepp_nepp | 11:c6f95a42d4d7 | 700 | if (ErrState == VL53L0X_OK) { |
sepp_nepp | 11:c6f95a42d4d7 | 701 | for (i = 0; i < VL53L0X_CHECKEN_NUMBER_OF_CHECKS; i++) |
sepp_nepp | 11:c6f95a42d4d7 | 702 | {/* get first the values,then the enables. GetLimitCheckValue will |
sepp_nepp | 11:c6f95a42d4d7 | 703 | modify the enable flags */ |
sepp_nepp | 11:c6f95a42d4d7 | 704 | if (ErrState == VL53L0X_OK) |
sepp_nepp | 11:c6f95a42d4d7 | 705 | { device_params.Limit_Chk_Val[i] = Get_limit_chk_val(i); } |
sepp_nepp | 11:c6f95a42d4d7 | 706 | else { break; } |
sepp_nepp | 11:c6f95a42d4d7 | 707 | if (ErrState == VL53L0X_OK) |
sepp_nepp | 11:c6f95a42d4d7 | 708 | { device_params.Limit_Chk_En[i]= Get_limit_chk_en(i);} |
sepp_nepp | 10:cd251e0fc2fd | 709 | else { break; } |
nikapov | 0:a1a69d32f310 | 710 | } |
nikapov | 0:a1a69d32f310 | 711 | } |
nikapov | 0:a1a69d32f310 | 712 | |
sepp_nepp | 11:c6f95a42d4d7 | 713 | if (ErrState == VL53L0X_OK) { |
sepp_nepp | 11:c6f95a42d4d7 | 714 | device_params.Wrap_Around_Chk_En = Get_Wrap_Around_Chk_En();} |
sepp_nepp | 11:c6f95a42d4d7 | 715 | |
sepp_nepp | 11:c6f95a42d4d7 | 716 | /* Need to be done at the end as it uses VCSELPPeriod */ |
sepp_nepp | 11:c6f95a42d4d7 | 717 | if (ErrState == VL53L0X_OK) { |
sepp_nepp | 11:c6f95a42d4d7 | 718 | device_params.Measure_Time_Budget_us = Get_Measure_Time_Budget_us(); } |
sepp_nepp | 11:c6f95a42d4d7 | 719 | |
sepp_nepp | 11:c6f95a42d4d7 | 720 | return device_params; |
nikapov | 0:a1a69d32f310 | 721 | } |
nikapov | 0:a1a69d32f310 | 722 | |
sepp_nepp | 11:c6f95a42d4d7 | 723 | void VL53L0X::Set_limit_chk_val(uint16_t limit_check_id, TFP1616 limit_chk_val) |
sepp_nepp | 11:c6f95a42d4d7 | 724 | { /* first verify that the ID is within bounds .. */ |
sepp_nepp | 11:c6f95a42d4d7 | 725 | if (limit_check_id>=VL53L0X_CHECKEN_NUMBER_OF_CHECKS) |
sepp_nepp | 11:c6f95a42d4d7 | 726 | { ErrState = VL53L0X_ERROR_INVALID_PARAMS; return; } |
sepp_nepp | 11:c6f95a42d4d7 | 727 | |
sepp_nepp | 11:c6f95a42d4d7 | 728 | /* Under all other circumstances store value in local array: */ |
sepp_nepp | 11:c6f95a42d4d7 | 729 | CurrParams.Limit_Chk_Val[limit_check_id] = limit_chk_val; |
sepp_nepp | 11:c6f95a42d4d7 | 730 | |
sepp_nepp | 11:c6f95a42d4d7 | 731 | /* in addition, if enabled, then write the external ones also to the Registers */ |
sepp_nepp | 11:c6f95a42d4d7 | 732 | if (CurrParams.Limit_Chk_En[ limit_check_id ]) |
nikapov | 0:a1a69d32f310 | 733 | switch (limit_check_id) { |
sepp_nepp | 11:c6f95a42d4d7 | 734 | case VL53L0X_CHECKEN_SIG_RATE_FINAL_RANGE: |
sepp_nepp | 11:c6f95a42d4d7 | 735 | Write_Word(REG_FINAL_RANGE_CONFIG_MIN_COUNT_RATE_RTN_LIMIT, |
sepp_nepp | 11:c6f95a42d4d7 | 736 | FP1616_TO_FP97(limit_chk_val)); |
nikapov | 0:a1a69d32f310 | 737 | break; |
sepp_nepp | 11:c6f95a42d4d7 | 738 | case VL53L0X_CHECKEN_SIG_RATE_MSRC: |
sepp_nepp | 11:c6f95a42d4d7 | 739 | case VL53L0X_CHECKEN_SIG_RATE_PRE_RANGE: |
sepp_nepp | 11:c6f95a42d4d7 | 740 | Write_Word(REG_PRE_RANGE_MIN_COUNT_RATE_RTN_LIMIT, |
sepp_nepp | 11:c6f95a42d4d7 | 741 | FP1616_TO_FP97(limit_chk_val)); |
sepp_nepp | 11:c6f95a42d4d7 | 742 | break; |
sepp_nepp | 11:c6f95a42d4d7 | 743 | } // switch |
nikapov | 0:a1a69d32f310 | 744 | } |
nikapov | 0:a1a69d32f310 | 745 | |
sepp_nepp | 11:c6f95a42d4d7 | 746 | |
sepp_nepp | 11:c6f95a42d4d7 | 747 | |
sepp_nepp | 11:c6f95a42d4d7 | 748 | |
sepp_nepp | 11:c6f95a42d4d7 | 749 | void VL53L0X::Get_interrupt_mask_status(uint32_t *p_interrupt_mask_status) |
sepp_nepp | 11:c6f95a42d4d7 | 750 | { uint8_t intStat; |
sepp_nepp | 11:c6f95a42d4d7 | 751 | |
sepp_nepp | 11:c6f95a42d4d7 | 752 | intStat = Read_Byte(REG_RESULT_INTERRUPT_STATUS); |
sepp_nepp | 11:c6f95a42d4d7 | 753 | *p_interrupt_mask_status = intStat & 0x07; |
sepp_nepp | 11:c6f95a42d4d7 | 754 | if (intStat & 0x18) { ErrState = VL53L0X_ERROR_RANGE_ERROR; } |
sepp_nepp | 11:c6f95a42d4d7 | 755 | } |
sepp_nepp | 11:c6f95a42d4d7 | 756 | |
sepp_nepp | 11:c6f95a42d4d7 | 757 | uint8_t VL53L0X::Get_Measurement_Ready() |
sepp_nepp | 11:c6f95a42d4d7 | 758 | { uint8_t sys_range_status_register; |
sepp_nepp | 11:c6f95a42d4d7 | 759 | uint32_t interrupt_mask; |
sepp_nepp | 11:c6f95a42d4d7 | 760 | |
sepp_nepp | 11:c6f95a42d4d7 | 761 | if (DevSpecParams.GpioFunctionality == REG_SYSINT_GPIO_NEW_SAMPLE_READY) |
sepp_nepp | 11:c6f95a42d4d7 | 762 | { Get_interrupt_mask_status(&interrupt_mask); |
sepp_nepp | 11:c6f95a42d4d7 | 763 | if (interrupt_mask == REG_SYSINT_GPIO_NEW_SAMPLE_READY) |
sepp_nepp | 11:c6f95a42d4d7 | 764 | { return 1; } else { return 0; } |
sepp_nepp | 11:c6f95a42d4d7 | 765 | } |
sepp_nepp | 11:c6f95a42d4d7 | 766 | else |
sepp_nepp | 11:c6f95a42d4d7 | 767 | { sys_range_status_register = Read_Byte(REG_RESULT_RANGE_STATUS); |
sepp_nepp | 11:c6f95a42d4d7 | 768 | if ( ( ErrState == VL53L0X_OK ) & (sys_range_status_register & 0x01) ) |
sepp_nepp | 11:c6f95a42d4d7 | 769 | { return 1; } else { return 0; } |
sepp_nepp | 10:cd251e0fc2fd | 770 | } |
nikapov | 0:a1a69d32f310 | 771 | } |
nikapov | 0:a1a69d32f310 | 772 | |
sepp_nepp | 11:c6f95a42d4d7 | 773 | void VL53L0X::Polling_delay() |
nikapov | 0:a1a69d32f310 | 774 | { |
sepp_nepp | 11:c6f95a42d4d7 | 775 | // do nothing VL53L0X_OsDelay(); |
nikapov | 0:a1a69d32f310 | 776 | } |
nikapov | 0:a1a69d32f310 | 777 | |
sepp_nepp | 11:c6f95a42d4d7 | 778 | void VL53L0X::Poll_Measure_Completion() |
sepp_nepp | 11:c6f95a42d4d7 | 779 | { uint8_t new_data_ready; |
sepp_nepp | 11:c6f95a42d4d7 | 780 | uint32_t loop_nb = 0; |
sepp_nepp | 11:c6f95a42d4d7 | 781 | |
sepp_nepp | 11:c6f95a42d4d7 | 782 | if (ErrState != VL53L0X_OK) { return; } // Do nothing if not Cleared error |
sepp_nepp | 11:c6f95a42d4d7 | 783 | |
sepp_nepp | 11:c6f95a42d4d7 | 784 | new_data_ready = Get_Measurement_Ready(); |
sepp_nepp | 11:c6f95a42d4d7 | 785 | |
sepp_nepp | 11:c6f95a42d4d7 | 786 | while ((ErrState==0) && (new_data_ready != 1) ) |
sepp_nepp | 11:c6f95a42d4d7 | 787 | { Polling_delay(); |
sepp_nepp | 11:c6f95a42d4d7 | 788 | new_data_ready = Get_Measurement_Ready(); |
sepp_nepp | 11:c6f95a42d4d7 | 789 | if (loop_nb++ >= VL53L0X_DEFAULT_MAX_LOOP) ErrState=VL53L0X_ERROR_TIME_OUT; |
sepp_nepp | 11:c6f95a42d4d7 | 790 | } // while ; |
nikapov | 0:a1a69d32f310 | 791 | } |
nikapov | 0:a1a69d32f310 | 792 | |
sepp_nepp | 11:c6f95a42d4d7 | 793 | /* Group Device Interrupt Functions */ |
sepp_nepp | 11:c6f95a42d4d7 | 794 | void VL53L0X::Clear_interrupt_mask(uint32_t interrupt_mask) |
sepp_nepp | 11:c6f95a42d4d7 | 795 | { uint8_t loop_count = 0; |
nikapov | 0:a1a69d32f310 | 796 | uint8_t byte; |
nikapov | 0:a1a69d32f310 | 797 | |
sepp_nepp | 11:c6f95a42d4d7 | 798 | if (ErrState != VL53L0X_OK) { return; } // Do nothing if not Cleared error |
sepp_nepp | 11:c6f95a42d4d7 | 799 | |
sepp_nepp | 7:41cbc431e1f4 | 800 | /* clear bit 0 range interrupt,bit 1 error interrupt */ |
nikapov | 0:a1a69d32f310 | 801 | do { |
sepp_nepp | 11:c6f95a42d4d7 | 802 | Write_Byte(REG_SYSINT_CLEAR,0x01); |
sepp_nepp | 11:c6f95a42d4d7 | 803 | Write_Byte(REG_SYSINT_CLEAR,0x00); |
sepp_nepp | 11:c6f95a42d4d7 | 804 | byte = Read_Byte(REG_RESULT_INTERRUPT_STATUS); |
sepp_nepp | 11:c6f95a42d4d7 | 805 | if (loop_count++ > 3) {ErrState =VL53L0X_ERROR_INTERRUPT_NOT_CLEARED;} |
sepp_nepp | 11:c6f95a42d4d7 | 806 | } while (((byte & 0x07) != 0x00) && (ErrState == VL53L0X_OK)); |
sepp_nepp | 11:c6f95a42d4d7 | 807 | |
nikapov | 0:a1a69d32f310 | 808 | } |
nikapov | 0:a1a69d32f310 | 809 | |
sepp_nepp | 11:c6f95a42d4d7 | 810 | void VL53L0X::Perf_single_Ref_calibration(uint8_t vhv_init_byte) |
sepp_nepp | 11:c6f95a42d4d7 | 811 | { if (ErrState != VL53L0X_OK) {return; } // no activity while in Error State!!!! |
sepp_nepp | 11:c6f95a42d4d7 | 812 | Write_Byte(REG_SYSRANGE_START, REG_SYSRANGE_MODE_START_STOP | vhv_init_byte); |
sepp_nepp | 11:c6f95a42d4d7 | 813 | Poll_Measure_Completion(); |
sepp_nepp | 11:c6f95a42d4d7 | 814 | Clear_interrupt_mask(0); |
sepp_nepp | 11:c6f95a42d4d7 | 815 | Write_Byte(REG_SYSRANGE_START,0x00); |
nikapov | 0:a1a69d32f310 | 816 | } |
nikapov | 0:a1a69d32f310 | 817 | |
sepp_nepp | 11:c6f95a42d4d7 | 818 | void VL53L0X::Ref_calibration_io(uint8_t read_not_write, |
sepp_nepp | 7:41cbc431e1f4 | 819 | uint8_t vhv_settings,uint8_t phase_cal, |
sepp_nepp | 7:41cbc431e1f4 | 820 | uint8_t *p_vhv_settings,uint8_t *p_phase_cal, |
sepp_nepp | 7:41cbc431e1f4 | 821 | const uint8_t vhv_enable,const uint8_t phase_enable) |
sepp_nepp | 11:c6f95a42d4d7 | 822 | { uint8_t phase_calint = 0; |
nikapov | 0:a1a69d32f310 | 823 | |
nikapov | 0:a1a69d32f310 | 824 | /* Read VHV from device */ |
sepp_nepp | 11:c6f95a42d4d7 | 825 | Write_Byte(0xFF,0x01); |
sepp_nepp | 11:c6f95a42d4d7 | 826 | Write_Byte(0x00,0x00); |
sepp_nepp | 11:c6f95a42d4d7 | 827 | Write_Byte(0xFF,0x00); |
nikapov | 0:a1a69d32f310 | 828 | |
nikapov | 0:a1a69d32f310 | 829 | if (read_not_write) { |
sepp_nepp | 11:c6f95a42d4d7 | 830 | if (vhv_enable ) { *p_vhv_settings = Read_Byte(0xCB); } |
sepp_nepp | 11:c6f95a42d4d7 | 831 | if (phase_enable) { phase_calint = Read_Byte(0xEE); } |
sepp_nepp | 11:c6f95a42d4d7 | 832 | } |
sepp_nepp | 11:c6f95a42d4d7 | 833 | else { |
sepp_nepp | 11:c6f95a42d4d7 | 834 | if (vhv_enable ) { Write_Byte(0xCB,vhv_settings); } |
sepp_nepp | 11:c6f95a42d4d7 | 835 | if (phase_enable) { Register_BitMask(0xEE,0x80,phase_cal); } |
sepp_nepp | 11:c6f95a42d4d7 | 836 | } |
sepp_nepp | 11:c6f95a42d4d7 | 837 | |
sepp_nepp | 11:c6f95a42d4d7 | 838 | Write_Byte(0xFF,0x01); |
sepp_nepp | 11:c6f95a42d4d7 | 839 | Write_Byte(0x00,0x01); |
sepp_nepp | 11:c6f95a42d4d7 | 840 | Write_Byte(0xFF,0x00); |
nikapov | 0:a1a69d32f310 | 841 | |
nikapov | 0:a1a69d32f310 | 842 | *p_phase_cal = (uint8_t)(phase_calint & 0xEF); |
nikapov | 0:a1a69d32f310 | 843 | } |
nikapov | 0:a1a69d32f310 | 844 | |
sepp_nepp | 11:c6f95a42d4d7 | 845 | void VL53L0X::Perf_vhv_calibration(uint8_t *p_vhv_settings, |
sepp_nepp | 11:c6f95a42d4d7 | 846 | const uint8_t get_data_enable, const uint8_t restore_config) |
sepp_nepp | 11:c6f95a42d4d7 | 847 | { uint8_t orig_sequence_config = 0; |
nikapov | 0:a1a69d32f310 | 848 | uint8_t vhv_settings = 0; |
nikapov | 0:a1a69d32f310 | 849 | uint8_t phase_cal = 0; |
nikapov | 0:a1a69d32f310 | 850 | uint8_t phase_cal_int = 0; |
nikapov | 0:a1a69d32f310 | 851 | |
nikapov | 0:a1a69d32f310 | 852 | /* store the value of the sequence config, |
sepp_nepp | 11:c6f95a42d4d7 | 853 | * this will be reset before the end of the function */ |
sepp_nepp | 11:c6f95a42d4d7 | 854 | orig_sequence_config = SequenceConfig; |
nikapov | 0:a1a69d32f310 | 855 | |
nikapov | 0:a1a69d32f310 | 856 | /* Run VHV */ |
sepp_nepp | 11:c6f95a42d4d7 | 857 | Set_SequenceConfig( 0x01 ); |
sepp_nepp | 11:c6f95a42d4d7 | 858 | Perf_single_Ref_calibration(0x40); |
nikapov | 0:a1a69d32f310 | 859 | |
nikapov | 0:a1a69d32f310 | 860 | /* Read VHV from device */ |
sepp_nepp | 11:c6f95a42d4d7 | 861 | if ((ErrState == VL53L0X_OK) && (get_data_enable == 1)) |
sepp_nepp | 11:c6f95a42d4d7 | 862 | { Ref_calibration_io(1,vhv_settings,phase_cal,/* Not used here */ |
sepp_nepp | 11:c6f95a42d4d7 | 863 | p_vhv_settings,&phase_cal_int, 1,0); } |
sepp_nepp | 11:c6f95a42d4d7 | 864 | else { *p_vhv_settings = 0; } |
sepp_nepp | 11:c6f95a42d4d7 | 865 | |
sepp_nepp | 11:c6f95a42d4d7 | 866 | if (restore_config) { /* restore the previous Sequence Config */ |
sepp_nepp | 11:c6f95a42d4d7 | 867 | Set_SequenceConfig( orig_sequence_config ); } // checks for ErrState |
nikapov | 0:a1a69d32f310 | 868 | } |
nikapov | 0:a1a69d32f310 | 869 | |
sepp_nepp | 11:c6f95a42d4d7 | 870 | void VL53L0X::Perf_phase_calibration(uint8_t *p_phase_cal,const uint8_t get_data_enable, |
nikapov | 0:a1a69d32f310 | 871 | const uint8_t restore_config) |
sepp_nepp | 11:c6f95a42d4d7 | 872 | { uint8_t orig_sequence_config; |
nikapov | 0:a1a69d32f310 | 873 | uint8_t vhv_settings = 0; |
nikapov | 0:a1a69d32f310 | 874 | uint8_t phase_cal = 0; |
nikapov | 0:a1a69d32f310 | 875 | uint8_t vhv_settingsint; |
nikapov | 0:a1a69d32f310 | 876 | |
sepp_nepp | 11:c6f95a42d4d7 | 877 | if (ErrState != VL53L0X_OK) { return; } // Do nothing if not Cleared error |
sepp_nepp | 11:c6f95a42d4d7 | 878 | |
sepp_nepp | 11:c6f95a42d4d7 | 879 | /* store the value of the sequence config, this will be reset before the end of the function */ |
sepp_nepp | 11:c6f95a42d4d7 | 880 | orig_sequence_config = SequenceConfig; |
sepp_nepp | 11:c6f95a42d4d7 | 881 | |
sepp_nepp | 11:c6f95a42d4d7 | 882 | /* Run PhaseCal: */ |
sepp_nepp | 11:c6f95a42d4d7 | 883 | Set_SequenceConfig( 0x02 ); // sets REG_SYSTEM_SEQUENCE_CONFIG |
sepp_nepp | 11:c6f95a42d4d7 | 884 | Perf_single_Ref_calibration(0x0); |
nikapov | 0:a1a69d32f310 | 885 | |
nikapov | 0:a1a69d32f310 | 886 | /* Read PhaseCal from device */ |
sepp_nepp | 11:c6f95a42d4d7 | 887 | if ((ErrState == VL53L0X_OK) && (get_data_enable == 1)) |
sepp_nepp | 11:c6f95a42d4d7 | 888 | { Ref_calibration_io(1,vhv_settings,phase_cal,/* Not used here */ |
sepp_nepp | 11:c6f95a42d4d7 | 889 | &vhv_settingsint,p_phase_cal, 0,1); } |
sepp_nepp | 11:c6f95a42d4d7 | 890 | else { *p_phase_cal = 0; } |
sepp_nepp | 11:c6f95a42d4d7 | 891 | |
sepp_nepp | 11:c6f95a42d4d7 | 892 | if (restore_config) { /* restore the previous Sequence Config */ |
sepp_nepp | 11:c6f95a42d4d7 | 893 | Set_SequenceConfig( orig_sequence_config ); } |
nikapov | 0:a1a69d32f310 | 894 | } |
nikapov | 0:a1a69d32f310 | 895 | |
sepp_nepp | 11:c6f95a42d4d7 | 896 | void VL53L0X::Perf_Ref_calibration(uint8_t *p_vhv_settings, |
sepp_nepp | 10:cd251e0fc2fd | 897 | uint8_t *p_phase_cal, uint8_t get_data_enable) |
sepp_nepp | 11:c6f95a42d4d7 | 898 | { uint8_t orig_sequence_config; |
nikapov | 0:a1a69d32f310 | 899 | |
nikapov | 0:a1a69d32f310 | 900 | /* store the value of the sequence config, |
sepp_nepp | 10:cd251e0fc2fd | 901 | * this will be reset before the end of the function */ |
sepp_nepp | 11:c6f95a42d4d7 | 902 | orig_sequence_config = SequenceConfig; |
nikapov | 0:a1a69d32f310 | 903 | |
nikapov | 0:a1a69d32f310 | 904 | /* In the following function we don't save the config to optimize |
nikapov | 0:a1a69d32f310 | 905 | * writes on device. Config is saved and restored only once. */ |
sepp_nepp | 11:c6f95a42d4d7 | 906 | Perf_vhv_calibration(p_vhv_settings,get_data_enable,0); |
sepp_nepp | 11:c6f95a42d4d7 | 907 | Perf_phase_calibration(p_phase_cal,get_data_enable,0); |
sepp_nepp | 11:c6f95a42d4d7 | 908 | |
sepp_nepp | 11:c6f95a42d4d7 | 909 | /* restore the previous Sequence Config */ |
sepp_nepp | 11:c6f95a42d4d7 | 910 | Set_SequenceConfig( orig_sequence_config ); // sets REG_SYSTEM_SEQUENCE_CONFIG |
nikapov | 0:a1a69d32f310 | 911 | } |
nikapov | 0:a1a69d32f310 | 912 | |
sepp_nepp | 11:c6f95a42d4d7 | 913 | void VL53L0X::Get_Next_Good_SPAD(uint8_t good_SPAD_array[],uint32_t size, |
sepp_nepp | 7:41cbc431e1f4 | 914 | uint32_t curr,int32_t *p_next) |
sepp_nepp | 10:cd251e0fc2fd | 915 | { uint32_t start_index; |
nikapov | 0:a1a69d32f310 | 916 | uint32_t fine_offset; |
sepp_nepp | 11:c6f95a42d4d7 | 917 | uint32_t c_SPADS_per_byte = 8; |
nikapov | 0:a1a69d32f310 | 918 | uint32_t coarse_index; |
nikapov | 0:a1a69d32f310 | 919 | uint32_t fine_index; |
nikapov | 0:a1a69d32f310 | 920 | uint8_t data_byte; |
nikapov | 0:a1a69d32f310 | 921 | uint8_t success = 0; |
nikapov | 0:a1a69d32f310 | 922 | |
sepp_nepp | 11:c6f95a42d4d7 | 923 | /* Starting with the current good SPAD,loop through the array to find |
nikapov | 0:a1a69d32f310 | 924 | * the next. i.e. the next bit set in the sequence. |
nikapov | 0:a1a69d32f310 | 925 | * The coarse index is the byte index of the array and the fine index is |
sepp_nepp | 11:c6f95a42d4d7 | 926 | * the index of the bit within each byte. */ |
nikapov | 0:a1a69d32f310 | 927 | *p_next = -1; |
nikapov | 0:a1a69d32f310 | 928 | |
sepp_nepp | 11:c6f95a42d4d7 | 929 | start_index = curr / c_SPADS_per_byte; |
sepp_nepp | 11:c6f95a42d4d7 | 930 | fine_offset = curr % c_SPADS_per_byte; |
nikapov | 0:a1a69d32f310 | 931 | |
nikapov | 0:a1a69d32f310 | 932 | for (coarse_index = start_index; ((coarse_index < size) && !success); |
nikapov | 0:a1a69d32f310 | 933 | coarse_index++) { |
nikapov | 0:a1a69d32f310 | 934 | fine_index = 0; |
sepp_nepp | 11:c6f95a42d4d7 | 935 | data_byte = good_SPAD_array[coarse_index]; |
nikapov | 0:a1a69d32f310 | 936 | |
nikapov | 0:a1a69d32f310 | 937 | if (coarse_index == start_index) { |
nikapov | 0:a1a69d32f310 | 938 | /* locate the bit position of the provided current |
sepp_nepp | 11:c6f95a42d4d7 | 939 | * SPAD bit before iterating */ |
nikapov | 0:a1a69d32f310 | 940 | data_byte >>= fine_offset; |
nikapov | 0:a1a69d32f310 | 941 | fine_index = fine_offset; |
nikapov | 0:a1a69d32f310 | 942 | } |
nikapov | 0:a1a69d32f310 | 943 | |
sepp_nepp | 11:c6f95a42d4d7 | 944 | while (fine_index < c_SPADS_per_byte) { |
nikapov | 0:a1a69d32f310 | 945 | if ((data_byte & 0x1) == 1) { |
nikapov | 0:a1a69d32f310 | 946 | success = 1; |
sepp_nepp | 11:c6f95a42d4d7 | 947 | *p_next = coarse_index * c_SPADS_per_byte + fine_index; |
nikapov | 0:a1a69d32f310 | 948 | break; |
nikapov | 0:a1a69d32f310 | 949 | } |
nikapov | 0:a1a69d32f310 | 950 | data_byte >>= 1; |
nikapov | 0:a1a69d32f310 | 951 | fine_index++; |
nikapov | 0:a1a69d32f310 | 952 | } |
nikapov | 0:a1a69d32f310 | 953 | } |
nikapov | 0:a1a69d32f310 | 954 | } |
nikapov | 0:a1a69d32f310 | 955 | |
sepp_nepp | 11:c6f95a42d4d7 | 956 | void VL53L0X::Enable_SPAD_bit(uint8_t SPAD_array[],uint32_t size,uint32_t SPAD_index) |
sepp_nepp | 11:c6f95a42d4d7 | 957 | { uint32_t c_SPADS_per_byte = 8; |
nikapov | 0:a1a69d32f310 | 958 | uint32_t coarse_index; |
nikapov | 0:a1a69d32f310 | 959 | uint32_t fine_index; |
nikapov | 0:a1a69d32f310 | 960 | |
sepp_nepp | 11:c6f95a42d4d7 | 961 | coarse_index = SPAD_index / c_SPADS_per_byte; |
sepp_nepp | 11:c6f95a42d4d7 | 962 | fine_index = SPAD_index % c_SPADS_per_byte; |
sepp_nepp | 11:c6f95a42d4d7 | 963 | if (coarse_index >= size) { ErrState = VL53L0X_ERROR_REF_SPAD_INIT; } |
sepp_nepp | 11:c6f95a42d4d7 | 964 | else { SPAD_array[coarse_index] |= (1 << fine_index); } |
nikapov | 0:a1a69d32f310 | 965 | } |
nikapov | 0:a1a69d32f310 | 966 | |
sepp_nepp | 11:c6f95a42d4d7 | 967 | void VL53L0X::Enable_Ref_SPADS( uint8_t aperture_SPADS, uint8_t good_SPAD_array[], |
sepp_nepp | 11:c6f95a42d4d7 | 968 | uint8_t SPAD_array[], uint32_t size, uint32_t start, uint32_t offset, |
sepp_nepp | 11:c6f95a42d4d7 | 969 | uint32_t SPAD_count, uint32_t *p_last_SPAD ) |
sepp_nepp | 11:c6f95a42d4d7 | 970 | { uint32_t index; |
nikapov | 0:a1a69d32f310 | 971 | uint32_t i; |
sepp_nepp | 11:c6f95a42d4d7 | 972 | int32_t next_good_SPAD = offset; |
sepp_nepp | 11:c6f95a42d4d7 | 973 | uint32_t current_SPAD; |
sepp_nepp | 11:c6f95a42d4d7 | 974 | uint8_t check_SPAD_array[6]; |
sepp_nepp | 11:c6f95a42d4d7 | 975 | |
sepp_nepp | 11:c6f95a42d4d7 | 976 | /* This function takes in a SPAD array which may or may not have SPADS |
nikapov | 0:a1a69d32f310 | 977 | * already enabled and appends from a given offset a requested number |
sepp_nepp | 11:c6f95a42d4d7 | 978 | * of new SPAD enables. The 'good SPAD map' is applied to |
sepp_nepp | 11:c6f95a42d4d7 | 979 | * determine the next SPADS to enable. |
nikapov | 0:a1a69d32f310 | 980 | * |
sepp_nepp | 11:c6f95a42d4d7 | 981 | * This function applies to only aperture or only non-aperture SPADS. |
nikapov | 0:a1a69d32f310 | 982 | * Checks are performed to ensure this. |
nikapov | 0:a1a69d32f310 | 983 | */ |
nikapov | 0:a1a69d32f310 | 984 | |
sepp_nepp | 11:c6f95a42d4d7 | 985 | current_SPAD = offset; |
sepp_nepp | 11:c6f95a42d4d7 | 986 | for (index = 0; index < SPAD_count; index++) { |
sepp_nepp | 11:c6f95a42d4d7 | 987 | Get_Next_Good_SPAD(good_SPAD_array,size,current_SPAD, &next_good_SPAD); |
sepp_nepp | 11:c6f95a42d4d7 | 988 | |
sepp_nepp | 11:c6f95a42d4d7 | 989 | if (next_good_SPAD == -1) |
sepp_nepp | 11:c6f95a42d4d7 | 990 | { ErrState = VL53L0X_ERROR_REF_SPAD_INIT; |
sepp_nepp | 11:c6f95a42d4d7 | 991 | break; } |
sepp_nepp | 11:c6f95a42d4d7 | 992 | |
nikapov | 0:a1a69d32f310 | 993 | |
nikapov | 0:a1a69d32f310 | 994 | /* Confirm that the next good SPAD is non-aperture */ |
sepp_nepp | 11:c6f95a42d4d7 | 995 | if (Is_ApertureSPAD(start + next_good_SPAD) != aperture_SPADS) { |
nikapov | 0:a1a69d32f310 | 996 | /* if we can't get the required number of good aperture |
sepp_nepp | 11:c6f95a42d4d7 | 997 | * SPADS from the current quadrant then this is an error */ |
sepp_nepp | 11:c6f95a42d4d7 | 998 | ErrState = VL53L0X_ERROR_REF_SPAD_INIT; |
sepp_nepp | 11:c6f95a42d4d7 | 999 | break;} |
sepp_nepp | 11:c6f95a42d4d7 | 1000 | |
sepp_nepp | 11:c6f95a42d4d7 | 1001 | current_SPAD = (uint32_t)next_good_SPAD; |
sepp_nepp | 11:c6f95a42d4d7 | 1002 | Enable_SPAD_bit(SPAD_array,size,current_SPAD); |
sepp_nepp | 11:c6f95a42d4d7 | 1003 | current_SPAD++; |
nikapov | 0:a1a69d32f310 | 1004 | } |
sepp_nepp | 11:c6f95a42d4d7 | 1005 | *p_last_SPAD = current_SPAD; |
sepp_nepp | 11:c6f95a42d4d7 | 1006 | |
sepp_nepp | 11:c6f95a42d4d7 | 1007 | if (ErrState == VL53L0X_OK) |
sepp_nepp | 11:c6f95a42d4d7 | 1008 | { I2c_Write(REG_GLOBAL_CONFIG_SPAD_ENABLES_REF_0, SPAD_array,6); } // set_Ref_SPAD_map() |
sepp_nepp | 11:c6f95a42d4d7 | 1009 | |
sepp_nepp | 11:c6f95a42d4d7 | 1010 | if (ErrState == VL53L0X_OK) { |
sepp_nepp | 11:c6f95a42d4d7 | 1011 | // Get the ref_SPAD_map from the device |
sepp_nepp | 11:c6f95a42d4d7 | 1012 | I2c_Read(REG_GLOBAL_CONFIG_SPAD_ENABLES_REF_0,check_SPAD_array,6); |
sepp_nepp | 11:c6f95a42d4d7 | 1013 | |
sepp_nepp | 11:c6f95a42d4d7 | 1014 | /* Compare SPAD maps. If not equal report error. */ |
nikapov | 0:a1a69d32f310 | 1015 | i = 0; |
nikapov | 0:a1a69d32f310 | 1016 | while (i < size) { |
sepp_nepp | 11:c6f95a42d4d7 | 1017 | if (SPAD_array[i] != check_SPAD_array[i]) { |
sepp_nepp | 11:c6f95a42d4d7 | 1018 | ErrState = VL53L0X_ERROR_REF_SPAD_INIT; |
nikapov | 0:a1a69d32f310 | 1019 | break; |
nikapov | 0:a1a69d32f310 | 1020 | } |
nikapov | 0:a1a69d32f310 | 1021 | i++; |
nikapov | 0:a1a69d32f310 | 1022 | } |
nikapov | 0:a1a69d32f310 | 1023 | } |
nikapov | 0:a1a69d32f310 | 1024 | } |
nikapov | 0:a1a69d32f310 | 1025 | |
sepp_nepp | 11:c6f95a42d4d7 | 1026 | void VL53L0X::Set_device_mode(VL53L0X_DeviceModes device_mode) |
sepp_nepp | 11:c6f95a42d4d7 | 1027 | { if (ErrState != VL53L0X_OK) {return; } // no reaction while in Error State!!!! |
nikapov | 0:a1a69d32f310 | 1028 | |
nikapov | 0:a1a69d32f310 | 1029 | switch (device_mode) { |
nikapov | 0:a1a69d32f310 | 1030 | case VL53L0X_DEVICEMODE_SINGLE_RANGING: |
nikapov | 0:a1a69d32f310 | 1031 | case VL53L0X_DEVICEMODE_CONTINUOUS_RANGING: |
nikapov | 0:a1a69d32f310 | 1032 | case VL53L0X_DEVICEMODE_CONTINUOUS_TIMED_RANGING: |
nikapov | 0:a1a69d32f310 | 1033 | case VL53L0X_DEVICEMODE_GPIO_DRIVE: |
sepp_nepp | 11:c6f95a42d4d7 | 1034 | case VL53L0X_DEVICEMODE_GPIO_OSC: /* Supported modes */ |
sepp_nepp | 11:c6f95a42d4d7 | 1035 | CurrParams.DeviceMode = device_mode; |
nikapov | 0:a1a69d32f310 | 1036 | break; |
sepp_nepp | 11:c6f95a42d4d7 | 1037 | default: /* Unsupported mode */ |
sepp_nepp | 11:c6f95a42d4d7 | 1038 | ErrState = VL53L0X_ERROR_MODE_NOT_SUPPORTED; |
nikapov | 0:a1a69d32f310 | 1039 | } |
nikapov | 0:a1a69d32f310 | 1040 | } |
nikapov | 0:a1a69d32f310 | 1041 | |
sepp_nepp | 11:c6f95a42d4d7 | 1042 | void VL53L0X::Set_interrupt_thresholds(VL53L0X_DeviceModes device_mode,TFP1616 threshold_low, |
sepp_nepp | 11:c6f95a42d4d7 | 1043 | TFP1616 threshold_high) |
sepp_nepp | 11:c6f95a42d4d7 | 1044 | { uint16_t threshold16; |
sepp_nepp | 5:b95f6951f7d5 | 1045 | |
sepp_nepp | 5:b95f6951f7d5 | 1046 | /* no dependency on DeviceMode for FlightSense */ |
nikapov | 0:a1a69d32f310 | 1047 | /* Need to divide by 2 because the FW will apply a x2 */ |
nikapov | 0:a1a69d32f310 | 1048 | threshold16 = (uint16_t)((threshold_low >> 17) & 0x00fff); |
sepp_nepp | 11:c6f95a42d4d7 | 1049 | Write_Word(REG_SYSTEM_THRESH_LOW,threshold16); |
sepp_nepp | 11:c6f95a42d4d7 | 1050 | |
sepp_nepp | 11:c6f95a42d4d7 | 1051 | /* Need to divide by 2 because the FW will apply a x2 */ |
sepp_nepp | 11:c6f95a42d4d7 | 1052 | threshold16 = (uint16_t)((threshold_high >> 17) & 0x00fff); |
sepp_nepp | 11:c6f95a42d4d7 | 1053 | Write_Word(REG_SYSTEM_THRESH_HIGH,threshold16); |
nikapov | 0:a1a69d32f310 | 1054 | } |
nikapov | 0:a1a69d32f310 | 1055 | |
sepp_nepp | 11:c6f95a42d4d7 | 1056 | void VL53L0X::Get_interrupt_thresholds(VL53L0X_DeviceModes device_mode,TFP1616 *p_threshold_low, |
sepp_nepp | 11:c6f95a42d4d7 | 1057 | TFP1616 *p_threshold_high) |
sepp_nepp | 11:c6f95a42d4d7 | 1058 | { uint16_t threshold16; |
sepp_nepp | 5:b95f6951f7d5 | 1059 | |
sepp_nepp | 5:b95f6951f7d5 | 1060 | /* no dependency on DeviceMode for FlightSense */ |
sepp_nepp | 11:c6f95a42d4d7 | 1061 | threshold16 = Read_Word(REG_SYSTEM_THRESH_LOW); |
nikapov | 0:a1a69d32f310 | 1062 | /* Need to multiply by 2 because the FW will apply a x2 */ |
sepp_nepp | 11:c6f95a42d4d7 | 1063 | *p_threshold_low = (TFP1616)((0x00fff & threshold16) << 17); |
sepp_nepp | 11:c6f95a42d4d7 | 1064 | |
sepp_nepp | 11:c6f95a42d4d7 | 1065 | if (ErrState == VL53L0X_OK) { |
sepp_nepp | 11:c6f95a42d4d7 | 1066 | threshold16 = Read_Word(REG_SYSTEM_THRESH_HIGH); |
nikapov | 0:a1a69d32f310 | 1067 | /* Need to multiply by 2 because the FW will apply a x2 */ |
sepp_nepp | 11:c6f95a42d4d7 | 1068 | *p_threshold_high = (TFP1616)((0x00fff & threshold16) << 17); |
nikapov | 0:a1a69d32f310 | 1069 | } |
nikapov | 0:a1a69d32f310 | 1070 | } |
nikapov | 0:a1a69d32f310 | 1071 | |
sepp_nepp | 11:c6f95a42d4d7 | 1072 | void VL53L0X::Load_tuning_settings(uint8_t *p_tuning_setting_buffer) |
sepp_nepp | 11:c6f95a42d4d7 | 1073 | { int i; |
nikapov | 0:a1a69d32f310 | 1074 | int index; |
nikapov | 0:a1a69d32f310 | 1075 | uint8_t msb; |
nikapov | 0:a1a69d32f310 | 1076 | uint8_t lsb; |
nikapov | 0:a1a69d32f310 | 1077 | uint8_t select_param; |
nikapov | 0:a1a69d32f310 | 1078 | uint8_t number_of_writes; |
nikapov | 0:a1a69d32f310 | 1079 | uint8_t address; |
nikapov | 0:a1a69d32f310 | 1080 | uint8_t local_buffer[4]; /* max */ |
nikapov | 0:a1a69d32f310 | 1081 | uint16_t temp16; |
nikapov | 0:a1a69d32f310 | 1082 | |
nikapov | 0:a1a69d32f310 | 1083 | index = 0; |
nikapov | 0:a1a69d32f310 | 1084 | |
nikapov | 0:a1a69d32f310 | 1085 | while ((*(p_tuning_setting_buffer + index) != 0) && |
sepp_nepp | 11:c6f95a42d4d7 | 1086 | (ErrState == VL53L0X_OK)) { |
nikapov | 0:a1a69d32f310 | 1087 | number_of_writes = *(p_tuning_setting_buffer + index); |
nikapov | 0:a1a69d32f310 | 1088 | index++; |
nikapov | 0:a1a69d32f310 | 1089 | if (number_of_writes == 0xFF) { |
nikapov | 0:a1a69d32f310 | 1090 | /* internal parameters */ |
nikapov | 0:a1a69d32f310 | 1091 | select_param = *(p_tuning_setting_buffer + index); |
nikapov | 0:a1a69d32f310 | 1092 | index++; |
nikapov | 0:a1a69d32f310 | 1093 | switch (select_param) { |
nikapov | 0:a1a69d32f310 | 1094 | case 0: /* uint16_t SigmaEstRefArray -> 2 bytes */ |
nikapov | 0:a1a69d32f310 | 1095 | msb = *(p_tuning_setting_buffer + index); |
nikapov | 0:a1a69d32f310 | 1096 | index++; |
nikapov | 0:a1a69d32f310 | 1097 | lsb = *(p_tuning_setting_buffer + index); |
nikapov | 0:a1a69d32f310 | 1098 | index++; |
sepp_nepp | 7:41cbc431e1f4 | 1099 | temp16 = VL53L0X_MAKEUINT16(lsb,msb); |
sepp_nepp | 10:cd251e0fc2fd | 1100 | SigmaEstRefArray = temp16; |
nikapov | 0:a1a69d32f310 | 1101 | break; |
nikapov | 0:a1a69d32f310 | 1102 | case 1: /* uint16_t SigmaEstEffPulseWidth -> 2 bytes */ |
nikapov | 0:a1a69d32f310 | 1103 | msb = *(p_tuning_setting_buffer + index); |
nikapov | 0:a1a69d32f310 | 1104 | index++; |
nikapov | 0:a1a69d32f310 | 1105 | lsb = *(p_tuning_setting_buffer + index); |
nikapov | 0:a1a69d32f310 | 1106 | index++; |
sepp_nepp | 7:41cbc431e1f4 | 1107 | temp16 = VL53L0X_MAKEUINT16(lsb,msb); |
sepp_nepp | 10:cd251e0fc2fd | 1108 | SigmaEstEffPulseWidth = temp16; |
nikapov | 0:a1a69d32f310 | 1109 | break; |
nikapov | 0:a1a69d32f310 | 1110 | case 2: /* uint16_t SigmaEstEffAmbWidth -> 2 bytes */ |
nikapov | 0:a1a69d32f310 | 1111 | msb = *(p_tuning_setting_buffer + index); |
nikapov | 0:a1a69d32f310 | 1112 | index++; |
nikapov | 0:a1a69d32f310 | 1113 | lsb = *(p_tuning_setting_buffer + index); |
nikapov | 0:a1a69d32f310 | 1114 | index++; |
sepp_nepp | 7:41cbc431e1f4 | 1115 | temp16 = VL53L0X_MAKEUINT16(lsb,msb); |
sepp_nepp | 10:cd251e0fc2fd | 1116 | SigmaEstEffAmbWidth = temp16; |
nikapov | 0:a1a69d32f310 | 1117 | break; |
nikapov | 0:a1a69d32f310 | 1118 | case 3: /* uint16_t targetRefRate -> 2 bytes */ |
nikapov | 0:a1a69d32f310 | 1119 | msb = *(p_tuning_setting_buffer + index); |
nikapov | 0:a1a69d32f310 | 1120 | index++; |
nikapov | 0:a1a69d32f310 | 1121 | lsb = *(p_tuning_setting_buffer + index); |
nikapov | 0:a1a69d32f310 | 1122 | index++; |
sepp_nepp | 7:41cbc431e1f4 | 1123 | temp16 = VL53L0X_MAKEUINT16(lsb,msb); |
sepp_nepp | 10:cd251e0fc2fd | 1124 | targetRefRate = temp16; |
nikapov | 0:a1a69d32f310 | 1125 | break; |
nikapov | 0:a1a69d32f310 | 1126 | default: /* invalid parameter */ |
sepp_nepp | 11:c6f95a42d4d7 | 1127 | ErrState = VL53L0X_ERROR_INVALID_PARAMS; |
nikapov | 0:a1a69d32f310 | 1128 | } |
nikapov | 0:a1a69d32f310 | 1129 | } else if (number_of_writes <= 4) { |
nikapov | 0:a1a69d32f310 | 1130 | address = *(p_tuning_setting_buffer + index); |
nikapov | 0:a1a69d32f310 | 1131 | index++; |
nikapov | 0:a1a69d32f310 | 1132 | for (i = 0; i < number_of_writes; i++) { |
sepp_nepp | 11:c6f95a42d4d7 | 1133 | local_buffer[i] = *(p_tuning_setting_buffer + index); |
nikapov | 0:a1a69d32f310 | 1134 | index++; |
nikapov | 0:a1a69d32f310 | 1135 | } |
sepp_nepp | 11:c6f95a42d4d7 | 1136 | I2c_Write(address,local_buffer,number_of_writes); |
nikapov | 0:a1a69d32f310 | 1137 | } else { |
sepp_nepp | 11:c6f95a42d4d7 | 1138 | ErrState = VL53L0X_ERROR_INVALID_PARAMS; |
nikapov | 0:a1a69d32f310 | 1139 | } |
nikapov | 0:a1a69d32f310 | 1140 | } |
sepp_nepp | 11:c6f95a42d4d7 | 1141 | } |
sepp_nepp | 11:c6f95a42d4d7 | 1142 | |
sepp_nepp | 11:c6f95a42d4d7 | 1143 | void VL53L0X::Check_and_load_interrupt_settings(uint8_t start_not_stopflag) |
sepp_nepp | 11:c6f95a42d4d7 | 1144 | { uint8_t interrupt_config; |
sepp_nepp | 11:c6f95a42d4d7 | 1145 | TFP1616 threshold_low; |
sepp_nepp | 11:c6f95a42d4d7 | 1146 | TFP1616 threshold_high; |
sepp_nepp | 5:b95f6951f7d5 | 1147 | |
sepp_nepp | 11:c6f95a42d4d7 | 1148 | if (ErrState != VL53L0X_OK) { return; } // Do nothing if not Cleared error |
sepp_nepp | 11:c6f95a42d4d7 | 1149 | |
sepp_nepp | 11:c6f95a42d4d7 | 1150 | interrupt_config = DevSpecParams.GpioFunctionality; |
sepp_nepp | 11:c6f95a42d4d7 | 1151 | |
sepp_nepp | 11:c6f95a42d4d7 | 1152 | if ((interrupt_config == GPIO_FUNC_THRESHOLD_CROSSED_LOW ) || |
sepp_nepp | 11:c6f95a42d4d7 | 1153 | (interrupt_config == GPIO_FUNC_THRESHOLD_CROSSED_HIGH) || |
sepp_nepp | 11:c6f95a42d4d7 | 1154 | (interrupt_config == GPIO_FUNC_THRESHOLD_CROSSED_OUT )) { |
sepp_nepp | 11:c6f95a42d4d7 | 1155 | Get_interrupt_thresholds(VL53L0X_DEVICEMODE_CONTINUOUS_RANGING, |
sepp_nepp | 7:41cbc431e1f4 | 1156 | &threshold_low,&threshold_high); |
nikapov | 0:a1a69d32f310 | 1157 | |
sepp_nepp | 11:c6f95a42d4d7 | 1158 | if (((threshold_low > 255 * 65536) || (threshold_high > 255 * 65536)) && |
sepp_nepp | 11:c6f95a42d4d7 | 1159 | (ErrState == VL53L0X_OK)) |
sepp_nepp | 11:c6f95a42d4d7 | 1160 | { if (start_not_stopflag != 0) |
sepp_nepp | 11:c6f95a42d4d7 | 1161 | {Load_tuning_settings(InterruptThresholdSettings); } |
sepp_nepp | 11:c6f95a42d4d7 | 1162 | else |
sepp_nepp | 11:c6f95a42d4d7 | 1163 | {Write_Byte(0xFF,0x04); |
sepp_nepp | 11:c6f95a42d4d7 | 1164 | Write_Byte(0x70,0x00); |
sepp_nepp | 11:c6f95a42d4d7 | 1165 | Write_Byte(0xFF,0x00); |
sepp_nepp | 11:c6f95a42d4d7 | 1166 | Write_Byte(0x80,0x00); |
sepp_nepp | 11:c6f95a42d4d7 | 1167 | } |
nikapov | 0:a1a69d32f310 | 1168 | } |
nikapov | 0:a1a69d32f310 | 1169 | } |
nikapov | 0:a1a69d32f310 | 1170 | } |
nikapov | 0:a1a69d32f310 | 1171 | |
sepp_nepp | 11:c6f95a42d4d7 | 1172 | void VL53L0X::Start_Measurement() |
sepp_nepp | 11:c6f95a42d4d7 | 1173 | { VL53L0X_DeviceModes device_mode; |
nikapov | 0:a1a69d32f310 | 1174 | uint8_t byte; |
sepp_nepp | 11:c6f95a42d4d7 | 1175 | uint8_t start_stop_byte = REG_SYSRANGE_MODE_START_STOP; |
nikapov | 0:a1a69d32f310 | 1176 | uint32_t loop_nb; |
nikapov | 0:a1a69d32f310 | 1177 | |
sepp_nepp | 11:c6f95a42d4d7 | 1178 | if (ErrState != VL53L0X_OK) {return; } // no activity while in Error State!!!! |
sepp_nepp | 11:c6f95a42d4d7 | 1179 | |
nikapov | 0:a1a69d32f310 | 1180 | /* Get Current DeviceMode */ |
sepp_nepp | 11:c6f95a42d4d7 | 1181 | device_mode = CurrParams.DeviceMode; |
sepp_nepp | 11:c6f95a42d4d7 | 1182 | |
sepp_nepp | 11:c6f95a42d4d7 | 1183 | Write_Byte(0x80,0x01); |
sepp_nepp | 11:c6f95a42d4d7 | 1184 | Write_Byte(0xFF,0x01); |
sepp_nepp | 11:c6f95a42d4d7 | 1185 | Write_Byte(0x00,0x00); |
sepp_nepp | 11:c6f95a42d4d7 | 1186 | Write_Byte(0x91,StopVariable); |
sepp_nepp | 11:c6f95a42d4d7 | 1187 | Write_Byte(0x00,0x01); |
sepp_nepp | 11:c6f95a42d4d7 | 1188 | Write_Byte(0xFF,0x00); |
sepp_nepp | 11:c6f95a42d4d7 | 1189 | Write_Byte(0x80,0x00); |
nikapov | 0:a1a69d32f310 | 1190 | |
nikapov | 0:a1a69d32f310 | 1191 | switch (device_mode) { |
nikapov | 0:a1a69d32f310 | 1192 | case VL53L0X_DEVICEMODE_SINGLE_RANGING: |
sepp_nepp | 11:c6f95a42d4d7 | 1193 | Write_Byte(REG_SYSRANGE_START,0x01); |
nikapov | 0:a1a69d32f310 | 1194 | |
nikapov | 0:a1a69d32f310 | 1195 | byte = start_stop_byte; |
sepp_nepp | 11:c6f95a42d4d7 | 1196 | if (ErrState == VL53L0X_OK) { |
nikapov | 0:a1a69d32f310 | 1197 | /* Wait until start bit has been cleared */ |
nikapov | 0:a1a69d32f310 | 1198 | loop_nb = 0; |
nikapov | 0:a1a69d32f310 | 1199 | do { |
nikapov | 0:a1a69d32f310 | 1200 | if (loop_nb > 0) |
sepp_nepp | 11:c6f95a42d4d7 | 1201 | byte = Read_Byte(REG_SYSRANGE_START); |
nikapov | 0:a1a69d32f310 | 1202 | loop_nb = loop_nb + 1; |
nikapov | 0:a1a69d32f310 | 1203 | } while (((byte & start_stop_byte) == start_stop_byte) |
sepp_nepp | 11:c6f95a42d4d7 | 1204 | && (ErrState == VL53L0X_OK) |
nikapov | 0:a1a69d32f310 | 1205 | && (loop_nb < VL53L0X_DEFAULT_MAX_LOOP)); |
nikapov | 0:a1a69d32f310 | 1206 | |
Davidroid | 3:e9269ff624ed | 1207 | if (loop_nb >= VL53L0X_DEFAULT_MAX_LOOP) { |
sepp_nepp | 11:c6f95a42d4d7 | 1208 | ErrState = VL53L0X_ERROR_TIME_OUT; |
Davidroid | 3:e9269ff624ed | 1209 | } |
nikapov | 0:a1a69d32f310 | 1210 | } |
nikapov | 0:a1a69d32f310 | 1211 | break; |
sepp_nepp | 11:c6f95a42d4d7 | 1212 | |
sepp_nepp | 11:c6f95a42d4d7 | 1213 | case VL53L0X_DEVICEMODE_CONTINUOUS_RANGING: |
sepp_nepp | 11:c6f95a42d4d7 | 1214 | /* Back-to-back mode, Check if need to apply interrupt settings */ |
sepp_nepp | 11:c6f95a42d4d7 | 1215 | Check_and_load_interrupt_settings(1); |
sepp_nepp | 11:c6f95a42d4d7 | 1216 | Write_Byte(REG_SYSRANGE_START,REG_SYSRANGE_MODE_BACKTOBACK); |
sepp_nepp | 11:c6f95a42d4d7 | 1217 | Set_Current_State( VL53L0X_STATE_RUNNING ); |
sepp_nepp | 11:c6f95a42d4d7 | 1218 | break; |
nikapov | 0:a1a69d32f310 | 1219 | case VL53L0X_DEVICEMODE_CONTINUOUS_TIMED_RANGING: |
sepp_nepp | 11:c6f95a42d4d7 | 1220 | /* Continuous mode; Check if need to apply interrupt settings */ |
sepp_nepp | 11:c6f95a42d4d7 | 1221 | Check_and_load_interrupt_settings(1); |
sepp_nepp | 11:c6f95a42d4d7 | 1222 | Write_Byte(REG_SYSRANGE_START, REG_SYSRANGE_MODE_TIMED); |
sepp_nepp | 11:c6f95a42d4d7 | 1223 | Set_Current_State( VL53L0X_STATE_RUNNING ); |
nikapov | 0:a1a69d32f310 | 1224 | break; |
nikapov | 0:a1a69d32f310 | 1225 | default: |
nikapov | 0:a1a69d32f310 | 1226 | /* Selected mode not supported */ |
sepp_nepp | 11:c6f95a42d4d7 | 1227 | ErrState = VL53L0X_ERROR_MODE_NOT_SUPPORTED; |
nikapov | 0:a1a69d32f310 | 1228 | } |
nikapov | 0:a1a69d32f310 | 1229 | } |
nikapov | 0:a1a69d32f310 | 1230 | |
sepp_nepp | 11:c6f95a42d4d7 | 1231 | /* Group Device Measurement Functions */ |
sepp_nepp | 11:c6f95a42d4d7 | 1232 | void VL53L0X::Perf_single_measurement() |
sepp_nepp | 11:c6f95a42d4d7 | 1233 | { VL53L0X_DeviceModes device_mode; |
sepp_nepp | 11:c6f95a42d4d7 | 1234 | |
sepp_nepp | 11:c6f95a42d4d7 | 1235 | if (ErrState != VL53L0X_OK) {return; } // no activity while in Error State!!!! |
nikapov | 0:a1a69d32f310 | 1236 | |
nikapov | 0:a1a69d32f310 | 1237 | /* Get Current DeviceMode */ |
sepp_nepp | 11:c6f95a42d4d7 | 1238 | device_mode = CurrParams.DeviceMode; |
nikapov | 0:a1a69d32f310 | 1239 | |
nikapov | 0:a1a69d32f310 | 1240 | /* Start immediately to run a single ranging measurement in case of |
nikapov | 0:a1a69d32f310 | 1241 | * single ranging or single histogram */ |
sepp_nepp | 11:c6f95a42d4d7 | 1242 | if (device_mode == VL53L0X_DEVICEMODE_SINGLE_RANGING) {Start_Measurement();} |
sepp_nepp | 11:c6f95a42d4d7 | 1243 | |
sepp_nepp | 11:c6f95a42d4d7 | 1244 | Poll_Measure_Completion(); |
sepp_nepp | 11:c6f95a42d4d7 | 1245 | |
sepp_nepp | 11:c6f95a42d4d7 | 1246 | /* Change Device State in case of single ranging or single histogram */ |
sepp_nepp | 11:c6f95a42d4d7 | 1247 | if (device_mode == VL53L0X_DEVICEMODE_SINGLE_RANGING) |
sepp_nepp | 11:c6f95a42d4d7 | 1248 | { Set_Current_State( VL53L0X_STATE_IDLE ); } |
nikapov | 0:a1a69d32f310 | 1249 | } |
nikapov | 0:a1a69d32f310 | 1250 | |
sepp_nepp | 11:c6f95a42d4d7 | 1251 | TFP1616 VL53L0X::Get_total_xtalk_rate(TRangeResults *p_ranging_results) |
sepp_nepp | 11:c6f95a42d4d7 | 1252 | { TFP1616 total_xtalk_MHz; |
sepp_nepp | 11:c6f95a42d4d7 | 1253 | |
sepp_nepp | 11:c6f95a42d4d7 | 1254 | // CurrParams.XTalk_Compens_En was Get_xtalk_compensation_enable |
sepp_nepp | 11:c6f95a42d4d7 | 1255 | if ( (ErrState == VL53L0X_OK) & (CurrParams.XTalk_Compens_En ) ) |
sepp_nepp | 11:c6f95a42d4d7 | 1256 | { /* FixPoint1616 * FixPoint 8:8 = FixPoint0824 */ |
sepp_nepp | 11:c6f95a42d4d7 | 1257 | total_xtalk_MHz = p_ranging_results->EffectiveSPADRtnCount * |
sepp_nepp | 11:c6f95a42d4d7 | 1258 | CurrParams.Xtalk_CompRate_MHz; |
sepp_nepp | 11:c6f95a42d4d7 | 1259 | |
sepp_nepp | 11:c6f95a42d4d7 | 1260 | /* FixPoint0824 >> 8 = FixPoint1616 */ |
sepp_nepp | 11:c6f95a42d4d7 | 1261 | return (total_xtalk_MHz + 0x80) >> 8; |
sepp_nepp | 11:c6f95a42d4d7 | 1262 | } |
sepp_nepp | 11:c6f95a42d4d7 | 1263 | else { return 0; } |
nikapov | 0:a1a69d32f310 | 1264 | } |
nikapov | 0:a1a69d32f310 | 1265 | |
sepp_nepp | 11:c6f95a42d4d7 | 1266 | void VL53L0X::Get_total_SIG_rate(TRangeResults *p_ranging_results, |
sepp_nepp | 11:c6f95a42d4d7 | 1267 | TFP1616 *p_total_SIG_rate_mcps) |
sepp_nepp | 11:c6f95a42d4d7 | 1268 | { TFP1616 total_xtalk_MHz; |
sepp_nepp | 11:c6f95a42d4d7 | 1269 | |
sepp_nepp | 11:c6f95a42d4d7 | 1270 | *p_total_SIG_rate_mcps = p_ranging_results->SignalRateRtnMHz; |
sepp_nepp | 11:c6f95a42d4d7 | 1271 | total_xtalk_MHz = Get_total_xtalk_rate(p_ranging_results); |
sepp_nepp | 5:b95f6951f7d5 | 1272 | |
sepp_nepp | 11:c6f95a42d4d7 | 1273 | if (ErrState == VL53L0X_OK) { *p_total_SIG_rate_mcps += total_xtalk_MHz;} |
nikapov | 0:a1a69d32f310 | 1274 | } |
nikapov | 0:a1a69d32f310 | 1275 | |
nikapov | 0:a1a69d32f310 | 1276 | /* To convert ms into register value */ |
sepp_nepp | 11:c6f95a42d4d7 | 1277 | uint32_t VL53L0X::Calc_timeout_mclks(uint32_t timeout_period_us, |
nikapov | 0:a1a69d32f310 | 1278 | uint8_t vcsel_period_pclks) |
sepp_nepp | 11:c6f95a42d4d7 | 1279 | { uint32_t macro_period_ns; |
sepp_nepp | 11:c6f95a42d4d7 | 1280 | |
sepp_nepp | 11:c6f95a42d4d7 | 1281 | macro_period_ns = (uint32_t)(vcsel_period_pclks) * VL53L0X_MACRO_PERIOD_NS; |
sepp_nepp | 11:c6f95a42d4d7 | 1282 | |
sepp_nepp | 11:c6f95a42d4d7 | 1283 | return (uint32_t)(((timeout_period_us * 1000) |
sepp_nepp | 11:c6f95a42d4d7 | 1284 | + (macro_period_ns / 2)) / macro_period_ns); |
nikapov | 0:a1a69d32f310 | 1285 | } |
nikapov | 0:a1a69d32f310 | 1286 | |
sepp_nepp | 11:c6f95a42d4d7 | 1287 | uint32_t VL53L0X::ISQRT(uint32_t num) |
sepp_nepp | 11:c6f95a42d4d7 | 1288 | { /* Implements an integer square root |
sepp_nepp | 11:c6f95a42d4d7 | 1289 | * From: http://en.wikipedia.org/wiki/Methods_of_computing_square_roots */ |
nikapov | 0:a1a69d32f310 | 1290 | uint32_t res = 0; |
nikapov | 0:a1a69d32f310 | 1291 | uint32_t bit = 1 << 30; |
sepp_nepp | 11:c6f95a42d4d7 | 1292 | /* The second-to-top bit is set: 1 << 14 for 16-bits,1 << 30 for 32 bits */ |
nikapov | 0:a1a69d32f310 | 1293 | |
nikapov | 0:a1a69d32f310 | 1294 | /* "bit" starts at the highest power of four <= the argument. */ |
sepp_nepp | 10:cd251e0fc2fd | 1295 | while (bit > num) { bit >>= 2; } |
nikapov | 0:a1a69d32f310 | 1296 | |
nikapov | 0:a1a69d32f310 | 1297 | while (bit != 0) { |
nikapov | 0:a1a69d32f310 | 1298 | if (num >= res + bit) { |
nikapov | 0:a1a69d32f310 | 1299 | num -= res + bit; |
nikapov | 0:a1a69d32f310 | 1300 | res = (res >> 1) + bit; |
sepp_nepp | 11:c6f95a42d4d7 | 1301 | } else { res >>= 1; } |
nikapov | 0:a1a69d32f310 | 1302 | bit >>= 2; |
nikapov | 0:a1a69d32f310 | 1303 | } |
nikapov | 0:a1a69d32f310 | 1304 | return res; |
nikapov | 0:a1a69d32f310 | 1305 | } |
nikapov | 0:a1a69d32f310 | 1306 | |
sepp_nepp | 11:c6f95a42d4d7 | 1307 | void VL53L0X::Calc_dmax(TFP1616 total_SIG_rate_mcps, |
sepp_nepp | 11:c6f95a42d4d7 | 1308 | TFP1616 total_corr_SIG_rate_mcps, |
sepp_nepp | 11:c6f95a42d4d7 | 1309 | TFP1616 pw_mult, |
nikapov | 0:a1a69d32f310 | 1310 | uint32_t sigma_estimate_p1, |
sepp_nepp | 11:c6f95a42d4d7 | 1311 | TFP1616 sigma_estimate_p2, |
nikapov | 0:a1a69d32f310 | 1312 | uint32_t peak_vcsel_duration_us, |
nikapov | 0:a1a69d32f310 | 1313 | uint32_t *pd_max_mm) |
sepp_nepp | 11:c6f95a42d4d7 | 1314 | { const uint32_t c_sigma_limit = 18; |
sepp_nepp | 11:c6f95a42d4d7 | 1315 | const TFP1616 c_SIG_limit = 0x4000; /* 0.25 */ |
sepp_nepp | 11:c6f95a42d4d7 | 1316 | const TFP1616 c_sigma_est_Ref = 0x00000042; /* 0.001 */ |
nikapov | 0:a1a69d32f310 | 1317 | const uint32_t c_amb_eff_width_sigma_est_ns = 6; |
nikapov | 0:a1a69d32f310 | 1318 | const uint32_t c_amb_eff_width_d_max_ns = 7; |
nikapov | 0:a1a69d32f310 | 1319 | uint32_t dmax_cal_range_mm; |
sepp_nepp | 11:c6f95a42d4d7 | 1320 | TFP1616 dmax_cal_SIG_rate_rtn_mcps; |
sepp_nepp | 11:c6f95a42d4d7 | 1321 | TFP1616 min_SIG_needed; |
sepp_nepp | 11:c6f95a42d4d7 | 1322 | TFP1616 min_SIG_needed_p1; |
sepp_nepp | 11:c6f95a42d4d7 | 1323 | TFP1616 min_SIG_needed_p2; |
sepp_nepp | 11:c6f95a42d4d7 | 1324 | TFP1616 min_SIG_needed_p3; |
sepp_nepp | 11:c6f95a42d4d7 | 1325 | TFP1616 min_SIG_needed_p4; |
sepp_nepp | 11:c6f95a42d4d7 | 1326 | TFP1616 sigma_limit_tmp; |
sepp_nepp | 11:c6f95a42d4d7 | 1327 | TFP1616 sigma_est_sq_tmp; |
sepp_nepp | 11:c6f95a42d4d7 | 1328 | TFP1616 signal_limit_tmp; |
sepp_nepp | 11:c6f95a42d4d7 | 1329 | TFP1616 signal_at0_mm; |
sepp_nepp | 11:c6f95a42d4d7 | 1330 | TFP1616 dmax_dark; |
sepp_nepp | 11:c6f95a42d4d7 | 1331 | TFP1616 dmax_ambient; |
sepp_nepp | 11:c6f95a42d4d7 | 1332 | TFP1616 dmax_dark_tmp; |
sepp_nepp | 11:c6f95a42d4d7 | 1333 | TFP1616 sigma_est_p2_tmp; |
nikapov | 0:a1a69d32f310 | 1334 | uint32_t signal_rate_temp_mcps; |
nikapov | 0:a1a69d32f310 | 1335 | |
sepp_nepp | 10:cd251e0fc2fd | 1336 | dmax_cal_range_mm = DmaxCalRangeMilliMeter; |
sepp_nepp | 10:cd251e0fc2fd | 1337 | |
sepp_nepp | 11:c6f95a42d4d7 | 1338 | dmax_cal_SIG_rate_rtn_mcps = DmaxCalSignalRateRtnMHz; |
nikapov | 0:a1a69d32f310 | 1339 | |
nikapov | 0:a1a69d32f310 | 1340 | /* uint32 * FixPoint1616 = FixPoint1616 */ |
sepp_nepp | 11:c6f95a42d4d7 | 1341 | signal_at0_mm = dmax_cal_range_mm * dmax_cal_SIG_rate_rtn_mcps; |
nikapov | 0:a1a69d32f310 | 1342 | |
nikapov | 0:a1a69d32f310 | 1343 | /* FixPoint1616 >> 8 = FixPoint2408 */ |
nikapov | 0:a1a69d32f310 | 1344 | signal_at0_mm = (signal_at0_mm + 0x80) >> 8; |
nikapov | 0:a1a69d32f310 | 1345 | signal_at0_mm *= dmax_cal_range_mm; |
nikapov | 0:a1a69d32f310 | 1346 | |
sepp_nepp | 11:c6f95a42d4d7 | 1347 | min_SIG_needed_p1 = 0; |
sepp_nepp | 11:c6f95a42d4d7 | 1348 | if (total_corr_SIG_rate_mcps > 0) { |
sepp_nepp | 11:c6f95a42d4d7 | 1349 | /* Shift by 10 bits to increase resolution prior to the division */ |
sepp_nepp | 11:c6f95a42d4d7 | 1350 | signal_rate_temp_mcps = total_SIG_rate_mcps << 10; |
nikapov | 0:a1a69d32f310 | 1351 | |
nikapov | 0:a1a69d32f310 | 1352 | /* Add rounding value prior to division */ |
sepp_nepp | 11:c6f95a42d4d7 | 1353 | min_SIG_needed_p1 = signal_rate_temp_mcps + (total_corr_SIG_rate_mcps / 2); |
nikapov | 0:a1a69d32f310 | 1354 | |
nikapov | 0:a1a69d32f310 | 1355 | /* FixPoint0626/FixPoint1616 = FixPoint2210 */ |
sepp_nepp | 11:c6f95a42d4d7 | 1356 | min_SIG_needed_p1 /= total_corr_SIG_rate_mcps; |
nikapov | 0:a1a69d32f310 | 1357 | |
nikapov | 0:a1a69d32f310 | 1358 | /* Apply a factored version of the speed of light. |
nikapov | 0:a1a69d32f310 | 1359 | Correction to be applied at the end */ |
sepp_nepp | 11:c6f95a42d4d7 | 1360 | min_SIG_needed_p1 *= 3; |
nikapov | 0:a1a69d32f310 | 1361 | |
nikapov | 0:a1a69d32f310 | 1362 | /* FixPoint2210 * FixPoint2210 = FixPoint1220 */ |
sepp_nepp | 11:c6f95a42d4d7 | 1363 | min_SIG_needed_p1 *= min_SIG_needed_p1; |
nikapov | 0:a1a69d32f310 | 1364 | |
nikapov | 0:a1a69d32f310 | 1365 | /* FixPoint1220 >> 16 = FixPoint2804 */ |
sepp_nepp | 11:c6f95a42d4d7 | 1366 | min_SIG_needed_p1 = (min_SIG_needed_p1 + 0x8000) >> 16; |
nikapov | 0:a1a69d32f310 | 1367 | } |
nikapov | 0:a1a69d32f310 | 1368 | |
sepp_nepp | 11:c6f95a42d4d7 | 1369 | min_SIG_needed_p2 = pw_mult * sigma_estimate_p1; |
nikapov | 0:a1a69d32f310 | 1370 | |
nikapov | 0:a1a69d32f310 | 1371 | /* FixPoint1616 >> 16 = uint32 */ |
sepp_nepp | 11:c6f95a42d4d7 | 1372 | min_SIG_needed_p2 = (min_SIG_needed_p2 + 0x8000) >> 16; |
nikapov | 0:a1a69d32f310 | 1373 | |
nikapov | 0:a1a69d32f310 | 1374 | /* uint32 * uint32 = uint32 */ |
sepp_nepp | 11:c6f95a42d4d7 | 1375 | min_SIG_needed_p2 *= min_SIG_needed_p2; |
sepp_nepp | 11:c6f95a42d4d7 | 1376 | |
sepp_nepp | 11:c6f95a42d4d7 | 1377 | /* Check sigmaEstimateP2; If this value is too high, there is not enough |
sepp_nepp | 11:c6f95a42d4d7 | 1378 | * signal rate to calculate dmax value so set a suitable value to ensure |
sepp_nepp | 11:c6f95a42d4d7 | 1379 | * a very small dmax. */ |
nikapov | 0:a1a69d32f310 | 1380 | sigma_est_p2_tmp = (sigma_estimate_p2 + 0x8000) >> 16; |
nikapov | 0:a1a69d32f310 | 1381 | sigma_est_p2_tmp = (sigma_est_p2_tmp + c_amb_eff_width_sigma_est_ns / 2) / |
nikapov | 0:a1a69d32f310 | 1382 | c_amb_eff_width_sigma_est_ns; |
nikapov | 0:a1a69d32f310 | 1383 | sigma_est_p2_tmp *= c_amb_eff_width_d_max_ns; |
nikapov | 0:a1a69d32f310 | 1384 | |
nikapov | 0:a1a69d32f310 | 1385 | if (sigma_est_p2_tmp > 0xffff) { |
sepp_nepp | 11:c6f95a42d4d7 | 1386 | min_SIG_needed_p3 = 0xfff00000; |
nikapov | 0:a1a69d32f310 | 1387 | } else { |
sepp_nepp | 11:c6f95a42d4d7 | 1388 | /* DMAX uses a different ambient width from sigma,so apply correction. |
sepp_nepp | 11:c6f95a42d4d7 | 1389 | * Perform division before multiplication to prevent overflow. */ |
nikapov | 0:a1a69d32f310 | 1390 | sigma_estimate_p2 = (sigma_estimate_p2 + c_amb_eff_width_sigma_est_ns / 2) / |
nikapov | 0:a1a69d32f310 | 1391 | c_amb_eff_width_sigma_est_ns; |
nikapov | 0:a1a69d32f310 | 1392 | sigma_estimate_p2 *= c_amb_eff_width_d_max_ns; |
nikapov | 0:a1a69d32f310 | 1393 | |
nikapov | 0:a1a69d32f310 | 1394 | /* FixPoint1616 >> 16 = uint32 */ |
sepp_nepp | 11:c6f95a42d4d7 | 1395 | min_SIG_needed_p3 = (sigma_estimate_p2 + 0x8000) >> 16; |
sepp_nepp | 11:c6f95a42d4d7 | 1396 | min_SIG_needed_p3 *= min_SIG_needed_p3; |
nikapov | 0:a1a69d32f310 | 1397 | } |
nikapov | 0:a1a69d32f310 | 1398 | |
nikapov | 0:a1a69d32f310 | 1399 | /* FixPoint1814 / uint32 = FixPoint1814 */ |
nikapov | 0:a1a69d32f310 | 1400 | sigma_limit_tmp = ((c_sigma_limit << 14) + 500) / 1000; |
nikapov | 0:a1a69d32f310 | 1401 | |
nikapov | 0:a1a69d32f310 | 1402 | /* FixPoint1814 * FixPoint1814 = FixPoint3628 := FixPoint0428 */ |
nikapov | 0:a1a69d32f310 | 1403 | sigma_limit_tmp *= sigma_limit_tmp; |
nikapov | 0:a1a69d32f310 | 1404 | |
nikapov | 0:a1a69d32f310 | 1405 | /* FixPoint1616 * FixPoint1616 = FixPoint3232 */ |
sepp_nepp | 11:c6f95a42d4d7 | 1406 | sigma_est_sq_tmp = c_sigma_est_Ref * c_sigma_est_Ref; |
nikapov | 0:a1a69d32f310 | 1407 | |
nikapov | 0:a1a69d32f310 | 1408 | /* FixPoint3232 >> 4 = FixPoint0428 */ |
nikapov | 0:a1a69d32f310 | 1409 | sigma_est_sq_tmp = (sigma_est_sq_tmp + 0x08) >> 4; |
nikapov | 0:a1a69d32f310 | 1410 | |
nikapov | 0:a1a69d32f310 | 1411 | /* FixPoint0428 - FixPoint0428 = FixPoint0428 */ |
nikapov | 0:a1a69d32f310 | 1412 | sigma_limit_tmp -= sigma_est_sq_tmp; |
nikapov | 0:a1a69d32f310 | 1413 | |
nikapov | 0:a1a69d32f310 | 1414 | /* uint32_t * FixPoint0428 = FixPoint0428 */ |
sepp_nepp | 11:c6f95a42d4d7 | 1415 | min_SIG_needed_p4 = 4 * 12 * sigma_limit_tmp; |
nikapov | 0:a1a69d32f310 | 1416 | |
nikapov | 0:a1a69d32f310 | 1417 | /* FixPoint0428 >> 14 = FixPoint1814 */ |
sepp_nepp | 11:c6f95a42d4d7 | 1418 | min_SIG_needed_p4 = (min_SIG_needed_p4 + 0x2000) >> 14; |
nikapov | 0:a1a69d32f310 | 1419 | |
nikapov | 0:a1a69d32f310 | 1420 | /* uint32 + uint32 = uint32 */ |
sepp_nepp | 11:c6f95a42d4d7 | 1421 | min_SIG_needed = (min_SIG_needed_p2 + min_SIG_needed_p3); |
nikapov | 0:a1a69d32f310 | 1422 | |
nikapov | 0:a1a69d32f310 | 1423 | /* uint32 / uint32 = uint32 */ |
sepp_nepp | 11:c6f95a42d4d7 | 1424 | min_SIG_needed += (peak_vcsel_duration_us / 2); |
sepp_nepp | 11:c6f95a42d4d7 | 1425 | min_SIG_needed /= peak_vcsel_duration_us; |
nikapov | 0:a1a69d32f310 | 1426 | |
nikapov | 0:a1a69d32f310 | 1427 | /* uint32 << 14 = FixPoint1814 */ |
sepp_nepp | 11:c6f95a42d4d7 | 1428 | min_SIG_needed <<= 14; |
nikapov | 0:a1a69d32f310 | 1429 | |
nikapov | 0:a1a69d32f310 | 1430 | /* FixPoint1814 / FixPoint1814 = uint32 */ |
sepp_nepp | 11:c6f95a42d4d7 | 1431 | min_SIG_needed += (min_SIG_needed_p4 / 2); |
sepp_nepp | 11:c6f95a42d4d7 | 1432 | min_SIG_needed /= min_SIG_needed_p4; |
nikapov | 0:a1a69d32f310 | 1433 | |
nikapov | 0:a1a69d32f310 | 1434 | /* FixPoint3200 * FixPoint2804 := FixPoint2804*/ |
sepp_nepp | 11:c6f95a42d4d7 | 1435 | min_SIG_needed *= min_SIG_needed_p1; |
nikapov | 0:a1a69d32f310 | 1436 | |
nikapov | 0:a1a69d32f310 | 1437 | /* Apply correction by dividing by 1000000. |
sepp_nepp | 11:c6f95a42d4d7 | 1438 | * This assumes 10E16 on the numerator of the equation and 10E-22 on the denominator. |
nikapov | 0:a1a69d32f310 | 1439 | * We do this because 32bit fix point calculation can't |
nikapov | 0:a1a69d32f310 | 1440 | * handle the larger and smaller elements of this equation, |
nikapov | 0:a1a69d32f310 | 1441 | * i.e. speed of light and pulse widths. |
nikapov | 0:a1a69d32f310 | 1442 | */ |
sepp_nepp | 11:c6f95a42d4d7 | 1443 | min_SIG_needed = (min_SIG_needed + 500) / 1000; |
sepp_nepp | 11:c6f95a42d4d7 | 1444 | min_SIG_needed <<= 4; |
sepp_nepp | 11:c6f95a42d4d7 | 1445 | |
sepp_nepp | 11:c6f95a42d4d7 | 1446 | min_SIG_needed = (min_SIG_needed + 500) / 1000; |
nikapov | 0:a1a69d32f310 | 1447 | |
nikapov | 0:a1a69d32f310 | 1448 | /* FixPoint1616 >> 8 = FixPoint2408 */ |
sepp_nepp | 11:c6f95a42d4d7 | 1449 | signal_limit_tmp = (c_SIG_limit + 0x80) >> 8; |
nikapov | 0:a1a69d32f310 | 1450 | |
nikapov | 0:a1a69d32f310 | 1451 | /* FixPoint2408/FixPoint2408 = uint32 */ |
nikapov | 0:a1a69d32f310 | 1452 | if (signal_limit_tmp != 0) { |
nikapov | 0:a1a69d32f310 | 1453 | dmax_dark_tmp = (signal_at0_mm + (signal_limit_tmp / 2)) |
nikapov | 0:a1a69d32f310 | 1454 | / signal_limit_tmp; |
sepp_nepp | 11:c6f95a42d4d7 | 1455 | } else { dmax_dark_tmp = 0; } |
sepp_nepp | 11:c6f95a42d4d7 | 1456 | |
sepp_nepp | 11:c6f95a42d4d7 | 1457 | dmax_dark = ISQRT(dmax_dark_tmp); |
nikapov | 0:a1a69d32f310 | 1458 | |
nikapov | 0:a1a69d32f310 | 1459 | /* FixPoint2408/FixPoint2408 = uint32 */ |
sepp_nepp | 11:c6f95a42d4d7 | 1460 | if (min_SIG_needed != 0) |
sepp_nepp | 11:c6f95a42d4d7 | 1461 | { dmax_ambient = (signal_at0_mm + min_SIG_needed / 2) / min_SIG_needed; } |
sepp_nepp | 11:c6f95a42d4d7 | 1462 | else { dmax_ambient = 0; } |
sepp_nepp | 11:c6f95a42d4d7 | 1463 | |
sepp_nepp | 11:c6f95a42d4d7 | 1464 | dmax_ambient = ISQRT(dmax_ambient); |
nikapov | 0:a1a69d32f310 | 1465 | |
nikapov | 0:a1a69d32f310 | 1466 | *pd_max_mm = dmax_dark; |
sepp_nepp | 11:c6f95a42d4d7 | 1467 | if (dmax_dark > dmax_ambient) { *pd_max_mm = dmax_ambient; } |
nikapov | 0:a1a69d32f310 | 1468 | } |
nikapov | 0:a1a69d32f310 | 1469 | |
sepp_nepp | 11:c6f95a42d4d7 | 1470 | void VL53L0X::Calc_sigma_estimate(TRangeResults *p_ranging_results, |
sepp_nepp | 11:c6f95a42d4d7 | 1471 | TFP1616 *p_sigma_estimate, uint32_t *p_dmax_mm) |
sepp_nepp | 11:c6f95a42d4d7 | 1472 | { /* Expressed in 100ths of a ns,i.e. centi-ns */ |
nikapov | 0:a1a69d32f310 | 1473 | const uint32_t c_pulse_effective_width_centi_ns = 800; |
sepp_nepp | 7:41cbc431e1f4 | 1474 | /* Expressed in 100ths of a ns,i.e. centi-ns */ |
nikapov | 0:a1a69d32f310 | 1475 | const uint32_t c_ambient_effective_width_centi_ns = 600; |
sepp_nepp | 11:c6f95a42d4d7 | 1476 | const TFP1616 c_dflt_final_range_integration_time_milli_secs = 0x00190000; /* 25ms */ |
nikapov | 0:a1a69d32f310 | 1477 | const uint32_t c_vcsel_pulse_width_ps = 4700; /* pico secs */ |
sepp_nepp | 11:c6f95a42d4d7 | 1478 | const TFP1616 c_sigma_est_max = 0x028F87AE; |
sepp_nepp | 11:c6f95a42d4d7 | 1479 | const TFP1616 c_sigma_est_rtn_max = 0xF000; |
sepp_nepp | 11:c6f95a42d4d7 | 1480 | const TFP1616 c_amb_to_SIG_ratio_max = 0xF0000000 / |
nikapov | 0:a1a69d32f310 | 1481 | c_ambient_effective_width_centi_ns; |
nikapov | 0:a1a69d32f310 | 1482 | /* Time Of Flight per mm (6.6 pico secs) */ |
sepp_nepp | 11:c6f95a42d4d7 | 1483 | const TFP1616 c_tof_per_mm_ps = 0x0006999A; |
nikapov | 0:a1a69d32f310 | 1484 | const uint32_t c_16bit_rounding_param = 0x00008000; |
sepp_nepp | 11:c6f95a42d4d7 | 1485 | const TFP1616 c_max_xtalk_kcps = 0x00320000; |
nikapov | 0:a1a69d32f310 | 1486 | const uint32_t c_pll_period_ps = 1655; |
nikapov | 0:a1a69d32f310 | 1487 | |
nikapov | 0:a1a69d32f310 | 1488 | uint32_t vcsel_total_events_rtn; |
nikapov | 0:a1a69d32f310 | 1489 | uint32_t final_range_timeout_micro_secs; |
nikapov | 0:a1a69d32f310 | 1490 | uint32_t pre_range_timeout_micro_secs; |
nikapov | 0:a1a69d32f310 | 1491 | uint32_t final_range_integration_time_milli_secs; |
sepp_nepp | 11:c6f95a42d4d7 | 1492 | TFP1616 sigma_estimate_p1; |
sepp_nepp | 11:c6f95a42d4d7 | 1493 | TFP1616 sigma_estimate_p2; |
sepp_nepp | 11:c6f95a42d4d7 | 1494 | TFP1616 sigma_estimate_p3; |
sepp_nepp | 11:c6f95a42d4d7 | 1495 | TFP1616 delta_t_ps; |
sepp_nepp | 11:c6f95a42d4d7 | 1496 | TFP1616 pw_mult; |
sepp_nepp | 11:c6f95a42d4d7 | 1497 | TFP1616 sigma_est_rtn; |
sepp_nepp | 11:c6f95a42d4d7 | 1498 | TFP1616 sigma_estimate; |
sepp_nepp | 11:c6f95a42d4d7 | 1499 | TFP1616 xtalk_correction; |
sepp_nepp | 11:c6f95a42d4d7 | 1500 | TFP1616 ambient_rate_kcps; |
sepp_nepp | 11:c6f95a42d4d7 | 1501 | TFP1616 peak_SIG_rate_kcps; |
sepp_nepp | 11:c6f95a42d4d7 | 1502 | TFP1616 xtalk_comp_rate_mcps; |
sepp_nepp | 11:c6f95a42d4d7 | 1503 | uint32_t xtalk_comp_rate_kcps; |
sepp_nepp | 11:c6f95a42d4d7 | 1504 | |
sepp_nepp | 11:c6f95a42d4d7 | 1505 | TFP1616 diff1_mcps; |
sepp_nepp | 11:c6f95a42d4d7 | 1506 | TFP1616 diff2_mcps; |
sepp_nepp | 11:c6f95a42d4d7 | 1507 | TFP1616 sqr1; |
sepp_nepp | 11:c6f95a42d4d7 | 1508 | TFP1616 sqr2; |
sepp_nepp | 11:c6f95a42d4d7 | 1509 | TFP1616 sqr_sum; |
sepp_nepp | 11:c6f95a42d4d7 | 1510 | TFP1616 sqrt_result_centi_ns; |
sepp_nepp | 11:c6f95a42d4d7 | 1511 | TFP1616 sqrt_result; |
sepp_nepp | 11:c6f95a42d4d7 | 1512 | TFP1616 total_SIG_rate_mcps; |
sepp_nepp | 11:c6f95a42d4d7 | 1513 | TFP1616 corrected_SIG_rate_mcps; |
sepp_nepp | 11:c6f95a42d4d7 | 1514 | TFP1616 sigma_est_Ref; |
nikapov | 0:a1a69d32f310 | 1515 | uint32_t vcsel_width; |
nikapov | 0:a1a69d32f310 | 1516 | uint32_t final_range_macro_pclks; |
nikapov | 0:a1a69d32f310 | 1517 | uint32_t pre_range_macro_pclks; |
nikapov | 0:a1a69d32f310 | 1518 | uint32_t peak_vcsel_duration_us; |
nikapov | 0:a1a69d32f310 | 1519 | uint8_t final_range_vcsel_pclks; |
nikapov | 0:a1a69d32f310 | 1520 | uint8_t pre_range_vcsel_pclks; |
nikapov | 0:a1a69d32f310 | 1521 | /*! \addtogroup calc_sigma_estimate |
nikapov | 0:a1a69d32f310 | 1522 | * @{ |
sepp_nepp | 11:c6f95a42d4d7 | 1523 | * Estimates the range sigma */ |
sepp_nepp | 11:c6f95a42d4d7 | 1524 | |
sepp_nepp | 11:c6f95a42d4d7 | 1525 | xtalk_comp_rate_mcps = CurrParams.Xtalk_CompRate_MHz; |
sepp_nepp | 10:cd251e0fc2fd | 1526 | |
sepp_nepp | 10:cd251e0fc2fd | 1527 | /* We work in kcps rather than mcps as this helps keep within the |
sepp_nepp | 11:c6f95a42d4d7 | 1528 | * confines of the 32 Fix1616 type. */ |
sepp_nepp | 11:c6f95a42d4d7 | 1529 | ambient_rate_kcps = (p_ranging_results->AmbientRateRtnMHz * 1000) >> 16; |
sepp_nepp | 11:c6f95a42d4d7 | 1530 | |
sepp_nepp | 11:c6f95a42d4d7 | 1531 | corrected_SIG_rate_mcps = p_ranging_results->SignalRateRtnMHz; |
sepp_nepp | 11:c6f95a42d4d7 | 1532 | |
sepp_nepp | 11:c6f95a42d4d7 | 1533 | Get_total_SIG_rate(p_ranging_results,&total_SIG_rate_mcps); |
sepp_nepp | 11:c6f95a42d4d7 | 1534 | xtalk_comp_rate_mcps = Get_total_xtalk_rate(p_ranging_results); |
nikapov | 0:a1a69d32f310 | 1535 | |
nikapov | 0:a1a69d32f310 | 1536 | /* Signal rate measurement provided by device is the |
sepp_nepp | 11:c6f95a42d4d7 | 1537 | * peak signal rate,not average. */ |
sepp_nepp | 11:c6f95a42d4d7 | 1538 | peak_SIG_rate_kcps = (total_SIG_rate_mcps * 1000); |
sepp_nepp | 11:c6f95a42d4d7 | 1539 | peak_SIG_rate_kcps = (peak_SIG_rate_kcps + 0x8000) >> 16; |
sepp_nepp | 11:c6f95a42d4d7 | 1540 | |
sepp_nepp | 11:c6f95a42d4d7 | 1541 | xtalk_comp_rate_kcps = xtalk_comp_rate_mcps * 1000; |
sepp_nepp | 11:c6f95a42d4d7 | 1542 | |
sepp_nepp | 11:c6f95a42d4d7 | 1543 | if (xtalk_comp_rate_kcps > c_max_xtalk_kcps) |
sepp_nepp | 11:c6f95a42d4d7 | 1544 | { xtalk_comp_rate_kcps = c_max_xtalk_kcps; } |
sepp_nepp | 11:c6f95a42d4d7 | 1545 | |
sepp_nepp | 11:c6f95a42d4d7 | 1546 | if (ErrState == VL53L0X_OK) { |
nikapov | 0:a1a69d32f310 | 1547 | /* Calculate final range macro periods */ |
sepp_nepp | 10:cd251e0fc2fd | 1548 | final_range_timeout_micro_secs = DevSpecParams.FinalRangeTimeoutMicroSecs; |
sepp_nepp | 11:c6f95a42d4d7 | 1549 | final_range_vcsel_pclks = DevSpecParams.FinalRangeVcselPPeriod; |
sepp_nepp | 11:c6f95a42d4d7 | 1550 | final_range_macro_pclks = Calc_timeout_mclks(final_range_timeout_micro_secs,final_range_vcsel_pclks); |
nikapov | 0:a1a69d32f310 | 1551 | |
nikapov | 0:a1a69d32f310 | 1552 | /* Calculate pre-range macro periods */ |
sepp_nepp | 10:cd251e0fc2fd | 1553 | pre_range_timeout_micro_secs = DevSpecParams.PreRangeTimeoutMicroSecs; |
sepp_nepp | 11:c6f95a42d4d7 | 1554 | pre_range_vcsel_pclks = DevSpecParams.PreRangeVcselPPeriod; |
sepp_nepp | 11:c6f95a42d4d7 | 1555 | pre_range_macro_pclks = Calc_timeout_mclks(pre_range_timeout_micro_secs,pre_range_vcsel_pclks); |
nikapov | 0:a1a69d32f310 | 1556 | vcsel_width = 3; |
sepp_nepp | 11:c6f95a42d4d7 | 1557 | if (final_range_vcsel_pclks == 8) { vcsel_width = 2; } |
nikapov | 0:a1a69d32f310 | 1558 | |
nikapov | 0:a1a69d32f310 | 1559 | peak_vcsel_duration_us = vcsel_width * 2048 * |
nikapov | 0:a1a69d32f310 | 1560 | (pre_range_macro_pclks + final_range_macro_pclks); |
nikapov | 0:a1a69d32f310 | 1561 | peak_vcsel_duration_us = (peak_vcsel_duration_us + 500) / 1000; |
nikapov | 0:a1a69d32f310 | 1562 | peak_vcsel_duration_us *= c_pll_period_ps; |
nikapov | 0:a1a69d32f310 | 1563 | peak_vcsel_duration_us = (peak_vcsel_duration_us + 500) / 1000; |
nikapov | 0:a1a69d32f310 | 1564 | |
nikapov | 0:a1a69d32f310 | 1565 | /* Fix1616 >> 8 = Fix2408 */ |
sepp_nepp | 11:c6f95a42d4d7 | 1566 | total_SIG_rate_mcps = (total_SIG_rate_mcps + 0x80) >> 8; |
nikapov | 0:a1a69d32f310 | 1567 | |
nikapov | 0:a1a69d32f310 | 1568 | /* Fix2408 * uint32 = Fix2408 */ |
sepp_nepp | 11:c6f95a42d4d7 | 1569 | vcsel_total_events_rtn = total_SIG_rate_mcps * peak_vcsel_duration_us; |
nikapov | 0:a1a69d32f310 | 1570 | |
nikapov | 0:a1a69d32f310 | 1571 | /* Fix2408 >> 8 = uint32 */ |
nikapov | 0:a1a69d32f310 | 1572 | vcsel_total_events_rtn = (vcsel_total_events_rtn + 0x80) >> 8; |
nikapov | 0:a1a69d32f310 | 1573 | |
nikapov | 0:a1a69d32f310 | 1574 | /* Fix2408 << 8 = Fix1616 = */ |
sepp_nepp | 11:c6f95a42d4d7 | 1575 | total_SIG_rate_mcps <<= 8; |
nikapov | 0:a1a69d32f310 | 1576 | } |
nikapov | 0:a1a69d32f310 | 1577 | |
sepp_nepp | 11:c6f95a42d4d7 | 1578 | if (ErrState != VL53L0X_OK) { return ; } |
sepp_nepp | 11:c6f95a42d4d7 | 1579 | |
sepp_nepp | 11:c6f95a42d4d7 | 1580 | if (peak_SIG_rate_kcps == 0) { |
nikapov | 0:a1a69d32f310 | 1581 | *p_sigma_estimate = c_sigma_est_max; |
sepp_nepp | 10:cd251e0fc2fd | 1582 | SigmaEstimate = c_sigma_est_max; |
nikapov | 0:a1a69d32f310 | 1583 | *p_dmax_mm = 0; |
nikapov | 0:a1a69d32f310 | 1584 | } else { |
sepp_nepp | 11:c6f95a42d4d7 | 1585 | if (vcsel_total_events_rtn < 1) {vcsel_total_events_rtn = 1; } |
nikapov | 0:a1a69d32f310 | 1586 | |
nikapov | 0:a1a69d32f310 | 1587 | sigma_estimate_p1 = c_pulse_effective_width_centi_ns; |
nikapov | 0:a1a69d32f310 | 1588 | |
nikapov | 0:a1a69d32f310 | 1589 | /* ((FixPoint1616 << 16)* uint32)/uint32 = FixPoint1616 */ |
sepp_nepp | 11:c6f95a42d4d7 | 1590 | sigma_estimate_p2 = (ambient_rate_kcps << 16) / peak_SIG_rate_kcps; |
sepp_nepp | 11:c6f95a42d4d7 | 1591 | if (sigma_estimate_p2 > c_amb_to_SIG_ratio_max) |
sepp_nepp | 11:c6f95a42d4d7 | 1592 | /* Clip to prevent overflow. Will ensure safe max result. */ |
sepp_nepp | 11:c6f95a42d4d7 | 1593 | { sigma_estimate_p2 = c_amb_to_SIG_ratio_max; } |
nikapov | 0:a1a69d32f310 | 1594 | sigma_estimate_p2 *= c_ambient_effective_width_centi_ns; |
sepp_nepp | 11:c6f95a42d4d7 | 1595 | sigma_estimate_p3 = 2 * ISQRT(vcsel_total_events_rtn * 12); |
nikapov | 0:a1a69d32f310 | 1596 | |
nikapov | 0:a1a69d32f310 | 1597 | /* uint32 * FixPoint1616 = FixPoint1616 */ |
sepp_nepp | 11:c6f95a42d4d7 | 1598 | delta_t_ps = p_ranging_results->RangeMilliMeter * c_tof_per_mm_ps; |
sepp_nepp | 11:c6f95a42d4d7 | 1599 | |
sepp_nepp | 11:c6f95a42d4d7 | 1600 | /* vcselRate - xtalkCompRate |
nikapov | 0:a1a69d32f310 | 1601 | * (uint32 << 16) - FixPoint1616 = FixPoint1616. |
nikapov | 0:a1a69d32f310 | 1602 | * Divide result by 1000 to convert to mcps. |
sepp_nepp | 11:c6f95a42d4d7 | 1603 | * 500 is added to ensure rounding when integer division truncates. */ |
sepp_nepp | 11:c6f95a42d4d7 | 1604 | diff1_mcps = (((peak_SIG_rate_kcps << 16) - 2 * xtalk_comp_rate_kcps) + 500) / 1000; |
nikapov | 0:a1a69d32f310 | 1605 | |
nikapov | 0:a1a69d32f310 | 1606 | /* vcselRate + xtalkCompRate */ |
sepp_nepp | 11:c6f95a42d4d7 | 1607 | diff2_mcps = ((peak_SIG_rate_kcps << 16) + 500) / 1000; |
sepp_nepp | 11:c6f95a42d4d7 | 1608 | |
sepp_nepp | 11:c6f95a42d4d7 | 1609 | /* Shift by 8 bits to increase resolution prior to the division */ |
nikapov | 0:a1a69d32f310 | 1610 | diff1_mcps <<= 8; |
nikapov | 0:a1a69d32f310 | 1611 | |
nikapov | 0:a1a69d32f310 | 1612 | /* FixPoint0824/FixPoint1616 = FixPoint2408 */ |
nikapov | 0:a1a69d32f310 | 1613 | // xTalkCorrection = abs(diff1_mcps/diff2_mcps); |
sepp_nepp | 11:c6f95a42d4d7 | 1614 | // abs is causing compiler overloading isue in C++, but unsigned types. So,redundant call anyway! |
sepp_nepp | 11:c6f95a42d4d7 | 1615 | xtalk_correction = diff1_mcps / diff2_mcps; |
nikapov | 0:a1a69d32f310 | 1616 | |
nikapov | 0:a1a69d32f310 | 1617 | /* FixPoint2408 << 8 = FixPoint1616 */ |
sepp_nepp | 11:c6f95a42d4d7 | 1618 | xtalk_correction <<= 8; |
sepp_nepp | 11:c6f95a42d4d7 | 1619 | |
sepp_nepp | 11:c6f95a42d4d7 | 1620 | if (p_ranging_results->RangeStatus != 0) |
sepp_nepp | 11:c6f95a42d4d7 | 1621 | { pw_mult = 1 << 16; } |
sepp_nepp | 11:c6f95a42d4d7 | 1622 | else { |
nikapov | 0:a1a69d32f310 | 1623 | /* FixPoint1616/uint32 = FixPoint1616 */ |
nikapov | 0:a1a69d32f310 | 1624 | pw_mult = delta_t_ps / c_vcsel_pulse_width_ps; /* smaller than 1.0f */ |
nikapov | 0:a1a69d32f310 | 1625 | |
sepp_nepp | 10:cd251e0fc2fd | 1626 | /* FixPoint1616 * FixPoint1616 = FixPoint3232,however both |
nikapov | 0:a1a69d32f310 | 1627 | * values are small enough such that32 bits will not be |
sepp_nepp | 11:c6f95a42d4d7 | 1628 | * exceeded. */ |
sepp_nepp | 11:c6f95a42d4d7 | 1629 | pw_mult *= ((1 << 16) - xtalk_correction); |
nikapov | 0:a1a69d32f310 | 1630 | |
nikapov | 0:a1a69d32f310 | 1631 | /* (FixPoint3232 >> 16) = FixPoint1616 */ |
nikapov | 0:a1a69d32f310 | 1632 | pw_mult = (pw_mult + c_16bit_rounding_param) >> 16; |
nikapov | 0:a1a69d32f310 | 1633 | |
nikapov | 0:a1a69d32f310 | 1634 | /* FixPoint1616 + FixPoint1616 = FixPoint1616 */ |
nikapov | 0:a1a69d32f310 | 1635 | pw_mult += (1 << 16); |
nikapov | 0:a1a69d32f310 | 1636 | |
sepp_nepp | 10:cd251e0fc2fd | 1637 | /* At this point the value will be 1.xx,therefore if we square |
nikapov | 0:a1a69d32f310 | 1638 | * the value this will exceed 32 bits. To address this perform |
sepp_nepp | 11:c6f95a42d4d7 | 1639 | * a single shift to the right before the multiplication. */ |
nikapov | 0:a1a69d32f310 | 1640 | pw_mult >>= 1; |
nikapov | 0:a1a69d32f310 | 1641 | /* FixPoint1715 * FixPoint1715 = FixPoint3430 */ |
nikapov | 0:a1a69d32f310 | 1642 | pw_mult = pw_mult * pw_mult; |
nikapov | 0:a1a69d32f310 | 1643 | |
nikapov | 0:a1a69d32f310 | 1644 | /* (FixPoint3430 >> 14) = Fix1616 */ |
nikapov | 0:a1a69d32f310 | 1645 | pw_mult >>= 14; |
nikapov | 0:a1a69d32f310 | 1646 | } |
nikapov | 0:a1a69d32f310 | 1647 | |
nikapov | 0:a1a69d32f310 | 1648 | /* FixPoint1616 * uint32 = FixPoint1616 */ |
nikapov | 0:a1a69d32f310 | 1649 | sqr1 = pw_mult * sigma_estimate_p1; |
nikapov | 0:a1a69d32f310 | 1650 | |
nikapov | 0:a1a69d32f310 | 1651 | /* (FixPoint1616 >> 16) = FixPoint3200 */ |
nikapov | 0:a1a69d32f310 | 1652 | sqr1 = (sqr1 + 0x8000) >> 16; |
nikapov | 0:a1a69d32f310 | 1653 | |
nikapov | 0:a1a69d32f310 | 1654 | /* FixPoint3200 * FixPoint3200 = FixPoint6400 */ |
nikapov | 0:a1a69d32f310 | 1655 | sqr1 *= sqr1; |
nikapov | 0:a1a69d32f310 | 1656 | sqr2 = sigma_estimate_p2; |
nikapov | 0:a1a69d32f310 | 1657 | |
nikapov | 0:a1a69d32f310 | 1658 | /* (FixPoint1616 >> 16) = FixPoint3200 */ |
nikapov | 0:a1a69d32f310 | 1659 | sqr2 = (sqr2 + 0x8000) >> 16; |
nikapov | 0:a1a69d32f310 | 1660 | |
nikapov | 0:a1a69d32f310 | 1661 | /* FixPoint3200 * FixPoint3200 = FixPoint6400 */ |
nikapov | 0:a1a69d32f310 | 1662 | sqr2 *= sqr2; |
nikapov | 0:a1a69d32f310 | 1663 | |
nikapov | 0:a1a69d32f310 | 1664 | /* FixPoint64000 + FixPoint6400 = FixPoint6400 */ |
nikapov | 0:a1a69d32f310 | 1665 | sqr_sum = sqr1 + sqr2; |
nikapov | 0:a1a69d32f310 | 1666 | |
nikapov | 0:a1a69d32f310 | 1667 | /* SQRT(FixPoin6400) = FixPoint3200 */ |
sepp_nepp | 11:c6f95a42d4d7 | 1668 | sqrt_result_centi_ns = ISQRT(sqr_sum); |
nikapov | 0:a1a69d32f310 | 1669 | |
nikapov | 0:a1a69d32f310 | 1670 | /* (FixPoint3200 << 16) = FixPoint1616 */ |
nikapov | 0:a1a69d32f310 | 1671 | sqrt_result_centi_ns <<= 16; |
nikapov | 0:a1a69d32f310 | 1672 | |
sepp_nepp | 11:c6f95a42d4d7 | 1673 | /* Note that the Speed Of Light is expressed in um per 1E-10 |
sepp_nepp | 11:c6f95a42d4d7 | 1674 | * seconds (2997) Therefore to get mm/ns we have to divide by 10000 */ |
nikapov | 0:a1a69d32f310 | 1675 | sigma_est_rtn = (((sqrt_result_centi_ns + 50) / 100) / |
nikapov | 0:a1a69d32f310 | 1676 | sigma_estimate_p3); |
nikapov | 0:a1a69d32f310 | 1677 | sigma_est_rtn *= VL53L0X_SPEED_OF_LIGHT_IN_AIR; |
nikapov | 0:a1a69d32f310 | 1678 | |
nikapov | 0:a1a69d32f310 | 1679 | /* Add 5000 before dividing by 10000 to ensure rounding. */ |
sepp_nepp | 11:c6f95a42d4d7 | 1680 | sigma_est_rtn = (sigma_est_rtn + 5000) / 10000; |
sepp_nepp | 11:c6f95a42d4d7 | 1681 | |
sepp_nepp | 11:c6f95a42d4d7 | 1682 | if (sigma_est_rtn > c_sigma_est_rtn_max) |
sepp_nepp | 11:c6f95a42d4d7 | 1683 | /* Clip to prevent overflow. Will ensure safe max result. */ |
sepp_nepp | 11:c6f95a42d4d7 | 1684 | { sigma_est_rtn = c_sigma_est_rtn_max; } |
sepp_nepp | 11:c6f95a42d4d7 | 1685 | |
nikapov | 0:a1a69d32f310 | 1686 | final_range_integration_time_milli_secs = |
nikapov | 0:a1a69d32f310 | 1687 | (final_range_timeout_micro_secs + pre_range_timeout_micro_secs + 500) / 1000; |
nikapov | 0:a1a69d32f310 | 1688 | |
nikapov | 0:a1a69d32f310 | 1689 | /* sigmaEstRef = 1mm * 25ms/final range integration time (inc pre-range) |
sepp_nepp | 11:c6f95a42d4d7 | 1690 | * sqrt(FixPoint1616/int) = FixPoint2408) */ |
sepp_nepp | 11:c6f95a42d4d7 | 1691 | sigma_est_Ref = |
sepp_nepp | 11:c6f95a42d4d7 | 1692 | ISQRT((c_dflt_final_range_integration_time_milli_secs + |
nikapov | 0:a1a69d32f310 | 1693 | final_range_integration_time_milli_secs / 2) / |
nikapov | 0:a1a69d32f310 | 1694 | final_range_integration_time_milli_secs); |
nikapov | 0:a1a69d32f310 | 1695 | |
nikapov | 0:a1a69d32f310 | 1696 | /* FixPoint2408 << 8 = FixPoint1616 */ |
sepp_nepp | 11:c6f95a42d4d7 | 1697 | sigma_est_Ref <<= 8; |
sepp_nepp | 11:c6f95a42d4d7 | 1698 | sigma_est_Ref = (sigma_est_Ref + 500) / 1000; |
nikapov | 0:a1a69d32f310 | 1699 | |
nikapov | 0:a1a69d32f310 | 1700 | /* FixPoint1616 * FixPoint1616 = FixPoint3232 */ |
nikapov | 0:a1a69d32f310 | 1701 | sqr1 = sigma_est_rtn * sigma_est_rtn; |
nikapov | 0:a1a69d32f310 | 1702 | /* FixPoint1616 * FixPoint1616 = FixPoint3232 */ |
sepp_nepp | 11:c6f95a42d4d7 | 1703 | sqr2 = sigma_est_Ref * sigma_est_Ref; |
nikapov | 0:a1a69d32f310 | 1704 | |
nikapov | 0:a1a69d32f310 | 1705 | /* sqrt(FixPoint3232) = FixPoint1616 */ |
sepp_nepp | 11:c6f95a42d4d7 | 1706 | sqrt_result = ISQRT((sqr1 + sqr2)); |
sepp_nepp | 11:c6f95a42d4d7 | 1707 | /* Note that the Shift by 4 bits increases resolution prior to |
sepp_nepp | 7:41cbc431e1f4 | 1708 | * the sqrt,therefore the result must be shifted by 2 bits to |
sepp_nepp | 11:c6f95a42d4d7 | 1709 | * the right to revert back to the FixPoint1616 format. */ |
nikapov | 0:a1a69d32f310 | 1710 | sigma_estimate = 1000 * sqrt_result; |
nikapov | 0:a1a69d32f310 | 1711 | |
sepp_nepp | 11:c6f95a42d4d7 | 1712 | if ((peak_SIG_rate_kcps < 1) || (vcsel_total_events_rtn < 1) || |
nikapov | 0:a1a69d32f310 | 1713 | (sigma_estimate > c_sigma_est_max)) { |
sepp_nepp | 11:c6f95a42d4d7 | 1714 | sigma_estimate = c_sigma_est_max; } |
nikapov | 0:a1a69d32f310 | 1715 | |
nikapov | 0:a1a69d32f310 | 1716 | *p_sigma_estimate = (uint32_t)(sigma_estimate); |
sepp_nepp | 10:cd251e0fc2fd | 1717 | SigmaEstimate = *p_sigma_estimate; |
sepp_nepp | 11:c6f95a42d4d7 | 1718 | Calc_dmax(total_SIG_rate_mcps, |
sepp_nepp | 11:c6f95a42d4d7 | 1719 | corrected_SIG_rate_mcps, |
nikapov | 0:a1a69d32f310 | 1720 | pw_mult, |
nikapov | 0:a1a69d32f310 | 1721 | sigma_estimate_p1, |
nikapov | 0:a1a69d32f310 | 1722 | sigma_estimate_p2, |
nikapov | 0:a1a69d32f310 | 1723 | peak_vcsel_duration_us, |
nikapov | 0:a1a69d32f310 | 1724 | p_dmax_mm); |
nikapov | 0:a1a69d32f310 | 1725 | } |
nikapov | 0:a1a69d32f310 | 1726 | } |
nikapov | 0:a1a69d32f310 | 1727 | |
sepp_nepp | 11:c6f95a42d4d7 | 1728 | void VL53L0X::Get_Device_range_status(uint8_t device_range_status, |
sepp_nepp | 11:c6f95a42d4d7 | 1729 | TFP1616 signal_rate, |
sepp_nepp | 11:c6f95a42d4d7 | 1730 | uint16_t effective_SPAD_rtn_count, |
sepp_nepp | 11:c6f95a42d4d7 | 1731 | TRangeResults *p_ranging_results, |
sepp_nepp | 11:c6f95a42d4d7 | 1732 | uint8_t *p_Device_range_status) |
sepp_nepp | 11:c6f95a42d4d7 | 1733 | { uint8_t none_flag; |
nikapov | 0:a1a69d32f310 | 1734 | uint8_t sigma_limitflag = 0; |
sepp_nepp | 11:c6f95a42d4d7 | 1735 | uint8_t signal_Ref_clipflag = 0; |
nikapov | 0:a1a69d32f310 | 1736 | uint8_t range_ignore_thresholdflag = 0; |
sepp_nepp | 11:c6f95a42d4d7 | 1737 | uint8_t sigma_limit_chk_en = 0; |
sepp_nepp | 11:c6f95a42d4d7 | 1738 | uint8_t signal_rate_final_range_limit_chk_en = 0; |
sepp_nepp | 11:c6f95a42d4d7 | 1739 | uint8_t signal_Ref_clip_limit_chk_en = 0; |
sepp_nepp | 11:c6f95a42d4d7 | 1740 | uint8_t range_ignore_threshold_chk_en = 0; |
sepp_nepp | 11:c6f95a42d4d7 | 1741 | TFP1616 sigma_estimate; |
sepp_nepp | 11:c6f95a42d4d7 | 1742 | TFP1616 sigma_limit_value; |
sepp_nepp | 11:c6f95a42d4d7 | 1743 | TFP1616 signal_Ref_clip_value; |
sepp_nepp | 11:c6f95a42d4d7 | 1744 | TFP1616 range_ignore_threshold; |
sepp_nepp | 11:c6f95a42d4d7 | 1745 | TFP1616 signal_rate_per_SPAD; |
nikapov | 0:a1a69d32f310 | 1746 | uint8_t device_range_status_internal = 0; |
nikapov | 0:a1a69d32f310 | 1747 | uint8_t temp8; |
nikapov | 0:a1a69d32f310 | 1748 | uint32_t dmax_mm = 0; |
sepp_nepp | 11:c6f95a42d4d7 | 1749 | |
sepp_nepp | 11:c6f95a42d4d7 | 1750 | /* VL53L0X has a good ranging when the value of the |
nikapov | 0:a1a69d32f310 | 1751 | * DeviceRangeStatus = 11. This function will replace the value 0 with |
nikapov | 0:a1a69d32f310 | 1752 | * the value 11 in the DeviceRangeStatus. |
sepp_nepp | 7:41cbc431e1f4 | 1753 | * In addition,the SigmaEstimator is not included in the VL53L0X |
sepp_nepp | 11:c6f95a42d4d7 | 1754 | * DeviceRangeStatus,this will be added in the DeviceRangeStatus. */ |
nikapov | 0:a1a69d32f310 | 1755 | |
nikapov | 0:a1a69d32f310 | 1756 | device_range_status_internal = ((device_range_status & 0x78) >> 3); |
nikapov | 0:a1a69d32f310 | 1757 | |
sepp_nepp | 11:c6f95a42d4d7 | 1758 | if ( device_range_status_internal == 0 || |
sepp_nepp | 11:c6f95a42d4d7 | 1759 | device_range_status_internal == 5 || |
sepp_nepp | 11:c6f95a42d4d7 | 1760 | device_range_status_internal == 7 || |
sepp_nepp | 11:c6f95a42d4d7 | 1761 | device_range_status_internal == 12 || |
sepp_nepp | 11:c6f95a42d4d7 | 1762 | device_range_status_internal == 13 || |
sepp_nepp | 11:c6f95a42d4d7 | 1763 | device_range_status_internal == 14 || |
sepp_nepp | 11:c6f95a42d4d7 | 1764 | device_range_status_internal == 15 ) |
sepp_nepp | 11:c6f95a42d4d7 | 1765 | { none_flag = 1; } |
sepp_nepp | 11:c6f95a42d4d7 | 1766 | else { none_flag = 0; } |
sepp_nepp | 11:c6f95a42d4d7 | 1767 | |
sepp_nepp | 11:c6f95a42d4d7 | 1768 | /* Check if Sigma limit is enabled,if yes then do comparison with limit |
sepp_nepp | 11:c6f95a42d4d7 | 1769 | * value and put the result back into pDeviceRangeStatus. */ |
sepp_nepp | 11:c6f95a42d4d7 | 1770 | if (ErrState == VL53L0X_OK) |
sepp_nepp | 11:c6f95a42d4d7 | 1771 | { sigma_limit_chk_en = Get_limit_chk_en(VL53L0X_CHECKEN_SIGMA_FINAL_RANGE); } |
sepp_nepp | 11:c6f95a42d4d7 | 1772 | |
sepp_nepp | 11:c6f95a42d4d7 | 1773 | if ((sigma_limit_chk_en != 0) && (ErrState == VL53L0X_OK)) { |
sepp_nepp | 11:c6f95a42d4d7 | 1774 | /* compute the Sigma and check with limit */ |
sepp_nepp | 11:c6f95a42d4d7 | 1775 | Calc_sigma_estimate(p_ranging_results, &sigma_estimate, &dmax_mm); |
sepp_nepp | 11:c6f95a42d4d7 | 1776 | if (ErrState == VL53L0X_OK) |
sepp_nepp | 11:c6f95a42d4d7 | 1777 | { p_ranging_results->RangeDMaxMilliMeter = dmax_mm; } |
sepp_nepp | 11:c6f95a42d4d7 | 1778 | |
sepp_nepp | 11:c6f95a42d4d7 | 1779 | if (ErrState == VL53L0X_OK) |
sepp_nepp | 11:c6f95a42d4d7 | 1780 | { sigma_limit_value = Get_limit_chk_val(VL53L0X_CHECKEN_SIGMA_FINAL_RANGE); |
sepp_nepp | 11:c6f95a42d4d7 | 1781 | |
sepp_nepp | 11:c6f95a42d4d7 | 1782 | if ((sigma_limit_value > 0) && (sigma_estimate > sigma_limit_value)) |
sepp_nepp | 11:c6f95a42d4d7 | 1783 | { sigma_limitflag = 1; }/* Limit Fail */ |
sepp_nepp | 11:c6f95a42d4d7 | 1784 | } |
sepp_nepp | 11:c6f95a42d4d7 | 1785 | } |
sepp_nepp | 11:c6f95a42d4d7 | 1786 | |
sepp_nepp | 11:c6f95a42d4d7 | 1787 | /* Check if Signal ref clip limit is enabled,if yes then do comparison |
sepp_nepp | 11:c6f95a42d4d7 | 1788 | * with limit value and put the result back into pDeviceRangeStatus. */ |
sepp_nepp | 11:c6f95a42d4d7 | 1789 | if (ErrState == VL53L0X_OK) |
sepp_nepp | 11:c6f95a42d4d7 | 1790 | {signal_Ref_clip_limit_chk_en = Get_limit_chk_en(VL53L0X_CHECKEN_SIG_REF_CLIP);} |
sepp_nepp | 11:c6f95a42d4d7 | 1791 | |
sepp_nepp | 11:c6f95a42d4d7 | 1792 | if ((signal_Ref_clip_limit_chk_en != 0) && (ErrState == VL53L0X_OK)) |
sepp_nepp | 11:c6f95a42d4d7 | 1793 | { signal_Ref_clip_value = Get_limit_chk_val(VL53L0X_CHECKEN_SIG_REF_CLIP); |
nikapov | 0:a1a69d32f310 | 1794 | |
nikapov | 0:a1a69d32f310 | 1795 | /* Read LastSignalRefMcps from device */ |
sepp_nepp | 11:c6f95a42d4d7 | 1796 | Write_Byte(0xFF,0x01); |
sepp_nepp | 11:c6f95a42d4d7 | 1797 | LastSignalRefMcps = FP97_TO_FP1616( Read_Word(REG_RESULT_PEAK_SIG_RATE_REF)); |
sepp_nepp | 11:c6f95a42d4d7 | 1798 | Write_Byte(0xFF,0x00); |
sepp_nepp | 11:c6f95a42d4d7 | 1799 | |
sepp_nepp | 11:c6f95a42d4d7 | 1800 | if ((signal_Ref_clip_value > 0) && (LastSignalRefMcps > signal_Ref_clip_value)) \ |
sepp_nepp | 11:c6f95a42d4d7 | 1801 | { signal_Ref_clipflag = 1; /* Limit Fail */ } |
sepp_nepp | 11:c6f95a42d4d7 | 1802 | } |
sepp_nepp | 11:c6f95a42d4d7 | 1803 | |
sepp_nepp | 11:c6f95a42d4d7 | 1804 | /* Check if Signal ref clip limit is enabled,if yes then do comparison |
sepp_nepp | 11:c6f95a42d4d7 | 1805 | * with limit value and put the result back into pDeviceRangeStatus. |
sepp_nepp | 11:c6f95a42d4d7 | 1806 | * EffectiveSPADRtnCount has a format 8.8 |
sepp_nepp | 11:c6f95a42d4d7 | 1807 | * If (Return signal rate < (1.5 x Xtalk x number of SPADS)) : FAIL */ |
sepp_nepp | 11:c6f95a42d4d7 | 1808 | if (ErrState == VL53L0X_OK) |
sepp_nepp | 11:c6f95a42d4d7 | 1809 | { range_ignore_threshold_chk_en = Get_limit_chk_en(VL53L0X_CHECKEN_RANGE_IGNORE_THRESHOLD); } |
sepp_nepp | 11:c6f95a42d4d7 | 1810 | |
sepp_nepp | 11:c6f95a42d4d7 | 1811 | if ((range_ignore_threshold_chk_en != 0) && (ErrState == VL53L0X_OK)) |
sepp_nepp | 11:c6f95a42d4d7 | 1812 | {/* Compute the signal rate per SPAD */ |
sepp_nepp | 11:c6f95a42d4d7 | 1813 | if (effective_SPAD_rtn_count == 0) { signal_rate_per_SPAD = 0; } |
sepp_nepp | 11:c6f95a42d4d7 | 1814 | else { signal_rate_per_SPAD = |
sepp_nepp | 11:c6f95a42d4d7 | 1815 | (TFP1616)((256 * signal_rate) / effective_SPAD_rtn_count); } |
sepp_nepp | 11:c6f95a42d4d7 | 1816 | |
sepp_nepp | 11:c6f95a42d4d7 | 1817 | range_ignore_threshold=Get_limit_chk_val(VL53L0X_CHECKEN_RANGE_IGNORE_THRESHOLD); |
sepp_nepp | 11:c6f95a42d4d7 | 1818 | |
sepp_nepp | 11:c6f95a42d4d7 | 1819 | if ((range_ignore_threshold > 0) && (signal_rate_per_SPAD < range_ignore_threshold)) { |
sepp_nepp | 11:c6f95a42d4d7 | 1820 | /* Limit Fail add 2^6 to range ErrState */ |
nikapov | 0:a1a69d32f310 | 1821 | range_ignore_thresholdflag = 1; |
nikapov | 0:a1a69d32f310 | 1822 | } |
nikapov | 0:a1a69d32f310 | 1823 | } |
nikapov | 0:a1a69d32f310 | 1824 | |
sepp_nepp | 11:c6f95a42d4d7 | 1825 | if (ErrState == VL53L0X_OK) { |
nikapov | 0:a1a69d32f310 | 1826 | if (none_flag == 1) { |
sepp_nepp | 11:c6f95a42d4d7 | 1827 | *p_Device_range_status = 255; /* NONE */ |
nikapov | 0:a1a69d32f310 | 1828 | } else if (device_range_status_internal == 1 || |
nikapov | 0:a1a69d32f310 | 1829 | device_range_status_internal == 2 || |
nikapov | 0:a1a69d32f310 | 1830 | device_range_status_internal == 3) { |
sepp_nepp | 11:c6f95a42d4d7 | 1831 | *p_Device_range_status = 5; /* HW fail */ |
nikapov | 0:a1a69d32f310 | 1832 | } else if (device_range_status_internal == 6 || |
nikapov | 0:a1a69d32f310 | 1833 | device_range_status_internal == 9) { |
sepp_nepp | 11:c6f95a42d4d7 | 1834 | *p_Device_range_status = 4; /* Phase fail */ |
nikapov | 0:a1a69d32f310 | 1835 | } else if (device_range_status_internal == 8 || |
nikapov | 0:a1a69d32f310 | 1836 | device_range_status_internal == 10 || |
sepp_nepp | 11:c6f95a42d4d7 | 1837 | signal_Ref_clipflag == 1) { |
sepp_nepp | 11:c6f95a42d4d7 | 1838 | *p_Device_range_status = 3; /* Min range */ |
nikapov | 0:a1a69d32f310 | 1839 | } else if (device_range_status_internal == 4 || |
nikapov | 0:a1a69d32f310 | 1840 | range_ignore_thresholdflag == 1) { |
sepp_nepp | 11:c6f95a42d4d7 | 1841 | *p_Device_range_status = 2; /* Signal Fail */ |
nikapov | 0:a1a69d32f310 | 1842 | } else if (sigma_limitflag == 1) { |
sepp_nepp | 11:c6f95a42d4d7 | 1843 | *p_Device_range_status = 1; /* Sigma Fail */ |
nikapov | 0:a1a69d32f310 | 1844 | } else { |
sepp_nepp | 11:c6f95a42d4d7 | 1845 | *p_Device_range_status = 0; /* Range Valid */ |
nikapov | 0:a1a69d32f310 | 1846 | } |
nikapov | 0:a1a69d32f310 | 1847 | } |
nikapov | 0:a1a69d32f310 | 1848 | |
nikapov | 0:a1a69d32f310 | 1849 | /* DMAX only relevant during range error */ |
sepp_nepp | 11:c6f95a42d4d7 | 1850 | if (*p_Device_range_status == 0) { p_ranging_results->RangeDMaxMilliMeter = 0; } |
sepp_nepp | 11:c6f95a42d4d7 | 1851 | |
sepp_nepp | 11:c6f95a42d4d7 | 1852 | /* fill the Limit Check ErrState */ |
sepp_nepp | 11:c6f95a42d4d7 | 1853 | signal_rate_final_range_limit_chk_en = Get_limit_chk_en(VL53L0X_CHECKEN_SIG_RATE_FINAL_RANGE); |
sepp_nepp | 11:c6f95a42d4d7 | 1854 | |
sepp_nepp | 11:c6f95a42d4d7 | 1855 | if (ErrState == VL53L0X_OK) { |
sepp_nepp | 11:c6f95a42d4d7 | 1856 | if ((sigma_limit_chk_en == 0) || (sigma_limitflag == 1)) |
sepp_nepp | 11:c6f95a42d4d7 | 1857 | { temp8 = 1; } else { temp8 = 0; } |
sepp_nepp | 11:c6f95a42d4d7 | 1858 | CurrParams.LimitChecksStatus[VL53L0X_CHECKEN_SIGMA_FINAL_RANGE] = temp8; |
sepp_nepp | 11:c6f95a42d4d7 | 1859 | |
sepp_nepp | 11:c6f95a42d4d7 | 1860 | if ((device_range_status_internal == 4) || (signal_rate_final_range_limit_chk_en == 0)) |
sepp_nepp | 11:c6f95a42d4d7 | 1861 | { temp8 = 1; } else { temp8 = 0; } |
sepp_nepp | 11:c6f95a42d4d7 | 1862 | CurrParams.LimitChecksStatus[VL53L0X_CHECKEN_SIG_RATE_FINAL_RANGE] = temp8; |
sepp_nepp | 11:c6f95a42d4d7 | 1863 | |
sepp_nepp | 11:c6f95a42d4d7 | 1864 | if ((signal_Ref_clip_limit_chk_en == 0) || (signal_Ref_clipflag == 1)) |
sepp_nepp | 11:c6f95a42d4d7 | 1865 | { temp8 = 1; } else { temp8 = 0; } |
sepp_nepp | 11:c6f95a42d4d7 | 1866 | CurrParams.LimitChecksStatus[VL53L0X_CHECKEN_SIG_REF_CLIP] = temp8; |
sepp_nepp | 11:c6f95a42d4d7 | 1867 | |
sepp_nepp | 11:c6f95a42d4d7 | 1868 | if ((range_ignore_threshold_chk_en == 0) || (range_ignore_thresholdflag == 1)) |
sepp_nepp | 11:c6f95a42d4d7 | 1869 | { temp8 = 1; } else { temp8 = 0;} |
sepp_nepp | 11:c6f95a42d4d7 | 1870 | CurrParams.LimitChecksStatus[VL53L0X_CHECKEN_RANGE_IGNORE_THRESHOLD] = temp8; |
Davidroid | 3:e9269ff624ed | 1871 | } |
nikapov | 0:a1a69d32f310 | 1872 | } |
nikapov | 0:a1a69d32f310 | 1873 | |
sepp_nepp | 11:c6f95a42d4d7 | 1874 | void VL53L0X::Get_ranging_results(TRangeResults *p_ranging_results) |
sepp_nepp | 11:c6f95a42d4d7 | 1875 | { uint8_t device_range_status; |
nikapov | 0:a1a69d32f310 | 1876 | uint8_t range_fractional_enable; |
sepp_nepp | 11:c6f95a42d4d7 | 1877 | uint8_t Device_range_status; |
sepp_nepp | 11:c6f95a42d4d7 | 1878 | uint8_t xtalk_compensation_enable; |
nikapov | 0:a1a69d32f310 | 1879 | uint16_t ambient_rate; |
sepp_nepp | 11:c6f95a42d4d7 | 1880 | TFP1616 signal_rate; |
sepp_nepp | 11:c6f95a42d4d7 | 1881 | uint16_t Xtalk_CompRate_MHz; |
sepp_nepp | 11:c6f95a42d4d7 | 1882 | uint16_t effective_SPAD_rtn_count; |
nikapov | 0:a1a69d32f310 | 1883 | uint16_t tmpuint16; |
nikapov | 0:a1a69d32f310 | 1884 | uint16_t xtalk_range_milli_meter; |
nikapov | 0:a1a69d32f310 | 1885 | uint16_t linearity_corrective_gain; |
nikapov | 0:a1a69d32f310 | 1886 | uint8_t localBuffer[12]; |
sepp_nepp | 11:c6f95a42d4d7 | 1887 | TRangeResults last_range_data_buffer; |
sepp_nepp | 11:c6f95a42d4d7 | 1888 | |
sepp_nepp | 11:c6f95a42d4d7 | 1889 | if (ErrState != VL53L0X_OK) { return; } // Do nothing while in error state |
sepp_nepp | 11:c6f95a42d4d7 | 1890 | |
sepp_nepp | 11:c6f95a42d4d7 | 1891 | /* use multi read even if some registers are not useful,result will |
sepp_nepp | 11:c6f95a42d4d7 | 1892 | * be more efficient start reading at REG_RESULT_RANGE_STATUS = 0x14 |
sepp_nepp | 11:c6f95a42d4d7 | 1893 | * end reading at 0x21 dec33 total 14 bytes to read */ |
sepp_nepp | 11:c6f95a42d4d7 | 1894 | I2c_Read(REG_RESULT_RANGE_STATUS, localBuffer,12); |
sepp_nepp | 11:c6f95a42d4d7 | 1895 | |
sepp_nepp | 11:c6f95a42d4d7 | 1896 | if (ErrState == VL53L0X_OK) { |
sepp_nepp | 11:c6f95a42d4d7 | 1897 | p_ranging_results->ZoneId = 0; /* Only one zone */ |
sepp_nepp | 11:c6f95a42d4d7 | 1898 | p_ranging_results->TimeStamp = 0; /* Not Implemented */ |
nikapov | 0:a1a69d32f310 | 1899 | |
sepp_nepp | 7:41cbc431e1f4 | 1900 | tmpuint16 = VL53L0X_MAKEUINT16(localBuffer[11],localBuffer[10]); |
nikapov | 0:a1a69d32f310 | 1901 | /* cut1.1 if SYSTEM__RANGE_CONFIG if 1 range is 2bits fractional |
sepp_nepp | 11:c6f95a42d4d7 | 1902 | *(format 11.2) else no fractional */ |
sepp_nepp | 11:c6f95a42d4d7 | 1903 | |
sepp_nepp | 11:c6f95a42d4d7 | 1904 | p_ranging_results->MeasurementTimeUsec = 0; |
sepp_nepp | 11:c6f95a42d4d7 | 1905 | |
sepp_nepp | 11:c6f95a42d4d7 | 1906 | signal_rate = FP97_TO_FP1616(VL53L0X_MAKEUINT16(localBuffer[7],localBuffer[6])); |
sepp_nepp | 11:c6f95a42d4d7 | 1907 | /* peak_SIG_count_rate_rtn_mcps */ |
sepp_nepp | 11:c6f95a42d4d7 | 1908 | p_ranging_results->SignalRateRtnMHz = signal_rate; |
nikapov | 0:a1a69d32f310 | 1909 | |
sepp_nepp | 7:41cbc431e1f4 | 1910 | ambient_rate = VL53L0X_MAKEUINT16(localBuffer[9],localBuffer[8]); |
sepp_nepp | 11:c6f95a42d4d7 | 1911 | p_ranging_results->AmbientRateRtnMHz = FP97_TO_FP1616(ambient_rate); |
sepp_nepp | 11:c6f95a42d4d7 | 1912 | |
sepp_nepp | 11:c6f95a42d4d7 | 1913 | effective_SPAD_rtn_count = VL53L0X_MAKEUINT16(localBuffer[3], localBuffer[2]); |
sepp_nepp | 11:c6f95a42d4d7 | 1914 | /* EffectiveSPADRtnCount is 8.8 format */ |
sepp_nepp | 11:c6f95a42d4d7 | 1915 | p_ranging_results->EffectiveSPADRtnCount = effective_SPAD_rtn_count; |
nikapov | 0:a1a69d32f310 | 1916 | |
nikapov | 0:a1a69d32f310 | 1917 | device_range_status = localBuffer[0]; |
nikapov | 0:a1a69d32f310 | 1918 | |
nikapov | 0:a1a69d32f310 | 1919 | /* Get Linearity Corrective Gain */ |
sepp_nepp | 10:cd251e0fc2fd | 1920 | linearity_corrective_gain = LinearityCorrectiveGain; |
nikapov | 0:a1a69d32f310 | 1921 | |
nikapov | 0:a1a69d32f310 | 1922 | /* Get ranging configuration */ |
sepp_nepp | 10:cd251e0fc2fd | 1923 | range_fractional_enable = RangeFractionalEnable; |
nikapov | 0:a1a69d32f310 | 1924 | |
nikapov | 0:a1a69d32f310 | 1925 | if (linearity_corrective_gain != 1000) { |
nikapov | 0:a1a69d32f310 | 1926 | tmpuint16 = (uint16_t)((linearity_corrective_gain |
nikapov | 0:a1a69d32f310 | 1927 | * tmpuint16 + 500) / 1000); |
nikapov | 0:a1a69d32f310 | 1928 | |
nikapov | 0:a1a69d32f310 | 1929 | /* Implement Xtalk */ |
sepp_nepp | 11:c6f95a42d4d7 | 1930 | Xtalk_CompRate_MHz = CurrParams.Xtalk_CompRate_MHz; |
sepp_nepp | 11:c6f95a42d4d7 | 1931 | xtalk_compensation_enable = CurrParams.XTalk_Compens_En; |
sepp_nepp | 11:c6f95a42d4d7 | 1932 | |
sepp_nepp | 11:c6f95a42d4d7 | 1933 | if (xtalk_compensation_enable) { |
sepp_nepp | 11:c6f95a42d4d7 | 1934 | if ((signal_rate - ((Xtalk_CompRate_MHz |
sepp_nepp | 11:c6f95a42d4d7 | 1935 | * effective_SPAD_rtn_count) >> 8)) <= 0) { |
sepp_nepp | 11:c6f95a42d4d7 | 1936 | if (range_fractional_enable) { xtalk_range_milli_meter = 8888; |
sepp_nepp | 11:c6f95a42d4d7 | 1937 | } else { xtalk_range_milli_meter = 8888 << 2; } |
nikapov | 0:a1a69d32f310 | 1938 | } else { |
sepp_nepp | 11:c6f95a42d4d7 | 1939 | xtalk_range_milli_meter = (tmpuint16 * signal_rate) |
sepp_nepp | 11:c6f95a42d4d7 | 1940 | / (signal_rate - ((Xtalk_CompRate_MHz * effective_SPAD_rtn_count) >> 8)); |
nikapov | 0:a1a69d32f310 | 1941 | } |
nikapov | 0:a1a69d32f310 | 1942 | tmpuint16 = xtalk_range_milli_meter; |
nikapov | 0:a1a69d32f310 | 1943 | } |
nikapov | 0:a1a69d32f310 | 1944 | } |
nikapov | 0:a1a69d32f310 | 1945 | |
nikapov | 0:a1a69d32f310 | 1946 | if (range_fractional_enable) { |
sepp_nepp | 11:c6f95a42d4d7 | 1947 | p_ranging_results->RangeMilliMeter = (uint16_t)((tmpuint16) >> 2); |
sepp_nepp | 11:c6f95a42d4d7 | 1948 | p_ranging_results->RangeFractionalPart = |
nikapov | 0:a1a69d32f310 | 1949 | (uint8_t)((tmpuint16 & 0x03) << 6); |
nikapov | 0:a1a69d32f310 | 1950 | } else { |
sepp_nepp | 11:c6f95a42d4d7 | 1951 | p_ranging_results->RangeMilliMeter = tmpuint16; |
sepp_nepp | 11:c6f95a42d4d7 | 1952 | p_ranging_results->RangeFractionalPart = 0; |
nikapov | 0:a1a69d32f310 | 1953 | } |
nikapov | 0:a1a69d32f310 | 1954 | |
sepp_nepp | 11:c6f95a42d4d7 | 1955 | /* For a standard definition of RangeStatus,this should |
nikapov | 0:a1a69d32f310 | 1956 | * return 0 in case of good result after a ranging |
sepp_nepp | 11:c6f95a42d4d7 | 1957 | * The range ErrState depends on the device so call a device |
sepp_nepp | 11:c6f95a42d4d7 | 1958 | * specific function to obtain the right ErrState. */ |
sepp_nepp | 11:c6f95a42d4d7 | 1959 | Get_Device_range_status(device_range_status,signal_rate,effective_SPAD_rtn_count, |
sepp_nepp | 11:c6f95a42d4d7 | 1960 | p_ranging_results,&Device_range_status); |
sepp_nepp | 11:c6f95a42d4d7 | 1961 | if (ErrState == VL53L0X_OK) { |
sepp_nepp | 11:c6f95a42d4d7 | 1962 | p_ranging_results->RangeStatus = Device_range_status; |
nikapov | 0:a1a69d32f310 | 1963 | } |
nikapov | 0:a1a69d32f310 | 1964 | } |
nikapov | 0:a1a69d32f310 | 1965 | |
sepp_nepp | 11:c6f95a42d4d7 | 1966 | if (ErrState == VL53L0X_OK) { |
sepp_nepp | 11:c6f95a42d4d7 | 1967 | /* Copy last read data into device+ buffer */ |
sepp_nepp | 10:cd251e0fc2fd | 1968 | last_range_data_buffer = LastRangeMeasure; |
nikapov | 0:a1a69d32f310 | 1969 | last_range_data_buffer.RangeMilliMeter = |
sepp_nepp | 11:c6f95a42d4d7 | 1970 | p_ranging_results->RangeMilliMeter; |
nikapov | 0:a1a69d32f310 | 1971 | last_range_data_buffer.RangeFractionalPart = |
sepp_nepp | 11:c6f95a42d4d7 | 1972 | p_ranging_results->RangeFractionalPart; |
nikapov | 0:a1a69d32f310 | 1973 | last_range_data_buffer.RangeDMaxMilliMeter = |
sepp_nepp | 11:c6f95a42d4d7 | 1974 | p_ranging_results->RangeDMaxMilliMeter; |
nikapov | 0:a1a69d32f310 | 1975 | last_range_data_buffer.MeasurementTimeUsec = |
sepp_nepp | 11:c6f95a42d4d7 | 1976 | p_ranging_results->MeasurementTimeUsec; |
sepp_nepp | 11:c6f95a42d4d7 | 1977 | last_range_data_buffer.SignalRateRtnMHz = |
sepp_nepp | 11:c6f95a42d4d7 | 1978 | p_ranging_results->SignalRateRtnMHz; |
sepp_nepp | 11:c6f95a42d4d7 | 1979 | last_range_data_buffer.AmbientRateRtnMHz = |
sepp_nepp | 11:c6f95a42d4d7 | 1980 | p_ranging_results->AmbientRateRtnMHz; |
sepp_nepp | 11:c6f95a42d4d7 | 1981 | last_range_data_buffer.EffectiveSPADRtnCount = |
sepp_nepp | 11:c6f95a42d4d7 | 1982 | p_ranging_results->EffectiveSPADRtnCount; |
nikapov | 0:a1a69d32f310 | 1983 | last_range_data_buffer.RangeStatus = |
sepp_nepp | 11:c6f95a42d4d7 | 1984 | p_ranging_results->RangeStatus; |
sepp_nepp | 10:cd251e0fc2fd | 1985 | LastRangeMeasure = last_range_data_buffer; |
nikapov | 0:a1a69d32f310 | 1986 | } |
nikapov | 0:a1a69d32f310 | 1987 | } |
nikapov | 0:a1a69d32f310 | 1988 | |
sepp_nepp | 11:c6f95a42d4d7 | 1989 | void VL53L0X::Perf_single_ranging_measurement( |
sepp_nepp | 11:c6f95a42d4d7 | 1990 | TRangeResults *p_ranging_results) |
sepp_nepp | 11:c6f95a42d4d7 | 1991 | { if (ErrState != VL53L0X_OK) {return; } // no activity while in Error State!!!! |
sepp_nepp | 11:c6f95a42d4d7 | 1992 | |
sepp_nepp | 11:c6f95a42d4d7 | 1993 | /* This function will do a complete single ranging Here we fix the mode! */ |
sepp_nepp | 11:c6f95a42d4d7 | 1994 | Set_device_mode(VL53L0X_DEVICEMODE_SINGLE_RANGING); |
sepp_nepp | 11:c6f95a42d4d7 | 1995 | |
sepp_nepp | 11:c6f95a42d4d7 | 1996 | Perf_single_measurement(); |
sepp_nepp | 11:c6f95a42d4d7 | 1997 | |
sepp_nepp | 11:c6f95a42d4d7 | 1998 | Get_ranging_results(p_ranging_results); |
sepp_nepp | 11:c6f95a42d4d7 | 1999 | |
sepp_nepp | 11:c6f95a42d4d7 | 2000 | Clear_interrupt_mask(0); |
nikapov | 0:a1a69d32f310 | 2001 | } |
nikapov | 0:a1a69d32f310 | 2002 | |
sepp_nepp | 11:c6f95a42d4d7 | 2003 | uint16_t VL53L0X::Get_Perf_Ref_SIG_measurement() |
sepp_nepp | 11:c6f95a42d4d7 | 2004 | { TRangeResults ranging_results; |
sepp_nepp | 11:c6f95a42d4d7 | 2005 | uint8_t orig_sequence_config; |
sepp_nepp | 11:c6f95a42d4d7 | 2006 | uint16_t Ref_SIG_rate ; |
nikapov | 0:a1a69d32f310 | 2007 | |
nikapov | 0:a1a69d32f310 | 2008 | /* store the value of the sequence config, |
sepp_nepp | 10:cd251e0fc2fd | 2009 | * this will be reset before the end of the function*/ |
sepp_nepp | 11:c6f95a42d4d7 | 2010 | orig_sequence_config = SequenceConfig; |
sepp_nepp | 10:cd251e0fc2fd | 2011 | |
sepp_nepp | 10:cd251e0fc2fd | 2012 | /* This function performs a reference signal rate measurement.*/ |
sepp_nepp | 11:c6f95a42d4d7 | 2013 | Set_SequenceConfig( 0xC0 ); // sets REG_SYSTEM_SEQUENCE_CONFIG |
sepp_nepp | 11:c6f95a42d4d7 | 2014 | |
sepp_nepp | 11:c6f95a42d4d7 | 2015 | Perf_single_ranging_measurement(&ranging_results); |
sepp_nepp | 11:c6f95a42d4d7 | 2016 | |
sepp_nepp | 11:c6f95a42d4d7 | 2017 | Write_Byte(0xFF,0x01); |
sepp_nepp | 11:c6f95a42d4d7 | 2018 | Ref_SIG_rate = Read_Word(REG_RESULT_PEAK_SIG_RATE_REF); |
sepp_nepp | 11:c6f95a42d4d7 | 2019 | Write_Byte(0xFF,0x00); |
sepp_nepp | 11:c6f95a42d4d7 | 2020 | |
sepp_nepp | 11:c6f95a42d4d7 | 2021 | /* restore the previous Sequence Config */ |
sepp_nepp | 11:c6f95a42d4d7 | 2022 | Set_SequenceConfig( orig_sequence_config ); // resets REG_SYSTEM_SEQUENCE_CONFIG |
sepp_nepp | 11:c6f95a42d4d7 | 2023 | |
sepp_nepp | 11:c6f95a42d4d7 | 2024 | return Ref_SIG_rate; |
nikapov | 0:a1a69d32f310 | 2025 | } |
nikapov | 0:a1a69d32f310 | 2026 | |
sepp_nepp | 11:c6f95a42d4d7 | 2027 | void VL53L0X::Perf_Ref_SPAD_management(uint32_t *ref_SPAD_count, |
sepp_nepp | 11:c6f95a42d4d7 | 2028 | uint8_t *is_aperture_SPADS) |
sepp_nepp | 11:c6f95a42d4d7 | 2029 | { uint8_t last_SPAD_array[6]; |
nikapov | 0:a1a69d32f310 | 2030 | uint8_t start_select = 0xB4; |
sepp_nepp | 11:c6f95a42d4d7 | 2031 | uint32_t minimum_SPAD_count = 3; |
sepp_nepp | 11:c6f95a42d4d7 | 2032 | uint32_t max_SPAD_count = 44; |
sepp_nepp | 11:c6f95a42d4d7 | 2033 | uint32_t current_SPAD_index = 0; |
sepp_nepp | 11:c6f95a42d4d7 | 2034 | uint32_t last_SPAD_index = 0; |
sepp_nepp | 11:c6f95a42d4d7 | 2035 | int32_t next_good_SPAD = 0; |
sepp_nepp | 11:c6f95a42d4d7 | 2036 | uint16_t target_Ref_rate = 0x0A00; /* 20 MHz in 9:7 format */ |
sepp_nepp | 11:c6f95a42d4d7 | 2037 | uint16_t peak_SIG_rate_Ref; |
sepp_nepp | 11:c6f95a42d4d7 | 2038 | uint32_t need_apt_SPADS = 0; |
nikapov | 0:a1a69d32f310 | 2039 | uint32_t index = 0; |
sepp_nepp | 11:c6f95a42d4d7 | 2040 | uint32_t SPAD_array_size = 6; |
nikapov | 0:a1a69d32f310 | 2041 | uint32_t signal_rate_diff = 0; |
sepp_nepp | 11:c6f95a42d4d7 | 2042 | uint32_t last_SIG_rate_diff = 0; |
nikapov | 0:a1a69d32f310 | 2043 | uint8_t complete = 0; |
nikapov | 0:a1a69d32f310 | 2044 | uint8_t vhv_settings = 0; |
nikapov | 0:a1a69d32f310 | 2045 | uint8_t phase_cal = 0; |
sepp_nepp | 11:c6f95a42d4d7 | 2046 | uint32_t ref_SPAD_count_int = 0; |
sepp_nepp | 11:c6f95a42d4d7 | 2047 | uint8_t is_aperture_SPADS_int = 0; |
nikapov | 0:a1a69d32f310 | 2048 | |
nikapov | 0:a1a69d32f310 | 2049 | /* |
nikapov | 0:a1a69d32f310 | 2050 | * The reference SPAD initialization procedure determines the minimum |
sepp_nepp | 11:c6f95a42d4d7 | 2051 | * amount of reference SPADS to be enables to achieve a target reference |
nikapov | 0:a1a69d32f310 | 2052 | * signal rate and should be performed once during initialization. |
nikapov | 0:a1a69d32f310 | 2053 | * |
sepp_nepp | 11:c6f95a42d4d7 | 2054 | * Either aperture or non-aperture SPADS are applied but never both. |
sepp_nepp | 11:c6f95a42d4d7 | 2055 | * Firstly non-aperture SPADS are set,begining with 5 SPADS,and |
sepp_nepp | 11:c6f95a42d4d7 | 2056 | * increased one SPAD at a time until the closest measurement to the |
nikapov | 0:a1a69d32f310 | 2057 | * target rate is achieved. |
nikapov | 0:a1a69d32f310 | 2058 | * |
sepp_nepp | 11:c6f95a42d4d7 | 2059 | * If the target rate is exceeded when 5 non-aperture SPADS are enabled, |
sepp_nepp | 11:c6f95a42d4d7 | 2060 | * initialization is performed instead with aperture SPADS. |
nikapov | 0:a1a69d32f310 | 2061 | * |
sepp_nepp | 11:c6f95a42d4d7 | 2062 | * When setting SPADS,a 'Good SPAD Map' is applied. |
nikapov | 0:a1a69d32f310 | 2063 | * |
nikapov | 0:a1a69d32f310 | 2064 | * This procedure operates within a SPAD window of interest of a maximum |
sepp_nepp | 11:c6f95a42d4d7 | 2065 | * 44 SPADS. |
sepp_nepp | 7:41cbc431e1f4 | 2066 | * The start point is currently fixed to 180,which lies towards the end |
nikapov | 0:a1a69d32f310 | 2067 | * of the non-aperture quadrant and runs in to the adjacent aperture |
sepp_nepp | 11:c6f95a42d4d7 | 2068 | * quadrant. */ |
sepp_nepp | 11:c6f95a42d4d7 | 2069 | target_Ref_rate = targetRefRate; |
sepp_nepp | 11:c6f95a42d4d7 | 2070 | |
sepp_nepp | 11:c6f95a42d4d7 | 2071 | /* Initialize SPAD arrays. |
sepp_nepp | 11:c6f95a42d4d7 | 2072 | * Currently the good SPAD map is initialised to 'All good'. |
sepp_nepp | 11:c6f95a42d4d7 | 2073 | * This is a short term implementation. The good SPAD map will be |
nikapov | 0:a1a69d32f310 | 2074 | * provided as an input. |
nikapov | 0:a1a69d32f310 | 2075 | * Note that there are 6 bytes. Only the first 44 bits will be used to |
sepp_nepp | 11:c6f95a42d4d7 | 2076 | * represent SPADS. */ |
sepp_nepp | 11:c6f95a42d4d7 | 2077 | for (index = 0; index < SPAD_array_size; index++) { |
sepp_nepp | 11:c6f95a42d4d7 | 2078 | SPADData.RefSPADEnables[index] = 0; } |
sepp_nepp | 11:c6f95a42d4d7 | 2079 | |
sepp_nepp | 11:c6f95a42d4d7 | 2080 | Write_Byte(0xFF,0x01); |
sepp_nepp | 11:c6f95a42d4d7 | 2081 | Write_Byte(REG_DYNAMIC_SPAD_REF_EN_START_OFFSET,0x00); |
sepp_nepp | 11:c6f95a42d4d7 | 2082 | Write_Byte(REG_DYNAMIC_SPAD_NUM_REQUESTED_REF_SPAD,0x2C); |
sepp_nepp | 11:c6f95a42d4d7 | 2083 | Write_Byte(0xFF,0x00); |
sepp_nepp | 11:c6f95a42d4d7 | 2084 | Write_Byte(REG_GLOBAL_CONFIG_REF_EN_START_SELECT,start_select); |
sepp_nepp | 11:c6f95a42d4d7 | 2085 | Write_Byte(REG_POWER_MANAGEMENT_GO1_POWER_FORCE,0); |
nikapov | 0:a1a69d32f310 | 2086 | |
nikapov | 0:a1a69d32f310 | 2087 | /* Perform ref calibration */ |
sepp_nepp | 11:c6f95a42d4d7 | 2088 | if (ErrState == VL53L0X_OK) |
sepp_nepp | 11:c6f95a42d4d7 | 2089 | {Perf_Ref_calibration(&vhv_settings, &phase_cal, 0);} |
sepp_nepp | 11:c6f95a42d4d7 | 2090 | |
sepp_nepp | 11:c6f95a42d4d7 | 2091 | if (ErrState == VL53L0X_OK) { |
sepp_nepp | 11:c6f95a42d4d7 | 2092 | /* Enable Minimum NON-APERTURE SPADS */ |
sepp_nepp | 11:c6f95a42d4d7 | 2093 | current_SPAD_index = 0; |
sepp_nepp | 11:c6f95a42d4d7 | 2094 | last_SPAD_index = current_SPAD_index; |
sepp_nepp | 11:c6f95a42d4d7 | 2095 | need_apt_SPADS = 0; |
sepp_nepp | 11:c6f95a42d4d7 | 2096 | Enable_Ref_SPADS(need_apt_SPADS, |
sepp_nepp | 11:c6f95a42d4d7 | 2097 | SPADData.RefGoodSPADMap, |
sepp_nepp | 11:c6f95a42d4d7 | 2098 | SPADData.RefSPADEnables, |
sepp_nepp | 11:c6f95a42d4d7 | 2099 | SPAD_array_size, |
nikapov | 0:a1a69d32f310 | 2100 | start_select, |
sepp_nepp | 11:c6f95a42d4d7 | 2101 | current_SPAD_index, |
sepp_nepp | 11:c6f95a42d4d7 | 2102 | minimum_SPAD_count, |
sepp_nepp | 11:c6f95a42d4d7 | 2103 | &last_SPAD_index); |
nikapov | 0:a1a69d32f310 | 2104 | } |
nikapov | 0:a1a69d32f310 | 2105 | |
sepp_nepp | 11:c6f95a42d4d7 | 2106 | if (ErrState == VL53L0X_OK) { |
sepp_nepp | 11:c6f95a42d4d7 | 2107 | current_SPAD_index = last_SPAD_index; |
sepp_nepp | 11:c6f95a42d4d7 | 2108 | |
sepp_nepp | 11:c6f95a42d4d7 | 2109 | peak_SIG_rate_Ref = Get_Perf_Ref_SIG_measurement(); |
sepp_nepp | 11:c6f95a42d4d7 | 2110 | if ((ErrState == VL53L0X_OK) && (peak_SIG_rate_Ref > target_Ref_rate)) |
sepp_nepp | 11:c6f95a42d4d7 | 2111 | { /* Signal rate measurement too high, switch to APERTURE SPADS */ |
sepp_nepp | 11:c6f95a42d4d7 | 2112 | for (index = 0; index < SPAD_array_size; index++) |
sepp_nepp | 11:c6f95a42d4d7 | 2113 | { SPADData.RefSPADEnables[index] = 0; } |
sepp_nepp | 11:c6f95a42d4d7 | 2114 | |
sepp_nepp | 11:c6f95a42d4d7 | 2115 | /* Increment to the first APERTURE SPAD */ |
sepp_nepp | 11:c6f95a42d4d7 | 2116 | while ((Is_ApertureSPAD(start_select + current_SPAD_index) |
sepp_nepp | 11:c6f95a42d4d7 | 2117 | == 0) && (current_SPAD_index < max_SPAD_count)) |
sepp_nepp | 11:c6f95a42d4d7 | 2118 | { current_SPAD_index++; } |
sepp_nepp | 11:c6f95a42d4d7 | 2119 | |
sepp_nepp | 11:c6f95a42d4d7 | 2120 | need_apt_SPADS = 1; |
sepp_nepp | 11:c6f95a42d4d7 | 2121 | |
sepp_nepp | 11:c6f95a42d4d7 | 2122 | Enable_Ref_SPADS(need_apt_SPADS, |
sepp_nepp | 11:c6f95a42d4d7 | 2123 | SPADData.RefGoodSPADMap, |
sepp_nepp | 11:c6f95a42d4d7 | 2124 | SPADData.RefSPADEnables, |
sepp_nepp | 11:c6f95a42d4d7 | 2125 | SPAD_array_size, |
nikapov | 0:a1a69d32f310 | 2126 | start_select, |
sepp_nepp | 11:c6f95a42d4d7 | 2127 | current_SPAD_index, |
sepp_nepp | 11:c6f95a42d4d7 | 2128 | minimum_SPAD_count, |
sepp_nepp | 11:c6f95a42d4d7 | 2129 | &last_SPAD_index); |
sepp_nepp | 11:c6f95a42d4d7 | 2130 | |
sepp_nepp | 11:c6f95a42d4d7 | 2131 | if (ErrState == VL53L0X_OK) { |
sepp_nepp | 11:c6f95a42d4d7 | 2132 | current_SPAD_index = last_SPAD_index; |
sepp_nepp | 11:c6f95a42d4d7 | 2133 | peak_SIG_rate_Ref = Get_Perf_Ref_SIG_measurement(); |
sepp_nepp | 11:c6f95a42d4d7 | 2134 | |
sepp_nepp | 11:c6f95a42d4d7 | 2135 | if ((ErrState == VL53L0X_OK) && (peak_SIG_rate_Ref > target_Ref_rate)) |
sepp_nepp | 11:c6f95a42d4d7 | 2136 | { /* Signal rate still too high after setting the minimum number of |
sepp_nepp | 11:c6f95a42d4d7 | 2137 | * APERTURE SPADS. Can do no more therefore set the min number of |
sepp_nepp | 11:c6f95a42d4d7 | 2138 | * aperture SPADS as the result. */ |
sepp_nepp | 11:c6f95a42d4d7 | 2139 | is_aperture_SPADS_int = 1; |
sepp_nepp | 11:c6f95a42d4d7 | 2140 | ref_SPAD_count_int = minimum_SPAD_count; |
nikapov | 0:a1a69d32f310 | 2141 | } |
nikapov | 0:a1a69d32f310 | 2142 | } |
sepp_nepp | 11:c6f95a42d4d7 | 2143 | } else { need_apt_SPADS = 0;} |
nikapov | 0:a1a69d32f310 | 2144 | } |
nikapov | 0:a1a69d32f310 | 2145 | |
sepp_nepp | 11:c6f95a42d4d7 | 2146 | if ((ErrState == VL53L0X_OK) && (peak_SIG_rate_Ref < target_Ref_rate)) |
sepp_nepp | 11:c6f95a42d4d7 | 2147 | { /* At this point,the minimum number of either aperture |
sepp_nepp | 11:c6f95a42d4d7 | 2148 | * or non-aperture SPADS have been set. Proceed to add |
sepp_nepp | 11:c6f95a42d4d7 | 2149 | * SPADS and perform measurements until the target reference is reached.*/ |
sepp_nepp | 11:c6f95a42d4d7 | 2150 | is_aperture_SPADS_int = need_apt_SPADS; |
sepp_nepp | 11:c6f95a42d4d7 | 2151 | ref_SPAD_count_int = minimum_SPAD_count; |
sepp_nepp | 11:c6f95a42d4d7 | 2152 | |
sepp_nepp | 11:c6f95a42d4d7 | 2153 | memcpy(last_SPAD_array,SPADData.RefSPADEnables, SPAD_array_size); |
sepp_nepp | 11:c6f95a42d4d7 | 2154 | last_SIG_rate_diff = abs(peak_SIG_rate_Ref - target_Ref_rate); |
nikapov | 0:a1a69d32f310 | 2155 | complete = 0; |
nikapov | 0:a1a69d32f310 | 2156 | |
nikapov | 0:a1a69d32f310 | 2157 | while (!complete) { |
sepp_nepp | 11:c6f95a42d4d7 | 2158 | Get_Next_Good_SPAD(SPADData.RefGoodSPADMap, |
sepp_nepp | 11:c6f95a42d4d7 | 2159 | SPAD_array_size,current_SPAD_index, &next_good_SPAD); |
sepp_nepp | 11:c6f95a42d4d7 | 2160 | |
sepp_nepp | 11:c6f95a42d4d7 | 2161 | if (next_good_SPAD == -1) { |
sepp_nepp | 11:c6f95a42d4d7 | 2162 | ErrState = VL53L0X_ERROR_REF_SPAD_INIT; |
nikapov | 0:a1a69d32f310 | 2163 | break; |
nikapov | 0:a1a69d32f310 | 2164 | } |
nikapov | 0:a1a69d32f310 | 2165 | |
sepp_nepp | 11:c6f95a42d4d7 | 2166 | /* Cannot combine Aperture and Non-Aperture SPADS,so |
sepp_nepp | 11:c6f95a42d4d7 | 2167 | * ensure the current SPAD is of the correct type. */ |
sepp_nepp | 11:c6f95a42d4d7 | 2168 | if (Is_ApertureSPAD((uint32_t)start_select + next_good_SPAD) != |
sepp_nepp | 11:c6f95a42d4d7 | 2169 | need_apt_SPADS) { |
sepp_nepp | 11:c6f95a42d4d7 | 2170 | /* At this point we have enabled the maximum number of Aperture SPADS. */ |
nikapov | 0:a1a69d32f310 | 2171 | complete = 1; |
nikapov | 0:a1a69d32f310 | 2172 | break; |
nikapov | 0:a1a69d32f310 | 2173 | } |
nikapov | 0:a1a69d32f310 | 2174 | |
sepp_nepp | 11:c6f95a42d4d7 | 2175 | (ref_SPAD_count_int)++; |
sepp_nepp | 11:c6f95a42d4d7 | 2176 | |
sepp_nepp | 11:c6f95a42d4d7 | 2177 | current_SPAD_index = next_good_SPAD; |
sepp_nepp | 11:c6f95a42d4d7 | 2178 | Enable_SPAD_bit(SPADData.RefSPADEnables, |
sepp_nepp | 11:c6f95a42d4d7 | 2179 | SPAD_array_size,current_SPAD_index); |
sepp_nepp | 11:c6f95a42d4d7 | 2180 | |
sepp_nepp | 11:c6f95a42d4d7 | 2181 | if (ErrState == VL53L0X_OK) { |
sepp_nepp | 11:c6f95a42d4d7 | 2182 | current_SPAD_index++; |
sepp_nepp | 11:c6f95a42d4d7 | 2183 | /* Proceed to apply the additional SPAD and perform measurement. */ |
sepp_nepp | 11:c6f95a42d4d7 | 2184 | I2c_Write(REG_GLOBAL_CONFIG_SPAD_ENABLES_REF_0, SPADData.RefSPADEnables,6); //Set_Ref_SPAD_map |
nikapov | 0:a1a69d32f310 | 2185 | } |
nikapov | 0:a1a69d32f310 | 2186 | |
sepp_nepp | 11:c6f95a42d4d7 | 2187 | if (ErrState != VL53L0X_OK) { break; } |
sepp_nepp | 11:c6f95a42d4d7 | 2188 | |
sepp_nepp | 11:c6f95a42d4d7 | 2189 | peak_SIG_rate_Ref = Get_Perf_Ref_SIG_measurement(); |
sepp_nepp | 11:c6f95a42d4d7 | 2190 | |
sepp_nepp | 11:c6f95a42d4d7 | 2191 | if (ErrState != VL53L0X_OK) { break; } |
sepp_nepp | 11:c6f95a42d4d7 | 2192 | |
sepp_nepp | 11:c6f95a42d4d7 | 2193 | signal_rate_diff = abs(peak_SIG_rate_Ref - target_Ref_rate); |
sepp_nepp | 11:c6f95a42d4d7 | 2194 | |
sepp_nepp | 11:c6f95a42d4d7 | 2195 | if (peak_SIG_rate_Ref > target_Ref_rate) { |
sepp_nepp | 11:c6f95a42d4d7 | 2196 | /* Select the SPAD map that provides the |
nikapov | 0:a1a69d32f310 | 2197 | * measurement closest to the target rate, |
sepp_nepp | 11:c6f95a42d4d7 | 2198 | * either above or below it. */ |
sepp_nepp | 11:c6f95a42d4d7 | 2199 | if (signal_rate_diff > last_SIG_rate_diff) { |
sepp_nepp | 11:c6f95a42d4d7 | 2200 | /* Previous SPAD map produced a closer measurement,so choose this. */ |
sepp_nepp | 11:c6f95a42d4d7 | 2201 | I2c_Write(REG_GLOBAL_CONFIG_SPAD_ENABLES_REF_0, last_SPAD_array,6); // Set_Ref_SPAD_map(); |
sepp_nepp | 11:c6f95a42d4d7 | 2202 | memcpy(SPADData.RefSPADEnables,last_SPAD_array,SPAD_array_size); |
sepp_nepp | 11:c6f95a42d4d7 | 2203 | (ref_SPAD_count_int)--; |
nikapov | 0:a1a69d32f310 | 2204 | } |
nikapov | 0:a1a69d32f310 | 2205 | complete = 1; |
nikapov | 0:a1a69d32f310 | 2206 | } else { |
sepp_nepp | 11:c6f95a42d4d7 | 2207 | /* Continue to add SPADS */ |
sepp_nepp | 11:c6f95a42d4d7 | 2208 | last_SIG_rate_diff = signal_rate_diff; |
sepp_nepp | 11:c6f95a42d4d7 | 2209 | memcpy(last_SPAD_array, SPADData.RefSPADEnables,SPAD_array_size); |
nikapov | 0:a1a69d32f310 | 2210 | } |
nikapov | 0:a1a69d32f310 | 2211 | } /* while */ |
nikapov | 0:a1a69d32f310 | 2212 | } |
nikapov | 0:a1a69d32f310 | 2213 | |
sepp_nepp | 11:c6f95a42d4d7 | 2214 | if (ErrState == VL53L0X_OK) { |
sepp_nepp | 11:c6f95a42d4d7 | 2215 | *ref_SPAD_count = ref_SPAD_count_int; |
sepp_nepp | 11:c6f95a42d4d7 | 2216 | *is_aperture_SPADS = is_aperture_SPADS_int; |
sepp_nepp | 11:c6f95a42d4d7 | 2217 | DevSpecParams.RefSPADSInitialised = 1; |
sepp_nepp | 11:c6f95a42d4d7 | 2218 | DevSpecParams.ReferenceSPADCount = (uint8_t)(*ref_SPAD_count); |
sepp_nepp | 11:c6f95a42d4d7 | 2219 | DevSpecParams.ReferenceSPADType = *is_aperture_SPADS; |
nikapov | 0:a1a69d32f310 | 2220 | } |
nikapov | 0:a1a69d32f310 | 2221 | } |
nikapov | 0:a1a69d32f310 | 2222 | |
sepp_nepp | 11:c6f95a42d4d7 | 2223 | void VL53L0X::Set_Reference_SPADS(uint32_t count,uint8_t is_aperture_SPADS) |
sepp_nepp | 11:c6f95a42d4d7 | 2224 | { uint32_t current_SPAD_index = 0; |
sepp_nepp | 11:c6f95a42d4d7 | 2225 | uint8_t start_select = 0xB4; |
sepp_nepp | 11:c6f95a42d4d7 | 2226 | uint32_t SPAD_array_size = 6; |
sepp_nepp | 11:c6f95a42d4d7 | 2227 | uint32_t max_SPAD_count = 44; |
sepp_nepp | 11:c6f95a42d4d7 | 2228 | uint32_t last_SPAD_index; |
nikapov | 0:a1a69d32f310 | 2229 | uint32_t index; |
nikapov | 0:a1a69d32f310 | 2230 | |
sepp_nepp | 11:c6f95a42d4d7 | 2231 | /* This function applies a requested number of reference SPADS,either |
sepp_nepp | 11:c6f95a42d4d7 | 2232 | * aperture or non-aperture,as requested. The good SPAD map will be applied.*/ |
sepp_nepp | 11:c6f95a42d4d7 | 2233 | Write_Byte(0xFF,0x01); |
sepp_nepp | 11:c6f95a42d4d7 | 2234 | Write_Byte(REG_DYNAMIC_SPAD_REF_EN_START_OFFSET,0x00); |
sepp_nepp | 11:c6f95a42d4d7 | 2235 | Write_Byte(REG_DYNAMIC_SPAD_NUM_REQUESTED_REF_SPAD,0x2C); |
sepp_nepp | 11:c6f95a42d4d7 | 2236 | Write_Byte(0xFF,0x00); |
sepp_nepp | 11:c6f95a42d4d7 | 2237 | Write_Byte(REG_GLOBAL_CONFIG_REF_EN_START_SELECT, start_select); |
sepp_nepp | 11:c6f95a42d4d7 | 2238 | |
sepp_nepp | 11:c6f95a42d4d7 | 2239 | for (index = 0; index < SPAD_array_size; index++) { |
sepp_nepp | 11:c6f95a42d4d7 | 2240 | SPADData.RefSPADEnables[index] = 0; } |
sepp_nepp | 11:c6f95a42d4d7 | 2241 | |
sepp_nepp | 11:c6f95a42d4d7 | 2242 | if (is_aperture_SPADS) { |
sepp_nepp | 11:c6f95a42d4d7 | 2243 | /* Increment to the first APERTURE SPAD */ |
sepp_nepp | 11:c6f95a42d4d7 | 2244 | while ((Is_ApertureSPAD(start_select + current_SPAD_index) == 0) && |
sepp_nepp | 11:c6f95a42d4d7 | 2245 | (current_SPAD_index < max_SPAD_count)) { |
sepp_nepp | 11:c6f95a42d4d7 | 2246 | current_SPAD_index++; |
nikapov | 0:a1a69d32f310 | 2247 | } |
nikapov | 0:a1a69d32f310 | 2248 | } |
sepp_nepp | 11:c6f95a42d4d7 | 2249 | Enable_Ref_SPADS(is_aperture_SPADS, |
sepp_nepp | 11:c6f95a42d4d7 | 2250 | SPADData.RefGoodSPADMap, |
sepp_nepp | 11:c6f95a42d4d7 | 2251 | SPADData.RefSPADEnables, |
sepp_nepp | 11:c6f95a42d4d7 | 2252 | SPAD_array_size, |
nikapov | 0:a1a69d32f310 | 2253 | start_select, |
sepp_nepp | 11:c6f95a42d4d7 | 2254 | current_SPAD_index, |
nikapov | 0:a1a69d32f310 | 2255 | count, |
sepp_nepp | 11:c6f95a42d4d7 | 2256 | &last_SPAD_index); |
sepp_nepp | 11:c6f95a42d4d7 | 2257 | |
sepp_nepp | 11:c6f95a42d4d7 | 2258 | if (ErrState == VL53L0X_OK) { |
sepp_nepp | 11:c6f95a42d4d7 | 2259 | DevSpecParams.RefSPADSInitialised = 1; |
sepp_nepp | 11:c6f95a42d4d7 | 2260 | DevSpecParams.ReferenceSPADCount = (uint8_t)(count); |
sepp_nepp | 11:c6f95a42d4d7 | 2261 | DevSpecParams.ReferenceSPADType = is_aperture_SPADS; |
nikapov | 0:a1a69d32f310 | 2262 | } |
nikapov | 0:a1a69d32f310 | 2263 | } |
nikapov | 0:a1a69d32f310 | 2264 | |
sepp_nepp | 11:c6f95a42d4d7 | 2265 | void VL53L0X::Set_GPIO_config(VL53L0X_DeviceModes device_mode, |
sepp_nepp | 11:c6f95a42d4d7 | 2266 | TGPIO_Func functionality, VL53L0X_InterruptPolarity polarity) |
sepp_nepp | 11:c6f95a42d4d7 | 2267 | { uint8_t pol_data; |
sepp_nepp | 11:c6f95a42d4d7 | 2268 | |
sepp_nepp | 11:c6f95a42d4d7 | 2269 | if (polarity == VL53L0X_INTERRUPTPOLARITY_LOW) |
sepp_nepp | 11:c6f95a42d4d7 | 2270 | { pol_data = 0x00;} else { pol_data = 0x10;} |
sepp_nepp | 11:c6f95a42d4d7 | 2271 | |
sepp_nepp | 11:c6f95a42d4d7 | 2272 | switch ( device_mode ) { |
sepp_nepp | 11:c6f95a42d4d7 | 2273 | case VL53L0X_DEVICEMODE_GPIO_DRIVE: |
sepp_nepp | 11:c6f95a42d4d7 | 2274 | Write_Byte(REG_GPIO_HV_MUX_ACTIVE_HIGH,pol_data); |
sepp_nepp | 11:c6f95a42d4d7 | 2275 | break; |
sepp_nepp | 11:c6f95a42d4d7 | 2276 | case VL53L0X_DEVICEMODE_GPIO_OSC: |
sepp_nepp | 11:c6f95a42d4d7 | 2277 | Write_Byte(0xff,0x01); |
sepp_nepp | 11:c6f95a42d4d7 | 2278 | Write_Byte(0x00,0x00); |
sepp_nepp | 11:c6f95a42d4d7 | 2279 | Write_Byte(0xff,0x00); |
sepp_nepp | 11:c6f95a42d4d7 | 2280 | Write_Byte(0x80,0x01); |
sepp_nepp | 11:c6f95a42d4d7 | 2281 | Write_Byte(0x85,0x02); |
sepp_nepp | 11:c6f95a42d4d7 | 2282 | Write_Byte(0xff,0x04); |
sepp_nepp | 11:c6f95a42d4d7 | 2283 | Write_Byte(0xcd,0x00); |
sepp_nepp | 11:c6f95a42d4d7 | 2284 | Write_Byte(0xcc,0x11); |
sepp_nepp | 11:c6f95a42d4d7 | 2285 | Write_Byte(0xff,0x07); |
sepp_nepp | 11:c6f95a42d4d7 | 2286 | Write_Byte(0xbe,0x00); |
sepp_nepp | 11:c6f95a42d4d7 | 2287 | Write_Byte(0xff,0x06); |
sepp_nepp | 11:c6f95a42d4d7 | 2288 | Write_Byte(0xcc,0x09); |
sepp_nepp | 11:c6f95a42d4d7 | 2289 | Write_Byte(0xff,0x00); |
sepp_nepp | 11:c6f95a42d4d7 | 2290 | Write_Byte(0xff,0x01); |
sepp_nepp | 11:c6f95a42d4d7 | 2291 | Write_Byte(0x00,0x00); |
sepp_nepp | 11:c6f95a42d4d7 | 2292 | break; |
sepp_nepp | 11:c6f95a42d4d7 | 2293 | default: |
sepp_nepp | 11:c6f95a42d4d7 | 2294 | if (functionality>GPIO_FUNC_NEW_MEASURE_READY) |
sepp_nepp | 11:c6f95a42d4d7 | 2295 | { ErrState = VL53L0X_ERROR_GPIO_FUNC_NOT_SUPPORTED; } |
sepp_nepp | 11:c6f95a42d4d7 | 2296 | else { Write_Byte(REG_SYSINT_CONFIG_GPIO,functionality); } |
sepp_nepp | 11:c6f95a42d4d7 | 2297 | |
sepp_nepp | 11:c6f95a42d4d7 | 2298 | if (ErrState == VL53L0X_OK) |
sepp_nepp | 11:c6f95a42d4d7 | 2299 | { Register_BitMask(REG_GPIO_HV_MUX_ACTIVE_HIGH,0xEF,pol_data); } |
sepp_nepp | 11:c6f95a42d4d7 | 2300 | |
sepp_nepp | 11:c6f95a42d4d7 | 2301 | if (ErrState == VL53L0X_OK) |
sepp_nepp | 11:c6f95a42d4d7 | 2302 | {DevSpecParams.GpioFunctionality = functionality; } |
sepp_nepp | 11:c6f95a42d4d7 | 2303 | |
sepp_nepp | 11:c6f95a42d4d7 | 2304 | Clear_interrupt_mask(0); |
sepp_nepp | 11:c6f95a42d4d7 | 2305 | } // switch |
sepp_nepp | 11:c6f95a42d4d7 | 2306 | } // Set_GPIO_config |
sepp_nepp | 11:c6f95a42d4d7 | 2307 | |
sepp_nepp | 11:c6f95a42d4d7 | 2308 | /* Encode timeout in macro periods in (LSByte * 2^MSByte) + 1 format */ |
sepp_nepp | 11:c6f95a42d4d7 | 2309 | uint16_t VL53L0X::Encode_timeout(uint32_t timeout_macro_clks) |
sepp_nepp | 11:c6f95a42d4d7 | 2310 | { uint16_t encoded_timeout = 0; |
nikapov | 0:a1a69d32f310 | 2311 | uint16_t ms_byte = 0; |
nikapov | 0:a1a69d32f310 | 2312 | |
nikapov | 0:a1a69d32f310 | 2313 | if (timeout_macro_clks > 0) { |
sepp_nepp | 11:c6f95a42d4d7 | 2314 | timeout_macro_clks = timeout_macro_clks - 1; |
sepp_nepp | 11:c6f95a42d4d7 | 2315 | while ((timeout_macro_clks & 0xFFFFFF00) > 0) { |
sepp_nepp | 11:c6f95a42d4d7 | 2316 | timeout_macro_clks = timeout_macro_clks >> 1; |
nikapov | 0:a1a69d32f310 | 2317 | ms_byte++; |
sepp_nepp | 11:c6f95a42d4d7 | 2318 | } // while |
sepp_nepp | 11:c6f95a42d4d7 | 2319 | encoded_timeout = (ms_byte << 8) + (uint16_t)(timeout_macro_clks & 0x000000FF); |
sepp_nepp | 11:c6f95a42d4d7 | 2320 | } |
nikapov | 0:a1a69d32f310 | 2321 | return encoded_timeout; |
nikapov | 0:a1a69d32f310 | 2322 | } |
nikapov | 0:a1a69d32f310 | 2323 | |
sepp_nepp | 11:c6f95a42d4d7 | 2324 | void VL53L0X::Set_Sequence_Step_Timeout(VL53L0X_SequenceStepId sequence_step_id, |
nikapov | 0:a1a69d32f310 | 2325 | uint32_t timeout_micro_secs) |
sepp_nepp | 11:c6f95a42d4d7 | 2326 | { uint8_t current_vcsel_PPeriod_p_clk; |
nikapov | 0:a1a69d32f310 | 2327 | uint8_t msrc_encoded_time_out; |
nikapov | 0:a1a69d32f310 | 2328 | uint16_t pre_range_encoded_time_out; |
nikapov | 0:a1a69d32f310 | 2329 | uint16_t pre_range_time_out_m_clks; |
nikapov | 0:a1a69d32f310 | 2330 | uint16_t msrc_range_time_out_m_clks; |
nikapov | 0:a1a69d32f310 | 2331 | uint32_t final_range_time_out_m_clks; |
nikapov | 0:a1a69d32f310 | 2332 | uint16_t final_range_encoded_time_out; |
sepp_nepp | 11:c6f95a42d4d7 | 2333 | VL53L0X_Sequence_Steps_t sequence_steps; |
sepp_nepp | 11:c6f95a42d4d7 | 2334 | |
sepp_nepp | 11:c6f95a42d4d7 | 2335 | switch (sequence_step_id) { |
sepp_nepp | 11:c6f95a42d4d7 | 2336 | case VL53L0X_SEQUENCESTEP_TCC: |
sepp_nepp | 11:c6f95a42d4d7 | 2337 | case VL53L0X_SEQUENCESTEP_DSS: |
sepp_nepp | 11:c6f95a42d4d7 | 2338 | case VL53L0X_SEQUENCESTEP_MSRC: |
sepp_nepp | 11:c6f95a42d4d7 | 2339 | current_vcsel_PPeriod_p_clk = /* Gets and converts the VCSEL period register into actual clock periods */ |
sepp_nepp | 11:c6f95a42d4d7 | 2340 | ( Read_Byte(REG_PRE_RANGE_CONFIG_VCSEL_PERIOD) + 1) << 1; |
sepp_nepp | 11:c6f95a42d4d7 | 2341 | |
sepp_nepp | 11:c6f95a42d4d7 | 2342 | if (ErrState == VL53L0X_OK) { |
sepp_nepp | 11:c6f95a42d4d7 | 2343 | msrc_range_time_out_m_clks = Calc_timeout_mclks(timeout_micro_secs, |
sepp_nepp | 11:c6f95a42d4d7 | 2344 | (uint8_t)current_vcsel_PPeriod_p_clk); |
sepp_nepp | 11:c6f95a42d4d7 | 2345 | |
sepp_nepp | 11:c6f95a42d4d7 | 2346 | if (msrc_range_time_out_m_clks > 256) { msrc_encoded_time_out = 255;} |
sepp_nepp | 11:c6f95a42d4d7 | 2347 | else {msrc_encoded_time_out = (uint8_t)msrc_range_time_out_m_clks - 1; } |
nikapov | 0:a1a69d32f310 | 2348 | |
sepp_nepp | 10:cd251e0fc2fd | 2349 | DevSpecParams.LastEncodedTimeout = msrc_encoded_time_out; |
sepp_nepp | 11:c6f95a42d4d7 | 2350 | } |
sepp_nepp | 11:c6f95a42d4d7 | 2351 | Write_Byte(REG_MSRC_CONFIG_TIMEOUT_MACROP,msrc_encoded_time_out); |
sepp_nepp | 11:c6f95a42d4d7 | 2352 | break; |
sepp_nepp | 11:c6f95a42d4d7 | 2353 | |
sepp_nepp | 11:c6f95a42d4d7 | 2354 | case VL53L0X_SEQUENCESTEP_PRE_RANGE: |
sepp_nepp | 11:c6f95a42d4d7 | 2355 | current_vcsel_PPeriod_p_clk = /* Gets and converts the VCSEL period register into actual clock periods */ |
sepp_nepp | 11:c6f95a42d4d7 | 2356 | ( Read_Byte(REG_PRE_RANGE_CONFIG_VCSEL_PERIOD) + 1) << 1; |
sepp_nepp | 11:c6f95a42d4d7 | 2357 | |
sepp_nepp | 11:c6f95a42d4d7 | 2358 | pre_range_time_out_m_clks = Calc_timeout_mclks(timeout_micro_secs, |
sepp_nepp | 11:c6f95a42d4d7 | 2359 | (uint8_t)current_vcsel_PPeriod_p_clk); |
sepp_nepp | 11:c6f95a42d4d7 | 2360 | pre_range_encoded_time_out = Encode_timeout(pre_range_time_out_m_clks); |
sepp_nepp | 11:c6f95a42d4d7 | 2361 | |
sepp_nepp | 11:c6f95a42d4d7 | 2362 | DevSpecParams.LastEncodedTimeout = pre_range_encoded_time_out; |
sepp_nepp | 11:c6f95a42d4d7 | 2363 | |
sepp_nepp | 11:c6f95a42d4d7 | 2364 | Write_Word(REG_PRE_RANGE_CONFIG_TIMEOUT_MACROP_HI,pre_range_encoded_time_out); |
sepp_nepp | 11:c6f95a42d4d7 | 2365 | |
sepp_nepp | 11:c6f95a42d4d7 | 2366 | if (ErrState == VL53L0X_OK) |
sepp_nepp | 11:c6f95a42d4d7 | 2367 | {DevSpecParams.PreRangeTimeoutMicroSecs=timeout_micro_secs; } |
sepp_nepp | 11:c6f95a42d4d7 | 2368 | break; |
sepp_nepp | 11:c6f95a42d4d7 | 2369 | |
sepp_nepp | 11:c6f95a42d4d7 | 2370 | case VL53L0X_SEQUENCESTEP_FINAL_RANGE: |
sepp_nepp | 11:c6f95a42d4d7 | 2371 | /* For the final range timeout,the pre-range timeout must be added. |
sepp_nepp | 11:c6f95a42d4d7 | 2372 | * To do this both final and pre-range timeouts must be expressed in |
sepp_nepp | 11:c6f95a42d4d7 | 2373 | * macro periods MClks because they have different vcsel periods.*/ |
sepp_nepp | 11:c6f95a42d4d7 | 2374 | sequence_steps = Get_sequence_step_enables(); |
nikapov | 0:a1a69d32f310 | 2375 | pre_range_time_out_m_clks = 0; |
sepp_nepp | 11:c6f95a42d4d7 | 2376 | |
sepp_nepp | 11:c6f95a42d4d7 | 2377 | if (sequence_steps.PreRangeOn) |
sepp_nepp | 11:c6f95a42d4d7 | 2378 | { current_vcsel_PPeriod_p_clk = /* Gets and converts the VCSEL period register into actual clock periods */ |
sepp_nepp | 11:c6f95a42d4d7 | 2379 | ( Read_Byte(REG_PRE_RANGE_CONFIG_VCSEL_PERIOD) + 1) << 1; |
sepp_nepp | 11:c6f95a42d4d7 | 2380 | |
sepp_nepp | 11:c6f95a42d4d7 | 2381 | /* Retrieve PRE-RANGE Timeout in Macro periods (MCLKS) */ |
sepp_nepp | 11:c6f95a42d4d7 | 2382 | if (ErrState == VL53L0X_OK) |
sepp_nepp | 11:c6f95a42d4d7 | 2383 | { pre_range_encoded_time_out = Read_Word(0x51); |
sepp_nepp | 11:c6f95a42d4d7 | 2384 | pre_range_time_out_m_clks = Decode_timeout(pre_range_encoded_time_out); |
sepp_nepp | 11:c6f95a42d4d7 | 2385 | } |
sepp_nepp | 11:c6f95a42d4d7 | 2386 | } |
sepp_nepp | 11:c6f95a42d4d7 | 2387 | |
sepp_nepp | 11:c6f95a42d4d7 | 2388 | /* Calculate FINAL RANGE Timeout in Macro Periode (MCLKS) and add PRE-RANGE value */ |
sepp_nepp | 11:c6f95a42d4d7 | 2389 | if (ErrState == VL53L0X_OK) |
sepp_nepp | 11:c6f95a42d4d7 | 2390 | { current_vcsel_PPeriod_p_clk /* Get and converts the VCSEL period register into actual clock periods */ |
sepp_nepp | 11:c6f95a42d4d7 | 2391 | = ( Read_Byte(REG_FINAL_RANGE_CONFIG_VCSEL_PERIOD) + 1) << 1; } |
sepp_nepp | 11:c6f95a42d4d7 | 2392 | |
sepp_nepp | 11:c6f95a42d4d7 | 2393 | if (ErrState == VL53L0X_OK) |
sepp_nepp | 11:c6f95a42d4d7 | 2394 | { final_range_time_out_m_clks = Calc_timeout_mclks(timeout_micro_secs, |
sepp_nepp | 11:c6f95a42d4d7 | 2395 | (uint8_t) current_vcsel_PPeriod_p_clk); |
nikapov | 0:a1a69d32f310 | 2396 | |
nikapov | 0:a1a69d32f310 | 2397 | final_range_time_out_m_clks += pre_range_time_out_m_clks; |
nikapov | 0:a1a69d32f310 | 2398 | |
sepp_nepp | 11:c6f95a42d4d7 | 2399 | final_range_encoded_time_out = Encode_timeout(final_range_time_out_m_clks); |
sepp_nepp | 11:c6f95a42d4d7 | 2400 | |
sepp_nepp | 11:c6f95a42d4d7 | 2401 | Write_Word(0x71,final_range_encoded_time_out); |
sepp_nepp | 11:c6f95a42d4d7 | 2402 | } |
sepp_nepp | 11:c6f95a42d4d7 | 2403 | |
sepp_nepp | 11:c6f95a42d4d7 | 2404 | if (ErrState == VL53L0X_OK) |
sepp_nepp | 11:c6f95a42d4d7 | 2405 | { DevSpecParams.FinalRangeTimeoutMicroSecs = timeout_micro_secs; } |
sepp_nepp | 11:c6f95a42d4d7 | 2406 | break; |
sepp_nepp | 11:c6f95a42d4d7 | 2407 | |
sepp_nepp | 11:c6f95a42d4d7 | 2408 | default: ErrState = VL53L0X_ERROR_INVALID_PARAMS; |
sepp_nepp | 11:c6f95a42d4d7 | 2409 | } // switch (sequence_step_id) |
sepp_nepp | 11:c6f95a42d4d7 | 2410 | } |
sepp_nepp | 11:c6f95a42d4d7 | 2411 | |
sepp_nepp | 11:c6f95a42d4d7 | 2412 | void VL53L0X::Set_Measure_Time_Budget_us (uint32_t Measure_Time_Budget_us) |
sepp_nepp | 11:c6f95a42d4d7 | 2413 | { uint32_t final_range_timing_budget_us; |
sepp_nepp | 11:c6f95a42d4d7 | 2414 | VL53L0X_Sequence_Steps_t sequence_steps; |
sepp_nepp | 11:c6f95a42d4d7 | 2415 | uint32_t msrc_dcc_tcc_timeout_us= 2000; |
sepp_nepp | 10:cd251e0fc2fd | 2416 | uint32_t start_overhead_us = 1910; |
sepp_nepp | 10:cd251e0fc2fd | 2417 | uint32_t end_overhead_us = 960; |
sepp_nepp | 10:cd251e0fc2fd | 2418 | uint32_t msrc_overhead_us = 660; |
sepp_nepp | 10:cd251e0fc2fd | 2419 | uint32_t tcc_overhead_us = 590; |
sepp_nepp | 10:cd251e0fc2fd | 2420 | uint32_t dss_overhead_us = 690; |
sepp_nepp | 10:cd251e0fc2fd | 2421 | uint32_t pre_range_overhead_us = 660; |
sepp_nepp | 11:c6f95a42d4d7 | 2422 | uint32_t final_range_overhead_us= 550; |
sepp_nepp | 10:cd251e0fc2fd | 2423 | uint32_t pre_range_timeout_us = 0; |
sepp_nepp | 10:cd251e0fc2fd | 2424 | uint32_t c_min_timing_budget_us = 20000; |
nikapov | 0:a1a69d32f310 | 2425 | uint32_t sub_timeout = 0; |
nikapov | 0:a1a69d32f310 | 2426 | |
sepp_nepp | 11:c6f95a42d4d7 | 2427 | if (Measure_Time_Budget_us < c_min_timing_budget_us) |
sepp_nepp | 11:c6f95a42d4d7 | 2428 | { ErrState = VL53L0X_ERROR_INVALID_PARAMS; |
sepp_nepp | 11:c6f95a42d4d7 | 2429 | return ; } |
sepp_nepp | 11:c6f95a42d4d7 | 2430 | |
sepp_nepp | 11:c6f95a42d4d7 | 2431 | final_range_timing_budget_us = Measure_Time_Budget_us - |
sepp_nepp | 11:c6f95a42d4d7 | 2432 | (start_overhead_us + end_overhead_us); |
sepp_nepp | 11:c6f95a42d4d7 | 2433 | |
sepp_nepp | 11:c6f95a42d4d7 | 2434 | sequence_steps = Get_sequence_step_enables(); |
sepp_nepp | 11:c6f95a42d4d7 | 2435 | |
sepp_nepp | 11:c6f95a42d4d7 | 2436 | if (ErrState == VL53L0X_OK && |
sepp_nepp | 11:c6f95a42d4d7 | 2437 | (sequence_steps.TccOn || |
sepp_nepp | 11:c6f95a42d4d7 | 2438 | sequence_steps.MsrcOn || |
sepp_nepp | 11:c6f95a42d4d7 | 2439 | sequence_steps.DssOn)) { |
nikapov | 0:a1a69d32f310 | 2440 | |
sepp_nepp | 7:41cbc431e1f4 | 2441 | /* TCC,MSRC and DSS all share the same timeout */ |
sepp_nepp | 11:c6f95a42d4d7 | 2442 | Get_Sequence_Step_Timeout(VL53L0X_SEQUENCESTEP_MSRC, |
sepp_nepp | 10:cd251e0fc2fd | 2443 | &msrc_dcc_tcc_timeout_us); |
nikapov | 0:a1a69d32f310 | 2444 | |
sepp_nepp | 11:c6f95a42d4d7 | 2445 | /* Subtract the TCC,MSRC and DSS timeouts if they are enabled. */ |
sepp_nepp | 11:c6f95a42d4d7 | 2446 | if (ErrState != VL53L0X_OK) {return ; } |
nikapov | 0:a1a69d32f310 | 2447 | |
nikapov | 0:a1a69d32f310 | 2448 | /* TCC */ |
sepp_nepp | 11:c6f95a42d4d7 | 2449 | if (sequence_steps.TccOn) { |
sepp_nepp | 11:c6f95a42d4d7 | 2450 | |
sepp_nepp | 11:c6f95a42d4d7 | 2451 | sub_timeout = msrc_dcc_tcc_timeout_us + tcc_overhead_us; |
sepp_nepp | 11:c6f95a42d4d7 | 2452 | |
sepp_nepp | 11:c6f95a42d4d7 | 2453 | if (sub_timeout < final_range_timing_budget_us) { |
sepp_nepp | 11:c6f95a42d4d7 | 2454 | final_range_timing_budget_us -= sub_timeout; |
sepp_nepp | 11:c6f95a42d4d7 | 2455 | } else { /* Requested timeout too big. */ |
sepp_nepp | 11:c6f95a42d4d7 | 2456 | ErrState = VL53L0X_ERROR_INVALID_PARAMS; |
nikapov | 0:a1a69d32f310 | 2457 | } |
nikapov | 0:a1a69d32f310 | 2458 | } |
nikapov | 0:a1a69d32f310 | 2459 | |
sepp_nepp | 11:c6f95a42d4d7 | 2460 | if (ErrState != VL53L0X_OK) {return; } |
nikapov | 0:a1a69d32f310 | 2461 | |
nikapov | 0:a1a69d32f310 | 2462 | /* DSS */ |
sepp_nepp | 11:c6f95a42d4d7 | 2463 | if (sequence_steps.DssOn) |
sepp_nepp | 11:c6f95a42d4d7 | 2464 | { sub_timeout = 2 * (msrc_dcc_tcc_timeout_us + dss_overhead_us); |
sepp_nepp | 11:c6f95a42d4d7 | 2465 | |
sepp_nepp | 11:c6f95a42d4d7 | 2466 | if (sub_timeout < final_range_timing_budget_us) |
sepp_nepp | 11:c6f95a42d4d7 | 2467 | { final_range_timing_budget_us -= sub_timeout; } |
sepp_nepp | 11:c6f95a42d4d7 | 2468 | else { /* Requested timeout too big. */ |
sepp_nepp | 11:c6f95a42d4d7 | 2469 | ErrState = VL53L0X_ERROR_INVALID_PARAMS; } |
sepp_nepp | 11:c6f95a42d4d7 | 2470 | } |
sepp_nepp | 11:c6f95a42d4d7 | 2471 | else if (sequence_steps.MsrcOn) /* MSRC */ |
sepp_nepp | 11:c6f95a42d4d7 | 2472 | { sub_timeout = msrc_dcc_tcc_timeout_us + msrc_overhead_us; |
sepp_nepp | 11:c6f95a42d4d7 | 2473 | |
sepp_nepp | 11:c6f95a42d4d7 | 2474 | if (sub_timeout < final_range_timing_budget_us) |
sepp_nepp | 11:c6f95a42d4d7 | 2475 | { final_range_timing_budget_us -= sub_timeout; } |
sepp_nepp | 11:c6f95a42d4d7 | 2476 | else /* Requested timeout too big. */ |
sepp_nepp | 11:c6f95a42d4d7 | 2477 | { ErrState = VL53L0X_ERROR_INVALID_PARAMS; } |
sepp_nepp | 11:c6f95a42d4d7 | 2478 | } |
nikapov | 0:a1a69d32f310 | 2479 | } |
nikapov | 0:a1a69d32f310 | 2480 | |
sepp_nepp | 11:c6f95a42d4d7 | 2481 | if (ErrState != VL53L0X_OK) {return; } |
sepp_nepp | 11:c6f95a42d4d7 | 2482 | |
sepp_nepp | 11:c6f95a42d4d7 | 2483 | if (sequence_steps.PreRangeOn) { |
nikapov | 0:a1a69d32f310 | 2484 | /* Subtract the Pre-range timeout if enabled. */ |
sepp_nepp | 11:c6f95a42d4d7 | 2485 | Get_Sequence_Step_Timeout(VL53L0X_SEQUENCESTEP_PRE_RANGE, |
sepp_nepp | 10:cd251e0fc2fd | 2486 | &pre_range_timeout_us); |
sepp_nepp | 11:c6f95a42d4d7 | 2487 | sub_timeout = pre_range_timeout_us + pre_range_overhead_us; |
sepp_nepp | 10:cd251e0fc2fd | 2488 | |
sepp_nepp | 10:cd251e0fc2fd | 2489 | if (sub_timeout < final_range_timing_budget_us) { |
sepp_nepp | 10:cd251e0fc2fd | 2490 | final_range_timing_budget_us -= sub_timeout; |
nikapov | 0:a1a69d32f310 | 2491 | } else { |
nikapov | 0:a1a69d32f310 | 2492 | /* Requested timeout too big. */ |
sepp_nepp | 11:c6f95a42d4d7 | 2493 | ErrState = VL53L0X_ERROR_INVALID_PARAMS; |
nikapov | 0:a1a69d32f310 | 2494 | } |
nikapov | 0:a1a69d32f310 | 2495 | } |
nikapov | 0:a1a69d32f310 | 2496 | |
sepp_nepp | 11:c6f95a42d4d7 | 2497 | if (ErrState == VL53L0X_OK && sequence_steps.FinalRangeOn) |
sepp_nepp | 11:c6f95a42d4d7 | 2498 | { final_range_timing_budget_us -= final_range_overhead_us; |
nikapov | 0:a1a69d32f310 | 2499 | |
nikapov | 0:a1a69d32f310 | 2500 | /* Final Range Timeout |
nikapov | 0:a1a69d32f310 | 2501 | * Note that the final range timeout is determined by the timing |
nikapov | 0:a1a69d32f310 | 2502 | * budget and the sum of all other timeouts within the sequence. |
sepp_nepp | 7:41cbc431e1f4 | 2503 | * If there is no room for the final range timeout,then an error |
nikapov | 0:a1a69d32f310 | 2504 | * will be set. Otherwise the remaining time will be applied to |
nikapov | 0:a1a69d32f310 | 2505 | * the final range. |
nikapov | 0:a1a69d32f310 | 2506 | */ |
sepp_nepp | 11:c6f95a42d4d7 | 2507 | Set_Sequence_Step_Timeout(VL53L0X_SEQUENCESTEP_FINAL_RANGE, |
sepp_nepp | 10:cd251e0fc2fd | 2508 | final_range_timing_budget_us); |
sepp_nepp | 10:cd251e0fc2fd | 2509 | |
sepp_nepp | 11:c6f95a42d4d7 | 2510 | CurrParams.Measure_Time_Budget_us = Measure_Time_Budget_us; |
nikapov | 0:a1a69d32f310 | 2511 | } |
nikapov | 0:a1a69d32f310 | 2512 | } |
nikapov | 0:a1a69d32f310 | 2513 | |
sepp_nepp | 11:c6f95a42d4d7 | 2514 | const uint8_t SEQUENCESTEP_MASK[] = |
sepp_nepp | 11:c6f95a42d4d7 | 2515 | { 0x10, //VL53L0X_SEQUENCESTEP_TCC = 0 |
sepp_nepp | 11:c6f95a42d4d7 | 2516 | 0x28, //VL53L0X_SEQUENCESTEP_DSS = 1 |
sepp_nepp | 11:c6f95a42d4d7 | 2517 | 0x04, //VL53L0X_SEQUENCESTEP_MSRC= 2 |
sepp_nepp | 11:c6f95a42d4d7 | 2518 | 0x40, //VL53L0X_SEQUENCESTEP_PRE_RANGE= 3 |
sepp_nepp | 11:c6f95a42d4d7 | 2519 | 0x80}; //VL53L0X_SEQUENCESTEP_FINAL_RANGE = 4 |
sepp_nepp | 11:c6f95a42d4d7 | 2520 | |
sepp_nepp | 11:c6f95a42d4d7 | 2521 | void VL53L0X::Set_sequence_step_enable(VL53L0X_SequenceStepId sequence_step_id, |
sepp_nepp | 11:c6f95a42d4d7 | 2522 | uint8_t sequence_step_enabled) |
sepp_nepp | 11:c6f95a42d4d7 | 2523 | { uint8_t new_config = 0; |
sepp_nepp | 11:c6f95a42d4d7 | 2524 | |
sepp_nepp | 11:c6f95a42d4d7 | 2525 | // SequenceConfig = Read_Byte(REG_SYSTEM_SEQUENCE_CONFIG); |
sepp_nepp | 11:c6f95a42d4d7 | 2526 | // instead of reading from the device, use the SequenceConfig local data field!! |
sepp_nepp | 11:c6f95a42d4d7 | 2527 | |
sepp_nepp | 11:c6f95a42d4d7 | 2528 | if (sequence_step_enabled == 1) /* Enable requested sequence step */ |
sepp_nepp | 11:c6f95a42d4d7 | 2529 | { new_config = SequenceConfig | SEQUENCESTEP_MASK[sequence_step_id]; } |
sepp_nepp | 11:c6f95a42d4d7 | 2530 | else /* Disable requested sequence step */ |
sepp_nepp | 11:c6f95a42d4d7 | 2531 | { new_config = SequenceConfig & (0xff - SEQUENCESTEP_MASK[sequence_step_id]); } |
sepp_nepp | 11:c6f95a42d4d7 | 2532 | |
sepp_nepp | 11:c6f95a42d4d7 | 2533 | if (new_config != SequenceConfig) { /* Apply New Setting */ |
sepp_nepp | 11:c6f95a42d4d7 | 2534 | Set_SequenceConfig( new_config ); |
sepp_nepp | 11:c6f95a42d4d7 | 2535 | if (ErrState == VL53L0X_OK) /* Recalculate timing budget */ |
sepp_nepp | 11:c6f95a42d4d7 | 2536 | { Set_Measure_Time_Budget_us(CurrParams.Measure_Time_Budget_us); } |
sepp_nepp | 11:c6f95a42d4d7 | 2537 | } // if (new_config != sequence_config) |
nikapov | 0:a1a69d32f310 | 2538 | } |
nikapov | 0:a1a69d32f310 | 2539 | |
sepp_nepp | 11:c6f95a42d4d7 | 2540 | void VL53L0X::Set_limit_chk_en(uint16_t limit_check_id, uint8_t limit_chk_en) |
sepp_nepp | 11:c6f95a42d4d7 | 2541 | { TFP1616 temp_fix1616 = 0; |
sepp_nepp | 11:c6f95a42d4d7 | 2542 | if (limit_chk_en!=0) {limit_chk_en=1;} // make sure we only have 0 or 1 as values!!! |
sepp_nepp | 11:c6f95a42d4d7 | 2543 | |
sepp_nepp | 11:c6f95a42d4d7 | 2544 | switch (limit_check_id) { |
sepp_nepp | 11:c6f95a42d4d7 | 2545 | case VL53L0X_CHECKEN_SIGMA_FINAL_RANGE: /* internal computation: */ |
sepp_nepp | 11:c6f95a42d4d7 | 2546 | case VL53L0X_CHECKEN_SIG_REF_CLIP: /* internal computation: */ |
sepp_nepp | 11:c6f95a42d4d7 | 2547 | case VL53L0X_CHECKEN_RANGE_IGNORE_THRESHOLD: /* internal computation: */ |
sepp_nepp | 11:c6f95a42d4d7 | 2548 | CurrParams.Limit_Chk_En[limit_check_id] = limit_chk_en; |
sepp_nepp | 11:c6f95a42d4d7 | 2549 | break; |
sepp_nepp | 11:c6f95a42d4d7 | 2550 | |
sepp_nepp | 11:c6f95a42d4d7 | 2551 | case VL53L0X_CHECKEN_SIG_RATE_FINAL_RANGE: |
sepp_nepp | 11:c6f95a42d4d7 | 2552 | temp_fix1616 = limit_chk_en * CurrParams.Limit_Chk_Val[limit_check_id]; |
sepp_nepp | 11:c6f95a42d4d7 | 2553 | Write_Word(REG_FINAL_RANGE_CONFIG_MIN_COUNT_RATE_RTN_LIMIT, |
sepp_nepp | 11:c6f95a42d4d7 | 2554 | FP1616_TO_FP97(temp_fix1616)); |
sepp_nepp | 11:c6f95a42d4d7 | 2555 | break; |
sepp_nepp | 11:c6f95a42d4d7 | 2556 | |
sepp_nepp | 11:c6f95a42d4d7 | 2557 | case VL53L0X_CHECKEN_SIG_RATE_MSRC: |
sepp_nepp | 11:c6f95a42d4d7 | 2558 | Register_BitMask(REG_MSRC_CONFIG_CONTROL,0xFE, (1-limit_chk_en)<< 1); |
sepp_nepp | 11:c6f95a42d4d7 | 2559 | break; |
sepp_nepp | 11:c6f95a42d4d7 | 2560 | |
sepp_nepp | 11:c6f95a42d4d7 | 2561 | case VL53L0X_CHECKEN_SIG_RATE_PRE_RANGE: |
sepp_nepp | 11:c6f95a42d4d7 | 2562 | Register_BitMask(REG_MSRC_CONFIG_CONTROL,0xEF, (1-limit_chk_en)<< 4); |
sepp_nepp | 11:c6f95a42d4d7 | 2563 | break; |
sepp_nepp | 11:c6f95a42d4d7 | 2564 | |
sepp_nepp | 11:c6f95a42d4d7 | 2565 | default: ErrState = VL53L0X_ERROR_INVALID_PARAMS; |
sepp_nepp | 11:c6f95a42d4d7 | 2566 | } // switch |
sepp_nepp | 11:c6f95a42d4d7 | 2567 | |
sepp_nepp | 11:c6f95a42d4d7 | 2568 | if (ErrState == VL53L0X_OK) { CurrParams.Limit_Chk_En[limit_check_id] = limit_chk_en; } |
nikapov | 0:a1a69d32f310 | 2569 | } |
nikapov | 0:a1a69d32f310 | 2570 | |
sepp_nepp | 11:c6f95a42d4d7 | 2571 | void VL53L0X::Static_init() |
sepp_nepp | 11:c6f95a42d4d7 | 2572 | { VL53L0X_DeviceParams_t new_curr_parameters; |
sepp_nepp | 11:c6f95a42d4d7 | 2573 | uint8_t *p_tuning_setting_buffer; |
nikapov | 0:a1a69d32f310 | 2574 | uint16_t tempword = 0; |
sepp_nepp | 11:c6f95a42d4d7 | 2575 | uint8_t tempbyte = 0; |
nikapov | 0:a1a69d32f310 | 2576 | uint32_t count = 0; |
sepp_nepp | 11:c6f95a42d4d7 | 2577 | uint8_t is_aperture_SPADS = 0; |
sepp_nepp | 11:c6f95a42d4d7 | 2578 | uint32_t ref_SPAD_count = 0; |
sepp_nepp | 11:c6f95a42d4d7 | 2579 | uint8_t aperture_SPADS = 0; |
sepp_nepp | 11:c6f95a42d4d7 | 2580 | uint8_t vcsel_PPeriod_pclk; |
nikapov | 0:a1a69d32f310 | 2581 | uint32_t seq_timeout_micro_secs; |
nikapov | 0:a1a69d32f310 | 2582 | |
sepp_nepp | 11:c6f95a42d4d7 | 2583 | Get_info_from_device(1); |
sepp_nepp | 11:c6f95a42d4d7 | 2584 | |
sepp_nepp | 11:c6f95a42d4d7 | 2585 | /* set the ref SPAD from NVM */ |
sepp_nepp | 11:c6f95a42d4d7 | 2586 | count = (uint32_t)DevSpecParams.ReferenceSPADCount; |
sepp_nepp | 11:c6f95a42d4d7 | 2587 | aperture_SPADS = DevSpecParams.ReferenceSPADType; |
nikapov | 0:a1a69d32f310 | 2588 | |
nikapov | 0:a1a69d32f310 | 2589 | /* NVM value invalid */ |
sepp_nepp | 11:c6f95a42d4d7 | 2590 | if ((aperture_SPADS > 1) || ((aperture_SPADS == 1) && (count > 32)) || |
sepp_nepp | 11:c6f95a42d4d7 | 2591 | ((aperture_SPADS == 0) && (count > 12))) |
sepp_nepp | 11:c6f95a42d4d7 | 2592 | { Perf_Ref_SPAD_management(&ref_SPAD_count, &is_aperture_SPADS); } |
sepp_nepp | 11:c6f95a42d4d7 | 2593 | else |
sepp_nepp | 11:c6f95a42d4d7 | 2594 | { Set_Reference_SPADS(count,aperture_SPADS); } |
nikapov | 0:a1a69d32f310 | 2595 | |
nikapov | 0:a1a69d32f310 | 2596 | /* Initialize tuning settings buffer to prevent compiler warning. */ |
nikapov | 0:a1a69d32f310 | 2597 | p_tuning_setting_buffer = DefaultTuningSettings; |
nikapov | 0:a1a69d32f310 | 2598 | |
sepp_nepp | 11:c6f95a42d4d7 | 2599 | if (ErrState == VL53L0X_OK) { |
sepp_nepp | 11:c6f95a42d4d7 | 2600 | if (UseInternalTuningSettings == 0) |
sepp_nepp | 11:c6f95a42d4d7 | 2601 | { p_tuning_setting_buffer = pTuningSettingsPointer; } |
sepp_nepp | 11:c6f95a42d4d7 | 2602 | else |
sepp_nepp | 11:c6f95a42d4d7 | 2603 | { p_tuning_setting_buffer = DefaultTuningSettings; } |
sepp_nepp | 11:c6f95a42d4d7 | 2604 | } |
sepp_nepp | 11:c6f95a42d4d7 | 2605 | |
sepp_nepp | 11:c6f95a42d4d7 | 2606 | if (ErrState == VL53L0X_OK) |
sepp_nepp | 11:c6f95a42d4d7 | 2607 | { Load_tuning_settings(p_tuning_setting_buffer); } |
sepp_nepp | 11:c6f95a42d4d7 | 2608 | |
sepp_nepp | 11:c6f95a42d4d7 | 2609 | /* Set interrupt config to new sample ready */ |
sepp_nepp | 11:c6f95a42d4d7 | 2610 | if (ErrState == VL53L0X_OK) |
sepp_nepp | 11:c6f95a42d4d7 | 2611 | { Set_GPIO_config(0,GPIO_FUNC_NEW_MEASURE_READY,VL53L0X_INTERRUPTPOLARITY_LOW); } |
sepp_nepp | 11:c6f95a42d4d7 | 2612 | |
sepp_nepp | 11:c6f95a42d4d7 | 2613 | Write_Byte(0xFF,0x01); |
sepp_nepp | 11:c6f95a42d4d7 | 2614 | tempword = Read_Word(0x84); |
sepp_nepp | 11:c6f95a42d4d7 | 2615 | Write_Byte(0xFF,0x00); |
sepp_nepp | 11:c6f95a42d4d7 | 2616 | |
sepp_nepp | 11:c6f95a42d4d7 | 2617 | if (ErrState == VL53L0X_OK) |
sepp_nepp | 11:c6f95a42d4d7 | 2618 | { DevSpecParams.OscFrequencyMHz=FP412_TO_FP1616(tempword); } |
sepp_nepp | 11:c6f95a42d4d7 | 2619 | |
sepp_nepp | 11:c6f95a42d4d7 | 2620 | /* After static init,some device parameters may be changed, so update them */ |
sepp_nepp | 11:c6f95a42d4d7 | 2621 | new_curr_parameters = Get_device_parameters(); |
sepp_nepp | 11:c6f95a42d4d7 | 2622 | |
sepp_nepp | 11:c6f95a42d4d7 | 2623 | if (ErrState == VL53L0X_OK) { tempbyte = Read_Byte(REG_SYSTEM_RANGE_CONFIG); } |
sepp_nepp | 11:c6f95a42d4d7 | 2624 | if (ErrState == VL53L0X_OK) { RangeFractionalEnable = (tempbyte & 1); } |
sepp_nepp | 11:c6f95a42d4d7 | 2625 | if (ErrState == VL53L0X_OK) { CurrParams = new_curr_parameters; } |
nikapov | 0:a1a69d32f310 | 2626 | |
nikapov | 0:a1a69d32f310 | 2627 | /* read the sequence config and save it */ |
sepp_nepp | 11:c6f95a42d4d7 | 2628 | Set_SequenceConfig( Read_Byte(REG_SYSTEM_SEQUENCE_CONFIG) ); // checks for ErrState |
nikapov | 0:a1a69d32f310 | 2629 | |
nikapov | 0:a1a69d32f310 | 2630 | /* Disable MSRC and TCC by default */ |
sepp_nepp | 11:c6f95a42d4d7 | 2631 | if (ErrState == VL53L0X_OK) |
sepp_nepp | 11:c6f95a42d4d7 | 2632 | { Set_sequence_step_enable(VL53L0X_SEQUENCESTEP_TCC,0); } |
sepp_nepp | 11:c6f95a42d4d7 | 2633 | |
sepp_nepp | 11:c6f95a42d4d7 | 2634 | if (ErrState == VL53L0X_OK) |
sepp_nepp | 11:c6f95a42d4d7 | 2635 | { Set_sequence_step_enable(VL53L0X_SEQUENCESTEP_MSRC,0); } |
sepp_nepp | 11:c6f95a42d4d7 | 2636 | |
sepp_nepp | 11:c6f95a42d4d7 | 2637 | /* Set State to standby */ |
sepp_nepp | 11:c6f95a42d4d7 | 2638 | Set_Current_State( VL53L0X_STATE_IDLE) ; |
nikapov | 0:a1a69d32f310 | 2639 | |
nikapov | 0:a1a69d32f310 | 2640 | /* Store pre-range vcsel period */ |
sepp_nepp | 11:c6f95a42d4d7 | 2641 | if (ErrState == VL53L0X_OK)/* Gets and converts the VCSEL period register into actual clock periods */ |
sepp_nepp | 11:c6f95a42d4d7 | 2642 | { vcsel_PPeriod_pclk = (Read_Byte(REG_PRE_RANGE_CONFIG_VCSEL_PERIOD) + 1) << 1; } |
sepp_nepp | 11:c6f95a42d4d7 | 2643 | |
sepp_nepp | 11:c6f95a42d4d7 | 2644 | if ( ErrState == VL53L0X_OK) |
sepp_nepp | 11:c6f95a42d4d7 | 2645 | { DevSpecParams.PreRangeVcselPPeriod = vcsel_PPeriod_pclk; } |
nikapov | 0:a1a69d32f310 | 2646 | |
nikapov | 0:a1a69d32f310 | 2647 | /* Store final-range vcsel period */ |
sepp_nepp | 11:c6f95a42d4d7 | 2648 | if (ErrState == VL53L0X_OK) |
sepp_nepp | 11:c6f95a42d4d7 | 2649 | { vcsel_PPeriod_pclk /* Get and convert the VCSEL period register into actual clock periods */ |
sepp_nepp | 11:c6f95a42d4d7 | 2650 | = ( Read_Byte(REG_FINAL_RANGE_CONFIG_VCSEL_PERIOD) + 1) << 1; } |
sepp_nepp | 11:c6f95a42d4d7 | 2651 | |
sepp_nepp | 11:c6f95a42d4d7 | 2652 | if (ErrState == VL53L0X_OK) |
sepp_nepp | 11:c6f95a42d4d7 | 2653 | { DevSpecParams.FinalRangeVcselPPeriod = vcsel_PPeriod_pclk; } |
nikapov | 0:a1a69d32f310 | 2654 | |
nikapov | 0:a1a69d32f310 | 2655 | /* Store pre-range timeout */ |
sepp_nepp | 11:c6f95a42d4d7 | 2656 | if (ErrState == VL53L0X_OK) |
sepp_nepp | 11:c6f95a42d4d7 | 2657 | { Get_Sequence_Step_Timeout( VL53L0X_SEQUENCESTEP_PRE_RANGE, |
sepp_nepp | 11:c6f95a42d4d7 | 2658 | &seq_timeout_micro_secs); } |
sepp_nepp | 11:c6f95a42d4d7 | 2659 | |
sepp_nepp | 11:c6f95a42d4d7 | 2660 | if (ErrState == VL53L0X_OK) |
sepp_nepp | 11:c6f95a42d4d7 | 2661 | { DevSpecParams.PreRangeTimeoutMicroSecs = seq_timeout_micro_secs; } |
nikapov | 0:a1a69d32f310 | 2662 | |
nikapov | 0:a1a69d32f310 | 2663 | /* Store final-range timeout */ |
sepp_nepp | 11:c6f95a42d4d7 | 2664 | if (ErrState == VL53L0X_OK) |
sepp_nepp | 11:c6f95a42d4d7 | 2665 | { Get_Sequence_Step_Timeout( VL53L0X_SEQUENCESTEP_FINAL_RANGE, |
sepp_nepp | 11:c6f95a42d4d7 | 2666 | &seq_timeout_micro_secs);} |
sepp_nepp | 11:c6f95a42d4d7 | 2667 | |
sepp_nepp | 11:c6f95a42d4d7 | 2668 | if (ErrState == VL53L0X_OK) |
sepp_nepp | 11:c6f95a42d4d7 | 2669 | { DevSpecParams.FinalRangeTimeoutMicroSecs = seq_timeout_micro_secs; } |
nikapov | 0:a1a69d32f310 | 2670 | } |
nikapov | 0:a1a69d32f310 | 2671 | |
sepp_nepp | 11:c6f95a42d4d7 | 2672 | void VL53L0X::Stop_Measurement() |
sepp_nepp | 11:c6f95a42d4d7 | 2673 | { Write_Byte(REG_SYSRANGE_START, REG_SYSRANGE_MODE_SINGLESHOT); |
sepp_nepp | 11:c6f95a42d4d7 | 2674 | Write_Byte(0xFF,0x01); |
sepp_nepp | 11:c6f95a42d4d7 | 2675 | Write_Byte(0x00,0x00); |
sepp_nepp | 11:c6f95a42d4d7 | 2676 | Write_Byte(0x91,0x00); |
sepp_nepp | 11:c6f95a42d4d7 | 2677 | Write_Byte(0x00,0x01); |
sepp_nepp | 11:c6f95a42d4d7 | 2678 | Write_Byte(0xFF,0x00); |
sepp_nepp | 11:c6f95a42d4d7 | 2679 | |
sepp_nepp | 11:c6f95a42d4d7 | 2680 | Set_Current_State( VL53L0X_STATE_IDLE ); |
nikapov | 0:a1a69d32f310 | 2681 | |
nikapov | 0:a1a69d32f310 | 2682 | /* Check if need to apply interrupt settings */ |
sepp_nepp | 11:c6f95a42d4d7 | 2683 | Check_and_load_interrupt_settings(0); |
nikapov | 0:a1a69d32f310 | 2684 | } |
nikapov | 0:a1a69d32f310 | 2685 | |
sepp_nepp | 11:c6f95a42d4d7 | 2686 | uint8_t VL53L0X::Get_Stop_Completed() |
sepp_nepp | 11:c6f95a42d4d7 | 2687 | { uint8_t Abyte = 0; |
sepp_nepp | 11:c6f95a42d4d7 | 2688 | |
sepp_nepp | 11:c6f95a42d4d7 | 2689 | Write_Byte(0xFF,0x01); |
sepp_nepp | 11:c6f95a42d4d7 | 2690 | Abyte = Read_Byte(0x04); |
sepp_nepp | 11:c6f95a42d4d7 | 2691 | Write_Byte(0xFF,0x0); |
sepp_nepp | 11:c6f95a42d4d7 | 2692 | |
sepp_nepp | 11:c6f95a42d4d7 | 2693 | if ((ErrState == VL53L0X_OK) & (Abyte == 0)) |
sepp_nepp | 11:c6f95a42d4d7 | 2694 | { Write_Byte(0x80,0x01); |
sepp_nepp | 11:c6f95a42d4d7 | 2695 | Write_Byte(0xFF,0x01); |
sepp_nepp | 11:c6f95a42d4d7 | 2696 | Write_Byte(0x00,0x00); |
sepp_nepp | 11:c6f95a42d4d7 | 2697 | Write_Byte(0x91,StopVariable); |
sepp_nepp | 11:c6f95a42d4d7 | 2698 | Write_Byte(0x00,0x01); |
sepp_nepp | 11:c6f95a42d4d7 | 2699 | Write_Byte(0xFF,0x00); |
sepp_nepp | 11:c6f95a42d4d7 | 2700 | Write_Byte(0x80,0x00); |
sepp_nepp | 11:c6f95a42d4d7 | 2701 | } |
sepp_nepp | 11:c6f95a42d4d7 | 2702 | return Abyte; |
nikapov | 0:a1a69d32f310 | 2703 | } |
nikapov | 0:a1a69d32f310 | 2704 | |
sepp_nepp | 11:c6f95a42d4d7 | 2705 | void VL53L0X::Wait_Measurement_Ready() |
sepp_nepp | 11:c6f95a42d4d7 | 2706 | { uint32_t loop_nb = 0; |
sepp_nepp | 11:c6f95a42d4d7 | 2707 | |
sepp_nepp | 11:c6f95a42d4d7 | 2708 | // Wait until it finished, or loopo count reached = avoids deadlock |
sepp_nepp | 11:c6f95a42d4d7 | 2709 | while ( !Get_Measurement_Ready() & (ErrState == VL53L0X_OK) ) |
sepp_nepp | 11:c6f95a42d4d7 | 2710 | { if (loop_nb++ >= VL53L0X_DEFAULT_MAX_LOOP) |
sepp_nepp | 11:c6f95a42d4d7 | 2711 | { ErrState = VL53L0X_ERROR_TIME_OUT;} |
sepp_nepp | 11:c6f95a42d4d7 | 2712 | else { Polling_delay(); } |
sepp_nepp | 11:c6f95a42d4d7 | 2713 | } // while ends |
nikapov | 0:a1a69d32f310 | 2714 | } |
nikapov | 0:a1a69d32f310 | 2715 | |
sepp_nepp | 11:c6f95a42d4d7 | 2716 | void VL53L0X::Wait_Stop_Completed() |
sepp_nepp | 11:c6f95a42d4d7 | 2717 | { uint32_t loop_nb = 0; |
sepp_nepp | 11:c6f95a42d4d7 | 2718 | |
sepp_nepp | 11:c6f95a42d4d7 | 2719 | // Wait until Stop_Completed, or loopo count reached = avoids deadlock |
sepp_nepp | 11:c6f95a42d4d7 | 2720 | while ( (ErrState == VL53L0X_OK) & !Get_Stop_Completed() ) |
sepp_nepp | 11:c6f95a42d4d7 | 2721 | { if (loop_nb++ >= VL53L0X_DEFAULT_MAX_LOOP) |
sepp_nepp | 11:c6f95a42d4d7 | 2722 | { ErrState = VL53L0X_ERROR_TIME_OUT;} |
sepp_nepp | 11:c6f95a42d4d7 | 2723 | else { Polling_delay(); } |
sepp_nepp | 11:c6f95a42d4d7 | 2724 | } // while ends |
nikapov | 0:a1a69d32f310 | 2725 | } |
nikapov | 0:a1a69d32f310 | 2726 | |
sepp_nepp | 11:c6f95a42d4d7 | 2727 | void VL53L0X::Range_meas_int_continuous_mode(void (*fptr)(void)) |
sepp_nepp | 11:c6f95a42d4d7 | 2728 | { Stop_Measurement(); // it is safer to do this while sensor is stopped |
sepp_nepp | 11:c6f95a42d4d7 | 2729 | |
sepp_nepp | 11:c6f95a42d4d7 | 2730 | Set_GPIO_config(VL53L0X_DEVICEMODE_CONTINUOUS_RANGING, |
sepp_nepp | 11:c6f95a42d4d7 | 2731 | GPIO_FUNC_NEW_MEASURE_READY, VL53L0X_INTERRUPTPOLARITY_HIGH); |
sepp_nepp | 11:c6f95a42d4d7 | 2732 | if (ErrState==VL53L0X_OK) { |
sepp_nepp | 11:c6f95a42d4d7 | 2733 | Attach_interrupt_measure_detection_irq(fptr); |
sepp_nepp | 11:c6f95a42d4d7 | 2734 | Enable_interrupt_measure_detection_irq(); } |
sepp_nepp | 11:c6f95a42d4d7 | 2735 | |
sepp_nepp | 11:c6f95a42d4d7 | 2736 | Clear_interrupt_mask(REG_RESULT_INTERRUPT_STATUS | REG_RESULT_RANGE_STATUS); |
sepp_nepp | 11:c6f95a42d4d7 | 2737 | // NB: return value was previously only passed to logging macro,but did not get passed back |
sepp_nepp | 11:c6f95a42d4d7 | 2738 | |
sepp_nepp | 11:c6f95a42d4d7 | 2739 | if (ErrState==VL53L0X_OK) { Range_start_continuous_mode(); } |
nikapov | 0:a1a69d32f310 | 2740 | } |
nikapov | 0:a1a69d32f310 | 2741 | |
sepp_nepp | 11:c6f95a42d4d7 | 2742 | |
sepp_nepp | 11:c6f95a42d4d7 | 2743 | VL53L0X_Error VL53L0X::Start_Measurement(TOperatingMode operating_mode, void (*fptr)(void)) |
sepp_nepp | 11:c6f95a42d4d7 | 2744 | { uint8_t VhvSettings; |
nikapov | 0:a1a69d32f310 | 2745 | uint8_t PhaseCal; |
sepp_nepp | 7:41cbc431e1f4 | 2746 | // *** from mass market cube expansion v1.1,ranging with satellites. |
sepp_nepp | 7:41cbc431e1f4 | 2747 | // default settings,for normal range. |
sepp_nepp | 11:c6f95a42d4d7 | 2748 | TFP1616 signalLimit = (TFP1616)(0.25 * 65536); |
sepp_nepp | 11:c6f95a42d4d7 | 2749 | TFP1616 sigmaLimit = (TFP1616)(18 * 65536); |
nikapov | 0:a1a69d32f310 | 2750 | uint32_t timingBudget = 33000; |
nikapov | 0:a1a69d32f310 | 2751 | uint8_t preRangeVcselPeriod = 14; |
nikapov | 0:a1a69d32f310 | 2752 | uint8_t finalRangeVcselPeriod = 10; |
nikapov | 0:a1a69d32f310 | 2753 | |
sepp_nepp | 11:c6f95a42d4d7 | 2754 | switch (operating_mode) { |
sepp_nepp | 11:c6f95a42d4d7 | 2755 | case op_INT: |
sepp_nepp | 11:c6f95a42d4d7 | 2756 | if (_gpio1Int == NULL) { ErrState=1; return ErrState; } |
sepp_nepp | 11:c6f95a42d4d7 | 2757 | Stop_Measurement(); // it is safer to do this while sensor is stopped |
sepp_nepp | 11:c6f95a42d4d7 | 2758 | |
sepp_nepp | 11:c6f95a42d4d7 | 2759 | Set_GPIO_config(VL53L0X_DEVICEMODE_CONTINUOUS_RANGING, |
sepp_nepp | 11:c6f95a42d4d7 | 2760 | GPIO_FUNC_NEW_MEASURE_READY, VL53L0X_INTERRUPTPOLARITY_HIGH); |
sepp_nepp | 11:c6f95a42d4d7 | 2761 | |
sepp_nepp | 11:c6f95a42d4d7 | 2762 | if (ErrState == VL53L0X_OK) |
sepp_nepp | 11:c6f95a42d4d7 | 2763 | { Attach_interrupt_measure_detection_irq(fptr); |
sepp_nepp | 11:c6f95a42d4d7 | 2764 | Enable_interrupt_measure_detection_irq(); } |
sepp_nepp | 11:c6f95a42d4d7 | 2765 | |
sepp_nepp | 11:c6f95a42d4d7 | 2766 | Clear_interrupt_mask(REG_RESULT_INTERRUPT_STATUS | REG_RESULT_RANGE_STATUS); |
sepp_nepp | 11:c6f95a42d4d7 | 2767 | // NB: return value was previously only passed to logging macro, but did not get passed back |
sepp_nepp | 11:c6f95a42d4d7 | 2768 | |
sepp_nepp | 11:c6f95a42d4d7 | 2769 | // Setup in continuous ranging mode |
sepp_nepp | 11:c6f95a42d4d7 | 2770 | Set_device_mode(VL53L0X_DEVICEMODE_CONTINUOUS_RANGING); |
sepp_nepp | 11:c6f95a42d4d7 | 2771 | Start_Measurement(); |
sepp_nepp | 11:c6f95a42d4d7 | 2772 | break; |
sepp_nepp | 11:c6f95a42d4d7 | 2773 | |
sepp_nepp | 11:c6f95a42d4d7 | 2774 | case op_single_shot_poll: |
sepp_nepp | 11:c6f95a42d4d7 | 2775 | // singelshot,polled ranging; no need to do this when we use VL53L0X_PerformSingleRangingMeasurement |
sepp_nepp | 11:c6f95a42d4d7 | 2776 | Set_device_mode(VL53L0X_DEVICEMODE_SINGLE_RANGING); // Setup in single ranging mode |
nikapov | 0:a1a69d32f310 | 2777 | |
nikapov | 0:a1a69d32f310 | 2778 | // Enable/Disable Sigma and Signal check |
sepp_nepp | 11:c6f95a42d4d7 | 2779 | if (ErrState == VL53L0X_OK) |
sepp_nepp | 11:c6f95a42d4d7 | 2780 | { Set_limit_chk_en(VL53L0X_CHECKEN_SIGMA_FINAL_RANGE,1); } |
sepp_nepp | 11:c6f95a42d4d7 | 2781 | |
sepp_nepp | 11:c6f95a42d4d7 | 2782 | if (ErrState == VL53L0X_OK) |
sepp_nepp | 11:c6f95a42d4d7 | 2783 | { Set_limit_chk_en(VL53L0X_CHECKEN_SIG_RATE_FINAL_RANGE,1); } |
sepp_nepp | 11:c6f95a42d4d7 | 2784 | |
sepp_nepp | 11:c6f95a42d4d7 | 2785 | |
sepp_nepp | 11:c6f95a42d4d7 | 2786 | /* Ranging configuration */ |
sepp_nepp | 11:c6f95a42d4d7 | 2787 | // *** from mass market cube expansion v1.1,ranging with satellites. |
sepp_nepp | 11:c6f95a42d4d7 | 2788 | // switch(rangingConfig) { |
sepp_nepp | 11:c6f95a42d4d7 | 2789 | // case LONG_RANGE: |
sepp_nepp | 11:c6f95a42d4d7 | 2790 | signalLimit = (TFP1616)(0.1 * 65536); |
sepp_nepp | 11:c6f95a42d4d7 | 2791 | sigmaLimit = (TFP1616)(60 * 65536); |
nikapov | 0:a1a69d32f310 | 2792 | timingBudget = 33000; |
nikapov | 0:a1a69d32f310 | 2793 | preRangeVcselPeriod = 18; |
nikapov | 0:a1a69d32f310 | 2794 | finalRangeVcselPeriod = 14; |
nikapov | 0:a1a69d32f310 | 2795 | /* break; |
nikapov | 0:a1a69d32f310 | 2796 | case HIGH_ACCURACY: |
sepp_nepp | 11:c6f95a42d4d7 | 2797 | signalLimit = (TFP1616)(0.25*65536); |
sepp_nepp | 11:c6f95a42d4d7 | 2798 | sigmaLimit = (TFP1616)(18*65536); |
nikapov | 0:a1a69d32f310 | 2799 | timingBudget = 200000; |
nikapov | 0:a1a69d32f310 | 2800 | preRangeVcselPeriod = 14; |
nikapov | 0:a1a69d32f310 | 2801 | finalRangeVcselPeriod = 10; |
nikapov | 0:a1a69d32f310 | 2802 | break; |
nikapov | 0:a1a69d32f310 | 2803 | case HIGH_SPEED: |
sepp_nepp | 11:c6f95a42d4d7 | 2804 | signalLimit = (TFP1616)(0.25*65536); |
sepp_nepp | 11:c6f95a42d4d7 | 2805 | sigmaLimit = (TFP1616)(32*65536); |
nikapov | 0:a1a69d32f310 | 2806 | timingBudget = 20000; |
nikapov | 0:a1a69d32f310 | 2807 | preRangeVcselPeriod = 14; |
nikapov | 0:a1a69d32f310 | 2808 | finalRangeVcselPeriod = 10; |
nikapov | 0:a1a69d32f310 | 2809 | break; |
nikapov | 0:a1a69d32f310 | 2810 | default: |
nikapov | 0:a1a69d32f310 | 2811 | debug_printf("Not Supported"); |
nikapov | 0:a1a69d32f310 | 2812 | } |
nikapov | 0:a1a69d32f310 | 2813 | */ |
nikapov | 0:a1a69d32f310 | 2814 | |
sepp_nepp | 11:c6f95a42d4d7 | 2815 | if (ErrState == VL53L0X_OK) |
sepp_nepp | 11:c6f95a42d4d7 | 2816 | { Set_limit_chk_val(VL53L0X_CHECKEN_SIG_RATE_FINAL_RANGE,signalLimit);} |
sepp_nepp | 11:c6f95a42d4d7 | 2817 | |
sepp_nepp | 11:c6f95a42d4d7 | 2818 | if (ErrState == VL53L0X_OK) |
sepp_nepp | 11:c6f95a42d4d7 | 2819 | { Set_limit_chk_val(VL53L0X_CHECKEN_SIGMA_FINAL_RANGE,sigmaLimit);} |
sepp_nepp | 11:c6f95a42d4d7 | 2820 | |
sepp_nepp | 11:c6f95a42d4d7 | 2821 | if (ErrState == VL53L0X_OK) |
sepp_nepp | 11:c6f95a42d4d7 | 2822 | { Set_Measure_Time_Budget_us(timingBudget);} |
sepp_nepp | 11:c6f95a42d4d7 | 2823 | |
sepp_nepp | 11:c6f95a42d4d7 | 2824 | if (ErrState == VL53L0X_OK) |
sepp_nepp | 11:c6f95a42d4d7 | 2825 | { Set_vcsel_PPeriod(VL53L0X_VCSEL_PRE_RANGE,preRangeVcselPeriod); } |
sepp_nepp | 11:c6f95a42d4d7 | 2826 | |
sepp_nepp | 11:c6f95a42d4d7 | 2827 | if (ErrState == VL53L0X_OK) |
sepp_nepp | 11:c6f95a42d4d7 | 2828 | { Set_vcsel_PPeriod(VL53L0X_VCSEL_FINAL_RANGE,finalRangeVcselPeriod);} |
sepp_nepp | 11:c6f95a42d4d7 | 2829 | |
sepp_nepp | 11:c6f95a42d4d7 | 2830 | if (ErrState == VL53L0X_OK) |
sepp_nepp | 11:c6f95a42d4d7 | 2831 | { Perf_Ref_calibration(&VhvSettings,&PhaseCal,1); } |
sepp_nepp | 11:c6f95a42d4d7 | 2832 | break; |
sepp_nepp | 11:c6f95a42d4d7 | 2833 | case op_poll: // Setup in continuous ranging mode |
sepp_nepp | 11:c6f95a42d4d7 | 2834 | Set_device_mode(VL53L0X_DEVICEMODE_CONTINUOUS_RANGING); |
sepp_nepp | 11:c6f95a42d4d7 | 2835 | Start_Measurement(); |
sepp_nepp | 11:c6f95a42d4d7 | 2836 | } // switch |
sepp_nepp | 11:c6f95a42d4d7 | 2837 | return ErrState; |
sepp_nepp | 11:c6f95a42d4d7 | 2838 | } |
sepp_nepp | 11:c6f95a42d4d7 | 2839 | |
sepp_nepp | 11:c6f95a42d4d7 | 2840 | VL53L0X_Error VL53L0X::Stop_Measurement(TOperatingMode operating_mode) |
sepp_nepp | 11:c6f95a42d4d7 | 2841 | { if ((ErrState == VL53L0X_OK) & |
sepp_nepp | 11:c6f95a42d4d7 | 2842 | (operating_mode == op_INT || operating_mode == op_poll) ) |
sepp_nepp | 11:c6f95a42d4d7 | 2843 | { // only stop if in one of the continuous modes !!!! |
sepp_nepp | 11:c6f95a42d4d7 | 2844 | Stop_Measurement(); |
sepp_nepp | 11:c6f95a42d4d7 | 2845 | Wait_Stop_Completed(); |
sepp_nepp | 11:c6f95a42d4d7 | 2846 | Clear_interrupt_mask( REG_SYSINT_GPIO_NEW_SAMPLE_READY); |
sepp_nepp | 11:c6f95a42d4d7 | 2847 | } |
sepp_nepp | 11:c6f95a42d4d7 | 2848 | return ErrState; |
sepp_nepp | 11:c6f95a42d4d7 | 2849 | } |
sepp_nepp | 11:c6f95a42d4d7 | 2850 | |
sepp_nepp | 11:c6f95a42d4d7 | 2851 | TRangeResults VL53L0X::Handle_irq(TOperatingMode operating_mode) |
sepp_nepp | 11:c6f95a42d4d7 | 2852 | { TRangeResults RangeResults; |
sepp_nepp | 11:c6f95a42d4d7 | 2853 | RangeResults = Get_Measurement(operating_mode); |
sepp_nepp | 11:c6f95a42d4d7 | 2854 | Enable_interrupt_measure_detection_irq(); |
sepp_nepp | 11:c6f95a42d4d7 | 2855 | return RangeResults; |
sepp_nepp | 11:c6f95a42d4d7 | 2856 | } |
sepp_nepp | 11:c6f95a42d4d7 | 2857 | |
sepp_nepp | 11:c6f95a42d4d7 | 2858 | /****************** Private device functions *************************/ |
sepp_nepp | 11:c6f95a42d4d7 | 2859 | |
sepp_nepp | 11:c6f95a42d4d7 | 2860 | void VL53L0X::Wait_read_strobe() |
sepp_nepp | 11:c6f95a42d4d7 | 2861 | { uint32_t loop_nb = 0; |
sepp_nepp | 11:c6f95a42d4d7 | 2862 | |
sepp_nepp | 11:c6f95a42d4d7 | 2863 | Write_Byte(0x83,0x00); // set strobe register to 0 |
sepp_nepp | 11:c6f95a42d4d7 | 2864 | |
sepp_nepp | 11:c6f95a42d4d7 | 2865 | /* polling while no error, no strobe, and not reached max number of loop to avoid deadlock*/ |
sepp_nepp | 11:c6f95a42d4d7 | 2866 | while ((ErrState == VL53L0X_OK) && (Read_Byte(0x83) == 0x00) ) |
sepp_nepp | 11:c6f95a42d4d7 | 2867 | { if (loop_nb++ >= VL53L0X_DEFAULT_MAX_LOOP) |
sepp_nepp | 11:c6f95a42d4d7 | 2868 | { ErrState = VL53L0X_ERROR_TIME_OUT; } } |
sepp_nepp | 11:c6f95a42d4d7 | 2869 | |
sepp_nepp | 11:c6f95a42d4d7 | 2870 | Write_Byte(0x83,0x01); // set strobe register back to 1 'manually' |
nikapov | 0:a1a69d32f310 | 2871 | } |
nikapov | 0:a1a69d32f310 | 2872 | |
sepp_nepp | 11:c6f95a42d4d7 | 2873 | void VL53L0X::Get_info_from_device(uint8_t option) |
sepp_nepp | 11:c6f95a42d4d7 | 2874 | { uint8_t byte; |
sepp_nepp | 11:c6f95a42d4d7 | 2875 | uint32_t tmp_dword; |
sepp_nepp | 11:c6f95a42d4d7 | 2876 | uint8_t module_id; |
sepp_nepp | 11:c6f95a42d4d7 | 2877 | uint8_t revision; |
sepp_nepp | 11:c6f95a42d4d7 | 2878 | uint8_t reference_SPAD_count = 0; |
sepp_nepp | 11:c6f95a42d4d7 | 2879 | uint8_t reference_SPAD_type = 0; |
sepp_nepp | 11:c6f95a42d4d7 | 2880 | uint32_t part_uid_upper = 0; |
sepp_nepp | 11:c6f95a42d4d7 | 2881 | uint32_t part_uid_lower = 0; |
sepp_nepp | 11:c6f95a42d4d7 | 2882 | uint32_t offset_fixed1104_mm = 0; |
sepp_nepp | 11:c6f95a42d4d7 | 2883 | int16_t offset_um = 0; |
sepp_nepp | 11:c6f95a42d4d7 | 2884 | uint32_t dist_meas_tgt_fixed1104_mm = 400 << 4; |
sepp_nepp | 11:c6f95a42d4d7 | 2885 | uint32_t dist_meas_fixed1104_400_mm = 0; |
sepp_nepp | 11:c6f95a42d4d7 | 2886 | uint32_t signal_rate_meas_fixed1104_400_mm = 0; |
sepp_nepp | 11:c6f95a42d4d7 | 2887 | char product_id[19]; |
sepp_nepp | 11:c6f95a42d4d7 | 2888 | uint8_t read_data_from_device_done; |
sepp_nepp | 11:c6f95a42d4d7 | 2889 | TFP1616 signal_rate_meas_fixed400_mm_fix = 0; |
sepp_nepp | 11:c6f95a42d4d7 | 2890 | uint8_t nvm_Ref_good_SPAD_map[REF_SPAD_BUFFER_SIZE]; |
sepp_nepp | 11:c6f95a42d4d7 | 2891 | int i; |
sepp_nepp | 11:c6f95a42d4d7 | 2892 | |
sepp_nepp | 11:c6f95a42d4d7 | 2893 | read_data_from_device_done = DevSpecParams.ReadDataFromDeviceDone; |
sepp_nepp | 11:c6f95a42d4d7 | 2894 | |
sepp_nepp | 11:c6f95a42d4d7 | 2895 | /* This access is done only once after that a GetDeviceInfo or datainit is done*/ |
sepp_nepp | 11:c6f95a42d4d7 | 2896 | if (read_data_from_device_done != 7) { |
sepp_nepp | 11:c6f95a42d4d7 | 2897 | Write_Byte(0x80,0x01); |
sepp_nepp | 11:c6f95a42d4d7 | 2898 | Write_Byte(0xFF,0x01); |
sepp_nepp | 11:c6f95a42d4d7 | 2899 | Write_Byte(0x00,0x00); |
sepp_nepp | 11:c6f95a42d4d7 | 2900 | Write_Byte(0xFF,0x06); |
sepp_nepp | 11:c6f95a42d4d7 | 2901 | byte = Read_Byte(0x83); |
sepp_nepp | 11:c6f95a42d4d7 | 2902 | Write_Byte(0x83,byte | 4); |
sepp_nepp | 11:c6f95a42d4d7 | 2903 | Write_Byte(0xFF,0x07); |
sepp_nepp | 11:c6f95a42d4d7 | 2904 | Write_Byte(0x81,0x01); |
sepp_nepp | 11:c6f95a42d4d7 | 2905 | Polling_delay(); // warning, does nothing!! |
sepp_nepp | 11:c6f95a42d4d7 | 2906 | Write_Byte(0x80,0x01); |
sepp_nepp | 11:c6f95a42d4d7 | 2907 | |
sepp_nepp | 11:c6f95a42d4d7 | 2908 | if (((option & 1) == 1) && |
sepp_nepp | 11:c6f95a42d4d7 | 2909 | ((read_data_from_device_done & 1) == 0)) { |
sepp_nepp | 11:c6f95a42d4d7 | 2910 | Write_Byte(0x94,0x6b); |
sepp_nepp | 11:c6f95a42d4d7 | 2911 | Wait_read_strobe(); |
sepp_nepp | 11:c6f95a42d4d7 | 2912 | tmp_dword = Read_DWord(0x90); |
sepp_nepp | 11:c6f95a42d4d7 | 2913 | reference_SPAD_count = (uint8_t)((tmp_dword >> 8) & 0x7f); |
sepp_nepp | 11:c6f95a42d4d7 | 2914 | reference_SPAD_type = (uint8_t)((tmp_dword >> 15) & 0x01); |
sepp_nepp | 11:c6f95a42d4d7 | 2915 | |
sepp_nepp | 11:c6f95a42d4d7 | 2916 | Write_Byte(0x94,0x24); |
sepp_nepp | 11:c6f95a42d4d7 | 2917 | Wait_read_strobe(); |
sepp_nepp | 11:c6f95a42d4d7 | 2918 | tmp_dword = Read_DWord(0x90); |
sepp_nepp | 11:c6f95a42d4d7 | 2919 | nvm_Ref_good_SPAD_map[0] = (uint8_t)((tmp_dword >> 24)& 0xff); |
sepp_nepp | 11:c6f95a42d4d7 | 2920 | nvm_Ref_good_SPAD_map[1] = (uint8_t)((tmp_dword >> 16)& 0xff); |
sepp_nepp | 11:c6f95a42d4d7 | 2921 | nvm_Ref_good_SPAD_map[2] = (uint8_t)((tmp_dword >> 8)& 0xff); |
sepp_nepp | 11:c6f95a42d4d7 | 2922 | nvm_Ref_good_SPAD_map[3] = (uint8_t)(tmp_dword & 0xff); |
sepp_nepp | 11:c6f95a42d4d7 | 2923 | |
sepp_nepp | 11:c6f95a42d4d7 | 2924 | Write_Byte(0x94,0x25); |
sepp_nepp | 11:c6f95a42d4d7 | 2925 | Wait_read_strobe(); |
sepp_nepp | 11:c6f95a42d4d7 | 2926 | tmp_dword = Read_DWord(0x90); |
sepp_nepp | 11:c6f95a42d4d7 | 2927 | nvm_Ref_good_SPAD_map[4] = (uint8_t)((tmp_dword >> 24)& 0xff); |
sepp_nepp | 11:c6f95a42d4d7 | 2928 | nvm_Ref_good_SPAD_map[5] = (uint8_t)((tmp_dword >> 16)& 0xff); |
nikapov | 0:a1a69d32f310 | 2929 | } |
sepp_nepp | 11:c6f95a42d4d7 | 2930 | |
sepp_nepp | 11:c6f95a42d4d7 | 2931 | if (((option & 2) == 2) && ((read_data_from_device_done & 2) == 0)) { |
sepp_nepp | 11:c6f95a42d4d7 | 2932 | Write_Byte(0x94,0x02); |
sepp_nepp | 11:c6f95a42d4d7 | 2933 | Wait_read_strobe(); |
sepp_nepp | 11:c6f95a42d4d7 | 2934 | module_id = Read_Byte(0x90); |
sepp_nepp | 11:c6f95a42d4d7 | 2935 | |
sepp_nepp | 11:c6f95a42d4d7 | 2936 | Write_Byte(0x94,0x7B); |
sepp_nepp | 11:c6f95a42d4d7 | 2937 | Wait_read_strobe(); |
sepp_nepp | 11:c6f95a42d4d7 | 2938 | revision = Read_Byte(0x90); |
sepp_nepp | 11:c6f95a42d4d7 | 2939 | |
sepp_nepp | 11:c6f95a42d4d7 | 2940 | Write_Byte(0x94,0x77); |
sepp_nepp | 11:c6f95a42d4d7 | 2941 | Wait_read_strobe(); |
sepp_nepp | 11:c6f95a42d4d7 | 2942 | tmp_dword = Read_DWord(0x90); |
sepp_nepp | 11:c6f95a42d4d7 | 2943 | product_id[0] = (char)((tmp_dword >> 25) & 0x07f); |
sepp_nepp | 11:c6f95a42d4d7 | 2944 | product_id[1] = (char)((tmp_dword >> 18) & 0x07f); |
sepp_nepp | 11:c6f95a42d4d7 | 2945 | product_id[2] = (char)((tmp_dword >> 11) & 0x07f); |
sepp_nepp | 11:c6f95a42d4d7 | 2946 | product_id[3] = (char)((tmp_dword >> 4) & 0x07f); |
sepp_nepp | 11:c6f95a42d4d7 | 2947 | |
sepp_nepp | 11:c6f95a42d4d7 | 2948 | byte = (uint8_t)((tmp_dword & 0x00f) << 3); |
sepp_nepp | 11:c6f95a42d4d7 | 2949 | |
sepp_nepp | 11:c6f95a42d4d7 | 2950 | Write_Byte(0x94,0x78); |
sepp_nepp | 11:c6f95a42d4d7 | 2951 | Wait_read_strobe(); |
sepp_nepp | 11:c6f95a42d4d7 | 2952 | tmp_dword = Read_DWord(0x90); |
sepp_nepp | 11:c6f95a42d4d7 | 2953 | product_id[4] = (char)(byte +((tmp_dword >> 29) & 0x07f)); |
sepp_nepp | 11:c6f95a42d4d7 | 2954 | product_id[5] = (char)((tmp_dword >> 22) & 0x07f); |
sepp_nepp | 11:c6f95a42d4d7 | 2955 | product_id[6] = (char)((tmp_dword >> 15) & 0x07f); |
sepp_nepp | 11:c6f95a42d4d7 | 2956 | product_id[7] = (char)((tmp_dword >> 8) & 0x07f); |
sepp_nepp | 11:c6f95a42d4d7 | 2957 | product_id[8] = (char)((tmp_dword >> 1) & 0x07f); |
sepp_nepp | 11:c6f95a42d4d7 | 2958 | byte = (uint8_t)((tmp_dword & 0x001) << 6); |
sepp_nepp | 11:c6f95a42d4d7 | 2959 | |
sepp_nepp | 11:c6f95a42d4d7 | 2960 | Write_Byte(0x94,0x79); |
sepp_nepp | 11:c6f95a42d4d7 | 2961 | Wait_read_strobe(); |
sepp_nepp | 11:c6f95a42d4d7 | 2962 | tmp_dword = Read_DWord(0x90); |
sepp_nepp | 11:c6f95a42d4d7 | 2963 | product_id[9] = (char)(byte +((tmp_dword >> 26) & 0x07f)); |
sepp_nepp | 11:c6f95a42d4d7 | 2964 | product_id[10] = (char)((tmp_dword >> 19) & 0x07f); |
sepp_nepp | 11:c6f95a42d4d7 | 2965 | product_id[11] = (char)((tmp_dword >> 12) & 0x07f); |
sepp_nepp | 11:c6f95a42d4d7 | 2966 | product_id[12] = (char)((tmp_dword >> 5) & 0x07f); |
sepp_nepp | 11:c6f95a42d4d7 | 2967 | |
sepp_nepp | 11:c6f95a42d4d7 | 2968 | byte = (uint8_t)((tmp_dword & 0x01f) << 2); |
sepp_nepp | 11:c6f95a42d4d7 | 2969 | |
sepp_nepp | 11:c6f95a42d4d7 | 2970 | Write_Byte(0x94,0x7A); |
sepp_nepp | 11:c6f95a42d4d7 | 2971 | Wait_read_strobe(); |
sepp_nepp | 11:c6f95a42d4d7 | 2972 | tmp_dword = Read_DWord(0x90); |
sepp_nepp | 11:c6f95a42d4d7 | 2973 | product_id[13] = (char)(byte +((tmp_dword >> 30) & 0x07f)); |
sepp_nepp | 11:c6f95a42d4d7 | 2974 | product_id[14] = (char)((tmp_dword >> 23) & 0x07f); |
sepp_nepp | 11:c6f95a42d4d7 | 2975 | product_id[15] = (char)((tmp_dword >> 16) & 0x07f); |
sepp_nepp | 11:c6f95a42d4d7 | 2976 | product_id[16] = (char)((tmp_dword >> 9) & 0x07f); |
sepp_nepp | 11:c6f95a42d4d7 | 2977 | product_id[17] = (char)((tmp_dword >> 2) & 0x07f); |
sepp_nepp | 11:c6f95a42d4d7 | 2978 | product_id[18] = '\0'; |
sepp_nepp | 11:c6f95a42d4d7 | 2979 | } |
sepp_nepp | 11:c6f95a42d4d7 | 2980 | |
sepp_nepp | 11:c6f95a42d4d7 | 2981 | if (((option & 4) == 4) && ((read_data_from_device_done & 4) == 0)) |
sepp_nepp | 11:c6f95a42d4d7 | 2982 | { Write_Byte(0x94,0x7B); |
sepp_nepp | 11:c6f95a42d4d7 | 2983 | Wait_read_strobe(); |
sepp_nepp | 11:c6f95a42d4d7 | 2984 | part_uid_upper = Read_DWord(0x90); |
sepp_nepp | 11:c6f95a42d4d7 | 2985 | |
sepp_nepp | 11:c6f95a42d4d7 | 2986 | Write_Byte(0x94,0x7C); |
sepp_nepp | 11:c6f95a42d4d7 | 2987 | Wait_read_strobe(); |
sepp_nepp | 11:c6f95a42d4d7 | 2988 | part_uid_lower = Read_DWord(0x90); |
sepp_nepp | 11:c6f95a42d4d7 | 2989 | |
sepp_nepp | 11:c6f95a42d4d7 | 2990 | Write_Byte(0x94,0x73); |
sepp_nepp | 11:c6f95a42d4d7 | 2991 | Wait_read_strobe(); |
sepp_nepp | 11:c6f95a42d4d7 | 2992 | tmp_dword = Read_DWord(0x90); |
sepp_nepp | 11:c6f95a42d4d7 | 2993 | signal_rate_meas_fixed1104_400_mm = (tmp_dword & 0x0000000ff) << 8; |
sepp_nepp | 11:c6f95a42d4d7 | 2994 | |
sepp_nepp | 11:c6f95a42d4d7 | 2995 | Write_Byte(0x94,0x74); |
sepp_nepp | 11:c6f95a42d4d7 | 2996 | Wait_read_strobe(); |
sepp_nepp | 11:c6f95a42d4d7 | 2997 | tmp_dword = Read_DWord(0x90); |
sepp_nepp | 11:c6f95a42d4d7 | 2998 | signal_rate_meas_fixed1104_400_mm |= ((tmp_dword & |
sepp_nepp | 11:c6f95a42d4d7 | 2999 | 0xff000000) >> 24); |
sepp_nepp | 11:c6f95a42d4d7 | 3000 | |
sepp_nepp | 11:c6f95a42d4d7 | 3001 | Write_Byte(0x94,0x75); |
sepp_nepp | 11:c6f95a42d4d7 | 3002 | Wait_read_strobe(); |
sepp_nepp | 11:c6f95a42d4d7 | 3003 | tmp_dword = Read_DWord(0x90); |
sepp_nepp | 11:c6f95a42d4d7 | 3004 | dist_meas_fixed1104_400_mm = (tmp_dword & 0x0000000ff)<< 8; |
sepp_nepp | 11:c6f95a42d4d7 | 3005 | |
sepp_nepp | 11:c6f95a42d4d7 | 3006 | Write_Byte(0x94,0x76); |
sepp_nepp | 11:c6f95a42d4d7 | 3007 | Wait_read_strobe(); |
sepp_nepp | 11:c6f95a42d4d7 | 3008 | tmp_dword = Read_DWord(0x90); |
sepp_nepp | 11:c6f95a42d4d7 | 3009 | dist_meas_fixed1104_400_mm |= ((tmp_dword & 0xff000000) >> 24); |
sepp_nepp | 11:c6f95a42d4d7 | 3010 | } |
sepp_nepp | 11:c6f95a42d4d7 | 3011 | |
sepp_nepp | 11:c6f95a42d4d7 | 3012 | Write_Byte(0x81,0x00); |
sepp_nepp | 11:c6f95a42d4d7 | 3013 | Write_Byte(0xFF,0x06); |
sepp_nepp | 11:c6f95a42d4d7 | 3014 | Write_Byte(0x83,Read_Byte(0x83) & 0xfb); |
sepp_nepp | 11:c6f95a42d4d7 | 3015 | Write_Byte(0xFF,0x01); |
sepp_nepp | 11:c6f95a42d4d7 | 3016 | Write_Byte(0x00,0x01); |
sepp_nepp | 11:c6f95a42d4d7 | 3017 | Write_Byte(0xFF,0x00); |
sepp_nepp | 11:c6f95a42d4d7 | 3018 | Write_Byte(0x80,0x00); |
nikapov | 0:a1a69d32f310 | 3019 | } |
nikapov | 0:a1a69d32f310 | 3020 | |
sepp_nepp | 11:c6f95a42d4d7 | 3021 | if ((ErrState == VL53L0X_OK) && (read_data_from_device_done != 7)) { |
sepp_nepp | 11:c6f95a42d4d7 | 3022 | /* Assign to variable if ErrState is ok */ |
sepp_nepp | 11:c6f95a42d4d7 | 3023 | if (((option & 1) == 1) && ((read_data_from_device_done & 1) == 0)) |
sepp_nepp | 11:c6f95a42d4d7 | 3024 | { DevSpecParams.ReferenceSPADCount=reference_SPAD_count; |
sepp_nepp | 11:c6f95a42d4d7 | 3025 | DevSpecParams.ReferenceSPADType =reference_SPAD_type; |
sepp_nepp | 11:c6f95a42d4d7 | 3026 | for (i = 0; i < REF_SPAD_BUFFER_SIZE; i++) |
sepp_nepp | 11:c6f95a42d4d7 | 3027 | { SPADData.RefGoodSPADMap[i] = nvm_Ref_good_SPAD_map[i]; } |
sepp_nepp | 11:c6f95a42d4d7 | 3028 | } |
sepp_nepp | 11:c6f95a42d4d7 | 3029 | |
sepp_nepp | 11:c6f95a42d4d7 | 3030 | if (((option & 2) == 2) &&((read_data_from_device_done & 2) == 0)) |
sepp_nepp | 11:c6f95a42d4d7 | 3031 | { DevSpecParams.ModuleId = module_id; |
sepp_nepp | 11:c6f95a42d4d7 | 3032 | DevSpecParams.Revision = revision; |
sepp_nepp | 11:c6f95a42d4d7 | 3033 | strcpy(DevSpecParams.ProductId, product_id); |
sepp_nepp | 11:c6f95a42d4d7 | 3034 | } |
sepp_nepp | 11:c6f95a42d4d7 | 3035 | |
sepp_nepp | 11:c6f95a42d4d7 | 3036 | if (((option & 4) == 4) && ((read_data_from_device_done & 4) == 0)) { |
sepp_nepp | 11:c6f95a42d4d7 | 3037 | DevSpecParams.PartUIDUpper = part_uid_upper; |
sepp_nepp | 11:c6f95a42d4d7 | 3038 | DevSpecParams.PartUIDLower = part_uid_lower; |
sepp_nepp | 11:c6f95a42d4d7 | 3039 | signal_rate_meas_fixed400_mm_fix = |
sepp_nepp | 11:c6f95a42d4d7 | 3040 | FP97_TO_FP1616(signal_rate_meas_fixed1104_400_mm); |
sepp_nepp | 11:c6f95a42d4d7 | 3041 | DevSpecParams.SignalRateMeasFixed400mm = signal_rate_meas_fixed400_mm_fix; |
sepp_nepp | 11:c6f95a42d4d7 | 3042 | DevSpecParams.SignalRateMeasFixed400mm = signal_rate_meas_fixed400_mm_fix; |
sepp_nepp | 11:c6f95a42d4d7 | 3043 | |
sepp_nepp | 11:c6f95a42d4d7 | 3044 | offset_um = 0; |
sepp_nepp | 11:c6f95a42d4d7 | 3045 | if (dist_meas_fixed1104_400_mm != 0) { |
sepp_nepp | 11:c6f95a42d4d7 | 3046 | offset_fixed1104_mm = dist_meas_fixed1104_400_mm - |
sepp_nepp | 11:c6f95a42d4d7 | 3047 | dist_meas_tgt_fixed1104_mm; |
sepp_nepp | 11:c6f95a42d4d7 | 3048 | offset_um = (offset_fixed1104_mm * 1000) >> 4; |
sepp_nepp | 11:c6f95a42d4d7 | 3049 | offset_um *= -1; |
sepp_nepp | 11:c6f95a42d4d7 | 3050 | } |
sepp_nepp | 11:c6f95a42d4d7 | 3051 | NVM_Offset_Cal_um = offset_um; |
nikapov | 0:a1a69d32f310 | 3052 | } |
sepp_nepp | 11:c6f95a42d4d7 | 3053 | byte = (uint8_t)(read_data_from_device_done | option); |
sepp_nepp | 11:c6f95a42d4d7 | 3054 | DevSpecParams.ReadDataFromDeviceDone = byte; |
nikapov | 0:a1a69d32f310 | 3055 | } |
nikapov | 0:a1a69d32f310 | 3056 | } |
nikapov | 0:a1a69d32f310 | 3057 | |
nikapov | 0:a1a69d32f310 | 3058 | /******************************************************************************/ |
sepp_nepp | 11:c6f95a42d4d7 | 3059 | /****************** Small Service and wrapper functions **********************/ |
sepp_nepp | 11:c6f95a42d4d7 | 3060 | /******************************************************************************/ |
sepp_nepp | 11:c6f95a42d4d7 | 3061 | uint32_t refArrayQuadrants[4] = {REF_ARRAY_SPAD_10,REF_ARRAY_SPAD_5, |
sepp_nepp | 11:c6f95a42d4d7 | 3062 | REF_ARRAY_SPAD_0,REF_ARRAY_SPAD_5 }; |
sepp_nepp | 11:c6f95a42d4d7 | 3063 | |
sepp_nepp | 11:c6f95a42d4d7 | 3064 | |
sepp_nepp | 11:c6f95a42d4d7 | 3065 | uint32_t VL53L0X::Decode_timeout(uint16_t encoded_timeout) |
sepp_nepp | 11:c6f95a42d4d7 | 3066 | { /*Decode 16-bit timeout register value - format (LSByte * 2^MSByte) + 1 */ |
sepp_nepp | 11:c6f95a42d4d7 | 3067 | return ((uint32_t) (encoded_timeout & 0x00FF) |
sepp_nepp | 11:c6f95a42d4d7 | 3068 | << (uint32_t)((encoded_timeout & 0xFF00) >> 8)) + 1; |
sepp_nepp | 11:c6f95a42d4d7 | 3069 | } |
sepp_nepp | 11:c6f95a42d4d7 | 3070 | |
sepp_nepp | 11:c6f95a42d4d7 | 3071 | uint8_t VL53L0X::Is_ApertureSPAD(uint32_t SPAD_index) |
sepp_nepp | 11:c6f95a42d4d7 | 3072 | { /* This function reports if a given SPAD index is an aperture SPAD by |
sepp_nepp | 11:c6f95a42d4d7 | 3073 | * deriving the quadrant = SPAD_index >> 6. */ |
sepp_nepp | 11:c6f95a42d4d7 | 3074 | if (refArrayQuadrants[SPAD_index >> 6] == REF_ARRAY_SPAD_0) |
sepp_nepp | 11:c6f95a42d4d7 | 3075 | { return 0; } else { return 1; } |
sepp_nepp | 11:c6f95a42d4d7 | 3076 | } |
sepp_nepp | 11:c6f95a42d4d7 | 3077 | |
sepp_nepp | 11:c6f95a42d4d7 | 3078 | /******************************************************************************/ |
sepp_nepp | 11:c6f95a42d4d7 | 3079 | /****************** Write and read functions from I2C *************************/ |
sepp_nepp | 11:c6f95a42d4d7 | 3080 | /******************************************************************************/ |
sepp_nepp | 11:c6f95a42d4d7 | 3081 | |
sepp_nepp | 11:c6f95a42d4d7 | 3082 | void VL53L0X::Write_Byte(uint8_t index, uint8_t data) |
sepp_nepp | 11:c6f95a42d4d7 | 3083 | { I2c_Write(index,&data,1); } |
sepp_nepp | 11:c6f95a42d4d7 | 3084 | |
sepp_nepp | 11:c6f95a42d4d7 | 3085 | void VL53L0X::Write_Word(uint8_t index,uint16_t data) |
sepp_nepp | 11:c6f95a42d4d7 | 3086 | { uint8_t buffer[2]; |
sepp_nepp | 11:c6f95a42d4d7 | 3087 | buffer[0] = data >> 8; |
sepp_nepp | 11:c6f95a42d4d7 | 3088 | buffer[1] = data & 0x00FF; |
sepp_nepp | 11:c6f95a42d4d7 | 3089 | I2c_Write(index,(uint8_t *)buffer,2); |
sepp_nepp | 11:c6f95a42d4d7 | 3090 | } |
sepp_nepp | 11:c6f95a42d4d7 | 3091 | |
sepp_nepp | 11:c6f95a42d4d7 | 3092 | void VL53L0X::Write_DWord(uint8_t index, uint32_t data) |
sepp_nepp | 11:c6f95a42d4d7 | 3093 | { uint8_t buffer[4]; |
sepp_nepp | 11:c6f95a42d4d7 | 3094 | buffer[0] = (data >> 24) & 0xFF; |
sepp_nepp | 11:c6f95a42d4d7 | 3095 | buffer[1] = (data >> 16) & 0xFF; |
sepp_nepp | 11:c6f95a42d4d7 | 3096 | buffer[2] = (data >> 8) & 0xFF; |
sepp_nepp | 11:c6f95a42d4d7 | 3097 | buffer[3] = (data >> 0) & 0xFF; |
sepp_nepp | 11:c6f95a42d4d7 | 3098 | I2c_Write(index,(uint8_t *)buffer,4); |
sepp_nepp | 11:c6f95a42d4d7 | 3099 | } |
sepp_nepp | 11:c6f95a42d4d7 | 3100 | |
sepp_nepp | 11:c6f95a42d4d7 | 3101 | uint8_t VL53L0X::Read_Byte(uint8_t index) |
sepp_nepp | 11:c6f95a42d4d7 | 3102 | { uint8_t result; |
sepp_nepp | 11:c6f95a42d4d7 | 3103 | I2c_Read(index,&result,1); |
sepp_nepp | 11:c6f95a42d4d7 | 3104 | return result; |
sepp_nepp | 11:c6f95a42d4d7 | 3105 | } |
sepp_nepp | 11:c6f95a42d4d7 | 3106 | |
sepp_nepp | 11:c6f95a42d4d7 | 3107 | uint16_t VL53L0X::Read_Word(uint8_t index) |
sepp_nepp | 11:c6f95a42d4d7 | 3108 | { uint8_t buffer[2] = {0,0}; |
sepp_nepp | 11:c6f95a42d4d7 | 3109 | I2c_Read(index, &buffer[0], 2); |
sepp_nepp | 11:c6f95a42d4d7 | 3110 | return (buffer[0] << 8) + buffer[1]; |
sepp_nepp | 11:c6f95a42d4d7 | 3111 | } |
sepp_nepp | 11:c6f95a42d4d7 | 3112 | |
sepp_nepp | 11:c6f95a42d4d7 | 3113 | uint32_t VL53L0X::Read_DWord(uint8_t index) |
sepp_nepp | 11:c6f95a42d4d7 | 3114 | { uint8_t buffer[4] = {0,0,0,0}; |
sepp_nepp | 11:c6f95a42d4d7 | 3115 | I2c_Read(index,buffer,4); |
sepp_nepp | 11:c6f95a42d4d7 | 3116 | return (buffer[0] << 24) + (buffer[1] << 16) + (buffer[2] << 8) + buffer[3]; |
sepp_nepp | 11:c6f95a42d4d7 | 3117 | } |
sepp_nepp | 11:c6f95a42d4d7 | 3118 | |
sepp_nepp | 11:c6f95a42d4d7 | 3119 | void VL53L0X::Register_BitMask(uint8_t index,uint8_t and_mask,uint8_t or_mask) |
sepp_nepp | 11:c6f95a42d4d7 | 3120 | { uint8_t buffer = 0; |
sepp_nepp | 11:c6f95a42d4d7 | 3121 | /* read data direct onto buffer */ |
sepp_nepp | 11:c6f95a42d4d7 | 3122 | I2c_Read(index,&buffer,1); |
sepp_nepp | 11:c6f95a42d4d7 | 3123 | if (ErrState==VL53L0X_OK) { |
sepp_nepp | 11:c6f95a42d4d7 | 3124 | buffer = (buffer & and_mask) | or_mask; |
sepp_nepp | 11:c6f95a42d4d7 | 3125 | I2c_Write(index,&buffer,(uint8_t)1); |
sepp_nepp | 11:c6f95a42d4d7 | 3126 | } |
sepp_nepp | 11:c6f95a42d4d7 | 3127 | } |
sepp_nepp | 11:c6f95a42d4d7 | 3128 | |
sepp_nepp | 11:c6f95a42d4d7 | 3129 | /** |
sepp_nepp | 11:c6f95a42d4d7 | 3130 | * @brief Writes a buffer towards the I2C peripheral device. |
sepp_nepp | 11:c6f95a42d4d7 | 3131 | * @param RegisterAddr specifies the internal address register |
sepp_nepp | 11:c6f95a42d4d7 | 3132 | * @param p_data pointer to the byte-array data to send |
sepp_nepp | 11:c6f95a42d4d7 | 3133 | * where to start writing to (must be correctly masked). |
sepp_nepp | 11:c6f95a42d4d7 | 3134 | * @param NumByteToWrite number of bytes to be written. |
sepp_nepp | 11:c6f95a42d4d7 | 3135 | * @note On some devices if NumByteToWrite is greater |
sepp_nepp | 11:c6f95a42d4d7 | 3136 | * than one, the RegisterAddr must be masked correctly! */ |
sepp_nepp | 11:c6f95a42d4d7 | 3137 | void VL53L0X::I2c_Write( uint8_t RegisterAddr, uint8_t *p_data, |
sepp_nepp | 11:c6f95a42d4d7 | 3138 | uint16_t NumByteToWrite ) |
sepp_nepp | 11:c6f95a42d4d7 | 3139 | { int ret; |
sepp_nepp | 11:c6f95a42d4d7 | 3140 | uint8_t tmp[TEMP_BUF_SIZE]; |
sepp_nepp | 11:c6f95a42d4d7 | 3141 | |
sepp_nepp | 11:c6f95a42d4d7 | 3142 | if (ErrState != VL53L0X_OK) {return; } // no comms while in Error State!!!! |
sepp_nepp | 11:c6f95a42d4d7 | 3143 | |
sepp_nepp | 11:c6f95a42d4d7 | 3144 | if (NumByteToWrite >= TEMP_BUF_SIZE) |
sepp_nepp | 11:c6f95a42d4d7 | 3145 | {ErrState = VL53L0X_ERROR_I2C_BUF_OVERFLOW; return; }; |
sepp_nepp | 11:c6f95a42d4d7 | 3146 | |
sepp_nepp | 11:c6f95a42d4d7 | 3147 | /* First, send device address. Then, send data and terminate with STOP condition */ |
sepp_nepp | 11:c6f95a42d4d7 | 3148 | tmp[0] = RegisterAddr; |
sepp_nepp | 11:c6f95a42d4d7 | 3149 | memcpy(tmp+1, p_data, NumByteToWrite); |
sepp_nepp | 11:c6f95a42d4d7 | 3150 | ret = _dev_i2c->write(I2cDevAddr, (const char*)tmp, NumByteToWrite+1, false); |
sepp_nepp | 11:c6f95a42d4d7 | 3151 | |
sepp_nepp | 11:c6f95a42d4d7 | 3152 | if (ret) { ErrState = VL53L0X_ERROR_CONTROL_INTERFACE; } |
sepp_nepp | 11:c6f95a42d4d7 | 3153 | } |
sepp_nepp | 11:c6f95a42d4d7 | 3154 | |
sepp_nepp | 11:c6f95a42d4d7 | 3155 | /**@brief Reads a buffer from the I2C peripheral device. |
sepp_nepp | 11:c6f95a42d4d7 | 3156 | * @param pBuffer pointer to the byte-array to read data in to |
sepp_nepp | 11:c6f95a42d4d7 | 3157 | * @param I2cDevAddr specifies the peripheral device slave address. |
sepp_nepp | 11:c6f95a42d4d7 | 3158 | * @param RegisterAddr specifies the internal address register |
sepp_nepp | 11:c6f95a42d4d7 | 3159 | * where to start reading from (must be correctly masked). |
sepp_nepp | 11:c6f95a42d4d7 | 3160 | * @param NumByteToRead number of bytes to be read, maximum VL53L0X_MAX_I2C_XFER_SIZE |
sepp_nepp | 11:c6f95a42d4d7 | 3161 | * @note On some devices if NumByteToWrite is greater |
sepp_nepp | 11:c6f95a42d4d7 | 3162 | * than one, the RegisterAddr must be masked correctly! |
sepp_nepp | 11:c6f95a42d4d7 | 3163 | */ |
sepp_nepp | 11:c6f95a42d4d7 | 3164 | void VL53L0X::I2c_Read(uint8_t RegisterAddr, uint8_t *p_data, |
sepp_nepp | 11:c6f95a42d4d7 | 3165 | uint16_t NumByteToRead) |
sepp_nepp | 11:c6f95a42d4d7 | 3166 | { int ret; |
sepp_nepp | 11:c6f95a42d4d7 | 3167 | if (ErrState != VL53L0X_OK) {return; } // no comms while in Error State, return value undefined!!!! |
sepp_nepp | 11:c6f95a42d4d7 | 3168 | |
sepp_nepp | 11:c6f95a42d4d7 | 3169 | /* Send device address, without STOP condition */ |
sepp_nepp | 11:c6f95a42d4d7 | 3170 | ret = _dev_i2c->write(I2cDevAddr, (const char*)&RegisterAddr, 1, true); |
sepp_nepp | 11:c6f95a42d4d7 | 3171 | if(!ret) /* Read data, with STOP condition */ |
sepp_nepp | 11:c6f95a42d4d7 | 3172 | { ret = _dev_i2c->read(I2cDevAddr, (char*)p_data, NumByteToRead, false); } |
sepp_nepp | 11:c6f95a42d4d7 | 3173 | |
sepp_nepp | 11:c6f95a42d4d7 | 3174 | if (ret) { ErrState = VL53L0X_ERROR_CONTROL_INTERFACE; } |
sepp_nepp | 11:c6f95a42d4d7 | 3175 | } |
sepp_nepp | 11:c6f95a42d4d7 | 3176 | |
sepp_nepp | 11:c6f95a42d4d7 | 3177 | /******************************************************************************/ |