Files
DCU_APP/GD32E508_DCU_APP/comm/esc_exmc_bus.cpp
T
cbb 52d7f9be76 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作为上限。
2026-07-16 23:00:52 +08:00

106 lines
4.9 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 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"
extern "C" {
#include "gd32e50x_rcu.h"
#include "gd32e50x_gpio.h"
#include "gd32e50x_exmc.h" /* RTE/Device/GD32E508VE 或 -I 同目录 */
}
/* 内存映射访问宏:基址 + 偏移(按 16-bit 半字对齐,LAN9252 HBI 地址左移 1 位)。 */
#define ESC_EXMC_REG16(offset) (*(volatile uint16_t*)(CONFIG_ESC_EXMC_BASE_ADDR + (offset)))
void EscExmcBus::init()
{
rcu_periph_clock_enable(RCU_GPIOD);
rcu_periph_clock_enable(RCU_GPIOE);
rcu_periph_clock_enable(RCU_AF);
rcu_periph_clock_enable(RCU_EXMC);
/* 配置 16-bit 数据线 D0-D15 为 AF 推挽 */
gpio_init(CONFIG_EXMC_D0_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, CONFIG_EXMC_D0_PIN);
gpio_init(CONFIG_EXMC_D1_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, CONFIG_EXMC_D1_PIN);
gpio_init(CONFIG_EXMC_D2_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, CONFIG_EXMC_D2_PIN);
gpio_init(CONFIG_EXMC_D3_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, CONFIG_EXMC_D3_PIN);
gpio_init(CONFIG_EXMC_D4_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, CONFIG_EXMC_D4_PIN);
gpio_init(CONFIG_EXMC_D5_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, CONFIG_EXMC_D5_PIN);
gpio_init(CONFIG_EXMC_D6_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, CONFIG_EXMC_D6_PIN);
gpio_init(CONFIG_EXMC_D7_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, CONFIG_EXMC_D7_PIN);
gpio_init(CONFIG_EXMC_D8_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, CONFIG_EXMC_D8_PIN);
gpio_init(CONFIG_EXMC_D9_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, CONFIG_EXMC_D9_PIN);
gpio_init(CONFIG_EXMC_D10_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, CONFIG_EXMC_D10_PIN);
gpio_init(CONFIG_EXMC_D11_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, CONFIG_EXMC_D11_PIN);
gpio_init(CONFIG_EXMC_D12_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, CONFIG_EXMC_D12_PIN);
gpio_init(CONFIG_EXMC_D13_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, CONFIG_EXMC_D13_PIN);
gpio_init(CONFIG_EXMC_D14_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, CONFIG_EXMC_D14_PIN);
gpio_init(CONFIG_EXMC_D15_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, CONFIG_EXMC_D15_PIN);
/* 控制线:A16 / NOE / NWE / NE1 */
gpio_init(CONFIG_EXMC_A16_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, CONFIG_EXMC_A16_PIN);
gpio_init(CONFIG_EXMC_NOE_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, CONFIG_EXMC_NOE_PIN);
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、非复用、异步写。
* 时序(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.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);
}
__attribute__((section(".ramfunc"), noinline))
uint16_t EscExmcBus::read16(uint32_t offset)
{
return ESC_EXMC_REG16(offset);
}
__attribute__((section(".ramfunc"), noinline))
void EscExmcBus::write16(uint32_t offset, uint16_t data)
{
ESC_EXMC_REG16(offset) = data;
}