/*
 * ad.c: very simple example of port I/O
 *
 * This code reads the 16 inputs of a connected 12-bit io-card
 * Compile with `gcc -O2 -lm -o adwandler adwandler.daemon.c`
 *
 * First written by Michael Moeller (moeller.heinemann@t-online.de
 * Adapted by Olaf Schultz (O.Schultz@tu-harburg.de) on the RTX03B
 * Status: Not userfriendly, need recompile but the output is flexibel
 * Further documentation: Should be found on http://experte.kt2.tu-harburg.de:8015
 */

#include <stdio.h>
#include <unistd.h>
#include <asm/io.h>
#include <math.h>
#include <time.h>

#define datei		"/tmp/adwandler_out.dat"
#define BASEPORT	0x200 		/* Portadresse der Karte */
#define AD_CHANNEL	(BASEPORT + 0)
#define AD_LOWBYTE	(BASEPORT + 1)
#define AD_HIGHBYTE	(BASEPORT + 2)
#define AD_SETZERO	(BASEPORT + 3)
#define AD_readf	(BASEPORT + 4)
#define AD_reads	(BASEPORT + 5)
#define DA_LOWBYTE	(BASEPORT + 6)
#define DA_HIGHBYTE	(BASEPORT + 7)
#define LOOPS		1		/* Anzahl der Messungen pro Output */
#define OFFSET		0		/* 0 Volt Fusspunkt */
#define MOVE		8		/* 7 fuer RTX-03A, 8 fuer RTX-03B */	
#define SAMPLES		1000		/* Anzahl der abzuholenden Samples
					 0 fuer Dauerwandlung bis Abbruch */

int main()
{
  double spannung;
  int highbyte;
  int lowbyte;
  int channel;
  int i;
  int a;
  int k;
  int ns; 				/* Laufzahl der Samples */
  FILE *protokoll;
  time_t sekunden;
  time_t sekunden_s;
   
   printf("Initialisieren ...");
  
  /* get access to the ports */
  if (ioperm(BASEPORT,8,1)) {perror("ioperm");exit(1);}
  
   printf("komplett\n");
  sekunden_s = time((time_t *) 0);

  protokoll = fopen(datei, "a"); 
  fprintf (protokoll, "\n#Ausgabe aus der Conrad AD-Wandlerkarte\n#Zeit\tSample\tch 1\tch 2\tch 3\tch 4\tch 5\tch 6\tch 7\tch 8\tch 9\tch 10\tch 11 \tch 12\tch 13\tch 14\tch 15\tch 16");

  for (ns=0;ns<SAMPLES;ns++)		/* Wandlungen durchfuehren */
  {
    sekunden = time((time_t *) 0)-sekunden_s;
    printf( "\nSample: %i,", ns); 
    fprintf(protokoll, "\n%i", ns); 
    printf("\t%lu Sekunden\t", sekunden);
    fprintf(protokoll, "\t%lu", sekunden);
    					/* Auslesen der Kanaele */
    for (channel = 0; channel < 4; channel++)
    {
       printf(" Kanal %i:", channel);
//       fprintf(protokoll, "\t Kanal %i:", channel);
	outb(0,AD_SETZERO);		/* Schieberegister loeschen */
	outb(channel,AD_CHANNEL);	/* Anwahl des Kanals */
	a = 0;

       for (i = 0; i < MOVE; i++)	/* Low-Byte digitalisieren */
	 {
	    a = inb(AD_readf);
	    usleep(10);		/* verzoeg. fuer den Wandler */
	 }
       for (i = 0; i < MOVE; i++) 	/* High-Byte digitalisieren */
	 {
	    a = inb(AD_reads);
	    usleep(10);		/* verzoeg. fuer den Wandler */
	 }
       highbyte = inb(AD_HIGHBYTE);
       lowbyte = inb(AD_LOWBYTE) ;
    
//     printf("hb %i lb %i ", highbyte, lowbyte);
     a = (highbyte & 0x3f)*256  + lowbyte ;
//     printf("a %i ", a);
     spannung = (float) a*8.5/8192-8.5;		/* -8.5 -- 8,5 V Bipolar */
//     spannung = (float) a*8.5/2/8192;		/* 0 -- 8,5 V Unipolar */
          
     
     printf( "%7.4f\n", spannung);       
     fprintf(protokoll, "\t%7.4f", spannung);
    }
       fflush(protokoll);
   usleep(1);				/* Wartezeit bis zum naechsten Wandler
   					durchlauf */

  }

/* We don't need the ports anymore */
if (ioperm(BASEPORT,3,0)) {perror("ioperm");exit(1);}

exit(0);
}

/* end of adwandler.daemon.c */

