/*********** Program to Read the Data from MAX187 *************/
/* You  compile  with -O or -O2 or similar. The functions are
   defined as inline macros, and will not be  substituted  in
   without  optimization  enabled,  causing unresolved refer­
   ences at link time.
*/

#include <stdio.h>
#include <stdlib.h>
#include <sys/io.h>
#include <unistd.h>

/* Base addresses of parallel ports */
#define LPT1 0x378
#define LPT2 0x278
#define LPT3 0x3BC


void usage(void)
  {
  printf("Syntax : getadc <portnum> \n\n");
  printf("portnum: 1, 2 or 3 for LPT1, LPT2 or LPT3.\n");
  printf("returns: analog value\n");
  printf("         or -1 if an error occurs\n\n");
  exit(-1);
  }

int main(int argc, char *argv[])
  {
  int status = 0;        /* data from port */
  int sclk;              /* step counter */
  int adc_val;           /* ADC value */
  
  int BASEPORT = LPT1;   /* base io port */

  if (argc != 2) usage();
  switch (argv[1][0])
    {
    case '1': BASEPORT = LPT1; break;
    case '2': BASEPORT = LPT2; break;
    case '3': BASEPORT = LPT3; break;
    default: usage();
    }

  /* Get access to the ports */
  if (ioperm(BASEPORT, 3, 1))
    { perror("Error: cannot access ioport"); exit(255); }

  /* make CS high, SCLK low */
  outb(0x80, BASEPORT);
  /* enable ADC - CS low, SCLK low */
  outb(0x00, BASEPORT);
  /* Check for the EOC, bit is inverted */
  do
    {
    status = (inb(BASEPORT + 1) ^ 0x80);
    } while ((status & 0x80) != 0);
  /* make CS low, SCLK high */
  outb(0x01, BASEPORT);
  /* make SCLK  low, to get first bit at the falling edge of th clock */
  outb(0x00, BASEPORT);
  adc_val= 0;
  for (sclk = 11; sclk >= 0; sclk--)
    {
    /* make SCLK high, data bit to be read at this point; CS remains low */
    outb(0x01, BASEPORT);
    status = (inb(BASEPORT + 1) ^ 0x80);
    if (status ==  0x80 )
      adc_val = adc_val + (1 << sclk);
    /* make SCLK low, for next data bit */
    outb(0x00, BASEPORT);
	}

  /* We don't need the ports anymore */
  if (ioperm(BASEPORT, 3, 0))
    { perror("Error: cannot access ioport"); exit(255); }

  /* return result */
  return(adc_val);
  }

