#include <linux/serial.h>
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>

int fd;

typedef unsigned char uchar;
int getstat()
{
  int s;
  ioctl(fd, TIOCMGET, &s);
  return s;
}

void setstat(int s)
{
  ioctl(fd, TIOCMSET, &s);
}

void init()
{
  struct termios ti;
  struct serial_struct snew;
  fd=open ("/dev/ttyS0" , O_RDWR | O_NOCTTY | O_NDELAY| O_SYNC);
  if(fd==-1)
    exit(1);
  ioctl(fd, TIOCGSERIAL,&snew);
  snew.flags |= ASYNC_LOW_LATENCY;
  ioctl(fd, TIOCSSERIAL,&snew);

  close(fd);
  fd=open ("/dev/ttyS0" , O_RDWR | O_NOCTTY | O_NDELAY| O_SYNC);
  if(fd==-1)
    exit(1);


  ti.c_cflag = B9600 | CS8 | CLOCAL | CREAD ;
  ti.c_iflag = IGNBRK | INPCK | ISIG ;
  ti.c_oflag = 0;
  ti.c_lflag = 0;
  ti.c_cc[VTIME] = 1;
  ti.c_cc[VMIN] = 0;

  tcsetattr( fd, TCSAFLUSH, &ti );

  printf("Presync\n");
  setstat(getstat()&~(TIOCM_RTS|TIOCM_CTS));
  while((getstat()&TIOCM_CTS));
}


int startsync()
{
  int to=0;
  int s=getstat();
  setstat(s|TIOCM_RTS);
  while(!(getstat()&TIOCM_CTS))
    {
      to++;
      if(to>0x10000)
	return 1;
    }
  printf("Startsync");
  return 0;
}
int endsync()
{
  int to=0;
  int s=getstat();

  setstat(s&~TIOCM_RTS);
  while((getstat()&TIOCM_CTS))
    {
      to++;
      if(to>0x10000)
	return 1;
    }
  printf("Endsync");
  return 0;
}

int exchange(uchar c)
{
  uchar s;
  int i;
  int to=0;

  write(fd,&c,1);
  while((i=read(fd,&s,1))==-1)
    {
      to++;
      if(to>0x10000)
        return -1;
    }

  printf("exchange %02X <->%02X",c,s);
  return s;
}

int main()
{
  init();
  printf("Init\n");
  while(1)
    {
      uchar s=0xff;
      printf("Start\n");
      if(startsync())continue;
      if(exchange(s)==-1)continue;
      if(endsync())continue;
    }
}
