Files
DCU_APP/GD32E508_DCU_APP/sys/systick.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

97 lines
3.4 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 systick.cpp
* @brief SysTick 时基模块实现。
*/
#include "main.h"
#include "sys/systick.h"
volatile uint32_t SysTickTimer::s_ms = 0U;
/**
* @brief SysTick 中断处理入口。
* @param[in] 无。
* @param[out] 无。
* @retval 无返回值。
* @note 每次 SysTick 中断到来时,将毫秒计数器自增 1。
*/
void SysTickTimer::onInterrupt()
{
s_ms++;
}
/**
* @brief 执行毫秒级阻塞延时。
* @param[in] ms 需要延时的毫秒数。
* @param[out] 无。
* @retval 无返回值。
* @note 基于 SysTick 维护的毫秒计数器忙等,适用于短时初始化等待。
*/
void SysTickTimer::delayMs(uint32_t ms)
{
uint32_t start = s_ms;
while((s_ms - start) < ms) { }
}
/**
* @brief SysTick 失效时的致命停机:裸寄存器 USART0(PA9) 输出 FATAL 后挂死。
* @param[in] 无。
* @param[out] 无。
* @retval 无返回值(不返回)。
* @note 此时 USART0 驱动尚未初始化,只能裸写寄存器;
* 时钟树已是 180MHz(SystemInit 完成),BAUD=60 对应 3M(与工程 printf 一致)。
* 注意 system_gd32e50x.c 的 HXTAL FAIL 段有寄存器 bug(CTL0 写到 STAT0 偏移、
* 漏开 USART0EN),本段使用修正后的地址:APB2EN bit14=USART0EN、CTL0 @ +0x0C。
*/
static void fatalSystickHalt()
{
*((volatile uint32_t *)0x40021018U) |= (1U << 14) | (1U << 2) | (1U << 0); /* USART0EN|PAEN|AFEN */
{ volatile uint32_t _ctl = *((volatile uint32_t *)0x40010804U); /* PA9 → AF_PP */
_ctl &= ~(0xFU << 4); _ctl |= (0xBU << 4);
*((volatile uint32_t *)0x40010804U) = _ctl; }
*((volatile uint32_t *)0x40013808U) = 60U; /* BAUD: 180MHz/3M */
*((volatile uint32_t *)0x4001380CU) = (1U << 3) | (1U << 13); /* CTL0: TEN | UEN */
{ const char *_msg = "[APP] init: FATAL systick\r\n";
for(int i=0; _msg[i]; i++){
*((volatile uint32_t *)0x40013804U) = _msg[i]; /* DATA */
while((*((volatile uint32_t *)0x40013800U) & (1U << 7)) == 0U) {} } } /* STAT0.TBE */
while(1){ }
}
/**
* @brief 初始化 1ms SysTick 时基并验证中断真实触发。
* @param[in] 无。
* @param[out] 无。
* @retval bool true=节拍已前进;false=配置失败(不返回,直接 FATAL 停机)。
* @note 先更新 `SystemCoreClock`,再按 1kHz 频率配置 SysTick。
* 节拍验证失败时系统失去一切超时/延时基础,继续运行等于盲跑,
* 按致命错误处理(裸串口报告 + 挂死,与 HXTAL FAIL 同级)。
*/
bool SysTickTimer::initMs()
{
SystemCoreClockUpdate();
if (SysTick_Config(SystemCoreClock / 1000U) != 0U) {
fatalSystickHalt();
}
/* 有界等待节拍前进:guard 预算约 50ms+,覆盖 1ms 节拍;
* 若无界等待,中断未触发时此处即死循环且无任何诊断。 */
const uint32_t start = s_ms;
volatile uint32_t guard = 2000000U;
while (s_ms == start) {
if (--guard == 0U) {
fatalSystickHalt();
}
}
return true;
}
/* ----- 中断入口 C 包装 ---------------------------------------------- */
/**
* @brief SysTick 中断向量入口。
* @param[in] 无。
* @param[out] 无。
* @retval 无返回值。
* @note C 向量包装函数,内部转调 `SysTickTimer::onInterrupt()`。
*/
extern "C" void SysTick_Handler(void) { SysTickTimer::onInterrupt(); }