#!/bin/bash
# ---------------------------------------------------------------------------
# NAME
#
#     InitOctalUartLines - configures the octal UART transceivers
#
# SYNOPSIS
#
#     sudo InitOctalUartLines {protocol0 { protocol1 { ... } }
#
# DESCRIPTION
#
#     The octal UART uses configurable transceivers that can be set to
#     either RS-232, RS-422, RS-485 or turned off.  This script takes a
#     variable number of protocol arguments that correspond to each port
#     starting with the third one (/dev/ttyLX2); any arguments not provided
#     disable the corresponding port transceiver.
#
#     The each parameter may be one of:
#
#         rs232:   configures the transceiver for RS-232
#         rs422:   configures the transceiver for RS-422
#         rs485:   configures the transceiver for RS-485
#         off:     disables the transceiver
#
#     Note that the first two ports (/dev/ttyLX0 and /dev/ttyLX1) are
#     configured in hardware for RS-232
#
# EXAMPLES
#
#     To configure the 3rd and 5th ports for RS-232, and leave everything
#     else turned off:
#
#         sudo InitOctalUartLines rs232 off rs232
#
# ---------------------------------------------------------------------------

# determines if the parameter is a valid state name; a return value of
# 0 indicates a good token
function ValidState()
{
	local __stateName="$1"
	local __retval

	shopt -s nocasematch

	if [ -z "$__stateName" ]
	then
		__stateName="OFF"
	fi

	case $__stateName in
		RS232|RS422|RS485|OFF)
			__retval="0"
			;;
		*)
			echo 1>&2 "Invalid state name $__stateName"
			__retval="1"
			;;
	esac

	shopt -u nocasematch
	return $__retval
}

# converts a state name to a nibble value (echoed); the return
# value is 0 on success
function NibbleValue()
{
	local __stateName="$1"
	local __retval

	shopt -s nocasematch

	if [ -z "$__stateName" ]
	then
		__stateName="OFF"
	fi

	case $__stateName in
		RS232)
			echo 8
			__retval="0"
			;;
		RS422)
			echo 9
			__retval="0"
			;;
		RS485)
			echo 13
			__retval="0"
			;;
		OFF)
			echo 0
			__retval="0"
			;;
		*)
			echo 1>&2 "Invalid state name $__stateName"
			__retval="1"
			;;
	esac

	shopt -u nocasematch
	return $__retval
}

# converts two state names to a hexdecimal byte value (echoed)
function ByteValue
{
	local lower=$( NibbleValue "$1" )
	local upper=$( NibbleValue "$2" )

	echo $(( 16*$upper + $lower ))
}

# exit if not run as root
CURUSER=`whoami`

if [ "$CURUSER" != "root" ]
then
	echo "This script must be run as root "
	exit 1
fi

# alias names
port2State="$1"
port3State="$2"
port4State="$3"
port5State="$4"
port6State="$5"
port7State="$6"

# any commands that fail will terminate the script
set -e

# the ports come up as unavailable, so I'm fixing up the permissions
chmod 777 /dev/ttyLX*

# validate the states
ValidState "$port2State"
ValidState "$port3State"
ValidState "$port4State"
ValidState "$port5State"
ValidState "$port6State"
ValidState "$port7State"

# set the direction of all registers to output (I'm going to write them)
i2cset -y 2 0x39 0x03 0x00
i2cset -y 2 0x3A 0x03 0x00
i2cset -y 2 0x3B 0x03 0x00

# write the changes
i2cset -y 2 0x39 0x01 `ByteValue $port2State $port3State`
i2cset -y 2 0x3A 0x01 `ByteValue $port4State $port5State`
i2cset -y 2 0x3B 0x01 `ByteValue $port6State $port7State`

# read the settings back and display them
base=`basename $0`
resultA=`i2cget -y 2 0x39 0x01`
resultB=`i2cget -y 2 0x3A 0x01`
resultC=`i2cget -y 2 0x3B 0x01 `
echo "$base: $resultA $resultB $resultC"

exit 0


