Files
DCU_APP/GD32E508_DCU_APP/device/Timer.cpp
T
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

109 lines
3.7 KiB
C++
Raw 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.
/**
* @file timer.cpp
* @brief 用户调度定时器模块实现。
*/
#include "main.h"
#include "device/timer.h"
#include "sys/task_manager.h"
#include "sys/systick.h"
#include "sys/config.h"
/**
* @brief 配置用户调度定时器本体参数。
* @param[in] 无。
* @param[out] 无。
* @retval 无返回值。
* @note 使用 `CONFIG_SCHED_TIMER_*` 系列配置完成 TIMER2 的 100us 调度时基初始化。
*/
void SchedulerTimer::configureTimer()
{
timer_parameter_struct timer_initpara;
rcu_periph_clock_enable(CONFIG_SCHED_TIMER_RCU);
timer_deinit(CONFIG_SCHED_TIMER_INSTANCE);
timer_struct_para_init(&timer_initpara);
timer_initpara.prescaler = CONFIG_SCHED_TIMER_PRESCALER;
timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
timer_initpara.counterdirection = TIMER_COUNTER_UP;
timer_initpara.period = CONFIG_SCHED_TIMER_PERIOD;
timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
timer_init(CONFIG_SCHED_TIMER_INSTANCE, &timer_initpara);
timer_interrupt_flag_clear(CONFIG_SCHED_TIMER_INSTANCE, TIMER_INT_FLAG_UP);
timer_interrupt_enable(CONFIG_SCHED_TIMER_INSTANCE, TIMER_INT_UP);
timer_enable(CONFIG_SCHED_TIMER_INSTANCE);
}
/**
* @brief 配置用户调度定时器对应的 NVIC。
* @param[in] 无。
* @param[out] 无。
* @retval 无返回值。
* @note 优先级分组已前移至 AppInitializer::init() 最开头统一设置;此处仅为调度定时器中断向量配置抢占优先级与子优先级。
*/
void SchedulerTimer::configureNvic()
{
nvic_irq_enable(CONFIG_SCHED_TIMER_IRQn, CONFIG_SCHED_TIMER_IRQ_PREEMPT_PRIO, CONFIG_SCHED_TIMER_IRQ_SUB_PRIO);
}
/**
* @brief 初始化用户调度定时器模块并验证节拍运行。
* @param[in] 无。
* @param[out] 无。
* @retval uint8_t SchedulerTimer::InitFault 故障码(0=回读一致且 tick_100us 已前进)。
* @note 依次完成定时器本体配置与 NVIC 中断配置;
* 验证覆盖"中断向量/优先级配错导致调度器静默停摆"这类纯写配置发现不了的故障。
*/
uint8_t SchedulerTimer::init()
{
configureTimer();
configureNvic();
/* 回读:计数器已使能、PSC/CAR 与配置一致 */
if ((TIMER_CTL0(CONFIG_SCHED_TIMER_INSTANCE) & TIMER_CTL0_CEN) == 0U) {
return kFaultNotEnabled;
}
if (TIMER_PSC(CONFIG_SCHED_TIMER_INSTANCE) != CONFIG_SCHED_TIMER_PRESCALER) {
return kFaultPscMismatch;
}
if (TIMER_CAR(CONFIG_SCHED_TIMER_INSTANCE) != CONFIG_SCHED_TIMER_PERIOD) {
return kFaultCarMismatch;
}
/* 有界等待 100us 中断节拍前进(50ms 预算 = 500 个 tick) */
const uint32_t start = g_scheduler.tick_100us;
const uint32_t deadline = SysTickTimer::getMs() + 50U;
while (g_scheduler.tick_100us == start) {
if ((int32_t)(SysTickTimer::getMs() - deadline) >= 0) {
return kFaultNoTick;
}
}
return kFaultOk;
}
/**
* @brief 用户调度定时器中断处理入口。
* @param[in] 无。
* @param[out] 无。
* @retval 无返回值。
* @note 响应更新中断,清除中断标志后推进一次 `TaskManager::tick100us()`。
*/
void SchedulerTimer::onInterrupt()
{
if(timer_interrupt_flag_get(CONFIG_SCHED_TIMER_INSTANCE, TIMER_INT_FLAG_UP) == RESET) return;
timer_interrupt_flag_clear(CONFIG_SCHED_TIMER_INSTANCE, TIMER_INT_FLAG_UP);
TaskManager::tick100us();
}
/* ----- 中断入口 C 包装 ---------------------------------------------- */
/**
* @brief TIMER2 中断向量入口。
* @param[in] 无。
* @param[out] 无。
* @retval 无返回值。
* @note C 向量包装函数,内部转调 `SchedulerTimer::onInterrupt()`。
*/
extern "C" void TIMER2_IRQHandler(void) { SchedulerTimer::onInterrupt(); }