/*! \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); } }