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

📄 pcmsock.cpp

📁 SBC2410 WinCE 5.0 BSP.绝大多数驱动已经调通。
💻 CPP
📖 第 1 页 / 共 2 页
字号:
        {
            if( pState->dwInteruptStatus & SOCK_INT_FUNC_IRQ_ROUTING )
            {
                tmp |= GetPCCardBusBridge()->GetFnInterruptNo(); // enable interrupt routing

            }
            else
            {
                tmp &= 0xf0; // disable interrupt routing
            }

            m_SocketState.dwInteruptStatus = pState->dwInteruptStatus;
            m_SocketState.fIREQRouting = pState->fIREQRouting;
        };

        if( ( pState->dwInterfaceType & CFG_IFACE_MEMORY_IO ) != 0 )
        {
            tmp |= INT_CARD_IS_IO;
        }

        m_SocketState.dwInterfaceType = pState->dwInterfaceType;
        PCICRegisterWrite( REG_INTERRUPT_AND_GENERAL_CONTROL, tmp );

        if( ( pState->dwEventStatus & SOCK_EVENT_EJECT ) != 0 ||
            ( pState->dwEventStatus & SOCK_EVENT_INSERT ) != 0 )
        {
            // Ask for ejection of the card.
            DEBUGMSG( ZONE_PDD,
                      ( TEXT( "PDCardSetSocket  CPCMSocket. Gernerate Artificial Eject\r\n" ) ) );
            CardInjectEvent();
        }
        else if( ( pState->fVcc & SOCK_VCC_LEVEL_MASK ) >=
                 NUM_POWER_ENTRIES ||
                 !( m_rgPowerEntries[pState->fVcc & SOCK_VCC_LEVEL_MASK].fSupply & PWR_SUPPLY_VCC ) )
        {
            pState->fVcc = m_SocketState.fVcc;
            status = CERR_BAD_VCC;
        }
        else
        {
            BYTE oldfVcc = m_SocketState.fVcc;
            BYTE olduVpp = m_SocketState.uVpp1;
            if( ( pState->fVcc & SOCK_VCC_LEVEL_MASK ) !=
                ( m_SocketState.fVcc & SOCK_VCC_LEVEL_MASK ) )
            {
                m_SocketState.fVcc = pState->fVcc;
            }
            if( ( pState->uVpp1 & SOCK_VCC_LEVEL_MASK ) !=
                ( m_SocketState.uVpp1 & SOCK_VCC_LEVEL_MASK ) )
            {
                if( ( pState->uVpp1 & SOCK_VCC_LEVEL_MASK ) >=
                    NUM_POWER_ENTRIES ||
                    !( m_rgPowerEntries[pState->uVpp1 & SOCK_VCC_LEVEL_MASK].fSupply & PWR_SUPPLY_VPP1 ) )
                    pState->uVpp1 = m_SocketState.uVpp1;
                m_SocketState.uVpp1 = pState->uVpp1;
                if( m_rgPowerEntries[m_SocketState.uVpp1 & SOCK_VCC_LEVEL_MASK].uPowerLevel !=
                    0 &&
                    m_rgPowerEntries[m_SocketState.uVpp1 & SOCK_VCC_LEVEL_MASK].uPowerLevel !=
                    120 )
                {
                    // VPP is same as VCC.
                    m_SocketState.uVpp1 = m_SocketState.fVcc;
                }
            }
            if( oldfVcc != m_SocketState.fVcc || olduVpp != m_SocketState.uVpp1 )
            {
                if( m_SocketState.fVcc == 0 )
                {
                    DEBUGMSG( ZONE_PDD,
                              ( TEXT( "PDCardSetSocket  CPCMSocket. Socket is Power Down! Function Interrupt Routing will force to Off\r\n" ) ) );
                    m_SocketState.dwInteruptStatus &= ~SOCK_INT_FUNC_IRQ_ROUTING;
                    PCICRegisterWrite( REG_POWER_CONTROL, 0 );
                }
                else
                {
                    PowerOnProcedure( m_SocketState.fVcc, m_SocketState.uVpp1 );
                    DEBUGMSG( ZONE_PDD,
                              ( TEXT( "PDCardSetSocket  CPCMSocket. Socket is Power Up with fVcc=%d\r\n" ),
                                m_SocketState.fVcc ) );
                }
            }
            else
            {
                DEBUGMSG( ZONE_PDD,
                          ( TEXT( "PDCardSetSocket  CPCMSocket. Same Power with fVcc=%d and uVpp1\r\n" ),
                            m_SocketState.fVcc,
                            m_SocketState.uVpp1 ) );
            }
        }

        DEBUGMSG( ZONE_PDD,
                  ( TEXT( "PDCardSetSocket Vcc = %d, Vpp = %d\r\n" ),
                    m_rgPowerEntries[m_SocketState.fVcc & SOCK_VCC_LEVEL_MASK].uPowerLevel,
                    m_rgPowerEntries[m_SocketState.uVpp1].uPowerLevel ) );

        DEBUGMSG( ZONE_PDD,
                  ( TEXT( "PDCardSetSocket REG_POWER_CONTROL = %x,Present Register=%x,Socket_Event=%x\r\n" ),
                    PCICRegisterRead( REG_POWER_CONTROL ), 0, 0 ) );
        PCICRegisterWrite( REG_INTERRUPT_AND_GENERAL_CONTROL,
                           PCICRegisterRead( REG_INTERRUPT_AND_GENERAL_CONTROL ) |
                           INT_CARD_NOT_RESET );
    }
    else
    {
        status = CERR_BAD_SOCKET;
    }
    Unlock();

#ifdef DEBUG
    bool fFlag = false;
    if( fFlag )
    {
        DumpAllRegisters();
    }
#endif
    return status;
}

void CPCMSocket::PowerCycleEvent()
{
    GetPCCardBusBridge()->PowerCycleEvent();
}

void CPCMSocket::CardInjectEvent()
{
    GetPCCardBusBridge()->CardInjectEvent();
}

void CPCMSocket::PowerOnProcedure( UINT8 fVcc, UINT8 fVpp )
{
    DEBUGMSG( ZONE_SOCKET,
              ( TEXT( "+SMDK2410!CPCMSocket:PowerOnProcedure fVcc=%d,fVpp=%d\r\n" ),
                fVcc,
                fVpp ) );

    if( !GetPCCardBusBridge()->PollingMode() )
    {
        // PD6710 specific code to enable management interrupt(routed to -INTR)
        UINT8 tmp = PCICRegisterRead( REG_INTERRUPT_AND_GENERAL_CONTROL );
        tmp |= INT_ENABLE_MANAGE_INT;
        PCICRegisterWrite( REG_INTERRUPT_AND_GENERAL_CONTROL, tmp );
    }

    //
    // Power off the socket
    //
    PCICRegisterWrite( REG_POWER_CONTROL, 0 );

    //
    // Tri-state outputs for 310ms
    //
    Sleep( 310 );

    //
    // Power the socket to default Vcc=50 and Vpp = Vcc;
    //
    DEBUGCHK( fVcc < NUM_POWER_ENTRIES );
    DEBUGCHK( fVpp < NUM_POWER_ENTRIES );
    BYTE bPowerReg = 0;
    if( m_rgPowerEntries[fVcc].uPowerLevel == 33 )
    {
        bPowerReg |= PWR_OUTPUT_ENABLE | PWR_VCC_POWER;
        DEBUGMSG( ZONE_PDD, (TEXT(" set to 3.3V\r\n")));
        PCICRegisterWrite( REG_GENERAL_CONTROL, PCICRegisterRead( REG_GENERAL_CONTROL ) | MISC1_VCC_33 );
    }
    else if( m_rgPowerEntries[fVcc].uPowerLevel == 50 )
    {
        bPowerReg |= PWR_OUTPUT_ENABLE | PWR_VCC_POWER;
        if( PCICRegisterRead( REG_GENERAL_CONTROL ) & MISC1_5V_DETECT ) //REG_MISC_CONTROL_1;
        { // i.e., if we detect a 5V card:
            DEBUGMSG( ZONE_PDD, (TEXT(" set to 5V\r\n")) );
            PCICRegisterWrite( REG_GENERAL_CONTROL, PCICRegisterRead( REG_GENERAL_CONTROL ) & ~MISC1_VCC_33 ); // disable 3.3V (i.e., use 5V)
        }
        else
        {
            // this is a 3.3V ONLY card and mustn't be powered at 5V
            // so ignore the command; we'd assert here save that card
            // services will attempt to apply 5V to read the CIS.

            DEBUGMSG( ZONE_PDD, (TEXT(" set to 3.3V[5V]\r\n")));
            PCICRegisterWrite( REG_GENERAL_CONTROL, PCICRegisterRead( REG_GENERAL_CONTROL ) | MISC1_VCC_33 );  // enable 3.3V
        }
    }
    if( fVcc == fVpp )
    { 
        bPowerReg |= PWR_VPP1_BIT0; // set Vpp = Vcc
    }
    else
    { 
        bPowerReg |= PWR_VPP1_BIT0 | PWR_VPP1_BIT1; // set Vpp = 0
    }
    PCICRegisterWrite( REG_POWER_CONTROL, bPowerReg );

    Sleep( 100 );

    //
    // Assert RESET for 20 MS
    //
    UINT8 intctl = PCICRegisterRead( REG_INTERRUPT_AND_GENERAL_CONTROL );
    PCICRegisterWrite( REG_INTERRUPT_AND_GENERAL_CONTROL, intctl & ~ INT_CARD_NOT_RESET );
    Sleep( 20 );

    Sleep(20);

    //
    // Deassert RESET
    //
    PCICRegisterWrite( REG_INTERRUPT_AND_GENERAL_CONTROL,
                       intctl | INT_CARD_NOT_RESET );

    //
    // Allow the card 2 seconds to assert RDY
    //
    DWORD dwCount;
    for( dwCount = 0; dwCount < 2000; dwCount += 20 )
    {
        // Check for one second.
        if( ( PCICRegisterRead( REG_INTERFACE_STATUS ) & STS_CARD_READY ) !=
            0 )
        {
            break;
        }
        PCICRegisterWrite( REG_POWER_CONTROL, bPowerReg );
        Sleep( 20 );
    };

    if( dwCount >= 2000 )
    {
        DEBUGMSG( ZONE_FUNCTION,
                  ( TEXT( "PDCardResetSocket: CARD IN SOCKET NOT RDY AFTER %dms\r\n" ),
                    dwCount ) );
    }

    PowerCycleEvent();
}

//
// ResetSocket - do a PCMCIA reset
// return CERR_SUCCESS on success, CERR_UNSUPPORTED_SERVICE if size is anomolous
//
STATUS CPCMSocket::CardResetSocket()
{
    DEBUGMSG( ZONE_SOCKET, ( TEXT( "+SMDK2410!ResetPCMCIASocket()\r\n" ) ) );

    // set INT_CARD_NOT_RESET in INTERRUPT_AND_GENERAL_CONTROL register as directed
    Lock();
    STATUS status = CERR_SUCCESS;
    if( m_pBridge )
    {
        //
        // Power the socket
        //
        UINT8 uTmp = PCICRegisterRead( REG_INTERFACE_STATUS );
        if( ( uTmp & ( STS_CD1 | STS_CD2 ) ) == 0 )
        {
            // No card Inserted
            status = CERR_NO_CARD;
        }
        else
        {
            BYTE uVcc = 1;
            if( PCICRegisterRead( REG_GENERAL_CONTROL ) & MISC1_5V_DETECT )
            {
                // 5 Volt Card.
                uVcc = 2;
                DEBUGMSG( ZONE_SOCKET,
                          ( TEXT( "+SMDK2410!ResetPCMCIASocket: Initial Power on is 5 Volt\r\n" ) ) );
            }
            else
            {
                DEBUGMSG( ZONE_SOCKET,
                          ( TEXT( "+SMDK2410!ResetPCMCIASocket: Initial Power on is 3 Volt\r\n" ) ) );
            }
            PowerOnProcedure( uVcc, 0 );

            //
            // Power the socket
            //
            m_SocketState.fVcc = uVcc;
            m_SocketState.uVpp1 = 0;
            m_SocketState.uVpp2 = 0;
        }
    }
    else
    {
        status = CERR_BAD_SOCKET;
    }
    DEBUGMSG( ZONE_SOCKET,
              ( TEXT( "-SMDK2410!ResetPCMCIASocket() return status =%x\r\n" ),
                status ) );
    Unlock();
    return status;
}

void CPCMSocket::SocketEventHandle( DWORD dwEvent, DWORD dwPresentStateReg ) // Event Handle from Interrupt.
{
    SS_SOCKET_STATE sSockState;
    Lock();
    CardGetSocket( &sSockState );
    // Update the state from interrupt. But not card detection. Card detection event
    // generate during object createion.
    sSockState.dwEventChanged &= ~SOCK_EVENT_CD;
    if( ( dwPresentStateReg & SPS_POWERCYCLE ) != 0 )
    {
        sSockState.dwEventStatus |= SOCK_EVENT_PWRCYCLE;
        sSockState.dwEventChanged |= SOCK_EVENT_PWRCYCLE;
    }
    Unlock();
    m_pBridge->CallBackToCardService( GetSocketHandle(),
                                      &sSockState );
}


CPcmciaCardSocket* CreatePCMCIASocket( CPcmciaBusBridge* pBridge )
{
    CPCMSocket* pNewSocket = new CPCMSocket( pBridge );
    if( pNewSocket != NULL )
    {
        if( pNewSocket->CardInitWindow( pNewSocket ) )
        {
            return pNewSocket;
        }
        else
        {
            delete pNewSocket;
        }
    }
    return NULL;
}

⌨️ 快捷键说明

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