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

📄 sdcontrol.cpp

📁 Microsoft WinCE 6.0 BSP FINAL release source code for use with the i.MX27ADS TO2 WCE600_FINAL_MX27_S
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//------------------------------------------------------------------------------
//
//  Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
//  Use of this source code is subject to the terms of the Microsoft end-user
//  license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
//  If you did not accept the terms of the EULA, you are not authorized to use
//  this source code. For a copy of the EULA, please see the LICENSE.RTF on
//  your install media.
//
//------------------------------------------------------------------------------
//
//  Copyright (C) 2004, Motorola Inc. All Rights Reserved
//
//-----------------------------------------------------------------------------
//
//  Copyright (C) 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
//  THIS SOURCE CODE, AND ITS USE AND DISTRIBUTION, IS SUBJECT TO THE TERMS
//  AND CONDITIONS OF THE APPLICABLE LICENSE AGREEMENT 
//
//-----------------------------------------------------------------------------
//
//  File:  sdcontrol.cpp
//
//  Implementation of SDHC common Device Driver
//
//  This file implements common SDHC functions 
//  This driver is still pending to PMIC integration. 
//------------------------------------------------------------------------------
#include <windows.h>
#include <nkintr.h>
#include <ceddk.h>

#include "csp.h"
#include "sdhc.h"

/*******************************************************************************
 GLOBAL OR STATIC VARIABLES  
*******************************************************************************/

/*******************************************************************************
 STATIC FUNCTION PROTOTYPES  
*******************************************************************************/
static DWORD SDControllerIstThread(PSDH_HARDWARE_CONTEXT pHCDevice);
static void IndicateBusRequestComplete(PSDH_HARDWARE_CONTEXT pController,
                                       PSD_BUS_REQUEST pRequest,
                                       SD_API_STATUS status);
static BOOL HandleCommandComplete(PSDH_HARDWARE_CONTEXT pController);
static BOOL HandleTransferDone(PSDH_HARDWARE_CONTEXT pController);
static void SetRate(PSDH_HARDWARE_CONTEXT pHc, PDWORD pRate, BOOL fSetNewRate);
static void SetClock(PSDH_HARDWARE_CONTEXT pController, BOOL Start) ;
static BOOL Drivstrset(DWORD dwIndex);
static void SoftwareReset(PSDH_HARDWARE_CONTEXT pController, BOOL bResetClock);
static void SetHardwarePowerState(PSDH_HARDWARE_CONTEXT pHc, CEDEVICE_POWER_STATE ds);
static void ResetCard(SDH_HARDWARE_CONTEXT *pController);
static void ProcessCardInsertion(void *pContext);
static void ProcessCardRemoval(void *pContext);
static void InitGlobals(PSDH_HARDWARE_CONTEXT pController);
static inline BOOL TransferIsSDIOAbort(PSD_BUS_REQUEST pRequest);
static DWORD SDControllerBusyWaitResponse(PSDH_HARDWARE_CONTEXT pHCDevice);
#if DMA
static BOOL InitDMA(PSDH_HARDWARE_CONTEXT pController) ;
static BOOL DeInitDMA(PSDH_HARDWARE_CONTEXT pController) ;
#endif //DMA
static BOOL SetupCardDetectIST(PSDH_HARDWARE_CONTEXT pHardwareContext) ; 
static void CleanupCardDetectIST(PSDH_HARDWARE_CONTEXT pHardwareContext);
static void DumpRegisters(PSDH_HARDWARE_CONTEXT pHc);


/*******************************************************************************
 EXPORTED FUNCTIONS
*******************************************************************************/
//------------------------------------------------------------------------------
//
// Function: SDInitialize
//
// Initialize the the MMC Controller
//
// Parameters:
//       pHardwareContext[in] - newly allocated hardware context
//
// Returns:
//      SD_API_STATUS code
//
//------------------------------------------------------------------------------
SD_API_STATUS SDInitialize(PSDCARD_HC_CONTEXT pHCContext)
{
    SD_API_STATUS status = SD_API_STATUS_SUCCESS;   // intermediate status
    PSDH_HARDWARE_CONTEXT pHardwareContext;       // hardware context
    pHardwareContext = GetExtensionFromHCDContext(PSDH_HARDWARE_CONTEXT, pHCContext);

    DEBUGMSG(ZONE_FUNCTION, (TEXT("+SDInitialize: Initialize the SDHC\r\n")));
    InitializeCriticalSection(&pHardwareContext->ControllerCriticalSection);

    // Init  globals
    InitGlobals(pHardwareContext);

    // Map Virtual Address
    pHardwareContext->pSDMMCRegisters = (PCSP_SDHC_REG) MmMapIoSpace(pHardwareContext->phySDHCAddr, sizeof(CSP_SDHC_REG), FALSE);
    if (pHardwareContext->pSDMMCRegisters == NULL)
    {
        ERRORMSG(ZONE_ERROR, (TEXT("SDInitialize:  MmMapIoSpace failed!\r\n")));
        goto exitInit;
    }
	
    //driving strength  SDHC
    Drivstrset(pHardwareContext->ControllerIndex);

    //Turn off the voltage regulator to the slot
    BSPSlotVoltageOff(pHardwareContext->ControllerIndex);

    //Set slot voltage 
    BSPSetVoltageSlot(pHardwareContext->ControllerIndex, 0) ;

    //Stopt clock gating mode 
    BSPSdhcSetClockGatingMode(FALSE, pHardwareContext->ControllerIndex) ; 

    //Setup GPIO
    BspSdhcSetGPIO(pHardwareContext->ControllerIndex);

    //Reset the controller 
    SoftwareReset(pHardwareContext, TRUE);

#if DMA
    // Initialize DMA 
    if (!InitDMA(pHardwareContext))
    {
        ERRORMSG(ZONE_ERROR, (TEXT("MMCSD_DMAInit: cannot init DMA!\r\n")));
        status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
        goto exitInit;
    }
#endif //DMA

    //Create interrupt event
    pHardwareContext->hControllerInterruptEvent = CreateEvent(NULL, FALSE, FALSE,NULL);
    if (NULL == pHardwareContext->hControllerInterruptEvent)
    {
        status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
        goto exitInit;
    }

    // Translate IRQ to SYSINTR
    if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &(pHardwareContext->dwIrqSDHC), 
                         sizeof(pHardwareContext->dwIrqSDHC), &(pHardwareContext->dwSysintrSDHC), 
                         sizeof(pHardwareContext->dwSysintrSDHC), NULL))
    {
        ERRORMSG(ZONE_ERROR,(TEXT("%s: Request SYSINTR failed\r\n"), __WFUNCTION__));
        goto exitInit;
    }

    //Initialize interrupt
    if (!InterruptInitialize(pHardwareContext->dwSysintrSDHC, 
                             pHardwareContext->hControllerInterruptEvent, NULL, 0))
    {
        ERRORMSG(ZONE_ERROR,(TEXT("%s: Interrupt initialization failed! \r\n"), __WFUNCTION__));
        goto exitInit;
    }

    //driver not shutting down
    pHardwareContext->DriverShutdown = FALSE;

    // Initialize SDControllerIstThread() to handle interrupt generated by Host Controller
    DWORD threadID;                         
    // create the interrupt thread for controller interrupts
    pHardwareContext->hControllerInterruptThread = CreateThread(NULL,
                                                                0,
                                                                (LPTHREAD_START_ROUTINE)SDControllerIstThread,
                                                                pHardwareContext,
                                                                0,
                                                                &threadID);

    if (NULL == pHardwareContext->hControllerInterruptThread)
    {
        status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
        goto exitInit;
    }

    // Create interrupt thread for card detection 
    if (!SetupCardDetectIST(pHardwareContext))
    {
        status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
    }

    exitInit:
    if (!SD_API_SUCCESS(status))
    {
        // just call the deinit handler directly to cleanup
        SDDeinitialize(pHCContext);
    }

    DEBUGMSG(ZONE_FUNCTION, (TEXT("-SDInitialize: Initialize the the MMC Controller\r\n")));
    return status;
}
//------------------------------------------------------------------------------
//
// Function: SDDeInitialize
//
// Deinitialize the the MMC Controller
//
// Parameters:
//       pHCContext[in] - Host controller context
//
// Returns:
//      SD_API_STATUS code
//
//------------------------------------------------------------------------------
SD_API_STATUS SDDeinitialize(PSDCARD_HC_CONTEXT pHCContext)
{
    PSDH_HARDWARE_CONTEXT pHardwareContext; // hardware context
    DEBUGMSG(ZONE_FUNCTION, (TEXT("+SDDeinitialize: \r\n")));
    pHardwareContext = GetExtensionFromHCDContext(PSDH_HARDWARE_CONTEXT, pHCContext);

    // make sure all interrupt sources are disabled
    InterruptDisable(pHardwareContext->dwSysintrSDHC);

    // Indicate shutdown to threads
    pHardwareContext->DriverShutdown = TRUE;

    // clean up controller IST
    if (NULL != pHardwareContext->hControllerInterruptThread)
    {
        // wake up the IST
        SetEvent(pHardwareContext->hControllerInterruptEvent);
        CloseHandle(pHardwareContext->hControllerInterruptThread);
        pHardwareContext->hControllerInterruptThread = NULL;
    }

    // clean up card detection IST and free card insertion interrupt
    CleanupCardDetectIST(pHardwareContext);

    // Release SYSINTR
    KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR, &(pHardwareContext->dwSysintrSDHC), 
                    sizeof(DWORD), NULL, 0, NULL);
    pHardwareContext->dwSysintrSDHC = (DWORD)SYSINTR_UNDEFINED;

    // free controller interrupt event
    if (NULL != pHardwareContext->hControllerInterruptEvent)
    {
        CloseHandle(pHardwareContext->hControllerInterruptEvent);
        pHardwareContext->hControllerInterruptEvent = NULL;
    }

#if DMA
    // Release DMA Resources 
    DeInitDMA(pHardwareContext); 
#endif //DMA

    // free the virtual space allocated for SDHC1 memory map
    if (pHardwareContext->pSDMMCRegisters != NULL)
    {
        MmUnmapIoSpace(pHardwareContext->pSDMMCRegisters, sizeof(CSP_SDHC_REG));
        pHardwareContext->pSDMMCRegisters = NULL;
    }
    DeleteCriticalSection(&pHardwareContext->ControllerCriticalSection);
    DEBUGMSG(ZONE_FUNCTION, (TEXT("-SDDeinitialize: \r\n")));
    return SD_API_STATUS_SUCCESS;
}

//------------------------------------------------------------------------------
//
// Function: SDControllerBusyWaitResponse
//
// 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 SDControllerBusyWaitResponse(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("+SDControllerBusyWaitResponse for SDHC/MMC Controller driver\r\n")));

    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("SDControllerBusyWaitResponse: Sleeping before issuing next Status cmd\r\n")));
			Sleep (0);
		}

		CardState = CardStatus;

		DEBUGMSG(ZONE_INFO, (TEXT("SDControllerBusyWaitResponse: 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
        OUTREG32(&pHCDevice->pSDMMCRegisters->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);

⌨️ 快捷键说明

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