全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:4349
推到 Plurk!
推到 Facebook!

讀取SD CARD遭遇到奇怪現象!

答題得分者是:bernie_w39
mmppeegg
一般會員


發表:1
回覆:11
積分:2
註冊:2008-10-22

發送簡訊給我
#1 引用回覆 回覆 發表時間:2008-11-03 11:47:06 IP:118.166.xxx.xxx 訂閱
大家好, 這個問題小弟困擾已久了.
小弟為了讀到啟動扇區的0xEB花了不少功夫, 卻始終失敗, 麻煩大家看看.
1. 讀取sector 0: 如果第一個byte是0, 則判斷第0x1be的byte是否為0x80或0x00. (此時[0x1be]為0x00)
2. 如果[0x1be]是0x80或0x00, 則讀取[0x1be]之後的第8, 9, 10, 11個byte並將其串起來(此時第8個byte為0x61, 第9個byte~第11個byte皆為0)
3. 讀取sector 0x61的內容.
於是接下來讀到的內容如下:
00000000h: B6 D1 80 E2 3F F7 E2 86 CD C0 ED 06 41 66 0F B7
00000010h: 02 00 00 00 00 F8 00 00 3F 00 FF 00 61 00 00 00
00000020h: 9F D3 03 00 CC 03 00 00 00 00 00 00 02 00 00 00
00000030h: 01 00 06 00 00 00 00 00 00 00 00 00 00 00 00 00
00000040h: 00 00 29 90 AC 61 9C 4E 4F 20 4E 41 4D 45 20 20
00000050h: 20 20 46 41 54 33 32 20 20 20 33 C9 8E D1 BC F4
00000060h: 7B 8E C1 8E D9 BD 00 7C 88 4E 02 8A 56 40 B4 08
00000070h: CD 13 73 05 B9 FF FF 8A F1 66 0F B6 C6 40 66 0F
00000080h: B6 D1 80 E2 3F F7 E2 86 CD C0 ED 06 41 66 0F B7
而我用WINHEX印出來的資料確是:
00000000h: EB 58 90 4D 53 44 4F 53 35 2E 30 00 02 02 20 00
00000010h: 02 00 00 00 00 F8 00 00 3F 00 FF 00 61 00 00 00
00000020h: 9F D3 03 00 CC 03 00 00 00 00 00 00 02 00 00 00
00000030h: 01 00 06 00 00 00 00 00 00 00 00 00 00 00 00 00
00000040h: 00 00 29 90 AC 61 9C 4E 4F 20 4E 41 4D 45 20 20
00000050h: 20 20 46 41 54 33 32 20 20 20 33 C9 8E D1 BC F4
00000060h: 7B 8E C1 8E D9 BD 00 7C 88 4E 02 8A 56 40 B4 08
00000070h: CD 13 73 05 B9 FF FF 8A F1 66 0F B6 C6 40 66 0F
00000080h: B6 D1 80 E2 3F F7 E2 86 CD C0 ED 06 41 66 0F B7
除了前面16個byte不同之外, 其他都一樣! 更奇怪的是, 第1到第16個byte和第128到第144個byte是一模一樣的!
於是小弟試著去讀別的sector, 發現所有sector的狀況都和這個sector一樣! 第1到第16個byte消失了!
請問有大大有遭遇過一樣的問題嗎? 小弟先謝謝了~

版主


發表:261
回覆:2302
積分:1667
註冊:2005-01-04

發送簡訊給我
#2 引用回覆 回覆 發表時間:2008-11-03 13:11:50 IP:60.249.xxx.xxx 未訂閱
check一下code吧. 你讀到的好像是這一行的data : 

00000080h: B6 D1 80 E2 3F F7 E2 86 CD C0 ED 06 41 66 0F B7

接著才是正確的data
------
-------------------------------------------------------------------------
走是為了到另一境界,停是為了欣賞人生;未走過千山萬水,怎知生命的虛實與輕重!?
mmppeegg
一般會員


發表:1
回覆:11
積分:2
註冊:2008-10-22

發送簡訊給我
#3 引用回覆 回覆 發表時間:2008-11-03 13:37:53 IP:118.166.xxx.xxx 訂閱
感謝回覆, 小弟的處理器是Freescale的IMX31, 有專用的SD介面. 
小弟發現不管去讀哪一個block, 都是會直接讀到第128個byte, 開頭的那16個byte怎樣就是讀不出來.

int ReadOneSecFromCard(U32 AddrOnCard, P_U32 DestAddr)
{
U32 mmc_nob = 1; //U32是指unsign DWORD
int rc = 0;

U32 *pt_des = DestAddr;
U32 SrcAddrOnCard = AddrOnCard;

rc = sdhc_Set_BLock_Length(mmc_blk_len); //mmc_blk_len固定給512
if(rc)
return rc;

//Data to transfer = NOB*BLK_LEN
reg32_write(&v_pSDHCRegs->NOB, 1); //對暫存器寫入1個block的命令
reg32_write(&v_pSDHCRegs->BLK_LEN, mmc_blk_len); // 對暫存器寫入512

rc = sdhc_send_read_command(SrcAddrOnCard, mmc_blk_len, 1);
if(rc) return rc;

sdhc_read_fifo_polling2(SD4_bit, mmc_blk_len, 1, (U32 *)(pt_des)); //這個指令會將SD CARD的block 中的值一個一個讀出來, 一次讀4個byte

rc = sdhc_stop_read_operation(mmc_rca, 1);
if(rc) return rc;
rc = mmc_blk_len*mmc_nob;
return rc;
}

請各位大大幫忙查看這樣的步驟有沒有錯誤, 如需細節小弟隨時再整理出來. 謝謝!
編輯記錄
mmppeegg 重新編輯於 2008-11-03 13:49:08, 註解 無‧
bernie_w39
資深會員


發表:3
回覆:199
積分:280
註冊:2007-10-07

發送簡訊給我
#4 引用回覆 回覆 發表時間:2008-11-03 18:45:11 IP:61.218.xxx.xxx 訂閱
請問 sdhc_read_fifo_polling2 是自己寫的嗎? 還是系統內建的 library?
如果是自己寫的, 要不要檢查一下會不會是這兒寫錯了?
mmppeegg
一般會員


發表:1
回覆:11
積分:2
註冊:2008-10-22

發送簡訊給我
#5 引用回覆 回覆 發表時間:2008-11-04 12:09:11 IP:118.166.xxx.xxx 訂閱
感謝回覆, 小弟這就把這個function整理出來:

static int sdhc_read_fifo_polling2(U32 BusWidth4, U32 blk_len, U32 nob, U32 *dest_addr)
{
U32 buffer_size;
U32 i; // how many buffers for each blk_len
U32 j; // nob
U32 k; // buffer size
U32 m = 0; // source address pointer
U32 buffer_count;
U32 buffer_access_times;
U32 sta;

buffer_size = (BusWidth4 == 0x1)?64:16; //64
buffer_count = blk_len/buffer_size; // buffer count of each block, 8
buffer_access_times = buffer_size/4; //16

for (j = 0; j < nob; j )
{
for(i = 0; i < buffer_count; i )
{

sta = reg32_read(&v_pSDHCRegs->STATUS);
while ( (sta & 0x80) != 0x80 )
{
sta = reg32_read(&v_pSDHCRegs->STATUS);
EdbgOutputDebugString("staloop : %Xh\n",sta); // wait until buffer ready for data
}
for (k = 0; k < buffer_access_times; k )
{
dest_addr[m ]=reg32_read(&v_pSDHCRegs->BUFFER_ACCESS);
EdbgOutputDebugString("dest_addr[%d] : %Xh\n",m-1, dest_addr[m-1]); //這行是小弟特地print出來的結果, 錯誤的值也是從這得到的
}
}
}
return 0;
}
bernie_w39
資深會員


發表:3
回覆:199
積分:280
註冊:2007-10-07

發送簡訊給我
#6 引用回覆 回覆 發表時間:2008-11-04 21:39:03 IP:118.166.xxx.xxx 訂閱
這一部份用看的應該是沒錯, 再請問 reg32_read 是自己寫的, 還是系統的呢?

另外你列出的 hexdump 應該不是 EdbgOutputDebugString("dest_addr[%d] : %Xh\n",m-1, dest_addr[m-1]);
這段程式印出來的吧, 格式看起來不一樣. 是後來輸出的 debug message 有再調整過,
還是是別的地方送出來的?
mmppeegg
一般會員


發表:1
回覆:11
積分:2
註冊:2008-10-22

發送簡訊給我
#7 引用回覆 回覆 發表時間:2008-11-05 15:16:53 IP:118.166.xxx.xxx 訂閱
感謝回應, reg32_read是一個macro, 定義如下:
#define reg32_read(addr) (*(volatile unsigned long * const)(addr))

我的debug訊息是這樣的:
dest_addr[0] : E280D1B6h
dest_addr[1] : 86E2F73Fh
dest_addr[2] : 06EDC0CDh
dest_addr[3] : B70F6641h
dest_addr[4] : 00000002h
dest_addr[5] : 0000F800h
dest_addr[6] : 00FF003Fh
dest_addr[7] : 00000061h
dest_addr[8] : 0003D39Fh
dest_addr[9] : 000003CCh
dest_addr[10] : 00000000h
dest_addr[11] : 00000002h
dest_addr[12] : 00060001h
dest_addr[13] : 00000000h
dest_addr[14] : 00000000h
dest_addr[15] : 00000000h
dest_addr[16] : BA290000h
dest_addr[17] : 4E04ACFFh
dest_addr[18] : 414E204Fh
dest_addr[19] : 2020454Dh
dest_addr[20] : 41462020h
dest_addr[21] : 20323354h
dest_addr[22] : C9332020h
dest_addr[23] : F4BCD18Eh
dest_addr[24] : 8EC18E7Bh
dest_addr[25] : 7C00BDD9h
dest_addr[26] : 8A024E88h
dest_addr[27] : 08B44056h
dest_addr[28] : 057313CDh
dest_addr[29] : 8AFFFFB9h
dest_addr[30] : B60F66F1h
dest_addr[31] : 0F6640C6h
dest_addr[32] : E280D1B6h
dest_addr[33] : 86E2F73Fh
dest_addr[34] : 06EDC0CDh
dest_addr[35] : B70F6641h
dest_addr[36] : E1F766C9h

這些訊息是我將register的第一手資料拿出來, 後來當然是把它分解成unsigned char再做分析了.
很明顯的dest_addr[0]到dest_addr[3]和dest_addr[32] 到dest_addr[35] 是相同的.
如果我的演算法沒錯, 難道錯的是晶片嗎...真不敢相信...
編輯記錄
mmppeegg 重新編輯於 2008-11-05 15:17:34, 註解 無‧
bernie_w39
資深會員


發表:3
回覆:199
積分:280
註冊:2007-10-07

發送簡訊給我
#8 引用回覆 回覆 發表時間:2008-11-05 22:05:11 IP:118.166.xxx.xxx 訂閱
其實我覺得這種 bug, 多半是自己寫的程式有問題. 機率比較大.

不過我之前想要看的, 是真的去讀取資料的部份, 以及顯示資料內容的部份,
目前看到了顯示內容的部份, 看起來是 ok 的. 讀取的部份, 是在
sdhc_send_read_command 這支程式裏嗎?

想要問一下, 傳入參數 SrcAddrOnCard 與 v_pSDHCRegs->BUFFER_ACCESS
之間的關聯, 是在哪兒建立的呢?
mmppeegg
一般會員


發表:1
回覆:11
積分:2
註冊:2008-10-22

發送簡訊給我
#9 引用回覆 回覆 發表時間:2008-11-06 13:28:48 IP:61.218.xxx.xxx 訂閱
先說聲抱歉, 這麼晚才回覆.

感謝大大不辭辛勞! 這iMX31並不是單晶片, 而是ARM11的CPU, 所以有對應的REGISTER可以去做讀取的動作. 所以對REGISTER的
寫入與存取方式也有特別的用法.

小弟這就把程式整理上來:

static int sdhc_send_read_command(U32 Start_addr, U32 blk_len, U32 nob){
int err;
U32 DatCon;
U32 startaddr = Start_addr* blk_len;
U32 arg_rca = 0x1 <<16;

DatCon = 0x209;//0x9|(0x10<<8); //4bit, read, with data, R1
if (nob == 0x1)
{
err = sdhc_issue_cmd_wait_resp(CMD_READ_SINGLE_BLOCK, startaddr, DatCon, CHECK_TIMEOUT);
if (err)
DBGprint("single read error\n");
}
else
{
err = sdhc_issue_cmd_wait_resp(CMD_READ_MULTIPLE_BLOCK, startaddr, DatCon, CHECK_TIMEOUT);
if (err)
DBGprint("multiple read error\n");
}
return err;
}

所以SrcAddrOnCard傳入之後, IMX31會將要讀取的地址寫入到register中, 而v_pSDHCRegs->BUFFER_ACCESS就是另一個register
所得到的card的回傳data. 如果在深入下去的話就得看spec了(如果大大願意的話), 耽誤到大大的時間與精神實在萬分抱歉.
bernie_w39
資深會員


發表:3
回覆:199
積分:280
註冊:2007-10-07

發送簡訊給我
#10 引用回覆 回覆 發表時間:2008-11-06 21:21:09 IP:118.166.xxx.xxx 訂閱
其實我不太能理能您說的 "iMX31並不是單晶片, 而是ARM11的CPU, 所以有對應的REGISTER可以去做讀取的動作.
所以對REGISTER的寫入與存取方式也有特別的用法." 這句話是什麼意思. 我自己沒有用過 ARM 系列的控制器,
所以無從猜起.

不管怎樣, SD 卡的運作是固定的, 指定位置與大小後, 就可以從卡上讀出 data. 如果這部份是系統包裝好的,
照說會出問題的機會不大. 有可能的幾個原因:

1. debug 訊息程式出錯, 明明是正確的資料, 但是 deubg 取自錯誤的位置, 印出錯誤的結果.

2. 資料讀取後, 在 debug 訊息出來之前, 有程式破壞了這一段資料.

3. 資料讀取時, 指定的 記憶體位置不對, 造成本身的覆蓋.

目前只有 1 的程式有看到, 看起來像是對的. 要排除 2, 最好是在讀入資料後, 就直接印出, 不要經過太多呼叫.
3 的話, 要仔細看系統的 library 包裝到什麼程度, 有沒有機會深入去追. 像是 v_pSDHCRegs 裏面的結構, 到底
是如何定義.... 諸如此類的問題.

附上一段我之前用 atmega128 寫的 sd card 讀寫程式, 它以 512 bytes 為單位, 一次讀一個 sector 出來,
用的是 SD card SPI 界面, 你可以注意它在送出了 read single block 指令之後, 要等候 SD card ready, 然後
再把資料一個一個 byte 出來, 最後是省略了 CRC 的檢查. 您不妨找找看, 在系統 library 中, 是否有類似的
動作, 亦或是這部份程式根本就是您自己寫的? 那應該不難找到問題所在.


[code cpp]
u_char sdCardReadBlock(u_char *buf, u_long addr)
// read a single data block from SD card
{
u_char rc = 1, try, rsp;
u_short i;

for (try = 0; try < 16 && rc; try )
{
sdCardSel(1);
sdCardSendCmd(SD_CMD_READ_SINGLE_BLOCK, addr);
if ((rsp = sdCardRecvR1()) == SD_RSPR1_IDLE_STATE)
{
if ((rsp = sdCardRecvR1 ()) == 0xfe)
{
for (i = 0; i < SD_BLOCK_LEN; i )
buf[i] = sdCardIo(0xff);
// ignore CRC
sdCardIo(0xff);
sdCardIo(0xff);
rc = 0;
}
else
printf("SD card command 'READ_SINGLE_BLOCK' doesn't get data leading: result = x\n", rsp);
}
else
printf("SD card command 'READ_SINGLE_BLOCK' fail: result = x\n", rsp);
sdCardSel(0);
}
return rc;
}


[/code]
mmppeegg
一般會員


發表:1
回覆:11
積分:2
註冊:2008-10-22

發送簡訊給我
#11 引用回覆 回覆 發表時間:2008-11-11 11:12:10 IP:118.166.xxx.xxx 訂閱
感謝大大, 並為這麼晚回覆說聲抱歉. 大大所提供的程序小弟會仔細check, 並把實驗結果發表上來. 大大所說的第一點和第二點, 小弟已初步排除, 因為的確是讀到的第一手資料. 整個對SD的控制都是小弟自己寫的, 在這邊把發送command的程式附上, 程序應和大大所說的差不多:  [code cpp]
static int sdhc_issue_cmd_wait_resp(U32 cmd_no, U32 cmd_arg, U32 cmd_dat_cont, U32 chk_res_to )
{
int err;
U32 resp_type;
//U32 status;
//status = reg32_read(&v_pSDHCRegs->STATUS);
//msStall(2);

reg32_write(&v_pSDHCRegs->CMD,cmd_no);
msStall(2);

reg32_write(&v_pSDHCRegs->ARG,cmd_arg);
msStall(2);

reg32_write(&v_pSDHCRegs->CMD_DAT_CONT,cmd_dat_cont);
msStall(2);

//if(cmd_no == 0x0010)
// dbgBreakPt();
//if(cmd_no != 0x0010)
sdhc_enable_clk(); //vannes: ok!

switch(cmd_dat_cont & 0x07) // set FORMAT_OF_RESPONSE
{
case 0:
resp_type = 0; // No response for current command
break;
case 1:
resp_type = 1; // 48-bit response with CRC7 check. Format R1/R1b/R5/R6
break;
case 2:
resp_type = 2; //136-bit, CSD/CID read response. Format R2.
break;
case 3:
resp_type = 3; //48-bit response without CRC check. Format R3/R4
break;
}
#if 1
err = sdhc_wait_end_cmd_resp(chk_res_to, resp_type);
#else
while(err = sdhc_wait_end_cmd_resp(chk_res_to, resp_type));
#endif
return err;
}

static int sdhc_wait_end_cmd_resp (U32 chk_res_to, U32 resp_type)
{
U32 status;
U32 a, b, c;
a = 0;
b = 0;
c = 0;

status = reg32_read(&v_pSDHCRegs->STATUS);
//EdbgOutputDebugString("SD_DL - sdhc_wait_end_cmd_resp: cmd Status: %x\r\n", status);
while((status & 0x2000) == 0x0)
{
//EdbgOutputDebugString("cmd Status: %x\r\n", status);
status = reg32_read(&v_pSDHCRegs->STATUS);
} // wait end_cmd_resp

if (chk_res_to == 0x1)
{
if((status & 0x20)!= 0)
{ // check timeout and crc error status
DBGprint("Error: RESPONSE CRC error\n");
reg32_write(&v_pSDHCRegs->STATUS,0x2020); // clear end_cmd_resp status bit
return MMC_ERR_RESPONSE_CRC;

}
if((status & 0x02)!= 0)
{
DBGprint("Error: RESPONSE TIMEOUT error\n");
reg32_write(&v_pSDHCRegs->STATUS,0x2002); // clear end_cmd_resp status bit
return MMC_ERR_RESPONSE_TIMEOUT;
}
}
else
{
if((status & 0x20)!= 0)
{ // only check crc error status
DBGprint("Error: CRC error\n");
reg32_write(&v_pSDHCRegs->STATUS,0x2020); // clear end_cmd_resp status bit
return MMC_ERR_RESPONSE_CRC;
}
}
reg32_write(&v_pSDHCRegs->STATUS,0x2000); // vannes: why?
// clear end_cmd_resp status bit
msStall(8);
switch(resp_type)
{
//U8 cnt;
case 1:
//48-bits RES. But we only want 32 bits?
a = reg32_read(&v_pSDHCRegs->RES_FIFO);
b = reg32_read(&v_pSDHCRegs->RES_FIFO);
c = reg32_read(&v_pSDHCRegs->RES_FIFO);
gResp[0] = ((a&0xff)<<24) | ((b& 0xffff)<<8) | ((c&0xff00)>>8);
//EdbgOutputDebugString("CRC7 check RES!! gResp[0]: %Xh\n",gResp[0]);
break;
case 2:
// vannes: Four 32-bit information. So total 4*32 = 128 bit? Why not 136-bit?
// Bcz the first byte is not stored in FIFO!!!
a = reg32_read(&v_pSDHCRegs->RES_FIFO);
b = reg32_read(&v_pSDHCRegs->RES_FIFO);
gResp[0] = ((a<<16) | (b& 0xffff));
a = reg32_read(&v_pSDHCRegs->RES_FIFO);
b = reg32_read(&v_pSDHCRegs->RES_FIFO);
gResp[1] = ((a<<16) | (b& 0xffff));
a = reg32_read(&v_pSDHCRegs->RES_FIFO);
b = reg32_read(&v_pSDHCRegs->RES_FIFO);
gResp[2] = ((a<<16) | (b& 0xffff));
a = reg32_read(&v_pSDHCRegs->RES_FIFO);
b = reg32_read(&v_pSDHCRegs->RES_FIFO);
gResp[3] = ((a<<16) | (b& 0xffff));
break;
case 3:
//Stall(10);
a = reg32_read(&v_pSDHCRegs->RES_FIFO);
b = reg32_read(&v_pSDHCRegs->RES_FIFO);
c = reg32_read(&v_pSDHCRegs->RES_FIFO);
gResp[0] = ((a&0xff)<<24) | ((b& 0xffff)<<8) | ((c&0xff00)>>8);

break;
default:
memset((void *)&gResp[0], 0, sizeof(U32)*4);
break;
}
return MMC_ERR_NONE;
}

[/code]
程式碼繁雜, 請大大勿怪. 所有的register都是32bit. msStall是delay函式.
bernie_w39
資深會員


發表:3
回覆:199
積分:280
註冊:2007-10-07

發送簡訊給我
#12 引用回覆 回覆 發表時間:2008-11-12 16:54:21 IP:61.218.xxx.xxx 訂閱
來回看了你的程式幾次, 因為我不太能理解你使用的 cpu 特性, 所以有些問題還猜不透.

想要請問一下, 你現在的狀況, 是不管讀哪一個 sector, 都會是第 0-15 bytes 被 128-143bytes
取代的狀況嗎? 還是只是單純 0-15bytes 資料不正確? 有沒有試過連續讀 2 個以上的 sector
進來看看呢?
mmppeegg
一般會員


發表:1
回覆:11
積分:2
註冊:2008-10-22

發送簡訊給我
#13 引用回覆 回覆 發表時間:2008-11-13 12:05:23 IP:118.166.xxx.xxx 訂閱
是的! 讀每一個block都如此!
連續讀兩個block我還沒試過!
可是連續讀2個不是那些讀sector的程序都要重做一遍嗎? 那很可能還是一樣的結果...
bernie_w39
資深會員


發表:3
回覆:199
積分:280
註冊:2007-10-07

發送簡訊給我
#14 引用回覆 回覆 發表時間:2008-11-13 12:18:45 IP:61.218.xxx.xxx 訂閱
連續讀兩個 sectors 時, 不用重新傳 set_block_len 這個指令. 其實應該是要試,
讀取sectors 對 sd card 下的指令愈少愈好. 看看問題的成因在哪兒.

再問一下, 像 &v_pSDHCRegs->STATUS 它從頭到尾, 都會是一樣的位置嗎?
或是像
&v_pSDHCRegs->BUFFER_ACCESS, 是否每次都是一樣的位置?
mmppeegg
一般會員


發表:1
回覆:11
積分:2
註冊:2008-10-22

發送簡訊給我
#15 引用回覆 回覆 發表時間:2008-11-13 14:29:04 IP:61.218.xxx.xxx 訂閱
是的, 都是讀一樣的位置. STATUS是一個暫存器. 至於BUFFER_ACCESS則是一個CPU中的FIFO, 將DATA存進一個固定的register, 每讀取完之後就會換下一筆資料. 
您提到說可能是程式的錯誤, 小弟卻是怕CPU本身的問題, 像這個FIFO到底初始化對不對, 真的不敢確定. 請看這個圖:
www.wretch.cc/album/show.php
編輯記錄
mmppeegg 重新編輯於 2008-11-13 14:33:12, 註解 無‧
mmppeegg 重新編輯於 2008-11-13 14:36:31, 註解 無‧
mmppeegg
一般會員


發表:1
回覆:11
積分:2
註冊:2008-10-22

發送簡訊給我
#16 引用回覆 回覆 發表時間:2008-11-13 17:45:01 IP:118.166.xxx.xxx 訂閱
最新消息, 連續讀取兩個block會有一樣的問題, 我開始懷疑那個FIFO...
bernie_w39
資深會員


發表:3
回覆:199
積分:280
註冊:2007-10-07

發送簡訊給我
#17 引用回覆 回覆 發表時間:2008-11-13 18:01:06 IP:61.218.xxx.xxx 訂閱
1 個 FIFO 16 bytes, 這樣就有一點 make senses 了. 也許真的該去找找,
那個 FIFO 的控制方法. 有可能在發送指令之前或之後, 要對 FIFO 下一些
initial, flush 之類的動作.

不過 FIFO 有 32 組, 你的讀取是差了 8 組, 這之間應該還是有一些深奧之處.
但是, 這些問題都超出了我的經驗範圍, 我當初只是用 SPI 界面而己. 你這個
是標準 (高速) 的 SDIO 界面, 應該會快很多. 加油了.

再八卦一下, 在發送完指令之後, 收到 response 後, 試著 delay 一下子,
看看結果有沒有不同. 我的猜測 (完全胡思亂想, 沒有根據的), 那個 FIFO 結構
不是雙向的, 因為你下完指令後, 它就開始用力的去讀 block, 當你的程式去
讀 FIFO 時, 它剛好讀到第 8 組, 為了應付你的讀取動作, 它就把目前正在
工作中的 FIFO page, 直接餵給你. 因為程式邏輯一致, 秒差一致, 所以
總是在第 8 組.

看看小小的 delay 後, 會不會跳去第 18 組, 就可以知道了.
mmppeegg
一般會員


發表:1
回覆:11
積分:2
註冊:2008-10-22

發送簡訊給我
#18 引用回覆 回覆 發表時間:2008-11-14 16:48:43 IP:118.166.xxx.xxx 訂閱
感謝大大, 這個delay我做過, 給他20秒他都是這個樣.
不過我還懷疑一點: 它上面寫的SDMA我沒有去用, 正在試著驅動它中.
mmppeegg
一般會員


發表:1
回覆:11
積分:2
註冊:2008-10-22

發送簡訊給我
#19 引用回覆 回覆 發表時間:2009-03-18 16:35:22 IP:118.166.xxx.xxx 訂閱
後來發現把幾個delay拿掉就正常了。
現在SD也正常運作中,謝謝大家的幫忙呢!
系統時間:2024-11-24 8:13:50
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!