LPC2378 Assembly Demos

Here are several very small example assembly language files for the
NXP LPC2378 ARM chip.  They were developed on the Olimex LPC-P2378
board.  It should be easy to convert them to any other development
board using the LPC2378 chip.  A few more changes might be necessary
to run some of them on other chips such as the LPC2106.

The first several examples blink the status LED.  If you are using a
different board, you should change the code related to the output
pin.  The Olimex board connects the LED to pin 19 of port 1 (P1.19).
A low turns on the LED.  A high turns off the LED.

If your board does not have a convenient LED to blink, just pick some
otherwise unused pin and put a logic probe on the pin to see it blink.

Note, the bootloader always runs when the chip reboots.  It decides
(based on the state of the ISP (in-system programming) pin and some
other criteria) whether to attempt to download a new program via the
serial port or whether to jump to the existing application program in
the chip's flash memory.


* Example programs

  led1.asm  

     This accepts the environment almost entirely as the bootloader
     leaves it.  It does tell the chip to use fast I/O rather than
     "legacy" slow I/O, since we need to know which I/O instructions
     to use to blink the LED.  It doesn't try to change or set the
     clock source or clock speed.  It doesn't set up any stacks.  It
     just uses an arbitrary delay value in a register to time the
     blinking. 

  led2.asm

     This is just like led1.asm except it makes an effort to calculate
     (but not to change) the clock speeds involved.  If the
     assumptions used for the calculations are correct, the LED should
     blink at the speed you request by the setting for SECONDS.  If
     you set SECONDS to 10, then the LED should be on for 10 seconds
     then off for 10 seconds then off for 10 seconds then ...

  led3.asm

     This is like led2.asm except it uses the timer for the delay
     between blinks.  It is an example of setting up a timer and
     polling it for timeout.  It doesn't use interrupts.

  led4.asm

     Finally, in this version, we explicitly set up the clock source
     to be the main oscillator which uses the 12 MHz crystal.  The
     first three used whatever clock source the bootloader used,
     i.e. the internal RC oscillator.

  ser1.asm

     This still blinks the LED but its main purpose is to exercise the
     serial port in a very simple fashion: it transmits the letter Q
     every time the LED turns on or off.  It sets up the clocks as in
     led4.asm and sets the baudrate based on the clocks and the value
     of BAUDRATE.  It does not attempt to set up the partial baudrate
     divisor.

     See the notes under ser2.asm related to the terminal program.

  ser2.asm

     This is an even simpler serial port example.  It ignores clocks,
     ports, etc.  It uses the autobaud feature of the LPC2378 chip to
     set up the baudrate.  The program waits for you to type an A
     (yes, it must be an upper case A).  At the first A, the chip sets
     the baudrate automatically to match that of the terminal on your
     PC.  then it transmits the string "Qabc".  Thereafter, it waits
     for you to type another A and then again transmits "Qabc" ...

     Note, if you download the program using the lpc_prog flash
     utility, it goes into a simple terminal automatically.  This is
     because the make file uses the -t option.  If you use this simple
     terminal program, it is not enough to type the A.  You must also
     press Enter.  It looks like this terminal is line oriented rather
     than character oriented.

     Note, if you use the minicom terminal (under Linux etc.), you do
     not need to press Enter after the A as minicom is character
     oriented.  However, minicom asserts the DTR and RTS lines.  This
     means you cannot use minicom unless you remove the ISP_E and
     RST_E jumpers on the Olimex P-2378 board.  Otherwise, the board
     will stay in reset and the program will never run.  (If you know
     how to tell minicom to leave DTR and RTS inactive, please tell
     me.) 

  ser3.asm

     Set up a stack (so we can use subroutines).  Set up the clock to
     use the external 12 MHz crystal (with PLL off).  Set up the
     serial port to use the fractional divisor register so we can get
     accurate baud rates up to 115,200 bps.  Equates in the program
     show the calculations involved.

* Binaries

     The binary versions of the above are included (e.g. ser3.bin) in
     case you would like to burn them into flash quickly without
     installing binutils to get the assembler etc.  However, if you
     are using a bootloader that requires a different form than *.bin,
     you may still need to install binutils in order to convert *.bin
     to *.srec or whatever your downloader needs.

* Why

These example programs might be useful for understanding how to change
clocks and calculate the various clock speeds and also for
understanding how to set up the serial port.  Plus they let you
exercise the hardware with "known good" programs.  (I think they are
known good.  If you find errors, please let me know.)


* Preprocessor

These programs are written using the semicolon (;) as the comment
character.  The GNU ARM assembler prefers the at-sign (@) as the
comment character.  The makefile takes care of this by running a
preprocessor program to convert semicolons to at-signs.  That's the
purpose of preasm.lisp.  Of course, you can convert it to run under
other Lisps, but as set up, it requires CLISP.  CLISP is very easy to
install under Linux (and other Unixes).  For example, to install under
Debian, at a shell prompt, type

    apt-get install clisp

CLISP is also easy to install under Microsoft Windows.  

If you would prefer not to install CLISP, all you need to do is write
a simple preprocessor in any language you like that takes the *.asm
file and produces an *.s file but with semicolons changed to
at-signs.  You could even do it manually with an editor.


* Assembler

These programs require the GNU ARM assembler.  This is included in the
binutils package.  You can install a binary version ARM version of it
for Linux or you can compile it yourself.  See various links on my web
site or do a web search for something like "binutils ARM".


* Flash utilities

Once a program is assembled, producing an *.elf file and an *.bin
and/or *.hex and/or *.srec version, you need to burn the program into
the LPC chip's flash memory.  The two serial download programs (flash
utilities) I have been using are lpc21isp and lpc_prog.  I have also
been using the openOCD program with a JTAG cable.

  If you type

    make led1.dl

it will assemble, link, create the *.bin version, and attempt to
download led1.bin to the flash using lpc21isp.

On the other hand, if you type

    make led1.dls

it will assemble, link, create the *.srec version, and attempt to
download led1.srec to the flash using lpc_prog.

On the third hand, if you type

    make led1.jtag

it will assemble, link, create the *.bin version, and attempt to
download led1.bin to the flash using the burn.sh script.  Of course,
you would need to have openOCD (and netcat) installed.  I am not
completely happy with the burn.sh script.  It just puts in an
arbitrary delay of 1 second between commands.  Sometimes the commands
fail, so watch for error message and type 'make led1.jtag' again.  I
may do this "right" someday.  Meanwhile this is still very
convenient.  You could also start openOCD in a terminal and start a
telnet connection to it in another terminal and type the commands
directly in the telnet session.


* Installation

Pick a directory, unzip asm-demos-YYYYMMDD-HHMM.zip into that
directory.  (And, of course, the ARM binutils and a flash utility and
possibly CLISP need to be installed also.)

Then, edit the makefile if you need to change the paths to your
assembler, etc.


* Make

Open a terminal (shell).  Move to the directory where you installed
the files.  Type

 make led1.s               to run just the preprocessor
 make led1.o               to run the assembler, creating the object file
 make led1.dl              to download using lpc21isp
 make led1.dls             to download using lpc_prog
 make led1.jtag            to download using openOCD and the JTAG cable

Of course, you do not need to do each step separately.  Simply typing

 make led1.dls

will do it all (at least the parts that need doing).


* GNU Debugger (gdb)

I have included the file .gdbinit as an example.  If you use gdb, be
sure to edit it to fix up the paths for your environment.


* Errors

Please email me if you find any typos or errors in these examples or
their documentation.


-- 
Frank
frank@pygmy.utoh.org
http://pygmy.utoh.org/riscy
