feat(canfd): 添加CANFD自检功能和桥接模式支持

- 添加完整的CANFD初始化流程,包括硬复位机制解决CAN1卡死问题
- 实现CANFD自检功能,包含物理总线测试和内部回环测试
- 支持CAN0到CAN1/CAN2的透传桥接模式
- 添加详细的初始化诊断信息输出
- 修复CAN滤波器配置和GPIO映射问题
- 增强错误处理和状态监控功能

perf(system): 优化系统时钟配置提高性能

- 将AHB时钟从SYSCLK/4调整为SYSCLK/2 (60MHz)
- 优化PLL预分频配置参数
- 更新相关时序注释以反映实际频率变化

docs(esc): 更新EXMC总线时序配置注释

- 添加LAN9252 HBI时序要求详细说明
- 注明当前ESC未启用状态下的占位符说明
- 提供实际计算得出的HCLK延迟要求
This commit is contained in:
cbb
2026-07-02 02:02:41 +08:00
parent b171767023
commit 6aa21a1f9d
11 changed files with 608 additions and 57 deletions
@@ -19,7 +19,10 @@
* [13..16] tx_count (LE) 通道累计发送
* [17..20] drop_count (LE)
* [21..24] error_count (LE)
* [25..] 条目逐条拼接:
* [25] tec 硬件发送错误计数器 (0~255)
* [26] rec 硬件接收错误计数器 (0~255)
* [27] bus_state 总线状态位图:bit0=init,bit1=sleep,bit2=error_passive,bit3=bus_off,bit4=error_warning
* [28..] 条目逐条拼接:
* id(4LE) + dlc(1) + flags(1) + reserved(2) + data(dlc)
* 每条 = 8 + dlc 字节
*
@@ -43,7 +46,7 @@ namespace {
constexpr uint8_t kFeedbackChannelCount = 3U;
constexpr uint16_t kFeedbackPayloadLen = 123U; /* kTxBufSize=128 - overhead=5 */
constexpr uint8_t kPageEntries = 8U;
constexpr uint16_t kFixedHeaderLen = 25U; /* ch(1)+page(1)+total(1)+cnt(1)+mode(1)+seq(4)+rx(4)+tx(4)+drop(4)+err(4) */
constexpr uint16_t kFixedHeaderLen = 28U; /* ch(1)+page(1)+total(1)+cnt(1)+mode(1)+seq(4)+rx(4)+tx(4)+drop(4)+err(4)+tec(1)+rec(1)+bus_state(1) */
void writeU32Le(uint8_t *dst, uint32_t value)
{
@@ -119,6 +122,9 @@ private:
writeU32Le(&payload[13], snap.stats.tx_count);
writeU32Le(&payload[17], snap.stats.rx_drop_count);
writeU32Le(&payload[21], snap.stats.error_count);
payload[25] = snap.stats.tec;
payload[26] = snap.stats.rec;
payload[27] = snap.stats.bus_state;
/* 打包 ID 条目 */
uint16_t offset = kFixedHeaderLen;
@@ -170,6 +176,7 @@ private:
switch (requested) {
case 0U: target = CanFd::Mode::kModeAllPass; break;
case 1U: target = CanFd::Mode::kModeFilterId; break;
case 2U: target = CanFd::Mode::kModeBridge0To12; break;
default: {
uint8_t err = 0xE1U;
bus.buildResponse(ctx.tx_buf, ctx.tx_buf_size, ctx.tx_len,
@@ -313,6 +313,7 @@ void AppSpiCommand::init()
m_txLen = 0U;
m_txPos = 0U;
m_logPending = false;
m_txActiveThisCs = false;
m_commandCount = 0U;
memset(m_txBuf, 0xFF, sizeof(m_txBuf));
memset(m_logBuf, 0, sizeof(m_logBuf));
@@ -495,6 +496,7 @@ void AppSpiCommand::onCsAssert()
m_csActive = true;
m_rxLen = 0U;
m_txPos = 0U;
m_txActiveThisCs = false;
/* 停止 DMA 并清理旧状态 */
DMA_CHCTL(SPI_TX_DMA_PERIPH, SPI_TX_DMA_CH) &= ~DMA_CHXCTL_CHEN;
@@ -516,6 +518,7 @@ void AppSpiCommand::onCsAssert()
/* 启动 DMA 发送响应帧(与 BOOT 完全一致) */
if (m_txLen > 0U) {
m_txActiveThisCs = true;
spi_dma_enable(SPI0, SPI_DMA_TRANSMIT);
startSpiTxDma(m_txBuf, m_txLen);
} else {
@@ -545,8 +548,19 @@ void AppSpiCommand::onCsRelease()
if (shouldIgnoreTransaction(m_rxBuf, m_rxLen)) {
m_rxLen = 0U;
if (m_txActiveThisCs) {
m_txLen = 0U;
m_txPos = 0U;
memset(m_txBuf, 0xFF, sizeof(m_txBuf));
}
m_txActiveThisCs = false;
return;
}
m_txLen = 0U;
m_txPos = 0U;
m_txActiveThisCs = false;
memset(m_txBuf, 0xFF, sizeof(m_txBuf));
m_cmdPending = true;
TaskManager::set(1UL << TASK_SPI_CMD_PROCESS);
}
@@ -1,4 +1,4 @@
#ifndef DEVICE_APP_SPI_COMMAND_H
#ifndef DEVICE_APP_SPI_COMMAND_H
#define DEVICE_APP_SPI_COMMAND_H
#include <cstdint>
@@ -70,6 +70,7 @@ private:
volatile uint8_t m_txPos = 0U;
volatile bool m_logPending = false;
volatile bool m_cmdPending = false; /**< ISR 置位,标记有待主循环解析的 SPI 命令。 */
bool m_txActiveThisCs = false;
uint8_t m_rxBuf[kRxBufSize] = {};
uint8_t m_txBuf[kTxBufSize] = {};
char m_logBuf[kLogBufSize] = {};