findecp.c
来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· C语言 代码 · 共 380 行
C
380 行
/*++
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:
FINDECP.C
Abstract:
ECP hardware detection functions
Notes:
--*/
#include <windows.h>
#include <wdm.h>
#include "pardbg.h"
#include "1284comm.h"
#include "tmtick.h"
#include "comdef.h"
#include "ecpreg.h"
// ECP ImpID
#define ECP_IMPID_MASK 0x70 // 0111 0000
#define ECP_IS_16BIT 0x00
#define ECP_IS_8BIT 0x10
#define ECP_IS_32BIT 0x20
// ECR test mode with interrupt enabled
#define ECP_TEST_MODE_INT 0xD0 // Test Mode,dmaEn=0,serviceIntr=0
// interrupt type in CnfgA
#define ECP_ISA_LEVEL 0x80
/*
//-------------------------------------------------------------------------
// Internal routine
//-------------------------------------------------------------------------
BOOL GetFifoInfo
(
PPortInformation PortObj
)
// PURPOSE
//
// This function supports to detect the depth of FIFO and read/write service
// interrupt threshold from test mode.
//
// ASSUMPTIONS & ASSERTIONS
// A)readIntrThreshold is determined by
// 1)setting direction bit to 1.
// 2)filling empty tFifo a PWORD at a time until serviceIntr is set.
//
// B)writeIntrThreshold is determined by
// 1)starting from a full FIFO
// 2)setting direction bit to 0
// 3)emptying FIFO a PWORD at a time until serviceIntr is set.
//
// C)depth of FIFO is determined by
// 1)filling empty tFifo a PWORD at a time until full bit is set.
//
// INTERNAL STRUCTURES
//
// UNRESOLVED ISSUES
//
//---------------------------------------------------------------------------
{
WORD wCount = 0;
WORD wData = 0xFFFF;
DWORD dwData = 0xFFFFFFFF;
BYTE bData;
BYTE bStatus;
unsigned uD_reg;
unsigned uC_reg;
unsigned uE_reg;
WORD wTemp;
uC_reg = PortObj->ulBase + ECP_DCR_Reg;
uE_reg = PortObj->ulBase + ECP_ECR_Reg;
uD_reg = PortObj->ulBase + ECP_TFifo;
DEBUGMSG(ZONE_IO,(TEXT("[GetFifoInfo]: Test mode, Interrupt enabled.")));
// Initialize FIFO records
PortObj->lpFIFO.wFifoDepth = 1;
PortObj->lpFIFO.writeIntrThreshold = 0;
PortObj->lpFIFO.readIntrThreshold = 1;
// Set direction = 1
bData = (BYTE)(READ_PORT_UCHAR((PUCHAR)uC_reg) | ECP_DCR_DIRECTION_BIT_1);
WRITE_PORT_UCHAR((PUCHAR)uC_reg, bData);
// Set to test mode and enable interrupt service
// Find out the depth of FIFO and read/write thresholds
WRITE_PORT_UCHAR((PUCHAR)uE_reg, ECP_TEST_MODE_INT);
bData = 0xFF;
do
{
// Write a PWORD to tFifo register, reverse direction now
//(PortObj->lpFIFO.wFifoSize == ECP_8BIT) ? WRITE_PORT_UCHAR((PUCHAR)uD_reg, bData) :
// (PortObj->lpFIFO.wFifoSize == ECP_16BIT) ? outps(uD_reg, wData) :
// outpl(uD_reg, dwData);
WRITE_PORT_UCHAR((PUCHAR)uD_reg, bData);
wCount ++;
bStatus = READ_PORT_UCHAR((PUCHAR)uE_reg);
if ((bStatus & ECP_FIFOBITS_MASK) == ECP_FIFO_EMPTY)
return(FALSE);
bStatus &= ECP_ECR_SERVICE_INT_BIT; //0x04
} while (bStatus != ECP_ECR_SERVICE_INT_ON);
PortObj->lpFIFO.readIntrThreshold = (WORD)(wCount * PortObj->lpFIFO.wFifoSize);
#ifdef MAXDEBUG
wTemp = PortObj->lpFIFO.readIntrThreshold;
_asm { push eax }
_asm { mov ax, wTemp }
Trace_Out("Get ReadIntrTh = #AX bytes ");
_asm { pop eax }
#endif
do
{
// Write a PWORD to tFifo register, forward direction now
(PortObj->lpFIFO.wFifoSize == ECP_8BIT) ? WRITE_PORT_UCHAR((PUCHAR)uD_reg, bData) :
(PortObj->lpFIFO.wFifoSize == ECP_16BIT) ? outps(uD_reg, wData) :
outpl(uD_reg, dwData);
wCount ++;
bStatus = (BYTE)(READ_PORT_UCHAR((PUCHAR)uE_reg) & ECP_FIFOBITS_MASK);
} while (bStatus != ECP_FIFO_FULL);
PortObj->lpFIFO.wFifoDepth = wCount;
#ifdef MAXDEBUG
_asm { push eax }
_asm { mov ax, wCount }
Trace_Out("Get fifo depth = #AX PWORD ");
_asm { pop eax }
#endif
// Now we have a full FIFO could be used for detecting write threshold
// Set direction 0 and reset serviceIntr
bData = READ_PORT_UCHAR((PUCHAR)uC_reg);
WRITE_PORT_UCHAR((PUCHAR)uC_reg, (BYTE)(bData & ECP_DCR_DIRECTION_BIT_MASK));
bData = READ_PORT_UCHAR((PUCHAR)uE_reg);
WRITE_PORT_UCHAR((PUCHAR)uE_reg, (BYTE)(bData & ECP_ECR_SERVICE_INT_MASK));
do
{
// read a PWORD from FIFO
(PortObj->lpFIFO.wFifoSize == ECP_8BIT) ? (bData = READ_PORT_UCHAR((PUCHAR)uD_reg)) :
(PortObj->lpFIFO.wFifoSize == ECP_16BIT) ? (wData = inpw(uD_reg)) :
(dwData = inpd(uD_reg));
wCount --;
// Check the interrupt sesrvice bit
bData = READ_PORT_UCHAR((PUCHAR)uE_reg);
if (bData & ECP_ECR_SERVICE_INT_BIT)
break;
} while (wCount > 0);
PortObj->lpFIFO.writeIntrThreshold = (WORD)(wCount * PortObj->lpFIFO.wFifoSize);
#ifdef MAXDEBUG
wTemp = PortObj->lpFIFO.writeIntrThreshold;
_asm { push eax }
_asm { mov ax, wTemp}
Trace_Out("Get WriteIntrTh = #AX bytes ");
_asm { pop eax }
#endif
return (TRUE);
}
*/
//---------------------------------------------------------------------------
BOOL
IsHwECP
(
PPortInformation PortObj // -> PPortInformation block
)
// PURPOSE
//
// Check if host is ECP capable. (host only)
// If host is ECP capable
//
// ASSUMPTIONS & ASSERTIONS
// 1)Read DCR, bits 0 and 1 are NOT equal to 01. If we do read 01, set
// the low two bits to 10.
// 2)Write bits <7:5> of ECR to 000. (change to standard Centronic mode)
// This will clear the FIFO if ECP exists.
// 3)Read ECR, bits <1:0> are equal to 01 for checking empty FIFO.
//
// INTERNAL STRUCTURES
//
// UNRESOLVED ISSUES
//
// REUTRNS
// 1)TRUE, if success.
// 2)IE_HARDWARE, there is no ECP existing.
//
//---------------------------------------------------------------------------
{
unsigned uDCR_reg;
unsigned uECR_reg;
BYTE bData;
// Initialize the LPT Port variables
uDCR_reg = PortObj->ulBase + ECP_DCR_Reg;
uECR_reg = PortObj->ulBase + ECP_ECR_Reg;
PortObj->wHost = HOST_NO_ECP;
//
// fEcpEnable can be turned FALSE in the registry
//
if( FALSE == PortObj->fEcpEnable )
return FALSE;
// Check if DCR contains FIFO empty pattern, actually at the sense of
// nAutoFd and nStrobe lines
bData = READ_PORT_UCHAR((PUCHAR)uDCR_reg);
if ((bData & ECP_FIFOBITS_MASK) == ECP_FIFO_EMPTY)
{
bData &= ECP_HW_DETECT;
WRITE_PORT_UCHAR((PUCHAR)uDCR_reg, bData);
}
// Set ECP into standard Centronic parallel mode
// The FIFO should be cleared if ECP exists.
bData = (BYTE)(READ_PORT_UCHAR((PUCHAR)uECR_reg) & 0x1F | 0x20);
WRITE_PORT_UCHAR((PUCHAR)uECR_reg, bData);
// Check if FIFO is empty, if not empty, it's not ECP capable.
// ECR should contain ECP_PS2_MODE+1 (0x35)
if ((READ_PORT_UCHAR((PUCHAR)uECR_reg) & ECP_FIFOBITS_MASK) != ECP_FIFO_EMPTY)
return (FALSE);
PortObj->wHost = HOST_HAS_ECP;
return TRUE;
}
//---------------------------------------------------------------------------
BOOL
GetECPInfo
(
PPortInformation PortObj // -> PPortInformation block
)
// PURPOSE
//
// If host is ECP capable, its FIFO, IRQ level and DMA channel info will
// be recorded in its PortObj
//
// ASSUMPTIONS & ASSERTIONS
// 1)Write bits <7:5> of ECR to 111. (change to CNFG mode)
// 2)Read CNFG A, test bits <7:4> if equal to 0 or 1, if yes
// 3)Write bits <7:5> of ECR to 000. (change to STD mode to clear FIFO)
// 4)Write bits <7:5> of ECR to 110. (change to TEST mode)
// 5)Read ECR, bit 0 is equal to 1. (FIFO is empty)
// 6)Write one PWORD data to FIFO.
// 7)Read ECR, bit 0 is equal to 0. (FIFO is not empty)
//
// If we go here witout error, then starting to find out the depth of FIFO,
// and IRQ level and DMA channel.
//
// INTERNAL STRUCTURES
//
// UNRESOLVED ISSUES
//
// REUTRNS
// 1)TRUE, if success.
// 2)IE_HARDWARE, there is no ECP existing.
//
//---------------------------------------------------------------------------
{
unsigned uDCR_reg;
unsigned uECR_reg;
unsigned uCnfgA_reg;
BYTE bData;
BYTE bTemp;
#ifdef NSC
if (FindNSC())
InitLP();
#endif
// Initialize the LPT Port variables
uDCR_reg = PortObj->ulBase + ECP_DCR_Reg;
uECR_reg = PortObj->ulBase + ECP_ECR_Reg;
uCnfgA_reg = PortObj->ulBase + ECP_CONFG_A;
// Here, we may have a ECP hardware. Apply method B to verify again.
// Set to configuration mode to find out the size of FIFO (PWORD)
WRITE_PORT_UCHAR((PUCHAR)uECR_reg, ECP_CONFG_MODE);
bTemp = READ_PORT_UCHAR((PUCHAR)uCnfgA_reg);
bData = (BYTE)(bTemp & ECP_IMPID_MASK); //0x70
//PortObj->lpFIFO.wFifoSize = 0;
//
// [a-jsouth]: need to add lpFifo info to PortInformation
//
if (bData == ECP_IS_8BIT)
{
//PortObj->lpFIFO.wFifoSize = ECP_8BIT;
}
else if (bData == ECP_IS_16BIT)
{
//PortObj->lpFIFO.wFifoSize = ECP_16BIT;
}
else if (bData == ECP_IS_32BIT)
{
//PortObj->lpFIFO.wFifoSize = ECP_32BIT;
}
else
{
// presumably we have switched modes to something other than compat mode
// so switch back.
WRITE_PORT_UCHAR((PUCHAR)uECR_reg, ECP_STD_MODE);
return (FALSE);
}
/*
(bTemp & ECP_ISA_LEVEL) ? // 0x80
(PortObj->pPortData.dwLastError = ISA_LEVEL) : // ISA Level interrupts
(PortObj->pPortData.dwLastError= ISA_PULSE); // ISA Pulsed interrupts
(bTemp & 0x04) ?
(PortObj->lpFIFO.bInXver = FALSE) : // 0 byte in transceiver
(PortObj->lpFIFO.bInXver = TRUE); // 1 byte in transceiver
*/
/*
if (FindNSC())
PortObj->lpFIFO.bInXver = FALSE;
if (!GetFifoInfo(PortObj))
{
// presumably we have switched modes something other than compat mode
// so switch back
WRITE_PORT_UCHAR((PUCHAR)uECR_reg, ECP_STD_MODE);
return (FALSE);
}
*/
(PortObj->pPortData.dwLastError == ISA_LEVEL) ?
WRITE_PORT_UCHAR((PUCHAR)uECR_reg, ECP_STD_MODE) :
WRITE_PORT_UCHAR((PUCHAR)uECR_reg, ECP_PS2_MODE);
return (TRUE);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?