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

📄 sdhc.c

📁 s3c6400 ADS下官方测试程序
💻 C
📖 第 1 页 / 共 5 页
字号:
void __irq SDHC_normalInt1(void) {	SDHC_normalIntHandler( SDHC_curr_card[SDHC_CHANNEL_1] );	INTC_ClearVectAddr();}//////////// File Name : SDHC_normalInt2// File Description : Normal Interrupt Handler 2// Input : NONE// Output : NONE.void __irq SDHC_normalInt2(void) {	SDHC_normalIntHandler( SDHC_curr_card[SDHC_CHANNEL_2] );	INTC_ClearVectAddr();}//////////// File Name : SDHC_InitCh// File Description : Initialize channel information.// Input : SDHC Channel Number, SDHC pointer..// Output : NONE.void SDHC_InitCh(SDHC_channel eCh, SDHC *sCh) {	sCh->m_eChannel = eCh;	SDHC_curr_card[sCh->m_eChannel]=sCh;	// Pointer...	if ( eCh == SDHC_CHANNEL_0 ) {		// Channel 0		sCh->m_uBaseAddr = (u8*)HSMMC0_BASE;		sCh->m_fDmaFn = SDHC_DMAInt0;		sCh->m_fReadFn = SDHC_ReadInt0;		sCh->m_fWriteFn = SDHC_WriteInt0;		sCh->m_fNormalFn = SDHC_normalInt0;		sCh->m_ucIntChannelNum = NUM_HSMMC0;	}	else if ( eCh == SDHC_CHANNEL_1 ) {	// Channel 1		sCh->m_uBaseAddr = (u8*)HSMMC1_BASE;		sCh->m_fDmaFn = SDHC_DMAInt1;		sCh->m_fReadFn = SDHC_ReadInt1;		sCh->m_fWriteFn = SDHC_WriteInt1;		sCh->m_fNormalFn = SDHC_normalInt1;		sCh->m_ucIntChannelNum = NUM_HSMMC1;	}	else if ( eCh == SDHC_CHANNEL_2 ) {	// channel 2->SPI muxed.		sCh->m_uBaseAddr = (u8*)HSMMC2_BASE;		sCh->m_fDmaFn = SDHC_DMAInt2;		sCh->m_fReadFn = SDHC_ReadInt2;		sCh->m_fWriteFn = SDHC_WriteInt2;		sCh->m_fNormalFn = SDHC_normalInt2;		sCh->m_ucIntChannelNum = NUM_SPI1;	}	else {		Assert(0);	}}//////////// File Name : SDHC_OpenMedia// File Description : Initialize channel information.// Input : SDHC Clock Source, SDHC pointer.// Output : Success or Failure.bool SDHC_OpenMedia(SDHC_clockSource eClkSrc, SDHC* sCh){	SDHC_SpeedMode speed;	u32 uSrcFreq;	u32 uOperFreq;	sCh->m_eClockSource = eClkSrc;	sCh->m_ucHostCtrlReg = 0;	sCh->m_usClkCtrlReg = 0;	if ( sCh->m_ucBandwidth == 0 )		sCh->m_ucBandwidth = 4;		// bit width.	// GPIO Setting.	SDHC_SetGPIO(sCh->m_eChannel, sCh->m_ucBandwidth);	if ( eClkSrc == SDHC_HCLK || eClkSrc == 0 ) {		uSrcFreq = g_HCLK;	}	else if ( eClkSrc == SDHC_EPLL ) {		uSrcFreq = Inp32(0x7E00F014);	// temp	//	((uSrcFreq>>16)&0xff) //M	//	((uSrcFreq>>8)&0x3f) //P	//	(uSrcFreq&0x07) //S	//   ignore K value		uSrcFreq = (u32)(((float)FIN)*((uSrcFreq>>16)&0xff)/(((uSrcFreq>>8)&0x3f)*(1<<(uSrcFreq&0x07))));	}	else if ( eClkSrc == SDHC_EXTCLK ) {		uSrcFreq = 48000000;	// 48MHz External crystal	}	else {		Assert(FALSE);	}	if ( sCh->m_uClockDivision == 0 ) {		uOperFreq = uSrcFreq;		if(uOperFreq>52000000) {			sCh->m_uClockDivision = 2;			uOperFreq = uSrcFreq / (sCh->m_uClockDivision*2);		}	}	else {		uOperFreq = uSrcFreq / (sCh->m_uClockDivision*2);	}	sdDbg(("WorkingFreq = %dMHz\n", uOperFreq/1000000 ));		SDHC_ResetController(sCh);//	youngbo.song -SDIO test.//	if( !SDHC_newOCR(sCh) ) { // for SDIO.		if (!SDHC_IdentifyCard(sCh))			return FALSE;//	}	if ( sCh->m_eCardType == SDHC_SDIO_CARD ) {		return TRUE;	}	// SDIO Test.... end	// card Selection	if ( !SDHC_IssueCommand( sCh, 7, (u32)(sCh->m_uRca<<16), SDHC_CMD_AC_TYPE, SDHC_RES_R1B_TYPE ) )		return FALSE;		if (sCh->m_eCardType == SDHC_MMC_CARD ) {		if (sCh->m_ucSpecVer >= 4) {			speed = ( uOperFreq > SDHC_MMC_HIGH_SPEED_CLOCK) ? (SDHC_HIGH_SPEED) : (SDHC_NORMAL_SPEED);			if (!SDHC_SetMmcSpeedMode(speed, sCh)) {				return FALSE;			}		}		else // old version			Assert(uOperFreq<=SDHC_MMC_HIGH_SPEED_CLOCK); // Error! Old version MMC card can not support working frequency higher than 20MHz");	}	else if ( sCh->m_eCardType == SDHC_SD_CARD ) {		SDHC_GetSdScr(sCh);		if (sCh->m_ucSpecVer==1||sCh->m_ucSpecVer==2) {			speed = ( uOperFreq > SDHC_SD_HIGH_SPEED_CLOCK) ? (SDHC_HIGH_SPEED) : (SDHC_NORMAL_SPEED);			if (!SDHC_SetSdCardSpeedMode(speed, sCh)) {				return FALSE;			}		}		else			Assert(uOperFreq<=SDHC_SD_HIGH_SPEED_CLOCK); // Error! Old version SD card can not support working frequency higher than 25MHz");	}	// host controller speed setting.	speed = ( uOperFreq > SDHC_MMC_HIGH_SPEED_CLOCK) ? (SDHC_HIGH_SPEED) : (SDHC_NORMAL_SPEED);	SDHC_SetHostCtrlSpeedMode( speed, sCh );	SDHC_SetSdClockOnOff(0, sCh); // If the sd clock is to be changed, you need to stop sd-clock.	SDHC_SetSdClock(sCh->m_uClockDivision, sCh, speed, uOperFreq);	// After a card was selected, then the bus width can be changed.	if (!SDHC_SetDataTransferWidth( sCh))		return FALSE;	if (!SDHC_WaitForCard2TransferState(sCh))		return FALSE;	if ( sCh->m_eCardType == SDHC_MMC_CARD ) {		SDHC_ReadMMCExtCSD( sCh );	}	else {		// CMD16 can not be set while card is in programming state.		if (!SDHC_IssueCommand(sCh, 16, 512, SDHC_CMD_AC_TYPE, SDHC_RES_R1_TYPE ) ) // Set the block size			return FALSE;	}	// youngbo.song	Outp32( sCh->m_uBaseAddr+SDHC_CONTROL2, Inp32(sCh->m_uBaseAddr+SDHC_CONTROL2)|(1<<8)|(2<<9)|(1<<28));	return TRUE;}//////////// File Name : SDHC_OpenMediaWithMode// File Description : SD/MMC Channel initialize with parameter.// Input : Bus width, Operation mode, Clock source, Clock divider, channel Number, Information Structuer pointer.// Output : Success or Failure.bool SDHC_OpenMediaWithMode(u32 uBusWidth, SDHC_operation eOpMode, SDHC_clockSource eClkSrc,	u32 uSdClkDivisor, SDHC_channel channel, SDHC* sCh){	sCh->m_eOpMode = eOpMode;	sCh->m_ucBandwidth = uBusWidth;	sCh->m_uClockDivision = uSdClkDivisor;	// channel initialize.	SDHC_InitCh(channel, sCh);		if ( !SDHC_OpenMedia(eClkSrc, sCh ) )		return FALSE;	return TRUE;}//////////// File Name : SDHC_CloseMedia// File Description : This function close media session.// Input : SDHC// Output : NONE.bool SDHC_IdentifyCard(SDHC* sCh){	if ( sCh->m_eClockSource == SDHC_EXTCLK ) {		SDHC_SetSdClock(0x40, sCh, SDHC_NORMAL_SPEED, 400000);	// Under 400Khz.	}	else {		SDHC_SetSdClock(0x80, sCh, SDHC_NORMAL_SPEED, 400000);	// Under 400Khz.	}	Outp8( sCh->m_uBaseAddr+SDHC_TIMEOUT_CTRL, 		(Inp8(sCh->m_uBaseAddr+SDHC_TIMEOUT_CTRL)&(0xF<<4))|0xe);	// Timeout setting.	Outp8( sCh->m_uBaseAddr+SDHC_HOST_CTRL,		Inp8( sCh->m_uBaseAddr+SDHC_HOST_CTRL ) & (~(0x1<<2)) );		// NORMAL Speed mode.	SDHC_SetHostCtrlSpeedMode(SDHC_NORMAL_SPEED, sCh);	SDHC_SetSdhcInterruptEnable(0xFF, 0xFF, sCh);//	INTC_SetVectAddr( sCh->m_ucIntChannelNum, sCh->m_fDmaFn );//	INTC_Enable( sCh->m_ucIntChannelNum );//	Outp16( sCh->m_uBaseAddr+SDHC_NORMAL_INT_SIGNAL_ENABLE,//		SDHC_DMA_SIG_INT_EN|//		SDHC_TRANSFERCOMPLETE_SIG_INT_EN|//		SDHC_COMMANDCOMPLETE_SIG_INT_EN);	// Check card OCR(Operation Condition Register)	if (SDHC_SetSDOCR(sCh))		sCh->m_eCardType = SDHC_SD_CARD;	else if (SDHC_SetMmcOcr(sCh))		sCh->m_eCardType = SDHC_MMC_CARD;	else		return FALSE;	// Check the attached card and place the card in the IDENT state rHM_RSPREG0	SDHC_IssueCommand( sCh, 2, 0, SDHC_CMD_BCR_TYPE, SDHC_RES_R2_TYPE );	sdDbg(("- Product Name : %c%c%c%c%c%c\n",((Inp32(sCh->m_uBaseAddr+SDHC_RSP2)>>24)&0xFF),		((Inp32(sCh->m_uBaseAddr+SDHC_RSP2)>>16)&0xFF),		((Inp32(sCh->m_uBaseAddr+SDHC_RSP2)>>8)&0xFF),		(Inp32(sCh->m_uBaseAddr+SDHC_RSP2)&0xFF),		((Inp32(sCh->m_uBaseAddr+SDHC_RSP1)>>24)&0xFF),		((Inp32(sCh->m_uBaseAddr+SDHC_RSP1)>>16)&0xFF)));	// Send RCA(Relative Card Address). It places the card in the STBY state	sCh->m_uRca= (sCh->m_eCardType==SDHC_MMC_CARD) ? (1): (0);	SDHC_IssueCommand( sCh, 3, sCh->m_uRca<<16, SDHC_CMD_AC_TYPE, SDHC_RES_R1_TYPE );	if( sCh->m_eCardType == SDHC_SD_CARD)	{		sCh->m_uRca = (Inp32(sCh->m_uBaseAddr+SDHC_RSP0)>>16)&0xFFFF;		sdDbg(("=>  RCA=0x%x\n", sCh->m_uRca));	}	//Send CSD	SDHC_IssueCommand( sCh, 9, sCh->m_uRca<<16, SDHC_CMD_AC_TYPE, SDHC_RES_R2_TYPE );	SDHC_DisplayCardInformation(sCh);	return true;}//////////// File Name : SDHC_CloseMedia// File Description : This function close media session.// Input : SDHC// Output : NONE.void SDHC_CloseMedia(SDHC* sCh){	SDHC_SetSdClockOnOff(FALSE, sCh); // SDCLK Disable}//////////// File Name : SDHC_WriteOneBlock// File Description : This function writes one block data by CPU transmission mode.// Input : SDHC( assert buffer pointer and remain data length.)// Output : NONE.void SDHC_WriteOneBlock( SDHC* sCh, int block_size ) {	u32* source_Ptr = sCh->m_uBufferPtr;	int i;	if ( block_size < 1 || block_size > 512 )		block_size = 512;		// Wait for buffer write ready... - SDHC_BUFFER_WRITEREADY_STS_INT_EN	SDHC_INT_WAIT_CLEAR( sCh, 4, i );	if ( 100000 - i > 1 )		printf( "100000 to time:%d\n", 100000-i);		block_size = (block_size+3) >> 2;	// block_size = (block_size+3) / 4;	for(i=block_size; i>0; i--)	//512/4	{		Outp32( sCh->m_uBaseAddr+SDHC_BUF_DAT_PORT, *source_Ptr++);	}	sCh->m_uRemainBlock--;	sCh->m_uBufferPtr = source_Ptr;}//////////// File Name : SDHC_ReadOneBlock// File Description : This function reads one block data by CPU transmission mode.// Input : SDHC( assert buffer pointer and remain data length.)//            one block size : If set 0, than assume 512 byte.// Output : NONE.void SDHC_ReadOneBlock( SDHC* sCh, int block_size ) {	u32* target_Ptr = sCh->m_uBufferPtr;	int i;	if ( block_size < 1 || block_size > 512 )		block_size = 512;	// Wait for buffer read ready...- SDHC_BUFFER_READREADY_STS_INT_EN	SDHC_INT_WAIT_CLEAR( sCh, 5, i );	if ( 100000 - i > 1 )		printf( "100000 to time:%d\n", 100000-i);			block_size = (block_size+3) >> 2;	// block_size = (block_size+3) / 4;	for(i=block_size; i>0; i--)	{		*target_Ptr++ = Inp32( sCh->m_uBaseAddr+SDHC_BUF_DAT_PORT );	}	sCh->m_uRemainBlock--;	sCh->m_uBufferPtr = target_Ptr;}//////////// File Name : SDHC_GetCeATATaskFile// File Description : This function gets CE-ATA Taskfile from CE-ATA Device.// Input : SDHC channel, CE-ATA Command, Taskfile buffer// Output : success or failurebool SDHC_GetCeATATaskFile( SDHC* sCh, SDHC_CEATACommand cmd, SDHC_ataTaskFile * taskFile ) {	int i;		SDHC_SetBlockSizeReg(sCh, 7, 0x10);		// Maximum DMA Buffer Size, Block Size		//	SDHC_SetBlockCountReg(sCh, 1);		// Block Numbers to Read	SDHC_SetTransferModeReg(0, 1, 0, 0, 0, sCh);	if ( SDHC_IssueCommand( sCh, 60, (u32)((0<<31)|(0<<16)|(0x10)), SDHC_CMD_ADTC_TYPE, SDHC_RES_R1_TYPE) == FALSE ) {		return FALSE;	}	memset ( taskFile, 0, sizeof(SDHC_ataTaskFile) );	taskFile->device_head = 0;	taskFile->command_status = cmd;	sCh->m_uRemainBlock = 1;	sCh->m_uBufferPtr = (u32*)taskFile;	SDHC_ReadOneBlock( sCh, 0x10);	SDHC_INT_WAIT_CLEAR( sCh, 1, i );	// SDHC_TRANSFERCOMPLETE_STS_INT_EN	return TRUE;}//////////// File Name : SDHC_SetCeATATaskFile// File Description : This function sets CE-ATA Taskfile to CE-ATA Device.// Input : SDHC channel, CE-ATA Command, start block address, Block Count, Taskfile buffer// Output : success or failurebool SDHC_SetCeATATaskFile( SDHC* sCh, SDHC_CEATACommand cmd, u32 startBlock, u32 blockCount, SDHC_ataTaskFile * taskFile ) {	int i;		SDHC_SetBlockSizeReg(sCh, 0, 0x10);//	SDHC_SetBlockCountReg(sCh, 1);		// Block Numbers to Read	SDHC_SetTransferModeReg(0, 0, 0, 0, 0, sCh);	// Write Mode.	if ( SDHC_IssueCommand( sCh, 60, (u32)((1<<31)|(0<<16)|(0x10)), SDHC_CMD_ADTC_TYPE, SDHC_RES_R1B_TYPE) == FALSE ) {		return FALSE;	}	memset ( taskFile, 0, sizeof(SDHC_ataTaskFile) );	taskFile->sectorCountExp = (u8)(blockCount>>8 & 0xff);;	taskFile->sectorCount = (u8)(blockCount & 0xff);	taskFile->LBALow = (u8)(startBlock & 0xff);	taskFile->LBAMID = (u8)(startBlock>>8 & 0xff);	taskFile->LBAHigh = (u8)(startBlock>>16 & 0xff);	taskFile->LBALowExp = (u8)(startBlock>>24 & 0xff);	taskFile->LBAMidExp = 0;	taskFile->LBAHighExp = 0;	taskFile->device_head = 0;	taskFile->command_status = cmd;		sCh->m_uRemainBlock = 1;	sCh->m_uBufferPtr = (u32*)taskFile;	SDHC_WriteOneBlock( sCh, 0x10);	SDHC_INT_WAIT_CLEAR( sCh, 1, i );	// SDHC_TRANSFERCOMPLETE_STS_INT_EN	return TRUE;}//////////// File Name : SDHC_GetCeATAIdentifyData// File Description : This function gets identify data from CE-ATA Device.// Input : SDHC channel, ATA-Taskfile, Buffer(512byte)// Output : success or failurebool SDHC_GetCeATAIdentifyData( SDHC* sCh, SDHC_ataTaskFile* taskFile, u8* buffer ) {	int i;	if ( SDHC_SetCeATATaskFile( sCh, SDHC_ATCMD_IDENTIFY_DEVICE, 0, 0, taskFile ) == FALSE ) {		return FALSE;	}	SDHC_SetBlockSizeReg(sCh, 7, 512);		// Maximum DMA Buffer Size, Block Size		//	SDHC_SetBlockCountReg(sCh, 1);		// Block Numbers to Read

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -