⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hs_mmc.c

📁 Samsung S3C2443 Test program source code
💻 C
📖 第 1 页 / 共 3 页
字号:
		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 + -