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

📄 sdhceventhandlers.cpp

📁 S3C2443 WINCE6.0 BSP
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                           DWORD                Argument,
                           SD_TRANSFER_CLASS    TransferClass,
                           SD_RESPONSE_TYPE     ResponseType,
                           PSD_COMMAND_RESPONSE pResponse,
                           DWORD                NumberOfBlocks,
                           ULONG                BlockSize,
                           PUCHAR               pBlockBuffer)
{
    SD_API_STATUS          status;          // intermediate status
    PSDCARD_DEVICE_CONTEXT pDevice;         // the device context 
    CSDBusDriver           *pBusDriver;     // the bus driver
    ULONG                  retryCount;      // retry count
    ULONG                  i;               // loop variable
    DWORD                  clientFlags;     // client flags backup 


    // send the APP Command primer (CMD 55)
    status = SendSDCommand(hDevice,
        SD_CMD_APP_CMD,
        ((DWORD)(((PSDCARD_DEVICE_CONTEXT)hDevice)->RelativeAddress)) << 16,
        ResponseR1,
        pResponse);

    if (!SD_API_SUCCESS(status)){
        return status;
    } 
    
    // CMD55 did not timeout so send the command
    if (CLIENT_HANDLES_RETRY(SDDCGetClientDeviceFromHandle(hDevice))) {
        status = SDSynchronousBusRequest__X(hDevice,
            Command,
            Argument,
            TransferClass, 
            ResponseType,
            pResponse,
            NumberOfBlocks,
            BlockSize, 
            pBlockBuffer,
            0);
    }
    else {
        // handle app cmd retry here if client does not handle it, 
        // tell bus driver do not handle retry
    	pDevice = SDDCGetClientDeviceFromHandle(hDevice);
        
        // save original ClientFlags
    	clientFlags = pDevice->ClientFlags;   
    	pDevice->ClientFlags |= SD_CLIENT_HANDLES_RETRY;
        pDevice = SDDCGetClientDeviceFromHandle(hDevice);

        status = SDSynchronousBusRequest__X(hDevice,
            Command,
            Argument,
            TransferClass, 
            ResponseType,
            pResponse,
            NumberOfBlocks,
            BlockSize, 
            pBlockBuffer,
            0);

        if (!SD_API_SUCCESS(status)) {
            pBusDriver =  SDDCGetBusDriver((PSDCARD_DEVICE_CONTEXT)hDevice);
        	retryCount = pBusDriver->GetRetryCount();

            for (i = 0; i < retryCount; i++) {
                // check for retry
                if ( !( (SD_API_STATUS_RESPONSE_TIMEOUT == status) || 
                        (SD_API_STATUS_DATA_TIMEOUT == status) ||
                        (SD_API_STATUS_CRC_ERROR == status) ) ) {
                    break;
                }

                // send the APP Command primer (CMD55)
                status = SendSDCommand(hDevice,
                    SD_CMD_APP_CMD,
                    ((DWORD)(((PSDCARD_DEVICE_CONTEXT)hDevice)->RelativeAddress)) << 16,
                    ResponseR1,
                    pResponse);

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

                // send the command again
                status = SDSynchronousBusRequest__X(hDevice,
                    Command,
                    Argument,
                    TransferClass, 
                    ResponseType,
                    pResponse,
                    NumberOfBlocks,
                    BlockSize, 
                    pBlockBuffer,
                    0);
            }
        }

        // restore client flags
        pDevice->ClientFlags = clientFlags;
    }

    return status;
}

///////////////////////////////////////////////////////////////////////////////
//  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 UpdateCachedRegisterFromResponse(PSDCARD_DEVICE_CONTEXT   pDevice, 
                                      SD_INFO_TYPE             Register,
                                      PSD_COMMAND_RESPONSE     pResponse) 
{

    switch (Register) { 

        case SD_INFO_REGISTER_CID:
            memcpy(pDevice->CachedRegisters.CID, pResponse->ResponseBuffer, SD_CID_REGISTER_SIZE);
            break;
        case SD_INFO_REGISTER_RCA:
            // RCA is in bytes 3,4
            pDevice->RelativeAddress = (SD_CARD_RCA)pResponse->ResponseBuffer[3];
            pDevice->RelativeAddress |= ((SD_CARD_RCA)pResponse->ResponseBuffer[4]) << 8;
            break;
        case SD_INFO_REGISTER_OCR: 
            pDevice->CachedRegisters.OCR[3] = pResponse->ResponseBuffer[4];
            pDevice->CachedRegisters.OCR[2] = pResponse->ResponseBuffer[3];
            pDevice->CachedRegisters.OCR[1] = pResponse->ResponseBuffer[2];
            pDevice->CachedRegisters.OCR[0] = pResponse->ResponseBuffer[1];
            break;
        case SD_INFO_REGISTER_CSD:
            memcpy(pDevice->CachedRegisters.CSD, pResponse->ResponseBuffer, SD_CSD_REGISTER_SIZE);
#if USE_MMCPLUS
		if ( g_bIsMMC == TRUE )
		{
			/*
			for ( int i= 0 ; i<SD_CSD_REGISTER_SIZE ; i++)
			{
				RETAILMSG(0,(TEXT("CSD[%d] = %x\r\n"),i,pResponse->ResponseBuffer[i] ));
			}*/
			if ( pResponse->ResponseBuffer[15] & 0x10 )
			{
				RETAILMSG(0,(TEXT("This card is HSMMC\r\n")));		
				g_bIsHSMMC = TRUE;
			}
			else
			RETAILMSG(0,(TEXT("This card is not HSMMC\r\n")));				
		}
#endif 
            break;
        case SD_INFO_REGISTER_IO_OCR:
            pDevice->CachedRegisters.IO_OCR[2] = pResponse->ResponseBuffer[3];
            pDevice->CachedRegisters.IO_OCR[1] = pResponse->ResponseBuffer[2];
            pDevice->CachedRegisters.IO_OCR[0] = pResponse->ResponseBuffer[1];
            break;
        default:
            DEBUGCHK(FALSE);
    }

}

///////////////////////////////////////////////////////////////////////////////
//  DelayForPowerUp - Delay for powerup 
//  Input:  pSlot - slot to delay on
//       
//  Output: 
//  Notes:  
//     
///////////////////////////////////////////////////////////////////////////////
VOID DelayForPowerUp(PSDBUS_HC_SLOT_CONTEXT pSlot)
{
    // delay for power up
    if (pSlot->PowerUpDelay != 0) {
        Sleep(pSlot->PowerUpDelay);
    } else {
        // powerup delay should be set
        DEBUG_CHECK(FALSE, (TEXT("SDBusDriver: Slot Delay is 0!!!\n")));
        Sleep(500);
    }
}


///////////////////////////////////////////////////////////////////////////////
//  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 SetCardPower(SDCARD_DEVICE_TYPE      DeviceType,
                           DWORD                   OperatingVoltageMask, 
                           PSDBUS_HC_SLOT_CONTEXT  pSlot,
                           BOOL                    SetHCPower,
                           CReg                   *pregDevice)
{
    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"), 
            pSlot->SlotIndex, OperatingVoltageMask)); 
        // set slot power           
        status = SDSetSlotPower(pSlot,
            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, pSlot->SlotIndex));
            return status;
        }

        DelayForPowerUp(pSlot);
    }

    if (Device_SD_IO != DeviceType) {
        // put the card into idle again
        status = SendSDCommand(pSlot->hDevice,
            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,
                pSlot->SlotIndex));
            return status;
        }
    }

    totalPowerUpTime = pregDevice->ValueDW(POWER_UP_POLL_TIME_KEY, 
        DEFAULT_POWER_UP_TOTAL_WAIT_TIME);
    powerUpInterval = pregDevice->ValueDW(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"), 
        pSlot->SlotIndex, powerUpRetries, totalPowerUpTime , powerUpInterval)); 

    while (powerUpRetries != 0) {

        if (appcmd) {
            // send it as an APP cmd
            status = SendSDAppCommand(pSlot->hDevice,
                command,
                OperatingVoltageMask,
                responseType,
                &response);
        } else {

            // send the command to get the ready bit
            status = SendSDCommand(pSlot->hDevice,
                command,
                OperatingVoltageMask,
                responseType,
                &response);
        }

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

        if (Device_SD_IO == DeviceType) {
            // check to see if the I/O is ready
            if (SD_IS_IO_READY(&response)) {
                // we're done
                break;
            }
        } else {
            // check to see if the MMC or Memory card is ready
            if (SD_IS_MEM_READY(&response)) {
                // card is ready
                break;
            }
        }


        DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDBusDriver: Card in slot %d not ready, countdown: %d \n"), 
            pSlot->SlotIndex, powerUpRetries)); 
        powerUpRetries--;
        // sleep the powerup interval
        Sleep(powerUpInterval);
    }

    if (0 == powerUpRetries) {
        DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: Device failed to powerup after voltage setting \n")));
        status = SD_API_STATUS_DEVICE_NOT_RESPONDING;
    } 

    if (SD_API_SUCCESS(status)) {
        DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDBusDriver: Card in slot %d ready \n"), 

⌨️ 快捷键说明

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