📄 hs_mmc.c
字号:
/*****************************************
NAME: HS_MMC.c
DESC: High Speed MMC test
HISTORY:
2006.12.18:GOM: draft ver 1.0
*****************************************/
#include <stdio.h>
#include <string.h>
#include "def.h"
#include "option.h"
#include "2443addr.h"
#include "system.h"
#include "pll.h"
#include "console.h"
#include "hs_mmc.h"
#define POL_Ver1 0
#define INT_Ver1 1
#define DMA_Ver1 2
#define SDI_Tx_buffer_HSMMC (_NONCACHE_STARTADDRESS)
#define SDI_Rx_buffer_HSMMC (_NONCACHE_STARTADDRESS+(0x01000000))
#define SDI_Compare_buffer_HSMMC (_NONCACHE_STARTADDRESS+(0x02000000))
#define Card_OneBlockSize_ver1 512
// Global variables
unsigned int *Tx_buffer_HSMMC;
unsigned int *Rx_buffer_HSMMC;
unsigned int *Compare_buffer_HSMMC;
volatile unsigned int rd_cnt_HSMMC;
volatile unsigned int wt_cnt_HSMMC;
volatile unsigned int BlockNum_HSMMC=0;
volatile unsigned int WriteBlockCnt_INT=0;
volatile unsigned int ReadBlockCnt_INT=0;
volatile unsigned int WRITEINT_DONE=0;
volatile unsigned int READINT_DONE=0;
volatile unsigned int COMPARE_INT_DONE=0;
volatile unsigned int CompareCnt_INT=0;
volatile unsigned int BufferBoundary_INT_Cnt=0;
volatile unsigned int HS_DMA_END = 0;
volatile unsigned int HS_CARD_DETECT = 0;
volatile int OCRcheck=0;
volatile int ThisIsMmc=0;
volatile int m_uRca=0;
volatile int m_ucMMCSpecVer = 0;
volatile int SDSpecVer=0;
volatile int CE_ATA=0;
volatile int SectorMode =0;
extern unsigned int ARMCLK, HCLK, PCLK;
//////////////////////////////////////////////////////////////////////////
#define NEW_SD_CARD 1
#define BUFFER_BOUNDARY 0
#define HCLK_OPERATION 0
//////////////////////////////////////////////////////////////////////////
void * func_HSMMC_test[][2]=
{
(void *)HS_MMC_WriteTest, "SDIO Write ",
(void *)HS_MMC_Write_AgingTest, "SD/MMC Write Aging ",
(void *)HS_MMC_ReadTest, "SDIO Read ",
(void *)HS_MMC_EraseBlock, "SDIO Block Erase ",
0,0
};
void Test_HS_MMC(void)
{
int i;
HS_MMC_SETGPIO();
HS_MMC_Reset();
if(!HS_MMC_init())
{
printf("\nCard initial fail\n");
}
while(1)
{
i=0;
printf("\n\n");
while(1)
{ //display menu
printf("%2d:%s",i,func_HSMMC_test[i][1]);
i++;
if((int)(func_HSMMC_test[i][0])==0)
{
printf("\n");
break;
}
if((i%3)==0)
printf("\n");
}
printf("\nSelect (\"-1\" to exit) : ");
i = GetIntNum();
if(i==-1)
break; // return.
if( (i<((sizeof(func_HSMMC_test)-1)/8)) ) // select and execute...
( (void (*)(void)) (func_HSMMC_test[i][0]) )();
}
}
int HS_MMC_init(void)
{
int uArg;
ClockOnOff(0);
rSCLKCON |=(1<<13);
SetClock(SD_EXTCLK, 0x20);
rHM_TIMEOUTCON = 0xe;
HostCtrlSpeedMode(NORMAL);
InterruptEnable(0xff, 0xff);
printf("rHM_NORINTSTS = %x\n",rHM_NORINTSTS);
IssueCommand(0,0x00,0);//Idle State
printf("\nEnter to the Idle State\n");
uArg = (0x1<<8)|(0xaa<<0); //This Line for HC SD card.
IssueCommand(8,uArg,0);
OCRcheck =1;
if(!(SDSpecVer == 2))
{
if(SetMMCOCR())
{
ThisIsMmc=1;
printf("MMC card is detected\n");
}
else if(SetSDOCR())
{
ThisIsMmc=0;
printf("SD card is detected\n");
}
else
return 0;
}
else
{
if(SetSDOCR())
{
ThisIsMmc=0;
printf("SD card is detected\n");
}
}
OCRcheck =0;
// Check the attached card and place the card in the IDENT state rHM_RSPREG0
IssueCommand(2,0,0);
printf("\n - Product Name : %c%c%c%c%c%c\n",((rHM_RSPREG2>>24)&0xFF),((rHM_RSPREG2>>16)&0xFF),((rHM_RSPREG2>>8)&0xFF),(rHM_RSPREG2&0xFF),((rHM_RSPREG1>>24)&0xFF),((rHM_RSPREG1>>16)&0xFF));
// Send RCA(Relative Card Address). It places the card in the STBY state
m_uRca = (ThisIsMmc) ? 0x0001 : 0x0000;
IssueCommand(3,m_uRca,0);
if(!ThisIsMmc)
{
m_uRca = (rHM_RSPREG0>>16)&0xFFFF;
printf("=> RCA=0x%x\n", m_uRca);
}
printf("\nEnter to the Stand-by State\n");
IssueCommand(9, m_uRca, 0);//Send CSD
DisplayCardInformation();
IssueCommand(7, m_uRca, 0);
//printf("\nEnter to the Transfer State\n");
//////////////////////// Operating Clock setting ////////////////////////////
#if HCLK_OPERATION
ClockConfig(SD_HCLK, 1);// Divisor 1 = Base clk /2 ,Divisor 2 = Base clk /4, Divisor 4 = Base clk /8 ...
#else
rLOCKCON1=0x800;
rCLKSRC|=(1<<6); // EPLL Output
SetEPLL(42, 1, 1);//100MHz
rEPLLCON &= ~(1<<24); // EPLL ON
rCLKDIV1 = (rCLKDIV1 & ~(0x3<<6)) | (0x0<<6);
rMISCCR = rMISCCR & ~(0x7<<8) | (1<<8);
rGPHCON = rGPHCON & ~(0x3<<28) | (1<<29);
ClockConfig(SD_EPLL, 1);// Divisor 1 = Base clk /2 ,Divisor 2 = Base clk /4, Divisor 4 = Base clk /8 ...
#endif
///////////////////////////////////////////////////////////////////////
if(ThisIsMmc)
{
if(!ReadExtCSD())
printf("\nFail to read Ext CSD");
}
while (!SetDataTransferWidth());
while (!IsCardInProgrammingState());
printf("\nSet a One Block size\n");
while(!IssueCommand(16, 512, 0));//Set the One Block size
rHM_NORINTSTS = 0xffff;
return 1;
}
int ReadExtCSD(void)
{
U32 uSfr;
U32 S_CMD_SET=0;
int i;
Rx_buffer_HSMMC = (U32 *)SDI_Rx_buffer_HSMMC;
for(i=0 ; i<512/4 ; i++)
*(Rx_buffer_HSMMC+i) = 0x0;
if (!IssueCommand(16, 512, 0))
return 0;
else
{
SetBlockSizeReg(7, 512);// Maximum DMA Buffer Size, Block Size
SetBlockCountReg(1); // Block Numbers to Read
SetArgumentReg(0); // Card Address to Read
SetTransferModeReg(0, 1, 0, 0, 0);
if(!IssueCommand(8, 0, 0)) // cmd8
return 0;
else
{
WaitForBufferReadReady();
ClearBufferReadReadyStatus();
for(i=1; i<129; i++)
{
uSfr = rHM_BDATA;
if (i==127)
S_CMD_SET = (uSfr & 0xff);
}
WaitForTransferComplete();
ClearTransferCompleteStatus();
if(S_CMD_SET & (1<<3))
printf("\n========Secure MMC 2.0========\n");
else if(S_CMD_SET & (1<<2))
printf("\n========Content Protection SecureMMC Card detect========\n");
else if(S_CMD_SET & (1<<1))
printf("\n========Secure MMC Card detect========\n");
else if(S_CMD_SET & (1<<0))
printf("\n========Standard MMC Card detect========\n");
return 1;
}
}
}
void HS_MMC_WriteTest(void)
{
U32 i, j, StartAddr, OneBlockSize, Offset, Testmode;
U32 TotalWriteByte, WriteBlockCnt =0;
U32 transtime=0;
U32 uTxBufAddr = SDI_Tx_buffer_HSMMC;
U32 uCompareBufAddr = SDI_Compare_buffer_HSMMC;
wt_cnt_HSMMC=0;
BlockNum_HSMMC = 0;
wt_cnt_HSMMC = 0;
WriteBlockCnt_INT = 0;
HS_DMA_END = 0;
printf("\nSD/MMC block write test\n");
printf("\n0:Polling write 1:Interrupt write 2:DMA write");
printf("\nSelect the test mode : ");
Testmode=GetIntNum();
printf("\nInput Write Start block number : ");
StartAddr = GetIntNum();
printf("Input Write Data Offset : ");
Offset = GetIntNum();
while((BlockNum_HSMMC == 0) || (BlockNum_HSMMC > 65535))
{
printf("Input number of Block [1~65535] : ");
BlockNum_HSMMC = GetIntNum();
}
if(SectorMode == 1)
{
StartAddr = StartAddr;
printf("\nSector Mode Addressing");
}
else
{
StartAddr = StartAddr * 512;
printf("\nByte Mode Addressing");
}
OneBlockSize = Card_OneBlockSize_ver1;
Tx_buffer_HSMMC = (U32 *)SDI_Tx_buffer_HSMMC;
for(i=0 ; i<(OneBlockSize*BlockNum_HSMMC)/4 ; i++)
{
*(Tx_buffer_HSMMC+i) = (i+Offset);
}
switch(Testmode)
{
case POL_Ver1:
printf("\nPolling mode data write\n");
SetBlockSizeReg(7, 512); // Maximum DMA Buffer Size, Block Size
SetBlockCountReg(BlockNum_HSMMC); // Block Numbers to Write
SetArgumentReg(StartAddr); // Card Address to Write
if(BlockNum_HSMMC == 1)//single block
{
SetTransferModeReg(0, 0, 1, 1, 0);
SetCommandReg(24, 0);
}
else//multi block
{
SetTransferModeReg(1, 0, 1, 1, 0);
SetCommandReg(25, 0);
}
if (!WaitForCommandComplete())
{
printf("\nCommand is NOT completed\n");
}
ClearCommandCompleteStatus();
for(j=0; j<BlockNum_HSMMC; j++)
{
if (!WaitForBufferWriteReady())
printf("WriteBuffer NOT Ready\n");
else
ClearBufferWriteReadyStatus();
for(i=0; i<512/4; i++)//512 byte should be writed.
{
rHM_BDATA = *Tx_buffer_HSMMC++;
wt_cnt_HSMMC++;
}
WriteBlockCnt ++;
}
TotalWriteByte = wt_cnt_HSMMC *4;
printf("\nWrite count=%dByte\n",TotalWriteByte);
if(!WaitForTransferComplete())
{
printf(("Transfer is NOT Complete\n"));
}
ClearTransferCompleteStatus();
break;
case INT_Ver1:
printf("Interrupt mode data write\n");
pISR_SDI_1=(unsigned)HS_WRITE_INT;
SetBlockSizeReg(7, 512); // Maximum DMA Buffer Size, Block Size
SetBlockCountReg(BlockNum_HSMMC); // Block Numbers to Write
SetArgumentReg(StartAddr); // Card Address to Write
StartStopwatch();
if(BlockNum_HSMMC == 1)//single block
{
SetTransferModeReg(0, 0, 1, 1, 0);
SetCommandReg(24, 0);
}
else//multi block
{
SetTransferModeReg(1, 0, 1, 1, 0);
SetCommandReg(25, 0);
}
if (!WaitForCommandComplete())
{
printf("\nCommand is NOT completed\n");
}
ClearCommandCompleteStatus();
rINTMSK &= ~(BIT_SDI1);
rHM_NORINTSIGEN = rHM_NORINTSIGEN & ~(0xffff) | BUFFER_WRITEREADY_SIG_INT_EN;
while(!WRITEINT_DONE);
if(!WaitForTransferComplete())
{
printf(("Transfer is NOT Complete\n"));
}
ClearTransferCompleteStatus();
rHM_NORINTSTS |= (1<<4);
transtime = EndStopwatch();
CalculationBPS_HSMMC(transtime);
ClearPending(BIT_TIMER0);
break;
case DMA_Ver1:
#if BUFFER_BOUNDARY
pISR_SDI_1 = (unsigned)HS_DMA_INT;
rINTMSK &= ~(BIT_SDI1);
rHM_NORINTSTSEN |= (DMA_STS_INT_EN |TRANSFERCOMPLETE_STS_INT_EN);
rHM_NORINTSIGEN = rHM_NORINTSIGEN & ~(0xffff) | DMA_SIG_INT_EN |TRANSFERCOMPLETE_SIG_INT_EN;
SetSystemAddressReg(SDI_Tx_buffer_HSMMC);// AHB System Address For Write
SetBlockSizeReg(0, 512); // 4K Byte Buffer Boundary, Block Size
SetBlockCountReg(BlockNum_HSMMC); // Block Numbers to Write
SetArgumentReg(StartAddr);// Card Start Block Address to Write
#else
pISR_SDI_1 = (unsigned)HS_DMA_INT;
rINTMSK &= ~(BIT_SDI1);
rHM_NORINTSTSEN = (rHM_NORINTSTSEN & ~(0xffff)) |
BUFFER_READREADY_STS_INT_EN |
BUFFER_WRITEREADY_STS_INT_EN |
TRANSFERCOMPLETE_STS_INT_EN |
COMMANDCOMPLETE_STS_INT_EN;
rHM_NORINTSIGEN = (rHM_NORINTSIGEN & ~(0xffff)) | TRANSFERCOMPLETE_SIG_INT_EN;
SetSystemAddressReg(SDI_Tx_buffer_HSMMC);// AHB System Address For Write
SetBlockSizeReg(7, 512); // Maximum DMA Buffer Size, Block Size
SetBlockCountReg(BlockNum_HSMMC); // Block Numbers to Write
SetArgumentReg(StartAddr);// Card Start Block Address to Write
#endif
StartStopwatch();
if (BlockNum_HSMMC == 1)
{
SetTransferModeReg(0, 0, 1, 1, 1);
SetCommandReg(24, 0); // CMD24: Single-Write
}
else
{
SetTransferModeReg(1, 0, 1, 1, 1);
SetCommandReg(25, 0); // CMD25: Multi-Write
}
if (!WaitForCommandComplete())
{
printf("\nCommand is NOT completed\n");
}
ClearCommandCompleteStatus();
while(!HS_DMA_END);
if(!WaitForTransferComplete())
{
printf(("Transfer is NOT Complete\n"));
}
ClearTransferCompleteStatus();
rHM_NORINTSTS |= (1<<3);
transtime = EndStopwatch();
CalculationBPS_HSMMC(transtime);
printf(("\nDMA Write End\n"));
break;
default :
break;
}
printf("\nPress Any key for Data compare\n");
Uart_getc();
DataRead_ForCompare(StartAddr);
DataCompare_HSMMC(uTxBufAddr, uCompareBufAddr, BlockNum_HSMMC * 128);
BlockNum_HSMMC = 0;
wt_cnt_HSMMC = 0;
WriteBlockCnt_INT = 0;
HS_DMA_END = 0;
BufferBoundary_INT_Cnt = 0;
CompareCnt_INT = 0;
Compare_buffer_HSMMC = 0;
}
unsigned int testNumber = 0;
volatile U32 realStartAddr=0;
void HS_MMC_Write_AgingTest(void)
{
U32 i, j, StartAddr;
U32 TotalWriteByte=0, WriteBlockCnt =0;
wt_cnt_HSMMC=0;
BlockNum_HSMMC = 0;
wt_cnt_HSMMC = 0;
WriteBlockCnt_INT = 0;
HS_DMA_END = 0;
printf("\nSD/MMC block write test\n");
BlockNum_HSMMC = 100;
testNumber =0;
printf("\nPolling mode data write\n");
for(realStartAddr=0;realStartAddr<BlockNum_HSMMC*1000;realStartAddr=realStartAddr+BlockNum_HSMMC )
{
StartAddr = realStartAddr * 512;
printf( "Count : %d/8100 ,,, %x\n", realStartAddr, testNumber );
SetBlockSizeReg(7, 512); // Maximum DMA Buffer Size, Block Size
SetBlockCountReg(BlockNum_HSMMC); // Block Numbers to Write
SetArgumentReg(StartAddr); // Card Address to Write
if(BlockNum_HSMMC == 1)//single block
{
SetTransferModeReg(0, 0, 1, 1, 0);
SetCommandReg(24, 0);
}
else//multi block
{
SetTransferModeReg(1, 0, 1, 1, 0);
SetCommandReg(25, 0);
}
if (!WaitForCommandComplete())
{
printf("\nCommand is NOT completed\n");
}
ClearCommandCompleteStatus();
if (rHM_NORINTSTS&0x8000)
printf("Command = %d, Error Stat = %x\n",(rHM_CMDREG>>8),rHM_ERRINTSTS);
for(j=0; j<BlockNum_HSMMC; j++)
{
if (!WaitForBufferWriteReady())
printf("WriteBuffer NOT Ready\n");
else
ClearBufferWriteReadyStatus();
for(i=0; i<512/4; i++)//512 byte should be writed.
{
rHM_BDATA = testNumber++;
wt_cnt_HSMMC++;
}
WriteBlockCnt ++;
}
TotalWriteByte = wt_cnt_HSMMC *4;
printf("\nWrite count=%dByte\n",TotalWriteByte);
if(!WaitForTransferComplete())
{
printf(("Transfer is NOT Complete\n"));
}
ClearTransferCompleteStatus();
while (!IsCardInProgrammingState());
}
}
void HS_MMC_ReadTest(void)
{
U32 i, j, StartAddr, OneBlockSize, Testmode, Addr_temp;
U32 TotalReadByte, WriteBlockCnt=0;
U32 transtime;
rd_cnt_HSMMC=0;
HS_DMA_END = 0;
BlockNum_HSMMC = 0;
rd_cnt_HSMMC = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -