📄 hs_mmc.c
字号:
GetSdSCR();
if (SDSpecVer==1)
{
if (WorkingFreq>25000000)
{
SetSDSpeedMode(HIGH);//Higher than 25MHz, should use high speed mode. Max 50MHz and 25MB/sec
printf("\nSet SD High speed mode OK!!\n");
}
else
{
SetSDSpeedMode(NORMAL);
printf("\nSet SD Normal speed mode OK!!\n");
}
}
else
printf("Old version SD card can not support working frequency higher than 25MHz");
}
if (WorkingFreq>25000000)// Higher than 25MHz, it is necessary to enable high speed mode of the host controller.
{
HostCtrlSpeedMode(HIGH);
}
else
{
HostCtrlSpeedMode(NORMAL);
}
ClockOnOff(0); // when change the sd clock frequency, need to stop sd clock.
SetClock(Clksrc, Divisior);
printf("clock config rHM_HOSTCTL = %x\n",rHM_HOSTCTL);
}
#else
void ClockConfig(U32 Clksrc, U32 Divisior)
{
U32 SrcFreq, WorkingFreq;
//printf("Clock Config\n");
if (Clksrc == SD_HCLK)
SrcFreq = HCLK;
else if (Clksrc == SD_EPLL)//Epll Out 48MHz
SrcFreq = 100000000;
else
Clksrc = HCLK;
WorkingFreq = SrcFreq/(Divisior*2);
printf("Card Working Frequency = %dMHz\n",WorkingFreq/(1000000));
if (ThisIsMmc)
{
if (m_ucMMCSpecVer==4)
{
if (WorkingFreq>20000000)// It is necessary to enable the high speed mode in the card before changing the clock freq to a freq higher than 20MHz.
{
SetMMCSpeedMode(HIGH);
printf("\nSet MMC High speed mode OK!!\n");
}
else
{
SetMMCSpeedMode(NORMAL);
printf("\nSet MMC Normal speed mode OK!!\n");
}
}
else // old version
printf("Old version MMC card can not support working frequency higher than 25MHz");
}
if (WorkingFreq>25000000)// Higher than 25MHz, it is necessary to enable high speed mode of the host controller.
{
HostCtrlSpeedMode(HIGH);
}
else
{
HostCtrlSpeedMode(NORMAL);
}
ClockOnOff(0); // when change the sd clock frequency, need to stop sd clock.
SetClock(Clksrc, Divisior);
printf("clock config rHM_HOSTCTL = %x\n",rHM_HOSTCTL);
}
#endif
void HS_MMC_Irq(void)
{
pISR_SDI_1 = (int)HS_CARD_DETECT_INT; // Set interrupt service routine.
rINTMSK &= ~(BIT_SDI1);
}
void HS_MMC_Reset(void)
{
rHM_SWRST = 0x3;
}
void HS_MMC_SETGPIO(void)
{
rGPLCON = rGPLCON & ~(0xfffff) | (0xaaaaa);
rGPJCON = rGPJCON & ~(0x3f<<26) | (0x2a<<26);
rGPJCON &= ~(0x3<<30) | (1<<30);
rGPJDAT |=(1<<15);
}
void SetTransferModeReg(U32 MultiBlk,U32 DataDirection, U32 AutoCmd12En,U32 BlockCntEn,U32 DmaEn)
{
rHM_TRNMOD = (rHM_TRNMOD & ~(0xffff)) | (MultiBlk<<5)|(DataDirection<<4)|(AutoCmd12En<<2)|(BlockCntEn<<1)|(DmaEn<<0);
printf("\nrHM_TRNMOD = %x\n",rHM_TRNMOD);
}
void SetArgumentReg(U16 uArg)
{
rHM_ARGUMENT = uArg;
}
void SetBlockCountReg(U16 uBlkCnt)
{
rHM_BLKCNT = uBlkCnt;
}
void SetSystemAddressReg(U32 SysAddr)
{
rHM_SYSAD = SysAddr;
}
void SetBlockSizeReg(U16 uDmaBufBoundary, U16 uBlkSize)
{
rHM_BLKSIZE = (uDmaBufBoundary<<12)|(uBlkSize);
}
void ClockOnOff(int OnOff)
{
if (OnOff == 0)
{
rHM_CLKCON &=~(0x1<<2);
/*
while (1)
{
if (!(rHM_CLKCON&(0x1<<3))) // SD_CLKSRC is Stable
break;
}
*/
}
else
{
rHM_CLKCON|=(0x1<<2);
while (1)
{
if (rHM_CLKCON&(0x1<<3)) // SD_CLKSRC is Stable
break;
}
}
}
void ClearCommandCompleteStatus(void)
{
rHM_NORINTSTS=(1<<0);
while (rHM_NORINTSTS&0x1)
{
rHM_NORINTSTS=(1<<0);
}
}
void ClearTransferCompleteStatus(void)
{
rHM_NORINTSTS |= (1<<1);
while (rHM_NORINTSTS&0x2)
{
rHM_NORINTSTS |= (1<<1);
}
}
void ClearBufferWriteReadyStatus(void)
{
rHM_NORINTSTS |= (1<<4);
while (rHM_NORINTSTS & 0x10)
rHM_NORINTSTS |= (1<<4);
}
void ClearBufferReadReadyStatus(void)
{
rHM_NORINTSTS |= (1<<5);
while (rHM_NORINTSTS & 0x20)
rHM_NORINTSTS |= (1<<5);
}
void ClearErrInterruptStatus(void)
{
while (rHM_NORINTSTS&(0x1<<15))
{
rHM_NORINTSTS =rHM_NORINTSTS;
rHM_ERRINTSTS =rHM_ERRINTSTS;
}
}
int WaitForBufferWriteReady(void)
{
U32 uLoop=0;
while (!(rHM_NORINTSTS&0x10))
{
if (uLoop%500000==0&&uLoop>0)
{
return 0;
}
uLoop++;
}
return 1;
}
int WaitForBufferReadReady(void)
{
U32 uLoop=0;
while (!(rHM_NORINTSTS&0x20))
{
if (uLoop%500000==0&&uLoop>0)
{
return 0;
}
uLoop++;
}
return 1;
}
int WaitForCommandComplete(void)
{
U32 Loop=0;
while (!(rHM_NORINTSTS&0x1))
{
if (Loop%500000==0&&Loop>0)
{
return 0;
}
Loop++;
}
return 1;
}
int WaitForTransferComplete(void)
{
U32 Loop=0;
/*
while (!(rHM_NORINTSTS&0x2))
{
if (Loop%500000==0&&Loop>0)
{
return 0;
}
Loop++;
}
*/
while (!(rHM_NORINTSTS&0x2))
return 1;
}
void InterruptEnable(U16 NormalIntEn, U16 ErrorIntEn)
{
ClearErrInterruptStatus();
rHM_NORINTSTSEN = NormalIntEn;
rHM_ERRINTSTSEN = ErrorIntEn;
}
#if BUFFER_BOUNDARY
void __irq HS_DMA_INT(void)
{
U32 i;
ClearPending(BIT_SDI1);
rINTMSK |= (BIT_SDI1);
BufferBoundary_INT_Cnt++;
//printf("\nISR rHM_NORINTSTS = %x",rHM_NORINTSTS);
if(rHM_NORINTSTS & (1<<1))
{
//printf("\nTransfer Complete\n");
HS_DMA_END=1;
rINTMSK |= (BIT_SDI1);
}
else if(rHM_NORINTSTS & (1<<3))
{
rHM_NORINTSTS |= (1<<3);
i = BufferBoundary_INT_Cnt * 0x1000;// 4K Byte boundary
SetSystemAddressReg(SDI_Tx_buffer_HSMMC + i);
rINTMSK &= ~(BIT_SDI1);
}
}
#else
void __irq HS_DMA_INT(void)
{
ClearPending(BIT_SDI1);
rINTMSK |= (BIT_SDI1);
printf("\nISR rHM_NORINTSTS = %x",rHM_NORINTSTS);
if(rHM_NORINTSTS & (1<<1))
{
//printf("\nTransfer Complete\n");
HS_DMA_END=1;
rHM_NORINTSTS |= (1<<1);
}
}
#endif
void __irq HS_WRITE_INT(void)
{
int i;
//printf("\nWrite ISR");
ClearPending(BIT_SDI1);
rINTMSK |= (BIT_SDI1);
/*
for(j=0; j<BlockNum_HSMMC; j++)
{
if (!WaitForBufferWriteReady())
printf("WriteBuffer NOT Ready\n");
else
ClearBufferWriteReadyStatus();
for(i=0; i<512/4; i++)
{
rHM_BDATA = *Tx_buffer_HSMMC++;
wt_cnt_HSMMC++;
}
WriteBlockCnt ++;
printf("\nWrite block count = %d", WriteBlockCnt);
}
*/
if (!WaitForBufferWriteReady())
printf("WriteBuffer NOT Ready\n");
else
ClearBufferWriteReadyStatus();
for(i=0; i<512/4; i++)
{
rHM_BDATA = *Tx_buffer_HSMMC++;
wt_cnt_HSMMC++;
}
WriteBlockCnt_INT ++;
//printf("\nWrite block count = %d", WriteBlockCnt_INT);
rINTMSK &= ~(BIT_SDI1);
if(BlockNum_HSMMC == WriteBlockCnt_INT)
{
WRITEINT_DONE = 1;
ClearPending(BIT_SDI1);
rINTMSK |= (BIT_SDI1);
}
}
void __irq HS_READ_INT(void)
{
int i;
printf("\nWrite ISR");
ClearPending(BIT_SDI1);
rINTMSK |= (BIT_SDI1);
/*
for(j=0; j<BlockNum_HSMMC; j++)
{
if (!WaitForBufferWriteReady())
printf("WriteBuffer NOT Ready\n");
else
ClearBufferWriteReadyStatus();
for(i=0; i<512/4; i++)
{
rHM_BDATA = *Tx_buffer_HSMMC++;
wt_cnt_HSMMC++;
}
WriteBlockCnt ++;
printf("\nWrite block count = %d", WriteBlockCnt);
}
*/
if (!WaitForBufferReadReady())
printf("WriteBuffer NOT Ready\n");
else
ClearBufferReadReadyStatus();
for(i=0; i<512/4; i++)
{
*Rx_buffer_HSMMC++ = rHM_BDATA;
rd_cnt_HSMMC++;
}
ReadBlockCnt_INT ++;
printf("\nWrite block count = %d", ReadBlockCnt_INT);
rINTMSK &= ~(BIT_SDI1);
if(BlockNum_HSMMC == ReadBlockCnt_INT)
{
READINT_DONE = 1;
ClearPending(BIT_SDI1);
rINTMSK |= (BIT_SDI1);
}
}
void __irq HS_READ_COMPARE_INT(void)
{
int i;
printf("\nWrite ISR");
ClearPending(BIT_SDI1);
rINTMSK |= (BIT_SDI1);
if (!WaitForBufferReadReady())
printf("WriteBuffer NOT Ready\n");
else
ClearBufferReadReadyStatus();
for(i=0; i<512/4; i++)
{
*Compare_buffer_HSMMC++ = rHM_BDATA;
}
CompareCnt_INT ++;
printf("\nWrite block count = %d", CompareCnt_INT);
rINTMSK &= ~(BIT_SDI1);
if(BlockNum_HSMMC == CompareCnt_INT)
{
COMPARE_INT_DONE = 1;
ClearPending(BIT_SDI1);
rINTMSK |= (BIT_SDI1);
}
}
void __irq HS_CARD_DETECT_INT(void)
{
ClearPending(BIT_SDI1);
rINTMSK |= (BIT_SDI1);
rHM_NORINTSIGEN &= ~((1<<7)|(1<<6));
printf("Card Detect ISR\n");
printf("rHM_NORINTSTS = %x\n",rHM_NORINTSTS);
if(rHM_PRNSTS & (1<<16))
{
printf("\nCard insert\n");
HS_CARD_DETECT = 1;
}
else
{
printf("\nCard removal\n");
HS_CARD_DETECT = 1;
}
rHM_NORINTSTS |= (1<<7)|(1<<6);
rINTMSK &= ~(BIT_SDI1);
}
void DisplayCardInformation(void)
{
U32 C_SIZE, C_SIZE_MULT, READ_BL_LEN, READ_BL_PARTIAL, CardSize, OneBlockSize;
if(ThisIsMmc)
{
m_ucMMCSpecVer=(rHM_RSPREG3>>18)& 0xF;
printf("=> m_ucMMCSpecVer=%d\n", m_ucMMCSpecVer);
}
READ_BL_LEN = ((rHM_RSPREG2>>8) & 0xf) ;
READ_BL_PARTIAL = ((rHM_RSPREG2>>7) & 0x1) ;
C_SIZE = ((rHM_RSPREG2 & 0x3) << 10) | ((rHM_RSPREG1 >> 22) & 0x3ff);
C_SIZE_MULT = ((rHM_RSPREG1>>7)&0x7);
CardSize = (1<<READ_BL_LEN)*(C_SIZE+1)*(1<<(C_SIZE_MULT+2))/1048576;
OneBlockSize = (1<<READ_BL_LEN);
printf("\n READ_BL_LEN: %d",READ_BL_LEN);
printf("\n READ_BL_PARTIAL: %d",READ_BL_PARTIAL);
printf("\n C_SIZE: %d",C_SIZE);
printf("\n C_SIZE_MULT: %d\n",C_SIZE_MULT);
printf("\n One Block Size: %dByte",OneBlockSize);
printf("\n Total Card Size: %dMByte\n\n\n",CardSize+1);
}
void CalculationBPS_HSMMC(int Time)
{
float x=0;
int y=0;
float bps=0;
x = (float)((float)1000000/(float)Time); //Unit is usec
y = BlockNum_HSMMC * 512 * 8;
bps = x*(float)y;
printf("\n\n\nTransfer Time = %dusec",Time);
printf("\nTransferSize = %dKByte",y/(8*1024));
printf("\nBPS = %fMByte/sec\n\n",bps/(1000000*8));
}
void DataRead_ForCompare(int StartAddr)
{
U32 i=0,j=0;
COMPARE_INT_DONE = 0;
ClearPending(BIT_SDI1);
rHM_NORINTSIGEN &= ~(0xffff);
Compare_buffer_HSMMC = (U32 *)SDI_Compare_buffer_HSMMC;
for(i=0 ; i<(512 * BlockNum_HSMMC)/4 ; i++)
*(Compare_buffer_HSMMC+i) = 0x0;
printf("\nPolling mode data read\n");
printf("\nRead BlockNum = %d\n",BlockNum_HSMMC);
while (!IsCardInProgrammingState());
SetBlockSizeReg(7, 512); // Maximum DMA Buffer Size, Block Size
SetBlockCountReg(BlockNum_HSMMC); // Block Numbers to Write
SetArgumentReg(StartAddr*512); // Card Address to Write
if(BlockNum_HSMMC == 1)//single block
{
printf("Single block read\n");
SetTransferModeReg(0, 1, 1, 1, 0);
SetCommandReg(17, 0); // CMD17: Single-Read
}
else//multi block
{
printf("Multi block read\n");
SetTransferModeReg(1, 1, 1, 1, 0);
SetCommandReg(18, 0); // CMD18: Multi-Read
}
if (!WaitForCommandComplete())
{
printf("\nCommand is NOT completed\n");
}
ClearCommandCompleteStatus();
for(j=0; j<BlockNum_HSMMC; j++)
{
if (!WaitForBufferReadReady());
//printf("ReadBuffer NOT Ready\n");
else
ClearBufferReadReadyStatus();
for(i=0; i<512/4; i++)
{
*Compare_buffer_HSMMC++ = rHM_BDATA;
CompareCnt_INT++;
}
}
printf("\nRead count=%x\n",CompareCnt_INT);
if(!WaitForTransferComplete())
{
printf(("Transfer NOT Complete\n"));
}
ClearTransferCompleteStatus();
printf("\n\nrHM_NORINTSTS = %x",rHM_NORINTSTS);
}
void DataCompare_HSMMC(U32 a0, U32 a1, U32 bytes)
{
U32 * pD0 = (U32 *)a0;
U32 * pD1 = (U32 *)a1;
U32 ErrCnt = 0;
U32 i;
for (i=0; i<bytes; i++)
{
if (*pD0 != *pD1)
{
printf("\n%08x=%02x <-> %08x=%02x", pD0, *pD0, pD1, *pD1);
ErrCnt++;
}
pD0++;
pD1++;
}
printf("\nTotal Error cnt = %d",ErrCnt);
if(ErrCnt == 0)
printf("\nData Compare Ok\n");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -