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
+50 -6
View File
@@ -65,14 +65,51 @@ void Adc::initDma()
}
/**
* @brief 初始化 ADC、DMA 与规则通道扫描配置。
* @brief 带超时等待 ADC_CTL1 指定位清零。
* @param[in] bit ADC_CTL1 位(RSTCLB/CLB)。
* @param[in] timeout_ms 超时毫秒数。
* @retval bool true=位已清零;false=超时(硬件未响应)。
* @note 替代库函数 adc_calibration_enable 内部的无超时死等——
* ADC 硬件异常时库函数会永久挂住 init,且无任何诊断。
*/
static bool waitAdcCtl1BitClear(uint32_t bit, uint32_t timeout_ms)
{
const uint32_t start = SysTickTimer::getMs();
while ((ADC_CTL1(CONFIG_ADC_INSTANCE) & bit) != 0U) {
if ((SysTickTimer::getMs() - start) >= timeout_ms) {
return false;
}
}
return true;
}
/**
* @brief 带超时执行 ADC 校准(RSTCLB → CLB 两段各等清零)。
* @retval uint8_t Adc::InitFault 故障码(0=校准完成;1=RSTCLB 超时;2=CLB 超时)。
*/
static uint8_t runCalibrationWithTimeout()
{
constexpr uint32_t kCalTimeoutMs = 10U; /* 校准实际仅数十 µs,10ms 裕量极大 */
ADC_CTL1(CONFIG_ADC_INSTANCE) |= ADC_CTL1_RSTCLB;
if (!waitAdcCtl1BitClear(ADC_CTL1_RSTCLB, kCalTimeoutMs)) {
return Adc::kFaultCalRstTimeout;
}
ADC_CTL1(CONFIG_ADC_INSTANCE) |= ADC_CTL1_CLB;
if (!waitAdcCtl1BitClear(ADC_CTL1_CLB, kCalTimeoutMs)) {
return Adc::kFaultCalTimeout;
}
return Adc::kFaultOk;
}
/**
* @brief 初始化 ADC、DMA 与规则通道扫描配置,并验证采样链有效。
* @param[in] 无。
* @param[out] 无。
* @retval 无返回值。
* @retval uint8_t Adc::InitFault 故障码(0=校准完成且 VREFINT→VDDA 换算在合理区间)。
* @note 按 `VIN_ADC / TEMP / VREFINT` 三通道顺序启用连续扫描与 DMA 采样。
* 参考 GD32E508 文档要求,内部温度与 VREFINT 通道使用长采样时间,以满足 ts_temp 要求。
*/
void Adc::init()
uint8_t Adc::init()
{
rcu_periph_clock_enable(RCU_ADC0);
rcu_periph_clock_enable(RCU_GPIOA);
@@ -103,10 +140,17 @@ void Adc::init()
adc_enable(CONFIG_ADC_INSTANCE);
SysTickTimer::delayMs(CONFIG_ADC_STABILIZE_DELAY_MS);
adc_calibration_enable(CONFIG_ADC_INSTANCE);
SysTickTimer::delayMs(CONFIG_ADC_STABILIZE_DELAY_MS);
const uint8_t calFault = runCalibrationWithTimeout();
if (calFault != kFaultOk) {
return calFault;
}
adc_software_trigger_enable(CONFIG_ADC_INSTANCE, ADC_REGULAR_CHANNEL);
SysTickTimer::delayMs(1U);
SysTickTimer::delayMs(CONFIG_ADC_STABILIZE_DELAY_MS);
/* 验证采样链:DMA 循环搬运在跑且 VREFINT 换算 VDDA 落在合理区间。
* calculateVdda 对非法 raw/超范围返回 0.0f。 */
const float vdda = calculateVdda(readVrefRaw());
return ((vdda >= kMinValidVdda) && (vdda <= kMaxValidVdda)) ? kFaultOk : kFaultVddaInvalid;
}
/**