Wiki

This version is outdated by a newer approved version.DiffThis version (06 Dec 2023 19:25) is a draft.
Approvals: 0/1
The Previously approved version (17 Nov 2023 17:39) is available.Diff

This is an old revision of the document!


AD2S1210 IIO Resolver-to-Digital Converter Linux Driver

Supported Devices

Evaluation Boards

Reference Circuits

Description

This is a Linux industrial I/O (IIO) subsystem driver, targeting Resolver-to-Digital Converters. The industrial I/O subsystem provides a unified framework for drivers for many different types of converters and sensors using a number of different physical interfaces (i2c, spi, etc). See IIO for more information.

Source Code

Status

Source Mainlined?
git Yes

Support for the AD2S1210 is in mainline for kernel v6.7 and is backported to v6.1 of the ADI tree. Some additional features are slated for v6.8. The device was previously supported by a staging driver with a different ABI.

Files

Adding Linux driver support

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

The Driver depends on CONFIG_SPI

Linux Kernel Configuration
	Device Drivers  --->
		[*] Staging drivers  --->
			<*>     Industrial I/O support --->
			    --- Industrial I/O support
			    -*-   Enable ring buffer support within IIO
			    -*-     Industrial I/O lock free software ring
			    -*-   Enable triggered sampling support

			          *** Resolver to digital converters ***
			    [--snip--]

			    <*>   Analog Devices AD2S1210 driver

			    [--snip--]

Driver Usage

To configure the chip, use the attributes according to the device register to IIO ABI mapping below:

Register Addr IIO ABI (sysfs) Units Notes
DOS Overrange Threshold 0x89 events/in_altvoltage0_thresh_rising_value mV
DOS Mismatch Threshold 0x8A events/in_altvoltage0_mag_rising_value mV
DOS Reset Maximum Threshold 0x8B events/in_altvoltage0_mag_rising_reset_max mV
DOS Reset Minimum Threshold 0x8C events/in_altvoltage0_mag_rising_reset_min mV
LOT High Threshold 0x8D events/in_angl1_thresh_rising_value Radians
LOT Low Threshold [1] 0x8E events/in_angl1_thresh_rising_hysteresis Radians
Excitation Frequency 0x91 out_altvoltage0_frequency Hz
Control 0x92 *as bit fields*
Phase lock range D5 events/in_phase0_mag_rising_value Radians
Hysteresis D4 in_angl0_hysteresis Radians
Encoder resolution D3:2 *not implemented*
Resolution D1:0 *device tree: assigned-resolution-bits* Bits 10, 12, 14, or 16
Soft Reset 0xF0 [2]
Fault 0xFF *not implemented*

[1]: The value written to the LOT low register is high value minus the hysteresis.

[2]: Soft reset is performed when `out_altvoltage0_frequency` is written.

Interfacing With the AD2S1210 via iio_attr

Accessing a list of channels:

This specifies any shell prompt running on the target

analog@setup-2-zed:~ $ iio_attr ad2s1210 -c
dev 'ad2s1210', channel 'angl0' (input, index: 0, format: be:U16/16>>0), found 5 channel-specific attributes
dev 'ad2s1210', channel 'anglvel0' (input, index: 1, format: be:S16/16>>0), found 3 channel-specific attributes
dev 'ad2s1210', channel 'timestamp' (input, index: 2, format: le:S64/64>>0), found 0 channel-specific attributes
dev 'ad2s1210', channel 'phase0' (input), found 1 channel-specific attributes
dev 'ad2s1210', channel 'altvoltage0' (output), found 3 channel-specific attributes
dev 'ad2s1210', channel 'altvoltage2' (input), found 1 channel-specific attributes
dev 'ad2s1210', channel 'angl1' (input), found 1 channel-specific attributes
dev 'ad2s1210', channel 'altvoltage0' (input), found 1 channel-specific attributes
dev 'ad2s1210', channel 'altvoltage1' (input), found 1 channel-specific attributes

For example, to get position channel angl0:

This specifies any shell prompt running on the target

analog@setup-2-zed:~ $ iio_attr ad2s1210 -ci angl0
dev 'ad2s1210', channel 'angl0' (input), attr 'hysteresis', value '1'
dev 'ad2s1210', channel 'angl0' (input), attr 'hysteresis_available', value '0 1'
dev 'ad2s1210', channel 'angl0' (input), attr 'label', value 'position'
dev 'ad2s1210', channel 'angl0' (input), attr 'raw', value '34114'
dev 'ad2s1210', channel 'angl0' (input), attr 'scale', value '0.000095874'

Or velocity channel anglvel0:

This specifies any shell prompt running on the target

analog@setup-2-zed:~ $ iio_attr ad2s1210 -ci anglvel0
dev 'ad2s1210', channel 'anglvel0' (input), attr 'label', value 'velocity'
dev 'ad2s1210', channel 'anglvel0' (input), attr 'raw', value '0'
dev 'ad2s1210', channel 'anglvel0' (input), attr 'scale', value '0.023968449'

Interfacing With the AD2S1210 via /sys/bus

Alternatively, you can read and write data directly from the device path in /sys/bus:

This specifies any shell prompt running on the target

analog@setup-2-zed:~ $ cd /sys/bus/iio/devices/iio\:device1/

analog@setup-2-zed:/sys/bus/iio/devices/iio:device1 $ ls -l
total 0
drwxr-xr-x 2 root root    0 Dec  5 16:05 buffer
drwxr-xr-x 2 root root    0 Dec  5 16:05 buffer0
-rw-r--r-- 1 root root 4096 Dec  5 16:05 current_timestamp_clock
-r--r--r-- 1 root root 4096 Dec  5 16:05 dev
drwxr-xr-x 2 root root    0 Dec  5 16:05 events
-r--r--r-- 1 root root 4096 Dec  5 16:05 in_altvoltage0_label
-r--r--r-- 1 root root 4096 Dec  5 16:05 in_altvoltage1_label
-r--r--r-- 1 root root 4096 Dec  5 16:05 in_altvoltage2_label
-rw-r--r-- 1 root root 4096 Dec  5 16:05 in_angl0_hysteresis
-r--r--r-- 1 root root 4096 Dec  5 16:05 in_angl0_hysteresis_available
-r--r--r-- 1 root root 4096 Dec  5 16:05 in_angl0_label
-rw-r--r-- 1 root root 4096 Dec  5 16:05 in_angl0_raw
-rw-r--r-- 1 root root 4096 Dec  5 16:05 in_angl0_scale
-r--r--r-- 1 root root 4096 Dec  5 16:05 in_angl1_label
-r--r--r-- 1 root root 4096 Dec  5 16:05 in_anglvel0_label
-rw-r--r-- 1 root root 4096 Dec  5 16:05 in_anglvel0_raw
-rw-r--r-- 1 root root 4096 Dec  5 16:05 in_anglvel0_scale
-r--r--r-- 1 root root 4096 Dec  5 16:05 in_phase0_label
-r--r--r-- 1 root root 4096 Dec  5 16:05 name
lrwxrwxrwx 1 root root    0 Dec  5 16:05 of_node -> ../../../../../../../../firmware/devicetree/base/axi/spi@e0006000/ad2s1210@0
-rw-r--r-- 1 root root 4096 Dec  5 16:05 out_altvoltage0_frequency
-r--r--r-- 1 root root 4096 Dec  5 16:05 out_altvoltage0_frequency_available
-r--r--r-- 1 root root 4096 Dec  5 16:05 out_altvoltage0_label
drwxr-xr-x 2 root root    0 Dec  5 16:05 power
drwxr-xr-x 2 root root    0 Dec  5 16:05 scan_elements
lrwxrwxrwx 1 root root    0 Dec  5 16:05 subsystem -> ../../../../../../../../bus/iio
drwxr-xr-x 2 root root    0 Dec  5 17:42 trigger
-rw-r--r-- 1 root root 4096 Dec  5 16:05 uevent
-r--r--r-- 1 root root 4096 Dec  5 16:05 waiting_for_supplier

analog@setup-2-zed:/sys/bus/iio/devices/iio:device1 $ cat name
ad2s1210

analog@setup-2-zed:/sys/bus/iio/devices/iio:device1 $ cat in_angl0_raw
34115

Hysteresis can be enabled or disabled this way. To do so, first check the output of in_angl0_hysteresis_available:

This specifies any shell prompt running on the target

root@setup-2-zed:/sys/bus/iio/devices/iio:device1# cat in_angl0_hysteresis_available 
0 1

To turn hysteresis off, write the first value from the output to in_angl0_hysteresis:

This specifies any shell prompt running on the target

root@setup-2-zed:/sys/bus/iio/devices/iio:device1# echo 0 > in_angl0_hysteresis

To turn it on, write the second value (which is dependent on the assigned bits for resolution and may not always be 1):

This specifies any shell prompt running on the target

root@setup-2-zed:/sys/bus/iio/devices/iio:device1# echo 1 > in_angl0_hysteresis

The second value from in_angl0_hysteresis_available can be multiplied by the value of in_angl0_scale to get the hysteresis in radians.

Triggered buffer

To generate samples using the triggered buffer, you will need a trigger. You can create an hrtimer trigger like this: mkdir /sys/kernel/config/iio/triggers/hrtimer/test

You can grab some samples like this to connect the trigger and make sure things are working: iio_readdev ad2s1210 -t test -s 1000 -T 10000 | hd

using the -t option to specify the trigger with iio_readdev resets the sampling rate of the hrtimer trigger back to 100Hz!

For other apps, we probably want a high sample rate. You can change the rate like this: iio_attr -d test sampling_frequency 10000

Reading IIO Events

See iio_event_monitor for an example of a program designed to read IIO events.

Fault to event mapping:

Fault Channel Type Direction
Sine/cosine inputs clipped [3] D7 altvoltage1 mag either
Sine/cosine inputs below LOS D6 altvoltage0 thresh falling
Sine/cosine inputs exceed DOS overrange D5 altvoltage0 thresh rising
Sine/cosine inputs exceed DOS mismatch D4 altvoltage0 mag rising
Tracking error exceeds LOT D3 angl1 thresh rising
Velocity exceeds maximum tracking rate D2 anglvel0 mag rising
Phase error exceeds phase lock range D1 phase0 mag rising
Configuration parity error D0 *writes to kernel log*

[3]: The chip does not differentiate between fault on sine vs. cosine so there will also be an event on the altvoltage2 channel.

Usage With the EVAL-AD2S1210SDZ Evaluation Board

Interfacing With a Raspberry Pi

Wiring

AD2S1210 Pin Eval Board Pin RPi Header Pin RPi Function
RES0 LK6 [1] 15 GPIO22
RES1 LK7 [1] 16 GPIO23
A0 J4-12 18 GPIO24
A1 J4-11 22 GPIO25
WR/FSYNC J4-4 24 SPI0 CE0
SAMPLE J4-1 12 GPIO18
VDRIVE J704-1 1 3.3V
DGND J704-2 9 GND
SCLK J4-10 23 SPI0 SCLK
SDI J4-9 19 SPI0 MOSI
SDO J4-8 21 SPI0 MISO
AD2S1210 Pin Eval Board Pins (Jumpered) Eval Board Signal
RD J4-3, J4-7 VDRIVE
CS J4-2, J4-6 DGND
Eval Board Signal Eval Board Jumper Position
SAMPLE LK1 B
CS LK2 C
RD LK3 C
A0 LK 4 C
A1 LK5 C
RES0 LK6 [1] C
RES1 LK7 [1] C
SOE LK9 B
VDRIVE LK703 B

[1] There aren’t J4 pins for RES0/1 so have to use jumper pins. It is also possible to hard-wire resolution pins RES0/1, but device tree would need to be changed accordingly.

Device Tree

Add dtoverlay=ad2s1210 to /boot/config.txt.

Overlay: ad2s1210-overlay.dts

Zedboard

More Information

resources/tools-software/linux-drivers/iio-resolver/ad2s1210.1701887111.txt.gz · Last modified: 06 Dec 2023 19:25 by Trevor Gamblin