feat(spi): 添加ADC反馈命令处理

新增SPI命令类型0xC4用于ADC调试反馈,实现在GD32上采集
温度/VDDA/VIN等模拟量数据的反馈功能,并支持主动推送和被动查询模式。

feat(spi): 扩展PING命令响应格式

修改PING命令响应格式,增加APP身份信息16字节载荷,包含版本号、
启动时间、功能开关位图等信息,用于主机获取从设备详细状态。

refactor(can_feedback): 优化CAN反馈推送逻辑

改进CAN反馈推送机制,跳过编译期关闭的通道,只遍历启用的通道,
确保推送效率并避免无效操作。

feat(comm): 添加EXMC总线初始化和诊断功能

添加了EXMC总线的初始化功能,包括GPIO配置、NOR/SRAM区域参数设置,
以及总线探活机制。实现了总线可见性检测,当检测到全0或全1的挂死状态时
会返回false并输出错误信息。同时添加了printf日志输出用于调试。

refactor(esc_lan9252): 重构ESC初始化返回值

将EscLan9252::init()方法的返回类型从void改为bool,
使其能够返回EXMC总线准备状态,便于上层进行状态检查。

docs(app_spi_cmd_ping): 添加代码注释文档

为SPI命令处理相关类和方法添加详细的Doxygen风格注释文档,
提高代码可读性和维护性。
This commit is contained in:
cbb
2026-07-20 02:36:56 +08:00
parent fedd39b902
commit 934836618a
18 changed files with 948 additions and 93 deletions
+42 -37
View File
@@ -1,4 +1,4 @@
/**
/**
* @file config.h
* @brief 应用级集中配置项定义。
* @note 用于统一管理当前项目中可调的外设、时序、通信与算法常量。
@@ -10,6 +10,40 @@
#include <stddef.h>
#include "gd32e50x.h"
/* ============================================================
* 功能开关(调试/特性总闸 — 改这里即可开关,改完重编)
* 0/false=关,1/true=开。需要 #if 的保留 #define。
* ============================================================ */
/** @brief 周期温度/电压 UART 打印(5s,task_manager #if)。 */
#define CONFIG_UART_TEMP_PERIODIC_PRINT 1
/** @brief UART 诊断详细级别(task_runner #if;0=精简 1=含 CAN 统计)。 */
#define CONFIG_UART_DIAG_LEVEL 1
/**
* @brief SPI 调试反馈 0xC4:GD32 ADC 温度/VDDA/VIN 1Hz 主动推送。
* @note 调试用;0=不注册 handler、不推送。与 ESP32 GD32_ADC_FEEDBACK_ENABLE 配对。
*/
#define CONFIG_SPI_ADC_FEEDBACK_ENABLE 1
/** @brief SPI 命令逐帧日志(#if)。 */
#define CONFIG_SPI_APP_LOG_ENABLE 0
/** @brief CAN_SEND 成功帧详细日志(#if)。 */
#define CONFIG_SPI_CAN_SEND_VERBOSE_LOG 0
/** @brief CAN-FD BRS 使能(canfd.cpp #if)。 */
#define CONFIG_CAN_FD_BRS_ENABLE 1U
/** @brief 启动时总线探测帧;正常固件关。 */
#define CONFIG_CAN_STARTUP_BUS_TEST_ENABLE 0
/** @brief 启动时内部回环自检;正常固件关。 */
#define CONFIG_CAN_STARTUP_LOOPBACK_TEST_ENABLE 0
/** @brief CAN 启动详细诊断 dump;默认关。 */
#define CONFIG_CAN_STARTUP_DIAG_VERBOSE 0
/** @brief CAN0/1/2 通道使能。 */
constexpr bool CONFIG_CAN_CH0_ENABLE = true;
constexpr bool CONFIG_CAN_CH1_ENABLE = true;
constexpr bool CONFIG_CAN_CH2_ENABLE = true;
/** @brief 主循环 WFI(main.cpp #if)。 */
#define CONFIG_MAIN_LOOP_WFI_ENABLE 0
/** @brief EtherCAT SYNC0 同步模式(#if)。 */
#define CONFIG_ETHERCAT_SYNC_MODE 0
/* ============================================================
* APP 固件版本号
* ============================================================ */
@@ -109,23 +143,7 @@ constexpr uint32_t CONFIG_CAN_DATA_BS1 = CAN_BT_BS1_3TQ;
/** @brief 数据段时间段 2。 */
constexpr uint32_t CONFIG_CAN_DATA_BS2 = CAN_BT_BS2_1TQ;
/** @brief BRS(比特率切换)使能开关。
* @note 保留 #define:canfd.cpp 中用 #if 做编译期分支。 */
#define CONFIG_CAN_FD_BRS_ENABLE 1U
/** @brief 启动时向物理总线发送 classic/FD/BRS 探测帧;正常固件默认关闭。 */
#define CONFIG_CAN_STARTUP_BUS_TEST_ENABLE 0
/** @brief 启动时切换控制器到内部回环执行自检;正常固件默认关闭。 */
#define CONFIG_CAN_STARTUP_LOOPBACK_TEST_ENABLE 0
/** @brief CAN 启动详细诊断(时钟/init 汇总/ERR 快照/寄存器 dump);默认关闭。 */
#define CONFIG_CAN_STARTUP_DIAG_VERBOSE 0
/** @brief CAN0 通道使能开关:true=启用初始化/收发/自测,false=完全禁用。 */
constexpr bool CONFIG_CAN_CH0_ENABLE = true;
/** @brief CAN1 通道使能开关。 */
constexpr bool CONFIG_CAN_CH1_ENABLE = true;
/** @brief CAN2 通道使能开关。 */
constexpr bool CONFIG_CAN_CH2_ENABLE = true;
/* BRS / 启动探测 / 通道使能:见文件顶部「功能开关」 */
/** @brief CAN 接收过滤器目标标准帧 ID。 */
constexpr uint32_t CONFIG_CAN_RX_FILTER_ID = CONFIG_CAN_STATUS_ID;
@@ -165,15 +183,7 @@ constexpr uint32_t CONFIG_TASK_PERIOD_HEARTBEAT_TICKS = 10000U;
/** @brief 调度基准节拍:APP 状态/诊断打印周期,50000 tick = 5s。 */
constexpr uint32_t CONFIG_TASK_PERIOD_DIAG_PRINT_TICKS = 50000U;
/** @brief 周期温度/电压 UART 打印开关。@note 保留 #define:task_manager.cpp #if 使用。 */
#define CONFIG_UART_TEMP_PERIODIC_PRINT 1
/** @brief UART 诊断打印级别。@note 保留 #define:task_runner.cpp #if 使用。 */
#define CONFIG_UART_DIAG_LEVEL 1
/** @brief SPI 命令逐帧日志开关。@note 保留 #define:#if 使用。 */
#define CONFIG_SPI_APP_LOG_ENABLE 0
/** @brief CAN_SEND 成功帧详细日志开关。@note 保留 #define:#if 使用。 */
#define CONFIG_SPI_CAN_SEND_VERBOSE_LOG 0
/* UART/SPI 调试开关:见文件顶部「功能开关」 */
/** @brief FWDGT 独立看门狗预分频值。 */
constexpr uint32_t CONFIG_FWDGT_PSC = FWDGT_PSC_DIV64;
@@ -206,17 +216,8 @@ constexpr uint32_t CONFIG_IRQ_PREEMPT_ETHERCAT_ESC = 1U;
constexpr uint32_t CONFIG_IRQ_PREEMPT_ETHERCAT_SYNC1 = 1U;
constexpr uint32_t CONFIG_IRQ_PREEMPT_SPI_USART = 3U;
/* ============================================================
* 主循环与实时策略
* EtherCAT LAN9252 配置(开关见顶部 CONFIG_MAIN_LOOP_WFI / ETHERCAT_SYNC_MODE)
* ============================================================ */
/** @brief 主循环 WFI 开关。@note 保留 #define:main.cpp #if 使用。 */
#define CONFIG_MAIN_LOOP_WFI_ENABLE 0
/* ============================================================
* EtherCAT LAN9252 使能与配置
* ============================================================ */
/** @brief SYNC0 同步模式。@note 保留 #define:#if 使用。 */
#define CONFIG_ETHERCAT_SYNC_MODE 0
constexpr uint32_t CONFIG_ETHERCAT_ISR_MAX_US_THRESHOLD = 5U;
constexpr uint32_t CONFIG_ESC_PDI_INPUT_OFFSET = 0x1000U;
constexpr uint32_t CONFIG_ESC_PDI_OUTPUT_OFFSET = 0x1200U;
@@ -272,6 +273,10 @@ constexpr uint32_t CONFIG_EXMC_D13_PORT = GPIOD; constexpr uint32_t CONFIG_EXMC
constexpr uint32_t CONFIG_EXMC_D14_PORT = GPIOD; constexpr uint32_t CONFIG_EXMC_D14_PIN = GPIO_PIN_9;
constexpr uint32_t CONFIG_EXMC_D15_PORT = GPIOD; constexpr uint32_t CONFIG_EXMC_D15_PIN = GPIO_PIN_10;
constexpr uint32_t CONFIG_EXMC_A16_PORT = GPIOD; constexpr uint32_t CONFIG_EXMC_A16_PIN = GPIO_PIN_11;
/* A17 (PD12) 用于 HBI Indexed Mode 访问 HBI_DATA_0 寄存器,已将 LAN9252 A2 (Pin 29) 接到 PD12。
* 注意 LAN9252 引脚顺序:Pin25=A1, Pin26=A3, Pin27=A4, Pin28=CS, Pin29=A2。
* A2 是 IDX/DATA 选择位,必须接到 PD12 才能访问 DATA 寄存器,EEPROM 烧录功能可用。 */
constexpr uint32_t CONFIG_EXMC_A17_PORT = GPIOD; constexpr uint32_t CONFIG_EXMC_A17_PIN = GPIO_PIN_12;
constexpr uint32_t CONFIG_EXMC_NOE_PORT = GPIOD; constexpr uint32_t CONFIG_EXMC_NOE_PIN = GPIO_PIN_4;
constexpr uint32_t CONFIG_EXMC_NWE_PORT = GPIOD; constexpr uint32_t CONFIG_EXMC_NWE_PIN = GPIO_PIN_5;
constexpr uint32_t CONFIG_EXMC_NE1_PORT = GPIOD; constexpr uint32_t CONFIG_EXMC_NE1_PIN = GPIO_PIN_7;
+25 -2
View File
@@ -212,9 +212,30 @@ void TaskRunner::taskCanRxParse()
* @param[in] 无。
* @param[out] 无。
* @retval 无返回值。
* @note 当前任务:推进 OTA Boot 请求、刷新 CAN 反馈快照、启动反馈推送轮次。
* @note 推进 OTA Boot 请求、刷新 CAN 反馈快照、启动 CAN/ADC 1Hz 推送轮次。
*/
void TaskRunner::taskHeartbeat() { OtaBootRequest::process(); CanFd::refreshFeedbackSnapshot(); canFeedbackStartRound(); }
void TaskRunner::taskHeartbeat()
{
OtaBootRequest::process();
CanFd::refreshFeedbackSnapshot();
canFeedbackStartRound();
/* ADC 调试反馈 1Hz:CONFIG_SPI_ADC_FEEDBACK_ENABLE=0 时为空操作 */
adcFeedbackStartRound();
}
/**
* @brief 拷贝当前 ADC 工程量快照(供 SPI 0xC4 等只读路径)。
* @param[out] out 非空时写入最新 Sample
* @return true 已写入(不保证 sample.valid==1)
*/
bool TaskRunner::copyAdcSample(Adc::Sample *out)
{
if (out == nullptr) {
return false;
}
*out = s_runtime.sample;
return true;
}
/**
* @brief 输出当前温度、电压与 CAN 诊断信息。
@@ -342,6 +363,8 @@ void TaskRunner::runPending()
* 替代 ESP32 主动轮询。非阻塞:上一帧未读走时立即返回。
* 每次主循环迭代调用一次,ESP32 读走一帧后 CS 释放中断唤醒主循环继续推送。 */
canFeedbackPushStep();
/* ADC 调试反馈(0xC4):优先级低于 CAN;ring 忙则跳过。可 config 关闭。 */
adcFeedbackPushStep();
/* 周期路径( SYNC0 ISR preempt=0 )用 s_periodicSeq 序列号通知主循环,
* 不再走 task_flags,避免 BASEPRI 临界区与 preempt=0 的 RMW 竞态。
+9
View File
@@ -1,6 +1,8 @@
#ifndef SYS_TASK_RUNNER_H
#define SYS_TASK_RUNNER_H
#include "device/adc.h"
/**
* @brief 任务执行器。
* @note 负责消费 TaskManager 置位的任务,并驱动各模块完成实际工作。
@@ -25,6 +27,13 @@ public:
*/
static void runPending();
/**
* @brief 拷贝当前 ADC 工程量快照(供 SPI 0xC4 调试反馈等只读路径)。
* @param[out] out 非空时写入最新 Sample。
* @return true 表示 out 已写入(不保证 valid==1,调用方看 sample.valid)。
*/
static bool copyAdcSample(Adc::Sample *out);
private:
struct Runtime;
static Runtime s_runtime;