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

📄 sdhcslot.cpp

📁 S3C2443 WINCE6.0 BSP
💻 CPP
📖 第 1 页 / 共 5 页
字号:
            DEBUGCHK( paCurrDmaBuffer < (m_paDmaBuffer + CB_DMA_BUFFER) );
            DEBUGCHK( paCurrDmaBuffer < (m_paDmaBuffer + TRANSFER_SIZE(pRequest)) );
            DEBUGCHK( paCurrDmaBuffer == ReadDword(SDHC_SYSTEMADDRESS_LO) );

            WriteDword(SDHC_SYSTEMADDRESS_LO, paCurrDmaBuffer);
        }
    }
    // else request must have been canceled due to an error
}


BOOL 
CSDHCSlotBase::UseDmaForRequest(
                                PSD_BUS_REQUEST pRequest
                                )
{
    PREFAST_DEBUGCHK(pRequest);

    BOOL fRet = FALSE;
    
    if (m_pbDmaBuffer) {
        DEBUGCHK(m_paDmaBuffer);

        if ( (pRequest->BlockSize % 4 == 0) &&
             (TRANSFER_SIZE(pRequest) <= CB_DMA_BUFFER) ) {
            DEBUGCHK(m_paDmaBuffer % 4 == 0);
            DEBUGCHK(PAGE_SIZE == CB_DMA_PAGE);
            fRet = TRUE;
        }
    }
    
    return fRet;
}


PVOID
CSDHCSlotBase::AllocPhysBuffer(
                               size_t cb,
                               PDWORD pdwPhysAddr
                               )
{
    PVOID pvUncached;
    PVOID pvRet = NULL;
    DWORD dwPhysAddr;

    pvUncached = AllocPhysMem(cb, PAGE_READWRITE, 0, 0, &dwPhysAddr);

    if (pvUncached) {
        *pdwPhysAddr = dwPhysAddr;
        pvRet = pvUncached;
    }

    return pvRet;
}


VOID
CSDHCSlotBase::FreePhysBuffer(
                              PVOID pv
                              )
{
    BOOL fSuccess;

    DEBUGCHK(pv);

    fSuccess = FreePhysMem(pv);
    DEBUGCHK(fSuccess);
}


VOID
CSDHCSlotBase::SetHardwarePowerState(
                                     CEDEVICE_POWER_STATE cpsNew
                                     )
{
    DEBUGCHK(VALID_DX(cpsNew));
    DEBUGCHK(!DX_D1_OR_D2(cpsNew));

    DEBUGCHK(m_cpsCurrent != cpsNew);
    CEDEVICE_POWER_STATE cpsCurrent = m_cpsCurrent;
    m_cpsCurrent = cpsNew;
    BYTE bWakeupControl = m_bWakeupControl;
	RETAILMSG(1,(TEXT("CSDHCSlotBase::SetHardwarePowerState 0x%08X\n"),this));
    if (cpsCurrent == D0) {
        SDClockOff();
        
        if (cpsNew == D3) {
            if ( m_fSDIOInterruptsEnabled &&  
                (bWakeupControl & WAKEUP_INTERRUPT) ) {
                    DEBUGCHK(m_fCardPresent);
                    m_fSleepsWithPower = TRUE;
                    m_fPowerUpDisabledInts = FALSE;
                }
            else {
                // Wake on status changes only
                WriteByte(SDHC_POWER_CONTROL, 0);
                bWakeupControl &= ~WAKEUP_INTERRUPT;
            }

            // enable wakeup sources
            m_wIntSignals = ReadWord(SDHC_NORMAL_INT_SIGNAL_ENABLE);
            WriteWord(SDHC_NORMAL_INT_SIGNAL_ENABLE, 0);
            WriteWord(SDHC_NORMAL_INT_STATUS, ReadWord(SDHC_NORMAL_INT_STATUS));
            WriteByte(SDHC_WAKEUP_CONTROL, bWakeupControl);
        }
        else {
            DEBUGCHK(cpsNew == D4);
            WriteByte(SDHC_CLOCK_CONTROL, 0);
            WriteByte(SDHC_POWER_CONTROL, 0);
        }
    }
    else if (cpsCurrent == D3) {
        // Coming out of wakeup state
        if (cpsNew == D0) {            
            WriteByte(SDHC_WAKEUP_CONTROL, 0);

            if (!m_fSleepsWithPower) {
                // Power was turned off to the socket. Re-enumerate card.
                if (m_fCardPresent) {
                    HandleRemoval(TRUE);
                }

                m_fCheckSlot = TRUE;
                SetInterruptEvent();
            }
            else {
                if (m_fCardPresent) {
                    // Do not do this if the card was removed or 
                    // if power was not kept.
                    if (m_fPowerUpDisabledInts) {
                        EnableSDIOInterrupts(TRUE);
                    }
                }
            }

            WriteWord(SDHC_NORMAL_INT_SIGNAL_ENABLE, m_wIntSignals);
        }
        else {
            DEBUGCHK(cpsNew == D4);
            WriteByte(SDHC_CLOCK_CONTROL, 0);
            WriteByte(SDHC_WAKEUP_CONTROL, 0);
            WriteByte(SDHC_POWER_CONTROL, 0);
            WriteWord(SDHC_NORMAL_INT_SIGNAL_ENABLE, m_wIntSignals);
        }

        m_fSleepsWithPower = FALSE;
    }
    else {
        DEBUGCHK(cpsCurrent == D4);

        // Coming out of unpowered state - signal card removal
        // so any card present will be re-enumerated.
        //
        // We do the same thing when we go to D3 as D0 because
        // the slot has lost power so it could have been removed
        // or changed. In other words, D3 is a meaningless state
        // after D4.
        m_cpsCurrent = D0; // Force to D0

        // Do not call HandleRemoval here because it could cause
        // a context switch in a PowerUp callback.
        m_fFakeCardRemoval = TRUE;
            
        m_fCheckSlot = TRUE;
              
        SetInterruptEvent();
    }
}



BOOL
CSDHCSlotBase::IsOnlySDIOInterrupt()
{
    WORD wIntStatus = ReadWord(SDHC_NORMAL_INT_STATUS);
    if (wIntStatus == NORMAL_INT_STATUS_CARD_INT && isSDIOInterrupt == TRUE ) {
		return TRUE;
    	}
	return FALSE;
}
VOID
CSDHCSlotBase::DoEnableSDIOInterrupts(
                                      BOOL fEnable
                                      )
{
    WORD wIntStatusEn = ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE);
    if (fEnable) {
		isSDIOInterrupt = FALSE;
	RETAILMSG(0,(TEXT("DoEnableSDIOInterrupts TRUE\n")));		
        wIntStatusEn |= NORMAL_INT_ENABLE_CARD_INT;
    }
    else {
		isSDIOInterrupt = TRUE;		
	RETAILMSG(0,(TEXT("DoEnableSDIOInterrupts FALSE\n")));		
        wIntStatusEn &= (~NORMAL_INT_ENABLE_CARD_INT);      
    }

    WriteWord(SDHC_NORMAL_INT_STATUS_ENABLE, wIntStatusEn);
}


template<class T>
BOOL
CSDHCSlotBase::WaitForReg(
    T (CSDHCSlotBase::*pfnReadReg)(DWORD),
    DWORD dwRegOffset,
    T tMask,
    T tWaitForEqual,
    DWORD dwTimeout
    )
{
    SETFNAME();
    
    const DWORD dwStart = GetTickCount();

    T tValue;

    BOOL fRet = TRUE;
    DWORD dwIteration = 1;
    
    // Verify that reset has completed.
    do {
        tValue = (this->*pfnReadReg)(dwRegOffset);

        if ( (dwIteration % 16) == 0 ) {
            // Check time
            DWORD dwCurr = GetTickCount();

            // Unsigned arithmetic handles rollover.
            DWORD dwTotal = dwCurr - dwStart;

            if (dwTotal > dwTimeout) {
                // Timeout
                fRet = FALSE;
                DEBUGMSG(SDCARD_ZONE_WARN, (_T("%s Timeout (%u ms) waiting for (ReadReg<%u>(0x%02x) & 0x%08x) == 0x%08x\r\n"),
                    pszFname, dwTimeout, sizeof(T), dwRegOffset, tMask, tWaitForEqual));
                break;
            }
        }
        
        ++dwIteration;
    } while ((tValue & tMask) != tWaitForEqual);

    return fRet;
}


BOOL 
CSDHCSlotBase::SoftwareReset(
                             BYTE bResetBits
                             )
{
    SETFNAME();
    
    // Reset the controller
    WriteByte(SDHC_SOFT_RESET, bResetBits);
    BOOL fSuccess = WaitForReg<BYTE>(&CSDHCSlotBase::ReadByte, SDHC_SOFT_RESET, bResetBits, 0);
    if (!fSuccess) {
        DEBUGMSG(SDCARD_ZONE_ERROR, (_T("%s Timeout waiting for controller reset - 0x%02x\r\n"),
            pszFname, bResetBits));
    }


	// set Clock Source to EPLL	added by JJG	06.10.11
	WriteDword(SDHC_CONTROL2, (0x1<<15)|(0x1<<14)|(0x1<<8)|(0x2/*EPLL*/<<4) );
	WriteDword(SDHC_CONTROL3, (0<<31) | (1<<23) | (0<<15) | (1<<7) );

    return fSuccess;
}


VOID
CSDHCSlotBase::EnableLED(
                         BOOL fEnable
                         )
{
    BYTE bHostControl = ReadByte(SDHC_HOST_CONTROL);

    if (fEnable) {
        bHostControl |= HOSTCTL_LED_CONTROL;
    }
    else {
        bHostControl &= ~HOSTCTL_LED_CONTROL;
    }

    WriteByte(SDHC_HOST_CONTROL, bHostControl);
}


VOID 
CSDHCSlotBase::IndicateSlotStateChange(SD_SLOT_EVENT sdEvent) {
    SDHCDIndicateSlotStateChange(m_pHCDContext,
        (UCHAR) m_dwSlot, sdEvent);
}


PSD_BUS_REQUEST
CSDHCSlotBase::GetAndLockCurrentRequest() {
    return SDHCDGetAndLockCurrentRequest(m_pHCDContext,
        (UCHAR) m_dwSlot);
}


VOID CSDHCSlotBase::PowerUpDown(BOOL fPowerUp, BOOL fKeepPower) {
    SDHCDPowerUpDown(m_pHCDContext, fPowerUp, fKeepPower,
        (UCHAR) m_dwSlot);
    
}


VOID 
CSDHCSlotBase::IndicateBusRequestComplete(
    PSD_BUS_REQUEST pRequest,
    SD_API_STATUS status
    )
{
	RETAILMSG(0,(TEXT("CSDHCSlotBase::IndicateBusRequestComplete\n")));
    const WORD c_wTransferIntSources = 
        NORMAL_INT_STATUS_CMD_COMPLETE | 
        NORMAL_INT_STATUS_TRX_COMPLETE |
        NORMAL_INT_STATUS_DMA |
        NORMAL_INT_STATUS_BUF_WRITE_RDY | 
        NORMAL_INT_STATUS_BUF_READ_RDY;
        
    DEBUGCHK(pRequest);

    if ( (m_fSDIOInterruptsEnabled && m_f4BitMode) == FALSE ) {
        SDClockOff();
    }
    // else need to leave clock on in order to receive interrupts in 4 bit mode
    
    // Turn off LED.
    EnableLED(FALSE);

    // Turn off interrupt sources
    WORD wIntStatusEn = ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE);
    wIntStatusEn &= ~c_wTransferIntSources;
    WriteWord(SDHC_NORMAL_INT_STATUS_ENABLE, wIntStatusEn);

    // Clear any remaining spurious interrupts.
    WriteWord(SDHC_NORMAL_INT_STATUS, c_wTransferIntSources);

#ifdef DEBUG
    m_dwReadyInts = 0;
#endif

    m_fCommandCompleteOccurred = FALSE;
    ASSERT(m_pCurrentRequest!=NULL);
    m_pCurrentRequest = NULL;
    if (m_fCurrentRequestFastPath) {
        if (status == SD_API_STATUS_SUCCESS) {
            status = SD_API_STATUS_FAST_PATH_SUCCESS;
        }
        m_FastPathStatus = status;
    }
    else
        SDHCDIndicateBusRequestComplete(m_pHCDContext, pRequest, status);
}


VOID 
CSDHCSlotBase::SetClockRate(
                            PDWORD pdwRate
                            )
{
	RETAILMSG(0,(TEXT("DEBUGCHK(m_dwMaxClockRate)\n")));
    DEBUGCHK(m_dwMaxClockRate);
	RETAILMSG(0,(TEXT("DEBUGCHK(m_dwMaxClockRate) success\n")));
    
    DWORD dwClockRate = *pdwRate;
    DWORD       dwMaxClockRate = m_dwMaxClockRate;
    int         i = 0; // 2^i is the divisor value


 	//   For supporting lower Clock
	//	added by JJG 06.10.16
	if(*pdwRate <= 400000)
	{
		dwMaxClockRate = 12000000;		// 12Mhz
		WriteDword(SDHC_CONTROL2, (0x1<<15)|(0x1<<14)|(0x1<<8)|(0x3/*EXT*/<<4) );
	}
	else if(*pdwRate <= 20000000)
	{
		dwMaxClockRate = 133000000;//S3C2443_HCLK;		// maybe 133Mhz		
		WriteDword(SDHC_CONTROL2, (0x1<<15)|(0x1<<14)|(0x1<<8)|(0x1/*EPLL*/<<4) );	
	}
	else
	{		
		Wr

⌨️ 快捷键说明

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