📄 sdcardnotworking.c
字号:
*/
/******************************************************************************
* Function: SDC_RESPONSE SendSDCCmd(BYTE cmd, DWORD address)
*
*
* Input: None
*
* Output: response - Response from the card
* - 0x00 or 0x01 Command received
* successfully, else, command failed
* -Bit 0 - In idle state if 1
* -Bit 1 - Erase Reset if 1
* -Bit 2 - Illgal Command if 1
* -Bit 3 - Com CRC Error if 1
* -Bit 4 - Erase Sequence Error if 1
* -Bit 5 - Address Error if 1
* -Bit 6 - Parameter Error if 1
* -Bit 7 - Not used, always '0'
*
* Side Effects: None
*
* Overview: SendSDCCmd prepares the command packet and sends it out
* over the SPI interface. Response data of type 'R1' or 'R2' for SEND_STATUS command (see
* SD or MMC product manuals) is returned.
*
* Note: SDC_CS is not set at the end of this function.
* if the command has no data stage, call macro
* mSendMediaCmd_NoData(), it reasserts SDC_CS to 1.
* If the command has a data stage, SDC_CS must be
* reasserted after the data transfer stage is complete.
* See SECTORread and SECTORwrite for examples.
*****************************************************************************/
SDC_RESPONSE SendSDCCmd(byte cmd, dword address)
{
word timeout = 8;
byte index;
SDC_RESPONSE response;
CMD_PACKET CmdPacket;
SDC_CS = 0; //Card Select
// Copy over data
CmdPacket.cmd = sdmmc_cmdtable[cmd].CmdCode;
CmdPacket.address = address;
CmdPacket.crc = sdmmc_cmdtable[cmd].CRC; // Calc CRC here
WriteSPI(CmdPacket.cmd); //Send Command
WriteSPI(CmdPacket.addr3); //Most Significant Byte
WriteSPI(CmdPacket.addr2);
WriteSPI(CmdPacket.addr1);
WriteSPI(CmdPacket.addr0); //Least Significant Byte
WriteSPI(CmdPacket.crc); //Send CRC
// see if we are going to get a response
if(sdmmc_cmdtable[cmd].responsetype == R1 || sdmmc_cmdtable[cmd].responsetype == R1b)
{
do
{
response.r1._byte = ReadMedia();
timeout--;
}while((response.r1._byte == 0xFF) && (timeout != 0));
}
else if(sdmmc_cmdtable[cmd].responsetype == R2)
{
ReadMedia();
response.r2._byte1 = ReadMedia();
response.r2._byte0 = ReadMedia();
}
if(sdmmc_cmdtable[cmd].responsetype == R1b)
{
response.r1._byte = 0x00;
for(index =0; index < 0xFF && response.r1._byte == 0x00; index++)
{
timeout = 0xFFFF;
do
{
response.r1._byte = ReadMedia();
timeout--;
}while((response.r1._byte == 0x00) && (timeout != 0));
}
}
mSend8ClkCycles(); //Required clocking (see spec)
// see if we are expecting data or not
if(!(sdmmc_cmdtable[cmd].moredataexpected))
SDC_CS = 1;
return(response);
}
/******************************************************************************
* Function: BYTE ReadMedia(void)
*
* PreCondition: None
*
* Input: None
*
* Output: BYTE - One byte of data read in from SPI port
*
* Side Effects: None
*
* Overview: ReadMedia reads in one byte of data while sending out 0xFF
*
* Note: Could not use ReadSPI because it initializes SSPBUF to
* 0x00. The card expects 0xFF (see spec).
*****************************************************************************/
byte ReadMedia(void)
{
SSPBUF = 0xFF; //Data Out - Logic ones
while(!SSPSTATbits.BF); //Wait until cycle complete
return(SSPBUF); //Return with byte read
}//end ReadMedia
void Delayms(byte milliseconds)
{
T1CON = 0xB0;
//enable interrupt
TMR1IE = 1;
do {
// load timer
TMR1H = high(0xFFFF - MILLISECDELAY);
TMR1L = low(0xFFFF - MILLISECDELAY);
// clear flag
TMR1IF = 0;
// turn on timer
TMR1ON = 1;
// wait for it to be done
while(!TMR1IF)
{
;
}
// turn off timer
TMR1ON = 0;
// Making a little more accurate
Nop();
Nop();
milliseconds--;
}while(milliseconds > 0);
Error:
// now turn everything off
TMR1ON = 0;
TMR1IE = 0;
}
/******************************************************************************
* Function: SDC_Error SECTORread(DWORD sector_addr, BYTE *buffer)
*
* PreCondition: None
*
* Input: sector_addr - Sector address, each sector contains 512-byte
* buffer - Buffer where data will be stored, see
* 'ram_acs.h' for 'block' definition.
* 'Block' is dependent on whether internal or
* external memory is used
*
* Output: See SDC_Error.
*
* Side Effects: None
*
* Overview: SECTORread reads 512 bytes of data from the card starting
* at the sector address specified by sector_addr and stores
* them in the location pointed to by 'buffer'.
*
* Note: The card expects the address field in the command packet
* to be byte address. Therefore the sector_addr must first
* be converted to byte address. This is accomplished by
* shifting the address left 9 times.
*****************************************************************************/
SDC_Error SECTORread(dword sector_addr, byte* buffer)
{
word index;
SDC_RESPONSE response;
byte data_token;
SDC_Error status = sdcValid;
/*
#ifdef STATUSLED
STTRIS = OUTPUT;
STLED = 1;
#endif
*/
// send the cmd
response = SendSDCCmd(READ_SINGLE_BLOCK,(sector_addr << 9));
// Make sure the command was accepted
if(response.r1._byte != 0x00)
{
status = sdcCardBadCmd;
}
else
{
index = 0x2FF;
//Now, must wait for the start token of data block
do
{
data_token = ReadMedia();
index--;
}while((data_token == SDC_FLOATING_BUS) && (index != 0));
// Hopefully that zero is the datatoken
if((index == 0) || (data_token != DATA_START_TOKEN))
status = sdcCardTimeout;
else
{
for(index = 0; index < SDC_SECTOR_SIZE; index++) //Reads in 512-byte of data
{
buffer[index] = ReadMedia();
//#ifdef DEBUG_SDMMC
// U8toHexString(buffer[index],string);
// if((index % 0x10) == 0x00)
// DEBUG_PRINT("\n\r");
// DEBUG_PRINT_RAM((char*)string);
// DEBUG_PRINT(" ");
// #endif
}
// Now ensure CRC
mReadCRC(); //Read 2 bytes of CRC
//status = mmcCardCRCError;
}
mSend8ClkCycles(); //Required clocking (see spec)
}
SDC_CS = 1;
// #ifdef STATUSLED
// STLED = 0;
// #endif
return(status);
}//end SECTORread
/******************************************************************************
* Function: MMC_Error SECTORwrite(DWORD sector_addr, BYTE *buffer)
*
* PreCondition: None
*
* Input: sector_addr - Sector address, each sector contains 512-byte
* buffer - Buffer where data will be read, see
* 'ram_acs.h' for 'block' definition.
* 'Block' is dependent on whether internal or
* external memory is used
*
* Output: See MMC_Error.
*
* Side Effects: None
*
* Overview: SECTORwrite sends 512 bytes of data from the location
* pointed to by 'buffer' to the card starting
* at the sector address specified by sector_addr.
*
* Note: The card expects the address field in the command packet
* to be byte address. Therefore the sector_addr must first
* be converted to byte address. This is accomplished by
* shifting the address left 9 times.
*****************************************************************************/
SDC_Error SECTORwrite(dword sector_addr, byte* buffer)
{
word index;
byte data_response;
SDC_RESPONSE response;
SDC_Error status = sdcValid;
/*
#ifdef STATUSLED
STTRIS = OUTPUT;
STLED = 1;
#endif
*/
// send the cmd
response = SendSDCCmd(WRITE_SINGLE_BLOCK,(sector_addr << 9));
// see if it was accepted
if(response.r1._byte != 0x00) {
status = sdcCardBadCmd;
} else {
WriteSPI(DATA_START_TOKEN); //Send data start token
for(index = 0; index < 512; index++) //Send 512 bytes of data
WriteSPI(buffer[index]);
// calc crc
mSendCRC(); //Send 2 bytes of CRC
data_response = ReadMedia(); //Read response
if((data_response & 0x0F) != DATA_ACCEPTED)
{
status = sdcCardDataRejected;
}
else
{
index = 0; //using i as a timeout counter
do //Wait for write completion
{
data_response = ReadMedia();
index++;
}while((data_response == 0x00) && (index != 0));
if(index == 0) //if timeout first
status = sdcCardTimeout;
}
mSend8ClkCycles();
}
SDC_CS = 1;
/*
#ifdef STATUSLED
STLED = 0;
#endif
*/
return(status);
} //end SECTORwrite
/*****************************************************************
Return the state of the WP Pin
*****************************************************************/
byte WriteProtectState(void)
{
return(MEDIA_WD);
}
// ShutdownMedia
// Simply turn off the card
//
void ShutdownMedia(void)
{
// close the spi bus
CloseSPI();
// deselect the device
SDC_CS = 1;
// Turn off the card
// SDC_OFF;
}
/******************************************************************************
* Function: SDC_Error CSDread(BYTE *buffer)
*
* PreCondition: None
*
* Input: buffer - Buffer where data will be stored
*
* Output: See SDC_Error.
*
* Side Effects: None
*
* Overview: CSDread reads Card Specific Data (CSD) from the card by issuing the
CMD9 SEND_CSD command. The contents of CSD register are used to find the
card size. Response type for SEND_CSD is R1
*****************************************************************************/
SDC_Error CSDread()
{
word index, timeout=0x2ff;
SDC_RESPONSE response;
byte data_token;
SDC_Error status = sdcValid;
byte cmd=SEND_CSD;
dword address=0x00;
CMD_PACKET CmdPacket;
SDC_CS = 0; //Card Select
// Copy over data
CmdPacket.cmd = sdmmc_cmdtable[cmd].CmdCode;
CmdPacket.address = address;
CmdPacket.crc = sdmmc_cmdtable[cmd].CRC; // Calc CRC here
WriteSPI(CmdPacket.cmd); //Send Command
WriteSPI(CmdPacket.addr3); //Most Significant Byte
WriteSPI(CmdPacket.addr2);
WriteSPI(CmdPacket.addr1);
WriteSPI(CmdPacket.addr0); //Least Significant Byte
WriteSPI(CmdPacket.crc); //Send CRC
// see if we are going to get a response
do
{
response.r1._byte = ReadMedia();
timeout--;
} while((response.r1._byte == 0xFF) && (timeout != 0));
//mSend8ClkCycles(); //Required clocking (see spec)
// see if we are expecting data or not
// if(!(sdmmc_cmdtable[cmd].moredataexpected))
// SDC_CS = 1;
// Make sure the command was accepted
if(response.r1._byte != 0x00)
{
status = sdcCardBadCmd;
}
else
{
index = 0x2FF;
//Now, must wait for the start token of data block
do
{
data_token = ReadMedia();
index--;
}while((data_token == SDC_FLOATING_BUS) && (index != 0));
// Hopefully that zero is the datatoken
if((index == 0) || (data_token != DATA_START_TOKEN))
status = sdcCardTimeout;
else
{
for(index = 0; index < CSD_SIZE; index++) //Reads in 16-byte of data
{
gblCSDReg._byte[index] = ReadMedia();
}
// Now ensure CRC
// mReadCRC(); //Read 2 bytes of CRC
//status = mmcCardCRCError;
}
mSend8ClkCycles(); //Required clocking (see spec)
}
SDC_CS = 1;
return(status);
}//end CSDread
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -