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 + -
显示快捷键?