1284neg.c

来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· C语言 代码 · 共 544 行 · 第 1/2 页

C
544
字号
/*++
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.
Copyright (c) 1995-2000 Microsoft Corporation.  All rights reserved.

Module Name:

1284neg.c

Abstract:

    P1284 protocol negotiation functions

DESCRIBED IN                 IEEE-1284 Standard Signaling Method
                             for a Bi-directional Parallel Peripheral
                             Interface for Personal Computer
Notes:


--*/
#include  <windows.h>
#include  <ceddk.h>
#include  "pardbg.h"
#include  "1284comm.h"
#include  "tmtick.h"
#include  "comdef.h"
#include  "ecpreg.h"
#include  "1284neg.h"
#include  "lptio.h"

#define   PD_UNSUPPORTED 0         /* Port is not supported */

//---------------------------------------------------------------------------
// ECP negotiation signals
//---------------------------------------------------------------------------
#define PE_STATE31_MASK     0xF0
#define PE_STATE31          0xF0
#define  swapbyte(wA)   (WORD)(((wA>>8) & 0x00FF) | (wA<<8))

VOID
ReadIDString
(
    PPortInformation    PortObj
)
{
    DWORD dwBytesRead;
    WORD  wTemp = 0x0000;
    ULONG uDSR_reg;

    DEBUGMSG(ZONE_MAXIO,(TEXT("[ReadIDStringl]: entry\r\n")));

    if( PortObj->pDeviceID.pdeviceID )
        return;

    uDSR_reg = PortObj->ulBase + 1;
    // wait 35ms for nDataAvail -- begin
    if (!CheckPort(uDSR_reg, 0x08, 0x00, P1284_TL_MS)) {
         DEBUGMSG(ZONE_MAXIO,(TEXT("[ReadIDStringl]: Failed CheckPort\r\n")));
        return;
     }
    
    
    NibbleRead(PortObj->ulBase, (LPSTR)&wTemp, 2, &dwBytesRead);
    
    wTemp = swapbyte(wTemp);
    if (wTemp < 2) {
         DEBUGMSG(ZONE_MAXIO,(TEXT("[ReadIDStringl]: Unable to read length bytes\r\n")));
        return;
     }

    PortObj->pDeviceID.pdeviceID =     (LPSTR)LocalAlloc(LPTR, wTemp - 1);

    if( NULL == PortObj->pDeviceID.pdeviceID )
        return;

    memset( PortObj->pDeviceID.pdeviceID, 0, wTemp-1 );

    NibbleRead(PortObj->ulBase, PortObj->pDeviceID.pdeviceID,
               wTemp - 2, &dwBytesRead);

    
    DEBUGMSG(ZONE_MAXIO,(TEXT("[ReadIDStringl]: Length bytes=%d String=%a\r\nID="),wTemp,PortObj->pDeviceID.pdeviceID));

    PortObj->pDeviceID.ulSize = dwBytesRead;
    PortObj->pPortData.dwLastError = PortObj->pPortData.dwCommError;
    PortObj->pPortData.dwCommError = 0;
    TerminateChannel(PortObj);
    return;
}
//---------------------------------------------------------------------------
BOOL
NegotiateChannel
(
    PPortInformation  PortObj,
    BOOL              bRequestDeviceID
)
// PURPOSE
//  Attempts to start a negotiation session with an attached 1284 printer
//  on a parallel port.
//
// ASSUMPTIONS & ASSERTIONS
//  bRequestDeviceID is set to TRUE for requesting device ID string.
//  Before return, the following fields of PortObj will be set:
//  1)bRevProtocol: reverse channel capability of device
//  2)bFrdProtocol : forward channel capability of device
//  3)bCurrentMode and bCurrentPhase : record of current status of hardware
// INTERNAL STRUCTURES
//
// UNRESOLVED ISSUES
//
// RETURNS
//  1)TRUE -> success
//---------------------------------------------------------------------------
{
    BYTE        bExtensibilityByte;
    switch (PortObj->wHost)
    {
        case HOST_HAS_ECP:        //currentMode = ECP_MODE, ELPT_MODE or NIBBLE_MODE
        {
            DEBUGMSG(ZONE_IO,(TEXT("[NegotiateChannel]: ECP card exists at host.\r\n")));

            // Set up default case
            PortObj->bCurrentPhase = FORWARD_IDLE;
            PortObj->bFrdProtocol = ID_ECP;
            //PortObj->pfnWrite = (PFN)ELPT_Write;

            // Negotiate for ECP mode, suppose ECP hardware is deteced.
            /*
            // at least, host has ECP hardware here.
            bExtensibilityByte = (BYTE)((bRequestDeviceID) ? 
                        (ECP_MODE | PN_REQ_DEVID) :  //0x14
                        ECP_MODE);                   //0x10                  //0x10
            */

            if( bRequestDeviceID )
            {
                if( PD_SUCCESS == Nibble_Connect( PortObj, (NIBBLE_MODE | PN_REQ_DEVID) ) )
                {
                    ReadIDString( PortObj );
                    TerminateChannel( PortObj );                    
                }
            }

            bExtensibilityByte = ECP_MODE;

            if ( ECP_Connect( PortObj, ECP_MODE ) != PD_SUCCESS )
            {                                      

                DEBUGMSG(ZONE_IO,(TEXT("[NegotiateChannel]:Printer doesn't have ECP card, read in nibble mode\r\n")));

                /*
                //read ID string in nibble mode
                bExtensibilityByte = (BYTE)((bRequestDeviceID) ? 
                              (NIBBLE_MODE | PN_REQ_DEVID) : 
                              NIBBLE_MODE);                                  
                
                    // Nibble/ID supported
                    if (bRequestDeviceID)
                    {
                        ReadIDString(PortObj);
                    }
                */
                
                if( PD_SUCCESS != Nibble_Connect(PortObj, NIBBLE_MODE) )
                {
                    // Peripheral doesn't support, not p1284 compliance.
                    PortObj->bCurrentMode = LPT_MODE;
                    PortObj->bRevProtocol = ID_LPT;
                }                
            }
            break;
        }
        case HOST_NO_ECP:         //current mode: LPT mode or Nibble mode
        {

            DEBUGMSG(ZONE_IO,(TEXT("[NegotiateChannel]:Without ECP at host, find reverse protocol:\r\n")));

            PortObj->bCurrentPhase = FORWARD_IDLE;
            PortObj->bFrdProtocol = ID_LPT;
            PortObj->pfnWrite = (PFN)LPT_WriteFewBytes;

            bExtensibilityByte = (BYTE)((bRequestDeviceID) ? 
                          (NIBBLE_MODE | PN_REQ_DEVID) : 
                          NIBBLE_MODE);

            if (PD_SUCCESS == Nibble_Connect(PortObj, bExtensibilityByte))
            {
                if (bRequestDeviceID)
                {
                    DEBUGMSG(ZONE_IO, (TEXT("nibble Connect : Reading ID String.\r\n")));
                    ReadIDString(PortObj);
                }
            }
            else
            {
                DEBUGMSG(ZONE_IO, (TEXT("nibble Connect Fail.\r\n")));

                PortObj->bCurrentMode = LPT_MODE;
                PortObj->bRevProtocol = ID_LPT;
            }  //nibble mode not supported
            break;
        }
    }
    return (TRUE);
}

//---------------------------------------------------------------------------
VOID
TerminateChannel
(
    PPortInformation     PortObj        // -> PortInformation block
)
// PURPOSE
//  Terminate a P1284 mode protocol and return to compatibility mode.
//  Only the PortObj->bCurrentPhase and PortObj->bCurrentMode will be changed.
//
// ASSUMPTIONS & ASSERTIONS
//  1)If the current status is in ECP reverse mode, negotiate channel from
//    reverse to forward before termination.
//  2)If any step during termination fails, drive control port to state 22
//    (0xEC) to abort, returns TRUE.
//
// INTERNAL STRUCTURES
//
// UNRESOLVED ISSUES
//
// RETURNS
//  1)TRUE -> success
//  2)FALSE -> I/O pending
//---------------------------------------------------------------------------
{
   ULONG        uECR_reg;
   ULONG        uDCR_reg;

   // not necessary to terminate if channel is in Compatibility mode already
    if (PortObj->bCurrentMode == LPT_MODE)
        return;
        
    // Initialize the Port variables
    uECR_reg = PortObj->ulBase + ECP_ECR_Reg;
    uDCR_reg = PortObj->ulBase + ECP_DCR_Reg;
  
    // #4620 Canon BJC-600e, touch control register will cause printer to flush buffer.
    if (PortObj->bCurrentMode == ELPT_MODE)
    { 
        WRITE_PORT_UCHAR((PUCHAR)uECR_reg, ECP_STD_MODE);
//        WRITE_PORT_UCHAR((PUCHAR)uDCR_reg, (BYTE)(inpb(uDCR_reg) & ECP_DCR_DIRECTION_BIT_MASK));
        return;
    }

    // Before returning, we will terminate the requested
    // mode and return to compatibility mode.
    if (PortObj->bCurrentMode & ECP_MODE)
    {
       // check the current phase
        if (PortObj->bCurrentPhase & REVERSE_MASK)
        {
            Reverse2Forward(PortObj);
            WRITE_PORT_UCHAR((PUCHAR)uDCR_reg, (BYTE)(READ_PORT_UCHAR((PUCHAR)uDCR_reg) & ECP_DCR_DIRECTION_BIT_MASK));
        }
        else
            WRITE_PORT_UCHAR((PUCHAR)uECR_reg, ECP_PS2_MODE);
    }        // fall through
   
    if ((PortObj->dwDevId != PN_REQ_DEVID) && 
        (PortObj->bCurrentMode == NIBBLE_MODE))
    {
        // Terminiate Nibble mode (w/o device id)
        P1284Terminate(PortObj->ulBase, TRUE);
    }    

⌨️ 快捷键说明

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