devc-ser & interrupts

I have a pice of hardware which communicates with PC via a serial port. The hardware sends a signal to let PC know that it has valid data ready to be read. So I decided to use the CTS line to handle that signal via interrupt service. I also decided to use the RTS line as a chip select. The problem is that the interrupt always occurs when a byte has been sent or received
and when the CTS line state has been changed. I need the interrupt only from CTS line. I’ve tried to avoid unwanted interrupts using InterruptMask() but it doesn’t work. What is wrong?

This is what I do:

I have a null-modem cable connection between ports.

/*************************************************/

This main() makes a transition on the RTS (and CTS) line.

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

OpenPort("/dev/ser1", PORT_BAUD_9600);	
while(1){
	SetRTS(RTS_OFF);
	GetRTS();
	sleep(2);		
	SetRTS(RTS_ON);
	GetRTS();
	sleep(2);		
}

ClosePort();

return EXIT_SUCCESS;

}

/*************************************************/

struct sigevent event;

//interrupt handler
const struct sigevent *IRQHandler(void *_arg, int _id){

return (&event);

}

//interrupt service thread
void *intr_service(void *arg){
int cnt = 0;
int CTS_cnt = 0;
int last_state = 0;
int current_state = 0;
int intr_id = 0;
unsigned char string[5] = {40,41,42,43,44};

ThreadCtl (_NTO_TCTL_IO, NULL);
intr_id = InterruptAttach (3, IRQHandler, NULL, 0,     _NTO_INTR_FLAGS_TRK_MSK);

while (1){
    InterruptWait (NULL, NULL);
InterruptMask(3, intr_id); 
memset(buff, 0, 10);       
    current_state = GetCTS();
cnt++;         
printf("interrupt counter %d\n", cnt);
    if( (!last_state) && (current_state) ){
	CTS_cnt++;  
	printf("CTS counter: %d\n", CTS_cnt);			
	WritePort(string, sizeof(string)); ///contains write()
    }
    last_state = current_state;
InterruptUnmask(3, intr_id);
}

}

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

SIGEV_INTR_INIT(&event);

pthread_create (NULL, NULL, intr_service, NULL);	
OpenPort("/dev/ser2", PORT_BAUD_9600);
while(1){
	GetCTS();
	sleep(1);		
}
ClosePort();
return EXIT_SUCCESS;

}

This is what I get:

from first main()

RTS is NOT set
RTS is SET!
RTS is NOT set
RTS is SET!
RTS is NOT set
RTS is SET!

from second main()

CTS is NOT set
interrupt counter 1
CTS is SET
interrupt counter 2
CTS counter: 1
CTS is SET
// here system’s write() is being called
interrupt counter 3
CTS is SET
interrupt counter 4
CTS is SET
interrupt counter 5
CTS is SET
interrupt counter 6
CTS is SET
interrupt counter 7
CTS is SET
CTS counter: 1
CTS is SET
CTS counter: 1
CTS is NOT set
interrupt counter 8
CTS is SET
interrupt counter 9
CTS counter: 2
CTS is SET
interrupt counter 10
CTS is SET
interrupt counter 11
CTS is SET
interrupt counter 12
CTS is SET
interrupt counter 13
CTS is SET
interrupt counter 14
CTS is SET
CTS counter: 2

It looks InterruptMask() hasn’t blocked the interrupt. Why???

You make reference to /dev/ser1. It’s a VERY bad idea to have to process accessing the same hardware…

That is right. So can’t I use open() and manipulate RTS and CTS lines at the same time? What if I want to send/receive data and use RTS and CTS lines additionally?

Yes you can read/write and control RTS, but you must use the standard Posix APIs provided, and you shouldn’t attach to the interrupt handler.

This page seems to cover things pretty well.

lafn.org/~dave/linux/Serial- … -HOWTO.txt

I’ve read this document and still I can’t figure out how to use hardware flow control to do that the same way without an interrupt service. Can someone give me a simple code example? I would like to avoid polling CTS and I want a thread to be blocked waiting for a transition on CTS. I need a kind of notification like an event or a signal to tell a thread that it can send a frame requesting valid data form an external hardware and read them.