警告
This document is not updated for ESP32C61 yet, so some of the content may not be correct.
This warning was automatically inserted due to the source file being in the add_warnings_pages list.
ESP SDIO 主从机通信
本文档介绍了 ESP 数字输入输出 (Secure Digital Input and Output,SDIO) 从机设备的初始化过程,并提供 ESP SDIO 从机协议的详细信息。该协议为非标准协议,允许 SDIO 主机与 ESP SDIO 从机进行通信。
创建 ESP SDIO 从机协议是为了实现 SDIO 主机和从机之间的通信。这是因为 SDIO 规范只说明了如何访问卡的自定义区(向功能 1-7 发送 CMD52 和 CMD53),却没有说明底层的硬件实现过程。
乐鑫芯片的 SDIO 从机功能
ESP32-C61 芯片的 SDIO 从机提供以下服务:
服务 |
ESP32-C61 |
---|---|
SDIO 从机 |
Y |
8 |
|
8 |
|
Y |
|
Y |
|
56* |
* 未包括中断寄存器
初始化 ESP SDIO 从机
主机需按照标准的 SDIO 初始化流程,对 ESP32-C61 SDIO 从机进行初始化(参考 SDIO Simplified Specification 3.1.2 章节)。下文将 SDIO 从机简称为 SD/SDIO 卡。以下是 ESP SDIO 从机初始化流程的一个简单示例:
SDIO 复位
CMD52(写入 0x6 = 0x8)
SD 复位
CMD0
检查 IO 卡(可选)
CMD8
发送 SDIO op cond 指令,等待 IO 卡就绪
CMD5 arg = 0x00000000
CMD5 arg = 0x00ff8000(根据以上响应进行轮询,直到 IO 卡就绪)
示例:
首次 CMD5 (arg = 0x00000000) 后 R4 的 arg 为 0xXXFFFF00。
不断发送 CMD5 arg = 0x00FFFF00,直到 R4 显示卡已就绪 (arg 31 = 1) 为止。
设置地址
CMD3
选择卡
CMD7(根据 CMD3 响应设置 arg)
示例:
CMD3 后 R6 的 arg 为 0x0001xxxx。
CMD7 的 arg 应为 0x00010000。
选择 4-bit 模式(可选)
CMD52(写入 0x07 = 0x02)
启用 Func1
CMD52(写入 0x02 = 0x02)
启用 SDIO 中断(使用中断线 (DAT1) 时必要)
CMD52(写入 0x04 = 0x03)
设置 Func0 块大小(可选,默认为 512 (0x200) 字节)
CMD52/53(读取 0x10 ~ 0x11)
CMD52/53(写入 0x10 = 0x00)
CMD52/53(写入 0x11 = 0x02)
CMD52/53(再次读取 0x10 ~ 0x11, 检查最终写入的值)
设置 Func1 块大小(可选,默认为 512 (0x200) 字节)
CMD52/53(读取 0x110 ~ 0x111)
CMD52/53(写入 0x110 = 0x00)
CMD52/53(写入 0x111 = 0x02)
CMD52/53(再次读取 0x110 ~ 0x111, 检查最终写入的值)
ESP SDIO 从机协议
ESP SDIO 从机协议基于 SDIO 规范的 I/O 读/写命令(即 CMD52 和 CMD53)创建。该协议提供以下服务:
发送 FIFO 和接收 FIFO
52 个主从机共享的 8 位读写寄存器(要了解详细信息,请参考 ESP32-C61 技术参考手册 > SDIO 从机控制器 > 寄存器列表 > SDIO SLC Host 寄存器 [PDF])
16 个通用中断源,其中 8 个从主机到从机的中断源,8 个自从机到主机的中断源。
开始通信前,主机需启用从机的 I/O Function 1,访问从机的寄存器,如下所示。
代码示例:peripherals/sdio
ESP32 SDIO 用作主机与 ESP32 SDIO 从机通信时,协议中涉及的逻辑由 ESP 串行从机链路 组件实现。
中断
SDIO 中断属于电平敏感中断。对于主机中断,从机通过在适当时间拉低 DAT1 线的方式发送中断。当该中断线被拉低后,主机会检测到变化并读取 INT_ST 寄存器,确定中断源。然后,主机写入 INT_CLR 寄存器清除中断位,并处理中断。主机也可以清除 INT_ENA 寄存器中相应位以屏蔽不需要的源。如果所有源都已清除或已屏蔽,DAT1 线状态无效。
ESP32-C61 上对应的 host_int 位:0 至 7。
对于从机中断,主机发起一次传输,将数据写入 SLAVE_INT 寄存器。一旦某位被写入 1,从机硬件和驱动程序就会检测到变化,通知应用程序。
接收 FIFO
要写入从机的接收 FIFO,主机应完成以下步骤:
读取 TOKEN_RDATA (0x044) 寄存器的 TOKEN1 字段(27-16 位)。 剩余的缓冲数量为 TOKEN1 减去主机使用的缓冲数量。
确保有足够的 buffer,(buffer_size x buffer_num 应大于要写入数据的长度,buffer_size 是主机和从机在开始通信前预定义的值)。如果 buffer 不够,重复步骤 1,直至满足要求为止。
用 CMD53 写入 FIFO 地址。注意, requested length 不应超过步骤 2 中计算出的长度,FIFO 地址与 requested length 有关。
计算已使用的缓冲。 注意,尾部的缓冲即使仅部分使用,也属于已使用的范围。
发送 FIFO
要读取从机的发送 FIFO,主机应完成以下步骤:
等待中断线有效。(可选,默认为低电平)
读取(轮询)INT_ST 寄存器中的中断位,以监控是否存在新数据包。
如果新数据包已准备就绪,读取 PKT_LEN 寄存器。在读取数据包之前,确定要读取数据的长度。由于主机会保留已从从机中读取的数据的长度,因此,要从 PKT_LEN 中减去该值,得到可读取的最大数据长度。如果发送 FIFO 中尚未写入过数据,则继续等待并轮询,直到从机准备就绪,然后更新 PKT_LEN。
用 CMD53 从 FIFO 中读取数据。注意, 要求长度 应不大于步骤 3 中计算出的长度,FIFO 地址与 要求长度 相关。
更新读取长度。