►Reading and Writing a single sector
Another fundamental function is reading a single sector of data from the SD card. Since the sector size is fixed in SPI mode, we expect to read 512 bytes at a time. The following function will achieve this.
A. Reading Sector
BYTE SD_ReadSector( ULONG SectorNumber, BYTE *Buffer ) { BYTE c, i; WORD count; /* send block-read command... */ SD_Command( CMD_READ_SINGLE_BLOCK, SectorNumber << 9 ); c = SD_GetR1(); i = SD_GetR1(); count = 0xFFFF; /* wait for data token... */ while( (i == 0xff) && --count) i = SD_GetR1(); /* handle time out... */ if(c || i != 0xFE) return( 1 ); /* read the sector... */ for( count=0; count<SD_DATA_SIZE; count++) *Buffer++ = SPI_Byte(0xFF); /* ignore the checksum... */ SPI_Byte(0xFF); SPI_Byte(0xFF); /* release the CS line... */ SPI_DisableCS(); return( 0 ); }
B. Writing Sector
BYTE SD_WriteSector( ULONG SectorNumber, BYTE *Buffer ) { BYTE i; WORD count; /* send block-write command... */ SD_Command( CMD_WRITE_SINGLE_BLOCK, SectorNumber << 9 ); i = SD_GetR1(); /* send start block token... */ SPI_Byte( 0xFE ); /* write the sector... */ for( count= 0; count< 512; count++ ) { SPI_Byte(*Buffer++); } /* ignore the checksum (dummy write)... */ SPI_Byte(0xFF); SPI_Byte(0xFF); /* wait for response token... */ while( SPI_Byte( 0xFF ) != 0xFF) /* these 8 clock cycles are critical for the card */ /* to finish up whatever it's working on at the */ /* time... (before CS is released!) */ SPI_Byte( 0xFF ); /* release the CS line... */ SPI_DisableCS(); SPI_Byte( 0xFF ); return( 0 ); }
One final function
Finally, you will need one last function to emulate everything Chan’s library needs to talk to the SD card. This function is a simple flush function that is used to make sure the card is ready for the next command.
BYTE SD_WaitForReady() { BYTE i; WORD j; SPI_Byte( 0xFF ); j = 500; do { i = SPI_Byte( 0xFF ); Delay( 1 ); } while ((i != 0xFF) && --j); return( i ); }