// The original Axis example is available on
// http://developer.axis.com/wiki/doku.php?id=rs485&s=rs485

#include <sys/ioctl.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <asm/ioctls.h>
#include <errno.h>
#include <termios.h>  

// Control struct for setting the port in 485 mode
struct rs485_ctrl {
  unsigned short rts_on_send;
  unsigned short rts_after_sent;
  unsigned int  delay_rts_before_send;
  unsigned short enabled;
};
 
// his struct is only needed if we would like to write with ioctl()
struct rs485_wrt {
  unsigned short outc_size;
  unsigned char *outc;
};
 
int main(void) {

  char dev[] = "/dev/ttyS3";
  char texttosend[] = "FOXBOARD\n\r";
  int  baudrate = B9600;

  unsigned char buf[100];
  struct rs485_ctrl ctrl485;
  int status;
  int fd;
  int size;
  struct termios ti;
  struct termios ti_prev;
  
  // Open the serial port
  fd = open(dev, O_RDWR|O_NONBLOCK);
  if (fd < 0) {
    printf("ERROR! Failed to open %s\n", dev);
    return -1;
  }
 
  // Set the serial port in 485 mode
  ctrl485.rts_on_send = 0;           // It means that DE is at 3.3 volt on send
  ctrl485.rts_after_sent = 1;        // It means that DE is at 0 volt on send
  ctrl485.delay_rts_before_send = 0; // DE will be active at same time of data
  ctrl485.enabled = 1;
  status = ioctl(fd, TIOCSERSETRS485, &ctrl485);  
  if (status) {
    printf("ERROR PORT 1! TIOCSERSETRS485 failed %i", status);
    return -1;
  }
 
  tcgetattr(fd, &ti_prev);    // Save the previous serial config
  tcgetattr(fd, &ti);         // Read the previous serial config
  cfsetospeed(&ti,baudrate);  // Set the TX baud rate
  cfsetispeed(&ti,baudrate);  // Set the RX baud rate

  cfmakeraw(&ti);
  tcsetattr(fd, TCSANOW, &ti);  // Set the new serial config
 
  // Send a text to RS485
  if (write(fd, texttosend, strlen(texttosend)) != strlen(texttosend)) {
    printf("ERROR! write() failed \r\n");
  }

  // Wait to receive an answer
  sleep(10);
  
  // Read the answer from RS485
  size = read(fd, buf, sizeof(buf)-1);
  if (size > 0) {
    buf[size]=0;
    printf("Read the following %d byte(s): %s \r\n", size, buf);
  } else if (size == 0) { 
    printf("End of file... \r\n");
  } else { 
    // EAGAIN indicates that no new data is available
    if (errno != EAGAIN) { 
      printf("ERROR reading %s: %i %m\r\n", dev, errno);
    }
  }

  ti_prev.c_cflag &= ~HUPCL;        // This to release the RTS after close
  tcsetattr(fd, TCSANOW, &ti_prev); // Restore the previous serial config
  close(fd);

  return 0;
}

