This commit is contained in:
2026-04-08 07:38:46 +08:00
parent a9ec02dc93
commit fda081c1f0
51 changed files with 51337 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,876 @@
/*
* Copyright (c) 2017, STMicroelectronics - All Rights Reserved
*
* This file is part of VL53L1 Core and is dual licensed,
* either 'STMicroelectronics
* Proprietary license'
* or 'BSD 3-clause "New" or "Revised" License' , at your option.
*
********************************************************************************
*
* 'STMicroelectronics Proprietary license'
*
********************************************************************************
*
* License terms: STMicroelectronics Proprietary in accordance with licensing
* terms at www.st.com/sla0081
*
* STMicroelectronics confidential
* Reproduction and Communication of this document is strictly prohibited unless
* specifically authorized in writing by STMicroelectronics.
*
*
********************************************************************************
*
* Alternatively, VL53L1 Core may be distributed under the terms of
* 'BSD 3-clause "New" or "Revised" License', in which case the following
* provisions apply instead of the ones mentioned above :
*
********************************************************************************
*
* License terms: BSD 3-clause "New" or "Revised" License.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
********************************************************************************
*
*/
/**
* @file vl53l1_api_core.c
*
* @brief EwokPlus25 low level API function definition
*/
#include "vl53l1_ll_def.h"
#include "vl53l1_ll_device.h"
#include "vl53l1_platform.h"
#include "vl53l1_register_map.h"
#include "vl53l1_register_funcs.h"
#include "vl53l1_register_settings.h"
#include "vl53l1_core.h"
#include "vl53l1_wait.h"
#include "vl53l1_api_preset_modes.h"
#include "vl53l1_silicon_core.h"
#include "vl53l1_api_core.h"
#include "vl53l1_api_calibration.h"
#ifdef VL53L1_LOG_ENABLE
#include "vl53l1_api_debug.h"
#endif
#ifdef VL53L1_LOGGING
#include "vl53l1_debug.h"
#endif
#define LOG_FUNCTION_START(fmt, ...) \
_LOG_FUNCTION_START(VL53L1_TRACE_MODULE_CORE, fmt, ##__VA_ARGS__)
#define LOG_FUNCTION_END(status, ...) \
_LOG_FUNCTION_END(VL53L1_TRACE_MODULE_CORE, status, ##__VA_ARGS__)
#define LOG_FUNCTION_END_FMT(status, fmt, ...) \
_LOG_FUNCTION_END_FMT(VL53L1_TRACE_MODULE_CORE, status, \
fmt, ##__VA_ARGS__)
#define trace_print(level, ...) \
_LOG_TRACE_PRINT(VL53L1_TRACE_MODULE_CORE, \
level, VL53L1_TRACE_FUNCTION_NONE, ##__VA_ARGS__)
#ifndef VL53L1_NOCALIB
VL53L1_Error VL53L1_run_ref_spad_char(
VL53L1_DEV Dev,
VL53L1_Error *pcal_status)
{
/*
* Runs Reference SPAD Characterisation
*/
VL53L1_Error status = VL53L1_ERROR_NONE;
VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
uint8_t comms_buffer[6];
VL53L1_refspadchar_config_t *prefspadchar = &(pdev->refspadchar);
LOG_FUNCTION_START("");
/*
* Ensure power force is enabled
*/
if (status == VL53L1_ERROR_NONE) /*lint !e774 always true*/
status = VL53L1_enable_powerforce(Dev);
/*
* Configure device
*/
if (status == VL53L1_ERROR_NONE)
status =
VL53L1_set_ref_spad_char_config(
Dev,
prefspadchar->vcsel_period,
prefspadchar->timeout_us,
prefspadchar->target_count_rate_mcps,
prefspadchar->max_count_rate_limit_mcps,
prefspadchar->min_count_rate_limit_mcps,
pdev->stat_nvm.osc_measured__fast_osc__frequency);
/*
* Run device test
*/
if (status == VL53L1_ERROR_NONE)
status = VL53L1_run_device_test(
Dev,
prefspadchar->device_test_mode);
/*
* Read results
*/
if (status == VL53L1_ERROR_NONE)
status =
VL53L1_ReadMulti(
Dev,
VL53L1_REF_SPAD_CHAR_RESULT__NUM_ACTUAL_REF_SPADS,
comms_buffer,
2);
if (status == VL53L1_ERROR_NONE) {
pdev->dbg_results.ref_spad_char_result__num_actual_ref_spads =
comms_buffer[0];
pdev->dbg_results.ref_spad_char_result__ref_location =
comms_buffer[1];
}
/*
* copy results to customer nvm managed G02 registers
*/
if (status == VL53L1_ERROR_NONE)
status =
VL53L1_WriteMulti(
Dev,
VL53L1_REF_SPAD_MAN__NUM_REQUESTED_REF_SPADS,
comms_buffer,
2);
if (status == VL53L1_ERROR_NONE) {
pdev->customer.ref_spad_man__num_requested_ref_spads =
comms_buffer[0];
pdev->customer.ref_spad_man__ref_location =
comms_buffer[1];
}
/* After Ref Spad Char the final set of good SPAD enables
* are stored in the NCY results registers below
*
* - RESULT__SPARE_0_SD_1
* - RESULT__SPARE_1_SD_1
* - RESULT__SPARE_2_SD_1
*/
if (status == VL53L1_ERROR_NONE)
status =
VL53L1_ReadMulti(
Dev,
VL53L1_RESULT__SPARE_0_SD1,
comms_buffer,
6);
/*
* copy reference SPAD enables to customer nvm managed
* G02 registers
*/
if (status == VL53L1_ERROR_NONE)
status =
VL53L1_WriteMulti(
Dev,
VL53L1_GLOBAL_CONFIG__SPAD_ENABLES_REF_0,
comms_buffer,
6);
if (status == VL53L1_ERROR_NONE) {
pdev->customer.global_config__spad_enables_ref_0 =
comms_buffer[0];
pdev->customer.global_config__spad_enables_ref_1 =
comms_buffer[1];
pdev->customer.global_config__spad_enables_ref_2 =
comms_buffer[2];
pdev->customer.global_config__spad_enables_ref_3 =
comms_buffer[3];
pdev->customer.global_config__spad_enables_ref_4 =
comms_buffer[4];
pdev->customer.global_config__spad_enables_ref_5 =
comms_buffer[5];
}
#ifdef VL53L1_LOG_ENABLE
/* Print customer nvm managed data */
if (status == VL53L1_ERROR_NONE)
VL53L1_print_customer_nvm_managed(
&(pdev->customer),
"run_ref_spad_char():pdev->lldata.customer.",
VL53L1_TRACE_MODULE_REF_SPAD_CHAR);
#endif
if (status == VL53L1_ERROR_NONE) {
switch (pdev->sys_results.result__range_status) {
case VL53L1_DEVICEERROR_REFSPADCHARNOTENOUGHDPADS:
status = VL53L1_WARNING_REF_SPAD_CHAR_NOT_ENOUGH_SPADS;
break;
case VL53L1_DEVICEERROR_REFSPADCHARMORETHANTARGET:
status = VL53L1_WARNING_REF_SPAD_CHAR_RATE_TOO_HIGH;
break;
case VL53L1_DEVICEERROR_REFSPADCHARLESSTHANTARGET:
status = VL53L1_WARNING_REF_SPAD_CHAR_RATE_TOO_LOW;
break;
}
}
/*
* Save unfiltered status
*/
*pcal_status = status;
/* Status exception code */
IGNORE_STATUS(
IGNORE_REF_SPAD_CHAR_NOT_ENOUGH_SPADS,
VL53L1_WARNING_REF_SPAD_CHAR_NOT_ENOUGH_SPADS,
status);
IGNORE_STATUS(
IGNORE_REF_SPAD_CHAR_RATE_TOO_HIGH,
VL53L1_WARNING_REF_SPAD_CHAR_RATE_TOO_HIGH,
status);
IGNORE_STATUS(
IGNORE_REF_SPAD_CHAR_RATE_TOO_LOW,
VL53L1_WARNING_REF_SPAD_CHAR_RATE_TOO_LOW,
status);
LOG_FUNCTION_END(status);
return status;
}
VL53L1_Error VL53L1_run_offset_calibration(
VL53L1_DEV Dev,
int16_t cal_distance_mm,
VL53L1_Error *pcal_status)
{
/*
* Runs offset calibration
*
* Recommended tuning parm settings:
*
* - pre_num_of_samples = 32
* - mm1_num_of_samples = 100
* - mm2_num_of_samples = 64
* - target_distance_mm = 140mm
* - target reflectance = 5%
*
* Standard Ranging (sigma delta mode):
* - dss_config__target_total_rate_mcps = 20.0 -40.0 Mcps
* - phasecal_config_timeout_us = 1000
* - range_config_timeout_us = 13000
* - mm_config_timeout_us = 13000
*
*
* Note: function parms simplified as part of
* Patch_CalFunctionSimplification_11791
*
*/
VL53L1_Error status = VL53L1_ERROR_NONE;
VL53L1_LLDriverData_t *pdev =
VL53L1DevStructGetLLDriverHandle(Dev);
VL53L1_DevicePresetModes device_preset_modes[VL53L1_MAX_OFFSET_RANGE_RESULTS];
VL53L1_range_results_t range_results;
VL53L1_range_results_t *prange_results = &range_results;
VL53L1_range_data_t *prange_data = NULL;
VL53L1_offset_range_data_t *poffset = NULL;
uint8_t i = 0;
uint8_t m = 0;
uint8_t measurement_mode =
VL53L1_DEVICEMEASUREMENTMODE_BACKTOBACK;
uint16_t manual_effective_spads =
pdev->gen_cfg.dss_config__manual_effective_spads_select;
uint8_t num_of_samples[VL53L1_MAX_OFFSET_RANGE_RESULTS];
LOG_FUNCTION_START("");
/* select requested offset calibration mode */
switch (pdev->offset_calibration_mode) {
default:
device_preset_modes[0] =
VL53L1_DEVICEPRESETMODE_STANDARD_RANGING;
device_preset_modes[1] =
VL53L1_DEVICEPRESETMODE_STANDARD_RANGING_MM1_CAL;
device_preset_modes[2] =
VL53L1_DEVICEPRESETMODE_STANDARD_RANGING_MM2_CAL;
break;
}
/* initialise num_of_samples */
/* Start Patch_CalFunctionSimplification_11791 */
num_of_samples[0] = pdev->offsetcal_cfg.pre_num_of_samples;
num_of_samples[1] = pdev->offsetcal_cfg.mm1_num_of_samples;
num_of_samples[2] = pdev->offsetcal_cfg.mm2_num_of_samples;
/* End Patch_CalFunctionSimplification_11791 */
/* force all offsets to zero */
switch (pdev->offset_calibration_mode) {
case VL53L1_OFFSETCALIBRATIONMODE__MM1_MM2__STANDARD_PRE_RANGE_ONLY:
/* only run pre range */
pdev->offset_results.active_results = 1;
break;
default:
pdev->customer.mm_config__inner_offset_mm = 0;
pdev->customer.mm_config__outer_offset_mm = 0;
pdev->offset_results.active_results =
VL53L1_MAX_OFFSET_RANGE_RESULTS;
break;
}
pdev->customer.algo__part_to_part_range_offset_mm = 0;
/* initialise offset range results */
pdev->offset_results.max_results = VL53L1_MAX_OFFSET_RANGE_RESULTS;
pdev->offset_results.cal_distance_mm = cal_distance_mm;
for (m = 0 ; m < VL53L1_MAX_OFFSET_RANGE_RESULTS; m++) {
poffset = &(pdev->offset_results.data[m]);
poffset->preset_mode = 0;
poffset->no_of_samples = 0;
poffset->effective_spads = 0;
poffset->peak_rate_mcps = 0;
poffset->sigma_mm = 0;
poffset->median_range_mm = 0;
}
for (m = 0 ; m < pdev->offset_results.active_results ; m++) {
poffset = &(pdev->offset_results.data[m]);
poffset->preset_mode = device_preset_modes[m];
/* Apply preset mode */
if (status == VL53L1_ERROR_NONE)
status =
VL53L1_set_preset_mode(
Dev,
device_preset_modes[m],
/* Start Patch_CalFunctionSimplification_11791 */
pdev->offsetcal_cfg.dss_config__target_total_rate_mcps,
pdev->offsetcal_cfg.phasecal_config_timeout_us,
pdev->offsetcal_cfg.mm_config_timeout_us,
pdev->offsetcal_cfg.range_config_timeout_us,
/* End Patch_CalFunctionSimplification_11791 */
100);
pdev->gen_cfg.dss_config__manual_effective_spads_select =
manual_effective_spads;
/* Initialise device and start range */
if (status == VL53L1_ERROR_NONE)
status =
VL53L1_init_and_start_range(
Dev,
measurement_mode,
VL53L1_DEVICECONFIGLEVEL_CUSTOMER_ONWARDS);
for (i = 0 ; i <= (num_of_samples[m]+2) ; i++) {
/* Wait for range completion */
if (status == VL53L1_ERROR_NONE)
status =
VL53L1_wait_for_range_completion(Dev);
/*
* Get Device Results
* - Checks the stream count is the expected one
* - Read device system results
*/
if (status == VL53L1_ERROR_NONE)
status =
VL53L1_get_device_results(
Dev,
VL53L1_DEVICERESULTSLEVEL_FULL,
prange_results);
/*
* Ignore 1st two ranges to give the sigma delta initial
* phase time to settle
*
* accummulate range results if range is successful
*/
prange_data = &(prange_results->data[0]);
if (prange_results->stream_count > 1) {
if (prange_data->range_status ==
VL53L1_DEVICEERROR_RANGECOMPLETE) {
poffset->no_of_samples++;
poffset->effective_spads +=
(uint32_t)prange_data->actual_effective_spads;
poffset->peak_rate_mcps +=
(uint32_t)prange_data->peak_signal_count_rate_mcps;
poffset->sigma_mm +=
(uint32_t)prange_data->sigma_mm;
poffset->median_range_mm +=
(int32_t)prange_data->median_range_mm;
poffset->dss_config__roi_mode_control =
pdev->gen_cfg.dss_config__roi_mode_control;
poffset->dss_config__manual_effective_spads_select =
pdev->gen_cfg.dss_config__manual_effective_spads_select;
}
}
/*
* Conditional wait for firmware ready. Only waits for timed
* and single shot modes. Mode check is performed inside the
* wait function
*/
if (status == VL53L1_ERROR_NONE)
status =
VL53L1_wait_for_firmware_ready(Dev);
/*
* Send ranging handshake
*
* - Update Zone management
* - Update GPH registers
* - Clear current interrupt
* - Initialise SYSTEM__MODE_START for next range (if there is one!)
*/
if (status == VL53L1_ERROR_NONE)
status =
VL53L1_clear_interrupt_and_enable_next_range(
Dev,
measurement_mode);
}
/* Stop range */
if (status == VL53L1_ERROR_NONE)
status = VL53L1_stop_range(Dev);
/* Wait for Stop (abort) range to complete */
if (status == VL53L1_ERROR_NONE)
status = VL53L1_WaitUs(Dev, 1000);
/* generate average values */
if (poffset->no_of_samples > 0) {
poffset->effective_spads += (poffset->no_of_samples/2);
poffset->effective_spads /= poffset->no_of_samples;
poffset->peak_rate_mcps += (poffset->no_of_samples/2);
poffset->peak_rate_mcps /= poffset->no_of_samples;
poffset->sigma_mm += (poffset->no_of_samples/2);
poffset->sigma_mm /= poffset->no_of_samples;
poffset->median_range_mm += (poffset->no_of_samples/2);
poffset->median_range_mm /= poffset->no_of_samples;
poffset->range_mm_offset = (int32_t)cal_distance_mm;
poffset->range_mm_offset -= poffset->median_range_mm;
/* remember the number of SPADs for standard ranging */
if (poffset->preset_mode ==
VL53L1_DEVICEPRESETMODE_STANDARD_RANGING)
manual_effective_spads =
(uint16_t)poffset->effective_spads;
}
}
/* Calculate offsets */
switch (pdev->offset_calibration_mode) {
case VL53L1_OFFSETCALIBRATIONMODE__MM1_MM2__STANDARD_PRE_RANGE_ONLY:
/* copy offsets to customer data structure */
pdev->customer.mm_config__inner_offset_mm +=
(int16_t)pdev->offset_results.data[0].range_mm_offset;
pdev->customer.mm_config__outer_offset_mm +=
(int16_t)pdev->offset_results.data[0].range_mm_offset;
break;
default:
/* copy offsets to customer data structure */
pdev->customer.mm_config__inner_offset_mm =
(int16_t)pdev->offset_results.data[1].range_mm_offset;
pdev->customer.mm_config__outer_offset_mm =
(int16_t)pdev->offset_results.data[2].range_mm_offset;
pdev->customer.algo__part_to_part_range_offset_mm = 0;
/* copy average rate and effective SPAD count to
additional offset calibration data structure */
pdev->add_off_cal_data.result__mm_inner_actual_effective_spads =
(uint16_t)pdev->offset_results.data[1].effective_spads;
pdev->add_off_cal_data.result__mm_outer_actual_effective_spads =
(uint16_t)pdev->offset_results.data[2].effective_spads;
pdev->add_off_cal_data.result__mm_inner_peak_signal_count_rtn_mcps =
(uint16_t)pdev->offset_results.data[1].peak_rate_mcps;
pdev->add_off_cal_data.result__mm_outer_peak_signal_count_rtn_mcps =
(uint16_t)pdev->offset_results.data[2].peak_rate_mcps;
break;
}
/* apply to device */
if (status == VL53L1_ERROR_NONE)
status =
VL53L1_set_customer_nvm_managed(
Dev,
&(pdev->customer));
/*
* Check the peak rates, sigma, min spads for each stage
*/
for (m = 0 ; m < pdev->offset_results.active_results ; m++) {
poffset = &(pdev->offset_results.data[m]);
if (status == VL53L1_ERROR_NONE) {
pdev->offset_results.cal_report = m;
if (poffset->no_of_samples < num_of_samples[m])
status = VL53L1_WARNING_OFFSET_CAL_MISSING_SAMPLES;
/* only check sigma for the pre-range as
* the it is not calculated by the device
* for the MM1 and MM2 stages
*/
if (m == 0 && poffset->sigma_mm >
((uint32_t)VL53L1_OFFSET_CAL_MAX_SIGMA_MM<<5))
status = VL53L1_WARNING_OFFSET_CAL_SIGMA_TOO_HIGH;
if (poffset->peak_rate_mcps >
VL53L1_OFFSET_CAL_MAX_PRE_PEAK_RATE_MCPS)
status = VL53L1_WARNING_OFFSET_CAL_RATE_TOO_HIGH;
if (poffset->dss_config__manual_effective_spads_select <
VL53L1_OFFSET_CAL_MIN_EFFECTIVE_SPADS)
status = VL53L1_WARNING_OFFSET_CAL_SPAD_COUNT_TOO_LOW;
if (poffset->dss_config__manual_effective_spads_select == 0)
status = VL53L1_ERROR_OFFSET_CAL_NO_SPADS_ENABLED_FAIL;
if (poffset->no_of_samples == 0)
status = VL53L1_ERROR_OFFSET_CAL_NO_SAMPLE_FAIL;
}
}
/*
* Save unfiltered status
*/
pdev->offset_results.cal_status = status;
*pcal_status = pdev->offset_results.cal_status;
/* Status exception codes */
IGNORE_STATUS(
IGNORE_OFFSET_CAL_MISSING_SAMPLES,
VL53L1_WARNING_OFFSET_CAL_MISSING_SAMPLES,
status);
IGNORE_STATUS(
IGNORE_OFFSET_CAL_SIGMA_TOO_HIGH,
VL53L1_WARNING_OFFSET_CAL_SIGMA_TOO_HIGH,
status);
IGNORE_STATUS(
IGNORE_OFFSET_CAL_RATE_TOO_HIGH,
VL53L1_WARNING_OFFSET_CAL_RATE_TOO_HIGH,
status);
IGNORE_STATUS(
IGNORE_OFFSET_CAL_SPAD_COUNT_TOO_LOW,
VL53L1_WARNING_OFFSET_CAL_SPAD_COUNT_TOO_LOW,
status);
#ifdef VL53L1_LOG_ENABLE
/* Prints out the offset calibration data for debug */
VL53L1_print_customer_nvm_managed(
&(pdev->customer),
"run_offset_calibration():pdev->lldata.customer.",
VL53L1_TRACE_MODULE_OFFSET_DATA);
VL53L1_print_additional_offset_cal_data(
&(pdev->add_off_cal_data),
"run_offset_calibration():pdev->lldata.add_off_cal_data.",
VL53L1_TRACE_MODULE_OFFSET_DATA);
VL53L1_print_offset_range_results(
&(pdev->offset_results),
"run_offset_calibration():pdev->lldata.offset_results.",
VL53L1_TRACE_MODULE_OFFSET_DATA);
#endif
LOG_FUNCTION_END(status);
return status;
}
#endif
#ifndef VL53L1_NOCALIB
VL53L1_Error VL53L1_run_spad_rate_map(
VL53L1_DEV Dev,
VL53L1_DeviceTestMode device_test_mode,
VL53L1_DeviceSscArray array_select,
uint32_t ssc_config_timeout_us,
VL53L1_spad_rate_data_t *pspad_rate_data)
{
/**
* Runs SPAD Rate Map
*/
VL53L1_Error status = VL53L1_ERROR_NONE;
VL53L1_LLDriverData_t *pdev =
VL53L1DevStructGetLLDriverHandle(Dev);
LOG_FUNCTION_START("");
/*
* Ensure power force is enabled
*/
if (status == VL53L1_ERROR_NONE)
status = VL53L1_enable_powerforce(Dev);
/*
* Configure the test
*/
if (status == VL53L1_ERROR_NONE) {
pdev->ssc_cfg.array_select = array_select;
pdev->ssc_cfg.timeout_us = ssc_config_timeout_us;
status =
VL53L1_set_ssc_config(
Dev,
&(pdev->ssc_cfg),
pdev->stat_nvm.osc_measured__fast_osc__frequency);
}
/*
* Run device test
*/
if (status == VL53L1_ERROR_NONE)
status =
VL53L1_run_device_test(
Dev,
device_test_mode);
/*
* Read Rate Data from Patch Ram
*/
if (status == VL53L1_ERROR_NONE)
status =
VL53L1_get_spad_rate_data(
Dev,
pspad_rate_data);
if (device_test_mode == VL53L1_DEVICETESTMODE_LCR_VCSEL_ON)
pspad_rate_data->fractional_bits = 7;
else
pspad_rate_data->fractional_bits = 15;
/* Ensure power force is disabled */
if (status == VL53L1_ERROR_NONE)
status = VL53L1_disable_powerforce(Dev);
#ifdef VL53L1_LOG_ENABLE
/* Print return rate data and map */
if (status == VL53L1_ERROR_NONE) {
VL53L1_print_spad_rate_data(
pspad_rate_data,
"run_spad_rate_map():",
VL53L1_TRACE_MODULE_SPAD_RATE_MAP);
VL53L1_print_spad_rate_map(
pspad_rate_data,
"run_spad_rate_map():",
VL53L1_TRACE_MODULE_SPAD_RATE_MAP);
}
#endif
LOG_FUNCTION_END(status);
return status;
}
#endif
#ifndef VL53L1_NOCALIB
VL53L1_Error VL53L1_run_device_test(
VL53L1_DEV Dev,
VL53L1_DeviceTestMode device_test_mode)
{
/*
* Runs the selected Device Test Mode
*/
VL53L1_Error status = VL53L1_ERROR_NONE;
VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
uint8_t comms_buffer[2];
uint8_t gpio_hv_mux__ctrl = 0;
LOG_FUNCTION_START("");
/*
* Get current interrupt config
*/
if (status == VL53L1_ERROR_NONE) /*lint !e774 always true*/
status =
VL53L1_RdByte(
Dev,
VL53L1_GPIO_HV_MUX__CTRL,
&gpio_hv_mux__ctrl);
if (status == VL53L1_ERROR_NONE)
pdev->stat_cfg.gpio_hv_mux__ctrl = gpio_hv_mux__ctrl;
/*
* Trigger the test
*/
if (status == VL53L1_ERROR_NONE)
status = VL53L1_start_test(
Dev,
device_test_mode);
/*
* Wait for test completion
*/
if (status == VL53L1_ERROR_NONE)
status = VL53L1_wait_for_test_completion(Dev);
/*
* Read range and report status
*/
if (status == VL53L1_ERROR_NONE)
status =
VL53L1_ReadMulti(
Dev,
VL53L1_RESULT__RANGE_STATUS,
comms_buffer,
2);
if (status == VL53L1_ERROR_NONE) {
pdev->sys_results.result__range_status = comms_buffer[0];
pdev->sys_results.result__report_status = comms_buffer[1];
}
/* mask range status bits */
pdev->sys_results.result__range_status &=
VL53L1_RANGE_STATUS__RANGE_STATUS_MASK;
if (status == VL53L1_ERROR_NONE) {
trace_print(
VL53L1_TRACE_LEVEL_INFO,
" Device Test Complete:\n\t%-32s = %3u\n\t%-32s = %3u\n",
"result__range_status",
pdev->sys_results.result__range_status,
"result__report_status",
pdev->sys_results.result__report_status);
/*
* Clear interrupt
*/
if (status == VL53L1_ERROR_NONE)
status = VL53L1_clear_interrupt(Dev);
}
/*
* Clear test mode register
* - required so that next test command will trigger
* internal MCU interrupt
*/
if (status == VL53L1_ERROR_NONE)
status =
VL53L1_start_test(
Dev,
0x00);
LOG_FUNCTION_END(status);
return status;
}
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,220 @@
// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
/******************************************************************************
* Copyright (c) 2020, STMicroelectronics - All Rights Reserved
This file is part of VL53L1 and is dual licensed,
either GPL-2.0+
or 'BSD 3-clause "New" or "Revised" License' , at your option.
******************************************************************************
*/
/**
* @file vl53l1_api_strings.c
* @brief VL53L1 API functions for decoding error codes to a text string
*/
#include "vl53l1_api_core.h"
#include "vl53l1_api_strings.h"
#include "vl53l1_error_codes.h"
#include "vl53l1_error_strings.h"
#define LOG_FUNCTION_START(fmt, ...) \
_LOG_FUNCTION_START(VL53L1_TRACE_MODULE_API, fmt, ##__VA_ARGS__)
#define LOG_FUNCTION_END(status, ...) \
_LOG_FUNCTION_END(VL53L1_TRACE_MODULE_API, status, ##__VA_ARGS__)
#define LOG_FUNCTION_END_FMT(status, fmt, ...) \
_LOG_FUNCTION_END_FMT(VL53L1_TRACE_MODULE_API, status, fmt, \
##__VA_ARGS__)
VL53L1_Error VL53L1_get_range_status_string(
uint8_t RangeStatus,
char *pRangeStatusString)
{
VL53L1_Error status = VL53L1_ERROR_NONE;
LOG_FUNCTION_START("");
#ifdef VL53L1_USE_EMPTY_STRING
SUPPRESS_UNUSED_WARNING(RangeStatus);
VL53L1_COPYSTRING(pRangeStatusString, "");
#else
switch (RangeStatus) {
case 0:
VL53L1_COPYSTRING(pRangeStatusString,
VL53L1_STRING_RANGESTATUS_RANGEVALID);
break;
case 1:
VL53L1_COPYSTRING(pRangeStatusString,
VL53L1_STRING_RANGESTATUS_SIGMA);
break;
case 2:
VL53L1_COPYSTRING(pRangeStatusString,
VL53L1_STRING_RANGESTATUS_SIGNAL);
break;
case 3:
VL53L1_COPYSTRING(pRangeStatusString,
VL53L1_STRING_RANGESTATUS_MINRANGE);
break;
case 4:
VL53L1_COPYSTRING(pRangeStatusString,
VL53L1_STRING_RANGESTATUS_PHASE);
break;
case 5:
VL53L1_COPYSTRING(pRangeStatusString,
VL53L1_STRING_RANGESTATUS_HW);
break;
default: /**/
VL53L1_COPYSTRING(pRangeStatusString,
VL53L1_STRING_RANGESTATUS_NONE);
}
#endif
LOG_FUNCTION_END(status);
return status;
}
VL53L1_Error VL53L1_get_pal_state_string(
VL53L1_State PalStateCode,
char *pPalStateString)
{
VL53L1_Error status = VL53L1_ERROR_NONE;
LOG_FUNCTION_START("");
#ifdef VL53L1_USE_EMPTY_STRING
SUPPRESS_UNUSED_WARNING(PalStateCode);
VL53L1_COPYSTRING(pPalStateString, "");
#else
switch (PalStateCode) {
case VL53L1_STATE_POWERDOWN:
VL53L1_COPYSTRING(pPalStateString,
VL53L1_STRING_STATE_POWERDOWN);
break;
case VL53L1_STATE_WAIT_STATICINIT:
VL53L1_COPYSTRING(pPalStateString,
VL53L1_STRING_STATE_WAIT_STATICINIT);
break;
case VL53L1_STATE_STANDBY:
VL53L1_COPYSTRING(pPalStateString,
VL53L1_STRING_STATE_STANDBY);
break;
case VL53L1_STATE_IDLE:
VL53L1_COPYSTRING(pPalStateString,
VL53L1_STRING_STATE_IDLE);
break;
case VL53L1_STATE_RUNNING:
VL53L1_COPYSTRING(pPalStateString,
VL53L1_STRING_STATE_RUNNING);
break;
case VL53L1_STATE_RESET:
VL53L1_COPYSTRING(pPalStateString,
VL53L1_STRING_STATE_RESET);
break;
case VL53L1_STATE_UNKNOWN:
VL53L1_COPYSTRING(pPalStateString,
VL53L1_STRING_STATE_UNKNOWN);
break;
case VL53L1_STATE_ERROR:
VL53L1_COPYSTRING(pPalStateString,
VL53L1_STRING_STATE_ERROR);
break;
default:
VL53L1_COPYSTRING(pPalStateString,
VL53L1_STRING_STATE_UNKNOWN);
}
#endif
LOG_FUNCTION_END(status);
return status;
}
VL53L1_Error VL53L1_get_sequence_steps_info(
VL53L1_SequenceStepId SequenceStepId,
char *pSequenceStepsString)
{
VL53L1_Error Status = VL53L1_ERROR_NONE;
LOG_FUNCTION_START("");
#ifdef VL53L1_USE_EMPTY_STRING
SUPPRESS_UNUSED_WARNING(SequenceStepId);
VL53L1_COPYSTRING(pSequenceStepsString, "");
#else
switch (SequenceStepId) {
case VL53L1_SEQUENCESTEP_VHV:
VL53L1_COPYSTRING(pSequenceStepsString,
VL53L1_STRING_SEQUENCESTEP_VHV);
break;
case VL53L1_SEQUENCESTEP_PHASECAL:
VL53L1_COPYSTRING(pSequenceStepsString,
VL53L1_STRING_SEQUENCESTEP_PHASECAL);
break;
case VL53L1_SEQUENCESTEP_REFPHASE:
VL53L1_COPYSTRING(pSequenceStepsString,
VL53L1_STRING_SEQUENCESTEP_DSS1);
break;
case VL53L1_SEQUENCESTEP_DSS1:
VL53L1_COPYSTRING(pSequenceStepsString,
VL53L1_STRING_SEQUENCESTEP_DSS1);
break;
case VL53L1_SEQUENCESTEP_DSS2:
VL53L1_COPYSTRING(pSequenceStepsString,
VL53L1_STRING_SEQUENCESTEP_DSS2);
break;
case VL53L1_SEQUENCESTEP_MM1:
VL53L1_COPYSTRING(pSequenceStepsString,
VL53L1_STRING_SEQUENCESTEP_MM1);
break;
case VL53L1_SEQUENCESTEP_MM2:
VL53L1_COPYSTRING(pSequenceStepsString,
VL53L1_STRING_SEQUENCESTEP_MM2);
break;
case VL53L1_SEQUENCESTEP_RANGE:
VL53L1_COPYSTRING(pSequenceStepsString,
VL53L1_STRING_SEQUENCESTEP_RANGE);
break;
default:
Status = VL53L1_ERROR_INVALID_PARAMS;
}
#endif
LOG_FUNCTION_END(Status);
return Status;
}
VL53L1_Error VL53L1_get_limit_check_info(uint16_t LimitCheckId,
char *pLimitCheckString)
{
VL53L1_Error Status = VL53L1_ERROR_NONE;
LOG_FUNCTION_START("");
#ifdef VL53L1_USE_EMPTY_STRING
SUPPRESS_UNUSED_WARNING(LimitCheckId);
VL53L1_COPYSTRING(pLimitCheckString, "");
#else
switch (LimitCheckId) {
case VL53L1_CHECKENABLE_SIGMA_FINAL_RANGE:
VL53L1_COPYSTRING(pLimitCheckString,
VL53L1_STRING_CHECKENABLE_SIGMA_FINAL_RANGE);
break;
case VL53L1_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE:
VL53L1_COPYSTRING(pLimitCheckString,
VL53L1_STRING_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE);
break;
default:
VL53L1_COPYSTRING(pLimitCheckString,
VL53L1_STRING_UNKNOW_ERROR_CODE);
}
#endif
LOG_FUNCTION_END(Status);
return Status;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,445 @@
/*
* Copyright (c) 2017, STMicroelectronics - All Rights Reserved
*
* This file is part of VL53L1 Core and is dual licensed,
* either 'STMicroelectronics
* Proprietary license'
* or 'BSD 3-clause "New" or "Revised" License' , at your option.
*
********************************************************************************
*
* 'STMicroelectronics Proprietary license'
*
********************************************************************************
*
* License terms: STMicroelectronics Proprietary in accordance with licensing
* terms at www.st.com/sla0081
*
* STMicroelectronics confidential
* Reproduction and Communication of this document is strictly prohibited unless
* specifically authorized in writing by STMicroelectronics.
*
*
********************************************************************************
*
* Alternatively, VL53L1 Core may be distributed under the terms of
* 'BSD 3-clause "New" or "Revised" License', in which case the following
* provisions apply instead of the ones mentioned above :
*
********************************************************************************
*
* License terms: BSD 3-clause "New" or "Revised" License.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
********************************************************************************
*
*/
/**
* @file vl53l1_core_support.c
*
* @brief EwokPlus25 core function definition
*/
#include "vl53l1_ll_def.h"
#include "vl53l1_ll_device.h"
#include "vl53l1_platform_log.h"
#include "vl53l1_core_support.h"
#include "vl53l1_platform_user_data.h"
#include "vl53l1_platform_user_defines.h"
#ifdef VL53L1_LOGGING
#include "vl53l1_debug.h"
#include "vl53l1_register_debug.h"
#endif
#define LOG_FUNCTION_START(fmt, ...) \
_LOG_FUNCTION_START(VL53L1_TRACE_MODULE_CORE, fmt, ##__VA_ARGS__)
#define LOG_FUNCTION_END(status, ...) \
_LOG_FUNCTION_END(VL53L1_TRACE_MODULE_CORE, status, ##__VA_ARGS__)
#define LOG_FUNCTION_END_FMT(status, fmt, ...) \
_LOG_FUNCTION_END_FMT(VL53L1_TRACE_MODULE_CORE, \
status, fmt, ##__VA_ARGS__)
#define trace_print(level, ...) \
_LOG_TRACE_PRINT(VL53L1_TRACE_MODULE_CORE, \
level, VL53L1_TRACE_FUNCTION_NONE, ##__VA_ARGS__)
uint32_t VL53L1_calc_pll_period_us(
uint16_t fast_osc_frequency)
{
/* Calculates PLL frequency using NVM fast_osc_frequency
* Fast osc frequency fixed point format = unsigned 4.12
*
* PLL period fixed point format = unsigned 0.24
* Min input fast osc frequency = 1 MHz
* PLL Multiplier = 64 (fixed)
* Min PLL freq = 64.0MHz
* -> max PLL period = 1/ 64
* -> only the 18 LS bits are used
*
* 2^30 = (2^24) (1.0us) * 4096 (2^12) / 64 (PLL Multiplier)
*/
uint32_t pll_period_us = 0;
LOG_FUNCTION_START("");
pll_period_us = (0x01 << 30) / fast_osc_frequency;
#ifdef VL53L1_LOGGING
trace_print(VL53L1_TRACE_LEVEL_DEBUG,
" %-48s : %10u\n", "pll_period_us",
pll_period_us);
#endif
LOG_FUNCTION_END(0);
return pll_period_us;
}
#ifdef PAL_EXTENDED
uint32_t VL53L1_duration_maths(
uint32_t pll_period_us,
uint32_t vcsel_parm_pclks,
uint32_t window_vclks,
uint32_t elapsed_mclks)
{
/*
* Generates the ranging duration in us
*
* duration_us = elapsed_mclks * vcsel_perm_pclks *
* window_vclks * pll_period_us
*
* returned value in [us] with no fraction bits
*/
uint64_t tmp_long_int = 0;
uint32_t duration_us = 0;
/* PLL period us = 0.24 18 LS bits used
* window_vclks = 12.0 (2304 max)
* output 30b (6.24)
*/
duration_us = window_vclks * pll_period_us;
/* down shift by 12
* output 18b (6.12)
*/
duration_us = duration_us >> 12;
/* Save first part of the calc (#1) */
tmp_long_int = (uint64_t)duration_us;
/* Multiply elapsed macro periods (22-bit)
* by VCSEL parameter 6.4 (max 63.9999)
* output 32b (28.4)
*/
duration_us = elapsed_mclks * vcsel_parm_pclks;
/* down shift by 4 to remove fractional bits (#2)
* output 28b (28.0)
*/
duration_us = duration_us >> 4;
/* Multiply #1 18b (6.12) by #2 28b (28.0)
* output 46b (34.12)
*/
tmp_long_int = tmp_long_int * (uint64_t)duration_us;
/* Remove fractional part
* output 34b (34.0)
*/
tmp_long_int = tmp_long_int >> 12;
/* Clip to 32-bits */
if (tmp_long_int > 0xFFFFFFFF) {
tmp_long_int = 0xFFFFFFFF;
}
duration_us = (uint32_t)tmp_long_int;
return duration_us;
}
uint32_t VL53L1_isqrt(uint32_t num)
{
/*
* Implements an integer square root
*
* From: http://en.wikipedia.org/wiki/Methods_of_computing_square_roots
*/
uint32_t res = 0;
uint32_t bit = 1 << 30; /* The second-to-top bit is set: 1 << 14 for 16-bits, 1 << 30 for 32 bits */
/* "bit" starts at the highest power of four <= the argument. */
while (bit > num) {
bit >>= 2;
}
while (bit != 0) {
if (num >= res + bit) {
num -= res + bit;
res = (res >> 1) + bit;
} else {
res >>= 1;
}
bit >>= 2;
}
return res;
}
uint16_t VL53L1_rate_maths(
int32_t events,
uint32_t time_us)
{
/*
* Converts events into count rate
*
* Max events = 512 Mcps * 1sec
* = 512,000,000 events
* = 29b
*
* If events > 2^24 use 3-bit fractional bits is used internally
* otherwise 7-bit fractional bits are used
*/
uint32_t tmp_int = 0;
uint32_t frac_bits = 7;
uint16_t rate_mcps = 0; /* 9.7 format */
/*
* Clip input event range
*/
if (events > VL53L1_SPAD_TOTAL_COUNT_MAX) {
tmp_int = VL53L1_SPAD_TOTAL_COUNT_MAX;
} else if (events > 0) {
tmp_int = (uint32_t)events;
}
/*
* if events > VL53L1_SPAD_TOTAL_COUNT_RES_THRES use 3 rather
* than 7 fractional bits internal to function
*/
if (events > VL53L1_SPAD_TOTAL_COUNT_RES_THRES) {
frac_bits = 3;
} else {
frac_bits = 7;
}
/*
* Create 3 or 7 fractional bits
* output 32b (29.3 or 25.7)
* Divide by range duration in [us] - no fractional bits
*/
if (time_us > 0) {
tmp_int = ((tmp_int << frac_bits) + (time_us / 2)) / time_us;
}
/*
* Re align if reduced resolution
*/
if (events > VL53L1_SPAD_TOTAL_COUNT_RES_THRES) {
tmp_int = tmp_int << 4;
}
/*
* Firmware internal count is 17.7 (24b) but it this
* case clip to 16-bit value for reporting
*/
if (tmp_int > 0xFFFF) {
tmp_int = 0xFFFF;
}
rate_mcps = (uint16_t)tmp_int;
return rate_mcps;
}
uint16_t VL53L1_rate_per_spad_maths(
uint32_t frac_bits,
uint32_t peak_count_rate,
uint16_t num_spads,
uint32_t max_output_value)
{
uint32_t tmp_int = 0;
/* rate_per_spad Format varies with prog frac_bits */
uint16_t rate_per_spad = 0;
/* Calculate rate per spad with variable fractional bits */
/* Frac_bits should be programmed as final frac_bits - 7 as
* the pk_rate contains an inherent 7 bit resolution
*/
if (num_spads > 0) {
tmp_int = (peak_count_rate << 8) << frac_bits;
tmp_int = (tmp_int + ((uint32_t)num_spads / 2)) / (uint32_t)num_spads;
} else {
tmp_int = ((peak_count_rate) << frac_bits);
}
/* Clip in case of overwrap - special code */
if (tmp_int > max_output_value) {
tmp_int = max_output_value;
}
rate_per_spad = (uint16_t)tmp_int;
return rate_per_spad;
}
int32_t VL53L1_range_maths(
uint16_t fast_osc_frequency,
uint16_t phase,
uint16_t zero_distance_phase,
uint8_t fractional_bits,
int32_t gain_factor,
int32_t range_offset_mm)
{
/*
* Converts phase information into distance in [mm]
*/
uint32_t pll_period_us = 0; /* 0.24 format */
int64_t tmp_long_int = 0;
int32_t range_mm = 0;
/* Calculate PLL period in [ps] */
pll_period_us = VL53L1_calc_pll_period_us(fast_osc_frequency);
/* Raw range in [mm]
*
* calculate the phase difference between return and reference phases
*
* phases 16b (5.11)
* output 17b including sign bit
*/
tmp_long_int = (int64_t)phase - (int64_t)zero_distance_phase;
/*
* multiply by the PLL period
*
* PLL period 24bit (0.24) but only 18 LS bits used
*
* Output 35b (0.35) (17b + 18b)
*/
tmp_long_int = tmp_long_int * (int64_t)pll_period_us;
/*
* Down shift by 9 - Output 26b (0.26)
*/
tmp_long_int = tmp_long_int / (0x01 << 9);
/*
* multiply by speed of light in air divided by 8
* Factor of 8 includes 2 for the round trip and 4 scaling
*
* VL53L1_SPEED_OF_LIGHT_IN_AIR_DIV_8 = 16b (16.2)
*
* Output 42b (18.24) (16b + 26b)
*/
tmp_long_int = tmp_long_int * VL53L1_SPEED_OF_LIGHT_IN_AIR_DIV_8;
/*
* Down shift by 22 - Output 20b (18.2)
*/
tmp_long_int = tmp_long_int / (0x01 << 22);
/* Add range offset */
range_mm = (int32_t)tmp_long_int + range_offset_mm;
/* apply correction gain */
range_mm *= gain_factor;
range_mm += 0x0400;
range_mm /= 0x0800;
/* Remove fractional bits */
if (fractional_bits == 0)
range_mm = range_mm / (0x01 << 2);
else if (fractional_bits == 1)
range_mm = range_mm / (0x01 << 1);
return range_mm;
}
#endif
uint8_t VL53L1_decode_vcsel_period(uint8_t vcsel_period_reg)
{
/*
* Converts the encoded VCSEL period register value into
* the real period in PLL clocks
*/
uint8_t vcsel_period_pclks = 0;
vcsel_period_pclks = (vcsel_period_reg + 1) << 1;
return vcsel_period_pclks;
}
void VL53L1_decode_row_col(
uint8_t spad_number,
uint8_t *prow,
uint8_t *pcol)
{
/**
* Decodes the array (row,col) location from
* the input SPAD number
*/
if (spad_number > 127) {
*prow = 8 + ((255-spad_number) & 0x07);
*pcol = (spad_number-128) >> 3;
} else {
*prow = spad_number & 0x07;
*pcol = (127-spad_number) >> 3;
}
}

View File

@@ -0,0 +1,304 @@
/*
* Copyright (c) 2017, STMicroelectronics - All Rights Reserved
*
* This file is part of VL53L1 Core and is dual licensed,
* either 'STMicroelectronics
* Proprietary license'
* or 'BSD 3-clause "New" or "Revised" License' , at your option.
*
********************************************************************************
*
* 'STMicroelectronics Proprietary license'
*
********************************************************************************
*
* License terms: STMicroelectronics Proprietary in accordance with licensing
* terms at www.st.com/sla0081
*
* STMicroelectronics confidential
* Reproduction and Communication of this document is strictly prohibited unless
* specifically authorized in writing by STMicroelectronics.
*
*
********************************************************************************
*
* Alternatively, VL53L1 Core may be distributed under the terms of
* 'BSD 3-clause "New" or "Revised" License', in which case the following
* provisions apply instead of the ones mentioned above :
*
********************************************************************************
*
* License terms: BSD 3-clause "New" or "Revised" License.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
********************************************************************************
*
*/
/**
* @file vl53l1_error_strings.c
* @brief VL53L1 API functions for decoding error codes to a text string
*/
#include "vl53l1_error_codes.h"
#include "vl53l1_error_strings.h"
#include "vl53l1_platform_log.h"
#include "vl53l1_ll_def.h"
#define LOG_FUNCTION_START(fmt, ...) \
_LOG_FUNCTION_START(VL53L1_TRACE_MODULE_API, fmt, ##__VA_ARGS__)
#define LOG_FUNCTION_END(status, ...) \
_LOG_FUNCTION_END(VL53L1_TRACE_MODULE_API, status, ##__VA_ARGS__)
#define LOG_FUNCTION_END_FMT(status, fmt, ...) \
_LOG_FUNCTION_END_FMT(VL53L1_TRACE_MODULE_API, \
status, fmt, ##__VA_ARGS__)
#ifndef VL53L1_DEBUG
#define VL53L1_USE_EMPTY_STRING
#endif
VL53L1_Error VL53L1_get_pal_error_string(
VL53L1_Error PalErrorCode,
char *pPalErrorString)
{
VL53L1_Error Status = VL53L1_ERROR_NONE;
#ifdef VL53L1_USE_EMPTY_STRING
SUPPRESS_UNUSED_WARNING(PalErrorCode);
#endif
LOG_FUNCTION_START("");
#ifdef VL53L1_USE_EMPTY_STRING
VL53L1_COPYSTRING(pPalErrorString, "");
#else
switch (PalErrorCode) {
case VL53L1_ERROR_NONE:
VL53L1_COPYSTRING(pPalErrorString,
VL53L1_STRING_ERROR_NONE);
break;
case VL53L1_ERROR_CALIBRATION_WARNING:
VL53L1_COPYSTRING(pPalErrorString,
VL53L1_STRING_ERROR_CALIBRATION_WARNING);
break;
case VL53L1_ERROR_MIN_CLIPPED:
VL53L1_COPYSTRING(pPalErrorString,
VL53L1_STRING_ERROR_MIN_CLIPPED);
break;
case VL53L1_ERROR_UNDEFINED:
VL53L1_COPYSTRING(pPalErrorString,
VL53L1_STRING_ERROR_UNDEFINED);
break;
case VL53L1_ERROR_INVALID_PARAMS:
VL53L1_COPYSTRING(pPalErrorString,
VL53L1_STRING_ERROR_INVALID_PARAMS);
break;
case VL53L1_ERROR_NOT_SUPPORTED:
VL53L1_COPYSTRING(pPalErrorString,
VL53L1_STRING_ERROR_NOT_SUPPORTED);
break;
case VL53L1_ERROR_RANGE_ERROR:
VL53L1_COPYSTRING(pPalErrorString,
VL53L1_STRING_ERROR_RANGE_ERROR);
break;
case VL53L1_ERROR_TIME_OUT:
VL53L1_COPYSTRING(pPalErrorString,
VL53L1_STRING_ERROR_TIME_OUT);
break;
case VL53L1_ERROR_MODE_NOT_SUPPORTED:
VL53L1_COPYSTRING(pPalErrorString,
VL53L1_STRING_ERROR_MODE_NOT_SUPPORTED);
break;
case VL53L1_ERROR_BUFFER_TOO_SMALL:
VL53L1_COPYSTRING(pPalErrorString,
VL53L1_STRING_ERROR_BUFFER_TOO_SMALL);
break;
case VL53L1_ERROR_COMMS_BUFFER_TOO_SMALL:
VL53L1_COPYSTRING(pPalErrorString,
VL53L1_STRING_ERROR_COMMS_BUFFER_TOO_SMALL);
break;
case VL53L1_ERROR_GPIO_NOT_EXISTING:
VL53L1_COPYSTRING(pPalErrorString,
VL53L1_STRING_ERROR_GPIO_NOT_EXISTING);
break;
case VL53L1_ERROR_GPIO_FUNCTIONALITY_NOT_SUPPORTED:
VL53L1_COPYSTRING(pPalErrorString,
VL53L1_STRING_ERROR_GPIO_FUNCTIONALITY_NOT_SUPPORTED);
break;
case VL53L1_ERROR_CONTROL_INTERFACE:
VL53L1_COPYSTRING(pPalErrorString,
VL53L1_STRING_ERROR_CONTROL_INTERFACE);
break;
case VL53L1_ERROR_INVALID_COMMAND:
VL53L1_COPYSTRING(pPalErrorString,
VL53L1_STRING_ERROR_INVALID_COMMAND);
break;
case VL53L1_ERROR_DIVISION_BY_ZERO:
VL53L1_COPYSTRING(pPalErrorString,
VL53L1_STRING_ERROR_DIVISION_BY_ZERO);
break;
case VL53L1_ERROR_REF_SPAD_INIT:
VL53L1_COPYSTRING(pPalErrorString,
VL53L1_STRING_ERROR_REF_SPAD_INIT);
break;
case VL53L1_ERROR_GPH_SYNC_CHECK_FAIL:
VL53L1_COPYSTRING(pPalErrorString,
VL53L1_STRING_ERROR_GPH_SYNC_CHECK_FAIL);
break;
case VL53L1_ERROR_STREAM_COUNT_CHECK_FAIL:
VL53L1_COPYSTRING(pPalErrorString,
VL53L1_STRING_ERROR_STREAM_COUNT_CHECK_FAIL);
break;
case VL53L1_ERROR_GPH_ID_CHECK_FAIL:
VL53L1_COPYSTRING(pPalErrorString,
VL53L1_STRING_ERROR_GPH_ID_CHECK_FAIL);
break;
case VL53L1_ERROR_ZONE_STREAM_COUNT_CHECK_FAIL:
VL53L1_COPYSTRING(pPalErrorString,
VL53L1_STRING_ERROR_ZONE_STREAM_COUNT_CHECK_FAIL);
break;
case VL53L1_ERROR_ZONE_GPH_ID_CHECK_FAIL:
VL53L1_COPYSTRING(pPalErrorString,
VL53L1_STRING_ERROR_ZONE_GPH_ID_CHECK_FAIL);
break;
case VL53L1_ERROR_XTALK_EXTRACTION_NO_SAMPLE_FAIL:
VL53L1_COPYSTRING(pPalErrorString,
VL53L1_STRING_ERROR_XTALK_EXTRACTION_NO_SAMPLES_FAIL);
break;
case VL53L1_ERROR_XTALK_EXTRACTION_SIGMA_LIMIT_FAIL:
VL53L1_COPYSTRING(pPalErrorString,
VL53L1_STRING_ERROR_XTALK_EXTRACTION_SIGMA_LIMIT_FAIL);
break;
case VL53L1_ERROR_OFFSET_CAL_NO_SAMPLE_FAIL:
VL53L1_COPYSTRING(pPalErrorString,
VL53L1_STRING_ERROR_OFFSET_CAL_NO_SAMPLE_FAIL);
break;
case VL53L1_ERROR_OFFSET_CAL_NO_SPADS_ENABLED_FAIL:
VL53L1_COPYSTRING(pPalErrorString,
VL53L1_STRING_ERROR_OFFSET_CAL_NO_SPADS_ENABLED_FAIL);
break;
case VL53L1_ERROR_ZONE_CAL_NO_SAMPLE_FAIL:
VL53L1_COPYSTRING(pPalErrorString,
VL53L1_STRING_ERROR_ZONE_CAL_NO_SAMPLE_FAIL);
break;
case VL53L1_WARNING_OFFSET_CAL_MISSING_SAMPLES:
VL53L1_COPYSTRING(pPalErrorString,
VL53L1_STRING_WARNING_OFFSET_CAL_MISSING_SAMPLES);
break;
case VL53L1_WARNING_OFFSET_CAL_SIGMA_TOO_HIGH:
VL53L1_COPYSTRING(pPalErrorString,
VL53L1_STRING_WARNING_OFFSET_CAL_SIGMA_TOO_HIGH);
break;
case VL53L1_WARNING_OFFSET_CAL_RATE_TOO_HIGH:
VL53L1_COPYSTRING(pPalErrorString,
VL53L1_STRING_WARNING_OFFSET_CAL_RATE_TOO_HIGH);
break;
case VL53L1_WARNING_OFFSET_CAL_SPAD_COUNT_TOO_LOW:
VL53L1_COPYSTRING(pPalErrorString,
VL53L1_STRING_WARNING_OFFSET_CAL_SPAD_COUNT_TOO_LOW);
break;
case VL53L1_WARNING_ZONE_CAL_MISSING_SAMPLES:
VL53L1_COPYSTRING(pPalErrorString,
VL53L1_STRING_WARNING_ZONE_CAL_MISSING_SAMPLES);
break;
case VL53L1_WARNING_ZONE_CAL_SIGMA_TOO_HIGH:
VL53L1_COPYSTRING(pPalErrorString,
VL53L1_STRING_WARNING_ZONE_CAL_SIGMA_TOO_HIGH);
break;
case VL53L1_WARNING_ZONE_CAL_RATE_TOO_HIGH:
VL53L1_COPYSTRING(pPalErrorString,
VL53L1_STRING_WARNING_ZONE_CAL_RATE_TOO_HIGH);
break;
case VL53L1_WARNING_REF_SPAD_CHAR_NOT_ENOUGH_SPADS:
VL53L1_COPYSTRING(pPalErrorString,
VL53L1_STRING_WARNING_REF_SPAD_CHAR_NOT_ENOUGH_SPADS);
break;
case VL53L1_WARNING_REF_SPAD_CHAR_RATE_TOO_HIGH:
VL53L1_COPYSTRING(pPalErrorString,
VL53L1_STRING_WARNING_REF_SPAD_CHAR_RATE_TOO_HIGH);
break;
case VL53L1_WARNING_REF_SPAD_CHAR_RATE_TOO_LOW:
VL53L1_COPYSTRING(pPalErrorString,
VL53L1_STRING_WARNING_REF_SPAD_CHAR_RATE_TOO_LOW);
break;
case VL53L1_WARNING_XTALK_MISSING_SAMPLES:
VL53L1_COPYSTRING(pPalErrorString,
VL53L1_STRING_WARNING_XTALK_MISSING_SAMPLES);
break;
case VL53L1_WARNING_XTALK_NO_SAMPLES_FOR_GRADIENT:
VL53L1_COPYSTRING(pPalErrorString,
VL53L1_STRING_WARNING_XTALK_NO_SAMPLES_FOR_GRADIENT);
break;
case VL53L1_WARNING_XTALK_SIGMA_LIMIT_FOR_GRADIENT:
VL53L1_COPYSTRING(pPalErrorString,
VL53L1_STRING_WARNING_XTALK_SIGMA_LIMIT_FOR_GRADIENT);
break;
case VL53L1_ERROR_DEVICE_FIRMWARE_TOO_OLD:
VL53L1_COPYSTRING(pPalErrorString,
VL53L1_STRING_ERROR_DEVICE_FIRMWARE_TOO_OLD);
break;
case VL53L1_ERROR_DEVICE_FIRMWARE_TOO_NEW:
VL53L1_COPYSTRING(pPalErrorString,
VL53L1_STRING_ERROR_DEVICE_FIRMWARE_TOO_NEW);
break;
case VL53L1_ERROR_UNIT_TEST_FAIL:
VL53L1_COPYSTRING(pPalErrorString,
VL53L1_STRING_ERROR_UNIT_TEST_FAIL);
break;
case VL53L1_ERROR_FILE_READ_FAIL:
VL53L1_COPYSTRING(pPalErrorString,
VL53L1_STRING_ERROR_FILE_READ_FAIL);
break;
case VL53L1_ERROR_FILE_WRITE_FAIL:
VL53L1_COPYSTRING(pPalErrorString,
VL53L1_STRING_ERROR_FILE_WRITE_FAIL);
break;
case VL53L1_ERROR_NOT_IMPLEMENTED:
VL53L1_COPYSTRING(pPalErrorString,
VL53L1_STRING_ERROR_NOT_IMPLEMENTED);
break;
default:
VL53L1_COPYSTRING(pPalErrorString,
VL53L1_STRING_UNKNOW_ERROR_CODE);
}
#endif
LOG_FUNCTION_END(Status);
return Status;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,146 @@
/*
* Copyright (c) 2017, STMicroelectronics - All Rights Reserved
*
* This file is part of VL53L1 Core and is dual licensed,
* either 'STMicroelectronics
* Proprietary license'
* or 'BSD 3-clause "New" or "Revised" License' , at your option.
*
********************************************************************************
*
* 'STMicroelectronics Proprietary license'
*
********************************************************************************
*
* License terms: STMicroelectronics Proprietary in accordance with licensing
* terms at www.st.com/sla0081
*
* STMicroelectronics confidential
* Reproduction and Communication of this document is strictly prohibited unless
* specifically authorized in writing by STMicroelectronics.
*
*
********************************************************************************
*
* Alternatively, VL53L1 Core may be distributed under the terms of
* 'BSD 3-clause "New" or "Revised" License', in which case the following
* provisions apply instead of the ones mentioned above :
*
********************************************************************************
*
* License terms: BSD 3-clause "New" or "Revised" License.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
********************************************************************************
*
*/
/**
* @file vl53l1_silicon_core.c
*
* @brief EwokPlus25 low level silicon LL Driver function definition
*/
#include "vl53l1_ll_def.h"
#include "vl53l1_platform.h"
#include "vl53l1_register_map.h"
#include "vl53l1_core.h"
#include "vl53l1_silicon_core.h"
#define LOG_FUNCTION_START(fmt, ...) \
_LOG_FUNCTION_START(VL53L1_TRACE_MODULE_CORE, fmt, ##__VA_ARGS__)
#define LOG_FUNCTION_END(status, ...) \
_LOG_FUNCTION_END(VL53L1_TRACE_MODULE_CORE, status, ##__VA_ARGS__)
#define LOG_FUNCTION_END_FMT(status, fmt, ...) \
_LOG_FUNCTION_END_FMT(VL53L1_TRACE_MODULE_CORE, status, fmt, ##__VA_ARGS__)
VL53L1_Error VL53L1_is_firmware_ready_silicon(
VL53L1_DEV Dev,
uint8_t *pready)
{
/**
* Determines if the firmware is ready to range
*
* There are 2 different behaviors depending on whether
* power force is enabled or not
*/
VL53L1_Error status = VL53L1_ERROR_NONE;
VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
uint8_t comms_buffer[5];
LOG_FUNCTION_START("");
/* read interrupt and power force reset status */
status = VL53L1_ReadMulti(
Dev,
VL53L1_INTERRUPT_MANAGER__ENABLES,
comms_buffer,
5);
if (status == VL53L1_ERROR_NONE) {
pdev->dbg_results.interrupt_manager__enables =
comms_buffer[0];
pdev->dbg_results.interrupt_manager__clear =
comms_buffer[1];
pdev->dbg_results.interrupt_manager__status =
comms_buffer[2];
pdev->dbg_results.mcu_to_host_bank__wr_access_en =
comms_buffer[3];
pdev->dbg_results.power_management__go1_reset_status =
comms_buffer[4];
if ((pdev->sys_ctrl.power_management__go1_power_force & 0x01) == 0x01) {
if (((pdev->dbg_results.interrupt_manager__enables & 0x1F) == 0x1F) &&
((pdev->dbg_results.interrupt_manager__clear & 0x1F) == 0x1F))
*pready = 0x01;
else
*pready = 0x00;
} else {
/* set ready flag if bit 0 is zero i.g G01 is in reset */
if ((pdev->dbg_results.power_management__go1_reset_status & 0x01) == 0x00)
*pready = 0x01;
else
*pready = 0x00;
}
}
LOG_FUNCTION_END(status);
return status;
}

View File

@@ -0,0 +1,558 @@
/*
* Copyright (c) 2017, STMicroelectronics - All Rights Reserved
*
* This file is part of VL53L1 Core and is dual licensed,
* either 'STMicroelectronics
* Proprietary license'
* or 'BSD 3-clause "New" or "Revised" License' , at your option.
*
********************************************************************************
*
* 'STMicroelectronics Proprietary license'
*
********************************************************************************
*
* License terms: STMicroelectronics Proprietary in accordance with licensing
* terms at www.st.com/sla0081
*
* STMicroelectronics confidential
* Reproduction and Communication of this document is strictly prohibited unless
* specifically authorized in writing by STMicroelectronics.
*
*
********************************************************************************
*
* Alternatively, VL53L1 Core may be distributed under the terms of
* 'BSD 3-clause "New" or "Revised" License', in which case the following
* provisions apply instead of the ones mentioned above :
*
********************************************************************************
*
* License terms: BSD 3-clause "New" or "Revised" License.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
********************************************************************************
*
*/
/**
* @file vl53l1_wait.c
*
* @brief EwokPlus25 low level Driver wait function definition
*/
#include "vl53l1_ll_def.h"
#include "vl53l1_ll_device.h"
#include "vl53l1_platform.h"
#include "vl53l1_core.h"
#include "vl53l1_silicon_core.h"
#include "vl53l1_wait.h"
#include "vl53l1_register_settings.h"
#define LOG_FUNCTION_START(fmt, ...) \
_LOG_FUNCTION_START(VL53L1_TRACE_MODULE_CORE, fmt, ##__VA_ARGS__)
#define LOG_FUNCTION_END(status, ...) \
_LOG_FUNCTION_END(VL53L1_TRACE_MODULE_CORE, status, ##__VA_ARGS__)
#define LOG_FUNCTION_END_FMT(status, fmt, ...) \
_LOG_FUNCTION_END_FMT(VL53L1_TRACE_MODULE_CORE, status, \
fmt, ##__VA_ARGS__)
VL53L1_Error VL53L1_wait_for_boot_completion(
VL53L1_DEV Dev)
{
/* Waits for firmware boot to finish
*/
VL53L1_Error status = VL53L1_ERROR_NONE;
VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
uint8_t fw_ready = 0;
LOG_FUNCTION_START("");
if (pdev->wait_method == VL53L1_WAIT_METHOD_BLOCKING) {
/* blocking version */
status =
VL53L1_poll_for_boot_completion(
Dev,
VL53L1_BOOT_COMPLETION_POLLING_TIMEOUT_MS);
} else {
/* implement non blocking version below */
fw_ready = 0;
while (fw_ready == 0x00 && status == VL53L1_ERROR_NONE) {
status = VL53L1_is_boot_complete(
Dev,
&fw_ready);
if (status == VL53L1_ERROR_NONE) {
status = VL53L1_WaitMs(
Dev,
VL53L1_POLLING_DELAY_MS);
}
}
}
LOG_FUNCTION_END(status);
return status;
}
VL53L1_Error VL53L1_wait_for_firmware_ready(
VL53L1_DEV Dev)
{
/* If in timed mode or single shot then check firmware is ready
* before sending handshake
*/
VL53L1_Error status = VL53L1_ERROR_NONE;
VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
uint8_t fw_ready = 0;
uint8_t mode_start = 0;
LOG_FUNCTION_START("");
/* Filter out tje measure mode part of the mode
* start register
*/
mode_start =
pdev->sys_ctrl.system__mode_start &
VL53L1_DEVICEMEASUREMENTMODE_MODE_MASK;
/*
* conditional wait for firmware ready
* only waits for timed and single shot modes
*/
if ((mode_start == VL53L1_DEVICEMEASUREMENTMODE_TIMED) ||
(mode_start == VL53L1_DEVICEMEASUREMENTMODE_SINGLESHOT)) {
if (pdev->wait_method == VL53L1_WAIT_METHOD_BLOCKING) {
/* blocking version */
status =
VL53L1_poll_for_firmware_ready(
Dev,
VL53L1_RANGE_COMPLETION_POLLING_TIMEOUT_MS);
} else {
/* implement non blocking version below */
fw_ready = 0;
while (fw_ready == 0x00 && status == VL53L1_ERROR_NONE) {
status = VL53L1_is_firmware_ready(
Dev,
&fw_ready);
if (status == VL53L1_ERROR_NONE) {
status = VL53L1_WaitMs(
Dev,
VL53L1_POLLING_DELAY_MS);
}
}
}
}
LOG_FUNCTION_END(status);
return status;
}
VL53L1_Error VL53L1_wait_for_range_completion(
VL53L1_DEV Dev)
{
/* Wrapper function for waiting for range completion
*/
VL53L1_Error status = VL53L1_ERROR_NONE;
VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
uint8_t data_ready = 0;
LOG_FUNCTION_START("");
if (pdev->wait_method == VL53L1_WAIT_METHOD_BLOCKING) {
/* blocking version */
status =
VL53L1_poll_for_range_completion(
Dev,
VL53L1_RANGE_COMPLETION_POLLING_TIMEOUT_MS);
} else {
/* implement non blocking version below */
data_ready = 0;
while (data_ready == 0x00 && status == VL53L1_ERROR_NONE) {
status = VL53L1_is_new_data_ready(
Dev,
&data_ready);
if (status == VL53L1_ERROR_NONE) {
status = VL53L1_WaitMs(
Dev,
VL53L1_POLLING_DELAY_MS);
}
}
}
LOG_FUNCTION_END(status);
return status;
}
VL53L1_Error VL53L1_wait_for_test_completion(
VL53L1_DEV Dev)
{
/* Wrapper function for waiting for test mode completion
*/
VL53L1_Error status = VL53L1_ERROR_NONE;
VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
uint8_t data_ready = 0;
LOG_FUNCTION_START("");
if (pdev->wait_method == VL53L1_WAIT_METHOD_BLOCKING) {
/* blocking version */
status =
VL53L1_poll_for_range_completion(
Dev,
VL53L1_TEST_COMPLETION_POLLING_TIMEOUT_MS);
} else {
/* implement non blocking version below */
data_ready = 0;
while (data_ready == 0x00 && status == VL53L1_ERROR_NONE) {
status = VL53L1_is_new_data_ready(
Dev,
&data_ready);
if (status == VL53L1_ERROR_NONE) {
status = VL53L1_WaitMs(
Dev,
VL53L1_POLLING_DELAY_MS);
}
}
}
LOG_FUNCTION_END(status);
return status;
}
VL53L1_Error VL53L1_is_boot_complete(
VL53L1_DEV Dev,
uint8_t *pready)
{
/**
* Determines if the firmware finished booting by reading
* bit 0 of firmware__system_status register
*/
VL53L1_Error status = VL53L1_ERROR_NONE;
uint8_t firmware__system_status = 0;
LOG_FUNCTION_START("");
/* read current range interrupt state */
status =
VL53L1_RdByte(
Dev,
VL53L1_FIRMWARE__SYSTEM_STATUS,
&firmware__system_status);
/* set *pready = 1 if new range data ready complete
* zero otherwise
*/
if ((firmware__system_status & 0x01) == 0x01) {
*pready = 0x01;
VL53L1_init_ll_driver_state(
Dev,
VL53L1_DEVICESTATE_SW_STANDBY);
} else {
*pready = 0x00;
VL53L1_init_ll_driver_state(
Dev,
VL53L1_DEVICESTATE_FW_COLDBOOT);
}
LOG_FUNCTION_END(status);
return status;
}
VL53L1_Error VL53L1_is_firmware_ready(
VL53L1_DEV Dev,
uint8_t *pready)
{
/**
* Determines if the firmware is ready to range
*/
VL53L1_Error status = VL53L1_ERROR_NONE;
VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
LOG_FUNCTION_START("");
status = VL53L1_is_firmware_ready_silicon(
Dev,
pready);
pdev->fw_ready = *pready;
LOG_FUNCTION_END(status);
return status;
}
VL53L1_Error VL53L1_is_new_data_ready(
VL53L1_DEV Dev,
uint8_t *pready)
{
/**
* Determines if new range data is ready by reading bit 0 of
* VL53L1_GPIO__TIO_HV_STATUS to determine the current state
* of output interrupt pin
*/
VL53L1_Error status = VL53L1_ERROR_NONE;
VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
uint8_t gpio__mux_active_high_hv = 0;
uint8_t gpio__tio_hv_status = 0;
uint8_t interrupt_ready = 0;
LOG_FUNCTION_START("");
gpio__mux_active_high_hv =
pdev->stat_cfg.gpio_hv_mux__ctrl &
VL53L1_DEVICEINTERRUPTLEVEL_ACTIVE_MASK;
if (gpio__mux_active_high_hv == VL53L1_DEVICEINTERRUPTLEVEL_ACTIVE_HIGH)
interrupt_ready = 0x01;
else
interrupt_ready = 0x00;
/* read current range interrupt state */
status = VL53L1_RdByte(
Dev,
VL53L1_GPIO__TIO_HV_STATUS,
&gpio__tio_hv_status);
/* set *pready = 1 if new range data ready complete zero otherwise */
if ((gpio__tio_hv_status & 0x01) == interrupt_ready)
*pready = 0x01;
else
*pready = 0x00;
LOG_FUNCTION_END(status);
return status;
}
VL53L1_Error VL53L1_poll_for_boot_completion(
VL53L1_DEV Dev,
uint32_t timeout_ms)
{
/**
* Polls the bit 0 of the FIRMWARE__SYSTEM_STATUS register to see if
* the firmware is ready.
*/
VL53L1_Error status = VL53L1_ERROR_NONE;
LOG_FUNCTION_START("");
/* after reset for the firmware blocks I2C access while
* it copies the NVM data into the G02 host register banks
* The host must wait the required time to allow the copy
* to complete before attempting to read the firmware status
*/
status = VL53L1_WaitUs(
Dev,
VL53L1_FIRMWARE_BOOT_TIME_US);
if (status == VL53L1_ERROR_NONE)
status =
VL53L1_WaitValueMaskEx(
Dev,
timeout_ms,
VL53L1_FIRMWARE__SYSTEM_STATUS,
0x01,
0x01,
VL53L1_POLLING_DELAY_MS);
if (status == VL53L1_ERROR_NONE)
VL53L1_init_ll_driver_state(Dev, VL53L1_DEVICESTATE_SW_STANDBY);
LOG_FUNCTION_END(status);
return status;
}
VL53L1_Error VL53L1_poll_for_firmware_ready(
VL53L1_DEV Dev,
uint32_t timeout_ms)
{
/**
* Polls the bit 0 of the FIRMWARE__SYSTEM_STATUS register to see if
* the firmware is ready.
*/
VL53L1_Error status = VL53L1_ERROR_NONE;
VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
uint32_t start_time_ms = 0;
uint32_t current_time_ms = 0;
int32_t poll_delay_ms = VL53L1_POLLING_DELAY_MS;
uint8_t fw_ready = 0;
/* calculate time limit in absolute time */
VL53L1_GetTickCount(Dev, &start_time_ms); /*lint !e534 ignoring return*/
pdev->fw_ready_poll_duration_ms = 0;
/* wait until firmware is ready, timeout reached on error occurred */
while ((status == VL53L1_ERROR_NONE) &&
(pdev->fw_ready_poll_duration_ms < timeout_ms) &&
(fw_ready == 0)) {
status = VL53L1_is_firmware_ready(
Dev,
&fw_ready);
if (status == VL53L1_ERROR_NONE &&
fw_ready == 0 &&
poll_delay_ms > 0) {
status = VL53L1_WaitMs(
Dev,
poll_delay_ms);
}
/*
* Update polling time (Compare difference rather than
* absolute to negate 32bit wrap around issue)
*/
VL53L1_GetTickCount(Dev, &current_time_ms); /*lint !e534 ignoring return*/
pdev->fw_ready_poll_duration_ms =
current_time_ms - start_time_ms;
}
if (fw_ready == 0 && status == VL53L1_ERROR_NONE)
status = VL53L1_ERROR_TIME_OUT;
LOG_FUNCTION_END(status);
return status;
}
VL53L1_Error VL53L1_poll_for_range_completion(
VL53L1_DEV Dev,
uint32_t timeout_ms)
{
/**
* Polls bit 0 of VL53L1_GPIO__TIO_HV_STATUS to determine
* the state of output interrupt pin
*
* Interrupt may be either active high or active low. Use active_high to
* select the required level check
*/
VL53L1_Error status = VL53L1_ERROR_NONE;
VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
uint8_t gpio__mux_active_high_hv = 0;
uint8_t interrupt_ready = 0;
LOG_FUNCTION_START("");
gpio__mux_active_high_hv =
pdev->stat_cfg.gpio_hv_mux__ctrl &
VL53L1_DEVICEINTERRUPTLEVEL_ACTIVE_MASK;
if (gpio__mux_active_high_hv == VL53L1_DEVICEINTERRUPTLEVEL_ACTIVE_HIGH)
interrupt_ready = 0x01;
else
interrupt_ready = 0x00;
status =
VL53L1_WaitValueMaskEx(
Dev,
timeout_ms,
VL53L1_GPIO__TIO_HV_STATUS,
interrupt_ready,
0x01,
VL53L1_POLLING_DELAY_MS);
LOG_FUNCTION_END(status);
return status;
}