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
+37 -2
View File
@@ -8,6 +8,7 @@
*/
#include "comm/esc_exmc_bus.h"
#include "sys/config.h"
#include <stdio.h>
extern "C" {
#include "gd32e50x_rcu.h"
@@ -18,8 +19,13 @@ extern "C" {
/* 内存映射访问宏:基址 + 偏移(按 16-bit 半字对齐,LAN9252 HBI 地址左移 1 位)。 */
#define ESC_EXMC_REG16(offset) (*(volatile uint16_t*)(CONFIG_ESC_EXMC_BASE_ADDR + (offset)))
void EscExmcBus::init()
bool EscExmcBus::s_ok = false;
bool EscExmcBus::init()
{
s_ok = false;
printf("[ECAT][EXMC] init: enable RCU clocks\r\n");
rcu_periph_clock_enable(RCU_GPIOD);
rcu_periph_clock_enable(RCU_GPIOE);
rcu_periph_clock_enable(RCU_AF);
@@ -43,11 +49,14 @@ void EscExmcBus::init()
gpio_init(CONFIG_EXMC_D14_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, CONFIG_EXMC_D14_PIN);
gpio_init(CONFIG_EXMC_D15_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, CONFIG_EXMC_D15_PIN);
/* 控制线:A16 / NOE / NWE / NE1 */
/* 控制线:A16 / A17 / NOE / NWE / NE1
* A17(PD12) 用于 HBI Indexed Mode 访问 HBI_DATA_0,已将 LAN9252 A2 (Pin 29) 接到 PD12。 */
gpio_init(CONFIG_EXMC_A16_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, CONFIG_EXMC_A16_PIN);
gpio_init(CONFIG_EXMC_A17_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, CONFIG_EXMC_A17_PIN);
gpio_init(CONFIG_EXMC_NOE_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, CONFIG_EXMC_NOE_PIN);
gpio_init(CONFIG_EXMC_NWE_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, CONFIG_EXMC_NWE_PIN);
gpio_init(CONFIG_EXMC_NE1_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, CONFIG_EXMC_NE1_PIN);
printf("[ECAT][EXMC] init: GPIO configured (D0-D15/A16/A17/NOE/NWE/NE1)\r\n");
/*
* EXMC NOR/SRAM Region1:16-bit、非复用、异步写。
@@ -88,8 +97,34 @@ void EscExmcBus::init()
wr_timing = rw_timing;
printf("[ECAT][EXMC] init: applying NOR/SRAM Region1 params (16b, async, t_data=%u HCLK)\r\n",
(unsigned)rw_timing.asyn_data_setuptime);
exmc_norsram_init(&norsram_init);
exmc_norsram_enable(CONFIG_ESC_EXMC_BANK_NOR_SRAM_REGION1);
/* 总线探活:Region1 使能后立即读取 LAN9252 芯片 ID 低半字(期望 0x4321)。
* 0x0000/0xFFFF 通常意味着 EXMC 时序不满足、地址线接错或 ESC 未上电;
* 此处仅做总线可见性探活,芯片 ID 完整性校验留给 EscLan9252::init()。 */
const uint16_t probe_low = read16((uint32_t)0x0000U << 1U);
const uint16_t probe_high = read16((uint32_t)0x0002U << 1U);
const uint32_t probe_id = ((uint32_t)probe_high << 16) | probe_low;
printf("[ECAT][EXMC] init: Region1 enabled, probe id_lo=0x%04X id_hi=0x%04X (id=0x%08lX)\r\n",
(unsigned)probe_low, (unsigned)probe_high, (unsigned long)probe_id);
/* 总线挂死(全 0/全 1)视为 EXMC 未就绪;chip ID 完整校验在 EscLan9252::init()。 */
if (probe_low == 0x0000U && probe_high == 0x0000U) {
printf("[ECAT][EXMC] init: FAIL, bus reads all-zero (check wiring/NE1/A16/timing)\r\n");
return false;
}
if (probe_low == 0xFFFFU && probe_high == 0xFFFFU) {
printf("[ECAT][EXMC] init: FAIL, bus reads all-ones (check ESC power/NOE/NWE)\r\n");
return false;
}
s_ok = true;
printf("[ECAT][EXMC] init: OK, bus visible\r\n");
return true;
}
__attribute__((section(".ramfunc"), noinline))