Sunday, December 8, 2013

UDOO: Adding IR and Building LIRC Kernel Module

I wanted to use inexpensive Adafruit's IR to integrate Udoo with a remote control and audio/video applications such as MPD,  XMBC and simply shut it down by pressing a button on a remote control.

It was not clear how to do that with this IR chip and what driver to use. Since I didn't find any LIRC kernel modules in the default Ubuntu distro for Udoo Dual, I've decided to build them.

My first attempt was around known lirc_serial driver that I tried to use with  iMX6's serial port /dev/ttymxc3 that is normally used for SAM3X (Arduino) to iMX6 communications and programming SAMX3. This port has its Rx and Tx interfaces exposed through Arduino's GPIO #0 and #1.

However, all attempts to make it working this way were fruitless - something didn't allow the signals to go through from Arduino's GPIO #0 to iMX6 (either with or without jumper 18 that controls this port).

The second obvious approach was to change known lirc_rpi driver that I've successfully used with RaspberryPI and make it suitable for Udoo device.

Fortunately, the changes were not that big and I got my brand new lirc_udoo driver working well with the IR in a couple of days. This is how my hardware solution looks like:

The IR receiver is in the upper right corner, the red LED on the right is an activity monitor that I was already writing about in the previous blog.

If you use a device of the same configuration with a stock Ubuntu kernel, you might need only binary modules - lirc_dev and lirc_udoo.

If you want to compile the LIRC modules yourself, you'll need to install Udoo kernel sources and lirc_udoo sources (lirc-udoo-3.0.35-src.tgz). Download them to a local directory on your Udoo device and run the following commands:

cd <kernel-src>
7z x
tar xzvf lirc-udoo-3.0.35.tgz
make oldconfig
chmod +x /root/kernel/Kernel_Unico-master/scripts/setsecoversion (I think this is a bug)
make prepare 
make modulesmake modules_install

You'll also need to make links from /lib/modules/3.0.35 to kernel's 'build' and 'source' dirs:

cd /lib/modules/3.0.35/
ln -s <kernel-src>/Kernel_Unico-master build
ln -s <kernel-src>/Kernel_Unico-master source

Finally, to check if your newly created kernel module works run:

modprobe lirc_udoo gpio_in_pin=<N> debug=1

<N> is a iMX6's GPIO input pin number used as an IR's signal receiver. By default it's 92 and this is what you could see on the picture above.

If everything was built correctly you should see something like this in your /var/log/syslog file:

Dec  9 00:58:00 imx6-qsdl kernel: [   83.145090] lirc_udoo: module is from the staging directory, the quality is unknown, you have been warned.
Dec  9 00:58:00 imx6-qsdl kernel: [   83.147076] lirc_udoo: lirc_udoo_init: in=92 out=-1 softcarrier=1 sense=-1
Dec  9 00:58:00 imx6-qsdl kernel: [   83.154221] lirc_udoo lirc_udoo.0: lirc_dev: driver lirc_udoo registered at minor = 0
Dec  9 00:58:00 imx6-qsdl kernel: [   83.154253] lirc_udoo: driver registered 0!
Dec  9 00:58:00 imx6-qsdl kernel: [   83.154298] lirc_udoo: is_right_chip gpio-2 64 92 00000000 00000000
Dec  9 00:58:00 imx6-qsdl kernel: [   83.154326] lirc_udoo: cant claim input gpio pin 92
Dec  9 00:58:00 imx6-qsdl kernel: [   83.154343] to_irq 348
Dec  9 00:58:00 imx6-qsdl kernel: [   83.234761] lirc_udoo: Interrupt 348 obtained 0

After verifying that everything works as expected, you can remove 'debug' parameter in 'modprobe' to reduce the number of messages in syslog.

Installing all other LIRC tools (lircd, irw, irexec, mode2, etc.) is simple and doesn't differ from the RaspberryPI case.