SDIO命令与响应:命令格式与响应类型深度解析

好,聊完了SDIO的协议架构和8-bit模式的数据通路,咱们得把目光聚焦到最基础的交互单元——命令与响应上。说白了,主机和设备之间能不能好好说话,全靠这个。

我记得刚开始接触SDIO时,对手册里那些密密麻麻的命令格式挺头疼的。后来调了几个月的WiFi驱动,才摸清楚哪些是真正需要操心的,哪些只是纸面功夫。今天我们就把它揉碎了讲。

命令格式:48位的“密码本”

每一笔SDIO命令,无论功能多复杂,最终都以48位串行数据的形式在CMD线上传输。这个48位的结构非常固定,我习惯把它看作一个“密码本”。

位域 长度 (bit) 描述
起始位 1 固定为0,标志命令开始
传输位 1 方向标识:1表示主机→设备(命令)
命令索引 6 具体命令编号,共64种,如CMD0、CMD52
参数 32 命令的附加信息,比如地址、数据等
CRC7 7 校验位,保护命令索引+参数
结束位 1 固定为1,标志命令结束

举个例子,常用的CMD52(IO读写命令),它的48位结构就是按照这张表拼出来的。起始位是0,传输位是1,命令索引是101000(二进制),后面32位参数指明要访问的IO编号和读写操作,最后加上7位CRC和结束位1。

一个经验点:调WiFi驱动时,我经常用逻辑分析仪抓CMD线上的波形。看到一串101000开头的,就知道是CMD52在读写WiFi的寄存器。如果波形对不上,八成是主机端的时序参数配错了。

实用技巧:CRC7的计算虽然规范里写得很清楚,但我前期调试时发现,很多SoC的SDIO控制器已经硬件帮你算了。你其实只需要填好参数,控制器会自动把CRC7和结束位附着上去。真正需要你手工算CRC的,反而是一些底层验证工具。

响应类型:设备怎么回话?

主机发出命令后,设备要在NCR(命令响应时间)内回一个响应。响应格式跟命令很像,但它多了些设备状态信息。SDIO规范定义了多种响应类型,不过对我们WiFi开发来说,重点就三四种。

  • R1(正常响应):最常见,包含设备状态、RCA、卡状态等。CMD3、CMD9、CMD7都是R1响应。
  • R2(CID和CSD响应):136位长响应,用于读取设备标识符和寄存器数据。像CMD2(获取CID)就是R2。
  • R3(OCR响应):用于OCR寄存器读取,比如CMD8。在WiFi模块初始化时比较常用。
  • R5(IO响应):这是SDIO特有的,伴随CMD52和CMD53。它包含IO数据,比如你读一个寄存器,数据就在R5响应里返回。

你想想看,为什么需要这么多响应类型?其实就是为了效率。R5把IO读写的结果直接塞进响应里,省掉一次额外的数据传输。我做第一个WiFi驱动项目时,就在R5响应里踩过坑——有个寄存器我总是读到0xFF,后来才发现是主机没在CMD52命令里设置正确的Function Number。

新手常犯的错误:以为所有命令都会得到响应。并非如此!有些广播命令,比如CMD0(Go Idle State),它就是“放烟花”,设备收到后执行复位,但不返回响应。如果你写代码时给这命令加了等待响应的逻辑,就会一直超时。

关键命令解析:CMD52与CMD53

在SDIO 8-bit模式下,WiFi驱动主要跟两个命令打交道:CMD52和CMD53。我敢说,80%的WiFi配置工作都靠它们完成。

  • CMD52 (IO读写):单字节读写。参数里携带Function Number、地址、读写方向和数据。响应是R5,里面那个数据域就是你要读的结果。
  • CMD53 (IO扩展读写):支持多字节、块传输。8-bit模式下尤其好用,因为它能拉满带宽。参数里除了地址,还有字节数/块数,以及是Byte Mode还是Block Mode。

举个例子,初始化时我们要从一个WiFi模块的IO-0地址0x100读其版本号,就会发一个CMD52读命令。如果我们要下载固件到WiFi模块中,那就用CMD53写模式,一次传个几千字节。

避坑指南:曾经我在一个项目中,CMD53的参数配置错了块大小。我在Block Mode下把块大小设为512,但芯片的FIFO只有256字节。结果每次传输都卡死——因为设备认为数据没完,而主机不知道。后来我改成Byte Mode才解决问题。所以,用CMD53之前,一定要搞清楚设备的Buffer能吞下多少字节。

命令与响应的时序节奏

命令和响应的执行,不是一锤子买卖。主机发完命令后,必须留出一个NCR窗口。这个窗口至少8个时钟周期,最多不超过64个时钟周期。如果设备没响应,主机就得做超时处理。

我刚开始用逻辑分析仪看SDIO波形时,总以为CMD线上只有命令和数据。后来才发现,波形里还有很多“空白”间隔。那些不是浪费,而是给设备喘息和准备数据的时间。尤其在8-bit模式下,数据吞吐量大,设备需要更多时间处理内部逻辑。

现在我们把整个交互逻辑画出来。这会帮你理解,主机和设备在初始化、配置、数据传输时怎么协作。

SDIO命令与响应交互流程 主机与设备命令响应交互 主机 (Host) 设备 (Device) 命令 (CMD线) NCR等待 (8-64个时钟) 响应 (CMD线) 设备内部处理 返回R5响应 (含IO数据) 响应 (CMD线) 注:主机必须严格等待NCR(命令响应时间)窗口内的任意时刻收到响应,超时则视为设备未应答。 WIFI驱动中,CMD53在8-bit模式下常配合块传输,单次可传4KB数据,减少命令开销。

图中把整个流程串起来了。你可以看到,真正的“命令-响应”时间很短,主要的开销其实在NCR等待和设备内部处理。8-bit模式之所以快,不是因为命令变快了,而是因为每个时钟周期能吞吐的数据量翻了8倍。

写在最后

整个SDIO的命令响应系统,其实就是个精心设计的“一问一答”机制。命令格式固定,响应类型分得很清楚。WiFi驱动开发时,你把CMD52和CMD53玩熟了,剩下的事情就是调参数、调时序。为什么我需要一个NCR窗口?因为设备也需要时间喘气。为什么CRC7只保护命令和参数,不保护起始结束位?因为起始结束位是信号边缘检测的,容错率够高。

记住一点:SDIO的主机控制器通常很智能,硬件会帮你把很多底层细节处理掉。但一旦遇到莫名其妙的问题,一定要回到这个48位的“密码本”上,用逻辑分析仪逐位去对。它永远不会骗你。