// ResistMeasure.bcpl -- board tester hardware operation // Last modified by McCreight June 25, 1984 1:35 PM // to accommodate a wider range of ohms by a hardware change // in the tester that produces a voltage proportional to // log of resistance. get "Resist.decl" get "AltoDefs.d" get "SysDefs.d" external [ // outgoing procedures MeasureOhms; CalibrateOhms; PulseChannel; Wait; SignalOn; TesterInterrupt // incoming procedures DecodeOhms; Max // incoming statics OsBuffer ] static [ testerOut; ticks signalOn = false signalState = false signalTimer = 0 lastSwitchState = 1 signalOnInterval = 3 // times 17 milliseconds signalOffInterval = 20 ] //------------------------------------- let MeasureOhms(channel) = valof //------------------------------------- // Returns resistance of channel in ohms // Returns the special value "open" if greater than 5k [ let cal5k = SampleChannel(chanCal5k) // 4990+50 ohms let cal100 = SampleChannel(chanCal100) // 100+50 ohms let cal0 = SampleChannel(chanCal0) // 0+50 ohms let unknown = SampleChannel(channel) // x+50 ohms if unknown ls cal5k then resultis open if unknown gr cal0 then resultis 0 // The calibration goes in two spans: 0 to 400 ohms, and 400 to 4990. // The first span is for unknown in [cal0-2*(cal0-cal100)..cal0], // and the second span covers the rest. let n, d, logCalRatio, delta = 0, 0, 0, 0 test unknown ge 2*cal100-cal0 ifnot [ n = unknown-cal5k d = cal100-cal5k logCalRatio = 162 // 32*lg((4990+50)/(100+50)) delta = 0 ] ifso [ n = unknown-cal100 d = cal0-cal100 logCalRatio = 51 // 32*lg((100+50)/(0+50)) delta = 162 // 32*lg((4990+50)/(100+50)) ] let an = Max(n, -n) // Abs(n) let logRatio = 2*(((logCalRatio/2)*an)/d)+ (2*(((logCalRatio/2)*an) rem d)+(logCalRatio rem 2)*an)/d // logRatio = (logCalRatio*an)/d, without overflow if n<0 then logRatio = -logRatio resultis DecodeOhms(logRatio+delta) ] //------------------------------------- and CalibrateOhms() = valof //------------------------------------- // Calibrates ohmmeter using built-in 0- // and 4990-ohm resistors. If all appears // well, returns result of measuring built-in 50-ohm // resistor. Otherwise returns an error code // that is out of range. [ let cal5k = SampleChannel(chanCal5k) let cal0 = SampleChannel(chanCal0) if cal5k ls 10 then resultis 10000 if cal0 gr 245 then resultis 10001 if cal0 le cal5k+100 then resultis 10002 resultis MeasureOhms(chanCal50) ] // --------------------------------------------------------------------------- and SampleChannel(channel) = valof // --------------------------------------------------------------------------- [ testerOut<<TesterOut.channel = channel for i = 1 to 100 do loop // 1 ms or so let dac = 128 let delta = 64 [ // repeat testerOut<<TesterOut.dac = dac @utilOut = not testerOut // output bits are inverted for i = 1 to 10 do loop // 100 microseconds or so test (@utilIn)<<TesterIn.comparator ne 0 ifso dac = dac - delta ifnot dac = dac + delta delta = delta rshift 1 ] repeatuntil delta eq 0 resultis dac ] // --------------------------------------------------------------------------- and PulseChannel(channel, time) be // --------------------------------------------------------------------------- // Sends high-frequency pulses out channel for specified time (17 ms units). // At the end, leaves channel deselected (precisely, leaves the 0-ohm // calibration channel selected instead). // This is to aid use of an external current tracer. [ testerOut<<TesterOut.dac = 128 // any constant value let endTime = ticks+time let chan = chanCal0 until ticks-endTime gr 0 & chan eq chanCal0 do [ chan = chan eq chanCal0? channel, chanCal0 testerOut<<TesterOut.channel = chan @utilOut = not testerOut // output bits are inverted ] ] // --------------------------------------------------------------------------- and Wait(time) be // --------------------------------------------------------------------------- // Busy-waits for time*17 ms. [ let endTime = ticks+time until ticks-endTime gr 0 do loop ] // --------------------------------------------------------------------------- and SignalOn(value) be // --------------------------------------------------------------------------- // Turns on or off the audible signal [ if value ne signalOn then [ signalOn = value signalTimer = 1 ] ] // --------------------------------------------------------------------------- and TesterInterrupt() be // --------------------------------------------------------------------------- [ ticks = ticks+1 if signalTimer gr 0 then [ signalTimer = signalTimer-1 if signalTimer eq 0 then test signalOn ifso [ signalState = not signalState testerOut<<TesterOut.signal = signalState signalTimer = signalState? signalOnInterval, signalOffInterval ] ifnot [ testerOut<<TesterOut.signal = false signalState = false ] @utilOut = not testerOut ] let switchState = (@utilIn)<<TesterIn.switch if switchState ne lastSwitchState then [ lastSwitchState = switchState if switchState eq 0 then CramKeyboardCharacter($*s) ] ] // --------------------------------------------------------------------------- and CramKeyboardCharacter(char) be // --------------------------------------------------------------------------- [ let newIn = OsBuffer>>OsBUF.In+1 if newIn eq OsBuffer>>OsBUF.Last then newIn = OsBuffer>>OsBUF.First if newIn ne OsBuffer>>OsBUF.Out then [ @(OsBuffer>>OsBUF.In) = char OsBuffer>>OsBUF.In = newIn ] ]