#! /bin/bash

#
# makeme.sh -- simple script for compiling and uploading programs to
#              the arduino ATmega8 board (or just a free-floating ATmega8)
# Copyright (C) 2007 Fred Barnes  <frmb@kent.ac.uk>
#

BAUD_RATE=19200
UPLOAD_PORT="/dev/ttyUSB0"
CPU_HZ=16000000
VERBOSE=0

AVRDUDE="/home/frmb/src/avrdude-5.2/avrdude"
AVRDUDEOPTS='-C /etc/avrdude.conf -F -p atmega8 -P @@UPLOAD_PORT@@ -c stk500 -b @@BAUD_RATE@@'

AVR_CC="avr-gcc"
AVR_CFLAGS='-DF_CPU=@@CPU_HZ@@ -I/usr/avr/include -Wall -Wstrict-prototypes -mmcu=atmega8 -gstabs -Os'
AVR_LDFLAGS='-L/usr/avr/lib/avr4'
AVR_OBJCOPY="avr-objcopy"
AVR_OBJCOPYOPTS="-O ihex -R .eeprom"


usage () #{{{
{
	printf 'Usage: %s [options] <command> [args...]\n' "$0"
	printf 'where options are:\n'
	printf '  -v | --verbose        be verbose\n'
	printf '  -h | --help           this help\n'
	printf '  -b | --baud  <rate>   set baud rate for upload (default %d)\n' "$BAUD_RATE"
	printf '  -p | --port  <port>   set port for uploadi (default %s)\n' "$UPLOAD_PORT"
	printf '  -f | --freq  <freq>   set CPU frequency in Hz (default %d)\n' "$CPU_HZ"
	printf 'and commands are:\n'
	printf '  hex <name>            build hex image for <name>.c\n'
	printf '  upload <name>         upload hex image and eeprom for <name>\n'
}

#}}}

eoo=0

#{{{  process arguments

while [ $# -gt 0 ] && [ $eoo -eq 0 ]; do

	case "$1" in
	"-v" | "--verbose")
		VERBOSE=$((VERBOSE + 1))
		;;
	"-h" | "--help")
		usage
		exit 0
		;;
	"-b" | "--baud")
		if [ "$2" = "" ]; then
			printf '%s: option %s requires argument!\n' "$0" "$1" 1>&2
			exit 1
		fi
		BAUD_RATE="$2"
		shift
		;;
	"-p" | "--port")
		if [ "$2" = "" ]; then
			printf '%s: option %s requires argument!\n' "$0" "$1" 1>&2
			exit 1
		fi
		UPLOAD_PORT="$2"
		shift
		;;
	"-f" | "--freq")
		if [ "$2" = "" ]; then
			printf '%s: option %s requires argument!\n' "$0" "$1" 1>&2
			exit 1
		fi
		CPU_HZ="$2"
		shift
		;;
	*)
		eoo=1
		break;
	esac

	if [ $eoo -eq 0 ]; then
		shift
	fi
done

#}}}

# fix up a couple of things
AVR_CFLAGS=$(printf '%s' "$AVR_CFLAGS" | sed -e 's/@@CPU_HZ@@/'"$CPU_HZ"'/g')
AVRDUDEOPTS=$(printf '%s' "$AVRDUDEOPTS" | sed -e 's:@@UPLOAD_PORT@@:'"$UPLOAD_PORT"':g' \
		-e 's/@@BAUD_RATE@@/'"$BAUD_RATE"'/g')


#{{{  assuming the rest is commands
while [ $# -gt 0 ]; do
	case "$1" in
	"hex")
		if [ "$2" = "" ]; then
			printf '%s: command %s requires argument!\n' "$0" "$1" 1>&2
			exit 1
		fi

		if [ $VERBOSE -gt 0 ]; then
			printf '%s -c %s -o %s %s\n' "$AVR_CC" "$AVR_CFLAGS" "$2".o "$2".c
		fi
		FAILED=0
		$AVR_CC -c $AVR_CFLAGS -o "$2".o "$2".c || FAILED=1
		if [ $FAILED -eq 1 ]; then
			printf '%s: failed to compile %s.c\n' "$0" "$2" 1>&2
			exit 1
		fi
		if [ $VERBOSE -gt 0 ]; then
			printf '%s %s %s -o %s %s\n' "$AVR_CC" "$AVR_CFLAGS" "$2".o "$2".elf "$AVR_LDFLAGS"
		fi
		$AVR_CC $AVR_CFLAGS "$2".o -o "$2".elf $AVR_LDFLAGS || FAILED=1
		if [ $FAILED -eq 1 ]; then
			printf '%s: failed to link %s.o\n' "$0" "$2" 1>&2
			exit 1
		fi
		if [ $VERBOSE -gt 0 ]; then
			printf '%s %s %s %s\n' "$AVR_OBJCOPY" "$AVR_OBJCOPYOPTS" "$2".elf "$2".hex
		fi
		$AVR_OBJCOPY $AVR_OBJCOPYOPTS "$2".elf "$2".hex || FAILED=1
		if [ $FAILED -eq 1 ]; then
			printf '%s: failed to generate hex from %s.elf\n' "$0" "$2" 1>&2
			exit 1
		fi

		shift
		;;
	"upload")
		if [ "$2" = "" ]; then
			printf '%s: command %s requires argument!\n' "$0" "$1" 1>&2
			exit 1
		fi

		if [ ! -f "$2".hex ] || [ "$2".c -nt "$2".hex ]; then
			printf '%s: hex file for %s needs updating!\n' "$0" "$1" 1>&2
			exit 1
		fi

		if [ -f "$2".hex ]; then
			AVRDUDEOPTS="$AVRDUDEOPTS -U flash:w:$2.hex"
		fi
		if [ -f "$2".eeprom ]; then
			AVRDUDEOPTS="$AVRDUDEOPTS -U eeprom:w:$2.eeprom:r"
		fi

		if [ $VERBOSE -gt 0 ]; then
			printf '%s %s\n' "$AVRDUDE" "$AVRDUDEOPTS"
		fi

		$AVRDUDE $AVRDUDEOPTS

		shift
		;;
	*)
		printf '%s: unknown command %s\n' "$0" "$1"
		;;
	esac

	shift
done

#}}}



