Files
GD32E230_VL53L4CD/Src/main.c
T

233 lines
6.4 KiB
C

/*!
\file main.c
\brief running LED
\version 2025-02-10, V2.4.0, demo for GD32E23x
*/
/*
Copyright (c) 2025, GigaDevice Semiconductor Inc.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "gd32e23x.h"
#include "systick.h"
#include "uart.h"
#include "uart_ring_buffer.h"
#include "led.h"
#include "command.h"
#include "i2c.h"
#include "board_config.h"
#include "VL53L4CD_Driver.h"
#include "calib_store.h"
/*!
\brief 向测距串口发送一个字节
\param[in] byte: 待发送字节
\param[out] none
\retval none
*/
static void uart_put_byte(uint8_t byte)
{
while (usart_flag_get(UART_PHY, USART_FLAG_TBE) == RESET) {}
usart_data_transmit(UART_PHY, byte);
}
/*!
\brief 向测距串口发送以 NUL 结尾的字符串
\param[in] s: 字符串指针
\param[out] none
\retval none
*/
static void uart_write_str(const char *s)
{
while (*s != '\0') {
uart_put_byte((uint8_t)*s++);
}
}
/*!
\brief 以十进制输出无符号整数(替代 printf,节省 libc 体积)
\param[in] value: 待输出的数值
\param[out] none
\retval none
*/
static void uart_write_u32(uint32_t value)
{
char temp[10];
uint8_t i = 0U;
if (value == 0U) {
uart_put_byte('0');
return;
}
while (value > 0U) {
temp[i++] = (char)('0' + (value % 10U));
value /= 10U;
}
while (i > 0U) {
uart_put_byte((uint8_t)temp[--i]);
}
}
/*!
\brief 以十进制输出有符号整数
\param[in] value: 待输出的数值
\param[out] none
\retval none
*/
static void uart_write_i32(int32_t value) __attribute__((unused));
static void uart_write_i32(int32_t value)
{
uint32_t magnitude;
if (value < 0) {
uart_put_byte('-');
magnitude = (uint32_t)(-value);
} else {
magnitude = (uint32_t)value;
}
uart_write_u32(magnitude);
}
/*!
\brief 输出一帧测距结果,格式与原 printf 版本逐字节一致
\param[in] r: 测距结果指针
\param[out] none
\retval none
*/
static void report_result(const vl53l4cd_result_t *r)
{
uart_write_str("Distance: ");
uart_write_u32(r->distance_mm);
uart_write_str(" mm | status: ");
uart_write_u32(r->range_status);
uart_write_str(" | signal: ");
uart_write_u32(r->signal_rate_kcps);
uart_write_str(" kcps | ambient: ");
uart_write_u32(r->ambient_rate_kcps);
uart_write_str(" kcps | sigma: ");
uart_write_u32(r->sigma_mm);
uart_write_str(" mm\r\n");
}
/*!
\brief main function
\param[in] none
\param[out] none
\retval none
*/
int main(void)
{
led_init();
mcu_detect_and_config();
// delay_ms(1000);
systick_config();
uart_ring_buffer_init();
uart_init();
i2c_config();
#if DEBUG_MODE == CFG_ENABLE
printf("Hello World!\r\n");
#endif
#if SEGGER_RTT_DETECTION == CFG_ENABLE
RTT_printf(0, "Hello World!\r\n");
#endif
#if DEBUG_VERBOSE == CFG_ENABLE
i2c_scan();
i2c_bus_reset();
#endif
if (vl53l4cd_init()) {
#if VL53L4CD_AUTO_CALIB == CFG_ENABLE
int16_t cal_offset = 0;
if (vl53l4cd_calibrate_offset(VL53L4CD_CALIB_TARGET_MM,
VL53L4CD_CALIB_SAMPLES,
&cal_offset)) {
uart_write_str("VL53L4CD offset calibrated: ");
uart_write_i32(cal_offset);
uart_write_str(" mm\r\n");
} else {
uart_write_str("VL53L4CD offset calibration failed\r\n");
}
#else
int16_t stored_offset = 0;
uint16_t stored_xtalk = 0;
bool applied = false;
#if VL53L4CD_PERSIST_CALIB == CFG_ENABLE
/* Flash 末页有有效校准数据时优先生效(M105 保存 / M107 擦除) */
if (calib_store_load(&stored_offset, &stored_xtalk)) {
vl53l4cd_set_offset(stored_offset);
vl53l4cd_set_xtalk(stored_xtalk);
applied = true;
}
#endif
if (!applied) {
vl53l4cd_set_offset(VL53L4CD_CALIB_OFFSET_MM);
#if VL53L4CD_GLASS_XTALK == CFG_ENABLE
/* 透过玻璃安装:写入编译期固定串扰补偿 */
vl53l4cd_set_xtalk(VL53L4CD_GLASS_XTALK_KCPS);
#endif
}
#endif
vl53l4cd_start_ranging();
uart_write_str("VL53L4CD ready\r\n");
} else {
uart_write_str("VL53L4CD init failed\r\n");
}
/* ========== Command Testing ========== */
/* ========== */
while(1){
command_process(); /* Process UART commands */
if (vl53l4cd_data_ready()) {
vl53l4cd_result_t result;
vl53l4cd_clear_interrupt();
if (vl53l4cd_get_result(&result)) {
command_set_last_result(&result); /* 供 M3 命令查询 */
if (get_sensor_report_enabled()) {
report_result(&result);
}
}
delay_ms(500);
}
delay_ms(10);
}
}