IRQ not being detected

If your board is a plain PC/104 (not PCI or PC/104+) board then YOU have
to jumper the IRQ of the board or you have to set the IRQ by your driver!
You have also to check if an other device (serial/printer) is using the
IRQ 5. If it is so try to use a different IRQ (10,11,12 e.g)
And … you must set the choosen IRQ as ‘legazy ISA’ in the BIOS setup!!
–Armin

Board as far as i can tell is plain pc104. There is a jumper to select
IRQ5 or IRQ10, set to IRQ5 on the board. Set in the bios IRQ5 and 10 to
‘legacy ISA’ dont think anything else is using those irq’s. the irq is
firing on the hardware(looked at it with a scope) so all thats missing is
how to detect it in qnx. Is there some sort of mapping i need to do?
Thanks.

Well i finaly solved it!!!
At least i learned a lot.
Here is a rundown of what the problems were and solutions for others who
follow:

The first problem was i was not registering any interrupts because my
interrupt funciton was buggy. The best thing to do is use the example here:
http://www.qnx.com/developers/docs/6.3.0SP2/neutrino/sys_arch/kernel.html#INTERRUPTHANDLING.
And modify it by changing the IRQ from the clock to what you need.

The second problem was that the recource manager was not picking the IRQ i
wanted from the hardware (IRQ 5). THe hardware worked because when i used
the example code from the link above and threw in there the code for my
hardware it was reading it correctly. So it had to be some issue with the
hardware not sending the IRQ.

Turned out that what i had was a P/C104, well that didnt mean much to me
before i started writing this so i ignored it. What i had to do was in the
BIOS change IRQ 5 to be for Legacy ISA and make sure nothing else was using
IRQ5. Thats when it started working!

I thank all of you that responded to my questions. There is no way i would
have figured this out if it wasnt for your help. THANK YOU VERY MUCH!!!

|My best regards,
wasiul

This does present an obvious question. If you needed to make a change
to the BIOS, how was it working with Linux?

This does present an obvious question. If you needed to make a change
to the BIOS, how was it working with Linux?

That i dont know and would like to find out. could there be something
setting that irq to ISA when the linux partition starts?

Dear gurus,
In my case also the same problem. The control is not moving into
the ISR handler for USB connection. When i did “pci -v” in
the terminal i got the IRQ as 5.

And please find the code below and suggest any changes so that the
interrupt can be triggered and the control moves into the ISR
handler.

Here IRQ is 5 and IO strating address of H/w is 01020h as given in Qnx
terminal through pci -v command.


#define WALKER_NR_PORTS 16
#define IOBASE 0x1020
#define DMKPC (IOBASE+0x00)

void *int_thread (void *arg);
extern const struct sigevent *isr_handler (void *arg, int id);

#define IRQ5 5
int intrAttach = 0;
struct sigevent event;




int main(int argc, char *argv[]) {
// interupt handler
int iSimpleArg = 0;

ThreadCtl(_NTO_TCTL_IO, NULL);
mmap_device_io(WALKER_NR_PORTS, IOBASE);
pthread_create (NULL, NULL, int_thread, (void *)iSimpleArg);

for(int iLoop = 0; iLoop < 1000; iLoop++)
{
for(int iLoop = 0; iLoop < 1000; iLoop++)
// std::cout<<"\nIam out of Thread";
sleep(2);
}

return EXIT_SUCCESS;
}

////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
void* int_thread (void *arg)
{
std::cout<<“The arg val is :”<<(int)arg;
// enables the IO privilages
ThreadCtl (_NTO_TCTL_IO, NULL);

memset(&event,0,sizeof(event));
event.sigev_notify = SIGEV_INTR;
SIGEV_INTR_INIT(&event);

int errvalue;
int errno;

errno = 0;

// Attach interuupt.
intrAttach = InterruptAttach (IRQ5, isr_handler, &event,
sizeof(event), 0);
if (intrAttach < 0)
{
errvalue = errno;
std::cout<< “The error generated was
%d\n”<< errvalue ;
std::cout<<“That means: %s\n”
<<strerror( errvalue );

}
while (1)
{
int iIntrWaitError = 0;
InterruptWait(0, NULL);

if (iIntrWaitError < 0)
{
//Error occured
}
else
{
if (SIGEV_INTR == event.sigev_notify)
{
//call the object of the class to filter the files.
std::cout<<"\n Interrupt detected.";
}
else
{
// continue this loop
}
}
// at this point, when InterruptWait unblocks,
// the ISR has returned a SIGEV_INTR, indicating
// that some form of work needs to be done.


// …
// do the work
// …
InterruptUnmask(IRQ5, intrAttach);
// if the isr_handler did an InterruptMask, then
// this thread should do an InterruptUnmask to
// allow interrupts from the hardware
}
InterruptDetach(intrAttach);

}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////

const struct sigevent *isr_handler (void *arg, int id)
{
// probably here if iam making a mistake please correct me.
if(!(in16(DMKPC) & 0x1020))
{
return NULL;
}
// Here what is the next step i have to do.
InterruptMask(IRQ5, intrAttach);
return (&event);
}

I am much awaiting for the reply …

-HideAndSeek.

HideAndSeek wrote:

Dear gurus,
In my case also the same problem. The control is not moving into
the ISR handler for USB connection. When i did “pci -v” in
the terminal i got the IRQ as 5.

Before making any comment on the code provided, I’d like to ask if this really is a USB device?

Dear all ,
i also write an interrupt handle for SH (not x86).
and i have also a problem the same …

int main(int argc, char *argv[]) {
int pathID;
int errvalue;
char *name;
struct sigaction sa;

if (-1 == ThreadCtl(_NTO_TCTL_IO, 0))
{
if (verbose)
{
printf("%s: main: ThreadCtl failed\n", argv[0]);
}
return 0;
}
dev=(hcan2_dev_t *) malloc(sizeof(hcan2_dev_t ));
dev->regbase = (uintptr_t)MAP_FAILED;


// parse the command-line options
options(argc, argv);

// make sure the driver isn’t already running
if ((name = malloc(sizeof(DEV_NAME) + 1)) == NULL)
{
fprintf(stderr, “%s: malloc failed\n”, progname);
exit(-1);
}

// sprintf(name, “%s%d”, RESMGR_NAME, adc_channel);
sprintf(name, “%s”, RESMGR_NAME);
single_instance(name);

// allocate and initialize a dispatch structure for use by our main
loop
dev->dpp = dispatch_create();
if (dev->dpp == NULL)
{
fprintf(stderr, “%s: couldn’t dispatch_create: %s\n”,
progname, strerror (errno));
exit(-1);
}

//
// Set up the resource manager attributes structure, we’ll
// use this as a way of passing information to resmgr_attach().
// For now, we just use defaults.
//
memset(&rattr, 0, sizeof (rattr));
rattr.nparts_max = MAX_IOV_SIZE; // max ctp->iov[] size
rattr.msg_max_size = MAX_MSG_SIZE; // max size of a message

//
// Intialize the connect functions and I/O functions tables to
// their defaults and then override the defaults with the
// functions that we are providing.
//
iofunc_func_init(_RESMGR_CONNECT_NFUNCS, &connect_funcs,
_RESMGR_IO_NFUNCS, &io_funcs);

// use our own: open, read, write, and devctl
connect_funcs.open = io_open;
io_funcs.read = io_read;
io_funcs.write = io_write;
io_funcs.devctl = io_devctl;

// set the mode to 0666 (R/W)
// Note leading 0 for octal -------v
iofunc_attr_init(&dev->hdr, S_IFCHR | 0666, NULL, NULL);

//
// Call resmgr_attach to register our prefix with the
// process manager, and also to let it know about our connect
// and I/O functions.
//
// On error, returns -1 and errno is set.
//
sprintf(name, “%s”, DEV_NAME);
dev->id= resmgr_attach(dev->dpp, &rattr, name, _FTYPE_ANY,
0,
&connect_funcs, &io_funcs, &dev->hdr);
if (dev->id == -1)
{
fprintf(stderr, “%s: couldn’t attach pathname: %s\n”,
progname, strerror(errno));
exit(1);
}
free(name);

/allocate a context structure/
dev->ctp = resmgr_context_alloc(dev->dpp);

//
// initialize the HW, map the registers and create driver structures
//
if (!hcan2_hw_init())
{
// HW init failed
fprintf(stderr, “%s: hcan_hw_init failed\n”, progname);
return 0;
}

//Start up a thread that is dedicated to interrupt processing
pthread_create(NULL, NULL, int_thread, NULL);

/Start the recource manager loop/
while (!done) {
if (dev->ctp == resmgr_block(dev->ctp))
resmgr_handler(dev->ctp);
else if (errno != EFAULT)
atomic_set(&done, 1);
}

free(dev);

return 0;
}

void *int_thread(void *arg)
{
int errvalue;
struct sigaction sa;

printf(“In interrupt thread: Attaching the interrupt\n”);

//Enable I/O privilege
ThreadCtl(_NTO_TCTL_IO, NULL);
memset(&dev->intr_event, 0, sizeof(&dev->intr_event));

// Initialize event structure
dev->intr_event.sigev_notify = SIGEV_INTR;
SIGEV_INTR_INIT(&dev->intr_event);


errno = EOK;
fprintf(stderr,“event =0x%04x
\n”,&dev->intr_event);
fprintf(stderr,“before interrupt dev->status=%d
\n”,&dev->status);
//Attach the ISR to IRQ
//interrupt attatch
dev->iid = InterruptAttach(dev->irq, (void*) _hcan2_irq_ser,
&dev,0, 0);

if(dev->iid==-1)
{
printf( “Couldn’t attach dev->irq %d\n”, dev->irq );

exit(-1);
}

fprintf(stderr,“after interrupt dev->status=%d
\n”,&dev->status);

errvalue = errno;
printf( “The error generated was %d\n”, errvalue );
printf( “That means: %s\n”, strerror( errvalue ) );

printf(“wait\n”);

while(!(dev->status & HCAN_STATUS_DONE))
{
InterruptWait(0, NULL);
printf(“received interrupt \n”);
}
InterruptUnmask(dev->irq,dev->iid);
InterruptDetach(dev->iid);


}

const struct sigevent *
_hcan2_irq_ser(void *arg, int iid)
{
hcan2_dev_t *dev=(hcan2_dev_t *)arg;
struct sigevent *event = NULL;
int icntr;
uint16_t whatReg = 0;


event = &dev->intr_event;

InterruptMask(dev->irq,dev->iid);
return (event);
}

when i run . the terminal announce like as:
“out of interrupt event!”
i don’t know why?
please help me
thanks,
tuyndie