namespace eval asm142 {} {
}

proc stdConfig::asm142 {} {
  controller bin

  pollperiod 0.01

  obj ASM142 rd
  prop read asm142::read
  kids "leak detector" {
    node p upd

    node state upd
    prop enum standby,cycle,test

    node vent upd
    prop enum 1

    node manualvalve par 0
    prop enum 1
  }
}

proc asm142::read {} {
  # we wait for at least one byte. the bin driver adds additional bytes
  # arriving immediately, but as we are sending nothing, nothing is purged
  # (modification of SICS 22.10.2014)
  sct send " / hex"
  return asm142::update
}

proc asm142::update {} {
  # Format of data sent from ASM142 to its remote control:
  # ff <adr> <data>
  # for <adr>==04 <data> is 2 bytes, for all other known <adr> 1 byte
  # several (not always all) data chunks are sent one by one
  # at the end, "ff 00 00" is sent, and the remote control respond is
  # "00 00" (or i.e. "00 02" when CYCLE is pressed)
  # if the remote control is not connected, only ff "00 00" is sent
  # known data chunks:
  # 01 <i>: mbar bargraph (<i> = 1 ... 20, meaning 1e-3 ... 2e+3, 3 per magnitude)
  # 02 <i>: leak rate bargraph (<i> = 1 ... 40, meaning 1.7e-12 ... 1e-2)
  # 04 nm cl: leak rate (n.mE-l, BCD format, where c seems to be the code for "-") 
  # 06 10tzaclr (LEDs bits: test, zero, autocal, cycle, left, right)
  # 07 0000v0s0 (LEDs bits: vent, snif)
  # 0d <i>: threshold for leak rate (blinking) (<i> = 128 + bar number)

  set buf [silent "" sct buf]
  set res [concat [silent "" sct oldres] [sct result]]
#clientput $res
  foreach byte $res {
    if {$byte eq "ff"} {
      if {[llength $buf] > 0} {
        set adr [lindex $buf 1]
        set val [lrange $buf 2 end]
        switch $adr {
          04 {
            set exp1 0
            scan $val "%1s%1s %1s%1s" dig1 dig2 exp1 exp2
            switch $exp1 {
            3 {set exp1 "e-1"}
            c {set exp1 "e-"}
            }
            if {$exp1 ne "0"} {
              sct update "${dig1}.${dig2}${exp1}${exp2}"
            }
          }
          01 {
            set p 0
            scan $val "%x" p
            updateval [sct]/p [expr pow(10, ($p-1)/3.0) * 0.001]
          }
          06 {
            set state 0
            set led 0
            scan $val "%x" led
            if {$led & 32} {
              set state 2
            } elseif {$led & 4} {
              set state 1
            }
            updateval [sct]/state $state
          }
          07 {
            set vent 0
            set led 0
            scan $val "%x" led
            if {$led & 8} {
              set vent 1
            }
            updateval [sct]/vent $vent            
          }
#          02 - 0d {
#            # ignore leak rate bar and level
#            set press 0
#            scan $val "%x" p
#            updateval [sct]/p [expr pow(10, ($p-1)/3.0) * 0.001]
#          }
#          default {
#            set old ""
#            global pars
#            catch {set old $pars($adr)}
#            if {$old ne $val} {
#              set pars($adr) $val
#              clientput "${adr}:${val}"
#            }
#          }
        }
        set buf ""
      }
      set buf $byte
    } else {
      append buf " $byte"
      if {$buf eq "ff 00 00" && [silent 0 sct noremote]} {
#clientput "send 00 00"
        sct buf ""
        sct send "00 00 /"
        return asm142::readnext
      }
    }
  }
  sct buf $buf
  return idle
}

proc asm142::readnext {} {
  sct oldres [sct result]
  return idle
}
