Files
DCU_APP/GD32E508_DCU_APP/sys/config.h
T

385 lines
40 KiB
C++
Raw Normal View History

2026-07-20 02:36:56 +08:00
/**
* @file config.h
* @brief 应用级集中�置项定义。
* @note 用于统一管�当�项目中�调的外设�时��通信与算法常�。
*/
#ifndef SYS_CONFIG_H
#define SYS_CONFIG_H
#include <stdint.h>
#include <stddef.h>
#include "gd32e50x.h"
2026-07-20 02:36:56 +08:00
/* ============================================================
* 功能开关(调试/特性总闸 — 改这里��开关,改完�编)
* 0/false=关,1/true=开。需� #if 的�留 #define。
* ============================================================ */
/**
* @brief 5s 诊断任务是�输出全� UART 摘�(task_runner)。
* @note 任务本身始终 5s 调度:0=默认仅状��化/错误增�;1=周期打� ADC/CAN/ECAT 全�行。
* 现场抓��/温度时改回 1 ��编��。
*/
#define CONFIG_UART_TEMP_PERIODIC_PRINT 0
/**
* @brief 全�摘�详细级别(仅 PERIODIC_PRINT=1 时生效;0=ADC 精简 1=� CAN 统计)。
* @note 默认 0;需� can_tx/rx/drop 等列时与 PERIODIC_PRINT 一并打开。
*/
#define CONFIG_UART_DIAG_LEVEL 0
2026-07-20 02:36:56 +08:00
/**
* @brief SPI 调试�馈 0xC4:GD32 ADC 温度/VDDA/VIN 1Hz 主动推�。
* @note 调试用;0=�注册 handler��推�。与 ESP32 GD32_ADC_FEEDBACK_ENABLE �对。
*/
#define CONFIG_SPI_ADC_FEEDBACK_ENABLE 1
/**
* @brief 多电机状�表 0xC5:CAN STATUS 帧缓存 + 250ms 主动推�。
* @note 0=�注册 handler��推���解� STATUS 帧。与 ESP32 端 motor_state_task �对。
*/
#define CONFIG_MOTOR_STATE_ENABLE 1
/**
* @brief 多电机版本 0xC6:CAN 版本应答帧(0x00FF)缓存 + 事件驱动推�。
* @note 0=�识别版本帧��推�。与 ESP32 端 motor_version 缓存�对。
* 版本为按需查询的低频数�,独立于 0xC5 周期推�。
*/
#define CONFIG_MOTOR_VERSION_ENABLE 1
/** @brief 最大电机节点数 (node ID 1-9)。 */
constexpr uint8_t CONFIG_MOTOR_MAX_NODES = 9U;
/** @brief 电机离线判定超时 (ms)。超过此时间未收到 STATUS 帧则标记 offline。 */
constexpr uint16_t CONFIG_MOTOR_OFFLINE_MS = 3000U;
2026-07-20 02:36:56 +08:00
/** @brief SPI 命令�帧日志(#if)。 */
#define CONFIG_SPI_APP_LOG_ENABLE 0
/** @brief CAN_SEND �功帧详细日志(#if)。 */
#define CONFIG_SPI_CAN_SEND_VERBOSE_LOG 0
/** @brief CAN-FD BRS 使能(canfd.cpp #if)。
* 关闭 BRS: 数�段用仲�段�速率,牢牢性更高。
* 电机 BOOT 无法正确接收 BRS 高速段→nonce(16B FD+BRS)被拒�→�手失败。 */
#define CONFIG_CAN_FD_BRS_ENABLE 1U
2026-07-20 02:36:56 +08:00
/** @brief �动时总线探测帧;正常固件关。 */
#define CONFIG_CAN_STARTUP_BUS_TEST_ENABLE 0
/** @brief �动时内部回环自检;正常固件关。 */
#define CONFIG_CAN_STARTUP_LOOPBACK_TEST_ENABLE 0
/** @brief CAN �动详细诊断 dump;默认关。 */
#define CONFIG_CAN_STARTUP_DIAG_VERBOSE 0
/**
* @brief 周期测试��任务(taskCanTxSend,� 0x18FF5000 64B FD 帧)。
* @note 调试用:该 PGN 无业务接收节点 ACK。auto_retrans=ENABLE 时无 ACK 被
* 无����进 TEC(TEC 一直涨);DISABLE 时��失败� MTEn→error_count++。
* 电机拓扑下无对端应答,默认关以消除�续错误帧。需�回放测试波形时打开。
*/
#define CONFIG_CAN_PERIODIC_TEST_TX_ENABLE 0
/** @brief CAN0/1/2 通�使能。CH1/CH2 未接设备,关闭���续 CAN 错误 + � SPI 带宽。 */
2026-07-20 02:36:56 +08:00
constexpr bool CONFIG_CAN_CH0_ENABLE = true;
constexpr bool CONFIG_CAN_CH1_ENABLE = true;
constexpr bool CONFIG_CAN_CH2_ENABLE = true;
2026-07-20 02:36:56 +08:00
/** @brief 主循环 WFI(main.cpp #if)。 */
#define CONFIG_MAIN_LOOP_WFI_ENABLE 0
/** @brief EtherCAT SYNC0 �步模�(#if)。 */
#define CONFIG_ETHERCAT_SYNC_MODE 0
/** @brief MOTOR-OTA INFO 级日志(�手/进度/�控 chatter);错误与关键事件��留。 */
#define CONFIG_OTA_RELAY_LOG_ENABLE 1
/** @brief CAN �始化/自检 INFO 级日志;�始化失败与硬件错误��留。 */
#define CONFIG_CAN_INIT_LOG_ENABLE 1
/** @brief EtherCAT/EXMC �始化 INFO 级日志;FAIL ��留。 */
#define CONFIG_ECAT_INIT_LOG_ENABLE 1
/** @brief HBI bring-up 诊断探针(bit-bang 探活 + predrive/回显 + 20s 周期�跑)。
* @note 硬件层已确认全通(IDX_0=0x1234�BYTE_TEST=0x87654321),默认关闭以清�上电日志,
* 并���次上电/� 20s 把 EXMC 引脚切� GPIO 手动拉一�。��/补焊需�新排查浮空时置 1。
* 网页万用表通断测试 continuityDrive() ��此开关影�,始终�用。 */
#define CONFIG_ESC_EXMC_DIAG 0
/** @brief �动横幅与 main 进度打�。 */
#define CONFIG_APP_BANNER_LOG_ENABLE 1
/* ============================================================
* 日志分级�:*_LOGI=INFO 级,由上方模�开关编译期�剪,
* 格�串�之被链接器回收;LOG_ERR=错误/关键事件,��留。
* 使用文件需自行�� printf 声明(<cstdio>)。
* ============================================================ */
#define LOG_ERR(...) printf(__VA_ARGS__)
#if CONFIG_OTA_RELAY_LOG_ENABLE
#define OTA_LOGI(...) printf(__VA_ARGS__)
#else
#define OTA_LOGI(...) ((void)0)
#endif
#if CONFIG_CAN_INIT_LOG_ENABLE
#define CAN_LOGI(...) printf(__VA_ARGS__)
#else
#define CAN_LOGI(...) ((void)0)
#endif
#if CONFIG_ECAT_INIT_LOG_ENABLE
#define ECAT_LOGI(...) printf(__VA_ARGS__)
#else
#define ECAT_LOGI(...) ((void)0)
#endif
#if CONFIG_APP_BANNER_LOG_ENABLE
#define APP_LOGI(...) printf(__VA_ARGS__)
#else
#define APP_LOGI(...) ((void)0)
#endif
2026-07-20 02:36:56 +08:00
/* ============================================================
* APP 固件版本�
* ============================================================ */
constexpr uint32_t APP_FW_VERSION_MAJOR = 1U;
constexpr uint32_t APP_FW_VERSION_MINOR = 5U;
constexpr uint32_t APP_FW_VERSION_PATCH = 43U; /* 1.5.43:修å¤� SAFEOP->OP 永远进ä¸�去(主站报 "è¿› OP 失败: AL=PREOP code=0x0000",且已边å�‘ processdata 边等 3s ä»�无效)——根因是 LAN9252 çš„ IRQ 引脚从未被使能,PDI_Isr 一次都没执行过。IRQ_CFG(0x054) 与 INT_EN(0x05C) 是 LAN9252 系统 CSR(HBI 索引直接å�¯è¾¾ï¼Œä¸�èµ° CSR 间接端å�£ï¼‰ï¼Œå¤�ä½�默认值å�‡ä¸º 0,å�³ IRQ_EN=0(引脚永久去断言)+ ECAT_INT_EN=0(EtherCAT 事件ä¸�汇入 IRQ,DS 8.2.6/8.3.1,ECAT_INT 为 INT_STS/INT_EN çš„ bit0);固件此å‰�å�ªé…�了 EXTI/GPIO/NVIC 侧(PB1 上拉输入+下é™�沿+preempt=1)与 EEPROM çš„ SYNC0/1(0x0151=0xCC),从æ�¥æ²¡æ‰“开芯片侧的中断输出总闸。å�Žæžœé“¾ï¼šPDI_Isr 从ä¸�触å�‘ → SSC æ”¶ä¸�到 PROCESS_OUTPUT_EVENT → bEcatFirstOutputsReceived æ�’ FALSE(该标志å�ªåœ¨ PDI_Isr(ecatappl.c:305) 或 free-run çš„ MainLoop 轮询分支(ecatappl.c:551, æ�¡ä»¶ !bEscIntEnabled)里置ä½�)→ AL_ControlInd çš„ SAFEOP_2_OP 分支(ecatslv.c:1993 `nPdOutputSize == 0 || bEcatFirstOutputsReceived`) 因本工程有 32B 输出而永ä¸�æˆ�ç«‹ → è¿�移被挂起(bApplEsmPending)å�Žå›žè�½ï¼ŒAL Status Code ä¿�æŒ� 0x0000(ä¸�是被拒ç»�,故ä¸�ç»™ 0x001B/0x001A)。注æ„�本工程 SyncType 使 UpdateSyncManagerParameter ç½® bEscIntEnabled=TRUE(ecatslv.c:951),因此 MainLoop çš„ free-run 轮询兜底分支ä¸�执行,中断是唯一通路。EscLan9252::init() 在 DL_STATUS bit0 确认 PDI 就绪å�Žæ–°å¢ž enableEcatIrqOutput():先写 INT_STS 清 ECAT_INT 悬留状æ€�(R/WC),å†�ç½® INT_EN.ECAT_INT_EN,最å�Žå¼€ IRQ_CFG 总闸并回读校验,打å�° [ECAT][ESC] IRQ output enabled(失败则 WARN 并指明 SAFEOP->OP 会å�¡ï¼‰ã€‚æž�性与 ethercat_sync.cpp ä¿�æŒ�一致:推挽 IRQ_TYPE=1 + 低有效 IRQ_POL=0,é…�对上拉输入的下é™�沿 EXTIï¼›INT_DEAS ä¿�æŒ� 0=ç¦�用去断言定时器。AL Event Mask(0x204) ä»�ç”± SSC 在状æ€�è¿�移时自行维护,ä¸�在此处干预。é…�套修主站工具(tools/ecat):(a) _require_op_ready/enter_op 请求 OP å�Žæ”¹ä¸ºè¾¹ send_processdata/receive_processdata è¾¹ state_check 循环至多 3s(SSC è¦�求先收到首帧输出æ‰� ack OP),中途回è�½åˆ™é‡�å�‘ OP 请求,失败信æ�¯æŒ‰ AL code 分æµ�排查方å�‘ï¼›(b) 修正 state_check è¶…æ—¶å�•ä½�——pysoem docstring 明确 "Timeout value in us",旧代ç �å�„处传 2000 实际å�ªç­‰ 2ms(SOEM 默认 EC_TIMEOUTSTATE=2000000=2s),PREOP/SAFEOP 能过纯属从站 ack 快的侥幸,现统一用 EC_TIMEOUT_STATE_US=2_000_000 常é‡�。1.5.42:修å¤�主站 config_map 失败(SdoError "Unsupported access to an object" / "Attempt to read to a write only object",实测 0x1600/0x1A00 çš„ sub0/3/4 报错而 sub1/2 通过)——两个独立的对象字典 bug,å�‡åœ¨ä»Žç«™ä¾§ï¼Œä¸Žä¸»ç«™å·¥å…·æ— å…³ã€‚(1) REC 对象的 entry descriptor 数组给少了:OBJ_GetEntryDesc()(objdef.c:554) 与 OBJ_GetEntryOffset()(objdef.c:609) å�ªå¯¹ OBJCODE_ARR å¤�用 pEntryDesc[1] æ��述所有å­�索引,对 OBJCODE_REC 是é€�下标索引 pEntryDesc[Subindex];而 dc_app.c 把 0x1600/0x1A00/0x7000/0x6000/0x2000 全声明为 REC(4|OBJCODE_REC<<8) å�´å�ªæ��ä¾› 2 元素æ��述数组,sub3/sub4 越界读到相邻常é‡�数组的垃圾 DataType/ObjAccess,正好解释"sub0/3/4 报错ã€�sub1/2 侥幸通过"的错误模å¼�(sub1/2 æ�°å¥½è�½åœ¨å�ˆæ³•项上)。现为 0x1600/0x1A00 补满 Sub0..Sub4 å…± 5 项(asPDOMappingEntryDesc),并把原共用的 asDataEntryDesc 拆æˆ� asOutputEntryDesc/asInputEntryDesc(å�„ 5 项)ã€�asSyncDiagEntryDesc 补到 5 项;å�Œæ—¶ç»™æ•°æ�®å­�æ�¡ç›®è¡¥ OBJACCESS_RXPDOMAPPING/TXPDOMAPPING(官方 sampleappl.h çš„ 0x7010/0x6000 å�Œæ­¤ï¼Œç¼ºè¿™ä¸¤ä¸ªæ ‡å¿—主站校验 0x1600/0x1A00 的映射目标时会拒ç»�),输入侧 0x6000 ç”± READWRITE 收紧为 ACCESS_READ。0x1C12/0x1C13 是 ARR ä¿�æŒ� 2 项ä¸�å�˜ã€‚(2) 结构体从未被紧排:ecat_def.h çš„ STRUCT_PACKED_START/MBX_STRUCT_PACKED_START/OBJ_STRUCT_PACKED_START 三对å®�全部留空,注释还误写"AC6 ä¸�需è¦�"——实际这些å®�就是 SSC 紧排结构体的唯一手段ï
2026-07-15 02:49:37 +08:00
constexpr uint32_t APP_FW_VERSION_BUILD = 0U;
/** @brief USART0 默认波特率。 */
constexpr uint32_t CONFIG_USART0_BAUDRATE = 3000000U; /* 3M:诊断打�高速输出,printf 阻塞����拖慢 relay */
/** @brief ADC 外设实例。 */
constexpr uint32_t CONFIG_ADC_INSTANCE = ADC0;
/** @brief ADC 外部 VIN 检测通��(原�图:PA6 -> VIN_ADC)。 */
constexpr uint32_t CONFIG_ADC_VIN_CHANNEL = ADC_CHANNEL_6;
/** @brief ADC 内部温度通��。 */
constexpr uint32_t CONFIG_ADC_TEMP_CHANNEL = ADC_CHANNEL_16;
/** @brief ADC 内部�考电压通��。 */
constexpr uint32_t CONFIG_ADC_VREFINT_CHANNEL = ADC_CHANNEL_17;
/** @brief ADC 满�程计数值。 */
constexpr float CONFIG_ADC_MAX_VALUE = 4095.0f;
/** @brief 内部�考电压典型值,�� V。 */
constexpr float CONFIG_ADC_VREFINT_TYPICAL_VOLTAGE = 1.20f;
/** @brief 温度传感器 25℃ 对应电压,�� V。 */
constexpr float CONFIG_ADC_TEMP_V25 = 1.43f;
/** @brief 温度传感器平�斜率,�� V/℃。 */
constexpr float CONFIG_ADC_TEMP_AVG_SLOPE = 0.0043f;
/** @brief ADC 上电�稳定等待时间,�� ms。 */
constexpr uint32_t CONFIG_ADC_STABILIZE_DELAY_MS = 2U;
/** @brief ADC 中值滤波窗�长度(最终样本数为该值 + 1)。 */
constexpr uint32_t CONFIG_ADC_FILTER_SIZE = 6U;
/** @brief CAN 状�报文标准帧 ID。 */
constexpr uint32_t CONFIG_CAN_STATUS_ID = 0x321U;
/** @brief ESP32 请求 DCU_APP 进入 Bootloader OTA 窗�的扩展帧 ID(备用 CAN 入�)。 */
constexpr uint32_t CONFIG_CAN_OTA_BOOT_REQ_ID = 0x00000320U;
/** @brief 进入 Bootloader OTA 请求魔术字节 0~3。 */
constexpr uint8_t CONFIG_CAN_OTA_BOOT_MAGIC0 = 0x4FU;
constexpr uint8_t CONFIG_CAN_OTA_BOOT_MAGIC1 = 0x54U;
constexpr uint8_t CONFIG_CAN_OTA_BOOT_MAGIC2 = 0x41U;
constexpr uint8_t CONFIG_CAN_OTA_BOOT_MAGIC3 = 0x21U;
/** @brief ESP32 在 APP �行期通过 SPI ��的进入 Bootloader OTA 命令。 */
constexpr uint8_t CONFIG_SPI_APP_OTA_BOOT_CMD = 0xB0U;
/** @brief SPI 进入 Bootloader OTA 命令确认状�:�功。 */
constexpr uint8_t CONFIG_SPI_APP_OTA_BOOT_ACK_OK = 0xB5U;
/** @brief SPI DATA_READY 输出端�(PB6 → ESP32;v2:低=有待读,高=空闲)。 */
constexpr uint32_t CONFIG_SPI_READY_PORT = GPIOB;
/** @brief SPI DATA_READY 输出引脚。 */
constexpr uint32_t CONFIG_SPI_READY_PIN = GPIO_PIN_6;
/** @brief APP SPI DMA/软件缓冲(字节)。业务 payload 上� = 本值 − V2_OVERHEAD(20)。 */
constexpr uint16_t CONFIG_SPI_TX_BUF_SIZE = 256U;
constexpr uint16_t CONFIG_SPI_RX_BUF_SIZE = 256U;
constexpr uint16_t CONFIG_SPI_LOG_BUF_SIZE = 256U;
/** @brief 主动按铃超时:ESP32 未在该时间内�读则 cancelRing(ms)。 */
constexpr uint32_t CONFIG_SPI_RING_TIMEOUT_MS = 50U;
/** @brief SPI 命令 handler 注册表容�。
*
* 当� init 注册 12 个:boot_request / ota_wait / ping / init_status / can_bridge /
* can_burst / can_feedback / id_snapshot / adc_feedback / motor_state / motor_ota / exmc_diag。
* registerHandler 表满时�默丢弃,motor_ota 曾因容�=8 被丢弃(0xD0 回 0xEE)。
* � 14 留余�;新增 handler 时须确认本容�足够。 */
constexpr uint8_t CONFIG_SPI_MAX_COMMANDS = 14U;
/** @brief �通���� ID 快照表最大�目数(与 ESP32 CANFD_ID_SNAPSHOT_MAX 对�)。 */
constexpr uint8_t CONFIG_CANFD_ID_SNAPSHOT_MAX = 16U;
/** @brief 快照�目最大数�字节数(CAN FD DLC 上�)。 */
constexpr uint8_t CONFIG_CANFD_ID_SNAPSHOT_DATA_MAX = 64U;
/** @brief ESP32 硬件��控制端�(PC9 接 ESP32 EN/RESET,对应原�图 WLESS_EN)。
* @note ��� PC9 浮空,ESP_CHIP_EN 会被 C41/U11 拉低;BOOT 也必须主动拉高。 */
constexpr uint32_t CONFIG_ESP32_RESET_PORT = GPIOC;
/** @brief ESP32 硬件��控制引脚。 */
constexpr uint32_t CONFIG_ESP32_RESET_PIN = GPIO_PIN_9;
/* ============================================================
* CAN-FD �时��置(三路 CAN0/CAN1/CAN2 共用)
* 时钟链: SYSCLK=180MHz → AHB=/1=180MHz(RCU_MODIFY_UP 强制)
* → APB1=/2=90MHz (CAN_CLK)
*
* 仲�段目标: 1.0 Mbps = 90MHz / (9 × 10 TQ)
* 数�段目标: 2.0 Mbps = 90MHz / (9 × 5 TQ)
*
* @note RCU_MODIFY_UP �在 system_clock_180m_hxtal() 末尾将 AHB 从 /4
* 临时切到 /1,这是 GigaDevice 官方行为,��删除。
* 最终 AHB=180MHz, APB1=90MHz, APB2=180MHz, TIMER2_CLK=180MHz。
* ============================================================ */
/** @brief 仲�段预分频值。 */
constexpr uint32_t CONFIG_CAN_NOMINAL_PRESCALER = 9U;
/** @brief 仲�段��步跳跃宽度。
* 1TQ→2TQ:总线空闲期��续 STUFF 接收错误(REC 冲 120+),OTA 数�帧被错误帧
* 击�触�应用层��;放宽接收��步容差(�改波特率/采样点,上�� BS2=2TQ �制)。 */
constexpr uint32_t CONFIG_CAN_NOMINAL_SJW = CAN_BT_SJW_2TQ;
/** @brief 仲�段时间段 1(PHSEG1)。 */
constexpr uint32_t CONFIG_CAN_NOMINAL_BS1 = CAN_BT_BS1_7TQ;
/** @brief 仲�段时间段 2(PHSEG2)。 */
constexpr uint32_t CONFIG_CAN_NOMINAL_BS2 = CAN_BT_BS2_2TQ;
/** @brief 数�段预分频值。 */
constexpr uint32_t CONFIG_CAN_DATA_PRESCALER = 9U;
/** @brief 数�段��步跳跃宽度。 */
constexpr uint32_t CONFIG_CAN_DATA_SJW = CAN_BT_SJW_1TQ;
/** @brief 数�段时间段 1。 */
constexpr uint32_t CONFIG_CAN_DATA_BS1 = CAN_BT_BS1_3TQ;
/** @brief 数�段时间段 2。 */
constexpr uint32_t CONFIG_CAN_DATA_BS2 = CAN_BT_BS2_1TQ;
2026-07-20 02:36:56 +08:00
/* BRS / �动探测 / 通�使能:�文件顶部「功能开关� */
/** @brief CAN 接收过滤器目标标准帧 ID。 */
constexpr uint32_t CONFIG_CAN_RX_FILTER_ID = CONFIG_CAN_STATUS_ID;
/** @brief CAN 接收过滤器标准帧掩�;0x7FF 表示精确匹� 11-bit ID。 */
constexpr uint32_t CONFIG_CAN_RX_FILTER_MASK = 0x7FFU;
/** @brief �次 CAN 接收解�任务最多消费的软件队列帧数。 */
constexpr uint32_t CONFIG_CAN_RX_PARSE_BUDGET = 48U;
/** @brief 用户调度定时器实例。 */
constexpr uint32_t CONFIG_SCHED_TIMER_INSTANCE = TIMER2;
/** @brief 用户调度定时器中断�。 */
constexpr IRQn_Type CONFIG_SCHED_TIMER_IRQn = TIMER2_IRQn;
/** @brief 用户调度定时器时钟使能��数。 */
constexpr rcu_periph_enum CONFIG_SCHED_TIMER_RCU = RCU_TIMER2;
/** @brief 用户调度定时器预分频值。
* 时钟链: SYSCLK=180MHz → AHB=/1=180MHz(RCU_MODIFY_UP 强制) → APB1=/2=90MHz → TIMER2_CLK=APB1×2=180MHz。
* �� 100us tick: (PSC+1)×(PER+1)=18000 → 180×100 → PSC=179, PER=99。
*/
constexpr uint32_t CONFIG_SCHED_TIMER_PRESCALER = 179U;
/** @brief 用户调度定时器周期�装值。 */
constexpr uint32_t CONFIG_SCHED_TIMER_PERIOD = 99U;
/** @brief 用户调度定时器 NVIC 抢�优先级。 */
constexpr uint32_t CONFIG_SCHED_TIMER_IRQ_PREEMPT_PRIO = 1U;
/** @brief 用户调度定时器 NVIC �优先级。 */
constexpr uint32_t CONFIG_SCHED_TIMER_IRQ_SUB_PRIO = 0U;
/** @brief 调度基准节�:ADC VREF 采样周期,�� 100us tick。 */
constexpr uint32_t CONFIG_TASK_PERIOD_VREF_SAMPLE_TICKS = 5U;
/** @brief 调度基准节�:ADC 温度采样/处�周期,�� 100us tick。 */
constexpr uint32_t CONFIG_TASK_PERIOD_TEMP_SAMPLE_TICKS = 10U;
/** @brief 调度基准节�:10ms 计数周期,�� 100us tick。 */
constexpr uint32_t CONFIG_TASK_PERIOD_CAN_RX_TICKS = 100U;
/** @brief 调度基准节�:CAN 周期��任务周期,100 tick = 10ms。
* @note 原 1ms/帧过密,改为 10ms/帧以�低 CAN 总线负载与 GD32 邮箱压力。 */
constexpr uint32_t CONFIG_TASK_PERIOD_CAN_TX_TICKS = 100U;
/** @brief 调度基准节�:心跳周期,�� 100us tick。 */
constexpr uint32_t CONFIG_TASK_PERIOD_HEARTBEAT_TICKS = 10000U;
/** @brief 调度基准节�:多电机状� 0xC5 主动推��动周期,2500 tick = 250ms。
* @note 独立于 1Hz heartbeat,��连带加速 OTA Boot 轮询 / CAN �馈快照刷新 /
* ADC 推� / checkOffline 离线判定(3s 阈值)。�端 age 应稳定在 ~120ms。 */
constexpr uint32_t CONFIG_TASK_PERIOD_MOTOR_STATE_TICKS = 2500U;
/** @brief 调度基准节�:APP 状�/诊断打�周期,50000 tick = 5s。 */
constexpr uint32_t CONFIG_TASK_PERIOD_DIAG_PRINT_TICKS = 50000U;
2026-07-20 02:36:56 +08:00
/* UART/SPI 调试开关:�文件顶部「功能开关� */
/** @brief FWDGT 独立看门狗预分频值。 */
constexpr uint32_t CONFIG_FWDGT_PSC = FWDGT_PSC_DIV64;
/** @brief FWDGT 独立看门狗�载值。
* è¶…æ—¶ = (64 / 40000) * (RLD + 1) = 1.6ms * (RLD+1)
* RLD=1874 → 1.6ms * 1875 ≈ 3.0s
*/
constexpr uint32_t CONFIG_FWDGT_RLD = 1874U;
/** @brief FWDGT 超时近似值(毫秒),仅供文档�考。 */
constexpr uint32_t CONFIG_FWDGT_TIMEOUT_MS = 3000U;
/* ============================================================
* BOOT 版本在 OTA �置页中的 Flash 存储地�
* 与 BOOT 工程 sys/config.h ��一致
* ============================================================ */
constexpr uint32_t CONFIG_OTA_CONFIG_PAGE_ADDR = 0x0807E000U;
constexpr uint32_t CONFIG_BOOT_VERSION_ADDR0 = CONFIG_OTA_CONFIG_PAGE_ADDR + 0x18U;
constexpr uint32_t CONFIG_BOOT_VERSION_ADDR1 = CONFIG_OTA_CONFIG_PAGE_ADDR + 0x1CU;
constexpr uint32_t CONFIG_OTA_CONFIG_WORD_COUNT = 8U;
/* ============================================================
* NVIC 优先级分组与中断优先级分层
* (EtherCAT 实时架构改造:PRE4_SUB0,4 �抢�优先级)
* ============================================================ */
constexpr uint32_t CONFIG_NVIC_PRIORITY_GROUP = NVIC_PRIGROUP_PRE4_SUB0;
constexpr uint32_t CONFIG_IRQ_PREEMPT_ETHERCAT_SYNC = 0U;
constexpr uint32_t CONFIG_IRQ_PREEMPT_SCHED = 1U;
constexpr uint32_t CONFIG_IRQ_PREEMPT_CAN = 2U;
constexpr uint32_t CONFIG_IRQ_PREEMPT_ETHERCAT_ESC = 1U;
constexpr uint32_t CONFIG_IRQ_PREEMPT_ETHERCAT_SYNC1 = 1U;
constexpr uint32_t CONFIG_IRQ_PREEMPT_SPI_USART = 3U;
/* ============================================================
2026-07-20 02:36:56 +08:00
* EtherCAT LAN9252 �置(开关�顶部 CONFIG_MAIN_LOOP_WFI / ETHERCAT_SYNC_MODE)
* ============================================================ */
/* 1.5.27:CONFIG_ETHERCAT_ISR_MAX_US_THRESHOLD / CONFIG_ESC_PDI_INPUT_OFFSET /
* CONFIG_ESC_PDI_OUTPUT_OFFSET / CONFIG_ETHERCAT_PDO_SIZE �死代� EthercatSlave::
* periodicIsr 三缓冲一并删除;PDO 交�由 SSC(dc_app.c APPL_*, 4×64bit=32B) 完�。 */
/* ---------- EXMC 引脚�置(GD32E508 EXMC 标准映射) ---------- */
constexpr uint32_t CONFIG_ESC_EXMC_BASE_ADDR = 0x60000000U;
/* Region0 = NE0 @ 0x60000000(GD32E50x 用户手册 Rev2.2 图25-3: Bank0 四 Region � 64MB,
* HADDR[27:26]=00 选中 NE0)。LAN9252 CS 接 PD7=EXMC_NE0(数�手册 GD32E508xx
* Datasheet Rev1.8 LQFP100 引脚表: PD7 Alternate2 = EXMC_NE0/EXMC_NCE1)。
* 注�: GD32E508Vx (LQFP100) �装�引出 NE0 一个 NOR/SRAM 片选引脚,
* NE1~NE3 仅在 LQFP144 (Zx) 上存在;因此必须使用 Region0(SNCTL0),�能用 Region1。 */
#ifndef EXMC_BANK0_NORSRAM_REGION0
#define EXMC_BANK0_NORSRAM_REGION0 ((uint32_t)0x00000000U)
#endif
#define CONFIG_ESC_EXMC_BANK_NOR_SRAM_REGION0 EXMC_BANK0_NORSRAM_REGION0
/* ---------- ESC 中断引脚(PB0/PB1/PB2,三个独立 EXTI ��) ---------- */
/** @note �留 PA0 给未� STANDBY 模�唤醒(WKUP_PIN0)。 */
constexpr uint32_t CONFIG_ESC_SYNC0_PORT = GPIOB;
constexpr uint32_t CONFIG_ESC_SYNC0_PIN = GPIO_PIN_0;
constexpr exti_line_enum CONFIG_ESC_SYNC0_EXTI = EXTI_0;
constexpr IRQn_Type CONFIG_ESC_SYNC0_IRQn = EXTI0_IRQn;
constexpr uint32_t CONFIG_ESC_SYNC0_EXTI_SOURCE_PORT = GPIO_PORT_SOURCE_GPIOB;
constexpr uint32_t CONFIG_ESC_SYNC0_EXTI_SOURCE_PIN = GPIO_PIN_SOURCE_0;
constexpr uint32_t CONFIG_ESC_IRQ_PORT = GPIOB;
constexpr uint32_t CONFIG_ESC_IRQ_PIN = GPIO_PIN_1;
constexpr exti_line_enum CONFIG_ESC_IRQ_EXTI = EXTI_1;
constexpr IRQn_Type CONFIG_ESC_IRQ_IRQn = EXTI1_IRQn;
constexpr uint32_t CONFIG_ESC_IRQ_EXTI_SOURCE_PORT = GPIO_PORT_SOURCE_GPIOB;
constexpr uint32_t CONFIG_ESC_IRQ_EXTI_SOURCE_PIN = GPIO_PIN_SOURCE_1;
constexpr uint32_t CONFIG_ESC_SYNC1_PORT = GPIOB;
constexpr uint32_t CONFIG_ESC_SYNC1_PIN = GPIO_PIN_2;
constexpr exti_line_enum CONFIG_ESC_SYNC1_EXTI = EXTI_2;
constexpr IRQn_Type CONFIG_ESC_SYNC1_IRQn = EXTI2_IRQn;
constexpr uint32_t CONFIG_ESC_SYNC1_EXTI_SOURCE_PORT = GPIO_PORT_SOURCE_GPIOB;
constexpr uint32_t CONFIG_ESC_SYNC1_EXTI_SOURCE_PIN = GPIO_PIN_SOURCE_2;
/* ---------- ESC 硬件��(PB10 → LAN9252 Pin11 RST#,SCH 第1页 Pin47) ---------- */
/** @note 2026-08-22(1.5.25) �固件从未�始化 PB10,RST# 仅� R44 10k 上拉自然释放,
* �满足 LAN9252 手册 18.6.3 tpurstd(电�稳定→RST#释放)≥25ms�trstia(低脉宽)≥200µs。
* 由 EscLan9252::hardwareReset() 执行�控���列;释放���推挽输出高,
* GD32 自身��期间引脚回浮空,由 R44 上拉维�高,�会误�� ESC。 */
constexpr uint32_t CONFIG_ESC_NRST_PORT = GPIOB;
constexpr uint32_t CONFIG_ESC_NRST_PIN = GPIO_PIN_10;
constexpr uint32_t CONFIG_ESC_NRST_ASSERT_MS = 30U; /* 低脉宽,�时覆盖 tpurstd 25ms 与 trstia 200µs */
constexpr uint32_t CONFIG_ESC_HBI_POLL_TIMEOUT_MS = 300U; /* RST# 释放�等待 ESC �动/EEPROM 加载 */
constexpr uint32_t CONFIG_ESC_HBI_POLL_STEP_MS = 5U;
/* ---------- EXMC 数�/控制线引脚(GD32E508 标准映射) ---------- */
constexpr uint32_t CONFIG_EXMC_D0_PORT = GPIOD; constexpr uint32_t CONFIG_EXMC_D0_PIN = GPIO_PIN_14;
constexpr uint32_t CONFIG_EXMC_D1_PORT = GPIOD; constexpr uint32_t CONFIG_EXMC_D1_PIN = GPIO_PIN_15;
constexpr uint32_t CONFIG_EXMC_D2_PORT = GPIOD; constexpr uint32_t CONFIG_EXMC_D2_PIN = GPIO_PIN_0;
constexpr uint32_t CONFIG_EXMC_D3_PORT = GPIOD; constexpr uint32_t CONFIG_EXMC_D3_PIN = GPIO_PIN_1;
constexpr uint32_t CONFIG_EXMC_D4_PORT = GPIOE; constexpr uint32_t CONFIG_EXMC_D4_PIN = GPIO_PIN_7;
constexpr uint32_t CONFIG_EXMC_D5_PORT = GPIOE; constexpr uint32_t CONFIG_EXMC_D5_PIN = GPIO_PIN_8;
constexpr uint32_t CONFIG_EXMC_D6_PORT = GPIOE; constexpr uint32_t CONFIG_EXMC_D6_PIN = GPIO_PIN_9;
constexpr uint32_t CONFIG_EXMC_D7_PORT = GPIOE; constexpr uint32_t CONFIG_EXMC_D7_PIN = GPIO_PIN_10;
constexpr uint32_t CONFIG_EXMC_D8_PORT = GPIOE; constexpr uint32_t CONFIG_EXMC_D8_PIN = GPIO_PIN_11;
constexpr uint32_t CONFIG_EXMC_D9_PORT = GPIOE; constexpr uint32_t CONFIG_EXMC_D9_PIN = GPIO_PIN_12;
constexpr uint32_t CONFIG_EXMC_D10_PORT = GPIOE; constexpr uint32_t CONFIG_EXMC_D10_PIN = GPIO_PIN_13;
constexpr uint32_t CONFIG_EXMC_D11_PORT = GPIOE; constexpr uint32_t CONFIG_EXMC_D11_PIN = GPIO_PIN_14;
constexpr uint32_t CONFIG_EXMC_D12_PORT = GPIOE; constexpr uint32_t CONFIG_EXMC_D12_PIN = GPIO_PIN_15;
constexpr uint32_t CONFIG_EXMC_D13_PORT = GPIOD; constexpr uint32_t CONFIG_EXMC_D13_PIN = GPIO_PIN_8;
constexpr uint32_t CONFIG_EXMC_D14_PORT = GPIOD; constexpr uint32_t CONFIG_EXMC_D14_PIN = GPIO_PIN_9;
constexpr uint32_t CONFIG_EXMC_D15_PORT = GPIOD; constexpr uint32_t CONFIG_EXMC_D15_PIN = GPIO_PIN_10;
constexpr uint32_t CONFIG_EXMC_A16_PORT = GPIOD; constexpr uint32_t CONFIG_EXMC_A16_PIN = GPIO_PIN_11;
2026-07-20 02:36:56 +08:00
/* A17 (PD12) 用于 HBI Indexed Mode 访问 HBI_DATA_0 寄存器,已将 LAN9252 A2 (Pin 29) 接到 PD12。
* 注� LAN9252 引脚顺�:Pin25=A1, Pin26=A3, Pin27=A4, Pin28=CS, Pin29=A2。
* A2 是 IDX/DATA 选择�,必须接到 PD12 �能访问 DATA 寄存器,EEPROM 烧录功能�用。
* 注� EXMC 16-bit 模�地�左移 1 �(用户手册 p869):A16(PD11)=CPU �移 0x20000�
* A17(PD12)=CPU �移 0x40000,HBI_DATA_0 访问�移� esc_lan9252.cpp。 */
2026-07-20 02:36:56 +08:00
constexpr uint32_t CONFIG_EXMC_A17_PORT = GPIOD; constexpr uint32_t CONFIG_EXMC_A17_PIN = GPIO_PIN_12;
constexpr uint32_t CONFIG_EXMC_NOE_PORT = GPIOD; constexpr uint32_t CONFIG_EXMC_NOE_PIN = GPIO_PIN_4;
constexpr uint32_t CONFIG_EXMC_NWE_PORT = GPIOD; constexpr uint32_t CONFIG_EXMC_NWE_PIN = GPIO_PIN_5;
/* LQFP100 �有 NE0(PD7) 一个 NOR/SRAM 片选,归 Region0(0x60000000);命�沿用硬件真值 NE0。 */
constexpr uint32_t CONFIG_EXMC_NE0_PORT = GPIOD; constexpr uint32_t CONFIG_EXMC_NE0_PIN = GPIO_PIN_7;
#endif /* SYS_CONFIG_H */