DRESULT disk_readp ( BYTE* dest, /* Pointer to the destination object */ DWORD sector, /* Sector number (LBA) */ WORD sofs, /* Offset in the sector */ WORD count /* Byte count (bit15:destination) */ ) { DRESULT res; USHORT timeout; USHORT bytes_to_read; select_card(); if(!(card_type & CT_BLOCK)) sector *= 512; res = RES_ERROR; if(send_cmd(CMD_17, sector, 0x00) != 0){ deselect_card(); return RES_ERROR; } timeout = 4000; while((rec_byte() != 0xFE) && timeout--){} if(timeout){ bytes_to_read = 514 - sofs - count; //Pass through offset if(sofs){ do{ rec_byte(); }while(--sofs); //Debug: check this } //get requested data bytes if(dest){ do { *dest++ = rec_byte(); } while (--count); }else{ do { rec_byte();//DEBUG: Not sure if i need this. Examples uses FORWARD(rec_byte()); for communication with a computer }while(--count); } //skip over trailing bytes do { rec_byte(); }while(--bytes_to_read); res = RES_OK; }//close if timeout deselect_card(); rec_byte(); return res; }
tCardInfo *mmc_card_info(int card_no) { tCardInfo *card = &card_info[card_no]; if (!card->initialized && ((card_no == 0) || mmc_detect())) { select_card(card_no); deselect_card(); } return card; }
DRESULT disk_writep ( const BYTE* buff, /* Pointer to the data to be written, NULL:Initiate/Finalize write operation */ DWORD sc /* Sector number (LBA) or Number of bytes to send */ ) { DRESULT res; WORD byte_count; static WORD bytes_left_in_block; //counter used to write data select_card(); res = RES_ERROR; if (buff) { byte_count = (WORD)sc; while(bytes_left_in_block && byte_count){ send_byte(*buff++); byte_count--; bytes_left_in_block--; }//end of while res = RES_OK; }//end of if(buf) else if (sc) { if(!(card_type & CT_BLOCK)) sc *= 512; //multiply address by 512 if the card is byte addrssed if(send_cmd(WRITE_BLOCK, sc, 0x00) == 0){ send_byte(0xFF); //Send header byte 1 send_byte(0xFE); //Send header byte 2 bytes_left_in_block = 512; } res = RES_OK; }//end of 1st else else{ fill_zeros(bytes_left_in_block); res = check_write_success(); deselect_card(); }//end 2nd else return res; }//End of writep
//This function assumes the SD card has been powered for at least a second before being called DSTATUS disk_initialize (void) { unsigned i; init_spi(); init_card_select_pin(); //pull CS high, then send at least 74 clock pulses to the module with SIMO high deselect_card(); for(i = 0; i <= 10; i++){ rec_byte(); } //pull CS low and send CMD0 to reset card and put it in SPI mode select_card(); if (send_cmd(CMD_0, 0x00000000, 0x95) != 1){ deselect_card(); return RES_ERROR; } if(send_cmd(CMD_8, 0x000001AA, 0x87) == 1){ //Check voltage range on card. If a non-one value is returned, card is not sd v.2 if(get_r7_resp(0xAA) != RES_OK){ //returns 1 if card works at 2.7-3.3V and check_pattern is valid deselect_card(); return RES_ERROR; } if(check_ocr_voltage_range() != RES_OK){ deselect_card(); return RES_ERROR; } if(wait_for_card_to_finish_init() != RES_OK){ deselect_card(); return RES_ERROR; } if(check_card_type() != RES_OK){ deselect_card(); return RES_ERROR; } }//close if cmd_8 //else{ //}//Version 1.0 or earlier deselect_card(); return RES_OK; }