您尚未登录。

楼主 # 昨天 16:36:21

狼狼
会员
注册时间: 2020-06-14
已发帖子: 111
积分: 150

ZYNQ的QSPI裸机驱动库使用注意事项分享

斗胆分享一下早先使用ZYNQ裸机编程过程中的一些笔记,希望能帮到有需要的人。

测试使用 ZYNQ7020 + Vitis2022.2。

QSPI 控制器的底层寄存器接口是 32bit 的,因此驱动库会根据收发数据的长度进行拼接或移位处理,使得发送的数据序列形成如 sizeof(uint32_t) * N + RemainBytes 的形式。这里简要说明下在裸机环境使用 XQSPIPS 库对 Flash 编程时需要注意的一些事项。

1 驱动库中没有对包含 DUMMY 字节指令的特殊处理

QSPI 的驱动库和普通 SPI 驱动库的不同之处在于,它提供了对 Flash 操作命令的一些封装,即它的设计面向场景即对 Flash 的操作。驱动库内部有一个 XQspiPsInstFormat FlashInst[] 结构体数组,位于 xqspips.c 文件中,其中预先定义了一些命令的长度信息。

image-20250825133711919.png

但是这些长度信息的使用上,似乎没有考虑到部分指令存在 DUMMY 字节的情况。这意味着,驱动库试图对指令和地址的“头部”信息进行判断,但是其后的数据格式并不关心。而如果需要使用包含 DUMMY 的指令,上层函数必须额外管理一个指令表,驱动库不能实现对这些指令荷载字段的剥离和提取操作。

DUMMY 字节在通信中的位置是:指令-地址-DUMMY-数据,是插入的无效通信周期。例如对于 FAST READ命令,需要8个 dummy cycle,即 1 字节。

image-20250825133925173.png

2 使用预定义指令访问寄存器接口时,单次读取长度不可超过指令定义长度

在测试中,使用 s32 XQspiPs_PolledTransfer(XQspiPs *InstancePtr, u8 *SendBufPtr, u8 *RecvBufPtr, u32 ByteCount) 函数接口执行 RDSR 操作读取状态寄存器进行测试。

RDSR 的单线模式读写时序如下:

image-20250825134539612.png

在 1 字节命令后如果执行连续读取,则始终传递所访问 SR 寄存器的 8bit 值。

但是实际测试中,当试图直接使用 XQspiPs_PolledTransfer API 连续访问时,由于驱动库中的限制,会导致实际访问周期加长,从而后续再调用 QSPI 接收会收到无效数据。

例程中对 0xB00000 位置执行 4K 扇区擦除,向 0xB00000 位置写入256 字节,而后向 0xB00000 位置读取 256 字节。程序打印和解读如下图所示。

image-20250825143722043.png

其它的命令执行都是正确的,但是对于 RDSR 命令,实际的读取波形是:

image-20250825141444502.png

驱动库在 RDSR 指令之后发起了多达 7 次的读取,而每一次的后 4 字节的周期似乎被延迟到了后续通过 API 执行读操作的过程中取出(虽然取出后的数据并不正确)。而当应用程序中将读写限制为一次,长度为2,即 05 XX 而非 05 XX XX 时,则 RDSR 命令波形和后续读取都是正常的。

这个例子说明,使用官方库对 QSPI Flash 操作时,对于已经存在的指令,应当按照实际长度进行多轮单次的读取,而不宜在一次操作中连续读取多次。

3 在超 4 字节数据发送场景下(如页编程),函数的 RecvBufPtr 参数必须为 NULL

在函数的后续处理中,又将指令和后续数据分开进行发送。收发缓冲区具有 FIFO,在进行收发处理时,分为两个阶段进行,即:

  • 先尝试将发送数据全部送入发送 FIFO 中;

  • 若存在剩余没有处理的(未发送/未接收)数据,则:

  • 在接收 FIFO 阈值范围内:

  • 若传入的接收缓冲区指针有效,则发送 DUMMY 数据(0xFFFFFFFF)直到全部数据长度处理完成;

  • 若传入的接收缓冲区指针无效(NULL),则发送在发送缓冲区中的剩余数据(从指令头取偏移)。

  • 执行其它必要的收发过程。

因此在调用 API 的时候必须注意,在数据发送场景下(典型如页编程),函数的 RecvBufPtr 参数必须为 NULL

当我们修复了上述问题,仍旧进行一次页编程,但是同时传递收发缓冲区指针看看。

image-20250825144533763.png

用 LA 抓一下波形可以看到,页编程的时候,数据就是错误的。

image-20250825144626210.png

驱动库中问题根源的代码片段如下。

image-20250825144745463.png

但是这个特性在函数注释中是没有提及的。所以如果不想改驱动库,那就在上层发起读请求的时候,令函数的 RecvBufPtr 参数为 NULL,即可适配大多数情况。

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn


东莞哇酷科技有限公司开发