在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

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

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

            作者: 時間:2016-12-08 來源:網(wǎng)絡(luò) 收藏

              SD卡由日本松下、東芝及美國SanDisk公司于1999年8月共同開發(fā)研制。

            本文引用地址:http://www.biyoush.com/article/201612/341311.htm

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

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

              1. SD卡的接口電路

                

             

              2. SD卡的協(xié)議

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

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

              3. S3C2410 SD卡控制器的介紹

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

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

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

              SDIPRE:對SDCLK的配置。

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

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

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

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

              SDITIMER:設(shè)置超時時間

              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.1 SD卡的初始化

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

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

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

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

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

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

              7)配置高速時鐘,準(zhǔn)備數(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(); //進(jìn)入idle

              //-- Check SD card 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:Set RCA, 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;

              // 設(shè)置高速時鐘Normal clock="25MHz"

              Card_sel_desel(1); // Select SD

              Set_4bit_bus(); //設(shè)置為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的相關(guān)配置

              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上面用到的響應(yīng)判斷函數(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) ))

              // 驗證反饋響應(yīng)完成

              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;

              }



            關(guān)鍵詞: ARM SDIO

            評論


            相關(guān)推薦

            技術(shù)專區(qū)

            關(guān)閉