TS-4200 ADC Core
The ADC core supports the MCP3428 which is an affordable 16-bit ADC board. This is available on several of the TS-Socket baseboards.
This core assumes the standard circuit which allows 2 differential channels and 4 single-ended channels. The single-ended channels are chosen using analog muxes controlled by the AN_SEL line. Since different base boards use a different pin for AN_SEL, a register is also provided to select the correct line. Channels 1 and 2 are differential channels with a range of -2.048V to +2.048V. Channels 3-6 are 0 to 10.24V.
Offset | Bits | Access | Usage |
---|---|---|---|
0x0 | 15-8 | Read Only | Core ID register (0xad) |
7-6 | Read Only | Reserved | |
5-4 | Read/Write | Analog Select
0 = Do not use an AN_SEL <br\> 1 = Use CN1 pin 77 for AN_SEL (TS-81X0) <br\> 2 = Use CN1 pin 74 for AN_SEL (TS-8390) <br\> 3 = Reserved | |
3-2 | Read/Write | Speed
0 = 240Hz, 12 bit resolution | |
1-0 | Read/Write | Programmable Gain
0 = No gain | |
0x2 | 15-0 | Read/Write | Channel Mask |
0x4 | 15-0 | Read Only | Channel 1 most recent conversion value |
0x6 | 15-0 | Read Only | Channel 2 most recent conversion value |
0x8 | 15-0 | Read Only | Channel 3 most recent conversion value |
0xa | 15-0 | Read Only | Channel 4 most recent conversion value |
0xc | 15-0 | Read Only | Channel 5 most recent conversion value |
0xe | 15-0 | Read Only | Channel 6 most recent conversion value |
The channel mask register controls which channels are enabled. Bits 0-5 enable channels 1-6 respectively. If a given channel is not enabled, (enable bit == 0) it will not be sampled and its conversion value register will contain an obsolete and meaningless value. The more channels that are enabled, the lower the sampling speed on each channel.
This example will sample the current value of all ADCs and output them in millivolts.
#include <stdio.h>
#include <stdint.h>
#include <fcntl.h>
#include <sys/mman.h>
volatile uint16_t *fpga = 0;
uint16_t peek16(uint16_t addr)
{
uint16_t value;
if(fpga == 0) {
int mem = open("/dev/mem", O_RDWR|O_SYNC);
fpga = mmap(0,
getpagesize(),
PROT_READ|PROT_WRITE,
MAP_SHARED,
mem,
0x30000000);
}
return fpga[addr/2];
}
void poke16(uint16_t addr, uint16_t value)
{
if(fpga == 0) {
int mem = open("/dev/mem", O_RDWR|O_SYNC);
fpga = mmap(0,
getpagesize(),
PROT_READ|PROT_WRITE,
MAP_SHARED,
mem,
0x30000000);
}
fpga[addr/2] = value;
}
int main()
{
int x, i;
// Select TS-81XX, 15hz, 16-bit resolution with 0x gain
poke16(0x80, 0x18);
// Select TS-8390, 15hz, 16-bit resolution with 0x gain
//poke16(0x80, 0x28);
// unmaks to enable all 6 channels
poke16(0x82, 0x3f);
usleep(500000); // allow time for conversions
for (i = 1; i <= 6; i++) {
x = (signed short)peek16(0x82 + 2*i);
if (i > 2) x = (x * 1006)/200;
x = (x * 2048)/0x8000;
printf("adc%d=%d\n", i, x);
}
return 0;
}