#!/bin/sh
#############################################################
# What this script does:
#   1) program ftdi GPIOs
#   2) program tiva using ftdi serial with GPIOs
#   3) send reset-3, to fix gwmio/agcio bug
#############################################################
path="${0%/*}"
. "$path/inc/gwhw.inc"

needRoot

usage() {
	die 'gwhw flash agcio [IMAGE]'
}

testcmd2 gpiofind
testcmd2 gpioset
testcmd2 gpioget
testcmd2 sflash
testcmd2 stty
testcmd2 fuser
#############################################################
script="${0##*/}"

setPath_AGCIO
TTY="${IOBOARD_TTY}"
BAUD="${IOBOARD_BAUD}"

binary="${1}"
shift

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

portInUse() {
	fuser -s "${TTY}" &>/dev/null
}

portWait() {
	wait_file "${TTY}"
	[ -c "${TTY}" ] || die "TTY not found (${TTY})"
}

setup_FTDI() {
	"$path/gwhw-flash-agcio-ftdi"
	portWait
}

setup_FTDI_GPIO() {
	PRG="$(gpiofind "${AGCIO_PRG}")"
	RST="$(gpiofind "${AGCIO_RST}")"

	[ -z "${PRG}" ] && die "Program pin not found (${AGCIO_PRG})"
	[ -z "${RST}" ] && die "Reset pin not found (${AGCIO_RST})"

	PRG_ON="${PRG}=0"
	RST_ON="${RST}=0"
	PRG_OFF="${PRG}=1"
	RST_OFF="${RST}=1"
}

toggleRST() {
	gpioset $RST_ON
	gpioset $RST_OFF
}

progON() {
	gpioset ${PRG_ON}  || die ; sleep 1
	gpioset ${RST_ON}  || die ; sleep 1
	gpioset ${RST_OFF} || die ; sleep 1
}

progOFF() {
	gpioset ${RST_ON} ; sleep 1
	gpioset ${PRG_OFF}; sleep 1
	gpioset ${RST_OFF}; sleep 1
}

isRST_ON() {
	# Reading RST pin will always give physical DIP switch position
	[ "$(gpioget ${RST})" = '1' ]
}

init_FTDI() {
	setup_FTDI
	setup_FTDI_GPIO
	isRST_ON || die "RST DIP switch is OFF, can not flash!"
}

init_Serial() {
	# Set timeout, so serial read will not block forever in sflash
	stty -F ${TTY} min 0 time 30
}

testPing0() {
	# Should succeed immediatelly with default bootloader
	# 1. Default bootloader works with auto-baud and will succeed
	# 2. Martem bootloader does not work with 38400 and will fail
	toggleRST
	if sflash /dev/null -s 16 -p 0x2800 -c ${TTY} -b 38400 -t -o 5; then
		toggleRST
		return 0
	else
		toggleRST
		return 1
	fi
}

testPing1() {
	# Should fail if we do not have our bootloader
	progON
	if sflash /dev/null -s 16 -p 0x2800 -c ${TTY} -b ${BAUD} -d -t; then
		progOFF
		return 0
	else
		progOFF
		return 1
	fi
}

agcioblSD() {
	# Get image from SD card
	if mountpoint /mnt/sd; then
		binary="${binary:-/mnt/sd/agciobl.bin}"
	fi
}

#############################################################
# Tiva programming

# Turn ON
$GPIO -es PERIF_USB_PWR
portWait
portInUse && die "Port is in use"

if [ "${script}" = 'gwhw-flash-agcio-bl' ]; then
	# setup bootloader
	# This will fail if our bootloader is already on the device.
	agcioblSD
	binary="${binary:-/tmp/agciobl.bin}"
	[ -r "${binary}" ] || die "Cant read binary: ${binary}"
	init_FTDI
	init_Serial
	testPing0 || die "Bootloader may be already flashed"
	sflash ${binary} -s 16 -p 0x0000 -c ${TTY} -b 38400 -o 10 || die "sflash failed"
else
	# setup io software
	# needs correct bootloader or it will fail
	binary="${binary:-$path/bin/agcio.bin}"
	[ 'blink-test' = "${binary}" ] && binary="${path}/bin/agcio_blink_test.bin"
	[ -r "${binary}" ] || die "Cant read binary: ${binary}"
	init_FTDI
	init_Serial
	testPing0 && die "Missing correct bootloader"
	progON
	sflash ${binary} -s 16 -p 0x2800 -c ${TTY} -b ${BAUD} -d || die "sflash failed"
	progOFF
	# Do reset3 over IEC101, this fixes not working last DI
	"$path/gwhw-io-reset3"
fi

