fix(esc_lan9252): 修复LAN9252 HBI访问模型和IRQ输出使能问题

- 修正HBI访问模型:将ESC核心CSR(0x0000-0x0FFF)改为通过ECAT_CSR_CMD/DATA
  间接端口访问,解决此前直接寻址导致核心寄存器恒读0/写丢弃的问题

- 新增csrRead/csrWrite/pramRead/pramWrite接口,正确实现LAN9252访问端口操作

- 添加PDI就绪检测:等待DL_STATUS bit0置位确认EEPROM加载完成和EtherCAT核心使能

- 实现IRQ引脚输出使能:配置IRQ_CFG和INT_EN寄存器,使EtherCAT事件能到达PB1,
  解决PDI_Isr未触发导致SAFEOP->OP无限挂起的问题

- 为ESC_EXMC硬件诊断添加CONFIG_ESC_EXMC_DIAG门控,默认关闭避免影响正常运行

- 修正system_gd32e50x.c中HXTAL故障诊断的寄存器偏移和位设置错
This commit is contained in:
cbb
2026-09-02 02:38:35 +08:00
parent cfe7725b26
commit 44d407390b
29 changed files with 1178 additions and 292 deletions
+80 -1
View File
@@ -6,10 +6,12 @@
/**
* @brief 应用初始化器:按固定顺序启动模块,成功位置 1,末尾汇总。
* @note 汇总结果(模块位图 / critical 失败位图 / 复位源 / init 状态)经静态 getter 导出,
* 供 SPI 0xA3 INIT_STATUS 命令与身份块 [15] 上报 ESP32。
*/
class AppInitializer {
public:
/** 启动模块位(成功置 1) */
/** 启动模块位(成功置 1);与 SPI 0xA3 上报位图共用,改动须同步 ESP32 侧注释 */
enum ModuleBit : uint32_t {
kNvic = 1u << 0,
kSysTick = 1u << 1,
@@ -26,15 +28,92 @@ public:
kWatchdog = 1u << 12,
};
/** init 总体状态(身份块 [15] 与 0xA3 payload[9] 共用编码) */
enum InitState : uint8_t {
kInitOk = 0U, /**< 全部模块成功 */
kInitDegraded = 1U, /**< critical 全成功,非 critical 有失败/跳过 */
kInitCriticalFail = 2U, /**< 有 critical 模块失败 */
};
/** 复位源位图(0xA3 payload[8] 编码),多位置位属正常(如 POR 常伴随其它标志) */
enum ResetCauseBit : uint8_t {
kRstPor = 1u << 0, /**< 上电/掉电复位 */
kRstEpr = 1u << 1, /**< 外部引脚复位(NRST) */
kRstFwdgt = 1u << 2, /**< 独立看门狗复位 */
kRstWwdgt = 1u << 3, /**< 窗口看门狗复位 */
kRstSw = 1u << 4, /**< 软件复位(含 OTA 跳转) */
kRstLp = 1u << 5, /**< 低功耗复位 */
};
/** 模块数量(fault code 数组长度,与 ModuleBit 位序一致:bit N → 索引 N) */
static constexpr uint8_t kModuleCount = 13U;
/**
* @brief 模块故障码(0xA3 payload[12..24],每模块 1B,0=成功)。
*
* 各模块码值定义位置:
* - nvic : kFaultNvic*(本类下)
* - systick : kFaultSystick*(本类下;实际失败时 FATAL 停机不上报,仅备查)
* - esp32_hold : kFaultEsp32Hold*(本类下)
* - usart0 : Usart0::InitFault(device/usart0.h)
* - adc : Adc::InitFault(device/adc.h)
* - canfd : CanFd::SelfTestFault(device/canfd.h),
* **编码 = 原因码 | (首个失败通道号 << 4)**,通道 0/1/2
* - ota_boot_req: 纯软件,恒 0
* - app_spi : 无自证手段,恒 0
* - task_manager: 纯软件,恒 0
* - scheduler : SchedulerTimer::InitFault(device/timer.h)
* - ethercat : kFaultEthercat*(本类下)
* - ethercat_sync: 跟随 ethercat,恒 0
* - watchdog : Watchdog::InitFault(device/watchdog.h)
*/
enum NvicFault : uint8_t {
kFaultNvicOk = 0U,
kFaultNvicPrigroupMismatch = 1U, /**< AIRCR.PRIGROUP 回读与配置不一致 */
};
enum SystickFault : uint8_t {
kFaultSystickOk = 0U,
kFaultSystickConfig = 1U, /**< SysTick_Config 失败(备查,实际 FATAL 停机) */
kFaultSystickNoTick = 2U, /**< 节拍未前进(备查,实际 FATAL 停机) */
};
enum Esp32HoldFault : uint8_t {
kFaultEsp32HoldOk = 0U,
kFaultEsp32HoldClamped = 1U, /**< PC9 输出高后回读仍为 0(被外部钳低) */
};
enum EthercatFault : uint8_t {
kFaultEthercatOk = 0U,
kFaultEthercatBusNotReady = 1U, /**< EXMC/HBI 总线探活失败(BYTE_TEST 未通过) */
kFaultEthercatSscFail = 2U, /**< SSC MainInit 返回非 0 */
kFaultEthercatCoreNotReady = 3U, /**< EEPROM 未加载完成,EtherCAT 核心未使能(1.5.39) */
};
/**
* @brief 按固定顺序完成模块初始化(过程只置位,结束统一报告成败/失败模块)。
*/
static void init();
/** @brief 已成功初始化的模块位图。 */
static uint32_t moduleMask() { return s_mask; }
/** @brief 初始化失败的 critical 模块位图(0=无 critical 失败)。 */
static uint32_t criticalFailMask();
/** @brief init 总体状态(InitState 编码)。 */
static uint8_t initState() { return s_initState; }
/** @brief 本次上电复位源位图(ResetCauseBit 编码,init 开头采集并已清硬件标志)。 */
static uint8_t resetCause() { return s_resetCause; }
/** @brief 指定模块(ModuleBit 位序索引 0..12)的故障码,0=成功。 */
static uint8_t faultCode(uint8_t module_index);
/** @brief 将全部模块故障码拷贝到 out(至少 kModuleCount 字节),返回长度。 */
static uint8_t faultCodes(uint8_t *out);
private:
static uint32_t s_mask;
static uint8_t s_initState;
static uint8_t s_resetCause;
static uint8_t s_faultCodes[kModuleCount];
static void mark(ModuleBit b);
static void setFault(ModuleBit b, uint8_t code);
static void captureResetCause();
static void report();
};