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

📄 pcmciabridge.cpp

📁 Microsoft WinCE 6.0 BSP FINAL release source code for use with the i.MX27ADS TO2 WCE600_FINAL_MX27_S
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*
 *
 * Copyright (C) 2003-2004, MOTOROLA, INC. All Rights Reserved
 * THIS SOURCE CODE IS CONFIDENTIAL AND PROPRIETARY AND MAY NOT
 * BE USED OR DISTRIBUTED WITHOUT THE WRITTEN PERMISSION OF
 * MOTOROLA, INC.
 *
 * Copyright (C) 2004-2006, Freescale Semiconductor, Inc. All Rights Reserved.
 * THIS SOURCE CODE, AND ITS USE AND DISTRIBUTION, IS SUBJECT TO THE TERMS
 * AND CONDITIONS OF THE APPLICABLE LICENSE AGREEMENT 
 *
 */

#define __PCMCIABRIDGE_CPP__
#include "pcmciabridge.h"

// workaround for daughter card: PC_POE_B signal is inverted on TO2 and above
#undef PCMCIA_PC_POE_B_WORKAROUND

#define PCMCIA_DELAY_MULTIPLIER        1000

#define PCMCIADelay(delayTime)      \
{                                                               \
    volatile UINT32 delay = delayTime * PCMCIA_DELAY_MULTIPLIER;   \
    while(delay--);                                             \
}

PCSP_PCCARD_REGS g_vPcmciaReg;

CPcmciaBusBridge::CPcmciaBusBridge( LPCTSTR RegPath ) : CPCCardBusBridgeBase( RegPath ),
					                CMiniThread( 0, TRUE )
{
	m_hISTEvent = NULL;
	m_uSocketNum = ( WORD ) - 1;
	m_pCardSocket = NULL;
	m_fPowerCycleEvent = FALSE;
	m_fCardInjectEvent = FALSE;
	m_fPollingMode = TRUE;
}

CPcmciaBusBridge::~CPcmciaBusBridge()
{
    // Terminate IST
    m_bTerminated = TRUE;
    if( m_hISTEvent )
    {
        SetEvent( m_hISTEvent );
        ThreadTerminated( 1000 );
        if( !m_fPollingMode )
        {
            InterruptDisable( m_dwCSCSysIntr );
        }
        CloseHandle( m_hISTEvent );
    };

	if( m_uSocketNum != ( UINT16 ) - 1 )
	{
	    GetSocketNumberFromCardService( FALSE );
	    m_uSocketNum = ( UINT16 ) - 1;
	}
	
	RemovePcmciaCardSocket();
}

BOOL CPcmciaBusBridge::InstallIsr()
{    
    // CreateIST Event
    m_hISTEvent = CreateEvent( 0, FALSE, FALSE, NULL );

    if( !m_fPollingMode )
    {
        // Run IST
        BOOL r = InterruptInitialize( m_dwCSCSysIntr, m_hISTEvent, 0, 0 );
        ASSERT( r );
    }
    return TRUE;
}

//
// Function to get the initial settings from the registry
//
// NOTE: lpRegPath is assumed to be under HKEY_LOCAL_MACHINE
//
// Returns ERROR_SUCCESS on success or a Win32 error code on failure
//
DWORD CPcmciaBusBridge::GetRegistryConfig()
{
    DWORD dwRet = 1;
    DWORD dwSize, dwType, dwData;

    // get the PCMCIA windows configuration
    
    if( !LoadWindowsSettings() )
    {
        dwRet = ERROR_INVALID_DATA;
        goto grc_fail;
    }
    
    // get the polling mode value
    dwSize = sizeof( DWORD );
    if( !RegQueryValueEx( POLLING_MODE_NAME,
                          &dwType,
                          ( PUCHAR ) & dwData,
                          &dwSize ) )
    {
        m_fPollingMode = FALSE; // RegQueryValueEx failed, default to FALSE
    }
    else
    {
        m_fPollingMode = dwData ? TRUE : FALSE;
    }

    // get client interrupt configuration
    dwSize = sizeof( DWORD );
    if( RegQueryValueEx( CLIENT_IRQ_VALUE_NAME,
                          &dwType,
                          ( PUCHAR ) & dwData,
                          &dwSize ) )
    {
        m_dwClientSysIntr = SYSINTR_UNDEFINED;
        m_dwClientIrq = dwData;
        
        // check if we should automatically convert the IRQ to SYSINTR value
        dwSize = sizeof( DWORD );
        if( RegQueryValueEx( FORCE_CLIENT_SYSINTR_NAME,
                              &dwType,
                              ( PUCHAR ) & dwData,
                              &dwSize ) )
        {
            if( dwData )
            {
                // Convert the interrupt to a logical sysintr value.
                if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &m_dwClientIrq, sizeof(DWORD), &m_dwClientSysIntr, sizeof(DWORD), NULL))
                {
                    DEBUGMSG(1, (TEXT("PCMCIA: Failed to IOCTL_HAL_REQUEST_SYSINTR for client interrupt!\r\n")));
                    m_dwClientSysIntr = SYSINTR_UNDEFINED;
                    dwRet = ERROR_INVALID_DATA;
                    goto grc_fail;
                }
                m_dwClientIrq = -1;
            }
        }
    }
    else
    {  	
        // IRQ value was not specified, try to get the SYSINTR value
        dwSize = sizeof( DWORD );
        if( RegQueryValueEx( CLIENT_SYSINTR_VALUE_NAME,
                              &dwType,
                              ( PUCHAR ) & dwData,
                              &dwSize ) )
        {
            m_dwClientSysIntr = dwData;
            m_dwClientIrq = -1;
        }
        else
        {
            DEBUGMSG(1, (TEXT("PCMCIA: Failed to obtain client interrupt information!\r\n")));
            dwRet = ERROR_INVALID_DATA;
            goto grc_fail;
        }
    }

    m_dwCSCSysIntr = SYSINTR_UNDEFINED;
    m_dwCSCIrq = -1;

    dwSize = sizeof( DWORD );
    if( RegQueryValueEx( CSC_SYSINTR_VALUE_NAME,
                            &dwType,
                            ( PUCHAR ) & dwData,
                            &dwSize ) )
    {
        m_dwCSCSysIntr = dwData;
    }
    else
    {
        dwSize = sizeof( DWORD );
        if( !RegQueryValueEx( CSC_IRQ_VALUE_NAME,
                                &dwType,
                                ( PUCHAR ) & dwData,
                                &dwSize ) )
        {
            m_fPollingMode = TRUE;
        }
        else
        {
            // Convert the interrupt to a logical sysintr value.
            if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &dwData, sizeof(DWORD), &m_dwCSCSysIntr, sizeof(DWORD), NULL))
            {
                m_dwCSCSysIntr = SYSINTR_UNDEFINED;
                m_fPollingMode = TRUE;
            }
        }
    }

    // get the pooling timeout value
    dwSize = sizeof( DWORD );
    if( !RegQueryValueEx( POLL_TIMEOUT_NAME,
                          &dwType,
                          ( PUCHAR ) & dwData,
                          &dwSize ) )
    {
        // RegQueryValueEx failed; if pooling, set the timeout to 0.5 sec, otherwise set to INFINITE
        m_dwPollTimeout = m_fPollingMode ? 500 : INFINITE;
    }
    else
    {
        m_dwPollTimeout = dwData;
    }

    dwRet = ERROR_SUCCESS;

    grc_fail : 
		DEBUGMSG( ZONE_PDD, (TEXT("m_fPollingMode=0x%X m_dwCSCIrq=0x%X m_dwCSCSysIntr=0x%X\r\n"), m_fPollingMode, m_dwCSCIrq, m_dwCSCSysIntr));	

		return dwRet;
}   // GetRegistryConfig

BOOL CPcmciaBusBridge::InitCardBusBridge( void )
{
    DWORD dwRet;

    // Get registry information
    if( ( dwRet = GetRegistryConfig() ) != ERROR_SUCCESS )
    {
        DEBUGMSG( ZONE_PDD,
                  ( TEXT( "PDCardInitServices GetRegistryConfig failed %d\r\n" ),
                    dwRet ) );
        return FALSE;
    }

    PHYSICAL_ADDRESS phyAddr;

    phyAddr.QuadPart = CSP_BASE_REG_PA_PCMCIA;
    g_vPcmciaReg = (PCSP_PCCARD_REGS)MmMapIoSpace(phyAddr, sizeof(CSP_PCCARD_REGS), FALSE);
    if(g_vPcmciaReg  ==  NULL)   
    {
        DEBUGMSG(ZONE_ERROR, (TEXT("\tVirtualCopy failed to map g_vPcmciaReg\n\r")));
	goto err_initialize;
    }
        
    // Initialize GPIO
    if(!InitGpio())
        goto err_initialize;
		
	
#ifdef PCMCIA_PC_POE_B_WORKAROUND
#if (MX21_TO_VER >= 20)
	// set PF16 to high  so PC_POE_B high at power-up/standby
	SetPoeBit(FALSE, 1);
#endif	

#endif //PCMCIA_PC_POE_B_WORKAROUND

	// Do software reset - then clear bit after it's done 
	PCMCIA_RESET_SOCKET(1);
	PCMCIADelay(100);
	PCMCIA_RESET_SOCKET(0);

	g_vPcmciaReg->PER = 0;	// Disable all the interrupts
	
	SetPccPower(0, FALSE);	// Set GPIO pins to 0 volt	
	
#ifdef PCMCIA_PC_POE_B_WORKAROUND
#if (MX21_TO_VER >= 20)
	// set PF16 to low before accesing PC card
	SetPoeBit(FALSE, 0);
#endif
#endif //PCMCIA_PC_POE_B_WORKAROUND	
	
	g_vPcmciaReg->PGCR = PCMCIA_PGCR_LOWPWRMODE;	// Set to Lower Power mode

   	InstallIsr();
	
	return TRUE;

err_initialize:
	
	DeinitGpio();
	
	if(g_vPcmciaReg) {
		MmUnmapIoSpace((void *)g_vPcmciaReg, 0);
		g_vPcmciaReg = NULL;
	}
	return FALSE;
 
}

BOOL CPcmciaBusBridge::Init()
{
	//DebugBreak();
	
    if( !loadPcCardEntry() )
    {
        return FALSE;
    }
	
    if( !InitCardBusBridge() )
    {
        return FALSE;
    }

    if( !GetSocketNumberFromCardService(TRUE ) )
    {
	m_uSocketNum = ( UINT16 ) - 1;
	return FALSE;
    }
   
    m_uPriority = DEFAULT_PRIORITY;	 // Set Tread Priority.
	
    DWORD dwRegPriority = 0;
	
    if( GetRegValue( RegPriority256,
                     ( PBYTE ) & dwRegPriority,
                     sizeof( dwRegPriority ) ) )
    {
        m_uPriority = ( UINT ) dwRegPriority;
    }	
    
    CeSetPriority( m_uPriority );	// Get Thread Priority from Registry and Set it
	
    m_bTerminated = FALSE;

    ThreadStart();

    return TRUE;
}

CPcmciaSocket* CPcmciaBusBridge::CreatePCMCIASocket(  )
{
    CPcmciaSocket* pNewSocket = new CPcmciaSocket( this );
	
    if( pNewSocket != NULL )
    {	
        if( pNewSocket->CardInitWindow( pNewSocket ) )
        {
            return pNewSocket;
        }
        else
        {
            delete pNewSocket;
        }

⌨️ 快捷键说明

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