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

📄 1284neg.c

📁 WinCE 3.0 BSP, 包含Inter SA1110, Intel_815E, Advantech_PCM9574 等
💻 C
字号:
/*++
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-1998  Microsoft Corporation

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))

// Multiplier used to access the printer registers.
extern unsigned dwPrinterRegMultiplier;

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

    DEBUGMSG(ZONE_MAXIO,(TEXT("[ReadIDStringl]: entry\r\n")));
    uDSR_reg = PortObj->ulBase + 1 * dwPrinterRegMultiplier;
    // fix for TI printer, wait 35ms for nDataAvail -- begin
    if (!CheckPort(uDSR_reg, 0x08, 0x00, P1284_TL_MS)) {
         DEBUGMSG(ZONE_MAXIO,(TEXT("[ReadIDStringl]: Failed CheckPort\r\n")));
        return;
     }
    // fix for TI printer -- end
    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;
     }
	if (PortObj->pDeviceID.pdeviceID) {
		LocalFree(PortObj->pDeviceID.pdeviceID);
		PortObj->pDeviceID.pdeviceID=NULL;
	}

    PortObj->pDeviceID.pdeviceID =     (LPSTR)LocalAlloc(LPTR, wTemp-1 );
	if (PortObj->pDeviceID.pdeviceID) {
		dwBytesRead=0;
		NibbleRead(PortObj->ulBase, PortObj->pDeviceID.pdeviceID,
			wTemp - 2, &dwBytesRead);
		if (dwBytesRead>=(DWORD)wTemp - 2)
			dwBytesRead=wTemp - 2;
		PortObj->pDeviceID.pdeviceID[dwBytesRead]='\0';

		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_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)
                {
                    ReadIDString(PortObj);
                }
            }
            else
            {
                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
//---------------------------------------------------------------------------
{

    DEBUGMSG(ZONE_MAXIO,(TEXT("[TerminateChannel]: entry\r\n")));
    // not necessary to terminate if channel is in Compatibility mode already
    if (PortObj->bCurrentMode == LPT_MODE)
        return;

    if ((PortObj->dwDevId != PN_REQ_DEVID) &&
        (PortObj->bCurrentMode == NIBBLE_MODE))
    {
        // Terminiate Nibble mode (w/o device id)
        P1284Terminate(PortObj->ulBase, TRUE);
    }
    else
    {
        // All other modes.
        P1284Terminate(PortObj->ulBase, FALSE);
    }

    PortObj->bCurrentMode = LPT_MODE;
    PortObj->bCurrentPhase = FORWARD_IDLE;
    PortObj->dwDevId = 0;
    PortObj->pPortData.dwLastError = PortObj->pPortData.dwCommError;
    PortObj->pPortData.dwCommError = 0;
    return;
}
//---------------------------------------------------------------------------
DWORD
Nibble_Connect
(
    PPortInformation  PortObj,
    BYTE              bExtenByte
)
// PURPOSE
//  Negotiate channel to nibble mode.  Stay at reverse idle phase to return.
//
// ASSUMPTIONS & ASSERTIONS
//  1) This code ASSUMES a ISA parallel port implementation.
//  2) current mode and phase are lpt/elpt mode, forward idle phase.
//
// INTERNAL STRUCTURES
//
// UNRESOLVED ISSUES
//
// RETURNS
//  1)PD_SUCCESS -> success
//  2)PD_NOTP1284
//  3)PD_UNSUPPORTED
//---------------------------------------------------------------------------
{
    DWORD dwError;
    ULONG uDCR_reg;
    ULONG uDSR_reg;

    DEBUGMSG(ZONE_IO,(TEXT("[Nibble_Connect]: entry\r\n")));
    if (bExtenByte & PN_REQ_DEVID)
    {
        // We'll use this flag to determine the correct
        // method for terminating from nibble mode.
        PortObj->dwDevId = PN_REQ_DEVID;
    }

    if ((dwError = P1284Negotiate(PortObj->ulBase, bExtenByte)) != PD_SUCCESS)
    {
        PortObj->pPortData.dwLastError = PortObj->pPortData.dwCommError;
        PortObj->pPortData.dwCommError = CE_MODE;
        return (dwError);
    }

    DEBUGMSG(ZONE_IO,(TEXT("[Nibble_Connect]: Successfully negotiated into Nibble mode.\r\n")));

    // Set the port status to reflect successful revese negotiation
    PortObj->bCurrentMode = NIBBLE_MODE;
    PortObj->bCurrentPhase = NB_REVERSE_IDLE;   // Go into REV_IDLE state.
    PortObj->bRevProtocol = ID_NIBBLE;

    uDSR_reg = PortObj->ulBase + 1 * dwPrinterRegMultiplier;
    if (!ChecknFault(uDSR_reg))
    {
        DEBUGMSG(ZONE_IO,(TEXT("[Nibble_Connect] data available.\r\n")));
        PortObj->bCurrentPhase = NB_DATA_AVAILABLE;
    }
    else
    {
        DEBUGMSG(ZONE_IO,(TEXT("[Nibble_Connect] data not available.\r\n")));
        //switch to reverse idle mode, drop HostBusy low to wait for interrupt
        uDCR_reg = PortObj->ulBase + 2 * dwPrinterRegMultiplier;
        //be carefule for PS/2 Type3 machine, avoid to touch AutoStrobe (b7)
        WRITE_PORT_UCHAR((PUCHAR)uDCR_reg,(BYTE)(READ_PORT_UCHAR((PUCHAR)uDCR_reg) | NAUTOFD_LOW));
        WRITE_PORT_UCHAR((PUCHAR)uDCR_reg,(BYTE)(READ_PORT_UCHAR((PUCHAR)uDCR_reg) | NAUTOFD_LOW));
        PortObj->bCurrentPhase = NB_REVERSE_IDLE;
    }
    PortObj->pPortData.dwLastError = PortObj->pPortData.dwCommError;
    PortObj->pPortData.dwCommError = 0;
    return (PD_SUCCESS);
}

⌨️ 快捷键说明

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