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
VL53L1_run_ref_spad_char(VL53L1_DEV Dev,VL53L1_Error * pcal_status)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
VL53L1_run_offset_calibration(VL53L1_DEV Dev,int16_t cal_distance_mm,VL53L1_Error * pcal_status)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
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)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
VL53L1_run_device_test(VL53L1_DEV Dev,VL53L1_DeviceTestMode device_test_mode)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
877