TS-4200 ADC Core

From embeddedTS Manuals

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 = 60Hz, 14 bit resolution
2 = 15Hz, 16 bit resolution
3 = Reserved

1-0 Read/Write Programmable Gain

0 = No gain
1 = 2x gain
2 = 4x gain
3 = 8x 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;
}