4700 ADC: Difference between revisions
(Created page with "The FPGA includes a core for communicating with the MCP3428 ADC controller we use on several of our baseboards. If you are using this on your own baseboard this core assumes ...") |
No edit summary |
||
Line 1: | Line 1: | ||
The FPGA includes a core for communicating with the MCP3428 ADC controller we use on several of our baseboards. If you are using this on your own baseboard 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 baseboards use a different pin for AN_SEL, a register is also provided to select the correct lines. Channels 1 and 2 are differential channels with a range of -2.048V to +2.048V. Channels 3-6 are 0 to 10.24V. | The FPGA includes a core for communicating with the MCP3428 ADC controller we use on several of our baseboards. If you are using this on your own baseboard 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 baseboards use a different pin for AN_SEL, a register is also provided to select the correct lines. Channels 1 and 2 are differential channels with a range of -2.048V to +2.048V. Channels 3-6 are 0 to 10.24V. | ||
Our default core shipped with the TS-4710 does not include support for ADC. Support can be included with this [ftp://ftp.embeddedarm.com/ts-socket-macrocontrollers/ts-4710-linux/binaries/ts-bitstreams/ts4710-fpga-rev3-default-ADC.vme.bz2 opencore bitstream]. See the [[#FPGA|FPGA]] section for more information on loading this bitstream, or building a custom one. | |||
This example prints out all 6 ADC readings in millivolts: | This example prints out all 6 ADC readings in millivolts: |
Revision as of 11:35, 13 March 2014
The FPGA includes a core for communicating with the MCP3428 ADC controller we use on several of our baseboards. If you are using this on your own baseboard 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 baseboards use a different pin for AN_SEL, a register is also provided to select the correct lines. Channels 1 and 2 are differential channels with a range of -2.048V to +2.048V. Channels 3-6 are 0 to 10.24V.
Our default core shipped with the TS-4710 does not include support for ADC. Support can be included with this opencore bitstream. See the FPGA section for more information on loading this bitstream, or building a custom one.
This example prints out all 6 ADC readings in millivolts:
#include <stdio.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <assert.h>
#include <fcntl.h>
#define peek16(adr) PEEK16((unsigned long)&syscon[(adr)/2])
#define poke16(adr, val) POKE16((unsigned long)&syscon[(adr)/2],(val))
static volatile unsigned short *syscon;
static inline unsigned short PEEK16(unsigned long addr) {
unsigned short ret;
asm volatile (
"ldrh %0, [ %1 ]\n"
: "=r" (ret)
: "r" (addr)
: "memory"
);
return ret;
}
static inline void POKE16(unsigned long addr, unsigned short dat) {
asm volatile (
"strh %1, [ %0 ]\n"
:
: "r" (addr), "r" (dat)
: "memory"
);
}
int main()
{
int x, i, devmem;
// Map the Syscon core
devmem = open("/dev/mem", O_RDWR|O_SYNC);
assert(devmem != -1);
syscon = (unsigned short *) mmap(0, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, devmem, 0x80004000);
//// Select AN_SEL line:
//// If you have a TS-TPC-8390 baseboard:
poke16(0x400, 0x28);
//// TS-8160/TS-8100
//poke16(0x400, 0x18);
//// if unknown baseboard, uses no an_sel
//// but assumes ADC is there
//poke16(0x400, 0x08);
// enable all 6 channels
poke16(0x402, 0x3f);
// allow time for conversions
usleep(500000);
for (i = 1; i <= 6; i++) {
x = (signed short)peek16(0x402 + 2*i);
if (i > 2) x = (x * 1006)/200;
x = (x * 2048)/0x8000;
printf("adc%d=%d\n", i, x);
}
return 0;
}
Running this code on a TS-TPC-8390 with pin 7 of the ADC header (channel 3) connected to 3.3V returns:
root@ts4700:~# ./adctest adc1=0 adc2=0 adc3=3302 adc4=0 adc5=0 adc6=0
Offset | Bits | Description | |||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
0x0 | 15:8 | Core ID register (reads 0xad) | |||||||||
7:6 | Reserved | ||||||||||
5:4 |
| ||||||||||
3:2 |
| ||||||||||
1:0 |
| ||||||||||
0x2 | 15:0 | Channel Mask | |||||||||
0x4 | 15:0 | Channel 1 most recent conversion value | |||||||||
0x6 | 15:0 | Channel 2 most recent conversion value | |||||||||
0x8 | 15:0 | Channel 3 most recent conversion value | |||||||||
0xa | 15:0 | Channel 4 most recent conversion value | |||||||||
0xc | 15:0 | Channel 5 most recent conversion value | |||||||||
0xe | 15:0 | 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.