#!/bin/sh

# Copyright (c) 2008, Technologic Systems.
# All rights reserved.
# This library works with 8-bit and 16-bit PC/104 systems.
# All the routines use 8-bit PC/104 cycles.

# Uncomment one of the following:
# TS-7200, TS-7250, TS-7260, TS-7300:
#export ISAIO8_BASE=0x11E00000
# TS-7350, TS-7370:
#export ISAIO8_BASE=0x600FF800
# TS-7800:
#export ISAIO8_BASE=0xEE000000

# bit_set ADDRESS BIT_NUMBER
bit_set() {
  local MASK VAL1 VAL2 ADDR1 ADDR2
  let MASK=1\<\<$2
  let ADDR1=$1
  let ADDR2=$ADDR1+1
  let VAL1=`peekpoke 8 $ADDR1`
  let VAL2=`peekpoke 8 $ADDR2`
  if test $2 -gt 7; then

    let MASK=$MASK\>\>8
    let VAL2=$MASK\|$VAL2
    peekpoke 8 $ADDR1 $VAL1
    peekpoke 8 $ADDR2 $VAL2
  else
    let VAL1=$MASK\|$VAL1
    peekpoke 8 $ADDR1 $VAL1
  fi
}

# bit_clr ADDRESS BIT_NUMBER
bit_clr() {
  local MASK VAL1 VAL2 ADDR1 ADDR2
  let MASK=1\<\<$2
  let ADDR1=$1
  let ADDR2=$ADDR1+1
  let VAL1=`peekpoke 8 $ADDR1`
  let VAL2=`peekpoke 8 $ADDR2`
  if test $2 -gt 7; then
    let MASK=$MASK\>\>8
    let VAL2=~$MASK\&$VAL2
    peekpoke 8 $ADDR1 $VAL1
    peekpoke 8 $ADDR2 $VAL2
  else
    let VAL1=~$MASK\&$VAL1
    peekpoke 8 $ADDR1 $VAL1
  fi
}

# bit_get ADDRESS BIT_NUMBER
bit_get() {
  local MASK VAL ADDR1 ADDR2
  let MASK=1\<\<$2
  let ADDR1=$1
  let ADDR2=$ADDR1+1
  let VAL=`peekpoke 8 $ADDR2`\<\<8
  let VAL=$VAL\|`peekpoke 8 $ADDR1`
  let VAL=$VAL\>\>$2
  let VAL=$VAL\&1
  echo $VAL
}

adc_baseio () {
  local VAL BID
  for i in 0x100 0x120 0x140 0x160 0x0
  do
    let VAL=$i\|$ISAIO8_BASE
    let BID=`peekpoke 8 $VAL`
    if [ $BID -eq 62 -o $BID -eq 63 ]; then break; fi
  done
  echo $VAL
}

adc_id () {
  let BASEIO=`adc_baseio`
  let BID=`peekpoke 8 $BASEIO`
  if test $BID -eq 62; then echo "TS-ADC16";
  elif test $BID -eq 63; then echo "TS-ADC24";
  else echo ""; fi
}

adc_status () {
  let BASEIO=`adc_baseio`\|0x2
  bit_get $BASEIO 0
}
adc_start () { 
  let BASEIO=`adc_baseio`\|0x2
  bit_set $BASEIO 0 > /dev/null
  bit_get $BASEIO 0
}
adc_restart () { 
  let BASEIO=`adc_baseio`\|0x2
  bit_clr $BASEIO 0 > /dev/null
  echo "delay" > /dev/null
  bit_set $BASEIO 0 > /dev/null
  bit_get $BASEIO 0
}
adc_stop () { 
  let BASEIO=`adc_baseio`\|0x2
  bit_clr $BASEIO 0 > /dev/null
  bit_get $BASEIO 0
}

adc_set_exttrig () { 
  if [ `adc_id` == "TS-ADC24" ]; then echo "Not available for the TS-ADC24"; return; fi
  let BASEIO=`adc_baseio`\|0x2
  bit_set $BASEIO 9 > /dev/null
  bit_get $BASEIO 9
}
adc_clr_exttrig () { 
  if [ `adc_id` == "TS-ADC24" ]; then echo "Not available for the TS-ADC24"; return; fi
  let BASEIO=`adc_baseio`\|0x2
  bit_clr $BASEIO 9 > /dev/null
  bit_get $BASEIO 9
}
adc_exttrig () { 
  if [ `adc_id` == "TS-ADC24" ]; then echo "Not available for the TS-ADC24"; return; fi
  let BASEIO=`adc_baseio`\|0x2
  bit_get $BASEIO 9
}

adc_set_sedif () { 
  adc_stop > /dev/null
  let BASEIO=`adc_baseio`\|0x2
  bit_set $BASEIO 5 > /dev/null
  bit_set $BASEIO 8 > /dev/null
  bit_get $BASEIO 8
}
adc_clr_sedif () { 
  adc_stop > /dev/null
  let BASEIO=`adc_baseio`\|0x2
  bit_clr $BASEIO 5 > /dev/null
  bit_clr $BASEIO 8 > /dev/null
  bit_get $BASEIO 8
}
adc_sedif () { 
  let BASEIO=`adc_baseio`\|0x2
  bit_get $BASEIO 8
}

adc_set_inrng () { 
  adc_stop > /dev/null
  let BASEIO=`adc_baseio`\|0x2
  let BIT6=$1\&0x1
  if test $BIT6 -eq 0; then
    bit_clr $BASEIO 6 > /dev/null
  else
    bit_set $BASEIO 6 > /dev/null
  fi
  let BIT7=$1\&0x2
  if test $BIT7 -eq 0; then
    bit_clr $BASEIO 7 > /dev/null
  else
    bit_set $BASEIO 7 > /dev/null
  fi
  echo `adc_inrng`  
}
adc_inrng () { 
  let BASEIO=`adc_baseio`\|0x2
  let VAL=`bit_get $BASEIO 7`\<\<1
  let VAL=$VAL\|`bit_get $BASEIO 6`
  echo $VAL
}

adc_set_numchan () {
  local BASEIO VAL1 VAL2 NUMCHAN
  adc_stop > /dev/null
  let NUMCHAN=$1\<\<1
  let NUMCHAN=$NUMCHAN\&0x1e
  let BASEIO=`adc_baseio`\|0x2
  let VAL1=`peekpoke 8 $BASEIO`
  let BASEIO=$BASEIO+0x1
  let VAL2=`peekpoke 8 $BASEIO`
  let BASEIO=`adc_baseio`\|0x2
  let VAL1=$VAL1\&~0x1e
  let VAL1=$VAL1\|$NUMCHAN
  peekpoke 8 $BASEIO $VAL1 > /dev/null
  let BASEIO=$BASEIO+0x1
  peekpoke 8 $BASEIO $VAL2 > /dev/null
  let NUMCHAN=$1\&0xf
  echo $NUMCHAN
}
adc_numchan () { 
  local BASEIO VAL
  let BASEIO=`adc_baseio`\|0x2
  let VAL=`peekpoke 8 $BASEIO`\&0x1e
  let VAL=$VAL\>\>1
  echo $VAL
}

adc_set_dly () { 
  local BASEIO DLY VAL
  adc_stop > /dev/null
  let BASEIO=`adc_baseio`\|0x6
  let DLY=$1\&0xffffff
  let VAL=$DLY\&0xff
  peekpoke 8 $BASEIO $VAL > /dev/null
  let BASEIO=$BASEIO+0x1
  let DLY=$DLY\>\>8
  let VAL=$DLY\&0xff
  peekpoke 8 $BASEIO $VAL > /dev/null
  let BASEIO=$BASEIO-0x3
  let DLY=$DLY\>\>8
  let VAL=$DLY\&0xff
  peekpoke 8 $BASEIO $VAL > /dev/null
  let DLY=$1\&0xffffff
  echo $DLY
}
adc_dly () { 
  local BASEIO DLY VAL
  let BASEIO=`adc_baseio`\|0x6
  let BASEIO=$BASEIO-0x2
  let VAL=`peekpoke 8 $BASEIO`\&0x3f
  let VAL=$VAL\<\<16
  let DLY=$VAL
  let BASEIO=$BASEIO+0x3
  let VAL=`peekpoke 8 $BASEIO`\<\<8
  let DLY=$DLY\|$VAL
  let BASEIO=$BASEIO-0x1
  let VAL=`peekpoke 8 $BASEIO`
  let DLY=$DLY\|$VAL
  echo $DLY
}

adc_fffull () { 
  let BASEIO=`adc_baseio`\|0x8
  bit_get $BASEIO 15
}
adc_ffhfull () { 
  let BASEIO=`adc_baseio`\|0x8
  bit_get $BASEIO 14
}
adc_ffcount () { 
  local FIFON BASEIO
  let BASEIO=`adc_baseio`\|0x9
  let FIFON=`peekpoke 8 $BASEIO`\<\<8
  let BASEIO=$BASEIO-0x1
  let FIFON=$FIFON\|`peekpoke 8 $BASEIO`
  let FIFON=$FIFON\>\>6\&0x03ff
  echo $FIFON
}
adc_ffhead () { 
  local BASEIO FFHEAD
  let BASEIO=`adc_baseio`\|0x8
  let FFHEAD=`peekpoke 8 $BASEIO`
  let FFHEAD=$FFHEAD\>\>1\&0x001f
  echo $FFHEAD
}
adc_set_ffcountint () { 
  local BASEIO VAL1 VAL2 FFCNTINT
  let FFCNTINT=$1\<\<6
  let FFCNTINT=$FFCNTINT\&0xffc0
  let BASEIO=`adc_baseio`\|0x8
  let VAL1=`peekpoke 8 $BASEIO`
  let VAL1=$VAL1\&~0xc0
  let VAL1=$VAL1\|$FFCNTINT
  peekpoke 8 $BASEIO $VAL1 > /dev/null
  let BASEIO=$BASEIO+0x1
  let VAL2=$FFCNTINT\>\>8
  peekpoke 8 $BASEIO $VAL2 > /dev/null
  let FFCNTINT=$FFCNTINT\>\>6
  echo $FFCNTINT
}

adc_set_inten () { 
  let BASEIO=`adc_baseio`\|0x8
  bit_set $BASEIO 0 > /dev/null
  bit_get $BASEIO 0
}
adc_clr_inten () { 
  let BASEIO=`adc_baseio`\|0x8
  bit_clr $BASEIO 0 > /dev/null
  bit_get $BASEIO 0
}
adc_inten () { 
  let BASEIO=`adc_baseio`\|0x8
  bit_get $BASEIO 0
}

adc_set_dac () { 
  if [ `adc_id` == "TS-ADC24" ]; then echo "Not available for the TS-ADC24"; return; fi
  local BASEIO CH GAIN BUF DAT VAL VAL1
  let BASEIO=`adc_baseio`\|0xe
  let CH=$1\&0x3
  let CH=$CH\<\<14
  let GAIN=$2\&0x1
  let GAIN=$GAIN\<\<13
  let BUF=$3\&0x1
  let BUF=$BUF\<\<12
  let DAT=$4\&0xfff
  let VAL=$CH\|$GAIN\|$BUF\|$DAT
  let VAL1=$VAL\&0xff
  peekpoke 8 $BASEIO $VAL1 > /dev/null
  let BASEIO=$BASEIO+0x1
  let VAL1=$VAL\>\>8
  peekpoke 8 $BASEIO $VAL1 > /dev/null
  echo $VAL
}
adc_set_dac0 () { 
  echo `adc_set_dac 0 1 0 $1`
}
adc_set_dac1 () { 
  echo `adc_set_dac 1 1 0 $1`
}
adc_set_dac2 () { 
  echo `adc_set_dac 2 1 0 $1`
}
adc_set_dac3 () { 
  echo `adc_set_dac 3 1 0 $1`
}

adc_counter () {
  if [ `adc_id` == "TS-ADC24" ]; then echo "Not available for the TS-ADC24"; return; fi
  local OFFSET BASEIO VAL
  let OFFSET=$1*2
  let BASEIO=`adc_baseio`\|0x11\|OFFSET
  let VAL=`peekpoke 8 $BASEIO`\<\<8
  let BASEIO=$BASEIO-0x1
  let VAL=$VAL\|`peekpoke 8 $BASEIO`
  echo $VAL
}
adc_counter0 () { 
  echo `adc_counter 0`
}
adc_counter1 () { 
  echo `adc_counter 1`
}
adc_counter2 () { 
  echo `adc_counter 2`
}
adc_counter3 () { 
  echo `adc_counter 3`
}

adc_din0 () { 
  if [ `adc_id` == "TS-ADC24" ]; then echo "Not available for the TS-ADC24"; return; fi
  let BASEIO=`adc_baseio`\|0x18
  bit_get $BASEIO 0
}
adc_din1 () { 
  if [ `adc_id` == "TS-ADC24" ]; then echo "Not available for the TS-ADC24"; return; fi
  let BASEIO=`adc_baseio`\|0x18
  bit_get $BASEIO 1
}
adc_din2 () { 
  if [ `adc_id` == "TS-ADC24" ]; then echo "Not available for the TS-ADC24"; return; fi
  let BASEIO=`adc_baseio`\|0x18
  bit_get $BASEIO 2
}
adc_din3 () { 
  if [ `adc_id` == "TS-ADC24" ]; then echo "Not available for the TS-ADC24"; return; fi
  let BASEIO=`adc_baseio`\|0x18
  bit_get $BASEIO 3
}

adc_set_dout0 () { 
  if [ `adc_id` == "TS-ADC24" ]; then echo "Not available for the TS-ADC24"; return; fi
  let BASEIO=`adc_baseio`\|0x18
  bit_set $BASEIO 4 > /dev/null
  bit_get $BASEIO 4
}
adc_clr_dout0 () { 
  if [ `adc_id` == "TS-ADC24" ]; then echo "Not available for the TS-ADC24"; return; fi
  let BASEIO=`adc_baseio`\|0x18
  bit_clr $BASEIO 4 > /dev/null
  bit_get $BASEIO 4
}
adc_dout0 () { 
  if [ `adc_id` == "TS-ADC24" ]; then echo "Not available for the TS-ADC24"; return; fi
  let BASEIO=`adc_baseio`\|0x18
  bit_get $BASEIO 4
}

adc_fifoh () { 
  local BASEIO ADCDAT
  let BASEIO=`adc_baseio`\|0x1b
  let ADCDAT=`peekpoke 8 $BASEIO`\<\<8
  let BASEIO=$BASEIO-0x1
  let ADCDAT=$ADCDAT\|`peekpoke 8 $BASEIO`
  if [ `adc_id` == "TS-ADC24" ]; then let ADCDAT=$ADCDAT\&0xFFF; fi
  echo $ADCDAT
}
adc_fifo () { 
  local FFCOUNT FFHEAD ADCDAT
  let FFCOUNT=`adc_ffcount`
  let FFHEAD=`adc_ffhead`
  let ADCDAT=`adc_fifoh`
  echo "FIFO_POS=$FFCOUNT ADC_CH=$FFHEAD DATA=$ADCDAT"
}
adc_fifon () { 
  local FIFON
  let FIFON=$1
  while test $FIFON -gt 0; do
    echo `adc_fifo`
    let FIFON=$FIFON-1
  done
}
adc_fifoall () { 
  let FIFON=`adc_ffcount`
  while test $FIFON -gt 0; do
    echo `adc_fifo`
    let FIFON=$FIFON-1
  done
}
adc_fifocont () { 
  let FIFON=`adc_ffcount`
  while test $FIFON -gt 0; do
    echo `adc_fifo`
    let FIFON=`adc_ffcount`
  done
}

tsadchelp () { 
  echo
  echo "Technologic Systems TS-ADC16/TS-ADC24 Linux shell library:"
  echo "=========================================================="
  echo
  echo "adc_status: Returns status of ADC machine"
  echo "adc_start: Starts ADC machine"
  echo "adc_restart: Re-starts ADC machine"
  echo "adc_stop: Stops ADC machine"
  echo
  echo "adc_exttrig: Returns status of ADC external trigger"
  echo "adc_set_exttrig: Enables ADC external trigger"
  echo "adc_clr_exttrig: Disables ADC external trigger"
  echo
  echo "adc_sedif: Returns status of ADC single ended/differential"
  echo "adc_set_sedif: Enables ADC sigle ended"
  echo "adc_clr_sedif: Enables ADC differential"
  echo
  echo "adc_inrng: Returns status of ADC input range"
  echo "adc_set_inrng [0-3]: Sets input range to parameter"
  echo
  echo "adc_inten: Returns status of interrupt enable"
  echo "adc_set_inten: Enables interrupt"
  echo "adc_clr_inten: Disables interrupts"
  echo "adc_set_ffcountint [0-512]: Sets fifo count for interrut to parameter"
  echo
  echo "adc_numchan: Returns number of pair of ADC channels "
  echo "adc_set_numchan [0-7]: Sets number of pair of ADC channels to parameter"
  echo
  echo "adc_dly: Returns 24-bit ADC pacing clock"
  echo "adc_set_dly [0-16777215]: Sets 24-bit ADC pacing clock to parameter"
  echo
  echo "adc_fffull: Returns FIFO full status"
  echo "adc_ffhfull: Returns FIFO half-full status"
  echo "adc_ffcount: Returns FIFO count"
  echo "adc_ffhead: Returns channel on the head of the FIFO"
  echo
  echo "adc_set_dac [0-3] [0-1] [0-1] [0-4095]: Sets dac channel, gain, buffer and value to parameters"
  echo "adc_set_dac0 [0-4095]: Sets dac channel 0 value to parameter"
  echo "adc_set_dac1 [0-4095]: Sets dac channel 1 value to parameter"
  echo "adc_set_dac2 [0-4095]: Sets dac channel 2 value to parameter"
  echo "adc_set_dac3 [0-4095]: Sets dac channel 3 value to parameter"
  echo
  echo "adc_counter [0-3]: Returns value of the counter of the parameter"
  echo "adc_counter0: Returns value of the counter 0"
  echo "adc_counter1: Returns value of the counter 1"
  echo "adc_counter2: Returns value of the counter 2"
  echo "adc_counter3: Returns value of the counter 3"
  echo
  echo "adc_din0: Returns status of the digital input 0"
  echo "adc_din1: Returns status of the digital input 1"
  echo "adc_din2: Returns status of the digital input 2"
  echo "adc_din3: Returns status of the digital input 3"
  echo
  echo "adc_dout0: Returns status of the digital output"
  echo "adc_set_dout0: Sets digital output to 1"
  echo "adc_clr_dout0: Sets digital output to 0"
  echo
  echo "adc_fifo: Returns channel on the head of the FIFO with information"
  echo "adc_fifoh: Returns channel on the head of the FIFO"
  echo "adc_fifon [0-512]: Returns n channels from FIFO"
  echo "adc_fifoall: Returns all channels from the FIFO"
  echo "adc_fifocont: Returns all channels from the FIFO, reading continuously"
  echo
}

