Files
cbb 44d407390b 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故障诊断的寄存器偏移和位设置错
2026-09-02 02:38:35 +08:00

121 lines
5.2 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#ifndef SYS_INITIAL_H
#define SYS_INITIAL_H
#include <stdint.h>
#include <stdbool.h>
/**
* @brief 应用初始化器:按固定顺序启动模块,成功位置 1,末尾汇总。
* @note 汇总结果(模块位图 / critical 失败位图 / 复位源 / init 状态)经静态 getter 导出,
* 供 SPI 0xA3 INIT_STATUS 命令与身份块 [15] 上报 ESP32。
*/
class AppInitializer {
public:
/** 启动模块位(成功置 1);与 SPI 0xA3 上报位图共用,改动须同步 ESP32 侧注释 */
enum ModuleBit : uint32_t {
kNvic = 1u << 0,
kSysTick = 1u << 1,
kEsp32Hold = 1u << 2,
kUsart0 = 1u << 3,
kAdc = 1u << 4,
kCanFd = 1u << 5,
kOtaBootReq = 1u << 6,
kAppSpi = 1u << 7,
kTaskManager = 1u << 8,
kScheduler = 1u << 9,
kEthercat = 1u << 10,
kEthercatSync = 1u << 11,
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();
};
#endif /* SYS_INITIAL_H */