Writing a Sector | Kickoff

Writing a Sector

24 Mar

Writing a Sector
MultiMediaCard firmware writes data to the storage media in sectors. The SectorWrite function and related code below perform this function. The function calls the ReadMedia and WriteSPI functions from Chapter 4 and the SendSDCCmd function above.

// This macro writes FFh twice to send two CRC bytes.
// The code assumes CRC values are ignored (the default in SPI mode).
#define mSendCRC() WriteSPI(0xFF); WriteSPI(0xFF);
#define DATA_ACCEPTED 0b00000101
SDC_Error SectorWrite(dword sector_addr, byte* buffer)
{
byte data_response;
word index;
SDC_RESPONSE response;
SDC_Error status = sdcValid;
// Issue a WRITE_SINGLE_BLOCK command.
// Pass the address of the first byte to write in the media.
// To obtain the address of a sector’s first byte,
// shift the sector address left 9 times to multiply by 512 (sector size).
response = SendSDCCmd(WRITE_SINGLE_BLOCK, (sector_addr << 9));
// A response of 00h indicates success.
if (response.r1._byte != 0×00)
status = sdcCardBadCmd;

else
{
// The command was accepted.
// Send a data start token.
WriteSPI(DATA_START_TOKEN);
// Send a sector’s worth of data.
for(index = 0; index < 512; index++)
WriteSPI(buffer[index]);
// Send the CRC bytes.
mSendCRC();
// Read the card’s response.
data_response = ReadMedia();
if ((data_response & 0×0F) != DATA_ACCEPTED)
{
status = sdcCardDataRejected;
}
else
{
// The card is writing the data into the storage media.
// Wait for the card to return non-zero (not busy) or a timeout.
index = 0;
do
{
data_response = ReadMedia();
index++;
} while ((data_response == 0×00) && (index != 0));

if (index == 0)
// The write timed out.
status = sdcCardTimeout;
}
// The write was successful.
// Generate 8 clock cycles to complete the command.
mSend8ClkCycles();
}
// Deselect the card.
SDC_CS = 1;
return(status);
}

Initializing Communications
Before accessing a card’s media. the card’s host must initialize communications by sending a sequence of commands. Initializing a card consists of the following actions by the host:

1. Configure the SPI port with a clock frequency of 400 kHz or less.
2. Enable the SPI port.
3. With CS high and DataIn high, generate clock cycles for the maximum of the power-supply ramp-up time, 1 millisecond, or 74 clock cycles. With a 400-kHz clock, 1 millisecond requires 400 clock cycles. The power-supply ramp-up time is the time required for the supply to rise from the minimum valid supply voltage to the supply voltage the card will use.
4. Issue the GO_IDLE_STATE command to select SPI mode.
5. Issue the SEND_OP_COND command repeatedly until the card responds or a timeout.
6. Issue the SEND_CSD command to read the CSD register.

The card is now ready for use in SPI mode. Firmware can perform these additional actions as desired:

Increase the SPI port’s clock frequency. The CSD register specifies the card’s maximum data-transfer rate.

Issue the CRC_ON_OFF command to enable CRC checking in the card.

If necessary, issue the SET_BLOCK_LEN command to change the block length for media reads and writes. The default is 512 bytes.

Read and store the state of the write-protect tab.

Issue block-read and block-write commands to access the media’s contents.

Cards in MultiMediaCard-bus mode always use the CRC values. In SPI mode, the card ignores the CRC values unless the host has issued a CRC_ON_OFF command to enable CRC. All cards are in MultiMediaCard- bus mode until the host issues a GO_IDLE_STATE command to switch the card to SPI mode. So the GO_IDLE_STATE command must
have a valid CRC value, but for all following commands in SPI mode, the host can use any stuff bits for the CRC if desired.

Random Posts

No comments yet

Leave a Reply

You must be logged in to post a comment.