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

📄 sdhcslot.cpp

📁 S3C2450BSP开发包,里面有很多资料。可以提供大家参考下。有什么需要解决问题。可以联系我QQ:314661
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//

// Copyright (c) 2002 BSQUARE Corporation.  All rights reserved.
// DO NOT REMOVE --- BEGIN EXTERNALLY DEVELOPED SOURCE CODE ID 40973--- DO NOT REMOVE

#include <bsp.h>
#include <bsp_cfg.h>

#include "SDHC.h"
#include "SDHCSlot.h"

static volatile BSP_ARGS *v_gBspArgs;
#define CARD_INSERTED 1
#define CARD_REMOVED 2

// Macros
#define DX_D1_OR_D2(cps)            ((cps) == D1 || (cps) == D2)
#define SETFNAME()  LPCTSTR pszFname = _T(__FUNCTION__) _T(":")

//#define _SRCCLK_48MHZ_	// for source clock using USB PHY 48MHz
//#define _FB_ON_			// for Feedback clock on

// 2007.06.25 D.Baek
// Define the global variable to check the initial state of card slot. When the driver is loading at boot,
// Check whether the card is inserted or not. If inserted, the process of insertion is executed automatically.
DWORD g_initialInsertion = 1;

#ifdef DEBUG
// dump the current request info to the debugger
static 
VOID 
DumpRequest(
    PSD_BUS_REQUEST pRequest,
    DWORD dwZone
    )
{   
  PREFAST_DEBUGCHK(pRequest);

  if (dwZone) {
    DEBUGMSG(1, (TEXT("DumpCurrentRequest: 0x%08X\n"), pRequest)); 
    DEBUGMSG(1, (TEXT("\t Command: %d\n"),  pRequest->CommandCode));
    DEBUGMSG(1, (TEXT("\t Argument: 0x%08x\n"),  pRequest->CommandArgument));
    DEBUGMSG(1, (TEXT("\t ResponseType: %d\n"),  pRequest->CommandResponse.ResponseType)); 
    DEBUGMSG(1, (TEXT("\t NumBlocks: %d\n"),  pRequest->NumBlocks)); 
    DEBUGMSG(1, (TEXT("\t BlockSize: %d\n"),  pRequest->BlockSize)); 
    DEBUGMSG(1, (TEXT("\t HCParam: %d\n"),    pRequest->HCParam)); 
  }
}
#else
#define DumpRequest(ptr, dw)
#endif


CSDHCSlotBase::CSDHCSlotBase(
    )
{
  m_pregDevice = NULL;
  m_dwSlot = 0;
  m_pbRegisters = NULL;
  m_pHCDContext = NULL;
  m_dwSysIntr = 0;
  m_hBusAccess = NULL;
  m_interfaceType = InterfaceTypeUndefined;
  m_dwBusNumber = 0;  

  m_dwVddWindows = 0;
  m_dwMaxClockRate = 0;
  m_dwTimeoutControl = 0;
  m_dwMaxBlockLen = 0;

  m_pbDmaBuffer = NULL;
  m_paDmaBuffer = 0;
  m_wRegClockControl = 0; 
  m_wIntSignals = 0;
  m_cpsCurrent = D0;
  m_cpsAtPowerDown = D0;

  m_dwDefaultWakeupControl = 0;
  m_bWakeupControl = 0;

#ifdef DEBUG
  m_dwReadyInts = 0;
#endif
  m_fCommandCompleteOccurred = FALSE;

  m_fSleepsWithPower = FALSE;
  m_fPowerUpDisabledInts = FALSE;
  m_fIsPowerManaged = FALSE;
  m_fSDIOInterruptsEnabled = FALSE;
  m_fCardPresent = FALSE;
  m_fAutoCMD12Success = FALSE;
  m_fCheckSlot = TRUE;
  m_fCanWakeOnSDIOInterrupts = FALSE;
  m_f4BitMode = FALSE;
  m_fFakeCardRemoval = FALSE;

  m_pCurrentRequest = NULL;
  m_fCurrentRequestFastPath = FALSE;

  m_dwPollingModeSize = NUM_BYTE_FOR_POLLING_MODE ;
}


CSDHCSlotBase::~CSDHCSlotBase(
    )
{
  DEBUGCHK(m_pbDmaBuffer == NULL);
}


BOOL
CSDHCSlotBase::Init(
    DWORD               dwSlot,
    volatile BYTE      *pbRegisters,
    PSDCARD_HC_CONTEXT  pHCDContext,
    DWORD               dwSysIntr,
    HANDLE              hBusAccess,
    INTERFACE_TYPE      interfaceType, 
    DWORD               dwBusNumber,
    CReg               *pregDevice
    )
{
  BOOL fRet = TRUE;

  DEBUGCHK(dwSlot < SDHC_MAX_SLOTS);
  DEBUGCHK(pbRegisters);
  DEBUGCHK(pHCDContext);
  DEBUGCHK(hBusAccess);
  PREFAST_DEBUGCHK(pregDevice && pregDevice->IsOK());

  m_dwSlot = dwSlot;
  m_pbRegisters = pbRegisters;
  m_pHCDContext = pHCDContext;
  m_dwSysIntr = dwSysIntr;
  m_hBusAccess = hBusAccess;
  m_interfaceType = interfaceType;
  m_dwBusNumber = dwBusNumber;
  m_pregDevice = pregDevice;

  fRet = SoftwareReset(SOFT_RESET_ALL);
  if (fRet) { 
    Sleep(10); // Allow time for card to power down after a device reset

    SSDHC_CAPABILITIES caps = GetCapabilities();

    DEBUGMSG(SDCARD_ZONE_INIT && caps.bits.DMA,
        (_T("SDHC Will use DMA for slot %u\n"), m_dwSlot));

    m_dwVddWindows = DetermineVddWindows();
    m_dwMaxClockRate = DetermineMaxClockRate();
    m_dwMaxBlockLen = DetermineMaxBlockLen();
    m_dwTimeoutControl = DetermineTimeoutControl();
    m_dwDefaultWakeupControl = DetermineWakeupSources();
    m_fCanWakeOnSDIOInterrupts = m_pregDevice->ValueDW(SDHC_CAN_WAKE_ON_INT_KEY);
    m_dwPollingModeSize = m_pregDevice->ValueDW(SDHC_POLLINGMODE_SIZE, NUM_BYTE_FOR_POLLING_MODE);

    Validate();

    DumpRegisters();
  }

  return fRet;
}


SD_API_STATUS
CSDHCSlotBase::Start(
    )
{
  Validate();

  SD_API_STATUS status;

  if (SoftwareReset(SOFT_RESET_ALL)) {
    // timeout control
    //WriteByte(SDHC_TIMEOUT_CONTROL, (BYTE) m_dwTimeoutControl);
    WriteByte(SDHC_TIMEOUT_CONTROL, (BYTE)0xE); // KYS

    // Enable error interrupt status and signals for all but the vendor
    // errors. This allows any normal error to generate an interrupt.
    WriteWord(SDHC_ERROR_INT_STATUS_ENABLE, ~0 & ~ERR_INT_STATUS_VENDOR);
    WriteWord(SDHC_ERROR_INT_SIGNAL_ENABLE, ~0 & ~ERR_INT_STATUS_VENDOR);

    // Enable all interrupt signals. During execution, we will enable 
    // and disable interrupt statuses as desired.
    WriteWord(SDHC_NORMAL_INT_SIGNAL_ENABLE, 0x1FF);
    //WriteWord(SDHC_NORMAL_INT_STATUS_ENABLE, 
    //    NORMAL_INT_ENABLE_CARD_INSERTION | NORMAL_INT_ENABLE_CARD_REMOVAL);
    WriteWord(SDHC_NORMAL_INT_STATUS_ENABLE, 0x1FF);

    status = SD_API_STATUS_SUCCESS;
  }
  else {
    status = SD_API_STATUS_DEVICE_NOT_RESPONDING;
  }

  v_gBspArgs = (volatile BSP_ARGS *)VirtualAlloc(0, sizeof(BSP_ARGS), MEM_RESERVE, PAGE_NOACCESS);
  if (!v_gBspArgs)
  {
    RETAILMSG(1, (TEXT("[HSMMC] Common Argument Area  VirtualAlloc failed!\r\n")));
    return FALSE; 
  }
  if (!VirtualCopy((PVOID)v_gBspArgs, (PVOID)(IMAGE_SHARE_ARGS_UA_START), sizeof(BSP_ARGS), PAGE_READWRITE | PAGE_NOCACHE ))
  {
    RETAILMSG(1, (TEXT("[HSMMC] BSP Common Argument Are VirtualCopy failed!\r\n")));
    return FALSE;
  }
  v_gBspArgs->g_SDCardState = CARD_REMOVED;//initialize
  v_gBspArgs->g_SDCardDetectEvent = CreateEvent(NULL, FALSE, FALSE,NULL);

  return status;
}


SD_API_STATUS
CSDHCSlotBase::Stop(
    )
{    
  if (m_fCardPresent) {
    // Remove device
    HandleRemoval(FALSE);
  }

  SoftwareReset(SOFT_RESET_ALL);

  if(NULL != v_gBspArgs->g_SDCardDetectEvent) 
  {
    CloseHandle(v_gBspArgs->g_SDCardDetectEvent);
    v_gBspArgs->g_SDCardDetectEvent = NULL;
  }

  return SD_API_STATUS_SUCCESS;
}


SD_API_STATUS 
CSDHCSlotBase::GetSlotInfo(
    PSDCARD_HC_SLOT_INFO pSlotInfo
    )
{
  PREFAST_DEBUGCHK(pSlotInfo);
  DEBUGCHK(m_pregDevice->IsOK());

  // set the slot capabilities
  DWORD dwCap = SD_SLOT_SD_4BIT_CAPABLE | 
    SD_SLOT_SD_1BIT_CAPABLE | 
    SD_SLOT_SDIO_CAPABLE    |
    SD_SLOT_SDIO_INT_DETECT_4BIT_MULTI_BLOCK;
  if (GetCapabilities().bits.HighSpeed)
    dwCap |= SD_SLOT_HIGH_SPEED_CAPABLE;

  SDHCDSetSlotCapabilities(pSlotInfo,dwCap );

  SDHCDSetVoltageWindowMask(pSlotInfo, m_dwVddWindows); 

  // Set optimal voltage
  SDHCDSetDesiredSlotVoltage(pSlotInfo, GetDesiredVddWindow());     

  // 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;
  SetClockRate(&dwMaxClockRateInSDRange);
  SDHCDSetMaxClockRate(pSlotInfo, dwMaxClockRateInSDRange);

  // Set power up delay. We handle this in SetVoltage().
  SDHCDSetPowerUpDelay(pSlotInfo, 1);

  return SD_API_STATUS_SUCCESS;
}


SD_API_STATUS
CSDHCSlotBase::SlotOptionHandler(
    SD_SLOT_OPTION_CODE   sdOption, 
    PVOID                 pData,
    DWORD                 cbData
    )
{
  SD_API_STATUS status = SD_API_STATUS_SUCCESS;

  switch (sdOption) {
    case SDHCDSetSlotPower: {
                              DEBUGCHK(cbData == sizeof(DWORD));
                              PDWORD pdwVddSetting = (PDWORD) pData;
                              SetVoltage(*pdwVddSetting);
                              break;
                            }

    case SDHCDSetSlotInterface: {
                                  DEBUGCHK(cbData == sizeof(SD_CARD_INTERFACE));
                                  PSD_CARD_INTERFACE pInterface = (PSD_CARD_INTERFACE) pData;

                                  DEBUGMSG(SDCARD_ZONE_INFO, 
                                      (TEXT("CSDHCSlotBase::SlotOptionHandler: Clock Setting: %d\n"), 
                                       pInterface->ClockRate));

                                  SD_CARD_INTERFACE_EX sdCardInterfaceEx;
                                  memset(&sdCardInterfaceEx,0, sizeof(sdCardInterfaceEx));
                                  sdCardInterfaceEx.InterfaceModeEx.bit.sd4Bit = (pInterface->InterfaceMode == SD_INTERFACE_SD_4BIT? 1: 0);
                                  /* 07.11.20 by KYS for HSMMC8BIT*/
                                  sdCardInterfaceEx.InterfaceModeEx.bit.hsmmc8Bit = (((pInterface->InterfaceMode) == SD_INTERFACE_MMC_8BIT)? 1:0);

                                  sdCardInterfaceEx.ClockRate = pInterface->ClockRate;
                                  sdCardInterfaceEx.InterfaceModeEx.bit.sdWriteProtected = (pInterface->WriteProtected?1:0);
                                  SetInterface(&sdCardInterfaceEx);
                                  // Update the argument back.
                                  if (sdCardInterfaceEx.InterfaceModeEx.bit.hsmmc8Bit != 0) {
                                    pInterface->InterfaceMode = SD_INTERFACE_MMC_8BIT;
                                  } else {
                                    pInterface->InterfaceMode = (sdCardInterfaceEx.InterfaceModeEx.bit.sd4Bit!=0?SD_INTERFACE_SD_4BIT:SD_INTERFACE_SD_MMC_1BIT);
                                  }
                                  pInterface->ClockRate =  sdCardInterfaceEx.ClockRate;
                                  pInterface->WriteProtected = (sdCardInterfaceEx.InterfaceModeEx.bit.sdWriteProtected!=0?TRUE:FALSE);
                                  break;
                                }
    case SDHCDSetSlotInterfaceEx: {
                                    DEBUGCHK(cbData == sizeof(SD_CARD_INTERFACE_EX));
                                    PSD_CARD_INTERFACE_EX pInterface = (PSD_CARD_INTERFACE_EX) pData;

                                    DEBUGMSG(SDCARD_ZONE_INFO, 
                                        (TEXT("CSDHCSlotBase::SlotOptionHandler: Clock Setting: %d\n"), 
                                         pInterface->ClockRate));

                                    SetInterface((PSD_CARD_INTERFACE_EX)pInterface);
                                    break;
                                  }

    case SDHCDEnableSDIOInterrupts:
    case SDHCDAckSDIOInterrupt:
                                  EnableSDIOInterrupts(TRUE);
                                  break;

    case SDHCDDisableSDIOInterrupts:
                                  EnableSDIOInterrupts(FALSE);
                                  break;

    case SDHCDGetWriteProtectStatus: {
                                       DEBUGCHK(cbData == sizeof(SD_CARD_INTERFACE));
                                       PSD_CARD_INTERFACE pInterface = (PSD_CARD_INTERFACE) pData;
                                       pInterface->WriteProtected = IsWriteProtected();
                                       break;
                                     }

    case SDHCDQueryBlockCapability: {
                                      DEBUGCHK(cbData == sizeof(SD_HOST_BLOCK_CAPABILITY));
                                      PSD_HOST_BLOCK_CAPABILITY pBlockCaps = 
                                        (PSD_HOST_BLOCK_CAPABILITY)pData;

                                      DEBUGMSG(SDCARD_ZONE_INFO, 
                                          (TEXT("CSDHCSlotBase::SlotOptionHandler: Read Block Length: %d , Read Blocks: %d\n"), 
                                           pBlockCaps->ReadBlockSize, pBlockCaps->ReadBlocks));
                                      DEBUGMSG(SDCARD_ZONE_INFO, 
                                          (TEXT("CSDHCSlotBase::SlotOptionHandler: Write Block Length: %d , Write Blocks: %d\n"), 
                                           pBlockCaps->WriteBlockSize, pBlockCaps->WriteBlocks));

                                      pBlockCaps->ReadBlockSize = max(pBlockCaps->ReadBlockSize, SDHC_MIN_BLOCK_LENGTH);
                                      pBlockCaps->ReadBlockSize = min(pBlockCaps->ReadBlockSize, (USHORT) m_dwMaxBlockLen);

                                      pBlockCaps->WriteBlockSize = max(pBlockCaps->WriteBlockSize, SDHC_MIN_BLOCK_LENGTH);
                                      pBlockCaps->WriteBlockSize = min(pBlockCaps->WriteBlockSize, (USHORT) m_dwMaxBlockLen);
                                      break;
                                    }

    case SDHCDGetSlotPowerState: {
                                   DEBUGCHK(cbData == sizeof(CEDEVICE_POWER_STATE));
                                   PCEDEVICE_POWER_STATE pcps = (PCEDEVICE_POWER_STATE) pData;

⌨️ 快捷键说明

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