TS-4200 ADC Core: Difference between revisions
(Created page with "The ADC core supports the MCP3428 which is an affordable 16-bit ADC board. We use this on several of our TS-Socket baseboards. Typically you will just access this using ts42...") |
No edit summary |
||
Line 83: | Line 83: | ||
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. | 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. | |||
<source lang=c> | |||
#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; | |||
} | |||
</source> |
Revision as of 09:38, 14 June 2013
The ADC core supports the MCP3428 which is an affordable 16-bit ADC board. We use this on several of our TS-Socket baseboards. Typically you will just access this using ts4200ctl.
ts4200ctl --adc
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;
}