Files
cbb cfe7725b26 feat(ethercat): LAN9252 bring-up完成,EEPROM烧录改主站侧并增强DC/AL可观测性
- 新增ESC硬件复位序列(1.5.25):PB10驱动LAN9252 RST#,拉低30ms+释放后300ms轮询HBI就绪,
  满足tpurstd/trstia时序;此前RST#仅靠R44上拉自然释放
- 修正EXMC 16-bit地址左移(1.5.27):HBI DATA偏移0x20000/0x30000→0x40000/0x60000;
  ADDSET 2→4 HCLK;片选更名NE1→NE0(LQFP100仅Region0)
- 按LAN9252手册/AN1907修正EEPROM镜像(1.5.28):word1高字节0x00→0xCC(SYNC0/1 Map+Output,
  否则SYNC0留LATCH态DC过程数据死)、word2=5000(脉宽50µs)、尾部补真实0xFF;
  gen_eeprom.py按ETG.1000.6重写;DCU_ESI.xml PDI 0x05→0x8D、RxPdo/TxPdo互换改4×64bit对齐
- 删除GD32侧EEPROM烧录路径(1.5.29):移除EscEeprom/esc_eeprom、eeprom_image.h及主循环
  烧录块,ESI镜像改由主站ecat_flash_eeprom.py经ESC 0x0500刷写(162字全校验通过);
  HBI互斥补屏蔽EXTI2(SYNC1),防Sync1_Isr两步事务打断主循环HBI访问致错址
- DC SYNC0通路可观测(1.5.30/31):EthercatSync新增sync0/sync1/escirq三个volatile计数器,
  task_runner 5s按增量打印速率;SSC OD新增只读0x2000 SYNC Diag,主站SDO轮询网页显示
- AL通路诊断(1.5.32):ECAT_Main/SetALStatus打印主站AL请求与写回状态+错误码,
  task_runner新增5s [ECAT][HB]心跳(仅同步ISR激活时);dc_app.c导出EcatDbg_ReadAlDiag
- 删除死代码EthercatSlave::periodicIsr三缓冲PDO桥,PDO交换由SSC完成(4×64bit=32B);
  EthercatSlave::init()恢复调用并以isBusReady()(BYTE_TEST)门控
- CANFD修复同通道突发只发3帧:transmitFrame新增allow_abort区分突发/软件队列路径,
  邮箱满落入软件TX队列(深度13)由TX完成中断drainTxQueueIsr回灌;BRS重新启用(0→1)
- motor_state新增CONFIG帧缓存(0x00000101, DLC 24)记录目标值回报,条目44B→76B、每页5→3
- SPI 0xA2诊断扩展action 20~24(ECAT_NRST拉低/拉高/浮空/回读);新增ESP32 EN自检打印
- 版本号更新至1.5.32
2026-09-01 03:07:48 +08:00

153 lines
6.1 KiB
C
Raw Permalink 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 el9800hw.h
* @brief SSC 硬件抽象层 — GD32E508 + LAN9252 (EXMC 16-bit HBI Indexed Mode)
*
* 本文件替换 Beckhoff EL9800 SPI 版本,提供 SSC 所需的 HW_EscRead/Write 宏
* 和中断/定时器控制宏。实际实现在 hw_gd32exmc.cpp。
*
* HBI Indexed 寻址(A2=LAN9252 Pin29←PD12=EXMC_A17, A1=Pin25←PD11=EXMC_A16;
* EXMC 16-bit 模式地址左移 1 位,EXMC_A16=CPU 偏移 0x20000、A17=0x40000):
* IDX_0 = EXMC offset 0x00000 (A2=0, A1=0)
* DATA_0 = EXMC offset 0x40000 (A2=1, A1=0) 低 16 位
* = EXMC offset 0x60000 (A2=1, A1=1) 高 16 位
*/
#ifndef _EL9800HW_H_
#define _EL9800HW_H_
/*-----------------------------------------------------------------------------------------
------
------ Includes
------
-----------------------------------------------------------------------------------------*/
#include "esc.h"
/* GD32E508 CMSIS (通过 RTE 组件获取) */
#include "RTE_Components.h"
#include CMSIS_device_header
/*-----------------------------------------------------------------------------------------
------
------ Hardware Timer Settings
------
-----------------------------------------------------------------------------------------*/
/** SSC 看门狗定时器分辨率:ticks per ms。
* 本项目使用 SysTick (180MHz / 1000 = 180000 ticks/ms)。
* 实际由 hw_gd32exmc.cpp 中 HW_GetTimer() 实现决定。 */
#define ECAT_TIMER_INC_P_MS 180000
/*-----------------------------------------------------------------------------------------
------
------ Interrupt Control (ESC IRQ = EXTI1, PB1)
------
-----------------------------------------------------------------------------------------*/
#ifndef DISABLE_ESC_INT
#define DISABLE_ESC_INT() NVIC_DisableIRQ(EXTI1_IRQn)
#endif
#ifndef ENABLE_ESC_INT
#define ENABLE_ESC_INT() NVIC_EnableIRQ(EXTI1_IRQn)
#endif
/*-----------------------------------------------------------------------------------------
------
------ AL Event Interrupt Mask (保留宏)
------
------ 1.5.27 起主循环 HBI 访问的互斥已内置到 hw_gd32exmc.cpp 的 HW_* 函数
------ (EscExmcBus::maskEnter/maskExit),SSC 源码不再需要显式调用本组宏。
------ 保留定义仅为兼容 SSC 变体中可能出现的引用。
-----------------------------------------------------------------------------------------*/
#ifndef DISABLE_AL_EVENT_INT
#define DISABLE_AL_EVENT_INT() do { NVIC_DisableIRQ(EXTI0_IRQn); NVIC_DisableIRQ(EXTI1_IRQn); } while(0)
#endif
#ifndef ENABLE_AL_EVENT_INT
#define ENABLE_AL_EVENT_INT() do { NVIC_EnableIRQ(EXTI1_IRQn); NVIC_EnableIRQ(EXTI0_IRQn); } while(0)
#endif
/*-----------------------------------------------------------------------------------------
------
------ Timer Access
------
-----------------------------------------------------------------------------------------*/
#ifndef HW_GetTimer
#define HW_GetTimer() HW_GetTimerValue()
#endif
#ifndef HW_ClearTimer
#define HW_ClearTimer() HW_ClearTimerValue()
#endif
/*-----------------------------------------------------------------------------------------
------
------ ESC Access Macros (SSC 核心接口)
------
------ MEM_ADDR = UINT16 (CONTROLLER_16BIT=1)
------ 所有宏最终调用 HW_EscRead / HW_EscWrite (hw_gd32exmc.cpp)
-----------------------------------------------------------------------------------------*/
#define HW_EscReadByte(ByteValue, Address) HW_EscRead(((MEM_ADDR *)&(ByteValue)), ((UINT16)(Address)), 1)
#define HW_EscReadWord(WordValue, Address) HW_EscRead(((MEM_ADDR *)&(WordValue)), ((UINT16)(Address)), 2)
#define HW_EscReadDWord(DWordValue, Address) HW_EscRead(((MEM_ADDR *)&(DWordValue)), ((UINT16)(Address)), 4)
#define HW_EscReadMbxMem(pData, Address, Len) HW_EscRead(((MEM_ADDR *)(pData)), ((UINT16)(Address)), (Len))
#define HW_EscReadByteIsr(ByteValue, Address) HW_EscReadIsr(((MEM_ADDR *)&(ByteValue)), ((UINT16)(Address)), 1)
#define HW_EscReadWordIsr(WordValue, Address) HW_EscReadIsr(((MEM_ADDR *)&(WordValue)), ((UINT16)(Address)), 2)
#define HW_EscReadDWordIsr(DWordValue, Address) HW_EscReadIsr(((MEM_ADDR *)&(DWordValue)), ((UINT16)(Address)), 4)
#define HW_EscWriteByte(ByteValue, Address) HW_EscWrite(((MEM_ADDR *)&(ByteValue)), ((UINT16)(Address)), 1)
#define HW_EscWriteWord(WordValue, Address) HW_EscWrite(((MEM_ADDR *)&(WordValue)), ((UINT16)(Address)), 2)
#define HW_EscWriteDWord(DWordValue, Address) HW_EscWrite(((MEM_ADDR *)&(DWordValue)), ((UINT16)(Address)), 4)
#define HW_EscWriteMbxMem(pData, Address, Len) HW_EscWrite(((MEM_ADDR *)(pData)), ((UINT16)(Address)), (Len))
#define HW_EscWriteByteIsr(ByteValue, Address) HW_EscWriteIsr(((MEM_ADDR *)&(ByteValue)), ((UINT16)(Address)), 1)
#define HW_EscWriteWordIsr(WordValue, Address) HW_EscWriteIsr(((MEM_ADDR *)&(WordValue)), ((UINT16)(Address)), 2)
#define HW_EscWriteDWordIsr(DWordValue, Address) HW_EscWriteIsr(((MEM_ADDR *)&(DWordValue)), ((UINT16)(Address)), 4)
#endif /* _EL9800HW_H_ */
/*-----------------------------------------------------------------------------------------
------
------ Function Prototypes
------
-----------------------------------------------------------------------------------------*/
#if _EL9800HW_
#define PROTO
#else
#define PROTO extern
#endif
#ifdef __cplusplus
extern "C" {
#endif
PROTO UINT8 HW_Init(void);
PROTO void HW_Release(void);
PROTO UINT16 HW_GetALEventRegister(void);
PROTO UINT16 HW_GetALEventRegister_Isr(void);
PROTO void HW_ResetALEventMask(UINT16 intMask);
PROTO void HW_SetALEventMask(UINT16 intMask);
PROTO void HW_SetLed(UINT8 RunLed, UINT8 ErrLed);
PROTO void HW_EscRead(MEM_ADDR *pData, UINT16 Address, UINT16 Len);
PROTO void HW_EscReadIsr(MEM_ADDR *pData, UINT16 Address, UINT16 Len);
PROTO void HW_EscWrite(MEM_ADDR *pData, UINT16 Address, UINT16 Len);
PROTO void HW_EscWriteIsr(MEM_ADDR *pData, UINT16 Address, UINT16 Len);
PROTO void HW_DisableSyncManChannel(UINT8 channel);
PROTO void HW_EnableSyncManChannel(UINT8 channel);
PROTO TSYNCMAN ESCMEM *HW_GetSyncMan(UINT8 channel);
/* Timer helpers (implemented in hw_gd32exmc.cpp) */
PROTO UINT32 HW_GetTimerValue(void);
PROTO void HW_ClearTimerValue(void);
#ifdef __cplusplus
}
#endif
#undef PROTO