mirror of
https://github.com/whowechina/chu_pico.git
synced 2025-01-31 12:03:43 +01:00
VL53L0X and GP2Y0E03 both supported
This commit is contained in:
parent
78519325ce
commit
4590e9ee14
Binary file not shown.
@ -21,6 +21,7 @@
|
||||
#include "i2c_hub.h"
|
||||
|
||||
static const uint8_t TOF_LIST[] = TOF_MUX_LIST;
|
||||
static uint8_t tof_model[sizeof(TOF_LIST)];
|
||||
static uint16_t distances[sizeof(TOF_LIST)];
|
||||
|
||||
void air_init()
|
||||
@ -36,14 +37,15 @@ void air_init()
|
||||
|
||||
for (int i = 0; i < sizeof(TOF_LIST); i++) {
|
||||
i2c_select(I2C_PORT, 1 << TOF_LIST[i]);
|
||||
#if defined(TOF_VL53L0X)
|
||||
vl53l0x_init_tof(true);
|
||||
vl53l0x_start_continuous(0);
|
||||
#elif defined(TOF_GP2Y0E03)
|
||||
gp2y0e_write(I2C_PORT, 0xa8, 0); // Accumulation 0:1, 1:5, 2:30, 3:10
|
||||
gp2y0e_write(I2C_PORT, 0x3f, 0x30); // Filter 0x00:7, 0x10:5, 0x20:9, 0x30:1
|
||||
gp2y0e_write(I2C_PORT, 0x13, 5); // Pulse [3..7]:[40, 80, 160, 240, 320] us
|
||||
#endif
|
||||
tof_model[i] = vl53l0x_is_present() ? 0 : 1;
|
||||
if (tof_model[i] == 0) {
|
||||
vl53l0x_init_tof(true);
|
||||
vl53l0x_start_continuous(0);
|
||||
} else if (tof_model[i] == 1) {
|
||||
gp2y0e_write(I2C_PORT, 0xa8, 0); // Accumulation 0:1, 1:5, 2:30, 3:10
|
||||
gp2y0e_write(I2C_PORT, 0x3f, 0x30); // Filter 0x00:7, 0x10:5, 0x20:9, 0x30:1
|
||||
gp2y0e_write(I2C_PORT, 0x13, 5); // Pulse [3..7]:[40, 80, 160, 240, 320] us
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -102,11 +104,11 @@ void air_update()
|
||||
{
|
||||
for (int i = 0; i < sizeof(TOF_LIST); i++) {
|
||||
i2c_select(I2C_PORT, 1 << TOF_LIST[i]);
|
||||
#if defined(TOF_VL53L0X)
|
||||
distances[i] = readRangeContinuousMillimeters() * 10;
|
||||
#elif defined(TOF_GP2Y0E03)
|
||||
distances[i] = gp2y0e_dist16(I2C_PORT);
|
||||
#endif
|
||||
if (tof_model[i] == 0) {
|
||||
distances[i] = readRangeContinuousMillimeters() * 10;
|
||||
} else if (tof_model[i] == 1) {
|
||||
distances[i] = gp2y0e_dist16(I2C_PORT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,8 +12,6 @@
|
||||
|
||||
#define I2C_HUB_EN 19
|
||||
|
||||
//#define TOF_GP2Y0E03
|
||||
#define TOF_VL53L0X
|
||||
#define TOF_MUX_LIST { 1, 2, 0, 4, 5 }
|
||||
|
||||
#define RGB_PIN 2
|
||||
|
@ -1,6 +1,8 @@
|
||||
/*
|
||||
* VL53L0X Distance measurement sensor
|
||||
* WHowe <github.com/whowechina>
|
||||
*
|
||||
* Most of this VL53L0X code is from https://github.com/pololu/vl53l0x-arduino
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
@ -9,38 +11,24 @@
|
||||
#include "hardware/i2c.h"
|
||||
#include "board_defs.h"
|
||||
|
||||
#define VL53L0X_DEF_ADDR 0x29
|
||||
// Most of the functionality of this library is based on the VL53L0X API
|
||||
// provided by ST (STSW-IMG005), and some of the explanatory comments are quoted
|
||||
// or paraphrased from the API source code, API user manual (UM2039), and the
|
||||
// VL53L0X datasheet.
|
||||
|
||||
#include "vl53l0x.h"
|
||||
|
||||
// Defines /////////////////////////////////////////////////////////////////////
|
||||
#define VL53L0X_DEF_ADDR 0x29
|
||||
|
||||
#define IO_TIMEOUT_US 10000
|
||||
// The Arduino two-wire interface uses a 7-bit number for the address,
|
||||
// and sets the last bit correctly based on reads and writes
|
||||
#define ADDRESS_DEFAULT 0b0101001
|
||||
|
||||
// Decode VCSEL (vertical cavity surface emitting laser) pulse period in PCLKs
|
||||
// from register value
|
||||
// based on VL53L0X_decode_vcsel_period()
|
||||
#define decodeVcselPeriod(reg_val) (((reg_val) + 1) << 1)
|
||||
|
||||
// Encode VCSEL pulse period register value from period in PCLKs
|
||||
// based on VL53L0X_encode_vcsel_period()
|
||||
#define encodeVcselPeriod(period_pclks) (((period_pclks) >> 1) - 1)
|
||||
|
||||
// Calculate macro period in *nanoseconds* from VCSEL period in PCLKs
|
||||
// based on VL53L0X_calc_macro_period_ps()
|
||||
// PLL_period_ps = 1655; macro_period_vclks = 2304
|
||||
#define calcMacroPeriod(vcsel_period_pclks) ((((uint32_t)2304 * (vcsel_period_pclks) * 1655) + 500) / 1000)
|
||||
|
||||
static i2c_inst_t *port;
|
||||
static uint8_t addr = VL53L0X_DEF_ADDR;
|
||||
static uint16_t io_timeout = 100;
|
||||
|
||||
static uint8_t stop_variable; // read by init and used when starting measurement; is StopVariable field of VL53L0X_DevData_t structure in API
|
||||
static uint32_t measurement_timing_budget_us;
|
||||
@ -53,26 +41,20 @@ void vl53l0x_init(i2c_inst_t *i2c_port, uint8_t i2c_addr)
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize sensor using sequence based on VL53L0X_DataInit(),
|
||||
// VL53L0X_StaticInit(), and VL53L0X_PerformRefCalibration().
|
||||
// This function does not perform reference SPAD calibration
|
||||
// (VL53L0X_PerformRefSpadManagement()), since the API user manual says that it
|
||||
// is performed by ST on the bare modules; it seems like that should work well
|
||||
// enough unless a cover glass is added.
|
||||
// If io_2v8 (optional) is true or not given, the sensor is configured for 2V8
|
||||
// mode.
|
||||
bool vl53l0x_is_present()
|
||||
{
|
||||
return read_reg(IDENTIFICATION_MODEL_ID) == 0xEE;
|
||||
}
|
||||
|
||||
bool vl53l0x_init_tof(bool io_2v8)
|
||||
{
|
||||
// check model ID register (value specified in datasheet)
|
||||
if (read_reg(IDENTIFICATION_MODEL_ID) != 0xEE) {
|
||||
if (!vl53l0x_is_present()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// VL53L0X_DataInit() begin
|
||||
|
||||
// sensor uses 1V8 mode for I/O by default; switch to 2V8 mode if necessary
|
||||
if (io_2v8)
|
||||
{
|
||||
if (io_2v8) {
|
||||
write_reg(VHV_CONFIG_PAD_SCL_SDA__EXTSUP_HV,
|
||||
read_reg(VHV_CONFIG_PAD_SCL_SDA__EXTSUP_HV) | 0x01); // set bit 0
|
||||
}
|
||||
@ -96,13 +78,11 @@ bool vl53l0x_init_tof(bool io_2v8)
|
||||
|
||||
write_reg(SYSTEM_SEQUENCE_CONFIG, 0xFF);
|
||||
|
||||
// VL53L0X_DataInit() end
|
||||
|
||||
// VL53L0X_StaticInit() begin
|
||||
|
||||
uint8_t spad_count;
|
||||
bool spad_type_is_aperture;
|
||||
if (!getSpadInfo(&spad_count, &spad_type_is_aperture)) { return false; }
|
||||
if (!getSpadInfo(&spad_count, &spad_type_is_aperture)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// The SPAD map (RefGoodSpadMap) is read by VL53L0X_get_info_from_device() in
|
||||
// the API, but the same data seems to be more easily readable from
|
||||
@ -110,8 +90,6 @@ bool vl53l0x_init_tof(bool io_2v8)
|
||||
uint8_t ref_spad_map[6];
|
||||
read_many(GLOBAL_CONFIG_SPAD_ENABLES_REF_0, ref_spad_map, 6);
|
||||
|
||||
// -- VL53L0X_set_reference_spads() begin (assume NVM values are valid)
|
||||
|
||||
write_reg(0xFF, 0x01);
|
||||
write_reg(DYNAMIC_SPAD_REF_EN_START_OFFSET, 0x00);
|
||||
write_reg(DYNAMIC_SPAD_NUM_REQUESTED_REF_SPAD, 0x2C);
|
||||
@ -137,11 +115,6 @@ bool vl53l0x_init_tof(bool io_2v8)
|
||||
|
||||
write_many(GLOBAL_CONFIG_SPAD_ENABLES_REF_0, ref_spad_map, 6);
|
||||
|
||||
// -- VL53L0X_set_reference_spads() end
|
||||
|
||||
// -- VL53L0X_load_tuning_settings() begin
|
||||
// DefaultTuningSettings from vl53l0x_tuning.h
|
||||
|
||||
write_reg(0xFF, 0x01);
|
||||
write_reg(0x00, 0x00);
|
||||
|
||||
@ -236,17 +209,10 @@ bool vl53l0x_init_tof(bool io_2v8)
|
||||
write_reg(0xFF, 0x00);
|
||||
write_reg(0x80, 0x00);
|
||||
|
||||
// -- VL53L0X_load_tuning_settings() end
|
||||
|
||||
// "Set interrupt config to new sample ready"
|
||||
// -- VL53L0X_SetGpioConfig() begin
|
||||
|
||||
write_reg(SYSTEM_INTERRUPT_CONFIG_GPIO, 0x04);
|
||||
write_reg(GPIO_HV_MUX_ACTIVE_HIGH, read_reg(GPIO_HV_MUX_ACTIVE_HIGH) & ~0x10); // active low
|
||||
write_reg(SYSTEM_INTERRUPT_CLEAR, 0x01);
|
||||
|
||||
// -- VL53L0X_SetGpioConfig() end
|
||||
|
||||
measurement_timing_budget_us = getMeasurementTimingBudget();
|
||||
|
||||
// "Disable MSRC and TCC by default"
|
||||
@ -261,29 +227,19 @@ bool vl53l0x_init_tof(bool io_2v8)
|
||||
// "Recalculate timing budget"
|
||||
setMeasurementTimingBudget(measurement_timing_budget_us);
|
||||
|
||||
// VL53L0X_StaticInit() end
|
||||
|
||||
// VL53L0X_PerformRefCalibration() begin (VL53L0X_perform_ref_calibration())
|
||||
|
||||
// -- VL53L0X_perform_vhv_calibration() begin
|
||||
|
||||
write_reg(SYSTEM_SEQUENCE_CONFIG, 0x01);
|
||||
if (!performSingleRefCalibration(0x40)) { return false; }
|
||||
|
||||
// -- VL53L0X_perform_vhv_calibration() end
|
||||
|
||||
// -- VL53L0X_perform_phase_calibration() begin
|
||||
if (!performSingleRefCalibration(0x40)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
write_reg(SYSTEM_SEQUENCE_CONFIG, 0x02);
|
||||
if (!performSingleRefCalibration(0x00)) { return false; }
|
||||
|
||||
// -- VL53L0X_perform_phase_calibration() end
|
||||
if (!performSingleRefCalibration(0x00)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// "restore the previous Sequence Config"
|
||||
write_reg(SYSTEM_SEQUENCE_CONFIG, 0xE8);
|
||||
|
||||
// VL53L0X_PerformRefCalibration() end
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -710,7 +666,7 @@ uint8_t getVcselPulsePeriod(vcselPeriodType type)
|
||||
// inter-measurement period in milliseconds determining how often the sensor
|
||||
// takes a measurement.
|
||||
// based on VL53L0X_StartMeasurement()
|
||||
void startContinuous(uint32_t period_ms)
|
||||
void vl53l0x_start_continuous(uint32_t period_ms)
|
||||
{
|
||||
write_reg(0x80, 0x01);
|
||||
write_reg(0xFF, 0x01);
|
||||
@ -748,7 +704,7 @@ void startContinuous(uint32_t period_ms)
|
||||
|
||||
// Stop continuous measurements
|
||||
// based on VL53L0X_StopMeasurement()
|
||||
void stopContinuous()
|
||||
void vl53l0x_stop_continuous()
|
||||
{
|
||||
write_reg(SYSRANGE_START, 0x01); // VL53L0X_REG_SYSRANGE_MODE_SINGLESHOT
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
/*
|
||||
* VL53L0X Distance measurement sensor
|
||||
* WHowe <github.com/whowechina>
|
||||
*
|
||||
* Most of this VL53L0X code is from https://github.com/pololu/vl53l0x-arduino
|
||||
*/
|
||||
|
||||
#ifndef VL53L0X_H
|
||||
@ -102,7 +104,7 @@ typedef enum {
|
||||
} vcselPeriodType;
|
||||
|
||||
void vl53l0x_init(i2c_inst_t *i2c_port, uint8_t i2c_addr);
|
||||
|
||||
bool vl53l0x_is_present();
|
||||
bool vl53l0x_init_tof(bool io_2v8);
|
||||
|
||||
void write_reg(uint8_t reg, uint8_t value);
|
||||
@ -124,8 +126,9 @@ uint32_t getMeasurementTimingBudget();
|
||||
bool setVcselPulsePeriod(vcselPeriodType type, uint8_t period_pclks);
|
||||
uint8_t getVcselPulsePeriod(vcselPeriodType type);
|
||||
|
||||
void startContinuous(uint32_t period_ms);
|
||||
void stopContinuous();
|
||||
void vl53l0x_start_continuous(uint32_t period_ms);
|
||||
void vl53l0x_stop_continuous();
|
||||
|
||||
uint16_t readRangeContinuousMillimeters();
|
||||
uint16_t readRangeSingleMillimeters();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user