# Copyright (c) 2009, Technologic Systems.
# All rights reserved.

# Note: Be sure you have 64-bit arithmetic compiled into your shell, or some
# of these functions will fail (e.g. for ADDRESS > 0x7FFFFFFF)

export PC104BASE=$((0x11E00000))

# bit_set BIT_WIDTH ADDRESS BIT_NUMBER
bit_set() {
  local MASK VAL
  MASK=$((1<<$3))
  VAL=`peekpoke $1 $2`
  VAL=$((MASK|VAL))
  peekpoke $1 $2 $VAL
}
                                                                                                                    
# bit_clr BIT_WIDTH ADDRESS BIT_NUMBER
bit_clr() {
  local MASK VAL
  MASK=$((1<<$3))
  VAL=`peekpoke $1 $2`
  VAL=$((~MASK&VAL))
  peekpoke $1 $2 $VAL
}
                                                                                                                    
# bit_get BIT_WIDTH ADDRESS BIT_NUMBER
bit_get() {
  local MASK VAL
  MASK=$((1<<$3))
  VAL=`peekpoke $1 $2`
  VAL=$((VAL>>$3))
  VAL=$((VAL&1))
  echo $VAL
}

find_ts9700() {
  local ADDR VAL
  for OFFSET in 0x160 0x168 0x180 0x188 0x250 0x258 0x260 0x268
  do
    ADDR=$(($PC104BASE+$OFFSET+1))
    VAL=`peekpoke 8 $ADDR`
    if [ $(($VAL)) -eq $((0x97)) ]; then
      echo -n "TS-9700 found at offset "
      echo $OFFSET
    fi
  done
}

#ts9700_read offset channel
ts9700_read() {
  local ADDR VAL
  ADDR=$(($PC104BASE+$1))
  #channel ranges from 1 to 8
  VAL=$(($2-1))
  peekpoke 8 $ADDR $VAL >/dev/null
  VAL=0
  while [ $VAL -eq 0 ]; do
    VAL=`peekpoke 8 $ADDR`
    VAL=$((0x80&$VAL))
  done
  ADDR=$(($PC104BASE+$1+3))
  VAL=`peekpoke 8 $ADDR`
  VAL=$(($VAL<<8))
  ADDR=$(($PC104BASE+$1+2))
  VAL=$(($VAL+`peekpoke 8 $ADDR`))
  echo $VAL
}

find_tsdio64() {
  local ADDR VAL
  for OFFSET in 0x100 0x110 0x120 0x130
  do
    ADDR=$(($PC104BASE+$OFFSET))
    VAL=`peekpoke 8 $ADDR`
    if [ $(($VAL)) -eq $((0xA4)) ]; then
      echo -n "TS-DIO64 found at offset "
      echo $OFFSET
    fi
  done
}

# dio64_bit_get offset pin
dio64_bit_get() {
  local ADDR BIT
  ADDR=$(($PC104BASE+$1+8+($2-1)/8))
  BIT=$((($2-1)%8))
  bit_get 8 $ADDR $BIT
}

# dio64_bit_set offset pin
dio64_bit_set() {
  local ADDR BIT
  ADDR=$(($PC104BASE+$1+4+($2-1)/8))
  BIT=$((($2-1)%8))
  bit_set 8 $ADDR $BIT >/dev/null
}

# dio64_bit_clr offset pin
dio64_bit_clr() {
  local ADDR BIT
  ADDR=$(($PC104BASE+$1+4+($2-1)/8))
  BIT=$((($2-1)%8))
  bit_clr 8 $ADDR $BIT >/dev/null
}
