📄 hs1_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 "hs1_mmc.h"
#define POL_Ver1 0
#define INT_Ver1 1
#define DMA_Ver1 2
#define SDI_Tx_buffer_HSMMC_CH1 (_NONCACHE_STARTADDRESS)
#define SDI_Rx_buffer_HSMMC_CH1 (_NONCACHE_STARTADDRESS+(0x01000000))
#define SDI_Compare_buffer_HSMMC_CH1 (_NONCACHE_STARTADDRESS+(0x02000000))
#define Card_OneBlockSize_ver1 512
// Global variables
unsigned int *Tx_buffer_HSMMC_ch1;
unsigned int *Rx_buffer_HSMMC_ch1;
unsigned int *Compare_buffer_HSMMC_ch1;
volatile unsigned int rd_cnt_HSMMC_ch1;
volatile unsigned int wt_cnt_HSMMC_ch1;
volatile unsigned int BlockNum_HSMMC_ch1=0;
volatile unsigned int WriteBlockCnt_INT_ch1=0;
volatile unsigned int ReadBlockCnt_INT_ch1=0;
volatile unsigned int WRITEINT_DONE_ch1=0;
volatile unsigned int READINT_DONE_ch1=0;
volatile unsigned int COMPARE_INT_DONE_ch1=0;
volatile unsigned int CompareCnt_INT_ch1=0;
volatile unsigned int BufferBoundary_INT_Cnt_ch1=0;
volatile unsigned int HS_DMA_END_ch1 = 0;
volatile unsigned int HS_ADMA_END_ch1 = 0;
volatile unsigned int HS_CARD_DETECT_ch1 = 0;
volatile unsigned int HS_DESCRIPTOR_INT_ch1 = 0;
volatile int OCRcheck_ch1=0;
volatile int ThisIsMmc_ch1=0;
volatile int m_uRca_ch1=0;
volatile int m_ucMMCSpecVer_ch1 = 0;
volatile int SDSpecVer_ch1=0;
volatile int CE_ATA_ch1=0;
volatile int SectorMode_ch1 =0;
volatile unsigned int CCS_END_ch1 = 0;
volatile unsigned int CEATA_ISR_ch1 = 0;
volatile unsigned int ISR_CCS_INT=0;
volatile unsigned int TotalCardBlock_number_ch1 =0;
extern unsigned int ARMCLK, HCLK, PCLK;
#define CEATA_DMA_ch1 0
//////////////////////////////////////////////////////////////////////////
#define NEW_SD_CARD_ch1 1
#define BUFFER_BOUNDARY_ch1 0
#define HCLK_OPERATION_ch1 1
//////////////////////////////////////////////////////////////////////////
void * func_HSMMC1_test[][2]=
{
(void *)MoviNand_BootWrite_CH1_Auto, "MoviNand Boot Write program Auto ",
(void *)MoviNand_BootWrite_CH1_Manual, "MoviNand Boot Write program Manual ",
(void *)HS_MMC_WriteTest_CH1, "CH1 SD/MMC Write ",
(void *)HS_MMC_Write_AgingTest_CH1, "CH1 SD/MMC Write Aging ",
(void *)HS_MMC_ReadTest_CH1, "CH1 SD/MMC Read ",
(void *)HS_MMC_EraseBlock_CH1, "CH1 SD/MMC Block Erase ",
(void *)HS_MMC_ADMATest_CH1, "CH1 SD/MMC ADMA Test ",
(void *)HS_MMC_ADMA_WriteTest_CH1, "CH1 SD/MMC ADMA Write Test ",
(void *)HS_MMC_ADMA_ReadTest_CH1, "CH1 SD/MMC ADMA Read Test ",
0,0
};
void * func_CEATA_test_ch1[][2]=
{
(void *)CE_ATA_WriteTest_CH1, "CE ATA Write ",
(void *)CE_ATA_ReadTest_CH1, "CE ATA Read ",
0,0
};
void Test_HS_MMC_CH1(void)
{
int i;
HS_MMC_SETGPIO_CH1();
//HS_MMC_CardDetect_CH1();
HS_MMC_Reset_CH1();
if(!HS_MMC_init_CH1())
{
printf("\nCard initial fail\n");
}
while(1)
{
i=0;
printf("\n\n");
while(1)
{ //display menu
printf("%2d:%s",i,func_HSMMC1_test[i][1]);
i++;
if((int)(func_HSMMC1_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_HSMMC1_test)-1)/8)) ) // select and execute...
( (void (*)(void)) (func_HSMMC1_test[i][0]) )();
}
}
void Test_CE_ATA_CH1(void)
{
int i;
CE_ATAInit_CH1();
while(1)
{
i=0;
printf("\n\n");
while(1)
{ //display menu
printf("%2d:%s",i,func_CEATA_test_ch1[i][1]);
i++;
if((int)(func_CEATA_test_ch1[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_ch1)-1)/8)) ) // select and execute...
( (void (*)(void)) (func_CEATA_test_ch1[i][0]) )();
}
}
int HS_MMC_init_CH1(void)
{
int uArg;
ClockOnOff_CH1(0);
rSCLKCON |=(1<<13);
SetClock_CH1(SD_HCLK_CH1, 0x40);
rHM1_TIMEOUTCON = 0xe;
HostCtrlSpeedMode_CH1(NORMAL_CH1);
InterruptEnable_CH1(0xff, 0xff);
printf("rHM_NORINTSTS = %x\n",rHM1_NORINTSTS);
IssueCommand_CH1(0,0x00,0);//Idle State
IssueCommand_CH1(0,0x00,0);//Idle State
IssueCommand_CH1(0,0x00,0);//Idle State
printf("\nEnter to the Idle State\n");
/*
uArg = (0x1<<8)|(0xaa<<0); //This Line for HC SD card.
IssueCommand_CH1(8,uArg,0);
*/
OCRcheck_ch1 =1;
if(!(SDSpecVer_ch1 == 2))
{
if(SetMMCOCR_CH1())
{
ThisIsMmc_ch1=1;
printf("MMC card is detected\n");
}
else if(SetSDOCR_CH1())
{
ThisIsMmc_ch1=0;
printf("SD card is detected\n");
}
else
return 0;
}
else
{
if(SetSDOCR_CH1())
{
ThisIsMmc_ch1=0;
printf("SD card is detected\n");
}
}
OCRcheck_ch1 =0;
// Check the attached card and place the card in the IDENT state rHM_RSPREG0
IssueCommand_CH1(2,0,0);
printf("\n - Product Name : %c%c%c%c%c%c\n",((rHM1_RSPREG2>>24)&0xFF),((rHM1_RSPREG2>>16)&0xFF),((rHM1_RSPREG2>>8)&0xFF),(rHM1_RSPREG2&0xFF),((rHM1_RSPREG1>>24)&0xFF),((rHM1_RSPREG1>>16)&0xFF));
// Send RCA(Relative Card Address). It places the card in the STBY state
m_uRca_ch1 = (ThisIsMmc_ch1) ? 0x0001 : 0x0000;
IssueCommand_CH1(3,m_uRca_ch1,0);
if(!ThisIsMmc_ch1)
{
m_uRca_ch1 = (rHM1_RSPREG0>>16)&0xFFFF;
printf("=> RCA=0x%x\n", m_uRca_ch1);
}
printf("\nEnter to the Stand-by State\n");
IssueCommand_CH1(9, m_uRca_ch1, 0);//Send CSD
DisplayCardInformation_CH1();
IssueCommand_CH1(7, m_uRca_ch1, 0);
//printf("\nEnter to the Transfer State\n");
//////////////////////// Operating Clock setting ////////////////////////////
#if 0
ClockConfig_CH1(SD_HCLK_CH1, 8);// Divisor 1 = Base clk /2 ,Divisor 2 = Base clk /4, Divisor 4 = Base clk /8 ...
#else
rLOCKCON1=0x800;
rCLKSRC|=(1<<6); // EPLL Output
SetEPLL(33, 1, 2);//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_CH1(SD_EPLL_CH1, 8);// Divisor 1 = Base clk /2 ,Divisor 2 = Base clk /4, Divisor 4 = Base clk /8 ...
#endif
///////////////////////////////////////////////////////////////////////
while (!IsCardInProgrammingState_CH1());
if(ThisIsMmc_ch1)
{
if(!ReadExtCSD_CH1())
printf("\nFail to read Ext CSD");
}
while (!SetDataTransferWidth_CH1());
while (!IsCardInProgrammingState_CH1());
printf("\nSet a One Block size\n");
while(!IssueCommand_CH1(16, 512, 0));//Set the One Block size
rHM1_NORINTSTS = 0xffff;
CE_ATA_ch1=0;
if(CE_ATA_ch1 == 1)
{
printf("\n\n------------CE ATA Device detect------------");
Test_CE_ATA_CH1();
}
return 1;
}
int ReadExtCSD_CH1(void)
{
U32 uSfr;
U32 S_CMD_SET, uHsTiming;
int i;
Rx_buffer_HSMMC_ch1 = (U32 *)SDI_Rx_buffer_HSMMC_CH1;
for(i=0 ; i<512/4 ; i++)
*(Rx_buffer_HSMMC_ch1+i) = 0x0;
IssueCommand_CH1(16, 512, 0);
rHM1_BLKSIZE = (7<<12)|(512); // Maximum DMA Buffer Size, Block Size
rHM1_BLKCNT = 1;
rHM1_TRNMOD = (0<<5)|(1<<4)|(0<<2)|(0<<1)|(0<<0);
rHM1_CMDREG = (8<<8)|(1<<5)|(1<<4)|(1<<3)|(2<<0);
WaitForBufferReadReady_CH1();
ClearBufferReadReadyStatus_CH1();
for(i=0; i<128; i++)
{
uSfr = rHM1_BDATA;
if (i==126)
S_CMD_SET = (uSfr & 0xff);
if(i==53)
{
if(uSfr != 0)
{
TotalCardBlock_number_ch1 = uSfr;
printf("TotalCardBlock_number_ch1 = %d",TotalCardBlock_number_ch1);
}
}
if (i==46)
uHsTiming = ((uSfr>>8) & 0xff);
}
printf("\nS_CMD_SET=%x",S_CMD_SET);
WaitForTransferComplete_CH1();
ClearTransferCompleteStatus_CH1();
if(S_CMD_SET & (1<<4))
CE_ATA_ch1 = 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_CH1(void)
{
U32 i, j, StartAddr, OneBlockSize, Offset, Testmode;
U32 TotalWriteByte, WriteBlockCnt =0;
U32 transtime=0;
U32 uTxBufAddr = SDI_Tx_buffer_HSMMC_CH1;
U32 uCompareBufAddr = SDI_Compare_buffer_HSMMC_CH1;
wt_cnt_HSMMC_ch1=0;
BlockNum_HSMMC_ch1 = 0;
wt_cnt_HSMMC_ch1 = 0;
WriteBlockCnt_INT_ch1 = 0;
HS_DMA_END_ch1 = 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_ch1 == 0) || (BlockNum_HSMMC_ch1 > 65535))
{
printf("Input number of Block [1~65535] : ");
BlockNum_HSMMC_ch1 = GetIntNum();
}
if(SectorMode_ch1 == 1)
{
StartAddr = StartAddr;
printf("\nSector Mode Addressing");
}
else
{
StartAddr = StartAddr * 512;
printf("\nByte Mode Addressing");
}
OneBlockSize = Card_OneBlockSize_ver1;
Tx_buffer_HSMMC_ch1 = (U32 *)SDI_Tx_buffer_HSMMC_CH1;
for(i=0 ; i<(OneBlockSize*BlockNum_HSMMC_ch1)/4 ; i++)
{
*(Tx_buffer_HSMMC_ch1+i) = (i+Offset);
}
switch(Testmode)
{
case POL_Ver1:
printf("\nPolling mode data write\n");
SetBlockSizeReg_CH1(7, 512); // Maximum DMA Buffer Size, Block Size
SetBlockCountReg_CH1(BlockNum_HSMMC_ch1); // Block Numbers to Write
SetArgumentReg_CH1(StartAddr); // Card Address to Write
if(BlockNum_HSMMC_ch1 == 1)//single block
{
SetTransferModeReg_CH1(0, 0, 1, 1, 0);
SetCommandReg_CH1(24, 0);
}
else//multi block
{
SetTransferModeReg_CH1(1, 0, 1, 1, 0);
SetCommandReg_CH1(25, 0);
}
if (!WaitForCommandComplete_CH1())
{
printf("\nCommand is NOT completed\n");
}
ClearCommandCompleteStatus_CH1();
for(j=0; j<BlockNum_HSMMC_ch1; j++)
{
if (!WaitForBufferWriteReady_CH1())
printf("WriteBuffer NOT Ready\n");
else
ClearBufferWriteReadyStatus_CH1();
for(i=0; i<512/4; i++)//512 byte should be writed.
{
rHM1_BDATA = *Tx_buffer_HSMMC_ch1++;
wt_cnt_HSMMC_ch1++;
}
WriteBlockCnt ++;
}
TotalWriteByte = wt_cnt_HSMMC_ch1 *4;
printf("\nWrite count=%dByte\n",TotalWriteByte);
if(!WaitForTransferComplete_CH1())
{
printf(("Transfer is NOT Complete\n"));
}
ClearTransferCompleteStatus_CH1();
break;
case INT_Ver1:
printf("Interrupt mode data write\n");
pISR_SDI_1=(unsigned)HS_WRITE_INT_CH1;
SetBlockSizeReg_CH1(7, 512); // Maximum DMA Buffer Size, Block Size
SetBlockCountReg_CH1(BlockNum_HSMMC_ch1); // Block Numbers to Write
SetArgumentReg_CH1(StartAddr); // Card Address to Write
StartStopwatch();
if(BlockNum_HSMMC_ch1 == 1)//single block
{
SetTransferModeReg_CH1(0, 0, 1, 1, 0);
SetCommandReg_CH1(24, 0);
}
else//multi block
{
SetTransferModeReg_CH1(1, 0, 1, 1, 0);
SetCommandReg_CH1(25, 0);
}
if (!WaitForCommandComplete_CH1())
{
printf("\nCommand is NOT completed\n");
}
ClearCommandCompleteStatus_CH1();
rINTMSK &= ~(BIT_SDI1);
rHM1_NORINTSIGEN = rHM1_NORINTSIGEN & ~(0xffff) | BUFFER_WRITEREADY_SIG_INT_EN_CH1;
while(!WRITEINT_DONE_ch1);
if(!WaitForTransferComplete_CH1())
{
printf(("Transfer is NOT Complete\n"));
}
ClearTransferCompleteStatus_CH1();
rHM1_NORINTSTS |= (1<<4);
transtime = EndStopwatch();
CalculationBPS_HSMMC_CH1(transtime);
ClearPending(BIT_TIMER0);
break;
case DMA_Ver1:
#if BUFFER_BOUNDARY_ch1
pISR_SDI_1 = (unsigned)HS_DMA_INT_CH1;
rINTMSK &= ~(BIT_SDI1);
rHM1_NORINTSTSEN |= (DMA_STS_INT_EN_CH1 |TRANSFERCOMPLETE_STS_INT_EN_CH1);
rHM1_NORINTSIGEN = rHM1_NORINTSIGEN & ~(0xffff) | DMA_SIG_INT_EN_CH1 |TRANSFERCOMPLETE_SIG_INT_EN_CH1;
SetSystemAddressReg_CH1(SDI_Tx_buffer_HSMMC_CH1);// AHB System Address For Write
SetBlockSizeReg_CH1(0, 512); // 4K Byte Buffer Boundary, Block Size
SetBlockCountReg_CH1(BlockNum_HSMMC_ch1); // Block Numbers to Write
SetArgumentReg_CH1(StartAddr);// Card Start Block Address to Write
#else
pISR_SDI_1 = (unsigned)HS_DMA_INT_CH1;
rINTMSK &= ~(BIT_SDI1);
rHM1_NORINTSTSEN = (rHM1_NORINTSTSEN & ~(0xffff)) |
BUFFER_READREADY_STS_INT_EN_CH1 |
BUFFER_WRITEREADY_STS_INT_EN_CH1 |
TRANSFERCOMPLETE_STS_INT_EN_CH1 |
COMMANDCOMPLETE_STS_INT_EN_CH1;
rHM1_NORINTSIGEN = (rHM1_NORINTSIGEN & ~(0xffff)) | TRANSFERCOMPLETE_SIG_INT_EN_CH1;
SetSystemAddressReg_CH1(SDI_Tx_buffer_HSMMC_CH1);// AHB System Address For Write
SetBlockSizeReg_CH1(7, 512); // Maximum DMA Buffer Size, Block Size
SetBlockCountReg_CH1(BlockNum_HSMMC_ch1); // Block Numbers to Write
SetArgumentReg_CH1(StartAddr);// Card Start Block Address to Write
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -