mirror of
https://github.com/paparazzi/paparazzi.git
synced 2026-05-22 12:28:03 +08:00
Multi ranger deck integration (#2524)
* [driver] factorize some vl53l1x function and use event loop - the reading of data is still not blocking, but using the event loop to perform all reading transactions in a row instead of splitting them in several periodic calls - move boot and reading sequence to the peripheral driver - add an auto address increment option to support several sensors [vl53l1] change boot return status to void * [module] support for the multi-ranger deck for crazyflie - add driver of the pca95x4 I/O expander - read and publish data of the 5 vl53l1x sensor of the deck * [conf] update config of crazyflie - update example in Enac folder - allow multi-ranger deck with forcefield module - use same IMU defaults than original crazyflie settings * [bug] syslink send_message buffer was 2 bytes too short * [sonar] poll new data at 50 Hz
This commit is contained in:
committed by
GitHub
parent
66a0f367a7
commit
cf5a989072
@@ -9,7 +9,7 @@
|
||||
<configure name="RTOS_DEBUG" value="0"/>
|
||||
|
||||
<target name="ap" board="crazyflie_2.1">
|
||||
<module name="gps" type="datalink"/>
|
||||
<!--module name="gps" type="datalink"/-->
|
||||
</target>
|
||||
|
||||
<target name="nps" board="pc">
|
||||
@@ -30,11 +30,12 @@
|
||||
<define name="IMU_BMI088_Z_SIGN" value="-1"/>
|
||||
</module>
|
||||
<module name="stabilization" type="int_quat"/>
|
||||
<!--module name="stabilization" type="indi_simple"/-->
|
||||
<module name="ahrs" type="madgwick">
|
||||
<configure name="AHRS_PROPAGATE_FREQUENCY" value="1000"/>
|
||||
<!--configure name="USE_MAGNETOMETER" value="FALSE"/-->
|
||||
</module>
|
||||
<module name="ins"/>
|
||||
<module name="ins" type="extended"/>
|
||||
<module name="sys_mon"/>
|
||||
<module name="air_data"/>
|
||||
<module name="baro_bmp3">
|
||||
@@ -43,6 +44,14 @@
|
||||
<define name="BMP3_SLAVE_ADDR" value="BMP3_I2C_ADDR_ALT"/>
|
||||
</module>
|
||||
|
||||
<module name="cf_deck" type="multi_ranger"/>
|
||||
<module name="range_forcefield">
|
||||
<define name="RANGE_FORCEFIELD_MAX_VEL" value="0.1"/>
|
||||
</module>
|
||||
<module name="sonar" type="vl53l1x"/>
|
||||
<define name="SENSOR_SYNC_SEND_SONAR"/>
|
||||
<define name="NO_GPS_NEEDED_FOR_NAV" value="TRUE"/>
|
||||
|
||||
</firmware>
|
||||
|
||||
<firmware name="test_chibios">
|
||||
@@ -181,12 +190,45 @@
|
||||
<define name="PSI_DDGAIN" value="300"/>
|
||||
</section>
|
||||
|
||||
<section name="STABILIZATION_ATTITUDE_INDI" prefix="STABILIZATION_INDI_">
|
||||
<!-- control effectiveness -->
|
||||
<define name="G1_P" value="0.0034724f"/>
|
||||
<define name="G1_Q" value="0.0052575f"/>
|
||||
<define name="G1_R" value="-0.0015942f"/>
|
||||
<define name="G2_R" value="-0.11281f"/>
|
||||
|
||||
<define name="FILTER_ROLL_RATE" value="FALSE"/>
|
||||
<define name="FILTER_PITCH_RATE" value="FALSE"/>
|
||||
<define name="FILTER_YAW_RATE" value="FALSE"/>
|
||||
|
||||
<!-- reference acceleration for attitude control -->
|
||||
<define name="REF_ERR_P" value="3.57f"/>
|
||||
<define name="REF_ERR_Q" value="3.57f"/>
|
||||
<define name="REF_ERR_R" value="3.57f"/>
|
||||
<define name="REF_RATE_P" value="14.0"/>
|
||||
<define name="REF_RATE_Q" value="14.0"/>
|
||||
<define name="REF_RATE_R" value="14.0"/>
|
||||
|
||||
<!-- second order filter parameters -->
|
||||
<define name="FILT_CUTOFF" value="8.0f"/>
|
||||
<define name="FILT_CUTOFF_R" value="8.0f"/>
|
||||
|
||||
<!-- first order actuator dynamics -->
|
||||
<define name="ACT_DYN_P" value="0.03149f"/>
|
||||
<define name="ACT_DYN_Q" value="0.03149f"/>
|
||||
<define name="ACT_DYN_R" value="0.03149f"/>
|
||||
|
||||
<!-- Adaptive Learning Rate -->
|
||||
<define name="USE_ADAPTIVE" value="FALSE"/>
|
||||
<define name="ADAPTIVE_MU" value="0.0001"/>
|
||||
</section>
|
||||
|
||||
<section name="GUIDANCE_V" prefix="GUIDANCE_V_">
|
||||
<define name="HOVER_KP" value="150"/>
|
||||
<define name="HOVER_KD" value="80"/>
|
||||
<define name="HOVER_KI" value="20"/>
|
||||
<!-- NOMINAL_HOVER_THROTTLE sets a fixed value instead of the adaptive estimation -->
|
||||
<!--define name="NOMINAL_HOVER_THROTTLE" value="0.5"/-->
|
||||
<define name="NOMINAL_HOVER_THROTTLE" value="0.75"/>
|
||||
</section>
|
||||
|
||||
<section name="GUIDANCE_H" prefix="GUIDANCE_H_">
|
||||
@@ -204,8 +246,9 @@
|
||||
</section>
|
||||
|
||||
<section name="AUTOPILOT">
|
||||
<define name="MODE_STARTUP" value="AP_MODE_NAV"/>
|
||||
<define name="MODE_MANUAL" value="AP_MODE_ATTITUDE_DIRECT"/>
|
||||
<define name="MODE_AUTO1" value="AP_MODE_HOVER_Z_HOLD"/>
|
||||
<define name="MODE_AUTO1" value="AP_MODE_ATTITUDE_Z_HOLD"/>
|
||||
<define name="MODE_AUTO2" value="AP_MODE_NAV"/>
|
||||
</section>
|
||||
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
<!DOCTYPE module SYSTEM "module.dtd">
|
||||
|
||||
<module name="cf_deck_multi_ranger" dir="range_finder">
|
||||
<doc>
|
||||
<description>
|
||||
Multi-ranger deck from Bitcraze for Crazyflie drones
|
||||
</description>
|
||||
<configure name="MULTI_RANGER_I2C_DEV" value="i2c1" description="I2C device to use for the multi_ranger deck"/>
|
||||
</doc>
|
||||
<header>
|
||||
<file name="cf_deck_multi_ranger.h"/>
|
||||
</header>
|
||||
<init fun="multi_ranger_init()"/>
|
||||
<periodic fun="multi_ranger_periodic()" freq="50.0" autorun="TRUE"/>
|
||||
<periodic fun="multi_ranger_report()" freq="5.0" autorun="TRUE"/>
|
||||
<event fun="multi_ranger_event()"/>
|
||||
<makefile target="ap">
|
||||
<configure name="MULTI_RANGER_I2C_DEV" default="i2c1" case="lower|upper"/>
|
||||
<define name="MULTI_RANGER_I2C_DEV" value="$(MULTI_RANGER_I2C_DEV_LOWER)"/>
|
||||
<define name="USE_$(MULTI_RANGER_I2C_DEV_UPPER)"/>
|
||||
<define name="VL53L1X_AUTO_INCR_ADDR"/>
|
||||
<file name="cf_deck_multi_ranger.c"/>
|
||||
<file name="pca95x4.c" dir="peripherals"/>
|
||||
<file name="vl53l1_platform.c" dir="peripherals"/>
|
||||
<file name="vl53l1x_api.c" dir="peripherals"/>
|
||||
<file name="vl53l1x_nonblocking.c" dir="peripherals"/>
|
||||
</makefile>
|
||||
</module>
|
||||
@@ -23,7 +23,7 @@
|
||||
</dl_settings>
|
||||
</settings>
|
||||
|
||||
<depends>laser_range_array</depends>
|
||||
<depends>laser_range_array|cf_deck_multi_ranger</depends>
|
||||
|
||||
<header>
|
||||
<file name="range_forcefield.h"/>
|
||||
|
||||
@@ -27,7 +27,8 @@
|
||||
</header>
|
||||
|
||||
<init fun="sonar_vl53l1x_init()"/>
|
||||
<periodic fun="sonar_vl53l1x_read()" period="0.020"/>
|
||||
<periodic fun="sonar_vl53l1x_read()" freq="50."/>
|
||||
<event fun="sonar_vl53l1x_event()"/>
|
||||
|
||||
<makefile target="ap|sim">
|
||||
<file name="sonar_vl53l1x.c"/>
|
||||
|
||||
@@ -42,7 +42,7 @@ PPRZ_MUTEX(syslink_tx_mtx);
|
||||
static void send_message(syslink_message_t *msg)
|
||||
{
|
||||
syslink_compute_cksum(msg);
|
||||
uint8_t buf[sizeof(syslink_message_t)];
|
||||
uint8_t buf[sizeof(syslink_message_t)+2];
|
||||
buf[0] = syslink_stx[0];
|
||||
buf[1] = syslink_stx[1];
|
||||
buf[2] = msg->type;
|
||||
|
||||
@@ -0,0 +1,269 @@
|
||||
/*
|
||||
* Copyright (C) Gautier Hattenberger <gautier.hattenberger@enac.fr>
|
||||
*
|
||||
* This file is part of paparazzi
|
||||
*
|
||||
* paparazzi is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* paparazzi is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with paparazzi; see the file COPYING. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** @file "modules/range_finder/cf_deck_multi_ranger.c"
|
||||
* @author Gautier Hattenberger <gautier.hattenberger@enac.fr>
|
||||
* Multi-ranger deck from Bitcraze for Crazyflie drones
|
||||
*/
|
||||
|
||||
#include "modules/range_finder/cf_deck_multi_ranger.h"
|
||||
#include "peripherals/pca95x4.h"
|
||||
#include "peripherals/vl53l1x_nonblocking.h"
|
||||
#include "peripherals/vl53l1x_api.h"
|
||||
#include "subsystems/abi.h"
|
||||
#include "subsystems/datalink/downlink.h"
|
||||
|
||||
// By default, do early init to be compatible with the flow_deck
|
||||
// Blocking i2c is only possible with ChibiOS
|
||||
// This module should be called before other modules using the VL53L1X sensor
|
||||
// without the possibility to turn off the sensor (i.e. flow_deck)
|
||||
#ifndef MULTI_RANGER_EARLY_INIT
|
||||
#define MULTI_RANGER_EARLY_INIT TRUE
|
||||
#endif
|
||||
|
||||
/* VL53L1X configuration */
|
||||
// Time budget for single measurement
|
||||
// Allowed values: 15, 20, 33, 50, 100, 200, 500
|
||||
// see VL53L1X_SetTimingBudgetInMs
|
||||
#ifndef MULTI_RANGER_TIMINGBUDGET_MS
|
||||
#define MULTI_RANGER_TIMINGBUDGET_MS 100
|
||||
#endif
|
||||
|
||||
// Allowed values: 1 (short, max ~1.3m), 2 (long, max ~4m)
|
||||
// see VL53L1X_SetDistanceMode
|
||||
#ifndef MULTI_RANGER_DISTANCEMODE
|
||||
#define MULTI_RANGER_DISTANCEMODE 2
|
||||
#endif
|
||||
|
||||
// Time between measurements
|
||||
// Should be larger than or equal to timing budget
|
||||
// see VL53L1X_SetInterMeasurementInMs
|
||||
// Note: may be limited by module periodic frequency
|
||||
#ifndef MULTI_RANGER_INTERMEASUREMENT_MS
|
||||
#define MULTI_RANGER_INTERMEASUREMENT_MS MULTI_RANGER_TIMINGBUDGET_MS
|
||||
#endif
|
||||
#if MULTI_RANGER_INTERMEASUREMENT_MS < MULTI_RANGER_TIMINGBUDGET_MS
|
||||
#warning MULTI_RANGER_INTERMEASUREMENT_MS should be greater than or equal to MULTI_RANGER_TIMINGBUDGET_MS
|
||||
#endif
|
||||
|
||||
// PCA I/O pins to enable sensors
|
||||
#define MULTI_RANGER_PIN_FRONT PCA95X4_P4
|
||||
#define MULTI_RANGER_PIN_BACK PCA95X4_P1
|
||||
#define MULTI_RANGER_PIN_RIGHT PCA95X4_P2
|
||||
#define MULTI_RANGER_PIN_LEFT PCA95X4_P6
|
||||
#define MULTI_RANGER_PIN_UP PCA95X4_P0
|
||||
#define MULTI_RANGER_PIN_ALL (MULTI_RANGER_PIN_FRONT | MULTI_RANGER_PIN_BACK | MULTI_RANGER_PIN_RIGHT | MULTI_RANGER_PIN_LEFT | MULTI_RANGER_PIN_UP)
|
||||
|
||||
enum MultiRangerStatus {
|
||||
MULTI_RANGER_UNINIT,
|
||||
MULTI_RANGER_CONF_IO,
|
||||
#ifdef MULTI_RANGER_EXTRA_DEV
|
||||
MULTI_RANGER_CONF_EXTRA,
|
||||
#endif
|
||||
MULTI_RANGER_CONF_FRONT,
|
||||
MULTI_RANGER_CONF_BACK,
|
||||
MULTI_RANGER_CONF_RIGHT,
|
||||
MULTI_RANGER_CONF_LEFT,
|
||||
MULTI_RANGER_CONF_UP,
|
||||
MULTI_RANGER_READ_FRONT,
|
||||
MULTI_RANGER_READ_BACK,
|
||||
MULTI_RANGER_READ_RIGHT,
|
||||
MULTI_RANGER_READ_LEFT,
|
||||
MULTI_RANGER_READ_UP
|
||||
};
|
||||
|
||||
enum MultiRangerDev {
|
||||
MULTI_RANGER_FRONT = 0,
|
||||
MULTI_RANGER_BACK,
|
||||
MULTI_RANGER_RIGHT,
|
||||
MULTI_RANGER_LEFT,
|
||||
MULTI_RANGER_UP,
|
||||
MULTI_RANGER_NB
|
||||
};
|
||||
|
||||
// Default orientation (azimuth, bearing) in rad of sensors relative to body
|
||||
#ifndef MULTI_RANGER_ARRAY_ORIENTATION
|
||||
#define MULTI_RANGER_ARRAY_ORIENTATION {{0.f, 0.f}, {0.f, M_PI}, {0.f, M_PI_2}, {0.f, -M_PI_2}, {M_PI_2, 0.f}}
|
||||
#endif
|
||||
static const float multi_ranger_array_orientation[][2] = MULTI_RANGER_ARRAY_ORIENTATION;
|
||||
|
||||
struct SingleRanger {
|
||||
VL53L1_Dev_t dev; ///< sensor driver
|
||||
float distance; ///< raw distance measurement
|
||||
float azimuth; ///< azimuth [rad] relative to body frame
|
||||
float bearing; ///< bearing [rad] relative to body frame
|
||||
uint8_t read_state; ///< current reading state
|
||||
};
|
||||
|
||||
struct cf_deck_multi_ranger {
|
||||
enum MultiRangerStatus status;
|
||||
// VL53L1X devices
|
||||
struct SingleRanger ranger[MULTI_RANGER_NB]; ///< sensor array
|
||||
// I/O expander
|
||||
struct pca95x4 pca;
|
||||
};
|
||||
|
||||
static struct cf_deck_multi_ranger multi_ranger;
|
||||
|
||||
/**
|
||||
* Boot a device
|
||||
*/
|
||||
static void multi_ranger_boot_device(VL53L1_Dev_t *dev UNUSED)
|
||||
{
|
||||
#ifndef SITL
|
||||
VL53L1X_BootDevice(dev, MULTI_RANGER_TIMINGBUDGET_MS, MULTI_RANGER_DISTANCEMODE, MULTI_RANGER_INTERMEASUREMENT_MS);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Module init
|
||||
*/
|
||||
void multi_ranger_init(void)
|
||||
{
|
||||
multi_ranger.status = MULTI_RANGER_UNINIT;
|
||||
|
||||
// init I/O expander
|
||||
pca95x4_init(&multi_ranger.pca, &(MULTI_RANGER_I2C_DEV), PCA95X4_DEFAULT_ADDRESS);
|
||||
#if MULTI_RANGER_EARLY_INIT
|
||||
pca95x4_configure(&multi_ranger.pca, ~(MULTI_RANGER_PIN_ALL), true); // configure output
|
||||
pca95x4_set_output(&multi_ranger.pca, ~(MULTI_RANGER_PIN_ALL), true); // select none
|
||||
#endif
|
||||
|
||||
// init vl53l1x array
|
||||
for (uint8_t i = 0; i < MULTI_RANGER_NB; i++) {
|
||||
multi_ranger.ranger[i].dev.i2c_p = &(MULTI_RANGER_I2C_DEV);
|
||||
multi_ranger.ranger[i].dev.i2c_trans.slave_addr = VL53L1_DEFAULT_ADDRESS;
|
||||
multi_ranger.ranger[i].dev.read_status = VL53L1_READ_IDLE;
|
||||
multi_ranger.ranger[i].distance = 0.f;
|
||||
multi_ranger.ranger[i].azimuth = multi_ranger_array_orientation[i][0];
|
||||
multi_ranger.ranger[i].bearing = multi_ranger_array_orientation[i][1];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read data from a device
|
||||
* @return true when read cycle is finished
|
||||
*/
|
||||
static bool multi_ranger_read(struct SingleRanger *ranger UNUSED)
|
||||
{
|
||||
#ifndef SITL
|
||||
uint16_t range_mm;
|
||||
bool new_data = false;
|
||||
bool ret = VL53L1X_NonBlocking_ReadDataEvent(&ranger->dev, &range_mm, &new_data);
|
||||
if (new_data) {
|
||||
ranger->distance = range_mm / 1000.f;
|
||||
AbiSendMsgOBSTACLE_DETECTION(42, ranger->distance, ranger->azimuth, ranger->bearing);
|
||||
}
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Module periodic function
|
||||
*/
|
||||
void multi_ranger_periodic(void)
|
||||
{
|
||||
switch (multi_ranger.status) {
|
||||
case MULTI_RANGER_UNINIT:
|
||||
pca95x4_configure(&multi_ranger.pca, ~(MULTI_RANGER_PIN_ALL), false); // configure output
|
||||
multi_ranger.status++;
|
||||
break;
|
||||
case MULTI_RANGER_CONF_IO:
|
||||
pca95x4_set_output(&multi_ranger.pca, MULTI_RANGER_PIN_FRONT, false); // select front
|
||||
multi_ranger.status++;
|
||||
break;
|
||||
case MULTI_RANGER_CONF_FRONT:
|
||||
multi_ranger_boot_device(&multi_ranger.ranger[MULTI_RANGER_FRONT].dev);
|
||||
pca95x4_set_output(&multi_ranger.pca, MULTI_RANGER_PIN_FRONT | MULTI_RANGER_PIN_BACK, false); // select back
|
||||
multi_ranger.status++;
|
||||
break;
|
||||
case MULTI_RANGER_CONF_BACK:
|
||||
multi_ranger_boot_device(&multi_ranger.ranger[MULTI_RANGER_BACK].dev);
|
||||
pca95x4_set_output(&multi_ranger.pca, MULTI_RANGER_PIN_FRONT | MULTI_RANGER_PIN_BACK | MULTI_RANGER_PIN_RIGHT, false); // select right
|
||||
multi_ranger.status++;
|
||||
break;
|
||||
case MULTI_RANGER_CONF_RIGHT:
|
||||
multi_ranger_boot_device(&multi_ranger.ranger[MULTI_RANGER_RIGHT].dev);
|
||||
pca95x4_set_output(&multi_ranger.pca, MULTI_RANGER_PIN_FRONT | MULTI_RANGER_PIN_BACK | MULTI_RANGER_PIN_RIGHT | MULTI_RANGER_PIN_LEFT, false); // select left
|
||||
multi_ranger.status++;
|
||||
break;
|
||||
case MULTI_RANGER_CONF_LEFT:
|
||||
multi_ranger_boot_device(&multi_ranger.ranger[MULTI_RANGER_LEFT].dev);
|
||||
pca95x4_set_output(&multi_ranger.pca, MULTI_RANGER_PIN_ALL, false); // select up
|
||||
multi_ranger.status++;
|
||||
break;
|
||||
case MULTI_RANGER_CONF_UP:
|
||||
multi_ranger_boot_device(&multi_ranger.ranger[MULTI_RANGER_UP].dev);
|
||||
multi_ranger.status++;
|
||||
break;
|
||||
case MULTI_RANGER_READ_FRONT:
|
||||
if (VL53L1X_NonBlocking_IsIdle(&multi_ranger.ranger[MULTI_RANGER_FRONT].dev)) {
|
||||
VL53L1X_NonBlocking_RequestData(&multi_ranger.ranger[MULTI_RANGER_FRONT].dev);
|
||||
multi_ranger.status++;
|
||||
}
|
||||
break;
|
||||
case MULTI_RANGER_READ_BACK:
|
||||
if (VL53L1X_NonBlocking_IsIdle(&multi_ranger.ranger[MULTI_RANGER_BACK].dev)) {
|
||||
VL53L1X_NonBlocking_RequestData(&multi_ranger.ranger[MULTI_RANGER_BACK].dev);
|
||||
multi_ranger.status++;
|
||||
}
|
||||
break;
|
||||
case MULTI_RANGER_READ_RIGHT:
|
||||
if (VL53L1X_NonBlocking_IsIdle(&multi_ranger.ranger[MULTI_RANGER_RIGHT].dev)) {
|
||||
VL53L1X_NonBlocking_RequestData(&multi_ranger.ranger[MULTI_RANGER_RIGHT].dev);
|
||||
multi_ranger.status++;
|
||||
}
|
||||
break;
|
||||
case MULTI_RANGER_READ_LEFT:
|
||||
if (VL53L1X_NonBlocking_IsIdle(&multi_ranger.ranger[MULTI_RANGER_LEFT].dev)) {
|
||||
VL53L1X_NonBlocking_RequestData(&multi_ranger.ranger[MULTI_RANGER_LEFT].dev);
|
||||
multi_ranger.status++;
|
||||
}
|
||||
break;
|
||||
case MULTI_RANGER_READ_UP:
|
||||
if (VL53L1X_NonBlocking_IsIdle(&multi_ranger.ranger[MULTI_RANGER_UP].dev)) {
|
||||
VL53L1X_NonBlocking_RequestData(&multi_ranger.ranger[MULTI_RANGER_UP].dev);
|
||||
multi_ranger.status = MULTI_RANGER_READ_FRONT;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void multi_ranger_event(void)
|
||||
{
|
||||
// call non blocking read/event functions
|
||||
multi_ranger_read(&multi_ranger.ranger[MULTI_RANGER_FRONT]);
|
||||
multi_ranger_read(&multi_ranger.ranger[MULTI_RANGER_BACK]);
|
||||
multi_ranger_read(&multi_ranger.ranger[MULTI_RANGER_RIGHT]);
|
||||
multi_ranger_read(&multi_ranger.ranger[MULTI_RANGER_LEFT]);
|
||||
multi_ranger_read(&multi_ranger.ranger[MULTI_RANGER_UP]);
|
||||
}
|
||||
|
||||
void multi_ranger_report(void)
|
||||
{
|
||||
float dist_array[MULTI_RANGER_NB];
|
||||
for (int i = 0; i < MULTI_RANGER_NB; i++) {
|
||||
dist_array[i] = multi_ranger.ranger[i].distance;
|
||||
}
|
||||
DOWNLINK_SEND_PAYLOAD_FLOAT(DefaultChannel, DefaultDevice, MULTI_RANGER_NB, dist_array);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (C) Gautier Hattenberger <gautier.hattenberger@enac.fr>
|
||||
*
|
||||
* This file is part of paparazzi
|
||||
*
|
||||
* paparazzi is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* paparazzi is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with paparazzi; see the file COPYING. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** @file "modules/range_finder/cf_deck_multi_ranger.h"
|
||||
* @author Gautier Hattenberger <gautier.hattenberger@enac.fr>
|
||||
* Multi-ranger deck from Bitcraze for Crazyflie drones
|
||||
*/
|
||||
|
||||
#ifndef CF_DECK_MULTI_RANGER_H
|
||||
#define CF_DECK_MULTI_RANGER_H
|
||||
|
||||
#include "std.h"
|
||||
|
||||
extern void multi_ranger_init(void);
|
||||
extern void multi_ranger_periodic(void);
|
||||
extern void multi_ranger_report(void);
|
||||
extern void multi_ranger_event(void);
|
||||
|
||||
#endif // CF_DECK_MULTI_RANGER_H
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
|
||||
#ifndef SONAR_VL53L1X_I2C_ADDR
|
||||
#define SONAR_VL53L1X_I2C_ADDR 0x52
|
||||
#define SONAR_VL53L1X_I2C_ADDR VL53L1_DEFAULT_ADDRESS
|
||||
#endif
|
||||
|
||||
// Signed distance offset in mm
|
||||
@@ -96,17 +96,7 @@ void sonar_vl53l1x_init(void)
|
||||
|
||||
/* Initialize sensor */
|
||||
#ifndef SITL
|
||||
uint8_t state;
|
||||
do {
|
||||
VL53L1X_BootState(&sonar_vl53l1x.dev, &state);
|
||||
} while (!state);
|
||||
VL53L1X_SensorInit(&sonar_vl53l1x.dev);
|
||||
/* Configure sensor */
|
||||
VL53L1X_SetTimingBudgetInMs(&sonar_vl53l1x.dev, SONAR_VL53L1X_TIMINGBUDGET_MS);
|
||||
VL53L1X_SetDistanceMode(&sonar_vl53l1x.dev, SONAR_VL53L1X_DISTANCEMODE);
|
||||
VL53L1X_SetInterMeasurementInMs(&sonar_vl53l1x.dev, SONAR_VL53L1X_INTERMEASUREMENT_MS);
|
||||
/* Start measurement */
|
||||
VL53L1X_StartRanging(&sonar_vl53l1x.dev);
|
||||
VL53L1X_BootDevice(&sonar_vl53l1x.dev, SONAR_VL53L1X_TIMINGBUDGET_MS, SONAR_VL53L1X_DISTANCEMODE, SONAR_VL53L1X_INTERMEASUREMENT_MS);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -114,26 +104,8 @@ void sonar_vl53l1x_init(void)
|
||||
void sonar_vl53l1x_read(void)
|
||||
{
|
||||
#ifndef SITL
|
||||
uint8_t isDataReady;
|
||||
uint16_t range_mm;
|
||||
switch (sonar_vl53l1x.read_state) {
|
||||
case 0:
|
||||
// Wait for data ready
|
||||
if (!VL53L1X_NonBlocking_CheckForDataReady(&sonar_vl53l1x.dev, &isDataReady)) { return; } // Check in progress
|
||||
sonar_vl53l1x.read_state++;
|
||||
/* Falls through. */
|
||||
case 1:
|
||||
// Get ranging data
|
||||
if (!VL53L1X_NonBlocking_GetDistance(&sonar_vl53l1x.dev, &range_mm)) { return; } // Read in progress
|
||||
sonar_vl53l1x_publish(range_mm);
|
||||
sonar_vl53l1x.read_state++;
|
||||
/* Falls through. */
|
||||
case 2:
|
||||
// Clear interrupt
|
||||
if (!VL53L1X_NonBlocking_ClearInterrupt(&sonar_vl53l1x.dev)) { return; } // Clear in progress
|
||||
sonar_vl53l1x.read_state = 0;
|
||||
break;
|
||||
default: return;
|
||||
if (VL53L1X_NonBlocking_IsIdle(&sonar_vl53l1x.dev)) {
|
||||
VL53L1X_NonBlocking_RequestData(&sonar_vl53l1x.dev);
|
||||
}
|
||||
#else // SITL
|
||||
float range_mm = stateGetPositionEnu_f()->z * 1.0e3f;
|
||||
@@ -142,3 +114,15 @@ void sonar_vl53l1x_read(void)
|
||||
}
|
||||
#endif // SITL
|
||||
}
|
||||
|
||||
void sonar_vl53l1x_event(void)
|
||||
{
|
||||
#ifndef SITL
|
||||
uint16_t range_mm;
|
||||
bool new_data = false;
|
||||
VL53L1X_NonBlocking_ReadDataEvent(&sonar_vl53l1x.dev, &range_mm, &new_data);
|
||||
if (new_data) {
|
||||
sonar_vl53l1x_publish(range_mm);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -34,5 +34,6 @@ extern struct sonar_vl53l1x_dev sonar_vl53l1x;
|
||||
|
||||
extern void sonar_vl53l1x_init(void);
|
||||
extern void sonar_vl53l1x_read(void);
|
||||
extern void sonar_vl53l1x_event(void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -35,13 +35,13 @@
|
||||
/// Default gyro full scale range +- 1000°/s
|
||||
#define BMI088_DEFAULT_GYRO_RANGE BMI088_GYRO_RANGE_1000
|
||||
/// Default gyro output rate
|
||||
#define BMI088_DEFAULT_GYRO_ODR BMI088_GYRO_ODR_400_BW_47
|
||||
#define BMI088_DEFAULT_GYRO_ODR BMI088_GYRO_ODR_1000_BW_116
|
||||
/// Default accel full scale range +- 6g
|
||||
#define BMI088_DEFAULT_ACCEL_RANGE BMI088_ACCEL_RANGE_6G
|
||||
#define BMI088_DEFAULT_ACCEL_RANGE BMI088_ACCEL_RANGE_12G
|
||||
/// Default accel output rate
|
||||
#define BMI088_DEFAULT_ACCEL_ODR BMI088_ACCEL_ODR_400
|
||||
#define BMI088_DEFAULT_ACCEL_ODR BMI088_ACCEL_ODR_1600
|
||||
/// Default accel bandwidth
|
||||
#define BMI088_DEFAULT_ACCEL_BW BMI088_ACCEL_BW_NORMAL
|
||||
#define BMI088_DEFAULT_ACCEL_BW BMI088_ACCEL_BW_OSR4
|
||||
|
||||
/** default gyro sensitivy from the datasheet
|
||||
* sens = 1/ [LSB/(deg/s)] * pi/180 * 2^INT32_RATE_FRAC
|
||||
@@ -71,21 +71,21 @@ extern const int32_t BMI088_GYRO_SENS_FRAC[5][2];
|
||||
|
||||
/** default accel sensitivy from the datasheet
|
||||
* sens = 9.81 [m/s^2] / [LSB/g] * 2^INT32_ACCEL_FRAC
|
||||
* ex: BMI with 8g has 4096 LSB/g
|
||||
* sens = 9.81 [m/s^2] / 4096 [LSB/g] * 2^INT32_ACCEL_FRAC = 2.4525
|
||||
* ex: BMI with 6g has 5460 LSB/g
|
||||
* sens = 9.81 [m/s^2] / 5460 [LSB/g] * 2^INT32_ACCEL_FRAC = 1.83982
|
||||
*/
|
||||
// FIXME
|
||||
#define BMI088_ACCEL_SENS_3G 0.919687
|
||||
#define BMI088_ACCEL_SENS_3G_NUM 9197
|
||||
#define BMI088_ACCEL_SENS_3G 0.919912
|
||||
#define BMI088_ACCEL_SENS_3G_NUM 9199
|
||||
#define BMI088_ACCEL_SENS_3G_DEN 10000
|
||||
#define BMI088_ACCEL_SENS_6G 1.83937
|
||||
#define BMI088_ACCEL_SENS_6G_NUM 18394
|
||||
#define BMI088_ACCEL_SENS_6G 1.83982
|
||||
#define BMI088_ACCEL_SENS_6G_NUM 18398
|
||||
#define BMI088_ACCEL_SENS_6G_DEN 10000
|
||||
#define BMI088_ACCEL_SENS_12G 3.67875
|
||||
#define BMI088_ACCEL_SENS_12G_NUM 36787
|
||||
#define BMI088_ACCEL_SENS_12G 3.67965
|
||||
#define BMI088_ACCEL_SENS_12G_NUM 36797
|
||||
#define BMI088_ACCEL_SENS_12G_DEN 10000
|
||||
#define BMI088_ACCEL_SENS_24G 7.3575
|
||||
#define BMI088_ACCEL_SENS_24G_NUM 7357
|
||||
#define BMI088_ACCEL_SENS_24G 7.3593
|
||||
#define BMI088_ACCEL_SENS_24G_NUM 7359
|
||||
#define BMI088_ACCEL_SENS_24G_DEN 1000
|
||||
|
||||
// Get default sensitivity from a table
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Gautier Hattenberger <gautier.hattenberger@enac.fr>
|
||||
*
|
||||
* This file is part of paparazzi.
|
||||
*
|
||||
* paparazzi is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* paparazzi is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with paparazzi; see the file COPYING. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file peripherals/pca95x4.c
|
||||
*
|
||||
* Driver for the 8-bit I/O expander based on i2c
|
||||
*/
|
||||
|
||||
#include "peripherals/pca95x4.h"
|
||||
|
||||
// Init function
|
||||
void pca95x4_init(struct pca95x4 *dev, struct i2c_periph *i2c_p, uint8_t addr)
|
||||
{
|
||||
/* set i2c_peripheral */
|
||||
dev->i2c_p = i2c_p;
|
||||
|
||||
/* slave address */
|
||||
dev->i2c_trans.slave_addr = addr;
|
||||
/* set initial status: Done */
|
||||
dev->i2c_trans.status = I2CTransDone;
|
||||
}
|
||||
|
||||
// Configure function
|
||||
bool pca95x4_configure(struct pca95x4 *dev, uint8_t val, bool blocking)
|
||||
{
|
||||
if (dev->i2c_trans.status != I2CTransDone &&
|
||||
dev->i2c_trans.status != I2CTransSuccess &&
|
||||
dev->i2c_trans.status != I2CTransFailed) {
|
||||
return false; // previous transaction not finished
|
||||
}
|
||||
// send config value
|
||||
dev->i2c_trans.buf[0] = PCA95X4_CONFIG_REG;
|
||||
dev->i2c_trans.buf[1] = val;
|
||||
if (blocking) {
|
||||
return i2c_blocking_transmit(dev->i2c_p, &dev->i2c_trans, dev->i2c_trans.slave_addr, 2);
|
||||
} else {
|
||||
return i2c_transmit(dev->i2c_p, &dev->i2c_trans, dev->i2c_trans.slave_addr, 2);
|
||||
}
|
||||
}
|
||||
|
||||
// Set output function
|
||||
bool pca95x4_set_output(struct pca95x4 *dev, uint8_t mask, bool blocking)
|
||||
{
|
||||
if (dev->i2c_trans.status != I2CTransDone &&
|
||||
dev->i2c_trans.status != I2CTransSuccess &&
|
||||
dev->i2c_trans.status != I2CTransFailed) {
|
||||
return false; // previous transaction not finished
|
||||
}
|
||||
// send mask value
|
||||
dev->i2c_trans.buf[0] = PCA95X4_OUTPUT_REG;
|
||||
dev->i2c_trans.buf[1] = mask;
|
||||
if (blocking) {
|
||||
return i2c_blocking_transmit(dev->i2c_p, &dev->i2c_trans, dev->i2c_trans.slave_addr, 2);
|
||||
} else {
|
||||
return i2c_transmit(dev->i2c_p, &dev->i2c_trans, dev->i2c_trans.slave_addr, 2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Gautier Hattenberger <gautier.hattenberger@enac.fr>
|
||||
*
|
||||
* This file is part of paparazzi.
|
||||
*
|
||||
* paparazzi is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* paparazzi is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with paparazzi; see the file COPYING. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file peripherals/pca95x4.h
|
||||
*
|
||||
* Driver for the 8-bit I/O expander based on i2c
|
||||
*/
|
||||
|
||||
#ifndef PCA95X4_H
|
||||
#define PCA95X4_H
|
||||
|
||||
#include "std.h"
|
||||
#include "mcu_periph/i2c.h"
|
||||
|
||||
#define PCA95X4_DEFAULT_ADDRESS 0x40
|
||||
|
||||
#define PCA95X4_INPUT_REG (0x00)
|
||||
#define PCA95X4_OUTPUT_REG (0x01)
|
||||
#define PCA95X4_POL_REG (0x02)
|
||||
#define PCA95X4_CONFIG_REG (0x03)
|
||||
|
||||
#define PCA95X4_P0 (1 << 0)
|
||||
#define PCA95X4_P1 (1 << 1)
|
||||
#define PCA95X4_P2 (1 << 2)
|
||||
#define PCA95X4_P3 (1 << 3)
|
||||
#define PCA95X4_P4 (1 << 4)
|
||||
#define PCA95X4_P5 (1 << 5)
|
||||
#define PCA95X4_P6 (1 << 6)
|
||||
#define PCA95X4_P7 (1 << 7)
|
||||
|
||||
#define PCA95X4_CLEAR_ALL 0x00
|
||||
|
||||
/** PCA95X4 structure
|
||||
*/
|
||||
struct pca95x4 {
|
||||
struct i2c_periph *i2c_p;
|
||||
struct i2c_transaction i2c_trans;
|
||||
};
|
||||
|
||||
/** Init PCA95X4
|
||||
* @param [in] dev address to pca95x4 device
|
||||
* @param [in] i2c_p addres of i2c bus
|
||||
* @param [in] addr i2c address
|
||||
*/
|
||||
extern void pca95x4_init(struct pca95x4 *dev, struct i2c_periph *i2c_p, uint8_t addr);
|
||||
|
||||
/** Configure PCA95X4
|
||||
* @param [in] dev address to pca95x4 device
|
||||
* @param [in] val value to write to confi register
|
||||
* @param [in] blocking true for blocking i2c transaction
|
||||
* @return false if i2c was not ready or transaction submit fails or timeout (blocking)
|
||||
*/
|
||||
extern bool pca95x4_configure(struct pca95x4 *dev, uint8_t val, bool blocking);
|
||||
|
||||
/** Set output value
|
||||
* @param [in] dev address to pca95x4 device
|
||||
* @param [in] mask output pins to set
|
||||
* @param [in] blocking true for blocking i2c transaction
|
||||
* @return false if i2c was not ready or transaction submit fails or timeout (blocking)
|
||||
*/
|
||||
extern bool pca95x4_set_output(struct pca95x4 *dev, uint8_t mask, bool blocking);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -37,7 +37,15 @@ extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#define VL53L1_DEFAULT_ADDRESS 0x52
|
||||
|
||||
enum VL53L1_ReadStatus {
|
||||
VL53L1_READ_IDLE,
|
||||
VL53L1_READ_DATA_READY,
|
||||
VL53L1_READ_STATUS,
|
||||
VL53L1_READ_DISTANCE,
|
||||
VL53L1_CLEAR_INT
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
struct i2c_periph *i2c_p;
|
||||
@@ -49,6 +57,7 @@ typedef struct {
|
||||
uint8_t state;
|
||||
uint8_t IntPol;
|
||||
} nonblocking;
|
||||
enum VL53L1_ReadStatus read_status;
|
||||
} VL53L1_Dev_t;
|
||||
|
||||
typedef VL53L1_Dev_t *VL53L1_DEV;
|
||||
|
||||
@@ -203,6 +203,11 @@ static const uint8_t status_rtn[24] = { 255, 255, 255, 5, 2, 4, 1, 7, 3, 0,
|
||||
255, 255, 11, 12
|
||||
};
|
||||
|
||||
#if VL53L1X_AUTO_INCR_ADDR
|
||||
// start after default address
|
||||
static uint8_t auto_incr_addr = VL53L1_DEFAULT_ADDRESS + 2;
|
||||
#endif
|
||||
|
||||
VL53L1X_ERROR VL53L1X_GetSWVersion(VL53L1X_Version_t *pVersion)
|
||||
{
|
||||
VL53L1X_ERROR Status = 0;
|
||||
@@ -240,9 +245,29 @@ VL53L1X_ERROR VL53L1X_SensorInit(VL53L1_DEV dev)
|
||||
status = VL53L1X_StopRanging(dev);
|
||||
status = VL53L1_WrByte(dev, VL53L1_VHV_CONFIG__TIMEOUT_MACROP_LOOP_BOUND, 0x09); /* two bounds VHV */
|
||||
status = VL53L1_WrByte(dev, 0x0B, 0); /* start VHV from the previous temperature */
|
||||
#if VL53L1X_AUTO_INCR_ADDR
|
||||
status = VL53L1X_SetI2CAddress(dev, auto_incr_addr);
|
||||
auto_incr_addr += 2; // auto increment by 2 (+1 on 7 bits address)
|
||||
#endif
|
||||
return status;
|
||||
}
|
||||
|
||||
void VL53L1X_BootDevice(VL53L1_DEV dev, uint16_t TimingBudgetInMs, uint16_t DistanceMode, uint32_t InterMeasurementInMs)
|
||||
{
|
||||
uint8_t state;
|
||||
do {
|
||||
VL53L1X_BootState(dev, &state);
|
||||
} while (!state);
|
||||
VL53L1X_SensorInit(dev);
|
||||
/* Configure sensor */
|
||||
VL53L1X_SetTimingBudgetInMs(dev, TimingBudgetInMs);
|
||||
VL53L1X_SetDistanceMode(dev, DistanceMode);
|
||||
VL53L1X_SetInterMeasurementInMs(dev, InterMeasurementInMs);
|
||||
/* Start measurement */
|
||||
VL53L1X_StartRanging(dev);
|
||||
}
|
||||
|
||||
|
||||
VL53L1X_ERROR VL53L1X_ClearInterrupt(VL53L1_DEV dev)
|
||||
{
|
||||
VL53L1X_ERROR status = 0;
|
||||
|
||||
@@ -77,47 +77,47 @@
|
||||
|
||||
typedef int8_t VL53L1X_ERROR;
|
||||
|
||||
#define SOFT_RESET 0x0000
|
||||
#define VL53L1_I2C_SLAVE__DEVICE_ADDRESS 0x0001
|
||||
#define VL53L1_VHV_CONFIG__TIMEOUT_MACROP_LOOP_BOUND 0x0008
|
||||
#define ALGO__CROSSTALK_COMPENSATION_PLANE_OFFSET_KCPS 0x0016
|
||||
#define ALGO__CROSSTALK_COMPENSATION_X_PLANE_GRADIENT_KCPS 0x0018
|
||||
#define ALGO__CROSSTALK_COMPENSATION_Y_PLANE_GRADIENT_KCPS 0x001A
|
||||
#define ALGO__PART_TO_PART_RANGE_OFFSET_MM 0x001E
|
||||
#define MM_CONFIG__INNER_OFFSET_MM 0x0020
|
||||
#define MM_CONFIG__OUTER_OFFSET_MM 0x0022
|
||||
#define GPIO_HV_MUX__CTRL 0x0030
|
||||
#define GPIO__TIO_HV_STATUS 0x0031
|
||||
#define SYSTEM__INTERRUPT_CONFIG_GPIO 0x0046
|
||||
#define PHASECAL_CONFIG__TIMEOUT_MACROP 0x004B
|
||||
#define RANGE_CONFIG__TIMEOUT_MACROP_A_HI 0x005E
|
||||
#define RANGE_CONFIG__VCSEL_PERIOD_A 0x0060
|
||||
#define RANGE_CONFIG__VCSEL_PERIOD_B 0x0063
|
||||
#define RANGE_CONFIG__TIMEOUT_MACROP_B_HI 0x0061
|
||||
#define RANGE_CONFIG__TIMEOUT_MACROP_B_LO 0x0062
|
||||
#define RANGE_CONFIG__SIGMA_THRESH 0x0064
|
||||
#define RANGE_CONFIG__MIN_COUNT_RATE_RTN_LIMIT_MCPS 0x0066
|
||||
#define RANGE_CONFIG__VALID_PHASE_HIGH 0x0069
|
||||
#define VL53L1_SYSTEM__INTERMEASUREMENT_PERIOD 0x006C
|
||||
#define SYSTEM__THRESH_HIGH 0x0072
|
||||
#define SYSTEM__THRESH_LOW 0x0074
|
||||
#define SD_CONFIG__WOI_SD0 0x0078
|
||||
#define SD_CONFIG__INITIAL_PHASE_SD0 0x007A
|
||||
#define ROI_CONFIG__USER_ROI_CENTRE_SPAD 0x007F
|
||||
#define ROI_CONFIG__USER_ROI_REQUESTED_GLOBAL_XY_SIZE 0x0080
|
||||
#define SYSTEM__SEQUENCE_CONFIG 0x0081
|
||||
#define VL53L1_SYSTEM__GROUPED_PARAMETER_HOLD 0x0082
|
||||
#define SYSTEM__INTERRUPT_CLEAR 0x0086
|
||||
#define SYSTEM__MODE_START 0x0087
|
||||
#define VL53L1_RESULT__RANGE_STATUS 0x0089
|
||||
#define VL53L1_RESULT__DSS_ACTUAL_EFFECTIVE_SPADS_SD0 0x008C
|
||||
#define RESULT__AMBIENT_COUNT_RATE_MCPS_SD 0x0090
|
||||
#define VL53L1_RESULT__FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD0 0x0096
|
||||
#define SOFT_RESET 0x0000
|
||||
#define VL53L1_I2C_SLAVE__DEVICE_ADDRESS 0x0001
|
||||
#define VL53L1_VHV_CONFIG__TIMEOUT_MACROP_LOOP_BOUND 0x0008
|
||||
#define ALGO__CROSSTALK_COMPENSATION_PLANE_OFFSET_KCPS 0x0016
|
||||
#define ALGO__CROSSTALK_COMPENSATION_X_PLANE_GRADIENT_KCPS 0x0018
|
||||
#define ALGO__CROSSTALK_COMPENSATION_Y_PLANE_GRADIENT_KCPS 0x001A
|
||||
#define ALGO__PART_TO_PART_RANGE_OFFSET_MM 0x001E
|
||||
#define MM_CONFIG__INNER_OFFSET_MM 0x0020
|
||||
#define MM_CONFIG__OUTER_OFFSET_MM 0x0022
|
||||
#define GPIO_HV_MUX__CTRL 0x0030
|
||||
#define GPIO__TIO_HV_STATUS 0x0031
|
||||
#define SYSTEM__INTERRUPT_CONFIG_GPIO 0x0046
|
||||
#define PHASECAL_CONFIG__TIMEOUT_MACROP 0x004B
|
||||
#define RANGE_CONFIG__TIMEOUT_MACROP_A_HI 0x005E
|
||||
#define RANGE_CONFIG__VCSEL_PERIOD_A 0x0060
|
||||
#define RANGE_CONFIG__VCSEL_PERIOD_B 0x0063
|
||||
#define RANGE_CONFIG__TIMEOUT_MACROP_B_HI 0x0061
|
||||
#define RANGE_CONFIG__TIMEOUT_MACROP_B_LO 0x0062
|
||||
#define RANGE_CONFIG__SIGMA_THRESH 0x0064
|
||||
#define RANGE_CONFIG__MIN_COUNT_RATE_RTN_LIMIT_MCPS 0x0066
|
||||
#define RANGE_CONFIG__VALID_PHASE_HIGH 0x0069
|
||||
#define VL53L1_SYSTEM__INTERMEASUREMENT_PERIOD 0x006C
|
||||
#define SYSTEM__THRESH_HIGH 0x0072
|
||||
#define SYSTEM__THRESH_LOW 0x0074
|
||||
#define SD_CONFIG__WOI_SD0 0x0078
|
||||
#define SD_CONFIG__INITIAL_PHASE_SD0 0x007A
|
||||
#define ROI_CONFIG__USER_ROI_CENTRE_SPAD 0x007F
|
||||
#define ROI_CONFIG__USER_ROI_REQUESTED_GLOBAL_XY_SIZE 0x0080
|
||||
#define SYSTEM__SEQUENCE_CONFIG 0x0081
|
||||
#define VL53L1_SYSTEM__GROUPED_PARAMETER_HOLD 0x0082
|
||||
#define SYSTEM__INTERRUPT_CLEAR 0x0086
|
||||
#define SYSTEM__MODE_START 0x0087
|
||||
#define VL53L1_RESULT__RANGE_STATUS 0x0089
|
||||
#define VL53L1_RESULT__DSS_ACTUAL_EFFECTIVE_SPADS_SD0 0x008C
|
||||
#define RESULT__AMBIENT_COUNT_RATE_MCPS_SD 0x0090
|
||||
#define VL53L1_RESULT__FINAL_CROSSTALK_CORRECTED_RANGE_MM_SD0 0x0096
|
||||
#define VL53L1_RESULT__PEAK_SIGNAL_COUNT_RATE_CROSSTALK_CORRECTED_MCPS_SD0 0x0098
|
||||
#define VL53L1_RESULT__OSC_CALIBRATE_VAL 0x00DE
|
||||
#define VL53L1_FIRMWARE__SYSTEM_STATUS 0x00E5
|
||||
#define VL53L1_IDENTIFICATION__MODEL_ID 0x010F
|
||||
#define VL53L1_ROI_CONFIG__MODE_ROI_CENTRE_SPAD 0x013E
|
||||
#define VL53L1_RESULT__OSC_CALIBRATE_VAL 0x00DE
|
||||
#define VL53L1_FIRMWARE__SYSTEM_STATUS 0x00E5
|
||||
#define VL53L1_IDENTIFICATION__MODEL_ID 0x010F
|
||||
#define VL53L1_ROI_CONFIG__MODE_ROI_CENTRE_SPAD 0x013E
|
||||
|
||||
/****************************************
|
||||
* PRIVATE define do not edit
|
||||
@@ -161,6 +161,12 @@ VL53L1X_ERROR VL53L1X_SetI2CAddress(VL53L1_DEV, uint8_t new_address);
|
||||
*/
|
||||
VL53L1X_ERROR VL53L1X_SensorInit(VL53L1_DEV dev);
|
||||
|
||||
/**
|
||||
* @brief Implement boot sequence of VL53L1 device as described in documentation
|
||||
* See VL53L1X_SetTimingBudgetInMs, VL53L1X_SetDistanceMode and VL53L1X_SetInterMeasurementInMs for params details
|
||||
*/
|
||||
void VL53L1X_BootDevice(VL53L1_DEV dev, uint16_t TimingBudgetInMs, uint16_t DistanceMode, uint32_t InterMeasurementInMs);
|
||||
|
||||
/**
|
||||
* @brief This function clears the interrupt, to be called after a ranging data reading
|
||||
* to arm the interrupt for the next data ready event.
|
||||
|
||||
@@ -30,6 +30,11 @@
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
// possible GetRangeStatus return value as in api.c GetRangeStatus
|
||||
static const uint8_t status_rtn[24] = { 255, 255, 255, 5, 2, 4, 1, 7, 3, 0,
|
||||
255, 255, 9, 13, 255, 255, 255, 255, 10, 6,
|
||||
255, 255, 11, 12
|
||||
};
|
||||
// Returns true upon completion
|
||||
static bool VL53L1_NonBlocking_WriteMulti(VL53L1_DEV dev, uint16_t index, uint8_t *pdata, uint32_t count)
|
||||
{
|
||||
@@ -106,6 +111,19 @@ bool VL53L1X_NonBlocking_CheckForDataReady(VL53L1_DEV dev, uint8_t *isDataReady)
|
||||
}
|
||||
}
|
||||
|
||||
// Returns true upon completion
|
||||
bool VL53L1X_NonBlocking_GetRangeStatus(VL53L1_DEV dev, uint8_t *rangeStatus)
|
||||
{
|
||||
uint8_t RgSt;
|
||||
*rangeStatus = 255;
|
||||
if (!VL53L1_NonBlocking_ReadMulti(dev, VL53L1_RESULT__RANGE_STATUS, &RgSt, 1)) { return false; }
|
||||
RgSt = RgSt & 0x1F;
|
||||
if (RgSt < 24) {
|
||||
*rangeStatus = status_rtn[RgSt];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Returns true upon completion
|
||||
bool VL53L1X_NonBlocking_GetDistance(VL53L1_DEV dev, uint16_t *distance)
|
||||
{
|
||||
@@ -122,3 +140,60 @@ bool VL53L1X_NonBlocking_ClearInterrupt(VL53L1_DEV dev)
|
||||
uint8_t data = 0x01;
|
||||
return VL53L1_NonBlocking_WriteMulti(dev, SYSTEM__INTERRUPT_CLEAR, &data, 1);
|
||||
}
|
||||
|
||||
bool VL53L1X_NonBlocking_ReadDataEvent(VL53L1_DEV dev, uint16_t *distance_mm, bool *new_data)
|
||||
{
|
||||
uint8_t isDataReady, rangeStatus;
|
||||
*new_data = false;
|
||||
switch (dev->read_status) {
|
||||
case VL53L1_READ_IDLE:
|
||||
// Idle, do nothing
|
||||
return false;
|
||||
case VL53L1_READ_DATA_READY:
|
||||
// Wait for data ready
|
||||
if (!VL53L1X_NonBlocking_CheckForDataReady(dev, &isDataReady)) {
|
||||
return false; // Check in progress
|
||||
}
|
||||
dev->read_status++;
|
||||
/* Falls through. */
|
||||
case VL53L1_READ_STATUS:
|
||||
// Get range status
|
||||
if (!VL53L1X_NonBlocking_GetRangeStatus(dev, &rangeStatus)) {
|
||||
return false; // Read status in progress
|
||||
}
|
||||
if (rangeStatus != 0) {
|
||||
dev->read_status = VL53L1_CLEAR_INT; // wrong measurement, clear interrupt and back to idle
|
||||
return true; // end cycle
|
||||
}
|
||||
dev->read_status++;
|
||||
/* Falls through. */
|
||||
case VL53L1_READ_DISTANCE:
|
||||
// Get ranging data
|
||||
if (!VL53L1X_NonBlocking_GetDistance(dev, distance_mm)) {
|
||||
return false; // Read in progress
|
||||
}
|
||||
*new_data = true;
|
||||
dev->read_status++;
|
||||
/* Falls through. */
|
||||
case VL53L1_CLEAR_INT:
|
||||
// Clear interrupt
|
||||
if (!VL53L1X_NonBlocking_ClearInterrupt(dev)) {
|
||||
return false; // Clear in progress
|
||||
}
|
||||
dev->read_status = VL53L1_READ_IDLE;
|
||||
return true; // Cycle is done
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool VL53L1X_NonBlocking_IsIdle(VL53L1_DEV dev)
|
||||
{
|
||||
return dev->read_status == VL53L1_READ_IDLE;
|
||||
}
|
||||
|
||||
bool VL53L1X_NonBlocking_RequestData(VL53L1_DEV dev)
|
||||
{
|
||||
dev->read_status = VL53L1_READ_DATA_READY;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -39,6 +39,13 @@
|
||||
*/
|
||||
bool VL53L1X_NonBlocking_CheckForDataReady(VL53L1_DEV dev, uint8_t *isDataReady);
|
||||
|
||||
/**
|
||||
* @brief This function returns the range status to discard wrong measurments
|
||||
* @param : rangeStatus (0:no error, 1:sigma failed, 2:signal failed, ..., 7:wrap-around)
|
||||
* @return: TRUE upon completion
|
||||
*/
|
||||
bool VL53L1X_NonBlocking_GetRangeStatus(VL53L1_DEV dev, uint8_t *rangeStatus);
|
||||
|
||||
/**
|
||||
* @brief This function returns the distance measured by the sensor in mm
|
||||
* @return: TRUE upon completion
|
||||
@@ -52,5 +59,22 @@ bool VL53L1X_NonBlocking_GetDistance(VL53L1_DEV dev, uint16_t *distance);
|
||||
*/
|
||||
bool VL53L1X_NonBlocking_ClearInterrupt(VL53L1_DEV dev);
|
||||
|
||||
/** @brief Implement non-blocking read sequence
|
||||
* The data reading actually starts when the read_state is set to VL53L1_READ_DATA_READY using VL53L1X_NonBlocking_RequestData()
|
||||
* @param : distance measurement in millimeter
|
||||
* @param : flag when a new data is available
|
||||
* @return: TRUE when a complete read sequence is finished
|
||||
*/
|
||||
bool VL53L1X_NonBlocking_ReadDataEvent(VL53L1_DEV dev, uint16_t *distance_mm, bool *new_data);
|
||||
|
||||
/** @brief Test is read status is on idle
|
||||
* @return: TRUE if idle
|
||||
*/
|
||||
bool VL53L1X_NonBlocking_IsIdle(VL53L1_DEV dev);
|
||||
|
||||
/** @brief Request a new reading
|
||||
* @return: TRUE if request successful
|
||||
*/
|
||||
bool VL53L1X_NonBlocking_RequestData(VL53L1_DEV dev);
|
||||
|
||||
#endif // VL53L1X_NONBLOCKING_H
|
||||
|
||||
Reference in New Issue
Block a user