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

📄 hp400.c

📁 WinCE 3.0 BSP, 包含Inter SA1110, Intel_815E, Advantech_PCM9574 等
💻 C
字号:
// Notes:
//
// _inp and _outp are input/output routines to write the
// registers controlling the parallel interface.  Replace
// these with the correct opertaions for the target system.
// Also, the port_base and offset values are specific to the
// PC, these may need to be altered as well.

// The data returned by the printer is as follows:
//
// byte 0: number of status byte (should be 6 for the 400)
//         the count includes this byte
// byte 1: printer error states
//		 0x00 - no error
//         0x01 - out of paper
//         0x02 - jammed
//         0x04 - stalled
//         0x08 - pen out
//         0x10 - aging
// byte 2: printer mode
//         0x01 - busy
//         0x02 - drying
//         0x04 - ASF
// byte 3: pen ID
//         0x00 - no pen
//         0x01 - black pen
//         0x10 - color pen
// byte 4: MSB of mech position
// byte 5: LSB of mech position
#include <windows.h>
#include <types.h>
#include <ceddk.h>
#include	"pardbg.h"
#include "cc.h"

#define DATA_OFFSET			0
#define DSR_OFFSET			1
#define DCR_OFFSET			2

/****************************************************************************
 * Modification done by Maneesh Gupta
 *
 * ECR Offsets have been modified for ASPEN/BIGSUR
 ****************************************************************************/
#define ECR_OFFSET			0x402
/****************************************************************************
 * End of Modification done by Maneesh Gupta
 ****************************************************************************/

#define ECR_COMPATIBLITY_MODE	0x14
#define ECR_PS2					0x34		// allows us to read the data lines

#define	CHANNEL_ADDRESS	0x80

// DCR - Compatibility Mode

#define	DCR_RESERVED			0xC0		// upper 2 bits are reserved
#define	N_DIRECTION_OUT		0x20		// 0 = Data register outputs to printer
#define	ENABLE_INTERRUPT		0x10
#define	N_SELECT_IN			0x08
#define	N_INIT				0x04
#define	N_AUTO_FD				0x02
#define	N_STROBE				0x01

// DCR - ECP Mode

#define	ACTIVE_1284		N_SELECT_IN
#define 	HOST_BUSY			N_AUTO_FD
#define 	HOST_CLK			N_STROBE
#define 	N_REVERSE_REQUEST	N_INIT
#define 	HOST_ACK			N_AUTO_FD

// DSR - Compatibility Mode
//	Note:
//		Bits 2-0 are undefined.  Some parallel ports return 0, 
//      some 1.  Make sure to always mask these bits before 
//      comparing the DSR to something.

#define 	BUSY				0x80
#define 	N_ACK			0x40
#define 	P_ERROR			0x20
#define 	SELECT			0x10
#define 	N_FAULT			0x08

// DSR - ECP Mode

#define 	PERIPH_ACK		BUSY
#define 	PERIPH_CLK		N_ACK
#define 	N_ACK_REVERSE		P_ERROR
#define	N_PERIPH_REQUEST	N_FAULT

// DCR_INVERT_MASK: cable<->register translation of DCR signal 
// values, identifies register signals that are inverted with 
// respect to the external cable value.
#define		DCR_INVERT_MASK		(N_SELECT_IN | N_AUTO_FD | N_STROBE)
#define		DCR_MASK			(N_SELECT_IN | N_INIT | N_AUTO_FD | N_STROBE)
// The IBM PS/2 H/W Tech. Ref. says we must clear the reserved
// bits. We need to clear nDirectionOut so data register 
// outputs are enabled. We want to disable the interrupts, 
// since we don't use them
#define		DCR_CLEAR			(DCR_RESERVED | N_DIRECTION_OUT | ENABLE_INTERRUPT)

// DSR_INVERT_MASK: cable<->register translation of DSR signal
// values, identifies register signals that are inverted with 
// respect to the external cable value.
#define 	DSR_INVERT_MASK		BUSY
#define 	DSR_MASK			(BUSY | N_ACK | P_ERROR | SELECT | N_FAULT)


#define IsSet(setMask) (setMask)
#define IsClear(clrMask) (clrMask)
#define DONT_CARE 0

/****************************************************************************
 * Modification done by Maneesh Gupta
 *
 * Multiplier used to access the printer registers.
 ****************************************************************************/
extern unsigned dwPrinterRegMultiplier;
/****************************************************************************
 * End of Modification done by Maneesh Gupta
 ****************************************************************************/

// Somtimes Delay is defined in the header files too, that leads to compiler 
// warning
#ifdef Delay
#	undef Delay
#endif Delay
#define Delay(time) \
	Sleep(time)

#define BitTest(byStatus, setMask, clrMask) \
	((unsigned char)((byStatus) & (unsigned char)((setMask) | (clrMask))) == \
	(unsigned char)(((setMask) & (~(clrMask)))))

#define Raise(input_value, target_mask, invert_mask) \
	(((input_value) & ~((target_mask) & (invert_mask))) | \
	((target_mask) & ~(invert_mask)))

#define Lower(input_value, target_mask, invert_mask) \
	(((input_value) & ~((target_mask) & ~(invert_mask))) | \
	((target_mask) & (invert_mask)))

#define RaiseDCR(byDCRValue, byTargetMask) \
	Raise(byDCRValue, byTargetMask, DCR_INVERT_MASK)

#define LowerDCR(byDCRValue, byTargetMask) \
	Lower(byDCRValue, byTargetMask, DCR_INVERT_MASK)

/****************************************************************************
 * Modification done by Maneesh Gupta
 *
 * Modified Register access address for different platform with the help of
 * dwPrinterRegMultiplier
 ****************************************************************************/
#define WriteDCR(port_addr, value) \
	WRITE_PORT_UCHAR((PUCHAR)port_addr+ (DCR_OFFSET * dwPrinterRegMultiplier),value)

#define ReadDSR(port_addr) \
	(unsigned char) READ_PORT_UCHAR((PUCHAR)port_addr+ (DSR_OFFSET * dwPrinterRegMultiplier))

#define ReadDCR(port_addr) \
	(unsigned char) READ_PORT_UCHAR((PUCHAR)port_addr+ (DCR_OFFSET * dwPrinterRegMultiplier))

#define WriteData(port_addr, value) \
	WRITE_PORT_UCHAR((PUCHAR)port_addr+ (DATA_OFFSET * dwPrinterRegMultiplier) ,value)

#define ReadData(port_addr) \
	(unsigned char) READ_PORT_UCHAR((PUCHAR)port_addr+ (DATA_OFFSET * dwPrinterRegMultiplier))

#define WriteECR(port_addr, value) \
	WRITE_PORT_UCHAR((PUCHAR)port_addr+ (ECR_OFFSET * dwPrinterRegMultiplier ),value)

/****************************************************************************
 * End of Modification done by Maneesh Gupta
 ****************************************************************************/

#define BitTestDSR(byDSRValue, bySetMask, byClrMask) \
	BitTest(((byDSRValue) ^ DSR_INVERT_MASK), (bySetMask), (byClrMask))

#define EncodeNibble(byDSRValue, byNibbleValue) \
	(((((byDSRValue & ~NIBBLE_HI_BIT) | ((byNibbleValue << 4) & NIBBLE_HI_BIT)) \
	& ~NIBBLE_LO_BITS) | ((byNibbleValue << 3) & NIBBLE_LO_BITS)) \
	^ DSR_INVERT_MASK)

#define ExtractNibble(byDSRValue) \
	(((((byDSRValue) ^ DSR_INVERT_MASK) & NIBBLE_HI_BIT)  >> 4) | \
	 ((((byDSRValue) ^ DSR_INVERT_MASK) & NIBBLE_LO_BITS) >> 3))


BOOL WaitForPrinter(unsigned long port_base, unsigned char SetMask, 
					unsigned char ClearMask)
{
	unsigned char		byDSR;
	int				i=1000;
	
	while (i>0)
	{
		byDSR = ReadDSR(port_base);
		if (!BitTestDSR(byDSR, SetMask, ClearMask))
			Delay(1);
		else
			return TRUE;
		i--;
	}

	return FALSE;
}

BOOL Enter_1284_ECP_Mode(unsigned long port_base)
{
	unsigned char byDCRData;
	BOOL ret_val;

	byDCRData = ReadDCR(port_base);
	
	// reinitialize the interface
	// note: if you reinitialize the interface the
	// printer will not return correct pen ID information
	// until it finishes resetting.  It seems to be OK
	// to skip these steps


	byDCRData = LowerDCR(byDCRData, N_INIT | 
					N_SELECT_IN | N_DIRECTION_OUT);
	WriteDCR(port_base, byDCRData);
	Delay(5);
	byDCRData = RaiseDCR(byDCRData, N_INIT | N_SELECT_IN);
	WriteDCR(port_base, byDCRData);
	Delay(5);

	
	// Set DCR to compatibility mode.					 
	// (ECP event -1)
	// *HostAck/*HostClk high, *1284Active low.  
	// Also *nInit high, as per 
	// the definition of nInit in the 1284 spec 
	// (Section 4.9 "Negotiation phase: set high").  
	
	byDCRData = RaiseDCR (byDCRData, HOST_ACK | 
					HOST_CLK | N_INIT);
	byDCRData = LowerDCR (byDCRData, ACTIVE_1284);
	WriteDCR(port_base, byDCRData);

	Delay(5000);


	// (ECP event 0)
	// Place ECP extensibility request value (0x10)
	// on the data lines.  See IEEE-1284 Table 4.      							  				  
	
	WriteData(port_base, 0x10);

	Delay(1);			// Delay for at least 1 us.
	
	// Enter negotiation: Is peripheral 1284 compliant?	 
	// (ECP event 1)
	// *1284Active high, *HostBusy low.

	byDCRData = RaiseDCR(byDCRData, ACTIVE_1284);
	byDCRData = LowerDCR(byDCRData, HOST_ACK);
	WriteDCR(port_base, byDCRData);


	// Await 1284-compliant reply			  
	// (ECP event 2)
	// (*PError/*nFault/Select high, nAck low)

	ret_val = WaitForPrinter(port_base, 
		P_ERROR | N_FAULT | SELECT, N_ACK);

	if (ret_val == FALSE)
	{
		DEBUGMSG(ZONE_IO,(TEXT("Event 2 failed\n")));
		return FALSE;
	}
	
	// Strobe extensibility req to peripheral.			  
	// (ECP event 2)
	// *HostClk low.	
	
	byDCRData = LowerDCR(byDCRData, HOST_CLK);
	WriteDCR(port_base, byDCRData);

	// *HostClk/*HostBusy high.							  
	// (ECP event 4)
	
	Delay(1);			// Delay for at least 1 us.


	byDCRData = RaiseDCR(byDCRData, HOST_ACK | HOST_CLK);

	WriteDCR(port_base, byDCRData);


	// Await 1284-compliant reply			  
	// (ECP event 5 and 6)
	// (Select/Nack high, P_error/Busy low)

	ret_val = WaitForPrinter(port_base, 
					SELECT | N_ACK, P_ERROR | BUSY);

	if (ret_val == FALSE)
	{
		DEBUGMSG(ZONE_IO,(TEXT("Event 5&6 failed\n")));
		return(FALSE);
	}

	Delay(1);

	// Drop HOST_ACK (ECP event 30)
	byDCRData = LowerDCR(byDCRData,HOST_ACK);
	WriteDCR(port_base, byDCRData);

	//DEBUGMSG(ZONE_IO,(TEXT("droped HOST_ACK, event 30\n")));

	ret_val = WaitForPrinter(port_base, P_ERROR, DONT_CARE);

	if (ret_val == FALSE)
		return FALSE;

	return TRUE;
	
}

BOOL Change_ECP_Channel(unsigned long port_base,int channel)
{
	unsigned char byDCRData;
	BOOL ret_val;

	ret_val = WaitForPrinter(port_base, DONT_CARE, BUSY);
	if (ret_val == FALSE)
		return FALSE;

	// Set HOST_ACK low to indicate ECP mode command
	byDCRData = ReadDCR(port_base);
	byDCRData = LowerDCR(byDCRData,HOST_ACK);
	WriteDCR(port_base,byDCRData);

	// Put the data on the bus (ECP event 34)
	WriteData(port_base, (UCHAR)(CHANNEL_ADDRESS | channel));

	// Set N_STROBE low to send data (ECP event 35)
	byDCRData = LowerDCR(byDCRData,N_STROBE);
	WriteDCR(port_base,byDCRData);

	//DEBUGMSG(ZONE_IO,(TEXT("set N_STROBE low, ECP event 35\n")));

	// Wait for Busy to go high (ECP event 36)
	ret_val = WaitForPrinter(port_base, BUSY, DONT_CARE);

	if (ret_val == FALSE)
		return FALSE;

	// Set N_STROBE high (ECP Event 37)
	Delay(1);
	byDCRData = RaiseDCR(byDCRData,N_STROBE);
	WriteDCR(port_base,byDCRData);

	// Wait for Busy to go low (ECP event 38)
	ret_val = WaitForPrinter(port_base, DONT_CARE, BUSY);

	if (ret_val == FALSE)
		return FALSE;

	return TRUE;
}

BOOL Fwd_to_Rev_Trans(unsigned long port_base)
{
	unsigned char byDCRData;
	BOOL ret_val;

	WriteECR(port_base,ECR_PS2);

	byDCRData = ReadDCR(port_base);
	byDCRData = RaiseDCR(byDCRData,N_DIRECTION_OUT);
	WriteDCR(port_base,byDCRData);

	byDCRData = LowerDCR(byDCRData,HOST_ACK);
	WriteDCR(port_base,byDCRData);

	Delay(1);	// wait for setup time

	byDCRData = LowerDCR(byDCRData,N_INIT);
	WriteDCR(port_base,byDCRData);

	ret_val = WaitForPrinter(port_base, DONT_CARE, P_ERROR);
	if (ret_val == FALSE)
		return FALSE;
	else
		return TRUE;

}

void Rev_to_Fwd_Trans(unsigned long port_base)
{
	unsigned char byDCRData;
	BOOL ret_val;

	byDCRData = ReadDCR(port_base);
	byDCRData = RaiseDCR(byDCRData,N_INIT);
	WriteDCR(port_base,byDCRData);

	ret_val = WaitForPrinter(port_base, N_ACK, DONT_CARE);
	if (ret_val == FALSE)
		DEBUGMSG(ZONE_IO,(TEXT("ERROR: printer didn't raise N_ACK, event 48!\n")));

	ret_val = WaitForPrinter(port_base, P_ERROR, DONT_CARE);
	if (ret_val == FALSE)
		DEBUGMSG(ZONE_IO,(TEXT("ERROR: printer didn't raise P_ERROR, event 49!\n")));

	WriteECR(port_base,ECR_COMPATIBLITY_MODE);
}

BOOL Read_1284_Port(unsigned long port_base, 
					unsigned char * data_byte)
{
	unsigned char byDCRData;
	BOOL ret_val;

	byDCRData = ReadDCR(port_base);
	
	ret_val = WaitForPrinter(port_base, DONT_CARE, N_ACK);
	if (ret_val == FALSE)
		return FALSE;

	byDCRData = RaiseDCR(byDCRData,HOST_ACK);
	WriteDCR(port_base,byDCRData);

	ret_val = WaitForPrinter(port_base,N_ACK, DONT_CARE);
	if (ret_val == FALSE)
		return FALSE;


	*data_byte = ReadData(port_base);

	byDCRData = LowerDCR(byDCRData,HOST_ACK);
	WriteDCR(port_base,byDCRData);

	return TRUE;
}

void Exit_1284_ECP_Mode(unsigned long port_base)
{
	unsigned char byDCRData;

	byDCRData = ReadDCR(port_base);
	byDCRData = LowerDCR(byDCRData,N_SELECT_IN);
	byDCRData = RaiseDCR(byDCRData,HOST_ACK);
	WriteDCR(port_base,byDCRData);

	byDCRData = LowerDCR(byDCRData,HOST_ACK);
	WriteDCR(port_base,byDCRData);

	byDCRData = RaiseDCR(byDCRData,HOST_ACK);
	WriteDCR(port_base,byDCRData);
}

int Get_DJ400_Dev_Status(unsigned long port_base,
						 unsigned char *buffer)

{

	int i;

	WriteECR(port_base,ECR_COMPATIBLITY_MODE);

	DEBUGMSG(ZONE_IO,(TEXT("calling Enter_1284_ECP_Mode()\n")));
	if (!Enter_1284_ECP_Mode(port_base))
		return 0;
	DEBUGMSG(ZONE_IO,(TEXT("calling Change_ECP_Channel()\n")));
	if (!Change_ECP_Channel(port_base,32))
		return 0;
	DEBUGMSG(ZONE_IO,(TEXT("calling Fwd_to_Rev_Trans()\n")));
	if (!Fwd_to_Rev_Trans(port_base))
		return 0;

	if (!Read_1284_Port(port_base,&buffer[0]))
		return 0;

	for (i=1;i<buffer[0];i++)
	{
		if (!Read_1284_Port(port_base,&buffer[i]))
			break;
	}

	Rev_to_Fwd_Trans(port_base);

	Exit_1284_ECP_Mode(port_base);

	return(i);

}

⌨️ 快捷键说明

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