amiro-lld / drivers / VL53L1X / v1 / api / core / vl53l1_api_calibration.c @ 4dba9195
History | View | Annotate | Download (23.219 KB)
1 |
/*
|
---|---|
2 |
* Copyright (c) 2017, STMicroelectronics - All Rights Reserved
|
3 |
*
|
4 |
* This file is part of VL53L1 Core and is dual licensed,
|
5 |
* either 'STMicroelectronics
|
6 |
* Proprietary license'
|
7 |
* or 'BSD 3-clause "New" or "Revised" License' , at your option.
|
8 |
*
|
9 |
********************************************************************************
|
10 |
*
|
11 |
* 'STMicroelectronics Proprietary license'
|
12 |
*
|
13 |
********************************************************************************
|
14 |
*
|
15 |
* License terms: STMicroelectronics Proprietary in accordance with licensing
|
16 |
* terms at www.st.com/sla0081
|
17 |
*
|
18 |
* STMicroelectronics confidential
|
19 |
* Reproduction and Communication of this document is strictly prohibited unless
|
20 |
* specifically authorized in writing by STMicroelectronics.
|
21 |
*
|
22 |
*
|
23 |
********************************************************************************
|
24 |
*
|
25 |
* Alternatively, VL53L1 Core may be distributed under the terms of
|
26 |
* 'BSD 3-clause "New" or "Revised" License', in which case the following
|
27 |
* provisions apply instead of the ones mentioned above :
|
28 |
*
|
29 |
********************************************************************************
|
30 |
*
|
31 |
* License terms: BSD 3-clause "New" or "Revised" License.
|
32 |
*
|
33 |
* Redistribution and use in source and binary forms, with or without
|
34 |
* modification, are permitted provided that the following conditions are met:
|
35 |
*
|
36 |
* 1. Redistributions of source code must retain the above copyright notice, this
|
37 |
* list of conditions and the following disclaimer.
|
38 |
*
|
39 |
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
40 |
* this list of conditions and the following disclaimer in the documentation
|
41 |
* and/or other materials provided with the distribution.
|
42 |
*
|
43 |
* 3. Neither the name of the copyright holder nor the names of its contributors
|
44 |
* may be used to endorse or promote products derived from this software
|
45 |
* without specific prior written permission.
|
46 |
*
|
47 |
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
48 |
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
49 |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
50 |
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
51 |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
52 |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
53 |
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
54 |
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
55 |
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
56 |
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
57 |
*
|
58 |
*
|
59 |
********************************************************************************
|
60 |
*
|
61 |
*/
|
62 |
|
63 |
/**
|
64 |
* @file vl53l1_api_core.c
|
65 |
*
|
66 |
* @brief EwokPlus25 low level API function definition
|
67 |
*/
|
68 |
|
69 |
|
70 |
#include "vl53l1_ll_def.h" |
71 |
#include "vl53l1_ll_device.h" |
72 |
#include "vl53l1_platform.h" |
73 |
#include "vl53l1_register_map.h" |
74 |
#include "vl53l1_register_funcs.h" |
75 |
#include "vl53l1_register_settings.h" |
76 |
#include "vl53l1_core.h" |
77 |
#include "vl53l1_wait.h" |
78 |
#include "vl53l1_api_preset_modes.h" |
79 |
#include "vl53l1_silicon_core.h" |
80 |
#include "vl53l1_api_core.h" |
81 |
#include "vl53l1_api_calibration.h" |
82 |
|
83 |
#ifdef VL53L1_LOG_ENABLE
|
84 |
#include "vl53l1_api_debug.h" |
85 |
#endif
|
86 |
#ifdef VL53L1_LOGGING
|
87 |
#include "vl53l1_debug.h" |
88 |
#endif
|
89 |
|
90 |
#define LOG_FUNCTION_START(fmt, ...) \
|
91 |
_LOG_FUNCTION_START(VL53L1_TRACE_MODULE_CORE, fmt, ##__VA_ARGS__) |
92 |
#define LOG_FUNCTION_END(status, ...) \
|
93 |
_LOG_FUNCTION_END(VL53L1_TRACE_MODULE_CORE, status, ##__VA_ARGS__) |
94 |
#define LOG_FUNCTION_END_FMT(status, fmt, ...) \
|
95 |
_LOG_FUNCTION_END_FMT(VL53L1_TRACE_MODULE_CORE, status, \ |
96 |
fmt, ##__VA_ARGS__) |
97 |
|
98 |
#define trace_print(level, ...) \
|
99 |
_LOG_TRACE_PRINT(VL53L1_TRACE_MODULE_CORE, \ |
100 |
level, VL53L1_TRACE_FUNCTION_NONE, ##__VA_ARGS__) |
101 |
|
102 |
|
103 |
#ifndef VL53L1_NOCALIB
|
104 |
VL53L1_Error VL53L1_run_ref_spad_char( |
105 |
VL53L1_DEV Dev, |
106 |
VL53L1_Error *pcal_status) |
107 |
{ |
108 |
/*
|
109 |
* Runs Reference SPAD Characterisation
|
110 |
*/
|
111 |
|
112 |
VL53L1_Error status = VL53L1_ERROR_NONE; |
113 |
VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev); |
114 |
|
115 |
uint8_t comms_buffer[6];
|
116 |
|
117 |
VL53L1_refspadchar_config_t *prefspadchar = &(pdev->refspadchar); |
118 |
|
119 |
LOG_FUNCTION_START("");
|
120 |
|
121 |
/*
|
122 |
* Ensure power force is enabled
|
123 |
*/
|
124 |
|
125 |
if (status == VL53L1_ERROR_NONE) /*lint !e774 always true*/ |
126 |
status = VL53L1_enable_powerforce(Dev); |
127 |
|
128 |
/*
|
129 |
* Configure device
|
130 |
*/
|
131 |
|
132 |
if (status == VL53L1_ERROR_NONE)
|
133 |
status = |
134 |
VL53L1_set_ref_spad_char_config( |
135 |
Dev, |
136 |
prefspadchar->vcsel_period, |
137 |
prefspadchar->timeout_us, |
138 |
prefspadchar->target_count_rate_mcps, |
139 |
prefspadchar->max_count_rate_limit_mcps, |
140 |
prefspadchar->min_count_rate_limit_mcps, |
141 |
pdev->stat_nvm.osc_measured__fast_osc__frequency); |
142 |
|
143 |
/*
|
144 |
* Run device test
|
145 |
*/
|
146 |
|
147 |
if (status == VL53L1_ERROR_NONE)
|
148 |
status = VL53L1_run_device_test( |
149 |
Dev, |
150 |
prefspadchar->device_test_mode); |
151 |
|
152 |
/*
|
153 |
* Read results
|
154 |
*/
|
155 |
|
156 |
if (status == VL53L1_ERROR_NONE)
|
157 |
status = |
158 |
VL53L1_ReadMulti( |
159 |
Dev, |
160 |
VL53L1_REF_SPAD_CHAR_RESULT__NUM_ACTUAL_REF_SPADS, |
161 |
comms_buffer, |
162 |
2);
|
163 |
|
164 |
if (status == VL53L1_ERROR_NONE) {
|
165 |
pdev->dbg_results.ref_spad_char_result__num_actual_ref_spads = |
166 |
comms_buffer[0];
|
167 |
pdev->dbg_results.ref_spad_char_result__ref_location = |
168 |
comms_buffer[1];
|
169 |
} |
170 |
|
171 |
/*
|
172 |
* copy results to customer nvm managed G02 registers
|
173 |
*/
|
174 |
|
175 |
if (status == VL53L1_ERROR_NONE)
|
176 |
status = |
177 |
VL53L1_WriteMulti( |
178 |
Dev, |
179 |
VL53L1_REF_SPAD_MAN__NUM_REQUESTED_REF_SPADS, |
180 |
comms_buffer, |
181 |
2);
|
182 |
|
183 |
if (status == VL53L1_ERROR_NONE) {
|
184 |
pdev->customer.ref_spad_man__num_requested_ref_spads = |
185 |
comms_buffer[0];
|
186 |
pdev->customer.ref_spad_man__ref_location = |
187 |
comms_buffer[1];
|
188 |
} |
189 |
|
190 |
/* After Ref Spad Char the final set of good SPAD enables
|
191 |
* are stored in the NCY results registers below
|
192 |
*
|
193 |
* - RESULT__SPARE_0_SD_1
|
194 |
* - RESULT__SPARE_1_SD_1
|
195 |
* - RESULT__SPARE_2_SD_1
|
196 |
*/
|
197 |
|
198 |
if (status == VL53L1_ERROR_NONE)
|
199 |
status = |
200 |
VL53L1_ReadMulti( |
201 |
Dev, |
202 |
VL53L1_RESULT__SPARE_0_SD1, |
203 |
comms_buffer, |
204 |
6);
|
205 |
|
206 |
/*
|
207 |
* copy reference SPAD enables to customer nvm managed
|
208 |
* G02 registers
|
209 |
*/
|
210 |
|
211 |
if (status == VL53L1_ERROR_NONE)
|
212 |
status = |
213 |
VL53L1_WriteMulti( |
214 |
Dev, |
215 |
VL53L1_GLOBAL_CONFIG__SPAD_ENABLES_REF_0, |
216 |
comms_buffer, |
217 |
6);
|
218 |
|
219 |
if (status == VL53L1_ERROR_NONE) {
|
220 |
pdev->customer.global_config__spad_enables_ref_0 = |
221 |
comms_buffer[0];
|
222 |
pdev->customer.global_config__spad_enables_ref_1 = |
223 |
comms_buffer[1];
|
224 |
pdev->customer.global_config__spad_enables_ref_2 = |
225 |
comms_buffer[2];
|
226 |
pdev->customer.global_config__spad_enables_ref_3 = |
227 |
comms_buffer[3];
|
228 |
pdev->customer.global_config__spad_enables_ref_4 = |
229 |
comms_buffer[4];
|
230 |
pdev->customer.global_config__spad_enables_ref_5 = |
231 |
comms_buffer[5];
|
232 |
} |
233 |
|
234 |
#ifdef VL53L1_LOG_ENABLE
|
235 |
/* Print customer nvm managed data */
|
236 |
if (status == VL53L1_ERROR_NONE)
|
237 |
VL53L1_print_customer_nvm_managed( |
238 |
&(pdev->customer), |
239 |
"run_ref_spad_char():pdev->lldata.customer.",
|
240 |
VL53L1_TRACE_MODULE_REF_SPAD_CHAR); |
241 |
#endif
|
242 |
|
243 |
if (status == VL53L1_ERROR_NONE) {
|
244 |
|
245 |
switch (pdev->sys_results.result__range_status) {
|
246 |
|
247 |
case VL53L1_DEVICEERROR_REFSPADCHARNOTENOUGHDPADS:
|
248 |
status = VL53L1_WARNING_REF_SPAD_CHAR_NOT_ENOUGH_SPADS; |
249 |
break;
|
250 |
|
251 |
case VL53L1_DEVICEERROR_REFSPADCHARMORETHANTARGET:
|
252 |
status = VL53L1_WARNING_REF_SPAD_CHAR_RATE_TOO_HIGH; |
253 |
break;
|
254 |
|
255 |
case VL53L1_DEVICEERROR_REFSPADCHARLESSTHANTARGET:
|
256 |
status = VL53L1_WARNING_REF_SPAD_CHAR_RATE_TOO_LOW; |
257 |
break;
|
258 |
} |
259 |
} |
260 |
|
261 |
/*
|
262 |
* Save unfiltered status
|
263 |
*/
|
264 |
|
265 |
*pcal_status = status; |
266 |
|
267 |
/* Status exception code */
|
268 |
|
269 |
IGNORE_STATUS( |
270 |
IGNORE_REF_SPAD_CHAR_NOT_ENOUGH_SPADS, |
271 |
VL53L1_WARNING_REF_SPAD_CHAR_NOT_ENOUGH_SPADS, |
272 |
status); |
273 |
|
274 |
IGNORE_STATUS( |
275 |
IGNORE_REF_SPAD_CHAR_RATE_TOO_HIGH, |
276 |
VL53L1_WARNING_REF_SPAD_CHAR_RATE_TOO_HIGH, |
277 |
status); |
278 |
|
279 |
IGNORE_STATUS( |
280 |
IGNORE_REF_SPAD_CHAR_RATE_TOO_LOW, |
281 |
VL53L1_WARNING_REF_SPAD_CHAR_RATE_TOO_LOW, |
282 |
status); |
283 |
|
284 |
|
285 |
LOG_FUNCTION_END(status); |
286 |
|
287 |
return status;
|
288 |
} |
289 |
|
290 |
VL53L1_Error VL53L1_run_offset_calibration( |
291 |
VL53L1_DEV Dev, |
292 |
int16_t cal_distance_mm, |
293 |
VL53L1_Error *pcal_status) |
294 |
{ |
295 |
/*
|
296 |
* Runs offset calibration
|
297 |
*
|
298 |
* Recommended tuning parm settings:
|
299 |
*
|
300 |
* - pre_num_of_samples = 32
|
301 |
* - mm1_num_of_samples = 100
|
302 |
* - mm2_num_of_samples = 64
|
303 |
* - target_distance_mm = 140mm
|
304 |
* - target reflectance = 5%
|
305 |
*
|
306 |
* Standard Ranging (sigma delta mode):
|
307 |
* - dss_config__target_total_rate_mcps = 20.0 -40.0 Mcps
|
308 |
* - phasecal_config_timeout_us = 1000
|
309 |
* - range_config_timeout_us = 13000
|
310 |
* - mm_config_timeout_us = 13000
|
311 |
*
|
312 |
*
|
313 |
* Note: function parms simplified as part of
|
314 |
* Patch_CalFunctionSimplification_11791
|
315 |
*
|
316 |
*/
|
317 |
|
318 |
VL53L1_Error status = VL53L1_ERROR_NONE; |
319 |
VL53L1_LLDriverData_t *pdev = |
320 |
VL53L1DevStructGetLLDriverHandle(Dev); |
321 |
|
322 |
VL53L1_DevicePresetModes device_preset_modes[VL53L1_MAX_OFFSET_RANGE_RESULTS]; |
323 |
|
324 |
VL53L1_range_results_t range_results; |
325 |
VL53L1_range_results_t *prange_results = &range_results; |
326 |
VL53L1_range_data_t *prange_data = NULL;
|
327 |
VL53L1_offset_range_data_t *poffset = NULL;
|
328 |
|
329 |
uint8_t i = 0;
|
330 |
uint8_t m = 0;
|
331 |
uint8_t measurement_mode = |
332 |
VL53L1_DEVICEMEASUREMENTMODE_BACKTOBACK; |
333 |
uint16_t manual_effective_spads = |
334 |
pdev->gen_cfg.dss_config__manual_effective_spads_select; |
335 |
|
336 |
uint8_t num_of_samples[VL53L1_MAX_OFFSET_RANGE_RESULTS]; |
337 |
|
338 |
LOG_FUNCTION_START("");
|
339 |
|
340 |
/* select requested offset calibration mode */
|
341 |
|
342 |
switch (pdev->offset_calibration_mode) {
|
343 |
|
344 |
default:
|
345 |
device_preset_modes[0] =
|
346 |
VL53L1_DEVICEPRESETMODE_STANDARD_RANGING; |
347 |
device_preset_modes[1] =
|
348 |
VL53L1_DEVICEPRESETMODE_STANDARD_RANGING_MM1_CAL; |
349 |
device_preset_modes[2] =
|
350 |
VL53L1_DEVICEPRESETMODE_STANDARD_RANGING_MM2_CAL; |
351 |
break;
|
352 |
} |
353 |
|
354 |
/* initialise num_of_samples */
|
355 |
/* Start Patch_CalFunctionSimplification_11791 */
|
356 |
num_of_samples[0] = pdev->offsetcal_cfg.pre_num_of_samples;
|
357 |
num_of_samples[1] = pdev->offsetcal_cfg.mm1_num_of_samples;
|
358 |
num_of_samples[2] = pdev->offsetcal_cfg.mm2_num_of_samples;
|
359 |
/* End Patch_CalFunctionSimplification_11791 */
|
360 |
|
361 |
/* force all offsets to zero */
|
362 |
|
363 |
switch (pdev->offset_calibration_mode) {
|
364 |
|
365 |
case VL53L1_OFFSETCALIBRATIONMODE__MM1_MM2__STANDARD_PRE_RANGE_ONLY:
|
366 |
/* only run pre range */
|
367 |
pdev->offset_results.active_results = 1;
|
368 |
|
369 |
break;
|
370 |
|
371 |
default:
|
372 |
|
373 |
pdev->customer.mm_config__inner_offset_mm = 0;
|
374 |
pdev->customer.mm_config__outer_offset_mm = 0;
|
375 |
pdev->offset_results.active_results = |
376 |
VL53L1_MAX_OFFSET_RANGE_RESULTS; |
377 |
|
378 |
break;
|
379 |
} |
380 |
|
381 |
pdev->customer.algo__part_to_part_range_offset_mm = 0;
|
382 |
|
383 |
/* initialise offset range results */
|
384 |
|
385 |
pdev->offset_results.max_results = VL53L1_MAX_OFFSET_RANGE_RESULTS; |
386 |
pdev->offset_results.cal_distance_mm = cal_distance_mm; |
387 |
|
388 |
for (m = 0 ; m < VL53L1_MAX_OFFSET_RANGE_RESULTS; m++) { |
389 |
|
390 |
poffset = &(pdev->offset_results.data[m]); |
391 |
poffset->preset_mode = 0;
|
392 |
poffset->no_of_samples = 0;
|
393 |
poffset->effective_spads = 0;
|
394 |
poffset->peak_rate_mcps = 0;
|
395 |
poffset->sigma_mm = 0;
|
396 |
poffset->median_range_mm = 0;
|
397 |
} |
398 |
|
399 |
for (m = 0 ; m < pdev->offset_results.active_results ; m++) { |
400 |
|
401 |
poffset = &(pdev->offset_results.data[m]); |
402 |
|
403 |
poffset->preset_mode = device_preset_modes[m]; |
404 |
|
405 |
/* Apply preset mode */
|
406 |
|
407 |
if (status == VL53L1_ERROR_NONE)
|
408 |
status = |
409 |
VL53L1_set_preset_mode( |
410 |
Dev, |
411 |
device_preset_modes[m], |
412 |
/* Start Patch_CalFunctionSimplification_11791 */
|
413 |
pdev->offsetcal_cfg.dss_config__target_total_rate_mcps, |
414 |
pdev->offsetcal_cfg.phasecal_config_timeout_us, |
415 |
pdev->offsetcal_cfg.mm_config_timeout_us, |
416 |
pdev->offsetcal_cfg.range_config_timeout_us, |
417 |
/* End Patch_CalFunctionSimplification_11791 */
|
418 |
100);
|
419 |
|
420 |
pdev->gen_cfg.dss_config__manual_effective_spads_select = |
421 |
manual_effective_spads; |
422 |
|
423 |
/* Initialise device and start range */
|
424 |
|
425 |
if (status == VL53L1_ERROR_NONE)
|
426 |
status = |
427 |
VL53L1_init_and_start_range( |
428 |
Dev, |
429 |
measurement_mode, |
430 |
VL53L1_DEVICECONFIGLEVEL_CUSTOMER_ONWARDS); |
431 |
|
432 |
for (i = 0 ; i <= (num_of_samples[m]+2) ; i++) { |
433 |
|
434 |
/* Wait for range completion */
|
435 |
|
436 |
if (status == VL53L1_ERROR_NONE)
|
437 |
status = |
438 |
VL53L1_wait_for_range_completion(Dev); |
439 |
|
440 |
/*
|
441 |
* Get Device Results
|
442 |
* - Checks the stream count is the expected one
|
443 |
* - Read device system results
|
444 |
*/
|
445 |
|
446 |
if (status == VL53L1_ERROR_NONE)
|
447 |
status = |
448 |
VL53L1_get_device_results( |
449 |
Dev, |
450 |
VL53L1_DEVICERESULTSLEVEL_FULL, |
451 |
prange_results); |
452 |
|
453 |
/*
|
454 |
* Ignore 1st two ranges to give the sigma delta initial
|
455 |
* phase time to settle
|
456 |
*
|
457 |
* accummulate range results if range is successful
|
458 |
*/
|
459 |
|
460 |
prange_data = &(prange_results->data[0]);
|
461 |
|
462 |
if (prange_results->stream_count > 1) { |
463 |
|
464 |
if (prange_data->range_status ==
|
465 |
VL53L1_DEVICEERROR_RANGECOMPLETE) { |
466 |
|
467 |
poffset->no_of_samples++; |
468 |
poffset->effective_spads += |
469 |
(uint32_t)prange_data->actual_effective_spads; |
470 |
poffset->peak_rate_mcps += |
471 |
(uint32_t)prange_data->peak_signal_count_rate_mcps; |
472 |
poffset->sigma_mm += |
473 |
(uint32_t)prange_data->sigma_mm; |
474 |
poffset->median_range_mm += |
475 |
(int32_t)prange_data->median_range_mm; |
476 |
|
477 |
poffset->dss_config__roi_mode_control = |
478 |
pdev->gen_cfg.dss_config__roi_mode_control; |
479 |
poffset->dss_config__manual_effective_spads_select = |
480 |
pdev->gen_cfg.dss_config__manual_effective_spads_select; |
481 |
} |
482 |
} |
483 |
|
484 |
/*
|
485 |
* Conditional wait for firmware ready. Only waits for timed
|
486 |
* and single shot modes. Mode check is performed inside the
|
487 |
* wait function
|
488 |
*/
|
489 |
|
490 |
if (status == VL53L1_ERROR_NONE)
|
491 |
status = |
492 |
VL53L1_wait_for_firmware_ready(Dev); |
493 |
|
494 |
/*
|
495 |
* Send ranging handshake
|
496 |
*
|
497 |
* - Update Zone management
|
498 |
* - Update GPH registers
|
499 |
* - Clear current interrupt
|
500 |
* - Initialise SYSTEM__MODE_START for next range (if there is one!)
|
501 |
*/
|
502 |
|
503 |
if (status == VL53L1_ERROR_NONE)
|
504 |
status = |
505 |
VL53L1_clear_interrupt_and_enable_next_range( |
506 |
Dev, |
507 |
measurement_mode); |
508 |
} |
509 |
|
510 |
/* Stop range */
|
511 |
|
512 |
if (status == VL53L1_ERROR_NONE)
|
513 |
status = VL53L1_stop_range(Dev); |
514 |
|
515 |
/* Wait for Stop (abort) range to complete */
|
516 |
|
517 |
if (status == VL53L1_ERROR_NONE)
|
518 |
status = VL53L1_WaitUs(Dev, 1000);
|
519 |
|
520 |
/* generate average values */
|
521 |
if (poffset->no_of_samples > 0) { |
522 |
|
523 |
poffset->effective_spads += (poffset->no_of_samples/2);
|
524 |
poffset->effective_spads /= poffset->no_of_samples; |
525 |
|
526 |
poffset->peak_rate_mcps += (poffset->no_of_samples/2);
|
527 |
poffset->peak_rate_mcps /= poffset->no_of_samples; |
528 |
|
529 |
poffset->sigma_mm += (poffset->no_of_samples/2);
|
530 |
poffset->sigma_mm /= poffset->no_of_samples; |
531 |
|
532 |
poffset->median_range_mm += (poffset->no_of_samples/2);
|
533 |
poffset->median_range_mm /= poffset->no_of_samples; |
534 |
|
535 |
poffset->range_mm_offset = (int32_t)cal_distance_mm; |
536 |
poffset->range_mm_offset -= poffset->median_range_mm; |
537 |
|
538 |
/* remember the number of SPADs for standard ranging */
|
539 |
if (poffset->preset_mode ==
|
540 |
VL53L1_DEVICEPRESETMODE_STANDARD_RANGING) |
541 |
manual_effective_spads = |
542 |
(uint16_t)poffset->effective_spads; |
543 |
} |
544 |
} |
545 |
|
546 |
/* Calculate offsets */
|
547 |
|
548 |
switch (pdev->offset_calibration_mode) {
|
549 |
|
550 |
case VL53L1_OFFSETCALIBRATIONMODE__MM1_MM2__STANDARD_PRE_RANGE_ONLY:
|
551 |
|
552 |
/* copy offsets to customer data structure */
|
553 |
pdev->customer.mm_config__inner_offset_mm += |
554 |
(int16_t)pdev->offset_results.data[0].range_mm_offset;
|
555 |
pdev->customer.mm_config__outer_offset_mm += |
556 |
(int16_t)pdev->offset_results.data[0].range_mm_offset;
|
557 |
break;
|
558 |
|
559 |
default:
|
560 |
/* copy offsets to customer data structure */
|
561 |
pdev->customer.mm_config__inner_offset_mm = |
562 |
(int16_t)pdev->offset_results.data[1].range_mm_offset;
|
563 |
pdev->customer.mm_config__outer_offset_mm = |
564 |
(int16_t)pdev->offset_results.data[2].range_mm_offset;
|
565 |
pdev->customer.algo__part_to_part_range_offset_mm = 0;
|
566 |
|
567 |
/* copy average rate and effective SPAD count to
|
568 |
additional offset calibration data structure */
|
569 |
|
570 |
pdev->add_off_cal_data.result__mm_inner_actual_effective_spads = |
571 |
(uint16_t)pdev->offset_results.data[1].effective_spads;
|
572 |
pdev->add_off_cal_data.result__mm_outer_actual_effective_spads = |
573 |
(uint16_t)pdev->offset_results.data[2].effective_spads;
|
574 |
|
575 |
pdev->add_off_cal_data.result__mm_inner_peak_signal_count_rtn_mcps = |
576 |
(uint16_t)pdev->offset_results.data[1].peak_rate_mcps;
|
577 |
pdev->add_off_cal_data.result__mm_outer_peak_signal_count_rtn_mcps = |
578 |
(uint16_t)pdev->offset_results.data[2].peak_rate_mcps;
|
579 |
|
580 |
break;
|
581 |
} |
582 |
|
583 |
|
584 |
/* apply to device */
|
585 |
|
586 |
if (status == VL53L1_ERROR_NONE)
|
587 |
status = |
588 |
VL53L1_set_customer_nvm_managed( |
589 |
Dev, |
590 |
&(pdev->customer)); |
591 |
|
592 |
/*
|
593 |
* Check the peak rates, sigma, min spads for each stage
|
594 |
*/
|
595 |
|
596 |
for (m = 0 ; m < pdev->offset_results.active_results ; m++) { |
597 |
|
598 |
poffset = &(pdev->offset_results.data[m]); |
599 |
|
600 |
if (status == VL53L1_ERROR_NONE) {
|
601 |
|
602 |
pdev->offset_results.cal_report = m; |
603 |
|
604 |
if (poffset->no_of_samples < num_of_samples[m])
|
605 |
status = VL53L1_WARNING_OFFSET_CAL_MISSING_SAMPLES; |
606 |
|
607 |
/* only check sigma for the pre-range as
|
608 |
* the it is not calculated by the device
|
609 |
* for the MM1 and MM2 stages
|
610 |
*/
|
611 |
if (m == 0 && poffset->sigma_mm > |
612 |
((uint32_t)VL53L1_OFFSET_CAL_MAX_SIGMA_MM<<5))
|
613 |
status = VL53L1_WARNING_OFFSET_CAL_SIGMA_TOO_HIGH; |
614 |
|
615 |
if (poffset->peak_rate_mcps >
|
616 |
VL53L1_OFFSET_CAL_MAX_PRE_PEAK_RATE_MCPS) |
617 |
status = VL53L1_WARNING_OFFSET_CAL_RATE_TOO_HIGH; |
618 |
|
619 |
if (poffset->dss_config__manual_effective_spads_select <
|
620 |
VL53L1_OFFSET_CAL_MIN_EFFECTIVE_SPADS) |
621 |
status = VL53L1_WARNING_OFFSET_CAL_SPAD_COUNT_TOO_LOW; |
622 |
|
623 |
if (poffset->dss_config__manual_effective_spads_select == 0) |
624 |
status = VL53L1_ERROR_OFFSET_CAL_NO_SPADS_ENABLED_FAIL; |
625 |
|
626 |
if (poffset->no_of_samples == 0) |
627 |
status = VL53L1_ERROR_OFFSET_CAL_NO_SAMPLE_FAIL; |
628 |
} |
629 |
} |
630 |
|
631 |
/*
|
632 |
* Save unfiltered status
|
633 |
*/
|
634 |
|
635 |
pdev->offset_results.cal_status = status; |
636 |
*pcal_status = pdev->offset_results.cal_status; |
637 |
|
638 |
/* Status exception codes */
|
639 |
|
640 |
IGNORE_STATUS( |
641 |
IGNORE_OFFSET_CAL_MISSING_SAMPLES, |
642 |
VL53L1_WARNING_OFFSET_CAL_MISSING_SAMPLES, |
643 |
status); |
644 |
|
645 |
IGNORE_STATUS( |
646 |
IGNORE_OFFSET_CAL_SIGMA_TOO_HIGH, |
647 |
VL53L1_WARNING_OFFSET_CAL_SIGMA_TOO_HIGH, |
648 |
status); |
649 |
|
650 |
IGNORE_STATUS( |
651 |
IGNORE_OFFSET_CAL_RATE_TOO_HIGH, |
652 |
VL53L1_WARNING_OFFSET_CAL_RATE_TOO_HIGH, |
653 |
status); |
654 |
|
655 |
IGNORE_STATUS( |
656 |
IGNORE_OFFSET_CAL_SPAD_COUNT_TOO_LOW, |
657 |
VL53L1_WARNING_OFFSET_CAL_SPAD_COUNT_TOO_LOW, |
658 |
status); |
659 |
|
660 |
#ifdef VL53L1_LOG_ENABLE
|
661 |
|
662 |
/* Prints out the offset calibration data for debug */
|
663 |
|
664 |
VL53L1_print_customer_nvm_managed( |
665 |
&(pdev->customer), |
666 |
"run_offset_calibration():pdev->lldata.customer.",
|
667 |
VL53L1_TRACE_MODULE_OFFSET_DATA); |
668 |
|
669 |
VL53L1_print_additional_offset_cal_data( |
670 |
&(pdev->add_off_cal_data), |
671 |
"run_offset_calibration():pdev->lldata.add_off_cal_data.",
|
672 |
VL53L1_TRACE_MODULE_OFFSET_DATA); |
673 |
|
674 |
VL53L1_print_offset_range_results( |
675 |
&(pdev->offset_results), |
676 |
"run_offset_calibration():pdev->lldata.offset_results.",
|
677 |
VL53L1_TRACE_MODULE_OFFSET_DATA); |
678 |
#endif
|
679 |
|
680 |
LOG_FUNCTION_END(status); |
681 |
|
682 |
return status;
|
683 |
} |
684 |
#endif
|
685 |
|
686 |
#ifndef VL53L1_NOCALIB
|
687 |
VL53L1_Error VL53L1_run_spad_rate_map( |
688 |
VL53L1_DEV Dev, |
689 |
VL53L1_DeviceTestMode device_test_mode, |
690 |
VL53L1_DeviceSscArray array_select, |
691 |
uint32_t ssc_config_timeout_us, |
692 |
VL53L1_spad_rate_data_t *pspad_rate_data) |
693 |
{ |
694 |
|
695 |
/**
|
696 |
* Runs SPAD Rate Map
|
697 |
*/
|
698 |
|
699 |
VL53L1_Error status = VL53L1_ERROR_NONE; |
700 |
|
701 |
VL53L1_LLDriverData_t *pdev = |
702 |
VL53L1DevStructGetLLDriverHandle(Dev); |
703 |
|
704 |
LOG_FUNCTION_START("");
|
705 |
|
706 |
/*
|
707 |
* Ensure power force is enabled
|
708 |
*/
|
709 |
if (status == VL53L1_ERROR_NONE)
|
710 |
status = VL53L1_enable_powerforce(Dev); |
711 |
|
712 |
/*
|
713 |
* Configure the test
|
714 |
*/
|
715 |
|
716 |
if (status == VL53L1_ERROR_NONE) {
|
717 |
pdev->ssc_cfg.array_select = array_select; |
718 |
pdev->ssc_cfg.timeout_us = ssc_config_timeout_us; |
719 |
status = |
720 |
VL53L1_set_ssc_config( |
721 |
Dev, |
722 |
&(pdev->ssc_cfg), |
723 |
pdev->stat_nvm.osc_measured__fast_osc__frequency); |
724 |
} |
725 |
|
726 |
/*
|
727 |
* Run device test
|
728 |
*/
|
729 |
|
730 |
if (status == VL53L1_ERROR_NONE)
|
731 |
status = |
732 |
VL53L1_run_device_test( |
733 |
Dev, |
734 |
device_test_mode); |
735 |
|
736 |
/*
|
737 |
* Read Rate Data from Patch Ram
|
738 |
*/
|
739 |
|
740 |
if (status == VL53L1_ERROR_NONE)
|
741 |
status = |
742 |
VL53L1_get_spad_rate_data( |
743 |
Dev, |
744 |
pspad_rate_data); |
745 |
|
746 |
if (device_test_mode == VL53L1_DEVICETESTMODE_LCR_VCSEL_ON)
|
747 |
pspad_rate_data->fractional_bits = 7;
|
748 |
else
|
749 |
pspad_rate_data->fractional_bits = 15;
|
750 |
|
751 |
/* Ensure power force is disabled */
|
752 |
|
753 |
if (status == VL53L1_ERROR_NONE)
|
754 |
status = VL53L1_disable_powerforce(Dev); |
755 |
|
756 |
#ifdef VL53L1_LOG_ENABLE
|
757 |
/* Print return rate data and map */
|
758 |
|
759 |
if (status == VL53L1_ERROR_NONE) {
|
760 |
VL53L1_print_spad_rate_data( |
761 |
pspad_rate_data, |
762 |
"run_spad_rate_map():",
|
763 |
VL53L1_TRACE_MODULE_SPAD_RATE_MAP); |
764 |
VL53L1_print_spad_rate_map( |
765 |
pspad_rate_data, |
766 |
"run_spad_rate_map():",
|
767 |
VL53L1_TRACE_MODULE_SPAD_RATE_MAP); |
768 |
} |
769 |
#endif
|
770 |
|
771 |
LOG_FUNCTION_END(status); |
772 |
|
773 |
return status;
|
774 |
} |
775 |
#endif
|
776 |
|
777 |
|
778 |
#ifndef VL53L1_NOCALIB
|
779 |
VL53L1_Error VL53L1_run_device_test( |
780 |
VL53L1_DEV Dev, |
781 |
VL53L1_DeviceTestMode device_test_mode) |
782 |
{ |
783 |
/*
|
784 |
* Runs the selected Device Test Mode
|
785 |
*/
|
786 |
|
787 |
VL53L1_Error status = VL53L1_ERROR_NONE; |
788 |
VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev); |
789 |
|
790 |
uint8_t comms_buffer[2];
|
791 |
uint8_t gpio_hv_mux__ctrl = 0;
|
792 |
|
793 |
LOG_FUNCTION_START("");
|
794 |
|
795 |
/*
|
796 |
* Get current interrupt config
|
797 |
*/
|
798 |
|
799 |
if (status == VL53L1_ERROR_NONE) /*lint !e774 always true*/ |
800 |
status = |
801 |
VL53L1_RdByte( |
802 |
Dev, |
803 |
VL53L1_GPIO_HV_MUX__CTRL, |
804 |
&gpio_hv_mux__ctrl); |
805 |
|
806 |
if (status == VL53L1_ERROR_NONE)
|
807 |
pdev->stat_cfg.gpio_hv_mux__ctrl = gpio_hv_mux__ctrl; |
808 |
|
809 |
/*
|
810 |
* Trigger the test
|
811 |
*/
|
812 |
if (status == VL53L1_ERROR_NONE)
|
813 |
status = VL53L1_start_test( |
814 |
Dev, |
815 |
device_test_mode); |
816 |
|
817 |
/*
|
818 |
* Wait for test completion
|
819 |
*/
|
820 |
if (status == VL53L1_ERROR_NONE)
|
821 |
status = VL53L1_wait_for_test_completion(Dev); |
822 |
|
823 |
/*
|
824 |
* Read range and report status
|
825 |
*/
|
826 |
if (status == VL53L1_ERROR_NONE)
|
827 |
status = |
828 |
VL53L1_ReadMulti( |
829 |
Dev, |
830 |
VL53L1_RESULT__RANGE_STATUS, |
831 |
comms_buffer, |
832 |
2);
|
833 |
|
834 |
if (status == VL53L1_ERROR_NONE) {
|
835 |
pdev->sys_results.result__range_status = comms_buffer[0];
|
836 |
pdev->sys_results.result__report_status = comms_buffer[1];
|
837 |
} |
838 |
|
839 |
/* mask range status bits */
|
840 |
|
841 |
pdev->sys_results.result__range_status &= |
842 |
VL53L1_RANGE_STATUS__RANGE_STATUS_MASK; |
843 |
|
844 |
if (status == VL53L1_ERROR_NONE) {
|
845 |
trace_print( |
846 |
VL53L1_TRACE_LEVEL_INFO, |
847 |
" Device Test Complete:\n\t%-32s = %3u\n\t%-32s = %3u\n",
|
848 |
"result__range_status",
|
849 |
pdev->sys_results.result__range_status, |
850 |
"result__report_status",
|
851 |
pdev->sys_results.result__report_status); |
852 |
|
853 |
/*
|
854 |
* Clear interrupt
|
855 |
*/
|
856 |
if (status == VL53L1_ERROR_NONE)
|
857 |
status = VL53L1_clear_interrupt(Dev); |
858 |
} |
859 |
|
860 |
/*
|
861 |
* Clear test mode register
|
862 |
* - required so that next test command will trigger
|
863 |
* internal MCU interrupt
|
864 |
*/
|
865 |
|
866 |
if (status == VL53L1_ERROR_NONE)
|
867 |
status = |
868 |
VL53L1_start_test( |
869 |
Dev, |
870 |
0x00);
|
871 |
|
872 |
LOG_FUNCTION_END(status); |
873 |
|
874 |
return status;
|
875 |
} |
876 |
#endif
|