Statistics
| Branch: | Tag: | Revision:

amiro-lld / drivers / VL53L1X / v1 / api / core / vl53l1_wait.c @ f0dd1ac4

History | View | Annotate | Download (13.237 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_wait.c
65
 *
66
 * @brief EwokPlus25 low level Driver wait 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_core.h"
74
#include "vl53l1_silicon_core.h"
75
#include "vl53l1_wait.h"
76
#include "vl53l1_register_settings.h"
77

    
78

    
79
#define LOG_FUNCTION_START(fmt, ...) \
80
        _LOG_FUNCTION_START(VL53L1_TRACE_MODULE_CORE, fmt, ##__VA_ARGS__)
81
#define LOG_FUNCTION_END(status, ...) \
82
        _LOG_FUNCTION_END(VL53L1_TRACE_MODULE_CORE, status, ##__VA_ARGS__)
83
#define LOG_FUNCTION_END_FMT(status, fmt, ...) \
84
        _LOG_FUNCTION_END_FMT(VL53L1_TRACE_MODULE_CORE, status, \
85
                fmt, ##__VA_ARGS__)
86

    
87

    
88
VL53L1_Error VL53L1_wait_for_boot_completion(
89
        VL53L1_DEV     Dev)
90
{
91

    
92
        /* Waits for firmware boot to finish
93
         */
94

    
95
        VL53L1_Error status = VL53L1_ERROR_NONE;
96
        VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
97

    
98
        uint8_t      fw_ready  = 0;
99

    
100
        LOG_FUNCTION_START("");
101

    
102
        if (pdev->wait_method == VL53L1_WAIT_METHOD_BLOCKING) {
103

    
104
                /* blocking version */
105

    
106
                status =
107
                        VL53L1_poll_for_boot_completion(
108
                                Dev,
109
                                VL53L1_BOOT_COMPLETION_POLLING_TIMEOUT_MS);
110

    
111
        } else {
112

    
113
                /* implement non blocking version below */
114

    
115
                fw_ready = 0;
116
                while (fw_ready == 0x00 && status == VL53L1_ERROR_NONE) {
117
                        status = VL53L1_is_boot_complete(
118
                                Dev,
119
                                &fw_ready);
120

    
121
                        if (status == VL53L1_ERROR_NONE) {
122
                                status = VL53L1_WaitMs(
123
                                        Dev,
124
                                        VL53L1_POLLING_DELAY_MS);
125
                        }
126
                }
127
        }
128

    
129
        LOG_FUNCTION_END(status);
130

    
131
        return status;
132

    
133
}
134

    
135

    
136
VL53L1_Error VL53L1_wait_for_firmware_ready(
137
        VL53L1_DEV     Dev)
138
{
139

    
140
        /* If in timed mode or single shot then check firmware is ready
141
         * before sending handshake
142
         */
143

    
144
        VL53L1_Error status = VL53L1_ERROR_NONE;
145
        VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
146

    
147
        uint8_t      fw_ready  = 0;
148
        uint8_t      mode_start  = 0;
149

    
150
        LOG_FUNCTION_START("");
151

    
152
        /* Filter out tje measure mode part of the mode
153
         * start register
154
         */
155
        mode_start =
156
                pdev->sys_ctrl.system__mode_start &
157
                VL53L1_DEVICEMEASUREMENTMODE_MODE_MASK;
158

    
159
        /*
160
         * conditional wait for firmware ready
161
         * only waits for timed and single shot modes
162
         */
163

    
164
        if ((mode_start == VL53L1_DEVICEMEASUREMENTMODE_TIMED) ||
165
                (mode_start == VL53L1_DEVICEMEASUREMENTMODE_SINGLESHOT)) {
166

    
167
                if (pdev->wait_method == VL53L1_WAIT_METHOD_BLOCKING) {
168

    
169
                        /* blocking version */
170

    
171
                        status =
172
                                VL53L1_poll_for_firmware_ready(
173
                                        Dev,
174
                                        VL53L1_RANGE_COMPLETION_POLLING_TIMEOUT_MS);
175

    
176
                } else {
177

    
178
                        /* implement non blocking version below */
179

    
180
                        fw_ready = 0;
181
                        while (fw_ready == 0x00 && status == VL53L1_ERROR_NONE) {
182
                                status = VL53L1_is_firmware_ready(
183
                                        Dev,
184
                                        &fw_ready);
185

    
186
                                if (status == VL53L1_ERROR_NONE) {
187
                                        status = VL53L1_WaitMs(
188
                                                Dev,
189
                                                VL53L1_POLLING_DELAY_MS);
190
                                }
191
                        }
192
                }
193
        }
194

    
195
        LOG_FUNCTION_END(status);
196

    
197
        return status;
198
}
199

    
200

    
201
VL53L1_Error VL53L1_wait_for_range_completion(
202
        VL53L1_DEV     Dev)
203
{
204

    
205
        /* Wrapper function for waiting for range completion
206
         */
207

    
208
        VL53L1_Error status = VL53L1_ERROR_NONE;
209
        VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
210

    
211
        uint8_t      data_ready  = 0;
212

    
213
        LOG_FUNCTION_START("");
214

    
215
        if (pdev->wait_method == VL53L1_WAIT_METHOD_BLOCKING) {
216

    
217
                /* blocking version */
218

    
219
                status =
220
                        VL53L1_poll_for_range_completion(
221
                                Dev,
222
                                VL53L1_RANGE_COMPLETION_POLLING_TIMEOUT_MS);
223

    
224
        } else {
225

    
226
                /* implement non blocking version below */
227

    
228
                data_ready = 0;
229
                while (data_ready == 0x00 && status == VL53L1_ERROR_NONE) {
230
                        status = VL53L1_is_new_data_ready(
231
                                Dev,
232
                                &data_ready);
233

    
234
                        if (status == VL53L1_ERROR_NONE) {
235
                                status = VL53L1_WaitMs(
236
                                        Dev,
237
                                        VL53L1_POLLING_DELAY_MS);
238
                        }
239
                }
240
        }
241

    
242
        LOG_FUNCTION_END(status);
243

    
244
        return status;
245
}
246

    
247

    
248
VL53L1_Error VL53L1_wait_for_test_completion(
249
        VL53L1_DEV     Dev)
250
{
251

    
252
        /* Wrapper function for waiting for test mode completion
253
         */
254

    
255
        VL53L1_Error status = VL53L1_ERROR_NONE;
256
        VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
257

    
258
        uint8_t      data_ready  = 0;
259

    
260
        LOG_FUNCTION_START("");
261

    
262
        if (pdev->wait_method == VL53L1_WAIT_METHOD_BLOCKING) {
263

    
264
                /* blocking version */
265

    
266
                status =
267
                        VL53L1_poll_for_range_completion(
268
                                Dev,
269
                                VL53L1_TEST_COMPLETION_POLLING_TIMEOUT_MS);
270

    
271
        } else {
272

    
273
                /* implement non blocking version below */
274

    
275
                data_ready = 0;
276
                while (data_ready == 0x00 && status == VL53L1_ERROR_NONE) {
277
                        status = VL53L1_is_new_data_ready(
278
                                Dev,
279
                                &data_ready);
280

    
281
                        if (status == VL53L1_ERROR_NONE) {
282
                                status = VL53L1_WaitMs(
283
                                        Dev,
284
                                        VL53L1_POLLING_DELAY_MS);
285
                        }
286
                }
287
        }
288

    
289
        LOG_FUNCTION_END(status);
290

    
291
        return status;
292
}
293

    
294

    
295

    
296

    
297
VL53L1_Error VL53L1_is_boot_complete(
298
        VL53L1_DEV     Dev,
299
        uint8_t       *pready)
300
{
301
        /**
302
         * Determines if the firmware finished booting by reading
303
         * bit 0 of firmware__system_status register
304
         */
305

    
306
        VL53L1_Error status = VL53L1_ERROR_NONE;
307
        uint8_t  firmware__system_status = 0;
308

    
309
        LOG_FUNCTION_START("");
310

    
311
        /* read current range interrupt state */
312

    
313
        status =
314
                VL53L1_RdByte(
315
                        Dev,
316
                        VL53L1_FIRMWARE__SYSTEM_STATUS,
317
                        &firmware__system_status);
318

    
319
        /* set *pready = 1 if new range data ready complete
320
         * zero otherwise
321
         */
322

    
323
        if ((firmware__system_status & 0x01) == 0x01) {
324
                *pready = 0x01;
325
                VL53L1_init_ll_driver_state(
326
                        Dev,
327
                        VL53L1_DEVICESTATE_SW_STANDBY);
328
        } else {
329
                *pready = 0x00;
330
                VL53L1_init_ll_driver_state(
331
                        Dev,
332
                        VL53L1_DEVICESTATE_FW_COLDBOOT);
333
        }
334

    
335
        LOG_FUNCTION_END(status);
336

    
337
        return status;
338
}
339

    
340

    
341
VL53L1_Error VL53L1_is_firmware_ready(
342
        VL53L1_DEV     Dev,
343
        uint8_t       *pready)
344
{
345
        /**
346
         * Determines if the firmware is ready to range
347
         */
348

    
349
        VL53L1_Error status = VL53L1_ERROR_NONE;
350
        VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
351

    
352
        LOG_FUNCTION_START("");
353

    
354
        status = VL53L1_is_firmware_ready_silicon(
355
                                        Dev,
356
                                        pready);
357

    
358
        pdev->fw_ready = *pready;
359

    
360
        LOG_FUNCTION_END(status);
361

    
362
        return status;
363
}
364

    
365

    
366
VL53L1_Error VL53L1_is_new_data_ready(
367
        VL53L1_DEV     Dev,
368
        uint8_t       *pready)
369
{
370
        /**
371
         * Determines if new range data is ready by reading bit 0 of
372
         * VL53L1_GPIO__TIO_HV_STATUS to determine the current state
373
         * of output interrupt pin
374
         */
375

    
376
        VL53L1_Error status = VL53L1_ERROR_NONE;
377
        VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
378

    
379
        uint8_t  gpio__mux_active_high_hv = 0;
380
        uint8_t  gpio__tio_hv_status      = 0;
381
        uint8_t  interrupt_ready          = 0;
382

    
383
        LOG_FUNCTION_START("");
384

    
385
        gpio__mux_active_high_hv =
386
                        pdev->stat_cfg.gpio_hv_mux__ctrl &
387
                        VL53L1_DEVICEINTERRUPTLEVEL_ACTIVE_MASK;
388

    
389
        if (gpio__mux_active_high_hv == VL53L1_DEVICEINTERRUPTLEVEL_ACTIVE_HIGH)
390
                interrupt_ready = 0x01;
391
        else
392
                interrupt_ready = 0x00;
393

    
394
        /* read current range interrupt state */
395

    
396
        status = VL53L1_RdByte(
397
                                        Dev,
398
                                        VL53L1_GPIO__TIO_HV_STATUS,
399
                                        &gpio__tio_hv_status);
400

    
401
        /* set *pready = 1 if new range data ready complete zero otherwise */
402

    
403
        if ((gpio__tio_hv_status & 0x01) == interrupt_ready)
404
                *pready = 0x01;
405
        else
406
                *pready = 0x00;
407

    
408
        LOG_FUNCTION_END(status);
409

    
410
        return status;
411
}
412

    
413

    
414

    
415

    
416
VL53L1_Error VL53L1_poll_for_boot_completion(
417
        VL53L1_DEV    Dev,
418
        uint32_t      timeout_ms)
419
{
420
        /**
421
         * Polls the bit 0 of the FIRMWARE__SYSTEM_STATUS register to see if
422
         * the firmware is ready.
423
         */
424

    
425
        VL53L1_Error status       = VL53L1_ERROR_NONE;
426

    
427
        LOG_FUNCTION_START("");
428

    
429
        /* after reset for the firmware blocks I2C access while
430
         * it copies the NVM data into the G02 host register banks
431
         * The host must wait the required time to allow the copy
432
         * to complete before attempting to read the firmware status
433
         */
434

    
435
        status = VL53L1_WaitUs(
436
                        Dev,
437
                        VL53L1_FIRMWARE_BOOT_TIME_US);
438

    
439
        if (status == VL53L1_ERROR_NONE)
440
                status =
441
                        VL53L1_WaitValueMaskEx(
442
                                Dev,
443
                                timeout_ms,
444
                                VL53L1_FIRMWARE__SYSTEM_STATUS,
445
                                0x01,
446
                                0x01,
447
                                VL53L1_POLLING_DELAY_MS);
448

    
449
        if (status == VL53L1_ERROR_NONE)
450
                VL53L1_init_ll_driver_state(Dev, VL53L1_DEVICESTATE_SW_STANDBY);
451

    
452
        LOG_FUNCTION_END(status);
453

    
454
        return status;
455
}
456

    
457

    
458
VL53L1_Error VL53L1_poll_for_firmware_ready(
459
        VL53L1_DEV    Dev,
460
        uint32_t      timeout_ms)
461
{
462
        /**
463
         * Polls the bit 0 of the FIRMWARE__SYSTEM_STATUS register to see if
464
         * the firmware is ready.
465
         */
466

    
467
        VL53L1_Error status          = VL53L1_ERROR_NONE;
468
        VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
469

    
470
        uint32_t     start_time_ms   = 0;
471
        uint32_t     current_time_ms = 0;
472
        int32_t      poll_delay_ms   = VL53L1_POLLING_DELAY_MS;
473
        uint8_t      fw_ready        = 0;
474

    
475
        /* calculate time limit in absolute time */
476

    
477
        VL53L1_GetTickCount(&start_time_ms); /*lint !e534 ignoring return*/
478
        pdev->fw_ready_poll_duration_ms = 0;
479

    
480
        /* wait until firmware is ready, timeout reached on error occurred */
481

    
482
        while ((status == VL53L1_ERROR_NONE) &&
483
                   (pdev->fw_ready_poll_duration_ms < timeout_ms) &&
484
                   (fw_ready == 0)) {
485

    
486
                status = VL53L1_is_firmware_ready(
487
                        Dev,
488
                        &fw_ready);
489

    
490
                if (status == VL53L1_ERROR_NONE &&
491
                        fw_ready == 0 &&
492
                        poll_delay_ms > 0) {
493
                        status = VL53L1_WaitMs(
494
                                Dev,
495
                                poll_delay_ms);
496
                }
497

    
498
                /*
499
                 * Update polling time (Compare difference rather than
500
                 * absolute to negate 32bit wrap around issue)
501
                 */
502
                VL53L1_GetTickCount(&current_time_ms);  /*lint !e534 ignoring return*/
503
                pdev->fw_ready_poll_duration_ms =
504
                                current_time_ms - start_time_ms;
505
        }
506

    
507
        if (fw_ready == 0 && status == VL53L1_ERROR_NONE)
508
                status = VL53L1_ERROR_TIME_OUT;
509

    
510
        LOG_FUNCTION_END(status);
511

    
512
        return status;
513
}
514

    
515

    
516
VL53L1_Error VL53L1_poll_for_range_completion(
517
        VL53L1_DEV     Dev,
518
        uint32_t       timeout_ms)
519
{
520
        /**
521
         * Polls bit 0 of VL53L1_GPIO__TIO_HV_STATUS to determine
522
         * the state of output interrupt pin
523
         *
524
         * Interrupt may be either active high or active low. Use active_high to
525
         * select the required level check
526
         */
527

    
528
        VL53L1_Error status = VL53L1_ERROR_NONE;
529
        VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
530

    
531
        uint8_t  gpio__mux_active_high_hv = 0;
532
        uint8_t  interrupt_ready          = 0;
533

    
534
        LOG_FUNCTION_START("");
535

    
536
        gpio__mux_active_high_hv =
537
                        pdev->stat_cfg.gpio_hv_mux__ctrl &
538
                        VL53L1_DEVICEINTERRUPTLEVEL_ACTIVE_MASK;
539

    
540
        if (gpio__mux_active_high_hv == VL53L1_DEVICEINTERRUPTLEVEL_ACTIVE_HIGH)
541
                interrupt_ready = 0x01;
542
        else
543
                interrupt_ready = 0x00;
544

    
545
        status =
546
                VL53L1_WaitValueMaskEx(
547
                        Dev,
548
                        timeout_ms,
549
                        VL53L1_GPIO__TIO_HV_STATUS,
550
                        interrupt_ready,
551
                        0x01,
552
                        VL53L1_POLLING_DELAY_MS);
553

    
554
        LOG_FUNCTION_END(status);
555

    
556
        return status;
557
}
558