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

📄 sddevice.cpp

📁 6410BSP3
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                break;
            else if (++m_dwCurSearchIndex>=m_dwArraySize)
                m_dwCurSearchIndex = 0 ;
        } while (dwStopIndex != m_dwCurSearchIndex);

        ASSERT(m_dwCurSearchIndex<m_dwArraySize);
        if( m_dwCurSearchIndex < m_dwArraySize && m_rgObjectArray[m_dwCurSearchIndex] == NULL )  {
            pReturn = m_rgObjectArray[m_dwCurSearchIndex] = pObject;
            pReturn->AddRef();
            if( pdwIndex )
                *( pdwIndex ) = m_dwCurSearchIndex;
        };
        Unlock();
        return pReturn;
    }
    else
    {
        return NULL;
    }
}
///////////////////////////////////////////////////////////////////////////////
//  GetCardRegisters - Get card registers
//  Input:  pBaseDevice - the base device
//          BaseDeviceType - base device type
//          pSlot - the slot
//  Output: 
//  Return:  SD_API_STATUS code
//  Notes:  This function retreives important card registers for the device type
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS CSDDevice::GetCardRegisters()
{
    if (m_FuncionIndex!=0) {
        ASSERT(FALSE);
        return SD_API_STATUS_DEVICE_UNSUPPORTED;
    }
    SD_API_STATUS               status = SD_API_STATUS_DEVICE_UNSUPPORTED;    // status
    SD_COMMAND_RESPONSE         response;  // response
    UCHAR                       scrReg[SD_SCR_REGISTER_SIZE]; // temporary buffer
    USHORT                      oidValue;  // oid value
    SD_CARD_STATUS              cardStatus; // card status

    // must get CID first in order to get the cards into the IDENT state.
    // Check for SD I/O - only cards; will not have  CID.
    if (Device_SD_IO != m_DeviceType) {
        DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("CSDDevice:  Getting registers from slot %d \n"), m_sdSlot.GetSlotIndex())); 

        // for MMC, SD Memory and SD Combo cards, retreive the CID
        status = SendSDCommand(SD_CMD_ALL_SEND_CID,0x00000000,ResponseR2,&response);

        if (!SD_API_SUCCESS(status)){
            return status;
        }

        DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("CSDDevice: Got CID from device in slot %d \n"), m_sdSlot.GetSlotIndex())); 
        // update shadow registers
        UpdateCachedRegisterFromResponse( SD_INFO_REGISTER_CID, &response);
    }

    // fetch/set the RCA
    if (Device_MMC != m_DeviceType) {
        DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("CSDDevice: Getting RCA from SD card in  slot %d .... \n"),m_sdSlot.GetSlotIndex())); 
        // get the RCA
        status = SendSDCommand(SD_CMD_SEND_RELATIVE_ADDR, 0x00000000,ResponseR6,&response);

        if (!SD_API_SUCCESS(status)){
            return status;
        }
        // update shadow registers
        UpdateCachedRegisterFromResponse(SD_INFO_REGISTER_RCA, &response);

        DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("CSDDevice: Got RCA (0x%04X) from SD card in slot %d \n"), 
                    m_RelativeAddress, m_sdSlot.GetSlotIndex())); 
    } else {
        // get OEM ID from the CID
        oidValue = m_CachedRegisters.CID[SD_CID_OID_OFFSET];
        oidValue |= (((USHORT)m_CachedRegisters.CID[SD_CID_OID_OFFSET + 1]) << 8);

        // for MMC cards set the RCA
        // take the unique OEM ID and add the slot number to it to form a system unique address
        m_RelativeAddress = (SD_CARD_RCA)(oidValue + m_sdSlot.GetSlotIndex());

        // add 1 if this is zero
        if (m_RelativeAddress == 0) {
            m_RelativeAddress++;
        }
        // for MMC cards, we must set the RCA
        DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("CSDDevice: Setting MMC RCA to 0x%04X .... \n"), m_RelativeAddress)); 

        // set the RCA
        status = SendSDCommand(SD_CMD_MMC_SET_RCA,((DWORD)m_RelativeAddress) << 16, ResponseR1,&response);

        if (!SD_API_SUCCESS(status)){
            return status;
        }

        DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("CSDDevice: RCA set for MMC device in slot %d \n"), m_sdSlot.GetSlotIndex())); 
    }

    // now that the RCA has been fetched/set, we can move on to do other things.........

    // check for SD I/O - Only cards. They will not have a CSD or card status
    if (Device_SD_IO != m_DeviceType) {
        DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("CSDDevice: Getting CSD in slot %d .... \n"), m_sdSlot.GetSlotIndex())); 

        // get the CSD
        status = SendSDCommand(SD_CMD_SEND_CSD,
                ((DWORD)m_RelativeAddress) << 16,
                ResponseR2,
                &response);

        if (!SD_API_SUCCESS(status)){
            return status;
        }

        // update shadow registers
        UpdateCachedRegisterFromResponse(SD_INFO_REGISTER_CSD, &response);
        DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("CSDDevice: Got CSD from device in slot %d \n"), m_sdSlot.GetSlotIndex())); 
        // get the card status
        status = SendSDCommand( SD_CMD_SEND_STATUS,((DWORD)m_RelativeAddress) << 16,ResponseR1, &response);
        if (!SD_API_SUCCESS(status)){
            return status;
        }


        SDGetCardStatusFromResponse(&response, &cardStatus);

        if (cardStatus & SD_STATUS_CARD_IS_LOCKED) {
            DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("CSDDevice: card in slot %d is locked\n"), m_sdSlot.GetSlotIndex())); 
            m_SDCardInfo.SDMMCInformation.CardIsLocked = TRUE;
        }

    }

    // now in order to get the SCR register we must be in the trans state
    // also in order to do a few other things, so lets select the card now and leave it
    // selected
    // send CMD 7 to select the card and keep it selected, this is required  for SDIO cards
    // too as mentioned in I/O working group newsgroup
    status = SendSDCommand( SD_CMD_SELECT_DESELECT_CARD,((DWORD)m_RelativeAddress) << 16, ResponseR1b, &response);

    if (!SD_API_SUCCESS(status)){
        DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("CSDDevice: Failed to select card in slot %d \n"), m_sdSlot.GetSlotIndex()));     
        return status;
    }

    DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("CSDDevice:Card in slot %d is now selected \n"), m_sdSlot.GetSlotIndex())); 

    // only SD Memory and Combo cards have an SCR
    if ((Device_SD_Memory == m_DeviceType) || (Device_SD_Combo == m_DeviceType)) {
        // if the card is unlocked, get the SCR
        if (!m_SDCardInfo.SDMMCInformation.CardIsLocked) {
            // get the SD Configuration register
            status = SendSDAppCmd(SD_ACMD_SEND_SCR, 0, SD_READ,  ResponseR1,&response,
                    1,                    // 1 block
                    SD_SCR_REGISTER_SIZE, // 64 bits
                    scrReg);

            // If the memory card is locked then the SCR becomes inaccessable. If we fail
            // to read the SCR then just set up the cached SCR register to default to
            // a 1bit access mode.

            if (!SD_API_SUCCESS(status)){
                DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("CSDDevice: Failed to get SCR from device in slot %d \n"), m_sdSlot.GetSlotIndex()));
                memset(m_CachedRegisters.SCR, 0, sizeof(m_CachedRegisters.SCR));
            } else {            
                // this is a spec discrepency, since the SCR register is not associated with 
                // an address, the byte order it ambiguous.  All the cards we have seen store the data 
                // most significant byte first as it arrives.  
                for (ULONG ii = 0 ; ii < sizeof(m_CachedRegisters.SCR); ii++) {
                    m_CachedRegisters.SCR[ii] = scrReg[(SD_SCR_REGISTER_SIZE - 1) - ii];
                }

                DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDBusDriver: Got SCR from device in slot %d \n"), m_sdSlot.GetSlotIndex()));     
            }
        }
    }

    return SD_API_STATUS_SUCCESS;
}
SD_API_STATUS CSDDevice::HandleDeviceSelectDeselect(SD_SLOT_EVENT SlotEvent,BOOL fSelect)
{
    SD_API_STATUS          status = SD_API_STATUS_SUCCESS;
    UCHAR                  regValue;
    SD_COMMAND_RESPONSE    response;
    DbgPrintZo(SDBUS_ZONE_DEVICE, (TEXT("CSDDevice: HandleSlotSelectDeselect++: %d \n"),SlotEvent));
    BOOL fSDIO = FALSE;
    BOOL fSDMemory = FALSE;

    if (m_DeviceType ==Device_SD_IO ||  m_DeviceType == Device_SD_Combo ) {
        fSDIO = TRUE;
    }
    if ((m_DeviceType == Device_MMC) || (m_DeviceType == Device_SD_Memory) ||(m_DeviceType == Device_SD_Combo)) { 
        fSDMemory = TRUE;
    }

    if (fSelect) {
        if (m_FuncionIndex == 0 ) {
            // Select I/O controller first
            if (fSDIO) {
                if ( m_sdSlot.GetSlotState()!= SlotDeselected ) {
                    // reset I/O controller 
                    regValue = SD_IO_REG_IO_ABORT_RES;
                    status = SDSynchronousBusRequest_I(SD_IO_RW_DIRECT,
                            BUILD_IO_RW_DIRECT_ARG((UCHAR)SD_IO_WRITE,FALSE,0,(SD_IO_REG_IO_ABORT),SD_IO_REG_IO_ABORT_RES),
                            SD_COMMAND,ResponseR5,&response,0,0,NULL,(DWORD)SD_SLOTRESET_REQUEST); 
                    m_RelativeAddress = 0;
                }

                // Query OCR
                if (SD_API_SUCCESS(status)) {
                    status = SendSDCommand(SD_CMD_IO_OP_COND,0,ResponseR4,&response);
                }

                // Re-init I/O controller by powering it up
                if (SD_API_SUCCESS(status)) {
                    status = SetCardPower(Device_SD_IO,m_OperatingVoltage,FALSE);
                }

                if (SD_API_SUCCESS(status)) {
                    status = GetCardRegisters();
                }
                else {
                    DbgPrintZo(SDCARD_ZONE_ERROR, (TEXT("CSDSlot: Failed to power up SDIO card \n")));  
                }
            }
            if (fSDMemory) {

                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)) {
                    m_RelativeAddress = 0;
                }
                else{
                    DbgPrintZo(SDCARD_ZONE_ERROR,
                            (TEXT("CSDSlot: Go Idle Failed during selection: Status: 0x%08X on slot:%d \n"),status,m_sdSlot.GetSlotIndex()));
                }
                if (SD_API_SUCCESS(status)) { 
                    if ((m_DeviceType == Device_SD_Memory) || (m_DeviceType == Device_SD_Combo)) {
                        status = SendSDAppCommand(SD_ACMD_SD_SEND_OP_COND,0,ResponseR3,&response);
                    }
                }
                // Should I send CMD1 for MMC card here????  TODO!!!

                // Now it is ready to re-initialize memory controller.
                // Re-initialize memory controller by powering it up
                // SetCardPower will send CMD0 first before issuing ACMD41
                if (SD_API_SUCCESS(status)) { 
                    status = SetCardPower(m_DeviceType, m_OperatingVoltage,FALSE);
                }
                // For SD Memory, GetCardRegisters will do the following things:
                //  Issue CMD2 to make memory state trans to IDENT
                //  Issue CMD3 to get or set RCA
                //  Issue CMD7 to select the card again
                //  For SD Memory card, additional ACMD51 would be issued too, but
                //  should not have impact for init process.
                if (SD_API_SUCCESS(status)) { 
                    status = GetCardRegisters();
                }
            }
        }
        else {
            CSDDevice * pDevice0 = m_sdSlot.GetFunctionDevice(0);
            if (pDevice0) {
                CopyContentFromParent(*pDevice0);
                pDevice0->DeRef();
            }
        }
    }
    else {// De select Card.
        if ((SlotEvent == SlotResetRequest) || (SlotEvent == SlotDeselectRequest)) {
            DbgPrintZo(SDBUS_ZONE_DEVICE, (TEXT("CSDSlot: Deselect the card\n")));

            if (m_FuncionIndex == 0 ) {
                // deselect I/O controller first, see SDIO Spec v1.1 Section 3.4.4
                if (fSDIO) {
                    regValue = SD_IO_REG_IO_ABORT_RES;
                    status = SDReadWriteRegistersDirect_I(SD_IO_WRITE,SD_IO_REG_IO_ABORT,FALSE,&regValue,1);
                    if (SD_API_SUCCESS(status))  {
                        // TODO, should CCCRShadowIntEnable to be updated???
                        m_SDCardInfo.SDIOInformation.pCommonInformation->CCCRShadowIOEnable = 0;
                    }
                    else {
                        DbgPrintZo(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: Failed to deselect SDIO card \n")));  
                    }
                }

⌨️ 快捷键说明

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