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:
@@ -11,6 +11,7 @@
|
||||
uint8_t Usart0::s_txBuf[Usart0::kTxBufSize];
|
||||
volatile uint16_t Usart0::s_txHead = 0U;
|
||||
volatile uint16_t Usart0::s_txTail = 0U;
|
||||
volatile uint32_t Usart0::s_txDropped = 0U;
|
||||
|
||||
/**
|
||||
* @brief 计算发送环形缓冲区中的下一个索引。
|
||||
@@ -35,19 +36,54 @@ bool Usart0::isBufferEmpty()
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 以非阻塞方式向 USART0 发送缓冲写入一个字符。
|
||||
* @brief 在临界区内直接轮询 TBE 发出一个字节,腾出一个缓冲槽位。
|
||||
* @param[in] 无。
|
||||
* @param[out] 无。
|
||||
* @retval bool true 表示成功发出一字节(s_txTail 已前进),false 表示等待 TBE 超时。
|
||||
* @note 调用者必须已持有临界区:USART0 中断为 preempt=3,已被 BASEPRI 屏蔽,
|
||||
* 故此处独占 s_txTail,不会与 onInterrupt() 取到同一字节。
|
||||
* 走轮询而非等中断,因此在中断上下文里调用 printf 也不会死锁。
|
||||
*/
|
||||
bool Usart0::drainOneByteLocked()
|
||||
{
|
||||
if(isBufferEmpty()) {
|
||||
return false;
|
||||
}
|
||||
uint32_t spin = kTbeSpinMax;
|
||||
while(usart_flag_get(USART0, USART_FLAG_TBE) == RESET) {
|
||||
if(--spin == 0U) {
|
||||
return false; /* USART 未在发送(外设异常/时钟丢失),交由调用者计丢弃 */
|
||||
}
|
||||
}
|
||||
usart_data_transmit(USART0, s_txBuf[s_txTail]);
|
||||
s_txTail = nextIndex(s_txTail);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 向 USART0 发送缓冲写入一个字符,缓冲满时自旋腾位而非丢弃。
|
||||
* @param[in] ch 待发送字符。
|
||||
* @param[out] 无。
|
||||
* @retval bool true 表示成功写入发送缓冲,false 表示缓冲已满而被丢弃。
|
||||
* @note 当前统一由 TBE 中断从队列中取字节发送;此处只负责入队并使能发送中断。
|
||||
* @retval bool true 表示成功写入发送缓冲,false 表示 USART 异常导致该字节被丢弃。
|
||||
* @note 正常路径仍是"入队 + 使能 TBE 中断"的非阻塞发送。仅在缓冲写满时
|
||||
* (3M 波特率下 init 阶段诊断突发写入会写满)就地轮询发出一字节腾位,
|
||||
* 以字节级背压换取日志完整——旧版此处静默丢弃且 putChar 忽略返回值,
|
||||
* 实测使 [ECAT] 诊断出现 "bus eaabled"/"pdi_type=0x8Dexect" 等掉字,
|
||||
* 曾导致 LAN9252 故障被两次误定性,故日志完整性优先于此处的等待开销。
|
||||
* 仅当 USART 外设本身不发送时才真正丢弃并累加 s_txDropped。
|
||||
*/
|
||||
bool Usart0::putCharNonBlocking(int ch)
|
||||
{
|
||||
uint32_t save = RT_CRITICAL_SAVE();
|
||||
const uint16_t next = nextIndex(s_txHead);
|
||||
uint16_t next = nextIndex(s_txHead);
|
||||
if(next == s_txTail) {
|
||||
RT_CRITICAL_RESTORE(save);
|
||||
return false;
|
||||
/* 缓冲已满:就地发出最老的一字节腾出槽位,失败则说明 USART 真的没在发。 */
|
||||
if(!drainOneByteLocked()) {
|
||||
++s_txDropped;
|
||||
RT_CRITICAL_RESTORE(save);
|
||||
return false;
|
||||
}
|
||||
next = nextIndex(s_txHead);
|
||||
}
|
||||
|
||||
s_txBuf[s_txHead] = static_cast<uint8_t>(ch);
|
||||
@@ -110,10 +146,10 @@ void Usart0::configurePins()
|
||||
* @brief 初始化 USART0 外设与中断。
|
||||
* @param[in] 无。
|
||||
* @param[out] 无。
|
||||
* @retval 无返回值。
|
||||
* @retval uint8_t Usart0::InitFault 故障码(0=USART 已使能,CTL0.UEN 回读置位)。
|
||||
* @note 使用 `CONFIG_USART0_BAUDRATE` 配置串口参数,并使能 USART0 TBE 中断用于队列发送。
|
||||
*/
|
||||
void Usart0::init()
|
||||
uint8_t Usart0::init()
|
||||
{
|
||||
rcu_periph_clock_enable(RCU_USART0);
|
||||
usart_deinit(USART0);
|
||||
@@ -125,6 +161,7 @@ void Usart0::init()
|
||||
usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);
|
||||
usart_enable(USART0);
|
||||
nvic_irq_enable(USART0_IRQn, CONFIG_IRQ_PREEMPT_SPI_USART, 0U);
|
||||
return ((USART_CTL0(USART0) & USART_CTL0_UEN) != 0U) ? kFaultOk : kFaultNotEnabled;
|
||||
}
|
||||
|
||||
/* ----- 中断入口 / printf 重定向的 C 包装 --------------------------- */
|
||||
|
||||
Reference in New Issue
Block a user