# ######################################################################
#    Riscy Pygness makefile                                            #
#                                                                      #
#    Read the comments and set the variables appropriate for your      #
#    environment, especially CPU CCLK PORT DLBAUD BIN                  #
#                                                                      #
#    If your prefix for the GNU ARM programs is not 'arm-elf-'         #
#    (e.g. arm-elf-as, arm-elf-objdump, etc.) then you will also       #
#    need to edit those program names below.                           #
#                                                                      #
#    Normal use is to assemble riscy.asm to make the riscy.bin file    #
#    that arm.lisp will use to create combo.bin, e.g.                  #
#                                                                      #
#              make                                                    #
#                                                                      #
#    Then, after running arm.lisp, you can use make to download        #
#    combo.bin to your target's flash with one of the following        #
#                                                                      #
#              make combo.dl                                           #
#              make combo.dls                                          #
#              make combo.jtag                                         #
#                                                                      #
# ######################################################################

# First, look over the section below named "VARIABLES that depend on
#  your environment" and edit them as appropriate.
#
#  The general steps for building Riscy Pygness are
#      1. edit riscy.asm and custom-*.asm if you wish to change the 
#         primitives or need to change clock and serial speed settings.
#
#      2. assemble riscy.asm to produce riscy.bin with
#             make riscy.bin
#         or, since riscy.bin is the default target, just
#             make
#
#         This preprocesses riscy.asm into riscy.s then assembles 
#         and links it to produce riscy.elf, then uses objdump to
#         make riscy.bin.
#
#      3. run arm.lisp which takes riscy.bin and extends it with
#         the high-level Forth words, producing combo.bin (i.e. a
#         combination of the primitives and the high-level words).
#
#      4. download combo.bin into the flash of your ARM chip with
#             make combo.dl
#         or
#             make combo.dls
#         depending on which flash utility you prefer.
#
#  I run arm.lisp "manually" by editing arm.lisp in Emacs and starting
#  CLISP with C-c C-z and then executing the (load "arm") form with
#  the Emacs C-x C-e keystrokes.  However, we might later run
#  arm.lisp directly from the makefile, much as preasm.lisp is now
#  run from the makefile.
#
#  If working with a demo or test program, such as led1.asm,
#  you can assemble it with 
#             make led1.bin
#  and then download it with
#             make led1.dls
#  or you can do both with 
#             make led1.dls
#
#  Note that the lpc_prog flash utility (always) and the lpc21isp
#  flash utility (when given the -control option) will control the
#  serial port's DTR and RTS lines in an attempt reset the ARM 
#  while holding the bootloader request line low.  This works only
#  if your ARM board supports it.  For example, on the Olimex P2378
#  board, make the two jumpers ISP_E and RST_E if you wish this to
#  work.  On hardware that does not support this, you still need to
#  change jumpers and/or push reset buttons as appropriate in order
#  for the bootloading to work.
#  
# ######################################################################


# ######################################################################
#    Quick REFERENCE to the meaning of some automatic variables        #
# ######################################################################
#
#   Given a rule such as  %.s: %.asm  which says how to make
#   an assembly file suitable for passing to the GNU assembler 
#   (e.g. led1.s) from a preprocessable assembly source file 
#   (e.g. led1.asm),
#      $*  is the stem (e.g. led1)
#      $@  is the target file (e.g. led1.o)
#      $<  is the source file (e.g. led1.S), i.e. the first prerequisite
#      $^  is the list of all the prerequisites
# ######################################################################


# ######################################################################
#    VARIABLES that depend on your environment                         #
# ######################################################################

# Set the following variables depending on the particular 
#   ARM chip, serial port, path to the assembler, etc. that
#   apply to your environment.
#       CPU    
#          the particular ARM chip on your development board,
#          for example, lpc2106 or lpc2378.  This is needed 
#          by the lpc_prog flash utility.  You can change this in
#          this makefile or you can call make from the command line
#          with the cpu, e.g.
#               make CPU=lpc2106 ...
#
#       CCLK
#          the CPU clock speed of your board in KHz.  This is used by
#          both the lpc_prog and the lpc21isp flash utilities.  Note 
#          that this is the external crystal speed when using the
#          LPC2106 but is always 14748 when using the LPC2378.
#
#       PORT
#          the full path of your PC's serial port, such as /dev/ttyS0
#          or COM1: for the first serial port.
#
#       DLBAUD
#          the serial rate you wish to use for downloading.  Start with
#          115200 but try slower speeds if you have trouble (e.g.
#          57600, 38400, 19200, 9600, 4800, etc.).
#
#       BIN
#          the full path to the directory that contains the ARM assembler
#          (arm-elf-as) and other binutils utilities such as arm-elf-objdump.
#
#       PREASM 
#          the full (or relative) path to the preprocessor that
#          converts *.asm files into *.s files.  Normally the
#          executable file is preasm.lisp but you could write a
#          replacement in Python or sed or whatever if you prefer.
#          Its main purpose at the moment is to replace semicolons (my
#          preferred comment character) with at-signs (the GNU ARM
#          assembler's preferred comment character).
#
# ######################################################################


# ######################################################################
# Use this section for lpc2106
#    lpc2106 on the Olimex board uses a 14.7456 MHz clock
# ######################################################################
#CPU = lpc2106
#CCLK = 14746

# ######################################################################


# ######################################################################
# Use this section for lpc2378
#    lpc2378 uses an internally generated clock of 14.748 MHz for bootloading
#    regardless of the crystal on the board.
# ######################################################################
#CPU = lpc2378
#CCLK = 14748

# ######################################################################
# Use this section for lpc2103
#    lpc2103 on the Olimex board uses a 14.7456 MHz clock
# ######################################################################
CPU = lpc2103
CCLK = 14746

# ######################################################################

# ######################################################################
# Serial Port
# ######################################################################

PORT = /dev/ttyS1
#PORT = /dev/ttyS0

# If using Microsoft Windows, you might need a PORT name such as
#  one of the following.  Remove the colon if necessary
#PORT = com1:
#PORT = com2:

# ######################################################################
# Download speed for the serial port (for the flash loader)
# ######################################################################

DLBAUD = 115200
#DLBAUD = 9600



# ######################################################################
# Paths to executable files
# ######################################################################

BIN = /usr/local/arm/bin
PREASM = ./preasm.lisp


# ######################################################################
#    other VARIABLES                                                   #
# ######################################################################
#
#       EQUATES
#          a list of the include files.  If you create additional include
#          files (such as equates for a different ARM chip), then add them
#          to this variable.
#
#       ASMFLAGS
#          flags passed to the assembler.
#
#       LNKFLAGS
#          flags passed to the linker.
#
#       ZIPFILES
#          a list of the files to be zip'd when I say 'make zip'
#
# ######################################################################

EQUATES = equates-lpc2xxx.s olimex-lpc2378-equates.s olimex-lpc2106-equates.s \
           olimex-lpc2103-equates.s

INCLUDES = custom-lpc23xx.s custom-lpc2106.s custom-lpc2103.s

ASMFLAGS = -mcpu=arm7tdmi -ahls -mapcs-32 -gstabs

LNKFLAGS =  -v -T lpc2xxx.ld -nostartfiles

ZIPFILES = readme.txt makefile lpc2xxx.ld COPYING LICENSE.txt burn.sh \
           riscypygness.txt FILES .gdbinit lpc2378_wig.cfg \
           riscy.forth mmc.forth block.forth fat16.forth \
           mem.lisp parse.lisp prim.lisp forth.lisp term.lisp arm.lisp \
           preasm.lisp \
           custom-lpc2103.asm custom-lpc2106.asm custom-lpc23xx.asm  \
           equates-lpc2xxx.asm \
           riscy.asm  \
           olimex-lpc2106-equates.asm olimex-lpc2378-equates.asm \
           olimex-lpc2103-equates.asm \
           led1-2103.asm led1-2378.asm


# ######################################################################
#                         end of VARIABLES
# ######################################################################


#  Following line prevents make from deleting these intermediate files
.PRECIOUS: %.o %.hex %.bin %.srec %.elf %.s

all: combo.bin 

clean:
	@ echo "...cleaning"
	rm -f *.o *.elf *.hex led*.s *.bin *.lst *.lnkh *.lnkt


zipdate =  `date +%Y%m%d-%H%M`
zipname = riscy-$(zipdate).zip

zip: $(ZIPFILES)
	zip $(zipname) $(ZIPFILES)
	chmod go+r $(zipname)
	cp -a $(zipname) ~/riscy/muse-riscy/downloads/riscy.zip
	cp -a $(zipname) ~/riscy/muse-riscy-stage/downloads/riscy.zip
	echo -e \\n"date and time of latest version is $(zipdate)"\\n >> ~/riscy/muse-riscy/download.muse
	echo -e \\n"date and time of latest version is $(zipdate)"\\n > ~/riscy/muse-riscy/downloads/versiondate.txt
	echo -e \\n"date and time of latest version is $(zipdate)"\\n > ~/riscy/muse-riscy-stage/downloads/versiondate.txt
	chmod go+r  ~/riscy/muse-riscy/downloads/*
	chmod go+r  ~/riscy/muse-riscy-stage/downloads/*

test:
	echo hello
	echo $(zipdate)
	echo $(zipname)

# ######################################################################
# Cancel any built-in rule that might attempt to run 
#  the assembler directly on an *.asm file or on an *.S file or that
#  might try to override our %.s:%.asm rule.
%.o : %.asm
%.o : %.S
%.o : %.s
# ######################################################################

combo.bin: riscy.bin riscy.forth
	/usr/bin/clisp -q arm.lisp

# e.g. 'make led1.s' to preprocess led1.asm into led1.s
%.s: %.asm makefile
	$(PREASM) $*.asm $@ 


# e.g. 'make led1.o' to assemble led1.s into an object file
%.o: %.s $(EQUATES) $(INCLUDES)
	$(BIN)/arm-elf-as -mcpu=arm7tdmi -mapcs-32 -gstabs -ahls=$*.lst  -o $@ $*.s


# e.g. 'make led1.dis' to produce a disassembly listing from led1.elf
%.dis: %.elf
	$(BIN)/arm-elf-objdump  -d --source $<  > $@


%.hex: %.bin
	$(BIN)/arm-elf-objcopy --input-target binary  --output-target ihex  $<  $*.hex

%.srec: %.bin
	$(BIN)/arm-elf-objcopy --input-target binary  --output-target srec  $<  $*.srec

%.bin: %.elf
	$(BIN)/arm-elf-objcopy -O binary $<  $*.bin

%.elf: %.o
	@ echo "...linking $@"
	$(BIN)/arm-elf-ld $(LNKFLAGS) -o $@ $<
	$(BIN)/arm-elf-objdump -h $@ > $*.lnkh
	$(BIN)/arm-elf-objdump -t $@ > $*.lnkt

# e.g. 'make led1.dl' to use the lpc21isp flash utility to download led1.bin
# lpc21isp is in my path, at /usr/local/bin/lpc21isp
%.dl: %.bin
	lpc21isp  -control -bin $*.bin  $(PORT) $(DLBAUD) $(CCLK)

# e.g. 'make led1.dls' to use the lpc_prog flash utility to download led1.srec
%.dls: %.srec
	lpc_prog -wvr --device $(PORT) --part $(CPU) --khz $(CCLK) --baud $(DLBAUD) $*.srec

# e.g. 'make led1.jtag' to use the openocd JTAG cable to download led1.bin
%.jtag: %.bin
	./burn.sh $*.bin
