Monday, June 18, 2012

Arch Linux on a WM8650 netbook

UPDATE 20th November 2012: Due to recent changes in the Arch Linux boot process, this tutorial is no longer valid. You can still download an old pre-built image and install it, as I explained here. But with this old image, updating the distro (with pacman -Syu) will most likely throw some errors and maybe even break the system. Also installing applications without updating the distro (with pacman -S application_name) will likely fail because of the not updated dependencies.

If you have searched the net for a very cheap tablet, maybe you have seen a lot of  7" chinese ones featuring the WM8650 SoC. This SoC has an ARM9 CPU running at 800 MHz, a DSP, a 2D graphics accelerator and a lot of peripherals.


I don't like tablets at all, but I found some cheap chinese netbooks containing pretty much the same hardware, removing the touchscreen and replacing it with a keyboard + touchpad. I couldn't resist and bought one of these netbooks in Aliexpress. It costed me around 50€, shipping costs included. The specs of this machine are:
  • Wondermedia WM8650 SoC at 800 MHz.
  • 256 MiB DDR RAM (I think it runs @ 800 MHz, but I'm not sure).
  • 2 GB internal NAND Flash.
  • 7" 800x480 pixels TFT screen.
  • 3 USB Host ports.
  • 1 Ethernet port.
  • WiFi.
  • Headphones and microphone ports.
  • Internal 7,4V 1800mAh LiPo battery.
  • 9V 1,5A power adapter.
  • Android 2.2.

The Android distro that comes pre-installed is pretty usable even without a touchscreen. As the specs of this machine are really far from being impressive, it doesn't run butter smooth, but works very well.

Android is OK, but as an Arch Linux fan I am, I wanted to make this netbook run it, so I started searching the net to see if anybody had already made it. The only thing I found was a Debian port for these netbooks, using the kernel from a preinstalled Android distro. This Debian port works, but isn't very well optimized, and for example, boot time takes almost 2 long minutes.



The closest thing I found is an Arch Linux port for a WM8650 based tablet. This tutorial is really great and very well detailed, and my work getting the kernel built is almost entirely based on it. John has made a really good job getting the Linux kernel built for these tablets.

In this post, I will detail the process I have followed to get a base Arch Linux system running in this netbook, but I will skip the kernel build process (maybe I'll detail it in a later blog post).

OK, let's get our hands dirty. You will need a SD card. The minimum required size of the SD card is 2 GB, but I recommend using at least a 4GB card, unless you don't need a desktop environment. The steps to get Arch Linux running are:

  1. Partition and format the card. To do it, I have used gparted application. First create a very small FAT32 partition, and name it BOOT. The smallest partition gparted allowed me to create was 33 MiB, more than enough (we need less than 4 MiB). Then create a ext3 partition using the remaining space, and label it ARCH_SYS.
Partitions created in the SD card
  1. Copy the boot script (wmt_scriptcmd) and kernel (uzImage.bin) to the BOOT partition. Download them here. Then run:
tar -xjf alarm-wm8650-boot.tar.bz2 -C /run/media/doragasu/BOOT/
Make sure to replace "/run/media/doragasu/BOOT/" with the directory where the BOOT partition of the SD card is mounted.
  1. Download the root filesystem and untar it in the ARCH_SYS partition:
wget http://archlinuxarm.org/os/ArchLinuxARM-armv5te-latest.tar.gz
tar -xzf ArchLinuxARM-armv5te-latest.tar.gz -C /run/media/doragasu/ARCH_SYS/
Make sure you replace "/run/media/doragasu/ARCH_SYS/" with the directory where the Arch Linux system partition is mounted, here and from now on. Also make sure to run it as root (write sudo before the tar command if you are not root).
  1. Copy the kernel modules to the ARCH_SYS partition. Download them here, and run (as root):
tar -xjf alarm-wm8650-modules.tar.bz2 -C /run/media/doragasu/ARCH_SYS/
  1. We are ready for the first boot. Unmount the SD card, insert it in the netbook and power it on. You should see the Android robot, and then the messages Loading Kernel... and Starting Linux... should appear. In a few seconds, you should be able to see the boot messages, and finally get the login prompt. The first boot will take a lot of time because udev has some problems and eats almost all the CPU. We will fix these proplems in the next step. Default password for the root user is root.
  2. Udev needs the accept4() OS call, that is not supplied by the Android kernel I have built. To fix this, you have to install libaccept4. Download this package and put it inside the SD card (for example in /root). Then start Linux, login as root and in the console change to the directory containing the downloaded package and type:
pacman -U libaccept4-570-1-arm.pkg.tar.xz
echo /usr/local/lib/libaccept4.so >> /etc/ld.so.preload
Accept the installation of the library, and reboot. Udev should be working fine from now on, and boot time will be a lot shorter.
  1. To extend battery life, power to the internal WiFi dongle is off by default. To enable it, you need to toggle the GPIO pin controlling its power. Download this package, copy it to the SD and install it with the following command:
pacman -U wmt-gpio-1.0-1-arm.pkg.tar.xz
Upon installing this package, to enable the WiFi chip, you have to input the command:
gpio 1:6:d8110040:d8110080:d81100c0

And to disable the WiFi chip:

gpio 0:6:d8110040:d8110080:d81100c0
You can create two scripts with these commands, or if you always use WiFi, you can add the first one to /etc/rc.local, to enable WiFi each time the system boots.
  1. To read the battery charge level, use the following command:
cat /sys/class/power_supply/wmt-battery/capacity
  1. To change the screen brightness, you have to write a number between 0 and 255 (the greater, the brighter) to /sys/class/leds/lcd-backlight/brightness. For example:
echo 200 > /sys/class/power_supply/wmt-battery/capacity
You can also add this line to rc.local to set the screen brightness to your favorite level each time the system boots.

Now you have a fully functional base Arch Linux install. It's highly recommended to update your system (pacman -Syu). Then you can start installing your favorite utilities, window manager, etc., by following the instructions documented in the awesome Arch Linux Wiki.

I'll give you some hints for Arch Linux newbies. Skip them all if you are experienced with this distro. You can start by editing /etc/rc.conf. This file contains some basic configuration parameters, like for example the timezone (TIMEZONE), the hostname (HOSTNAME) and some basic network configuration parameters (that default to DHCP on the Ethernet port). Very important in this file is the last line, detailing the services started when the system boots, and the order in which they are started. I usually remove netfs from the list, replace network with networkmanager (you'll have to install it first) and add dbus (you'll need it for the window manager and some more programs). If you use networkmanager instead of network daemon, make sure you put it after dbus.

To set the locale (in case you don't want the default en_US.UTF8), you have to follow these steps:
  1. Edit /etc/locale.gen. This file details the locales generated by the system. You can replace/add the desired locales to this file. For example, to generate locales for spanish language, add:
es_ES.UTF-8 UTF-8  
es_ES ISO-8859-1  
es_ES@euro ISO-8859-15  
  1. Generate the new locales by running (with root privileges):
locale-gen
  1. Edit /etc/rc.conf and change the default locale to the desired one. Of course, the locale must be one of the included in /etc/rocale.gen. For example, for spanish:
LOCALE=es_ES.UTF-8

To change the root password, use the command passwd. To create a new user, use the command adduser. Leave the default parameters, but when asked for additional groups, enter the following:
audio,lp,storage,video,wheel,games,power,scanner

It's highly recommended to install sudo and add the user to the sudoers. Just follow these steps:
  1. Install sudo:
pacman -S sudo
  1. Allow all the users in the wheel group to use sudo. Run the visudo command, and uncomment  (remove the '#') the following line:
# %wheel ALL=(ALL) ALL
If you don't know how to use the vi editor, press the [I] key to [I]nsert text, when you finish, press [ESC] to enter command mode and write :wq to write the file and quit the editor. If you mess something up, just press [ESC] to switch to command mode, and write :!q to quit without saving changes. Then try again the visudo command.
And that's all for today. If you followed this tutorial to the end, congratulations! You should be able to launch GNU/Linux in your shiny WM8650 laptop, with the locale, timezone and (hopefully) Ethernet network properly configured. You should be also able to login as a non privileged user, and use sudo to run tasks as root. If you have questions, feel free to ask them.

What? You don't like the console? Don't worry. In the next chapter, we will learn how to install a graphical desktop environment. Stay tuned!

TROUBLESHOOTING:

I have patched the kernel to make it compatible with the environment of the Android distro that comes pre-installed in some netbooks. You should be able to boot Android (without the SD card inserted) and GNU/Linux (with the SD card inserted). It works on my netbook, but it looks like there are different hardware revisions of these netbooks, and some of them, may require to change some variables in the environment stored inside the internal Flash memory. Typical problems that may arise are for example not being able to use the Ethernet port, or losing the ability to read the internal battery level. If you experience these problems, I can provide you with a modified wmt_scriptcmd that changes some variables of the environment stored in Flash, to make the broken things work. But I'll not post it here unless someone asks for it, because if you overwrite some variables, you may break things in the Android kernel (i.e. you can loose the battery level information in Android). And if you didn't back up that variables first, you might not be able to fix these problems.

Other problem that may arise, is that WiFi may not work. WiFi in these netbooks is implemented using an internal USB WiFi dongle. The one used in my unit has a Realtek RT8188CU chipset. I had to search the net for a compatible driver (rtl8192cu) and merge it into the kernel drivers. If your netbook uses a dongle with a different chipset, WiFi may not work. Enable WiFi with the gpio command, run lsusb and show me its output. I'll try to help you to get the dongle working.

Of course you may find a lot more problems. Feel free to ask for help! You can also read the follow-up to this post: Arch Linux on a WM8650 netbook (II).

Sunday, April 22, 2012

The BTKeychain

The BTKeychain is just what its unimaginative name suggests: a keychain with a Bluetooth interface. It's a device I created to solve a problem my wife has: she never remembers where she put her keys. In addition to the Bluetooth interface, the keychain also has a buzzer and a small battery. The Bluetooth interface is always discoverable. This way, if I want to find the keys, I can search the Bluetooth name of the keychain, and then connect to it and make the buzzer beep. You can see the BTKeychain in action in the following video.



Any open device (i.e. anyone you can develop for) with a Bluetooth interface can be used to make the keychain beep. I have coded a script that can be used for this task with any GNU+Linux PC. I have also written a J2ME Java application that should be compatible with any Java enabled phone, and that will make the BTKeychain beep the same way. Of course similar scripts/applications can be developed for Windows, OS-X, Android and iOS devices.

Searching for the keys (sorry about the messages in spanish)

Keys found (sorry about the messages in spanish)
As designing a custom case is expensive, I have used one from one of those cheap photo frame keychains. I threw the original PCB away and took the case and the 180 mA/h LiPo battery. I had to make three holes to the back of the case: one for the status LED, one for the charge LED, and a bigger one for the buzzer output.




Here you can see the designed PCB. It's very small (3cm x 3,5cm) and has the same shape that the original PCB in the photo frame keychain had.




The board has a Bluetooth chip (U1) that includes an internal aerial, a MSP430 microcontroller (U2), a battery charger (U3) and a low drop-out 3.3V linear regulator (U4). The MSP430 microcontroller family was chosen, because this family has the lowest power consumption in the market. Also these microcontrollers are 16-bit, and more powerful than most similar microcontrollers. To make everything fit inside the PCB dimensions, SMD components were used. Passive elements use a 0603 footprint.



If you look closely the photographs, you'll be able to see there's a flaw in the design. The USB connector must be soldered in the opposite side the pads are. So to make it work, you must wire two connections to power the design. Other than this, the board works nice and no more problems have been detected.

In the software side, special care was taken to reach the lowest power consumption possible. The microcontroller is almost always in low power mode (LPM3), and is only awaken when a key is pressed or while the Bluetooth and buzzer are active. The Bluetooth chip requires an external 32 kHz crystal (X1) to be able to go to low power mode (PM0). While idle, the board drains only about 755 microamperes, but each several seconds the Bluetooth chip has fast burst that drain several milliamperes. The battery has a capacity of 180 mA/h, and lasts for two days and a half, so average power consumption must be about 3 mA.

If you want to have a look, you can download the schematics, gerber files and the source files for the BTKeyring firmware, the J2ME Java application and the GNU+Linux script here.

The BTKeychain works great, but... did it solve the problem it was created for? Unfortunately not, because my wife always forgets to charge the keychain O_o. How can I solve this new problem? Maybe using a Bluetooth 4.0 Low Energy device and some kind of energy harvesting? I think getting a new wife will be easier...

My Guruplug + USBLCD

A lot of years ago, I set up a hacked XBox Crystal as a download server, file server and repository. I installed a Gentoo GNU+Linux distro, and I decided not to install X-Windows, because of the low RAM the XBox has (64 MB). The XBox worked great, but due to its low memory, was a bit slow (a lot of HDD thrashing happened) when performing some tasks, like downloading files using aMule daemon, for example. So two years ago, I decided to retire my old XBox to replace it with a Guruplug Server +.

The Guruplug Server + is a nice and small ARM machine. It has a 1,2 GHz CPU, 512 MB RAM, two Gigabit Ethernet ports, WiFi, Bluetooth, an eSata port, two high speed USB host ports, a microSD card reader, etc. The problem with this machine is that it has a flagrant design flaw: The internal heatsink is unable to keep the CPU and memory cool, and this makes the system highly unstable. In my first tests, the system was continuously rebooting even with medium-low CPU loads. This problem was reported to Globalscale (why didn't they discover it anyway?), and in the second batch of Guruplugs, the heatsink was replaced with a tiny and very very noisy fan. The heat problem was solved, but for most users, the noise created a new problem.

To solve the heat problems, I decided to mod my Guruplug. I removed the heatsink, the internal 5V power source (later I used it for The Fonera Plugstrip) and used the hollow it left to add a big heatsink with a silent fan.

The removed tiny heatsink

The removed power source

The heatsink with the fan occupies the space left by the power source

Another capture of the heatsing with the fan
I applied polysynthetic silver thermal compound on the CPU, the RAM chips and the Gigabit Ethernet PHY, and placed the heatsink over them. Then I wired a panel mounted Jack to the 5V input and to the fan power cables. I had to do two holes on the case: a small one for the panel mounted 5V DC Jack, and a big one for the fan. This is the finished mod.

As you can see, the fan has a big air flow input. Ideally, I should have made some more holes to the case, for the air flow output, but it looks like it's not needed, the system works perfect as is, and is very stable (no hangs/reboots in almost two years of work!). To power the entire system, I use a 5V/25W power brick. I could have used a smaller one (maybe 10W are enough), because the entire system drains less than 5W, but as I also have to add a hard disk (about 2,5W more) and maybe some more USB bus powered devices... better safe than sorry.

On the software side, I have built a custom Ångström GNU+Linux distribution. To build the system I have used OpenEmbedded, a set of tools, scripts and configuration files, aimed to build GNU+Linux distributions for embedded systems. OpenEmbedded uses a tool called BitBake for building. BitBake is similar to the Portage tool used in Gentoo distribution, but it is aimed to cross compile for embedded systems.

The Ångström OS image I have built is console based (no X-Windows) and has tools for file serving (samba, ftp, sftp), file sharing (aMule daemon, rtorrent), file downloading (plowshare), and media serving (mediatomb). I have also created some scripts that report specific events to a Twitter account (using OAuth authentication), automagically mount external USB disk drives read only (for unpluging without having to manually unmount them), and share its multimedia contents via mediatomb.

The system works perfect, but I was still missing something: a way to promptly know the system status at a glance, without having to use a computer/smartphone/tablet with a SSH or web client. For that task, I dedided to create USBLCD.

LCD + LEDs + Pushbuttons + USB
USBLCD is just what its somewhat unimaginative name says: A USB board with a LCD. Going into details, it has a 2x12 characters LCD, 6 LEDs, 5 pushbuttons and of course the LCD interface. The heart of the board is a PIC18F4550. There is a small expansion connector to the right of the board, in case I dedide to plug something in (like for example a temperature and humidity sensor). I have defined a simple protocol that allows the host to display whatever it wants in the display and to turn ON and OFF the LEDs. The protocol also defines a way for the USBLCD board to notify the host when a pushbutton is pressed and released.

Guruplug + USBLCD + eSata HDD
A small program running in the host, can display three different screens and switch among them when the user pushes the buttons. The first screen shows the upload and download bit rates, and the disk usage in bytes and %. To the bottom right there is a "spinner" made by cycling the "|/-\" characters. The second screen shows the last file downloaded by plowshare, aMule daemon or rtorrent. The third screen shows mediatomb status and allows to launch and kill it. Just by having a quick look to USBLCD, it's possible to know the system status without the need to launch a SSH client and log in the system. Mission accomplished. If you are interested in making your own USBLCD, or are simply curious, you can get the schematics, gerber files and sources for both the microcontroller and the host here.

BONUS: for the LCD, I have used one without backlight, but the board is also prepared for displays with LED backlight. There is a small mosfet transistor driven by a PWM inside the microcontroller, that can drive LEDs up to 300 mA. I have connected another USBLCD board to a white LED strip and have coded a PWM driver. The firmware allows you to change LED intensity from 0 to 100% in steps of 1%, and it also has a timer that automatically shuts down the light when the count hits 0. Both the remaining time and the LED intensity are shown in the screen. Source files for this function, here.

Saturday, April 21, 2012

The Fonera Plugstrip

The Fonera Plugstrip is a gadget I made to be able to power ON and OFF some home appliances wherever and whenever I want. This device is always connected to The Internet, and can be controlled by any device with an Internet connection and a browser. There are already commercial devices like this, but they are very expensive, and I had a Fonera lying around and wanted to use it for something useful. The control is made using a simple CGI. In this video you can watch the device in action (skip to 1:40 if you don't want to hear how the system has been constructed).



The system has three elements:



In this figure you can see a schematic representation of the elements and the connections among them (clic to make it bigger). The status LEDs and the relay optocouplers have been omitted.


The power entering the plugstrip is routed to the gray box only when the power switch is on. Then it's routed to the 5V power source (that powers the Fonera) and to the relay switches. When the relay switches are closed, power is routed to the sockets in the plugstrip, and devices plugged to these sockets are powered.

Each relay switch is independently controlled by a GPIO pin inside the Fonera. So the Fonera controls when a socket has power or not. A CGI inside the Fonera is in charge of rendering a web page that serves as a control panel for each socket in the plugstrip. The user can interact with this web page, and the CGI will power ON/OFF the sockets accordingly.

The Fonera is a closed platform, so to be able to control the GPIO pins and install software inside it, you have to hack it first. You can find instructions here. Once hacked, it's not necessary, but it's recommended to install OpenWRT, a GNU+Linux distro designed mainly for routers and other similar small systems. Info about OpenWRT and the installation process, here.

And finally we get to code something. I have created an init script that configures the GPIO pins and the default status of the sockets. I have also coded a CGI in Linux shell script that renders the control panel and controls the sockets in the plugstrip. Both of them share a configuration file (/etc/plugstrip.conf) that can be used to map GPIO pins to the sockets, to change the text labels in the web page, to set the default socket status, etc. Grab the sources and installation instructions (including how to set up basic HTTP authentication) here.

This project is almost finished, but I want to add a new feature: the ability to configure time trigged events to power ON/OFF the sockets. I'll update this entry if I get some time to code it.

Serial ICD

This is the last version I built of an ICD2 clone, to program and debug Microchip PIC and dsPIC microcontrollers. It's based in the original In-Circuit Debugger made by Lothar Stolz.

It's the simplest version: must be plugged to a RS232 serial port (no fancy USB ports in this device). It has two LEDs, the green one is the Power LED, the red one is the Busy LED. The switch, when closed, allows to power (5V) the target. The case is the same I used for the RGBUZEBOX, tiny, cheap and easy to work with.



I have used it even with 3.3V dsPICs and it always worked pretty well, for both programming and debugging, but has two drawbacks that doesn't allow me to recommend it if you want to code medium-high or high complexity stuff, or if you plan to use one of the newer chips:

  1. While debugging, stepping through the code, and watching variables, is SLOW, specially with dsPIC chips.
  2. I couldn't make this ICD2 clone work with MPLAB versions later than 7.5. I'm not sure, but I suspect Microchip have added a protection to MPLAB to avoid the use of these kind of devices.
Other than these two problems, it works great. In fact, this is the tool I actually use for my PIC/dsPIC projects!

If still interested, you can grab the schematics and Gerber files here.

RGBUZEBOX

Chances are you know the infamous UZEBOX console. In case you don't, it's an 8 bit console that uses only four integrated circuits: an ATMega, a RGB to NTSC video converter and two linear regulators. It can display up to 256 simultaneous colors, resolution can be up to 360x224, supports NES and SNES controllers, can display up to 32 simultaneous sprites and has 3 wavetable channels + 1 PCM or noise for sound. Not bad for a bare ATMega without any external processors!


I wanted to build my own version, even simpler and smaller than the original. I decided to remove the RGB to NTSC video converter, as here in Europe nowadays most (if not all) televisions have a RGB input. I also decided to remove the 5V regulator, as I'm powering it with a 5V brick. I have used SMD components to  make the board even smaller. For the video output, I have decided to put the same DIN connector used in the Genesis/Megadrive console, so I can use my Megadrive RGB cable to connect this console to the TV. The result:







The console works great, video is really clear (and best viewed in a CRT TV). The most difficult part in making this console was finding the SNES connectors. I bought a cheap multitap in eBay and salvaged the connectors. To enclose the console I have used a cheap and small box (Hammond RL6115, about 2€ in Digikey). The box was customized using just some drills, abrasive files and patience.

This was a very easy to make, funny and rewarding project. You can find schematic and Gerber Files (GPL v3 license) here. For more information, devkit, games and the latest firmware version, go to the Uzebox homepage.

BALSAMO

BALSAMO (Bloqueador Automático de Llamadas Sistemáticas, Automatizadas y Molestas y Ocultas) is a dsPIC based gadget I made to filter incoming calls. At first, I was planning to use a simple 8 bit microcontroller with one of those chips that implement Caller ID (CID) decoding and return the resulting number using a serial line, but to my surprise, all the chips I found (HT9032, CMX602B, HT95168, MT8843, PCD3316) were discontinued, so I decided to implement the CID protocols myself.

CID protocols are described in the standard ETSI EN 300 659 parts 1, 2 and 3. Part 1 details the presentation, data link and physical layers for on-hook data transmission. Part 3 details the used data encoding. Part 2 is for off-hook data transmission. As I have only implemented on-hook data decoding, I have not used part 2.

CID data is transmitted between the first and the second ring patterns, using a FSK modulation, so basically the system has to:

  1. Wait until the first RING is detected.
  2. Enable the FSK demodulator.
  3. Wait for the Channel Seizure Signal (300 bits alternating "0"s and "1"s).
  4. Wait for the Mark Signal (a block of 180 ± 25 mark bits, or 80 ± 25 mark bits).
  5. Decode the messages, and match the checksum.

The designed system has a signal conditioning stage, a hardware RING detector, a dsPIC to control everything and process the input signal, and a user interface with a 2x16 LCD, some LEDs and some pushbuttons. Also included are a relay to pick up/hang the phone, a serial port mainly for debugging purposes and a microSD card reader I have not used yet. You can find the schematics here.



The FSK encoded signal has a bitrate of 1200 bps. A typical FSK demodulator for this kind of signals has only a delay block, a multiplier (that multiplies the signal by its delayed version) and a low pass filter. Before implementing the demodulator in the dsPIC, I tested it using GNU Octave (a free software clone of Matlab). I created a FSK modulator, injected noise to the modulated signal, and implemented the demodulator. The following graph illustrates how the demodulator works with these parameters:

  • Input sequence: 0   0   1   0   1   0   1   0   1   1   0   0   1   0   1   0   1   0   1   1
  • Sampling rate: 7200 Hz (1200 * 6)
  • F0 = 2100 Hz
  • F1 = 1300 Hz
  • Carrier amplitude: -40 dB
  • Noise: -43 dB


The demodulator works perfect and the output sequence matches the input sequence even with high noise levels. The Octave script not only tests the demodulator, it also calculates the coefficients needed for the low pass filter, in Q0.15 format.

Once the demodulator was tested in Octave, firmware for the device was coded. The system is in Sleep mode until a RING is detected by the hardware RING detector. Then the dsPIC wakes up, and starts the ADC and demodulator stages. Once the calling number is decoded, it's displayed in the LCD. if it's a hidden number, or it's blacklisted, the relay is activated to pick up the phone, and then it is deactivated to hang the phone. The FSK demodulator has been coded in highly optimized dsPIC assembly. The remaining code has been written in plain C.

Right now, the system only picks up and hangs the phone, but I'd like to add a feature to play some audio tracks recorded in the micro SD card. Also I'd like to add logging capabilities, and a flexible configuration interface. If you want a software release, you can ask for it, but I'd like to implement these capabilities first.