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

📄 modmflow.c

📁 NXP产品LPC23XX的开发板的源文件
💻 C
📖 第 1 页 / 共 4 页
字号:
/*++

Copyright (c) 1991, 1992, 1993 Microsoft Corporation
Copyright (c) 2000 Maverick Research Inc

Module Name:

    modmflow.c

Abstract:

    This module contains *MOST* of the code used to manipulate
    the modem control and status registers.  The vast majority
    of the remainder of flow control is concentrated in the
    Interrupt service routine.  A very small amount resides
    in the read code that pull characters out of the interrupt
    buffer.

Author:

    Anthony V. Ercolano 26-Sep-1991
	Henry Tan			11-Aug-2000

Environment:

    Kernel mode

Revision History :

--*/

//#include "precomp.h"
#include "wdm.h"
#include "stdarg.h"
#include "stdio.h"
#include "usbdi.h"
#include "usbdlib.h"
#include "usbcom.h"

BOOLEAN
SerialDecrementRTSCounter(
    IN PVOID Context
    );
/*
#ifdef ALLOC_PRAGMA
#if 0
#pragma alloc_text(PAGESER,SerialHandleReducedIntBuffer)
#pragma alloc_text(PAGESER,SerialProdXonXoff)
#pragma alloc_text(PAGESER,SerialHandleModemUpdate)
#pragma alloc_text(PAGESER,SerialPerhapsLowerRTS)
#pragma alloc_text(PAGESER,SerialStartTimerLowerRTS)
#pragma alloc_text(PAGESER,SerialInvokePerhapsLowerRTS)
#pragma alloc_text(PAGESER,SerialSetDTR)
//#pragma alloc_text(PAGESER,SerialClrDTR)
#pragma alloc_text(PAGESER,SerialSetRTS)
//#pragma alloc_text(PAGESER,SerialClrRTS)
//#pragma alloc_text(PAGESER,SerialSetupNewHandFlow)
#pragma alloc_text(PAGESER,SerialSetHandFlow)
#pragma alloc_text(PAGESER,SerialTurnOnBreak)
#pragma alloc_text(PAGESER,SerialTurnOffBreak)
#pragma alloc_text(PAGESER,SerialPretendXoff)
#pragma alloc_text(PAGESER,SerialPretendXon)
#pragma alloc_text(PAGESER,SerialDecrementRTSCounter)
#endif
#endif
*/

BOOLEAN
SerialSetDTR(
    IN PVOID Context
    )

/*++

Routine Description:

    This routine which is only called at interrupt level is used
    to set the DTR in the modem control register.

Arguments:

    Context - Really a pointer to the device extension.

Return Value:

    This routine always returns FALSE.

--*/

{

    PDEVICE_EXTENSION Extension = Context;
/*    UCHAR ModemControl;

    ModemControl = READ_MODEM_CONTROL(Extension->Controller);

    ModemControl |= SERIAL_MCR_DTR;

    SerialDump(
        SERFLOW,
        ("SERIAL: Setting DTR for %x\n",
         Extension->Controller)
        );
    WRITE_MODEM_CONTROL(
        Extension->Controller,
        ModemControl
        );
*/

	UsbCom_SendVendor(Extension->DeviceObject, VendorSetDTR, 0x01);

    return FALSE;

}

BOOLEAN
SerialClrDTR(
    IN PVOID Context
    )

/*++

Routine Description:

    This routine which is only called at interrupt level is used
    to clear the DTR in the modem control register.

Arguments:

    Context - Really a pointer to the device extension.

Return Value:

    This routine always returns FALSE.

--*/

{

    PDEVICE_EXTENSION Extension = Context;
/*    UCHAR ModemControl;

    ModemControl = READ_MODEM_CONTROL(Extension->Controller);

    ModemControl &= ~SERIAL_MCR_DTR;

    SerialDump(
        SERFLOW,
        ("SERIAL: Clearing DTR for %x\n",
         Extension->Controller)
        );
    WRITE_MODEM_CONTROL(
        Extension->Controller,
        ModemControl
        );
*/

	UsbCom_SendVendor(Extension->DeviceObject, VendorSetDTR, 0x00);

    return FALSE;

}

BOOLEAN
SerialSetRTS(
    IN PVOID Context
    )

/*++

Routine Description:

    This routine which is only called at interrupt level is used
    to set the RTS in the modem control register.

Arguments:

    Context - Really a pointer to the device extension.

Return Value:

    This routine always returns FALSE.

--*/

{

    PDEVICE_EXTENSION Extension = Context;
/*    UCHAR ModemControl;

    ModemControl = READ_MODEM_CONTROL(Extension->Controller);

    ModemControl |= SERIAL_MCR_RTS;

    SerialDump(
        SERFLOW,
        ("SERIAL: Setting Rts for %x\n",
         Extension->Controller)
        );
    WRITE_MODEM_CONTROL(
        Extension->Controller,
        ModemControl
        );
*/

	UsbCom_SendVendor(Extension->DeviceObject, VendorSetRTS, 0x01);

    return FALSE;

}

BOOLEAN
SerialClrRTS(
    IN PVOID Context
    )

/*++

Routine Description:

    This routine which is only called at interrupt level is used
    to clear the RTS in the modem control register.

Arguments:

    Context - Really a pointer to the device extension.

Return Value:

    This routine always returns FALSE.

--*/

{

    PDEVICE_EXTENSION Extension = Context;
/*    UCHAR ModemControl;

    ModemControl = READ_MODEM_CONTROL(Extension->Controller);

    ModemControl &= ~SERIAL_MCR_RTS;

    SerialDump(
        SERFLOW,
        ("SERIAL: Clearing Rts for %x\n",
         Extension->Controller)
        );
    WRITE_MODEM_CONTROL(
        Extension->Controller,
        ModemControl
        );
*/

	UsbCom_SendVendor(Extension->DeviceObject, VendorSetRTS, 0x00);

    return FALSE;

}

BOOLEAN
SerialSetupNewHandFlow(
    IN PDEVICE_EXTENSION Extension,
    IN PSERIAL_HANDFLOW NewHandFlow
    )

/*++

Routine Description:

    This routine adjusts the flow control based on new
    control flow.

Arguments:

    Extension - A pointer to the serial device extension.

    NewHandFlow - A pointer to a serial handflow structure
                  that is to become the new setup for flow
                  control.

Return Value:

    This routine always returns FALSE.

--*/

{

    SERIAL_HANDFLOW New = *NewHandFlow;

    //
    // If the Extension->DeviceIsOpened is FALSE that means
    // we are entering this routine in response to an open request.
    // If that is so, then we always proceed with the work regardless
    // of whether things have changed.
    //

    //
    // First we take care of the DTR flow control.  We only
    // do work if something has changed.
    //

    if ((!Extension->DeviceIsOpened) ||
        ((Extension->HandFlow.ControlHandShake & SERIAL_DTR_MASK) !=
         (New.ControlHandShake & SERIAL_DTR_MASK))) {

        SerialDump(
            SERFLOW,
            ("SERIAL: Processing DTR flow for %x\n",
             Extension->Controller)
            );

        if (New.ControlHandShake & SERIAL_DTR_MASK) {

            //
            // Well we might want to set DTR.
            //
            // Before we do, we need to check whether we are doing
            // dtr flow control.  If we are then we need to check
            // if then number of characters in the interrupt buffer
            // exceeds the XoffLimit.  If it does then we don't
            // enable DTR AND we set the RXHolding to record that
            // we are holding because of the dtr.
            //

            if ((New.ControlHandShake & SERIAL_DTR_MASK)
                == SERIAL_DTR_HANDSHAKE) {

                if ((Extension->BufferSize - New.XoffLimit) >
                    Extension->CharsInInterruptBuffer) {

                    //
                    // However if we are already holding we don't want
                    // to turn it back on unless we exceed the Xon
                    // limit.
                    //

                    if (Extension->RXHolding & SERIAL_RX_DTR) {

                        //
                        // We can assume that its DTR line is already low.
                        //

                        if (Extension->CharsInInterruptBuffer >
                            (ULONG)New.XonLimit) {

                            SerialDump(
                                SERFLOW,
                                ("SERIAL: Removing DTR block on reception for %x\n",
                                 Extension->Controller)
                                );
                            Extension->RXHolding &= ~SERIAL_RX_DTR;
                            SerialSetDTR(Extension);

                        }

                    } else {

                        SerialSetDTR(Extension);

                    }

                } else {

                    SerialDump(
                        SERFLOW,
                        ("SERIAL: Setting DTR block on reception for %x\n",
                         Extension->Controller)
                        );
                    Extension->RXHolding |= SERIAL_RX_DTR;
                    SerialClrDTR(Extension);

                }

            } else {

                //
                // Note that if we aren't currently doing dtr flow control then
                // we MIGHT have been.  So even if we aren't currently doing
                // DTR flow control, we should still check if RX is holding
                // because of DTR.  If it is, then we should clear the holding
                // of this bit.
                //

                if (Extension->RXHolding & SERIAL_RX_DTR) {

                    SerialDump(
                        SERFLOW,
                        ("SERIAL: Removing dtr block of reception for %x\n",
                        Extension->Controller)
                        );
                    Extension->RXHolding &= ~SERIAL_RX_DTR;

                }

                SerialSetDTR(Extension);

            }

        } else {

            //
            // The end result here will be that DTR is cleared.
            //
            // We first need to check whether reception is being held
            // up because of previous DTR flow control.  If it is then
            // we should clear that reason in the RXHolding mask.
            //

            if (Extension->RXHolding & SERIAL_RX_DTR) {

                SerialDump(
                    SERFLOW,
                    ("SERIAL: removing dtr block of reception for %x\n",
                    Extension->Controller)
                    );
                Extension->RXHolding &= ~SERIAL_RX_DTR;

            }

            SerialClrDTR(Extension);

        }

    }

    //
    // Time to take care of the RTS Flow control.
    //
    // First we only do work if something has changed.
    //

    if ((!Extension->DeviceIsOpened) ||
        ((Extension->HandFlow.FlowReplace & SERIAL_RTS_MASK) !=
         (New.FlowReplace & SERIAL_RTS_MASK))) {

        SerialDump(
            SERFLOW,
            ("SERIAL: Processing RTS flow\n",
             Extension->Controller)
            );

        if ((New.FlowReplace & SERIAL_RTS_MASK) ==
            SERIAL_RTS_HANDSHAKE) {

            //
            // Well we might want to set RTS.
            //
            // Before we do, we need to check whether we are doing
            // rts flow control.  If we are then we need to check
            // if then number of characters in the interrupt buffer
            // exceeds the XoffLimit.  If it does then we don't
            // enable RTS AND we set the RXHolding to record that
            // we are holding because of the rts.
            //

            if ((Extension->BufferSize - New.XoffLimit) >
                Extension->CharsInInterruptBuffer) {

⌨️ 快捷键说明

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