Saturday, June 14, 2008

Microcontroller Development Under Mac OS X (Part 1)

I intend for this to be a series of posts explaining how to get up and running developing for the Freescale HC(S)12, Atmel AVR, Microchip PIC, and ARM LPx platforms. These instructions have been tested on my laptop, which runs Mac OS X Leopard. However, there is nothing *explicitly* Mac-specific about what I'll be covering; most of this guide should apply to *NIX platforms, and possibly Windows, too.

Required Development Tools
- a compiler
- a linker/assembler
- a c library
- some way of getting your code on the uC

ATEN International PL2303-based USB-to-Serial

Many modern microcontrollers support self-programming via a serial bootloader.  This feature makes updating firmware a breeze.  While you can find newer development kits with USB-to-TTL converters onboard, a few of the development kits that I'll be discussing use old-fashioned RS-232 serial ports.  My MacBook doesn't have a RS-232 serial port, so I use the generic PL2303-based USB-to-RS232 adaptor that you see above.  You can pick one up for about $20. 

Freescale HC11/HC(S)12 Family

Compiler, Linker/Assembler, C Library

The good folks at the GNU Project provide a free compiler (m68hc11/12) and a set of binary utilities (Binutils). The C library (Newlib) is generously distributed by the folks at Red Hat. While you can compile and install these tools by hand, I chose to use Fink, which installs and manages the files automagically.

At the time of writing a Leopard installer for Fink wasn't available, so I bootstrapped from source.  You can find directions for that here.  (After installing Fink, don't forget to append '/sw2/bin/init.sh' and '/sw2/bin' to $PATH in your ~/.bash_profile.)  My line looks like:

export PATH=/usr/local/cuda/bin:$PATH:/opt/local/bin:/sw2/bin

Open a new terminal window and type the following to install everything in one fell-swoop:

fink install m681x-binutils m681x-gcc m681x-newlib m681x-gdb

After a few minutes, you'll have a full set of development tools installed and ready to go.

If you uncomfortable using the GNU-as assembler, Eric Engler's as12 is a great alternative.  You can download the source code here.  Compiling the code is as simple as typing 'make' in the unzipped directory.  Copy the binary files, as11 and as12, to a directory in your $PATH.

Getting code on your HC(S)12

Two of my development kits, the Freescale DEMO9s12NE64 and the Technological Arts M68DKIT912C32, use the AN2546 serial bootloader.  I found a few tools which support this protocol: hcs12mem, Binload.  I decided to use hcs12mem, mainly because the website for Binload was down when I tried to access it.  Since I couldn't find a binary package for hcs12mem, I decided to compile it from scratch.  You can grab it here and do so yourself.
tar -xzvf hcs12mem-1.4.1.tar.gz
cd hcs12mem-1.4.1
./configure
make && sudo make install
Developing for the HC(S)12

The HC12 will always hold a special place in my heart; it was the first uC that I learned to program for back in ECE362 @ Purdue.  It has a great instruction set: understandable, powerful, and well-supported by Freescale.  Throughout the years, I've programmed for 3 HC(S)12 families: the C32, the NE64, and the DP256.  The corresponding development kits that I have for the three platforms are: Technological Arts M68DKIT912C32,  Freescale DEMO9S12NE64, and the Wytec Minidragon+.

The development process is very similar across the three families;  there are occasionally differences in the pin/register names, memory layout, and supported subsystems.  Pin names are usually defined in a family-specific header file.  I've collected header files for each of the families and made them available below.  For the development tools we are using, the memory layout is defined in a file named 'memory.x'.  Be sure to examine each of the memory.x files in the examples below.  You should also take a look at the 'vectors.s' file.  This is where the interrupt vectors are defined.

The examples below have accompanying Makefiles.  In addition to the standard 'make' target, there is a 'make load' target which attempts to burn the generated .s19 file to the development board using hcs12mem.  You will probably have to modify the serial port path in the Makefile to match your machine.


Technological Arts M68DKIT912C32







Freescale DEMO9s12NE64









Wytec Minidragon+








In my next post, I'll walk through the example code and give you a quick introduction to programming AVRs!  

- Sumanth Peddamatham

Additional Information


How to Compile uip-NE64 Example

Macintosh-5:uip-hcs12NE-bafoontecha me$ make 
m6811-elf-gcc -m68hc12 -Os -fno-ident -fno-common -fomit-frame-pointer -mshort -fsigned-char -mauto-incdec -c ethernet.c
m6811-elf-gcc -m68hc12 -Os -fno-ident -fno-common -fomit-frame-pointer -mshort -fsigned-char -mauto-incdec -c ethernet_stats.c
m6811-elf-gcc -m68hc12 -Os -fno-ident -fno-common -fomit-frame-pointer -mshort -fsigned-char -mauto-incdec -c main.c
m6811-elf-gcc -m68hc12 -Os -fno-ident -fno-common -fomit-frame-pointer -mshort -fsigned-char -mauto-incdec -c netlog.c
m6811-elf-gcc -m68hc12 -Os -fno-ident -fno-common -fomit-frame-pointer -mshort -fsigned-char -mauto-incdec -c timer.c
m6811-elf-gcc -m68hc12 -Os -fno-ident -fno-common -fomit-frame-pointer -mshort -fsigned-char -mauto-incdec -c uip.c
m6811-elf-gcc -m68hc12 -Os -fno-ident -fno-common -fomit-frame-pointer -mshort -fsigned-char -mauto-incdec -c uip_arch.c
m6811-elf-gcc -m68hc12 -Os -fno-ident -fno-common -fomit-frame-pointer -mshort -fsigned-char -mauto-incdec -c uip_arp.c
m6811-elf-gcc -m68hc12 -Os -fno-ident -fno-common -fomit-frame-pointer -mshort -fsigned-char -mauto-incdec -c adc.c
m6811-elf-gcc -m68hc12 -Os -fno-ident -fno-common -fomit-frame-pointer -mshort -fsigned-char -mauto-incdec -Wl,-u,-mm68hc12elfb -o uip-ne64.elf ethernet.o ethernet_stats.o main.o netlog.o timer.o uip.o uip_arch.o uip_arp.o adc.o mc9s12ne_vectors.s
/sw2/bin/m6811-elf-ld:ldscripts/m68hc12elfb.x:127: warning: memory region page0 not declared
m6811-elf-objcopy -O srec uip-ne64.elf uip-ne64.s19

How to Load uip-NE64 Example

Macintosh-5:uip-hcs12NE-bafoontecha me$ make load
hcs12mem -i sm -p /dev/tty.PL2303-0000101D -t mc9s12ne64 -o 25MHz --flash-erase --flash-write uip-ne64.s19
hcs12mem: Freescale S12 MCU memory loader V1.4.1 (C) 2005-2007 Michal Konieczny 

target info 
target mcu family osc <25.000000>
SM serial port baud rate <115200>
SM target connected
SM version <2.01> date <2004-01-16>
S12 part id <0x8201> family memory <64kb> mask <0.1>
S12 part security backdoor key 
S12 register space <1kb> address range <0x0000-0x03ff>
S12 RAM size <8kb> space <8kb> align address range <0x2000-0x3fff>
S12 EEPROM not present
S12 FLASH module state ROMHM 
S12 FLASH size <64kb> space <48kb> off-chip/on-chip space <876kb/128kb>
S12 FLASH protection all high area <2kb> low area 
FLASH erase: wait ...
FLASH erase: memory erased
FLASH write: image file 
FLASH write: image info entry <0x4000>
FLASH write: address range <0x4000-0x6297> size <0x2298>
FLASH write: address range <0xff80-0xffff> size <0x0080>
FLASH write: image [##################################################]
FLASH write: image size <8984> time <1.03> rate <8722>

Connecting to DEMO9S12NE64 Development Board

Macintosh-5:uip-hcs12NE-bafoontecha me$ telnet 192.168.0.20
Trying 192.168.0.20...
Connected to 192.168.0.20.
Escape character is '^]'.

-------------------------------
 Welcome to the DEMOS19NE64!   
-------------------------------
Press bar to terminate.

ADC Port 0: 003D
ADC Port 0: 0098
ADC Port 0: 00BC
ADC Port 0: 00E0
ADC Port 0: 00E2
ADC Port 0: 00FF
ADC Port 0: 00FF
ADC Port 0: 00FF
ADC Port 0: 00F1
ADC Port 0: 00A4
ADC Port 0: 0080
ADC Port 0: 006F
ADC Port 0: 0056
ADC Port 0: 003D
ip: packet not for us.
ADC Port 0: 003D
ip: packet not for us.
ADC Port 0: 003D
ip: packet not for us.
ADC Port 0: 003D
ip: packet not for us.
ADC Port 0: 003D
ip: packet not for us.
ADC Port 0: 003D
ip: packet not for us.
ADC Port 0: 003D
ip: packet not for us.
ADC 
ADC Port 0: 002C
ADC Port 0: 0027
ADC Port 0: 0015
ADC Port 0: 0000
ADC Port 0: 0000Connection closed by foreign host.

Links



Thursday, December 20, 2007

Magnets, and the meaning of life.

Truth be told, I wanted my first blog entry to be about Young's double-slit experiment;  or rather, my recreation of said experiment.  However, I found myself in a familiar loop, "oh, just a few more days until the laser arrives, you can hold off on the blog until then", "oh, I need a microscopy slide to etch the slits into, hold off a few more days until you find one", "oh, the light is not diffracting properly, hold off until you read more about optics", ad infinitum.  Despite all the 'oh'ing, there was a whole lot of nothing being done, a far worse crime than starting sentences with 'Truth be told".  So, I decided to begin with a something a bit different but equally mysterious and beautiful, magnetism.

Yesterday, my research group and I had the privilege of teaching the Happy Hollow Elementary Science Club about magnetism.  Well, not everything about magnetism, but a few fundamental principles: the non-linear relationship between magnetic field strength and distance, and the effect of increasing a system's magnetic moment.

In English, the first part means that the force you feel from a magnet increases very quickly, actually, stupendously quickly as you get closer to the magnet (and vice-versa).  In mathematics, this type of relationship has a name: exponential.  The second part means that if you change the number of magnetic particles in a system, you affect the field strength of that system.  To stretch this paragraph out a bit longer: if you take a magnet and break it exactly into two, you will get two magnets with half the total field strength in each.

My role in the demonstration was to deliver the opening monologue, which I did, along with the following visual aide.


Not to be confused with a Torii, this simple device consisted of a pair of (in actuality, we had six)  super-strong magnets taped to the center of a suspended, wooden dowel.  A pair of steel washers were attached to both the base of the contraption and a pair of plastic cups, which were suspended wirelessly (you get the idea) under the magnets.  



The only difference between the two washers was their respective distance from the magnets.  The jar on left of the first picture contains plastic beads, which were used as units of mass.  


The demonstration was to show that even a teeny, tiny difference in distance (about 1 cm) affects the attractive force felt by the washer immensely; the closer washer being 'pulled' more strongly than the further away washer.  This discrepancy was made quite clear by the difference in the number of beads each washer/cup assembly was able to support.  The cup on the right fell after ~20 beads, but the cup on the left, a mere centimeter closer, was able to hold a cupful of beads and probably more!  I was able to milk the tension by taking bets at the beginning of each trial and counting slowly as I incremented the number of beads in each cup.  (My demonstration was followed by two hands-on activities, which let the kids explore the concepts more deeply.)




Overall, I was very impressed by the acuity of the kids.  In fact, quite a few of them were already familiar with the concept of magnetism and asked a number of questions which were fundamentally interesting: "Can you get a magnet with only one pole?", "What happens if you break a magnet into two?", "Is the magnetic field blocked by tape?", "Why are some materials magnetic and others not?"...  All valid, scientific questions; some yet to be answered!

For the lay person, I would highly recommend: Physics 2000, a wonderful presentation of physics concepts in the style of the Socratic Dialogue.  If you manage your way through all the applets there, I also recommend PhET and Physics 8.02 @ MIT.

For the more advanced reader, I can't express what a revelation Prof. Lewin's online lecture videos were for me: 8.02 Electricity and Magnetism.

theory meets application.