?? sdhcslot.cpp
字號:
BOOL CSDHCSlotBase::PollingForCommandComplete()
{
BOOL fContinue = TRUE;
if (m_fFakeCardRemoval && m_fCardPresent) {
m_fFakeCardRemoval = FALSE;
HandleRemoval(TRUE);
}
else {
// Assume we reading PCI register at 66 Mhz. for times of 100 us. it should be 10*1000 time
for (DWORD dwIndex=0; fContinue && dwIndex<10*1000; dwIndex ++ ) {
WORD wIntStatus = ReadWord(SDHC_NORMAL_INT_STATUS);
if (wIntStatus != 0) {
DEBUGMSG(SDHC_INTERRUPT_ZONE,
(TEXT("PollingForCommandComplete (%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();
fContinue = FALSE;
}
// Command Complete handling.
if ( wIntStatus & NORMAL_INT_STATUS_CMD_COMPLETE ) {
// Clear status
m_fCommandCompleteOccurred = TRUE;
fContinue = FALSE;
WriteWord(SDHC_NORMAL_INT_STATUS, NORMAL_INT_STATUS_CMD_COMPLETE);
if (HandleCommandComplete()) { // If completed.
WriteWord(SDHC_NORMAL_INT_STATUS, (wIntStatus & NORMAL_INT_STATUS_TRX_COMPLETE));
}
}
}
}
}
ASSERT(!fContinue);
return (!fContinue);
}
VOID
CSDHCSlotBase::EnableSDIOInterrupts(
BOOL fEnable
)
{
Validate();
if (fEnable) {
m_fSDIOInterruptsEnabled = TRUE;
DoEnableSDIOInterrupts(fEnable);
}
else {
DoEnableSDIOInterrupts(fEnable);
m_fSDIOInterruptsEnabled = FALSE;
}
}
#ifndef _SMDK6410_CH0_EXTCD_
VOID CSDHCSlotBase::HandleInterrupt()
#else
// New Interrupt handler function can process factors on new card detect interrupt of HSMMC ch0 on SMDK6410.
VOID CSDHCSlotBase::HandleInterrupt(SDSLOT_INT_TYPE intType)
#endif
{
Validate();
#ifdef _SMDK6410_CH0_EXTCD_
// in case of it is occurred a card detect interrupt of HSMMC ch0 on SMDK6410
if (intType == SDSLOT_INT_CARD_DETECTED) {
m_fCheckSlot = TRUE;
} else {
#endif
WORD wIntStatus = 0;
wIntStatus = ReadWord(SDHC_NORMAL_INT_STATUS);
if (m_fFakeCardRemoval ) {
m_fFakeCardRemoval = FALSE;
if (m_fCardPresent)
HandleRemoval(TRUE);
m_fCheckSlot = TRUE;
}
else if (wIntStatus != 0) {
DEBUGMSG(SDHC_INTERRUPT_ZONE,
(TEXT("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_STATUS, 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_STATUS, NORMAL_INT_STATUS_DMA);
// get the current request
PSD_BUS_REQUEST pRequest = GetAndLockCurrentRequest();
if (m_SlotDma && pRequest)
m_SlotDma->DMANotifyEvent(*pRequest, DMA_COMPLETE);
else {
ASSERT(FALSE);
}
// 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_STATUS, 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_STATUS, 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_STATUS,
NORMAL_INT_STATUS_TRX_COMPLETE | NORMAL_INT_STATUS_DMA);
HandleTransferDone();
}
// SDIO Interrupt Handling
if ( wIntStatus & NORMAL_INT_STATUS_CARD_INT ) {
DEBUGCHK(m_fSDIOInterruptsEnabled);
DEBUGMSG(SDHC_INTERRUPT_ZONE, (_T("SDHCControllerIst: Card interrupt!\n")));
EnableSDIOInterrupts(FALSE);
IndicateSlotStateChange(DeviceInterrupting);
}
// Card Detect Interrupt Handling
if (wIntStatus & (NORMAL_INT_STATUS_CARD_INSERTION | NORMAL_INT_STATUS_CARD_REMOVAL)) {
WriteWord(SDHC_NORMAL_INT_STATUS,
NORMAL_INT_STATUS_CARD_INSERTION | NORMAL_INT_STATUS_CARD_REMOVAL);
m_fCheckSlot = TRUE;
}
}
#ifdef _SMDK6410_CH0_EXTCD_
} // The end of "if(intType == SDSLOT_INT_CARD_DETECTED)"
#endif
if (m_fCheckSlot) {
m_fCheckSlot = FALSE;
#ifdef _SMDK6410_CH0_EXTCD_
// At this time, we have to validate the card present status.
if((IsCardPresent() == TRUE) && (m_fCardPresent != TRUE))
#else
// check card inserted or removed
DWORD dwPresentState = ReadDword(SDHC_PRESENT_STATE);
if (dwPresentState & STATE_CARD_INSERTED)
#endif
{
DEBUGMSG(SDHC_INTERRUPT_ZONE, (TEXT("SDHCControllerIst - Card is Inserted! \n")));
RETAILMSG(TRUE, (TEXT("[HSMMC0] SDHCControllerIst - Card is Inserted! \n")));
m_fFakeCardRemoval = FALSE;
if (m_fCardPresent == FALSE ) {
Start();
HandleInsertion();
}
}
#ifdef _SMDK6410_CH0_EXTCD_
else if((IsCardPresent() == FALSE))
#else
else
#endif
{
DEBUGMSG(SDHC_INTERRUPT_ZONE, (TEXT("SDHCControllerIst - Card is Removed! \n")));
RETAILMSG(TRUE, (TEXT("[HSMMC0] SDHCControllerIst - Card is Removed! \n")));
m_fFakeCardRemoval = FALSE;
if (m_fCardPresent) {
HandleRemoval(TRUE);
}
}
}
}
#ifdef _SMDK6410_CH0_EXTCD_
// New function can detect whether card is presented of HSMMC ch0 on SMDK6410.
BOOL CSDHCSlotBase::IsCardPresent()
{
BOOL fRetVal;
volatile S3C6410_GPIO_REG *pIOPreg = NULL;
PHYSICAL_ADDRESS ioPhysicalBase = {0,0};
ioPhysicalBase.LowPart = S3C6410_BASE_REG_PA_GPIO;
pIOPreg = (volatile S3C6410_GPIO_REG *)MmMapIoSpace(ioPhysicalBase, sizeof(S3C6410_GPIO_REG), FALSE);
if (pIOPreg == NULL) {
RETAILMSG (1,(TEXT("GPIO registers not mapped\r\n")));
return FALSE;
}
if ( (pIOPreg->GPNDAT & (0x1<<13)) == 0 ) {
fRetVal = TRUE;
} else {
fRetVal = FALSE;
}
MmUnmapIoSpace((PVOID)pIOPreg, sizeof(S3C6410_GPIO_REG));
return fRetVal;
}
#endif
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;
// 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
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);
DumpRequest(pRequest, 0);
IndicateBusRequestComplete(pRequest, SD_API_STATUS_DEVICE_REMOVED);
}
}
if (m_SlotDma) {
delete m_SlotDma;
m_SlotDma = NULL;
// 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);
WriteWord(SDHC_NORMAL_INT_STATUS, NORMAL_INT_STATUS_DMA);
// To diable the Data CRC error interrupt
WriteWord(SDHC_ERROR_INT_SIGNAL_ENABLE,0);
WriteWord(SDHC_ERROR_INT_STATUS,wErrIntStatus);
WriteWord(SDHC_ERROR_INT_SIGNAL_ENABLE,wErrIntSignalEn);
}
// 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;
// To control the Data CRC error
WORD wErrIntSignalEn = ReadWord(SDHC_ERROR_INT_SIGNAL_ENABLE);
WORD wErrIntStatusEn = ReadWord(SDHC_ERROR_INT_STATUS_ENABLE);
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
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -