QNX驱动开发——SD卡SD模式开发实录

        和大多数朋友一样以前只用过SD卡的SPI模式,因为这种模式简单,无需专门的控制器,在大多数单片机上都可以实现,且无需CRC校验,控制起来也比较方便。而SD模式可以实现4条数据线同时传输,在速度上,比SPI模式有很大优势,所以这次项目选择了SD模式,使用处理器自带的SDHC控制器控制。

        其实硬件开发基本要搞清楚三点才能少走弯路,一是清楚被控硬件的驱动流程,二是要熟悉处理器控制器每个寄存器的具体含义和操作方法,三是有一定的调试手段。具体处理器控制器的介绍和SD卡的相关知识就不再赘述,本文主要记录下调试过程中遇到的问题和解决方法。

        1.初始化无法进入SD模式,总是进入到SPI模式。这个问题让我纠结了好几天,明明SD卡上电默认进入SD模式,设置也明明把DATA3进行了上拉,可是无论在CMD线上发送什么命令都得不到回应。

        解决办法:用示波器观察波形,发现上电后DATA3CS)就被拉低,SD卡进入了SPI状态,DATA0MISO)进行了响应,查看了n编程序后发现没有拉低的操作,很是丧气,后来发现是硬件上问题,原来硬件工程师为了使SD卡可以适应两种模式,对DATA3设置了上拉电阻和下拉电阻,而且表现为下拉!都是没有仔细看原理图,把下拉电阻去掉就OK了。

        2. 初始化顺序不明确。由于SD模式初始化顺序与SPI不一样,初期一直按着SPI的初始化顺序在搞,结果碰了钉子,久久没有搞定。于是GOOGLE下,在CSDN上下载了一个比较全的说明文档,帮了大忙,才发现下面的初始化流程。

       QNX驱动开发——SD卡SD模式开发实录_第1张图片

        3.如何使用SDHC控制器进行复位。这个控制器可以硬件上电复位也可通过一定的时序实现软件复位,而在开发驱动程序的时候软件复位是必需的,因为这样驱动程序可以实现动态加载。然而,这个SDHC的控制器有一个非常诡异的复位顺序,到现在也不知所云,不过既然人家都说这样行,咱们也不能跟他较劲,干脆照着办。

        4.如何发送一个命令。SD模式与SPI模式除了初始化流程不同外最大的区别就是你该如何发送一个命令。SPI就比较简单了,可以直接用SPI发送命令,而SD模式则是通过设置SDHC的控制器发出来的,每个位都必须看仔细,否则会出现十分诡异的现象。比如说有一个位专门管在发送CMD0的时候是不是要先发送80个时钟,让SD卡自己完成初始化;有专门控制读写以及是否有数据传输的位;以及数据宽度的控制;根据发送每个CMD的不同情况需要设置不同的参数等等,确实比SPI模式复杂不少。

        5.如何判断卡的状态。在发送不同的命令以及参数后,SD卡会给出不同的响应,只有SD卡回应ready的时候才能发送下一条指令。下面就按照发送指令的顺说一下所遇到的问题。

        1CMD0.这是第一条需要发送的命令,目的是初始化SD卡状态机,使SD卡进入idle转态,这一条命令就让我有点抓狂。按照SPI的方法,发送完CMD0是有回应的!可是怎么也想不明白为什么就没有,后来在GOOGLE了下发现这方面的资料少的可怜,不过最终的答案是SD模式CMD0就是没有响应的!真是坑爹呀。

        2CMD8.这条指令是一条协商SD卡工作电压以及判断SD卡是V1.0的版本还是V2.0的版本的指令,有响应的话就是V2.0的卡。可是参数为啥是0x1AA呢?后来的得到的答案是,这是一种初始化模式,询问SD卡是否可以工作在2.7v-3.3v,如果SD可以工作在这个电压范围的化,同样回复0x1AA,没问题,可以工作。可是找了半天也没有找到更多的资料,为啥没有别的参数可以带带,强烈建议手册上加入这一点。

        3ACMD41.这是一条特殊指令,其实是CMD55+CMD41,作用是查询SD卡是否支持SDHC以及让卡返回工作电压参数。大多数朋友之所以得不到正确的回应,十有八九是因为把参数写错了!ACMD41主要是写SD卡的OCR寄存器,置位HCS位的同时,千万不要忘了把支持的电压参数写上,不然在回应的OCR寄存器参数无法使其处于ready的状态!而且还要通过读CCS位来判断这是不是一个SDHC卡。

        4CMD2.这一步是为了获得CID寄存器信息,不过貌似没啥大用,确实初始化不可的一部分,之后发送CMD3SD卡建立一个相对地址RCA,这样当多个SDCMD线并联的时候就可以知道是向那个卡发送命令。这个相对地址在以后的好多指令中都会用到。

        5CMD9.获得CSD信息。这一步其实主要是获得SD卡的容量信息,按照返回的CSD寄存器的值根据相应的位判断是否为SDHC,并且根据相应的计算方法计算容量。如果使SDHC,大部分参数都是固定的,容量也比较计算,如果不是的化就会复杂的多,一般4G以上的卡都是SDHC卡。

        6CMD7.连接卡,使卡进入transfer的状态。具体还要根据SD卡状态机转移图来确定,如下所示:

        QNX驱动开发——SD卡SD模式开发实录_第2张图片

由此可见其主要作用是使卡在stand by 状态与transfer状态之间转换,从以一个方面说其实就是连不连接SD卡,如果连接了就进入Programming的状态,否则就进入stand by状态,一旦进入这种状态,之后的读写命令是无法响应的,一定要注意!

        6.如何更改SD卡的bus width.可变更的数据线宽度是SD模式最大的优势,可以实现4bit数据同时传输,也是本次设计更改主要考虑的因素。这个操作主要有三个步骤:第一,发送CMD42SD卡解锁;第二,发送ACMD6更该SD卡从1bit模式到4bit模式;第三,设置SDHC控制器,改变传输数据控制模式。其中有一点值得指出的是,在发送完每条指令时一定要检测下卡返回的status里是否是ready的状态,否则需要重新发送命令,等待SD卡处于就绪的状态再发送下一条命令,否则会发送失败。

        7.读写一个数据块。SD卡开发的最终目的是为了存储数据,那么读写一个数据块就是最关键的一步,实现了这步就算是大功告成了。读写操作是通过发送CMD17CMD24实现的,但在此之前最好要使用CMD13来查询卡的状态,确保卡处于ready的状态,读写命名才有效。得到回应后,SD卡中的数据被直接存在SDHC的数据buffer中,需要判断buffer可读写的标志才能对buffer进行有效读写。

       这样弄下来发现了不少问题,经过三周才最终搞定,其中有不少挑战,也有不少乐趣。

 

你可能感兴趣的:(QNX驱动程序开发)