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

📄 pcmsock.cpp

📁 SBC2410 WinCE 5.0 BSP.绝大多数驱动已经调通。
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.

Module Name:  

Abstract:

    Samsung SMDK2410 PCMCIA Socket Services Object for PCMCIA(16-bit) Interface.

Notes: 
--*/
#include <windows.h>
#include <types.h>
#include <socksv2.h>
#include <memory.h>
#include <ceddk.h>
#include <debug.h>
#define ZONE_SOCKET ZONE_PDD

#include "PCMSock.h"

//--------------------Pcmcia Socket Implementation--------------------------------------------
const SS_SOCKET_INFO CPCMSocket::ms_SocketInitInfo =
{
    SOCK_CAP_MEM_CARD |
    SOCK_CAP_IO_MEMORY_CARD,      //dwSocketCaps
    SOCK_CAP_PWRCYCLE |
    SOCK_CAP_CD |
    SOCK_CAP_SUSPEND_RESUME |
    SOCK_CAP_WP |
    SOCK_CAP_BVD1 |
    SOCK_CAP_BVD2,  // Socket Interrupt Capability Set follow bitmap.
    SOCK_CAP_PWRCYCLE |
    SOCK_CAP_CD |
    SOCK_CAP_SUSPEND_RESUME |
    SOCK_CAP_WP |
    SOCK_CAP_BVD1 |
    SOCK_CAP_BVD2,  // Socket status report capability
    0,              // Socket status indicate capability
    0,              // Number of power entry this socket have.
    0,              // Number of Window supported in this Socket.
    Internal,       // Bus Type is Internal.
    (DWORD) -1,     // Bus Number.
    { - 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}
};
const SS_SOCKET_STATE CPCMSocket::ms_SocketInitState =
{
    SOCK_EVENT_PWRCYCLE |
    SOCK_EVENT_CD |
    SOCK_EVENT_SUSPEND_RESUME |
    SOCK_EVENT_WP |
    SOCK_EVENT_BVD1 |
    SOCK_EVENT_BVD2, // Initial EventMask
    0, // Event Changed.
    0, // Event Status
    CFG_IFACE_MEMORY,  //default interface type
    0,  // Interrupt Enable.
    0,  // Vcc
    0,  // Vpp1
    0   // Vpp2

};

CPCMSocket::CPCMSocket( CPcmciaBusBridge* pBridge ) : CPCMCIASocketBase<CPcmciaMemWindows, CPcmciaIoWindows, CPcmciaCardSocket, CPcmciaBusBridge>( pBridge )
{
    DEBUGMSG( ZONE_SOCKET, ( TEXT( "+CPCMSocket::CPCMSocket\r\n" ) ) );
    m_SocketState = ms_SocketInitState;
    m_SocketInfo = ms_SocketInitInfo;

    if( pBridge->GetFnIRQ() == -1 )
    {
        m_SocketInfo.dwSocketCaps |= SOCK_CAP_ONLY_SYSINTR;
    }

    for( DWORD dwIndex = 0; dwIndex < IRQ_ROUTINGTABLE_SIZE; dwIndex++ )
    {
        if( m_SocketInfo.dwSocketCaps & SOCK_CAP_ONLY_SYSINTR )
        {
            m_SocketInfo.bArrayIrqRouting[dwIndex] = ( BYTE )pBridge->GetFnSysInt();
        }
        else
        {
            m_SocketInfo.bArrayIrqRouting[dwIndex] = ( BYTE )pBridge->GetFnIRQ();
        }
    }
    m_SocketInfo.dwNumOfPowerEntry = NUM_POWER_ENTRIES;
    m_SocketInfo.dwNumOfWindows = pBridge->GetMemWindowCount() +
                                          pBridge->GetIoWindowCount();
    m_SocketInfo.dwBusNumber = 0;

    if( !pBridge->PollingMode() )
    {
        PCICRegisterWrite( REG_STATUS_CHANGE_INT_CONFIG,
                        CFG_BATTERY_DEAD_ENABLE |
                        CFG_BATTERY_WARNING_ENABLE |
                        CFG_CARD_DETECT_ENABLE |
                        CFG_READY_ENABLE );
    }
    m_bResuming = FALSE;

    DEBUGMSG( ZONE_SOCKET, ( TEXT( "-CPCMSocket::CPCMSocket\r\n" ) ) );
}
CPCMSocket::~CPCMSocket()
{
    DEBUGMSG( ZONE_SOCKET, ( TEXT( "+CPCMSocket::Deinitialize()\r\n" ) ) );
    Lock();
    BOOL bInitWindow = CardDeInitWindow();
    DEBUGCHK( bInitWindow );
    PCICRegisterWrite( REG_POWER_CONTROL,
                       PCICRegisterRead( REG_POWER_CONTROL ) & ~PWR_OUTPUT_ENABLE );
    Unlock();
    DEBUGMSG( ZONE_SOCKET, ( TEXT( "-CPCMSocket::Deinitialize()\r\n" ) ) );
}

//
// GetSocket - return Socket state
// [In/Out] pBuf - pointer to SS_SOCKET_STATE struct
// [In/Out] pnBuf - pointer to size of struct pointed to by pBuf
// return CERR_SUCCESS on success, CERR_UNSUPPORTED_SERVICE if size is anomolous
//
STATUS CPCMSocket::CardGetSocket( PSS_SOCKET_STATE pState )
{
    DWORD dwReg;

    DEBUGMSG( ZONE_SOCKET, ( TEXT( "+CPCMSocket::GetSocket()\r\n" ) ) );
    Lock();
    if( pState )
    {
        // Read voltage information
        dwReg = PCICRegisterRead( REG_POWER_CONTROL );
        if( dwReg & PWR_VCC_POWER )
        {
            dwReg = PCICRegisterRead( REG_GENERAL_CONTROL );
            if( dwReg & MISC1_VCC_33 ) // Vcc = 3V
            {
                // Vcc = 3V
                m_SocketState.fVcc = 0x1;
            }
            else
            {
                // Vcc = 5V
                m_SocketState.fVcc = 0x2;
            }
        }
        else
        {
            // Vcc = 0V
            m_SocketState.fVcc = 0x0;
        }
        m_SocketState.uVpp1 = m_SocketState.uVpp2 = 0; //m_SocketState.fVcc;

        BYTE uStatusChange = 0;
        m_SocketState.dwEventChanged |= ( ( uStatusChange & CSC_DETECT_CHANGE ) !=
                                        0 ?
                                        SOCK_EVENT_CD :
                                        0 );
        m_SocketState.dwEventChanged |= ( ( uStatusChange & CSC_BATTERY_DEAD_OR_STS_CHG ) !=
                                        0 ?
                                        SOCK_EVENT_BVD1 :
                                        0 );
        m_SocketState.dwEventChanged |= ( ( uStatusChange & CSC_BATTERY_WARNING ) !=
                                        0 ?
                                        SOCK_EVENT_BVD2 :
                                        0 );
        m_SocketState.dwEventChanged |= ( ( uStatusChange & CSC_READY_CHANGE ) !=
                                        0 ?
                                        SOCK_EVENT_READY :
                                        0 );

        BYTE uCurrentStatus = PCICRegisterRead( REG_INTERFACE_STATUS );
        m_SocketState.dwEventStatus = 0;
        m_SocketState.dwEventStatus |= ( ( uCurrentStatus & ( STS_CD1 | STS_CD2 ) ) ==
                                       ( STS_CD1 | STS_CD2 ) ?
                                       SOCK_EVENT_CD :
                                       0 );
        m_SocketState.dwEventStatus |= ( ( uCurrentStatus & STS_BVD1 ) ==
                                       0 ?
                                       SOCK_EVENT_BVD1 :
                                       0 );
        m_SocketState.dwEventStatus |= ( ( uCurrentStatus & STS_BVD2 ) ==
                                       0 ?
                                       SOCK_EVENT_BVD2 :
                                       0 );
        m_SocketState.dwEventStatus |= ( ( uCurrentStatus & STS_CARD_READY ) !=
                                       0 ?
                                       SOCK_EVENT_READY :
                                       0 );
        m_SocketState.dwEventStatus |= ( ( uCurrentStatus & STS_WRITE_PROTECT ) !=
                                       0 ?
                                       SOCK_EVENT_WP :
                                       0 );

        m_SocketState.dwEventStatus &= ~SOCK_EVENT_CARDBUS_CARD;
        *pState = m_SocketState;
        pState->dwEventChanged &= pState->dwEventMask;

        DEBUGMSG( ZONE_SOCKET,
                  ( TEXT( "-CPCMSocket::GetSocket(): dwEventMask: %x dwEventChanged: %x dwEventStatus: %x\r\n" ),
                    pState->dwEventMask,
                    pState->dwEventChanged,
                    pState->dwEventStatus ) );
    }
    Unlock();
    return CERR_SUCCESS;
}
void CPCMSocket::PowerMgrCallback( BOOL bPowerOff )
{
    SS_SOCKET_STATE sSocketState = m_SocketState;
    sSocketState.dwEventChanged = SOCK_EVENT_SUSPEND_RESUME;
    sSocketState.dwEventStatus = ( bPowerOff ?
                                   SOCK_EVENT_CD :
                                   ( SOCK_EVENT_CD |
                                     SOCK_EVENT_SUSPEND_RESUME ) );
    m_pBridge->CallBackToCardService( GetSocketHandle(),
                                      &sSocketState );
}

void CPCMSocket::PowerMgr( BOOL bPowerDown )
{
    if( bPowerDown )
    {
        // Power Off Socket If it is applied.
        PowerMgrCallback( bPowerDown );
        if( ( m_SocketState.dwInteruptStatus & SOCK_INT_FUNC_IRQ_WAKE ) == 0 ) // We can shut down this function card
        {
            m_bBackupPCICPwrCtrlReg = PCICRegisterRead( REG_POWER_CONTROL );
            // Disable Socket Power.
            PCICRegisterWrite( REG_POWER_CONTROL, 0 );
            m_bResuming = TRUE;
        }
    }
    else
    {
        if( m_bResuming )
        {
            PCICRegisterWrite( REG_POWER_CONTROL, m_bBackupPCICPwrCtrlReg );
            m_pBridge->NeedPowerResuming();
        }
        else
        {
            PowerMgrCallback( bPowerDown );
        }
    }
}
BOOL CPCMSocket::Resuming()
{
    if( m_bResuming )
    {
        Lock();
        DWORD dwStartTickCount = GetTickCount();
        // Wait for 100MS for power set .
        while( GetTickCount() - dwStartTickCount < 100 )
            Sleep( 0 ); //Yeild among same priority thread.
        //Assert Resetting.
        dwStartTickCount = GetTickCount();
        while( GetTickCount() - dwStartTickCount < 20 )
            Sleep( 0 ); //Yeild among same priority thread.
        // Deassert Reset.
        PCICRegisterWrite( REG_INTERRUPT_AND_GENERAL_CONTROL,
                           INT_CARD_NOT_RESET/*|INT_ENABLE_MANAGE_INT*/ ); 
        dwStartTickCount = GetTickCount();
        while( GetTickCount() - dwStartTickCount < 20 )
            Sleep( 0 ); //Yeild among same priority thread.
        m_bResuming = FALSE;
        dwStartTickCount = GetTickCount();

        PowerMgrCallback( FALSE );
        Unlock();
        return TRUE;
    }
    return FALSE;
}

#ifdef DEBUG
VOID CPCMSocket::DumpAllRegisters()
{
    DEBUGMSG( ZONE_FUNCTION,
        ( TEXT( "Dumping all PCIC registers:\r\n" ) ) );
    for( UINT8 nRegNum = 0; nRegNum < 0x40; nRegNum++ )
    {
        UINT8 val = PCICRegisterRead( nRegNum );
        DEBUGMSG( ZONE_FUNCTION,
                  ( TEXT( "PCIC Register %02x: %02x\r\n" ), nRegNum, val ) );
    }
}
#endif DEBUG

//
// PDCardSetSocket
//
// @func    STATUS | PDCardSetSocket | Set the socket state of the specified socket.
// @rdesc   Returns one of the CERR_* return codes in cardserv.h.
//
// @comm    This function sets the specified socket's state and adjusts the socket
//          controller appropriately.
//          PDCardGetSocketState will usually be called first and adjustments will
//          be made to the PDCARD_SOCKET_STATE structure before PDCardSetSocketState
//          is called.  This avoids duplicated socket state on different layers and
//          it avoids unintentionally setting socket parameters.
//
// @xref <f PDCardGetSocketState>
//

STATUS CPCMSocket::CardSetSocket( PSS_SOCKET_STATE pState )
{
    Lock();
    STATUS status = CERR_SUCCESS;
    if( m_pBridge && pState )
    {
        m_SocketState.dwEventMask = pState->dwEventMask;
        m_SocketState.dwEventChanged &= ~pState->dwEventChanged;

        BYTE tmp = PCICRegisterRead( REG_INTERRUPT_AND_GENERAL_CONTROL ) & ( INT_RING_INDICATE_ENABLE |
                                                                             INT_ENABLE_MANAGE_INT |
                                                                             INT_CARD_NOT_RESET |
                                                                             0x0f );
        tmp |= INT_CARD_NOT_RESET ;
        if( ( pState->dwInteruptStatus & SOCK_INT_FUNC_IRQ_ROUTING ) !=
            ( m_SocketState.dwInteruptStatus & SOCK_INT_FUNC_IRQ_ROUTING ) )

⌨️ 快捷键说明

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