nRF24L01+ wireless transceiver on the mini2440!

Over the festive period Will and I ported Neil MacMillan’s nRF24l01 driver for the Atmel AT90 to the mini2440. Neil has an excellent description of the radio and his driver on his website. The exact series of events are hazy, but they went something like this:

1) Configure SPI and enable a pullup for the IRQ pin in the mini2440 kernel.

2) Modify the spidev module to expose the IRQ using the userspace I/O system.

3) Write new SPI functions to interface between the radio and Neil’s driver.

4) Write a threaded interrupt handler to deal with the IRQ from the radio.

6) Port the driver to an ATmega16 development board and configure this as a receiver for testing.

5) Write a user space program to configure the radio as a transmitter and transmit a test message to the ATmega16 dev board.

We used the following development environment:

..and here are the modules on the dev boards:

The code for all of this (alpha at best) is available here:

The next stage is to improve the speed of the driver. We currently estimate a maximum bandwidth of ~10B/s with jiffies set to 1000 which is a fraction of the true potential. One of the ideas so far is to move the SPI routines, the chip enable toggling and the interrupt handling back into the kernel, and then interface with something like a netlink socket. If anyone has any helpful advice we’d be pleased to hear from you.

More details will be posted on our forthcoming website which is TBA.

Building Angstrom for the mini2440 with Fedora 15

Here’s a quick update for anyone struggling with building Angstrom for the mini2440 on Fedora 15 (probably also relevant for F14).

If you’re using BusError’s original repo then follow the OE instructions as normal, then you can use this guide if you want. As mentioned you’ll need to downgrade patch. I also had to downgrade make due to some incompatibility.

yum downgrade patch --releasever=12

yum downgrade make --releasever=13

At first i had some error about the GPG key so i downloaded them for F13 and F12 from here. You can install them like this, for example:

rpm --import E8E40FDE.txt

Then, you’re good to bake.

If you want something bleeding edge you’ll need to get your hands dirty, OE has changed a lot recently!

CAT3626 RGB LED Driver + Qt Embedded 4.6 on the Mini2440

The CAT3626 is a nice little I2C device from ON Semiconductor. It comes in a 14 pin TQFN package which is probably the most difficult thing i’ve ever soldered! Each pad is separated from it’s neighbour by about 100 micrometers! To make matters even more difficult there’s a ground pad right in the middle for sinking heat away. Really you should get some sort of breakout board or reflow it but that would be boring! Here’s a picture of the device before soldering:

…and here’s the finished product! The LED is 10mm diffuse with a common anode and a maximum current rating of 20mA per channel.  As soon as i’d soldered the wires to the CAT3626 i glued it to the board with epoxy, threaded the wires through the holes and then glued those down with more epoxy. After that i realised i’d forgotten where pin 1 had gone so i had to scrape the glue off the top of the chip!

The wire coming through the hole in the middle of this picture is soldered to the CAT3626 and acts as a crude heat sink. In practice it seems to work well enough although i probably should have used copper. I pulled the ceramics from an old projector i had lying around. Not the neatest job but it works fine!

After I’d built that i tested it quickly using I2C tools and then wrote a kernel driver.  The CAT3626 allows a maximum of 32mA per channel regulated in steps of 0.5mA. Unfortunately because my LED can take a maximum of 20mA per channel i can only generate ~64,000 colours. To make matters worse the light intensity is not in general a linear function of the input current so the achievable fade sequences are not as nice as those done with PWM but they still look pretty good. Here’s a video!

Watch this video on YouTube.

Update: The kernel driver for the CAT3626 is now available for free on github!

Chameleon 135 for the Mini2440

Thanks to both Will and I now have the Chameleon 135 enclosure for the Mini2440.  I’ve been working on a li-ion charger and once that’s finished we should be ready for some field testing. It takes a little while to get the holes drilled in the right place but once it’s screwed together the case is extremely sturdy. There’s loads of room inside for additional wiring 🙂

You can get the Chameleon from

Fix the lacking vosao database indexes from a vanilla 0.8 install

Certain database queries made using the Google app engine (GAE) require a set indexes to be created before they can be executed successfully. There appears to be a bug in the vanilla installation of vosao where the datastore indexes for the PageEntity are not automatically created.

Screen shot of database indexes in the GAE control panel

A symptom to look out for is the archive page not returning any results when you click on a month in which you have blog entries. As there is no indication from the CMS itself, this can be rather difficult to diagnose.

However, if you look deeper you will likely see an array of warning messages in the log section of the GAE dashboard.

The messages will likely contain something cryptic like this:

AbstractService BeanImpl - -no matching index found..

Along with info about the offending entry:

    <datastore-index kind="PageEntity" ancestor="false" source="manual">

        <property name="parentUrl" direction="asc"/>

        <property name="publishDate" direction="asc"/>



Fortunately the solution is a simple one.

If you uploaded vosao to the app engine yourself, Simply create a file called datastore-indexes.xml in the WEB-INF directory of the extracted vosao archive archive, and paste in the following text:

<?xml version="1.0" encoding="utf-8"?>



    <datastore-index kind="PageEntity" ancestor="false" source="manual">

        <property name="parentUrl" direction="asc"/>

        <property name="publishDate" direction="asc"/>



The path to this file should be something like the following:

<path to extracted vosaocms-0.8.war>/WEB-INF/datastore-indexes.xml

Rerun the in your app engine bin directory:

<path to app engine sdk>/bin/ update <path to extracted vosaocms-0.8.war>

Next in the configuration section of the CMS control panel, browse to the “Site Configuration” tab and click on “Export” . Perform a full export, and save the resulting file to some where safe.

After the exporting has completed, making sure you are still on the same page, click cache reset.

Wait for this to complete before finally pressing “Create Search Index”.

If you browse back to the database indexes section in your GAE dashboard , you should find a page similar to this:

Screen shot of database indexes in the GAE control panel

Please note there may be some delay before your PageEntity is ready to serve.

Check that everything is ok by visiting the archives page, or using a statement such as:

${service.findPageChildrenMonth("/blog", $year, $yearMonth)})

with the velocity engine. Here, $year and $yearMonth are a year and month or one of your blog entries. If all goes well this should return non-empty list ( an empty list will display [ ] ).

Useful Information:

Google indexes FAQ

Google help page on database indexes with an example datastore-indexes.xml

Vosao setup help page

Bluetooth GPS on the mini2440 with GPSd

For a long time i’ve had a SiRF 3 bluetooth GPS which i’ve just connected to the mini2440 using a ludicrously cheap USB bluetooth adapter from DealExtreme. Including shipping it cost £1.38 delivered!! Here’s what you get for your money:

The chip is a Conwise CW6626. Anyway, what matters most is that if you have bluetooth configured it works out of the box!

Connecting to the GPS is easy. First check the interface:

hciconfig -a

If it says down bring it up:

hciconfig hci0 up

After executing the above I got the following:

root@mini2440:~# hciconfig -a
hci0:    Type: USB
BD Address: 00:15:83:15:A3:10 ACL MTU: 672:3 SCO MTU: 128:2
RX bytes:348 acl:0 sco:0 events:11 errors:0
TX bytes:38 acl:0 sco:0 commands:11 errors:0
Features: 0xff 0x3e 0x85 0x30 0x18 0x18 0x00 0x00
Packet type: DM1 DM3 DM5 DH1 DH3 DH5 HV1 HV2 HV3
Link policy:
Name: ''
Class: 0x000208
Service Classes: Unspecified
Device Class: Phone, Cordless
HCI Ver: 2.0 (0x3) HCI Rev: 0xc5c LMP Ver: 2.0 (0x3) LMP Subver: 0xc5c
Manufacturer: Cambridge Silicon Radio (10)

Now turn your GPS on and do a scan:

root@mini2440:~# hcitool scan
Scanning ...
00:0D:B5:32:2C:02    BT-GPS-322C02

Now fill in /etc/bluetooth/rfcomm.conf with the details. Here’s mine:

# RFCOMM configuration file.
rfcomm0 {
# Automatically bind the device at startup
bind yes;

# Bluetooth address of the device
device 00:0D:B5:32:2C:02;

# RFCOMM channel for the connection
channel    1;

# Description of the connection
comment "BT-GPS-322C02";

Next bind the device:

rfcomm bind rfcomm0

And check the device output using:

cat /dev/rfcomm0

Next i bitbaked gpsd, by simply typing:

bitbake gpsd

In my OE installation (see the various posts about setting this up).

Once this builds you can install the appropriate ipks. From memory I think i installed the following:






This pulled in a whole load of other packages. Next you can start gpsd by typing:

gpsd /dev/rfcomm0

And monitor the output using:


If all has gone well you should get a text output of the parsed NMEA data:

Anyway..that’s just the tip of the iceburg. If you want to learn more have a look at the gpsd website and the bluetooth page i have based this post on.

Qt Embedded 4.6.0 + Qwt + kxps5 accelerometer!

After testing the operation of the kxps5 accelerometer with i2c-tools i wrote a test application using the i2c-dev interface. If you want to test your code before you write a kernel driver this is definately a good place to start. Once i had the configuration registers set properly and i had a routine for reading the acceleration vectors I stripped down a ds1621 kernel driver to a bare minimum, and then built it back up again to work with the kxps5. I then bitbaked the kxps5 driver as a kernel module, along with hwmon and it works perfectly! 🙂 Next i cross compiled qwt 5.2.0 and plotted the acceleration as function of time. The video below is taken with antialiased lines which slows down the refresh rate but makes them look nice. If you plot it without this enabled it runs very smoothly. Here you see the kxps5 running without an external low pass filter (the internal filter is 1kHz) and despite this the output is pretty stable. What impressed me the most is the sensitivity. When placed on a desk the free fall interrupt indicator lights up if you drop one of the little nuts from the friendlyarm LCD about 10cm away from the device!

Watch this video on YouTube.

The kernel driver for this is now available here.

Bitbaking the kernel, Angstrom and qt4-embedded all at once

This is what i should have done to begin with! The instructions are very similar to previous ones except this time we clone the right git repository!

On a fresh copy of Fedora 11 I updated the system and installed the packages reccommended by OE:

su -cyum install python m4 make wget curl ftp cvs subversion tar bzip2 gzip unzip
python-psyco perl texinfo texi2html diffstat openjade docbook-style-dsssl
docbook-style-xsl docbook-dtds docbook-utils sed bison bc glibc-devel glibc-static
gcc binutils pcre pcre-devel git quilt groff linuxdoc-tools patch linuxdoc-tools
gcc-c++ help2man perl-ExtUtils-MakeMaker”

I then made a folder called OE in my home directory and git cloned the mini2440 repo:

cd ~

mkdir OE

cd OE

git clone git:// openembedded

I then setup the source-me.txt similar to before:

gedit source-me.txt

I put the following in:

export OETREE="/home/doug/OE"


echo Setting up dev env for Ångström

if [ -z ${ORG_PATH} ] ; then
export ORG_PATH

if [ -z ${ORG_LD_LIBRARY_PATH} ] ; then


export LANG=C

su -c 'sysctl vm.mmap_min_addr=0'

echo "Altered environment for OE Development"

Now all you need to do is setup the local.conf. Simply edit the example and copy it to the right place:

cd openembedded
gedit mini2440_local_conf_example.conf

Read this file and edit as appropriate. I have attached mine as an example. Now copy it to the conf/local.conf

cp mini2440_local_conf_example.conf conf/local.conf

If you want qt4-embedded or any other package included in the build simply edit the recipe in:


I added qt4-embedded:

#Angstrom bootstrap image

IMAGE_PREPROCESS_COMMAND = "create_etc_timestamp"


DEPENDS =  "task-base-extended
esekeyd u-boot-utils tslib
i2c-tools i2c screen rsync nfs-utils
directfb gdbserver directfb mtd-utils

IMAGE_INSTALL = "task-base-extended
psplash-zap qt4-embedded
esekeyd u-boot-utils tslib-calibrate tslib-tests
i2c-tools i2c screen rsync nfs-utils-client
directfb gdbserver directfb mtd-utils
rsvg pango

export IMAGE_BASENAME = "mini2440-image"

inherit image

Then all you have to do is source the script from wherever you put it:

source source-me.txt

and run bitbake:

bitbake mini2440-image

from the ~/OE/openembedded/ directory..

If you get an error trying to build a package try cleaning it:

bitbake -c clean INSERTPACKAGENAME

Then try and build the image again. Maybe you won’t have this problem. I guess it’s either because the checksum parser failed to build or my hdd is dodgy. It only happened once on binutils but worked fine after cleaning it.

A few hours later if all goes well you should have images in:


Obviously that directory depends on what you setup in the local.conf.

Good luck!

Configuring Open Embedded to bake Angstrom images for the mini2440

Please Note: I noticed a few people were having trouble with the Angstrom build using Doug’s article, so I thought I’d post the exact method I used (which seemed to work!) so others can retrace my steps with out confusing anyone by editing the previous article! If you have already successfully baked an Angstrom image please ignore this post!

First off I’d like to point out that this article is essentially an amalgamation of the Open Embedded Wiki (Getting Started) and Angstrom’s ‘Building Angstrom’ articles but in context relating to the mini2440 Embedded PC. If you would like a more detailed and probably better written explanation please refer to these two articles.

Make sure you have the packages needed for Open Embedded(OE) by visiting here and looking under the section relating to your distro. Running fedora 11 I did:

su -c "yum install python m4 make wget curl ftp cvs subversion tar bzip2 gzip unzip
python-psyco perl texinfo texi2html diffstat openjade docbook-style-dsssl
docbook-style-xsl docbook-dtds docbook-utils sed bison bc glibc-devel glibc-static
gcc binutils pcre pcre-devel git quilt groff linuxdoc-tools patch linuxdoc-tools
gcc-c++ help2man perl-ExtUtils-MakeMaker"

Getting down to business…

Open up a terminal. Issue these commands:

su -
mkdir -p /stuff2/build/conf
chmod 777 -Rf /stuff2/
cd /stuff2/

Download latest bitbake from here and extract the bitbake directory in the archive (eg. bitbake-1.8.16) to /stuff2/

A few more commands:

mv bitbake-1.8.16/ bitbake
git clone git://
cp openembedded/conf/local.conf.sample build/conf/local.conf

Edit the config you have just copied using your favourite text editor.

gedit build/conf/local.conf

It is important that you read the config carefully so that you understand what everything does…

Next edit it to look something like this (which is just a slightly modified version of openembedded/contrib/angstrom/local.conf) :

Note: Do not copy and paste from this article due to formatting issues. You can download a pre-made local.conf here.Just extract to /stuff2/build/conf/ …

MACHINE = "mini2440"

# Where to store sources
DL_DIR = "/stuff2/downloads"

INHERIT += " rm_work "

# Make sure you have these installed
ASSUME_PROVIDED += "gdk-pixbuf-csource-native imagemagick-native librsvg-native"

# Which files do we want to parse:
BBFILES := "/stuff2/openembedded/recipes/*/*.bb"

# What kind of images do we want?
IMAGE_FSTYPES += " tar.bz2 "

# Set TMPDIR instead of defaulting it to $pwd/tmp
TMPDIR = "/stuff2/${DISTRO}-dev"

# Make use of SMP and fast disks

#INHERIT += "oestats-client"
OESTATS_BUILDER      = "myname"

DISTRO = "angstrom-2008.1"

Save and exit the editor. Download this script and move it to the directory /stuff2/ .

Check it is ok:

gedit /stuff2/source-me.txt

It should look something like this:

export OETREE="/stuff2"
export PATH=/stuff2/bitbake/bin:$PATH
echo Setting up dev env for Ångström

if [ -z ${ORG_PATH} ] ; then
export ORG_PATH

if [ -z ${ORG_LD_LIBRARY_PATH} ] ; then



export LANG=C

echo "Altered environment for OE Development"

save, and start the script:

cd /stuff2/
source source-me.txt
cd ../openembedded

one last update:

git pull

Issue a few commands to fix build issues:

sysctl vm.mmap_min_addr=0
setenforce 0 (Fixes an SELINUX problem during building)

issue build commands:

bitbake base-image ; bitbake console-image ; bitbake  x11-image

Be prepared to saturate your internet connection, wait a long time and take up a lot of disk space!
The result ends up in:


You should have the image(s) in .jffs2 for flashing and .tar.gz for mounting using NFS.

New hardware!

After breaking the z-axis connection on my first device I ordered a new KXPS5 accelerometer from crodnet on ebay. I really recommend this seller, he’s very cheap and sends things rapidly.

I quickly knocked together a circuit on veroboard and hooked up the base of a transistor to the freefall / motion interrupt pin to check it was working. It is remarkably sensitive, the LED flicks on if i drop my pen at one end of my desk when the device is at the other! I was quite pleased that everything was working well so i hooked it up to the I2C bus using the cable kit kindly supplied by Using I2C tools i was able to set registers and read acceleration vectors without any trouble so i’m pretty sure everything is working well. I was a bit worried about exceeding the bus capacitance at first.



It turns out that i can still use the old device if i rely on the internal low pass filter. I was thinking of doing this anyway and using a Kalman filter to process the output. First i need to write a device driver so i’ve rapidly being trying to learn C. So far i’ve got a very basic kernel module up and running on the mini2440 🙂