EP9302 MAX197

From Technologic Systems Manuals

The TS-7200 supports an optional eight-channel, 12-bit A/D converter (ADC) with a conversion time of 12 uS. This will allow up to 60,000 samples per second. Each channel is independently software programmable for a variety of analog input ranges: -10V to +10V, -5V to +5V, 0V to +10V, or 0V to +5V. This allows an effective dynamic range of 14 bits.

The datasheet for the MAX197 is available here.

I/O Address Access Description
0x10F0_0000 Write Only Initiate A/D Conversion
0x10F0_0000 Read Only LSB of Conversion
0x10F0_0001 Read Only MSB of Conversion
0x2240_0000 Read Only Bit 0 = 1 if OP-ADC is installed
0x1080_0000 Read Only Bit 7 = 0 when conversion completed.

Each channel is overvoltage tolerant from -16V to + 16V, and a fault condition on any channel will not affect the conversion result of the selected channel. This is all accomplished with a 5V only power supply; no negative supply voltage is required. The Maxim MAX197 chip can be replaced with a MAX199 chip if a lower range of analog input levels is required (-4V to +4V, -2V to +2V, 0V to 4V, and 0V to 2V).

A/D Convrol Register 0x10f0_0000 (Write Only)

Bit Description Details
0-2 Analog Channel Select Channels 0-7
3 Unipolar / Bipolar 0 = Unipolar (0-5V)

1 = Bipolar (-5v to +5v)

4 Range Select 0 = 5V range

1 = 10V range

5-7 Mode Bits 0, 1, 0

This example program assumes a test fixture is attached to the A/D header with 2.35 VDC on all even channels and 1.18 VDC on all odd channels. This test uses a 0-10V unipolar. Therefore even channels are nominally 22% (21.5-22.5 => good) and odd channels are nominally 11% (10.5-11.5 => good).

#include<unistd.h>
#include<sys/types.h>
#include<sys/mman.h>
#include<stdio.h>
#include<fcntl.h>
#include<assert.h>
#include<time.h>
#include<stdlib.h>

#define PLD_ATOD_SET     0x01		//bit0 at OPTIONS
#define OPTIONS          0x22400000		
#define CTRL_BYTE        0x10f00000
#define BUSY             0x10800000
#define CHANNEL_0        0x50
#define CHANNEL_7        0x57
#define BUSYBIT          0x80

int main(int argc, char **argv) 
{
	volatile unsigned char *options, *controlByte, *busy;
	unsigned char *registerValue;
	unsigned short *results;
	double percentage;
	int ctrlByte, n;
	int fd = open("/dev/mem", O_RDWR|O_SYNC);
	assert(fd != -1);
		
	setvbuf(stdout, NULL, _IONBF, 0);

	/* Lets intialize our pointers */
	options = mmap(0, getpagesize(), PROT_READ|PROT_WRITE, MAP_SHARED, fd,
	  OPTIONS);
	assert(options != MAP_FAILED);
	controlByte = mmap(0, getpagesize(), PROT_READ|PROT_WRITE, MAP_SHARED,
	  fd, CTRL_BYTE);
	assert(controlByte != MAP_FAILED);
	busy = mmap(0, getpagesize(), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 
	  BUSY);
	assert(busy != MAP_FAILED);

	printf("checking if MAX197-ADC option is set...");
	registerValue = (unsigned char *)options;
	if( *registerValue & PLD_ATOD_SET ) {
		printf("ok\n"); 
	} else {
		printf("FAIL, not set\n");
		return 1;
	}

	/* Lets go do the conversions */
	for( ctrlByte = CHANNEL_0; ctrlByte <= CHANNEL_7; ctrlByte++)
	{
		//lets write out our control byte	
		*controlByte = ctrlByte;

		printf("waiting for ADC to respond on channel %d...",
		  ctrlByte - CHANNEL_0);
		//lets poll the busy bit to determine when the conversion is done
		registerValue = (unsigned char *)busy;

		n = 0; 
		while(n < 14 && (*registerValue & BUSYBIT) != 0x0) {
			usleep(1 << n);
			n++;
		}
		if (n == 14) {
			printf("FAIL, timed out\n");
			return 4;
		} else {
			printf("ok\n");
		}
	
		printf("reading result...");
		results = (unsigned short *) controlByte;	
		percentage = (((double) *results) * 100) / 4096;
	
		if( (ctrlByte - 0x10) % 2 ==0 ) //even number channel
		{
			if(percentage < 21.5 || percentage > 22.5) {
				printf("FAIL, got %3.1f%% "
				  "(should be 20%% - 24%%)\n", percentage);
				return 2;
			} else {
				printf("ok\n");
			}
		} else { //odd number channel
			if(percentage < 10.5 || percentage > 11.5) {
				printf("FAIL, got %3.1f%% "
				  "(should be 9%% - 13%%)\n", percentage);
				return 3;
			} else {
				printf("ok\n");
			}
		}
	}
	return 0;
}