feat(comm): 添加EtherCAT CAN桥接和PDO功能模块

添加了ethercat_can_bridge.h/cpp和ethercat_pdo.h/cpp四个文件,
扩展通信模块功能,支持CAN桥接和PDO相关操作。

fix(comm): 修复LAN9252 EXMC总线时序配置问题

将BUSLAT从1调整为4,确保满足数据手册要求的最小13ns间隔,
解决因时序余量不足导致的温漂偶发读错问题。

feat(comm): 配置ESC过程数据看门狗时间为1秒

修改ESC_REG_WD_TIME_PD寄存器值从默认100ms到1s,
防止主站调试周期触发SM2看门狗导致状态被拖回SAFEOP。
This commit is contained in:
cbb
2026-09-05 16:54:38 +08:00
parent 44d407390b
commit f9ef1b8da2
16 changed files with 2218 additions and 86 deletions
+37 -4
View File
@@ -198,11 +198,22 @@ bool EscExmcBus::init() {
/* 读/写共用时序(非 extended mode)
* 2026-08-20 慢档测试(16/16/256 HCLK)无效,已还原:慢档时序未带来任何
* 读数变化,速度因素彻底排除(与 bit-bang 40-80us 仍失败一致)。 */
* 读数变化,速度因素彻底排除(与 bit-bang 40-80us 仍失败一致)。
* 注:那轮测试的失败根因是访问模型错误(直读核心 CSR 索引空间,1.5.39 修复),
* 与时序无关;时序余量本身仍需按 DS 表 9-4/9-5 独立核算,见下方 BUSLAT。 */
rw_timing.asyn_access_mode = EXMC_ACCESS_MODE_A;
rw_timing.syn_data_latency = EXMC_DATALAT_2_CLK;
rw_timing.syn_clk_division = EXMC_SYN_CLOCK_RATIO_DISABLE;
rw_timing.bus_latency = 1U;
/* BUSLAT: 1→4 (1.5.57)。DS 表 9-4/9-5 要求 trdrd/twrwr/twrrd ≥ 13ns,
* 该间隔由 EXMC 在两次访问之间插入的总线空闲期承担 = (1 固有 + BUSLAT) HCLK。
* BUSLAT=1 → 2 HCLK ≈ 11.1ns,低于 13ns 下限,仅靠 AHB 取指间隙偶然兜底:
* 常温刚好可用,温度升高(传播延迟增大)/电压下降(驱动减弱)即越界,表现为
* 偶发读到 0xFFFF 或错值——与实测的温漂偶发读错吻合。
* BUSLAT=4 → 5 HCLK ≈ 27.8ns,余量 2.1 倍,覆盖全温区与电压波动。
* 代价:每次 HBI 访问多 3 HCLK(16.7ns)。满载 1024B 过程数据按每 DWORD
* 两次 16-bit 访问计,增加约 256×2×16.7ns ≈ 8.6us,相对原 218us 增幅 3.9%,
* 4ms 周期占用从 5.4% 升至 5.7%,无实质影响。 */
rw_timing.bus_latency = 4U;
rw_timing.asyn_address_setuptime = 4U; /* ~22ns。DS 表9-4/9-5: trdrd/twrwr/twrrd
≥13ns——选通间隔=ADDSET 相,2 HCLK≈11.1ns
不达标(仅靠 AHB 间隙兜底),4 HCLK 稳过 */
@@ -212,8 +223,11 @@ bool EscExmcBus::init() {
wr_timing = rw_timing;
ECAT_LOGI("[ECAT][EXMC] init: applying NOR/SRAM Region0 params (16b, async, "
"t_data=%u HCLK)\r\n",
(unsigned)rw_timing.asyn_data_setuptime);
"ADDSET=%u AHLD=%u DSET=%u BUSLAT=%u HCLK)\r\n",
(unsigned)rw_timing.asyn_address_setuptime,
(unsigned)rw_timing.asyn_address_holdtime,
(unsigned)rw_timing.asyn_data_setuptime,
(unsigned)rw_timing.bus_latency);
exmc_norsram_init(&norsram_init);
exmc_norsram_enable(CONFIG_ESC_EXMC_BANK_NOR_SRAM_REGION0);
@@ -229,6 +243,25 @@ bool EscExmcBus::init() {
ECAT_LOGI("[ECAT][EXMC] init: SNCTL0 fix: before=0x%08lX after=0x%08lX (bit7 reserved cleared)\r\n",
(unsigned long)snctl_before, (unsigned long)snctl_after);
/* 时序寄存器实测回读:确认写入的 BUSLAT 真正落到硬件(1.5.57)。
* SNTCFG0 位域: [3:0]=ASET-1 [7:4]=AHLD-1 [15:8]=DSET-1 [19:16]=BUSLAT-1。
* 期望 ASET=4/AHLD=2/DSET=20/BUSLAT=4 → 0x0313_0000|... 逐字段解码打印,
* 避免只看整字导致的位域误读;BUSLAT 实际值 <4 说明库或硬件截断,须立即排查。 */
{
const uint32_t tcfg = EXMC_SNTCFG0;
const unsigned aset = (unsigned)((tcfg & EXMC_SNTCFG_ASET) >> 0) + 1U;
const unsigned ahld = (unsigned)((tcfg & EXMC_SNTCFG_AHLD) >> 4) + 1U;
const unsigned dset = (unsigned)((tcfg & EXMC_SNTCFG_DSET) >> 8) + 1U;
const unsigned buslat = (unsigned)((tcfg & EXMC_SNTCFG_BUSLAT) >> 16) + 1U;
ECAT_LOGI("[ECAT][EXMC] init: SNTCFG0=0x%08lX -> ASET=%u AHLD=%u DSET=%u BUSLAT=%u\r\n",
(unsigned long)tcfg, aset, ahld, dset, buslat);
/* 5 HCLK @180MHz = 27.8ns,DS trdrd 下限 13ns → 需 BUSLAT>=2 才达标,取 4 留余量 */
if (buslat < 4U) {
ECAT_LOGI("[ECAT][EXMC] WARN: BUSLAT=%u < 4, trdrd 余量不足,"
" 温漂/压降时会偶发读到 0xFFFF 或错值\r\n", buslat);
}
}
/* 总线探活:LAN9252 处于 16-bit HBI Indexed Mode,无法通过固定偏移直接读取。
* 真实的芯片 ID / AL 状态校验由 EscLan9252::init() 通过 HBI_IDX_0/HBI_DATA_0
* 间接访问完成。 注意:LAN9252 上电后第一次 Host Bus