From 5ff887d64d0b26e686834b9bf0a7bc35ad8c7e15 Mon Sep 17 00:00:00 2001 From: ian Date: Sat, 31 Dec 2005 04:40:49 +0000 Subject: [PATCH] stopgap controller program --- hostside/stopgap-controller | 300 ++++++++++++++++++++++++++++++++++++ 1 file changed, 300 insertions(+) create mode 100755 hostside/stopgap-controller diff --git a/hostside/stopgap-controller b/hostside/stopgap-controller new file mode 100755 index 0000000..24f3cb7 --- /dev/null +++ b/hostside/stopgap-controller @@ -0,0 +1,300 @@ +#!/usr/bin/tclsh8.4 + +set testonly 1 +set port /dev/ttya0 +# unset always + +set m xx +set segs xx +set polarity 908000 +set pq {} ;# unset: cdu charged and waiting +# unset pointpos($point) +# unset segdetect($seg) ;# unset: shown D0; {}: shown D1; or: after id, D1->0 + +proc gui {m} { + puts "GUI $m" +} + +proc gui_init {} { + global watchdog polarity segdetect + gui "M A2 0" + gui "M A5 0 J" + gui "M A6 0 J" + if {[info exists watchdog]} { gui "P 1" } + if {![regexp {^90} $polarity]} { gui_polarity } + foreach seg [array names segdetect] { + gui "D1 $seg" + } +} + +proc debug {m} { + puts $m +} + +proc tellpic {m} { + global p testonly + puts ">> $m" + if {$testonly} return + set b [binary format H* $m] + puts -nonewline $p $b +} + +proc bgerror {m} { + if {[catch { + global errorInfo errorCode + puts stderr "$m\n$errorCode\n$errorInfo" + fail "bgerror $m" + } emsg]} { + exit 127 + } +} + +proc fail_now {} { + global p + debug "failing now" + fconfigure $p -blocking yes + gui "P 0" + tellpic 20 + exit 1 +} + +proc fail {m} { + global watchdog p + catch { after cancel $watchdog; unset watchdog } + puts "failing $m" + tellpic a001 ;# 16ms + after 2000 fail_now + fileevent $p readable {} +} + +proc gui_polarity {} { + foreach seg { + X8 + X9 + X10 + X1 + X2 + X3 + X4 + X5 + X6 + X7 + } { + gui "R $seg" + } +} + +proc polarity {m} { + global polarity + debug "polarising $m" + tellpic $m + if {[string compare $m $polarity]} { + gui_polarity + } + set polarity $m +} +proc polarity_l {} { polarity 908000 } +proc polarity_x {} { polarity 97ff7f } + +proc pt_now {how point pos xtra} { + set msg a0[lindex $point $pos] + debug "$how point $point pos=$pos msg=$msg$xtra" + gui "M [lindex $point 2] [expr {!$pos}]" + tellpic $msg +} +proc pt_must {point newpos} { + upvar #0 pointpos($point) pos + global pq + if {[info exists pos] && $pos == $newpos} return + set pos $newpos + if {[info exists pq]} { + lappend pq [list $point $pos] + debug "queue point $point pos=$pos l=[llength $pq]" + return + } + pt_now immed $point $pos {} + set pq {} +} + +proc pm_charged {} { + global pq + if {[llength $pq]} { + set v [lindex $pq 0] + set pq [lrange $pq 1 end] + pt_now nowdo [lindex $v 0] [lindex $v 1] " l=[llength $pq]" + } else { + debug "cdu-charged" + unset pq + } +} + +proc pt_maybe {point} { + global always rand + if {[info exists always]} { + set pos $always + } else { + set c [read $rand 1]; if {![string length $c]} { error "eof on rand" } + binary scan $c H* x + set pos [expr [regexp {^[89a-f]} $x] ? 1 : 0] + debug "chose point $point pos=$pos (x=$x)" + } + pt_must $point $pos +} + +proc s0 {seg} { + upvar #0 segdetect($seg) segd + if {![info exists segd]} { + debug "segment $seg = already" + } elseif {[string length $segd]} { + debug "segment $seg = pending already" + } else { + debug "segment $seg = soon" + set segd [after 100 s0t $seg] + } +} +proc s0t {seg} { + upvar #0 segdetect($seg) segd + debug "segment $seg = now" + unset segd + gui "D0 $seg" +} +proc s1 {seg} { + upvar #0 segdetect($seg) segd + if {![info exists segd]} { + debug "segment $seg ! (overwrites =)" + } elseif {[string length $segd]} { + debug "segment $seg ! (cancels =)" + after cancel $segd + } else { + debug "segment $seg ! already" + return + } + gui "D1 $seg" + set segd {} +} + +proc pm_maydetect {d seg} { + switch -exact $seg { + 06 { s$d X10 } + 09 { s$d X8 } + 0a { s$d X6 } + 04 { s$d X5 } + 02 { s$d X7 } + 07 { s$d X9 } + 14 { s$d A5 } + 20 { s$d A6 } + 1a { s$d A4 } + 10 { s$d A2 } + 03 { s$d X1 } + 05 { s$d X3 } + 16 { s$d A3 } + 1c { s$d A1 } + 08 { s$d X2 } + 0b { s$d X4 } + } +} + +proc pm_detect {seg} { + global segs + switch -exact $seg { + 07 - 06 { polarity_l } + 16 - 1c - 1a - 10 - 03 - 05 - 08 - 0b { polarity_x } + } + switch -exact $seg { + 14 - 20 { pt_must "02 03 A5" 1; pt_must "42 43 A6" 1 } + 04 - 0a { pt_must "00 01 X7" 1; pt_must "40 41 X8" 1 } + 03 - 05 { pt_must "00 01 X7" 0 } + 08 - 0b { pt_must "40 41 X8" 0 } + 16 - 1c { pt_must "02 03 A5" 0 } + 1a - 10 { pt_must "42 43 A6" 0 } + } + if {[lsearch -exact $segs $seg] < 0} { + set segs [list [lindex $segs end] $seg] + } + switch -exact [join $segs -] { + 07-02 { pt_maybe "00 01 X7" } + 02-07 { pt_maybe "02 03 A5" } + 06-09 { pt_maybe "40 41 X8" } + 09-06 { pt_maybe "42 43 A6" } + } +} + +proc watchdog {} { + global watchdog testonly + if {$testonly} return + catch { after cancel $watchdog } + set watchdog [after 50 watchdog] + tellpic 9808 ;# 128ms +} + +proc pm_hello {} { + debug "got hello, starting up" + tellpic 21 + gui "P 1" + watchdog +} + +proc frompic {m} { + debug "<< $m" + switch -glob [lindex $m 0] { + 09 { pm_hello } + 28 { pm_charged } + 9[0-7] { pm_maydetect 0 [lindex $m 1] } + 9? { pm_detect [lindex $m 1]; pm_maydetect 1 [lindex $m 1] } + 0a - [234567]? { puts "pic debug $m" } + * { fail "pic unknown $m" } + } +} + +proc onreadp_test {} { + if {![gets stdin m]} { return } + frompic $m +} + +proc onreadp {} { + global p m + while 1 { + set c [read $p 1] + if {![string llength $c]} { + if {[eof $p]} { error "eof on device" } + return + } + binary scan $c H* x + lappend m $x + if {[regexp {^[89a-f]} $x]} { + if {![regexp {^x} $m]} { + frompic $m + } + set m {} + } + } +} + +proc setup {} { + global port p rand testonly + if {!$testonly} { + set p [open $port {RDWR NONBLOCK} 0] + + exec stty -F $port min 1 time 0 -istrip -ocrnl -onlcr -onocr -opost \ + -ctlecho -echo -echoe -echok -echonl -iexten -isig \ + -icanon -icrnl \ + 9600 clocal cread crtscts -hup -parenb cs8 -cstopb \ + -ixoff bs0 cr0 ff0 nl0 -ofill -olcuc + + fconfigure $p -encoding binary -translation binary \ + -blocking false -buffering none + + fileevent $p readable onreadp + } else { + set p stdin + fconfigure stdin -blocking false + fileevent stdin readable onreadp_test + } + + set rand [open /dev/urandom {RDONLY} 0] + fconfigure $rand -encoding binary -translation binary +} + +setup +gui_init +vwait end -- 2.30.2