TS-7250-V3 FPGA ADC
The TS-7250-V3 includes a simple low speed ADC to support the analog input on mikrobus modules.
- 304hz sample rate
- 8-bits resolution
- 10kohm input impedance
- 0-6V input range
- 3% absolute accuracy
This ADC is accessed using the IIO subsystem. One time samples can be read from /sys/:
root@tsimx6:~# cat /sys/bus/iio/devices/iio\:device0/in_voltage0_raw 127 root@tsimx6:~# cat /sys/bus/iio/devices/iio\:device0/in_voltage0_scale 25.781250000
The raw value is 0-255, and the scale value converts this to real world values. For example, 127*25.78125=3274.21875mV.
Faster samples, up to 304hz, are available using the buffer interface.
root@tsimx6:~# echo 1 > /sys/bus/iio/devices/iio\:device0/scan_elements/in_voltage0_en root@tsimx6:~# iio_readdev iio:device0 | hexdump -C WARNING: High-speed mode not enabled 00000000 80 00 00 00 00 00 00 00 4c a8 d9 e8 b7 33 83 15 |........L....3..| 00000010 7f 00 00 00 00 00 00 00 df 8f 22 e9 b7 33 83 15 |.........."..3..| 00000020 7f 00 00 00 00 00 00 00 b7 aa 55 e9 b7 33 83 15 |..........U..3..| 00000030 80 00 00 00 00 00 00 00 e9 d7 86 e9 b7 33 83 15 |.............3..|
In this case, column 1 that starts with 80 is the ADC value. Columns 2-8 are 0 padding. Columns 9-16 are the 64-bit ns timestamp. This is accurate to approximately 10us.
The ADC buffers can also be filled using libiio directly:
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <signal.h>
#include <stdio.h>
#include <assert.h>
#include <inttypes.h>
#include <iio.h>
static bool stop;
static void handle_sig(int sig)
{
stop = true;
}
int main (int argc, char **argv)
{
const struct iio_data_format *fmt;
static struct iio_context *ctx;
static struct iio_buffer *rxbuf;
struct iio_channel *chn;
struct iio_device *dev;
/* Catch ctrl+c */
signal(SIGINT, handle_sig);
ctx = iio_create_default_context();
assert(ctx);
iio_context_set_timeout(ctx, 10000);
assert(iio_context_get_devices_count(ctx) > 0);
dev = iio_context_find_device(ctx, "50000180.mikro_adc");
assert(dev);
chn = iio_device_get_channel(dev, 0); /* voltage0 */
assert(chn);
iio_channel_enable(chn);
fmt = iio_channel_get_data_format(chn);
assert(fmt);
rxbuf = iio_device_create_buffer(dev, 256, false);
assert(rxbuf);
printf("%s\n", iio_channel_get_id(chn));
while (!stop) {
ssize_t nbytes;
uint8_t *dat;
nbytes = iio_buffer_refill(rxbuf);
if (nbytes < 0) {
printf("Error refilling buf %d\n",(int) nbytes);
break;
}
for (dat = iio_buffer_first(rxbuf, chn);
dat < (uint8_t *)iio_buffer_end(rxbuf);
dat += iio_buffer_step(rxbuf)) {
printf("%d\n", dat[0]);
//printf("%.0f,\n", (float)dat[0] * fmt->scale);
}
}
iio_buffer_destroy(rxbuf);
iio_channel_disable(chn);
iio_context_destroy(ctx);
return 0;
}
For most users we recommend using the existing linux drivers, but the hardware core can be found at 0x50000180. It is a single 32-bit register:
Bits | Reset value | Description |
---|---|---|
31:24 | 0x55 | Reserved |
23:16 | 0x0 | sample |
15:3 | 0x0 | Reserved |
2 | 0 | sample_missed [1] |
1 | 0 | sample_ready [2] |
0 | 1 | standby_en |