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

📄 sdhcslot.cpp

📁 2443 wince5.0 bsp, source code
💻 CPP
📖 第 1 页 / 共 5 页
字号:
			
        // BlockCount
        DEBUGMSG(SDHC_SEND_ZONE,(TEXT("Sending command block count 0x%04X\r\n"), 
            (WORD) pRequest->NumBlocks));            
        WriteWord(SDHC_BLOCKCOUNT, (WORD) pRequest->NumBlocks);

        if (pRequest->Flags & SD_AUTO_ISSUE_CMD12) {
            wRegTxnMode |= TXN_MODE_AUTO_CMD12;
        }

        if (TRANSFER_IS_READ(pRequest)) {
            wRegTxnMode |= TXN_MODE_DATA_DIRECTION_READ;     
        }

        // check dat inhibit, wait until okay
        fSuccess = WaitForReg<DWORD>(ReadDword, SDHC_PRESENT_STATE, STATE_DAT_INHIBIT, 0); 
        if (!fSuccess) {
            DEBUGMSG(SDCARD_ZONE_ERROR, (_T("%s Timeout waiting for DAT Inhibit\r\n"),
                pszFname));
            status = SD_API_STATUS_DEVICE_NOT_RESPONDING;
            goto EXIT;
        }
        
        DEBUGMSG(SDHC_SEND_ZONE,(TEXT("Sending Transfer Mode 0x%04X\r\n"),wRegTxnMode));	
        WriteWord(SDHC_TRANSFERMODE, wRegTxnMode);
    }
    else {
		RETAILMSG(0,(TEXT("Command Only\n")));
        // Command-only
        if (pRequest->CommandCode == SD_CMD_STOP_TRANSMISSION) {
            wRegCommand |= CMD_TYPE_ABORT;
        }
        else if (TransferIsSDIOAbort(pRequest)) {
            // Use R5b For CMD52, Function 0, I/O Abort
            DEBUGMSG(SDHC_SEND_ZONE, (TEXT("Sending Abort command \r\n")));
            wRegCommand |= CMD_TYPE_ABORT | CMD_RESPONSE_R1B_R5B;
        }
	
        // The following is required for the Pegasus. If it is not present,
        // command-only transfers will sometimes fail (especially R1B and R5B).
        WriteDword(SDHC_SYSTEMADDRESS_LO, 0);
        WriteWord(SDHC_BLOCKSIZE, 0);
        WriteWord(SDHC_BLOCKCOUNT, 0);
    }


	if(pRequest->CommandCode == 1) pRequest->CommandArgument = 0xFF8000;	// added by JJG
	
    RETAILMSG(0,(TEXT("Sending command register 0x%04X\r\n"),wRegCommand));
    RETAILMSG(0,(TEXT("Sending command Argument 0x%08X\r\n"),pRequest->CommandArgument));
    RETAILMSG(0,(TEXT("Sending command IntStatusEn 0x%08X\r\n"),wIntStatusEn));

    DEBUGMSG(SDHC_SEND_ZONE,(TEXT("Sending command register 0x%04X\r\n"),wRegCommand));
    DEBUGMSG(SDHC_SEND_ZONE,(TEXT("Sending command Argument 0x%08X\r\n"),pRequest->CommandArgument));

    WriteDword(SDHC_ARGUMENT_0, pRequest->CommandArgument);

    // Enable transfer interrupt sources.
    WriteWord(SDHC_NORMAL_INT_STATUS_ENABLE, wIntStatusEn);

    // Turn the clock on. It is turned off in IndicateBusRequestComplete().
    SDClockOn();

    // Turn the LED on.
    EnableLED(TRUE);

    // Writing the upper byte of the command register starts the command.
    // All register initialization must already be complete by this point.
    WriteWord(SDHC_COMMAND, wRegCommand);
	
    status = SD_API_STATUS_PENDING;
    RETAILMSG(0,(TEXT("Sending command IntStatusEn 0x%08X\r\n"),ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE)));
EXIT:
    return status;
}


VOID 
CSDHCSlotBase::EnableSDIOInterrupts(
                                    BOOL fEnable
                                    )
{
    Validate();

    if (fEnable) {
        m_fSDIOInterruptsEnabled = TRUE;
        DoEnableSDIOInterrupts(fEnable);
    }
    else {
        DoEnableSDIOInterrupts(fEnable);
        m_fSDIOInterruptsEnabled = FALSE;
    }
}


VOID 
CSDHCSlotBase::HandleInterrupt(
                               )
{
    Validate();

    WORD wIntStatus = ReadWord(SDHC_NORMAL_INT_STATUS);

	RETAILMSG(0,(TEXT("Status = 0x%X\n"),wIntStatus));	

    if (m_fFakeCardRemoval && m_fCardPresent) {
    	RETAILMSG(0,(TEXT("Wakeup !!!!!! m_fFakeCardRemoval && m_fCardPresent\n")));
        m_fFakeCardRemoval = FALSE;
        HandleRemoval(TRUE);
    }
		
    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();

        }
		//if ( wIntStatus & NORMAL_INT_STATUS_CMD_COMPLETE ) {
        // Command Complete handling.
        else if ( wIntStatus & NORMAL_INT_STATUS_CMD_COMPLETE ) {		// modifyed by JJG 06.10.11
            // 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);
                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_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")));

            // 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);
            //WriteWord(SDHC_NORMAL_INT_STATUS, NORMAL_INT_STATUS_CARD_INT);
		//RETAILMSG(1,(TEXT("SDHC_NORMAL_INT_STATUS=0x%X\n"),ReadWord(SDHC_NORMAL_INT_STATUS)));			
            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;
        }
    }			
    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);
            }
        }
    } 
}


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 (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);
        WriteWord(SDHC_NORMAL_INT_STATUS, NORMAL_INT_STATUS_DMA);
    }
}


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

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

	

    //while(1);
    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);
}


BOOL 
CSDHCSlotBase::HandleCommandComplete(
                                     )
{
    SETFNAME();
    
    PSD_BUS_REQUEST pRequest;
    BOOL fRet = FALSE;

	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);
        SD_API_STATUS transferStatus = SD_API_STATUS_SUCCESS;
        
        if (NoResponse != pRequest->CommandResponse.ResponseType) {
            // Copy response over to request structure. Note that this is a 
            // bus driver buffer, so we do not need to SetProcPermissions 
            // or __try/__except.
            UNALIGNED DWORD *pdwResponseBuffer = 
                (PDWORD) (pRequest->CommandResponse.ResponseBuffer + 1); // Skip CRC
            WORD wCommand = ReadWord(SDHC_COMMAND);

            if ((wCommand & CMD_RESPONSE_R1B_R5B) == CMD_RESPONSE_R1B_R5B) {
                // wait for Transfer Complete status, which indicate the busy wait is over.
                // we should not handle this TXN_COMPLETE interrupt in IST in this case
                
		/*
		 RETAILMSG(0,(TEXT("HandleCommandComplete Status: 0x%X\n"),ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE)));				
		 RETAILMSG(0,(TEXT("HandleCommandComplete Signal: 0x%X\n"),ReadWord(SDHC_NORMAL_INT_SIGNAL_ENABLE)));								
                BOOL fSuccess = WaitForReg<WORD>(ReadWord, SDHC_NORMAL_INT_STATUS, 
                    NORMAL_INT_STATUS_TRX_COMPLETE, NORMAL_INT_STATUS_TRX_COMPLETE, 5000);
                    RETAILMSG(0, (_T("%s Go waiting for NORMAL_INT_STATUS_TRX_COMPLETE\r\n"),
                        pszFname));					
                if (!fSuccess) {
                    RETAILMSG(0, (_T("%s Timeout waiting for NORMAL_INT_STATUS_TRX_COMPLETE\r\n"),
                        pszFname));					
                    DEBUGMSG(SDCARD_ZONE_ERROR, (_T("%s Timeout waiting for NORMAL_INT_STATUS_TRX_COMPLETE\r\n"),
                        pszFname));
                    transferStatus = SD_API_STATUS_RESPONSE_TIMEOUT;
                }*/

		   RETAILMSG(0,(TEXT("CSDHCSlotBase::HandleCommandComplete    SoftwareReset\n")));	
                // Reset cmd and dat circuits
                SoftwareReset(SOFT_RESET_CMD | SOFT_RESET_DAT);
            }
		
            pdwResponseBuffer[0] = ReadDword(SDHC_R0);
            RETAILMSG(0,(TEXT("pdwResponseBuffer[0]= 0x%X\n"),pdwResponseBuffer[0]));
            if (pRequest->CommandResponse.ResponseType == ResponseR2) {
                pdwResponseBuffer[1] = ReadDword(SDHC_R2);
                pdwResponseBuffer[2] = ReadDword(SDHC_R4);
                pdwResponseBuffer[3] = ReadDword(SDHC_R6);
            RETAILMSG(0,(TEXT("pdwResponseBuffer[1]= 0x%X\n"),pdwResponseBuffer[1]));

⌨️ 快捷键说明

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