How we finally managed to get the AVR toolchain working on the Macintosh…
UPDATE 2007-10-01: Life just got a lot simpler:
I’ve prepared an installer package that lets you skip most of the steps outlined below.
See this post
Introduction
For some years now, we have been developing our projects around the BasicStamp microprocessor from Parallax –
mainly because of its simplicity, because of Murat n Konar’s exellent BasicStamp programming app for the Macintosh
– it simply worked…
But the BasicStamp is quite slow and limited, has very little RAM, … we wanted to
- program in C
- use existing libraries
- have interrupts
- etc
And we wanted to do all this from a Macintosh.
it is possible, and there are some resources on the net, but we just spent 3 days getting all up and running so we’d like to share our experiences to get you started a little bit more painlessly
Here’s how it worked (at least for us)
Setup
We’re using the following Hardware
- Apple Macintosh PowerBooks running OSX 10.4 Tiger
- STK500 Development Board from ATMEL
- Keyspan USB-Serial Adaptors
Installing the toolchain
To be able to program AVR microprocessors on your Macintosh you need to download and install the AVR Toolchain – a whole set of open source tools. Mike Seeman has a downloadable archive of all the tools on his
website “AVR Microcontroller Programming on a Mac” but, at the time of this writing, it was a bit outdated.
There are fink-packages available, but they weren’t up to date either. As we wanted to be able to program more recent AVRs (atMega88, or the atTiny2313) we decided to get the latest sources and build all from scratch. It took about three hours to be up and running – here’s how we did it (using the bash terminal) :
Step 1: Developer Tools
In order to be able to compile the sources, you need gcc for PowerPC – install the Apple Developer Tools from the original Tiger installation DVD. (XCode is very nice to write your AVR code in, later, anyway)
Step 2: GNU binutils
the GNU binutils are some tools to manipulate binary data, there can be different versions of binutils for different targets installed on the same system. We’ll compile binutils for the AVR target and put them into a dedicated directiory: /usr/local/avr.
- download the latest version of binutils from http://www.gnu.org/software/binutils/
(we were using version 2.16) - unzip the archive, open a new terminal window,
cd
into the unzipped folder, and type, one by one: ./configure --target=avr --prefix=/usr/local/avr
make
sudo make install
Next, we have to add our new avr directory to the PATH variable, for gcc to find the avr-binutils
- open the hidden file ~/.profile (with BBEdit, for example) and add the following line
export PATH=$PATH:/usr/local/avr/bin
Step 3: avr-gcc
We’ll need another version of the gcc-compiler, itself compiled for the avr target. It will get the prefix “avr-” and will go into it’s own directory, so it shouldn’t interfere with the already installed gcc
- Download the latest version of gcc from http://gcc.gnu.org/
we used version 4.0.1
gcc wants to be compiled in a fresh, empty (temporary) directory. Make a new folder outside the unzipped archive – we’ll refer to it as [objdir], as opposed to the archive, which we’ll call [srcdir]…
cd [objdir]
[srcdir]/configure --target=avr --prefix=/usr/local/avr --disable-nls --enable-languages=c
make
sudo make install
Step 4: avr-libc
As we want to code the AVR in C, we’ll need the avr-libc library, which contains basic C routines and data structures for the AVR.
- download the latest version of avr-libc from http://www.nongnu.org/avr-libc/
(we were using version 1.4.3) cd
into the expanded archive./configure --host=avr --prefix=/usr/local/avr
make
sudo make install
Step 5: uisp
Once our future AVR C code compiled, we’ll need a way to download the binary files into the AVRs flash memory. uisp does just that, and does it great!
- download the latest version of uisp from http://savannah.nongnu.org/projects/uisp/
(we were using version 20050207) cd
into the expanded archive./configure
make
sudo make install
Step 6: avrlib
Here, the complete AVR toolchain is installed, and we would be ready to code, compile and flash. But Pascal Stang has written an exellent open source library that does some common and less common tasks, and as we don’t want to reinvent the weel every time, we want that library, too…
(Note: avrlib sounds a lot like avr-libc, but it really is another thing…)
- download the latest version of avrlib from http://hubbard.engr.scu.edu/embedded/avr/avrlib/
You can unzip and use the library anywhere you’d like (for example in ~/code/avr/) – just add the correct AVRLIB environment variable that points to your avrlib directory to your ~/.profile
AVRLIB=[dir]
(where [dir] is the path to your avrlib directory)
Step 7. VT100 Terminal emulation
we use minicom to be able to listen to the avr, see:
How to install minicom on Mac OS X with Darwinports
That’s it – we can start to code, almost…
Pitfalls
Although we installed everything like we were told, we ran into some problems:
First, we weren’t able to compile any of the examples in Pascal Stangs avrlib. There seems to be a problem in his global makefile with our configuration. We found the following solution:
- open the global avrlib makefile: $AVRLIB/make/avrproj_make (you might want to make a backup copy first…)
- uncomment BLOCK 8
- change last rule of BLOCK 9 to:
%.cof: %.elf $(BIN) -O ihex --change-section-address .data-0x800000 --change-section-address .bss-0x800000 --change-section-address .noinit-0x800000 --change-section-address .eeprom-0x810000 $< $@
Then, the Keyspan serial adaptor changes its name every time you plug it into another USB port - this can get very annoying with uisp, so we use the -dserial option in uisp like this:
-dserial=`echo /dev/tty.UP*`
for the USB-Parallel/Serial adaptor, and
-dserial=`echo /dev/tty.US*`
for the USB-Serial adaptor, like in
uisp -dprog=stk500 -dserial=`echo /dev/tty.UP*` -dpart=atmega8 --erase --upload --verify if=rprintftest.hex
And finally we'd get only garbage when we wanted to get data back through the serial port to a VT100 terminal. We spent 2 days testing, trying every possible combination of baud-rates and parity and stopbits, worrying, analysing the signal with an oscilloscope, abandoning, double-checking makefiles and global.h...
Just to find out, that, even if uisp tells us the programmer runs the target AVR at an oscillator frequency of 3686400 hz, an out of the box atMega8 runs on an internal RC-Oscillator at quite unstable 1 Mhz, unless you set the fuse bits to use an external oscillator...
CHECK THE FUSE BITS!!
uisp -dprog=stk500 -dserial=`echo /dev/tty.UP*` -dpart=atmega8 --rd_fuses
ATTENTION: if you're using a crystal above 8 MHZ, you'll have to set the high fuse byte FIRST, otherwise you can lock youself out of the avr...
uisp -dprog=stk500 -dserial=`echo /dev/tty.UP*` -dpart=atmega8 --wr_fuse_h=0xc9
...sets atmega 8 to prepare for crystal > 8Mhz (CKOPT set to 0), then do:
uisp -dprog=stk500 -dserial=`echo /dev/tty.UP*` -dpart=atmega8 --wr_fuse_l=0xef
which actually turns on the external crystal...
check your processors datasheet for more details on the fuse bits...
Resources
- A GNU Development Environment for the AVR Microcontroller
- Using AVR Microprocessors Under OS/X
- Embedded Developement with XCode
- A Firmware-Only USB Driver for Atmel AVR Microcontrollers
- Compiling for the AVR with XCode (german)
last update: 2006-02-18
Leave a Reply