#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/termios.h>
#include <sys/io.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>

char device[] = "/dev/ttyUSB0";

int open_port(char *device)
  {
  /*
   * Oeffnet seriellen Port
   * Gibt das Filehandle zurueck oder -1 bei Fehler
   *
   * RS232-Parameter
   * - 115200 baud
   * - 8 bits/byte
   * - no parity
   * - no handshake
   * - 1 stop bit
   */
   int fd;
   struct termios options;
   
   fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY); 
   if (fd >= 0)
     {
     /* get the current options */
     if (ioctl(fd,TIOCEXCL) != 0)      return(-1);
     if (fcntl(fd, F_SETFL, 0) != 0)   return(-2);
     if (tcgetattr(fd, &options) != 0) return(-3);
     bzero(&options, sizeof(options)); /* Structure loeschen */

     cfsetspeed(&options, B115200);      /* setze 115200 bps */

     /* setze Optionen */
     options.c_cflag &= ~PARENB;         /* kein Paritybit */
     options.c_cflag &= ~CSTOPB;         /* 1 Stoppbit */
     options.c_cflag &= ~CSIZE;          /* 8 Datenbits */
     options.c_cflag |= CS8;
     options.c_cflag |= (CLOCAL | CREAD);/* CD-Signal ignorieren */
     /* Kein Echo, keine Steuerzeichen, keine Interrupts */
     options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
     options.c_oflag &= ~OPOST;          /* setze "raw" Input */
     options.c_cc[VMIN]  = 2;            /* warten auf min. 2 Zeichen */
     options.c_cc[VTIME] = 10;           /* Timeout 1 Sekunde */
     tcflush(fd,TCIOFLUSH);
     if (tcsetattr(fd, TCSAFLUSH, &options) != 0) return(-4);

     fcntl(fd, F_SETFL, FNDELAY);
     fcntl(fd, F_SETFL, 0);
     /* Init Interface: Binary Mode */
     }
  return(fd);
  }

int send_command(int fd, char command)
  {
  /* Kommando an den dlp_io8 senden */
  int result;
  result = write(fd, &command,1);
  return(result);
  }
  
float get_analog(int fd, int channel)
  {
  /* Analogwert von dlp_io8 einlesen und in Spannung umrechnen     */
  /* Der dlp_io8 muss vorher auf Binaerausgabe eingestellt werden  */
  /* (Kommando '\\')                                               */
  unsigned char buffer[100];
  float fvalue;
  int got, intvalue;
  /* Kanalzuordnung: */
  char chan[9] = {'-','Z','X','C','V','B','N','M',','};
  /* Channel       -   1   2   3   4   5   6   7   8    */
  if ((channel < 1) || (channel > 8)) return(-1);
  /* flush IO-Buffers */
  if (tcflush(fd,TCIOFLUSH) != 0) return(-1); 
  send_command(fd,chan[channel]);          /* start conversion */
  got = read(fd,buffer, sizeof(buffer));   /* 2 Byte lesen */
  if (got < 2) return(-1);
  intvalue = buffer[0] * 256 + buffer[1];
  /* Umrechnung in Spannung: Uref = 5 V, Aufloesung 10 Bit, also: */
  fvalue = intvalue * 5.0 / 1023.0;
  return(fvalue);
  }
  
/* Demo-/Testprogramm */
int main(void)
  {
  int i, fd, res;
  float wert;
  
  fd = open_port(device);
  if (fd < 0)
    {
    printf("Fehler beim Oeffnen: %d\n", fd);
    exit(1);
    }
  res = send_command(fd,'\\'); /* set binary output */
  while (1)
    {
    /* 8 Kanaele anzeigen */
    for (i=1; i<9; i++)
      {
      wert = get_analog(fd,i);
      printf("Kanal %d: %6.2f V\n", i, wert);
      }
    printf("\n");
    sleep(1);
    }
  return(0);
  }
 
