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

📄 cserpdd.cpp

📁 wince下的串口驱动源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//
// 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.
//
// 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:  CSerpdd.cpp

Abstract:

    Serial PDD Common Code.

Notes: 
--*/

#include <windows.h>
#include <types.h>
#include <ceddk.h>
#include <notify.h>
#include <ddkreg.h>
#include <serhw.h>
#include <ser16550.h>
#include <hw16550.h>
#include <ddkreg.h>
#include <pm.h>
#include <Serdbg.h>
#include "CSerPdd.h"

CSerialPDDPowerUpCallback::CSerialPDDPowerUpCallback(CSerialPDD * pSerialObj)
:   m_pSerialObj(pSerialObj)
,   CMiniThread (0, TRUE)
{
    DEBUGCHK(m_pSerialObj!=NULL);
    m_hEvent =CreateEvent(NULL,FALSE,FALSE,NULL);
    ThreadStart();
}
CSerialPDDPowerUpCallback::~CSerialPDDPowerUpCallback()
{
    m_bTerminated = TRUE;
    SignalCallback();
    ThreadTerminated(1000);
}
DWORD CSerialPDDPowerUpCallback::ThreadRun()
{
    while (!IsTerminated() && m_hEvent!=NULL && m_pSerialObj!=NULL) {
        if (WaitForSingleObject(m_hEvent,INFINITE)==WAIT_OBJECT_0) {
            if (!IsTerminated()) {
                m_pSerialObj->NotifyPDDInterrupt(INTR_NONE);
            }
        }
        else 
            ASSERT(FALSE);
        
    }
    return 0;
}

CSerialPDD::CSerialPDD(LPTSTR lpActivePath, PVOID pMdd,  PHWOBJ pHwObj  )
:   CRegistryEdit(lpActivePath)
,   m_pMdd(pMdd)
,   m_pHwObj(pHwObj)
{

    m_hParent = CreateBusAccessHandle(lpActivePath);
    m_PowerHelperHandle = INVALID_HANDLE_VALUE;
    m_hPowerLock = NULL;
    // Initial Open Count.
    m_lOpenCount = 0;
    m_ulCommErrors = 0;
    m_PowerCallbackThread = NULL;
    if (!GetRegValue(PC_REG_SERIALPRIORITY_VAL_NAME,(LPBYTE)&m_dwPriority256,sizeof(DWORD))) {
        m_dwPriority256 = DEFAULT_CE_THREAD_PRIORITY+55;
    }
}
CSerialPDD::~CSerialPDD()
{   
    InitialEnableInterrupt(FALSE); 
    if (m_hParent)
        CloseBusAccessHandle(m_hParent);
    if (m_PowerHelperHandle != INVALID_HANDLE_VALUE )
        DDKPwr_Deinitialize(m_PowerHelperHandle);
    if (m_PowerCallbackThread)
        delete m_PowerCallbackThread;
    InitialPower(FALSE);
}

BOOL CSerialPDD::Init()
{
    InitialPower(TRUE);
    if (m_PowerCallbackThread  == NULL) {
        m_PowerCallbackThread = new CSerialPDDPowerUpCallback(this);
        if ( m_PowerCallbackThread  && !m_PowerCallbackThread->Init()){
            delete m_PowerCallbackThread;
            m_PowerCallbackThread = NULL;
        }
    }
    m_PowerHelperHandle = DDKPwr_Initialize(SetPowerStateStatic, (DWORD)this , TRUE, 1000 );
    return (m_PowerCallbackThread!=NULL && m_PowerHelperHandle!=INVALID_HANDLE_VALUE );
}
void CSerialPDD::PostInit() 
{
    InitialEnableInterrupt(TRUE); 
    InitModem(TRUE);
}

BOOL CSerialPDD::Open()
{
    if (InterlockedExchange(&m_lOpenCount,1) !=0)
        return FALSE;
    
    PREFAST_ASSERT(m_PowerHelperHandle!=INVALID_HANDLE_VALUE);
    ASSERT(m_hPowerLock==NULL);
    m_hPowerLock= DDKPwr_RequestLevel( m_PowerHelperHandle, D0 );  
    ASSERT(m_hPowerLock!=NULL);
    
    SetDefaultConfiguration(); 
    InitLine(TRUE);
    InitReceive(TRUE);
    InitXmit(TRUE);
    return TRUE;
}
BOOL CSerialPDD::Close()
{
    if (InterlockedExchange(&m_lOpenCount,0) !=1)
        return FALSE;
    InitXmit(FALSE);
    InitReceive(FALSE);
    InitLine(FALSE);
    
    PREFAST_ASSERT(m_PowerHelperHandle!=INVALID_HANDLE_VALUE);
    ASSERT(m_hPowerLock!=NULL);
    DDKPwr_ReleaseLevel(m_PowerHelperHandle, m_hPowerLock);  
    m_hPowerLock=NULL;
    
    return TRUE;
}
void CSerialPDD::Reset()
{
    InitialPower(TRUE);
    InitModem(TRUE);
    InitLine(TRUE);
    InitReceive(TRUE);
    InitXmit(TRUE);
    InitialEnableInterrupt(TRUE); 
}
BOOL CSerialPDD::Ioctl(DWORD dwCode,PBYTE pBufIn,DWORD dwLenIn,PBYTE pBufOut,DWORD dwLenOut,PDWORD pdwActualOut)
{
    BOOL RetVal=FALSE;
    switch ( dwCode ) {
    case IOCTL_POWER_CAPABILITIES: 
        if (!pBufOut || dwLenOut < sizeof(POWER_CAPABILITIES) || !pdwActualOut) {
            SetLastError(ERROR_INVALID_PARAMETER);
            RetVal = FALSE;
        } else {
            m_IsThisPowerManaged= TRUE;
            PPOWER_CAPABILITIES ppc = (PPOWER_CAPABILITIES)pBufOut;        
            *ppc= GetPowerCapabilities();
            if (pdwActualOut)
                *pdwActualOut = sizeof(POWER_CAPABILITIES);
            RetVal = TRUE;
        }
        break;
    case IOCTL_POWER_SET:
        if (!pBufOut || dwLenOut < sizeof(CEDEVICE_POWER_STATE) || !pdwActualOut || m_PowerHelperHandle == INVALID_HANDLE_VALUE ) {
            SetLastError(ERROR_INVALID_PARAMETER);
            RetVal = FALSE;
        } else {
            m_IsThisPowerManaged= TRUE;
            CEDEVICE_POWER_STATE newDx = *(PCEDEVICE_POWER_STATE) pBufOut;
            DEBUGMSG(1, (TEXT("COM: IOCTL_POWER_SET: D%d\r\n"), newDx));
            RetVal = DDKPwr_SetDeviceLevel( m_PowerHelperHandle, newDx, NULL );
            // did we set the device power?
            if(RetVal == TRUE) {
                *(PCEDEVICE_POWER_STATE)pBufOut = DDKPwr_GetDeviceLevel(m_PowerHelperHandle );
                if (pdwActualOut) {
                    *pdwActualOut = sizeof(CEDEVICE_POWER_STATE);
                }
            }
            else
                SetLastError(ERROR_INVALID_PARAMETER);
        }
        break;
    default:
        SetLastError(ERROR_INVALID_PARAMETER);
        RetVal = FALSE;
        break;
    }
    return RetVal;
}
//
//Power Managment Operation
BOOL CSerialPDD::InitialPower(BOOL bInit)
{
    m_PowerState=D0;
    m_IsThisPowerManaged=FALSE;
    m_PowerCapabilities.DeviceDx=DX_MASK(D0)|DX_MASK(D3)|DX_MASK(D4);
    return TRUE;
}
CEDEVICE_POWER_STATE CSerialPDD::SetPowerStateStatic(DWORD dwContext, CEDEVICE_POWER_STATE powerState)
{
    CEDEVICE_POWER_STATE rState = powerState;
    if (dwContext) {
        ((CSerialPDD *)dwContext)->SetDevicePowerState(powerState);
        rState = ((CSerialPDD *)dwContext)->GetDevicePowerState();
    }
    else
        ASSERT(FALSE);
    return rState;
}
BOOL CSerialPDD::PowerOff()
{
    if (!m_IsThisPowerManaged ) {
        SerialRegisterBackup();        
        if (m_hParent ) {
            ::SetDevicePowerState( m_hParent, D4, NULL);
        }
    }
    return TRUE;
}
BOOL CSerialPDD::PowerOn()
{
    if (!m_IsThisPowerManaged ) {
        if ( m_hParent ) {
            ::SetDevicePowerState( m_hParent, D0, NULL);
        }
        SerialRegisterRestore();
    }
    m_IsResumed = 1;
    if (m_PowerCallbackThread)
        m_PowerCallbackThread->SignalCallback();
    return TRUE;
}
BOOL  CSerialPDD::SetDevicePowerState(CEDEVICE_POWER_STATE pwrState)
{
    if (m_PowerState!=pwrState) {
        BOOL bReturn = TRUE;
        if ((m_PowerState != D3 && m_PowerState !=D4) && (pwrState== D3 || pwrState==D4)) { // Power Off.
            SerialRegisterBackup();
        }
        if (m_hParent && ::SetDevicePowerState( m_hParent, pwrState, NULL)) {
            m_PowerState = pwrState;
            bReturn =  TRUE;
        }
        else
            bReturn =  FALSE;
        if ((m_PowerState == D3 || m_PowerState ==D4) && (pwrState!= D3 && pwrState!=D4)) { // Power On.
            SerialRegisterRestore();
            m_IsResumed = 1;
        }
        return bReturn;
    }
    return TRUE;
}
//
// Interrupt Handle
BOOL CSerialPDD::InitialEnableInterrupt(BOOL /*bEnable*/ ) 
{
    m_InterruptLock.Lock();
    m_dwInterruptFlag = INTR_NONE;
    m_InterruptLock.Unlock();
    return TRUE;
}
extern "C" VOID SerialEventHandler(PVOID pMddHead);

BOOL CSerialPDD::NotifyPDDInterrupt(INTERRUPT_TYPE interruptType)
{
    m_InterruptLock.Lock();
    // The interrupt is define as Bit event.
    m_dwInterruptFlag |= (DWORD)interruptType;
    m_InterruptLock.Unlock();
    if (IsPowerResumed ( )) {
        if (m_lOpenCount) { // If application is opened.
            EventCallback( EV_POWER );
        }
        else {
            if (GetModemStatus() & MS_RLSD_ON)
                CeEventHasOccurred (NOTIFICATION_EVENT_RS232_DETECTED, NULL);
        }
    }
    SerialEventHandler(m_pMdd);
    return TRUE;
}
INTERRUPT_TYPE CSerialPDD::GetInterruptType()
{
    m_InterruptLock.Lock();
    // The interrupt is define as Bit event.
    INTERRUPT_TYPE lIntrFlagRet= (INTERRUPT_TYPE )m_dwInterruptFlag;
    m_dwInterruptFlag = INTR_NONE;
    m_InterruptLock.Unlock();
    return lIntrFlagRet;
}
BOOL CSerialPDD::DataReplaced(PBYTE puData,BOOL isBadData)
{
    BOOL bReturn = FALSE;
    if (puData) {
        UCHAR inputData= *puData;
        if (m_DCB.fDsrSensitivity && IsDSROff() ) {
        }
        else 
        if (inputData==NULL &&  m_DCB.fNull) {
        }
        else {
            bReturn = TRUE;
            if (m_DCB.fErrorChar && isBadData) {
                inputData = m_DCB.ErrorChar;

⌨️ 快捷键说明

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