在工业以太网与运动控制应用中,Microchip的LAN9252 EtherCAT从站控制器因其高集成度而备受青睐。在与主控器(如Xilinx ZYNQ)通信时,SPI接口是常用选择。然而,标准SPI的带宽有时会成为性能瓶颈。为此,将其升级至Quad SPI(QSPI)模式,充分利用四线并行数据传输能力,是提升吞吐量的有效途径。
在ZYNQ平台上实现LAN9252的驱动,主要有三种路径:
- 使用PS端的SPI并通过EMIO驱动:这种方式相对灵活稳定,但受限于PS端SPI外设,通常无法原生支持QSPI模式。
- 调用PL侧的AXI-QUAD-SPI IP核:理论上,该IP应支持SPI与QSPI的灵活配置。但在实际应用(例如Vivado 2022.2版本)中发现,其模式切换较为固定,通常仅对特定指令序列支持QSPI,且稳定性不佳,易出现通信卡死现象。
- 自主编写AXI Quad SPI IP核:这是实现最高灵活性和控制权的方案,可以精确适配LAN9252的QSPI协议要求。
最初尝试方案二后,笔者更推荐方案一用于标准SPI驱动;若追求QSPI的高性能,则方案三是更可靠的选择。在从SPI转向QSPI的自研过程中,时序设计是关键,尤其需要注意以下两个容易忽略的“坑”。
关键陷阱一:数据采样沿的选择
根据常规SPI时序理解,数据在时钟(SCK)的下降沿由从设备输出,主机在随后的上升沿进行采样。如果直接套用此逻辑驱动LAN9252的QSPI,则很可能无法正确读取数据。
问题根源在于LAN9252数据手册中关于读时序的参数定义。其中关键时序参数如下:
- t_v: 从SCK到数据输出有效的时间。在负载为30pF和10pF时,典型值分别为11.0 ns和9.0 ns。
- t_ho: SCK之后数据输出的保持时间,为0 ns。
- t_dis: 从片选(SCS#)无效到数据输出禁止的时间。
更关键的是手册中的一条注释(注5):数据有效性取决于时钟频率和脉冲宽度,数据直到SCK的下一个上升沿之后才会稳定有效。因此,主机SPI控制器可能需要将数据采样延迟一段固定时间,或者直接使用SCK的下降沿对数据进行采样。
这意味着,对于主机(FPGA)而言,最稳妥的采样时刻不是在SCK的上升沿,而是在其下降沿。同时,如果系统运行在80MHz(周期12.5ns),而t_v参数高达11ns,留给数据建立和稳定的时间裕量非常紧张,极易导致采样错误。因此,为保证通信稳定性,建议在初期将QSPI时钟频率设定在50MHz以下,待时序调优后再尝试提升至80MHz。
关键陷阱二:读/写指令的空位(Dummy Cycles)差异
在QSPI模式下,另一个容易因惯性思维而出错的地方是“空字节”(Dummy Bytes)或“空位”(Dummy Cycles)的使用。在标准SPI的快速读(FAST READ)指令中,通常在发送地址后会跟随若干个空时钟周期,等待从设备准备数据。
然而,查阅LAN9252支持的QSPI指令集可以发现,写操作指令序列中不包含空位。这一点在设计状态机和控制逻辑时必须特别注意。
LAN9252支持丰富的SPI/QSPI操作指令,其格式与位宽定义如下表所示(位宽度格式为:命令位宽度 / 地址或空位宽度 / 数据位宽度):
| 操作类型 |
指令名称 |
描述 |
位宽格式 |
十六进制命令 |
地址字节数 |
参数位 |
频率范围 |
| 读操作 |
READ |
标准读操作 |
1-1-1 |
03h |
2 |
0 |
≤30 MHz |
|
FASTREAD |
快速读操作 |
1-1-1 |
0Bh |
2 |
1 |
≤80 MHz |
|
SDOR |
SPI双输出读 |
1-1-2 |
3Bh |
2 |
1 |
≤80 MHz |
|
SDIOR |
SPI双输入输出读 |
1-2-2 |
BBh |
2 |
2 |
≤80 MHz |
|
SQOR |
SPI四输出读 |
1-1-4 |
6Bh |
2 |
1 |
≤80 MHz |
|
SQIOR |
SPI四输入输出读 |
1-4-4 |
EBh |
2 |
4 |
≤80 MHz |
| 写操作 |
WRITE |
标准写操作 |
1-1-1 |
02h |
2 |
0 |
≤80 MHz |
|
SDDW |
SPI双数据写 |
1-1-2 |
32h |
2 |
0 |
≤80 MHz |
|
SDADW |
SPI双地址/数据写 |
1-2-2 |
B2h |
2 |
0 |
≤80 MHz |
|
SQDW |
SPI四数据写 |
1-1-4 |
62h |
2 |
0 |
≤80 MHz |
|
SQADW |
SPI四地址/数据写 |
1-4-4 |
E2h |
2 |
0 |
≤80 MHz |
注:表格中高亮显示的SQOR(四输出读)和SQDW(四数据写)是实现QSPI高速通信的核心指令。尤其注意“参数位”一列,读操作(如SQOR)需要1个空位,而对应的写操作(SQDW)则为0。
实现总结
上述两个时序细节上的“坑”,如果能够预先仔细研读数据手册是可以避免的。这也提醒我们,在进行底层硬件接口驱动开发,特别是涉及高速SPI通信时,对器件数据手册的深度理解至关重要。
关于在FPGA侧实现LAN9252 QSPI驱动的核心代码,其思路是通过自定义的AXI4-Lite接口IP核来配置和控制QSPI状态机,并利用FIFO缓冲读写数据。状态机需严格按照指令表(如发送6Bh指令进行四线读)和上述时序要求(如下降沿采样、正确处理空位)来设计。由于篇幅所限,具体代码实现可参考相关的开源项目或自行设计,其核心在于一个能够精确产生SCK时钟、并协调CS#、IO引脚变化的状态机。
参考资料
[1] 让LAN9252飞起来:全面升级为Quad SPI的高性能实践, 微信公众号:mp.weixin.qq.com/s/hEKdoVJ8Zd2P7k1xLpT5HQ
版权声明:本文由 云栈社区 整理发布,版权归原作者所有。
|