LEDs are blinking!

Today I have been successful in getting the two LEDs blinking on the board, as the video will show.

A recap of what I did:

  • Install arm-elf-gcc toolchain, roughly using instructions from Madox.net. I used GCC-4.3.3 instead of 4.3.2. And, instead of using "/usr/local" as the prefix, I chose to use "/usr/local/arm" so that the executables don't get mixed in with other things in my OS. This caused a problem when building newlib because it depends on the gcc executable that should be in the path. Basically, "sudo" commands don't take on the path set in ~/.bashrc so when using "sudo make all install" to install newlib, the arm-elf-gcc is not found. This is solved by changing to root using "su" and manually adding /usr/local/arm/bin to the path. Not the best way to do it, but it works.
  • Install Flash Magic in WINE. This is easy. Download the installer EXE from flashmagictool.com and then run it in Wine and let it install wherever it wants.
  • Add a symbolic link in ~/.wine/dosdevices/ as follows: link com1 to /dev/ttyUSB0 to use USB serial port. With this, Flash Magic successfully uses the serial port to communicate with the LPC's bootloader.
  • Download sample code (by Martin Thomas) for similar processor, available here. This is for LPC23XX but it's very similar to LPC24XX. To be safe, I found the LPC24xx.h header file in a sample application zip folder provided by NXP, and used that instead of the 23xx.h included in the project. I used this sample code to create a template for HAC-1. Martin's webpage says this is set up for WinARM, but the makefile works just fine as-is on a Linux command line as well.
  • For now, I have removed much of what was in Martin's main.c file, such as the timer and UART functions. Martin had some LED blink code in there, but it was set for a particular commercial board where the LED is on a different pin, so I moved it to the pin that one of our LEDs is on and duplicated it for the second LED.
  • In the Common/src folder of the template, the setup routine in target.c is supposed to enable the PLL and start up the external 12MHz oscillator. For some reason the program doesn't seem to work in this case, so for now I have commented out the call to the function ConfigurePLL() and left the CPU running on the internal oscillator. Hopefully we can get this kink ironed out before moving on to the display controller; The 4MHz internal RC oscillator will not be sufficient for that.

It's alive!

It's been a while since we have made a post; not much has been going on until the last couple few weeks, when we finally got our boards fabbed and all of the parts.

Here is a mostly assembled HAC-1 board:

What has happened so far:

  • Soldering of 208-QFP CPU chip, TSOP DRAM chip on backside. For IC mounting, a soldering iron temperature of 300C was used. One of three attempts at the CPU mounting was a failure due to pins getting bent when appying too much heat trying to wick away excess solder. Next time, 280C might work better.
  • Add 5V and 3.3V regulators, connector for FTDI Chip TTL232R cable.
  • 1st attempt at communicating with CPU. At the time, we hadn't ordered our surface mount resistors and caps, so we wanted to try verifying CPU operation without the passives. We tried connecting using the Flash Magic tool (unfortunately Windows-only, but it looks like it should work with little trouble in WINE under Linux), and sent an "Erase Flash" command. The CPU did not respond.

Here's where a little bit of sloppiness on our part comes in (lessons learned.. for the nth time). Our first idea was to check the oscillator so we probed that with the scope, and were discouraged when we saw no signal on the oscillator circuit. However, according to the LPC 2478 User Manual, the chip contains a 4MHZ internal RC oscillator which is automatically used on startup. The external oscillator circuit does not start up until it is told to do so in software.

After obtaining and mounting the passives (all 0805 size, soldered at 280C), the CPU did indeed respond to the Flash Magic erase command! My suspicion is now that the lack of the pull-up resistor on the reset line may have been the cause of failure before. My assumption was that unconnected lines should tend to float "high," but I guess this is not necessarily the case.

The plan now:

  • UPDATED: Precompiled binaries from gnuarm.com did not seem to work. Will have to build from source. Not too hard to do, though.
  • Write and test simple standalone CPU code: LED blink, serial port, external memory test, LCD driver.
  • Add SD card interface, figure out how to configure U-boot or some other bootloader for ucLinux. Linux image should be stored on SD card.


PCB development

This week we sat down and did some work on the board. Had a tough time deciding if we should use 4 or 2 layers, but due to costs we are probably going to use a 2 layer board and hope that will be fine.

We redid the processor-memory layout after finding a orientation that enabled us to trace the connection without to much trouble, and moved one of the switches to the far end of the board.

Here is the bottom layer
and the top layer

Before we order up the board we will probably probably make space for an breakout board for an Ethernet connection. At the moment we are concidering the following part:

So; We should be able to order the board during next week :)


PCB current status

Here is a picture showing the current status of the PCB. It is kind of messy, but as long as everything is connected we should be fine :)

Anyways, still got some work to do on it and as Steve said, there are plenty of room for additional components....


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.