Thundersoft
/
VL6180XA1_for_TT_Mxx
Creating a project about VL6180XA1 for TT_Mxx
VL6180XA1/VL6180X/VL6180X.cpp@3:7a97a01bad5e, 2019-04-26 (annotated)
- Committer:
- ThunderSoft
- Date:
- Fri Apr 26 09:34:53 2019 +0000
- Revision:
- 3:7a97a01bad5e
- Parent:
- 2:8343c9a07b66
"update the mbed-os code to support TT_M4G9"
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
ThunderSoft | 0:293917667c17 | 1 | #include <VL6180X.h> |
ThunderSoft | 1:46408c6b6d96 | 2 | //#include "dm_platform.h" |
ThunderSoft | 0:293917667c17 | 3 | #include "common_define.h" |
ThunderSoft | 0:293917667c17 | 4 | // Defines ///////////////////////////////////////////////////////////////////// |
ThunderSoft | 0:293917667c17 | 5 | |
ThunderSoft | 0:293917667c17 | 6 | // The Arduino two-wire interface uses a 7-bit number for the address, |
ThunderSoft | 0:293917667c17 | 7 | // and sets the last bit correctly based on reads and writes |
ThunderSoft | 0:293917667c17 | 8 | #define ADDRESS_DEFAULT (0x29 << 1) |
ThunderSoft | 0:293917667c17 | 9 | |
ThunderSoft | 0:293917667c17 | 10 | // RANGE_SCALER values for 1x, 2x, 3x scaling - see STSW-IMG003 core/src/vl6180x_api.c (ScalerLookUP[]) |
ThunderSoft | 0:293917667c17 | 11 | static uint16_t const ScalerValues[] = {0, 253, 127, 84}; |
ThunderSoft | 0:293917667c17 | 12 | |
ThunderSoft | 1:46408c6b6d96 | 13 | #define constrain(amt,low,high) ((amt)<=(low)?(low):((amt)>(high)?(high):(amt))) |
ThunderSoft | 0:293917667c17 | 14 | // Constructors //////////////////////////////////////////////////////////////// |
ThunderSoft | 0:293917667c17 | 15 | |
ThunderSoft | 0:293917667c17 | 16 | VL6180X::VL6180X(I2C *_i2c) |
ThunderSoft | 0:293917667c17 | 17 | : address(ADDRESS_DEFAULT) |
ThunderSoft | 0:293917667c17 | 18 | , scaling(0) |
ThunderSoft | 0:293917667c17 | 19 | , ptp_offset(0) |
ThunderSoft | 0:293917667c17 | 20 | , io_timeout(0) // no timeout |
ThunderSoft | 0:293917667c17 | 21 | , did_timeout(false) |
ThunderSoft | 0:293917667c17 | 22 | { |
ThunderSoft | 2:8343c9a07b66 | 23 | i2c = _i2c; |
ThunderSoft | 0:293917667c17 | 24 | //configureDefault(); |
ThunderSoft | 0:293917667c17 | 25 | } |
ThunderSoft | 0:293917667c17 | 26 | |
ThunderSoft | 0:293917667c17 | 27 | // Public Methods ////////////////////////////////////////////////////////////// |
ThunderSoft | 0:293917667c17 | 28 | |
ThunderSoft | 0:293917667c17 | 29 | void VL6180X::setAddress(uint8_t new_addr) |
ThunderSoft | 0:293917667c17 | 30 | { |
ThunderSoft | 0:293917667c17 | 31 | writeReg(I2C_SLAVE__DEVICE_ADDRESS, new_addr & 0x7F); |
ThunderSoft | 0:293917667c17 | 32 | address = new_addr; |
ThunderSoft | 0:293917667c17 | 33 | } |
ThunderSoft | 0:293917667c17 | 34 | |
ThunderSoft | 0:293917667c17 | 35 | // Initialize sensor with settings from ST application note AN4545, section 9 - |
ThunderSoft | 0:293917667c17 | 36 | // "Mandatory : private registers" |
ThunderSoft | 0:293917667c17 | 37 | void VL6180X::init() |
ThunderSoft | 0:293917667c17 | 38 | { |
ThunderSoft | 0:293917667c17 | 39 | // Store part-to-part range offset so it can be adjusted if scaling is changed |
ThunderSoft | 0:293917667c17 | 40 | ptp_offset = readReg(SYSRANGE__PART_TO_PART_RANGE_OFFSET); |
ThunderSoft | 0:293917667c17 | 41 | |
ThunderSoft | 0:293917667c17 | 42 | if (readReg(SYSTEM__FRESH_OUT_OF_RESET) == 1) |
ThunderSoft | 0:293917667c17 | 43 | { |
ThunderSoft | 0:293917667c17 | 44 | scaling = 1; |
ThunderSoft | 0:293917667c17 | 45 | |
ThunderSoft | 0:293917667c17 | 46 | writeReg(0x207, 0x01); |
ThunderSoft | 0:293917667c17 | 47 | writeReg(0x208, 0x01); |
ThunderSoft | 0:293917667c17 | 48 | writeReg(0x096, 0x00); |
ThunderSoft | 0:293917667c17 | 49 | writeReg(0x097, 0xFD); // RANGE_SCALER = 253 |
ThunderSoft | 0:293917667c17 | 50 | writeReg(0x0E3, 0x00); |
ThunderSoft | 0:293917667c17 | 51 | writeReg(0x0E4, 0x04); |
ThunderSoft | 0:293917667c17 | 52 | writeReg(0x0E5, 0x02); |
ThunderSoft | 0:293917667c17 | 53 | writeReg(0x0E6, 0x01); |
ThunderSoft | 0:293917667c17 | 54 | writeReg(0x0E7, 0x03); |
ThunderSoft | 0:293917667c17 | 55 | writeReg(0x0F5, 0x02); |
ThunderSoft | 0:293917667c17 | 56 | writeReg(0x0D9, 0x05); |
ThunderSoft | 0:293917667c17 | 57 | writeReg(0x0DB, 0xCE); |
ThunderSoft | 0:293917667c17 | 58 | writeReg(0x0DC, 0x03); |
ThunderSoft | 0:293917667c17 | 59 | writeReg(0x0DD, 0xF8); |
ThunderSoft | 0:293917667c17 | 60 | writeReg(0x09F, 0x00); |
ThunderSoft | 0:293917667c17 | 61 | writeReg(0x0A3, 0x3C); |
ThunderSoft | 0:293917667c17 | 62 | writeReg(0x0B7, 0x00); |
ThunderSoft | 0:293917667c17 | 63 | writeReg(0x0BB, 0x3C); |
ThunderSoft | 0:293917667c17 | 64 | writeReg(0x0B2, 0x09); |
ThunderSoft | 0:293917667c17 | 65 | writeReg(0x0CA, 0x09); |
ThunderSoft | 0:293917667c17 | 66 | writeReg(0x198, 0x01); |
ThunderSoft | 0:293917667c17 | 67 | writeReg(0x1B0, 0x17); |
ThunderSoft | 0:293917667c17 | 68 | writeReg(0x1AD, 0x00); |
ThunderSoft | 0:293917667c17 | 69 | writeReg(0x0FF, 0x05); |
ThunderSoft | 0:293917667c17 | 70 | writeReg(0x100, 0x05); |
ThunderSoft | 0:293917667c17 | 71 | writeReg(0x199, 0x05); |
ThunderSoft | 0:293917667c17 | 72 | writeReg(0x1A6, 0x1B); |
ThunderSoft | 0:293917667c17 | 73 | writeReg(0x1AC, 0x3E); |
ThunderSoft | 0:293917667c17 | 74 | writeReg(0x1A7, 0x1F); |
ThunderSoft | 0:293917667c17 | 75 | writeReg(0x030, 0x00); |
ThunderSoft | 0:293917667c17 | 76 | |
ThunderSoft | 0:293917667c17 | 77 | writeReg(SYSTEM__FRESH_OUT_OF_RESET, 0); |
ThunderSoft | 0:293917667c17 | 78 | } |
ThunderSoft | 0:293917667c17 | 79 | else |
ThunderSoft | 0:293917667c17 | 80 | { |
ThunderSoft | 0:293917667c17 | 81 | // Sensor has already been initialized, so try to get scaling settings by |
ThunderSoft | 0:293917667c17 | 82 | // reading registers. |
ThunderSoft | 0:293917667c17 | 83 | |
ThunderSoft | 0:293917667c17 | 84 | uint16_t s = readReg16Bit(RANGE_SCALER); |
ThunderSoft | 0:293917667c17 | 85 | |
ThunderSoft | 0:293917667c17 | 86 | if (s == ScalerValues[3]) { scaling = 3; } |
ThunderSoft | 0:293917667c17 | 87 | else if (s == ScalerValues[2]) { scaling = 2; } |
ThunderSoft | 0:293917667c17 | 88 | else { scaling = 1; } |
ThunderSoft | 0:293917667c17 | 89 | |
ThunderSoft | 0:293917667c17 | 90 | // Adjust the part-to-part range offset value read earlier to account for |
ThunderSoft | 0:293917667c17 | 91 | // existing scaling. If the sensor was already in 2x or 3x scaling mode, |
ThunderSoft | 0:293917667c17 | 92 | // precision will be lost calculating the original (1x) offset, but this can |
ThunderSoft | 0:293917667c17 | 93 | // be resolved by resetting the sensor and Arduino again. |
ThunderSoft | 0:293917667c17 | 94 | ptp_offset *= scaling; |
ThunderSoft | 0:293917667c17 | 95 | } |
ThunderSoft | 0:293917667c17 | 96 | } |
ThunderSoft | 0:293917667c17 | 97 | |
ThunderSoft | 0:293917667c17 | 98 | // Configure some settings for the sensor's default behavior from AN4545 - |
ThunderSoft | 0:293917667c17 | 99 | // "Recommended : Public registers" and "Optional: Public registers" |
ThunderSoft | 0:293917667c17 | 100 | // |
ThunderSoft | 0:293917667c17 | 101 | // Note that this function does not set up GPIO1 as an interrupt output as |
ThunderSoft | 0:293917667c17 | 102 | // suggested, though you can do so by calling: |
ThunderSoft | 0:293917667c17 | 103 | // writeReg(SYSTEM__MODE_GPIO1, 0x10); |
ThunderSoft | 0:293917667c17 | 104 | void VL6180X::configureDefault(void) |
ThunderSoft | 0:293917667c17 | 105 | { |
ThunderSoft | 0:293917667c17 | 106 | // "Recommended : Public registers" |
ThunderSoft | 0:293917667c17 | 107 | |
ThunderSoft | 0:293917667c17 | 108 | // readout__averaging_sample_period = 48 |
ThunderSoft | 0:293917667c17 | 109 | writeReg(READOUT__AVERAGING_SAMPLE_PERIOD, 0x30); |
ThunderSoft | 0:293917667c17 | 110 | |
ThunderSoft | 0:293917667c17 | 111 | // sysals__analogue_gain_light = 6 (ALS gain = 1 nominal, actually 1.01 according to Table 14 in datasheet) |
ThunderSoft | 0:293917667c17 | 112 | writeReg(SYSALS__ANALOGUE_GAIN, 0x46); |
ThunderSoft | 0:293917667c17 | 113 | |
ThunderSoft | 0:293917667c17 | 114 | // sysrange__vhv_repeat_rate = 255 (auto Very High Voltage temperature recalibration after every 255 range measurements) |
ThunderSoft | 0:293917667c17 | 115 | writeReg(SYSRANGE__VHV_REPEAT_RATE, 0xFF); |
ThunderSoft | 0:293917667c17 | 116 | |
ThunderSoft | 0:293917667c17 | 117 | // sysals__integration_period = 99 (100 ms) |
ThunderSoft | 0:293917667c17 | 118 | // AN4545 incorrectly recommends writing to register 0x040; 0x63 should go in the lower byte, which is register 0x041. |
ThunderSoft | 0:293917667c17 | 119 | writeReg16Bit(SYSALS__INTEGRATION_PERIOD, 0x0063); |
ThunderSoft | 0:293917667c17 | 120 | |
ThunderSoft | 0:293917667c17 | 121 | // sysrange__vhv_recalibrate = 1 (manually trigger a VHV recalibration) |
ThunderSoft | 0:293917667c17 | 122 | writeReg(SYSRANGE__VHV_RECALIBRATE, 0x01); |
ThunderSoft | 0:293917667c17 | 123 | |
ThunderSoft | 0:293917667c17 | 124 | |
ThunderSoft | 0:293917667c17 | 125 | // "Optional: Public registers" |
ThunderSoft | 0:293917667c17 | 126 | |
ThunderSoft | 0:293917667c17 | 127 | // sysrange__intermeasurement_period = 9 (100 ms) |
ThunderSoft | 0:293917667c17 | 128 | writeReg(SYSRANGE__INTERMEASUREMENT_PERIOD, 0x09); |
ThunderSoft | 0:293917667c17 | 129 | |
ThunderSoft | 0:293917667c17 | 130 | // sysals__intermeasurement_period = 49 (500 ms) |
ThunderSoft | 0:293917667c17 | 131 | writeReg(SYSALS__INTERMEASUREMENT_PERIOD, 0x31); |
ThunderSoft | 0:293917667c17 | 132 | |
ThunderSoft | 0:293917667c17 | 133 | // als_int_mode = 4 (ALS new sample ready interrupt); range_int_mode = 4 (range new sample ready interrupt) |
ThunderSoft | 0:293917667c17 | 134 | writeReg(SYSTEM__INTERRUPT_CONFIG_GPIO, 0x24); |
ThunderSoft | 0:293917667c17 | 135 | |
ThunderSoft | 0:293917667c17 | 136 | |
ThunderSoft | 0:293917667c17 | 137 | // Reset other settings to power-on defaults |
ThunderSoft | 0:293917667c17 | 138 | |
ThunderSoft | 0:293917667c17 | 139 | // sysrange__max_convergence_time = 49 (49 ms) |
ThunderSoft | 0:293917667c17 | 140 | writeReg(VL6180X::SYSRANGE__MAX_CONVERGENCE_TIME, 0x31); |
ThunderSoft | 0:293917667c17 | 141 | |
ThunderSoft | 0:293917667c17 | 142 | // disable interleaved mode |
ThunderSoft | 0:293917667c17 | 143 | writeReg(INTERLEAVED_MODE__ENABLE, 0); |
ThunderSoft | 0:293917667c17 | 144 | |
ThunderSoft | 0:293917667c17 | 145 | // reset range scaling factor to 1x |
ThunderSoft | 0:293917667c17 | 146 | setScaling(1); |
ThunderSoft | 0:293917667c17 | 147 | } |
ThunderSoft | 0:293917667c17 | 148 | |
ThunderSoft | 0:293917667c17 | 149 | // Writes an 8-bit register |
ThunderSoft | 0:293917667c17 | 150 | void VL6180X::writeReg(uint16_t reg, uint8_t value) |
ThunderSoft | 0:293917667c17 | 151 | { |
ThunderSoft | 0:293917667c17 | 152 | i2cWriteForVL6180X(i2c,ADDRESS_DEFAULT,&value,reg,sizeof(value)); |
ThunderSoft | 0:293917667c17 | 153 | // Wire.beginTransmission(address); |
ThunderSoft | 0:293917667c17 | 154 | // Wire.write((reg >> 8) & 0xff); // reg high byte |
ThunderSoft | 0:293917667c17 | 155 | // Wire.write(reg & 0xff); // reg low byte |
ThunderSoft | 0:293917667c17 | 156 | // Wire.write(value); |
ThunderSoft | 0:293917667c17 | 157 | // last_status = Wire.endTransmission(); |
ThunderSoft | 0:293917667c17 | 158 | } |
ThunderSoft | 0:293917667c17 | 159 | |
ThunderSoft | 0:293917667c17 | 160 | // Writes a 16-bit register |
ThunderSoft | 0:293917667c17 | 161 | void VL6180X::writeReg16Bit(uint16_t reg, uint16_t value) |
ThunderSoft | 0:293917667c17 | 162 | { |
ThunderSoft | 0:293917667c17 | 163 | uint8_t buffer[2]; |
ThunderSoft | 0:293917667c17 | 164 | buffer[0] = (value >> 8) & 0xff; |
ThunderSoft | 0:293917667c17 | 165 | buffer[1] = value & 0xff; |
ThunderSoft | 0:293917667c17 | 166 | i2cWriteForVL6180X(i2c,ADDRESS_DEFAULT,buffer,reg,sizeof(value)); |
ThunderSoft | 0:293917667c17 | 167 | // Wire.beginTransmission(address); |
ThunderSoft | 0:293917667c17 | 168 | // Wire.write((reg >> 8) & 0xff); // reg high byte |
ThunderSoft | 0:293917667c17 | 169 | // Wire.write(reg & 0xff); // reg low byte |
ThunderSoft | 0:293917667c17 | 170 | // Wire.write((value >> 8) & 0xff); // value high byte |
ThunderSoft | 0:293917667c17 | 171 | // Wire.write(value & 0xff); // value low byte |
ThunderSoft | 0:293917667c17 | 172 | // last_status = Wire.endTransmission(); |
ThunderSoft | 0:293917667c17 | 173 | } |
ThunderSoft | 0:293917667c17 | 174 | |
ThunderSoft | 0:293917667c17 | 175 | // Writes a 32-bit register |
ThunderSoft | 0:293917667c17 | 176 | void VL6180X::writeReg32Bit(uint16_t reg, uint32_t value) |
ThunderSoft | 0:293917667c17 | 177 | { |
ThunderSoft | 0:293917667c17 | 178 | uint8_t buffer[4]; |
ThunderSoft | 0:293917667c17 | 179 | buffer[0] = (value >> 24) & 0xff; |
ThunderSoft | 0:293917667c17 | 180 | buffer[1] = (value >> 16)& 0xff; |
ThunderSoft | 0:293917667c17 | 181 | buffer[2] = (value >> 8)& 0xff; |
ThunderSoft | 0:293917667c17 | 182 | buffer[3] = value & 0xff; |
ThunderSoft | 0:293917667c17 | 183 | i2cWriteForVL6180X(i2c,ADDRESS_DEFAULT,buffer,reg,sizeof(value)); |
ThunderSoft | 0:293917667c17 | 184 | // Wire.beginTransmission(address); |
ThunderSoft | 0:293917667c17 | 185 | // Wire.write((reg >> 8) & 0xff); // reg high byte |
ThunderSoft | 0:293917667c17 | 186 | // Wire.write(reg & 0xff); // reg low byte |
ThunderSoft | 0:293917667c17 | 187 | // Wire.write((value >> 24) & 0xff); // value highest byte |
ThunderSoft | 0:293917667c17 | 188 | // Wire.write((value >> 16) & 0xff); |
ThunderSoft | 0:293917667c17 | 189 | // Wire.write((value >> 8) & 0xff); |
ThunderSoft | 0:293917667c17 | 190 | // Wire.write(value & 0xff); // value lowest byte |
ThunderSoft | 0:293917667c17 | 191 | // last_status = Wire.endTransmission(); |
ThunderSoft | 0:293917667c17 | 192 | } |
ThunderSoft | 0:293917667c17 | 193 | |
ThunderSoft | 0:293917667c17 | 194 | // Reads an 8-bit register |
ThunderSoft | 0:293917667c17 | 195 | uint8_t VL6180X::readReg(uint16_t reg) |
ThunderSoft | 0:293917667c17 | 196 | { |
ThunderSoft | 0:293917667c17 | 197 | uint8_t value = 0xff; |
ThunderSoft | 0:293917667c17 | 198 | i2cReadForVL6180X(i2c,ADDRESS_DEFAULT,&value,reg,1); |
ThunderSoft | 0:293917667c17 | 199 | return value; |
ThunderSoft | 0:293917667c17 | 200 | |
ThunderSoft | 0:293917667c17 | 201 | // Wire.beginTransmission(address); |
ThunderSoft | 0:293917667c17 | 202 | // Wire.write((reg >> 8) & 0xff); // reg high byte |
ThunderSoft | 0:293917667c17 | 203 | // Wire.write(reg & 0xff); // reg low byte |
ThunderSoft | 0:293917667c17 | 204 | // last_status = Wire.endTransmission(); |
ThunderSoft | 0:293917667c17 | 205 | |
ThunderSoft | 0:293917667c17 | 206 | // Wire.requestFrom(address, (uint8_t)1); |
ThunderSoft | 0:293917667c17 | 207 | // value = Wire.read(); |
ThunderSoft | 0:293917667c17 | 208 | // Wire.endTransmission(); |
ThunderSoft | 0:293917667c17 | 209 | |
ThunderSoft | 0:293917667c17 | 210 | // return value; |
ThunderSoft | 0:293917667c17 | 211 | } |
ThunderSoft | 0:293917667c17 | 212 | |
ThunderSoft | 0:293917667c17 | 213 | // Reads a 16-bit register |
ThunderSoft | 0:293917667c17 | 214 | uint16_t VL6180X::readReg16Bit(uint16_t reg) |
ThunderSoft | 0:293917667c17 | 215 | { |
ThunderSoft | 0:293917667c17 | 216 | uint16_t value; |
ThunderSoft | 0:293917667c17 | 217 | i2cReadForVL6180X(i2c,ADDRESS_DEFAULT,(uint8_t *)&value,reg,sizeof(value)); |
ThunderSoft | 0:293917667c17 | 218 | return value; |
ThunderSoft | 0:293917667c17 | 219 | // uint16_t value; |
ThunderSoft | 0:293917667c17 | 220 | |
ThunderSoft | 0:293917667c17 | 221 | // Wire.beginTransmission(address); |
ThunderSoft | 0:293917667c17 | 222 | // Wire.write((reg >> 8) & 0xff); // reg high byte |
ThunderSoft | 0:293917667c17 | 223 | // Wire.write(reg & 0xff); // reg low byte |
ThunderSoft | 0:293917667c17 | 224 | // last_status = Wire.endTransmission(); |
ThunderSoft | 0:293917667c17 | 225 | |
ThunderSoft | 0:293917667c17 | 226 | // Wire.requestFrom(address, (uint8_t)2); |
ThunderSoft | 0:293917667c17 | 227 | // value = (uint16_t)Wire.read() << 8; // value high byte |
ThunderSoft | 0:293917667c17 | 228 | // value |= Wire.read(); // value low byte |
ThunderSoft | 0:293917667c17 | 229 | // Wire.endTransmission(); |
ThunderSoft | 0:293917667c17 | 230 | |
ThunderSoft | 0:293917667c17 | 231 | // return value; |
ThunderSoft | 0:293917667c17 | 232 | } |
ThunderSoft | 0:293917667c17 | 233 | |
ThunderSoft | 0:293917667c17 | 234 | // Reads a 32-bit register |
ThunderSoft | 0:293917667c17 | 235 | uint32_t VL6180X::readReg32Bit(uint16_t reg) |
ThunderSoft | 0:293917667c17 | 236 | { |
ThunderSoft | 0:293917667c17 | 237 | uint32_t value; |
ThunderSoft | 0:293917667c17 | 238 | i2cReadForVL6180X(i2c,ADDRESS_DEFAULT,(uint8_t *)&value,reg,sizeof(value)); |
ThunderSoft | 0:293917667c17 | 239 | return value; |
ThunderSoft | 0:293917667c17 | 240 | // uint32_t value; |
ThunderSoft | 0:293917667c17 | 241 | |
ThunderSoft | 0:293917667c17 | 242 | // Wire.beginTransmission(address); |
ThunderSoft | 0:293917667c17 | 243 | // Wire.write((reg >> 8) & 0xff); // reg high byte |
ThunderSoft | 0:293917667c17 | 244 | // Wire.write(reg & 0xff); // reg low byte |
ThunderSoft | 0:293917667c17 | 245 | // last_status = Wire.endTransmission(); |
ThunderSoft | 0:293917667c17 | 246 | |
ThunderSoft | 0:293917667c17 | 247 | // Wire.requestFrom(address, (uint8_t)4); |
ThunderSoft | 0:293917667c17 | 248 | // value = (uint32_t)Wire.read() << 24; // value highest byte |
ThunderSoft | 0:293917667c17 | 249 | // value |= (uint32_t)Wire.read() << 16; |
ThunderSoft | 0:293917667c17 | 250 | // value |= (uint16_t)Wire.read() << 8; |
ThunderSoft | 0:293917667c17 | 251 | // value |= Wire.read(); // value lowest byte |
ThunderSoft | 0:293917667c17 | 252 | // Wire.endTransmission(); |
ThunderSoft | 0:293917667c17 | 253 | |
ThunderSoft | 0:293917667c17 | 254 | // return value; |
ThunderSoft | 0:293917667c17 | 255 | } |
ThunderSoft | 0:293917667c17 | 256 | |
ThunderSoft | 0:293917667c17 | 257 | // Set range scaling factor. The sensor uses 1x scaling by default, giving range |
ThunderSoft | 0:293917667c17 | 258 | // measurements in units of mm. Increasing the scaling to 2x or 3x makes it give |
ThunderSoft | 0:293917667c17 | 259 | // raw values in units of 2 mm or 3 mm instead. In other words, a bigger scaling |
ThunderSoft | 0:293917667c17 | 260 | // factor increases the sensor's potential maximum range but reduces its |
ThunderSoft | 0:293917667c17 | 261 | // resolution. |
ThunderSoft | 0:293917667c17 | 262 | |
ThunderSoft | 0:293917667c17 | 263 | // Implemented using ST's VL6180X API as a reference (STSW-IMG003); see |
ThunderSoft | 0:293917667c17 | 264 | // VL6180x_UpscaleSetScaling() in vl6180x_api.c. |
ThunderSoft | 0:293917667c17 | 265 | void VL6180X::setScaling(uint8_t new_scaling) |
ThunderSoft | 0:293917667c17 | 266 | { |
ThunderSoft | 0:293917667c17 | 267 | uint8_t const DefaultCrosstalkValidHeight = 20; // default value of SYSRANGE__CROSSTALK_VALID_HEIGHT |
ThunderSoft | 0:293917667c17 | 268 | |
ThunderSoft | 0:293917667c17 | 269 | // do nothing if scaling value is invalid |
ThunderSoft | 0:293917667c17 | 270 | if (new_scaling < 1 || new_scaling > 3) { return; } |
ThunderSoft | 0:293917667c17 | 271 | |
ThunderSoft | 0:293917667c17 | 272 | scaling = new_scaling; |
ThunderSoft | 0:293917667c17 | 273 | writeReg16Bit(RANGE_SCALER, ScalerValues[scaling]); |
ThunderSoft | 0:293917667c17 | 274 | |
ThunderSoft | 0:293917667c17 | 275 | // apply scaling on part-to-part offset |
ThunderSoft | 0:293917667c17 | 276 | writeReg(VL6180X::SYSRANGE__PART_TO_PART_RANGE_OFFSET, ptp_offset / scaling); |
ThunderSoft | 0:293917667c17 | 277 | |
ThunderSoft | 0:293917667c17 | 278 | // apply scaling on CrossTalkValidHeight |
ThunderSoft | 0:293917667c17 | 279 | writeReg(VL6180X::SYSRANGE__CROSSTALK_VALID_HEIGHT, DefaultCrosstalkValidHeight / scaling); |
ThunderSoft | 0:293917667c17 | 280 | |
ThunderSoft | 0:293917667c17 | 281 | // This function does not apply scaling to RANGE_IGNORE_VALID_HEIGHT. |
ThunderSoft | 0:293917667c17 | 282 | |
ThunderSoft | 0:293917667c17 | 283 | // enable early convergence estimate only at 1x scaling |
ThunderSoft | 0:293917667c17 | 284 | uint8_t rce = readReg(VL6180X::SYSRANGE__RANGE_CHECK_ENABLES); |
ThunderSoft | 0:293917667c17 | 285 | writeReg(VL6180X::SYSRANGE__RANGE_CHECK_ENABLES, (rce & 0xFE) | (scaling == 1)); |
ThunderSoft | 0:293917667c17 | 286 | } |
ThunderSoft | 0:293917667c17 | 287 | |
ThunderSoft | 0:293917667c17 | 288 | // Performs a single-shot ranging measurement |
ThunderSoft | 0:293917667c17 | 289 | uint8_t VL6180X::readRangeSingle() |
ThunderSoft | 0:293917667c17 | 290 | { |
ThunderSoft | 0:293917667c17 | 291 | writeReg(SYSRANGE__START, 0x01); |
ThunderSoft | 0:293917667c17 | 292 | return readRangeContinuous(); |
ThunderSoft | 0:293917667c17 | 293 | } |
ThunderSoft | 0:293917667c17 | 294 | |
ThunderSoft | 0:293917667c17 | 295 | // Performs a single-shot ambient light measurement |
ThunderSoft | 0:293917667c17 | 296 | uint16_t VL6180X::readAmbientSingle() |
ThunderSoft | 0:293917667c17 | 297 | { |
ThunderSoft | 0:293917667c17 | 298 | writeReg(SYSALS__START, 0x01); |
ThunderSoft | 0:293917667c17 | 299 | return readAmbientContinuous(); |
ThunderSoft | 0:293917667c17 | 300 | } |
ThunderSoft | 0:293917667c17 | 301 | |
ThunderSoft | 0:293917667c17 | 302 | // Starts continuous ranging measurements with the given period in ms |
ThunderSoft | 0:293917667c17 | 303 | // (10 ms resolution; defaults to 100 ms if not specified). |
ThunderSoft | 0:293917667c17 | 304 | // |
ThunderSoft | 0:293917667c17 | 305 | // The period must be greater than the time it takes to perform a |
ThunderSoft | 0:293917667c17 | 306 | // measurement. See section 2.4.4 ("Continuous mode limits") in the datasheet |
ThunderSoft | 0:293917667c17 | 307 | // for details. |
ThunderSoft | 0:293917667c17 | 308 | void VL6180X::startRangeContinuous(uint16_t period) |
ThunderSoft | 0:293917667c17 | 309 | { |
ThunderSoft | 0:293917667c17 | 310 | int16_t period_reg = (int16_t)(period / 10) - 1; |
ThunderSoft | 0:293917667c17 | 311 | period_reg = constrain(period_reg, 0, 254); |
ThunderSoft | 0:293917667c17 | 312 | |
ThunderSoft | 0:293917667c17 | 313 | writeReg(SYSRANGE__INTERMEASUREMENT_PERIOD, period_reg); |
ThunderSoft | 0:293917667c17 | 314 | writeReg(SYSRANGE__START, 0x03); |
ThunderSoft | 0:293917667c17 | 315 | } |
ThunderSoft | 0:293917667c17 | 316 | |
ThunderSoft | 0:293917667c17 | 317 | // Starts continuous ambient light measurements with the given period in ms |
ThunderSoft | 0:293917667c17 | 318 | // (10 ms resolution; defaults to 500 ms if not specified). |
ThunderSoft | 0:293917667c17 | 319 | // |
ThunderSoft | 0:293917667c17 | 320 | // The period must be greater than the time it takes to perform a |
ThunderSoft | 0:293917667c17 | 321 | // measurement. See section 2.4.4 ("Continuous mode limits") in the datasheet |
ThunderSoft | 0:293917667c17 | 322 | // for details. |
ThunderSoft | 0:293917667c17 | 323 | void VL6180X::startAmbientContinuous(uint16_t period) |
ThunderSoft | 0:293917667c17 | 324 | { |
ThunderSoft | 0:293917667c17 | 325 | int16_t period_reg = (int16_t)(period / 10) - 1; |
ThunderSoft | 0:293917667c17 | 326 | period_reg = constrain(period_reg, 0, 254); |
ThunderSoft | 0:293917667c17 | 327 | |
ThunderSoft | 0:293917667c17 | 328 | writeReg(SYSALS__INTERMEASUREMENT_PERIOD, period_reg); |
ThunderSoft | 0:293917667c17 | 329 | writeReg(SYSALS__START, 0x03); |
ThunderSoft | 0:293917667c17 | 330 | } |
ThunderSoft | 0:293917667c17 | 331 | |
ThunderSoft | 0:293917667c17 | 332 | // Starts continuous interleaved measurements with the given period in ms |
ThunderSoft | 0:293917667c17 | 333 | // (10 ms resolution; defaults to 500 ms if not specified). In this mode, each |
ThunderSoft | 0:293917667c17 | 334 | // ambient light measurement is immediately followed by a range measurement. |
ThunderSoft | 0:293917667c17 | 335 | // |
ThunderSoft | 0:293917667c17 | 336 | // The datasheet recommends using this mode instead of running "range and ALS |
ThunderSoft | 0:293917667c17 | 337 | // continuous modes simultaneously (i.e. asynchronously)". |
ThunderSoft | 0:293917667c17 | 338 | // |
ThunderSoft | 0:293917667c17 | 339 | // The period must be greater than the time it takes to perform both |
ThunderSoft | 0:293917667c17 | 340 | // measurements. See section 2.4.4 ("Continuous mode limits") in the datasheet |
ThunderSoft | 0:293917667c17 | 341 | // for details. |
ThunderSoft | 0:293917667c17 | 342 | void VL6180X::startInterleavedContinuous(uint16_t period) |
ThunderSoft | 0:293917667c17 | 343 | { |
ThunderSoft | 0:293917667c17 | 344 | int16_t period_reg = (int16_t)(period / 10) - 1; |
ThunderSoft | 0:293917667c17 | 345 | period_reg = constrain(period_reg, 0, 254); |
ThunderSoft | 0:293917667c17 | 346 | |
ThunderSoft | 0:293917667c17 | 347 | writeReg(INTERLEAVED_MODE__ENABLE, 1); |
ThunderSoft | 0:293917667c17 | 348 | writeReg(SYSALS__INTERMEASUREMENT_PERIOD, period_reg); |
ThunderSoft | 0:293917667c17 | 349 | writeReg(SYSALS__START, 0x03); |
ThunderSoft | 0:293917667c17 | 350 | } |
ThunderSoft | 0:293917667c17 | 351 | |
ThunderSoft | 0:293917667c17 | 352 | // Stops continuous mode. This will actually start a single measurement of range |
ThunderSoft | 0:293917667c17 | 353 | // and/or ambient light if continuous mode is not active, so it's a good idea to |
ThunderSoft | 0:293917667c17 | 354 | // wait a few hundred ms after calling this function to let that complete |
ThunderSoft | 0:293917667c17 | 355 | // before starting continuous mode again or taking a reading. |
ThunderSoft | 0:293917667c17 | 356 | void VL6180X::stopContinuous() |
ThunderSoft | 0:293917667c17 | 357 | { |
ThunderSoft | 0:293917667c17 | 358 | |
ThunderSoft | 0:293917667c17 | 359 | writeReg(SYSRANGE__START, 0x01); |
ThunderSoft | 0:293917667c17 | 360 | writeReg(SYSALS__START, 0x01); |
ThunderSoft | 0:293917667c17 | 361 | |
ThunderSoft | 0:293917667c17 | 362 | writeReg(INTERLEAVED_MODE__ENABLE, 0); |
ThunderSoft | 0:293917667c17 | 363 | } |
ThunderSoft | 0:293917667c17 | 364 | |
ThunderSoft | 0:293917667c17 | 365 | // Returns a range reading when continuous mode is activated |
ThunderSoft | 0:293917667c17 | 366 | // (readRangeSingle() also calls this function after starting a single-shot |
ThunderSoft | 0:293917667c17 | 367 | // range measurement) |
ThunderSoft | 0:293917667c17 | 368 | uint8_t VL6180X::readRangeContinuous() |
ThunderSoft | 0:293917667c17 | 369 | { |
ThunderSoft | 0:293917667c17 | 370 | uint16_t millis_start = millis(); |
ThunderSoft | 0:293917667c17 | 371 | while ((readReg(RESULT__INTERRUPT_STATUS_GPIO) & 0x04) == 0) |
ThunderSoft | 0:293917667c17 | 372 | { |
ThunderSoft | 0:293917667c17 | 373 | if (io_timeout > 0 && ((uint16_t)millis() - millis_start) > io_timeout) |
ThunderSoft | 0:293917667c17 | 374 | { |
ThunderSoft | 0:293917667c17 | 375 | did_timeout = true; |
ThunderSoft | 0:293917667c17 | 376 | return 255; |
ThunderSoft | 0:293917667c17 | 377 | } |
ThunderSoft | 0:293917667c17 | 378 | } |
ThunderSoft | 0:293917667c17 | 379 | |
ThunderSoft | 0:293917667c17 | 380 | uint8_t range = readReg(RESULT__RANGE_VAL); |
ThunderSoft | 0:293917667c17 | 381 | writeReg(SYSTEM__INTERRUPT_CLEAR, 0x01); |
ThunderSoft | 0:293917667c17 | 382 | |
ThunderSoft | 0:293917667c17 | 383 | return range; |
ThunderSoft | 0:293917667c17 | 384 | } |
ThunderSoft | 0:293917667c17 | 385 | |
ThunderSoft | 0:293917667c17 | 386 | // Returns an ambient light reading when continuous mode is activated |
ThunderSoft | 0:293917667c17 | 387 | // (readAmbientSingle() also calls this function after starting a single-shot |
ThunderSoft | 0:293917667c17 | 388 | // ambient light measurement) |
ThunderSoft | 0:293917667c17 | 389 | uint16_t VL6180X::readAmbientContinuous() |
ThunderSoft | 0:293917667c17 | 390 | { |
ThunderSoft | 0:293917667c17 | 391 | uint16_t millis_start = millis(); |
ThunderSoft | 0:293917667c17 | 392 | while ((readReg(RESULT__INTERRUPT_STATUS_GPIO) & 0x20) == 0) |
ThunderSoft | 0:293917667c17 | 393 | { |
ThunderSoft | 0:293917667c17 | 394 | if (io_timeout > 0 && ((uint16_t)millis() - millis_start) > io_timeout) |
ThunderSoft | 0:293917667c17 | 395 | { |
ThunderSoft | 0:293917667c17 | 396 | did_timeout = true; |
ThunderSoft | 0:293917667c17 | 397 | return 0; |
ThunderSoft | 0:293917667c17 | 398 | } |
ThunderSoft | 0:293917667c17 | 399 | } |
ThunderSoft | 0:293917667c17 | 400 | writeReg(SYSTEM__FRESH_OUT_OF_RESET, 0); |
ThunderSoft | 0:293917667c17 | 401 | uint16_t ambient = readReg16Bit(RESULT__ALS_VAL); |
ThunderSoft | 0:293917667c17 | 402 | writeReg(SYSTEM__INTERRUPT_CLEAR, 0x02); |
ThunderSoft | 0:293917667c17 | 403 | return ambient; |
ThunderSoft | 0:293917667c17 | 404 | } |
ThunderSoft | 0:293917667c17 | 405 | |
ThunderSoft | 0:293917667c17 | 406 | // Did a timeout occur in one of the read functions since the last call to |
ThunderSoft | 0:293917667c17 | 407 | // timeoutOccurred()? |
ThunderSoft | 0:293917667c17 | 408 | bool VL6180X::timeoutOccurred() |
ThunderSoft | 0:293917667c17 | 409 | { |
ThunderSoft | 0:293917667c17 | 410 | bool tmp = did_timeout; |
ThunderSoft | 0:293917667c17 | 411 | did_timeout = false; |
ThunderSoft | 0:293917667c17 | 412 | return tmp; |
ThunderSoft | 0:293917667c17 | 413 | } |
ThunderSoft | 0:293917667c17 | 414 |