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:
@@ -32,36 +32,72 @@ uint8_t EthercatSlave::s_alState = 0U;
|
||||
|
||||
void EthercatSlave::init()
|
||||
{
|
||||
EscLan9252::init();
|
||||
printf("[ECAT][SLAVE] init: begin\r\n");
|
||||
|
||||
if (!EscLan9252::init()) {
|
||||
/* EXMC 总线未就绪:无法继续读芯片 ID 与 AL 状态,统一上报 FAIL。 */
|
||||
s_chipId = 0U;
|
||||
s_alState = 0U;
|
||||
s_escReady = false;
|
||||
printf("[ECAT][SLAVE] init: FAIL, ESC bus not ready\r\n");
|
||||
s_inputWriteIdx = 0U;
|
||||
s_outputReadIdx = 0U;
|
||||
s_periodicSeq = 0U;
|
||||
s_processedSeq = 0U;
|
||||
return;
|
||||
}
|
||||
|
||||
/* 第 1 层调试可观测性:读取芯片 ID 并打印 selfTest 结果 */
|
||||
s_chipId = EscLan9252::readChipId();
|
||||
const bool chipIdOk = (s_chipId == 0x87654321U);
|
||||
printf("[ECAT][SLAVE] chip id=0x%08lX expected=0x%08lX selfTest=%s\r\n",
|
||||
(unsigned long)s_chipId, (unsigned long)0x87654321UL,
|
||||
chipIdOk ? "PASS" : "FAIL");
|
||||
|
||||
/* AL 状态守卫:仅在芯片 ID 匹配时读取 AL 状态(ID 不匹配时 EXMC 可能读回 0/0xFFFF,无意义)。
|
||||
* AL ≥ SAFEOP(0x04) 才认为 SYNC0 可触发;完整 ESC 配置(SM/FMMU/AL Control/SYNC0)需 SSC 集成。 */
|
||||
s_alState = 0U;
|
||||
uint16_t alStatusReg = 0U; /* 0x0130:AL Status(bit0-3=state,bit8-15=AL Status Code) */
|
||||
if (chipIdOk) {
|
||||
s_alState = (uint8_t)(EscLan9252::initOnlyReadReg(0x0130U) & 0x000FU);
|
||||
alStatusReg = EscLan9252::initOnlyReadReg(0x0130U);
|
||||
s_alState = (uint8_t)(alStatusReg & 0x000FU);
|
||||
}
|
||||
const uint8_t alCode = (uint8_t)((alStatusReg >> 8U) & 0xFFU);
|
||||
s_escReady = chipIdOk && (s_alState >= AL_STATE_SAFEOP);
|
||||
|
||||
/* AL 状态码 → 可读字符串(EtherCAT 状态机定义,见 ETG.1000.6)。
|
||||
* 0x01=INIT, 0x02=PREOP, 0x03=BOOT, 0x04=SAFEOP, 0x08=OP。
|
||||
* 本工程 AL_STATE_SAFEOP=0x04 与官方定义一致;守卫 s_alState>=0x04,
|
||||
* 因此 OP(0x08) 也会通过,SAFEOP(0x04) 刚好通过,BOOT/PREOP/INIT 不通过。 */
|
||||
const char *alStateName = "UNKNOWN";
|
||||
switch (s_alState) {
|
||||
case 0x00U: alStateName = "NONE"; break;
|
||||
case 0x01U: alStateName = "INIT"; break;
|
||||
case 0x02U: alStateName = "PREOP"; break;
|
||||
case 0x03U: alStateName = "BOOT"; break;
|
||||
case 0x04U: alStateName = "SAFEOP"; break;
|
||||
case 0x08U: alStateName = "OP"; break;
|
||||
default: break;
|
||||
}
|
||||
/* AL Status Code(寄存器 0x0130 高 8 位):非 0 表示从站进入错误状态
|
||||
* (如 SM Watchdog=0x1B、FMMU 配置错、邮箱协议错),需主站介入。 */
|
||||
|
||||
if (!chipIdOk) {
|
||||
printf("[ECAT] ESC chip id=0x%08lX selfTest=FAIL\r\n", (unsigned long)s_chipId);
|
||||
printf("[ECAT] ESC NOT ready, sync ISR disabled (check EXMC wiring/timing)\r\n");
|
||||
printf("[ECAT][SLAVE] ESC NOT ready, sync ISR disabled (check EXMC wiring/timing)\r\n");
|
||||
} else if (s_alState < AL_STATE_SAFEOP) {
|
||||
printf("[ECAT] ESC chip id=0x%08lX selfTest=PASS, but AL state=0x%02X < SAFEOP(0x%02X)\r\n",
|
||||
(unsigned long)s_chipId, (unsigned)s_alState, (unsigned)AL_STATE_SAFEOP);
|
||||
printf("[ECAT] SYNC0 will not fire, full ESC config requires SSC integration\r\n");
|
||||
printf("[ECAT][SLAVE] chip id PASS, but AL state=0x%02X(%s) < SAFEOP(0x%02X), code=0x%02X\r\n",
|
||||
(unsigned)s_alState, alStateName, (unsigned)AL_STATE_SAFEOP, (unsigned)alCode);
|
||||
printf("[ECAT][SLAVE] SYNC0 will not fire, full ESC config requires SSC integration\r\n");
|
||||
} else {
|
||||
printf("[ECAT] ESC ready, chip id=0x%08lX, AL state=0x%02X\r\n",
|
||||
(unsigned long)s_chipId, (unsigned)s_alState);
|
||||
printf("[ECAT][SLAVE] ESC ready, chip id=0x%08lX, AL state=0x%02X(%s), code=0x%02X\r\n",
|
||||
(unsigned long)s_chipId, (unsigned)s_alState, alStateName, (unsigned)alCode);
|
||||
}
|
||||
|
||||
s_inputWriteIdx = 0U;
|
||||
s_outputReadIdx = 0U;
|
||||
s_periodicSeq = 0U;
|
||||
s_processedSeq = 0U;
|
||||
printf("[ECAT][SLAVE] init: %s\r\n", s_escReady ? "OK" : "FAIL(partial)");
|
||||
}
|
||||
|
||||
__attribute__((section(".ramfunc"), noinline))
|
||||
|
||||
Reference in New Issue
Block a user