Wiki

This version (21 Nov 2023 14:58) was approved by Marcelo Schmitt.

AD7091R-2/-4/-8 ADC Linux Driver

Supported Devices

Evaluation Boards

Status

Source Mainlined?
git [Not yet]

Files

Overview

The ad7091r-2, ad7091r-4, and AD7091r-8 are 2-/4-/8-channel, ultra lowpower power dissipation, 1 MSPS successive approximation register (SAR) analog-to-digital converter (ADC). The AD7091R-2/-4/-8 ADCs are multichannel versions of AD7091r. The AD7091R-2/AD7091R-4/AD7091R-8 operates from a single 2.7 V to 5.25 V power supply and is capable of achieving a sampling rate of 1 MSPS.

The AD7091R-2/AD7091R-4/AD7091R-8 family offers up to eight single-ended analog input channels with a channel sequencer that allows a preprogrammed selection of channels to be converted sequentially. Program the channel sequencer by writing to the channel register (address 0x01) through direct register access. AD7091R-2/-4/-8 devices can be fully configured by writing to the desired device registers through direct register access.

The conversion process and data acquisition are controlled using the CONVST pin, which is pulsed on every read to the conversion result register. Writing and reading to registers other than the conversion result register will not trigger a pulse on the CONVST line.

Hardware configuration

Use the test points for interfacing the EVAL-AD7091R-xSDZ with a machine running Linux.

The instructions below describe how to set up EVAL-AD7091R-xSDZ with RPI-4.

The evaluation board default configuration is intended to work with EVAL-SDP-CB1Z so it must be adapted to connect to a different platform.

For the jumper links, use the following configuration:

Link Link Position
LK1 B
LK2 B
LK3 B
LK8 A
LK9 B
LK11 A

Use a soldering iron to change a few soldering links.

  • Unsolder R126 (enable drive CS through CS test point)
  • Unsolder R127 (enable drive SDI through SDI test point)
  • Unsolder R128 (enable drive CONVST through CONVST test point)
  • Unsolder SL19 (enable drive SCLK through SCLK test point)
  • Unsolder SL20 (enable drive SDO through SDO test point)
  • Power VDD and Vdrive supplied with RPI-4 3.3V pins.
  • Solder R68 points together (enable drive the RESET pin through RESET test point)
  • Unsolder LK13 and LK14 from position A and solder them in position C (tie MUX_OUT with ADC_IN).
  • Unsolder SL09 and SL10 from position A and solder each of them to position B to allow the VIN7 signal to bypass the input buffer.

After the changes in the link positions and soldering links, the EVAL-AD7091R-xSDZ evaluation board should look like the following.

There are a number of connections to make between the ADC evaluation board and the Linux machine.

EVAL-AD7091R-xSDZ test point Pin Function RPI-4 Pin function (Pin number)
CS Chip Select CE0 (pin 24)
SCLK Serial Clock SCLK (pin 23)
SDO Serial Data Out MISO (pin 21)
SDI Serial Data In MOSI (pin 19)
RESET ADC Reset GPIO 27 (pin 13)
CONVST Conversion Start Signal GPIO 25 (pin 22)
VDRIVE (J4) Digital Supply Voltage Input 3.3V (pin 17
GND (J4) Digital Supply Voltage Ground GND (pin 20)
VDD (J9) Power Supply Input 3.3V (pin 1)
GND (J9) Power Supply Ground GND (pin 6)

Where J4 is the external VDRIVE and GND power connector and J9 is the external VDD and GND power connector.

Here is how it looks after everything is connected.

The collection of jumpers looks messy and hard to follow so review the textual description in case of doubt.

Adding Linux driver support

Enabling the driver

Configure kernel with “make menuconfig” (alternatively use “make xconfig” or “make qconfig”)

The AD7091R8 Driver depends on CONFIG_SPI

Linux Kernel Configuration
    Device Drivers  --->
        ...
        <*>     Industrial I/O support --->
            --- Industrial I/O support
            ...
            Analog to digital converters  ---> 
                ...
                <*>   Analog Devices AD7091R8 ADC driver
                ...
            ...
        ...

Adding a device tree entry

Required properties

  • compatible: Must be one of “adi,ad7091r2”, “adi,ad7091r4”, “adi,ad7091r8”.
  • reg: number of SPI chip select id for the device.
  • adi,conversion-start-gpios: Device tree identifier of the CONVST pin.
  • reset-gpios: Device tree identifier of the RESET pin.

Optional properties

  • vref-supply: phandle + specifier to a regulator for the external VREF supply. If no external VREF is supplied this attribute should be omitted.
    see: Documentation/devicetree/bindings/regulator/regulator.txt

Device tree generic example

    #include <dt-bindings/interrupt-controller/irq.h>
    #include <dt-bindings/gpio/gpio.h>
    spi {
        #address-cells = <1>;
        #size-cells = <0>;

        adc@0 {
                compatible = "adi,ad7091r8";
                reg = <0x0>;
                spi-max-frequency = <45454545>;
                vref-supply = <&adc_vref>;
                adi,conversion-start-gpios = <&gpio 25 GPIO_ACTIVE_LOW>;
                reset-gpios = <&gpio 27 GPIO_ACTIVE_LOW>;
                interrupts = <22 IRQ_TYPE_EDGE_FALLING>;
                interrupt-parent = <&gpio>;
        };
    };

Device tree overlay example

// SPDX-License-Identifier: GPL-2.0

/dts-v1/;
/plugin/;

#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/gpio/gpio.h>

/ {
	compatible = "brcm,bcm2835", "brcm,bcm2711";
};

&gpio {
	ad7091r8_pins: ad7091r8_pins {
		brcm,pins = <22>; // interrupt
		brcm,function = <0>; // input
	};
};

&spi0 {
	status = "okay";

	cs-gpios = <&gpio 8 GPIO_ACTIVE_LOW>;

	ad7091r8@0 {
		compatible = "adi,ad7091r8";
		reg = <0x0>;
		spi-max-frequency = <1000000>;
		adi,conversion-start-gpios = <&gpio 25 GPIO_ACTIVE_LOW>;
		reset-gpios = <&gpio 27 GPIO_ACTIVE_LOW>;
		pinctrl-names = "default";
		pinctrl-0 = <&ad7091r8_pins>;
		interrupt-parent = <&gpio>;
		interrupts = <22 IRQ_TYPE_EDGE_FALLING>;
	};
};

&spidev0 {
	status = "disabled";
};

&spidev1 {
	status = "disabled";
};

Driver testing

Each and every IIO device, typically a hardware chip, has a device folder under /sys/bus/iio/devices/iio:deviceX. Where X is the IIO index of the device. Under every of these directory folders reside a set of files, depending on the characteristics and features of the hardware device in question. These files are consistently generalized and documented in the IIO ABI documentation. In order to determine which IIO deviceX corresponds to which hardware device, the user can read the name file /sys/bus/iio/devices/iio:deviceX/name. In case the sequence in which the iio device drivers are loaded/registered is constant, the numbering is constant and may be known in advance.

02 Mar 2011 15:16

TIP: An example program whiroot@analog:/sys/bus/iio/devices# ls -lch uses the interface can be found here:


Show device name

This specifies any shell prompt running on the target

marcelo@raspberrypi:~ $ cat /sys/bus/iio/devices/iio\:device0/name
ad7091r-8

Show channel scale

Description:
Scale to be applied to in_voltageX_raw in order to obtain the measured voltage in millivolts

This specifies any shell prompt running on the target

marcelo@raspberrypi:~ $ cat /sys/bus/iio/devices/iio\:device0/in_voltage_scale 
0.610351562

Example test of channel sequencer reading channels 0, 3, 6, and 7.

This specifies any shell prompt running on the target

marcelo@raspberrypi:~ $ ls -l /sys/bus/iio/devices/iio\:device0/
total 0
-rw-r--r-- 1 root root 4096 Sep 14 13:24 in_voltage0_raw
-rw-r--r-- 1 root root 4096 Sep 14 13:24 in_voltage1_raw
-rw-r--r-- 1 root root 4096 Sep 14 13:24 in_voltage2_raw
-rw-r--r-- 1 root root 4096 Sep 14 13:24 in_voltage3_raw
-rw-r--r-- 1 root root 4096 Sep 14 13:24 in_voltage4_raw
-rw-r--r-- 1 root root 4096 Sep 14 13:24 in_voltage5_raw
-rw-r--r-- 1 root root 4096 Sep 14 13:24 in_voltage6_raw
-rw-r--r-- 1 root root 4096 Sep 14 13:24 in_voltage7_raw
-rw-r--r-- 1 root root 4096 Sep 14 13:24 in_voltage_scale
-r--r--r-- 1 root root 4096 Sep 14 13:24 name
lrwxrwxrwx 1 root root    0 Sep 14 13:24 of_node -> ../../../../../../../../firmware/devicetree/base/soc/spi@7e204000/ad7091r8@0
drwxr-xr-x 2 root root    0 Sep 14 13:24 power
lrwxrwxrwx 1 root root    0 Sep 14 13:24 subsystem -> ../../../../../../../../bus/iio
-rw-r--r-- 1 root root 4096 Sep 14 13:24 uevent
marcelo@raspberrypi:~ $ sudo su
root@raspberrypi:~# cd /sys/kernel/debug/iio/iio\:device0/
root@raspberrypi:/sys/kernel/debug/iio/iio:device0# echo 0x02 > direct_reg_access 
root@raspberrypi:/sys/kernel/debug/iio/iio:device0# cat direct_reg_access 
0xC0
root@raspberrypi:/sys/kernel/debug/iio/iio:device0# echo 0x02 0xC1 > direct_reg_access
root@raspberrypi:/sys/kernel/debug/iio/iio:device0# echo 0x01 0x00C5 > direct_reg_access 
root@raspberrypi:/sys/kernel/debug/iio/iio:device0# echo 0x00 > direct_reg_access 
root@raspberrypi:/sys/kernel/debug/iio/iio:device0# cat direct_reg_access 
0xE001
root@raspberrypi:/sys/kernel/debug/iio/iio:device0# cat direct_reg_access 
0xA8E
root@raspberrypi:/sys/kernel/debug/iio/iio:device0# cat direct_reg_access 
0x4AA3
root@raspberrypi:/sys/kernel/debug/iio/iio:device0# cat direct_reg_access 
0xC001
root@raspberrypi:/sys/kernel/debug/iio/iio:device0# cat direct_reg_access 
0xE001
root@raspberrypi:/sys/kernel/debug/iio/iio:device0# cat direct_reg_access 
0x8E9
root@raspberrypi:/sys/kernel/debug/iio/iio:device0# cat direct_reg_access 
0x4AA7
root@raspberrypi:/sys/kernel/debug/iio/iio:device0# cat direct_reg_access 
0xC001
root@raspberrypi:/sys/kernel/debug/iio/iio:device0# cat direct_reg_access 
0xE001

Example test single-shot readings through IIO device sysfs interface.

Don't forget to provide an external voltage reference through EXT_REF J12 jack or to enable the internal on-chip 2.5V voltage reference through direct register access as done in the previous example.

This specifies any shell prompt running on the target

marcelo@raspberrypi:~ $ ls -l /sys/bus/iio/devices/iio\:device0/
total 0
-rw-r--r-- 1 root root 4096 Sep 14 13:24 in_voltage0_raw
-rw-r--r-- 1 root root 4096 Sep 14 13:24 in_voltage1_raw
-rw-r--r-- 1 root root 4096 Sep 14 13:24 in_voltage2_raw
-rw-r--r-- 1 root root 4096 Sep 14 13:24 in_voltage3_raw
-rw-r--r-- 1 root root 4096 Sep 14 13:24 in_voltage4_raw
-rw-r--r-- 1 root root 4096 Sep 14 13:24 in_voltage5_raw
-rw-r--r-- 1 root root 4096 Sep 14 13:24 in_voltage6_raw
-rw-r--r-- 1 root root 4096 Sep 14 13:24 in_voltage7_raw
-rw-r--r-- 1 root root 4096 Sep 14 13:24 in_voltage_scale
-r--r--r-- 1 root root 4096 Sep 14 13:24 name
lrwxrwxrwx 1 root root    0 Sep 14 13:24 of_node -> ../../../../../../../../firmware/devicetree/base/soc/spi@7e204000/ad7091r8@0
drwxr-xr-x 2 root root    0 Sep 14 13:24 power
lrwxrwxrwx 1 root root    0 Sep 14 13:24 subsystem -> ../../../../../../../../bus/iio
-rw-r--r-- 1 root root 4096 Sep 14 13:24 uevent
marcelo@raspberrypi:~ $ cat /sys/bus/iio/devices/iio\:device0/in_voltage_scale 
0.610351562
marcelo@raspberrypi:~ $ cat /sys/bus/iio/devices/iio\:device0/in_voltage0_raw 
2711
marcelo@raspberrypi:~ $ cat /sys/bus/iio/devices/iio\:device0/in_voltage0_raw 
2717
marcelo@raspberrypi:~ $ cat /sys/bus/iio/devices/iio\:device0/in_voltage0_raw 
2716
marcelo@raspberrypi:~ $ cat /sys/bus/iio/devices/iio\:device0/in_voltage2_raw 
2715
marcelo@raspberrypi:~ $ cat /sys/bus/iio/devices/iio\:device0/in_voltage5_raw 
1
marcelo@raspberrypi:~ $ cat /sys/bus/iio/devices/iio\:device0/in_voltage1_raw 
1428
marcelo@raspberrypi:~ $ cat /sys/bus/iio/devices/iio\:device0/in_voltage6_raw 
1

Play with IIO events

Description:
IIO events are a way for the IIO subsystem to notify applications when some event of importance happens.

Example monitoring IIO events and being notified when ADC readings fall above or below the limit registers. The voltage supplied to channel 6 is roughly 1.6V throughout the example. Two shells/terminals are used. First, in one of the shells, run iio_event_monitor to catch IIO events. Then, on the other shell, configure device low limit and high limit registers and experiment with them. The commands and output on the device shell are shown first followed by the commands and output on the shell monitoring IIO events.

This specifies any shell prompt running on the target

marcelo@raspberrypi:~ $ sudo su
root@raspberrypi:/home/marcelo# cd /sys/kernel/debug/iio/iio\:device0/
root@raspberrypi:/sys/kernel/debug/iio/iio:device0# echo 0x02 > direct_reg_access
root@raspberrypi:/sys/kernel/debug/iio/iio:device0# cat direct_reg_access
0xD0
root@raspberrypi:/sys/kernel/debug/iio/iio:device0# echo 0x02 0xd1 > direct_reg_access
root@raspberrypi:/sys/kernel/debug/iio/iio:device0# echo 0x01 0x40 > direct_reg_access
root@raspberrypi:/sys/kernel/debug/iio/iio:device0# echo 0x00 > direct_reg_access
root@raspberrypi:/sys/kernel/debug/iio/iio:device0# cat direct_reg_access
0xA82
root@raspberrypi:/sys/kernel/debug/iio/iio:device0# cat direct_reg_access
0xC9E8
root@raspberrypi:/sys/kernel/debug/iio/iio:device0# cat direct_reg_access
0xC9E3
root@raspberrypi:/sys/kernel/debug/iio/iio:device0# cat direct_reg_access
0xC9EA
root@raspberrypi:/sys/kernel/debug/iio/iio:device0# echo 0x17 > direct_reg_access
root@raspberrypi:/sys/kernel/debug/iio/iio:device0# cat direct_reg_access
0xFFF
root@raspberrypi:/sys/kernel/debug/iio/iio:device0# echo 0x17 0x100 > direct_reg_access
root@raspberrypi:/sys/kernel/debug/iio/iio:device0# echo 0x00 > direct_reg_access
root@raspberrypi:/sys/kernel/debug/iio/iio:device0# cat direct_reg_access
0xD9EE
root@raspberrypi:/sys/kernel/debug/iio/iio:device0# cat direct_reg_access
0xD9EF
root@raspberrypi:/sys/kernel/debug/iio/iio:device0# cat direct_reg_access
0xD9E7
root@raspberrypi:/sys/kernel/debug/iio/iio:device0# cat direct_reg_access
0xD9E5
root@raspberrypi:/sys/kernel/debug/iio/iio:device0# echo 0x16 0x1F0 > direct_reg_access
root@raspberrypi:/sys/kernel/debug/iio/iio:device0# echo 0x00 > direct_reg_access
root@raspberrypi:/sys/kernel/debug/iio/iio:device0# cat direct_reg_access
0xD9EB
root@raspberrypi:/sys/kernel/debug/iio/iio:device0# cat direct_reg_access
0xD9DF
root@raspberrypi:/sys/kernel/debug/iio/iio:device0# echo 0x17 0x1FF > direct_reg_access
root@raspberrypi:/sys/kernel/debug/iio/iio:device0# echo 0x00 > direct_reg_access
root@raspberrypi:/sys/kernel/debug/iio/iio:device0# cat direct_reg_access
0xD9E5
root@raspberrypi:/sys/kernel/debug/iio/iio:device0# cat direct_reg_access
0xD9EC
root@raspberrypi:/sys/kernel/debug/iio/iio:device0# echo 0x16 0x00 > direct_reg_access
root@raspberrypi:/sys/kernel/debug/iio/iio:device0# echo 0x00 > direct_reg_access
root@raspberrypi:/sys/kernel/debug/iio/iio:device0# cat direct_reg_access
0xC9F5
root@raspberrypi:/sys/kernel/debug/iio/iio:device0# cat direct_reg_access
0xC9EF

The iio_event_monitor program can be obtained from the Linux kernel sources.

This specifies any shell prompt running on the target

marcelo@raspberrypi:~ $ ./lsiio 
Device 000: ad7091r-8
marcelo@raspberrypi:~ $ sudo ./iio_event_monitor ad7091r-8
Found IIO device with name ad7091r-8 with device number 0
Event: time: 1700534117816565501, type: voltage, channel: 6, evtype: thresh, direction: rising
Event: time: 1700534121380706350, type: voltage, channel: 6, evtype: thresh, direction: rising
Event: time: 1700534124979082850, type: voltage, channel: 6, evtype: thresh, direction: rising
Event: time: 1700534131460506653, type: voltage, channel: 6, evtype: thresh, direction: rising
Event: time: 1700534272107877759, type: voltage, channel: 6, evtype: thresh, direction: rising
Event: time: 1700534272107877759, type: voltage, channel: 6, evtype: thresh, direction: falling
Event: time: 1700534276149341028, type: voltage, channel: 6, evtype: thresh, direction: rising
Event: time: 1700534276149341028, type: voltage, channel: 6, evtype: thresh, direction: falling
Event: time: 1700534325953991984, type: voltage, channel: 6, evtype: thresh, direction: falling
Event: time: 1700534339240761056, type: voltage, channel: 6, evtype: thresh, direction: falling

More Information

resources/tools-software/linux-drivers/iio-adc/ad7091r8.txt · Last modified: 21 Nov 2023 04:14 by Marcelo Schmitt