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

📄 sdcontrol.cpp

📁 freescale i.mx31 BSP CE5.0全部源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
            }
        } else
            status = SD_API_STATUS_INVALID_PARAMETER;
        break;

    case SDHCDQueryBlockCapability:
        if (pData && OptionSize == sizeof(SD_HOST_BLOCK_CAPABILITY))
        {
            pBlockCaps = (PSD_HOST_BLOCK_CAPABILITY)pData;
            DEBUGMSG(ZONE_INFO, 
                     (TEXT("SDHSlotOptionHandler: Read Block Length: %d , Read Blocks: %d\r\n"), 
                      pBlockCaps->ReadBlockSize, 
                      pBlockCaps->ReadBlocks));
            DEBUGMSG(ZONE_INFO, 
                     (TEXT("SDHSlotOptionHandler: Write Block Length: %d , Write Blocks: %d\r\n"), 
                      pBlockCaps->WriteBlockSize, 
                      pBlockCaps->WriteBlocks));

            if (pBlockCaps->ReadBlockSize > SDH_MAX_BLOCK_SIZE)
            {
                pBlockCaps->ReadBlockSize = SDH_MAX_BLOCK_SIZE;
            }

            if (pBlockCaps->ReadBlockSize < SDH_MIN_BLOCK_SIZE )
            {
                pBlockCaps->ReadBlockSize = SDH_MIN_BLOCK_SIZE;
            }

            if (pBlockCaps->WriteBlockSize > SDH_MAX_BLOCK_SIZE)
            {
                pBlockCaps->WriteBlockSize = SDH_MAX_BLOCK_SIZE;
            }

            if (pBlockCaps->WriteBlockSize < SDH_MIN_BLOCK_SIZE )
            {
                pBlockCaps->WriteBlockSize = SDH_MIN_BLOCK_SIZE;
            }

            // ARM11 is limited by DMA buffer size allocated for MMCSD
            pBlockCaps->ReadBlocks = SDHC_MAX_NUM_BLOCKS; 
            pBlockCaps->WriteBlocks = SDHC_MAX_NUM_BLOCKS; 
        } else
            status = SD_API_STATUS_INVALID_PARAMETER;
        break;

    case SDHCDGetSlotInfo:
        DEBUGMSG(ZONE_INFO, 
                 (TEXT("SDHSlotOptionHandler - called - SDHCDGetSlotInfo   \r\n"))); 
        if ( OptionSize != sizeof(SDCARD_HC_SLOT_INFO) || pData == NULL )
        {
            status = SD_API_STATUS_INVALID_PARAMETER;
        } else
        {
            PSDCARD_HC_SLOT_INFO pSlotInfo = (PSDCARD_HC_SLOT_INFO)pData;
            // set the slot capabilities
            SDHCDSetSlotCapabilities(pSlotInfo, SD_SLOT_SD_1BIT_CAPABLE | 
                                     SD_SLOT_SD_4BIT_CAPABLE |
                                     SD_SLOT_SDIO_CAPABLE |
                                     SD_SLOT_SDMEM_4BIT_CAPABLE |
                                     SD_SLOT_SDIO_INT_DETECT_4BIT_MULTI_BLOCK);

            //TODO: Set all valid masks.
            //TODO: PMIC do not support ranges >3.00V. 
            //Set Slot voltage window
            pController->dwVoltageWindowMask = (SD_VDD_WINDOW_2_9_TO_3_0 | 
                                                SD_VDD_WINDOW_3_0_TO_3_1 |
                                                SD_VDD_WINDOW_3_1_TO_3_2);

            SDHCDSetVoltageWindowMask(pSlotInfo, pController->dwVoltageWindowMask);

            // Set optimal voltage
            //TODO : is this range supported
            pController->dwOptVoltageMask = SLOT_VOLTAGE_MAX_BITMASK;
            SDHCDSetDesiredSlotVoltage(pSlotInfo, pController->dwOptVoltageMask);

            // Controller may be able to clock at higher than the max SD rate,
            // but we should only report the highest rate in the range.
            DWORD dwMaxClockRateInSDRange = SD_FULL_SPEED_RATE;
            SetRate(pController, &dwMaxClockRateInSDRange, FALSE);
            SDHCDSetMaxClockRate(pSlotInfo, dwMaxClockRateInSDRange);

            // Set power up delay. 
            pController->dwPowerUpDelay = SDHC_MAX_POWER_SUPPLY_RAMP_UP;
            SDHCDSetPowerUpDelay(pSlotInfo, pController->dwPowerUpDelay);
        }
        break;

    default:
        status = SD_API_STATUS_INVALID_PARAMETER;
        break;
    }
    return status;
}
//------------------------------------------------------------------------------
//
// Function: SDPowerUp
//
// Power up handler. To be called within XXX_PowerOn only
//
// Parameters:
//      pHostContext[in] - host controller context
//
// Returns:
//      none
//
//------------------------------------------------------------------------------
void SDPowerUp(PSDCARD_HC_CONTEXT pHCContext)
{
    PSDH_HARDWARE_CONTEXT pHCDevice;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("SDPowerUp+\r\n")));
    pHCDevice = GetExtensionFromHCDContext(PSDH_HARDWARE_CONTEXT, pHCContext);

    SetHardwarePowerState(pHCDevice, pHCDevice->PsAtPowerDown);

    //Since 1 controller support 1 SD slot, we use index 0
    SDHCDPowerUpDown(pHCContext, TRUE, TRUE, 0);

    DEBUGMSG(ZONE_FUNCTION, (TEXT("SDPowerUp-\r\n")));
}    
//------------------------------------------------------------------------------
//
// Function: SDPowerDown
//
// Power down handler. To be called within XXX_PowerDown only 
//
// Parameters:
//      pHostContext[in] - host controller context
//
// Returns:
//      none
//
//------------------------------------------------------------------------------
void SDPowerDown(PSDCARD_HC_CONTEXT pHCContext)
{
    PSDH_HARDWARE_CONTEXT pHCDevice;
    CEDEVICE_POWER_STATE cps;
    DEBUGMSG(ZONE_FUNCTION, (TEXT("SDPowerDown+\r\n")));

    // Do not allow client driver to continue submit request during power down.
    //Since 1 controller support 1 SD slot, we use index 0
    SDHCDPowerUpDown(pHCContext, FALSE, FALSE, 0);
	
    pHCDevice = GetExtensionFromHCDContext(PSDH_HARDWARE_CONTEXT, pHCContext);

    pHCDevice->PsAtPowerDown = pHCDevice->CurrentPowerState;

    if (pHCDevice->fWakeOnSDIOInt)
    {
        cps = D3;
    } else
    {
        cps = D4;
    }
	
    SetHardwarePowerState(pHCDevice, cps);

    DEBUGMSG(ZONE_FUNCTION, (TEXT("SDPowerDown-\r\n")));
}
/*******************************************************************************
 PRIVATE FUNCTIONS
*******************************************************************************/

#ifdef SD_R1B_BUSYWAIT_WORKAROUND
//------------------------------------------------------------------------------
//
// Function: SDControllerBusyResponseThread
//
// Thread for SDHC/MMC Controller driver which busy waits for controller to be ready
// in order to invoke next commands
//
// Parameters:
//      pHCDevice[in] - the controller instance
//
// Returns:
//      Thread exit code
//
//------------------------------------------------------------------------------
DWORD SDControllerBusyResponseThread(PSDH_HARDWARE_CONTEXT pHCDevice)
{
    DWORD 			cmdatRegister=0, cmdArg = 0;   // CMDAT register
    PSD_BUS_REQUEST 	pRequest;
    SD_API_STATUS 	status = SD_API_STATUS_SUCCESS;
    LONG     			ii;             // loop variable  
    USHORT   			responseBuffer[SDH_RESPONSE_FIFO_DEPTH - 5]; // response buffer
    SD_CARD_STATUS	CardStatus = 0, CardState = 0;
    PUCHAR  			tempBuffer = NULL;
    CHAR			retryCount =0;
    
    DEBUGMSG(ZONE_FUNCTION, (TEXT("+SDControllerBusyResponseThread: Thread for SDHC/MMC Controller driver\r\n")));
#if !VPMX31
    //cant use with virtio. It will cause thread synchronization problem
    if (!CeSetThreadPriority(GetCurrentThread(), (pHCDevice->ControllerIstThreadPriority + 2)))
    {
        ERRORMSG(ZONE_ERROR, (TEXT("SDControllerBusyResponseThread: warning, failed to set CEThreadPriority \n")));
    }
#endif //VPMX31
    while (1)
    {

       DEBUGMSG(ZONE_INFO, (TEXT("SDControllerBusyResponseThread:Wait For Signal ... \r\n")));
       if (WaitForSingleObject(pHCDevice->hControllerBusyEvent, INFINITE) != WAIT_OBJECT_0)
       {
            // bail out
            ERRORMSG(ZONE_ERROR, (TEXT("SDControllerBusyResponseThread: Wait Failed!  \r\n")));
            return 0;
       }

      	if (pHCDevice->DriverShutdown)
      	{
      		DEBUGMSG(ZONE_INFO, (TEXT("SDControllerBusyResponseThread: Thread Exiting\r\n")));
      		return 0;
      	}

	retryCount = DEFAULT_BUS_REQUEST_RETRY_COUNT;
       pRequest = SDHCDGetAndLockCurrentRequest(pHCDevice->pHCContext, 0);
	cmdArg = (((DWORD)((SDDCGetClientDeviceFromHandle(pRequest->hDevice))->RelativeAddress)) << 16);
       do
       {
      		status = SD_API_STATUS_SUCCESS;
		if (CardState != CardStatus)
		{
			DEBUGMSG (ZONE_INFO,(TEXT("SDControllerBusyResponseThread: Sleeping before issuing next Status cmd\r\n")));
			Sleep (0);
		}

		CardState = CardStatus;

		DEBUGMSG(ZONE_INFO, (TEXT("SDControllerBusyResponseThread: Sending Status Command %d\r\n"), retryCount));
		
		CardState = SD_STATUS_CURRENT_STATE_TRAN;
			
		CSP_BITFINS(cmdatRegister, SDHC_CDC_FORMAT, 1);        
	         // check to see if we need to enable wide bus (4 bit) data transfer mode
	       CSP_BITFINS(cmdatRegister, SDHC_CDC_BW, pHCDevice->BusWidthSetting);
	    	// clear all status
	    	OUTREG32(&pHCDevice->pSDMMCRegisters->STATUS, 0xFFFFFFFF);
	    	// set the command
	    	INSREG32BF(&pHCDevice->pSDMMCRegisters->CMD, SDHC_CMD_CMD, SD_CMD_SEND_STATUS);
	    	// set the argument
	    	INSREG32BF(&pHCDevice->pSDMMCRegisters->ARG, SDHC_ARG_ARG, cmdArg);
			
	   	// write the CMDAT register
	    	OUTREG32(&pHCDevice->pSDMMCRegisters->CMD_DAT_CONT, cmdatRegister);

	    	//start clock
	    	SetClock(pHCDevice, TRUE);

	       while (!EXTREG32BF(&pHCDevice->pSDMMCRegisters->STATUS, SDHC_SR_ECR))
			Sleep (0);
		   
	       // Clear interrupt status by writing 1 to the corresponsing bit only
	       OUTREG32(&pHCDevice->pSDMMCRegisters->STATUS, CSP_BITFVAL(SDHC_SR_ECR, 1));

	    	//Check for response time-out or crc error.If found, retry again
	    	if (EXTREG32BF(&pHCDevice->pSDMMCRegisters->STATUS, SDHC_SR_TORESP))
	    	{
	        	// Clear status by writing 1 
	        	OUTREG32(&pHCDevice->pSDMMCRegisters->STATUS, CSP_BITFVAL(SDHC_SR_TORESP, 1));
			retryCount --;
			status = SD_API_STATUS_RESPONSE_TIMEOUT;
			ERRORMSG(ZONE_ERROR, (TEXT("SDControllerBusyResponseThread: Status Command timeout\r\n")));
			continue;
	    	}
			
		if (EXTREG32BF(&pHCDevice->pSDMMCRegisters->STATUS, SDHC_SR_RSPCERR))
		{
	        	// Clear status by writing 1 
	        	OUTREG32(&pHCDevice->pSDMMCRegisters->STATUS, CSP_BITFVAL(SDHC_SR_RSPCERR, 1));
			retryCount --;
			status = SD_API_STATUS_CRC_ERROR;
			ERRORMSG(ZONE_ERROR, (TEXT("SDControllerBusyResponseThread:  response CRC error\r\n")));
			continue;		
		}
		
		memset ((&responseBuffer), 0, (SDH_RESPONSE_FIFO_DEPTH - 5));
		
	        // read in the response words from the response fifo.
	        for (ii = 2; ii >= 0; ii--)
	        {
	             // read from the fifo
	             responseBuffer[ii] =INREG16(&pHCDevice->pSDMMCRegisters->RES_FIFO);
	             DEBUGMSG(ZONE_INFO, (TEXT("responseBuffer[%d]=0x%x\r\n"),ii,responseBuffer[ii]));       
	        }    

		tempBuffer = (PUCHAR)responseBuffer;

		memcpy((&CardStatus), &tempBuffer[1], sizeof(SD_CARD_STATUS));
		DEBUGMSG(ZONE_INFO, (TEXT("CardStatus=0x%x\r\n"),SD_STATUS_CURRENT_STATE(CardStatus)));
	}while ( (SD_STATUS_CURRENT_STATE (CardStatus) != CardState) && (retryCount > 0) );
	
       IndicateBusRequestComplete(pHCDevice, pRequest, status);	
	CardStatus = CardState = 0;
    }
	
}
#endif

//------------------------------------------------------------------------------
//
// Function: SDControllerIstThread
//
// IST thread for MMC Controller driver
//
// Parameters:
//      pHCDevice[in] - the controller instance
//
// Returns:
//      Thread exit code
//
//------------------------------------------------------------------------------
DWORD SDControllerIstThread(PSDH_HARDWARE_CONTEXT pHCDevice)
{
    DEBUGMSG(ZONE_FUNCTION, (TEXT("+SDControllerIstThread: IST thread for MMC Controller driver\r\n")));
#if !VPMX31
    //cant use with virtio. It will cause thread synchronization problem
    if (!CeSetThreadPriority(GetCurrentThread(), pHCDevice->ControllerIstThreadPriority))
    {
        ERRORMSG(ZONE_ERROR, (TEXT("SDControllerIstThread: warning, failed to set CEThreadPriority \n")));
    }
#endif //VPMX31
    while (1)
    {

⌨️ 快捷键说明

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