2017-12-04 06:52 AM
Hello,
i want to use the VL53L0X sensor with an ARM processor. For that purpose I took the Pololu Arduino library, rewrote the i2c part and everything worked fine. My problem with the Pololu librays is that they dont do a SPAD management and dont have a function for temperature calibration. Both functions are essential for me so i looked trough the ST API and copied the needed functions from there. Now I have the problem that the SPAD Management hangs when the single ref calibration is done with the function VL53L0X_perform_single_ref_calibration(). I read the register 0x13h and check if the value is 0x07h like it is done in the API with several function calls. But I only get 0x40h back as an Answer from the sensor. If i reset the controller and not the sensor in that moment the sensor dont even respond anymore. Only after a power reset the sensor responses so i think there is a problem in the initialization.
This is the code to the SPAD Management function.
int32_t VL53L0X_init(bool io_2v8)
{
timeout_Init();
int32_t Status = kStatus_Success;
// VL53L0X_DataInit() begin
// sensor uses 1V8 mode for I/O by default; switch to 2V8 mode if necessary
if (io_2v8)
{
VL53L0X_writeReg(VHV_CONFIG_PAD_SCL_SDA__EXTSUP_HV,
VL53L0X_readReg(VHV_CONFIG_PAD_SCL_SDA__EXTSUP_HV) | 0x01); // set bit 0
}
// 'Set I2C standard mode'
VL53L0X_writeReg(0x88, 0x00);
VL53L0X_writeReg(0x80, 0x01);
VL53L0X_writeReg(0xFF, 0x01);
VL53L0X_writeReg(0x00, 0x00);
stop_variable = VL53L0X_readReg(0x91);
VL53L0X_writeReg(0x00, 0x01);
VL53L0X_writeReg(0xFF, 0x00);
VL53L0X_writeReg(0x80, 0x00);
// disable SIGNAL_RATE_MSRC (bit 1) and SIGNAL_RATE_PRE_RANGE (bit 4) limit checks
VL53L0X_writeReg(MSRC_CONFIG_CONTROL, VL53L0X_readReg(MSRC_CONFIG_CONTROL) | 0x12);
VL53L0X_setSignalRateLimit(0.25);
VL53L0X_writeReg(SYSTEM_SEQUENCE_CONFIG, 0xFF);
// VL53L0X_DataInit() end
// VL53L0X_StaticInit() begin
// 'Set interrupt config to new sample ready'
// -- VL53L0X_SetGpioConfig() begin
Status |= VL53L0X_writeReg(SYSTEM_INTERRUPT_CONFIG_GPIO, 0x04); //IRQ Pin set to Measure Ready. Other options in vl53l0x_api.c line 2667
Status |= VL53L0X_writeReg(GPIO_HV_MUX_ACTIVE_HIGH, VL53L0X_readReg(GPIO_HV_MUX_ACTIVE_HIGH) & ~0x10); // active low
Status |= VL53L0X_writeReg(SYSTEM_INTERRUPT_CLEAR, 0x01);
// -- VL53L0X_SetGpioConfig() end
uint8_t spad_count;
uint8_t spad_type_is_aperture;
// Reset SPAD Maps
for (uint8_t index = 0; index < SPAD_ARRAY_SIZE; index++)
refEnabledSPadMap[index] = 0;
for (uint8_t index = 0; index < SPAD_ARRAY_SIZE; index++)
refGoodSpadMap[index] = 0;
if (VL53L0X_getNvmRefGoodSpad(refGoodSpadMap, &spad_count, &spad_type_is_aperture) != kStatus_Success)
return kStatus_Fail;
if ((spad_type_is_aperture > 1) || ((spad_type_is_aperture == 1) && (spad_count > 32)) || ((spad_type_is_aperture == 0) && (spad_count > 12)))
{
Status = VL53L0X_performRefSpadManagement();
if (Status != kStatus_Success)
return Status;
}else
{
Status = VL53L0X_setReferenceSpads(spad_count, spad_type_is_aperture);
}
.
.
.
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?
The SPAD Management works until the ref calibration call
int32_t VL53L0X_performRefSpadManagement(void)
{
uint32_t currentSpadIndex = 0;
uint32_t lastSpadIndex = 0;
int32_t nextGoodSpad = 0;
uint32_t needAptSpads = 0;
int32_t Status = kStatus_Success;
uint16_t peakSignalRateRef;
uint16_t targetRefRate = 0x0A00; /* 10 MCPS in 9:7 format. */
uint32_t refSpadCount_int = 0;
uint32_t signalRateDiff = 0;
uint32_t lastSignalRateDiff = 0;
uint8_t complete = 0;
uint8_t lastSpadArray[SPAD_ARRAY_SIZE];
for (uint8_t index = 0; index < SPAD_ARRAY_SIZE; index++)
refEnabledSPadMap[index] = 0;
VL53L0X_writeReg(0xFF, 0x01);
VL53L0X_writeReg(DYNAMIC_SPAD_REF_EN_START_OFFSET, 0x00);
VL53L0X_writeReg(DYNAMIC_SPAD_NUM_REQUESTED_REF_SPAD, 0x2C); //44bit SPAD Data requested
VL53L0X_writeReg(0xFF, 0x00);
VL53L0X_writeReg(GLOBAL_CONFIG_REF_EN_START_SELECT, SPAD_START);
VL53L0X_writeReg(POWER_MANAGEMENT_GO1_POWER_FORCE, 0);
Status = VL53L0X_performRefCalibration();
.
.
.
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?
In the ref calibration the vhv calibration is called
int32_t VL53L0X_performRefCalibration(void)
{
int32_t Status = kStatus_Success;
uint8_t SequenceConfig = 0;
uint8_t pVhvSettings;
uint8_t pPhaseCal;
/* store the value of the sequence config,
* this will be reset before the end of the function
*/
SequenceConfig = VL53L0X_readReg(SYSTEM_SEQUENCE_CONFIG);
/* In the following function we don't save the config to optimize
* writes on device. Config is saved and restored only once. */
Status = VL53L0X_performVhvCalibration(&pVhvSettings, 1, 0);
.
.
.
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?
In that function the single ref calibration function is called
int32_t VL53L0X_performVhvCalibration(uint8_t *pVhvSettings, const uint8_t get_data_enable, const uint8_t restore_config)
{
int32_t Status = kStatus_Success;
uint8_t PhaseCalInt = 0;
uint8_t SequenceConfig = 0;
/* Save Sequence config */
if (restore_config == 1)
SequenceConfig = VL53L0X_readReg(SYSTEM_SEQUENCE_CONFIG);
/* Run VHV Calibration */
Status = VL53L0X_writeReg(SYSTEM_SEQUENCE_CONFIG, 0x01);
if (Status == kStatus_Success)
Status = VL53L0X_performSingleRefCalibration(0x40);
.
.
.
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?
And in that function the sensor stops working on the while loop when reading the 'Result Interrupt Status' register (0x13h)
int32_t VL53L0X_performSingleRefCalibration(uint8_t vhv_init_byte)
{
int32_t Status = kStatus_Success;
Status |= VL53L0X_writeReg(SYSRANGE_START, 0x01 | vhv_init_byte); // VL53L0X_REG_SYSRANGE_MODE_START_STOP
START_TIMEOUT;
while ((VL53L0X_readReg(RESULT_INTERRUPT_STATUS) & 0x07) == 0)
{
if (TIMEOUT_EXPIRED) { END_TIMEOUT; return kStatus_Fail; }
}
.
.
.
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?
The register is always 0x40h
Maybe you can find an error in my initialization of the sensor or there is a known solution to that error.
#arm #single-ref-calibration #vl53l0x2018-10-17 08:12 AM
Has anyone answered this for you?