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

📄 sdhcslot.cpp

📁 2443 wince5.0 bsp, source code
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                              )
{
    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>(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;

    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
	{		
		WriteDword(SDHC_CONTROL2, (0x1<<15)|(0x1<<14)|(0x1<<8)|(0x2/*EPLL*/<<4) );	
	}
	/////////////////////////////////////////////

    // shift MaxClockRate until we find the closest frequency <= target
    while ( (dwClockRate < dwMaxClockRate) && ( i < 8 ) ) {
        dwMaxClockRate = dwMaxClockRate >> 1;
        i++;
    }

    // set the actual clock rate 
    *pdwRate = dwMaxClockRate;
    m_wRegClockControl = CLOCK_INTERNAL_ENABLE;

    if (i != 0) {
        DWORD dwDivisor = 1 << (i - 1);
        m_wRegClockControl |= (dwDivisor << 8);
    }

    RETAILMSG(1,(TEXT("SDHCSetRate - Clock Control Reg = %X\n"), 
        m_wRegClockControl));
    RETAILMSG(1,(TEXT("SDHCSetRate - Actual clock rate = %d\n"), *pdwRate));
    DEBUGMSG(SDHC_CLOCK_ZONE,(TEXT("SDHCSetRate - Clock Control Reg = %X\n"), 
        m_wRegClockControl));
    DEBUGMSG(SDHC_CLOCK_ZONE,(TEXT("SDHCSetRate - Actual clock rate = %d\n"), *pdwRate));
}


VOID 
CSDHCSlotBase::SDClockOn(
                         )
{
    SETFNAME();
    
    // Must call SetClockRate() first to init m_wRegClockControl
    // We separate clock divisor calculation with ClockOn, so we can call 
    // ClockOn without recalcuating the divisor.
    WriteWord(SDHC_CLOCK_CONTROL, m_wRegClockControl);
	RETAILMSG(0,(TEXT("SDHC_CLOCK_CONTROL = 0x%X\n"),m_wRegClockControl));
	RETAILMSG(0,(TEXT("CONTROL2 = 0x%X\n"),ReadDword(SDHC_CONTROL2)));
	RETAILMSG(0,(TEXT("CONTROL3 = 0x%X\n"),ReadDword(SDHC_CONTROL3)));	

    // wait until clock stable
    BOOL fSuccess = WaitForReg<WORD>(ReadWord, SDHC_CLOCK_CONTROL, 
        CLOCK_STABLE, CLOCK_STABLE); 
    if (fSuccess) {
        RETAILMSG(0, (_T("%s Enable Clock\r\n"),	pszFname));	
        // enable it
        	//WriteWord(SDHC_CLOCK_CONTROL, (0x20<<8) | CLOCK_ENABLE | CLOCK_INTERNAL_ENABLE);
        	WriteWord(SDHC_CLOCK_CONTROL, m_wRegClockControl | CLOCK_ENABLE);
		fSuccess = WaitForReg<WORD>(ReadWord, SDHC_CLOCK_CONTROL, 
        		CLOCK_EXTERNAL_ENABLE, CLOCK_EXTERNAL_ENABLE); 		
		RETAILMSG(0,(TEXT("fSuccess = 0x%X\n"),fSuccess));			
    }
    else {
        RETAILMSG(0, (_T("%s Timeout waiting for CLOCK_STABLE\r\n"),
            pszFname));		
        DEBUGMSG(SDCARD_ZONE_ERROR, (_T("%s Timeout waiting for CLOCK_STABLE\r\n"),
            pszFname));
    }
}


VOID 
CSDHCSlotBase::SDClockOff(
                          )
{
     WriteWord(SDHC_CLOCK_CONTROL, m_wRegClockCont

⌨️ 快捷键说明

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