drivers/staging/iio/Documentation/
. wget http://www.kernel.org/pub/linux/kernel/v3.x/linux-3.5.tar.bz2 tar xvjf linux-3.5.tar.bz2 cd linux-3.5
make ARCH=arm at91sam9xxxx_defconfigYou can enable the AT91 IIO ADC driver by enabling the symbol
CONFIG_AT91_ADC
or using the Linux kernel configuration interface:
make ARCH=arm menuconfig
Device Drivers ---> <*> Industrial I/O support ---> Analog to digital converters ---> <M> Atmel AT91 ADC -*- Enable buffer support within IIO <*> Industrial I/O buffering based on kfifo -*- Enable triggered sampling support (2) Maximum number of consumers per trigger (NEW)
make ARCH=arm CROSS_COMPILE=<path_to_cross-compiler/cross-compiler-prefix->path_to_cross-compiler is only needed if it is not in your PATH. Usually cross-compiler-prefix- looks like
arm-linux-
, arm-elf-
or arm-none-linux-gnueabi-
.
To produce a kernel image suitable for U-Boot:
mkimage -A arm -O linux -C none -T kernel -a 20008000 -e 20008000 -n linux-2.6 -d arch/arm/boot/zImage uImage.bin
# dmesg | grep iio [ 2.450000] iio iio:device0: Resolution used: 10 bits [ 2.450000] iio iio:device0: ADC Touch screen is disabled.So you can skip this setup about modules. If the insertion of the module is needed, this driver's name is
at91_adc
, so you can load it simply using
modprobe at91_adcor
insmod ./at91_adc.ko
root@at91sam9g20ek:~# insmod /lib/modules/3.5.0/kernel/drivers/iio/adc/at91_adc.koLoading the module should have created a sysfs directory in
/sys/bus/iio/devices/iio:deviceN
, N being between 0 and 255. It is most likely to be 0, but you can be sure by looking into the name file in that directory.
root@at91sam9g20ek:~# ls -l /sys/bus/iio/devices/iio\:device0/ drwxr-xr-x 2 root root 0 Mar 10 02:24 buffer -r--r--r-- 1 root root 4096 Mar 10 02:24 dev -r--r--r-- 1 root root 4096 Mar 10 02:24 in_voltage0_raw -r--r--r-- 1 root root 4096 Mar 10 02:24 in_voltage1_raw -r--r--r-- 1 root root 4096 Mar 10 02:24 in_voltage2_raw -r--r--r-- 1 root root 4096 Mar 10 02:24 in_voltage3_raw -rw-r--r-- 1 root root 4096 Mar 10 02:24 in_voltage_scale -r--r--r-- 1 root root 4096 Mar 10 02:24 name drwxr-xr-x 2 root root 0 Mar 10 02:24 power drwxr-xr-x 2 root root 0 Mar 10 02:24 scan_elements lrwxrwxrwx 1 root root 0 Mar 10 02:24 subsystem -> ../../../../bus/iio drwxr-xr-x 2 root root 0 Mar 10 02:24 trigger -rw-r--r-- 1 root root 4096 Mar 10 02:24 ueventIf you have devtmpfs, it will also have created an
iio:deviceN
file under /dev
.
in_voltageX_raw
: raw value of the channel X of the ADC
in_voltage_scale
: value you have to multiply in_voltageX_raw with to have a value in microvolts
in_voltageX_raw
will perform a software trigger on the ADC, then block until the conversion is completed, and finally return the value of this conversion.
Please note that conversions are done one channel at a time.
Here is the output on the AT91SAM9 console that shows an ADC measure when a 3V
DC power supply is connected between analog ground AGND
and ADC input 0 AD0
pins:
root@at91sam9g20ek:~# cat /sys/bus/iio/devices/iio\:device0/in_voltage0_raw 948 root@at91sam9g20ek:~# cat /sys/bus/iio/devices/iio\:device0/in_voltage_scale 3222.000000We can calculate the result:
948 x 3222
= 3.0V
iio:deviceX
directory are: buffer
trigger
scan_elements
enabled
: get and set the state of the buffer
length
: get and set the length of the buffer.
triggerX
directories in /sys/bus/iio/devices/
Finally, scan_elements exposes 3 files per channel: in_voltageX_en
: is this channel enabled?
in_voltageX_index
: index of this channel in the buffer's chunks
in_voltageX_type
: How the ADC stores its data. Reading this file should return you a weird looking string. How to interpret it is explained in the Going Further section
in_timestamp_*
files.
# echo 1 > /sys/bus/iio/devices/iio:device0/scan_elements/in_voltage0_en # echo 1 > /sys/bus/iio/devices/iio:device0/scan_elements/in_voltage1_en # echo 1 > /sys/bus/iio/devices/iio:device0/scan_elements/in_voltage2_en # echo 1 > /sys/bus/iio/devices/iio:device0/scan_elements/in_voltage3_enSet up the trigger we want to use (it must be the name of one of the triggers present in
iio/devices
).
name
sysfs file is there to inform you
# echo "at91_adc-dev0-external" > /sys/bus/iio/devices/iio:device0/trigger/current_triggeror
# echo "fc034000.adc-dev0-continuous" > /sys/bus/iio/devices/iio:device0/trigger/current_triggerfor instance. Set up the buffer length (Maximum number of data kept in the buffer, if we reach this number, the older data will be dropped)
# echo 100 > /sys/bus/iio/devices/iio:device0/buffer/lengthEnable the capture
# echo 1 > /sys/bus/iio/devices/iio:device0/buffer/enable #Now, all the captures are exposed in the character device /dev/iio:device0, with the following format
8 bytes | 8 bytes | |||
Chan 0 | Chan 1 | Chan 2 | Chan 3 | Timestamp |
2 bytes | 2 bytes | 2 bytes | 2 bytes |
poll()
or select()
on it to wait for data to arrive, and get them by reading the file, just like you would do with any other file.
And to stop the capture, just disable the buffer
# echo 0 > /sys/bus/iio/devices/iio:device0/buffer/enable
drivers/staging/iio/Documentation/generic_buffer.c
.
First, we need to compile it
arm-linux-gnueabi-gcc --static generic_buffer.c -o generic_bufferor
<path_to_cross-compiler/cross-compiler-prefix->-gcc --static generic_buffer.c -o generic_bufferThen copy the
generic_buffer
program on your board.
Below is an example of how to use this tool :
First, load the driver:
# modprobe at91_adcThen enable the channels:
# echo 1 > /sys/bus/iio/devices/iio:device0/scan_elements/in_voltage0_en # echo 1 > /sys/bus/iio/devices/iio:device0/scan_elements/in_voltage1_en # echo 1 > /sys/bus/iio/devices/iio:device0/scan_elements/in_voltage3_enFinally, the
generic_buffer
tool does all the "enable" and "disable" actions for you.
You will only need to specify the IIO driver and the trigger you want to use (at91_adc
and at91_adc-dev0-external
respectively or fc034000.adc
and fc034000.adc-dev0-external
respectively).
You can also specify the buffer length to use (2
in this example). The default value is 128
.
# ./generic_buffer -n at91_adc -t at91_adc-dev0-external -l 2 iio device number being used is 0 iio trigger number being used is 3 /sys/bus/iio/devices/iio:device0 at91_adc-dev0-external 7.000000 239.000000 71.000000 480890114100 7.000000 238.000000 72.000000 8365721275892or with a device tree system:
name
sysfs file is there to inform you
# ./generic_buffer -n fc034000.adc -t fc034000.adc-dev0-external -l 2 iio device number being used is 0 iio trigger number being used is 3 /sys/bus/iio/devices/iio:device0 fc034000.adc-dev0-external 7.000000 239.000000 71.000000 480890114100 7.000000 238.000000 72.000000 8365721275892While running, it displays values that are stored in the buffer. So using the setup above, we have the following trace:
Channel 0 | Channel 1 | Channel 3 | Timestamp | |
Sample 1 | 7 | 239 | 71 | 480890114100 |
Sample 2 | 7 | 238 | 72 | 8365721275892 |
in_voltageX_type
file should return you something like: le:u10/16>>0
le
represents the endianness, here little endian
u
is the sign of the value returned. It could be either u
(for unsigned) or s
(for signed)
10
is the number of relevant bits of information
16
is the actual number of bits used to store the datum
0
is the number of right shifts needed.
include/linux/platform_data/at91_adc.h
, and the values are filled in the board files (for example arch/arm/mach-at91/board-at91sam9g20ek.c
for the SAM9G20-EK board).
The important fields of that structure for the multiplexing are : channels_used
: it is a bitmask of the channels available on the board. Every bit is a boolean to use or not the corresponding channel. For example, the SAM9G20-EK board has 4 ADC channels, so the default value is BIT(0) | BIT(1) | BIT(2) | BIT(3)
. If you just want the two first channels, just put BIT(0) | BIT(1)
instead. The pins for the two last channels won't be multiplexed as ADC outputs, and the channels won't be available in the driver.
use_external
: it is just a boolean. Just set it to true
or false
whether you want the pin corresponding to the external trigger multiplexed as trigger inputs or not. Of course, if you set it to false
here, all the triggers relying on this pin won't be available to the driver.
R21
resistor and provide an external 3.3V
reference voltage source using ADVREF
/ VREFP
(J24
pin 38).
WebFaqBaseForm | |
---|---|
Boards | Sama5d4Xplained, Sama5d4ek, Sama5d3Xplained, Sama5d3xek, AT91sam9x5-ek, other AT91SAM9 boards |
Components | Kernel, linux-3.10-at91, linux-3.18-at91, linux-4.1-at91, linux-4.4-at91, linux-4.9-at91, linux-4.14-at91, linux-4.19-at91, linux-5.4-at91 |
Summary | Adc IIO driver introduction |
I | Attachment | Action | Size | Date | Who | Comment |
---|---|---|---|---|---|---|
![]() |
atmel_tca.c | manage | 1.2 K | 2011-12-13 - 15:38 | FreeElectrons | Example on how to setup the timer counters |
Copyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Linux® is the registered trademark of Linus Torvalds in the U.S. and other countries.
Microchip® and others, are registered trademarks or trademarks of Microchip Technology Inc. and its subsidiaries.
Arm® and others are registered trademarks or trademarks of Arm Limited (or its affiliates). Other terms and product names may be trademarks of others.
Ideas, requests, contributions ? Connect to LinksToCommunities page.