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

📄 sdhcslot.cpp

📁 S3C2450BSP开发包,里面有很多资料。可以提供大家参考下。有什么需要解决问题。可以联系我QQ:314661
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                                   *pcps = GetPowerState();
                                   break;
                                 }

    case SDHCDSetSlotPowerState: {
                                   DEBUGCHK(cbData == sizeof(CEDEVICE_POWER_STATE));
                                   PCEDEVICE_POWER_STATE pcps = (PCEDEVICE_POWER_STATE) pData;
                                   SetPowerState(*pcps);
                                   break;
                                 }

    case SDHCDWakeOnSDIOInterrupts: {
                                      DEBUGCHK(cbData == sizeof(BOOL));
                                      PBOOL pfWake = (PBOOL) pData;

                                      if (m_fCanWakeOnSDIOInterrupts) {
                                        DWORD dwWakeupControl = m_dwDefaultWakeupControl;

                                        if (*pfWake) {
                                          dwWakeupControl |= WAKEUP_INTERRUPT;
                                        }

                                        m_bWakeupControl = (BYTE) dwWakeupControl;
                                      }
                                      else {
                                        status = SD_API_STATUS_UNSUCCESSFUL;
                                      }
                                      break;
                                    }

    case SDHCDGetSlotInfo: {
                             DEBUGCHK(cbData == sizeof(SDCARD_HC_SLOT_INFO));
                             PSDCARD_HC_SLOT_INFO pSlotInfo = (PSDCARD_HC_SLOT_INFO) pData;
                             status = GetSlotInfo(pSlotInfo);
                             break;
                           }

    default:
                           status = SD_API_STATUS_INVALID_PARAMETER;
  }

  return status;
}


DWORD
CSDHCSlotBase::DetermineMaxClockRate(
    )
{
  DEBUGCHK(m_pregDevice->IsOK());

  // We allow the registry to override what is in the capabilities register.
  DWORD dwMaxClockRate = m_pregDevice->ValueDW(SDHC_FREQUENCY_KEY);
  if (dwMaxClockRate == 0) {
    SSDHC_CAPABILITIES caps = GetCapabilities();

    dwMaxClockRate = caps.bits.ClkFreq * 1000000;
    if (dwMaxClockRate == 0) {
      // No clock frequency specified. Use the highest possible that
      // could have been specified so that a working clock divisor 
      // will be chosen.
      dwMaxClockRate = SDHC_MAX_CLOCK_FREQUENCY;
      DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHC: No base clock frequency specified\n")));
      DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHC: Using default frequency of %u\n"), 
            dwMaxClockRate));
    }
  }

  return dwMaxClockRate;
}


DWORD
CSDHCSlotBase::DetermineMaxBlockLen(
    )
{
  static const USHORT sc_rgusBlockLen[] = { 
    SDHC_CAPABILITIES_MAX_BLOCK_LENGTH_0,
    SDHC_CAPABILITIES_MAX_BLOCK_LENGTH_1,
    SDHC_CAPABILITIES_MAX_BLOCK_LENGTH_2
  };

  SSDHC_CAPABILITIES caps = GetCapabilities();

  // Determine the maximum block length
  DEBUGCHK(caps.bits.MaxBlockLen < dim(sc_rgusBlockLen));
  DWORD dwMaxBlockLen = sc_rgusBlockLen[caps.bits.MaxBlockLen];
  DEBUGCHK(dwMaxBlockLen <= SDHC_MAX_BLOCK_LENGTH);
  return dwMaxBlockLen;
}


DWORD
CSDHCSlotBase::DetermineTimeoutControl(
    )
{
  // We try to come as close to the desired timeout without going below it.

  DEBUGCHK(m_pregDevice->IsOK());

  SSDHC_CAPABILITIES caps = GetCapabilities();

  // Determine the DAT line timeout divisor.
  // We allow the registry to override what is in the capabilities register.
  DWORD dwTimeoutClock = m_pregDevice->ValueDW(SDHC_TIMEOUT_FREQUENCY_KEY);
  if (dwTimeoutClock == 0) {
    dwTimeoutClock = caps.bits.TOFreq * 1000;

    if (dwTimeoutClock == 0) {
      dwTimeoutClock = SDHC_MAX_CLOCK_FREQUENCY;
      DEBUGMSG(SDCARD_ZONE_ERROR, 
          (_T("SDHC: No timeout frequency specified. Using default of %u\n"), 
           dwTimeoutClock));
    }
    else if (caps.bits.TimeoutUnit == 1) {
      // listing is in MHz, not KHz
      dwTimeoutClock *= 1000;
    }
  }

  DEBUGCHK(dwTimeoutClock != 0);

  DWORD dwTimeoutInMS = m_pregDevice->ValueDW(SDHC_TIMEOUT_KEY, 
      SDHC_DEFAULT_TIMEOUT);

  DOUBLE dTimeoutControl = SdhcTimeoutSecondsToControl(dwTimeoutClock, 
      dwTimeoutInMS / 1000.0);
  DWORD dwTimeoutControl;

  if (dTimeoutControl < 0) {
    dwTimeoutControl = 0;
  }
  else {
    dTimeoutControl = ceil(dTimeoutControl);
    dwTimeoutControl= (DWORD) dTimeoutControl;
  }

  dwTimeoutControl = min(dwTimeoutControl, SDHC_TIMEOUT_CONTROL_MAX);

#ifdef DEBUG
  {        
    TCHAR szTimeout[4];
    DOUBLE dActualTimeout = SdhcTimeoutControlToSeconds(dwTimeoutClock, 
        dwTimeoutControl);
    _sntprintf(szTimeout, dim(szTimeout), _T("%0.1f"), dActualTimeout);
    DEBUGCHK(szTimeout[dim(szTimeout) - 1] == 0);
    szTimeout[dim(szTimeout) - 1] = 0; // Null-terminate

    DEBUGMSG(SDCARD_ZONE_INIT, (_T("SDHC: Using timeout control value of 0x%x for %s seconds\n"), 
          dwTimeoutControl, szTimeout));
  }
#endif

  dwTimeoutControl = 0xE;
  return dwTimeoutControl;
}


DWORD 
CSDHCSlotBase::DetermineWakeupSources(
    )
{
  DEBUGCHK(m_pregDevice->IsOK());
  DWORD dwWakeupSources = m_pregDevice->ValueDW(SDHC_WAKEUP_SOURCES_KEY);
  dwWakeupSources &= WAKEUP_ALL_SOURCES;

  // Waking on SDIO interrupts must be enabled by the bus driver.
  dwWakeupSources &= ~WAKEUP_INTERRUPT; 

  return dwWakeupSources;
}


VOID
CSDHCSlotBase::SetVoltage(
    DWORD dwVddSetting
    )
{
  Validate();

  UCHAR ucVoltageSelection = SDBUS_POWER_ON;
  UCHAR ucOldVoltage;

  DEBUGCHK(dwVddSetting & m_dwVddWindows);

  if ( dwVddSetting & 
      (SD_VDD_WINDOW_3_2_TO_3_3 | SD_VDD_WINDOW_3_3_TO_3_4) ) {
    ucVoltageSelection |= SDBUS_VOLTAGE_SELECT_3_3V;
  }
  else if ( dwVddSetting & 
      (SD_VDD_WINDOW_2_9_TO_3_0 | SD_VDD_WINDOW_3_0_TO_3_1) ) {
    ucVoltageSelection |= SDBUS_VOLTAGE_SELECT_3_0V;
  }
  else if ( dwVddSetting & 
      (SD_VDD_WINDOW_1_7_TO_1_8 | SD_VDD_WINDOW_1_8_TO_1_9) ) {
    ucVoltageSelection |= SDBUS_VOLTAGE_SELECT_1_8V;
  }

  ucOldVoltage = ReadByte(SDHC_POWER_CONTROL);
  if (ucOldVoltage != ucVoltageSelection) {
    // SD Bus Power must be initially set to 0 when changing voltages
    WriteByte(SDHC_POWER_CONTROL, 0);
    WriteByte(SDHC_POWER_CONTROL, ucVoltageSelection);

    DEBUGMSG(SDCARD_ZONE_INFO,( 
          TEXT("CSDHCSlotBase::SetVoltage: Set SDHC_POWER_CONTROL reg = 0x%02x\n"),
          ucVoltageSelection));

    Sleep(GetPowerSupplyRampUpMs());
  }
}


// Set up the controller according to the interface parameters.
VOID 
CSDHCSlotBase::SetInterface(
    PSD_CARD_INTERFACE_EX pInterface
    )
{            
  PREFAST_DEBUGCHK(pInterface);
  Validate();

#if 0
  BYTE bHostCtr = 0;
  m_f4BitMode = (pInterface->InterfaceModeEx.bit.sd4Bit!=0);
  bHostCtr |= (m_f4BitMode?HOSTCTL_DAT_WIDTH:0);
  bHostCtr |= (pInterface->InterfaceModeEx.bit.sdHighSpeed!=0?HOSTCTL_HIGH_SPEED:0);
#endif
  BYTE hostctl = 0;
  if (1 == pInterface->InterfaceModeEx.bit.hsmmc8Bit) {
    DEBUGMSG(SDCARD_ZONE_INIT, 
        (TEXT("SHCSDSlotOptionHandler - Setting for 8 bit mode\n")));
    RETAILMSG(1, 
        (TEXT("[HSMMC] Setting for 8 bit mode , Clock Rate = %d Hz\n"),pInterface->ClockRate));
    hostctl |= HOSTCTL_DAT_WIDTH_8BIT;
    m_f4BitMode = TRUE;
  } else if (SD_INTERFACE_SD_MMC_1BIT == pInterface->InterfaceModeEx.bit.sd4Bit) {
    DEBUGMSG(SDCARD_ZONE_INIT, 
        (TEXT("SHCSDSlotOptionHandler - Setting for 1 bit mode\n")));
    RETAILMSG(1, 
        (TEXT("[HSMMC] Setting for 1 bit mode , Clock Rate = %d Hz\n"),pInterface->ClockRate));		
    hostctl = 0;
    m_f4BitMode = FALSE;
  } else if (SD_INTERFACE_SD_4BIT == pInterface->InterfaceModeEx.bit.sd4Bit) {
    DEBUGMSG(SDCARD_ZONE_INIT, 
        (TEXT("SHCSDSlotOptionHandler - Setting for 4 bit mode\n")));
    RETAILMSG(1, 
        (TEXT("[HSMMC] Setting for 4 bit mode , Clock Rate = %d Hz\n"),pInterface->ClockRate));
    hostctl |= HOSTCTL_DAT_WIDTH;
    m_f4BitMode = TRUE;
  }
  else {
    DEBUGCHK(FALSE);
  }

  // 2007.09.01 D.Baek
  // In the S3C6400, the high-speed enable bit of HOST_CONTROL register must be disabled
  // even if the card inserted operates at high-speed mode. This is limited only to the S3C6400.
#if 0
  if( (pInterface->ClockRate > 26000000) || (pInterface->InterfaceModeEx.bit.sdHighSpeed!=0) )
  {
    RETAILMSG(1, (TEXT("[HSMMC] Setting for high speed mode.\n")));
    hostctl |= HOSTCTL_HIGH_SPEED;
  }
#endif


  DEBUGMSG(SDCARD_ZONE_INIT, 
      (TEXT("SHCSDSlotOptionHandler - Setting Host Control Register %x \n"),bHostCtr));
  //    WriteByte(SDHC_HOST_CONTROL, bHostCtr);
  WriteByte(SDHC_HOST_CONTROL, hostctl);
  SetClockRate(&pInterface->ClockRate);
}


VOID
CSDHCSlotBase::SetPowerState(
    CEDEVICE_POWER_STATE cpsNew
    )
{
  DEBUGCHK(VALID_DX(cpsNew));

  m_fIsPowerManaged = TRUE;

  if (DX_D1_OR_D2(cpsNew)) {
    cpsNew = D0;
  }

  if (m_cpsCurrent != cpsNew) {
    SetHardwarePowerState(cpsNew);
  }
}


VOID
CSDHCSlotBase::PowerDown(
    )
{
  Validate();

  m_cpsAtPowerDown = m_cpsCurrent;

  if (!m_fIsPowerManaged) {
    CEDEVICE_POWER_STATE cps;

    if (m_bWakeupControl) {
      cps = D3;
    }
    else {
      //cps = D4;
      cps = (_CEDEVICE_POWER_STATE)D4;	// KYS
    }

    SetHardwarePowerState(cps);
  }

  BOOL fKeepPower = FALSE;
  if (m_fSleepsWithPower || m_cpsCurrent == D0) {
    DEBUGCHK(!m_fSleepsWithPower || m_cpsCurrent == D3);
    fKeepPower = TRUE;
  }

  PowerUpDown(FALSE, fKeepPower);
}


VOID 
CSDHCSlotBase::PowerUp(
    )
{
  Validate();

  if (!m_fIsPowerManaged) {
    SetHardwarePowerState(m_cpsAtPowerDown);
  }
  else if (m_fSleepsWithPower) {
    WORD wIntStatus = ReadWord(SDHC_NORMAL_INT_STATUS);
    if (wIntStatus == NORMAL_INT_STATUS_CARD_INT) {
      // We woke system through a card interrupt. We need to clear
      // this so that the IST will not be signalled.
      EnableSDIOInterrupts(FALSE);
      m_fPowerUpDisabledInts = TRUE;
    }
  }

  PowerUpDown(TRUE, TRUE);
}


  SD_API_STATUS
CSDHCSlotBase::BusRequestHandler( PSD_BUS_REQUEST pRequest)
{
  SETFNAME();
  SD_API_STATUS status;
  PREFAST_DEBUGCHK(pRequest);
  Validate();
  DEBUGMSG(SDHC_SEND_ZONE, (TEXT("%s CMD:%d\n"), pszFname, pRequest->CommandCode));
  RETAILMSG(0, (TEXT("CMD:%d\n"), pRequest->CommandCode));
  if (m_pCurrentRequest) { // We have outstand request.
    ASSERT(FALSE);
    IndicateBusRequestComplete(pRequest, SD_API_STATUS_CANCELED);
    m_pCurrentRequest = NULL;
  }
  if (!m_fCardPresent) {
    status= SD_API_STATUS_DEVICE_REMOVED;
  }
  else {
    WORD wIntSignals = ReadWord(SDHC_NORMAL_INT_SIGNAL_ENABLE);
    WriteWord(SDHC_NORMAL_INT_SIGNAL_ENABLE,0);
    m_fCurrentRequestFastPath = FALSE;
    m_pCurrentRequest = pRequest ;
    // if no data transfer involved, use FAST PATH
    if ((pRequest->SystemFlags & SD_FAST_PATH_AVAILABLE)!=0) { // Fastpath 
      m_fCurrentRequestFastPath = TRUE;
      status = SubmitBusRequestHandler( pRequest );

      if( status == SD_API_STATUS_PENDING ) { // Polling for completion.
        while (m_pCurrentRequest && (ReadDword(SDHC_PRESENT_STATE) & STATE_CARD_INSERTED)!=0 ) {
          HandleInterrupt();
        }               
        status = m_FastPathStatus;
        // 08.01.27 by KYS
        // Below added code clear before status of fastpath.
        m_FastPathStatus = 0;
        if (m_pCurrentRequest) {
          ASSERT(FALSE);

⌨️ 快捷键说明

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