Pleco Phase01 completed

I started playing with microcontrollers in 2005 and, if not at the very start, at least very quickly I decided to aim to have some sort of remote controlled Linux device with controllable camera with digital wireless communication. Now, 6 years later, I have completed my first phase :)

Couple of photos of the earlier devices are shown in the project page.

After several planning iterations and code rewrites I ended up using Qt both on the remote controlled Gumstix and on the GUI controller. I decided that trying to optimize everything from the memory and CPU consumption to the network bandwidth just isn’t worth the time spent in implementing it. The most CPU intensive task is the video encoding to H263 and that’s done in the DSP. I’m running MeeGo on the Gumstix and it provides e.g. the GStreamer plugins for the DSP.

Using Qt framework with self made simple protocol over UDP I got the Phase01 code implemented quite quickly compared to my previous efforts. The protocol allows low priority packets (like periodic statistics and video stream) to be lost and guarantees the passing of high priority packets (control commands etc.). Also only the latest control command of each type is retransmitted, i.e. an old packet is not retransmitted if a new overriding command has already been given.

The controller GUI shows the states the slave sends, like motor speeds, WLAN signal strength, CPU load average and some protocol statistics like round trip time and the number of retransmissions.

Currently the motors are controlled using the a,s,d,w keys in 10% steps and the camera is controlled dragging the mouse left button pressed on top of the video window.

Here’s a video (direct link) of the Phase01. You need HTML5 video capable browser with Ogg Theora/Vorbis codecs.

Speex encoder on n800’s DSP

I’ve been wanting to run things on OMAP‘s DSP processor since the day I tested an OMAP1510 development board some years ago. Finally after a Proof of concept G.711 dsptask mail by Simon Pickering I decided to cut’n’paste that and try.

I knew the Speex had already been ported to the DSP (TMS320C55) used by OMAP1 (770) and OMAP2 (n800) so I started porting it to the DSP Gateway to be able to use it in my n800.

The DSP Gateway’s DSP tasks are seen as /dev/dsptask/<taskname> devices on ARM side and are interacted with read, write, and ioctl calls. Very linux stylish and convenient in my opinion. On the DSP code one struct defines callbacks for these calls. The code overhead on DSP side is some tens of lines.

Speex has speex_alloc functions that can be overwritten if the default memory allocation is not suitable. In the existing DSP port these were overwritten with functions using preallocated global char arrays that are used for all allocations, freeing is not possible. The DSP char is 16 bits as is int. The long is 32 bits and a pointer is 23 bits. Long long is 40 bits. I had some problems with calculating with pointers (casting a pointer to long didn’t produce valid looking value) in the existing implementation so I rewrote the allocation functions to use arrays and indexes. Also the existing implementation printed pointer values as %x which seemed to print completely different values than %p. I did use dbg() however, not fprintf.

The dbg() prints will be shown in dmesg or syslog on the ARM side if the kernel is compiled with mbox debug. The n800 stock kernel is not, but it’s almost trivial to compile a kernel of your own. My kernel with mbox debugs and built-in ext3 is here.

Other than the allocation functions there was not much to port, couple of functions calling the speex’ init and encode functions. I did have an odd problem though: the DSP seemed to jam after some tens of seconds and the DSP kernel was rebooted. After I added poll_disable(task) in my encoding callback function, the jamming was gone. The function will disable the polling for 10 seconds. Afaik, that should be called only if the completion of the function takes more that 10 seconds, which it doesn’t.

My speex patch against the git head is available, if somebody wants to test it. There can be some weirdness as this is my first test with the DSP stuff and I don’t even know how to use the git ;)

If my measurements are correct it takes roughly 40 ms to encode one 20 ms frame without compiler optimizations. With -o3 it takes a bit over 20 ms. The speex is meant to be portable and has a header defining some math functions. The functions are ported to different CPUs like ARMv5 and Blackfin. Maybe some DSP guru quickly ports those to the TMS320C55 too? :)

I think the best place for DSP information for the tablets is in maemo.org wiki as I hope it will be kept up to date with the latest projects and tweaks. One thing to be added there would be a note about the skeleton page. I used the Active Block Receiving and Active Block Sending.