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

📄 sddevice.cpp

📁 6410BSP3
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                if (fSDMemory && SD_API_SUCCESS(status)) {
                    status = SDSynchronousBusRequest_I(SD_CMD_GO_IDLE_STATE,
                            0x00000000,SD_COMMAND,NoResponse,NULL,0,0,NULL,(DWORD)SD_SLOTRESET_REQUEST);
                    if (SD_API_SUCCESS(status))  {
                        DbgPrintZo(SDCARD_ZONE_ERROR,(TEXT("CSDSlot: Go Idle Failed during deselection: Status: 0x%08X \n"),
                                    status));
                    }

                }
            }
            m_RelativeAddress = 0;
            m_bCardDeselectRequest = FALSE;
        }
    }
    return status;
}

///////////////////////////////////////////////////////////////////////////////
//  DeactivateCardDetect - Deativate Card Detect resistors on SD devices
//  Input:  pBaseDevice - the base device
//          BaseDeviceType - the base device type
//          pSlot - the slot
//  Output: 
//  Return : SD_API_STATUS code
//  Notes:  This function deactivates the card detect resistor for SDIO,
//          SD and or Combo cards
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS CSDDevice::DeactivateCardDetect()
{
    UCHAR                   regValue;       // intermediate value
    SD_API_STATUS           status;         // status
    SD_COMMAND_RESPONSE     response;       // response
    BOOL                    fDisableSDIO;   // disable SDIO portion?

    ASSERT(m_FuncionIndex == 0);
    if (Device_SD_IO == m_DeviceType ) {
        fDisableSDIO = TRUE;
    }
    else if (Device_SD_Combo == m_DeviceType) {
        fDisableSDIO = TRUE;

        // *** Combo Card Issue ***
        // SDIO 1.00 requires that both memory and SDIO portions of combo
        // cards be deactivated.
        // SDIO 1.10 only requires one of memory or SDIO combo to be disabled. (4.6)
        // Some 1.10 cards have a problem where only one can be disabled--disabling 
        // both simultaneously will fail.
        //
        // Our solution is to disable both for < 1.10 and only disable memory 
        // for >= 1.10.

        BYTE bSDIORevision; // SDIO spec version
        status = SDReadWriteRegistersDirect_I(SD_IO_READ, SD_IO_REG_CCCR, FALSE, &bSDIORevision, sizeof(bSDIORevision));
        if (!SD_API_SUCCESS(status)) {
            DEBUGMSG(SDCARD_ZONE_ERROR, 
                    (TEXT("SDBusDriver: Failed to read SDIO revision in slot %d. We will treat it as a 1.0 combo card \n"),
                     m_sdSlot.GetSlotIndex()));
        }
        else {
            bSDIORevision >>= 4; // SDIO revision is in the upper four bits.
            if (bSDIORevision != 0x0) {
                fDisableSDIO = FALSE;
            }
        }
    }
    else {
        DEBUGCHK(Device_SD_Memory == m_DeviceType || 
                Device_MMC == m_DeviceType);
        fDisableSDIO = FALSE;
    }

    // for SD memory or combo, send ACMD42 to turn off card detect resistor
    if ( (Device_SD_Memory == m_DeviceType) || 
            (Device_SD_Combo == m_DeviceType) ) {
        // send ACMD42
        status = SendSDAppCommand(SD_ACMD_SET_CLR_CARD_DETECT,
                0x00000000,  // bit 0 - cleared to disconnect pullup resistor
                ResponseR1,
                &response);

        if (!SD_API_SUCCESS(status)){
            DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: Failed to turn off CD resistor in slot %d \n"), m_sdSlot.GetSlotIndex())); 
            return status;
        }
    }

    // for SD I/O or SD Combo cards, write to the Bus Interface control register and clear the CD bit
    if (fDisableSDIO) {
        regValue = SD_IO_BUS_CONTROL_CD_DETECT_DISABLE; 

        status = SDReadWriteRegistersDirect_I(SD_IO_WRITE,
                SD_IO_REG_BUS_CONTROL,
                TRUE,        // read after write
                &regValue,
                1);

        if (!SD_API_SUCCESS(status)){
            DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: Failed to turn off CD resistor for SDIO Device in slot %d \n"), m_sdSlot.GetSlotIndex())); 
            return status;
        }
    }

    return SD_API_STATUS_SUCCESS;
}
///////////////////////////////////////////////////////////////////////////////
//  UpdateCachedRegisterFromResponse - update the device shadow registers from the
//                                     information in the response buffer
//  Input:  pDevice - the device who's shadowed register should be updated
//          Register - the information to update
//          pResponse - the response containing the register data
//  Output: 
//  Return
//  Notes:  
//         
///////////////////////////////////////////////////////////////////////////////
VOID CSDDevice::UpdateCachedRegisterFromResponse(SD_INFO_TYPE  Register,PSD_COMMAND_RESPONSE     pResponse) 
{

    switch (Register) { 

        case SD_INFO_REGISTER_CID:
            memcpy(m_CachedRegisters.CID, pResponse->ResponseBuffer, SD_CID_REGISTER_SIZE);
            break;
        case SD_INFO_REGISTER_RCA:
            // RCA is in bytes 3,4
            m_RelativeAddress = (SD_CARD_RCA)pResponse->ResponseBuffer[3];
            m_RelativeAddress |= ((SD_CARD_RCA)pResponse->ResponseBuffer[4]) << 8;
            break;
        case SD_INFO_REGISTER_OCR: 
            m_CachedRegisters.OCR[3] = pResponse->ResponseBuffer[4];
            m_CachedRegisters.OCR[2] = pResponse->ResponseBuffer[3];
            m_CachedRegisters.OCR[1] = pResponse->ResponseBuffer[2];
            m_CachedRegisters.OCR[0] = pResponse->ResponseBuffer[1];
            break;
        case SD_INFO_REGISTER_CSD:
            memcpy(m_CachedRegisters.CSD, pResponse->ResponseBuffer, SD_CSD_REGISTER_SIZE);
            break;
        case SD_INFO_REGISTER_IO_OCR:
            m_CachedRegisters.IO_OCR[2] = pResponse->ResponseBuffer[3];
            m_CachedRegisters.IO_OCR[1] = pResponse->ResponseBuffer[2];
            m_CachedRegisters.IO_OCR[0] = pResponse->ResponseBuffer[1];
            break;
        default:
            DEBUGCHK(FALSE);
    }

}
SD_API_STATUS  CSDDevice::SetOperationVoltage(SDCARD_DEVICE_TYPE DeviceType,BOOL SetHCPower)
{
    SD_API_STATUS status = SD_API_STATUS_DEVICE_UNSUPPORTED;
    if (SetHCPower) {
        DWORD ocrValue;
        ASSERT(m_FuncionIndex == 0 );
        if (m_DeviceType == Device_SD_Memory || m_DeviceType == Device_MMC) {
            ocrValue = (DWORD)m_CachedRegisters.OCR[0] & ~0xF;
            ocrValue |= ((DWORD)m_CachedRegisters.OCR[1]) << 8;  
            ocrValue |= ((DWORD)m_CachedRegisters.OCR[2]) << 16; 
        }
        else if (m_DeviceType == Device_SD_IO || m_DeviceType == Device_SD_Combo) {
            ocrValue = (DWORD)m_CachedRegisters.IO_OCR[0] & ~0xF;
            ocrValue |= ((DWORD)m_CachedRegisters.IO_OCR[1]) << 8; 
            ocrValue |= ((DWORD)m_CachedRegisters.IO_OCR[2]) << 16;
        }
        else 
            ASSERT(FALSE);
        m_OperatingVoltage = m_sdSlot.SDGetOperationalVoltageRange(ocrValue);
    }
    // check to see if the voltages can be supported
    if (0 != m_OperatingVoltage ) {

        // power up the card
        status = SetCardPower(DeviceType, m_OperatingVoltage, SetHCPower);
    }
    return status;

}

///////////////////////////////////////////////////////////////////////////////
//  SetCardPower - Set the card power
//  Input:  DeviceType - the device type 
//          OperatingVoltageMask - operating voltage mask
//          pSlot - the slot
//          SetHCPower - flag to indicate whether the power should be set in the HC
//                       (combo cards do not need to reset power if the I/O portion
//                        was already powered).     
//              
//  Output: 
//  Return: SD_API_STATUS code
//  Notes:  
//          This function sets the card power and polls the card until it is
//          not busy
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS CSDDevice::SetCardPower(SDCARD_DEVICE_TYPE DeviceType,DWORD OperatingVoltageMask,BOOL SetHCPower)
{
    SD_API_STATUS       status = SD_API_STATUS_SUCCESS;  // intermediate status 
    SD_COMMAND_RESPONSE response;                        // response
    UCHAR               command;                         // command
    SD_RESPONSE_TYPE    responseType;                    // response type
    ULONG               powerUpRetries;                  // power up retries
    BOOL                appcmd = FALSE;                  // command is an app cmd
    ULONG               powerUpInterval;                 // powerup interval
    ULONG               totalPowerUpTime;                // total powerup time
    ULONG               powerUpIntervalByDevice;         // powerup interval by device

    switch (DeviceType) {

        case Device_MMC:
            command = SD_CMD_MMC_SEND_OPCOND;
            responseType = ResponseR3;
            powerUpIntervalByDevice = DEFAULT_POWER_UP_MMC_POLL_INTERVAL;
            break;
        case Device_SD_IO:
            command = SD_CMD_IO_OP_COND;
            responseType = ResponseR4;
            powerUpIntervalByDevice = DEFAULT_POWER_UP_SDIO_POLL_INTERVAL;
            break;
        case Device_SD_Memory:
            command = SD_ACMD_SD_SEND_OP_COND;
            responseType = ResponseR3;
            appcmd = TRUE;
            powerUpIntervalByDevice = DEFAULT_POWER_UP_SD_POLL_INTERVAL;
            break;
        default:
            DEBUGCHK(FALSE);
            return SD_API_STATUS_INVALID_PARAMETER;
    }

    // check to see if we need to apply power
    if (SetHCPower) {
        DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDBusDriver: Setting slot %d power to 0x%08X \n"), 
                    m_sdSlot.GetSlotIndex(), OperatingVoltageMask)); 
        // set slot power           
        status = m_sdSlot.SDSetSlotPower(OperatingVoltageMask);    

        if (!SD_API_SUCCESS(status)) {
            DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: Host failed to set slot power 0x%08X on slot:%d \n"),
                        status, m_sdSlot.GetSlotIndex()));
            return status;
        }

        m_sdSlot.DelayForPowerUp();
    }

    if (Device_SD_IO != DeviceType) {
        // put the card into idle again
        status = SendSDCommand(SD_CMD_GO_IDLE_STATE, 0x00000000, NoResponse, NULL);
        if (!SD_API_SUCCESS(status)){
            DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: Go Idle Failed during powerup: Status: 0x%08X on slot:%d \n"),status,
                        m_sdSlot.GetSlotIndex()));
            return status;
        }
        if ((Device_SD_Memory == DeviceType || Device_MMC==DeviceType) && IsValid20Card()) {
            OperatingVoltageMask |= 0x40000000; // HCS
        }
    }

    totalPowerUpTime = CSDHostContainer::RegValueDWORD(POWER_UP_POLL_TIME_KEY, DEFAULT_POWER_UP_TOTAL_WAIT_TIME);
    powerUpInterval = CSDHostContainer::RegValueDWORD(POWER_UP_POLL_TIME_INTERVAL_KEY, powerUpIntervalByDevice);

    powerUpRetries = totalPowerUpTime/powerUpInterval;

    DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDBusDriver: Power Set, checking card in slot %d, MaxRetries: %d, Time: %d MS, Interval: %d MS \n"), 
                m_sdSlot.GetSlotIndex(), powerUpRetries, totalPowerUpTime , powerUpInterval)); 

    while (powerUpRetries != 0) {

        if (appcmd) {
            // send it as an APP cmd
            status = SendSDAppCommand(command,
                    OperatingVoltageMask,
                    responseType,
                    &response);
        } else {
#ifdef _MMC_SPEC_42_
            /**
             * Description : To support MMC Spec 4.2
             */
            OperatingVoltageMask |= (1<<30);
#endif
            // send the command to get the ready bit
            status = SendSDCommand(command,
                    OperatingVoltageMask,
                    responseType,
                    &response);
        }

⌨️ 快捷键说明

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