►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
CODE:
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 );
}
{
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
CODE:
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 );
}
{
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.
CODE:
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 );
}
{
BYTE i;
WORD j;
SPI_Byte( 0xFF );
j = 500;
do
{
i = SPI_Byte( 0xFF );
Delay( 1 );
} while ((i != 0xFF) && --j);
return( i );
}
No comments:
Post a Comment