Appendix E - 82C55A PIA Data Sheet and PIA Control Code for Experts
The data sheet presented at the end of this appendix details the use of the Harris 82C55A peripheral interface adapter (PIA). The following code provides general purpose driver routines. This code may prove useful to those who wish to configure ports PPB and lower PPC for general purpose digital I/O (rather than for the keypad/display interface). For those who are adding a PIA to their custom off-board circuitry, this code can serve as a template to simplify the creation of the PIA driver routines.
For Experts: General Purpose Control Code for the PIA
The PIA has three 8-bit I/O ports which are easily configured via a single control register. The control register is referred to as PIA.CONTROL, and the I/O ports are named PPA, PPB, and PPC (Peripheral Ports A, B, and C). Once configured, the PIA's port bits may be read using C@, and outputs are controlled by setting and clearing port bits using C!, SET.BITS, and CLEAR.BITS.
The PIA can be configured to operate in any of three different modes. Only the general purpose I/O mode is discussed in this appendix. The other modes support uni-directional or bi-directional data buses with handshaking and interrupt control. For information regarding these modes, refer to the 82C55A data sheet.
Configuring the PIA Ports
Like other ports, PPA, PPB, and PPC are configured by writing to a configuration register. The PIA has only one register named PIA.CONTROL for configuring the three ports. Port PPA may be configured as either 8 digital inputs or 8 digital outputs. Likewise, Port PPB may be configured as either 8 inputs or 8 outputs. Port PPC may be all input, all output, or half input and half output. Configuring ports PPA, PPB, and PPC is accomplished by setting or clearing bits 0, 1, 3, and 4 in the PIA.CONTROL register. The table below describes the PIA.CONTROL bit settings needed to configure each port as either inputs or outputs:
PIA.CONTROL | ||
---|---|---|
PIA Port | Direction | Bit Configuration |
PPA | Input | Bit 4 set |
PPA | Output | Bit 4 clear |
PPB | Input | Bit 1 set |
PPB | Output | Bit 1 clear |
Upper 4 bits of PPC | Input | Bit 3 set |
Upper 4 bits of PPC | Output Bit 3 | clear |
Lower 4 bits of PPC | Input Bit 0 | set |
Lower 4 bits of PPC | Output Bit 0 | clear |
Observe that peripheral ports configured for input have their control bit set, and ports configured as output have their control bit cleared. The meaning assigned to these configuration bits is opposite the meaning of bits in the 68HC11 data direction registers.
To use these ports for general purpose I/O, configure PIA.CONTROL for mode 0 operation. This is accomplished by setting bit 7 and clearing bits 2, 5, and 6.
In other words, to operate the PIA as three general purpose I/O ports, the contents stored in PIA.CONTROL should be of the binary form
Bit#: 7 6 5 4 3 2 1 0 Contents: 1 0 0 x x 0 x x
where the specified 1's and 0's set the PIA for mode 0 (standard digital I/O), and the x bits configure the ports for input or output according to the table above. Configuring the PIA is accomplished by computing a configuration value according to this template and then storing it in PIA.CONTROL.
The following words simplify the computation of PIA configuration values for setting PIA.CONTROL.
HEX \ set the number base to hexadecimal 8083 REGISTER: PIA.CONTROL \ define the PIA control register \ Note that PPA, PPB, and PPC are already defined in QED-Forth 80 CONSTANT MODE.0 \ mask for configuring PIA for mode 0 10 CONSTANT PPA.INPUT \ mask for making PPA an input 02 CONSTANT PPB.INPUT \ mask for making PPB an input 08 CONSTANT UPPER.PPC.INPUT \ mask for making upper PPC input 01 CONSTANT LOWER.PPC.INPUT \ mask for making lower PPC input
Using these words to compute a PIA configuration value is as simple as using the logical OR operation to combine the input specification masks with the MODE.0 mask. For example, to configure PPA and PPB as an inputs, and PPC as all outputs, an appropriate configuration value is left on the data stack if we execute:
PPA.INPUT PPB.INPUT OR MODE.0 OR
Since PPC is specified as all outputs, its masks are not used. This is because ports are configured as outputs by the value 0, so the mask required to set up a port as output is just 0, and performing a logical OR with a 0 value does not affect the result. We just specify which ports are inputs and OR the resulting masks with the MODE.0 mask.
After computing the PIA configuration value, the ports are configured by writing to the PIA.CONTROL register. The following example configures PPA, PPB and PPC as outputs:
MODE.0 PIA.CONTROL C!
Since each port is an output, no masks are ORed with the MODE.0 mask.
To configure PPA and lower PPC as outputs, and PPB and upper PPC as inputs, execute:
MODE.0 PPB.INPUT OR UPPER.PPC.INPUT OR PIA.CONTROL C!
Port configuration diagrams in the 82C55A data sheet provide another method for computing appropriate PIA configuration values.
When a PIA configuration value is stored in PIA.CONTROL, all output bits in ports PPA, PPB and PPC are cleared, even if the value written to PIA.CONTROL is the same as its current contents. Therefore, it is best to use a static configuration for the PIA. If the external hardware can withstand temporary transients on the output signals, an alternative is to save the states of output pins before reconfiguring the PIA, and then restore the outputs after the change.
Once the PIA has been configured, PPA, PPB and PPC port bits are controlled like 68HC11F1 I/O port bits. Ports are read using the C@ command. To read PIA port PPA, we simply execute
PPA C@
and the result is left on the stack, with 1's in the bit positions corresponding to a logical HIGH voltage, and 0's in bit positions corresponding to a logical LOW voltage. Ports pins configured as outputs are set HIGH by writing a 1 to the appropriate port bit using C! or SET.BITS or assembly code. For example, if PPB is configured as all output, the following command sets the top 4 bits of PPB high without modifying the lower four bits:
HEX F0 PPB SET.BITS
Output port bits are cleared by writing a 0 to them using C! or CLEAR.BITS or assembly code operations.