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

📄 sdhcslot.cpp

📁 s3c2450 bsp for wince 5.0 经验证,完全没问题
💻 CPP
📖 第 1 页 / 共 5 页
字号:
#elif (BSP_TYPE == BSP_SMDK2450)
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("[HSMMC1] 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("[HSMMC1] 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("[HSMMC1] 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("[HSMMC1] 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);
}
#endif


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 = (_CEDEVICE_POWER_STATE)D4;
    }

    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);
#if (BSP_TYPE == BSP_SMDK2443)
  Start();	// added by JJG 06.11.11

#elif (BSP_TYPE == BSP_SMDK2450)
#endif
}


#if (BSP_TYPE == BSP_SMDK2443)
SD_API_STATUS
CSDHCSlotBase::BusRequestHandler(
    PSD_BUS_REQUEST pRequest
    )
{
  SETFNAME();

  PREFAST_DEBUGCHK(pRequest);
  Validate();

  WORD            wRegCommand;
  SD_API_STATUS   status;
  WORD            wIntStatusEn;
  BOOL            fSuccess;

  DEBUGCHK(m_dwReadyInts == 0);
  DEBUGCHK(!m_fCommandCompleteOccurred);

  RETAILMSG(0, (TEXT("%s CMD:%d\n"), pszFname, pRequest->CommandCode));
  DEBUGMSG(SDHC_SEND_ZONE, (TEXT("%s CMD:%d\n"), pszFname, pRequest->CommandCode));

  // bypass CMD12 if AutoCMD12 was done by hardware
  if (pRequest->CommandCode == 12) {
    if (m_fAutoCMD12Success) {
      RETAILMSG(0, 
          (TEXT("%s AutoCMD12 Succeeded, bypass CMD12.\n"), pszFname));			
      DEBUGMSG(SDHC_SEND_ZONE, 
          (TEXT("%s AutoCMD12 Succeeded, bypass CMD12.\n"), pszFname));
      // The response for Auto CMD12 is in a special area
      UNALIGNED DWORD *pdwResponseBuffer = 
        (PDWORD) (pRequest->CommandResponse.ResponseBuffer + 1); // Skip CRC
      *pdwResponseBuffer = ReadDword(SDHC_R6);
      IndicateBusRequestComplete(pRequest, SD_API_STATUS_SUCCESS);
      status = SD_API_STATUS_SUCCESS;
      goto EXIT;
    }
  }

  m_fAutoCMD12Success = FALSE;

  // initialize command register with command code
  RETAILMSG(0,(TEXT("SendCommand  0x%x\n"),pRequest->CommandCode));
  wRegCommand = (pRequest->CommandCode << CMD_INDEX_SHIFT) & CMD_INDEX_MASK;

  // check for a response
  switch (pRequest->CommandResponse.ResponseType) {
    case NoResponse:
      break;

    case ResponseR2:
      wRegCommand |= CMD_RESPONSE_R2;
      break;

    case ResponseR3:
    case ResponseR4:
      wRegCommand |= CMD_RESPONSE_R3_R4;
      break;

    case ResponseR1:
    case ResponseR5:
    case ResponseR6:
#ifdef _MMC_SPEC_42_
      /*************************************************************************/
      /****** Date : 07.05.14                                         	******/
      /****** Developer : HS.JANG											******/
      /****** Description : to support SD SPEC20 card. Response7 is added	******/
      /****** 			  for supporting SD SPEC20 card					******/
      /*************************************************************************/

    case ResponseR7:
      /*************************************************************************/
#endif    

      wRegCommand |= CMD_RESPONSE_R1_R5_R6;
      break;

    case ResponseR1b:
      wRegCommand |= CMD_RESPONSE_R1B_R5B;   
      break;

    default:
      status = SD_API_STATUS_INVALID_PARAMETER;
      goto EXIT;
  }

  // Set up variable for the new interrupt sources. Note that we must
  // enable DMA and read/write interrupts in this routine (not in
  // HandleCommandComplete) or they will be missed.
  wIntStatusEn = ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE);
  wIntStatusEn |= NORMAL_INT_ENABLE_CMD_COMPLETE | NORMAL_INT_ENABLE_TRX_COMPLETE;

  // check command inhibit, wait until OK
  fSuccess = WaitForReg<DWORD>(ReadDword, SDHC_PRESENT_STATE, STATE_CMD_INHIBIT, 0);
  if (!fSuccess) {
    DEBUGMSG(SDCARD_ZONE_ERROR, (_T("%s Timeout waiting for CMD Inhibit\r\n"),
          pszFname));
    status = SD_API_STATUS_DEVICE_NOT_RESPONDING;
    goto EXIT;
  }

  // programming registers
  if (!TRANSFER_IS_COMMAND_ONLY(pRequest)) {
    WORD wRegTxnMode = 0;   

#ifdef _MMC_SPEC_42_
    /*************************************************************************/
    /****** Date : 07.05.14                                         	******/
    /****** Developer : HS.JANG											******/
    /****** Description : to support MMCMicro this code was added	 	******/
    /*************************************************************************/

    if ( (ReadByte(SDHC_TIMEOUT_CONTROL) != m_dwTimeoutControl) && 
        pRequest->CommandCode != MMC_CMD_SEND_EXT_CSD ) 
    {
      WriteByte(SDHC_TIMEOUT_CONTROL, (BYTE) m_dwTimeoutControl);
    }

    if ( pRequest->CommandCode == MMC_CMD_SEND_EXT_CSD ) 
    {
      WriteByte(SDHC_TIMEOUT_CONTROL, 0x3);
    }
    /*************************************************************************/
#endif


    wRegCommand |= CMD_DATA_PRESENT;

    if (UseDmaForRequest(pRequest)) {
      wIntStatusEn |= NORMAL_INT_ENABLE_DMA;

      BOOL fNoException;
      DEBUGCHK(TRANSFER_SIZE(pRequest) <= CB_DMA_BUFFER);

      if (TRANSFER_IS_WRITE(pRequest)) {
        DWORD cbToTransfer = TRANSFER_SIZE(pRequest);

        SD_SET_PROC_PERMISSIONS_FROM_REQUEST(pRequest) {
          fNoException = SDPerformSafeCopy(m_pbDmaBuffer,
              pRequest->pBlockBuffer, cbToTransfer);
        } SD_RESTORE_PROC_PERMISSIONS();

        if (fNoException == FALSE) {
          status = SD_API_STATUS_ACCESS_VIOLATION;
          goto EXIT;
        }
      }

      WriteDword(SDHC_SYSTEMADDRESS_LO, m_paDmaBuffer);
      wRegTxnMode |= TXN_MODE_DMA;
    }
    else {
      if (TRANSFER_IS_WRITE(pRequest)) {
        wIntStatusEn |= NORMAL_INT_ENABLE_BUF_WRITE_RDY;
      }
      else {
        wIntStatusEn |= NORMAL_INT_ENABLE_BUF_READ_RDY;
      }
    }

    // BlockSize
    // Note that for DMA we are programming the buffer boundary for 512K Bytes
    DEBUGMSG(SDHC_SEND_ZONE,(TEXT("Sending command block size 0x%04X\r\n"), (WORD) pRequest->BlockSize));
    WriteWord(SDHC_BLOCKSIZE,  (WORD)((0x7<<12)| pRequest->BlockSize));

    // We always go into block mode even if there is only 1 block. 
    // Otherwise the Pegasus will occaissionally hang when
    // writing a single block with DMA.

    wRegTxnMode |= (TXN_MODE_MULTI_BLOCK | TXN_MODE_BLOCK_COUNT_ENABLE);
    /*
       if(pRequest->CommandCode == 18 || pRequest->CommandCode == 25)
       wRegTxnMode |= (TXN_MODE_MULTI_BLOCK | TXN_MODE_BLOCK_COUNT_ENABLE);
       else
       wRegTxnMode |= ( TXN_MODE_BLOCK_COUNT_ENABLE);*/


    // BlockCount
    DEBUGMSG(SDHC_SEND_ZONE,(TEXT("Sending command block count 0x%04X\r\n"), 
          (WORD) pRequest->NumBlocks));            
    WriteWord(SDHC_BLOCKCOUNT, (WORD) pRequest->NumBlocks);

    //if (pRequest->Flags & SD_AUTO_ISSUE_CMD12 && *((DWORD *)(pRequest->hDevice)) != 0 ) {
    if (pRequest->Flags & SD_AUTO_ISSUE_CMD12) {
      wRegTxnMode |= TXN_MODE_AUTO_CMD12;
    }

    if (TRANSFER_IS_READ(pRequest)) {
      wRegTxnMode |= TXN_MODE_DATA_DIRECTION_READ;     
    }

    // check dat inhibit, wait until okay
    fSuccess = WaitForReg<DWORD>(ReadDword, SDHC_PRESENT_STATE, STATE_DAT_INHIBIT, 0); 
    if (!fSuccess) {
      DEBUGMSG(SDCARD_ZONE_ERROR, (_T("%s Timeout waiting for DAT Inhibit\r\n"),
            pszFname));
      RETAILMSG(1, (_T("%s Timeout waiting for DAT Inhibit\r\n"),
            pszFname));

      status = SD_API_STATUS_DEVICE_NOT_RESPONDING;
      goto EXIT;
    }

    DEBUGMSG(SDHC_SEND_ZONE,(TEXT("Sending Transfer Mode 0x%04X\r\n"),wRegTxnMode));	
    WriteWord(SDHC_TRANSFERMODE, wRegTxnMode);
  } else {
    RETAILMSG(0,(TEXT("Command Only\n")));
    // Command-only
    if (pRequest->CommandCode == SD_CMD_STOP_TRANSMISSION) {
      wRegCommand |= CMD_TYPE_ABORT;
    }
    else if (TransferIsSDIOAbort(pRequest)) {
      // Use R5b For CMD52, Function 0, I/O Abort
      DEBUGMSG(SDHC_SEND_ZONE, (TEXT("Sending Abort command \r\n")));
      wRegCommand |= CMD_TYPE_ABORT | CMD_RESPONSE_R1B_R5B;
    }
    if (pRequest->CommandCode == 23) {
      wRegCommand |= CMD_INDEX_CHECK | CMD_CRC_CHECK | CMD_RESPONSE_LENGTH_48;
    }	

    // The following is required for the Pegasus. If it is not present,
    // command-only transfers will sometimes fail (especially R1B and R5B).
    WriteDword(SDHC_SYSTEMADDRESS_LO, 0);
    WriteWord(SDHC_BLOCKSIZE, 0);
    WriteWord(SDHC_BLOCKCOUNT, 0);
  }

  RETAILMSG(0,(TEXT("Sending command register 0x%04X\r\n"),wRegCommand));
  RETAILMSG(0,(TEXT("Sending command Argument 0x%08X\r\n"),pRequest->CommandArgument));

⌨️ 快捷键说明

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