×
单片机 > 单片机程序设计 > 详情

S3C6410裸机SD卡驱动(SDIO模式)

发布时间:2020-06-06 发布时间:
|

花了几天写了SD卡裸机驱动,现在还不完善,只支持4G以内的卡,以后再加上;现在经过修改可以写入数据了,亲测没问题.


S3C6410_SDIO.C


  1. #include "s3c6410_system.h"  

  2. #include "s3c6410_sdio.h"  

  3.   

  4. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////  

  5. //配置  

  6. //块大小寄存器(0通道)BLKSIZE0  

  7. #define BLKSIZE0_BLKSIZE            0x0200      //块大小为512字节           

  8. //传输模式寄存器(0通道)TRNMOD0  

  9. #define TRNMOD0_CCSCON              0           //正常模式  

  10. #define TRNMOD0_MUL1SIN0            (0 <

  11. #define TRNMOD0_RD1WT0              (1 <

  12. #define TRNMOD0_ENACMD12            (0 <

  13. #define TRNMOD0_ENBLKCNT            (0 <

  14. #define TRNMOD0_ENDMA               (0 <

  15. //主机控制寄存器(0通道)HOSTCTL0  

  16. #define HOSTCTL0_WIDE8              (0 <

  17. #define HOSTCTL0_DMASEL             (0 <

  18. #define HOSTCTL0_OUTEDGEINV         (0 <

  19. #define HOSTCTL0_WIDE4              (0 <

  20. //电源控制寄存器(0通道)PWRCON0  

  21. #define PWRCON0_SELPWRLVL           (7 <

  22. #define PWRCON0_PWRON               (1 <

  23. //容限寄存器(0 通道)CAPAREG0  

  24. #define CAPAREG0_V18                (1 <

  25. #define CAPAREG0_V30                (0 <

  26. #define CAPAREG0_V33                (1 <

  27. #define CAPAREG0_SUSRES             (1 <

  28. #define CAPAREG0_DMA                (1 <

  29. #define CAPAREG0_HSPD               (1 <

  30. #define CAPAREG0_ADMA2              (0 <

  31. #define CAPAREG0_MAXBLKLEN          (0 <

  32. #define CAPAREG0_BASECLK            (25 <

  33. #define CAPAREG0_TOUTUNIT           (0 <

  34. #define CAPAREG0_TOUTCLK            (10 <

  35. //最大电流容限寄存器(0 通道)MAXCURR0  

  36. #define MAXCURR0_MAXCURR18          (10 <

  37. #define MAXCURR0_MAXCURR30          (10 <

  38. #define MAXCURR0_MAXCURR33          (10 <

  39. //控制寄存器2 CONTROL2_0  

  40. #define CONTROL2_0_ENSTAASYNCCLR    (0 <

  41. #define CONTROL2_0_ENCMDCNFMSK      (0 <

  42. #define CONTROL2_0_CDINVRXD3        (0 <

  43. #define CONTROL2_0_SELCARDOUT       (0 <

  44. #define CONTROL2_0_FLTCLKSEL        (8 <

  45. #define CONTROL2_0_ENFBCLKTX        (0 <

  46. #define CONTROL2_0_ENFBCLKRX        (0 <

  47. #define CONTROL2_0_SDCDSEL          (0 <

  48. #define CONTROL2_0_SDSIGPC          (0 <

  49. #define CONTROL2_0_ENBUSYCHKTXSTART (0 <

  50. #define CONTROL2_0_DFCNT            (0 <

  51. #define CONTROL2_0_ENCLKOUTHOLD     (1 <

  52. #define CONTROL2_0_RWAITMODE        (0 <

  53. #define CONTROL2_0_DISBUFRD         (0 <

  54. //HCLK = 128MHZ     EPLL = 24MHZ  

  55. #define CONTROL2_0_SELBASECLK       (2 <

  56. #define CONTROL2_0_PWRSYNC          (0 <

  57. #define CONTROL2_0_ENCLKOUTMSKCON   (0 <

  58. #define CONTROL2_0_HWINITFIN        (1 <

  59. //时钟控制寄存器(0 通道)CLKCON0  

  60. #define CLKCON0_SELFREQ             (0x80 <

  61. #define CLKCON0_ENSDCLK             (1 <

  62. #define CLKCON0_ENINTCLK            (1 <

  63. //超时控制寄存器(0 通道)TIMEOUTCON0  

  64.   

  65.   

  66.   

  67. /******************************************************************************* 

  68. * Function Name  : SDIO_DeInit 

  69. * Description    : Deinitializes the SDIO peripheral registers to their default 

  70. *                  reset values. 

  71. * Input          : None 

  72. * Output         : None 

  73. * Return         : None 

  74. *******************************************************************************/  

  75. void SDIO_DeInit(void)  

  76. {  

  77.     //初始化硬件IO     

  78.     rGPGCON = 0x2222222;    //初始化IO为SDIO模式  

  79.     rGPGPUD = 0;            //禁止上下拉  

  80.           

  81.     //时钟控制寄存器配置  

  82.     SDIO0->CLKCON = CLKCON0_SELFREQ + CLKCON0_ENSDCLK + CLKCON0_ENINTCLK;  

  83.     //主机控制寄存器配置  

  84.     SDIO0->HOSTCTL = HOSTCTL0_WIDE8 + HOSTCTL0_DMASEL + HOSTCTL0_OUTEDGEINV + HOSTCTL0_WIDE4;  

  85.     //容限寄存器配置  

  86.     SDIO0->CAPAREG = CAPAREG0_V18 + CAPAREG0_V30 + CAPAREG0_V33 + CAPAREG0_SUSRES + CAPAREG0_DMA + CAPAREG0_HSPD + CAPAREG0_ADMA2 +\  

  87.                     CAPAREG0_MAXBLKLEN + CAPAREG0_BASECLK + CAPAREG0_TOUTUNIT + CAPAREG0_TOUTCLK;  

  88.     //控制寄存器2配置                

  89.     SDIO0->CONTROL2 = CONTROL2_0_ENSTAASYNCCLR + CONTROL2_0_ENCMDCNFMSK + CONTROL2_0_CDINVRXD3 + CONTROL2_0_SELCARDOUT + CONTROL2_0_FLTCLKSEL + \  

  90.                     CONTROL2_0_ENFBCLKTX + CONTROL2_0_ENFBCLKRX + CONTROL2_0_SDCDSEL + CONTROL2_0_SDSIGPC + CONTROL2_0_ENBUSYCHKTXSTART + \  

  91.                     CONTROL2_0_DFCNT + CONTROL2_0_ENCLKOUTHOLD + CONTROL2_0_RWAITMODE + CONTROL2_0_DISBUFRD + CONTROL2_0_SELBASECLK + \  

  92.                     CONTROL2_0_PWRSYNC + CONTROL2_0_ENCLKOUTMSKCON + CONTROL2_0_HWINITFIN;    

  93.     //传输模式寄存器配置  

  94.     SDIO0->TRNMOD = TRNMOD0_CCSCON + TRNMOD0_MUL1SIN0 + TRNMOD0_RD1WT0 + TRNMOD0_ENACMD12 + TRNMOD0_ENBLKCNT + TRNMOD0_ENDMA;      

  95.     //超时控制寄存器(0 通道)  

  96.     SDIO0->TIMEOUTCON    = 0x0e;     //超时设置最大              

  97.     //电源控制寄存器配置  

  98.     SDIO0->PWRCON = PWRCON0_SELPWRLVL + PWRCON0_PWRON;  

  99.     //块间隔寄存器  

  100.     SDIO0->BLKGAP = 0;  

  101.     //开启卡插入+卡移除+传输完成+指令完成中断状态+数据超时错误+命令索引错误+指令最后位错误+指令超时错误+指令CRC + 缓冲区读就绪 + 写缓冲区就绪  

  102.     SDIO_FlagConfig(SDIO_FLAG_CARDREMOVAL | SDIO_FLAG_CARDINSERTION | SDIO_FLAG_TRANSFER | SDIO_FLAG_COMMANDEND | SDIO_FLAG_DATACRC |  

  103.                     SDIO_FLAG_DATATIMEOUT | SDIO_FLAG_COMMANDINDEX | SDIO_FLAG_COMMANDCRC | SDIO_FLAG_COMMANDTIMEOUT | SDIO_FLAG_BUFFREAD | SDIO_FLAG_BUFFWRITE,Enable);  

  104.     //使能卡插入拔出中断  

  105.     SDIO_FlagITConfig(SDIO_FLAG_CARDREMOVAL | SDIO_FLAG_CARDINSERTION,Enable);    

  106.     SDIO_ClearFlag(SDIO_FLAG_ALL);  //清除所有中断标志            

  107. }  

  108.   

  109.   

  110.   

  111. void SDIO_FlagITConfig(u32 SDIO_FLAG, u8 EN)  

  112. {  

  113.     if(EN)  //中断使能  

  114.         SDIO0->INTSEGEN |= SDIO_FLAG;  

  115.     else  

  116.         SDIO0->INTSEGEN &= ~SDIO_FLAG;  

  117.           

  118. }  

  119.   

  120.   

  121. void SDIO_FlagConfig(u32 SDIO_FLAG, u8 EN)  

  122. {  

  123.     if(EN)  //状态使能  

  124.         SDIO0->INTSTSEN |= SDIO_FLAG;  

  125.     else  

  126.         SDIO0->INTSTSEN &= ~SDIO_FLAG;  

  127.           

  128. }  

  129.   

  130. /************************************************************************************************************************* 

  131. *函数        :    void SD_SendCommand(vu8 CmdIdx,vu32 CmdArg,vu8 CmdTyp,vu8 Misc) 

  132. *功能        :    向SD卡发送一个命令 

  133. *参数        :    CmdIdx:指令索引;CmdArg:命令参数;CmdMisc:其它杂项设置,详见说明 

  134. *返回        :    无 

  135. *依赖        :    底层宏定义 

  136. *作者        :    陈鹏 

  137. *时间        :    20120507 

  138. *最后修改时间:    20120507 

  139. *说明        :    写SD命令寄存器; 

  140.                 指令索引:这些位设置为SD存储卡物理层规范中指令格式的第40到45位和SDIO卡规范中指定的指令数(CMD0-63, ACMD0-63)。 

  141.                  

  142.                 杂项: SDIO_Type_Default   一般为0 

  143.                         SDIO_Type_Pend      写总线暂停 

  144.                         SDIO_Type_FS        功能选择 

  145.                         SDIO_Type_IT        中断模式 

  146.                          

  147.                         SDIO_CMDIndexEn     SDIO指令索引使能 

  148.                         SDIO_CMDCrcEn       SDIO指令CRC校验使能 

  149.                          

  150.                         SDIO_Response_No           无应答 

  151.                         SDIO_Response_Short        短应答  48 

  152.                         SDIO_Response_Long        长应答   136 

  153.                         SDIO_Response_ShortBusy    短应答+检测繁忙情况 

  154. *************************************************************************************************************************/  

  155. void SDIO_SendCommand(vu8 CmdIdx,vu32 CmdArg,vu8 CmdMisc)  

  156. {     

  157.     u16 temreg = 0;  

  158.   

  159.   

  160.     SDIO_ClearFlag(SDIO_FLAG_ALL); //清除所有状态寄存  

  161.   

  162.   

  163.     temreg = CmdIdx;  

  164.     temreg <<= 8;  

  165.     temreg |= CmdMisc;  

  166.   

  167.   

  168.     SDIO0->ARGUMENT = CmdArg;   //先写入命令参数  

  169.     SDIO0->CMDREG = temreg;     //再写入命令索引以及类型等参数  

  170.   

  171.   

  172.     while(!(SDIO0->PRNSTS & BIT0)); //等待命令线空忙,也就是开始执行命令  

  173.     while(SDIO0->PRNSTS & BIT0);    //等待命令线空闲,也就是命令执行完毕  

  174. }  

  175.   

  176.   

  177.   

  178.   

  179.   

  180. /************************************************************************************************************************* 

  181. *函数        :    u32 SD_GetResponse(u8 SDIO_RESP) 

  182. *功能        :    获取SD卡的应答 

  183. *参数        :    Rep:应答数据存放的位置 

  184.                 SDIO_RESP1: Response Register 1 

  185. *               SDIO_RESP2: Response Register 2 

  186. *               SDIO_RESP3: Response Register 3 

  187. *               SDIO_RESP4: Response Register 4   

  188. *返回        :    返回应答 

  189. *依赖        :    底层宏定义 

  190. *作者        :    陈鹏 

  191. *时间        :    20120507 

  192. *最后修改时间:    20120507 

  193. *说明        :    存放应答数据的缓冲区为128BIT;4个32bit; 

  194.                 指令应答。下表27-4为每一个应答描述了从SD总线到寄存器的指令映射。在这个表中,在表中 R[]指出在SD总线上传输的应答数据的范围, 

  195.                 REP[]指出应答寄存器中位的范围。128位应答位的顺序: {RSPREG3, RSPREG2, RSPREG1, RSPREG0} 

  196. *************************************************************************************************************************/  

  197. u32 SDIO_GetResponse(u8 SDIO_RESP)  

  198. {  

  199.     return (SDIO0->RSPREG[SDIO_RESP]);  

  200. }  

  201.   

  202.   

  203. u32 SDIO_ReadData(void)  

  204. {   

  205.     return SDIO0->BDATA;     //从缓冲区读数据  

  206. }  

  207.   

  208.   

  209. void SDIO_WriteData(u32 Data)  

  210. {   

  211.     SDIO0->BDATA = Data;  

  212. }  

  213.   

  214.   

  215. u8 SDIO_GetFlagStatus(u32 SDIO_FLAG)  

  216. {   

  217.     return ((SDIO_STATUS & SDIO_FLAG) ? 1 : 0);  

  218. }  

  219.   

  220.   

  221. void SDIO_ClearFlag(u32 SDIO_FLAG)  

  222. {   

  223.     SDIO_STATUS |= SDIO_FLAG;  

  224. }  

  225.   

  226.   

  227.   

  228.   

  229. /************************************************************************************************************************* 

  230. * 函数    :   void SDIO_SetFIFOInterruptAddress(u8 FIFOxAdd,u8 WordAdd) 

  231. * 功能    :   设置FIFO中断触发位置 

  232. * 参数    :   FIFOxAdd:FIFO地址选择 

  233.             WordAdd:触发位置选择,单位为字,共512B,也就是1-128字 

  234. * 返回    :   SD_OK:成功,其它见SD Card Error code. 

  235. * 依赖    :   底层寄存器操作函数 

  236. * 作者    :   陈鹏 

  237. * 时间    :   20120516 

  238. * 最后修改时间 : 20120516 

  239. * 说明    :   无 

  240. *************************************************************************************************************************/  

  241. void SDIO_SetFIFOInterruptAddress(u8 FIFOxAdd,u8 WordAdd)  

  242. {  

  243.     if(WordAdd > 128)  

  244.         WordAdd = 128;  

  245.     switch (FIFOxAdd)  

  246.     {  

  247.         case FIFO_A0:  

  248.         {  

  249.             SDIO0->CONTROL3 &= ~(0x1f);  

  250.             SDIO0->CONTROL3 |= WordAdd;  

  251.         }break;  

  252.         case FIFO_A1:  

  253.         {  

  254.             SDIO0->CONTROL3 &= ~(0x1f <

  255.             SDIO0->CONTROL3 |= WordAdd <

  256.         }break;  

  257.         case FIFO_A2:  

  258.         {  

  259.             SDIO0->CONTROL3 &= ~(0x1f <

  260.             SDIO0->CONTROL3 |= WordAdd <

  261.         }break;  

  262.         case FIFO_A3:  

  263.         {  

  264.             SDIO0->CONTROL3 &= ~(0x1f <

  265.             SDIO0->CONTROL3 |= WordAdd <

  266.         }break;  

  267.         default : break;  

  268.     }  

  269. }  

  270.   

  271.   

  272. /************************************************************************************************************************* 

  273. * 函数    :   void SDIO_CLKFrequencySelect(u8 SDCLK)   

  274. * 功能    :   设置SDIO时钟分频系数 

  275. * 参数    :   SDCLK:设置SDIO时钟分频系数 

  276. * 返回    :   SD_OK:成功,其它见SD Card Error code. 

  277. * 依赖    :   底层寄存器操作函数 

  278. * 作者    :   陈鹏 

  279. * 时间    :   20120516 

  280. * 最后修改时间 : 20120516 

  281. * 说明    :   高速基础时钟为50MHz 

  282.             低速基础时钟为25MHz 

  283. *************************************************************************************************************************/  

  284. void SDIO_CLKFrequencySelect(u8 SDCLK)    

  285. {  

  286.     SDIO_SDClkDisable();            //时钟停止  

  287.     SDIO0->CAPAREG &= ~(0x3f <

  288.     SDIO0->CAPAREG |= (50 <

  289.     SDIO0->CLKCON &= ~(0xff <

  290.     SDIO0->CLKCON |= (SDCLK <

  291.     SDIO_SDClkEnable();             //时钟使能  

  292.     while(!(SDIO0->CLKCON & BIT0));  //等待时钟稳定  

  293. }  

  294.   

  295.   

  296.   

  297. /************************************************************************************************************************* 

  298. * 函数    :   void SDIO_SoftwareReset(u32 SDIO_RST) 

  299. * 功能    :   设置SDIO软件复位 

  300. * 参数    :   SDIO_RST: 

  301.                     SDIO_RSTDAT //复位DAT线 

  302.                     SDIO_RSTCMD //复位CMD线 

  303.                     SDIO_RSTALL //复位所有 

  304. * 返回    :   SD_OK:成功,其它见SD Card Error code. 

  305. * 依赖    :   底层寄存器操作函数 

  306. * 作者    :   陈鹏 

  307. * 时间    :   20120516 

  308. * 最后修改时间 : 20120516 

  309. * 说明    :   无 

  310. *************************************************************************************************************************/  

  311. void SDIO_SoftwareReset(u32 SDIO_RST)  

  312. {  

  313.     SDIO0->SWRST |= SDIO_RST;            //复位  

  314.     while(SDIO0->SWRST & SDIO_RST);      //等待复位完成  

  315. }  

  316.   

  317.   

  318.   

  319. /************************************************************************************************************************* 

  320. *函数        :    void SDIO_SetTimeOutClock(u8 Unit,u8 Frequency) 

  321. *功能        :    超时时钟设置 

  322. *参数        :    Unit:超时时钟单位选择 

  323.                             TIME_OUT_UNIT_KHZ(0):超时时钟单位为KHZ 

  324.                             TIME_OUT_UNIT_MHZ(1):超时时钟单位为MHZ 

  325.                 Frequency:时钟频率:1~63 

  326. *返回        :    返回应答 

  327. *依赖        :    底层宏定义 

  328. *作者        :    陈鹏 

  329. *时间        :    20120521 

  330. *最后修改时间:    20120521 

  331. *说明        :    配置指令超时时间 

  332. *************************************************************************************************************************/  

  333. void SDIO_SetTimeOutClock(u8 Unit,u8 Frequency)  

  334. {  

  335.     SDIO0->CAPAREG &= ~(0xff);   //清除原先设置  

  336.     if(Unit)                    //配置超时时钟单位:MHZ  

  337.         SDIO0->CAPAREG |= (1 <

  338.     if(Frequency > 63)           //最大只能设置为63  

  339.         Frequency = 63;  

  340.     SDIO0->CAPAREG |= Frequency;  

  341. }  



s3c6410_sdio.h


  1. #ifndef _S3C6410_SDIO_H_  

  2. #define _S3C6410_SDIO_H_  

  3.   

  4. #include "s3c6410_system.h"  

  5.   

  6.   

  7.   

  8. #define FIFO_A0 0   //FIFO中断地址0  

  9. #define FIFO_A1 1   //FIFO中断地址1  

  10. #define FIFO_A2 2   //FIFO中断地址2  

  11. #define FIFO_A3 3   //FIFO中断地址3  

  12.   

  13.   

  14. //SDIO总线宽度设置  

  15. #define SDIO_BusWide_1b                     ((u8)0)  

  16. #define SDIO_BusWide_4b                     ((u8)1)  

  17. #define SDIO_BusWide_8b                     ((u8)2)  

  18.   

  19. //SDIO 命令杂项设置  

  20. //SDIO响应类型  

  21. #define SDIO_Response_No                    ((u8)0) //无应答  

  22. #define SDIO_Response_Long                  ((u8)1) //长应答   136  

  23. #define SDIO_Response_Short                 ((u8)2) //短应答   48  

  24. #define SDIO_Response_ShortBusy             ((u8)3) //短应答+检测繁忙情况  

  25. //其它设置  

  26. #define SDIO_CMDIndexEn                     ((u8)1 <

  27. #define SDIO_CMDCrcEn                       ((u8)1 <

  28. #define SDIO_DataSelect                     ((u8)1 <

  29. //SDIO指令类型CmdTyp  

  30. #define SDIO_Type_Default                   ((u8)0 <

  31. #define SDIO_Type_Pend                      ((u8)1 <

  32. #define SDIO_Type_FS                        ((u8)2 <

  33. #define SDIO_Type_IT                        ((u8)3 <

  34.   

  35.   

  36.   

  37. //SDIO响应寄存器选择  

  38. #define SDIO_RESP1                          ((u8)0)  

  39. #define SDIO_RESP2                          ((u8)1)  

  40. #define SDIO_RESP3                          ((u8)2)  

  41. #define SDIO_RESP4                          ((u8)3)  

  42.   

  43.   

  44.   

  45.   

  46.   

  47. /* SDIO Data Block Size ------------------------------------------------------*/  

  48. #define SDIO_DataBlockSize_1b               ((u16)1)  

  49. #define SDIO_DataBlockSize_2b               ((u16)2)  

  50. #define SDIO_DataBlockSize_4b               ((u16)3)  

  51. #define SDIO_DataBlockSize_8b               ((u16)4)  

  52. #define SDIO_DataBlockSize_16b              ((u16)16)  

  53. #define SDIO_DataBlockSize_32b              ((u16)32)  

  54. #define SDIO_DataBlockSize_64b              ((u16)64)  

  55. #define SDIO_DataBlockSize_128b             ((u16)128)  

  56. #define SDIO_DataBlockSize_256b             ((u16)256)  

  57. #define SDIO_DataBlockSize_512b             ((u16)512)  

  58. #define SDIO_DataBlockSize_1024b            ((u16)1024)  

  59. #define SDIO_DataBlockSize_2048b            ((u16)2048)  

  60. #define SDIO_DataBlockSize_4096b            ((u16)4096)  

  61. #define SDIO_DataBlockSize_8192b            ((u16)8192)  

  62. #define SDIO_DataBlockSize_16384b           ((u16)16384)  

  63.   

  64.   

  65. /* SDIO Flags ----------------------------------------------------------------*/  

  66. //SDIO中断状态  

  67. #define SDIO_STATUS                         (SDIO0->INTSTS)  

  68. #define SDIO_FLAG_FIFOADDERR3               ((u32)1 <

  69. #define SDIO_FLAG_FIFOADDERR2               ((u32)1 <

  70. #define SDIO_FLAG_FIFOADDERR1               ((u32)1 <

  71. #define SDIO_FLAG_FIFOADDERR0               ((u32)1 <

  72. #define SDIO_FLAG_READWAIT                  ((u32)1 <

  73. #define SDIO_FLAG_CCS                       ((u32)1 <

  74. #define SDIO_FLAG_CARD                      ((u32)1 <

  75. #define SDIO_FLAG_CARDREMOVAL               ((u32)1 <

  76. #define SDIO_FLAG_CARDINSERTION             ((u32)1 <

  77. #define SDIO_FLAG_BUFFREAD                  ((u32)1 <

  78. #define SDIO_FLAG_BUFFWRITE                 ((u32)1 <

  79. #define SDIO_FLAG_DMA                       ((u32)1 <

  80. #define SDIO_FLAG_BLOCKGAP                  ((u32)1 <

  81. #define SDIO_FLAG_TRANSFER                  ((u32)1 <

  82. #define SDIO_FLAG_COMMANDEND                ((u32)1 <

  83. #define SDIO_FLAG_ADMA                      ((u32)1 <

  84. #define SDIO_FLAG_AUTOCMD12                 ((u32)1 <

  85. #define SDIO_FLAG_DATAENDBIT                ((u32)1 <

  86. #define SDIO_FLAG_DATACRC                   ((u32)1 <

  87. #define SDIO_FLAG_DATATIMEOUT               ((u32)1 <

  88. #define SDIO_FLAG_COMMANDINDEX              ((u32)1 <

  89. #define SDIO_FLAG_COMMANDENDBIT             ((u32)1 <

  90. #define SDIO_FLAG_COMMANDCRC                ((u32)1 <

  91. #define SDIO_FLAG_COMMANDTIMEOUT            ((u32)1 <

  92. #define SDIO_FLAG_ALL                       ((u32)0xffffffff)   //所有标志  

  93.   

  94.   

  95.   

  96.   

  97.   

  98.   

  99.   

  100. void SDIO_DeInit(void);  

  101. void SDIO_ClockCmd(u8 EN);  

  102. void SDIO_SetPowerState(u32 SDIO_PowerState);  

  103. void SDIO_FlagITConfig(u32 SDIO_FLAG, u8 EN);  

  104. void SDIO_FlagConfig(u32 SDIO_FLAG, u8 EN);  

  105. void SDIO_SendCommand(vu8 CmdIdx,vu32 CmdArg,vu8 CmdMisc);  

  106. u32 SDIO_GetResponse(u8 SDIO_RESP);  

  107. u32 SDIO_ReadData(void);  

  108. void SDIO_WriteData(u32 Data);  

  109. u8 SDIO_GetFlagStatus(u32 SDIO_FLAG);  

  110. void SDIO_ClearFlag(u32 SDIO_FLAG);  

  111. void SDIO_SetFIFOInterruptAddress(u8 FIFOxAdd,u8 WordAdd);  

  112. void SDIO_SetTimeOutClock(u8 Unit,u8 Frequency);  

  113. void SDIO_CLKFrequencySelect(u8 SDCLK);  

  114. void SDIO_SoftwareReset(u32 SDIO_RST);//软件复位  

  115.   

  116.   

  117. //设置需要传输的块数量  

  118. #define SDIO_SetTransferBlockCnt(x)                 (SDIO0->BLKCNT = x)  

  119. //获取剩余传输的块的数量  

  120. #define SDIO_GetTransferBlockCnt()                  (SDIO0->BLKCNT)  

  121. //设置单次传输的块的大小  

  122. #define SDIO_SetTransferBlockSize(x)                (SDIO0->BLKSIZE = (x & 0xfff))  

  123. //设置为单块传输模式  

  124. #define SDIO_SingleBlockMode()                      (SDIO0->TRNMOD &= ~(BIT5))  

  125. //设置为多区段传输模式  

  126. #define SDIO_MultipleBlockMode()                    (SDIO0->TRNMOD |= BIT5)  

  127. //自动CMD12命令启动  

  128. #define SDIO_AutoCMD12Enable()                      (SDIO0->TRNMOD |= BIT2)  

  129. //自动CMD12命令禁止  

  130. #define SDIO_AuotCMD12Disable()                     (SDIO0->TRNMOD &= ~(BIT2))  

  131. //设置SDIO为写数据模式  

  132. #define SDIO_WriteMode()                            (SDIO0->TRNMOD &= ~(BIT4))  

  133. //设置SDIO为读数据模式  

  134. #define SDIO_ReadMode()                             (SDIO0->TRNMOD |= BIT4)  

  135. //块计数器启动  

  136. #define SDIO_BlockCountEnable()                     (SDIO0->TRNMOD |= BIT1)  

  137. //禁止块计数器启动  

  138. #define SDIO_BlockCountDisable()                    (SDIO0->TRNMOD &= ~(BIT1))  

  139. //DMA启动  

  140. #define SDIO_DMAEnable()                            (SDIO0->TRNMOD |= BIT0)  

  141. //DMA禁止   

  142. #define SDIO_DMADisable()                           (SDIO0->TRNMOD &= ~(BIT0))  

  143. //数据线忙  

  144. #define SDIO_DATLineActive()                        (SDIO0->PRNSTS & BIT2)  

  145. //指令禁止  

  146. #define SDIO_CommandInhibit()                       (SDIO0->PRNSTS & BIT0)  

  147. //高速时钟模式使能  

  148. #define SDIO_HighSpeedEnable()                      (SDIO0->CAPAREG |= BIT21)  

  149. //取消高速时钟模式  

  150. #define SDIO_HighSpeedDisable()                     (SDIO0->CAPAREG &= ~BIT21)  

  151. //数据线宽度设置为4bit  

  152. #define SDIO_SetDataDataWidth_4b()                  (SDIO0->HOSTCTL |= BIT1)  

  153. //数据线宽设置为1bit  

  154. #define SDIO_SetDataDataWidth_1b()                  (SDIO0->HOSTCTL &= ~BIT1)  

  155. //总线电压选择3.3V  

  156. #define SDIO_SetBusVoltage_3_3V()                   (SDIO0->PWRCON &= ~(0x7 

  157. //总线电源开启  

  158. #define SDIO_BusPowerON()                           (SDIO0->PWRCON |= BIT0)  

  159. //总线电压关闭  

  160. #define SDIO_BusPowerOFF()                          (SDIO0->PWRCON &= ~BIT0)  

  161. //唤醒发生在SD卡插入  

  162. #define SDIO_WakeupOnSDInsertion()                  (SDIO0->WAKCON |= BIT1  

  163. //使能SD时钟  

  164. #define SDIO_SDClkEnable()                          (SDIO0->CLKCON |= BIT2)  

  165. //SD时钟停止      

  166. #define SDIO_SDClkDisable()                         (SDIO0->CLKCON &= ~BIT2)               

  167.   

  168. //超时时钟单位设置  

  169. #define TIME_OUT_UNIT_KHZ   0   //超时时钟单位为KHZ  

  170. #define TIME_OUT_UNIT_MHZ   1   //超时时钟单位为MHZ  

  171.   

  172.   

  173. //时钟分频系数  

  174. #define SDCLK_1_256     ((u8)0x80)  //基础时钟256分频  

  175. #define SDCLK_1_128     ((u8)0x40)  //基础时钟128分频  

  176. #define SDCLK_1_64  ((u8)0x20)  //基础时钟64分频  

  177. #define SDCLK_1_32  ((u8)0x10)  //基础时钟32分频  

  178. #define SDCLK_1_16  ((u8)0x08)  //基础时钟16分频  

  179. #define SDCLK_1_8   ((u8)0x04)  //基础时钟8分频  

  180. #define SDCLK_1_4   ((u8)0x02)  //基础时钟4分频  

  181. #define SDCLK_1_2   ((u8)0x01)  //基础时钟2分频  

  182. #define SDCLK_1_1       ((u8)0x00)  //基础时钟1分频  

  183.   

  184. //软件复位选择  

  185. #define SDIO_RSTDAT     BIT2    //复位DAT线  

  186. #define SDIO_RSTCMD     BIT1    //复位CMD线  

  187. #define SDIO_RSTALL     BIT0    //复位所有  

  188.   

  189.   

  190. #endif  


sdcard_sdio.c,

  1. /******************************************************************************* 

  2. //功能:SDCARD 驱动,SDIO 模式 

  3. //作者:陈鹏 

  4. //创建时间:2012-05-16 10:32 

  5. //修改时间:2012-05-16 10:32 

  6. //修订说明: 

  7. //声明:源程序借鉴了意法STM32F103X库函数 

  8. ********************************************************************************/  

  9. #include "sdcard_sdio.h"  

  10. #include "s3c6410_sdio.h"  

  11. #include "s3c6410_system.h"  

  12.   

  13. u8 SDMMC0_MOV_Flag = 0;     //sdmmc0卡移除信号有  

  14.   

  15. /* 

  16. 1.3 寄存器 

  17. 名称 宽度 描述 

  18. CID 128 卡标识号 

  19. RCA 16 相对卡地址(Relative card address):本地系统中卡的地 

  20. 址,动态变化,在主机初始化的时候确定 

  21. *SPI 模式中没有 

  22. CSD 128 卡描述数据:卡操作条件相关的信息数据 

  23. SCR 64 SD 配置寄存器:SD 卡特定信息数据 

  24. OCR 32 操作条件寄存器*/  

  25.   

  26. //容量 = BLOCKNR * BLOCK_LEN = (C_SIZE+1)*2^(C_SIZE_MULT+2)*2^(READ_BL_LEN)  

  27.   

  28.   

  29. #define SD_BlockSize            512     //SD卡块大小  

  30. #define SDIO_CMD0TIMEOUT        1000000 //超时计数器大小  

  31. #define SDIO_READTIMEOUT        1000000 //读等待超时  

  32. #define SDIO_WRITETIMEOUT       2000000 //写等待超时  

  33.   

  34. // SD卡指令表        

  35. #define CMD0    0       //卡复位  

  36. #define CMD1    1  

  37. #define CMD9    9       //命令9 ,读CSD数据  

  38. #define CMD10   10      //命令10,读CID数据  

  39. #define CMD12   12      //命令12,停止数据传输  

  40. #define CMD16   16      //命令16,设置SectorSize 应返回0x00  

  41. #define CMD17   17      //命令17,读sector  

  42. #define CMD18   18      //命令18,读Multi sector  

  43. #define ACMD23  23      //命令23,设置多sector写入前预先擦除N个block  

  44. #define CMD24   24      //命令24,写sector  

  45. #define CMD25   25      //命令25,写Multi sector  

  46. #define ACMD41  41      //命令41,应返回0x00  

  47. #define CMD55   55      //命令55,应返回0x01  

  48. #define CMD58   58      //命令58,读OCR信息  

  49. #define CMD59   59      //命令59,使能/禁止CRC,应返回0x0  

  50.   

  51. /* Mask for errors Card Status R1 (OCR Register) */  

  52. #define SD_OCR_ADDR_OUT_OF_RANGE        ((u32)0x80000000)  

  53. #define SD_OCR_ADDR_MISALIGNED          ((u32)0x40000000)  

  54. #define SD_OCR_BLOCK_LEN_ERR            ((u32)0x20000000)  

  55. #define SD_OCR_ERASE_SEQ_ERR            ((u32)0x10000000)  

  56. #define SD_OCR_BAD_ERASE_PARAM          ((u32)0x08000000)  

  57. #define SD_OCR_WRITE_PROT_VIOLATION     ((u32)0x04000000)  

  58. #define SD_OCR_LOCK_UNLOCK_FAILED       ((u32)0x01000000)  

  59. #define SD_OCR_COM_CRC_FAILED           ((u32)0x00800000)  

  60. #define SD_OCR_ILLEGAL_CMD              ((u32)0x00400000)  

  61. #define SD_OCR_CARD_ECC_FAILED          ((u32)0x00200000)  

  62. #define SD_OCR_CC_ERROR                 ((u32)0x00100000)  

  63. #define SD_OCR_GENERAL_UNKNOWN_ERROR    ((u32)0x00080000)  

  64. #define SD_OCR_STREAM_READ_UNDERRUN     ((u32)0x00040000)  

  65. #define SD_OCR_STREAM_WRITE_OVERRUN     ((u32)0x00020000)  

  66. #define SD_OCR_CID_CSD_OVERWRIETE       ((u32)0x00010000)  

  67. #define SD_OCR_WP_ERASE_SKIP            ((u32)0x00008000)  

  68. #define SD_OCR_CARD_ECC_DISABLED        ((u32)0x00004000)  

  69. #define SD_OCR_ERASE_RESET              ((u32)0x00002000)  

  70. #define SD_OCR_AKE_SEQ_ERROR            ((u32)0x00000008)  

  71. #define SD_OCR_ERRORBITS                ((u32)0xFDFFE008)  

  72.   

  73. /* Masks for R6 Response */  

  74. #define SD_R6_GENERAL_UNKNOWN_ERROR     ((u32)0x00002000)  

  75. #define SD_R6_ILLEGAL_CMD               ((u32)0x00004000)  

  76. #define SD_R6_COM_CRC_FAILED            ((u32)0x00008000)  

  77.   

  78. #define SD_VOLTAGE_WINDOW_SD            ((u32)0x80100000)  

  79. #define SD_HIGH_CAPACITY                ((u32)0x40000000)  

  80. #define SD_STD_CAPACITY                 ((u32)0x00000000)  

  81. #define SD_CHECK_PATTERN                ((u32)0x000001AA)  

  82.   

  83. #define SD_MAX_VOLT_TRIAL               ((u32)0x0000FFFF)  

  84. #define SD_ALLZERO                      ((u32)0x00000000)  

  85.   

  86. #define SD_WIDE_BUS_SUPPORT             ((u32)0x00040000)  

  87. #define SD_SINGLE_BUS_SUPPORT           ((u32)0x00010000)  

  88. #define SD_CARD_LOCKED                  ((u32)0x02000000)  

  89. #define SD_CARD_PROGRAMMING             ((u32)0x00000007)  

  90. #define SD_CARD_RECEIVING               ((u32)0x00000006)  

  91. #define SD_DATATIMEOUT                  ((u32)0x000FFFFF)  

  92. #define SD_0TO7BITS                     ((u32)0x000000FF)  

  93. #define SD_8TO15BITS                    ((u32)0x0000FF00)  

  94. #define SD_16TO23BITS                   ((u32)0x00FF0000)  

  95. #define SD_24TO31BITS                   ((u32)0xFF000000)  

  96. #define SD_MAX_DATA_LENGTH              ((u32)0x01FFFFFF)  

  97.   

  98. #define SD_HALFFIFO                     ((u32)0x00000008)  

  99. #define SD_HALFFIFOBYTES                ((u32)0x00000020)  

  100.   

  101. /* Command Class Supported */  

  102. #define SD_CCCC_LOCK_UNLOCK             ((u32)0x00000080)  

  103. #define SD_CCCC_WRITE_PROT              ((u32)0x00000040)  

  104. #define SD_CCCC_ERASE                   ((u32)0x00000020)  

  105.   

  106. /* Following commands are SD Card Specific commands. 

  107.    SDIO_APP_CMD should be sent before sending these commands. */  

  108. #define SDIO_SEND_IF_COND               ((u32)0x00000008)  

  109.   

  110. //#define SDIO_MULTIMEDIA_CARD               ((u32)0x0)  

  111. #define SDIO_SECURE_DIGITAL_CARD           ((u32)0x1)  

  112. //#define SDIO_SECURE_DIGITAL_IO_CARD        ((u32)0x2)  

  113. //#define SDIO_HIGH_SPEED_MULTIMEDIA_CARD    ((u32)0x3)  

  114. //#define SDIO_SECURE_DIGITAL_IO_COMBO_CARD  ((u32)0x4)  

  115. //#define SDIO_HIGH_CAPACITY_SD_CARD         ((u32)0x5)  

  116. //#define SDIO_HIGH_CAPACITY_MMC_CARD        ((u32)0x6)  

  117.   

  118. #define SDIO_INIT_CLK_DIV                  ((u8)0xB2)  

  119. #define SDIO_TRANSFER_CLK_DIV              ((u8)0x01)  //时钟分频  

  120.   

  121. /* Private macro -------------------------------------------------------------*/  

  122. /* Private variables ---------------------------------------------------------*/  

  123. static u32 CardType =  SDIO_SECURE_DIGITAL_CARD;  

  124. static u32 CSD_Tab[4], CID_Tab[4], RCA = 0;  

  125. //static u32 DeviceMode = SD_POLLING_MODE;  

  126. //static u32 TotalNumberOfBytes = 0, StopCondition = 0;  

  127. u32 *SrcBuffer, *DestBuffer;  

  128. volatile SD_Error TransferError = SD_OK;  

  129. vu32 TransferEnd = 0;  

  130. vu32 NumberOfBytes = 0;  

  131. //SD卡中断服务程序,用来检测卡的插入与移除的  

  132. static void __irq Isr_SDMMC_Card(void);  

  133.   

  134.   

  135. /* Private function prototypes -----------------------------------------------*/  

  136. static SD_Error CmdError(void);  

  137. static SD_Error CmdResp1Error(void);  

  138. static SD_Error CmdResp7Error(void);  

  139. static SD_Error CmdResp3Error(void);  

  140. static SD_Error CmdResp2Error(void);  

  141. static SD_Error CmdResp6Error(u16 *prca);  

  142. static SD_Error SDEnWideBus(u8 EN);  

  143. static SD_Error IsCardProgramming(u8 *pstatus);  

  144. static SD_Error FindSCR(u16 rca, u32 *pscr);  

  145.   

  146. #define DebugPrintf printf  

  147.   

  148. /************************************************************************************************************************* 

  149. * 函数    :   SD_Error SD_Init(void) 

  150. * 功能    :   SD卡初始化 

  151. * 参数    :   无 

  152. * 返回    :   SD_OK:成功,其它见SD Card Error code. 

  153. * 依赖    :   底层寄存器操作函数 

  154. * 作者    :   陈鹏 

  155. * 时间    :   20120516 

  156. * 最后修改时间 : 20120524 

  157. * 说明    :   初始化SD卡 

  158. *************************************************************************************************************************/  

  159. SD_Error SD_Init(void)  

  160. {  

  161.     SD_Error errorstatus = SD_OK;  

  162.       

  163.     SDIO_SoftwareReset(SDIO_RSTALL);    //软件复位所有寄存器  

  164.     SDIO_DeInit();  //初始化SDIO硬件  

  165.     SDIO_FlagITConfig(SDIO_FLAG_CARDREMOVAL | SDIO_FLAG_CARDINSERTION,Enable);//使能卡插入拔出中断  

  166.     Set_IsrAddr(INT_HSMMC0,(vu32)Isr_SDMMC_Card);   //设置中断矢量入口  

  167.     Set_IntEnable(INT_HSMMC0,Enable);   //开启SDMMC0中断  

  168.       

  169.     errorstatus = SD_SetIdleSta();  //SD卡上电  

  170.     if (errorstatus != SD_OK)       //卡上电发送错误  

  171.     {  

  172.         DebugPrintf("SD power up error:(%d)!\n",errorstatus);   //调试,打印错误  

  173.         return(errorstatus);    //返回错误  

  174.     }  

  175.   

  176.     errorstatus = SD_InitializeCards();  

  177.     if (errorstatus != SD_OK)  

  178.     {  

  179.         DebugPrintf("SD initialize error(%d)!\n",errorstatus);  //调试,打印错误  

  180.         return(errorstatus);  

  181.     }  

  182.       

  183.     return(errorstatus);  

  184. }  

  185.   

  186.   

  187.   

  188. /************************************************************************************************************************* 

  189. * 函数    :   SD_Error SD_SetIdleSta(void) 

  190. * 功能    :   SD卡上电进入空闲模式,并识别卡 

  191. * 参数    :   无 

  192. * 返回    :   SD_OK:成功,其它见SD Card Error code. 

  193. * 依赖    :   底层寄存器操作函数 

  194. * 作者    :   陈鹏 

  195. * 时间    :   20120516 

  196. * 最后修改时间 : 20120516 

  197. * 说明    :   SD卡上电进入空闲模式 

  198. *************************************************************************************************************************/  

  199. SD_Error SD_SetIdleSta(void)  

  200. {  

  201.   SD_Error errorstatus = SD_OK;  

  202.   u32 response = 0, count = 0;  

  203.   bool validvoltage = FALSE;  

  204.   u32 SDType = SD_STD_CAPACITY;  

  205.   u16 i;  

  206.   

  207.     SDIO_CLKFrequencySelect(SDCLK_1_64);        //设置时钟400KHZ  

  208.     SDIO_SetTimeOutClock(TIME_OUT_UNIT_KHZ,1);  //设置超时时钟频率最低  

  209.     //发送至少74个时钟,等待SD卡上电成功并同步  

  210.     for(response = 0;response 

  211.     

  212.       

  213.     //循环发生发送CMD0,无响应,无返回,让SD卡进入空闲模式  

  214.     for(i = 0;i 

  215.     {  

  216.         SDIO_SendCommand(CMD0,0,0);       

  217.         errorstatus = CmdError();       //判断命令是否执行成功,此命令只要初始化了SDIO就会执行成功  

  218.         if(errorstatus == SD_OK)  

  219.             break;  

  220.     }  

  221.     if(errorstatus != SD_OK)  

  222.     {  

  223.         DEBUG("error!(%d)\n",errorstatus);  //调试,打印信息     

  224.         return(errorstatus);  

  225.     }  

  226.       

  227.     //发送CMD8:SEND_IF_COND;短响应,命令参数:SD_CHECK_PATTERN;返回响应R7  

  228.     //识别卡版本  

  229.     SDIO_SendCommand(SDIO_SEND_IF_COND,SD_CHECK_PATTERN,SDIO_CMDIndexEn | SDIO_CMDCrcEn | SDIO_Response_Short);  

  230.     errorstatus = CmdResp7Error();  

  231.     if (errorstatus == SD_OK)       //返回成功;说明卡为SD Card 2.0 V2.0  

  232.     {  

  233.         CardType = SDIO_STD_CAPACITY_SD_CARD_V2_0; /* SD Card 2.0 */  

  234.         SDType = SD_HIGH_CAPACITY;    

  235.         DEBUG("SDIO_STD_CAPACITY_SD_CARD_V2_0!\n"); //调试,打印错误信息  

  236.     }  

  237.     else    //V1.0 V1.1  

  238.     {  

  239.         DEBUG("SD Card V1.1!\n");   //调试,打印信息  

  240.         CardType = SDIO_STD_CAPACITY_SD_CARD_V1_1;      //V1.0 V1.1  

  241.         SDIO_SendCommand(CMD55,0,SDIO_CMDIndexEn | SDIO_CMDCrcEn | SDIO_Response_Short);  

  242.         CmdResp1Error();  

  243.     }  

  244.   

  245.     do  

  246.     {  

  247.         //发送CMD55 SDIO_APP_CMD;命令参数:0;返回响应R1,设置RCA为0,短响应  

  248.         SDIO_SendCommand(SDIO_APP_CMD,0,SDIO_CMDIndexEn | SDIO_CMDCrcEn | SDIO_Response_Short);  

  249.         errorstatus = CmdResp1Error();  

  250.         if (errorstatus != SD_OK)  

  251.         {  

  252.             DEBUG("CMD55 error(%d)!\n",errorstatus);    //调试,打印错误信息  

  253.             return(errorstatus);  

  254.         }  

  255.         //发送ACM41命令;命令参数:SD_APP_OP_COND(0x80100000);短响应.响应为R3,返回操作条件寄存器RCA  

  256.         SDIO_SendCommand(SDIO_SD_APP_OP_COND,SD_VOLTAGE_WINDOW_SD | SDType,SDIO_CMDIndexEn | SDIO_CMDCrcEn | SDIO_Response_Short);  

  257.         errorstatus = CmdResp3Error();  

  258.         if (errorstatus != SD_OK)  

  259.         {  

  260.             DEBUG("ACM41 error(%d)!\n",errorstatus);    //调试,打印错误信息  

  261.             return(errorstatus);  

  262.         }  

  263.         response = SDIO_GetResponse(SDIO_RESP1);    //获取响应,RESE1  

  264.         validvoltage = (bool) (((response >> 31) == 1) ? 1 : 0);  

  265.         count++;  

  266.     }  

  267.     while((!validvoltage) && (count 

  268.   

  269.     if (count >= SD_MAX_VOLT_TRIAL)  //重试次数超出  

  270.     {  

  271.         errorstatus = SD_INVALID_VOLTRANGE;  

  272.         return(errorstatus);  

  273.     }  

  274.   

  275.     if (response &= SD_HIGH_CAPACITY)  

  276.     {  

  277.         CardType = SDIO_HIGH_CAPACITY_SD_CARD;  

  278.     }  

  279.   

  280.     return(errorstatus);  

  281. }  

  282.   

  283. /************************************************************************************************************************* 

  284. * 函数    :   SD_Error SD_PowerOFF(void) 

  285. * 功能    :   SD卡掉电 

  286. * 参数    :   无 

  287. * 返回    :   SD_OK:成功,其它见SD Card Error code. 

  288. * 依赖    :   底层寄存器操作函数 

  289. * 作者    :   陈鹏 

  290. * 时间    :   20120516 

  291. * 最后修改时间 : 20120516 

  292. * 说明    :   SD卡掉电 

  293. *************************************************************************************************************************/  

  294. SD_Error SD_PowerOFF(void)  

  295. {  

  296.     SD_Error errorstatus = SD_OK;  

  297.       

  298.     SDIO_BusPowerOFF(); //关闭总线电源  

  299.       

  300.     return(errorstatus);  

  301. }  

  302.   

  303.   

  304. /************************************************************************************************************************* 

  305. * 函数    :   SD_Error SD_PowerON(void) 

  306. * 功能    :   SD卡电源开启 

  307. * 参数    :   无 

  308. * 返回    :   SD_OK:成功,其它见SD Card Error code. 

  309. * 依赖    :   底层寄存器操作函数 

  310. * 作者    :   陈鹏 

  311. * 时间    :   20120516 

  312. * 最后修改时间 : 20120524 

  313. * 说明    :   SD卡电源开启 

  314. *************************************************************************************************************************/  

  315. SD_Error SD_PowerON(void)  

  316. {  

  317.     SD_Error errorstatus = SD_OK;  

  318.       

  319.     SDIO_BusPowerON();  //打开总线电源  

  320.       

  321.     return(errorstatus);  

  322. }  

  323.   

  324.   

  325.   

  326. /************************************************************************************************************************* 

  327. * 函数    :   SD_Error SD_InitializeCards(void) 

  328. * 功能    :   将所有的卡进行初始化配置 

  329. * 参数    :   无 

  330. * 返回    :   SD_OK:成功,其它见SD Card Error code. 

  331. * 依赖    :   底层寄存器操作函数 

  332. * 作者    :   陈鹏 

  333. * 时间    :   20120516 

  334. * 最后修改时间 : 20120516 

  335. * 说明    :   将所有的卡进行初始化配置 

  336. *************************************************************************************************************************/  

  337. SD_Error SD_InitializeCards(void)  

  338. {  

  339.     SD_Error errorstatus = SD_OK;  

  340.     u16 rca = 0x01;  

  341.   

  342.     //发送CMD2 SDIO_ALL_SEND_CID命令,命令参数:0;长回复,R2  

  343.     //发送CMD用来获取CID信息的  

  344.     SDIO_SendCommand(SDIO_ALL_SEND_CID,0,SDIO_CMDIndexEn | SDIO_CMDCrcEn | SDIO_Response_Long);  

  345.     errorstatus = CmdResp2Error();              //获取响应R2  

  346.     if (errorstatus != SD_OK)  

  347.     {  

  348.         DEBUG("error!(%d)\n",errorstatus);                  //调试,打印错误信息  

  349.         return(errorstatus);  

  350.     }  

  351.     //到每个卡以获取每个卡的唯一标识CID  

  352.     CID_Tab[0] = SDIO_GetResponse(SDIO_RESP1);        

  353.     CID_Tab[1] = SDIO_GetResponse(SDIO_RESP2);  

  354.     CID_Tab[2] = SDIO_GetResponse(SDIO_RESP3);  

  355.     CID_Tab[3] = SDIO_GetResponse(SDIO_RESP4);  

  356.       

  357.     //发送CMD3,SET_REL_ADDR命令,参数0,响应,短响应,R6  

  358.     //用来获取卡地址  

  359.     //主机发送CMD3(SEND_RELATIVE_ADDR)要求卡发布一个新的相对卡地址RCA,地址比CID短,在以后的数据传输模式中用来寻址卡。一旦获得RCA后,卡状态变成就绪状态(Stand-by state)  

  360.     SDIO_SendCommand(SDIO_SET_REL_ADDR,0,SDIO_CMDIndexEn | SDIO_CMDCrcEn | SDIO_Response_Short);  

  361.     errorstatus = CmdResp6Error(&rca);  //获取卡地址  

  362.     if (errorstatus != SD_OK)  

  363.     {  

  364.         DEBUG("error!(%d)!\n",errorstatus);                 //调试,打印错误信息  

  365.         return(errorstatus);  

  366.     }  

  367.           

  368.     RCA = rca;//存储卡地址  

  369.       

  370.     //发送CMD9 SDIO_SEND_CSD命令,参数:rca地址;长响应,R2;  

  371.     //给卡发送一个新的RCA,主要是用来设置卡地址的  

  372.     SDIO_SendCommand(SDIO_SEND_CSD,(u32)rca <

  373.     errorstatus = CmdResp2Error();  

  374.     if (errorstatus != SD_OK)  

  375.     {  

  376.         DEBUG("error!(%d)!\n",errorstatus);                 //调试,打印错误信息  

  377.         return(errorstatus);  

  378.     }  

  379.       

  380.     //获取CSD  

  381.     CSD_Tab[0] = SDIO_GetResponse(SDIO_RESP1);  

  382.     CSD_Tab[1] = SDIO_GetResponse(SDIO_RESP2);  

  383.     CSD_Tab[2] = SDIO_GetResponse(SDIO_RESP3);  

  384.     CSD_Tab[3] = SDIO_GetResponse(SDIO_RESP4);  

  385.       

  386.     //选中卡,并激活  

  387.     errorstatus = SD_SelectDeselect((u32)RCA <

  388.     if(errorstatus != SD_OK)  

  389.     {  

  390.         DEBUG("SelectDeselect error!(%d)!\n",errorstatus);                  //调试,打印错误信息  

  391.         return(errorstatus);  

  392.     }  

  393.   

  394.     errorstatus = SD_OK; /* All cards get intialized */  

  395.       

  396.     SDIO_CLKFrequencySelect(SDCLK_1_2); //设置时钟  

  397.     SDIO_SetTimeOutClock(TIME_OUT_UNIT_KHZ,63); //设置超时时钟频率最高  

  398.     errorstatus = SD_EnableWideBusMode(Enable);  

  399.     if(errorstatus == SD_OK)    //配置SD卡为4线模式  

  400.     {  

  401.         DEBUG("SD SDIO 4BIT OK\n");  

  402.     }  

  403.     else  

  404.     {  

  405.         errorstatus = SD_EnableWideBusMode(Disable);  

  406.         DEBUG("SD SDIO 4BIT ERROR (%d)\n",errorstatus);  

  407.     }  

  408.       

  409.     SDIO_SetTransferBlockSize(SD_BlockSize);//设置传输块大小为512字节  

  410.     errorstatus = SD_SetBlockSize(SD_BlockSize);//配置SD卡块大小    

  411.     if (errorstatus != SD_OK)  

  412.     {  

  413.         DEBUG("SD SetBlockSize error(%d)!\n",errorstatus);  

  414.         return(errorstatus);  

  415.     }  

  416.       

  417.     return(errorstatus);  

  418. }  

  419.   

  420.   

  421. /************************************************************************************************************************* 

  422. * 函数    :   SD_Error SD_SelectDeselect(u32 addr) 

  423. * 功能    :   选中一个卡,并处于传输状态 

  424. * 参数    :   addr:卡地址 

  425. * 返回    :   SD_OK:成功,其它见SD Card Error code. 

  426. * 依赖    :   底层寄存器操作函数 

  427. * 作者    :   陈鹏 

  428. 『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
单片机制作超级流水灯