📄 l1_storage.c
字号:
// input paremeters:
// none
// return value:
// 0x00 - No error
// 0x01 - CMD13 error
// 0x02 - CMD7 error
// 0x03 - the card is not in the correct satet
UCHAR L1_SDCheckState(void) USING_0
{
UCHAR CmdBuf[5];
UCHAR RspBuf[17];
UCHAR error;
CmdBuf[0] = 0x4d; // TX "CMD13" to get card's state
CmdBuf[1] = SD_RCA[0];
CmdBuf[2] = SD_RCA[1];
CmdBuf[3] = 0x00;
CmdBuf[4] = 0x00;
L2_SDTxCommand(CmdBuf);
error=L2_SDRxResponse(RspBuf,0,1);
if(error!=0) return 0x01;
if(RspBuf[0]!=0x0d) return 0x01; // check the response number
if((RspBuf[3] & 0x1e)==0x06) { // if in the stand-by state, go to the transfer state
CmdBuf[0] = 0x47;
CmdBuf[1] = SD_RCA[0];
CmdBuf[2] = SD_RCA[1];
CmdBuf[3] = 0x00;
CmdBuf[4] = 0x00;
L2_SDTxCommand(CmdBuf); // TX "CMD7" to go the the transfer state
error=L2_SDRxResponse(RspBuf,0,1);
if(error!=0) return 0x02;
if(RspBuf[0]!=0x07) return 0x02; // check the response number
}
else
{
// if not in standby state or transfer state, discard the operation
if((RspBuf[3] & 0x1e)!=0x08) return 0x03;
}
CmdBuf[0] = 0x4d;
CmdBuf[1] = SD_RCA[0];
CmdBuf[2] = SD_RCA[1];
CmdBuf[3] = 0x00;
CmdBuf[4] = 0x00;
L2_SDTxCommand(CmdBuf); // TX "CMD13" to get card's state
error=L2_SDRxResponse(RspBuf,0,1);
if(error!=0) return 0x01;
if(RspBuf[0]!=0x0d) return 0x01; // check the response number
// if not in transfer state, discard the operation
if((RspBuf[3] & 0x1e)!=0x08)
return 0x03;
//PRINT_L1("Check State is finished!\n");
return 0x00;
}
//-----------------------------------------------------------------------------
//L1_SDSetBusMode
//-----------------------------------------------------------------------------
// input paremeters:
// BusMode - 0: 1-bit mode, 1: 4-bit mode
// return value:
// 0x00 - No error
// 0x01 - CMD55 error
// 0x02 - ACMD42 error
// 0x03 - ACMD6 error
UCHAR L1_SDSetBusMode(UCHAR BusMode) USING_0
{
UCHAR CmdBuf[5];
UCHAR RspBuf[17];
UCHAR error;
//PRINT_L1("Enter SetBusMode\n");
L2_SDConfig(0,BusMode); // 24MHz, 1bit bus mode
CmdBuf[0] = 0x77;
CmdBuf[1] = SD_RCA[0];
CmdBuf[2] = SD_RCA[1];
CmdBuf[3] = 0x00;
CmdBuf[4] = 0x00;
L2_SDTxCommand(CmdBuf); // TX "CMD55"
error=L2_SDRxResponse(RspBuf,0,1);
if(error!=0) return 0x01;
if(RspBuf[0]!=0x37) return 0x01; // check the response number
CmdBuf[0] = 0x6A;
CmdBuf[1] = 0x00;
CmdBuf[2] = 0x00;
CmdBuf[3] = 0x00;
if(BusMode==0) CmdBuf[4] = 0x01; // TX "ACMD42" to connect the pull-up resistor on line 'data3'
else CmdBuf[4] = 0x00; // TX "ACMD42" to disconnect the pull-up resistor on line 'data3'
L2_SDTxCommand(CmdBuf);
error=L2_SDRxResponse(RspBuf,0,1);
if(error!=0) return 0x02;
if(RspBuf[0]!=0x2A) return 0x02; // check the response number
CmdBuf[0] = 0x77;
CmdBuf[1] = SD_RCA[0];
CmdBuf[2] = SD_RCA[1];
CmdBuf[3] = 0x00;
CmdBuf[4] = 0x00;
L2_SDTxCommand(CmdBuf); // TX "CMD55"
error=L2_SDRxResponse(RspBuf,0,1);
if(error!=0) return 0x01;
if(RspBuf[0]!=0x37) return 0X01; // check the response number
CmdBuf[0] = 0x46;
CmdBuf[1] = 0x00;
CmdBuf[2] = 0x00;
CmdBuf[3] = 0x00;
if(BusMode==0) CmdBuf[4] = 0x00; // TX "ACMD6" to set the card's to 1-bit bus
else CmdBuf[4] = 0x02; // TX "ACMD6" to set the card's to 4-bit bus
L2_SDTxCommand(CmdBuf);
error=L2_SDRxResponse(RspBuf,0,1);
if(error!=0) return 0x03;
if(RspBuf[0]!=0x06) return 0x03; // check the response number
//PRINT_L1("Exit SetBusMode\n");
return 0x00;
}
//-----------------------------------------------------------------------------
//L1_DMARdSD
//-----------------------------------------------------------------------------
// input paremeters:
// Dst - the source of DMA
// 0: DRAM
// 1: CPU 4K SRAM (0x1000 ~ 0x1FFF)
// 2: forbidden (flash itself)
// 3: Audio
// 4: USB
// SAdr - read starting address
// BlockCnt - number of block to be read
// BlockSize - read length of one block from SD
// return value:
// 0x00 - No error
// 0x01 - CMD17/CMD18 error
// 0x02 - data CRC16 error
// 0x03 - CMD12 error
UCHAR L1_DMARdSD(UCHAR Dst, ULONG SAdr, ULONG BlockCnt, USHORT BlockSize) USING_0
{
ULONG dramaddr = 0;// 102302@wyeo
ULONG block;
ULONG sdaddr;
UCHAR CmdBuf[5];
UCHAR RspBuf[17];
UCHAR error;
UCHAR tmp;
UCHAR j;
//L2_FlashMode(5, 1, 1);
////DbgPrint("Enter DMAReadData\n");
/* if(Dst==0) L2_ReadDRAMDMAAdr(&dramaddr); */ //Chamber PA8591
sdaddr = SAdr;
for(block=BlockCnt ; block > 32 ; block=block-32)
{
CmdBuf[0] = 0x52;
CmdBuf[1] = (sdaddr & 0xFF000000) >> 24;
CmdBuf[2] = (sdaddr & 0x00FF0000) >> 16;
CmdBuf[3] = (sdaddr & 0x0000FF00) >> 8;
CmdBuf[4] = (sdaddr & 0x000000FF);
L2_SDTxCommand(CmdBuf);
for(j=0; j<32; j++)
{
// check the CMD18 response
if(j==1)
{
do{
L2_SDRspBufState(&tmp);
}while(tmp==0); // wait until response buffer full
L2_SDReadRspBuf(1,&tmp);
if(tmp!=0x12) return 0x01;
}
if(Dst==1) L2_DoDMA(2,Dst,BlockSize,0,0);
//richie@mi0415 begin
else if (Dst == K_DMA_USB)
{
UCHAR bi;
L2_SetSRAMDMA((USHORT)G_ucStorData-K_SRAM_HI_START_OFFSET);
L2_DoDMA(K_DMA_FLASH,K_DMA_SRAM,BlockSize,0,0);
for (bi=0;bi<8;bi++)
{
L2_DoDMA(K_DMA_SRAM,K_DMA_USB,64,0,0);
while ((XBYTE[K_USB_CLASS_IN_BUF_SIZE] < 64) && (G_UI_USBConnect == K_UI_USB_CONNECT)) ; //wait for 64 in bulk buffer
XBYTE[0x25a1] = K_USB_CLASS_IN_OPEN;//0x01;//open bulk in
while (((XBYTE[0x25c2] & K_USB_CLASS_IN_ACK_MASK) == 0) && (G_UI_USBConnect == K_UI_USB_CONNECT)) ; //wait pc ack
XBYTE[0x25c2] = XBYTE[0x25c2] & K_USB_CLASS_IN_ACK_RESET;//reset 0x25c2
}
}
//richie@mi0415 end
else {
L2_SetSRAMDMA((USHORT)G_ucStorData-K_SRAM_HI_START_OFFSET);
L2_DoDMA(2,1,BlockSize,0,0);
/* if(Dst==0) L2_SetDRAMDMA(dramaddr); */ //Chamber PA8591
L2_DoDMA(1,Dst,BlockSize,0,0);
}
L2_SDWaitIdle();
L2_SDCheckCRC16(&tmp);
if(tmp!=1) return 0x02; // check data CRC16
if(Dst == 0) dramaddr += (ULONG)(BlockSize>>1);
}
CmdBuf[0] = 0x4C; // TX "CMD12" to stop read
L2_SDTxCommand(CmdBuf);
error=L2_SDRxResponse(RspBuf,0,1);
if(error!=0) return 0x03;
if(RspBuf[0]!=0x0C) return 0x03; // check the response number
L2_SDTxDummy();
sdaddr += (ULONG)BlockSize<<5;
}
if(block != 0)
{
if(block==1)
{ // TX "CMD17" to read single block data
CmdBuf[0] = 0x51;
CmdBuf[1] = (sdaddr & 0xFF000000) >> 24;
CmdBuf[2] = (sdaddr & 0x00FF0000) >> 16;
CmdBuf[3] = (sdaddr & 0x0000FF00) >> 8;
CmdBuf[4] = (sdaddr & 0x000000FF);
L2_SDTxCommand(CmdBuf);
}
else
{ // TX "CMD18" to read mutiple block data
CmdBuf[0] = 0x52;
CmdBuf[1] = (sdaddr & 0xFF000000) >> 24;
CmdBuf[2] = (sdaddr & 0x00FF0000) >> 16;
CmdBuf[3] = (sdaddr & 0x0000FF00) >> 8;
CmdBuf[4] = (sdaddr & 0x000000FF);
L2_SDTxCommand(CmdBuf);
}
for(j=0; j<block; j++)
{
// check the CMD18 response
if(j==1)
{
do{
L2_SDRspBufState(&tmp);
}while(tmp==0); // wait until response buffer full
L2_SDReadRspBuf(1,&tmp);
if(tmp!=0x12) return 0x01;
}
if(Dst==1) L2_DoDMA(2,Dst,BlockSize,0,0);
//richie@mi0415 begin
else if (Dst == K_DMA_USB)
{
UCHAR bi;
L2_SetSRAMDMA((USHORT)G_ucStorData-K_SRAM_HI_START_OFFSET);
L2_DoDMA(K_DMA_FLASH,K_DMA_SRAM,BlockSize,0,0);
for (bi=0;bi<8;bi++)
{
L2_DoDMA(K_DMA_SRAM,K_DMA_USB,64,0,0);
while ((XBYTE[K_USB_CLASS_IN_BUF_SIZE] < 64) && (G_UI_USBConnect == K_UI_USB_CONNECT)) ; //wait for 64 in bulk buffer
XBYTE[0x25a1] = K_USB_CLASS_IN_OPEN;//0x01;//open bulk in
while (((XBYTE[0x25c2] & K_USB_CLASS_IN_ACK_MASK) == 0) && (G_UI_USBConnect == K_UI_USB_CONNECT)) ; //wait pc ack
XBYTE[0x25c2] = XBYTE[0x25c2] & K_USB_CLASS_IN_ACK_RESET;//reset 0x25c2
}
}
//richie@mi0415 end
else {
L2_SetSRAMDMA((USHORT)G_ucStorData-K_SRAM_HI_START_OFFSET);
L2_DoDMA(2,1,BlockSize,0,0);
/* if(Dst==0) L2_SetDRAMDMA(dramaddr); */ // Chamber PA8591
L2_DoDMA(1,Dst,BlockSize,0,0);
}
L2_SDWaitIdle();
L2_SDCheckCRC16(&tmp);
if(tmp!=1) return 0x02; // check data CRC16
if(Dst == 0) dramaddr += (ULONG)(BlockSize>>1);
}
if(block==1)
{
do{L2_SDRspBufState(&tmp);}while(tmp==0); // wait until response buffer full
L2_SDReadRspBuf(1,&tmp);
if(tmp!=0x11) return 0x01; // check the response number
}
else
{
CmdBuf[0] = 0x4C; // TX "CMD12" to stop read
L2_SDTxCommand(CmdBuf);
error=L2_SDRxResponse(RspBuf,0,1);
if(error!=0) return 0x03;
if(RspBuf[0]!=0x0C) return 0x03; // check the response number
}
L2_SDTxDummy();
}
////DbgPrint("Exit DMAReadData\n");
return 0x00;
}
#if (MMC)
UCHAR L1_MMCIdentification(USHORT BlockSize)
{
UCHAR CmdBuf[5];
UCHAR RspBuf[17];
UCHAR i,error;
UCHAR READ_BL_LEN;
USHORT BLOCK_LEN;
USHORT C_SIZE;
UCHAR C_SIZE_MULT;
USHORT MULT;
ULONG BLOCKNR;
L2_FlashMode(6, 1, 1);
L2_MMCInit();
L2_SDConfig(3,0);
L2_SDBlockSize(BlockSize);
for(i=0; i<100; i++) { // Tx 80 clock for power on sequence
L2_SDTxDummy();
}
CmdBuf[0] = 0x40;
CmdBuf[1] = 0x00;
CmdBuf[2] = 0x00;
CmdBuf[3] = 0x00;
CmdBuf[4] = 0x00;
L2_SDTxCommand(CmdBuf); // Tx "CMD0",//go idle state
L2_SDTxDummy();
do
{
CmdBuf[0] = 0x41;
CmdBuf[1] = 0x00;
CmdBuf[2] = 0x08;
CmdBuf[3] = 0x00;
CmdBuf[4] = 0x00;
L2_SDTxCommand(CmdBuf); // TX "CMD1",SEND_OP_COND
error=L2_SDRxResponse(RspBuf,0,0);
if (error!=0) return 0x01;
if(RspBuf[0]!=0x3f) return 0x01; // check the response number
} while((RspBuf[1] & 0x80)==0);
// get card's OCR register
for(i=0; i<4; i++) SD_OCR[i] = RspBuf[i+1];
//version4.0@ada@0513 for MMC
/* for (i = 0; i < 4; i++)
{
//DbgPrint("SD card register OCR[%bx] = %bx\n",i,SD_OCR[i]);
}
*/
CmdBuf[0] = 0x42;
CmdBuf[1] = 0x00;
CmdBuf[2] = 0x00;
CmdBuf[3] = 0x00;
CmdBuf[4] = 0x00;
L2_SDTxCommand(CmdBuf); // TX "CMD2",SEND_ALL_CID
error=L2_SDRxResponse(RspBuf,1,0);
if (error!=0) return 0x02;
if(RspBuf[0]!=0x3f) return 0x02; // check if response number
// get card's CID register
/* for(i=0; i<16; i++) MMC_CID[i] = RspBuf[i+1];
//DbgPrint("MMC card MID1 = %bx, MID2 = %bx, MID3 = %bx\n",MMC_CID[0],MMC_CID[1],MMC_CID[2]);
//DbgPrint("MMC card CIN1 = %bx, CIN2 = %bx, CIN3 = %bx\n",MMC_CID[3],MMC_CID[4],MMC_CID[5]);
//DbgPrint("MMC card CIN4 = %bx, CIN5 = %bx, CIN6 = %bx\n",MMC_CID[6],MMC_CID[7],MMC_CID[8]);
//DbgPrint("MMC card CIN7 = %bx, CIN8 = %bx, CIN9 = %bx\n",MMC_CID[9],MMC_CID[10],MMC_CID[11]);
//DbgPrint("MMC card CIN10 = %bx, CIN11 = %bx, CIN12 = %bx\n",MMC_CID[12],MMC_CID[13],MMC_CID[14]);
*/
// set card's RCA register
SD_RCA[0]=0x55;
SD_RCA[1]=0xAA;
CmdBuf[0] = 0x43;
CmdBuf[1] = SD_RCA[0];
CmdBuf[2] = SD_RCA[1];
CmdBuf[3] = 0x00;
CmdBuf[4] = 0x00;
L2_SDTxCommand(CmdBuf); // TX "CMD3",SET_RELATIVE_ADDR
error=L2_SDRxResponse(RspBuf,0, 1);
if(error!=0) return 0x03;
if(RspBuf[0]!=0x03) return 0x03; // check the response number
CmdBuf[0] = 0x49;
CmdBuf[1] = SD_RCA[0];
CmdBuf[2] = SD_RCA[1];
CmdBuf[3] = 0x00;
CmdBuf[4] = 0x00;
L2_SDTxCommand(CmdBuf); // TX "CMD9",SEND_CSD
error=L2_SDRxResponse(RspBuf,1, 0);
if (error!=0) return 0x04;
if(RspBuf[0]!=0x3f) return 0x04; // check the response number
// get card's CMMC register
for(i=0; i<16; i++)
{
SD_CSD[i] = RspBuf[i+1];
// //DbgPrint("SD_CSD[%bx] = %bx\n",i,SD_CSD[i]);
}
/* //DbgPrint("MMC card CSD_STRUCTURE = %bx\n",SD_CSD[0] >> 6);
//DbgPrint("MMC card MMC_PORT = %bx\n",SD_CSD[0] >> 4);
//DbgPrint("MMC card TAAC = %bx\n",SD_CSD[1]);
//DbgPrint("MMC card NSAC = %bx\n",SD_CSD[2]);
//DbgPrint("MMC card TRAN_SPEED = %bx\n",SD_CSD[3]);
//DbgPrint("MMC card CCC = %x\n",((((USHORT)SD_CSD[4]) << 8) | (USHORT)SD_CSD[5]) >> 4);
//DbgPrint("MMC card READ_BL_LEN = %bx\n",SD_CSD[5] & 0x0f);
*/
READ_BL_LEN = SD_CSD[5] & 0x0f;
BLOCK_LEN = 0x0001 << READ_BL_LEN;
// //DbgPrint("BLOCK_LEN = %x\n",BLOCK_LEN);
SD_BlockSize = BLOCK_LEN;
// //DbgPrint("MMC card C_SIZE = %x\n",(((USHORT)SD_CSD[6]) << 10) | ((USHORT)SD_CSD[7] << 2) | ((USHORT)SD_CSD[8] >> 6));
C_SIZE = (((USHORT)SD_CSD[6]) << 10) | ((USHORT)SD_CSD[7] << 2) | ((USHORT)SD_CSD[8] >> 6);
// //DbgPrint("MMC card C_SIZE_MULT = %bx\n",((SD_CSD[9] & 0x03) << 1) | (SD_CSD[10] >> 7));
C_SIZE_MULT = (((SD_CSD[9] & 0x03) << 1) | (SD_CSD[10] >> 7));
MULT = 0x0001 << (USHORT)(C_SIZE_MULT + 2);
// //DbgPrint("MULT = %x\n",MULT);
BLOCKNR = ((ULONG)(C_SIZE + 1) * (ULONG)MULT);
// //DbgPrint("BLOCKNR = %lx\n",BLOCKNR);
G_Card_TotalCardSize = BLOCKNR * (ULONG)BLOCK_LEN;
// //DbgPrint("G_Card_TotalCardSize = %lx\n",G_Card_TotalCardSize);
L2_SDConfig(1,0); // 12MHz, 1bit bus mode
return 0x00;
}
#endif
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -