Serial port programming in Linux
Hi, currently I'm working on a device that was attached to a serial port (ttyS0). The device can be used as I/O to and from the computer. The input is in a form of buttons while the output is in a form of LEDs. Currently I'm still working on the output.
I added SDL as a event handler so every time I clicked a mouse, it will blink if it was turned off or vice versa. The blinking was done by sending "fls 1 1 1\r" to the device, and turned off by sending "turnoff 1\r". The funny thing was I have to click numerous time until the mode toggle itself. For example:
Quote:
State 1: LED turned off
> Mouse click --> mode = 1, sent "fls 1 1 1\r" to device, still in state 1
> Mouse click --> mode = 0, sent "turnoff 1\r" to device, still in state 1
> Mouse click --> mode = 1, sent "fls 1 1 1\r" to device, change to state 2
State 2: LED blinked
> Mouse click --> mode = 0, sent "turnoff 1\r" to device, still in state 2
> Mouse click --> mode = 1, sent "fls 1 1 1\r" to device, still in state 2
> Mouse click --> mode = 0, sent "turnoff 1\r" to device, still in state 2
> Mouse click --> mode = 1, sent "fls 1 1 1\r" to device, still in state 2
> Mouse click --> mode = 0, sent "turnoff 1\r" to device, change to state 1
State 1: LED turned off
...
The behaviour is not always like that. Sometimes I have to click multiple times to change the state, but sometimes one click is just what it needed. Why is this happening? BTW, my initialization step is:
Code:
#define BAUDRATE B4800
#define STOPBITS 0
#define PARITY 0
#define PARITYON 0
int fd,c, res;
struct termios oldtio,newtio;
struct sigaction saio; /* definition of signal action */
char buf[255];
fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NONBLOCK | O_NDELAY );
if (fd <0)
{
perror("/dev/ttyS0");
exit(-1);
}
saio.sa_handler = signal_handler_IO;
sigemptyset(&saio.sa_mask); //saio.sa_mask = 0;
saio.sa_flags = 0;
saio.sa_restorer = NULL;
sigaction(SIGIO,&saio,NULL);
fcntl(fd, F_SETOWN, getpid());
fcntl(fd, F_SETFL, FASYNC);
tcgetattr(fd,&oldtio); /* save current serial port settings */
bzero(&newtio, sizeof(newtio)); /* clear struct for new port settings */
newtio.c_cflag = BAUDRATE | CS8 | STOPBITS| PARITY |PARITYON | CLOCAL | CREAD ;
newtio.c_iflag = IGNPAR | ICRNL;
//newtio.c_oflag = 0;
newtio.c_oflag = OPOST|ONLCR;
newtio.c_lflag = ICANON;// | ECHO | ECHOE;
tcflush(fd, TCIFLUSH);
tcsetattr(fd,TCSANOW,&newtio);