Paparazzi UAS  v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
vl53l1x_nonblocking.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2020 Tom van Dijk <tomvand@users.noreply.github.com>
3  *
4  * This file is part of paparazzi.
5  *
6  * paparazzi is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2, or (at your option)
9  * any later version.
10  *
11  * paparazzi is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with paparazzi; see the file COPYING. If not, write to
18  * the Free Software Foundation, 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  *
21  */
29 #include "vl53l1x_nonblocking.h"
30 
31 #include <assert.h>
32 
33 // possible GetRangeStatus return value as in api.c GetRangeStatus
34 static const uint8_t status_rtn[24] = { 255, 255, 255, 5, 2, 4, 1, 7, 3, 0,
35  255, 255, 9, 13, 255, 255, 255, 255, 10, 6,
36  255, 255, 11, 12
37  };
38 // Returns true upon completion
40 {
41  switch (dev->nonblocking.i2c_state) {
42  case 0:
43  assert(2 + count <= I2C_BUF_LEN);
44  dev->i2c_trans.buf[0] = (index & 0xFF00) >> 8; // MSB first
45  dev->i2c_trans.buf[1] = (index & 0x00FF);
46  for (uint8_t i = 0; i < count; ++i) { dev->i2c_trans.buf[i + 2] = pdata[i]; }
47  i2c_transmit(dev->i2c_p, &dev->i2c_trans, dev->i2c_trans.slave_addr, 2 + count);
48  dev->nonblocking.i2c_state++;
49  /* Falls through. */
50  case 1:
51  if (dev->i2c_trans.status == I2CTransFailed) {
52  dev->nonblocking.i2c_state = 0; // Try again.
53  return false;
54  }
55  if (dev->i2c_trans.status != I2CTransSuccess) { return false; } // Wait for transaction to complete.
56  // Transaction success
57  dev->nonblocking.i2c_state = 0;
58  return true;
59  default: return false;
60  }
61 }
62 
63 // Returns true upon completion
65 {
66  switch (dev->nonblocking.i2c_state) {
67  case 0:
68  assert(count <= I2C_BUF_LEN);
69  dev->i2c_trans.buf[0] = (index & 0xFF00) >> 8; // MSB first
70  dev->i2c_trans.buf[1] = (index & 0x00FF);
71  i2c_transceive(dev->i2c_p, &dev->i2c_trans, dev->i2c_trans.slave_addr, 2, count);
72  dev->nonblocking.i2c_state++;
73  /* Falls through. */
74  case 1:
75  if (dev->i2c_trans.status == I2CTransFailed) {
76  dev->nonblocking.i2c_state = 0; // Try again.
77  return false;
78  }
79  if (dev->i2c_trans.status != I2CTransSuccess) { return false; } // Wait for transaction to complete.
80  // Transaction success
81  for (uint8_t i = 0; i < count; ++i) { pdata[i] = dev->i2c_trans.buf[i]; }
82  dev->nonblocking.i2c_state = 0;
83  return true;
84  default: return false;
85  }
86 }
87 
88 // Returns true upon completion
90 {
91  uint8_t Temp;
92  switch (dev->nonblocking.state) {
93  case 0:
94  // GetInterruptPolarity
95  if (!VL53L1_NonBlocking_ReadMulti(dev, GPIO_HV_MUX__CTRL, &Temp, 1)) { return false; }
96  Temp = Temp & 0x10;
97  dev->nonblocking.IntPol = !(Temp >> 4);
98  dev->nonblocking.state++;
99  /* Falls through. */
100  case 1:
101  /* Read in the register to check if a new value is available */
102  if (!VL53L1_NonBlocking_ReadMulti(dev, GPIO__TIO_HV_STATUS, &Temp, 1)) { return false; }
103  if ((Temp & 1) == dev->nonblocking.IntPol) {
104  *isDataReady = 1;
105  } else {
106  *isDataReady = 0;
107  }
108  dev->nonblocking.state = 0;
109  return true;
110  default: return false;
111  }
112 }
113 
114 // Returns true upon completion
116 {
117  uint8_t RgSt;
118  *rangeStatus = 255;
119  if (!VL53L1_NonBlocking_ReadMulti(dev, VL53L1_RESULT__RANGE_STATUS, &RgSt, 1)) { return false; }
120  RgSt = RgSt & 0x1F;
121  if (RgSt < 24) {
122  *rangeStatus = status_rtn[RgSt];
123  }
124  return true;
125 }
126 
127 // Returns true upon completion
129 {
130  uint8_t tmp[2];
132  tmp, 2)) { return false; }
133  *distance = (tmp[0] << 8) | tmp[1];
134  return true;
135 }
136 
137 // Returns true upon completion
139 {
140  uint8_t data = 0x01;
142 }
143 
144 bool VL53L1X_NonBlocking_ReadDataEvent(VL53L1_DEV dev, uint16_t *distance_mm, bool *new_data)
145 {
146  uint8_t isDataReady, rangeStatus;
147  *new_data = false;
148  switch (dev->read_status) {
149  case VL53L1_READ_IDLE:
150  // Idle, do nothing
151  return false;
153  // Wait for data ready
154  if (!VL53L1X_NonBlocking_CheckForDataReady(dev, &isDataReady)) {
155  return false; // Check in progress
156  }
157  dev->read_status++;
158  /* Falls through. */
159  case VL53L1_READ_STATUS:
160  // Get range status
161  if (!VL53L1X_NonBlocking_GetRangeStatus(dev, &rangeStatus)) {
162  return false; // Read status in progress
163  }
164  if (rangeStatus != 0) {
165  dev->read_status = VL53L1_CLEAR_INT; // wrong measurement, clear interrupt and back to idle
166  return true; // end cycle
167  }
168  dev->read_status++;
169  /* Falls through. */
171  // Get ranging data
172  if (!VL53L1X_NonBlocking_GetDistance(dev, distance_mm)) {
173  return false; // Read in progress
174  }
175  *new_data = true;
176  dev->read_status++;
177  /* Falls through. */
178  case VL53L1_CLEAR_INT:
179  // Clear interrupt
181  return false; // Clear in progress
182  }
183  dev->read_status = VL53L1_READ_IDLE;
184  return true; // Cycle is done
185  default:
186  return false;
187  }
188 }
189 
191 {
192  return dev->read_status == VL53L1_READ_IDLE;
193 }
194 
196 {
197  dev->read_status = VL53L1_READ_DATA_READY;
198  return true;
199 }
#define I2C_BUF_LEN
I2C buffer length.
Definition: i2c.h:84
bool i2c_transmit(struct i2c_periph *p, struct i2c_transaction *t, uint8_t s_addr, uint8_t len)
Submit a write only transaction.
Definition: i2c.c:324
bool i2c_transceive(struct i2c_periph *p, struct i2c_transaction *t, uint8_t s_addr, uint8_t len_w, uint16_t len_r)
Submit a write/read transaction.
Definition: i2c.c:344
@ I2CTransSuccess
transaction successfully finished by I2C driver
Definition: i2c.h:57
@ I2CTransFailed
transaction failed
Definition: i2c.h:58
static const struct usb_device_descriptor dev
Definition: usb_ser_hw.c:74
@ VL53L1_READ_DATA_READY
@ VL53L1_READ_STATUS
@ VL53L1_READ_DISTANCE
@ VL53L1_CLEAR_INT
@ VL53L1_READ_IDLE
unsigned short uint16_t
Typedef defining 16 bit unsigned short type.
Definition: vl53l1_types.h:88
unsigned int uint32_t
Typedef defining 32 bit unsigned int type.
Definition: vl53l1_types.h:78
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.
Definition: vl53l1_types.h:98
#define SYSTEM__INTERRUPT_CLEAR
Definition: vl53l1x_api.h:110
#define GPIO__TIO_HV_STATUS
Definition: vl53l1x_api.h:90
#define VL53L1_RESULT__RANGE_STATUS
Definition: vl53l1x_api.h:112
#define VL53L1_RESULT__FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD0
Definition: vl53l1x_api.h:115
#define GPIO_HV_MUX__CTRL
Definition: vl53l1x_api.h:89
bool VL53L1X_NonBlocking_RequestData(VL53L1_DEV dev)
Request a new reading.
bool VL53L1X_NonBlocking_IsIdle(VL53L1_DEV dev)
Test is read status is on idle.
static bool VL53L1_NonBlocking_ReadMulti(VL53L1_DEV dev, uint16_t index, uint8_t *pdata, uint32_t count)
bool VL53L1X_NonBlocking_GetDistance(VL53L1_DEV dev, uint16_t *distance)
This function returns the distance measured by the sensor in mm.
bool VL53L1X_NonBlocking_GetRangeStatus(VL53L1_DEV dev, uint8_t *rangeStatus)
This function returns the range status to discard wrong measurments.
bool VL53L1X_NonBlocking_CheckForDataReady(VL53L1_DEV dev, uint8_t *isDataReady)
This function checks if the new ranging data is available by polling the dedicated register.
bool VL53L1X_NonBlocking_ClearInterrupt(VL53L1_DEV dev)
This function clears the interrupt, to be called after a ranging data reading to arm the interrupt fo...
static const uint8_t status_rtn[24]
static bool VL53L1_NonBlocking_WriteMulti(VL53L1_DEV dev, uint16_t index, uint8_t *pdata, uint32_t count)
bool VL53L1X_NonBlocking_ReadDataEvent(VL53L1_DEV dev, uint16_t *distance_mm, bool *new_data)
Implement non-blocking read sequence The data reading actually starts when the read_state is set to V...
Non-blocking runtime functions for the VL53L1X.