DEFINITION MODULE AnalogueIO; (********************************************************) (* *) (* Analogue Input and Output. *) (* *) (* Programmer: P. Moylan *) (* Last edited: 13 February 1991 *) (* Status: Working, more tests desirable. *) (* *) (********************************************************) (************************************************************************) (* *) (* This module supports the RTI-800/815 Multifunction Input/Output *) (* Board. (RTI is a trademark of Analog Devices). The board has one *) (* 8-bit digital output port, one 8-bit digital input port, and between *) (* 8 and 32 channels (depending on hardware options) of analogue input. *) (* The RTI-815 version has also two channels of analogue output. The *) (* A/D and D/A converters are 12-bit devices. *) (* *) (* Details such as whether the analogue signals are unipolar or bipolar *) (* are controlled by hardware jumpers, and not by software, except for *) (* a choice of a 1/10/100/500 gain on analogue input. It is the user's *) (* responsibility to know what this means in terms of actual voltages; *) (* the software has no way of knowing which hardware options have been *) (* selected. *) (* *) (* The board also contains an AM9513A Counter/Timer chip (a product of *) (* Advanced Micro Devices Inc.) which supplies 5 16-bit counters along *) (* with the support logic to use them in many different ways for *) (* various counting and timing applications. This module reserves the *) (* use of counters 4 and 5 for its own internal purposes, as a timing *) (* source to control the A/D sampling rate. (The output of timer 5 is *) (* connected, on the RTI-800/815 board, to the gate input of timer 4, *) (* and the output of timer 4 triggers an A/D conversion). The first *) (* three timers are not used by this module, and are free to be used *) (* for any other purpose which does not interfere with timers 4 and 5. *) (* (NOTE: the first three timers are called timers 1-3 in the AM9513A *) (* data sheets, but are called timers 0-2 in the RTI-800/815 manual). *) (* Because of the great variety of operating options for the timers, *) (* and the impossibility of predicting what the user will want to do *) (* with them, this module does not attempt to provide any support *) (* software for using timers 1-3. *) (* *) (************************************************************************) FROM SYSTEM IMPORT (* type *) BYTE, WORD; TYPE GainCode = [0..3]; (* The gain code for the A/D converter has the interpretation: *) (* 0 gain=1 range -10 V to +10 V *) (* 1 gain=10 range -1 V to +1 V *) (* 2 gain=100 range -100 mV to +100 mV *) (* 3 gain=500 range -20 mV to +20 mV *) (* The ranges are those applicable when the board is jumpered for *) (* 10V bipolar operation. The modifications for the unipolar and *) (* 5V bipolar cases should be obvious. *) OutputChannelNumber = [0..1]; InputChannelNumber = [0..31]; (************************************************************************) (* DIGITAL I/O *) (************************************************************************) PROCEDURE DigitalOut (value: BYTE); (* Sends the given value to the digital output port of the board. *) PROCEDURE DigitalInput (): BYTE; (* Reads the digital input port of the board. *) (************************************************************************) (* ANALOGUE OUTPUT (RTI-815 ONLY) *) (************************************************************************) PROCEDURE AnalogueOut (channel: OutputChannelNumber; value: WORD); (* Analogue output. The channel number should be 0 or 1. Only the *) (* least significant 12 bits of the value are used. The value can *) (* be treated as either a signed or an unsigned 12-bit number, *) (* depending on hardware jumper selections. *) (************************************************************************) (* ANALOGUE INPUT - SINGLE SAMPLE *) (************************************************************************) PROCEDURE AnalogueInput (channel: InputChannelNumber; gain: GainCode): WORD; (* Analogue input. The value returned can be a signed or unsigned *) (* number, depending on jumper selections on the board. *) (* This procedure picks up a single sample when called. It does *) (* not use interrupts or DMA. It is recommended for use only in *) (* those cases (e.g. isolated sample, or aperiodic sampling) where *) (* the caller takes responsibility for timing. More commonly, the *) (* procedures in the following section will be more appropriate. *) (* This procedure should NOT be called when periodic sampling has *) (* been activated; the results would be unpredictable. *) (************************************************************************) (* ANALOGUE INPUT - PERIODIC SAMPLING *) (************************************************************************) PROCEDURE StartPeriodicSampling (first, last: InputChannelNumber; SamplingInterval: LONGCARD; AmplifierGain: GainCode; VAR (*OUT*) Buffer: ARRAY OF BYTE); (* Initiates a mode of operation in which channels first..last, *) (* inclusive, will be sampled every SamplingInterval microseconds, *) (* with the results stored in array Buffer. At each sampling time, *) (* the specified channels are read as nearly simultaneously as the *) (* hardware will allow. Procedure WaitForNextSample, below, should *) (* be called to check when the data are available in array Buffer. *) (* If WaitForNextSample is not called often enough, there can be a *) (* data overrun in which data are overwritten. We do not signal *) (* this as an error since the only thing which can be done about it *) (* is to use the new data and ignore whatever data have been lost. *) (* WARNING: Although the sampling interval is specified in *) (* microseconds, to allow fine tuning of the interval if desired, *) (* it is in general impractical to specify an interval shorter than *) (* about one or two milliseconds, because of software overheads. *) (* The precise limit depends on how much computation is done per *) (* sample, what other high-priority tasks are in the system, and so *) (* on. It is advisable to test the system for evidence of data *) (* overrun, for example by looking at analogue inputs and outputs *) (* with a CRO, and to increase the sampling interval if there *) (* appear to be problems. *) PROCEDURE WaitForNextSample; (* Pauses until the buffer specified in the preceding procedure has *) (* been filled with valid data. Notice that this is essentially a *) (* synchronization procedure; the caller does not have to do any *) (* timing operations since a return from this procedure implies *) (* that the next sample time has arrived. *) (* WARNINGS: *) (* 1. This procedure should not be called unless periodic sampling *) (* is currently in effect. Otherwise, it might never return. *) (* 2. Periodic sampling implies that the data buffer is re-filled *) (* regularly, regardless of whether the user code has finished *) (* with the previous data. There are no interlocks, and no *) (* protection against data being updated just as one is reading *) (* it. (Any such protection could interfere with the precision *) (* of the timing of sampling external data). The caller is *) (* advised to move data out of the buffer promptly, especially *) (* when the sampling rate is high. *) PROCEDURE StopPeriodicSampling; (* Turns off the periodic sampling mode of A/D conversion. *) END AnalogueIO.