Skip to main content
Version: BSP 7.x.y

ADC (Linux)

This article will guide you on how to use the Industrial Input/Output (IIO) framework to control ADC pins on Toradex's System on Modules (SoMs).

Keep in mind that Torizon OS is preferred for reading ADC data due to its ease of use and smoother application development experience. For controlling ADC pins using Torizon, refer to How to Use ADC on Torizon OS.

The IIO framework alows you to control devices that perform either analog-to-digital conversion (ADC) or digital-to-analog conversion (DAC), or both. It offers access to ADC/DAC devices through sysfs files, providing an easy-to-use, file driven interface to control the devices.

There are two ways for userspace interaction with iio drivers:

  • /sys/bus/iio/iio:deviceX/, this represents a hardware sensor and groups together the data channels of the same chip.
  • /dev/iio:deviceX, character device node interface used for buffered data transfer and for events information retrieval.

General information

The ADC Linux drivers usually support two modes of performing conversations:

  • One-shot conversion: A slow-rate conversion, meant for reading a single, instantaneous value. You can perform it by reading the ADC files for your specific board, for example: /dev/verdin-adc*.
  • Continuous conversion: The kernel continuously samples the analog input in the background, and pushes the data into a buffer. In this mode, you can read the buffer data from the /dev/iio:device* file.

When the ADC sequencer finishes cycling through all the enabled channels, the user can decide if the sequencer should stop (one-shot mode), or loop back and schedule again (continuous mode).

In the following sections, you will learn how to use each of these modes.

One-shot Mode

To read a single ADC output from a particular channel, Toradex provides useful symlinks for each SoM family. This also helps you to write software that is compatible across SoMs from the same family.

Toradex NameDevice
ADC_1/dev/verdin-adc1
ADC_2/dev/verdin-adc2
ADC_3/dev/verdin-adc3
ADC_4/dev/verdin-adc4

You can list the available Verdin pin-compatible ADCs with the command below. The -l flag will display the corresponding names used by the BSP (such as /sys/devices/platform/soc@0/30800000.bus/30a20000.i2c/i2c-0/0-0049/iio:device0/in_voltage3_raw). Keep in mind that the ADCs will appear in the kernel logs with their real names, and not the Verdin symlinks (e.g. /dev/verdin-adc1).

# ls -l /dev/verdin-adc*

To get a one-shot conversion, just read the file contents:

# cat /dev/verdin-adc1

Continuous Mode

The Single-Channel Continuous Conversion Mode converts a single channel continuously without any intervention from the CPU, and allows the ADC to work in the background. Additionally, you can use the DMA in circular mode, thus reducing the CPU load.

You can control the ADC in Continuous Conversion Mode from the files in the /sys/bus/iio/devices/iio:device* directory.

warning

Some ADC drivers do not support Continuous Conversion Mode, or present certain limitations. For example, the i.MX 6ULL's ADC can only read the values of one channel at a time in Continuous Mode, as mentioned in 53.3 ADC Driver Overview of the i.MX Linux Reference Manual and in the NXP Community.

Check your ADC with the following command, you can use its name to search for its Continuous Mode capabilities.

# cat /sys/bus/iio/devices/iio:deviceX/name

Important subdirectories inside iio:device* are:

  • buffer directory.

    • data_available: a read-only value indicating the bytes of data available in the buffer.
    • enable: Stores the state of the buffer (0 if stopped, 1 if running). Write 1 to it to start reading the ADC data into the buffer.
    • length: Stores the size of the buffer. You can change the buffer size by writing to this file.
    • watermark: Stores the maximum number of samples to wait for. After this number is reached, the buffer becomes available for read.
  • scan_elements directory contains interfaces for elements that will be captured for a single sample set in the buffer:

    • in_voltageX_en: Stores the state of the channel X for continuous read (0 if disabled, 1 if enabled).
    • in_voltageX_index: Stores the position of the channel X inside the buffer.
    • in_voltageX_type: Stores the format of the ADC data. For example, the value le:u12/16>>0 would mean the data is stored in little endian, with 1

Read ADC Data in Continuous Mode

To use the ADC in Continuous Mode, follow the procedure below. In this example, we will set up the continuous mode for device 0, channel 0:

  1. Set a software trigger for the device. Depending on your board's ADC, you may not need to set a trigger manually. You may try the next steps before running the commands below.

    # modprobe iio-trig-sysfs
    # echo 0 > /sys/bus/iio/devices/iio_sysfs_trigger/add_trigger
    # cat /sys/bus/iio/devices/trigger0/name > /sys/bus/iio/devices/iio:device0/trigger/current_trigger
  2. Set up the channels in use. Keep in mind that you can enable any combination of the channels you want:

    # echo 1 > /sys/bus/iio/devices/iio\:device0/scan_elements/in_voltage0_en
  3. Set up the buffer length:

    # echo 100 > /sys/bus/iio/devices/iio\:device0/buffer/length
  4. Enable the capture:

    # echo 1 > /sys/bus/iio/devices/iio\:device0/buffer/enable
  5. Read the buffer data from the /dev/iio:device0

    # hexdump -e '"iio0 :" 1/2 "%04x " "\n"' /dev/iio:device0
  6. While the previous command runs, open a new shell and run the manual trigger, if you've set it up in step 1.

    # echo 1 > /sys/bus/iio/devices/trigger0/trigger_now

You can also use userspace libs like iioutils/libiio to control the ADC. These libraries abstract the low-level details of the hardware and provide a simple, yet complete programming interface that can be used for advanced projects.

Notes

  • Colibri/Apalis iMX6: Since the ADC is shared with the touchscreen it's not recommended to change the ADC characteristics such as sample time.
  • Colibri iMX7: The ADC channels are only 1.8V capable! This is a limitation of the i.MX7 SoC.
Send Feedback!