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:
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user