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

📄 sdhcslot.cpp

📁 s3c2450 bsp for wince 5.0 经验证,完全没问题
💻 CPP
📖 第 1 页 / 共 5 页
字号:
      }

      // Buffer Write Ready handling
      if (wIntStatus & NORMAL_INT_STATUS_BUF_WRITE_RDY ) {
        // Clear status
        WriteWord(SDHC_NORMAL_INT_STATUS, NORMAL_INT_STATUS_BUF_WRITE_RDY);
        HandleWriteReady();
        // do not break here. Continue to check TransferComplete. 
      }
    }
    else {
      // We received data transfer interrupt before command 
      // complete interrupt. Wait for the command complete before
      // processing the data interrupt.
    }

    // Transfer Complete handling
    if ( wIntStatus & NORMAL_INT_STATUS_TRX_COMPLETE ) {
      // Clear status
      WriteWord(SDHC_NORMAL_INT_STATUS, 
          NORMAL_INT_STATUS_TRX_COMPLETE | NORMAL_INT_STATUS_DMA);
      HandleTransferDone();
    }

    // SDIO Interrupt Handling
    if ( wIntStatus & NORMAL_INT_STATUS_CARD_INT ) {
      DEBUGCHK(m_fSDIOInterruptsEnabled);
      DEBUGMSG(SDHC_INTERRUPT_ZONE, (_T("SDHCControllerIst: Card interrupt!\n")));

      // Because SDIO Interrupt is level triggered, we are not able to clear
      // the status. The status should be cleared by the card
      // we just disable the interrupt from Interrupt Signal Register
      // and Interrupt Status Enable register, and indicate that 
      // the card is interrupting
      EnableSDIOInterrupts(FALSE);
      //WriteWord(SDHC_NORMAL_INT_STATUS, NORMAL_INT_STATUS_CARD_INT);
      //RETAILMSG(1,(TEXT("SDHC_NORMAL_INT_STATUS=0x%X\n"),ReadWord(SDHC_NORMAL_INT_STATUS)));			
      IndicateSlotStateChange(DeviceInterrupting);
    }

    // Card Detect Interrupt Handling
    if (wIntStatus & (NORMAL_INT_STATUS_CARD_INSERTION | NORMAL_INT_STATUS_CARD_REMOVAL)) {
      WriteWord(
          SDHC_NORMAL_INT_STATUS,
          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) {
      RETAILMSG(1, (TEXT("+++++++++++++++++++++SDHCControllerIst - Card is Inserted! 0x%08X\n"),this));			
      DEBUGMSG(SDHC_INTERRUPT_ZONE, (TEXT("SDHCControllerIst - Card is Inserted! \n")));
      m_fFakeCardRemoval = FALSE;			// added by JJG 06.11.13
      if (m_fCardPresent == FALSE ) {
        HandleInsertion();
      }
    }
    else {
      RETAILMSG(1, (TEXT("------------------------SDHCControllerIst - Card is Removed! 0x%08X\n"),this));	

      DEBUGMSG(SDHC_INTERRUPT_ZONE, (TEXT("SDHCControllerIst - Card is Removed! \n")));
      m_fFakeCardRemoval = FALSE;			// added by JJG 06.11.13
      if (m_fCardPresent) {
        HandleRemoval(TRUE);
      }
    }
  }
}

#elif (BSP_TYPE == BSP_SMDK2450)

#ifndef _SMDK2450_CH0_EXTCD_
VOID CSDHCSlotBase::HandleInterrupt()
#else
// 08.03.20 by KYS
// New Interrupt handler function can process factors on new card detect interrupt of HSMMC ch0 on SMDK450.
VOID CSDHCSlotBase::HandleInterrupt(SDSLOT_INT_TYPE intType)
#endif
{
  Validate();
#ifdef _SMDK2450_CH0_EXTCD_
	// in case of it is occurred a card detect interrupt of HSMMC ch0 on SMDK2450.
	if (intType == SDSLOT_INT_CARD_DETECTED) {
		RETAILMSG(0,(TEXT("[HSMMC0] Card Insertion or Removal Detect!!\n")));	
		m_fCheckSlot = TRUE;
	} else {  
#endif
  WORD wIntStatus = 0;
  wIntStatus = ReadWord(SDHC_NORMAL_INT_STATUS);

  if (m_fFakeCardRemoval && m_fCardPresent) {
    m_fFakeCardRemoval = FALSE;
    HandleRemoval(TRUE);
  }

  if (wIntStatus != 0) {
    DEBUGMSG(SDHC_INTERRUPT_ZONE, 
        (TEXT("HandleInterrupt (%u) - Normal Interrupt_Status=0x%02x\n"),
         m_dwSlot, wIntStatus));
    RETAILMSG(0, 
        (TEXT("HandleInterrupt (%u) - Normal Interrupt_Status=0x%02x\n"),
         m_dwSlot, wIntStatus));

    // Error handling. Make sure to handle errors first. 
    if ( wIntStatus & NORMAL_INT_STATUS_ERROR_INT ) {
      HandleErrors();
    }

    // Command Complete handling.
    if ( wIntStatus & NORMAL_INT_STATUS_CMD_COMPLETE ) {
      // Clear status
      m_fCommandCompleteOccurred = TRUE;
      WriteWord(SDHC_NORMAL_INT_SIGNAL_ENABLE,(ReadWord(SDHC_NORMAL_INT_SIGNAL_ENABLE) & ~(NORMAL_INT_STATUS_CMD_COMPLETE)));
      WriteWord(SDHC_NORMAL_INT_STATUS_ENABLE,(ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE) & ~(NORMAL_INT_STATUS_CMD_COMPLETE)));
      do {
        WriteWord(SDHC_NORMAL_INT_STATUS, NORMAL_INT_STATUS_CMD_COMPLETE);
      }while(ReadWord(SDHC_NORMAL_INT_STATUS) & (NORMAL_INT_STATUS_CMD_COMPLETE));
      WriteWord(SDHC_NORMAL_INT_STATUS_ENABLE,(ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE) | NORMAL_INT_STATUS_CMD_COMPLETE));
      WriteWord(SDHC_NORMAL_INT_SIGNAL_ENABLE,(ReadWord(SDHC_NORMAL_INT_SIGNAL_ENABLE) | NORMAL_INT_STATUS_CMD_COMPLETE));

      if ( HandleCommandComplete() ) {
        wIntStatus &= ~NORMAL_INT_STATUS_TRX_COMPLETE; // this is command-only request. 
      }
    }

    // Sometimes at the lowest clock rate, the Read/WriteBufferReady
    // interrupt actually occurs before the CommandComplete interrupt.
    // This confuses our debug validation code and could potentially
    // cause problems. This is why we will verify that the CommandComplete
    // occurred before processing any data transfer interrupts.
    if (m_fCommandCompleteOccurred) {
      if (wIntStatus & NORMAL_INT_STATUS_DMA) {
        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));

        HandleDma();
        // do not break here. Continue to check TransferComplete. 
      }

      // Buffer Read Ready handling
      if (wIntStatus & NORMAL_INT_STATUS_BUF_READ_RDY ) {
        // Clear status
        WriteWord(SDHC_NORMAL_INT_SIGNAL_ENABLE,(ReadWord(SDHC_NORMAL_INT_SIGNAL_ENABLE) & ~(NORMAL_INT_STATUS_BUF_READ_RDY)));
        WriteWord(SDHC_NORMAL_INT_STATUS_ENABLE,(ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE) & ~(NORMAL_INT_STATUS_BUF_READ_RDY)));
        do {
          WriteWord(SDHC_NORMAL_INT_STATUS, NORMAL_INT_STATUS_BUF_READ_RDY);
        }while((ReadWord(SDHC_NORMAL_INT_STATUS) & NORMAL_INT_STATUS_BUF_READ_RDY));
        WriteWord(SDHC_NORMAL_INT_STATUS_ENABLE,(ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE) | NORMAL_INT_STATUS_BUF_READ_RDY));
        WriteWord(SDHC_NORMAL_INT_SIGNAL_ENABLE, (ReadWord(SDHC_NORMAL_INT_SIGNAL_ENABLE) | NORMAL_INT_STATUS_BUF_READ_RDY));

        HandleReadReady();
        // do not break here. Continue to check TransferComplete. 
      }

      // Buffer Write Ready handling
      if (wIntStatus & NORMAL_INT_STATUS_BUF_WRITE_RDY ) {
        // Clear status
        WriteWord(SDHC_NORMAL_INT_SIGNAL_ENABLE,(ReadWord(SDHC_NORMAL_INT_SIGNAL_ENABLE) & ~(NORMAL_INT_STATUS_BUF_WRITE_RDY)));
        WriteWord(SDHC_NORMAL_INT_STATUS_ENABLE,(ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE) & ~(NORMAL_INT_STATUS_BUF_WRITE_RDY)));
        do {
          WriteWord(SDHC_NORMAL_INT_STATUS, NORMAL_INT_STATUS_BUF_WRITE_RDY);
        }while((ReadWord(SDHC_NORMAL_INT_STATUS) & NORMAL_INT_STATUS_BUF_WRITE_RDY));
        WriteWord(SDHC_NORMAL_INT_STATUS_ENABLE,(ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE) | NORMAL_INT_STATUS_BUF_WRITE_RDY));
        WriteWord(SDHC_NORMAL_INT_SIGNAL_ENABLE,(ReadWord(SDHC_NORMAL_INT_SIGNAL_ENABLE) | NORMAL_INT_STATUS_BUF_WRITE_RDY));

        HandleWriteReady();
        // do not break here. Continue to check TransferComplete. 
      }
    }
    else {
      // We received data transfer interrupt before command 
      // complete interrupt. Wait for the command complete before
      // processing the data interrupt.
    }

    // Transfer Complete handling
    if ( wIntStatus & NORMAL_INT_STATUS_TRX_COMPLETE ) {
      // Clear status
      WriteWord(SDHC_NORMAL_INT_SIGNAL_ENABLE,(ReadWord(SDHC_NORMAL_INT_SIGNAL_ENABLE) & ~(NORMAL_INT_STATUS_TRX_COMPLETE)));
      WriteWord(SDHC_NORMAL_INT_STATUS_ENABLE,(ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE) & ~(NORMAL_INT_STATUS_TRX_COMPLETE)));
      do {
        WriteWord(SDHC_NORMAL_INT_STATUS, NORMAL_INT_STATUS_TRX_COMPLETE | NORMAL_INT_STATUS_DMA);
      }while(ReadWord(SDHC_NORMAL_INT_STATUS) & (NORMAL_INT_STATUS_TRX_COMPLETE|NORMAL_INT_STATUS_DMA));
      WriteWord(SDHC_NORMAL_INT_STATUS_ENABLE,(ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE) | NORMAL_INT_STATUS_TRX_COMPLETE));
      WriteWord(SDHC_NORMAL_INT_SIGNAL_ENABLE,(ReadWord(SDHC_NORMAL_INT_SIGNAL_ENABLE) | NORMAL_INT_STATUS_TRX_COMPLETE));


      HandleTransferDone();
    }

    // SDIO Interrupt Handling
    if ( wIntStatus & NORMAL_INT_STATUS_CARD_INT ) {
      DEBUGCHK(m_fSDIOInterruptsEnabled);
      DEBUGMSG(SDHC_INTERRUPT_ZONE, (_T("SDHCControllerIst: Card interrupt!\n")));

      // Because SDIO Interrupt is level triggered, we are not able to clear
      // the status. The status should be cleared by the card
      // we just disable the interrupt from Interrupt Signal Register
      // and Interrupt Status Enable register, and indicate that 
      // the card is interrupting
      EnableSDIOInterrupts(FALSE);
      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;
    }
  }
#ifdef _SMDK2450_CH0_EXTCD_
  } // The end of "if(intType == SDSLOT_INT_CARD_DETECTED)"
#endif

  if (m_fCheckSlot) {
    m_fCheckSlot = FALSE;
#ifdef _SMDK2450_CH0_EXTCD_
		// At this time, we have to validate the card present status.
		if((IsCardPresent() == TRUE) && (m_fCardPresent != TRUE))
#else	
    // check card inserted or removed
    DWORD dwPresentState = ReadDword(SDHC_PRESENT_STATE);
    if (dwPresentState & STATE_CARD_INSERTED)
#endif
    {
      DEBUGMSG(SDHC_INTERRUPT_ZONE, (TEXT("SDHCControllerIst - Card is Inserted! \n")));
      RETAILMSG(1, (TEXT("[HSMMC0] Card is Inserted! \n")));
      m_fFakeCardRemoval = FALSE;	// KYS
      if (m_fCardPresent == FALSE ) {
        Start();
        HandleInsertion();
      }
    }
#ifdef _SMDK2450_CH0_EXTCD_
		else if((IsCardPresent() == FALSE))
#else    
    else
#endif
    {
      DEBUGMSG(SDHC_INTERRUPT_ZONE, (TEXT("SDHCControllerIst - Card is Removed! \n")));
      RETAILMSG(1, (TEXT("[HSMMC0] Card is Removed! \n")));
      m_fFakeCardRemoval = FALSE;	// KYS
      if (m_fCardPresent) {
        HandleRemoval(TRUE);
      }
    }
  }
}
#endif  // !(BSP_TYPE == BSP_SMDK2443)


#ifdef _SMDK2450_CH0_EXTCD_
// New function can detect whether card is presented of HSMMC ch0 on SMDK2450.
BOOL CSDHCSlotBase::IsCardPresent()
{
	BOOL fRetVal;
	volatile S3C2450_IOPORT_REG *pIOPreg = NULL;
  pIOPreg = (volatile S3C2450_IOPORT_REG *)VirtualAlloc(0, sizeof(S3C2450_IOPORT_REG), MEM_RESERVE, PAGE_NOACCESS);
  if (pIOPreg == NULL) {
    RETAILMSG(1,(TEXT("[HSMMC0] GPIO registers is *NOT* allocated.\n")));
    return FALSE;
  }
  if (!VirtualCopy((PVOID)pIOPreg, (PVOID)(S3C2450_BASE_REG_PA_IOPORT >> 8),
        sizeof(S3C2450_IOPORT_REG), PAGE_PHYSICAL|PAGE_READWRITE|PAGE_NOCACHE)) {
    RETAILMSG(1,(TEXT("[HSMMC0] GPIO registers is *NOT* mapped.\n")));
    return FALSE;
  }

  if ( (pIOPreg->GPFDAT & (0x1<<1)) == 0 ) {
		fRetVal = TRUE;
	}	else {
		fRetVal = FALSE;
	}

	RETAILMSG(0,(TEXT("IsCardPresent() : fRetVal = %d  GPFDAT = 0x%x\n"), fRetVal, pIOPreg->GPFDAT));

  VirtualFree((PVOID) pIOPreg, 0, MEM_RELEASE);

	return fRetVal;
}
#endif


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;

#if (BSP_TYPE == BSP_SMDK2443)

#elif (BSP_TYPE == BSP_SMDK2450)
  // 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
#endif
  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);
#if (BSP_TYPE == BSP_SMDK2443)
    WriteWord(SDHC_NORMAL_INT_STATUS, NORMAL_INT_STATUS_DMA);

#elif (BSP_TYPE == BSP_SMDK2450)
    WriteWord(SDHC_NO

⌨️ 快捷键说明

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