Programming the paralel port with QNX...

Someone can help me to programing the paralel port with QNX?

Thanks!

ALBERTO.

What do you want to do?? I have some code that works ( but its for nuetrino(QNX6.00))

/*

  • This program will set up a irq handler, and
  • set up a 82c54-10 on the parrallel port inorder
  • to generate interrupts at a controlled pace.
  • This program uses the eventattach call, it is not as fast as
  • the interruptattach version
  • the commandline args are
  • portevent [PORT address] [interrupt number] [divisor]
  • the comand word is made from the following
  • d7 d6 d5 d4 d3 d2 d1 d0
  •                    *  bcd =1 binary=0
    
  •           *  *  * --- mode <<1  ie mode 1 is 02 mode 2 is 0x04 mode 3 is 0x06
    
  •     *   * ----------- read write control: 00 latch cnt, 01 is r/w lsb only
    
  •                        10 is r/w msb only and 11 is r/w lsb then msb
    
      • ------------------ select counter 00 is c/t 1, 01 is c/t2 10 is c/t3
  •                        and the read back command is 11
    
  • Pat Ford april 18 2000
    */





    #include <stdio.h>
    #include <stdlib.h>
    #include <hw/inout.h>
    #include <sys/neutrino.h>
    #include <sys/syspage.h>
    #include <inttypes.h>
    #include <sys/mman.h>
    #include <errno.h>
    #include <string.h>

/*
mapping info for base + 2 (control)
where d3 d2 d1 d0


what A1 A0 RD WR Hex

wr_cntr0 0 0 1 0 0x09
wr_cntr1 0 1 1 0 0x01
wr_cntr2 1 0 1 0 0x0D
wr_cntrl 1 1 1 0 0x05
rd_cntr0 0 0 0 1 0x0A
rd_cntr1 0 1 0 1 0x02
rd_cntr2 1 0 0 1 0x0E
It looks funky but remember that d0, d1, d3, are inverted
*/

#define wr_ct1 0x09
#define wr_ct2 0x01
#define wr_ct3 0x0D
#define wr_cntrl 0x05
#define rd_ct1 0x0A
#define rd_ct2 0x02
#define rd_ct3 0x0E
#define rd_cntrl 0x06
#define cntrl_off 0x0B
#define idle 0x08

#define A0 0x04
#define A1 0x08
#define WR 0x02
#define RD 0x01

#define A0 0x04
#define A1 0x08
#define WR 0x02
#define RD 0x01

#define control_word_ct1 0x00
#define control_word_ct2 0x40
#define control_word_ct3 0x80
#define control_word_lsb 0x10
#define control_word_msb 0x20
#define control_word_word 0x30

#define control_mode_0 0x00
#define control_mode_1 0x02
#define control_mode_2 0x04
#define control_mode_3 0x06
#define control_mode_4 0x08
#define control_mode_5 0x0A

#define control_mode_bcd 0x01
#define control_mode_bin 0x00
#define base PORT
#define inputs PORT+1
#define control PORT+2

struct sigevent event;
volatile unsigned counter;


int main(int argc, char *argv[])
{

int i=0, j=0, mode=0, lsb=0, msb=0, tmp=0, c=0, id=0, cnt=400, PORT=0, IRQ=0;
uintptr_t lpt1;
size_t len=6;
uint64_t cps=0, t1=0, t2=0, sum=0, td;
float sec,hi, lo=1.0;



// Initialize event structure
event.sigev_notify = SIGEV_INTR;

mode=0x34;

PORT=strtol(argv[1], 0, 0);
IRQ=strtol(argv[2], 0, 0);
i=strtol(argv[3], 0, 0);
lsb=i & 0xff;
msb= i>>8;

if ( PORT==0 || IRQ==0 || i==0 )
{
printf("\n You MUST include [PORT address] [interrupt number] and [divisor] as commandline args\n");
exit(EXIT_FAILURE);
}

// Request I/O privity
ThreadCtl(_NTO_TCTL_IO, 0);


// map the io space we want
lpt1=mmap_device_io( len, PORT );
if( errno != EOK)
printf("\nMmap_device errno %s\n", strerror( errno ) );


//set up the counter timer
out8( control, 0x04); // set the address bus
out8(base,mode); // have to setup data
out8(control,wr_cntrl); // then drop the write enable
out8(control, idle); // raise the write enable
out8(control, 0x08);
out8(base,lsb);
out8(control,wr_ct1);
printf ("\noutputing %x as lsb",lsb);
out8(control, idle);

out8(control, 0x08);
out8(base,msb);
out8(control,wr_ct1);
printf ("\noutputing %x as msb",msb);
out8(control, idle);

// assert the irq enable
out8(control, ( idle | 0x10));
out8(base,0x00);

//out8(control,0xD8);

// Attach ISR vector
id=InterruptAttachEvent(IRQ, &event, _NTO_INTR_FLAGS_TRK_MSK);
if (id == -1)
{
perror(“InterruptAttachEvent failed”);
exit(EXIT_FAILURE);
}

cps = SYSPAGE_ENTRY(qtime)->cycles_per_sec;

printf("\nwaiting to be interrupted\n");
for (i = 0; i < cnt; ++i)
{
InterruptWait(0, NULL);
tmp=InterruptUnmask(7, id);
t1=ClockCycles();
if (i!=0)
{
td=t1-t2;
sec=(float)td/cps;
if (sec<lo)
lo=sec;
if (sec>hi)
hi=sec;
sum+=sec;
t2=t1;
}
else
{
sum=t1;
t2=t1;
}
}

td=sum/(cnt-1);
printf(" the value for cps is %lld \n",cps);
printf (“the value of lo is %2.8f \n”,lo);
printf (“the value of hi is %2.8f \n”,hi);
printf("the average time was… %2.8f\n ", sec);
return 0;
}


Previously, Alberto Rodríguez wrote in comp.os.qnx:
{ Someone can help me to programing the paralel port with QNX?
{
{ Thanks!
{
{ ALBERTO.
{
{
{


Pat Ford email: pford@qnx.com
QNX Software Systems, Ltd. WWW: http://www.qnx.com
(613) 591-0931 (voice) mail: 175 Terence Matthews
(613) 591-3579 (fax) Kanata, Ontario, Canada K2M 1W8

I’m working with QNX Neutrino…

I need to comunicate with an microcontroler across paralel port…

I read that the standar driver’s paralel port is not bidireccional, is there
some driver BIdireccional for Neutrino?

Thanks a lot!

ALBERTO.

“Pat Ford” <pford@qnx.com> escribió en el mensaje
news:Voyager.010125112205.30259F@funnel.qnx.com
What do you want to do?? I have some code that works ( but its for
nuetrino(QNX6.00))

/*

  • This program will set up a irq handler, and
  • set up a 82c54-10 on the parrallel port inorder
  • to generate interrupts at a controlled pace.
  • This program uses the eventattach call, it is not as fast as
  • the interruptattach version
  • the commandline args are
  • portevent [PORT address] [interrupt number] [divisor]
  • the comand word is made from the following
  • d7 d6 d5 d4 d3 d2 d1 d0
  •                    *  bcd =1 binary=0
    
  •           *  *  * --- mode <<1  ie mode 1 is 02 mode 2 is 0x04 mode 3
    

is 0x06

  •     *   * ----------- read write control: 00 latch cnt, 01 is r/w lsb
    

only

  •                        10 is r/w msb only and 11 is r/w lsb then msb
    
      • ------------------ select counter 00 is c/t 1, 01 is c/t2 10 is
        c/t3
  •                        and the read back command is 11
    
  • Pat Ford april 18 2000
    */





    #include <stdio.h>
    #include <stdlib.h>
    #include <hw/inout.h>
    #include <sys/neutrino.h>
    #include <sys/syspage.h>
    #include <inttypes.h>
    #include <sys/mman.h>
    #include <errno.h>
    #include <string.h>

/*
mapping info for base + 2 (control)
where d3 d2 d1 d0


what A1 A0 RD WR Hex

wr_cntr0 0 0 1 0 0x09
wr_cntr1 0 1 1 0 0x01
wr_cntr2 1 0 1 0 0x0D
wr_cntrl 1 1 1 0 0x05
rd_cntr0 0 0 0 1 0x0A
rd_cntr1 0 1 0 1 0x02
rd_cntr2 1 0 0 1 0x0E
It looks funky but remember that d0, d1, d3, are inverted
*/

#define wr_ct1 0x09
#define wr_ct2 0x01
#define wr_ct3 0x0D
#define wr_cntrl 0x05
#define rd_ct1 0x0A
#define rd_ct2 0x02
#define rd_ct3 0x0E
#define rd_cntrl 0x06
#define cntrl_off 0x0B
#define idle 0x08

#define A0 0x04
#define A1 0x08
#define WR 0x02
#define RD 0x01

#define A0 0x04
#define A1 0x08
#define WR 0x02
#define RD 0x01

#define control_word_ct1 0x00
#define control_word_ct2 0x40
#define control_word_ct3 0x80
#define control_word_lsb 0x10
#define control_word_msb 0x20
#define control_word_word 0x30

#define control_mode_0 0x00
#define control_mode_1 0x02
#define control_mode_2 0x04
#define control_mode_3 0x06
#define control_mode_4 0x08
#define control_mode_5 0x0A

#define control_mode_bcd 0x01
#define control_mode_bin 0x00
#define base PORT
#define inputs PORT+1
#define control PORT+2

struct sigevent event;
volatile unsigned counter;


int main(int argc, char *argv[])
{

int i=0, j=0, mode=0, lsb=0, msb=0, tmp=0, c=0, id=0, cnt=400, PORT=0,
IRQ=0;
uintptr_t lpt1;
size_t len=6;
uint64_t cps=0, t1=0, t2=0, sum=0, td;
float sec,hi, lo=1.0;



// Initialize event structure
event.sigev_notify = SIGEV_INTR;

mode=0x34;

PORT=strtol(argv[1], 0, 0);
IRQ=strtol(argv[2], 0, 0);
i=strtol(argv[3], 0, 0);
lsb=i & 0xff;
msb= i>>8;

if ( PORT==0 || IRQ==0 || i==0 )
{
printf("\n You MUST include [PORT address] [interrupt number] and [divisor]
as commandline args\n");
exit(EXIT_FAILURE);
}

// Request I/O privity
ThreadCtl(_NTO_TCTL_IO, 0);


// map the io space we want
lpt1=mmap_device_io( len, PORT );
if( errno != EOK)
printf("\nMmap_device errno %s\n", strerror( errno ) );


//set up the counter timer
out8( control, 0x04); // set the address bus
out8(base,mode); // have to setup data
out8(control,wr_cntrl); // then drop the write enable
out8(control, idle); // raise the write enable
out8(control, 0x08);
out8(base,lsb);
out8(control,wr_ct1);
printf ("\noutputing %x as lsb",lsb);
out8(control, idle);

out8(control, 0x08);
out8(base,msb);
out8(control,wr_ct1);
printf ("\noutputing %x as msb",msb);
out8(control, idle);

// assert the irq enable
out8(control, ( idle | 0x10));
out8(base,0x00);

//out8(control,0xD8);

// Attach ISR vector
id=InterruptAttachEvent(IRQ, &event, _NTO_INTR_FLAGS_TRK_MSK);
if (id == -1)
{
perror(“InterruptAttachEvent failed”);
exit(EXIT_FAILURE);
}

cps = SYSPAGE_ENTRY(qtime)->cycles_per_sec;

printf("\nwaiting to be interrupted\n");
for (i = 0; i < cnt; ++i)
{
InterruptWait(0, NULL);
tmp=InterruptUnmask(7, id);
t1=ClockCycles();
if (i!=0)
{
td=t1-t2;
sec=(float)td/cps;
if (sec<lo)
lo=sec;
if (sec>hi)
hi=sec;
sum+=sec;
t2=t1;
}
else
{
sum=t1;
t2=t1;
}
}

td=sum/(cnt-1);
printf(" the value for cps is %lld \n",cps);
printf (“the value of lo is %2.8f \n”,lo);
printf (“the value of hi is %2.8f \n”,hi);
printf("the average time was… %2.8f\n ", sec);
return 0;
}


Previously, Alberto Rodríguez wrote in comp.os.qnx:
{ Someone can help me to programing the paralel port with QNX?
{
{ Thanks!
{
{ ALBERTO.
{
{
{


Pat Ford email: pford@qnx.com
QNX Software Systems, Ltd. WWW: http://www.qnx.com
(613) 591-0931 (voice) mail: 175 Terence Matthews
(613) 591-3579 (fax) Kanata, Ontario, Canada K2M 1W8

The code sample I gave should work just make sure you slay the parallel driver first. You could also try read() or write() on /dev/parX

Previously, Alberto Rodríguez wrote in comp.os.qnx:
{ I’m working with QNX Neutrino…
{
{ I need to comunicate with an microcontroler across paralel port…
{
{ I read that the standar driver’s paralel port is not bidireccional, is there
{ some driver BIdireccional for Neutrino?
{
{ Thanks a lot!
{
{ ALBERTO.
{
{ “Pat Ford” <pford@qnx.com> escribió en el mensaje
{ news:Voyager.010125112205.30259F@funnel.qnx.com
{ What do you want to do?? I have some code that works ( but its for
{ nuetrino(QNX6.00))
{
{ /*
{ * This program will set up a irq handler, and
{ * set up a 82c54-10 on the parrallel port inorder
{ * to generate interrupts at a controlled pace.
{ * This program uses the eventattach call, it is not as fast as
{ * the interruptattach version
{ *
{ * the commandline args are
{ * portevent [PORT address] [interrupt number] [divisor]
{ *
{ * the comand word is made from the following
{ * d7 d6 d5 d4 d3 d2 d1 d0
{ * * bcd =1 binary=0
{ * * * * — mode <<1 ie mode 1 is 02 mode 2 is 0x04 mode 3
{ is 0x06
{ * * * ----------- read write control: 00 latch cnt, 01 is r/w lsb
{ only
{ * 10 is r/w msb only and 11 is r/w lsb then msb
{ * * * ------------------ select counter 00 is c/t 1, 01 is c/t2 10 is
{ c/t3
{ * and the read back command is 11
{ * Pat Ford april 18 2000
{ /
{
{
{
{
{
{ #include <stdio.h>
{ #include <stdlib.h>
{ #include <hw/inout.h>
{ #include <sys/neutrino.h>
{ #include <sys/syspage.h>
{ #include <inttypes.h>
{ #include <sys/mman.h>
{ #include <errno.h>
{ #include <string.h>
{
{ /

{ mapping info for base + 2 (control)
{ where d3 d2 d1 d0
{ __ __
{ what A1 A0 RD WR Hex
{ ------------------------------------------------------------
{ wr_cntr0 0 0 1 0 0x09
{ wr_cntr1 0 1 1 0 0x01
{ wr_cntr2 1 0 1 0 0x0D
{ wr_cntrl 1 1 1 0 0x05
{ rd_cntr0 0 0 0 1 0x0A
{ rd_cntr1 0 1 0 1 0x02
{ rd_cntr2 1 0 0 1 0x0E
{ It looks funky but remember that d0, d1, d3, are inverted
{ */
{
{ #define wr_ct1 0x09
{ #define wr_ct2 0x01
{ #define wr_ct3 0x0D
{ #define wr_cntrl 0x05
{ #define rd_ct1 0x0A
{ #define rd_ct2 0x02
{ #define rd_ct3 0x0E
{ #define rd_cntrl 0x06
{ #define cntrl_off 0x0B
{ #define idle 0x08
{
{ #define A0 0x04
{ #define A1 0x08
{ #define WR 0x02
{ #define RD 0x01
{
{ #define A0 0x04
{ #define A1 0x08
{ #define WR 0x02
{ #define RD 0x01
{
{ #define control_word_ct1 0x00
{ #define control_word_ct2 0x40
{ #define control_word_ct3 0x80
{ #define control_word_lsb 0x10
{ #define control_word_msb 0x20
{ #define control_word_word 0x30
{
{ #define control_mode_0 0x00
{ #define control_mode_1 0x02
{ #define control_mode_2 0x04
{ #define control_mode_3 0x06
{ #define control_mode_4 0x08
{ #define control_mode_5 0x0A
{
{ #define control_mode_bcd 0x01
{ #define control_mode_bin 0x00
{ #define base PORT
{ #define inputs PORT+1
{ #define control PORT+2
{
{ struct sigevent event;
{ volatile unsigned counter;
{
{
{ int main(int argc, char *argv[])
{ {
{
{ int i=0, j=0, mode=0, lsb=0, msb=0, tmp=0, c=0, id=0, cnt=400, PORT=0,
{ IRQ=0;
{ uintptr_t lpt1;
{ size_t len=6;
{ uint64_t cps=0, t1=0, t2=0, sum=0, td;
{ float sec,hi, lo=1.0;
{
{
{
{ // Initialize event structure
{ event.sigev_notify = SIGEV_INTR;
{
{ mode=0x34;
{
{ PORT=strtol(argv[1], 0, 0);
{ IRQ=strtol(argv[2], 0, 0);
{ i=strtol(argv[3], 0, 0);
{ lsb=i & 0xff;
{ msb= i>>8;
{
{ if ( PORT==0 || IRQ==0 || i==0 )
{ {
{ printf("\n You MUST include [PORT address] [interrupt number] and [divisor]
{ as commandline args\n");
{ exit(EXIT_FAILURE);
{ }
{
{ // Request I/O privity
{ ThreadCtl(_NTO_TCTL_IO, 0);
{
{
{ // map the io space we want
{ lpt1=mmap_device_io( len, PORT );
{ if( errno != EOK)
{ printf("\nMmap_device errno %s\n", strerror( errno ) );
{
{
{ //set up the counter timer
{ out8( control, 0x04); // set the address bus
{ out8(base,mode); // have to setup data
{ out8(control,wr_cntrl); // then drop the write enable
{ out8(control, idle); // raise the write enable
{ out8(control, 0x08);
{ out8(base,lsb);
{ out8(control,wr_ct1);
{ printf ("\noutputing %x as lsb",lsb);
{ out8(control, idle);
{
{ out8(control, 0x08);
{ out8(base,msb);
{ out8(control,wr_ct1);
{ printf ("\noutputing %x as msb",msb);
{ out8(control, idle);
{
{ // assert the irq enable
{ out8(control, ( idle | 0x10));
{ out8(base,0x00);
{
{ //out8(control,0xD8);
{
{ // Attach ISR vector
{ id=InterruptAttachEvent(IRQ, &event, _NTO_INTR_FLAGS_TRK_MSK);
{ if (id == -1)
{ {
{ perror(“InterruptAttachEvent failed”);
{ exit(EXIT_FAILURE);
{ }
{
{ cps = SYSPAGE_ENTRY(qtime)->cycles_per_sec;
{
{ printf("\nwaiting to be interrupted\n");
{ for (i = 0; i < cnt; ++i)
{ {
{ InterruptWait(0, NULL);
{ tmp=InterruptUnmask(7, id);
{ t1=ClockCycles();
{ if (i!=0)
{ {
{ td=t1-t2;
{ sec=(float)td/cps;
{ if (sec<lo)
{ lo=sec;
{ if (sec>hi)
{ hi=sec;
{ sum+=sec;
{ t2=t1;
{ }
{ else
{ {
{ sum=t1;
{ t2=t1;
{ }
{ }
{
{ td=sum/(cnt-1);
{ printf(" the value for cps is %lld \n",cps);
{ printf (“the value of lo is %2.8f \n”,lo);
{ printf (“the value of hi is %2.8f \n”,hi);
{ printf("the average time was… %2.8f\n ", sec);
{ return 0;
{ }
{
{
{ Previously, Alberto Rodríguez wrote in comp.os.qnx:
{ { Someone can help me to programing the paralel port with QNX?
{ {
{ { Thanks!
{ {
{ { ALBERTO.
{ {
{ {
{ {
{
{ –
{ Pat Ford email: pford@qnx.com
{ QNX Software Systems, Ltd. WWW: http://www.qnx.com
{ (613) 591-0931 (voice) mail: 175 Terence Matthews
{ (613) 591-3579 (fax) Kanata, Ontario, Canada K2M 1W8
{
{
{
{


Pat Ford email: pford@qnx.com
QNX Software Systems, Ltd. WWW: http://www.qnx.com
(613) 591-0931 (voice) mail: 175 Terence Matthews
(613) 591-3579 (fax) Kanata, Ontario, Canada K2M 1W8

Can i help me to make an paralel port driver for QNX Neutrino. I need the
port adress, …

Thanks Pat!

ALBERTO.

“Pat Ford” <pford@qnx.com> escribió en el mensaje
news:Voyager.010126134607.28029B@node141.ott.qnx.com
The code sample I gave should work just make sure you slay the parallel
driver first. You could also try read() or write() on /dev/parX

Previously, Alberto Rodríguez wrote in comp.os.qnx:
{ I’m working with QNX Neutrino…
{
{ I need to comunicate with an microcontroler across paralel port…
{
{ I read that the standar driver’s paralel port is not bidireccional, is
there
{ some driver BIdireccional for Neutrino?
{
{ Thanks a lot!
{
{ ALBERTO.
{
{ “Pat Ford” <pford@qnx.com> escribió en el mensaje
{ news:Voyager.010125112205.30259F@funnel.qnx.com
{ What do you want to do?? I have some code that works ( but its for
{ nuetrino(QNX6.00))
{
{ /*
{ * This program will set up a irq handler, and
{ * set up a 82c54-10 on the parrallel port inorder
{ * to generate interrupts at a controlled pace.
{ * This program uses the eventattach call, it is not as fast as
{ * the interruptattach version
{ *
{ * the commandline args are
{ * portevent [PORT address] [interrupt number] [divisor]
{ *
{ * the comand word is made from the following
{ * d7 d6 d5 d4 d3 d2 d1 d0
{ * * bcd =1 binary=0
{ * * * * — mode <<1 ie mode 1 is 02 mode 2 is 0x04 mode
3
{ is 0x06
{ * * * ----------- read write control: 00 latch cnt, 01 is r/w
lsb
{ only
{ * 10 is r/w msb only and 11 is r/w lsb then msb
{ * * * ------------------ select counter 00 is c/t 1, 01 is c/t2 10 is
{ c/t3
{ * and the read back command is 11
{ * Pat Ford april 18 2000
{ /
{
{
{
{
{
{ #include <stdio.h>
{ #include <stdlib.h>
{ #include <hw/inout.h>
{ #include <sys/neutrino.h>
{ #include <sys/syspage.h>
{ #include <inttypes.h>
{ #include <sys/mman.h>
{ #include <errno.h>
{ #include <string.h>
{
{ /

{ mapping info for base + 2 (control)
{ where d3 d2 d1 d0
{ __ __
{ what A1 A0 RD WR Hex
{ ------------------------------------------------------------
{ wr_cntr0 0 0 1 0 0x09
{ wr_cntr1 0 1 1 0 0x01
{ wr_cntr2 1 0 1 0 0x0D
{ wr_cntrl 1 1 1 0 0x05
{ rd_cntr0 0 0 0 1 0x0A
{ rd_cntr1 0 1 0 1 0x02
{ rd_cntr2 1 0 0 1 0x0E
{ It looks funky but remember that d0, d1, d3, are inverted
{ */
{
{ #define wr_ct1 0x09
{ #define wr_ct2 0x01
{ #define wr_ct3 0x0D
{ #define wr_cntrl 0x05
{ #define rd_ct1 0x0A
{ #define rd_ct2 0x02
{ #define rd_ct3 0x0E
{ #define rd_cntrl 0x06
{ #define cntrl_off 0x0B
{ #define idle 0x08
{
{ #define A0 0x04
{ #define A1 0x08
{ #define WR 0x02
{ #define RD 0x01
{
{ #define A0 0x04
{ #define A1 0x08
{ #define WR 0x02
{ #define RD 0x01
{
{ #define control_word_ct1 0x00
{ #define control_word_ct2 0x40
{ #define control_word_ct3 0x80
{ #define control_word_lsb 0x10
{ #define control_word_msb 0x20
{ #define control_word_word 0x30
{
{ #define control_mode_0 0x00
{ #define control_mode_1 0x02
{ #define control_mode_2 0x04
{ #define control_mode_3 0x06
{ #define control_mode_4 0x08
{ #define control_mode_5 0x0A
{
{ #define control_mode_bcd 0x01
{ #define control_mode_bin 0x00
{ #define base PORT
{ #define inputs PORT+1
{ #define control PORT+2
{
{ struct sigevent event;
{ volatile unsigned counter;
{
{
{ int main(int argc, char *argv[])
{ {
{
{ int i=0, j=0, mode=0, lsb=0, msb=0, tmp=0, c=0, id=0, cnt=400, PORT=0,
{ IRQ=0;
{ uintptr_t lpt1;
{ size_t len=6;
{ uint64_t cps=0, t1=0, t2=0, sum=0, td;
{ float sec,hi, lo=1.0;
{
{
{
{ // Initialize event structure
{ event.sigev_notify = SIGEV_INTR;
{
{ mode=0x34;
{
{ PORT=strtol(argv[1], 0, 0);
{ IRQ=strtol(argv[2], 0, 0);
{ i=strtol(argv[3], 0, 0);
{ lsb=i & 0xff;
{ msb= i>>8;
{
{ if ( PORT==0 || IRQ==0 || i==0 )
{ {
{ printf("\n You MUST include [PORT address] [interrupt number] and
[divisor]
{ as commandline args\n");
{ exit(EXIT_FAILURE);
{ }
{
{ // Request I/O privity
{ ThreadCtl(_NTO_TCTL_IO, 0);
{
{
{ // map the io space we want
{ lpt1=mmap_device_io( len, PORT );
{ if( errno != EOK)
{ printf("\nMmap_device errno %s\n", strerror( errno ) );
{
{
{ //set up the counter timer
{ out8( control, 0x04); // set the address bus
{ out8(base,mode); // have to setup data
{ out8(control,wr_cntrl); // then drop the write enable
{ out8(control, idle); // raise the write enable
{ out8(control, 0x08);
{ out8(base,lsb);
{ out8(control,wr_ct1);
{ printf ("\noutputing %x as lsb",lsb);
{ out8(control, idle);
{
{ out8(control, 0x08);
{ out8(base,msb);
{ out8(control,wr_ct1);
{ printf ("\noutputing %x as msb",msb);
{ out8(control, idle);
{
{ // assert the irq enable
{ out8(control, ( idle | 0x10));
{ out8(base,0x00);
{
{ //out8(control,0xD8);
{
{ // Attach ISR vector
{ id=InterruptAttachEvent(IRQ, &event, _NTO_INTR_FLAGS_TRK_MSK);
{ if (id == -1)
{ {
{ perror(“InterruptAttachEvent failed”);
{ exit(EXIT_FAILURE);
{ }
{
{ cps = SYSPAGE_ENTRY(qtime)->cycles_per_sec;
{
{ printf("\nwaiting to be interrupted\n");
{ for (i = 0; i < cnt; ++i)
{ {
{ InterruptWait(0, NULL);
{ tmp=InterruptUnmask(7, id);
{ t1=ClockCycles();
{ if (i!=0)
{ {
{ td=t1-t2;
{ sec=(float)td/cps;
{ if (sec<lo)
{ lo=sec;
{ if (sec>hi)
{ hi=sec;
{ sum+=sec;
{ t2=t1;
{ }
{ else
{ {
{ sum=t1;
{ t2=t1;
{ }
{ }
{
{ td=sum/(cnt-1);
{ printf(" the value for cps is %lld \n",cps);
{ printf (“the value of lo is %2.8f \n”,lo);
{ printf (“the value of hi is %2.8f \n”,hi);
{ printf("the average time was… %2.8f\n ", sec);
{ return 0;
{ }
{
{
{ Previously, Alberto Rodríguez wrote in comp.os.qnx:
{ { Someone can help me to programing the paralel port with QNX?
{ {
{ { Thanks!
{ {
{ { ALBERTO.
{ {
{ {
{ {
{
{ –
{ Pat Ford email: pford@qnx.com
{ QNX Software Systems, Ltd. WWW: http://www.qnx.com
{ (613) 591-0931 (voice) mail: 175 Terence Matthews
{ (613) 591-3579 (fax) Kanata, Ontario, Canada K2M 1W8
{
{
{
{


Pat Ford email: pford@qnx.com
QNX Software Systems, Ltd. WWW: http://www.qnx.com
(613) 591-0931 (voice) mail: 175 Terence Matthews
(613) 591-3579 (fax) Kanata, Ontario, Canada K2M 1W8

0x378 for par1

Previously, Alberto Rodríguez wrote in comp.os.qnx:
{ Can i help me to make an paralel port driver for QNX Neutrino. I need the
{ port adress, …
{
{ Thanks Pat!
{
{ –
{
{ ALBERTO.
{
{ “Pat Ford” <pford@qnx.com> escribió en el mensaje
{ news:Voyager.010126134607.28029B@node141.ott.qnx.com
{ The code sample I gave should work just make sure you slay the parallel
{ driver first. You could also try read() or write() on /dev/parX
{
{ Previously, Alberto Rodríguez wrote in comp.os.qnx:
{ { I’m working with QNX Neutrino…
{ {
{ { I need to comunicate with an microcontroler across paralel port…
{ {
{ { I read that the standar driver’s paralel port is not bidireccional, is
{ there
{ { some driver BIdireccional for Neutrino?
{ {
{ { Thanks a lot!
{ {
{ { ALBERTO.
{ {
{ { “Pat Ford” <pford@qnx.com> escribió en el mensaje
{ { news:Voyager.010125112205.30259F@funnel.qnx.com
{ { What do you want to do?? I have some code that works ( but its for
{ { nuetrino(QNX6.00))
{ {
{ { /*
{ { * This program will set up a irq handler, and
{ { * set up a 82c54-10 on the parrallel port inorder
{ { * to generate interrupts at a controlled pace.
{ { * This program uses the eventattach call, it is not as fast as
{ { * the interruptattach version
{ { *
{ { * the commandline args are
{ { * portevent [PORT address] [interrupt number] [divisor]
{ { *
{ { * the comand word is made from the following
{ { * d7 d6 d5 d4 d3 d2 d1 d0
{ { * * bcd =1 binary=0
{ { * * * * — mode <<1 ie mode 1 is 02 mode 2 is 0x04 mode
{ 3
{ { is 0x06
{ { * * * ----------- read write control: 00 latch cnt, 01 is r/w
{ lsb
{ { only
{ { * 10 is r/w msb only and 11 is r/w lsb then msb
{ { * * * ------------------ select counter 00 is c/t 1, 01 is c/t2 10 is
{ { c/t3
{ { * and the read back command is 11
{ { * Pat Ford april 18 2000
{ { /
{ {
{ {
{ {
{ {
{ {
{ { #include <stdio.h>
{ { #include <stdlib.h>
{ { #include <hw/inout.h>
{ { #include <sys/neutrino.h>
{ { #include <sys/syspage.h>
{ { #include <inttypes.h>
{ { #include <sys/mman.h>
{ { #include <errno.h>
{ { #include <string.h>
{ {
{ { /

{ { mapping info for base + 2 (control)
{ { where d3 d2 d1 d0
{ { __ __
{ { what A1 A0 RD WR Hex
{ { ------------------------------------------------------------
{ { wr_cntr0 0 0 1 0 0x09
{ { wr_cntr1 0 1 1 0 0x01
{ { wr_cntr2 1 0 1 0 0x0D
{ { wr_cntrl 1 1 1 0 0x05
{ { rd_cntr0 0 0 0 1 0x0A
{ { rd_cntr1 0 1 0 1 0x02
{ { rd_cntr2 1 0 0 1 0x0E
{ { It looks funky but remember that d0, d1, d3, are inverted
{ { */
{ {
{ { #define wr_ct1 0x09
{ { #define wr_ct2 0x01
{ { #define wr_ct3 0x0D
{ { #define wr_cntrl 0x05
{ { #define rd_ct1 0x0A
{ { #define rd_ct2 0x02
{ { #define rd_ct3 0x0E
{ { #define rd_cntrl 0x06
{ { #define cntrl_off 0x0B
{ { #define idle 0x08
{ {
{ { #define A0 0x04
{ { #define A1 0x08
{ { #define WR 0x02
{ { #define RD 0x01
{ {
{ { #define A0 0x04
{ { #define A1 0x08
{ { #define WR 0x02
{ { #define RD 0x01
{ {
{ { #define control_word_ct1 0x00
{ { #define control_word_ct2 0x40
{ { #define control_word_ct3 0x80
{ { #define control_word_lsb 0x10
{ { #define control_word_msb 0x20
{ { #define control_word_word 0x30
{ {
{ { #define control_mode_0 0x00
{ { #define control_mode_1 0x02
{ { #define control_mode_2 0x04
{ { #define control_mode_3 0x06
{ { #define control_mode_4 0x08
{ { #define control_mode_5 0x0A
{ {
{ { #define control_mode_bcd 0x01
{ { #define control_mode_bin 0x00
{ { #define base PORT
{ { #define inputs PORT+1
{ { #define control PORT+2
{ {
{ { struct sigevent event;
{ { volatile unsigned counter;
{ {
{ {
{ { int main(int argc, char *argv[])
{ { {
{ {
{ { int i=0, j=0, mode=0, lsb=0, msb=0, tmp=0, c=0, id=0, cnt=400, PORT=0,
{ { IRQ=0;
{ { uintptr_t lpt1;
{ { size_t len=6;
{ { uint64_t cps=0, t1=0, t2=0, sum=0, td;
{ { float sec,hi, lo=1.0;
{ {
{ {
{ {
{ { // Initialize event structure
{ { event.sigev_notify = SIGEV_INTR;
{ {
{ { mode=0x34;
{ {
{ { PORT=strtol(argv[1], 0, 0);
{ { IRQ=strtol(argv[2], 0, 0);
{ { i=strtol(argv[3], 0, 0);
{ { lsb=i & 0xff;
{ { msb= i>>8;
{ {
{ { if ( PORT==0 || IRQ==0 || i==0 )
{ { {
{ { printf("\n You MUST include [PORT address] [interrupt number] and
{ [divisor]
{ { as commandline args\n");
{ { exit(EXIT_FAILURE);
{ { }
{ {
{ { // Request I/O privity
{ { ThreadCtl(_NTO_TCTL_IO, 0);
{ {
{ {
{ { // map the io space we want
{ { lpt1=mmap_device_io( len, PORT );
{ { if( errno != EOK)
{ { printf("\nMmap_device errno %s\n", strerror( errno ) );
{ {
{ {
{ { //set up the counter timer
{ { out8( control, 0x04); // set the address bus
{ { out8(base,mode); // have to setup data
{ { out8(control,wr_cntrl); // then drop the write enable
{ { out8(control, idle); // raise the write enable
{ { out8(control, 0x08);
{ { out8(base,lsb);
{ { out8(control,wr_ct1);
{ { printf ("\noutputing %x as lsb",lsb);
{ { out8(control, idle);
{ {
{ { out8(control, 0x08);
{ { out8(base,msb);
{ { out8(control,wr_ct1);
{ { printf ("\noutputing %x as msb",msb);
{ { out8(control, idle);
{ {
{ { // assert the irq enable
{ { out8(control, ( idle | 0x10));
{ { out8(base,0x00);
{ {
{ { //out8(control,0xD8);
{ {
{ { // Attach ISR vector
{ { id=InterruptAttachEvent(IRQ, &event, _NTO_INTR_FLAGS_TRK_MSK);
{ { if (id == -1)
{ { {
{ { perror(“InterruptAttachEvent failed”);
{ { exit(EXIT_FAILURE);
{ { }
{ {
{ { cps = SYSPAGE_ENTRY(qtime)->cycles_per_sec;
{ {
{ { printf("\nwaiting to be interrupted\n");
{ { for (i = 0; i < cnt; ++i)
{ { {
{ { InterruptWait(0, NULL);
{ { tmp=InterruptUnmask(7, id);
{ { t1=ClockCycles();
{ { if (i!=0)
{ { {
{ { td=t1-t2;
{ { sec=(float)td/cps;
{ { if (sec<lo)
{ { lo=sec;
{ { if (sec>hi)
{ { hi=sec;
{ { sum+=sec;
{ { t2=t1;
{ { }
{ { else
{ { {
{ { sum=t1;
{ { t2=t1;
{ { }
{ { }
{ {
{ { td=sum/(cnt-1);
{ { printf(" the value for cps is %lld \n",cps);
{ { printf (“the value of lo is %2.8f \n”,lo);
{ { printf (“the value of hi is %2.8f \n”,hi);
{ { printf("the average time was… %2.8f\n ", sec);
{ { return 0;
{ { }
{ {
{ {
{ { Previously, Alberto Rodríguez wrote in comp.os.qnx:
{ { { Someone can help me to programing the paralel port with QNX?
{ { {
{ { { Thanks!
{ { {
{ { { ALBERTO.
{ { {
{ { {
{ { {
{ {
{ { –
{ { Pat Ford email: pford@qnx.com
{ { QNX Software Systems, Ltd. WWW: http://www.qnx.com
{ { (613) 591-0931 (voice) mail: 175 Terence Matthews
{ { (613) 591-3579 (fax) Kanata, Ontario, Canada K2M 1W8
{ {
{ {
{ {
{ {
{
{ –
{ Pat Ford email: pford@qnx.com
{ QNX Software Systems, Ltd. WWW: http://www.qnx.com
{ (613) 591-0931 (voice) mail: 175 Terence Matthews
{ (613) 591-3579 (fax) Kanata, Ontario, Canada K2M 1W8
{
{
{
{


Pat Ford email: pford@qnx.com
QNX Software Systems, Ltd. WWW: http://www.qnx.com
(613) 591-0931 (voice) mail: 175 Terence Matthews
(613) 591-3579 (fax) Kanata, Ontario, Canada K2M 1W8

0x378 Normally lpt1
0x278 Normally lpt2
0x3BC Normally lpt3

These sometimes can be messed with in the bios. Irqs as well can be
adjusted.

http://www.lvr.com/parport.htm

might also help for non qnx issues.

If you are talking to it don’t forget to enable talking to the h/w and
also you have to be root :slight_smile:

Simon

In article <Voyager.010129104636.8458D@node141.ott.qnx.com>, Pat Ford
<pford@qnx.com> writes

0x378 for par1

Previously, Alberto Rodríguez wrote in comp.os.qnx:
{ Can i help me to make an paralel port driver for QNX Neutrino. I need the
{ port adress, …
{
{ Thanks Pat!
{
{ –
{
{ ALBERTO.
{
{ “Pat Ford” <> pford@qnx.com> > escribió en el mensaje
{ news:> Voyager.010126134607.28029B@node141.ott.qnx.com> …
{ The code sample I gave should work just make sure you slay the parallel
{ driver first. You could also try read() or write() on /dev/parX
{
{ Previously, Alberto Rodríguez wrote in comp.os.qnx:
{ { I’m working with QNX Neutrino…
{ {
{ { I need to comunicate with an microcontroler across paralel port…
{ {
{ { I read that the standar driver’s paralel port is not bidireccional, is
{ there
{ { some driver BIdireccional for Neutrino?
{ {
{ { Thanks a lot!
{ {
{ { ALBERTO.
{ {
{ { “Pat Ford” <> pford@qnx.com> > escribió en el mensaje
{ { news:> Voyager.010125112205.30259F@funnel.qnx.com> …
{ { What do you want to do?? I have some code that works ( but its for
{ { nuetrino(QNX6.00))
{ {
{ { /*
{ { * This program will set up a irq handler, and
{ { * set up a 82c54-10 on the parrallel port inorder
{ { * to generate interrupts at a controlled pace.
{ { * This program uses the eventattach call, it is not as fast as
{ { * the interruptattach version
{ { *
{ { * the commandline args are
{ { * portevent [PORT address] [interrupt number] [divisor]
{ { *
{ { * the comand word is made from the following
{ { * d7 d6 d5 d4 d3 d2 d1 d0
{ { * * bcd =1 binary=0
{ { * * * * — mode <<1 ie mode 1 is 02 mode 2 is 0x04 mode
{ 3
{ { is 0x06
{ { * * * ----------- read write control: 00 latch cnt, 01 is r/w
{ lsb
{ { only
{ { * 10 is r/w msb only and 11 is r/w lsb then msb
{ { * * * ------------------ select counter 00 is c/t 1, 01 is c/t2 10 is
{ { c/t3
{ { * and the read back command is 11
{ { * Pat Ford april 18 2000
{ { /
{ {
{ {
{ {
{ {
{ {
{ { #include <stdio.h
{ { #include <stdlib.h
{ { #include <hw/inout.h
{ { #include <sys/neutrino.h
{ { #include <sys/syspage.h
{ { #include <inttypes.h
{ { #include <sys/mman.h
{ { #include <errno.h
{ { #include <string.h
{ {
{ { /

{ { mapping info for base + 2 (control)
{ { where d3 d2 d1 d0
{ { __ __
{ { what A1 A0 RD WR Hex
{ { ------------------------------------------------------------
{ { wr_cntr0 0 0 1 0 0x09
{ { wr_cntr1 0 1 1 0 0x01
{ { wr_cntr2 1 0 1 0 0x0D
{ { wr_cntrl 1 1 1 0 0x05
{ { rd_cntr0 0 0 0 1 0x0A
{ { rd_cntr1 0 1 0 1 0x02
{ { rd_cntr2 1 0 0 1 0x0E
{ { It looks funky but remember that d0, d1, d3, are inverted
{ { */
{ {
{ { #define wr_ct1 0x09
{ { #define wr_ct2 0x01
{ { #define wr_ct3 0x0D
{ { #define wr_cntrl 0x05
{ { #define rd_ct1 0x0A
{ { #define rd_ct2 0x02
{ { #define rd_ct3 0x0E
{ { #define rd_cntrl 0x06
{ { #define cntrl_off 0x0B
{ { #define idle 0x08
{ {
{ { #define A0 0x04
{ { #define A1 0x08
{ { #define WR 0x02
{ { #define RD 0x01
{ {
{ { #define A0 0x04
{ { #define A1 0x08
{ { #define WR 0x02
{ { #define RD 0x01
{ {
{ { #define control_word_ct1 0x00
{ { #define control_word_ct2 0x40
{ { #define control_word_ct3 0x80
{ { #define control_word_lsb 0x10
{ { #define control_word_msb 0x20
{ { #define control_word_word 0x30
{ {
{ { #define control_mode_0 0x00
{ { #define control_mode_1 0x02
{ { #define control_mode_2 0x04
{ { #define control_mode_3 0x06
{ { #define control_mode_4 0x08
{ { #define control_mode_5 0x0A
{ {
{ { #define control_mode_bcd 0x01
{ { #define control_mode_bin 0x00
{ { #define base PORT
{ { #define inputs PORT+1
{ { #define control PORT+2
{ {
{ { struct sigevent event;
{ { volatile unsigned counter;
{ {
{ {
{ { int main(int argc, char *argv[])
{ { {
{ {
{ { int i=0, j=0, mode=0, lsb=0, msb=0, tmp=0, c=0, id=0, cnt=400, PORT=0,
{ { IRQ=0;
{ { uintptr_t lpt1;
{ { size_t len=6;
{ { uint64_t cps=0, t1=0, t2=0, sum=0, td;
{ { float sec,hi, lo=1.0;
{ {
{ {
{ {
{ { // Initialize event structure
{ { event.sigev_notify = SIGEV_INTR;
{ {
{ { mode=0x34;
{ {
{ { PORT=strtol(argv[1], 0, 0);
{ { IRQ=strtol(argv[2], 0, 0);
{ { i=strtol(argv[3], 0, 0);
{ { lsb=i & 0xff;
{ { msb= i>>8;
{ {
{ { if ( PORT==0 || IRQ==0 || i==0 )
{ { {
{ { printf("\n You MUST include [PORT address] [interrupt number] and
{ [divisor]
{ { as commandline args\n");
{ { exit(EXIT_FAILURE);
{ { }
{ {
{ { // Request I/O privity
{ { ThreadCtl(_NTO_TCTL_IO, 0);
{ {
{ {
{ { // map the io space we want
{ { lpt1=mmap_device_io( len, PORT );
{ { if( errno != EOK)
{ { printf("\nMmap_device errno %s\n", strerror( errno ) );
{ {
{ {
{ { //set up the counter timer
{ { out8( control, 0x04); // set the address bus
{ { out8(base,mode); // have to setup data
{ { out8(control,wr_cntrl); // then drop the write enable
{ { out8(control, idle); // raise the write enable
{ { out8(control, 0x08);
{ { out8(base,lsb);
{ { out8(control,wr_ct1);
{ { printf ("\noutputing %x as lsb",lsb);
{ { out8(control, idle);
{ {
{ { out8(control, 0x08);
{ { out8(base,msb);
{ { out8(control,wr_ct1);
{ { printf ("\noutputing %x as msb",msb);
{ { out8(control, idle);
{ {
{ { // assert the irq enable
{ { out8(control, ( idle | 0x10));
{ { out8(base,0x00);
{ {
{ { //out8(control,0xD8);
{ {
{ { // Attach ISR vector
{ { id=InterruptAttachEvent(IRQ, &event, _NTO_INTR_FLAGS_TRK_MSK);
{ { if (id == -1)
{ { {
{ { perror(“InterruptAttachEvent failed”);
{ { exit(EXIT_FAILURE);
{ { }
{ {
{ { cps = SYSPAGE_ENTRY(qtime)->cycles_per_sec;
{ {
{ { printf("\nwaiting to be interrupted\n");
{ { for (i = 0; i < cnt; ++i)
{ { {
{ { InterruptWait(0, NULL);
{ { tmp=InterruptUnmask(7, id);
{ { t1=ClockCycles();
{ { if (i!=0)
{ { {
{ { td=t1-t2;
{ { sec=(float)td/cps;
{ { if (sec<lo)
{ { lo=sec;
{ { if (sec>hi)
{ { hi=sec;
{ { sum+=sec;
{ { t2=t1;
{ { }
{ { else
{ { {
{ { sum=t1;
{ { t2=t1;
{ { }
{ { }
{ {
{ { td=sum/(cnt-1);
{ { printf(" the value for cps is %lld \n",cps);
{ { printf (“the value of lo is %2.8f \n”,lo);
{ { printf (“the value of hi is %2.8f \n”,hi);
{ { printf("the average time was… %2.8f\n ", sec);
{ { return 0;
{ { }
{ {
{ {
{ { Previously, Alberto Rodríguez wrote in comp.os.qnx:
{ { { Someone can help me to programing the paralel port with QNX?
{ { {
{ { { Thanks!
{ { {
{ { { ALBERTO.
{ { {
{ { {
{ { {
{ {
{ { –
{ { Pat Ford email: > pford@qnx.com
{ { QNX Software Systems, Ltd. WWW: > http://www.qnx.com
{ { (613) 591-0931 (voice) mail: 175 Terence Matthews
{ { (613) 591-3579 (fax) Kanata, Ontario, Canada K2M 1W8
{ {
{ {
{ {
{ {
{
{ –
{ Pat Ford email: > pford@qnx.com
{ QNX Software Systems, Ltd. WWW: > http://www.qnx.com
{ (613) 591-0931 (voice) mail: 175 Terence Matthews
{ (613) 591-3579 (fax) Kanata, Ontario, Canada K2M 1W8
{
{
{
{


Pat Ford email: > pford@qnx.com
QNX Software Systems, Ltd. WWW: > http://www.qnx.com
(613) 591-0931 (voice) mail: 175 Terence Matthews
(613) 591-3579 (fax) Kanata, Ontario, Canada K2M 1W8


Simon Wakley
Visit our web site at <<www.cameracontrol.com>>

What do you want to do? Standard and Bi-DIrectional Parallel Ports
use three I/O ports usually starting at 0x378, 0x278, or 0x3bc.
EPP and ECP uses additional I/O ports.


Previously, Alberto Rodríguez wrote in comp.os.qnx:

Someone can help me to programing the paralel port with QNX?

Thanks!

ALBERTO.
\


Mitchell Schoenbrun --------- maschoen@pobox.com

Previously, Alberto Rodríguez wrote in comp.os.qnx:

I’m working with QNX Neutrino…

I need to comunicate with an microcontroler across paralel port…

I read that the standar driver’s paralel port is not bidireccional, is there
some driver BIdireccional for Neutrino?

The standard driver is no doubt for printing. Printing is basically a one
way affair. For a driver to implement bidirectional support, there would
have to be a protocol assumed at both ends. A parallel port has only
8 data lines whose default direction is from the host. They can be
turned around, but there must be a protocol controlling when to do
this.


Mitchell Schoenbrun --------- maschoen@pobox.com

“Mitchell Schoenbrun” <maschoen@pobox.com> wrote in message
news:Voyager.010131165937.225C@schoenbrun.com
Previously, Alberto Rodríguez wrote in comp.os.qnx:

I’m working with QNX Neutrino…

I need to comunicate with an microcontroler across paralel port…

I read that the standar driver’s paralel port is not bidireccional, is
there
some driver BIdireccional for Neutrino?

If it’s not bidirectional how can it autodetect the printer model?

Previously, Mario Charest wrote in comp.os.qnx:

If it’s not bidirectional how can it autodetect the printer model?

There are a few different ways to answer this. Some printers
simply will not be able to autodetect a printer model. This
should be a rare occurance since almost all printer ports can
at least be configured to be bi-directional. There is a common
technique for reading data from a non-bi-directional printer
port, which is to use four control lines to move data over a
nibble at a time. This is so common, that the IEEE parallel
port standard uses it as the default mode, NIBBLE mode.

Mitchell Schoenbrun --------- maschoen@pobox.com