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

📄 sdhcslot.cpp

📁 6410BSP3
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                    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;
        }
    }

    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(TRUE, (TEXT("[HSMMC1] SDHCControllerIst - Card is Inserted! \n")));
            m_fFakeCardRemoval = FALSE;
            if (m_fCardPresent == FALSE ) {
                Start();
                HandleInsertion();
            }
        }
        else {
            DEBUGMSG(SDHC_INTERRUPT_ZONE, (TEXT("SDHCControllerIst - Card is Removed! \n")));
            RETAILMSG(TRUE, (TEXT("[HSMMC1] SDHCControllerIst - Card is Removed! \n")));
            m_fFakeCardRemoval = FALSE;
            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;

    // 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);    
    }
    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
    // with allowance for power supply ramp-up time. (SD Phys Layer 6.4)
    // Note that power supply ramp-up time occurs in SetVoltage().
    SetClockRate(&dwClockRate);
    SDClockOn();
    DWORD dwSleepMs = (74 / (dwClockRate / 1000)) + 1;
    Sleep(dwSleepMs);
    SDClockOff();
    if (m_SlotDma) {
        ASSERT(FALSE);
        delete m_SlotDma;
        m_SlotDma = NULL;
    }

    if (!m_fDisableDMA) {
        SSDHC_CAPABILITIES caps = GetCapabilities();
        if (FALSE) { // Disable ADM2 support for now    // caps.bits.ADMA2
            m_SlotDma = new CSDHCSlotBase32BitADMA2(*this);
        }
        else if (caps.bits.SDMA) {
            m_SlotDma = new CSDHCSlotBaseSDMA(*this);
        }

        if (m_SlotDma && !m_SlotDma->Init()) { // failed.
            delete m_SlotDma;
            m_SlotDma = NULL;
        }
        ASSERT(!(caps.bits.ADMA2 || caps.bits.SDMA) || m_SlotDma!=NULL);
    }

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

    // Indicate device arrival
    IndicateSlotStateChange(DeviceInserted);

    // Disable the command and data CRC error
    WriteWord(SDHC_ERROR_INT_SIGNAL_ENABLE, (wErrIntSignalEn | (0x20)));
    WriteWord(SDHC_ERROR_INT_STATUS_ENABLE, (wErrIntStatusEn | (0x20)));
    v_gBspArgs->g_SDCardState = CARD_INSERTED;
    SetEvent( v_gBspArgs->g_SDCardDetectEvent );
}

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

    PSD_BUS_REQUEST pRequest;
    BOOL fRet = FALSE;

    // get the current request
    pRequest = GetAndLockCurrentRequest();
    DEBUGCHK(m_dwReadyInts == 0);

    if (pRequest) {
        DEBUGCHK(pRequest->HCParam == 0);
        // INT_TRX_COMPLETE is not suitable for s3c6410, so I comment out below code.
        // therefore, in order to keep fastpath status, those code like just below is needed.
        SD_API_STATUS transferStatus = (m_FastPathStatus >= SD_API_STATUS_SUCCESS) ? SD_API_STATUS_SUCCESS : m_FastPathStatus;

        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) {
                // Reset cmd and dat circuits
                SoftwareReset(SOFT_RESET_CMD | SOFT_RESET_DAT);
            }

            pdwResponseBuffer[0] = ReadDword(SDHC_R0);
            if (pRequest->CommandResponse.ResponseType == ResponseR2) {
                pdwResponseBuffer[1] = ReadDword(SDHC_R2);
                pdwResponseBuffer[2] = ReadDword(SDHC_R4);
                pdwResponseBuffer[3] = ReadDword(SDHC_R6);
            }
        }

        // check for command/response only
        if (TRANSFER_IS_COMMAND_ONLY(pRequest)) {
            IndicateBusRequestComplete(pRequest, transferStatus);
            fRet = TRUE;
        } else {
            // handle data phase transfer
            pRequest->HCParam = 0;
            fRet = FALSE;
        }
    }
    // else request must have been canceled due to an error

    return fRet;
}

VOID 
CSDHCSlotBase::HandleErrors(
        )
{
    SD_API_STATUS status = SD_API_STATUS_SUCCESS;

    // get the current request
    PSD_BUS_REQUEST pRequest = NULL;
    pRequest = GetAndLockCurrentRequest();

    WORD wErrorStatus = 0;
    WORD RetryCount = 100;

    do {
        wErrorStatus = ReadWord(SDHC_ERROR_INT_STATUS);
        RetryCount--;
    } while ((wErrorStatus == 0) || (RetryCount != 0));

    if (wErrorStatus == 0)
    {
        DEBUGMSG(SDCARD_ZONE_ERROR, 
                (TEXT("HandleErrors - ERROR INT STATUS=0x%02X\n"), wErrorStatus));
        return;
    }

    DEBUGMSG(SDCARD_ZONE_ERROR, 
            (TEXT("HandleErrors - ERROR INT STATUS=0x%02X\n"), wErrorStatus));
    if (pRequest) {
        DumpRequest(pRequest, SDCARD_ZONE_ERROR);
          // For simple debugging, we have to confirm the command number!
          RETAILMSG(TRUE, (TEXT("[HSMMC1] HandleErrors - ERR CMD:%d : "), pRequest->CommandCode));
    }

    DEBUGCHK( (wErrorStatus & ERR_INT_STATUS_VENDOR) == 0 );

    if (wErrorStatus) {
        if ( wErrorStatus & ERR_INT_STATUS_CMD_TIMEOUT ) {
            status = SD_API_STATUS_RESPONSE_TIMEOUT;
            switch(pRequest->CommandCode) {
                case 1 : RETAILMSG(TRUE, (TEXT("If the card is not a MMC, CMD 1 does not work in reason.\n")));
                    break;
                case 5 : RETAILMSG(TRUE, (TEXT("If the card is not a SDIO, CMD 5 does not work in reason.\n")));
                    break;
                case 8 : RETAILMSG(TRUE, (TEXT("If the card is not SD SPEC 2.0, CMD 8 does not work in reason.\n")));
                    break;
                default :
                    RETAILMSG(TRUE, (TEXT("[HSMMC1] HandleErrors - CMD Timeout Error...\n")));
                    break;
            }
        }

        if ( wErrorStatus & ERR_INT_STATUS_CMD_CRC ) {
            RETAILMSG(TRUE,(TEXT("[HSMMC1] HandleErrors - CMD CRC Error...\r\n")));            
            status = SD_API_STATUS_CRC_ERROR;
            if ( wErrorStatus & ERR_INT_STATUS_CMD_TIMEOUT )
                status = SD_API_STATUS_DEVICE_RESPONSE_ERROR;
        }

        if ( wErrorStatus & ERR_INT_STATUS_CMD_ENDBIT ) {
            RETAILMSG(TRUE,(TEXT("[HSMMC1] HandleErrors - CMD ENDBIT Error...\r\n")));                        
            status = SD_API_STATUS_RESPONSE_TIMEOUT;
        }

        if ( wErrorStatus & ERR_INT_STATUS_CMD_INDEX ) {
            RETAILMSG(TRUE,(TEXT("[HSMMC1] HandleErrors - CMD INDEX Error...\r\n")));            
            status = SD_API_STATUS_DEVICE_RESPONSE_ERROR;
        }

        if ( wErrorStatus & ERR_INT_STATUS_DAT_TIMEOUT ) {
            RETAILMSG(TRUE,(TEXT("[HSMMC1] HandleErrors - DAT Timeout Error...\r\n")));            
            status = SD_API_STATUS_DATA_TIMEOUT;
        }

        if ( wErrorStatus & ERR_INT_STATUS_DAT_CRC ) {
            RETAILMSG(TRUE,(TEXT("[HSMMC1] HandleErrors - Data CRC Error...\r\n")));              
            status = SD_API_STATUS_CRC_ERROR;
        }

        if ( wErrorStatus & ERR_INT_STATUS_DAT_ENDBIT ) {
            RETAILMSG(TRUE,(TEXT("[HSMMC1] HandleErrors - DAT END BIT Error...\r\n")));            
            status = SD_API_STATUS_DEVICE_RESPONSE_ERROR;
        }

        if ( wErrorStatus & ERR_INT_STATUS_BUS_POWER ) {
            RETAILMSG(TRUE,(TEXT("[HSMMC1] HandleErrors - Bus Power Error...\r\n")));
            status = SD_API_STATUS_DEVICE_RESPONSE_ERROR;
        }

        if ( wErrorStatus & ERR_INT_STATUS_AUTOCMD12 ) {
            RETAILMSG(TRUE,(TEXT("[HSMMC1] HandleErrors - AUTOCMD12 Error...\r\n")));            
            status = SD_API_STATUS_DEVICE_RESPONSE_ERROR;
        }

        if (wErrorStatus & ERR_INT_STATUS_ADMA) { // ADMA Error
            RETAILMSG(TRUE,(TEXT("[HSMMC1] HandleErrors - ADMA Error...\r\n")));
            if (m_SlotDma && pRequest ) {
                m_SlotDma->DMANotifyEvent(*pRequest, DMA_ERROR_OCCOR );
            }
            else {

⌨️ 快捷键说明

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