niuyi
驱动牛犊
驱动牛犊
  • 注册日期2006-06-08
  • 最后登录2010-02-24
  • 粉丝1
  • 关注0
  • 积分13分
  • 威望34点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
阅读:2485回复:4

做裸笨SD卡驱动(SDIO)碰到的奇怪问题,有经验的请进。

楼主#
更多 发布于:2008-08-07 16:13
为了实现从SD卡升级系统
最近在做PXA270的裸笨下的SD卡驱动(CLK=9.75M),用SDIO通讯,
出现了CMD17读数据不对,但SD卡初始化是对的。
读数据有以下几个特点:
我读取0扇区的数据时,发现有4个数据是对的。本来这4个数据中间的3个丢了
例如,本来应该是
448[ 61],449[ 0],450[ 6],451[ 29],452[221],453[218],454[249],455[ 0],456[ 0],457[ 0],458[ 7],459[ 91],460[ 30]
但实际是:
224[ 61]225[221]226[ 0]227[ 30]

其他的位置都是0
还有个现象,就是从RXFIFO中只能读8次(应该是16次)每次32字节,然后就等不到RXFIFO请求了。


串口消息如下:
Send command 0 to card (Reset SD/MMC).
MMC stat is 0x2140
Send ACMD41 to card (Reset SD/MMC).
Get response <R1> (0x37, 0x0, 0x0, 0x1, 0x20, 0x0)
SD Card OCR register is 0xff8000
...(重复20-30次后)
SD Card OCR register is 0xff8000
Get response <R1> (0x37, 0x0, 0x0, 0x1, 0x20, 0x0)
SD Card OCR register is 0x80ff8000
Begin send CMD2 (ALL_SEND_CID) to card.
0[3f]1[1b]2[53]3[4d]4[30]5[30]6[30]7[30]8[30]9[10]a[b1]b[28]c[25]d[5a]e[0]f[83]10[3f]11[1b]Begin send CMD3 (SEND_RELATIVE_ADDR) to card.
cmd3 RES for CARD ADDRESS: response <R1> (0x3, 0x0, 0x2, 0x5, 0x0, 0x30)
Card address : 0x2
Begin send CMD9 (SEND_CSD) to card.//这里读到的CSD是对的,因为我用SPI方式可以正常通讯,也是一模一样的值
0[3f]1[0]2[7f]3[ff]4[32]5[5f]6[59]7[83]8[cb]9[76]a[db]b[df]c[ff]d[96]e[40]f[0]10[3f]11[0]---------------------SD Card CSD register-------------------
csd = 0x0
taac.man = 0x7f
nsac = 0xff
tran_speed.man = 0x32
ccc = 0x5f5
read_len = 0x9
read_part = 0x1
write_mis = 0x0
read_mis = 0x0
dsr = 0x0
c_size = 0xf2d
vcc_r_min = 0x6
vcc_r_max = 0x2
vcc_w_min = 0x6
vcc_w_max = 0x6
c_size_mult = 0x7
er_blk_en = 0x1
er_sec_size = 0x3f
wp_grp_size = 0x7f
wp_grp_en = 0x1
r2w_factor = 0x5
write_len = 0x9
write_part = 0x0
ffmt_grp = 0x0
copy = 0x0
perm_wp = 0x0
tmp_wp = 0x0
ffmt = 0x0
--------------------------END--------------------------
Begin send CMD7 (Select/deselect_card) to card.
cmd7 RES for CARD ADDRESS: response <R1> (0x7, 0x0, 0x0, 0x7, 0x0, 0x5f)
Begin send CMD16 (SEND_STATUS) to card.
Get response <R1> (0x10, 0x20, 0x0, 0x9, 0x0, 0x5f)
Begin send CMD17 () to card.
Get response <R1> (0x11, 0x0, 0x0, 0x9, 0x0, 0x5f)
xxxxxxxx//这里只有8次
wait rxfifo req out 17 out delay = 0//我加了超时才退出来,否则,死等
xwait transfer done out 17 out delay = 65534
//下面是读出来的数据
0[ 0] 1[ 0] 2[ 0] 3[ 0] 4[ 0] 5[ 0] 6[ 0] 7[ 0] 8[ 0] 9[ 0] 10[ 0] 11[ 0] 12[ 0] 13[ 0] 14[ 0] 15[ 0] 16[ 0] 17[ 0] 18[ 0] 19[ 0] 20[ 0] 21[ 0] 22[ 0] 23[ 0] 24[ 0] 25[ 0] 26[ 0] 27[ 0] 28[ 0] 29[ 0] 30[ 0] 31[ 0] 32[ 0] 33[ 0] 34[ 0] 35[ 0] 36[ 0] 37[ 0] 38[ 0] 39[ 0] 40[ 0] 41[ 0] 42[ 0] 43[ 0] 44[ 0] 45[ 0] 46[ 0] 47[ 0] 48[ 0] 49[ 0] 50[ 0] 51[ 0] 52[ 0] 53[ 0] 54[ 0] 55[ 0] 56[ 0] 57[ 0] 58[ 0] 59[ 0] 60[ 0] 61[ 0] 62[ 0] 63[ 0] 64[ 0] 65[ 0] 66[ 0] 67[ 0] 68[ 0] 69[ 0] 70[ 0] 71[ 0] 72[ 0] 73[ 0] 74[ 0] 75[ 0] 76[ 0] 77[ 0] 78[ 0] 79[ 0] 80[ 0] 81[ 0] 82[ 0] 83[ 0] 84[ 0] 85[ 0] 86[ 0] 87[ 0] 88[ 0] 89[ 0] 90[ 0] 91[ 0] 92[ 0] 93[ 0] 94[ 0] 95[ 0] 96[ 0] 97[ 0] 98[ 0] 99[ 0]100[ 0]101[ 0]102[ 0]103[ 0]104[ 0]105[ 0]106[ 0]107[ 0]108[ 0]109[ 0]110[ 0]111[ 0]112[ 0]113[ 0]114[ 0]115[ 0]116[ 0]117[ 0]118[ 0]119[ 0]120[ 0]121[ 0]122[ 0]123[ 0]124[ 0]125[ 0]126[ 0]127[ 0]128[ 0]129[ 0]130[ 0]131[ 0]132[ 0]133[ 0]134[ 0]135[ 0]136[ 0]137[ 0]138[ 0]139[ 0]140[ 0]141[ 0]142[ 0]143[ 0]144[ 0]145[ 0]146[ 0]147[ 0]148[ 0]149[ 0]150[ 0]151[ 0]152[ 0]153[ 0]154[ 0]155[ 0]156[ 0]157[ 0]158[ 0]159[ 0]160[ 0]161[ 0]162[ 0]163[ 0]164[ 0]165[ 0]166[ 0]167[ 0]168[ 0]169[ 0]170[ 0]171[ 0]172[ 0]173[ 0]174[ 0]175[ 0]176[ 0]177[ 0]178[ 0]179[ 0]180[ 0]181[ 0]182[ 0]183[ 0]184[ 0]185[ 0]186[ 0]187[ 0]188[ 0]189[ 0]190[ 0]191[ 0]192[ 0]193[ 0]194[ 0]195[ 0]196[ 0]197[ 0]198[ 0]199[ 0]200[ 0]201[ 0]202[ 0]203[ 0]204[ 0]205[ 0]206[ 0]207[ 0]208[ 0]209[ 0]210[ 0]211[ 0]212[ 0]213[ 0]214[ 0]215[ 0]216[ 0]217[ 0]218[ 0]219[ 0]220[ 0]221[ 0]222[ 0]223[ 0]224[ 61]225[221]226[ 0]227[ 30]228[ 0]229[ 0]230[ 0]231[ 0]232[ 0]233[ 0]234[ 0]235[ 0]236[ 0]237[ 0]238[ 0]239[ 0]240[ 0]241[ 0]242[ 0]243[ 0]244[ 0]245[ 0]246[ 0]247[ 0]248[ 0]249[ 0]250[ 0]251[ 0]252[ 0]253[ 0]254[ 0]255[ 0]256[ 0]257[ 0]258[ 0]259[ 0]260[ 0]261[ 0]262[ 0]263[ 0]264[ 0]265[ 0]266[ 0]267[ 0]268[ 0]269[ 0]270[ 0]271[ 0]272[ 0]273[ 0]274[ 0]275[ 0]276[ 0]277[ 0]278[ 0]279[ 0]280[ 0]281[ 0]282[ 0]283[ 0]284[ 0]285[ 0]286[ 0]287[ 0]288[ 0]289[ 0]290[ 0]291[ 0]292[ 0]293[ 0]294[ 0]295[ 0]296[ 0]297[ 0]298[ 0]299[ 0]300[ 0]301[ 0]302[ 0]303[ 0]304[ 0]305[ 0]306[ 0]307[ 0]308[ 0]309[ 0]310[ 0]311[ 0]312[ 0]313[ 0]314[ 0]315[ 0]316[ 0]317[ 0]318[ 0]319[ 0]320[ 0]321[ 0]322[ 0]323[ 0]324[ 0]325[ 0]326[ 0]327[ 0]328[ 0]329[ 0]330[ 0]331[ 0]332[ 0]333[ 0]334[ 0]335[ 0]336[ 0]337[ 0]338[ 0]339[ 0]340[ 0]341[ 0]342[ 0]343[ 0]344[ 0]345[ 0]346[ 0]347[ 0]348[ 0]349[ 0]350[ 0]351[ 0]352[ 0]353[ 0]354[ 0]355[ 0]356[ 0]357[ 0]358[ 0]359[ 0]360[ 0]361[ 0]362[ 0]363[ 0]364[ 0]365[ 0]366[ 0]367[ 0]368[ 0]369[ 0]370[ 0]371[ 0]372[ 0]373[ 0]374[ 0]375[ 0]376[ 0]377[ 0]378[ 0]379[ 0]380[ 0]381[ 0]382[ 0]383[ 0]384[ 0]385[ 0]386[ 0]387[ 0]388[ 0]389[ 0]390[ 0]391[ 0]392[ 0]393[ 0]394[ 0]395[ 0]396[ 0]397[ 0]398[ 0]399[ 0]400[ 0]401[ 0]402[ 0]403[ 0]404[ 0]405[ 0]406[ 0]407[ 0]408[ 0]409[ 0]410[ 0]411[ 0]412[ 0]413[ 0]414[ 0]415[ 0]416[ 0]417[ 0]418[ 0]419[ 0]420[ 0]421[ 0]422[ 0]423[ 0]424[ 0]425[ 0]426[ 0]427[ 0]428[ 0]429[ 0]430[ 0]431[ 0]432[ 0]433[ 0]434[ 0]435[ 0]436[ 0]437[ 0]438[ 0]439[ 0]440[ 0]441[ 0]442[ 0]443[ 0]444[ 0]445[ 0]446[ 0]447[ 0]448[ 0]449[ 0]450[ 0]451[ 0]452[ 0]453[ 0]454[ 0]455[ 0]456[ 0]457[ 0]458[ 0]459[ 0]460[ 0]461[ 0]462[ 0]463[ 0]464[ 0]465[ 0]466[ 0]467[ 0]468[ 0]469[ 0]470[ 0]471[ 0]472[ 0]473[ 0]474[ 0]475[ 0]476[ 0]477[ 0]478[ 0]479[ 0]480[ 0]481[ 0]482[ 0]483[ 0]484[ 0]485[ 0]486[ 0]487[ 0]488[ 0]489[ 0]490[ 0]491[ 0]492[ 0]493[ 0]494[ 0]495[ 0]496[ 0]497[ 0]498[ 0]499[ 0]500[ 0]501[ 0]502[ 0]503[ 0]504[ 0]505[ 0]506[ 0]507[ 0]508[ 0]509[ 0]510[ 0]511[ 0]
!! ERROR !! <reading the main partition table>

我参考过WINCE、网上(说是能正确工作的程序)、朋友给的(能正确工作的程序)
跟这几种程序的发命令流程、参数、回应完全一致。但是最后仍然有这样的问题,
排除硬件问题,因为在WINCE下SD卡可以工作正常同样工作在9.75M,还有换别的卡也出现一样的问题

如果谁有经验请赐教,这个问题卡了我好几天了。
niuyi
驱动牛犊
驱动牛犊
  • 注册日期2006-06-08
  • 最后登录2010-02-24
  • 粉丝1
  • 关注0
  • 积分13分
  • 威望34点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2008-08-07 16:28
补充:


    Log ("Begin send CMD17 () to card.\r\n");
    if (send_command_to_cards (17, (BlockAddr * 0x200),
                                (MMC_CMDAT_DATA_EN | MMC_CMDAT_RESPONSE_R1), 1, 1, 0)//(1<<11)|
         != MSC_PASSED)
      return MSC_FAILED;
    delay = 0xffff;
    while(!(*MMC_I_REG & 1)){
        if(!delay--)
            break;
    }
    if (getrespondR1 (1) != MSC_PASSED)
        return MSC_FAILED;
    
    i = 0;delay = 0xffff;
    while ( (i < 0x200) )
    {
        do {
            mmc_ireg = *MMC_I_REG;
            if(!(--delay))
                break;
            }
        while(! (mmc_ireg & MMC_IREG_RXFIFO_REQ));    
        if (*MMC_I_REG & MMC_IREG_RXFIFO_REQ)
        {
            for (j = 0; j < 32; j++)
            {
                pBufPtr[i++] = *MMC_RXFIFO;//pMMC_RX_Fifo;
            }
            Log("x");
        }

        if(!delay)
            break;
        else
            delay = 0xffff;
    }


Log("\r\nwait rxfifo req out 17  out  delay = %d\r\n",delay);
    pBufPtr += i;

    delay = 0xffff;
    do {
        mmc_stat = *MMC_STAT;// READ_MMC_REGISTER_DWORD( pSDMMCRegisters, MMC_STAT);
        Log("x");
        if(delay == 0)
            break;
        else
            delay--;
    } while (!(mmc_stat & MMC_STAT_DATA_TRANSFER_DONE)) ;
Log("wait transfer done out 17  out  delay = %d\r\n",delay);
niuyi
驱动牛犊
驱动牛犊
  • 注册日期2006-06-08
  • 最后登录2010-02-24
  • 粉丝1
  • 关注0
  • 积分13分
  • 威望34点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2008-08-07 17:44
再补充:
看SD卡spec
发完CMD7命令后SD卡应该是"data"状态
可是根据我的命令回复却是"tran "状态
Begin send CMD17 () to card.
Get response <R1> (0x11, 0x0, 0x0, 0x9, 0x0, 0x5f)

如果是
Get response <R1> (0x11, 0x0, 0x0, 0xa, 0x0, 0x5f)
则是data 状态

sd spec 第50页有说明这点。
但是现在不知道怎么才能让他在发CMD17时返回"data"状态。
niuyi
驱动牛犊
驱动牛犊
  • 注册日期2006-06-08
  • 最后登录2010-02-24
  • 粉丝1
  • 关注0
  • 积分13分
  • 威望34点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
地板#
发布于:2008-08-08 23:42
s     结贴!!!!
问题出在这句:  
pBufPtr[i++] = *MMC_RXFIFO;//pMMC_RX_Fifo;  
PXA270的书册说从寄存器MMC_RXFIFO读到的32位数据的高24位无效,可是我读出来的是有效的.所以把有效的3字节就这样当作无效丢了。  
经过多次看PXA270手册,对读这个寄存器还是没有很准确和清晰的描述和使用,甚至有矛盾 的地方.(就这样让我检查了 一周,也因为这个原因我对SD的协议却非常熟悉了,呵呵,还感谢这个PXA270 spec的错误)  
sufferpriest
驱动牛犊
驱动牛犊
  • 注册日期2008-06-06
  • 最后登录2009-01-22
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望11点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2009-01-20 13:40
CMD18才返回data状态,CMD17返回trans,并且CMD17每次只能读一个512字节
游客

返回顶部