generated from hulk/gd32e23x_template_cmake_vscode
233 lines
6.4 KiB
C
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);
|
|
}
|
|
}
|