3/19/2010

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:

mmcinit
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.

No comments:

Post a Comment