Saturday, 27 July 2013

Sampling analogue signals using the ADC on the Beaglebone Black


7 channels of the ADC are available on the expansion port of the Beaglebone Black. Accessing them can seem like a daunting task at first but it is quite simple once you get the hang of it.

The kernel that ships with the BBB as of 27 July doesn't support the stuff below. So compile one from the latest sources available at

If you don't know how to compile the latest kernel sources, check the following links for help on how to compile the kernel.

After booting the BBB, you have to configure the ADC pins and enable the Touchscreen/ADC (TSADC) module in the processor. This is done via the device tree(DT) files.

DT is a standard format since kernel 3.8 that tells the kernel what it needs to do to enable the TSADC module and configure the ADC pins.

Thanks to the great people at, you only need to do this
    echo BB-ADC > /sys/devices/bone_capemgr.*/slots

Check that it loaded correctly using dmesg
You can also list the current configured peripherals using

    cat /sys/devices/bone_capemgr.*/slots

Now checking the analogue value at one instant is simple
All you need to do is type the following

    cat /sys/bus/iio/iio:deviceX/in_voltageY_raw

where X is your adc device number and usually 0.
And Y is your analogue channel number.

Some people might be happy with one sample every once in a while in their applications.

However, the ADC is capable of much more. If you need to sample a signal continuously via a C/C++ application from the userspace, you are in luck.

The am335x driver is a standard IIO driver. And the IIO subsystem provides a sample test application to test the driver. Or in our case, to read from the driver.

The test application can be found in your kernel sources in the drivers/staging/iio/Documentation directory titled generic_buffer.c

Or if you want to take the easy route, check the following link for sources.

There are two parts to continuous sampling.
Configuring the ADC and the buffer.
Triggering the driver to tell it when to start filling in the buffer.

The IIO subsystem supports a trigger mechanism which is separate from the main ADC driver. The ADC driver supports any standard IIO trigger. And IIO provides trigger files which enable triggering via GPIOs or sysfs files.

Here I'll explain the sysfs way of doing things.

To add a sysfs trigger file type the following

    echo 1 > /sys/bus/iio/iio_sysfs_trigger/add_trigger

this creates a trigger directory in


Note: If you dont see this directory. You don't have a supported kernel. Compile the one using the latest sources.

Running the following pulses the trigger.

    echo 1 > /sys/bus/iio/trigger0/trigger_now
The trigger alone is useless. We need to connect this trigger to the adc driver.

Compile generic_buffer.c from the above github repo.

Then run the file using the following parameters

    ./generic_buffer -n TI-am335x-adc -t sysfstrig1 -l 128
The application searches for an IIO driver named 'TI-am335x-adc'.
Connects the trigger named "sysfstrig1" to the driver.
And configures the buffer size for 128 samples.

You might have noticed that you haven't exactly specified which channel you wish to sample. That is enabled separately via sysfs.

All this might seem confusing at first. But the IIO subsystem is designed to be highly configurable and adaptable to accommodate a variety of peripherals such as accelerometers, gyros, adcs etc.

Enabling which channel to sample using the triggered buffer mechanism is as simple as

    echo 1 > /sys/bus/iio/iio:deviceX/scan_elements/in_voltageX_en 

Where X is the channel number.

If you wish to enable another channel. Go ahead. The generic_buffer application will list both channels. Just note that the buffer is common for both channels.

e.g. 128 will result in 64 samples of 2 channels.

generic_buffer.c is just a starting point for your userspace application.
To sum up, you need to run the following to read continuously from the ADC.

    echo 1 > /sys/bus/iio/devices/iio_sysfs_trigger/add_trigger
    echo 1 > /sys/bus/iio/devices/iio\:device0/scan_elements/in_voltage7_en
    echo 1 > /sys/bus/iio/devices/iio\:device0/scan_elements/in_voltage5_en
    /home/root/main -n TI-am335x-adc -t sysfstrig1 -l 128 

And then run this in another terminal to trigger the driver to start sampling

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

The generic_buffer application will display the length of samples.

Enjoy hacking with the BBB.
Leave a comment if you have a question or notice a bug somewhere.

Fixes accepted and upstreamed. Continuous mode Upstream effort Round 3

The fixes I sent upstream were accepted! :)

So now the adc driver will have correct one-shot adc reading since 3.11-rc3.

Greg KH has a way with patches. This space is wrong. Fix.
And he'll stop reviewing the thing! lol.

Thankfully I'm getting comfortable with git rebase.
Fix and resend.

GregKH This indent is wrong. Fix.
Fix and resend.

A dozen exchanges like this came the much awaited.
Acked-by: Greg Kroah-Hartman <>
And then
Signed-off-by: Russ Dill <>


I have sent the patch upstream

Lets see what IIO has to say about it. I'm kinda happy with the driver now. It wasn't good previously.
The only intricate thing in my mind is the way I used IIO triggers.
Triggers are meant to be used for acquiring one sample. I used the iio trigger to acquire a buffer of samples. Who knows. Maybe they aren't solely for acquiring one sample and its my misjudgment. I couldn't find from the wikis..

Lets see


Saturday, 20 July 2013

Upstream effort 2

After greg kh pointed out some really newbie mistakes, I redid the patches.

1 - messed up authorship. patches seemed as if I authored them.

Corrected with. git commit --author "orig author

2- code formatting issues were handled at the end by 3 patches.
totally non-standard practice. each patch has to have correct formatting.
redid the entire series.

Also, squashed some patches together.
Learned git rebase in the process which is really powerfulllllll.

I resubmitted the patch series

Feedback has been cool. Jonathan(King of IIO) pointed out that part of the patch series is a fix. The ones that fixed the first sample read issue by adding a timeout in sampling.

He wanted to separate the patch series into fix and feature..

I just did the fix part.

Now. The feature part is tricky. While working on continuous mode, I realized that its one big patch. Then a number of bug fixes. Whats the point. I did squash some bug fixes in the big patch. but left out some bug fixes too..
to maintain git history.

Jonathan  asked to squash the rest of the bug fixes in too.. Lars-Peter acked that as well.

It'll basically reduce the patch series to around 3 i think.
1 for tsc tweaks related to shared irq.
1 for mfd tweaks maybe.
1 big one for the adc driver.
n voila.

Jonathan also pointed out that the show mode and set mode are redundant as the buffer enabled bit can be used. wow. I was impressed. one look and he removed a bunch of code in the driver because it is there in the subsystem already. just check a boolean!!

he wanted some comments about irqs that i have to look into. i didnt know the answer directly lol.

this upstream thing is tricky stuff!

In any case, I have one ack which at least fixes the adc for one-shot mode in the mainline!
now for continuous mode.. I wanted to fix the triggers too. Lets see..


Wednesday, 17 July 2013

Upstream effort part 1

I'm not expecting the mainline to welcome all the patches with open arms :p

But let the bashing begin. :)

Upstreaming continuous support for the ADC drivers for the BBB.

Monday, 15 July 2013

Project video

A bit late. but better late than never :)

I liked the idea of two narrating robotic voices from a youtube video once. the cooler software xtranormal is being shutdown. But this goanimate website is cool stuff too.

Exporting the video to youtube costs money lol. i'll pay the fee if it passes and is needed on youtube. Their own online player is pretty cool. Should be sufficient.

gsoc project video beagleboard by ZubairLK on GoAnimate

Sunday, 14 July 2013

Continuous sampling mode for ADC driver for BBB. Kernel 3.10!


Finally got it to work!

That was a rather large pain. And I'm not sure how it will be received by the mainline folk either.

Basically the 3.2 based tree by TI had patched their am335x driver for continuous sampling. However, iio had changed quite a bit from 3.2 till 3.10.

Forward porting all changes meant going through everything and checking the latest stable drivers to see what the difference was. The differences were minor. But there nonetheless..

And this is a rather large changeset! I was concerned that the patch was becoming rather huge. But then. It is a rather large feature. So can't do this in small increments.

The first patch adds continuous sampling and some fixes to it all bundled together. The original author is Patil Rachna. I kept the bug fixes later on by Russ dill as separate patches.

Thank-fully the driver was there and I was only reworking it. Going through the TRM helped a bit in understanding the flow a bit. But I didn't have to make it from scratch which would have been an even bigger pain. Especially as the TRM can be very cryptic..

Patches available at

Sunday, 7 July 2013

Ring Buffer issues

Access to the ADC using the /dev/iio entries is supported on the kernel side by implementing buffers.. /dev/iio is basically used for continuous sampling.

One-shot sampling is implemented via the sysfs interfaces. One-shot is up and running. So now I turned my attention to continuous sampling.

TI has implemented it for 3.2 in the following commit.;a=commitdiff;h=b332370651a7d64d3c6ed8780d939fc18163e141;hp=09597d7a244a8e6f5ea79da3c5dced3a5ea620c4

I went through it manually and applied all the changes to my adc file.


I found out that it was a big time waste. The underlying buffer being used by the driver in the 3.2 based tree was implemented in ring_sw.c

This buffer was depreciated and none of the drivers use it any more!
The linux kernel has moved on to another kfifo based implementation or something.

This patch is might require some really nitty gritty work.. Or it might just be a few carefully chosen lines to replace..

Uboot tftpboot notes Good stuff on automating tftp boot.

uenv to boot from the kernel on my laptop

optargs=quiet drm.debug=7

#run tftpboot 0x80200000 uImage
#uenvcmd=run loaduimage run loadfdt run mmcargs bootz 0x802800000 - 0x80F80000

bootargs=console=ttyO0,115200n8 root=/dev/mmcblk0p2 ro rootfstype=ext4 rootwait
uenvcmd=echo "Booting from Network";tftpboot 0x80200000 uImage; bootm 0x80200000

Friday, 5 July 2013

Pull requests

Took a while to get git up and running the way i wanted.
It can have a steep learning curve!

And we have pull requests for the 3.8 tree for the 3.11 tree

Time to chill for the weekend!

Update. They've been merged. Yeaaaaaaaaaaa :)

4 wire resistive touchscreen HW emulator

While the TSC is on its way, I couldn't just move on with tinkering the ADC drivers without knowing if I've accidentally broken the TSC ones.

So here comes the hardware 4 wire touchscreen emulator!

Folks at #beagle-gsoc were pretty helpful in guiding me on how to test the TSC without the TSC.

"evtest /dev/input/touchscreen0 " runs a great utility detecting touchscreen input.

And the hardware is just resistors/potentiometers.

I googled and after a while. This is what I could come up with. Note : Dont use 100K ohm resistors. I tried. It doesnt work. :p
These are in the range of 10K ohms.

The circuit is kinda like.

AIN0 --- Pot1        Pot4 ---AIN2
               |               |
                    Pot 3
               |               |
AIN1 --- Pot2          Pot5--- AIN3

evtest gives great output. pot 3 controls the pressure value.
pot 1/2/4/5 control X/Y coordinates.

Who needs a touchscreen when you have potentiometers! :)

Thursday, 4 July 2013

One-shot ADC reading in 3.11

I successfully reinvented the wheel :)

After realizing that IIO was disabled in Kconfig, it was easy once things started running somewhat. Previously it'll all be just blank!

Manually re-based the patches that I had done previously for 3.8.

I have one-shot ADC reading up and fixed for 3.11.

These patches can be upstreamed too! Especially the one that fixes the first sample read and the Ebusy signal bugs.

The iio-scale parameter requires a bit more refinement. At the moment, I have fixed the scale to 1800mV which is for BBB. Ideally this should be read from somewhere(perhaps a configured register..) or an input via sysfs..

I really need to get around configuring the resisters for the TSC test. Evtest works great. But I'll need switches and a few pots for a proper test bench..

Too pre-occupied with the MSc thesis during the day time.

Now for looking at how to update my github fork so that I can upload these patches and send a pull request to koen.. Have to send that pull request for the 3.8 ones too..

IIO in 3.11

It took ages to realize that IIO had not been enabled in the Kconfig file!!

I was trying to debug why the ADC wasn't working and if the DT was wrong etc.

O well.. I guess a guy has to learn these things from experience..

Wednesday, 3 July 2013

IIO Map for bone-helper

IIO has a map interface that was used by the bone-helper function.
This was added via a patch in the old patch series.

I didnt want to disturb people using the bone-helper function so I added the patch (after the required modifications) to my series as well.

the bone-helper now works great. Doesn't give erroneous values. And doesn't require multiple refreshes either.