Detecting Interrupt

#include <stdio.h>
#include <hw/inout.h> /* for in*() a/nd out*() functions /
#include <sys/neutrino.h> /
for ThreadCtl() */
#include <iostream.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/mman.h>
#include <inttypes.h> //need for uintptr_t type
#include <stdint.h>

using namespace std;

//Hardware specifications
#define COM1 0x3f8
#define IRQ4 4
#define DivisorLow 0x02
#define DivisorHi 0x00
//#define IIR_MASK 0x07
//#define IIR_MSR 0x00
//#define IIR_THE 0x02
//#define IIR_RX 0x04
//#define IIR_LSR 0x06

struct sigevent event;
void* int_thread (void *arg);
const struct sigevent * isr_handler (void *arg, int id);
int intId;
char buffer[1025];
int bufferin = 0;

/* Gain access to device registers */
uintptr_t reg0Id=mmap_device_io (0x01, COM1);
uintptr_t reg1Id=mmap_device_io (0x01, COM1+1);
uintptr_t reg2Id=mmap_device_io (0x01, COM1+2);
uintptr_t reg3Id=mmap_device_io (0x01, COM1+3);
uintptr_t reg4Id=mmap_device_io (0x01, COM1+4);
uintptr_t reg5Id=mmap_device_io (0x01, COM1+5);
uintptr_t reg6Id=mmap_device_io (0x01, COM1+6);
uintptr_t reg7Id=mmap_device_io (0x01, COM1+7);
//IRQ Register??
uintptr_t regIRQ=mmap_device_io (0x01, 0x21);

int main ()
{
// char value;
// perform initializations, etc.
event.sigev_notify = SIGEV_INTR;
// start up a thread that is dedicated to interrupt processing
pthread_create (NULL, NULL, int_thread, NULL);
cout << “I am in main”<<endl;
sleep(500);
}

// this thread is dedicated to handling and managing interrupts
void* int_thread (void *arg)
{
// enable I/O privilege
cout <<“ThreadCTL”<<ThreadCtl (_NTO_TCTL_IO, NULL)<<endl;
//-------initialize the 8250chip, etc.-----------------------
//First disable interrupt-----
out8( (COM1+1), 0x00 );
//Set the DLAB to 1
out8( (COM1+3), 0x80 );
//-------Set baud rate---------
//----------At 57600-----------
out8( (COM1), DivisorLow );
out8( (COM1+1), DivisorHi );
//-------Set Bit Pattern-------
//—8-N-1, No Parity----------
out8( (COM1+3), 0x03 );
//Set FIFO(First In/First Out)-
out8( (COM1+2), 0xc7 );
//Turn on DTR, RTS, and AUX Out2
out8( (COM1+4), 0x0b);
//Set IRQ??
// out8( regIRQ, (in8(0x21) & IRQ4) );
//Enable interrupts on the serial port
//MSR, THE, RX, LSR Interrupts
out8( (COM1+1), 0x0f );
// attach the ISR to IRQ 4
intId=InterruptAttach (IRQ4, isr_handler, NULL, 0, 0);
cout <<“intId”<< intId<<endl;
cout <<“IntUnMask”<< InterruptUnmask (IRQ4, intId)<<endl;

// now service the hardware when the ISR says to
while (1)
{
    InterruptWait (NULL, NULL);

// InterruptUnmask (IRQ4, intId);
cout << “received interrupt” << endl;
}
}

// this is the ISR
const struct sigevent *
isr_handler (void *arg, int id)
{
return (&event);
}

When I said “freed” I meant I have used the mmap_device_io call to gain access to the registers.

While this is probably not important, it might be useful to know that this program will receive at most one interrupt.

Well, I know that it’ll receive interrupt if I don’t slay the devc-ser8250 process. Now that I think of it, I think the problem may be the 8250 chip that I have configured, but I can’t figure out what I’m missing. Is there a way to test my chip configuration without actually causing interrupts? Like, just to see that it can actually transmit data or some sort?

You absolutely can run the chip without interrupts. The whole interrupt mechanism can work without ever firing the processor interrupt line. There is a control bit somewhere that makes this connection. Instead of using interrupts you can poll the status line. For that matter, you can transmit bytes easily without involving an interrupt. The interrupt just tells you when it is ok to load another byte.

Just a quick question…is it possible to write a device driver without the use of io-char library? because I am not. :unamused:

The answer is yes, but in this context it is rather meaningless. Why? Well of course you can write a device driver without the io-char library because you could write your own io-char library, at least in principle.

If you would be writing a serial port driver with io-char you endup rewriting devc-8250, what would be the point?

Okay good, it’s just that I am trying to avoid using the io-char library, but at the same time I read online somewhere that it may be needed, so I was just making sure.

The io-char is used to handle most of the terminal related features, echo, CR/LF conversion, etc as well as all the buffering of input and output data. But it also imposes the POSIX interface which is what you are trying to avoid I guess.

Okay, after this whole time I finally got my code working, at least to start anyways. I forgot to read into the interrupt id registers to reset the interrupt. Before I was trying to use InterruptMask() and InterruptUnmask, but I guess I should of in8() the IIR instead(since that IS what the data sheet I found in wikipedia said :blush:)

I am now able to detect interrupt when I hit keystrokes into hyperterminal.

Next step…send file using xmodem protocol from hyperterminal to QNX.

Thank you for all you guys’ help.

Is this for any kind of purpose other then to learn, because you are reinventing the wheel.

I’m doing this mainly for my professor who doesn’t have time to do this, and to learn at the same time. It is my first time dealing with this kind of stuff so I learned a lot, and plus I am also taking a real-time embedded system course right now so this experience plus the course really combine to give me a lot of knowledge. Not to mention my coding experience in C++ too :slight_smile: .