EP9302 MAX197
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;
}