feat(device_exmc): 添加GD32E508 EXMC外设支持用于LAN9252通信

添加EXMC 16-bit并行总线驱动实现,用于LAN9252 ESC通信。
在cproject.yml中添加device_exmc组和相关源文件,包括
gd32e50x_exmc.c/h文件,并更新头文件搜索路径。

由于GigaDevice DFP未将EXMC注册为CMSIS组件,需要本地编入
RTE/Device目录下的EXMC源文件以支持LAN9252并行总线功能。

fix(canfd): 优化CANFD驱动中的条件编译和DLC处理逻辑

将CANFD相关的配置项从硬编码改为使用sys/config.h中的配置。
添加对DLC=0情况的支持(表示无数据负载的远程帧),
修正了数据长度检查逻辑,确保DLC为0时不需要提供数据指针。

同时重构了调试代码的条件编译,使用CONFIG_CAN_STARTUP_DIAG_VERBOSE
等配置开关控制调试输出函数的编译。

refactor(ethercat): 统一配置项管理,移除硬编码常量

将EtherCAT相关配置项从硬编码改为统一的sys/config.h配置,
提升代码可维护性。

docs(spi): 更新SPI命令响应缓冲区大小说明

更新CAN桥接和ID快照命令的响应payload大小计算说明,
统一使用AppSpiCommand::kTxBufSize - V2_OVERHEAD作为上限。
This commit is contained in:
cbb
2026-07-16 23:00:52 +08:00
parent 76da7a3dd6
commit 52d7f9be76
23 changed files with 2853 additions and 1458 deletions
+43 -28
View File
@@ -1,6 +1,10 @@
/**
* @file esc_exmc_bus.cpp
* @brief LAN9252 ESC 的 EXMC 16-bit 并行总线驱动实现。
*
* 使用 GigaDevice gd32e50x_exmc 标准库。
* 注意:DFP 只把 FMC 注册为 CMSIS 组件,EXMC 未进组件列表;
* 源文件放在 RTE/Device/... 并由 cproject group device_exmc 本地编译。
*/
#include "comm/esc_exmc_bus.h"
#include "sys/config.h"
@@ -8,22 +12,17 @@
extern "C" {
#include "gd32e50x_rcu.h"
#include "gd32e50x_gpio.h"
#ifdef EXMC_NORSRAM_REGION1
#include "gd32e50x_exmc.h"
#endif
#include "gd32e50x_exmc.h" /* RTE/Device/GD32E508VE 或 -I 同目录 */
}
/* 内存映射访问宏:基址 + 偏移(按 16-bit 半字对齐,LAN9252 HBI 地址左移 1 位)。
* 使用 volatile uint16_t* 转换避免依赖 CMSIS 的 __IO 宏。 */
/* 内存映射访问宏:基址 + 偏移(按 16-bit 半字对齐,LAN9252 HBI 地址左移 1 位)。 */
#define ESC_EXMC_REG16(offset) (*(volatile uint16_t*)(CONFIG_ESC_EXMC_BASE_ADDR + (offset)))
void EscExmcBus::init()
{
/* 使能 GPIO 与 EXMC 时钟 */
rcu_periph_clock_enable(RCU_GPIOD);
rcu_periph_clock_enable(RCU_GPIOE);
rcu_periph_clock_enable(RCU_AF);
#ifdef EXMC_NORSRAM_REGION1
rcu_periph_clock_enable(RCU_EXMC);
/* 配置 16-bit 数据线 D0-D15 为 AF 推挽 */
@@ -50,31 +49,47 @@ void EscExmcBus::init()
gpio_init(CONFIG_EXMC_NWE_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, CONFIG_EXMC_NWE_PIN);
gpio_init(CONFIG_EXMC_NE1_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, CONFIG_EXMC_NE1_PIN);
/* EXMC NOR/SRAM Region1 时序配置(16-bit,非复用,异步) */
/*
* EXMC NOR/SRAM Region1:16-bit、非复用、异步写。
* 时序(AHB=180MHz,1 HCLK ≈ 5.56ns):
* LAN9252 HBI 最小读/写周期约 100ns → data_setup ≥ 18 HCLK。
* asyn_* 字段单位为 HCLK 计数(库文档范围 address_setup 1..16,data_setup 2..256)。
*/
exmc_norsram_parameter_struct norsram_init;
exmc_norsram_timing_parameter_struct rw_timing;
exmc_norsram_timing_parameter_struct wr_timing;
norsram_init.read_write_timing = &rw_timing;
norsram_init.write_timing = &wr_timing;
exmc_norsram_struct_para_init(&norsram_init);
norsram_init.norsram_region = CONFIG_ESC_EXMC_BANK_NOR_SRAM_REGION1;
norsram_init.write_mode = EXMC_ASYN_WRITE;
norsram_init.read_mode = EXMC_ASYN_READ;
norsram_init.nwait_mode = EXMC_NWAIT_DISABLE;
norsram_init.asyn_wait = DISABLE;
norsram_init.nwait_polarity = EXMC_NWAIT_POLARITY_LOW;
norsram_init.databus_width = EXMC_NOR_DATABUS_WIDTH_16B;
/* TODO(spec): 时序:按 LAN9252 HBI 要求配置 read/write wait state
* LAN9252 HBI 最小 read/write cycle = 100ns。
* AHB=180MHz(RCU_MODIFY_UP 强制 /1),1 HCLK = 5.6ns。
* 6 HCLK = 33ns → 不满足,需 ≥ 18 HCLK 才能达到 100ns。
* 当前 ESC 未启用(selfTest FAIL),EXMC 库未纳入编译,此参数仅占位。
* 启用 ESC 时需安装 EXMC 库并实测调整 HCLK 数。 */
norsram_init.read_latency = EXMC_DEN_ALE_TR_6_HCLK; // 占位,启用 ESC 时需调整为 ≥18 HCLK
norsram_init.write_latency = EXMC_DEN_ALE_TR_6_HCLK; // 占位,启用 ESC 时需调整为 ≥18 HCLK
norsram_init.norsram_region = CONFIG_ESC_EXMC_BANK_NOR_SRAM_REGION1;
norsram_init.write_mode = EXMC_ASYN_WRITE;
norsram_init.extended_mode = DISABLE;
norsram_init.asyn_wait = DISABLE;
norsram_init.nwait_signal = DISABLE;
norsram_init.memory_write = ENABLE;
norsram_init.nwait_config = EXMC_NWAIT_CONFIG_BEFORE;
norsram_init.wrap_burst_mode = DISABLE;
norsram_init.nwait_polarity = EXMC_NWAIT_POLARITY_LOW;
norsram_init.burst_mode = DISABLE;
norsram_init.databus_width = EXMC_NOR_DATABUS_WIDTH_16B;
norsram_init.memory_type = EXMC_MEMORY_TYPE_SRAM;
norsram_init.address_data_mux = DISABLE;
/* 读/写共用时序(非 extended mode) */
rw_timing.asyn_access_mode = EXMC_ACCESS_MODE_A;
rw_timing.syn_data_latency = EXMC_DATALAT_2_CLK;
rw_timing.syn_clk_division = EXMC_SYN_CLOCK_RATIO_DISABLE;
rw_timing.bus_latency = 1U;
rw_timing.asyn_address_setuptime = 2U; /* ~11ns */
rw_timing.asyn_address_holdtime = 2U; /* min 2 */
rw_timing.asyn_data_setuptime = 20U; /* ~111ns ≥ 100ns HBI */
wr_timing = rw_timing;
exmc_norsram_init(&norsram_init);
exmc_norsram_enable(CONFIG_ESC_EXMC_BANK_NOR_SRAM_REGION1);
#else
/* EXMC 外设库未安装(gd32e50x_exmc.h 缺失):EtherCAT ESC EXMC 总线初始化为空,
* 运行期 selfTest 必失败,EtherCAT 自动禁用。启用 ESC 需先安装 EXMC 组件。 */
#warning "EXMC peripheral library not included; EtherCAT ESC EXMC bus init is a no-op"
#endif
}
__attribute__((section(".ramfunc"), noinline))
+1 -3
View File
@@ -14,9 +14,7 @@
#include <cstdint>
#include <cstddef>
/** @brief 默认 PDO 大小(可按需调整)。 */
constexpr size_t CONFIG_ETHERCAT_PDO_SIZE = 32U;
#include "sys/config.h" /* CONFIG_ETHERCAT_PDO_SIZE */
/** @brief EtherCAT AL 状态码(EtherCAT 协议定义,ESC AL Status 寄存器低 4 位)。 */
constexpr uint8_t AL_STATE_SAFEOP = 0x04U; /**< SAFEOP 状态(SYNC0 可触发下限)。 */