资料一、
(1) Wifi卡的常用接口有:
–CF 接口
–USB接口
–SDIO接口
–SPI接口
–PCMCIA接口
很多时候,同一个wifi卡同时支持多种接口,譬如marvell的8686的wifi卡,既支持spi接口,也支持sdio接口.
(2) SD卡与SDIO卡的异同
1.SD卡使用的是SD卡协议,而SDIO卡使用的是SDIO协议;协议不一样,初始化/读写方式都不一样
2.ARK1600控制器既支持SD卡也支持SDIO卡,在驱动上完全可以做到同一个卡槽既支持SD卡也支持SDIO卡,甚至combo卡,因此在驱动上有个判断过程,判断插进来的是SD卡还是SDIO卡
3.两者的引脚定义不一样,尽管引脚个数都一样
(3)
•SDIO协议
–相对于SD协议,SDIO协议特有的命令有:cmd5,cmd52,cmd53
–cmd5命令相当于SD卡协议中的acmd41,用于匹配SDIO卡的电压
–对于SDIO卡中的单个寄存器的读写一般都使用cmd52命令,而对于多字节数据的读写则用cmd53命令。
–cmd53分字节和块传输模式
对于字节传输模式相当于SD协议的单块读写(cmd17,cmd24)
对于块传输模式相当于SD协议的块读写(cmd18,cmd25)
(4)
•Cmd53
–对于字节传输模式,它可以是1~512之间的任意长度的传输,而不是固定长度
–对于块传输模式,首先它的块长度可以人为设定,但不能超过规定的最大块长度
–相对于SD卡中的块传输模式,在最后一个块传输末尾,是不需要发送块停止命令的(cmd12)
--每个SDIO卡都由1~7个function (optional)和一个memory function(mandatory)组成
•什么是function ?
–所谓function,就是一个I/O设备,它实质就是一些寄存器的集合
(5) SDIO卡里function的组织分布
•CIA就是function0,也就是memory function,它每个SDIO卡所必须具有的,它里面包含了如下一些重要信息:
–SDIO协议的版本号,BUS MOD,块大小等。这些信息有些是只读的,有些是可读可写的
•Function1~7是可选的,根据具体的应用的不同,所包含的function数目也不一样,譬如我门使用的marvell的8686芯片,它就只有function0和function1
(6)sdio 1~4bit mode
PIN | SDIO 4-BIT MODE | SDIO 1-BIT MODE | ||
1 | CD/DAT3 | Data line 3 | N/C | Not used |
2 | CMD | Command line | CMD | Command line |
3 | VSS1 | Ground | VSS1 | Ground |
4 | VDD | Supply voltage | VDD | Supply voltage |
5 | CLK | Clock | CLK | Clock |
6 | VSS2 | Ground | VSS2 | Ground |
7 | DAT[0] | Data line 0 | DATA | Data line |
8 | DAT[1] | Data line1 or INT line | IRQ | Interruption |
9 | DAT[2] | Data line2 or read wait | RW | Read wait |
1.SDIO mode 同样也有1bit和4bit 总线模式
2.SD与SDIO卡的引脚的一个最大的区别是:SDIO有个中断引脚DAT[1],在4bit模式下,DAT[1]既做数据线,又做中断线,因此是分时复用的,在总线发送命令期间,DAT[1]用作中断线。
(7)SD
PIN | SD MODE | ||
1 | Name | Type | Description |
2 | CD/DATA3 | I/O/PP | Card detect/data line3 |
3 | CMD | Pp | Command/response |
4 | Vss1 | S | Ground |
5 | VDD | S | Supply voltage |
6 | Vss2 | S | Ground |
7 | DAT0 | I/O/PP | Data line0 |
8 | DAT1 | I/O/PP | Data line1 |
9 | DAT2 | I/O/PP | Data line2 |
•当HOST同时连接多个卡时:
–时钟,电源,地线可以为每个卡公共
–但每个卡都有自己单独的数据和命令总线,避免干扰
–在卡的初始化过程中,命令是单独发到每个卡的,允许驱动来检测每个卡槽的卡是否存在,并且分配相应的逻辑地址给每个卡槽。
–HOST与每个卡槽的卡的数据传输都是单独进行的,因为每个卡槽都有自己的数据总线
–在卡的初始化完成后,命令可以同时发送到每个卡槽,因为此时命令中已经包含了卡的逻辑地址(在卡的分别初始化时分配的)
(8)SD卡与SDIO卡的检测判别
–上电,发送CMD5命令,如果有响应,并且响应中的MP位为0,说明对应卡槽中的卡为SDIO卡,进而开始SDIO卡的初始化流程
–如果发送CMD5命令没有响应,则说明对应卡槽的卡为SD或MMC卡,进而开始SD/MMC卡的初始化流程
–如果发送CMD5命令,有响应,且响应中的MP位为1,说明这个卡不但是SDIO卡,同时也时SD卡,也就是所谓的combo卡,则进行combo卡的初始化流程
(9)目前linux下,已支持的wifi卡有如下厂家的卡:
–Marvell 8385 and Marvell 8686
–Intersil公司 Prism54 chips series
–Intel IWL4965 and IWL3945
–Atheros corporation 5xxx chipset
–Broadcom(博通)43xx
–Ralink(雷凌)RT2x00
•Linux下已经支持了市面上的大多数wifi卡的驱动
•每种wifi卡都是需要固件(firmware)才能驱动的,并且同一种卡工作在不同接口时对应的firmware是不一样的
•需要注意的是:很多firmware都是要花钱的
•固件通过其驱动下载到无线卡中,才能驱动起来
(10)wifi驱动的通用的软件架构
1. 分为两部分,上面为主机端驱动,下面是我们之前所说的firmware
2. 其中固件部分的主要工作是:因为天线接受和发送回来的都是802.11帧的帧,而主机接受和传送出来的数据都必须是802.3的帧,所以必须由firmware来负责802.3的帧和802.11帧之间的转换,
3. 当天线收到数据,并被firmware处理好后会放在一个buffer里,并产生一个中断,主机在收到中断后就去读这个buffer。
资料二、
对STM32的SDIO——SD卡输入/输出模块摸索了一下,今天只看了POWER UP这个函数的实现。对SDIO编写驱动,需要参考SD卡的协议,我手上的SD卡协议是
ver2.00的物理层简化协议。协议主要规定了主机(这里就是STM32)向SD卡写入的各种控制指令,以及SD卡的初始化过程状态转
移图。了解SD卡从初始化状态转移图开始。
这个图看起来有点复杂,感觉无从下手,其实仔细瞧瞧就跟我们数电学的状态转移图差不多,框框里面是各种操作,箭头指向下一步操作,直线引出去的部分就是状态发生跳转的条件。首先上电(power-on),然后发出CMD0,再接着发送CMD8,有应答(response)判断为Ver2.00或更新的SDMC,无应答(no response)判断为ver2.00或者更新版SDMC(电压不匹配(voltage mismatch) )或ver1.X SDMC或不是SDMC。若判断为前一种情况,则问询是否为有效应答(valid response),如果不是,判断为无效卡,否则判断为有效卡且开始循环发送ACMD41指令直至SD卡发出power up应答。然后判断CCS(card capacity status——卡容量状态)位,为1则判断为ver2.00或者更新的大容量卡(high capacity SD memory card),否则判断为ver2.00或者更新的标准卡(sandard capacity SD memory card)。至此,power on工作结束。
上文只是对状态图进行了一个解读,真正要控制还是需要知道各个CMD如何发送。SD卡协议提供了几个CMD的格式以及其响应值的格式(如果有相应的话)。下面就对函数的具体编写进行下总结。
(1)初始化SDIO
利用SDIO_Init中的结构体初始化SDIO接口。该结构体有以下几个成员函数:SDIO_ClockDiv、SDIO_ClockEdge、SDIO_ClockBypass、SDIO_ClockPowerSave、SDIO_BusWide、SDIO_HardwareFlowControl。其中比较重要的是SDIO_ClockDiv成员,它确定了SDIO的分频系数,在不使用旁路时钟(ByPass)的时候SDIO_CLK=HCLK/(SDIO_ClockDiv+2),我们在这里将SDIO_CLK设置为400kHZ,就是通过设置分频系数实现的。初始化完成后,就进行第一步,也就是power on,调用SDIO_SetPowerState函数即可。最后别忘记使能SDIO的时钟。
(2)发送CMD0
由STM32向SD卡发送指令可以直接调用SDIO_SendCommand函数,该函数包含一个结构体,该结构体有以下几个成员:SDIO_Argument、SDIO_CmdIndex、SDIO_Response、SDIO_Wait、SDIO_CPSM。跟我们编程密切相关的一个是SDIO_Argument——参数,许多带有响应的命令都需要通过设置参数来实现,由于CMD0没有响应,所以此处设为0x00即可。SDIO_CmdIndex成员是该结构体核心——指令指数。也就是说,如果我要发送CMD0,SDIO_CmdIndex=0,如果发送ACMD41,SDIO_CmdIndex=41,但是注意此处SDIO_CmdIndex的值是等于指令,而且是指令的十进制形式,但是我们在给SDIO_CmdIndex赋值时必须转换成十六进制。SDIO_Wait设置等待中断。填写好结构体后检测是否正确受到CMD0,然后才能进行下一步。为了保证程序正确,这样的检测在每一个指令发送周期都是必须的。
(3)发送CMD8
用同样类似的方式发送CMD8。注意此时CMD8是带有响应的指令,接收到指令后sd返回该SDIO_Argument的值,所以对SDIO_Argument要进行特殊设置,设置后SDIO->ARG寄存器便有了该值。SDIO_Response——把应答模式设置成短应答,这是根据参考指南设置的。同样地,在填写完结构体后检查是否接收到命令。根据SD协议初始化流程图,此时如果有响应则SD遵循2.00协议,否则说明是1.x 或者mmc。无论是哪一种情况,都发送CMD55来检测。
(4)发送CMD55
CMD55是一个特殊的指令,该指令告诉主机下一个command将会是一个应用指令(application command),比如要发送ACMD41之前必须先发送CMD55。此处发送CMD55是为了检测卡的类型。不过暂时没没看懂为什么是发送CMD55,因为关于CMD55的解释中并没有提到它能够检测卡类型,只说了它的应答类型是R1。判断是SD卡或者是不支持的卡。
(5)进入循环,再次发送CMD55
这次发送CMD55就是为发送ACMD41做准备了。为什么要在循环里发送呢?因为SD协议初始化状态图中发送ACMD的过程是一个反复地,指导检测出power up为1为止,所以该处的循环条件设置成!validvoltage,validvoltage为OCR的power up位。需要注意的是例程中的循环条件是(!validvoltage) && (count < SD_MAX_VOLT_TRIAL),也就是说它设置了一个最大检测次数,当超过该检测次数仍然没有power up时就可以跳出,反馈检测失败的信息,这样程序不会死在此处。
(6)发送ACMD41
发送了CMD55后检测到收到指令,紧接着发送ACMD41指令。ACMD41响应类型是R3,该响应返回OCR寄存器的值,稍后我们需要这个寄存器来判断卡容量以及power up状态。注意此处参数格式规定的是HCS和Voltage Window共同确定的。填写完结构体后检查是否正确接收指令,然后检测power up位是不是1,不是的话再次循环,是则根据条件跳出循环。如果达到最大循环次数power up仍然没置位,则返回卡不可用的信息。
(7)检测卡的最终类型
正常上电好后,检测OCR的CCS为,一次来判断卡是SDHC还是SDSC。至此,power on函数功能到此结束。
资料三、
http://www.it165.net/embed/html/201307/2324.html
或者
http://wenku.baidu.com/link?url=dCcAC7xaau9ZxnEGCKN6CN_qGtCHbwbwAG6h0MjPmFAYzrjAsdcszfWr8E31fMFbHSEW-P4C8l7TtpNsTdLSFh7cT22Cu2fCvzcFwzhDInK