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

📄 hs_mmc.c

📁 samsung最近推出的s3c2443 soc芯片的完整测试代码(官方),外围设备包括ADC,Audio,Timer,RTC,WDT,Video,cs8900,IIC,SPI,CF,SD/MMC,以及
💻 C
📖 第 1 页 / 共 3 页
字号:
				}
			return 0;								
			}
	}

}

void GetResponseData(U32 uCmd)
{
	U32 uSfr0;
	uSfr0 = rHM_RSPREG0;
	
	if(uCmd==3)
	{
 		if(!ThisIsMmc)
 		{
			m_uRca = (uSfr0>>16)&0xFFFF;			
			printf("=>  RCA=%d\n", m_uRca);
 		}
	}
	else if (uCmd==9)
	{
		if(ThisIsMmc)
		{
			m_ucMMCSpecVer=(rHM_RSPREG3>>18)& 0xF;
			printf("=>  m_ucMMCSpecVer=%d\n", m_ucMMCSpecVer);
		}
	}
}

int GetSdSCR()
{
	U32  uSCR1;

	if (!IssueCommand(16, 8, 0))
		return 0;
	else
	{
		SetBlockSizeReg(7, 8);
		SetBlockCountReg(1);
		SetArgumentReg(0*8);

		SetTransferModeReg(0, 1, 0, 0, 0);
		if (!IssueCommand(55, m_uRca, 0))		// CMD55 (For ACMD)
			return 0;
		else
		{
			if (!IssueCommand(51, 0, 1))			// Acmd51
				return 0;
			else
			{
				WaitForBufferReadReady();
				ClearBufferReadReadyStatus();

				uSCR1 = rHM_BDATA;

				WaitForTransferComplete();
				ClearTransferCompleteStatus();

				if ((uSCR1&0xf) == 0x0)
					SDSpecVer = 0; // Version 1.0 ~ 1.01
				else if ((uSCR1&0xf) == 0x1)
					SDSpecVer = 1; // Version 1.10, support cmd6
				else if((uSCR1&0xf) == 0x2)
					SDSpecVer = 2; // Version 2.0 support cmd6 and cmd8

				printf("SDSpecVer=%d\n", SDSpecVer);
				return 1;
			}
		}
	}
}

int IsCardInProgrammingState(void)
{
	// check the card status.
	if (!IssueCommand(13, m_uRca, 0))
		return 0;
	else
	{
		if(((rHM_RSPREG0>>9)&0xf) == 4)
			{
			printf("Card is transfer status\n");
			return 1;
			}
		return 0;
	}
}

void HostCtrlSpeedMode(U8 SpeedMode)
{
	U8  ucSpeedMode;
	ucSpeedMode = (SpeedMode == HIGH) ? 1 : 0;
	rHM_HOSTCTL &= ~(0x1<<2);
	rHM_HOSTCTL |= ucSpeedMode<<2;	
}

void ClockConfig(U32 Clksrc, U32 Divisior)
{
	U32 SrcFreq = 0, WorkingFreq;	
	
	if (Clksrc == SD_HCLK)
		SrcFreq = HCLK;
	else if (Clksrc == SD_EPLL)//Epll Out 48MHz
		SrcFreq = 100000000;
	else
		Clksrc = HCLK;

	WorkingFreq = SrcFreq/(Divisior*2);
	printf("WorkingFreq = %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");
	}
	else
	{
		GetSdSCR();
		if (SDSpecVer==1||SDSpecVer==2 )
		{
			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); 
}

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) | (U32)(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);
}

void SetArgumentReg(U32 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);
	}
		
	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)
{
	while (!(rHM_NORINTSTS&0x10));
	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)
{
	while (!(rHM_NORINTSTS&0x2))
		return 1;
	return 0;
}

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++;
	
	if(rHM_NORINTSTS & (1<<1))
	{
		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);

	if(rHM_NORINTSTS & (1<<1))
	{
		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);	

	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 ++;

	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;
	
    	ClearPending(BIT_SDI1);
	rINTMSK |= (BIT_SDI1);	

	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 ++;

	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);

	if(SectorMode == 1)
		StartAddr = StartAddr;
	else
		StartAddr = StartAddr * 512;

	while (!IsCardInProgrammingState());

	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
		{
			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 + -