parallel port interrupt issues

Hi QNX Community!

I’m writing a software in which I need to synchronize my tasks on an external timer.

In my solution, I configure the 10th pin of the lpt port as interrupt source.

[code]
//*************************************************************
#include <stdio.h>
#include <sys/neutrino.h>
#include <hw/inout.h>
#include <stdlib.h>
#include <stdint.h>
#include <sys/mman.h>
#include <unistd.h>

#define IRQ7 0x07
#define BASE_ADDRESS_LPT1 0x378
#define INTR_BIT 0x10
#define MASK_RUN 0x20

int main(void){

//variables
int i, id;
int irqActive;
unsigned char reg;
unsigned long lpt;
struct sigevent event;

ThreadCtl(_NTO_TCTL_IO, 0);

event.sigev_notify = SIGEV_INTR;
id = InterruptAttachEvent(IRQ7, &event,
NTO_INTR_FLAGS_TRK_MSK);

/mapping 3 bytes to configure, read and write LPT port/
lpt = mmap_device_io(3, BASE_ADDRESS_LPT1);

/interrupt hardware set/
reg = in8(lpt + 2);
out8(lpt + 2, reg|INTR_BIT);

printf(“init…\n”);

/waiting start/
while(~in8(lpt + 1) & MASK_RUN);
printf(“start…\n”);

i = 0;
while(in8(lpt + 1) & MASK_RUN){
interruptWait(0, NULL);
i += 1;
i %= 10000;
InterruptUnmask(IRQ7, id);
}
printf("%d interruption(s)\n", i);

munmap_device_io(lpt, 3);
InterruptDetach(id1);

return 0;

}

//************************************************************[/code]

Explainations :

the interrupts signal period is 100us (50% low… 50% high).

I use one input pin to define a start-stop, when this signal is high, I perform my tests.

The problem is :

I can run the test during around 5 seconds, but if I try to test longer… My program “freezes” on InterruptWait.

Does someone have a clue or a answer?

Is it a kind of overflow or is it because the loop is really tight?

I am a little lost because I tried with the internal timer (irq0) and I didn’t get these problems.

I read some websites about IRQ7, but didn’t get information about its servicing.

Thanks for your help and answers.
Hargan

I think you should read “Writing an Interrupt Handler” carefully. There is a good source code aproach little more elegant. There is a thread dedicated only to interrupt processing and there is and ISR handler that returns an event structure. This ISR should be as short and fast as posible.

I did something very similar with the but in QNX4, and it works fine.

Regards,
Juan Manuel

Thanks Juan Manuel for your advice. I also used this approach to handle with parallel port interrupt :

When I observe my output pin (on which I perform a toggle every time there’s an interrupt from the lpt port),
the execution stops after a while (around 10 seconds).

This is the other code I wrote :

[code]//****************************************************
#include <stdio.h>
#include <sys/neutrino.h>
#include <hw/inout.h>
#include <stdlib.h>
#include <stdint.h>
#include <sys/mman.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>

#define IRQ7 0x07
#define BASE_ADDRESS_LPT1 0x378
#define INTR_BIT 0x10
#define MASK_RUN 0x20
#define MASK_TOGGLE 0x02

#define MAX_PRIO 100

sem_t endRun;
pthread_t tInterrupt;
struct sigevent event;
volatile int id1;

const struct sigevent *handler(void *area, int id);

void *interrupt_handler(void *arg){
unsigned char reg;
unsigned long lpt;

ThreadCtl(_NTO_TCTL_IO, 0);
event.sigev_notify = SIGEV_INTR;

id1 = InterruptAttach(IRQ7, &handler, NULL, 0, 0 );

lpt = mmap_device_io(3, BASE_ADDRESS_LPT1);

reg = in8(lpt + 2);
out8(lpt + 2, reg|INTR_BIT);

while(~in8(lpt + 1) & MASK_RUN);
while(in8(lpt + 1) & MASK_RUN){
	InterruptWait(0, NULL);
	reg = in8(lpt);
	out8(lpt, reg ^ MASK_TOGGLE);
	InterruptUnmask(IRQ7, id1);
}

munmap_device_io(lpt, 3);
InterruptDetach(id1);

sem_post(&endRun);
return NULL;

}

int main(void){
sched_param_t parametre;
pthread_attr_t attribut;
int status;

status = sem_init(&endRun, NULL, 0);
if (status != 0){
	printf("Error creating semaphore 'endRun' : %d\n", status);
	return -1;
}

pthread_attr_init(&attribut);

status = pthread_attr_getschedparam(&attribut, &parametre);
if (status != 0){
	printf("Error while getting scheduler parameters : code <%d>\n", status);
	return -1;
}

parametre.sched_priority = MAX_PRIO;
pthread_attr_setschedparam(&attribut, &parametre);

status = pthread_create(&tInterrupt, &attribut, interrupt_handler, NULL);
if (status != 0){
	printf ("Error creating tInterrupt thread : %d\n", status);
	return -1;
}

sem_wait(&endRun);	
return 0;

}

const struct sigevent *handler(void *area, int id) {
if (id == id1){
InterruptMask(IRQ7, id1);
return &event;
}
else{
return NULL;
}
}[/code]

Thanks for all your help or hints.
Regards,
Hargan

I got a solution to my problem on the official forum. To solve this problem, I had to stop the parallel port driver with the command slay.

Have a nice day,
Hargan