📄 sdcardnotworking.c
字号:
#include "sdcard.h"
extern volatile far byte msd_buffer[512];
CSD gblCSDReg;
//#include "system\usb\usbmmap.h"
/*
#pragma udata MSD=0x600
volatile far byte gblSDMMCBuf[512];
#pragma udata
*/
//#pragma udata msd=0x600 //SDCBUFFER
//byte* gblSDMMCBuf=msd_buffer;
//[SDC_SECTOR_SIZE];
//#pragma udata
//#pragma code
typedef enum
{
GO_IDLE_STATE,
SEND_OP_COND,
SEND_CSD,
SEND_CID,
STOP_TRANSMISSION,
SEND_STATUS,
SET_BLOCKLEN,
READ_SINGLE_BLOCK,
READ_MULTI_BLOCK,
WRITE_SINGLE_BLOCK,
WRITE_MULTI_BLOCK,
TAG_SECTOR_START,
TAG_SECTOR_END,
UNTAG_SECTOR,
TAG_ERASE_GRP_START,
TAG_ERASE_GRP_END,
UNTAG_ERASE_GRP,
ERASE,
LOCK_UNLOCK,
SD_APP_OP_COND,
APP_CMD,
READ_OCR,
CRC_ON_OFF
}sdmmc_cmd;
/*********************************************************************
* sdmmc_cmdtable
* - Provides information for all the sdmmc commands that we support
*
* Notes: We turn off the CRC as soon as possible, so the commands with
* 0xFF don't need to be calculated in runtime
*********************************************************************/
const rom typSDC_CMD sdmmc_cmdtable[] =
{
// cmd crc response
{cmdGO_IDLE_STATE, 0x95, R1, NODATA},
{cmdSEND_OP_COND, 0xF9, R1, NODATA},
{cmdSEND_CSD, 0xAF, R1, MOREDATA},
{cmdSEND_CID, 0x1B, R1, MOREDATA},
{cmdSTOP_TRANSMISSION, 0xC3, R1, NODATA},
{cmdSEND_STATUS, 0xAF, R2, NODATA},
{cmdSET_BLOCKLEN, 0xFF, R1, NODATA},
{cmdREAD_SINGLE_BLOCK, 0xFF, R1, MOREDATA},
{cmdREAD_MULTI_BLOCK, 0xFF, R1, MOREDATA},
{cmdWRITE_SINGLE_BLOCK, 0xFF, R1, MOREDATA},
{cmdWRITE_MULTI_BLOCK, 0xFF, R1, MOREDATA},
{cmdTAG_SECTOR_START, 0xFF, R1, NODATA},
{cmdTAG_SECTOR_END, 0xFF, R1, NODATA},
{cmdUNTAG_SECTOR, 0xFF, R1, NODATA},
{cmdTAG_ERASE_GRP_START, 0xFF, R1, NODATA},
{cmdTAG_ERASE_GRP_END, 0xFF, R1, NODATA},
{cmdUNTAG_ERASE_GRP, 0xFF, R1, NODATA},
{cmdERASE, 0xDF, R1b, NODATA},
{cmdLOCK_UNLOCK, 0x89, R1b, NODATA},
{cmdSD_APP_OP_COND, 0xE5, R1, NODATA},
{cmdAPP_CMD, 0x73, R1, NODATA},
{cmdREAD_OCR, 0x25, R3, NODATA},
{cmdCRC_ON_OFF, 0x25, R1, NODATA}
};
//Function Prototypes
void Delayms(byte);
byte MediaDetect(void);
SDC_Error MediaInitialize(void);
void SocketInitialize(void);
SDC_RESPONSE SendSDCCmd(byte, dword);
byte ReadMedia(void);
//void DetectSDCard (void);
SDC_Error sdcardinitialize(void);
SDC_Error RMediaInitialize(SDCSTATE *);
byte WriteProtectState(void);
SDC_Error SECTORread(dword, byte*);
SDC_Error SECTORwrite(dword, byte*);
SDC_Error CSDread(void);
SDC_Error RMediaInitialize(SDCSTATE *Flag)
{
word timeout;
SDC_Error status = sdcValid, CSDstatus = sdcValid;
SDC_RESPONSE response;
// clear out flags
Flag->_byte = 0x0;
SDC_CS = 1; //Initialize Chip Select line
// This function was called for a reason Turn it on
//SDC_ON;
//Media powers up in the open-drain mode and cannot handle a clock faster
//than 400kHz. Initialize SPI port to slower than 400kHz
OpenSPI(SPI_FOSC_64, MODE_11, SMPMID);
// let the card power on and initialize
Delayms(100);
//Media requires 80 clock cycles to startup [8 clocks/BYTE * 10 us]
for(timeout=0; timeout<10; timeout++)
mSend8ClkCycles();
SDC_CS = 0;
Delayms(1);
// Send CMD0 to reset the media
response = SendSDCCmd(GO_IDLE_STATE,0x0);
if(response.r1._byte == SDC_BAD_RESPONSE)
{
status = sdcCardInitCommFailure; // we have not got anything back from the card
goto InitError;
}
// See if the device is ready
if(response.r1._byte != 0x01) //0x01=No Err&Busy Initializing
{
status = sdcCardNotInitFailure; // we have not got anything back from the card
goto InitError;
}
// According to spec cmd1 must be repeated until MMC card is fully initialized
timeout = 0xFFF;
do
{
response = SendSDCCmd(SEND_OP_COND,0x0);
timeout--;
}while(response.r1._byte != 0x00 && timeout != 0);
// see if it failed
if(timeout == 0)
{
status = sdcCardInitTimeout; // we have not got anything back from the card
goto InitError;
}
else {
// get the CSD register before increasing the spped page 4-8 of sd card manual last line
CSDstatus=CSDread();
if(!CSDstatus)
OpenSPI(SPI_FOSC_4, MODE_11, SMPMID); //Increase clock speed
else
status=sdcCardTypeInvalid;
}
// Turn off CRC7 if we can, might be an invalid cmd on some cards (CMD59)
//response = SendMMCCmd(cmdCRC_ON_OFF,0x0);
// Ok Now set the block length to 512. It should be already
SendSDCCmd(SET_BLOCKLEN,BLOCKLEN_512);
// set the write protect state
if(WriteProtectState())
Flag->isWP = TRUE;
// read it a couple times until we sucessfully read it, seen san disks that really do not
// like this init routine for somereason, almost have to prime the device...
//for(timeout = 0xFF; timeout > 0 && SECTORread(0x0,gblSDMMCBuf) != sdcValid; timeout--)
for(timeout = 0xFF; timeout > 0 && SECTORread(0x0,(byte*)msd_buffer)!= sdcValid; timeout--)
{;}
// see if we had an issue
if(timeout == 0)
{
status = sdcCardNotInitFailure;
goto InitError;
}
// Get card information
/*
#ifdef DEBUG_SDMMC
DebugSDMMC_Info();
#endif
*/
return(status);
InitError:
SDC_CS = 1; // deselect the devices
// Turn it off
//MMC_OFF;
return(status);
}//end MediaInitialize
SDC_Error sdcardinitialize()
{
word i;
byte var;
SDC_CS=1;
OpenSPI(SPI_FOSC_64, MODE_11, SMPMID);
for (i=0; i<10; i++)
putcSPI(0xFF);
SDC_CS=0;
Delayms(1);
putcSPI(0x40);
putcSPI(0x00);
putcSPI(0x00);
putcSPI(0x00);
putcSPI(0x00);
putcSPI(0x95);
i=0xfff;
do {
var=ReadMedia(); //getting 0x09 in absence of card...
if(var==0x01)
break;
i--;
} while (i>0);
if (i==0) return sdcCardInitCommFailure;// false;
else {
i=0xfff;
do {
putcSPI(0x41);
putcSPI(0x00);
putcSPI(0x00);
putcSPI(0x00);
putcSPI(0x00);
putcSPI(0xF9);
putcSPI(0xff);
var=ReadMedia(); //getting 0x09 in absence of card...
if(var==0x0)
break;
var=ReadMedia(); //getting 0x09 in absence of card...
if(var==0x0)
break;
i--;
} while (i>0);
//SDC_CS=1;
//putcSPI(0xFF);
if (i==0) return sdcCardInitTimeout; //false;
return sdcValid;// true;
} // end if var==1
// return sdcCardInitCommFailure;// false;
} // end sdcardinitialize
/******************************************************************************
* Function: BYTE MediaDetect(void)
*
* PreCondition: SocketInitialize function has been executed.
*
* Input: void
*
* Output: TRUE - Card detected
* FALSE - No card detected
*
* Side Effects: None
*
* Overview: None
*
* Note: None
*****************************************************************************/
byte MediaDetect()
{
// give it a debounce here
Delayms(10);
return(!MEDIA_CD);
}//end MediaDetect
/******************************************************************************
* Function: SDC_Error MediaInitialize()
*
* PreCondition: None
*
* Input: None
*
* Output: sdcValid - Everything is fine
* sdcCardInitCommFailure - Communication has never been established with card
* sdcCardNotInitFailure - Card did not go into an initialization phase
* sdcCardInitTimeout - Card initialization has timedout
* sdcCardTypeInvalid - Card type was not able to be defined
* sdcCardBadCmd - Card did not reconized the command
* sdcCardTimeout - Card timedout during a read, write or erase sequence
* sdcCardCRCError - A CRC error has occurred during a read, data should be invalidated
* sdcCardDataRejected - Card and data sent's CRC did not match
*
* Side Effects: Variable 'gblSDC_media' is updated
*
* Overview: MediaInitialize initializes the media card and supporting variables.
*
* Note: goto's were used for error conditions
*****************************************************************************/
SDC_Error MediaInitialize()
{
byte timeout;
SDC_Error status = sdcValid;
SDC_RESPONSE response;
//SDC_CS = 1; //Initialize Chip Select line
// This function was called for a reason Turn it on
// SDC_ON=1;
//Media powers up in the open-drain mode and cannot handle a clock faster
//than 400kHz. Initialize SPI port to slower than 400kHz
// SMPMID = Input data sample at middle of data out
OpenSPI(SPI_FOSC_64, MODE_11, SMPMID); // Clock speed 48/4=12MHz, CKP (Clock Polarity)=1, SPI Clock Select (CKE)=1,
// let the card power on and initialize
Delayms(100);
//Media requires 80 clock cycles to startup [8 clocks/BYTE * 10 us]
for(timeout=0; timeout<10; timeout++)
mSend8ClkCycles();
SDC_CS = 0;
Delayms(1);
// Send CMD0 to reset the media
response = SendSDCCmd(GO_IDLE_STATE,0x0);
if(response.r1._byte == 0xFF)
{
status = sdcCardInitCommFailure; // we have not got anything back from the card
goto InitError;
}
// See if the device is ready
if(response.r1._byte != 0x01) //0x01=No Err&Busy Initializing
{
status = sdcCardNotInitFailure; // we have not got anything back from the card
goto InitError;
}
// According to spec cmd1 must be repeated until MMC card is fully initialized
timeout = 0xFFF;
do
{
response = SendSDCCmd(SEND_OP_COND,0x0);
timeout--;
}while((response.r1._byte != 0x00) && (timeout != 0));
// see if it failed
if(timeout == 0)
{
status = sdcCardInitTimeout; // we have not got anything back from the card
goto InitError;
}
else
OpenSPI(SPI_FOSC_4, MODE_11, SMPMID); //Increase clock speed
// Turn off CRC7 if we can, might be an invalid cmd on some cards (CMD59)
response = SendSDCCmd(cmdCRC_ON_OFF,0x0);
// Ok Now set the block length to 512. It should be already
SendSDCCmd(SET_BLOCKLEN,BLOCKLEN_512);
// set the write protect state
//if(WriteProtectState())
// Flag->isWP = TRUE;
// read it a couple times until we sucessfully read it, seen san disks that really do not
// like this init routine for somereason, almost have to prime the device...
//for(timeout = 0xFF; timeout > 0 && SECTORread(0x0,gblSDMMCBuf) != mmcValid; timeout--)
//{;}
// see if we had an issue
if(timeout == 0)
{
status = sdcCardNotInitFailure;
goto InitError;
}
// Get card information
//#ifdef DEBUG_SDMMC
// DebugSDMMC_Info();
//#endif
return(status);
InitError:
SDC_CS = 1; // deselect the devices
// Turn it off
// SDC_ON=0;
return(status);
}//end MediaInitialize
/******************************************************************************
* Function: void SocketInitialize(void)
*
* PreCondition: None
*
* Input: None
*
* Output: None
*
* Side Effects: None
*
* Overview: SocketInitialize initializes the socket interface.
* It initializes card select and detect signals.
*
* Note: None
*****************************************************************************/
void SocketInitialize(void)
{
// Turn off the card
// SDC_ON_DIR=OUTPUT; // Card Power - output
MEDIA_CD_DIR = INPUT; //Card Detect - input
SDC_CS = 1; //Initialize Chip Select line
SDC_CS_DIR = OUTPUT; //Card Select - output
MEDIA_WD_DIR = INPUT; //Write Protect - input
}//end SocketInitialize
/*
void DetectSDCard (void)
{
// SDC_ON=1; // Turned the power for the card ON (RB4 signal available)
if (MEDIA_CD==1) // RB4==1 ---> SD Card not present
{
// SDC_ON=0; // So turn off the SD Card power
return;
}
else if (MEDIA_CD==0) // RB4==0 ---> SD Card present
{
return; // Let the power be "ON" for SD card
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -