I have been playing with Arduino for one week now and really enjoyed the simplicity with which Wiring allows access to I/O ports. The comprehensible but mandatory structure of a program works really well as long as things are kept simple, while somewhat more advanced programs could certainly benefit from access to interrupts.
However, before making things more complicated on the Software side, I wanted to replace Arduino’s microcontroller chip (ATmega8) with the Atmega168-20PU ($4.11 at DigiKey), which most of all, doubles the amount of Flash Memory, the memory space, where binary versions of compiled programs end up.
Burn Baby Burn
The Arduino Mini board is already based on the ATmega168 and the development environment supports the ATmega168 as well. But how to burn the boot loader on to the bigger chip was still a bit of a mystery, at least to me.
Obviously, the microcontroller chips isn’t any bigger and comes in the same 28-lead PDIP packaging, and since it is not soldered on to the board but sits in a socket, replacing the chip is very straight forward and took only a couple of seconds.
Burning the boot loader on the other hand took a little longer. The Arduino board has the AVR typical 6 headers ICSP, an in system programming port, which allows burning a boot loader without removing the microcontroller chip from the board. Most ISPs (In-System-Programmers) still require an serial or parallel port but don’t work too well through USB-to-Serial adapters, not even with devices like the Keyspan HS19, and Mac users have to rely on AVR’s AVRISP mkII (ATAVRIPS2-ND), available for $34 at DigiKey.
The AVRIPS can program newer 8-bit RISC microcontrollers (with ICSP Interface) through the USB port. The target board still needs to be powered and its regular ports should be disconnected from other devices. Only after following Dr. T.C.P.‘s advice, disconnecting the HD44780 LCD, I was able to have the Mac communicate with the Arduino board through the ICSP.
Arduino’s Development Environment uses the uisp tool for uploading binaries into the microcontroller’s flash memory. However, uisp doesn’t work directly through the USB port and therefore avrdude is our tool of choice. Unfortunately, the avrdude version that is included in the Arduino distribution (currently Arduino-0006) is somewhat outdated and doesn’t support the ATmega168 chip yet.
I’m not a big fan of Fink for compiling myself every tool ever needed and made my life a little easier, by downloading per-build avrdude 5.2 from theOSX-AVR project.
Finding the Boot Loader
The boot loader itself is not too widely available; I found it only here:
At this point, the microcontroller chip on the Arduino board had been replaced with the 16 KByte ATmega168 and everything but the ICSP port had been disconnected. The Arduino board itself was powered by a 7.5V 500mA power supply and the AVRISP-mkII connected the board with the Mac’s USB port.
On the software side, avrdude 5.2 was installed into /usr/local/bin and the ATmega168 boot-loader was made available here /AT168.hex
Burning and Fuses
Burning a new boot loader is a three-step process: unlocking the boot loader segment, uploading the new boot loader, and looking boot loader segment again. For an AVR microcontroller, the closest thing to a config file is its set of fuses. Fuses are used to configure important system parameters and a few important but obscure options can only be set through the ICSP. For instance, the ATmega168 defaults to the use of a 1 MHz internal clock and would ignoring the 16 MHz crystal on the Arduino board, if not told otherwise, through a fuse setting.
- Unlocking the boot loader segment, erase the chip, and set fuses (set boot loader size to 1024 words [=2KByte]: 0xE00-0xFFF, set clock speed to external 16 MHz)
/usr/local/bin/avrdude -p m168 -b 115200 -P usb -c avrispmkII -V -e -U lock:w:0x3F:m -U hfuse:w:0xDF:m -U lfuse:w:0xFF:m -U efuse:w:0xF8:m
- Uploading the boot loader
/usr/local/bin/avrdude -p m168 -b 115200 -P usb -c avrispmkII -V -D -U flash:w:/AT168.hex:i
- Re-locking the boot loader segment
/usr/local/bin/avrdude -p m168 -b 115200 -P usb -c avrispmkII -V -U lock:w:0xCF:m
After removing the AVRISP mkII In-System Programmer and changing the power-selector on the Arduino board, it was time to fire-up the Arduino IDE. The IDE already supports the ATmega168 and it’s set by selecting atmega168 from the Tools/Microcontroller(MCU) menu. The blinky program was quickly uploaded and running – the IDE reported 14.336 bytes program memory available, which makes sense, considering that we set the efuse to preserve 2K = 1024 words for the boot loader.
Like mentioned above, Wiring has a comprehensible but mandatory structure and allows uncomplicated access to all I/O ports. However, somewhat more advanced programs could certainly benefit from access to interrupts.
Let’s see if we can get the ATmega168 empowered Arduino to do C programmming, preferrably using an IDE like Eclipse.