#!/system/bin/sh
trap "kill 0" SIGINT

RESET_GPIO=62
BOOT0_GPIO=55
BOOT1_GPIO=56

UART="/dev/ttymxc4"

if [ -d /data/local/tmp ]; then
	TMPDIR=/data/local/tmp
elif [ -d /tmp ]; then
	TMPDIR=/tmp
fi

if [ -f /tmp/busybox ]; then
	BUSYBOX="/tmp/busybox"
else
	BUSYBOX="/system/bin/busybox"
fi

usage() {
	echo "Usage: $0 <reset|bl|normal|pgm|shell|fpga> (bin_file_to_program)"
	exit 1
}

gpio_init() {
	if [ ! -d /sys/class/gpio/export/gpio${1} ]; then
		echo "$1" > /sys/class/gpio/export
	fi
}

gpio_high() {
	echo high > /sys/class/gpio/gpio${1}/direction
}

gpio_low() {
	echo low > /sys/class/gpio/gpio${1}/direction
}

reset() {
	echo "Resetting coprocessor"

	gpio_init "$RESET_GPIO"

	gpio_high "$RESET_GPIO"
	sleep 1
	gpio_low "$RESET_GPIO"
}

bl() {
	echo "Set coprocessor to boot from internal bootloader"

	gpio_init "$BOOT0_GPIO"
	gpio_init "$BOOT1_GPIO"

	gpio_high "$BOOT0_GPIO"
	gpio_low "$BOOT1_GPIO"
}

normal() {
	echo "Set coprocessor to boot from flash"

	gpio_init "$BOOT0_GPIO"
	gpio_init "$BOOT1_GPIO"

	gpio_low "$BOOT0_GPIO"
	gpio_high "$BOOT1_GPIO"

	$BUSYBOX stty -F "$UART" 115200 -echo
}

pgm() {
	if [ ! -f "$1" ]; then
		echo "Cannot access $1"
		exit 1
	fi

	if [ -f /tmp/stm32flash ]; then
		FLASH="/tmp/stm32flash"
	elif [ -f /system/bin/stm32flash ]; then
		FLASH="/system/bin/stm32flash"
	else
		echo "Can't find stm32flash.  Aborting"
		exit 1
	fi

	bl
	reset
	sleep 1
	$FLASH -w $1 -v -g 0x0 "$UART"
	normal

}

shell() {
	$BUSYBOX stty -F "$UART" 115200 -echo igncr
	cat $UART &
	echo '\n' > $UART
	while [ 1 ]; do
		read -n1 C
		echo -n $C > $UART
	done
}

fpga() {
	timeout=90
	echo "Checking for FPGA image update...."
	echo
	rm -f $TMPDIR/fpga_retval
	normal
	reset
	$BUSYBOX stty -F "$UART" 115200 -echo igncr
	grep -m 1 "FPGA Update Code" $UART | $BUSYBOX sed 's/.*\[-\?\([[:digit:]]*\)\].*/\1/' > $TMPDIR/fpga_retval &
	sleep 3
	echo -n 'F' > $UART
	while [ ! -f $TMPDIR/fpga_retval -o ! -s $TMPDIR/fpga_retval ]; do
		sleep 1
		timeout=`expr $timeout - 1`
		if [ $timeout -eq 0 ]; then
			break;
		fi
	done
	RET=`cat $TMPDIR/fpga_retval`
	rm $TMPDIR/fpga_retval
	if [ $timeout -eq 0 ]; then
		echo "FPGA Update Timeout"
		RET=1
	elif [ $RET -ne 0 ]; then
		echo "FPGA Update Error $RET"
	else
		echo "FPGA Update Complete"
	fi
	exit $RET
}

argc=$#
if [ $argc -ne 1 -a $argc -ne 2 ]; then
	usage "$0"
fi

case "$1" in
	reset)
		reset
		;;
	bl)
		bl
		;;
	normal)
		normal
		;;
	pgm)
		if [ $argc -ne 2 ]; then
			usage "$0"
		fi

		pgm "$2"
		;;
	shell)
		shell
		;;
	fpga)
		fpga
		;;
	*)
		usage "$0"
		;;
esac
