<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > 基于ARM含SD控制器的SD卡的SDIO模式驅(qū)動解析

          基于ARM含SD控制器的SD卡的SDIO模式驅(qū)動解析

          作者: 時間:2016-11-11 來源:網(wǎng)絡 收藏
          SD卡由日本松下、東芝及美國SanDisk公司于1999年8月共同開發(fā)研制。

          SD卡的結構能保證數(shù)字文件傳送的安全性,也很容易重新格式化,因此越來越多的被應用的嵌入式系統(tǒng)中。

          本文引用地址:http://www.ex-cimer.com/article/201611/316808.htm

          SD卡的使用非常方便,常見的有兩種工作模式:SPI和SDIO。SPI是串行的工作模式,速度相對較低,但是使用方便,只要MCU含有SPI接口均可使用。SDIO模式,可以最多4線傳輸,因此速度比較快,由于SD卡的普及,越來越多的MCU內(nèi)部集成了SDIO控制器,簡化了我們的工作。本文以三星s3c2410為例介紹。

          1.SD卡的接口電路

          2.SD卡的協(xié)議

          SD卡的控制指令非常強大,支持SPI,SDIO模式,兼容MMC等。而且不同的

          指令有不同的響應(3種),這在我們使用指令是要注意的。我在附件里面放了一個SD卡的中文協(xié)議,包括數(shù)據(jù)包介紹,指令索引介紹,反饋介紹等。

          3.S3C2410 SD卡控制器的介紹

          SD卡控制器幫我們完成了協(xié)議上的很多工作,我們只需要按照協(xié)議配置寄存器

          以及按照協(xié)議流程對SD卡操作就可以完成SD卡的功能了。

          SDICON:完成SD卡基礎配置,包括大小端,中斷允許,模式選擇,時鐘使能等。

          SDIPRE:對SDCLK的配置。

          SDICARG:指令的參數(shù)存放在這里

          SDICCON:控制指令形式的寄存器,配置SPI還是SDI指令,指令的反饋長度,是否等待反饋,是否運行指令,指令的索引等

          SDICSTA:指令狀態(tài)寄存器,指令是否超時,傳送,結束,CRC是否正確等

          SDIRSPO:反映SD的狀態(tài)

          SDITIMER:設置超時時間

          SDIBSIZE:block的大小

          SDIDCON:數(shù)據(jù)控制寄存器,配置是幾線傳輸,數(shù)據(jù)發(fā)送方向,數(shù)據(jù)傳送方式等。

          SDIDSTA:數(shù)據(jù)狀態(tài)寄存器,數(shù)據(jù)是否發(fā)送完,CRC效驗,超時等

          SDIFSTA:FIFO狀態(tài)積存器,DMA傳輸時否判斷FIFO

          SDIMSK:中斷屏蔽

          4.SD卡SDIO模式的驅(qū)動分析

          4.1SD卡的初始化

          步驟是:1)配置時鐘,慢速一般為400K,設置工作模式

          2)發(fā)送CMD0,進入空閑態(tài),該指令沒有反饋

          3)發(fā)送CMD55+ACMD41,判斷SD卡的上電是否正確,短反饋

          4)發(fā)送CMD2,驗證SD卡是否接入,長反饋

          5)發(fā)送CMD3,讀取SD卡的RCA(地址),短反饋

          6)發(fā)送CMD7,使能SD卡

          7)配置高速時鐘,準備數(shù)據(jù)傳輸,一般20M~25M

          8)發(fā)送CMD55+ACMD6配置為4bit數(shù)據(jù)傳輸模式

          代碼如下:

          int SD_card_init(void)

          {

          int i;

          char key;

          rSDIPRE=PCLK/(2*INICLK)-1;//時鐘400KHz

          rSDICON=(1<<4)|(1<<1)|1;// Type B, FIFO reset, clk enable

          rSDIBSIZE=0x200;// 512byte(128word)

          rSDIDTIMER=0xffff;// Set timeout count

          for(i=0;i<0x1000;i++);// Wait 74SDCLK for MMC card

          CMD0();//進入idle

          //--CheckSDcard OCR

          if(Chk_SD_OCR())//發(fā)送AM41,判斷電壓正確否

          ;

          else

          {

          ;

          return 0;

          }

          RECMD2:

          rSDICARG=0x0;

          // CMD2(stuff bit),判斷連接

          rSDICCON=(0x1<<10)|(0x1<<9)|(0x1<<8)|0x42;

          //lng_resp, wait_resp, start, CMD2

          //-- Check end of CMD2

          if(!Chk_CMDend(2, 1))//查詢反饋是否正確

          goto RECMD2;

          RECMD3:

          //--Send RCA,得到SD卡的地址

          rSDICARG=MMC<<16;

          // CMD3(MMC:SetRCA,SD:Ask RCA-->SBZ)

          rSDICCON=(0x1<<9)|(0x1<<8)|0x43;

          // sht_resp, wait_resp, start, CMD3

          //-- Check end of CMD3

          if(!Chk_CMDend(3, 1))

          goto RECMD3;

          //--Publish RCA

          RCA=( rSDIRSP0 & 0xffff0000 )>>16;

          //--State(stand-by) check

          if( rSDIRSP0 & 0x1e00!=0x600 )

          // CURRENT_STATE check驗證反饋

          goto RECMD3;

          rSDIPRE=PCLK/(2*NORCLK)-1;

          //設置高速時鐘Normal clock="25MHz"

          Card_sel_desel(1);// Select SD

          Set_4bit_bus();//設置為4bit模式

          }

          void Set_4bit_bus(void)

          {

          Wide=1;

          SetBus();

          }

          void SetBus(void)

          {

          SET_BUS:

          CMD55();

          // Make ACMD

          //-- CMD6 implement

          rSDICARG=Wide<<1;

          //Wide 0: 1bit, 1: 4bit

          rSDICCON=(0x1<<9)|(0x1<<8)|0x46;

          //sht_resp, wait_resp, start, CMD55

          if(!Chk_CMDend(6, 1))// ACMD6

          goto SET_BUS;

          }

          4.2SD卡的讀與寫

          讀寫就是正反向的問題,這里只分析讀

          步驟:1)讀單block CMD17多block CMD18

          (寫單block CMD24多block CMD25)

          2)發(fā)送CMD12,終止數(shù)據(jù)傳輸

          程序如下:采用DMA模式

          void Rd_Block(void)

          {

          int status;

          rd_cnt=0;

          rSDICON |= rSDICON|(1<<1);// FIFO reset

          rSDICARG=0x0;// CMD17/18(addr參數(shù))

          RERDCMD:

          pISR_DMA0=(unsigned)DMA_end;//DMA的相關配置

          rINTMSK = ~(BIT_DMA0);

          rDISRC0=(int)(SDIDAT);// SDIDAT

          rDISRCC0=(1<<1)+(1<<0);// APB, fix

          rDIDST0=(U32)(Rx_buffer);// Rx_buffer

          rDIDSTC0=(0<<1)+(0<<0);// AHB, inc

          rDCON0=(1<<31)+(0<<30)+(1<<29)+(0<<28)+(0<<27)+(2<<24)+(1<<23)+(1<<22)+(2<<20)+128*block;

          //handshake, sync PCLK, TC int, single tx, single service, SDI, H/W request,

          //auto-reload off, word, 128blk*num

          rDMASKTRIG0=(0<<2)+(1<<1)+0;

          //no-stop, DMA2 channel on, no-sw trigger

          rSDIDCON=(1<<19)|(1<<17)|(Wide<<16)|(1<<15)|(2<<12)|(block<<0);

          // Rx after rsp, blk, 4bit bus, dma enable, Rx start, blk num

          if(block<2)// SINGLE_READ

          {

          rSDICCON=(0x1<<9)|(0x1<<8)|0x51;

          // sht_resp, wait_resp, dat, start, CMD17

          if(!Chk_CMDend(17, 1))

          //-- Check end of CMD17

          goto RERDCMD;

          }

          else// MULTI_READ

          {

          rSDICCON=(0x1<<9)|(0x1<<8)|0x52;

          // sht_resp, wait_resp, dat, start, CMD18

          if(!Chk_CMDend(18, 1))

          //-- Check end of CMD18

          goto RERDCMD;

          }

          while(!TR_end);

          rINTMSK |= (BIT_DMA0);

          TR_end=0;

          rDMASKTRIG0=(1<<2);//DMA0 stop

          break;

          default:

          break;

          }

          //-- Check end of DATA

          if(!Chk_DATend())

          ;

          rSDIDSTA=0x10;// Clear data Tx/Rx end

          if(block>1)

          {

          RERCMD12:

          //--Stop cmd(CMD12)

          rSDICARG=0x0;//CMD12(stuff bit)

          rSDICCON=(0x1<<9)|(0x1<<8)|0x4c;

          //sht_resp, wait_resp, start, CMD12

          //-- Check end of CMD12

          if(!Chk_CMDend(12, 1))

          goto RERCMD12;

          }

          }

          4.3上面用到的響應判斷函數(shù)

          主要完成對反饋狀態(tài)的分析。

          函數(shù)如下:

          int Chk_CMDend(int cmd, int be_resp)//指令反饋判斷函數(shù)

          {

          int finish0;

          if(!be_resp)// No response

          {

          finish0=rSDICSTA;

          while((finish0&0x800)!=0x800)//驗證指令是不是發(fā)送

          finish0=rSDICSTA;

          rSDICSTA=finish0;// Clear cmd end state

          return 1;

          }

          else// With response

          {

          finish0=rSDICSTA;

          while( !( ((finish0&0x200)==0x200) | ((finish0&0x400)==0x400) ))

          //驗證反饋響應完成

          finish0=rSDICSTA;

          if(cmd==1 | cmd==9 | cmd==41)// CRC no check

          {

          if( (finish0&0xf00) != 0xa00 )// CRC是否錯誤

          {

          rSDICSTA=finish0;// Clear error state

          if(((finish0&0x400)==0x400))//驗證超時

          return 0;}

          rSDICSTA=finish0;

          // Clear cmd & rsp end state

          }

          else// CRC check

          {

          if( (finish0&0x1f00) != 0xa00 )// Check error

          {

          ;

          rSDICSTA=finish0;// Clear error state

          if(((finish0&0x400)==0x400))

          return 0;// Timeout error

          }

          rSDICSTA=finish0;

          }

          return 1;

          }

          }

          int Chk_DATend(void)

          {

          int finish;

          finish=rSDIDSTA;

          while( !( ((finish&0x10)==0x10) | ((finish&0x20)==0x20) ))

          // Chek timeout or data end

          finish=rSDIDSTA;

          if( (finish&0xfc) != 0x10 )

          {

          rSDIDSTA=0xec;// Clear error state

          return 0;

          }

          return 1;

          }

          int Chk_BUSYend(void)//數(shù)據(jù)反饋判斷函數(shù)

          {

          int finish;

          finish=rSDIDSTA;

          while( !( ((finish&0x08)==0x08) | ((finish&0x20)==0x20) ))

          finish=rSDIDSTA;//等待數(shù)據(jù)發(fā)送完成或超時

          if( (finish&0xfc) != 0x08 )

          {

          rSD

          IDSTA=0xf4;//clear error state

          return 0;

          }

          return 1;

          }



          關鍵詞: ARMSD控制器SDIO模

          評論


          技術專區(qū)

          關閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();