How to Send Output to the Parallel Port

The sample program below simply sends an alernating high-low signal to the parallel port's data register, which will appear on the output data lines. The cycle frequency is dictated by the length of the sleep() delays.

For more detailed information about the parallel port, and handling it in software, refer to my other web page on Parallel Port Interrupt Handling.

Note that you should slay devc-par to prevent it from trying to handle the same piece of hardware (the parallel port, of course) as your program. Having two software processes attempting to handle the same piece of hardware is not usually a good idea!

Note also that you will need to run this program as root, so that the process can get the necessary permissions to access the hardware.


#include <stdio.h>
#include <unistd.h>       /* for sleep() */
#include <stdint.h>       /* for uintptr_t */
#include <hw/inout.h>     /* for in*() and out*() functions */
#include <sys/neutrino.h> /* for ThreadCtl() */
#include <sys/mman.h>     /* for mmap_device_io() */

/* The Neutrino IO port used here corresponds to a single register, which is
 * one byte long */
#define PORT_LENGTH 1 

/* The first parallel port usually starts at 0x378. Each parallel port is
 * three bytes wide. The first byte is the Data register, the second byte is
 * the Status register, the third byte is the Control register. */
#define DATA_ADDRESS 0x378
#define CTRL_ADDRESS 0x37a
 /* bit 2 = printer initialisation (high to initialise)
  * bit 4 = hardware IRQ (high to enable) */
#define INIT_BIT 0x04

#define LOW 0x00
#define HIGH 0xFF

#define MAX_COUNT 60


/* ______________________________________________________________________ */
int
main( )
{
   int privity_err;
   uintptr_t ctrl_handle;
   uintptr_t data_handle;
   int count;

   /* Give this thread root permissions to access the hardware */
   privity_err = ThreadCtl( _NTO_TCTL_IO, NULL );
   if ( privity_err == -1 )
   {
      fprintf( stderr, "can't get root permissions\n" );
      return -1;
   }

   /* Get a handle to the parallel port's Control register */
   ctrl_handle = mmap_device_io( PORT_LENGTH, CTRL_ADDRESS );
   /* Initialise the parallel port */
   out8( ctrl_handle, INIT_BIT );

   /* Get a handle to the parallel port's Data register */
   data_handle = mmap_device_io( PORT_LENGTH, DATA_ADDRESS );

   for ( count = 0; count < MAX_COUNT; count++ )
   {  
      /* Output a byte of lows to the data lines */
      out8( data_handle, LOW );
      printf( "Low\n" );
      sleep( 1 );

      /* Output a byte of highs to the data lines */
      out8( data_handle, HIGH );
      printf( "High\n" );
      sleep( 1 );
   }

   return 0;
}


Home About Me
Copyright © Neil Carter

Content last updated: 2003-09-23