problem with LPT programming


I going to use parallel port to control the AD420 DAC. Because the AD420 uses SPI to communicate so I need a few separate lines of LPT located in the data and control registers. The only way to do that is to use out8() call.

Here is the code taken from :
and modified a little bit.

#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

/* ______________________________________________________________________ */
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 );
/* 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);
	out8( ctrl_handle, (LOW & 0x0f ) );
	printf( "Low\n" );
	sleep( 1 );

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

return 0;


I run it as root. It doesn’t work properly. It swithes only pins located under the control register.Why pins under the data register doesn’t want to switch? Besides pin 4 of LPT (bit num 4 in the data register) is on.
I tried to slay devc-par from command line but it doesn’t effect. The program still work the same way.
What is wrong with that?
Please help.


I tried to send some data and read them back.
When I send various data to the data register and then I read them and I get 0. Sending to and reading back the control register looks ok. For example I send 0x0a and I get 0xca.

uintptr_t ctrl_handle = 0;
uintptr_t data_handle = 0;
unsigned char r_data = 0;
unsigned char r_ctrl = 0;
ThreadCtl( _NTO_TCTL_IO, NULL );
data_handle = mmap_device_io( 1, 0x378 );
ctrl_handle = mmap_device_io( 1, 0x37a );
printf("data handle %x\n",data_handle);
printf("ctrl handle %x\n",ctrl_handle);	
out8( data_handle, 0xfa);
out8( ctrl_handle, 0x0a);
r_data = in8(data_handle);
r_ctrl = in8(ctrl_handle);
printf("r_data :%x\n", r_data);	
printf("r_ctrl :%x\n", r_ctrl);

I forgot to mention that I’m using QNX Neutrino 6.3.0.
Also I checked my parallel port under WindowsXP and it works properly.

Any suggestions?


I have solved the problem:-). The problem was in the BIOS parallel port settings. Since I switched settings from EPP mode to SPP mode it has been working correctly.