分享

SD Card 驱动流程分析

 jiffes 2017-07-24

一、硬件接口电路

         首先来看一下SD card的一个硬件应用电路,如下图所示:

        SD卡有两种工作模式,一个是spi接口模式,一个是SD模式,后者传输速率快些,这里讨论SD模式;SD总线包含4个数据总线(SDIO0-SDIO3),1个命令线(SDCMD)和一个同步时钟SDCLK;图上第10脚是卡检测信号。这里需注意的是传输总线必须加上拉。数据总线不一定全部要用到,根据需求可以选择数据总线个数。

 

二、SD卡初始化过程

             SD卡的初始化过程,简单一点说包括:1.主机reset所有挂在SD总线上的CARD. 2.确认卡的工作电压范围。3.获取卡的RCA(相对地址)。卡划分为十个工作状态,分别是如下所示:

 

        初始化阶段需要涉及前面四个状态,即inactive state、idle 、ready、identification  state。 初始化状态图如下:

 

        SD卡是通过命令与host互动的,主机发命令,sd卡接收到命令后返回相应的响应。所有命令和响应的传输都是在命令线上进行的。刚上电时,host发送CMD0来reset所有的sd卡(不管当前处于什么状态),使之进入idle状态。

        通过发送CMD8命令,告诉SD卡host提供的工作电压范围,若SD卡支持host提供的工作范围,将在命令线上返回该值,可以说明当前是ver2.0SD存储卡。若SD卡不支持host提供的工作电压范围,它将没有响应而继续处在idle state。如果该卡没有响应则是ver1.x。对于高容量SD存储卡CMD8命令是必须的。接下来需要发送ACMD41来决定是否拒绝或者说抛弃当前的SD卡(让它们进入inactive state),很明显那些与host设计工作电压范围不匹配的卡将会遭此待遇。另外ACMD41命令的参数里面还包含了HCS位,即host capicity support,置1表示host支持高容量sd卡。对于高容量SD存储卡,该位必须设为1,否则高容量卡响应中的busy 位不会置1,该busy位在OCR寄存器的第31位,是用来指示SD卡是否初始化完毕,即进入ready state(busy bit is set to 1)。对于标准SD容量卡,HCS位设为0。要使的sd卡初始化完成并进入ready状态,不仅HCS位要设置正确,host还必须重复发送ACMD41命令,直到busy 位置1。ACMD41的响应中除了busy位,还有一个CCS位(card capcity status),当CCS = 1时,表示当前sd卡是高容量sd卡,CCS=0表示当前sd卡是标准容量sd卡。

      接着host发送cmd2来获取sd卡的一些出厂信息(CID),比如出厂序列号之类的,这些信息也是通过命令响应的方式传送给host,sd卡返回CID信息后就进入identification state。

      发送cmd3使card传送rca给host,rca是用来给sd卡编址的,用于后面的数据传送。一旦获取了rca,sd卡就进入stand-by state。这个时候如果host想得到新的rca,再次发送cmd3即可。

      具体的初始化和卡识别流程如下图:

      初始化注意事项:1、在初始化动作之前,至少发送74个null clock ,否则可能会遇到初始化失败。

2、ACMD命令发送之前需要发送cmd55命令,告诉sd卡host接下来要发送ACMD类型的命令,A表示application,初始化的时候cmd55命令参数中的rca使用默认的值0x0000,初始化之后必须是相应rca。

3、整个初始化过程使用小于400KHZ时钟,因为有的卡在初始化和识别阶段对clock有限制,在数据传送之前把clock调整即可。

 

三、数据传送      

         

       从上图可以很清晰地看到它的一个流程,进入数据传送模式开始sd卡是处在Stand-by状态的,此时可以发送命令获取SD卡的一些信息,比如发送cmd9来计算sd卡的容量。要想进入transfer状态,我们必须通过CMD7先选中某一张卡,该命令的参数设为我们想要选中sd卡的RCA,即初始化阶段得到的RCA。在同一个时刻,只能有一张卡处在transfer状态,其他与cmd7命令携带参数(RCA)不匹配的卡会回到stand-by状态。所以说要选中某张卡,只要设置相应的RCA,而释放一张卡,我们就设置与之不匹配的RCA(一般设为默认的值0x0000)。选中卡之后就进入transfer state,这时我们可以发送acmd6设置数据传输的总线位宽,默认是1,注意此操作有两个前提,一是处在transfer state ,二是当前卡没有被lock。发送cmd17读单快数据,cmd18读多块数据,cmd24写单块,cmd25写多块,这些命令都带需要读取数据的首地址。在对多块进行读写的时,直到host发送cmd12才停止。

       对block写数据操作完成后,sd卡会进入编程阶段,sd卡是提供缓冲区的,也就是说上一个block在编程时可以写下一个block数据。当缓冲区满了,并且这是卡还在programming,这时DAT0数据线会被拉低,告诉host此时忙碌。

四、程序

        程序是在ZSP200内核的DSP芯片上实现的,16位数据总线,60MH的奔跑速度。下面是调试代码,还没来及优化,实现了block的读写,在板子上验证ok

  1. <span style="font-family:Microsoft YaHei;font-size:12px;"></span>   
  1. <span style="font-family:Microsoft YaHei;font-size:12px;">void sd_mmc_setup()  
  2. {  
  3.     uint16 reg16_val;  
  4.     uint32 reg32_val;  
  5.     U8 i;  
  6.       
  7.     SysReadAMBAReg((uint32)SYS_PWRPEN_REG,reg32_val);  
  8.     reg32_val |= (1L<<2);  
  9.     SysWriteAMBAReg((uint32)SYS_PWRPEN_REG,reg32_val);      //开启SD/MMC控制器  
  10.   
  11.     sys_delay_ms(300L);  
  12.      
  13.     mmc_write_reg(MMC_CAR_SEL, 0xdd);        // enable module, enable mmcclk   
  14.     mmc_write_reg(MMC_CRC_CTL, 0xd0);        // CRC circuit enable  
  15.     mmc_write_reg(MMC_CTL, 0x0b);            // 1bit,low speed(256KHZ),1/4 divider,auto transfer, mmc mode.  
  16.     //mmc_write_reg(MMC_INT_MASK, 0x7f);       // unmask all interrupt   
  17.     
  18.     for (i = 0; i<10; i++)                   // at least 74 clock for setup  
  19.     {  
  20.         mmc_write_reg(MMC_IO,0x24);          // only 8 null clock generation  
  21.   
  22.         mmc_read_reg(MMC_INT_CLR,reg16_val);  
  23.         while(reg16_val != 0x01)  
  24.         {  
  25.             mmc_read_reg(MMC_INT_CLR,reg16_val);  
  26.         }  
  27.         mmc_write_reg(MMC_INT_CLR,reg16_val);  
  28.     }  
  29.   
  30.     myptf("sd_mmc_setup finished!\r\n");  
  31.       
  32.     return;  
  33. }  
  34.   
  35. U8 sd_write_cmd(U8 *cmd, BOOL b_resp)  
  36. {  
  37.     U8 i;  
  38.     uint16 reg16_val;  
  39.     uint32 addr = MMC_CMD_BUF4;  
  40.       
  41.     for(i=0;i<5;i++)  
  42.     {  
  43.       mmc_write_reg(addr, cmd[i]);  
  44.       addr -= 2;  
  45.     }  
  46.     if(b_resp == FALSE)  
  47.     {  
  48.         mmc_write_reg(MMC_IO,0x04);     //auto only command enable  
  49.     }  
  50.     else if ((cmd == cmd2) || (cmd == cmd9))  
  51.     {  
  52.         mmc_write_reg(MMC_IO,0x54);     //auto command + response,enable get CID front command buffer[135:8]  
  53.         //mmc_write_reg(MMC_IO,0x0c);    //auto only response enable  
  54.     }  
  55.     /*else if (cmd == cmd24) 
  56.     { 
  57.         mmc_write_reg(MMC_IO, 0x01);              //write data, trig transfer 
  58.     }*/  
  59.     else   
  60.     {  
  61.         mmc_write_reg(MMC_IO,0x44);     //auto command + response  
  62.     }  
  63.   
  64.     /*wait and clear sdmmc CMD done interrupt*/  
  65.     mmc_read_reg(MMC_INT_CLR,reg16_val);  
  66.     while(!(reg16_val & (1<<0)))  
  67.     {  
  68.         mmc_read_reg(MMC_INT_CLR,reg16_val);  
  69.         if ((reg16_val & (1<<6)) != 0)           //command or response timer out  
  70.         {  
  71.             mmc_write_reg(MMC_INT_CLR,0x40);    //clear interrupt;  
  72.             myptf("Send Cmd%d  Timerout!\r\n", cmd[0]-0x40);  
  73.             return 0;  
  74.         }  
  75.     }  
  76.     myptf("Interrupt Flag : %d\r\n", reg16_val);  
  77.     mmc_write_reg(MMC_INT_CLR,0x1);        //clear CMD done interrupt;  
  78.       
  79.     return 1;  
  80. }  
  81. SD_RESPONSE_INFO get_response_info(void//Only for 48 bit response  
  82. {  
  83.     SD_RESPONSE_INFO res;  
  84.     uint16 reg16_val;  
  85.     uint32 reg32_val,addr;  
  86.     U8 i;  
  87.       
  88.     addr = MMC_CMD_BUF3;  
  89.     mmc_read_reg(MMC_CMD_BUF4, reg16_val);  
  90.     myptf("res.cmd_index =%d\r\n", reg16_val);  
  91.     res.cmd_index = reg16_val;  
  92.   
  93.     for (i=0; i<4; i++)  
  94.     {     
  95.         reg32_val <<= 8;  
  96.         mmc_read_reg(addr, reg16_val);  
  97.         reg32_val |= reg16_val;  
  98.         addr -= 2;  
  99.     }  
  100.     res.card_status = reg32_val;  
  101.       
  102.     myptf("res.card_status =%ld\r\n", reg32_val);  
  103.   
  104.     mmc_read_reg(MMC_CRC_VAL, reg16_val);  
  105.     res.crc = reg16_val;  
  106.   
  107.     return res;  
  108.   
  109. }  
  110.   
  111. BOOL sd_mmc_identify()  
  112. {  
  113.     SD_RESPONSE_INFO resp;  
  114.     U16 reg16_val;  
  115.     U8 i;  
  116.   
  117.     sd_write_cmd(cmd0,FALSE);       //set the card into idle state  
  118.   
  119.     sd_write_cmd(cmd8,TRUE);        //verify the card operation condition;  
  120.     resp = get_response_info();       
  121.   
  122.     CardType = 0; //ver2.0  
  123.     if ( (resp.cmd_index != 0x08)  
  124.       || (resp.card_status != 0x15a) )  
  125.     {  
  126.         myptf("Erro Response for cmd8\r\n");  
  127.         CardType = 1;   
  128.     }  
  129.   
  130.     myptf("Ready to Tansmit ACMD!\r\n");  
  131.     do  
  132.     {  
  133. CMD55:                                    
  134.         sd_write_cmd(cmd55, TRUE);      //For Transmit ACMD;  
  135.         resp = get_response_info();  
  136.         if ((resp.card_status & (1L<<5)) != 0x20)  
  137.         {  
  138.             goto CMD55;  
  139.         }  
  140.   
  141.         if(CardType == 0)  
  142.             sd_write_cmd(acmd41_1, TRUE);  
  143.         else  
  144.             sd_write_cmd(acmd41_0, TRUE);  
  145.         resp = get_response_info();  
  146.         if ( (resp.cmd_index != 0x3f)   
  147.           || ((resp.card_status & 0x00ffffff) != 0xff8000) )  
  148.         {  
  149.             myptf("Unusable Card!\r\n");  
  150.             //return FALSE;  
  151.         }  
  152.     }while( (resp.card_status & (1L<<31)) == 0 ); //card is busy Wait for power up!   
  153.     myptf("SD Card Power On!\r\n");  
  154.     if ( !(resp.card_status & (1L<<30)) )  
  155.     {  
  156.         myptf("This is Standard Capacity SD Memery Card!\r\n");  
  157.     }  
  158.     else  
  159.     {  
  160.         myptf("This is High Capacity SD Memery Card!\r\n");  
  161.     }  
  162. CMD2:  
  163.     sd_write_cmd(cmd2,TRUE);    //it makes card identification state  
  164.     mmc_read_reg(MMC_CMD_BUF15, reg16_val);  
  165.     if (reg16_val != 0x3f)  
  166.     {  
  167.         goto CMD2;  
  168.     }  
  169.     myptf("Read CID...\r\n");  
  170. CMD3:  
  171.     sd_write_cmd(cmd3,TRUE);    //get the card's RCA and change to standby state;  
  172.     resp = get_response_info();  
  173.     if (resp.cmd_index != 0x03)  
  174.     {  
  175.         //myptf("Erro Response for cmd3!\r\n");  
  176.         goto CMD3;  
  177.     }  
  178.     card_addr = (U16)((resp.card_status & 0xffff0000) >> 16);  
  179.     card_state = (U16)(resp.card_status & 0x0000ffff);  
  180.     myptf("current card addr is %ld\r\n",card_addr);  
  181.     myptf("current card state is %ld\r\n",card_state);  
  182.       
  183.     return TRUE;  
  184. }  
  185. BOOL read_cards_capacity(U16 rca)  
  186. {  
  187.     U16 reg16_val;  
  188.     U32 c_size;  
  189.   
  190.     cmd9[1] = rca/256;  
  191.     cmd9[2] = rca%256;  
  192.     sd_write_cmd(cmd9, TRUE);  
  193.     mmc_read_reg(MMC_CMD_BUF15, reg16_val);  
  194.     if (reg16_val != 0x3f)  
  195.     {  
  196.         myptf("Read Capacity Failed!\r\n");  
  197.         return FALSE;  
  198.     }  
  199.       
  200.     mmc_read_reg(MMC_CMD_BUF7, reg16_val); //read c_zize value  
  201.     c_size = reg16_val & 0x3f;  
  202.     c_size <<= 8;  
  203.     mmc_read_reg(MMC_CMD_BUF6, reg16_val);  
  204.     c_size |= reg16_val;  
  205.     c_size <<= 8;  
  206.     mmc_read_reg(MMC_CMD_BUF5, reg16_val);  
  207.     c_size |= reg16_val;  
  208.   
  209.     card_capacity = ((c_size + 1) * 512) / 1024;  
  210.   
  211.     return TRUE;    
  212. }  
  213. void card_select(U16 rca, BOOL sel)  //change between standby and transfer state;  
  214. {  
  215.     SD_RESPONSE_INFO resp;  
  216.       
  217.     cmd7[1] = 0x00;     //deselect card;  
  218.     cmd7[2] = 0x00;  
  219.     if (sel == TRUE)    //Select card  
  220.     {  
  221.         cmd7[1] = rca/256;  
  222.         cmd7[2] = rca%256;  
  223.     }  
  224. CMD7:  
  225.     if (!(sd_write_cmd(cmd7, TRUE)))  
  226.     {  
  227.         goto CMD7;  
  228.     }  
  229.     //get_response_info();  
  230. }  
  231.   
  232. void set_bus_width(U8 wide)               // width = 0:1bit; width = 2: 4bit ;  
  233. {  
  234.   
  235.     acmd6[4] = wide;  
  236.     cmd55[1] = card_addr/256;  
  237.     cmd55[2] = card_addr%256;                 //note: cmd55's argument include rca;  
  238. SETBUS:  
  239.     sd_write_cmd(cmd55, TRUE);                //For Transmit ACMD;  
  240.     //get_response_info();  
  241.     if (!(sd_write_cmd(acmd6, TRUE)))  
  242.     goto SETBUS;  
  243.     get_response_info();      
  244.     return;  
  245. }  
  246.   
  247. void set_block_size()  
  248. {  
  249.     sd_write_cmd(cmd16, TRUE);  // set block length 512 bytes;  
  250.     get_response_info();  
  251. }  
  252.   
  253. void read_block(U32 addr, U8 block_cnt)  
  254. {  
  255.     U16 reg16_val;  
  256.     U32 reg32_val;  
  257.     U8 i,j;  
  258.     //SD_RESPONSE_INFO resp;  
  259.   
  260.     //addr <<= 9;             // addr*521  
  261.     mmc_write_reg(MMC_buf_ctl, 0x9000);       //active fifo status,flush fifo,disable dma,read sd-card,wm-128  
  262.       
  263.     if (block_cnt < 2)      //read single block  
  264.     {  
  265.         cmd17[1] = (U8)(addr>>24);  
  266.         cmd17[2] = (U8)((addr>>16) & 0xff);  
  267.         cmd17[3] = (U8)((addr>>8) & 0xff);  
  268.         cmd17[4] = (U8)(addr & 0xff);                 
  269. CMD17:  
  270.         if(!(sd_write_cmd(cmd17, TRUE)))  
  271.         {  
  272.             goto CMD17;  
  273.         }  
  274.         get_response_info();  
  275.         mmc_write_reg(MMC_BYTE_CNTH, 0x02);               //transfer 512 bytes  
  276.         mmc_write_reg(MMC_IO, 0x03);                      //read data, auto transfer     
  277.     }  
  278.     else                                                  //read multi blockss  
  279.     {  
  280.         cmd18[1] = (U8)(addr>>24);  
  281.         cmd18[2] = (U8)((addr>>16) & 0xff);  
  282.         cmd18[3] = (U8)((addr>>8) & 0xff);  
  283.         cmd18[4] = (U8)(addr & 0xff);  
  284. CMD18:          
  285.         if (!(sd_write_cmd(cmd18, TRUE)))  
  286.         {  
  287.             goto CMD18;  
  288.         }  
  289.         //get_response_info();  
  290.         //sys_delay_ms(20L);                               //delay befor trig transfer orelse erro  
  291.         mmc_write_reg(MMC_BLOCK_CNT, block_cnt);         // set read block number;  
  292.         //mmc_write_reg(MMC_IO, 0xc0);  
  293.         mmc_write_reg(MMC_IO_MBCTL, 0x53);               // trig data transfer;      
  294.     }  
  295.       
  296.     mmc_read_reg(MMC_buf_ctl, reg16_val);  
  297.     while( !( reg16_val & ( 1<<0 ) ) )                  //wait for fifo full;  
  298.     {  
  299.         mmc_read_reg(MMC_buf_ctl, reg16_val);  
  300.     }  
  301.     //myptf("FIFO Full\r\n");  
  302.     for(j=0; j<128*block_cnt; j++)  
  303.     {  
  304.         /*mmc_read_reg(MMC_buf_ctl, reg16_val); 
  305.         while( ( reg16_val & ( 1<<1 ) ) == 0x02 )              // fifo empty? 
  306.         { 
  307.             mmc_read_reg(MMC_buf_ctl, reg16_val); 
  308.             myptf("fifo empty!\nPlease Wait...\r\n"); 
  309.         }*/  
  310.         SysReadAMBAReg(MMC_DATA_BUF0, sd_rd_buf[j]);  
  311.         //for(i=0; i<50; i++);                           //delay for reading data else data erro appeared;  
  312.     }    
  313.     mmc_read_reg(MMC_INT_CLR,reg16_val);               //wait for data transfer finished  
  314.     while( (reg16_val & (1<<1)) != 0x02 )         
  315.     {  
  316.         mmc_read_reg(MMC_INT_CLR,reg16_val);  
  317.     }  
  318.     myptf("Read Data Finished!\r\n");  
  319.     mmc_write_reg(MMC_INT_CLR,0x02);                  //clear interrupt;  
  320.       
  321.     //mmc_read_reg(MMC_buf_ctl, reg16_val);  
  322.     //myptf("fifo full?:%d\r\n", (reg16_val&0x01));  
  323.     //myptf("fifo Empty?:%d\r\n", (reg16_val&0x02));  
  324.   
  325.     if (block_cnt > 1)  
  326.     {  
  327.         while((reg16_val & (1<<4)) != 0x10)  
  328.         {  
  329.             mmc_read_reg(MMC_INT_CLR,reg16_val);  
  330.         }  
  331.         mmc_write_reg(MMC_INT_CLR,0x10);            //clear interrupt flag;   
  332.         myptf("Read Muliti Block Finished!\r\n");  
  333. CMD12:  
  334.         if (!(sd_write_cmd(cmd12, TRUE)))  
  335.         {  
  336.             goto CMD12;  
  337.         }  
  338.     }  
  339. }  
  340.   
  341. void write_block(U32 addr, U8 block_cnt)        //block_cnt <65536  
  342. {  
  343.     U16 reg16_val;  
  344.     U8 i,j;  
  345.     //SD_RESPONSE_INFO resp;  
  346.   
  347.     //addr <<= 9;  
  348.     if (block_cnt < 2)                            //write single block  
  349.     {  
  350.         cmd24[1] = (U8)(addr>>24);  
  351.         cmd24[2] = (U8)((addr>>16) & 0xff);  
  352.         cmd24[3] = (U8)((addr>>8) & 0xff);  
  353.         cmd24[4] = (U8)(addr & 0xff);  
  354. CMD24:  
  355.         if(!(sd_write_cmd(cmd24, TRUE)))  
  356.         {  
  357.             goto CMD24;  
  358.         }  
  359.         //get_response_info();  
  360.         //sys_delay_ms(20L);  
  361.         mmc_write_reg(MMC_BYTE_CNTH, 0x02);       //transfer 512 bytes   
  362.         mmc_write_reg(MMC_buf_ctl, 0x9800);       //active fifo status,disable dma, write sd-card,  
  363.         mmc_write_reg(MMC_IO, 0x01);              //write data, trig transfer  
  364.     }  
  365.     else                                          //write multi block  
  366.     {  
  367.         cmd25[1] = (U8)(addr>>24);  
  368.         cmd25[2] = (U8)((addr>>16) & 0xff);  
  369.         cmd25[3] = (U8)((addr>>8) & 0xff);  
  370.         cmd25[4] = (U8)(addr & 0xff);  
  371.         cmd55[1] = card_addr / 256;  
  372.         cmd55[2] = card_addr % 256;  
  373.         acmd23[3] = block_cnt / 256;  
  374.         acmd23[4] = block_cnt % 256;  
  375. ACMD23:  
  376.         sd_write_cmd(cmd55, TRUE);  
  377.         if(!(sd_write_cmd(acmd23, TRUE)))  
  378.         {  
  379.             goto ACMD23;  
  380.         }  
  381. CMD25:    
  382.         if(!(sd_write_cmd(cmd25, TRUE)))  
  383.         {  
  384.             goto CMD25;  
  385.         }  
  386.         //get_response_info();  
  387.         //sys_delay_ms(20L);  
  388.         mmc_write_reg(MMC_BLOCK_CNT, block_cnt);   // set write block number;   
  389.         mmc_write_reg(MMC_buf_ctl, 0x9800);       //active fifo status,disable dma, write sd-card,  
  390.         mmc_write_reg(MMC_IO_MBCTL, 0x51);        // trig data transfer;    
  391.     }  
  392.     mmc_read_reg(MMC_buf_ctl, reg16_val);  
  393.     while( !( reg16_val & ( 1<<1 ) ) )           //wait for fifo empty;  
  394.     {  
  395.         mmc_read_reg(MMC_buf_ctl, reg16_val);  
  396.     }  
  397.     //myptf("FIFO Empty\r\n");  
  398.     for(j=0; j<128*block_cnt; j++)  
  399.     {             
  400.         SysWriteAMBAReg(MMC_DATA_BUF0, sd_rd_buf[j]);  
  401.         //for(i=0; i<220; i++);  
  402.         /*mmc_read_reg(MMC_buf_ctl, reg16_val); 
  403.         while((reg16_val & 0x01) == 0x01)              //fifo full? 
  404.         { 
  405.             myptf("fifo full!\nPlease Wait...\r\n"); 
  406.             mmc_read_reg(MMC_buf_ctl, reg16_val); 
  407.         }*/  
  408.     }  
  409.     mmc_read_reg(MMC_INT_CLR,reg16_val);         //wait for data transfer finished   
  410.     while((reg16_val & (1<<1)) != 0x02 )          
  411.     {   
  412.         mmc_read_reg(MMC_INT_CLR,reg16_val);  
  413.     }  
  414.     myptf("Interrupt Flag : %d\r\n", reg16_val);  
  415.     mmc_write_reg(MMC_INT_CLR,0x02);             //clear data done interrupt;  
  416.     myptf("Write Data finished!\r\n");  
  417.     if ( block_cnt > 1 )  
  418.     {  
  419.         while((reg16_val & (1<<4)) != 0x10)     //wait multi block done  
  420.         {  
  421.             mmc_read_reg(MMC_INT_CLR,reg16_val);  
  422.         }  
  423.         mmc_write_reg(MMC_INT_CLR,0x10);        //clear multi block done interrupt;  
  424.         myptf("Write multi block finished!\r\n");  
  425. CMD12_1:  
  426.         if (!(sd_write_cmd(cmd12, TRUE)))       //End Data transfer;  
  427.         {  
  428.             goto CMD12_1;  
  429.         }  
  430.         get_response_info();  
  431.     }         
  432. }  
  433.   
  434. void sd_mmc_initial()  
  435. {  
  436.     sd_mmc_setup();  
  437.     if (sd_mmc_identify() == FALSE)  
  438.     {  
  439.         myptf("sd card initial failed!\r\n");  
  440.     }  
  441.     else  
  442.     {            
  443.         myptf("sd card initial succesful!\r\n");  
  444.           
  445.         if ( read_cards_capacity(card_addr) == TRUE )  
  446.         {  
  447.             myptf("current card capacity is: %ldM\r\n", card_capacity);  
  448.         }  
  449.         card_select(card_addr, TRUE);  
  450.         set_bus_width(BUS_4_BIT);             // set transfer data bus;  
  451.         set_block_size();  
  452.         mmc_write_reg(MMC_CTL,0xc3);          // 4bit data,high speed(30M),1/2 divider,auto transfer, mmc mode.  
  453.         mmc_write_reg(MMC_IO_MBCTL, 0x50);    // timer out scal   
  454.     }     
  455. }  
  456.   
  457. </span>  

/*测试代码*/

  1. U8 cmd0[5]={0x40,0x00,0x00,0x00,0x00};  
  2. U8 cmd2[5]={0x42,0x00,0x00,0x00,0x00};  
  3. U8 cmd3[5]={0x43,0x00,0x00,0x00,0x00};  
  4. U8 cmd7[5]={0x47,0x00,0x00,0x00,0x00};  
  5. U8 cmd8[5]={0x48,0x00,0x00,0x01,0x5a};     // 2.7-3.6V; use‘10101010b’for the‘check pattern’  
  6. U8 cmd9[5]={0x49,0x00,0x00,0x00,0x00};  
  7. U8 cmd12[5]={0x4c,0x00,0x00,0x00,0x00};    // stop transfer command;  
  8. U8 cmd16[5]={0x50,0x00,0x00,0x02,0x00};    // set block length 512 bytes;  
  9. U8 cmd17[5]={0x51,0x00,0x00,0x00,0x00};    // read single block;  
  10. U8 cmd18[5]={0x52,0x00,0x00,0x00,0x00};    // read multi block;   
  11. U8 cmd24[5]={0x58,0x00,0x00,0x00,0x00};    // write single block;  
  12. U8 cmd25[5]={0x59,0x00,0x00,0x00,0x00};    // write single block;  
  13. U8 cmd55[5]={0x77,0x00,0x00,0x00,0x00};  
  14. U8 acmd6[5]={0x46,0x00,0x00,0x00,0x00};    // set transfer data bus  
  15. U8 acmd23[5]={0x57,0x00,0xff,0x80,0x00};  
  16. U8 acmd41_1[5]={0x69,0x40,0xff,0x80,0x00}; // HCS =1; voltage range 2.7-3.6V;  
  17. U8 acmd41_0[5]={0x69,0x00,0xff,0x80,0x00}; // HCS =0; voltage range 2.7-3.6V;  
  18.      
  19. typedef struct  
  20. {  
  21.     U8 cmd_index;  
  22.     uint32 card_status;  
  23.     U8 crc;  
  24. }SD_RESPONSE_INFO;  
  25.   
  26. uint16 card_addr;  
  27. uint16 card_state;  
  28. U8 CardType;  
  29. U32 card_capacity;  
  30. U32 sd_rd_buf[1024]={0};  
  31. U32 sd_write_buf[512]={0};  


  1.    
  1. void main()  
  1. {  
  1. sd_mmc_initial();  
  2. while(1)  
  3. {  
  4.     sys_wdtrestart();  
  5.     read_block(153600, 8);           
  6.     //read_block(153601, 3);           //31760  
  7.     //read_block(300, 3);             //30760*512  
  8.     //read_block(30, 1);           //30*512  
  9.     for(j=0; j<128; j++)  
  10.     {            
  11.         myptf("sd_rd_buf[%d] = %ld\r\n", j, sd_rd_buf[j]);  
  12.     }  
  13.     write_block(153605, 1);  
  14.     write_block(153606, 8);  
  15.     //write_block(153609, 3);  
  16.     //read_block(153604, 3);  
  17.     /*for(j=0; j<384; j++) 
  18.     {           
  19.         myptf("sd_rd_buf[%d] = %ld\r\n", j, sd_rd_buf[j]); 
  20.     }*/  
  21.     //while(1);  
  22. }  
  1. }  

 就分析到这里,有分析不对的地方请博友们指正,愿意同大家交流。微笑

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多