变更点: 1. CAN-FD(device/CANFD.cpp、sys/config.h) - 发送统一 FD+BRS(DLC≤8 不再回退经典 CAN);OTA 期仍按通道压制 BRS - 空通道自动识别:连续 5 个 1Hz 窗口无有效帧且有错误 → 静默上报;有帧即恢复 - 三路 CAN 默认全开;RX parse budget 48→64 2. EtherCAT 桥 / PDO - 段1 增 txtxid/rx00ff;版本应答 0x00FF 粘滞发布,避免被 CONFIG 冲掉 - STATUS 禁止写入 xrx 快照;processSeq 新鲜度救援 3. OTA / 配置 - sys/config.h include 仓库内 shared/ota_layout.h(与 BOOT 共用,不再依赖仓外路径) - ota_boot_request 对齐配置页 word 布局 4. docs/audit_ecat_spi_wifi_ota_compatibility.md:ECAT/SPI/WiFi/OTA 兼容性审计 5. .gitignore:忽略 .trae/、docs/traework-import、评审过程稿
135 lines
8.3 KiB
C++
135 lines
8.3 KiB
C++
/**
|
|
* @file esc_lan9252.h
|
|
* @brief LAN9252 EtherCAT 从站控制器(ESC)驱动接口。
|
|
* @note 通过 EscExmcBus 16-bit 并行总线,以 HBI Indexed Address Mode 访问 LAN9252。
|
|
* 访问模型(DS 12.11):
|
|
* - HBI 直接地址空间:仅 LAN9252 系统 CSR(BYTE_TEST 0x064 等)+ 访问端口
|
|
* (PRAM FIFO 0x000-0x03C、ECAT_CSR_DATA/CMD 0x300/0x304、PRAM_ADDR_LEN/CMD
|
|
* 0x308-0x314)——经 HBI_IDX_0/HBI_DATA_0 直接读写;
|
|
* - EtherCAT 核心 CSR(0x0000-0x0FFF:AL Status、SyncManager、EEPROM 接口等)
|
|
* 不在直接空间,必须经 ECAT_CSR_CMD/CSR_DATA 间接访问(csrRead/csrWrite);
|
|
* - 过程 RAM(0x1000-0x1FFF:邮箱/PDO)必须经 PRAM FIFO(pramRead/pramWrite)。
|
|
*
|
|
* 接口调用约束(避免 EXMC 总线争用):
|
|
* - 运行期 ESC 寄存器/PDI 访问统一走 SSC 移植层 hw_gd32exmc.cpp 的 HW 系列函数
|
|
* (主循环路径带 HBI 互斥守卫,ISR 路径由 ethercat_sync.cpp 包装器保证互斥)。
|
|
* - initOnly 系列:INIT-ONLY,仅允许在 EthercatSync::init() 使能 EXTI NVIC 之前调用
|
|
* (如 EthercatSlave::init 的芯片 ID/AL 状态探针)。
|
|
*/
|
|
#ifndef COMM_ESC_LAN9252_H
|
|
#define COMM_ESC_LAN9252_H
|
|
|
|
#include <cstdint>
|
|
#include <cstddef>
|
|
|
|
/**
|
|
* @brief LAN9252 ESC 驱动。
|
|
* @note 封装 ESC 寄存器读写与 PDI(Process Data Interface)内存块访问。
|
|
*/
|
|
class EscLan9252 {
|
|
public:
|
|
/** @brief 初始化 EXMC 总线与 ESC 基本寄存器。
|
|
* @note 内部先执行一次 hardwareReset() 受控复位(s_resetDone 门控,
|
|
* 重复调用不会二次复位 SSC 已配置好的芯片),再探活 EXMC/HBI。
|
|
* @return bool true 表示 EXMC 总线探活通过(可继续读取芯片 ID)。 */
|
|
static bool init();
|
|
|
|
/** @brief INIT-ONLY:ECAT_NRST(PB10)受控复位序列(拉低 CONFIG_ESC_NRST_ASSERT_MS 后释放)。
|
|
* @note 满足 LAN9252 手册 18.6.3 tpurstd≥25ms/trstia≥200µs;RST# 释放瞬间
|
|
* 重锁 CHIP_MODE strap。运行期调用会打断 EtherCAT 通信,仅供 init/诊断用。 */
|
|
static void hardwareReset();
|
|
|
|
/** @brief 诊断:手动控制/回读 ECAT_NRST(PB10)实际电平(SPI 0xA2 action 20+ 转发到此)。
|
|
* @param action 0=恢复自动态(推挽输出高) 1=持续拉低 2=持续拉高 3=浮空输入(交给 R44) 4=只读回
|
|
* @return 实际引脚电平 0/1(GD32 输入通路常连引脚,输出态亦读真实电压);0xEE=无效 action。
|
|
* 判读:action 1→2 切换后引脚电平不变 => 网络被外部短路或驱动器损伤;
|
|
* 驱动高读回低 => ECAT_NRST 被按死在复位,LAS9252 永在复位态。 */
|
|
static uint8_t nrstDrive(uint8_t action);
|
|
|
|
/** @brief 诊断:LAN9252 芯片级电源管理(休眠/唤醒,SPI 0xA2 action 30+ 转发到此)。
|
|
* @param op 0=读状态 1=进 D1 2=进 D2 3=进 D3(先两 PHY General Power Down) 4=手动唤醒
|
|
* @return 打包状态字节 bit0=READY bit1=PM_SLEEP_EN bit3:2=PM_MODE;
|
|
* 唤醒 op 另有 1=成功 0=超时;0xEE=无效 op;0xE1=HBI 总线未就绪。
|
|
* @note DS 6.3:PMT_CTRL(0x084) PM_MODE[31:29] 选档 + PM_SLEEP_EN(bit28) 进入,
|
|
* 两字段必须分两次写。D1/D2/D3 下主机接口停摆、EtherCAT 通信中断(主站
|
|
* wkc 报错),唤醒后 PM_MODE/PM_SLEEP_EN 自清、寄存器配置保留、READY 回高
|
|
* (正常 ≤2ms)。D3 最深(晶振/PLL 全关)且手册要求先置两 PHY BMCR.PowerDown
|
|
* (经 ESC 核心 MII 管理 0x0510 间接访问,PHY A 地址模式相关 0/2 运行期判定),
|
|
* 唤醒后本函数自动恢复 PHY 上电,链路重新自协商需数秒。 */
|
|
static uint8_t pmDrive(uint8_t op);
|
|
|
|
/**
|
|
* @brief 读取 ESC 芯片 ID(INIT-ONLY,供 init 打印诊断用)。
|
|
* @return uint32_t 32-bit 芯片 ID(期望值 0x87654321)。
|
|
*/
|
|
static uint32_t readChipId();
|
|
|
|
/** @brief INIT-ONLY:仅允许在 EthercatSync::init() 使能 EXTI NVIC 之前调用;运行期禁止调用,需 ESC 寄存器访问须通过 SSC 移植层(HW_*)。
|
|
* @note 经 CSR_CMD/CSR_DATA 间接端口读 ESC 核心 CSR
|
|
* (EtherCAT 核心寄存器不在 HBI 直接地址空间,直读恒 0)。 */
|
|
static uint16_t initOnlyReadReg(uint16_t addr);
|
|
|
|
/** @brief INIT-ONLY:仅允许在 EthercatSync::init() 使能 EXTI NVIC 之前调用;运行期禁止调用。 */
|
|
static void initOnlyWriteReg(uint16_t addr, uint16_t v);
|
|
|
|
/** @brief ESC 核心 CSR 间接读(ECAT_CSR_CMD/DATA 端口,0x0000-0x0FFF 地址空间)。
|
|
* @note LAN9252 的 HBI/SPI 直接地址空间只有 LAN9252 系统 CSR 与访问端口
|
|
* (DS 12.11/表 12-13),EtherCAT 核心寄存器(0x0000-0x0FFF)必须经
|
|
* CSR_CMD(0x304)/CSR_DATA(0x300) 间接访问;过程 RAM(0x1000-0x1FFF)
|
|
* 必须经 PRAM FIFO。size=1/2/4(size2 需偶地址,size4 需 4 字节对齐)。
|
|
* 调用方负责 HBI 互斥(主循环 EscExmcBus::maskEnter / 已在 ISR 上下文)。
|
|
* @param verify true(默认)=双读比对+不一致重试(防 EXMC 毛刺,SM/AL/邮箱
|
|
* 等关键路径必须开);false=单读(诊断回读/MII busy 轮询/init 等低风险路径,
|
|
* 省约一半 CSR 间接访问)。 */
|
|
static uint32_t csrRead(uint16_t addr, uint8_t size, bool verify = true);
|
|
|
|
/** @brief ESC 核心 CSR 间接写(ECAT_CSR_CMD/DATA 端口)。约束同 csrRead。 */
|
|
static void csrWrite(uint16_t addr, uint32_t data, uint8_t size);
|
|
|
|
/** @brief 过程 RAM(0x1000-0x1FFF)经 PRAM 读 FIFO 读取 len 字节到 buf。 */
|
|
static void pramRead(uint16_t addr, uint8_t *buf, uint16_t len);
|
|
|
|
/** @brief 过程 RAM(0x1000-0x1FFF)经 PRAM 写 FIFO 写入 len 字节。 */
|
|
static void pramWrite(uint16_t addr, const uint8_t *buf, uint16_t len);
|
|
|
|
/** @brief EXMC 总线 + BYTE_TEST 往返探针通过(init 成功)后为 true。
|
|
* @note HBI_IDX_0 复位默认值仅作诊断读数,不参与放行
|
|
* (它只证明"芯片刚出过复位",证明不了 HBI 通路)。
|
|
* 与 init() 返回值一致,可作运行期查询。 */
|
|
static bool isBusReady() { return s_busReady; }
|
|
|
|
/** @brief EEPROM(SII) 加载完成、EtherCAT 核心使能。
|
|
* @note false 时核心寄存器对 PDI 读全 0、写静默丢弃,SSC MainInit 会全部
|
|
* 落空(AL Event Mask/邮箱 SM 配置写不进),调用方必须跳过 SSC 初始化。 */
|
|
static bool isCoreReady() { return s_coreReady; }
|
|
|
|
/** @brief ESC 已被 pmDrive 置入 D1-D3 睡眠、所有 HBI 消费者必须静默。
|
|
* @note 睡眠中任何 HBI 访问(含读)都会把芯片打回 D0。置位期间
|
|
* task_runner 停调 MainLoop()/AL 守护/AL 心跳,ethercat_sync 三个 EXTI
|
|
* ISR 清 pending 后直接返回——否则芯片进入睡眠后毫秒级就被主循环的
|
|
* ECAT_Main(读 0x220)叫醒,根本睡不住。
|
|
* 解除:pmDrive 唤醒/读到 D0、nrstDrive 释放复位、hardwareReset。
|
|
* ISR 上下文安全:读一个 bool 静态成员,无锁。 */
|
|
static bool pmSuspended() { return s_pmSuspended; }
|
|
|
|
private:
|
|
/** @brief 使能 LAN9252 的 IRQ 引脚输出(IRQ_CFG 0x054 / INT_EN 0x05C)。
|
|
* @note 由 init() 在 PDI/核心就绪后调用。两寄存器复位默认全 0,
|
|
* 不配则 EtherCAT 事件永不到达 PB1、SSC 的 PDI_Isr 从不执行,
|
|
* SAFEOP->OP 被无限挂起。 */
|
|
static void enableEcatIrqOutput();
|
|
|
|
/** @brief 过程数据看门狗 100ms(复位默认)→1s。
|
|
* @note 由 init() 在 PDI/核心就绪后调用。写 ESC_REG_WD_TIME_PD(0x0420)=10000
|
|
* (100µs 分频保持默认)。不写则主站 100ms 手动调试周期触发 SM2 看门狗,
|
|
* SSC 以 0x001B 拖回 SAFEOP。 */
|
|
static void configPdWatchdog();
|
|
|
|
static bool s_busReady; /**< init 成功(EXMC+BYTE_TEST 往返;IDX 残值不挡)后置位。 */
|
|
static bool s_coreReady; /**< EEPROM 加载完成、EtherCAT 核心使能后置位。 */
|
|
static bool s_resetDone; /**< hardwareReset 已执行门控(防二次复位清掉 SSC 配置)。 */
|
|
static bool s_pmPhyDown; /**< pmDrive 进 D3 时两 PHY 已被置 PowerDown,唤醒后需恢复。 */
|
|
static bool s_pmSuspended; /**< ESC 睡眠挂起:置位期间全固件 HBI 消费者静默(见 pmSuspended)。 */
|
|
};
|
|
|
|
#endif /* COMM_ESC_LAN9252_H */ |