📄 sd_driver.c
字号:
while(!(gSD_SDSATAT&0x0400)) ; // wait for cmd end
kSD_OCR_H = SD_SDRSP;
kSD_OCR_M = SD_SDRSP;
kSD_OCR_L = SD_SDRSP;
kSD_OCR_H = ( (kSD_OCR_H & 0xff) <<24);
kSD_OCR_M = ( kSD_OCR_M << 8);
kSD_OCR_L = ( (kSD_OCR_L & 0xFF00) >> 8);
kSD_OCR =( kSD_OCR_H | kSD_OCR_M | kSD_OCR_L);
gSD_SDSATAT=0;
kSD_OCR &= 0x00FF8000; // check the OCR range is within 2.7v~3.6V
if(kSD_OCR) // response not 0, means the card has response. Must be a MMC card
goto InitMMCLoop;
InitLoop:
//-------------------
// card initializtion
SD_SendCommand(0x0037, 0x0000, 0x0000, 0x0001); // cmd55
while(!(gSD_SDSATAT&0x0400)) ; // wait for cmd end
// SD_CheckResponse(); // to checking ACMD response to identify whether the plugged card is SD or MMC
SD_SendCommand(0x0029, 0x00FF, 0x8000, 0x0003); // cmd41, OCR
UTL_Delay(6);
while(!(gSD_SDSATAT&0x0400)) ; // wait for cmd end
kSD_OCR_H = SD_SDRSP;
kSD_OCR_M = SD_SDRSP;
kSD_OCR_L = SD_SDRSP;
kSD_OCR_H = ( (kSD_OCR_H & 0xff) <<24);
kSD_OCR_M = ( kSD_OCR_M << 8);
kSD_OCR_L = ( (kSD_OCR_L & 0xFF00) >> 8);
kSD_OCR =( kSD_OCR_H | kSD_OCR_M | kSD_OCR_L);
gSD_SDSATAT=0;
for(i=0; i<70; i++)
asm NOP; // delay 900us for next card init
if((kSD_loop_counter == 10000) && (kSD_OCR == 0))
goto InitMMCLoop;// return(1); // SD identification error
else if((!(kSD_OCR & 0x80000000)) && (kSD_loop_counter<100000) )
{
kSD_loop_counter++;
goto InitLoop;
}
else if( (kSD_OCR & 0x80000000) && (kSD_loop_counter<100000) )
gSD_SDcard = 1; // plugged flash card is SD
goto EndInitLoop;
InitMMCLoop:
SD_SendCommand(0x0001, 0x80FF, 0x8000, 0x0003); // CMD1 SEND_OP_COND, for MMC initializtion
while(!(gSD_SDSATAT&0x0400)) ; // wait for cmd end
kSD_OCR_H = SD_SDRSP;
kSD_OCR_M = SD_SDRSP;
kSD_OCR_L = SD_SDRSP;
kSD_OCR_H = ( (kSD_OCR_H & 0xff) <<24);
kSD_OCR_M = ( kSD_OCR_M << 8);
kSD_OCR_L = ( (kSD_OCR_L & 0xFF00) >> 8);
kSD_OCR =( kSD_OCR_H | kSD_OCR_M | kSD_OCR_L);
gSD_SDSATAT=0;
for(i=0; i<70; i++)
asm NOP;
if((!(kSD_OCR & 0x80000000)) && (kSD_loop_counter<4000) )
{
kSD_loop_counter++;
goto InitMMCLoop;
}
else if(kSD_loop_counter == 4000)
return(1); // SD identification error
if( (kSD_OCR & 0x80000000) && (kSD_loop_counter<4000) )
gSD_SDcard = 0; // plugged flash card is MMC
EndInitLoop:
return(0);
}
// ==================================================================
// SD_Init() -
//
// Step 3, to initialize the flash card
//
// Input - nil
//
// Output - nil
//
// Function - nil.
//
// Returned value list:
// 0: no error
// 1: An error happened while SD_AllSendCID
// 2: An error happened while SD_AllSendRCA
// 3: An error happened while SD_SendCSD
// 4: An error happened while SD_SelectSDcard
// 5: An error happened while SD_SetBlockLength
// 6: An error happened while SD_SetBusWidth
//
// ==================================================================
muint8 SD_Init(void)
{
// muint8 kSD_ReturnedValue;
SD_AllSendCID();
SD_AllSendRCA();
SD_SendCSD();
SD_SelectSDcard((muint16)(gSD_RCA));
SD_SetBlockLength(0x0200); // set block length to 512 bytes
// if(!gSD_SDcard) // MMC card plugged
// SD_SetBusWidth(0x01); // 1 bit mode
// else
if (gSD_SDcard)
SD_SetBusWidth(0x04); // SD card plugged, force to 4-bits mode
SD_SDCLKCON = 0x000a; // card clk enable, 1/2, 6MHz
UTL_Delay(1);
return(0);
}
// ==================================================================
// SD_AllSendCID() -
//
// Ask the card to send out it's CID (Card Identification)
//
// Input - nil
//
// Output - nil
//
// Function - nil.
// Returned value list:
// 0: no error
// 1: An error happened while SD_AllSendCID
//
// ==================================================================
void SD_AllSendCID(void)
{
muint16 i;
gSD_SDSATAT=0;
SD_SDBLKLN = 0x0200; // set block length to 512 bytes
SD_SendCommand(0x0002, 0x0000, 0x0000, 0x0002);
while(!(gSD_SDSATAT&0x0400)) ; // wait for cmd end
for(i=0;i<8;i++)
gSD_CID[i] = SD_SDRSP;
gSD_SDSATAT=0;
for(i=0; i<100; i++)
asm NOP; // delay 1ms for next card init
}
// ==================================================================
// SD_AllSendRCA() -
//
// Ask the card to send out it's RCA (Card Relative Address)
//
// Input - nil
//
// Output - nil
//
// Function - nil.
//
// Returned value list:
// 0: no error
// 1: An error happened while SD_AllSendRCA
//
// ==================================================================
void SD_AllSendRCA(void)
{
muint16 i;
muint16 kSD_RCA_H, kSD_RCA_M, kSD_RCA_L;
gSD_SDSATAT=0;
//-----------------
// all send RCA
if(gSD_SDcard)
{
SD_SendCommand(0x0003, 0x0000, 0x0000, 0x0001);
while(!(gSD_SDSATAT&0x0400)) ; // wait for cmd end
kSD_RCA_H = SD_SDRSP;
kSD_RCA_M = SD_SDRSP;
kSD_RCA_L = SD_SDRSP;
gSD_SDSATAT=0;
kSD_RCA_H = (kSD_RCA_H & 0x00ff); // RCA[31:16]
kSD_RCA_M = ( kSD_RCA_M & 0xff00);
gSD_RCA =( (kSD_RCA_H << 8) | (kSD_RCA_M >> 8));
}
else
{
gSD_RCA = 0x0102; // for MMC card
SD_SendCommand(0x0003, gSD_RCA, 0x0000, 0x0001); // RCA=0xaaaa for MMC card
while(!(gSD_SDSATAT&0x0400)) ; // wait for cmd end
}
for(i=0; i<100; i++)
asm NOP; // delay 1ms for next card init
}
// ==================================================================
// SD_SendCSD() -
//
// Ask the card to send out it's CSD (Card Specific Data)
//
// Input - nil
//
// Output - nil
//
// Function - nil.
//
// Returned value list:
// 0: no error
// 1: An error happened while SD_SendCSD
//
// ==================================================================
void SD_SendCSD(void)
{
muint16 i;
gSD_SDSATAT=0;
SD_SendCommand(0x0009, (muint16)gSD_RCA, 0x0000, 0x0002); // CMD9 SEND_CSD
while(!(gSD_SDSATAT&0x0400)) ; // wait for cmd end
for(i=0; i<8; i++)
gSD_CSD[i] = SD_SDRSP;
for(i=0; i<100; i++)
asm NOP; // delay 1ms for next card init
// gSD_MaxBlockNumber = ( ((gSD_CSD[3] & 0x3FF) << 2) | ( (gSD_CSD[4] & 0xC000) >> 14) ) * pow(2, ( (gSD_CSD[5] & 0x7000) >> 12 )+2 );
// gSD_Capacity = (muint32)gSD_MaxBlockNumber * 0.5;
// for(i=0; i<7; i++)
// kSD_Temp |= gSD_CSD[i];
//
// if(kSD_Temp == 0)
// return(1);
// else
// return(0); // no error
}
// ==================================================================
// SD_SelectSDcard() -
//
// Select the card
//
// Input - nil
//
// Output - nil
//
// Function - nil.
// Returned value list:
// 0: no error, the card is ready
// 1: the card is not ready
//
// ==================================================================
void SD_SelectSDcard(muint16 kSD_RCA)
{
muint16 i;
// muint32 kSD_Temp;
gSD_SDSATAT=0;
SD_SendCommand(0x0007, kSD_RCA, 0x0000, 0x0001); // 0xbb0b: Toshiba SD card
UTL_Delay(6);
while(!(gSD_SDSATAT&0x0400)) ; // wait for cmd end
SD_SDBLKLN = 0x0200; // set block length to 512 bytes
SD_SDNOBLK = 2; // test, Number of block in block mode transmission
for(i=0; i<100; i++)
asm NOP; // delay 1ms for next card init
//
// kSD_Temp =SD_CheckResponse();
// if((kSD_Temp & 0x0100) == 0x0100) // bit8=1 means the card is ready
// return(0); // no error
// else
// return(1); // not ready
}
// ==================================================================
// SD_SetBlockLength() -
//
// Set block length fixed to 512 bytes
//
// Input - nil
//
// Output - nil
//
// Function - nil.
//
// Returned value list:
// 0: no error, the card is ready
// 1: the card is not ready
//
// ==================================================================
void SD_SetBlockLength(muint16 SD_BlockLength)
{
muint16 i;
gSD_SDSATAT=0;
SD_SendCommand(0x0010, 0x0000, SD_BlockLength, 0x0001);
while(!(gSD_SDSATAT&0x0400)) ; // wait for cmd end
for(i=0; i<100; i++)
asm NOP; // delay 1ms for next card init
// kSD_Temp =SD_CheckResponse();
// if((kSD_Temp & 0x0100) == 0x0100) // bit8=1 means the card is ready
// return(0); // no error
// else
// return(1); // not ready
}
// ==================================================================
// SD_SetBusWidth() -
//
// Set bus width to 1 or 4 bits mode
//
// Input - nil
//
// Output - nil
//
// Function - nil.
//
// Returned value list:
// 0: no error, the card is ready
// 1: the card is not ready
//
// ==================================================================
void SD_SetBusWidth(muint16 SD_BusWidth)
{
muint16 i;
gSD_SDSATAT=0;
if(gSD_SDcard)
{
SD_SendCommand(0x0037, (muint16)gSD_RCA, 0x0000, 0x0001); // cmd55, RCA, stuff bits
UTL_Delay(6);
while(!(gSD_SDSATAT&0x0400)) ; // wait for cmd end
if(SD_BusWidth == 1)
SD_SendCommand(0x0006, 0x0000, 0x0000, 0x0001); // cmd6 SET_BUS_WIDTH, [31:2]stuff bits, [1:0] bus width, 00=1bit, 0x200=1bit
else
SD_SendCommand(0x0006, 0x0000, 0x0002, 0x0201); // 4 bits
while(!(gSD_SDSATAT&0x0400)) ; // wait for cmd end
UTL_Delay(6);
for(i=0; i<100; i++)
asm NOP; // delay 1ms for next card init
// kSD_Temp =SD_CheckResponse();
//
// if((kSD_Temp & 0x0100) == 0x0100) // bit8=1 means the card is ready
// return(0); // no error
// else
// return(1); // not ready
}
}
// ==================================================================
// SD_CheckStatus() -
//
// Check the response from SD card
//
// Input - nil
//
// Output - nil
//
// Function - nil.
//
// Returned value list:
// 0: RDY
// 1: Not RDY
//
// ==================================================================
muint8 SD_CheckStatus(void)
{
muint32 kSD_ResponseCheck;
muint16 i;
gSD_SDSATAT=0;
SD_SendCommand(0x000d, gSD_RCA, 0x0000, 0x0001); // CMD13 SEND_STATUS,
while(!(gSD_SDSATAT&0x0400)) ; // wait for cmd end
kSD_ResponseCheck = SD_CheckResponse();
for(i=0; i<100; i++)
asm NOP; // delay 1ms for next card init
if( (kSD_ResponseCheck&0x0100)==0x0100 ) // bit8=1=RDY
return(1); // the card is ready
else
return(0); // the card is not ready
}
// ==================================================================
// SD_CheckResponse() -
//
// Check the response from SD card
//
// Input - nil
//
// Output - nil
//
// Function - nil.
//
// ==================================================================
muint32 SD_CheckResponse(void)
{
muint32 kSD_Resp;
muint8 *cptr;
cptr=(muint8*)&kSD_Resp;
*cptr++=0;
*cptr++ = (muint8)SD_SDRSP;
*cptr++ = (muint8)SD_SDRSP;
*cptr++ = (muint8)SD_SDRSP;
return(kSD_Resp);
}
// ==================================================================
// SD_SendCommand() -
//
//
// Input - nil
//
// Output - nil
//
// Function - nil.
//
// ==================================================================
void SD_SendCommand(muint16 SD_CMDNo, muint16 SD_argh, muint16 SD_argl, muint16 SD_RespNo)
{
// muint16 i;
SD_SDCMDNO = SD_CMDNo;
SD_SDARGH = SD_argh;
SD_SDARGL = SD_argl;
SD_SDCMDATCON = SD_RespNo;
while (!(gSD_SDSATAT & 0x0400));
}
// ==================================================================
// SD_LBACommand1() -
//
// To set command to SM device
//
// Input - = 3 command parameters
//
// Output - =
//
// Function returns error code
//
// ==================================================================
muint8 SD_LBACommand1(muint8 Block, muint8 *pLBA, muint8 QueBuffer)
{
muint32 *lptr;
volatile muint32 SD_LBA;
muint16 status;
lptr=(muint32*)pLBA;
gSD_LBA=*lptr;
gSD_DSCR_B = Block;
mClearBit(QnEN,QC1CR); // disable QC1
QC1REQ = 0xff; // remap QC1 to mon-existing resources
QC2REQ = 0xff; // remap QC1 to mon-existing resources
mSetBit(DBRST,QC34DCR); // reset QC34
mSetBit(QnPRST, QC3CR); // reset QC3
SD_LBA=gSD_LBA;
IQUECR = (1<<CH34DBE)+(1<<IQUEEN); // Enable double buffer
QC34DTR = 0; // Enable force handshake
mClearBit(SBTE,QC34DCR); // clear single buffer mode
QC3CR=0x17; // Q1SML = 0, large buffer 16-bit transfer
QC3SZB=0x10+QueBuffer<<1; // 512 bytes block, starting from $x000+QueBuffer
QC3REQ=0x08; // SD Rx channel
status = SD_QUE_ReadMultipleBlock(SD_LBA, gSD_DSCR_B);
IQUECR = (1<<CH34DBE)+(1<<IQUEEN); // Enable double buffer
QC34DTR = (1<<DTHE)+(1<<DRHE); // Enable force handshake
QC3CR = (1<<QnEN)+(1<<Qn16EN)+(1<<QnPRST);
QC3SZB = 0x12; // 2 block 0f 256 bytes (HS), base 0x2000
QC3REQ = 0x01; // Channel 3 set to USB TX
QC1CR = (1<<QnEN)+(1<<Qn16EN)+(1<<QnPRST);
QC1SZB = 0x10; // 2 block of 256 bytes (HS)
QC1REQ = 0x00; // Channel 1 set to USB RX
return(0);
}
//
// The end of file sd_driver.c
// *********************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -