/*********** Program to Read the Data from MAX158 *************/
/* 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> <channel>\n\n");
  printf("portnum: 1, 2 or 3 for LPT1, LPT2 or LPT3.\n");
  printf("channel: analog channel - 0...7.\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 channel = 0;       /* ADC channel */
  int temp;
  int BASEPORT = LPT1;   /* base io port */

  if (argc != 3) usage();
  switch (argv[1][0])
    {
    case '1': BASEPORT = LPT1; break;
    case '2': BASEPORT = LPT2; break;
    case '3': BASEPORT = LPT3; break;
    default: usage();
    }

  /* get channel, cut to range 0..7 */
  channel = atoi(argv[2]) % 8;

  /* Get access to the ports */
  if (ioperm(BASEPORT, 3, 1))
    { perror("Error: cannot access ioport"); exit(255); }

  /* disable ADC */
  outb(0xFF, BASEPORT);
  /* set channel (D3 remains high) */
  outb(channel | 0x08, BASEPORT);
  /* Start conversion , D3 goes low */
  outb(channel & 0x07, BASEPORT);
  /* Check for the ADC_Rdy Line Status coming low */
  do
    {
    status = ((inb(BASEPORT + 1) ^ 0x80) >> 3);
    } while ((status & 0x10) != 0);
  /* Read the digital data, low nibble */
  outb(channel & 0x07, BASEPORT);
  temp = ((inb(BASEPORT + 1) ^ 0x80) >> 3);
  /* Read the digital data, high nibble */
  outb((channel & 0x07) | 0x10, BASEPORT);
  status = ((inb(BASEPORT + 1) ^ 0x80) >> 3);
  /* combine nibbles */
  status = (status << 4) + temp;
  /* disable ADC */
  outb(0xFF, BASEPORT);

  /* We don't need the ports anymore */
  if (ioperm(BASEPORT, 3, 0))
    { perror("Error: cannot access ioport"); exit(255); }

  /* return result */
  return(status);
  }
