/* A program to read out an ADC 08031 from the parallel port. Currently hooked up: 6 LEDs on the data pins D0...D5 ADC's chipselect on D6 (pc->adc), clock on D7 (pc->adc), data out on BUSY (adc->pc) Software by Michiel Overtoom, motoom@xs4all.nl, november 2007 Uses FreeBSD's ppi 'geek' interface */#include <stdio.h>#include <errno.h>#include <stdlib.h>#include <fcntl.h>#include <sys/ioctl.h>#include <time.h>#include <dev/ppbus/ppi.h>#include <dev/ppbus/ppbconf.h>/* Handle of parallel port /dev/ppiN */int fd=-1;/* mirrors current value of data port */u_int8_t val=0;/* current value of status port */u_int8_t inval=0;// Chip select to ADC 08031void cs(int hi){ if (hi) val|=0x40; else val&=0xbf; ioctl(fd,PPISDATA,&val);}// Clock to ADC 08031void clk(int hi){ if (hi) val|=0x80; else val&=0x7f; ioctl(fd,PPISDATA,&val);}// LEDs are on D0...D5void leds(unsigned char ledpart){ ledpart&=0x3F; val&=0xC0; val|=ledpart; ioctl(fd,PPISDATA,&val);}// Data out from ADC 08031int d0(void){ ioctl(fd,PPIGSTATUS,&inval); return (inval&0x80)==0; // high bit of status port is the BUSY line, which is active low}main(){ char *device="/dev/ppi0"; fd=open("/dev/ppi0",O_RDWR); if (fd==-1) { printf("Can't open %s: %s\n",device,strerror(errno)); exit(1); } // Initialize; data port 0, CS and CLK high val=0; cs(1); clk(1); usleep(100000); for (;;) { printf("Start conversion: "); // start conversion clk(0); cs(0); clk(1); clk(0); int i; unsigned char adc=0; for (i=0;i<8;i++) { adc<<=1; clk(1); clk(0); if (d0()) { adc|=1; printf("1"); } else printf("0"); } printf(" 0x%02X %3d\n",adc,adc); // end of conversion, return to normal cs(1); clk(1); // display result on LEDs int lit=adc*6/255; unsigned char ledval=0; for (i=0;i<lit;i++) { ledval<<=1; ledval|=1; } leds(ledval); // wait a bit and do it again usleep(100000); } close(fd); exit(0);}// TODO: Push it to the max. The ADC 08031 still works at a clock of of 1.750 Mhz.