📄 hs0_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 "2450addr.h"
#include "system.h"
#include "pll.h"
#include "console.h"
#include "hs0_mmc.h"
#define POL_Ver1 0
#define INT_Ver1 1
#define DMA_Ver1 2
#define SDI_Tx_buffer_HSMMC_CH0 (_NONCACHE_STARTADDRESS)
#define SDI_Rx_buffer_HSMMC_CH0 (_NONCACHE_STARTADDRESS+(0x01000000))
#define SDI_Compare_buffer_HSMMC_CH0 (_NONCACHE_STARTADDRESS+(0x02000000))
#define Card_OneBlockSize_ver1 512
// Global variables
unsigned int *Tx_buffer_HSMMC_ch0;
unsigned int *Rx_buffer_HSMMC_ch0;
unsigned int *Compare_buffer_HSMMC_ch0;
volatile unsigned int rd_cnt_HSMMC_ch0;
volatile unsigned int wt_cnt_HSMMC_ch0;
volatile unsigned int BlockNum_HSMMC_ch0=0;
volatile unsigned int WriteBlockCnt_INT_ch0=0;
volatile unsigned int ReadBlockCnt_INT_ch0=0;
volatile unsigned int WRITEINT_DONE_ch0=0;
volatile unsigned int READINT_DONE_ch0=0;
volatile unsigned int COMPARE_INT_DONE_ch0=0;
volatile unsigned int CompareCnt_INT_ch0=0;
volatile unsigned int BufferBoundary_INT_Cnt_ch0=0;
volatile unsigned int HS_DMA_END_ch0 = 0;
volatile unsigned int HS_ADMA_END_ch0 = 0;
volatile unsigned int HS_CARD_DETECT_ch0 = 0;
volatile unsigned int HS_DESCRIPTOR_INT_ch0 = 0;
volatile int OCRcheck_ch0=0;
volatile int ThisIsMmc_ch0=0;
volatile int m_uRca_ch0=0;
volatile int m_ucMMCSpecVer_ch0 = 0;
volatile int SDSpecVer_ch0=0;
volatile int CE_ATA_ch0=0;
volatile int SectorMode_ch0 =0;
volatile unsigned int CCS_END_ch0 = 0;
volatile unsigned int CEATA_ISR_ch0 = 0;
volatile unsigned int TotalCardBlock_number_ch0 =0;
extern unsigned int ARMCLK, HCLK, PCLK;
#define CEATA_DMA_ch0 0
//////////////////////////////////////////////////////////////////////////
#define NEW_SD_CARD_ch0 1
#define BUFFER_BOUNDARY_ch0 1
#define HCLK_OPERATION_ch0 1
//////////////////////////////////////////////////////////////////////////
void * func_HSMMC0_test[][2]=
{
(void *)HS_MMC_WriteTest_CH0, "CH0 SD/MMC Write ",
(void *)HS_MMC_Write_AgingTest_CH0, "CH0 SD/MMC Write Aging",
(void *)HS_MMC_ReadTest_CH0, "CH0 SD/MMC Read ",
(void *)HS_MMC_EraseBlock_CH0, "CH0 SD/MMC Block Erase",
(void *)HS_MMC_ADMATest_CH0, "CH0 SD/MMC ADMA Test ",
(void *)HS_MMC_ADMA_WriteTest_CH0, "CH0 SD/MMC ADMA Write Test ",
(void *)HS_MMC_ADMA_ReadTest_CH0, "CH0 SD/MMC ADMA Read Test ",
0,0
};
void * func_CEATA_test_ch0[][2]=
{
(void *)CE_ATA_WriteTest_CH0, "CE ATA Write ",
(void *)CE_ATA_ReadTest_CH0, "CE ATA Read ",
0,0
};
void Test_HS_MMC_CH0(void)
{
int i;
HS_MMC_SETGPIO_CH0();
//HS_MMC_CardDetect_CH0();
HS_MMC_Reset_CH0();
if(!HS_MMC_init_CH0())
{
printf("\nCard initial fail\n");
}
while(1)
{
i=0;
printf("\n\n");
while(1)
{ //display menu
printf("%2d:%s",i,func_HSMMC0_test[i][1]);
i++;
if((int)(func_HSMMC0_test[i][0])==0)
{
printf("\n");
break;
}
if((i%1)==0)
printf("\n");
}
printf("\nSelect (\"-1\" to exit) : ");
i = GetIntNum();
if(i==-1)
break; // return.
if( (i<((sizeof(func_HSMMC0_test)-1)/8)) ) // select and execute...
( (void (*)(void)) (func_HSMMC0_test[i][0]) )();
}
}
void Test_CE_ATA_CH0(void)
{
int i;
CE_ATAInit_CH0();
while(1)
{
i=0;
printf("\n\n");
while(1)
{ //display menu
printf("%2d:%s",i,func_CEATA_test_ch0[i][1]);
i++;
if((int)(func_CEATA_test_ch0[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_CEATA_test_ch0)-1)/8)) ) // select and execute...
( (void (*)(void)) (func_CEATA_test_ch0[i][0]) )();
}
}
int HS_MMC_init_CH0(void)
{
int uArg;
ClockOnOff_CH0(0);
rSCLKCON |=(1<<13);
SetClock_CH0(SD_HCLK_CH0, 0x20);
rHM0_TIMEOUTCON = 0xe;
HostCtrlSpeedMode_CH0(NORMAL_CH0);
InterruptEnable_CH0(0xff, 0xff);
printf("rHM_NORINTSTS = %x\n",rHM0_NORINTSTS);
IssueCommand_CH0(0,0x00,0);//Idle State
printf("\nEnter to the Idle State\n");
uArg = (0x1<<8)|(0xaa<<0); //This Line for HC SD card.
IssueCommand_CH0(8,uArg,0);
OCRcheck_ch0 =1;
if(!(SDSpecVer_ch0 == 2))
{
if(SetMMCOCR_CH0())
{
ThisIsMmc_ch0=1;
printf("MMC card is detected\n");
}
else if(SetSDOCR_CH0())
{
ThisIsMmc_ch0=0;
printf("SD card is detected\n");
}
else
return 0;
}
else
{
if(SetSDOCR_CH0())
{
ThisIsMmc_ch0=0;
printf("SD card is detected\n");
}
}
OCRcheck_ch0 =0;
// Check the attached card and place the card in the IDENT state rHM_RSPREG0
IssueCommand_CH0(2,0,0);
printf("\n - Product Name : %c%c%c%c%c%c\n",((rHM0_RSPREG2>>24)&0xFF),((rHM0_RSPREG2>>16)&0xFF),((rHM0_RSPREG2>>8)&0xFF),(rHM0_RSPREG2&0xFF),((rHM0_RSPREG1>>24)&0xFF),((rHM0_RSPREG1>>16)&0xFF));
// Send RCA(Relative Card Address). It places the card in the STBY state
m_uRca_ch0 = (ThisIsMmc_ch0) ? 0x0001 : 0x0000;
IssueCommand_CH0(3,m_uRca_ch0,0);
if(!ThisIsMmc_ch0)
{
m_uRca_ch0 = (rHM0_RSPREG0>>16)&0xFFFF;
printf("=> RCA=0x%x\n", m_uRca_ch0);
}
printf("\nEnter to the Stand-by State\n");
IssueCommand_CH0(9, m_uRca_ch0, 0);//Send CSD
DisplayCardInformation_CH0();
IssueCommand_CH0(7, m_uRca_ch0, 0);
//printf("\nEnter to the Transfer State\n");
//////////////////////// Operating Clock setting ////////////////////////////
#if 0
ClockConfig_CH0(SD_HCLK_CH0, 2);// Divisor 1 = Base clk /2 ,Divisor 2 = Base clk /4, Divisor 4 = Base clk /8 ...
#else
rLOCKCON1=0x800;
rCLKSRC|=(1<<6); // EPLL Output
//rCLKSRC &= ~(1<<6); // EPLL Output disable
SetEPLL(33, 1, 2);//100MHz
rEPLLCON &= ~(1<<24); // EPLL ON
//rEPLLCON |= (1<<24); // EPLL OFF
rCLKDIV1 = (rCLKDIV1 & ~(0x3<<6)) | (0x0<<6);
rMISCCR = rMISCCR & ~(0x7<<8) | (1<<8);
rGPHCON = rGPHCON & ~(0x3<<28) | (1<<29);
ClockConfig_CH0(SD_EPLL_CH0, 8);// Divisor 1 = Base clk /2 ,Divisor 2 = Base clk /4, Divisor 4 = Base clk /8 ...
#endif
///////////////////////////////////////////////////////////////////////
if(ThisIsMmc_ch0)
{
if(!ReadExtCSD_CH0())
printf("\nFail to read Ext CSD");
}
while (!SetDataTransferWidth_CH0());
while (!IsCardInProgrammingState_CH0());
printf("\nSet a One Block size\n");
while(!IssueCommand_CH0(16, 512, 0));//Set the One Block size
rHM0_NORINTSTS = 0xffff;
CE_ATA_ch0=0;
if(CE_ATA_ch0 == 1)
{
printf("\n\n------------CE ATA Device detect------------");
Test_CE_ATA_CH0();
}
return 1;
}
int ReadExtCSD_CH0(void)
{
U32 uSfr;
U32 S_CMD_SET, uHsTiming;
int i;
Rx_buffer_HSMMC_ch0 = (U32 *)SDI_Rx_buffer_HSMMC_CH0;
for(i=0 ; i<512/4 ; i++)
*(Rx_buffer_HSMMC_ch0+i) = 0x0;
IssueCommand_CH0(16, 512, 0);
rHM0_BLKSIZE = (7<<12)|(512); // Maximum DMA Buffer Size, Block Size
rHM0_BLKCNT = 1;
rHM0_TRNMOD = (0<<5)|(1<<4)|(0<<2)|(0<<1)|(0<<0);
rHM0_CMDREG = (8<<8)|(1<<5)|(1<<4)|(1<<3)|(2<<0);
WaitForBufferReadReady_CH0();
ClearBufferReadReadyStatus_CH0();
for(i=0; i<128; i++)
{
uSfr = rHM0_BDATA;
if (i==126)
S_CMD_SET = (uSfr & 0xff);
if(i==53)
{
if(uSfr != 0)
{
TotalCardBlock_number_ch0 = uSfr;
printf("TotalCardBlock_number_ch1 = %d",TotalCardBlock_number_ch0);
}
}
if (i==46)
uHsTiming = ((uSfr>>8) & 0xff);
}
printf("\nS_CMD_SET=%x",S_CMD_SET);
WaitForTransferComplete_CH0();
ClearTransferCompleteStatus_CH0();
if(S_CMD_SET & (1<<4))
CE_ATA_ch0 = 1;
else 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_CH0(void)
{
U32 i, j, StartAddr, OneBlockSize, Offset, Testmode;
U32 TotalWriteByte, WriteBlockCnt =0;
U32 transtime=0;
U32 uTxBufAddr = SDI_Tx_buffer_HSMMC_CH0;
U32 uCompareBufAddr = SDI_Compare_buffer_HSMMC_CH0;
wt_cnt_HSMMC_ch0=0;
BlockNum_HSMMC_ch0 = 0;
wt_cnt_HSMMC_ch0 = 0;
WriteBlockCnt_INT_ch0 = 0;
HS_DMA_END_ch0 = 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_ch0 == 0) || (BlockNum_HSMMC_ch0 > 65535))
{
printf("Input number of Block [1~65535] : ");
BlockNum_HSMMC_ch0 = GetIntNum();
}
if(SectorMode_ch0 == 1)
{
StartAddr = StartAddr;
printf("\nSector Mode Addressing");
}
else
{
StartAddr = StartAddr * 512;
printf("\nByte Mode Addressing");
}
OneBlockSize = Card_OneBlockSize_ver1;
Tx_buffer_HSMMC_ch0 = (U32 *)SDI_Tx_buffer_HSMMC_CH0;
for(i=0 ; i<(OneBlockSize*BlockNum_HSMMC_ch0)/4 ; i++)
{
*(Tx_buffer_HSMMC_ch0+i) = (i+Offset);
}
switch(Testmode)
{
case POL_Ver1:
printf("\nPolling mode data write\n");
SetBlockSizeReg_CH0(7, 512); // Maximum DMA Buffer Size, Block Size
SetBlockCountReg_CH0(BlockNum_HSMMC_ch0); // Block Numbers to Write
SetArgumentReg_CH0(StartAddr); // Card Address to Write
if(BlockNum_HSMMC_ch0 == 1)//single block
{
SetTransferModeReg_CH0(0, 0, 1, 1, 0);
SetCommandReg_CH0(24, 0);
}
else//multi block
{
SetTransferModeReg_CH0(1, 0, 1, 1, 0);
SetCommandReg_CH0(25, 0);
}
if (!WaitForCommandComplete_CH0())
{
printf("\nCommand is NOT completed\n");
}
ClearCommandCompleteStatus_CH0();
for(j=0; j<BlockNum_HSMMC_ch0; j++)
{
if (!WaitForBufferWriteReady_CH0())
printf("WriteBuffer NOT Ready\n");
else
ClearBufferWriteReadyStatus_CH0();
for(i=0; i<512/4; i++)//512 byte should be writed.
{
rHM0_BDATA = *Tx_buffer_HSMMC_ch0++;
wt_cnt_HSMMC_ch0++;
}
WriteBlockCnt ++;
}
TotalWriteByte = wt_cnt_HSMMC_ch0 *4;
printf("\nWrite count=%dByte\n",TotalWriteByte);
if(!WaitForTransferComplete_CH0())
{
printf(("Transfer is NOT Complete\n"));
}
ClearTransferCompleteStatus_CH0();
break;
case INT_Ver1:
printf("Interrupt mode data write\n");
pISR_SDI_0=(unsigned)HS_WRITE_INT_CH0;
SetBlockSizeReg_CH0(7, 512); // Maximum DMA Buffer Size, Block Size
SetBlockCountReg_CH0(BlockNum_HSMMC_ch0); // Block Numbers to Write
SetArgumentReg_CH0(StartAddr); // Card Address to Write
//StartStopwatch();
if(BlockNum_HSMMC_ch0 == 1)//single block
{
SetTransferModeReg_CH0(0, 0, 1, 1, 0);
SetCommandReg_CH0(24, 0);
}
else//multi block
{
SetTransferModeReg_CH0(1, 0, 1, 1, 0);
SetCommandReg_CH0(25, 0);
}
if (!WaitForCommandComplete_CH0())
{
printf("\nCommand is NOT completed\n");
}
ClearCommandCompleteStatus_CH0();
rINTMSK &= ~(BIT_SDI0);
rHM0_NORINTSIGEN = rHM0_NORINTSIGEN & ~(0xffff) | BUFFER_WRITEREADY_SIG_INT_EN_CH0;
while(!WRITEINT_DONE_ch0);
if(!WaitForTransferComplete_CH0())
{
printf(("Transfer is NOT Complete\n"));
}
ClearTransferCompleteStatus_CH0();
rHM0_NORINTSTS |= (1<<4);
//transtime = EndStopwatch();
//CalculationBPS_HSMMC_CH0(transtime);
ClearPending(BIT_TIMER0);
break;
case DMA_Ver1:
#if BUFFER_BOUNDARY_ch0
pISR_SDI_0 = (unsigned)HS_DMA_INT_CH0;
rINTMSK &= ~(BIT_SDI0);
rHM0_NORINTSTSEN |= (DMA_STS_INT_EN_CH0 |TRANSFERCOMPLETE_STS_INT_EN_CH0);
rHM0_NORINTSIGEN = rHM0_NORINTSIGEN & ~(0xffff) | DMA_SIG_INT_EN_CH0 |TRANSFERCOMPLETE_SIG_INT_EN_CH0;
SetSystemAddressReg_CH0(SDI_Tx_buffer_HSMMC_CH0);// AHB System Address For Write
SetBlockSizeReg_CH0(0, 512); // 4K Byte Buffer Boundary, Block Size
SetBlockCountReg_CH0(BlockNum_HSMMC_ch0); // Block Numbers to Write
SetArgumentReg_CH0(StartAddr);// Card Start Block Address to Write
#else
pISR_SDI_0 = (unsigned)HS_DMA_INT_CH0;
rINTMSK &= ~(BIT_SDI0);
rHM0_NORINTSTSEN = (rHM0_NORINTSTSEN & ~(0xffff)) |
BUFFER_READREADY_STS_INT_EN_CH0 |
BUFFER_WRITEREADY_STS_INT_EN_CH0 |
TRANSFERCOMPLETE_STS_INT_EN_CH0 |
COMMANDCOMPLETE_STS_INT_EN_CH0;
rHM0_NORINTSIGEN = (rHM0_NORINTSIGEN & ~(0xffff)) | TRANSFERCOMPLETE_SIG_INT_EN_CH0;
SetSystemAddressReg_CH0(SDI_Tx_buffer_HSMMC_CH0);// AHB System Address For Write
SetBlockSizeReg_CH0(7, 512); // Maximum DMA Buffer Size, Block Size
SetBlockCountReg_CH0(BlockNum_HSMMC_ch0); // Block Numbers to Write
SetArgumentReg_CH0(StartAddr);// Card Start Block Address to Write
#endif
StartStopwatch();
if (BlockNum_HSMMC_ch0 == 1)
{
SetTransferModeReg_CH0(0, 0, 1, 1, 1);
SetCommandReg_CH0(24, 0); // CMD24: Single-Write
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -