hp400.c

来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· C语言 代码 · 共 468 行

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

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

#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

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

#define WriteDCR(port_addr, value) \
     WRITE_PORT_UCHAR((PUCHAR)port_addr+DCR_OFFSET,value)

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

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

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

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

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


#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))
    {
        RETAILMSG(1,(TEXT("Fwd_to_Rev_Trans() fail\r\n")));
          return 0;
    }

     if (!Read_1284_Port(port_base,&buffer[0]))
    {
        RETAILMSG(1,(TEXT("Read_1284_Port()fail\r\n")));
          return 0;
    }

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

    //RETAILMSG(1,(TEXT("Rev_to_Fwd_Trans(port _ base );\r\n")));
     Rev_to_Fwd_Trans(port_base);

     Exit_1284_ECP_Mode(port_base);  

     return(i);

}

⌨️ 快捷键说明

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