作者:下家山
五.多字节传输
ID号已经读出来了,
CMD52只是对单个寄存器进行读写操作,而SDIO的优势是多字节传输。SDIO的协议规范专门定义了一个命令CMD53来实现。
多字节传输又分流方式和块方式。(Stream Mode or Block Mode)
因为,要挂接DMA,所以我这里先介绍BlockMode。
5.1 如何着手
调试这类设备,一般是先写,然后读,看读出来的是否与写进去的相等。但,有时对一个全新的东西没有一点把握,此时可先读,看读出来的是不是那么回事。(如何把SDIO挂接到DMA上去,我这里就不介绍了)
5.2对CMD53的理解
S,D,Command Index,R/W Flag,CRC7,E这些域应该不用解释了;
Function Number:在实际配置命令参数时,应该设置为多少呢?还记得发送CMD后的响应值吗,你这里的值要根据它来设置,在我的例子中,CMD5返回值中Function Number为1(即可支持到FN0和FN1),因为FN0中存放的是common CIS,所以,要读写卡内存,应该用FN1,故这里设置到1.
Block Mode: 设置到1;
OP code: 设置到0(固定地址);(我还没有完全搞懂 )
RegisterAddress: 设置到0;(我还没有完全搞懂 )
Byte/BlockCount: 设置到2,表示只传输2个块。
注意:如果BlockMode设置到0,表示以流方式(Stream)传输,Byte/BlockCount就应该是要传输的字节数;如果BlockMode设置到1,表示以块方式(Block)传输,Byte/BlockCount就应该设置为要传输的块的数目。
5.3 以块方式读10个字节
5.3.1 CMD53配置
rSDICARG == 0x18000002;
rSDICCON == 0x00000B75;
响应
rSDICSTA == 0x00000A35;
rSDIRSP0 == 0x00001300;
解读0x00000B75(略)
解读0x00000A35(略)
解读0x00001300:参照R5可知发生了command out of range! invalid function number!两个错误。对于这两个问题,因Function Number错误只涉及到一个位,所以先解决这个问题。根据参考代码(我这里有一份Marvell-wifi-sdio-card代码)发现有操作CCCR的02寄存器,但当时也没有去在意这个操作,后来细读SDIO规范,发现I/O enable这个寄存器是个非常重要的寄存器。
看到了吗?I/O Enable控制着IOE1~IOE7,这七个IOE对应着FN1—FN7,
所以要用FN1功能就必须使能IOE1。
对I/O Enable的操作是通过CMD52来实现的。
5.3.2 对CCCR I/O Enable的操作
CMD52配置
rSDICARG == 0x80000402;
rSDICCON == 0x00000B74;
响应
rSDICSTA == 0x00000A34;
rSDIRSP0 == 0x00001002;
解读
0x00000B74(略)
0x00000A34(略)
0x00001002: 低8位表示写到I/O Enable寄存器的值为2。
回到5.3.1,再次发送CMD53(内容略)。
这次响应值为
rSDIRSP0 == 0x00001100;
说明invalid function number错误已解决;还剩下command out of range错误,造成这个错误的
原因比较多,所以很难定位。这个地方花了我比较长的时间,后来同事提醒我块的尺寸设置没有(他
当时也在帮我看着部分),我突然想起参考代码有这个动作,只不过他放在写块中,而我调试的是读
块动作。所以,我马上把这个动作加进去了,果然得到了回应码0x00001000;
5.3.3 对FN1的I/O block size的操作
CMD52配置
设置block size低8位
rSDICARG == 0x8002200A;
rSDICCON == 0x00000B74;
响应
rSDICSTA == 0x00000A34;
rSDIRSP0 == 0x0000100a;
解读 0x00000B74(略)
0x00000A34(略) 0x0000100a: 低8位表示设置到FN1 Block Size大小的低字节为0x0a。
设置block size高8位
rSDICARG == 0x80022200;
rSDICCON == 0x00000B74;
响应
rSDICSTA == 0x00000A34;
rSDIRSP0 == 0x00001000;
解读 0x00000B74(略)
0x00000A34(略) 0x00001000: 低8位表示设置到FN1 Block Size大小的高8位为0x00。回到5.3.1,再次发送CMD53(内容略)。这次响应值为
rSDIRSP0 == 0x00001000; OK!
而且,DMA中断发生了,并且得到了读出来的值。但,因不知道这读出来的20个字节为何物,所以还得先写,如果都以块操作应该没什么问题。
文章评论(0条评论)
登录后参与讨论