Files
GD32E230_VL53L4CD/Inc/VL53L4CD_Driver.h
T

223 lines
8.8 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* @file VL53L4CD_Driver.h
* @brief VL53L4CD 测距传感器驱动接口
*
* 基于 ST VL53L4CD ULD 和 Pololu 参考实现,寄存器地址均为 16 位,
* 通过项目现有硬件 I2C0 (PA9/PA10) 访问。
*/
#ifndef VL53L4CD_DRIVER_H
#define VL53L4CD_DRIVER_H
#include <stdbool.h>
#include <stdint.h>
/* 板载默认 7 位 I2C 地址,VL53L4CD 出厂默认 0x29 */
#define VL53L4CD_I2C_ADDR 0x29U
/* 寄存器地址 */
#define VL53L4CD_REG_I2C_SLAVE_DEVICE_ADDRESS 0x0001U
#define VL53L4CD_REG_VHV_TIMEOUT_MACROP_LOOP_BOUND 0x0008U
#define VL53L4CD_REG_XTALK_PLANE_OFFSET_KCPS 0x0016U
#define VL53L4CD_REG_XTALK_X_PLANE_GRADIENT_KCPS 0x0018U
#define VL53L4CD_REG_XTALK_Y_PLANE_GRADIENT_KCPS 0x001AU
#define VL53L4CD_REG_RANGE_OFFSET_MM 0x001EU
#define VL53L4CD_REG_INNER_OFFSET_MM 0x0020U
#define VL53L4CD_REG_OUTER_OFFSET_MM 0x0022U
#define VL53L4CD_REG_GPIO_HV_MUX_CTRL 0x0030U
#define VL53L4CD_REG_GPIO_TIO_HV_STATUS 0x0031U
#define VL53L4CD_REG_SYSTEM_INTERRUPT 0x0046U
#define VL53L4CD_REG_RANGE_CONFIG_A 0x005EU
#define VL53L4CD_REG_RANGE_CONFIG_B 0x0061U
#define VL53L4CD_REG_SIGMA_THRESHOLD 0x0064U
#define VL53L4CD_REG_MIN_COUNT_RATE_RTN_LIMIT 0x0066U
#define VL53L4CD_REG_INTERMEASUREMENT_MS 0x006CU
#define VL53L4CD_REG_THRESH_HIGH 0x0072U
#define VL53L4CD_REG_THRESH_LOW 0x0074U
#define VL53L4CD_REG_SYSTEM_INTERRUPT_CLEAR 0x0086U
#define VL53L4CD_REG_SYSTEM_START 0x0087U
#define VL53L4CD_REG_RESULT_RANGE_STATUS 0x0089U
#define VL53L4CD_REG_RESULT_SPAD_NB 0x008CU
#define VL53L4CD_REG_RESULT_SIGNAL_RATE 0x008EU
#define VL53L4CD_REG_RESULT_AMBIENT_RATE 0x0090U
#define VL53L4CD_REG_RESULT_SIGMA 0x0092U
#define VL53L4CD_REG_RESULT_DISTANCE 0x0096U
#define VL53L4CD_REG_RESULT_OSC_CALIBRATE_VAL 0x00DEU
#define VL53L4CD_REG_FIRMWARE_SYSTEM_STATUS 0x00E5U
#define VL53L4CD_REG_IDENTIFICATION_MODEL_ID 0x010FU
/* 等待固件启动 / 数据就绪的最大时间 */
#define VL53L4CD_BOOT_TIMEOUT_MS 200U
#define VL53L4CD_DATA_TIMEOUT_MS 500U
/* 一次结果块读包含的字节数:0x89..0x97 */
#define VL53L4CD_RESULT_BLOCK_SIZE 15U
/* 测距状态码(已由原始状态映射为用户可读状态) */
typedef enum {
VL53L4CD_STATUS_RANGE_VALID = 0, /* 测距有效 */
VL53L4CD_STATUS_SIGMA_FAIL, /* Sigma 超限 */
VL53L4CD_STATUS_SIGNAL_FAIL, /* 信号强度不足 */
VL53L4CD_STATUS_MIN_RANGE_FAIL, /* 目标过近 */
VL53L4CD_STATUS_PHASE_FAIL, /* 相位故障 */
VL53L4CD_STATUS_HW_FAIL, /* 硬件故障 */
VL53L4CD_STATUS_NO_TARGET, /* 未检测到目标 */
VL53L4CD_STATUS_SIGNAL_FAIL_NEAR, /* 近距离信号不足 */
VL53L4CD_STATUS_OUT_OF_BOUNDS, /* 超出边界 */
VL53L4CD_STATUS_XTALK_SIGNAL_FAIL, /* 串扰信号失败 */
VL53L4CD_STATUS_LOW_SIGNAL_FAIL, /* 低信号失败 */
VL53L4CD_STATUS_CROSSTALK_SIGNAL_FAIL,/* 串扰信号失败 */
VL53L4CD_STATUS_AMBIENT_SIGNAL_FAIL, /* 环境光信号失败 */
VL53L4CD_STATUS_SNSPD_AMBIENT_FAIL, /* 单光子雪崩二极管环境光失败 */
VL53L4CD_STATUS_UNKNOWN = 255 /* 未知状态 */
} vl53l4cd_range_status_t;
/* 单次测量结果 */
typedef struct {
uint16_t distance_mm; /* 距离,单位 mm */
uint8_t range_status; /* 测距状态码 */
uint8_t number_of_spad; /* 有效 SPAD 数 */
uint32_t signal_rate_kcps; /* 信号速率,单位 kcps */
uint32_t ambient_rate_kcps; /* 环境光速率,单位 kcps */
uint32_t signal_per_spad_kcps; /* 每 SPAD 信号速率 */
uint32_t ambient_per_spad_kcps; /* 每 SPAD 环境光速率 */
uint16_t sigma_mm; /* Sigma,单位 mm */
} vl53l4cd_result_t;
/**
* @brief 初始化 VL53L4CD
* @param[in] none
* @retval true: 初始化成功; false: 初始化失败
*/
bool vl53l4cd_init(void);
/**
* @brief 启动连续测距
* @param[in] none
* @retval true: 启动成功; false: 启动失败
*/
bool vl53l4cd_start_ranging(void);
/**
* @brief 停止连续测距
* @param[in] none
* @retval true: 停止成功; false: 停止失败
*/
bool vl53l4cd_stop_ranging(void);
/**
* @brief 检查是否有新测距结果
* @param[in] none
* @retval true: 有新结果; false: 无新结果或读取失败
*/
bool vl53l4cd_data_ready(void);
/**
* @brief 清除测距完成中断
* @param[in] none
* @retval true: 清除成功; false: 清除失败
*/
bool vl53l4cd_clear_interrupt(void);
/**
* @brief 读取并解析一次测距结果
* @param[out] result: 结果结构体指针
* @retval true: 读取成功; false: 读取失败
*/
bool vl53l4cd_get_result(vl53l4cd_result_t *result);
/**
* @brief 设置测距时序预算和测距周期
* @param[in] timing_budget_ms: 10..200 ms
* @param[in] inter_measurement_ms: 当前驱动只支持 0(连续模式)
* @retval true: 设置成功; false: 参数无效或设置失败
*/
bool vl53l4cd_set_range_timing(uint8_t timing_budget_ms, uint32_t inter_measurement_ms);
/**
* @brief 写入手动指定的距离偏移量
* @param[in] offset_mm: 偏移量,单位 mm,可为负
* @retval true: 成功; false: 失败
*/
bool vl53l4cd_set_offset(int16_t offset_mm);
/**
* @brief 写入串扰(玻璃反射)补偿值,透过玻璃测距时使用
* @details 写 XTALK_PLANE_OFFSET_KCPS (0x0016) 并将 X/Y 梯度寄存器清零,
* 寄存器值为 xtalk_kcps * 512
* @param[in] xtalk_kcps: 串扰补偿值,单位 kcps,范围 0..127
* @retval true: 成功; false: 参数无效或写入失败
*/
bool vl53l4cd_set_xtalk(uint16_t xtalk_kcps);
/**
* @brief 读取当前生效的串扰补偿值
* @param[out] xtalk_kcps: 返回串扰值,单位 kcps
* @retval true: 成功; false: 失败
*/
bool vl53l4cd_get_xtalk(uint16_t *xtalk_kcps);
/**
* @brief 读取当前生效的距离偏移量
* @param[out] offset_mm: 返回偏移量,单位 mm
* @retval true: 成功; false: 失败
*/
bool vl53l4cd_get_offset(int16_t *offset_mm);
/**
* @brief 以当前目标执行一次偏移校准
* @param[in] target_distance_mm: 目标实际距离,单位 mm,范围 10..1000
* @param[in] num_samples: 有效采样次数,范围 5..255
* @param[out] measured_offset_mm: 计算得到的偏移量,单位 mm
* @retval true: 校准并写入成功; false: 失败
*/
bool vl53l4cd_calibrate_offset(uint16_t target_distance_mm, uint16_t num_samples,
int16_t *measured_offset_mm);
/**
* @brief 执行一次串扰校准(透过玻璃安装时使用)
* @details 参照 ST ULD vl53l4cd_calibration.c 的 CalibrateXtalk 流程,定点数实现:
* 先清零串扰补偿,热机 10 帧,然后采样有效测距帧,
* xtalk = (1 - 平均距离/目标距离) * 平均信号/平均SPAD数,上限 127 kcps。
* 校准期间传感器被独占,主循环上报会暂停。
* @param[in] target_distance_mm: 玻璃后方目标的实际距离,单位 mm,范围 10..5000
* @param[in] num_samples: 采样次数,范围 5..255ST 建议至少 10
* @param[out] measured_xtalk_kcps: 计算得到的串扰值,单位 kcps
* @retval true: 校准并写入成功; false: 失败(含有效样本不足或串扰超限)
*/
bool vl53l4cd_calibrate_xtalk(uint16_t target_distance_mm, uint16_t num_samples,
uint16_t *measured_xtalk_kcps);
/**
* @brief 读一个 8 位寄存器
* @param[in] reg: 16 位寄存器地址
* @param[out] value: 返回值指针
* @retval true: 成功; false: 失败
*/
bool vl53l4cd_read_reg8(uint16_t reg, uint8_t *value);
/**
* @brief 读一个 16 位寄存器
* @param[in] reg: 16 位寄存器地址
* @param[out] value: 返回值指针
* @retval true: 成功; false: 失败
*/
bool vl53l4cd_read_reg16(uint16_t reg, uint16_t *value);
/**
* @brief 写一个 8 位寄存器
* @param[in] reg: 16 位寄存器地址
* @param[in] value: 写入值
* @retval true: 成功; false: 失败
*/
bool vl53l4cd_write_reg8(uint16_t reg, uint8_t value);
/**
* @brief 写一个 16 位寄存器
* @param[in] reg: 16 位寄存器地址
* @param[in] value: 写入值
* @retval true: 成功; false: 失败
*/
bool vl53l4cd_write_reg16(uint16_t reg, uint16_t value);
#endif /* VL53L4CD_DRIVER_H */