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

📄 sdhcslot.cpp

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

    // Card Detect Interrupt Handling
    if (wIntStatus & (NORMAL_INT_STATUS_CARD_INSERTION | NORMAL_INT_STATUS_CARD_REMOVAL)) {
      WriteWord(SDHC_NORMAL_INT_SIGNAL_ENABLE,
          (ReadWord(SDHC_NORMAL_INT_SIGNAL_ENABLE) &~(NORMAL_INT_STATUS_CARD_INSERTION | NORMAL_INT_STATUS_CARD_REMOVAL)));
      WriteWord(SDHC_NORMAL_INT_STATUS_ENABLE,
          (ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE) &~(NORMAL_INT_STATUS_CARD_INSERTION | NORMAL_INT_STATUS_CARD_REMOVAL)));
      do {
        WriteWord(
            SDHC_NORMAL_INT_STATUS,
            NORMAL_INT_STATUS_CARD_INSERTION | NORMAL_INT_STATUS_CARD_REMOVAL);
      }while(ReadWord(SDHC_NORMAL_INT_STATUS) & (NORMAL_INT_STATUS_CARD_INSERTION | NORMAL_INT_STATUS_CARD_REMOVAL));
      WriteWord(SDHC_NORMAL_INT_STATUS_ENABLE,
          (ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE) | (NORMAL_INT_STATUS_CARD_INSERTION | NORMAL_INT_STATUS_CARD_REMOVAL)));
      WriteWord(SDHC_NORMAL_INT_SIGNAL_ENABLE,
          (ReadWord(SDHC_NORMAL_INT_SIGNAL_ENABLE) | (NORMAL_INT_STATUS_CARD_INSERTION | NORMAL_INT_STATUS_CARD_REMOVAL)));

      m_fCheckSlot = TRUE;
    }
  }

  if (m_fCheckSlot) {
    m_fCheckSlot = FALSE;

    // check card inserted or removed
    DWORD dwPresentState = ReadDword(SDHC_PRESENT_STATE);
    if (dwPresentState & STATE_CARD_INSERTED) {
      DEBUGMSG(SDHC_INTERRUPT_ZONE, (TEXT("SDHCControllerIst - Card is Inserted! \n")));
      RETAILMSG(1, (TEXT("[HSMMC] Card is Inserted! \n")));
      m_fFakeCardRemoval = FALSE;	// KYS
      if (m_fCardPresent == FALSE ) {
        Start();
        HandleInsertion();
      }
    }
    else {
      DEBUGMSG(SDHC_INTERRUPT_ZONE, (TEXT("SDHCControllerIst - Card is Removed! \n")));
      RETAILMSG(1, (TEXT("[HSMMC] Card is Removed! \n")));
      m_fFakeCardRemoval = FALSE;	// KYS
      if (m_fCardPresent) {
        HandleRemoval(TRUE);
      }
    }
  }
}


VOID 
CSDHCSlotBase::HandleRemoval(
    BOOL fCancelRequest
    )
{    
  m_fCardPresent = FALSE;
  m_fIsPowerManaged = FALSE;
  m_fSleepsWithPower = FALSE;
  m_fPowerUpDisabledInts = FALSE;
  m_f4BitMode = FALSE;
  m_cpsCurrent = D0;

  // Wake on SDIO interrupt must be set by the client
  m_bWakeupControl &= ~WAKEUP_INTERRUPT;

  // To control the Data CRC error
  WORD wErrIntSignalEn = ReadWord(SDHC_ERROR_INT_SIGNAL_ENABLE);
  WORD wErrIntStatusEn = ReadWord(SDHC_ERROR_INT_STATUS_ENABLE);
  WORD wErrIntStatus = ReadWord(SDHC_ERROR_INT_STATUS);
  WriteWord(SDHC_ERROR_INT_SIGNAL_ENABLE, (wErrIntSignalEn & ~(0x20))); //Command and Data CRC error disable
  WriteWord(SDHC_ERROR_INT_STATUS_ENABLE, (wErrIntStatusEn & ~(0x20))); //Command and Data CRC error disable


  if (m_fSDIOInterruptsEnabled) {
    EnableSDIOInterrupts(FALSE);
  }

  IndicateSlotStateChange(DeviceEjected);

  // turn off clock and remove power from the slot
  SDClockOff();
  WriteByte(SDHC_POWER_CONTROL, 0);

  if (fCancelRequest) {
    // get the current request  
    PSD_BUS_REQUEST pRequest = GetAndLockCurrentRequest();

    if (pRequest != NULL) {
      DEBUGMSG(SDCARD_ZONE_WARN, 
          (TEXT("Card Removal Detected - Canceling current request: 0x%08X, command: %d\n"), 
           pRequest, pRequest->CommandCode));
      DumpRequest(pRequest, SDHC_SEND_ZONE || SDHC_RECEIVE_ZONE);
      IndicateBusRequestComplete(pRequest, SD_API_STATUS_DEVICE_REMOVED);
    }
  }

  if (m_pbDmaBuffer) {
    DEBUGCHK(m_paDmaBuffer);
    FreePhysBuffer(m_pbDmaBuffer);
    m_pbDmaBuffer = NULL;
    m_paDmaBuffer = 0;

    // The Pegasus requires the following so that the next
    // insertion will work correctly.
    SoftwareReset(SOFT_RESET_CMD | SOFT_RESET_DAT);
    WriteDword(SDHC_SYSTEMADDRESS_LO, 0);
    WriteWord(SDHC_BLOCKSIZE, 0);
    WriteWord(SDHC_BLOCKCOUNT, 0);

    WriteWord(SDHC_NORMAL_INT_SIGNAL_ENABLE, (ReadWord(SDHC_NORMAL_INT_SIGNAL_ENABLE) & ~(NORMAL_INT_STATUS_DMA)));
    WriteWord(SDHC_NORMAL_INT_STATUS_ENABLE,(ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE) & ~(NORMAL_INT_STATUS_DMA)));
    do {
      WriteWord(SDHC_NORMAL_INT_STATUS, NORMAL_INT_STATUS_DMA);
    }while(ReadWord(SDHC_NORMAL_INT_STATUS) & NORMAL_INT_STATUS_DMA);
    WriteWord(SDHC_NORMAL_INT_STATUS_ENABLE, (ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE) | NORMAL_INT_STATUS_DMA));
    WriteWord(SDHC_NORMAL_INT_SIGNAL_ENABLE, (ReadWord(SDHC_NORMAL_INT_SIGNAL_ENABLE) | NORMAL_INT_STATUS_DMA));

    // To diable the Data CRC error interrupt
    WriteWord(SDHC_ERROR_INT_SIGNAL_ENABLE,0);  
    do
    {
      WriteWord(SDHC_ERROR_INT_STATUS,wErrIntStatus);
    }while(ReadWord(SDHC_ERROR_INT_STATUS));
    WriteWord(SDHC_ERROR_INT_SIGNAL_ENABLE,wErrIntSignalEn);
  }
  v_gBspArgs->g_SDCardState = CARD_REMOVED;
  SetEvent( v_gBspArgs->g_SDCardDetectEvent );
}


VOID 
CSDHCSlotBase::HandleInsertion(
    )
{
  DWORD dwClockRate = SD_DEFAULT_CARD_ID_CLOCK_RATE;

  WORD wErrIntSignalEn = ReadWord(SDHC_ERROR_INT_SIGNAL_ENABLE);
  WORD wErrIntStatusEn = ReadWord(SDHC_ERROR_INT_STATUS_ENABLE);

  g_initialInsertion = 0;
  m_fCardPresent = TRUE;

  // Apply the initial voltage to the card.
  SetVoltage(GetMaxVddWindow());

  // Send at least 74 clocks to the card over the course of at least 1 ms
  // with allowance for power supply ramp-up time. (SD Phys Layer 6.4)
  // Note that power supply ramp-up time occurs in SetVoltage().
  SetClockRate(&dwClockRate);
  SDClockOn();
  DWORD dwSleepMs = (74 / (dwClockRate / 1000)) + 1;
  Sleep(dwSleepMs);
  SDClockOff();

  if (GetCapabilities().bits.DMA) {
    PHYSICAL_ADDRESS SystemAddr = { 0 };
    PVOID pvBuffer = AllocPhysBuffer(CB_DMA_BUFFER, &SystemAddr.LowPart);        
    if (pvBuffer) {
      PHYSICAL_ADDRESS BusAddr;

      // Translate physical address to logical (bus-relative) address.
      BOOL fSuccess = TranslateSystemAddr(m_hBusAccess, m_interfaceType, 
          m_dwBusNumber, SystemAddr, &BusAddr);
      if (fSuccess) {
        m_pbDmaBuffer= (PBYTE) pvBuffer;
        m_paDmaBuffer = BusAddr.LowPart;
      }
      else {
        // If we fail, we will simply fall back to PIO mode
        FreePhysBuffer(pvBuffer);
      }
    }
  }

  // Interrupts are not enabled on a newly inserted card.
  EnableSDIOInterrupts(FALSE);

  // Indicate device arrival
  IndicateSlotStateChange(DeviceInserted);

  WriteWord(SDHC_ERROR_INT_SIGNAL_ENABLE, (wErrIntSignalEn | (0x20))); //Command and Data CRC error disable
  WriteWord(SDHC_ERROR_INT_STATUS_ENABLE, (wErrIntStatusEn | (0x20))); //Command and Data CRC error disable

  v_gBspArgs->g_SDCardState = CARD_INSERTED;
  SetEvent( v_gBspArgs->g_SDCardDetectEvent );
}


BOOL 
CSDHCSlotBase::HandleCommandComplete(
    )
{
  SETFNAME();

  PSD_BUS_REQUEST pRequest;
  BOOL fRet = FALSE;

  // get the current request  
  pRequest = GetAndLockCurrentRequest();

  DEBUGCHK(m_dwReadyInts == 0);

  if (pRequest) {

    DEBUGCHK(pRequest->HCParam == 0);
    // 08.02.03 by KYS
    // INT_TRX_COMPLETE is not suitable for s3c6410, so I comment out below code.
    // therefore, in order to keep fastpath status, those code like just below is needed.
    //SD_API_STATUS transferStatus = SD_API_STATUS_SUCCESS;
    SD_API_STATUS transferStatus = m_FastPathStatus>=0 ? SD_API_STATUS_SUCCESS : m_FastPathStatus;

    if (NoResponse != pRequest->CommandResponse.ResponseType) {
      // Copy response over to request structure. Note that this is a 
      // bus driver buffer, so we do not need to SetProcPermissions 
      // or __try/__except.
      UNALIGNED DWORD *pdwResponseBuffer = 
        (PDWORD) (pRequest->CommandResponse.ResponseBuffer + 1); // Skip CRC
      WORD wCommand = ReadWord(SDHC_COMMAND);

      if ((wCommand & CMD_RESPONSE_R1B_R5B) == CMD_RESPONSE_R1B_R5B) {
        // wait for Transfer Complete status, which indicate the busy wait is over.
        // we should not handle this TXN_COMPLETE interrupt in IST in this case
#if 0
        BOOL fSuccess = WaitForReg<WORD>(ReadWord, SDHC_NORMAL_INT_STATUS, 
            NORMAL_INT_STATUS_TRX_COMPLETE, NORMAL_INT_STATUS_TRX_COMPLETE, 5000);
        if (!fSuccess) {
          DEBUGMSG(SDCARD_ZONE_ERROR, (_T("%s Timeout waiting for NORMAL_INT_STATUS_TRX_COMPLETE\r\n"),
                pszFname));
          transferStatus = SD_API_STATUS_RESPONSE_TIMEOUT;
        }
#endif
        // Reset cmd and dat circuits
        SoftwareReset(SOFT_RESET_CMD | SOFT_RESET_DAT);
      }

      pdwResponseBuffer[0] = ReadDword(SDHC_R0);

      if (pRequest->CommandResponse.ResponseType == ResponseR2) {
        pdwResponseBuffer[1] = ReadDword(SDHC_R2);
        pdwResponseBuffer[2] = ReadDword(SDHC_R4);
        pdwResponseBuffer[3] = ReadDword(SDHC_R6);
      }
    }

    // check for command/response only
    if (TRANSFER_IS_COMMAND_ONLY(pRequest)) {
      IndicateBusRequestComplete(pRequest, transferStatus);
      fRet = TRUE;
    } else {
      // handle data phase transfer
      pRequest->HCParam = 0;
      fRet = FALSE;
    }
  }
  // else request must have been canceled due to an error

  return fRet;
}


VOID 
CSDHCSlotBase::HandleErrors(
    )
{
  SD_API_STATUS status = SD_API_STATUS_SUCCESS;
  // 2007.06.10
  // S/W workaround for the following problem
  // Problem : When the interrupt is occurred, it is late to update the interrupt status register related to the interrupt source
  while((ReadWord(SDHC_ERROR_INT_STATUS) == 0));

  // get the current request
  PSD_BUS_REQUEST pRequest = NULL;
  pRequest = GetAndLockCurrentRequest();

  WORD wErrorStatus = ReadWord(SDHC_ERROR_INT_STATUS);
  DEBUGMSG(SDCARD_ZONE_ERROR, 
      (TEXT("HandleErrors - ERROR INT STATUS=0x%02X\n"), wErrorStatus));
  if (pRequest) {
    DumpRequest(pRequest, SDCARD_ZONE_ERROR);
  }

  DEBUGCHK( (wErrorStatus & ERR_INT_STATUS_VENDOR) == 0 );

  if (wErrorStatus) {
    if ( wErrorStatus & ERR_INT_STATUS_CMD_TIMEOUT ) {
      status = SD_API_STATUS_RESPONSE_TIMEOUT;
      RETAILMSG(1, (TEXT("[HSMMC] CMD Timeout Error...\n")));
    }

    if ( wErrorStatus & ERR_INT_STATUS_CMD_CRC ) {
      status = SD_API_STATUS_CRC_ERROR;
      RETAILMSG(1, (TEXT("[HSMMC] CMD CRC Error...\n")));
      if ( wErrorStatus & ERR_INT_STATUS_CMD_TIMEOUT )
        status = SD_API_STATUS_DEVICE_RESPONSE_ERROR;
      RETAILMSG(1, (TEXT("[HSMMC] CMD Timeout Error...\n")));
    }

    if ( wErrorStatus & ERR_INT_STATUS_CMD_ENDBIT ) {
      status = SD_API_STATUS_RESPONSE_TIMEOUT;
      RETAILMSG(1, (TEXT("[HSMMC] CMD ENDBIT Error...\n")));
    }

    if ( wErrorStatus & ERR_INT_STATUS_CMD_INDEX ) {
      status = SD_API_STATUS_DEVICE_RESPONSE_ERROR;
      RETAILMSG(1, (TEXT("[HSMMC] CMD INDEX Error...\n")));
    }

    if ( wErrorStatus & ERR_INT_STATUS_DAT_TIMEOUT ) {
      status = SD_API_STATUS_DATA_TIMEOUT;
      RETAILMSG(1, (TEXT("[HSMMC] DAT Timeout Error...\n")));
    }

    if ( wErrorStatus & ERR_INT_STATUS_DAT_CRC ) {
      status = SD_API_STATUS_CRC_ERROR;
      RETAILMSG(1, (TEXT("[HSMMC] DAT CRC Error...\n")));
    }

    if ( wErrorStatus & ERR_INT_STATUS_DAT_ENDBIT ) {
      status = SD_API_STATUS_DEVICE_RESPONSE_ERROR;
      RETAILMSG(1, (TEXT("[HSMMC] DAT ENDBIT Error...\n")));
    }

    if ( wErrorStatus & ERR_INT_STATUS_BUS_POWER ) {
      status = SD_API_STATUS_DEVICE_RESPONSE_ERROR;
      RETAILMSG(1, (TEXT("[HSMMC] BUS POWER Error...\n")));
    }

    if ( wErrorStatus & ERR_INT_STATUS_AUTOCMD12 ) {
      status = SD_API_STATUS_DEVICE_RESPONSE_ERROR;
      RETAILMSG(1, (TEXT("[HSMMC] AUTOCMD12 Error...\n")));
    }

    // Perform basic error recovery
    WORD wErrIntSignal = ReadWord(SDHC_ERROR_INT_SIGNAL_ENABLE);
    WriteWord(SDHC_ERROR_INT_SIGNAL_ENABLE, 0);
    WORD wErrIntStatusEn = ReadWord(SDHC_ERROR_INT_STATUS_ENABLE);	// KYS
    WriteWord(SDHC_ERROR_INT_STATUS_ENABLE,0);	// KYS


    if (IS_CMD_LINE_ERROR(wErrorStatus)) {
      // Reset CMD line
      DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("HandleErrors - Command line error (0x%x). Resetting CMD line.\r\n"),
            wErrorStatus));
      do {
        WriteWord(SDHC_ERROR_INT_STATUS, wErrorStatus);
      } while(ReadWord(SDHC_ERROR_INT_STATUS) && (ReadWord(SDHC_NORMAL_INT_STATUS) & NORMAL_INT_STATUS_ERROR_INT));

      SoftwareReset(SOFT_RESET_CMD);
    }

    if (IS_DAT_LINE_ERROR(wErrorStatus)) {
      // Reset DAT line
      DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("HandleErrors - Data line error (0x%x). Resetting DAT line.\r\n"),
            wErrorStatus));
      SoftwareReset(SOFT_RESET_DAT);
    }

    // clear all error status
    do {
      WriteWord(SDHC_ERROR_INT_STATUS, wErrorStatus);
    }while(ReadWord(SDHC_ERROR_INT_STATUS));	// KYS

    // re-enable error interrupt signals
    WriteWord(SDHC_ERROR_INT_STATUS_ENABLE, wErrIntStatusEn);
    WriteWord(SDHC_ERROR_INT_SIGNAL_ENABLE, wErrIntSignal);	// KYS

    // complete the request
    if (pRequest) {
      IndicateBusRequestComplete(pRequest, status);
    }
    else {  // KYS
      WORD wIntEnable = ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE);
      wIntEnable |= NORMAL_INT_ENABLE_CMD_COMPLETE | NORMAL_INT_ENABLE_TRX_COMPLETE;
      WriteWord(SDHC_NORMAL_INT_STATUS_ENABLE,wIntEnable);
      RETAILMSG(0,(TEXT("Error Handler : 0x%X\n"),ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE)));
    }
  }
}


VOID 
CSDHCSlotBase::HandleTransferDone(
    )
{
  PSD_BUS_REQUEST pRequest;
  SD_API_STATUS   status = SD_API_STATUS_SUCCESS;

⌨️ 快捷键说明

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