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

📄 sdhcslot.cpp

📁 Samsung公司S3C6400芯片的BSP源码包
💻 CPP
📖 第 1 页 / 共 5 页
字号:

    // Turn the LED on.
    EnableLED(TRUE);

    // Writing the upper byte of the command register starts the command.
    // All register initialization must already be complete by this point.
    WriteWord(SDHC_COMMAND, wRegCommand);
	RETAILMSG(SDIO_DEBUG,(TEXT("[CMD%d] ARG : 0x%x\r\n"),pRequest->CommandCode, pRequest->CommandArgument));
    status = SD_API_STATUS_PENDING;
    
    RETAILMSG(0,(TEXT("Sending command IntStatusEn 0x%08X\r\n"),ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE)));
EXIT:
    return status;
}


VOID
CSDHCSlotBase::EnableSDIOInterrupts(
                                    BOOL fEnable
                                    )
{
    Validate();

    if (fEnable) {
        m_fSDIOInterruptsEnabled = TRUE;
        DoEnableSDIOInterrupts(fEnable);
    }
    else {
        DoEnableSDIOInterrupts(fEnable);
        m_fSDIOInterruptsEnabled = FALSE;
    }
}


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

    WORD wIntStatus= ReadWord(SDHC_NORMAL_INT_STATUS);
    WORD wErrIntStatus = ReadWord(SDHC_ERROR_INT_STATUS);
    WORD wErrIntSignalEn = ReadWord(SDHC_ERROR_INT_SIGNAL_ENABLE);
    WORD wErrIntStatusEn = ReadWord(SDHC_ERROR_INT_STATUS_ENABLE);
    //RETAILMSG(CRC_DEBUG,(TEXT("m_fCardPresent : %d\r\n"),m_fCardPresent));
    RETAILMSG(SDIO_DEBUG,(TEXT("CSDHCSlotBase:: +HandleInterrupt\r\n")));

	// 2007.06.14 D.BAek
	// There is bug in the S3C6400. After the interrupt is occurred, the normal interrupt status register is updated lately.
	// The following if statement is added to wait for setting the interrupt source to the "Normal Interrupt Status Register".
	if(g_initialInsertion != 1)
	{
		while(( wIntStatus=ReadWord(SDHC_NORMAL_INT_STATUS)) == 0);
	}

//2007.10.04 D.Baek
	RETAILMSG(0,(TEXT("INT : 0x%x\r\n"),wIntStatus));

    if (m_fFakeCardRemoval && m_fCardPresent) {
        RETAILMSG(0,(TEXT("Wakeup !!!!!! m_fFakeCardRemoval && m_fCardPresent\n"))); // jylee
#ifndef NEW_POWER_MANAGEMENT
        m_fFakeCardRemoval = FALSE;
#endif
        HandleRemoval(TRUE);
    }

    if (wIntStatus != 0) {
        DEBUGMSG(SDHC_INTERRUPT_ZONE, (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.
        else if ( wIntStatus & NORMAL_INT_STATUS_CMD_COMPLETE ) {		// modifyed by JJG 06.10.11
            // Clear status
            m_fCommandCompleteOccurred = TRUE;

            //For Check
            RETAILMSG(CRC_DEBUG,(TEXT("Before NORMAL_INT_STATUS_CMD_COMPLETE : 0x%x\r\n"),ReadWord(SDHC_NORMAL_INT_STATUS)));
            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));
            RETAILMSG(CRC_DEBUG,(TEXT("After  NORMAL_INT_STATUS_CMD_COMPLETE : 0x%x\r\n"),ReadWord(SDHC_NORMAL_INT_STATUS)));
            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) {
              RETAILMSG(0,(TEXT("Before NORMAL_INT_STATUS_DMA : 0x%x\r\n"),ReadWord(SDHC_NORMAL_INT_STATUS)));
              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));
              RETAILMSG(0,(TEXT("After  NORMAL_INT_STATUS_DMA : 0x%x\r\n"),ReadWord(SDHC_NORMAL_INT_STATUS)));
              HandleDma();
                // do not break here. Continue to check TransferComplete.
            }

            // Buffer Read Ready handling
            if (wIntStatus & NORMAL_INT_STATUS_BUF_READ_RDY ) {
                // Clear status
               RETAILMSG(CRC_DEBUG,(TEXT("Before NORMAL_INT_STATUS_BUF_READ_RDY : 0x%x\r\n"),ReadWord(SDHC_NORMAL_INT_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));
               RETAILMSG(0,(TEXT("After  NORMAL_INT_STATUS_BUF_READ_RDY : 0x%x\r\n"),ReadWord(SDHC_NORMAL_INT_STATUS)));
               HandleReadReady();
                // do not break here. Continue to check TransferComplete.
            }

            // Buffer Write Ready handling
            if (wIntStatus & NORMAL_INT_STATUS_BUF_WRITE_RDY ) {
                // Clear status
                RETAILMSG(CRC_DEBUG,(TEXT("Before NORMAL_INT_STATUS_BUF_WRITE_RDY : 0x%x\r\n"),ReadWord(SDHC_NORMAL_INT_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));
                RETAILMSG(0,(TEXT("After  NORMAL_INT_STATUS_BUF_WRITE_RDY : 0x%x\r\n"),ReadWord(SDHC_NORMAL_INT_STATUS)));
                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
            RETAILMSG(CRC_DEBUG,(TEXT("Before NORMAL_INT_STATUS_TRX_COMPLETE : 0x%x\r\n"),ReadWord(SDHC_NORMAL_INT_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));
            RETAILMSG(CRC_DEBUG,(TEXT("After  NORMAL_INT_STATUS_TRX_COMPLETE : 0x%x\r\n"),ReadWord(SDHC_NORMAL_INT_STATUS)));
            HandleTransferDone();
        }

        // SDIO Interrupt Handling
        if ( wIntStatus & NORMAL_INT_STATUS_CARD_INT ) {
            DEBUGCHK(m_fSDIOInterruptsEnabled);
            DEBUGMSG(SDHC_INTERRUPT_ZONE, (_T("SDHCControllerIst: Card interrupt!\n")));
            RETAILMSG(SDIO_DEBUG, (_T("SDHCControllerIst: Card interrupt!\r\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);

            RETAILMSG(SDIO_DEBUG, (_T("SDHCControllerIst: Card interrupt finish!\r\n")));
        }

        // Card Detect Interrupt Handling
        if (wIntStatus & (NORMAL_INT_STATUS_CARD_INSERTION | NORMAL_INT_STATUS_CARD_REMOVAL)) {
#if 0
            if(wIntStatus & NORMAL_INT_STATUS_CARD_INSERTION)
            {
				// Card Insertion Interrupt Disable & Card Removal Interrupt Enable
				WriteWord(SDHC_NORMAL_INT_SIGNAL_ENABLE,  (ReadWord(SDHC_NORMAL_INT_SIGNAL_ENABLE) & ~(NORMAL_INT_STATUS_CARD_INSERTION)));
				WriteWord(SDHC_NORMAL_INT_STATUS_ENABLE, (ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE) & ~(NORMAL_INT_STATUS_CARD_INSERTION)));
				RETAILMSG(0,(TEXT("Card Inserted[NORMAL_INT_STATUS] : 0x%x\r\n"),ReadWord(SDHC_NORMAL_INT_STATUS))); // jylee
            }
            if(wIntStatus & NORMAL_INT_STATUS_CARD_REMOVAL)
            {
				// Card Insertion Interrupt Enable & Card Removal Interrupt Disable
				WriteWord(SDHC_NORMAL_INT_SIGNAL_ENABLE,  (ReadWord(SDHC_NORMAL_INT_SIGNAL_ENABLE) &~(NORMAL_INT_STATUS_CARD_REMOVAL)));
				WriteWord(SDHC_NORMAL_INT_STATUS_ENABLE, (ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE) & ~(NORMAL_INT_STATUS_CARD_REMOVAL)));
				RETAILMSG(0,(TEXT("Card Removed[NORMAL_INT_STATUS] : 0x%x\r\n"),ReadWord(SDHC_NORMAL_INT_STATUS))); // jylee
            }
#endif
#if 1
			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)));
            
            RETAILMSG(0,(TEXT("INT_STATUS_ENABLE : 0x%x\r\n"),ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE))); // jylee
            RETAILMSG(0,(TEXT("INT_SIGNAL_ENABLE : 0x%x\r\n"),ReadWord(SDHC_NORMAL_INT_SIGNAL_ENABLE))); // jylee
#endif
            do{
				WriteWord(SDHC_NORMAL_INT_STATUS, NORMAL_INT_STATUS_CARD_INSERTION | NORMAL_INT_STATUS_CARD_REMOVAL);
				RETAILMSG(0,(TEXT("[Card Detect INT] SDHC_NORMAL_INT_STATUS=0x%X\n"),ReadWord(SDHC_NORMAL_INT_STATUS))); // jylee
            }while(ReadWord(SDHC_NORMAL_INT_STATUS) & (NORMAL_INT_STATUS_CARD_INSERTION | NORMAL_INT_STATUS_CARD_REMOVAL));

            // 2007.04.05 D.Baek
            // Enable the "Signal" & "Status" interrupt enable bit
            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;
        }
    }else
    {
    	RETAILMSG(0,(TEXT("STATUS Error.\r\n"))); // jylee
	}

    if (m_fCheckSlot) {
        m_fCheckSlot = FALSE;

        // check card inserted or removed
        DWORD dwPresentState = ReadDword(SDHC_PRESENT_STATE);
        RETAILMSG(0, (TEXT("HandleInterrupt -  Card Present Status :  0x%08X\n"),dwPresentState));

        if (dwPresentState & STATE_CARD_INSERTED) {
            RETAILMSG(1, (TEXT("[HSMMC] Card is Inserted.\n\r"))); // jylee
            DEBUGMSG(SDHC_INTERRUPT_ZONE, (TEXT("SDHCControllerIst - Card is Inserted! \n")));

#ifdef NEW_POWER_MANAGEMENT
			// for wakeup problem. hsjang 070823
			RETAILMSG(0,(TEXT("m_fFakeCardRemoval : %d\r\n"),m_fFakeCardRemoval));
	        if ( m_fFakeCardRemoval)
	        {
				m_fWhileWakeup = TRUE;
			}
#endif

            m_fFakeCardRemoval = FALSE;			// added by JJG 06.11.13
            if (m_fCardPresent == FALSE ) {
		  Start(); // D.Baek
                HandleInsertion();
            }
        }
        else {
            RETAILMSG(1, (TEXT("[HSMMC] Card is Removed.\n\r")));	// jylee
            DEBUGMSG(SDHC_INTERRUPT_ZONE, (TEXT("SDHCControllerIst - Card is Removed! \n")));

#ifdef NEW_POWER_MANAGEMENT
			// for wakeup problem. hsjang 070823
	        if ( m_fFakeCardRemoval)
	        {
				SetEvent(m_hWaitForEndofWakeup);
			}            
#endif
            m_fFakeCardRemoval = FALSE;			// added by JJG 06.11.13
            if (m_fCardPresent) {
                HandleRemoval(TRUE);
            }
        }
    }
    RETAILMSG(CRC_DEBUG,(TEXT("CSDHCSlotBase:: -HandleInterrupt\r\n")));
}


VOID
CSDHCSlotBase::HandleRemoval(
                             BOOL fCancelRequest
                             )
{
    m_fCardPresent = FALSE;
    m_fIsPowerManaged = FALSE;
    m_fSleepsWithPower = FALSE;
    m_fPowerUpDisabledInts = FALSE;
    m_f4BitMode = FALSE;
    m_cpsCurrent = D0;
    //RETAILMSG(0,(TEXT("+HandleRemoval\r\n"))); // jylee
    // Wake on SDIO interrupt must be set by he client
    m_bWakeupControl &= ~WAKEUP_INTERRUPT;
	
#if 1
   // 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);
#endif
#if 1
   	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));
            RETAILMSG(CRC_DEBUG, (TEXT("Card Removal Detected - Canceling current request: 0x%08X, command: %d\n"), pRequest, pRequest->CommandCode)); // jylee
            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.
        RETAILMSG(CRC_DEBUG,(TEXT("[HandleRemoval] SoftwareReset is called\r\n"))); // jylee
        SoftwareReset(SOFT_RESET_CMD | SOFT_RESET_DAT);
        WriteDword(SDHC_SYSTEMADDRESS_LO, 0);
        WriteWord(SDHC_BLOCKSIZE, 0);
        WriteWord(SDHC_BLOCKCOUNT, 0);

⌨️ 快捷键说明

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