Getting closer to HAC-1

The main parts (CPU and memory chips) have been ordered, and we did some work on the PCB design today... lots of interesting (maybe?) updates to come, and hopefully in a few weeks we might have this thing up and running!

So far:

No JTAG connector since we don't have any JTAG hardware to begin with (maybe add one if really necessary).
Programming the CPU's internal flash may be done with the in-system programming option via UART. When "in-system programming enable" pin is asserted at reset, the hard-coded bootloader takes over the CPU for ISP.
Since max232 chips and related circuitry are a big waste of board space, we're going with 6-pin headers for FTDI chip TTL232R 3V3 cables for this.

VLSI MP3 chip for audio.
PS/2 port for keyboard input.
12-bit color video output from LCD controller.
SD Card connector added.

There's lots of room left on the board, so we may consider an ethernet interface, and we will definitely add some general purpose IO.

This gentleman down in Nagoya has very recently built something similar to what we are doing, and was kind enough to share schematics and PCB layout.

I was hoping for some insight on how to wire up the memory with the very inconvenient pin assignments, but Havard seems to have done OK with that anyway.


Deciding on a deisgn for SBC

While trying to decide what processor and logic to use for our homebrew computer design, we kicked around a few ideas and tried to think of the pros and cons of each.

First, we were thinking of two designs:

1. ARM microcontroller, Cool Runner 2 CPLD memory interface and framebuffer:

This system comes with the advantage that the pin assignments on the CPLD are pretty much a free for all, but the disadvantage that two chips, likely QFP 144 (MCU) and 208 (CPLD) are needed. The reason for 208 on the CPLD is that the QFP144 versions might just barely not have enough I/O pins for everything we want to do, since memory bus interfaces to both the MCU and the RAM are needed.

2. FPGA with soft CPU
For the same price as an ARM microcontroller + CPLD, we could get a Spartan 3E in 208 QFP package. This should be large enough to hold a capable soft CPU such as the OpenRISC 1k, with room left for framebuffer and other logic. This has the advantage that pin assignments are very flexible, but the disadvantage that the Spartan 3 requires three different supply voltages, making the power distribution system a bit more complicated to design. Especially for a two-layer PCB, which is basically what we are limited to based on cost.

Finally we settled on a third option:
NXP LPC2478 ARM7 microcontroller. This contains a display controller on board, so only one main chip is needed, which saves us some space. The pin assignments look a little inconvenient, but should be possible on two layers, somehow or other.

The specs we are planning are:
Serial port to FTDI chip TTL-232R cable for loading bootloader to flash, no need for MAX 232 level converter
SD card slot to store linux kernel and data
Interface to our analog RGB LCD, as well as VGA and composite video for TV out if possible
Sound.. MP3 Codec chip? (TBD)
Ethernet PHY? (TBD)
PS/2 keyboard/mouse interface? (TBD)


AVR32 Linux

The AVR32 chips have built-in LCD controller hardware, and AVR32 Linux has a framebuffer driver available. So, in theory it should be pretty easy to get the LCD running on this.

The board I have at my desk, NGW100m does not have an LCD already on it, and thus does not have the LCD controller initialized, nor the framebuffer, so it is necessary to configure compile and load a new kernel image to the board in order to get anything on the screen.
When I first attempted this, the kernel seemed to compile fine if I remember correctly, but I had problems understanding how to actually load the kernel image. I was busy with other things, so I set it aside and forgot about it for a great length of time.

Last night, I tried compiling the kernel with the LCD init code added, and modified for the timing specs of our QVGA LCD from Casio (or identical one labeled SHARP).
In avr32linux.org notes on Modifying the NGW100, there is a patch the 2.6.22 kernel to add LCD code. This does not compile correctly for 2.6.33 because of an error the code required to set the "alternate" pin assignments to accommodate this particular board. This applies to the code attached to http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=62356 which is what I tried to modify and use.
In linux-2.6.xx/arch/avr32/mach-at32ap/at32ap7000.c, the line:

select_peripheral(PC(20), PERIPH_A, 0);

and many similar lines setting peripheral functions fail because the select_periph macro in the new version requires four arguments instead of three.
This allows functions to be set all at once rather than one pin at a time.
The correct code to replace the above line, going one at a time anyway, would be:

pinmask = 1 << 20;
select_peripheral(PIOE, pinmask, PERIPH_A, 0);

After changing this, and perhaps one other thing in the code that I copied, I got a successfully compiled kernel image (noting that I enabled the framebuffer support in make menuconfig, which is reasonably well documented elsewhere).

Next was the task of getting the kernel to run. Normally it is interesting to post what didn't work and see why, but I'm just going to stick with what works.
There is some procedure to set up an FTP server and have the board look for the kernel image on that, but it only timed out when I tried it. And, I don't like having this board in between my computer and its main internet connection, so I'd rather do everything with the serial port and SD card.
The stock u-boot version did not like my SD card, so I ran the flash upgrade image at http://www.atmel.no/buildroot/buildroot-u-boot.html by copying it to RAM through the serial port (using c-kermit) and finally got to the point where I can run my custom kernel image like so:

1. compile kernel
2. copy resulting uImage file to custom_uImage in SD card root folder
3. put SD card in board
4. reset board, interrupt with spacebar to run u-boot
5. run u-boot commands:

ext2load mmc 0:1 0x10400000 /custom_uImage
bootm 0x10400000

This can be easily automated by setting the boot command environment variable on u-boot and saving it.

With my custom image, I could do

cat /dev/urandom > /dev/fb0

and see random pixels written to my LCD screen. The timing is quite jittery, so in order to get this to work fully, I need to adjust that.


Welcome to our collection of nerdiness.

Havard and I plan to build our own minimal embedded linux board. For not much more money than what this is going to run us, there are already some pretty impressive single board computers out there.
But, we're going for the satisfaction of building something rudimentary from the ground up.
This all started when a labmate of ours told us of a website run in Tokyo that sells very cheap LCDs and other odds and ends that very well serve electronics hobbyists.
After looking around at what they had to offer, we decided on these 300 yen (about $3US!!) 320x240 Casio LCDs that are apparently either used or taken from some unsold stock of something.
First we set up a simple framebuffer on a Digilent Spartan 3 Starter board. Here is what that looks like:

But the hardware is not much without some software to run with it. That, and we wanted to have something that's not really just a big prototype on the table. After much time thinking about what to do, we eventually decided to try designing a simple SBC. More to come on the decision and design process.

In the meantime, I'm playing around with an AVR32 Linux board that I have sitting around. It's very different from what our project will be, but it's definitely helping me feel my way around embedded linux in some ways.