sama5_defconfig
. Otherwise, check you have set CONFIG_AT91_SAMA5D2_ADC
.
To check that ADC driver is correctly loaded:
# dmesg|grep at91-sama5d2_adc at91-sama5d2_adc fc030000.adc: version: 800 # ls /sys/bus/iio/devices/iio\:device0 dev in_voltage2_raw in_voltage8_raw in_voltage-voltage_scale in_voltage3_raw in_voltage9_raw in_voltage0-voltage1_raw in_voltage4-voltage5_raw in_voltage_scale in_voltage0_raw in_voltage4_raw name in_voltage10-voltage11_raw in_voltage5_raw of_node in_voltage10_raw in_voltage6-voltage7_raw power in_voltage11_raw in_voltage6_raw sampling_frequency in_voltage1_raw in_voltage7_raw subsystem in_voltage2-voltage3_raw in_voltage8-voltage9_raw uevent
pinctrl_adc_default: adc_default { pinmux = <PIN_PD23__GPIO>; bias-disable; };For example, pins PD20 and PD21 which are connected to ADC input channels 1 and 2 respectively are also used for i2c0 bus. i2c0 bus will not function if the ADC will request these pins for conversion.
# cat /sys/bus/iio/devices/iio\:device0/in_voltage4_raw 3693
# cat /sys/bus/iio/devices/iio\:device0/in_voltage_scale 0.805664062
3693 x 0.8 = 2954.4 mV
# cat /sys/bus/iio/devices/iio\:device0/ in_voltage4-voltage5_raw -396
# cat /sys/bus/iio/devices/iio\:device0/in_voltage-voltage_scale 1.611328125
-396 x 1.6 = -633,6 mV
# cat /sys/bus/iio/devices/iio\:device0/in_voltage4_raw 1237 # cat /sys/bus/iio/devices/iio\:device0/in_voltage5_raw 2031 # cat /sys/bus/iio/devices/iio\:device0/in_voltage_scale 0.805664062 (1237-2031) x 0.8 = -635.2 mV
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 "fc030000.adc-dev0-external_rising" > /sys/bus/iio/devices/iio:device0/trigger/current_triggeror
# echo "fc030000.adc-dev0-external_falling" > /sys/bus/iio/devices/iio:device0/trigger/current_triggerfor instance.
# 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
tools/iio/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_bufferor
cd tools make iioThen copy the
generic_buffer
program on your board.
Below is an example of how to use this tool :
First, load the driver:
# modprobe at91-sama5d2_adcThen enable the channels:
# 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 (fc030000.adc
and for the trigger fc030000.adc-dev0-external_rising
for example).
You can also specify the buffer length to use (2
in this example). The default value is 128
.
# ./generic_buffer -n fc030000.adc -t fc030000.adc-dev0-external_rising -l 2 iio device number being used is 0 iio trigger number being used is 0 /sys/bus/iio/iio iio/iio:device0 fc030000.adc-dev0-external_rising: 1681.420898 3296.777344 1841.748047 3296.777344 1841.748047 3296.777344While running, it displays values that are stored in the buffer. So using the setup above, we have the following trace:
Channel 1 | Channel 3 | ||
Sample 1 | 1681.420898 | 3296.777344 | |
Sample 2 | 1841.748047 | 3296.777344 | |
Sample 3 | 1841.748047 | 3296.777344 |
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.
echo 100 > /sys/bus/iio/devices/iio\:device0/buffer/length
echo 50 > /sys/bus/iio/devices/iio\:device0/buffer/watermarkThis means that the DMA will stop once 50 conversions are done (example), and then report the results. If a single edge is detected on the hardware trigger, we should not see any conversion results. This is normal. Linux is no longer interrupted on each trigger, and the DMA will carry the data and notify only when the watermark is reached. Once 50 edges happen, we should see all 50 results in bulk.
cat /sys/bus/iio/devices/iio\:device0/hwfifo_enabled cat /sys/bus/iio/devices/iio\:device0/hwfifo_watermark
cat /sys/bus/iio/devices/iio\:device0/hwfifo_watermark_min cat /sys/bus/iio/devices/iio\:device0/hwfifo_watermark_max
atmel,min-sample-rate-hz = <200000>; atmel,max-sample-rate-hz = <20000000>;By default, the driver will pick the minimum sample rate of the clock. This means that 200kHz will be used, and we can do a sample with a delay of 21 clocks (datasheet), until the ADC capacitors are loaded. This means we can achieve a theoretical speed of around 8 kSamples/second. To achieve a better speed, we can increase the clock to 20 mHz, which is the maximum supported sample rate:
echo 20000000 > /sys/bus/iio/devices/iio:deviceX/sampling_frequencyWith this clock, we can push the ADC, DMA and kernel system to the limit and achieve a higher sampling speed. This could not be achieved if we did not use DMA, because the kernel would be interrupted for each conversion, and it would hog the CPU. During tests in our lab, we could manage to obtain 400kSamples/second until edges were lost.
echo 4 > /sys/bus/iio/devices/iio:deviceX/oversampling_ratioThis means that we can use 4 samples to get an additional bit. The ADC will do 4 measurements instead of a single one, and report a single value, the average of the 4, with an extra bit set.
echo 16 > /sys/bus/iio/devices/iio:deviceX/oversampling_ratioThis means that we can use 16 samples to get an additional bit. The ADC will do 16 measurements instead of a single one, and report a single value, the average of the 16, with two extra bits set.
cat /sys/bus/iio/devices/iio:deviceX/oversampling_ratio_availableTo restore the default behavior (no oversampling enabled), use:
echo 1 > /sys/bus/iio/devices/iio:deviceX/oversampling_ratio
WebFaqBaseForm | |
---|---|
Boards | Sam9x60EK, Sama5d27WLSom1EK, Sama5d27Som1EK, Sama5d2PtcEK, Sama5d2Xplained |
Components | Kernel, 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 | Using the SAMA5D2-compatible ADC device |
I | Attachment | Action | Size | Date | Who | Comment |
---|---|---|---|---|---|---|
![]() |
20151215_174632.jpg | manage | 3082.9 K | 2016-04-26 - 15:18 | LudovicDesroches |
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.
Atmel® and others, are registered trademarks or trademarks of Atmel Corporation or its subsidiaries.
ARM® and others are registered trademarks or trademarks of ARM Ltd. Other terms and product names may be trademarks of others.
Ideas, requests, contributions ? Connect to LinksToCommunities page.