Card Information

24 Mar

Card Information
The SDCSTATE union below is a byte that identifies the device as an SD Card/MultiMediaCard and indicates if the card is write-protected:

typedef union _SDCstate
{
struct
{
byte isSDMMC : 1; // set for an SD Card or MultiMediaCard
byte isWP : 1; // set if write protected
};
byte _byte;
} SDCSTATE;

The IsWriteProtected function returns true if the card has a write-protect tab that is set to write protect.

byte IsWriteProtected(void)
{
if (MEDIA_WD) return TRUE;
else return FALSE;
}

Delay Timer
A function that returns after a specific delay time is often useful for tasks such as waiting for hardware to initialize. The Delayms function uses an on-chip hardware timer to delay the number of milliseconds passed to the function. When the time has elapsed, the function returns. This function is very specific to the PICMicro architecture and accesses registers defined in the compiler file p18f4550.h. Firmware for other chips can perform equivalent functions using hardware timers in the chips.

Error:
// On error or completion of the delay, turn off the timer and disable its interrupt.
TMR1ON = 0;
TMR1IE = 0;
}

A Function for Initializing
The MediaInitialize function performs initialization tasks and returns status in an SDC_Error structure. The function accepts a pointer to an SDCSTATE structure and sets the states of the structure’s two members. The function uses the 512-byte msd_buffer array introduced in Chapter 3 to hold data read from the card’s storage media. The function calls the Open- SPI function from Chapter 4.

SDC_Error MediaInitialize(SDCSTATE *Flag)
{
SDC_Error CSDstatus = sdcValid;
SDC_RESPONSE response;
SDC_Error status = sdcValid;
word timeout;
Flag -> _byte = 0×0;
// Deselect the card.
SDC_CS = 1;
// Open the SPI port.
// Clock speed must be <= 400 kHz until the card is initialized
// and the CSD register has been read.
// MultiMediaCards require CKE = 0, CKP = 1,
// and sampling DataOut in the middle of a clock cyle.
OpenSPI(SPI_FOSC_64, MODE_11, SMPMID);
// Allow the card time to initialize.
Delayms(100);

// Generate clock cycles for 1 millisecond as required by the MultiMediaCard spec.
for (timeout = 0; timeout < 50; timeout++)
mSend8ClkCycles();
// Select the card.
SDC_CS = 0;
Delayms(1);
// Issue the GO_IDLE_STATE command to select SPI mode.
response = SendSDCCmd(GO_IDLE_STATE, 0×0);
if (response.r1._byte == SDC_BAD_RESPONSE)
{
status = sdcCardInitCommFailure;
goto InitError;
}
// A response of 01h means the card is in the idle state and is initializing.
if (response.r1._byte != 0×01)
{
status = sdcCardNotInitFailure;
goto InitError;
}
// Issue the SEND_OP_COND command until the card responds or a timeout.
timeout = 0xFFF;
do
{
response = SendSDCCmd(SEND_OP_COND, 0×0);
timeout–;
} while (response.r1._byte != 0×00 && timeout != 0);
if (timeout == 0)
{
status = sdcCardInitTimeout;
goto InitError;
}

else {
// The command succeeded.
// Read the CSD register.
CSDstatus = CSDRead();
if (!CSDstatus)
// The response was zero. The CSD was read successfully.
// OK to increase the clock speed.
OpenSPI(SPI_FOSC_4, MODE_11, SMPMID);
else
// Unable to read the CSD.
status = sdcCardTypeInvalid;
}
// Issue the SET_BLOCKLEN command to set the block length to 512.
// (Optional, since this is the default.)
SendSDCCmd(SET_BLOCKLEN, 512);
// Set a bit in the SDCSTATE structure if the card is write-protected.
if (IsWriteProtected())
Flag -> isWP = TRUE;
// Read sector zero from the card into msd_buffer until success or a timeout.
// Some cards require multiple attempts.
for (timeout = 0xFF;
timeout > 0 && SectorRead(0×0, (byte*)msd_buffer) != sdcValid;
timeout–)

// The attempt to read timed out.
if (timeout == 0)
{
status = sdcCardNotInitFailure;
goto InitError;
}
return(status);
InitError:
// On error or success, deselect the device.
SDC_CS = 1;
return(status);
}

Random Posts

No comments yet

Leave a Reply

You must be logged in to post a comment.