asm335x系列adc和触摸屏驱动(转)

Posted xihong

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了asm335x系列adc和触摸屏驱动(转)相关的知识,希望对你有一定的参考价值。

An analog-to-digital converter (abbreviated ADC) is a device that uses sampling to convert a continuous quantity to a discrete time representation in digital form.

The TSC_ADC_SS (Touchscreen_ADC_subsystem) is an 8 channel general purpose ADC, with optional support for interleaving Touch Screen conversions. The TSC_ADC_SS can be used and configured in one of the following application options:

  • 8 general purpose ADC channels
  • 4 wire TS, with 4 general purpose ADC channels
  • 5 wire TS, with 3 general purpose ADC channels
  • 8 wire TS

ADC used is 12 bit SAR ADC with a sample rate of 200 KSPS (Kilo Samples Per Second). The ADC samples the analog signal when "start of conversion" signal is high and continues sampling 1 clock cycle after the falling edge. It captures the signal at the end of sampling period and starts conversion. It uses 12 clock cycles to digitize the sampled input; then an "end of conversion" signal is enabled high indicating that the digital data ADCOUT<11:0> is ready for SW to consume. A new conversion cycle can be initiated after the previous data is read. Please note that the ADC output is positive binary weighted data.

Driver Configuration

You can enable ADC driver in the kernel as follows.

Device Drivers  --->
         [*]  Staging drivers  --->
                  [*]  Industrial I/O support  --->  
                  [*]  Enable buffer support within IIO
                  <*>     Industrial I/O lock free software ring                                                               
                  < >     Industrial I/O buffering based on kfifo
                  -*-  Enable triggered sampling support                                                                      
                  (2)     Maximum number of consumers per trigger
                       Analog to digital converters  --->
                                <*>   TI‘s ADC driver

Building as Loadable Kernel Module

  • In-case if you want to build the driver as module, use <M> instead of <*> during menuconfig while selecting the drivers (as shown below). For more information on loadable modules refer Loadable Module HOWTO
Device Drivers  --->
         [*]  Staging drivers  --->
                  [*]  Industrial I/O support  --->
                  [*]  Enable buffer support within IIO
                  <*>     Industrial I/O lock free software ring                                                               
                  < >     Industrial I/O buffering based on kfifo
                  -*-  Enable triggered sampling support                                                                      
                  (2)     Maximum number of consumers per trigger
                       Analog to digital converters  --->
                                <M>   TI‘s ADC driver
  • This step applies if the driver is built as module
  1. Do "make modules" to build the ADC driver as module. The module should be present in "drivers/staging/iio/adc/ti_adc.ko".
  2. Load the driver using "ti_adc.ko".

Platform data

ADC platform data is added in board file(arch/arm/mach-omap2/board-am335xevm.c) as shown below.

#include <linux/platform_data/ti_adc.h>
static struct adc_data am335x_adc_data = {
        .adc_channels = 4,
};
static struct mfd_tscadc_board tscadc = {
        .tsc_init = &am335x_touchscreen_data,
        .adc_init = &am335x_adc_data,
};

The parameter "adc_channels" needs to hold data related to how many channels you want to use for ADC.

  • If ADC and touchscreen are used together, add platform data as shown above.
  • If ADC alone is being used, you will need to remove platform data for touch screen.

Example below. Notice adc_channels is increased to 8 in the adc initialization.

static struct adc_data am335x_adc_data = { 
        .adc_channels = 8,
};
/*
static struct tsc_data am335x_touchscreen_data  = {
        .wires  = 4,
        .x_plate_resistance = 200,
        .steps_to_configure = 5,
}; */
static struct mfd_tscadc_board tscadc = {
   /*   .tsc_init = &am335x_touchscreen_data, */
        .adc_init = &am335x_adc_data,
};

You can find the source code for ADC here

Usage

To test ADC, Connect a DC voltage supply to each of the AIN0 through AIN7 pins (based on your channel configuration), and vary voltage between 0 and 1.8v reference voltage.

CAUTION

Make sure that the voltage supplied does not cross 1.8v

On loading the module you would see the IIO device created

[email protected]:~# ls -al /sys/bus/iio/devices/iio\:device0/
drwxr-xr-x    5 root     root            0 Jan  1 00:00 .
drwxr-xr-x    4 root     root            0 Jan  1 00:00 ..
drwxr-xr-x    2 root     root            0 Jan  1 00:00 buffer
-r--r--r--    1 root     root         4096 Jan  1 00:00 dev
-r--r--r--    1 root     root         4096 Jan  1 00:00 in_voltage0_raw
-r--r--r--    1 root     root         4096 Jan  1 00:00 in_voltage1_raw
-r--r--r--    1 root     root         4096 Jan  1 00:00 in_voltage2_raw
-r--r--r--    1 root     root         4096 Jan  1 00:00 in_voltage3_raw
-r--r--r--    1 root     root         4096 Jan  1 00:00 in_voltage4_raw
-r--r--r--    1 root     root         4096 Jan  1 00:00 in_voltage5_raw
-r--r--r--    1 root     root         4096 Jan  1 00:00 in_voltage6_raw
-r--r--r--    1 root     root         4096 Jan  1 00:00 in_voltage7_raw
-rw-r--r--    1 root     root         4096 Jan  1 00:00 mode
-r--r--r--    1 root     root         4096 Jan  1 00:00 name
drwxr-xr-x    2 root     root            0 Jan  1 00:00 power
drwxr-xr-x    2 root     root            0 Jan  1 00:00 scan_elements
lrwxrwxrwx    1 root     root            0 Jan  1 00:00 subsystem -> ../../../../../../bus/iio
-rw-r--r--    1 root     root         4096 Jan  1 00:00 uevent
[email protected]:~#

Modes of operation

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). If one-shot mode is enabled, then the sequencer will only be scheduled one time (the sequencer HW will automatically disable the StepEnable bit after it is scheduled which will guarantee only one sample is taken per channel). When the user wants to continuously take samples, continuous mode needs to be enabled. One cannot read ADC data from one channel operating in One-shot mode and and other in continuous mode at the same time.

One-shot Mode

To read a single ADC output from a particular channel this interface can be used.

[email protected]:~# cat /sys/bus/iio/devices/iio\:device0/in_voltage0_raw
4095

This feature is exposed by IIO through the following files:

  • in_voltageX_raw: raw value of the channel X of the ADC

 

NOTE

Check ADC mode.
[email protected]:~# cat /sys/bus/iio/devices/iio\:device0/mode
oneshot

To read a single ADC value, ADC has to be configured in one-shot mode. If not in one-shot mode, This can be set by:

[email protected]:~# echo oneshot > /sys/bus/iio/devices/iio\:device0/mode

Continuous Mode

CAUTION

Please note that continuous mode is only supported with the v3.2_AM335xPSP_04.06.00.10-rc1 release or later

Important folders in the iio:deviceX directory are:

  • Buffer
    • bytes_per_datum:
    • enabled: get and set the state of the buffer
    • length: get and set the length of the buffer.

The buffer directory contains 3 files:

[email protected]:~# ls -al /sys/bus/iio/devices/iio\:device0/buffer/
drwxr-xr-x    2 root     root            0 Jan  1 00:00 .
drwxr-xr-x    5 root     root            0 Jan  1 00:00 ..
-rw-r--r--    1 root     root         4096 Jan  1 00:01 bytes_per_datum
-rw-r--r--    1 root     root         4096 Jan  1 00:01 enable
-rw-r--r--    1 root     root         4096 Jan  1 00:01 length
  • Scan_elements directory contains interfaces for elements that will be captured for a single sample set in the buffer.
[email protected]:~# ls -al /sys/bus/iio/devices/iio\:device0/scan_elements/
drwxr-xr-x    2 root     root            0 Jan  1 00:00 .
drwxr-xr-x    5 root     root            0 Jan  1 00:00 ..
-rw-r--r--    1 root     root         4096 Jan  1 00:02 in_voltage0_en
-r--r--r--    1 root     root         4096 Jan  1 00:02 in_voltage0_index
-r--r--r--    1 root     root         4096 Jan  1 00:02 in_voltage0_type
-rw-r--r--    1 root     root         4096 Jan  1 00:02 in_voltage1_en
-r--r--r--    1 root     root         4096 Jan  1 00:02 in_voltage1_index
-r--r--r--    1 root     root         4096 Jan  1 00:02 in_voltage1_type
-rw-r--r--    1 root     root         4096 Jan  1 00:02 in_voltage2_en
-r--r--r--    1 root     root         4096 Jan  1 00:02 in_voltage2_index
-r--r--r--    1 root     root         4096 Jan  1 00:02 in_voltage2_type
-rw-r--r--    1 root     root         4096 Jan  1 00:02 in_voltage3_en
-r--r--r--    1 root     root         4096 Jan  1 00:02 in_voltage3_index
-r--r--r--    1 root     root         4096 Jan  1 00:02 in_voltage3_type
-rw-r--r--    1 root     root         4096 Jan  1 00:02 in_voltage4_en
-r--r--r--    1 root     root         4096 Jan  1 00:02 in_voltage4_index
-r--r--r--    1 root     root         4096 Jan  1 00:02 in_voltage4_type
-rw-r--r--    1 root     root         4096 Jan  1 00:02 in_voltage5_en
-r--r--r--    1 root     root         4096 Jan  1 00:02 in_voltage5_index
-r--r--r--    1 root     root         4096 Jan  1 00:02 in_voltage5_type
-rw-r--r--    1 root     root         4096 Jan  1 00:02 in_voltage6_en
-r--r--r--    1 root     root         4096 Jan  1 00:02 in_voltage6_index
-r--r--r--    1 root     root         4096 Jan  1 00:02 in_voltage6_type
-rw-r--r--    1 root     root         4096 Jan  1 00:02 in_voltage7_en
-r--r--r--    1 root     root         4096 Jan  1 00:02 in_voltage7_index
-r--r--r--    1 root     root         4096 Jan  1 00:02 in_voltage7_type
[email protected]:~#

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 string something like below:
[email protected]:~# cat /sys/bus/iio/devices/iio\:device0/scan_elements/in_voltage1_type
le:u12/32>>0

Where:

  • 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)
  • 12 is the number of relevant bits of information
  • 32 is the actual number of bits used to store the datum
  • 0 is the number of right shifts needed.

 

How to set it up

To read ADC data continuously we need to enable buffer and channels to be used.

NOTE

Check ADC mode.
[email protected]:~# cat /sys/bus/iio/devices/iio\:device0/mode
oneshot

To read data continuously, ADC has to be configured in continuous mode. This can be done by:

[email protected]:~# echo continuous > /sys/bus/iio/devices/iio\:device0/mode

Set up the channels in use (you can enable any combination of the channels you want)

[email protected]:~# echo 1 > /sys/bus/iio/devices/iio\:device0/scan_elements/in_voltage0_en
[email protected]:~# echo 1 > /sys/bus/iio/devices/iio\:device0/scan_elements/in_voltage5_en
[email protected]:~# echo 1 > /sys/bus/iio/devices/iio\:device0/scan_elements/in_voltage7_en

Set up the buffer length

[email protected]:~# echo 100 > /sys/bus/iio/devices/iio\:device0/buffer/length

Enable the capture

[email protected]:~# echo 1 > /sys/bus/iio/devices/iio\:device0/buffer/enable

Now, all the captures are exposed in the character device /dev/iio:device0 

To stop the capture, just disable the buffer

[email protected]:~# echo 0 > /sys/bus/iio/devices/iio\:device0/buffer/enable

ADC Driver Limitations

This driver is based on the IIO (Industrial I/O subsystem), however this is the first release of this driver and it has limited functionality:

  1. No HW trigger Support. Currently only supporting software trigger.
  2. Limited number of samples in continuous capture mode. (Only 1528 samples per capture)
  3. Limited maximum sample rate in continuous mode: 8K samples / second.
  4. Simultaneous capture on multiple ADC channels is not supported. Currently only supports continuous capture on a single ADC input channel at a time.
  5. "Out of Range" not supported by ADC driver.

Formula Used for Calculation

To cross verify the digital values read use,

D = Vin * (2^n - 1) / Vref
Where:
D = Digital value
Vin = Input voltage
n = No of bits
Vref = reference voltage

Ex: Read value on channel AIN4 for input voltage supplied 1.01:

Formula:

Vin = 1.01 * (2^12 -1 )/ 1.8
Vin = 2297.75

Value read from sysfs:

[email protected]:~# cat /sys/bus/iio/devices/iio\:device0/in_voltage4_raw
2298

Board setup

To test ADC on AM335x EVM

On top of EVM, on LCD daughter board, J8 connector can be used, where ADC channel input AIN0-AN7 pins are brought out. For further information of J8 connector layout please refer to EVM schematics here

To test ADC on Beaglebone:

On BeagleBone platform, P9 expansion header can be used. For further information on expansion header layout please refer to the Beaglebone schematics here

 

Sample Application

The source code is located under kernel sources "drivers/staging/iio/Documentation/generic_buffer.c". Since our driver is not trigger based we need to modify this application to bypass the trigger detection. Please apply patchMedia:Generic_buffer.patch on top of the application generic_buffer.c in order to bypass the trigger conditions.

How to compile:

arm-arago-linux-gnueabi-gcc --static generic_buffer.c -o generic_buffer

or

<path_to_cross-compiler/cross-compiler-prefix->-gcc --static generic_buffer.c -o generic_buffer

Then copy the generic_buffer program on your target board and follow below sequence -

Enable the channels:

[email protected]:~# echo 1 > /sys/bus/iio/devices/iio\:device0/scan_elements/in_voltage4_en

Check the mode:

[email protected]:~# cat /sys/bus/iio/devices/iio\:device0/mode
oneshot
[email protected]:~# echo continuous > /sys/bus/iio/devices/iio\:device0/mode

Finally, the generic_buffer application does all the "enable" and "disable" actions for you. You will only need to specify the IIO driver. Application takes two arguments, buffer length to use (256 in this example) the default value is 128 and the number of iterations you want to run (3 in this example).

[email protected]:~# ./generic_buffer -n tiadc -l 256 -c 3

The output of this application is directly printed on console

 

来源:http://processors.wiki.ti.com/index.PHP/AM335x_ADC_Driver‘s_Guide

 

以上是关于asm335x系列adc和触摸屏驱动(转)的主要内容,如果未能解决你的问题,请参考以下文章

「技术干货」工业触摸屏之驱动开发及异常分析(连载)

linux驱动之触摸屏驱动程序

Am335x 下GPIO控制实例-驱动程序(转)

ADC_驱动

[国嵌攻略][140][触摸屏驱动分析]

STM32入门开发:编写XPT2046电阻触摸屏驱动(模拟SPI)