/*********** Program to send Data to the MAX530 *************/
/* 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.
*/

/* 
   PC data port is connected to the DAC data port (8 bit mode)
   PC control port ist used as:
   port bit    DAC pin
     C0          A0
     C1          A1
     C2          /WR
*/     

#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 :setdac <portnum> <value>\n\n");
  printf("portnum: 1, 2 or 3 for LPT1, LPT2 or LPT3.\n");
  printf("value: analog value - 0...4095.\n");
  printf("returns: -1 if an error occurs\n\n");
  exit(-1);
  }

int main(int argc, char *argv[])
  {
  int value = 0;       /* DAC value */
  int control;
  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 */
  value = atoi(argv[2]) % 4096;

  /* Get access to the ports */
  if (ioperm(BASEPORT, 3, 1))
    { perror("Error: cannot access ioport"); exit(255); }

  control = 0x1F;                       /* set all bits to 1 */
  outb(control ^ 0x0B, BASEPORT + 2);  
 
  /* low data, 8 bits */
  control = 4;                          /* A0 = A1 = 0, WR = 1 */
  outb(control ^ 0x0B, BASEPORT + 2);  
  outb(value % 256, BASEPORT);          /* D0 ... D7 */
  control = 0;                          /* A0 = A1 = 0, WR = 0 */
  outb(control ^ 0x0B, BASEPORT + 2);
  /* high data, 4 bits */
  control = 7;                          /* A0 = A1 = 1, WR = 1 */
  outb(control ^ 0x0B, BASEPORT + 2);  
  outb(value / 256, BASEPORT);          /* D8 ... D11 */
  control = 3;                          /* A0 = A1 = 1, WR = 0 */
  outb(control ^ 0x0B, BASEPORT + 2);
  /* standby */
  control = 0x1F;                       /* set all bits to 1 */
  outb(control ^ 0x0B, BASEPORT + 2);  

  /* We don't need the ports anymore */
  if (ioperm(BASEPORT, 3, 0))
    { perror("Error: cannot access ioport"); exit(255); }

  /* return result */
  return(0);
  }

