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

📄 sdhcslot.cpp

📁 s3c2450 bsp for wince 5.0 PM_REL_0.04_080519 经验证,完全没问题
💻 CPP
📖 第 1 页 / 共 5 页
字号:
			m_fCheckSlot = TRUE;
		}
	}			
	if (m_fCheckSlot) {
		m_fCheckSlot = FALSE;

		// check card inserted or removed
		DWORD dwPresentState = ReadDword(SDHC_PRESENT_STATE);
		if (dwPresentState & STATE_CARD_INSERTED) {
			RETAILMSG(1, (TEXT("+++++++++++++++++++++SDHCControllerIst - Card is Inserted! 0x%08X\n"),this));			
			DEBUGMSG(SDHC_INTERRUPT_ZONE, (TEXT("SDHCControllerIst - Card is Inserted! \n")));
			m_fFakeCardRemoval = FALSE;			// added by JJG 06.11.13
			if (m_fCardPresent == FALSE ) {
				HandleInsertion();
			}
		}
		else {
			RETAILMSG(1, (TEXT("------------------------SDHCControllerIst - Card is Removed! 0x%08X\n"),this));	

			DEBUGMSG(SDHC_INTERRUPT_ZONE, (TEXT("SDHCControllerIst - Card is Removed! \n")));
			m_fFakeCardRemoval = FALSE;			// added by JJG 06.11.13
			if (m_fCardPresent) {
				HandleRemoval(TRUE);
			}
		}
	}
}

#elif (BSP_TYPE == BSP_SMDK2450)
VOID 
CSDHCSlotBase::HandleInterrupt(
		)
{
	Validate();

	WORD wIntStatus = ReadWord(SDHC_NORMAL_INT_STATUS);
	//  if(g_initialInsertion != 1) {
	//    while(( wIntStatus=ReadWord(SDHC_NORMAL_INT_STATUS)) == 0);
	//  }

	if (m_fFakeCardRemoval && m_fCardPresent) {
		m_fFakeCardRemoval = FALSE;
		HandleRemoval(TRUE);
	}

	if (wIntStatus != 0) {
		DEBUGMSG(SDHC_INTERRUPT_ZONE, 
				(TEXT("HandleInterrupt (%u) - Normal Interrupt_Status=0x%02x\n"),
				 m_dwSlot, wIntStatus));
		RETAILMSG(0, 
				(TEXT("1. HandleInterrupt (%u) - Normal Interrupt_Status=0x%02x\n"),
				 m_dwSlot, wIntStatus));

		// Error handling. Make sure to handle errors first. 
		if ( wIntStatus & NORMAL_INT_STATUS_ERROR_INT ) {
			HandleErrors();
		}

		// Command Complete handling.
		if ( wIntStatus & NORMAL_INT_STATUS_CMD_COMPLETE ) {
			// Clear status
			m_fCommandCompleteOccurred = TRUE;
			WriteWord(SDHC_NORMAL_INT_SIGNAL_ENABLE,(ReadWord(SDHC_NORMAL_INT_SIGNAL_ENABLE) & ~(NORMAL_INT_STATUS_CMD_COMPLETE)));
			WriteWord(SDHC_NORMAL_INT_STATUS_ENABLE,(ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE) & ~(NORMAL_INT_STATUS_CMD_COMPLETE)));
			do {
				WriteWord(SDHC_NORMAL_INT_STATUS, NORMAL_INT_STATUS_CMD_COMPLETE);
			}while(ReadWord(SDHC_NORMAL_INT_STATUS) & (NORMAL_INT_STATUS_CMD_COMPLETE));
			WriteWord(SDHC_NORMAL_INT_STATUS_ENABLE,(ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE) | NORMAL_INT_STATUS_CMD_COMPLETE));
			WriteWord(SDHC_NORMAL_INT_SIGNAL_ENABLE,(ReadWord(SDHC_NORMAL_INT_SIGNAL_ENABLE) | NORMAL_INT_STATUS_CMD_COMPLETE));

			if ( HandleCommandComplete() ) {
				wIntStatus &= ~NORMAL_INT_STATUS_TRX_COMPLETE; // this is command-only request. 
			}
		}

		// Sometimes at the lowest clock rate, the Read/WriteBufferReady
		// interrupt actually occurs before the CommandComplete interrupt.
		// This confuses our debug validation code and could potentially
		// cause problems. This is why we will verify that the CommandComplete
		// occurred before processing any data transfer interrupts.
		if (m_fCommandCompleteOccurred) {
			if (wIntStatus & NORMAL_INT_STATUS_DMA) {
				WriteWord(SDHC_NORMAL_INT_SIGNAL_ENABLE,(ReadWord(SDHC_NORMAL_INT_SIGNAL_ENABLE) & ~(NORMAL_INT_STATUS_DMA)));
				WriteWord(SDHC_NORMAL_INT_STATUS_ENABLE,(ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE) & ~(NORMAL_INT_STATUS_DMA)));
				do {
					WriteWord(SDHC_NORMAL_INT_STATUS, NORMAL_INT_STATUS_DMA);
				}while(ReadWord(SDHC_NORMAL_INT_STATUS) & NORMAL_INT_STATUS_DMA);
				WriteWord(SDHC_NORMAL_INT_STATUS_ENABLE,(ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE) | NORMAL_INT_STATUS_DMA));
				WriteWord(SDHC_NORMAL_INT_SIGNAL_ENABLE,(ReadWord(SDHC_NORMAL_INT_SIGNAL_ENABLE) | NORMAL_INT_STATUS_DMA));

				HandleDma();
				// do not break here. Continue to check TransferComplete. 
			}

			// Buffer Read Ready handling
			if (wIntStatus & NORMAL_INT_STATUS_BUF_READ_RDY ) {
				// Clear status
				WriteWord(SDHC_NORMAL_INT_SIGNAL_ENABLE,(ReadWord(SDHC_NORMAL_INT_SIGNAL_ENABLE) & ~(NORMAL_INT_STATUS_BUF_READ_RDY)));
				WriteWord(SDHC_NORMAL_INT_STATUS_ENABLE,(ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE) & ~(NORMAL_INT_STATUS_BUF_READ_RDY)));
				do {
					WriteWord(SDHC_NORMAL_INT_STATUS, NORMAL_INT_STATUS_BUF_READ_RDY);
				}while((ReadWord(SDHC_NORMAL_INT_STATUS) & NORMAL_INT_STATUS_BUF_READ_RDY));
				WriteWord(SDHC_NORMAL_INT_STATUS_ENABLE,(ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE) | NORMAL_INT_STATUS_BUF_READ_RDY));
				WriteWord(SDHC_NORMAL_INT_SIGNAL_ENABLE, (ReadWord(SDHC_NORMAL_INT_SIGNAL_ENABLE) | NORMAL_INT_STATUS_BUF_READ_RDY));

				HandleReadReady();
				// do not break here. Continue to check TransferComplete. 
			}

			// Buffer Write Ready handling
			if (wIntStatus & NORMAL_INT_STATUS_BUF_WRITE_RDY ) {
				// Clear status
				WriteWord(SDHC_NORMAL_INT_SIGNAL_ENABLE,(ReadWord(SDHC_NORMAL_INT_SIGNAL_ENABLE) & ~(NORMAL_INT_STATUS_BUF_WRITE_RDY)));
				WriteWord(SDHC_NORMAL_INT_STATUS_ENABLE,(ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE) & ~(NORMAL_INT_STATUS_BUF_WRITE_RDY)));
				do {
					WriteWord(SDHC_NORMAL_INT_STATUS, NORMAL_INT_STATUS_BUF_WRITE_RDY);
				}while((ReadWord(SDHC_NORMAL_INT_STATUS) & NORMAL_INT_STATUS_BUF_WRITE_RDY));
				WriteWord(SDHC_NORMAL_INT_STATUS_ENABLE,(ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE) | NORMAL_INT_STATUS_BUF_WRITE_RDY));
				WriteWord(SDHC_NORMAL_INT_SIGNAL_ENABLE,(ReadWord(SDHC_NORMAL_INT_SIGNAL_ENABLE) | NORMAL_INT_STATUS_BUF_WRITE_RDY));

				HandleWriteReady();
				// do not break here. Continue to check TransferComplete. 
			}
		}
		else {
			// We received data transfer interrupt before command 
			// complete interrupt. Wait for the command complete before
			// processing the data interrupt.
		}

		// Transfer Complete handling
		if ( wIntStatus & NORMAL_INT_STATUS_TRX_COMPLETE ) {
			// Clear status
			WriteWord(SDHC_NORMAL_INT_SIGNAL_ENABLE,(ReadWord(SDHC_NORMAL_INT_SIGNAL_ENABLE) & ~(NORMAL_INT_STATUS_TRX_COMPLETE)));
			WriteWord(SDHC_NORMAL_INT_STATUS_ENABLE,(ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE) & ~(NORMAL_INT_STATUS_TRX_COMPLETE)));
			do {
				WriteWord(SDHC_NORMAL_INT_STATUS, NORMAL_INT_STATUS_TRX_COMPLETE | NORMAL_INT_STATUS_DMA);
			}while(ReadWord(SDHC_NORMAL_INT_STATUS) & (NORMAL_INT_STATUS_TRX_COMPLETE|NORMAL_INT_STATUS_DMA));
			WriteWord(SDHC_NORMAL_INT_STATUS_ENABLE,(ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE) | NORMAL_INT_STATUS_TRX_COMPLETE));
			WriteWord(SDHC_NORMAL_INT_SIGNAL_ENABLE,(ReadWord(SDHC_NORMAL_INT_SIGNAL_ENABLE) | NORMAL_INT_STATUS_TRX_COMPLETE));


			HandleTransferDone();
		}

		// SDIO Interrupt Handling
		if ( wIntStatus & NORMAL_INT_STATUS_CARD_INT ) {
			DEBUGCHK(m_fSDIOInterruptsEnabled);
			DEBUGMSG(SDHC_INTERRUPT_ZONE, (_T("SDHCControllerIst: Card interrupt!\n")));

			// Because SDIO Interrupt is level triggered, we are not able to clear
			// the status. The status should be cleared by the card
			// we just disable the interrupt from Interrupt Signal Register
			// and Interrupt Status Enable register, and indicate that 
			// the card is interrupting
			EnableSDIOInterrupts(FALSE);
			IndicateSlotStateChange(DeviceInterrupting);
		}

		// Card Detect Interrupt Handling
		if (wIntStatus & (NORMAL_INT_STATUS_CARD_INSERTION | NORMAL_INT_STATUS_CARD_REMOVAL)) {
			WriteWord(SDHC_NORMAL_INT_SIGNAL_ENABLE,
					(ReadWord(SDHC_NORMAL_INT_SIGNAL_ENABLE) &~(NORMAL_INT_STATUS_CARD_INSERTION | NORMAL_INT_STATUS_CARD_REMOVAL)));
			WriteWord(SDHC_NORMAL_INT_STATUS_ENABLE,
					(ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE) &~(NORMAL_INT_STATUS_CARD_INSERTION | NORMAL_INT_STATUS_CARD_REMOVAL)));
			do {
				WriteWord(
						SDHC_NORMAL_INT_STATUS,
						NORMAL_INT_STATUS_CARD_INSERTION | NORMAL_INT_STATUS_CARD_REMOVAL);
			}while(ReadWord(SDHC_NORMAL_INT_STATUS) & (NORMAL_INT_STATUS_CARD_INSERTION | NORMAL_INT_STATUS_CARD_REMOVAL));
			WriteWord(SDHC_NORMAL_INT_STATUS_ENABLE,
					(ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE) | (NORMAL_INT_STATUS_CARD_INSERTION | NORMAL_INT_STATUS_CARD_REMOVAL)));
			WriteWord(SDHC_NORMAL_INT_SIGNAL_ENABLE,
					(ReadWord(SDHC_NORMAL_INT_SIGNAL_ENABLE) | (NORMAL_INT_STATUS_CARD_INSERTION | NORMAL_INT_STATUS_CARD_REMOVAL)));

			m_fCheckSlot = TRUE;
		}
	}

	if (m_fCheckSlot) {
		m_fCheckSlot = FALSE;

		// check card inserted or removed
		DWORD dwPresentState = ReadDword(SDHC_PRESENT_STATE);
		if (dwPresentState & STATE_CARD_INSERTED) {
			DEBUGMSG(SDHC_INTERRUPT_ZONE, (TEXT("SDHCControllerIst - Card is Inserted! \n")));
			RETAILMSG(1, (TEXT("[HSMMC1] Card is Inserted! \n")));
			m_fFakeCardRemoval = FALSE;	// KYS
			if (m_fCardPresent == FALSE ) {
				Start();
				HandleInsertion();
			}
		}
		else {
			DEBUGMSG(SDHC_INTERRUPT_ZONE, (TEXT("SDHCControllerIst - Card is Removed! \n")));
			RETAILMSG(1, (TEXT("[HSMMC1] Card is Removed! \n")));
			m_fFakeCardRemoval = FALSE;	// KYS
			if (m_fCardPresent) {
				HandleRemoval(TRUE);
			}
		}
	}
}
#endif  // !(BSP_TYPE == BSP_SMDK2443)


VOID 
CSDHCSlotBase::HandleRemoval(
		BOOL fCancelRequest
		)
{    
	m_fCardPresent = FALSE;
	m_fIsPowerManaged = FALSE;
	m_fSleepsWithPower = FALSE;
	m_fPowerUpDisabledInts = FALSE;
	m_f4BitMode = FALSE;
	m_cpsCurrent = D0;

	// Wake on SDIO interrupt must be set by the client
	m_bWakeupControl &= ~WAKEUP_INTERRUPT;

#if (BSP_TYPE == BSP_SMDK2443)

#elif (BSP_TYPE == BSP_SMDK2450)
	// To control the Data CRC error
	WORD wErrIntSignalEn = ReadWord(SDHC_ERROR_INT_SIGNAL_ENABLE);
	WORD wErrIntStatusEn = ReadWord(SDHC_ERROR_INT_STATUS_ENABLE);
	WORD wErrIntStatus = ReadWord(SDHC_ERROR_INT_STATUS);
	WriteWord(SDHC_ERROR_INT_SIGNAL_ENABLE, (wErrIntSignalEn & ~(0x20))); //Command and Data CRC error disable
	WriteWord(SDHC_ERROR_INT_STATUS_ENABLE, (wErrIntStatusEn & ~(0x20))); //Command and Data CRC error disable
#endif
	if (m_fSDIOInterruptsEnabled) {
		EnableSDIOInterrupts(FALSE);
	}

	IndicateSlotStateChange(DeviceEjected);

	// turn off clock and remove power from the slot
	SDClockOff();
	WriteByte(SDHC_POWER_CONTROL, 0);

	if (fCancelRequest) {
		// get the current request  
		PSD_BUS_REQUEST pRequest = GetAndLockCurrentRequest();

		if (pRequest != NULL) {
			DEBUGMSG(SDCARD_ZONE_WARN, 
					(TEXT("Card Removal Detected - Canceling current request: 0x%08X, command: %d\n"), 
					 pRequest, pRequest->CommandCode));
			DumpRequest(pRequest, SDHC_SEND_ZONE || SDHC_RECEIVE_ZONE);
			IndicateBusRequestComplete(pRequest, SD_API_STATUS_DEVICE_REMOVED);
		}
	}

	if (m_pbDmaBuffer) {
		DEBUGCHK(m_paDmaBuffer);
		FreePhysBuffer(m_pbDmaBuffer);
		m_pbDmaBuffer = NULL;
		m_paDmaBuffer = 0;

		// The Pegasus requires the following so that the next
		// insertion will work correctly.
		SoftwareReset(SOFT_RESET_CMD | SOFT_RESET_DAT);
		WriteDword(SDHC_SYSTEMADDRESS_LO, 0);
		WriteWord(SDHC_BLOCKSIZE, 0);
		WriteWord(SDHC_BLOCKCOUNT, 0);
#if (BSP_TYPE == BSP_SMDK2443)
		WriteWord(SDHC_NORMAL_INT_STATUS, NORMAL_INT_STATUS_DMA);

#elif (BSP_TYPE == BSP_SMDK2450)
		WriteWord(SDHC_NORMAL_INT_SIGNAL_ENABLE, (ReadWord(SDHC_NORMAL_INT_SIGNAL_ENABLE) & ~(NORMAL_INT_STATUS_DMA)));
		WriteWord(SDHC_NORMAL_INT_STATUS_ENABLE,(ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE) & ~(NORMAL_INT_STATUS_DMA)));
		do {
			WriteWord(SDHC_NORMAL_INT_STATUS, NORMAL_INT_STATUS_DMA);
		}while(ReadWord(SDHC_NORMAL_INT_STATUS) & NORMAL_INT_STATUS_DMA);
		WriteWord(SDHC_NORMAL_INT_STATUS_ENABLE, (ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE) | NORMAL_INT_STATUS_DMA));
		WriteWord(SDHC_NORMAL_INT_SIGNAL_ENABLE, (ReadWord(SDHC_NORMAL_INT_SIGNAL_ENABLE) | NORMAL_INT_STATUS_DMA));

		// To diable the Data CRC error interrupt
		WriteWord(SDHC_ERROR_INT_SIGNAL_ENABLE,0);  
		do
		{
			WriteWord(SDHC_ERROR_INT_STATUS,wErrIntStatus);
		}while(ReadWord(SDHC_ERROR_INT_STATUS));
		WriteWord(SDHC_ERROR_INT_SIGNAL_ENABLE,wErrIntSignalEn);
#endif
	}

	// 08.04.03 by KYS
	// Below code lines are needed for working as a mass storage device
	v_gBspArgs->g_SDCardState = CARD_REMOVED;
	SetEvent( v_gBspArgs->g_SDCardDetectEvent ); 
}


VOID 
CSDHCSlotBase::HandleInsertion(
		)
{
	DWORD dwClockRate = SD_DEFAULT_CARD_ID_CLOCK_RATE;

#if (BSP_TYPE == BSP_SMDK2443)

#elif (BSP_TYPE == BSP_SMDK2450)
	WORD wErrIntSignalEn = ReadWord(SDHC_ERROR_INT_SIGNAL_ENABLE);
	WORD wErrIntStatusEn = ReadWord(SDHC_ERROR_INT_STATUS_ENABLE);

	g_initialInsertion = 0;
#endif
	m_fCardPresent = TRUE;

	// Apply the initial voltage to the card.
	SetVoltage(GetMaxVddWindow());

	// Send at least 74 clocks to the card over the course of at least 1 ms
	// with allowance for power supply ramp-up time. (SD Phys Layer 6.4)
	// Note that power supply ramp-up time occurs in SetVoltage().
	RETAILMSG(0,(TEXT("++SetClockRate(&dwClockRate)\n")));
	SetClockRate(&dwClockRate);

	SDClockOn();
	DWORD dwSleepMs = (74 / (dwClockRate / 1000)) + 1;
	Sleep(dwSleepMs);

	SDClockOff();

	if (GetCapabilities().bits.DMA) {
		RETAILMSG(0,(TEXT("Use DMA\n")));
		PHYSICAL_ADDRESS SystemAddr = { 0 };
		PVOID pvBuffer = AllocPhysBuffer(CB_DMA_BUFFER, &SystemAddr.LowPart);        
		if (pvBuffer) {
			PHYSICAL_ADDRESS BusAddr;

			// Translate physical address to logical (bus-relative) address.
			BOOL fSuccess = TranslateSystemAddr(m_hBusAccess, m_interfaceType, 
					m_dwBusNumber, SystemAddr, &BusAddr);
			if (fSuccess) {
				RETAILMSG(0,(TEXT("Use DMA Success.\n")));				
				m_pbDmaBuffer= (PBYTE) pvBuffer;
				m_paDmaBuffer = BusAddr.LowPart;
			}
			else {
				// If we fail, we will simply fall back to PIO mode
				FreePhysBuffer(pvBuffer);
			}
		}
	}

	// Interrupts are not enabled on a newly inserted card.
	EnableSDIOInterrupts(FALSE);

	// Indicate device arrival
	IndicateSlotStateChange(DeviceInserted);
#if (BSP_TYPE == BSP_SMDK2443)

#elif (BSP_TYPE == BSP_SMDK2450)
	WriteWord(SDHC_ERROR_INT_SIGNAL_ENABLE, (wErrIntSignalEn | (0x20))); //Command and Data CRC error disable
	WriteWord(SDHC_ERROR_INT_STATUS_ENABLE, (wErrIntStatusEn | (0x20))); //Command and Data CRC error disable
#endif

	// 08.04.03 by KYS
	// Below code lines are needed for working as a mass storage device
	v_gBspArgs->g_SDCardState = CARD_INSERTED;
	SetEvent( v_gBspArgs->g_SDCardDetectEvent );
}


BOOL 
CSDHCSlotBase::HandleCommandComplete(
		)
{
	SETFNAME();

	PSD_BUS_REQUEST pRequest;
	BOOL fRet = FALSE;
	int count = 0 ;
	RETAILMSG(0,(TEXT("CSDHCSlotBase::HandleCommandComplete\n")));
	// get the current request  
	pRequest = GetAndLockCurrentRequest();

	DEBUGCHK(m_dwReadyInts == 0);

	if (pRequest) {
		RETAILMSG(0,(TEXT("CSDHCSlotBase::HandleCommandComplete    pRequest\n")));		
		DEBUGCHK(pRequest->HCParam == 0);
#if (BSP_TYPE == BSP_SMDK2443)
		SD_API_STATUS transferStatus = SD_API_STATUS_SUCCESS;

#elif (BSP_TYPE == BSP_SMDK2450)
		// 08.02.03 by KYS
		// INT_TRX_COMPLETE is not suitable for s3c2450, so I comment out below code.
		// therefore, in order to keep fastpath status, those code like just below is needed.
		//SD_API_STATUS transferStatus = SD_API_STATUS_SUCCESS;
		SD_API_STATUS transferStatus = m_Fa

⌨️ 快捷键说明

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