#!/bin/sh
#
# Copyright 2009 under the GPL by Oliver Dippel <o.dippel@gmx.de>
#


if test "$1" != ""
then
	FILENAME="$1"
	if echo "$FILENAME" | grep -s -q -i "\.hex$"
	then
		cd "`dirname "$FILENAME"`"
		uisp -v -dprog=dapa --erase --upload if="`basename "$FILENAME"`" || gdialog --msgbox "Error: uisp -v -dprog=dapa --erase --upload if=\"$FILENAME\""
	fi
	exit
fi



TEMPFILE="`mktemp /tmp/avr-fuses.tmp.XXXXX`"
TEMPFILE2="`mktemp /tmp/avr-fuses2.tmp.XXXXX`"

uisp -v -dprog=dapa --rd_fuses > "$TEMPFILE2" 2>&1 || gdialog --msgbox "Error: No AVR connected !"

CPU_NAME="`head -n2 $TEMPFILE2 | tail -n1`"


LOW_NAMES="\
BODLEVEL: Brown out detector trigger level
BODEN: Brown out detector enable
SUT1: Select start-up time
SUT0: Select start-up time
CKSEL3: Select Clock source
CKSEL2: Select Clock source
CKSEL1: Select Clock source
CKSEL0: Select Clock source
"

if echo "$CPU_NAME" | grep -s -q "ATmega16 "
then
	HIGH_NAMES="\
OCDEN: Enable OCD
JTAGEN: Enable JTAG
SPIEN: Enable Serial Program and Data Downloading {programmed=SPI programming enabled}
CKOPT: Oscillator options
EESAVE: EEPROM memory is preserved through the Chip Erase {unprogrammed=EEPROM not preserved}
BOOTSZ1: Select Boot Size
BOOTSZ0: Select Boot Size
BOOTRST: Select Reset Vector
"
else
	HIGH_NAMES="\
?RSTDISBL: Select if PC6 is I/O pin or RESET pin {unprogrammed=PC6 is RESET}
?WDTON: WDT always on {unprogrammed=WDT enabled by WDTCR}
SPIEN: Enable Serial Program and Data Downloading {programmed=SPI programming enabled}
CKOPT: Oscillator options
EESAVE: EEPROM memory is preserved through the Chip Erase {unprogrammed=EEPROM not preserved}
BOOTSZ1: Select Boot Size
BOOTSZ0: Select Boot Size
BOOTRST: Select Reset Vector
"
fi



EXTENDED_NAMES="\
EXT7
EXT6
EXT5
EXT4
EXT3
EXT2
EXT1
EXT0
"

LOCK_NAMES="\
UNKNOWN: Unused
UNKNOWN: Unused
BLB12: Boot Lock bit
BLB11: Boot Lock bit
BLB02: Boot Lock bit
BLB01: Boot Lock bit
LB2: Lock bit
LB1: Lock bit
"



while echo -n
do
	echo -n > "$TEMPFILE"
	cat "$TEMPFILE2" | grep "^Fuse \|^Lock Bits" | while read LINE
	do
		TYPE="`echo $LINE | cut -d" " -f2`"
		VALUE="`echo $LINE | cut -d"=" -f2- | sed "s|  *||g"`"
		if test "$TYPE" = "Low"
		then
			echo "$TYPE '$LINE'" >> "$TEMPFILE"
		elif test "$TYPE" = "High"
		then
			echo "$TYPE '$LINE'" >> "$TEMPFILE"
		elif test "$TYPE" = "Extended"
		then
			echo "$TYPE '$LINE'" >> "$TEMPFILE"
		elif test "$TYPE" = "Bits"
		then
			echo "$TYPE '$LINE'" >> "$TEMPFILE"
		fi
	done
	VALUES="`cat "$TEMPFILE"`"
	echo -n > "$TEMPFILE"
	eval gdialog --title \"$CPU_NAME\" --menu \"AVR-Fuses\" 20 120 10 $VALUES flash Hex-File exit Exit 2> "$TEMPFILE" || break
	RET="`cat "$TEMPFILE"`"
	if test "$RET" = "exit"
	then
		break;
	elif test "$RET" = "flash"
	then
		#dialog --fselect ./ 0 0 2> $TEMPFILE
		zenity --title="Select a file to flash (*.hex)" --file-selection > $TEMPFILE
		FILENAME="`cat "$TEMPFILE"`"
		if echo "$FILENAME" | grep -s -q -i "\.hex$"
		then
			(
				cd "`dirname "$FILENAME"`"
				uisp -v -dprog=dapa --erase --upload if="`basename "$FILENAME"`" || gdialog --msgbox "Error: uisp -v -dprog=dapa --erase --upload if=\"$FILENAME\""
			)
		fi
		continue
	fi

	TYPE="`cat "$TEMPFILE"`"
	VALUE="`cat "$TEMPFILE2" | grep "^Fuse $TYPE Byte\|^Lock $TYPE" | cut -d"=" -f2- | sed "s|  *||g"`"
	let VALUE=$VALUE
	TOGGLE="0"
	if test "$TYPE" = "Low"
	then
		while echo -n
		do
			let VALUE2=$VALUE
			N="1"
			echo -n > "$TEMPFILE"
			for BIT in 128 64 32 16 8 4 2 1
			do
				echo -n "$BIT '`echo "$LOW_NAMES" | head -n$N | tail -n1` " >> "$TEMPFILE"
				if test "$VALUE2" -ge "$BIT"
				then
					VALUE2="`expr $VALUE2 - $BIT`"
					echo "1 (unprogrammed)'" >> "$TEMPFILE"
				else
					echo "0 (programmed)'" >> "$TEMPFILE"
				fi
				N="`expr $N + 1`"
			done
			VALUES="`cat "$TEMPFILE"`"
			eval gdialog --title \"$CPU_NAME\" --menu \"Low-Fuses \(0x`printf "%02X" $VALUE`\)\" 20 120 10 $VALUES burn Burn-Low-Fuses exit Exit 2> "$TEMPFILE" || break
			TOGGLE="`cat "$TEMPFILE"`"
			if test "$TOGGLE" = "exit"
			then
				break;
			elif test "$TOGGLE" = "burn"
			then
				clear
				echo "Burn Low-Fuses: 0x`printf "%02X" $VALUE`"
				uisp -v -dprog=dapa --wr_fuse_l=0x`printf "%02X" $VALUE` || gdialog --msgbox "Error: uisp -v -dprog=dapa --wr_fuse_l=0x`printf "%02X" $VALUE`"
				sleep 1
				uisp -v -dprog=dapa --rd_fuses > "$TEMPFILE2" || gdialog --msgbox "Error: No AVR connected !"
				break;
			else
				let VALUE2=$VALUE
				for BIT in 128 64 32 16 8 4 2 1
				do
					if test "$VALUE2" -ge "$BIT"
					then
						VALUE2="`expr $VALUE2 - $BIT`"
						if test "$TOGGLE" = "$BIT"
						then
							VALUE="`expr $VALUE - $BIT`"
						fi
					else
						if test "$TOGGLE" = "$BIT"
						then
							VALUE="`expr $VALUE + $BIT`"
						fi
					fi
				done
			fi
		done
		rm -rf "/tmp/exit"
	elif test "$TYPE" = "High"
	then
		while echo -n
		do
			let VALUE2=$VALUE
			N="1"
			echo -n > "$TEMPFILE"
			for BIT in 128 64 32 16 8 4 2 1
			do
				echo -n "$BIT '`echo "$HIGH_NAMES" | head -n$N | tail -n1` " >> "$TEMPFILE"
				if test "$VALUE2" -ge "$BIT"
				then
					VALUE2="`expr $VALUE2 - $BIT`"
					echo "1 (unprogrammed)'" >> "$TEMPFILE"
				else
					echo "0 (programmed)'" >> "$TEMPFILE"
				fi
				N="`expr $N + 1`"
			done
			VALUES="`cat "$TEMPFILE"`"
			eval gdialog --title \"$CPU_NAME\" --menu \"High-Fuses \(0x`printf "%02X" $VALUE`\)\" 20 120 10 $VALUES burn Burn-High-Fuses exit Exit 2> "$TEMPFILE" || break
			TOGGLE="`cat "$TEMPFILE"`"
			if test "$TOGGLE" = "exit"
			then
				break;
			elif test "$TOGGLE" = "burn"
			then
				clear
				echo "Burn High-Fuses: 0x`printf "%02X" $VALUE`"
				uisp -v -dprog=dapa --wr_fuse_h=0x`printf "%02X" $VALUE` || gdialog --msgbox "Error: uisp -v -dprog=dapa --wr_fuse_h=0x`printf "%02X" $VALUE`"
				sleep 1
				uisp -v -dprog=dapa --rd_fuses > "$TEMPFILE2" || gdialog --msgbox "Error: No AVR connected !"
				break;
			else
				let VALUE2=$VALUE
				for BIT in 128 64 32 16 8 4 2 1
				do
					if test "$VALUE2" -ge "$BIT"
					then
						VALUE2="`expr $VALUE2 - $BIT`"
						if test "$TOGGLE" = "$BIT"
						then
							VALUE="`expr $VALUE - $BIT`"
						fi
					else
						if test "$TOGGLE" = "$BIT"
						then
							VALUE="`expr $VALUE + $BIT`"
						fi
					fi
				done
			fi
		done
		rm -rf "/tmp/exit"
	elif test "$TYPE" = "Extended"
	then
		while echo -n
		do
			let VALUE2=$VALUE
			N="1"
			echo -n > "$TEMPFILE"
			for BIT in 128 64 32 16 8 4 2 1
			do
				echo -n "$BIT '`echo "$EXTENDED_NAMES" | head -n$N | tail -n1` " >> "$TEMPFILE"
				if test "$VALUE2" -ge "$BIT"
				then
					VALUE2="`expr $VALUE2 - $BIT`"
					echo "1 (unprogrammed)'" >> "$TEMPFILE"
				else
					echo "0 (programmed)'" >> "$TEMPFILE"
				fi
				N="`expr $N + 1`"
			done
			VALUES="`cat "$TEMPFILE"`"
			eval gdialog --title \"$CPU_NAME\" --menu \"Extended-Fuses \(0x`printf "%02X" $VALUE`\)\" 20 120 10 $VALUES burn Burn-Extended-Fuses exit Exit 2> "$TEMPFILE" || break
			TOGGLE="`cat "$TEMPFILE"`"
			if test "$TOGGLE" = "exit"
			then
				break;
			elif test "$TOGGLE" = "burn"
			then
				clear
				echo "Burn Extended-Fuses: 0x`printf "%02X" $VALUE`"
				uisp -v -dprog=dapa --wr_fuse_e=0x`printf "%02X" $VALUE` || gdialog --msgbox "Error: uisp -v -dprog=dapa --wr_fuse_e=0x`printf "%02X" $VALUE`"
				sleep 1
				uisp -v -dprog=dapa --rd_fuses > "$TEMPFILE2" || gdialog --msgbox "Error: No AVR connected !"
				break;
			else
				let VALUE2=$VALUE
				for BIT in 128 64 32 16 8 4 2 1
				do
					if test "$VALUE2" -ge "$BIT"
					then
						VALUE2="`expr $VALUE2 - $BIT`"
						if test "$TOGGLE" = "$BIT"
						then
							VALUE="`expr $VALUE - $BIT`"
						fi
					else
						if test "$TOGGLE" = "$BIT"
						then
							VALUE="`expr $VALUE + $BIT`"
						fi
					fi
				done
			fi
		done
		rm -rf "/tmp/exit"
	elif test "$TYPE" = "Bits"
	then
		while echo -n
		do
			let VALUE2=$VALUE
			N="1"
			echo -n > "$TEMPFILE"
			for BIT in 128 64 32 16 8 4 2 1
			do
				echo -n "$BIT '`echo "$LOCK_NAMES" | head -n$N | tail -n1` " >> "$TEMPFILE"
				if test "$VALUE2" -ge "$BIT"
				then
					VALUE2="`expr $VALUE2 - $BIT`"
					echo "1 (unprogrammed)'" >> "$TEMPFILE"
				else
					echo "0 (programmed)'" >> "$TEMPFILE"
				fi
				N="`expr $N + 1`"
			done
			VALUES="`cat "$TEMPFILE"`"
			eval gdialog --title \"$CPU_NAME\" --menu \"Lock-Bits \(0x`printf "%02X" $VALUE`\)\" 20 120 10 $VALUES burn Burn-Lock-Bits exit Exit 2> "$TEMPFILE" || break
			TOGGLE="`cat "$TEMPFILE"`"
			if test "$TOGGLE" = "exit"
			then
				break;
			elif test "$TOGGLE" = "burn"
			then
				clear
				echo "Burn Lock-Bits: 0x`printf "%02X" $VALUE`"
				uisp -v -dprog=dapa --wr_lock=0x`printf "%02X" $VALUE` || gdialog --msgbox "Error: uisp -v -dprog=dapa --wr_lock=0x`printf "%02X" $VALUE`"
				sleep 1
				uisp -v -dprog=dapa --rd_fuses > "$TEMPFILE2" || gdialog --msgbox "Error: No AVR connected !"
				break;
			else
				let VALUE2=$VALUE
				for BIT in 128 64 32 16 8 4 2 1
				do
					if test "$VALUE2" -ge "$BIT"
					then
						VALUE2="`expr $VALUE2 - $BIT`"
						if test "$TOGGLE" = "$BIT"
						then
							VALUE="`expr $VALUE - $BIT`"
						fi
					else
						if test "$TOGGLE" = "$BIT"
						then
							VALUE="`expr $VALUE + $BIT`"
						fi
					fi
				done
			fi
		done
		rm -rf "/tmp/exit"
	fi
done

rm -rf "$TEMPFILE"
rm -rf "$TEMPFILE2"

