title: how to read status registers of a printer in qnx
body: <p>i am using an x86 processor.
  the interface used to connect to the printer is a usb parallel port ieee1284.</p>
  
  <p>i can send data to the printer no problem.
  i have tested it with the following command.</p>
  
  <pre><code>cat file.txt &gt; /dev/usbpar0
  </code></pre>
  
  <p>i have read on several forums that there is no base address for a usb parallel port.
  what would be the easiest way of reading the status of the printer. 
  I need to know if it is out of paper or there is a paper jam. that is why i need to read the status registers.</p>
  
  <p>I have included the source code i have tried to copy from [here][1]</p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;iomanip&gt;
  
  #include &lt;errno.h&gt;   /* Error number definitions */
  #include &lt;termios.h&gt; /* POSIX terminal control definitions */
  
  #include "stdlib.h"
  #include "unistd.h"
  #include "sys/io.h"
  
  #include &lt;hw/inout.h&gt;
  #include &lt;stdint.h&gt;
  #include &lt;sys/mman.h&gt;
  
  #include &lt;stdio.h&gt;
  #include &lt;fcntl.h&gt;      /* open() */
  #include &lt;sys/types.h&gt;      /* open() */
  #include &lt;sys/stat.h&gt;       /* open() */
  #include &lt;sys/ioctl.h&gt;
  #include "parport.h"
  #include "ppdev.h"
  
  #define DEVICE "/dev/usbpar0"
  
  int write_data(int fd, unsigned char data);
  int status_pins(int fd);
  
  using namespace std;
  
  int main(int argc, char **argv)
  {
      struct ppdev_frob_struct frob;
      int fd;
      int mode;
  
      if((fd=open(DEVICE, O_RDWR)) &lt; 0) {
          fprintf(stderr, "can not open %s\n", DEVICE);
          return 10;
      }
  
      ThreadCtl(_NTO_TCTL_IO, 0);
  status_pins(fd);
      close(fd);
  
      return 0;
  }
  
  /* trivial example how to write data */
  int write_data(int fd, unsigned char data)
  {
      return(ioctl(fd, PPWDATA, &amp;data));
  }
  
  /* example how to read 8 bit from the data lines */
  int read_data(int fd)
  {
      int mode, res;
      unsigned char data;
  
      mode = IEEE1284_MODE_ECP;
      res=ioctl(fd, PPSETMODE, &amp;mode);    /* ready to read ? */
      mode=255;
      res=ioctl(fd, PPDATADIR, &amp;mode);    /* switch output driver off */
      printf("ready to read data !\n");
      fflush(stdout);
      sleep(10);
      res=ioctl(fd, PPRDATA, &amp;data);  /* now fetch the data! */
      printf("data=%02x\n", data);
      fflush(stdout);
      sleep(10);
      data=0;
      res=ioctl(fd, PPDATADIR, data);
      return 0;
  }
  
  /* example how to read the status lines. */
  int status_pins(int fd)
  {
      int val;
  
      ioctl(fd, PPRSTATUS, &amp;val);
      val^=PARPORT_STATUS_BUSY; /* /BUSY needs to get inverted */
  
      printf("BUSY  = %s\n",
          ((val &amp; PARPORT_STATUS_BUSY)==PARPORT_STATUS_BUSY)?"HI":"LO");
      printf("ERROR  = %s\n",
          ((val &amp; PARPORT_STATUS_ERROR)==PARPORT_STATUS_ERROR)?"HI":"LO");
      printf("SELECT = %s\n",
          ((val &amp; PARPORT_STATUS_SELECT)==PARPORT_STATUS_SELECT)?"HI":"LO");
      printf("PAPEROUT = %s\n",
          ((val &amp; PARPORT_STATUS_PAPEROUT)==PARPORT_STATUS_PAPEROUT)?"HI":"LO");
      printf("ACK = %s\n",
          ((val &amp; PARPORT_STATUS_ACK)==PARPORT_STATUS_ACK)?"HI":"LO");
      return 0;
  }
  
  /* example how to use frob ... toggle STROBE on and off without messing
     around the other lines */
  int strobe_blink(int fd)
  {
      struct ppdev_frob_struct frob;
  
      frob.mask = PARPORT_CONTROL_STROBE; /* change only this pin ! */
      while(1) {
          frob.val = PARPORT_CONTROL_STROBE;  /* set STROBE ... */
          ioctl(fd, PPFCONTROL, &amp;frob);
          usleep(500);
          frob.val = 0;               /* and clear again */
          ioctl(fd, PPFCONTROL, &amp;frob);
          usleep(500);
      }
  }
  </code></pre>
  
  <p>"parport.h"</p>
  
  <pre><code>    /* $Id: parport.h,v 1.1 1998/05/17 10:57:52 andrea Exp andrea $ */
  
      /*
       * Any part of this program may be used in documents licensed under
       * the GNU Free Documentation License, Version 1.1 or any later version
       * published by the Free Software Foundation.
       */
  
      #ifndef _PARPORT_H_
      #define _PARPORT_H_
  
      /* Start off with user-visible constants */
  
      /* Maximum of 16 ports per machine */
      #define PARPORT_MAX  16
  
      /* Magic numbers */
      #define PARPORT_IRQ_NONE  -1
      #define PARPORT_DMA_NONE  -1
      #define PARPORT_IRQ_AUTO  -2
      #define PARPORT_DMA_AUTO  -2
      #define PARPORT_DMA_NOFIFO -3
      #define PARPORT_DISABLE   -2
      #define PARPORT_IRQ_PROBEONLY -3
      #define PARPORT_IOHI_AUTO -1
  
      #define PARPORT_CONTROL_STROBE    0x1
      #define PARPORT_CONTROL_AUTOFD    0x2
      #define PARPORT_CONTROL_INIT      0x4
      #define PARPORT_CONTROL_SELECT    0x8
  
      #define PARPORT_STATUS_ERROR      0x8
      #define PARPORT_STATUS_SELECT     0x10
      #define PARPORT_STATUS_PAPEROUT   0x20
      #define PARPORT_STATUS_ACK        0x40
      #define PARPORT_STATUS_BUSY       0x80
  
      /* Type classes for Plug-and-Play probe.  */
      typedef enum {
          PARPORT_CLASS_LEGACY = 0,       /* Non-IEEE1284 device */
          PARPORT_CLASS_PRINTER,
          PARPORT_CLASS_MODEM,
          PARPORT_CLASS_NET,
          PARPORT_CLASS_HDC,              /* Hard disk controller */
          PARPORT_CLASS_PCMCIA,
          PARPORT_CLASS_MEDIA,            /* Multimedia device */
          PARPORT_CLASS_FDC,              /* Floppy disk controller */
          PARPORT_CLASS_PORTS,
          PARPORT_CLASS_SCANNER,
          PARPORT_CLASS_DIGCAM,
          PARPORT_CLASS_OTHER,            /* Anything else */
          PARPORT_CLASS_UNSPEC,           /* No CLS field in ID */
          PARPORT_CLASS_SCSIADAPTER
      } parport_device_class;
  
      /* The "modes" entry in parport is a bit field representing the
         capabilities of the hardware. */
      #define PARPORT_MODE_PCSPP  (1&lt;&lt;0) /* IBM PC registers available. */
      #define PARPORT_MODE_TRISTATE   (1&lt;&lt;1) /* Can tristate. */
      #define PARPORT_MODE_EPP    (1&lt;&lt;2) /* Hardware EPP. */
      #define PARPORT_MODE_ECP    (1&lt;&lt;3) /* Hardware ECP. */
      #define PARPORT_MODE_COMPAT (1&lt;&lt;4) /* Hardware 'printer protocol'. */
      #define PARPORT_MODE_DMA    (1&lt;&lt;5) /* Hardware can DMA. */
      #define PARPORT_MODE_SAFEININT  (1&lt;&lt;6) /* SPP registers accessible in IRQ. */
  
      /* IEEE1284 modes:
         Nibble mode, byte mode, ECP, ECPRLE and EPP are their own
         'extensibility request' values.  Others are special.
         'Real' ECP modes must have the IEEE1284_MODE_ECP bit set.  */
      #define IEEE1284_MODE_NIBBLE             0
      #define IEEE1284_MODE_BYTE              (1&lt;&lt;0)
      #define IEEE1284_MODE_COMPAT            (1&lt;&lt;8)
      #define IEEE1284_MODE_BECP              (1&lt;&lt;9) /* Bounded ECP mode */
      #define IEEE1284_MODE_ECP               (1&lt;&lt;4)
      #define IEEE1284_MODE_ECPRLE            (IEEE1284_MODE_ECP | (1&lt;&lt;5))
      #define IEEE1284_MODE_ECPSWE            (1&lt;&lt;10) /* Software-emulated */
      #define IEEE1284_MODE_EPP               (1&lt;&lt;6)
      #define IEEE1284_MODE_EPPSL             (1&lt;&lt;11) /* EPP 1.7 */
      #define IEEE1284_MODE_EPPSWE            (1&lt;&lt;12) /* Software-emulated */
      #define IEEE1284_DEVICEID               (1&lt;&lt;2)  /* This is a flag */
      #define IEEE1284_EXT_LINK               (1&lt;&lt;14) /* This flag causes the
                               * extensibility link to
                               * be requested, using
                               * bits 0-6. */
  
      /* For the benefit of parport_read/write, you can use these with
       * parport_negotiate to use address operations.  They have no effect
       * other than to make parport_read/write use address transfers. */
      #define IEEE1284_ADDR           (1&lt;&lt;13) /* This is a flag */
      #define IEEE1284_DATA            0  /* So is this */
  
      /* Flags for block transfer operations. */
      #define PARPORT_EPP_FAST        (1&lt;&lt;0) /* Unreliable counts. */
      #define PARPORT_W91284PIC       (1&lt;&lt;1) /* have a Warp9 w91284pic in the device */
  
      /* The rest is for the kernel only */
      #endif /* _PARPORT_H_ */
  </code></pre>
  
  <p>"ppdev.h"</p>
  
  <pre><code>/*
   * linux/include/linux/ppdev.h
   *
   * User-space parallel port device driver (header file).
   *
   * Copyright (C) 1998-9 Tim Waugh &lt;tim@cyberelk.demon.co.uk&gt;
   *
   * This program is free software; you can redistribute it and/or
   * modify it under the terms of the GNU General Public License
   * as published by the Free Software Foundation; either version
   * 2 of the License, or (at your option) any later version.
   *
   * Added PPGETTIME/PPSETTIME, Fred Barnes, 1999
   * Added PPGETMODES/PPGETMODE/PPGETPHASE, Fred Barnes &lt;frmb2@ukc.ac.uk&gt;, 03/01/2001
   */
  
  #define PP_IOCTL    'p'
  
  /* Set mode for read/write (e.g. IEEE1284_MODE_EPP) */
  #define PPSETMODE   _IOW(PP_IOCTL, 0x80, int)
  
  /* Read status */
  #define PPRSTATUS   _IOR(PP_IOCTL, 0x81, unsigned char)
  #define PPWSTATUS   OBSOLETE__IOW(PP_IOCTL, 0x82, unsigned char)
  
  /* Read/write control */
  #define PPRCONTROL  _IOR(PP_IOCTL, 0x83, unsigned char)
  #define PPWCONTROL  _IOW(PP_IOCTL, 0x84, unsigned char)
  
  struct ppdev_frob_struct {
      unsigned char mask;
      unsigned char val;
  };
  #define PPFCONTROL      _IOW(PP_IOCTL, 0x8e, struct ppdev_frob_struct)
  
  /* Read/write data */
  #define PPRDATA     _IOR(PP_IOCTL, 0x85, unsigned char)
  #define PPWDATA     _IOW(PP_IOCTL, 0x86, unsigned char)
  
  /* Read/write econtrol (not used) */
  #define PPRECONTROL OBSOLETE__IOR(PP_IOCTL, 0x87, unsigned char)
  #define PPWECONTROL OBSOLETE__IOW(PP_IOCTL, 0x88, unsigned char)
  
  /* Read/write FIFO (not used) */
  #define PPRFIFO     OBSOLETE__IOR(PP_IOCTL, 0x89, unsigned char)
  #define PPWFIFO     OBSOLETE__IOW(PP_IOCTL, 0x8a, unsigned char)
  
  /* Claim the port to start using it */
  #define PPCLAIM     _IO(PP_IOCTL, 0x8b)
  
  /* Release the port when you aren't using it */
  #define PPRELEASE   _IO(PP_IOCTL, 0x8c)
  
  /* Yield the port (release it if another driver is waiting,
   * then reclaim) */
  #define PPYIELD     _IO(PP_IOCTL, 0x8d)
  
  /* Register device exclusively (must be before PPCLAIM). */
  #define PPEXCL      _IO(PP_IOCTL, 0x8f)
  
  /* Data line direction: non-zero for input mode. */
  #define PPDATADIR   _IOW(PP_IOCTL, 0x90, int)
  
  /* Negotiate a particular IEEE 1284 mode. */
  #define PPNEGOT     _IOW(PP_IOCTL, 0x91, int)
  
  /* Set control lines when an interrupt occurs. */
  #define PPWCTLONIRQ _IOW(PP_IOCTL, 0x92, unsigned char)
  
  /* Clear (and return) interrupt count. */
  #define PPCLRIRQ    _IOR(PP_IOCTL, 0x93, int)
  
  /* Set the IEEE 1284 phase that we're in (e.g. IEEE1284_PH_FWD_IDLE) */
  #define PPSETPHASE  _IOW(PP_IOCTL, 0x94, int)
  
  /* Set and get port timeout (struct timeval's) */
  #define PPGETTIME   _IOR(PP_IOCTL, 0x95, struct timeval)
  #define PPSETTIME   _IOW(PP_IOCTL, 0x96, struct timeval)
  
  /* Get available modes (what the hardware can do) */
  #define PPGETMODES  _IOR(PP_IOCTL, 0x97, unsigned int)
  
  /* Get the current mode and phaze */
  #define PPGETMODE   _IOR(PP_IOCTL, 0x98, int)
  #define PPGETPHASE  _IOR(PP_IOCTL, 0x99, int)
  
  /* get/set flags */
  #define PPGETFLAGS  _IOR(PP_IOCTL, 0x9a, int)
  #define PPSETFLAGS  _IOW(PP_IOCTL, 0x9b, int)
  
  /* flags visible to the world */
  #define PP_FASTWRITE    (1&lt;&lt;2)
  #define PP_FASTREAD (1&lt;&lt;3)
  #define PP_W91284PIC    (1&lt;&lt;4)
  
  /* only masks user-visible flags */
  #define PP_FLAGMASK (PP_FASTWRITE | PP_FASTREAD | PP_W91284PIC)
  </code></pre>