Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Altera_Forum
Honored Contributor I
686 Views

Problem about the writing function of SD card

File System: FAT 

SD card : support the SD 1.1 protocol 

Device: DE2 EP2C35F672C6 

Software: Quartus II 9.1 Nios II 9.1 

Problem: function for writing the block is not correct(the code as follow) 

Description: 

I use SPI mode to read and write SD card, the function of reading is successful. but the function of writing part is not finished, I plan to split the writing function into 2 parts, one is give the CMD24 instruction, and other one is send the 512 byte block. the first parts, I suppose, reach the aim of the SD 1.1 protocol. I have get the right response signal (0x00h) as the regulation on the SD card standard. the 2nd part, until now, I could not get the successful signal(0x05), I do not understand the reason of the strange error. my idea is like that: 

1, send CMD24(write instruction, including the 8bit-CRC checking code, I do not know why? SPI mode do not care about the checking code. If I do not care about this, it create an error) 

2. send 8 clocks 

3. get the response code(it need get 0x00, it is successful) 

4. send 8 clocks 

5. send start code 0xFE 

6. send the 512 byte block(the wire of the data and command is tried, but I can not get the response code 0x05) 

7. send the 16bit-CRC(formulation is x^16+x^12+x^5+1, I suppose the error reason is at this place, because the reason like the CMD24 instruction, and the cases online are a little different, I continue to try it at this place) 

8.get the response code(it need get 0x05) 

9.wait for writing the SD card until it cancel the busy state. 

10. read another block. 

this is my idea after reading and studying many cases, many materials and SD standard.  

 

 

 

bool SD_write_block(alt_u32 block_number, alt_u8 *buff) 

alt_u8 temp,k; 

alt_u16 crc=0, b=0; 

alt_u32 i,j,lba; 

int try = 0; 

const int max_try = 5000; 

printf("SD Write %d Block(%s)\n", block_number, buff); 

lba = block_number * 512; 

SD_DAT_OUT; 

SD_CMD_OUT; 

Ncc(); 

cmd_buffer[0] = cmd24[0]; 

cmd_buffer[1] = (lba>>24)&0xff; 

cmd_buffer[2] = (lba>>16)&0xff; 

cmd_buffer[3] = (lba>>8)&0xff; 

cmd_buffer[4] = lba&0xff; 

send_cmd(cmd_buffer); 

SD_DAT_IN; 

Ncr(); 

//if(response_R(1)>1) 

// return 1; 

// Ncc(); 

for(i=0;i<6;i++) 

SD_CLK_LOW; 

SD_CLK_HIGH; 

// get response 

while(1) 

SD_CLK_LOW; 

SD_CLK_HIGH; 

printf("<%x>[%x]", SD_TEST_CMD, SD_TEST_DAT); 

if(SD_TEST_CMD == 0x00) // check bit0 

break; 

if (try++ > max_try) 

return FALSE; 

printf("\n"); 

SD_DAT_OUT; 

SD_CMD_OUT; 

Ncc(); 

WriteByteMMC(0xFE); 

/////////////content 

for(i=0; i < 512; i++) 

temp = buff

for(k=0x80; k!=0; k=k>>1) 

sd_clk_low; 

if(temp&k) 

sd_cmd_high; 

else 

sd_cmd_low; 

sd_clk_high; 

b = b*2; 

if((b&0x10000)) 

b = b^0x11021; 

if((temp&k)) 

b = b^(0x10000^0x11021); 

crc = b; 

// crc =((crc<<1)|0x01); //////////////end bit 

////////////crc 

crc = uscalculcrc(buff, 512); 

 

for(i=0; i<16; i++) 

sd_clk_low; 

if(crc&0x8000) 

sd_cmd_high; 

else 

sd_cmd_low; 

sd_clk_high; 

crc<<=1; 

 

 

/* 

for(i=0; i < 512; i++) 

crc = writebytemmc(buff); 

crc &= 0x7f; 

crc =((crc<<1)|0x01); ////////////end bit "1" added by jiayanfu 

WriteByteMMC(0xFF); 

WriteByteMMC(0xFF); 

//if(response_R(1)>1) 

// printf("error"); 

*/ 

SD_DAT_IN; 

SD_CMD_IN; 

while(1) 

SD_CLK_LOW; 

SD_CLK_HIGH; 

printf("<%x>[%x]", SD_TEST_CMD, SD_TEST_DAT); 

if((SD_TEST_CMD & 0x1f) == 0x05) // check bit0 

break; 

if (try++ > max_try) 

return FALSE; 

 

while(ReadByteMMC()!=0xff); 

 

 

 

return TRUE; 

}
0 Kudos
0 Replies
Reply