#include <PiaVia.h>
Inherits RulbusDevice.
PIA and VIA offer the following interface pins.
port pin direction description A PA0..PA7 i/o level inputs and outputs A CA1 input active edge transition sets interrupt flag A CA2 i/o complex operation B PB0..PB7 i/o level inputs and outputs B CB1 input active edge transition sets interrupt flag B CB2 i/o complex operation
See Pia and Via for a more detailed description of the IC's capabilities.
The PiaVia interface contains the following groups of peripheral i/o methods:
The port-related functions allow you to read or write a complete port at one time, or to get or set its data direction.
However, if you want to act on a single line, the line-related functions are more convenient to use.
The following tables show the port names and the bit-positions for the various peripheral lines as used in the unified port-related functions and the line names and data-direction specifications for the unified line- related functions.
bit direction active edge port 7 6 5 4 3 2 1 0 line in out neg pos ------------------------------- ------------------------------- "PA" PA7 . . . . . . PA0 "PAn" 'i' 'o' "CA" CA2 CA1 "CA1" 'n' 'p' "CA2" 'i' 'o' "PB" PB7 . . . . . . PB0 "PBn" 'i' 'o' "CB" CB2 CB1 "CB1" 'n' 'p' "CB2" 'i' 'o' peripheral lines bit-positions peripheral lines data-direction for port-related functions for line-related functions (i/o and data-direction) (n: 0..7)
When setting data direction, a 0 in the bitmask makes a line input, whereas a 1 makes it an output. For CA1 and CB1, a 0 makes the input act on the negative edge, a 1 makes it sensitive to the positive, upgoing edge.
When setting output, a 0 in the bitmask makes the line level low, whereas a 1 makes it high.
When reading data-direction from port CA or CB, the CA1 and CA2 (CB1 and CB2) data-direction settings are combined as follows:
int dir = ( getDirCA2() != 'i' ) << 1 ) | getEdgeCA1() != 'n';
When reading port CA, or CB the CA1 and CA2 (CB1 and CB2) lines are combined as follows:
int data = ( getLevelCA2() << 1 ) | getIrqCA1();
So to set PB0..PB1 and CB2 to output and to set PB2..PB3 to input, you may write (pia already created):
pia.setPortDir( "PB", 0x03 ); pia.setPortDir( "CB", 0x02 );
Note that this ignores the previous data-direction setting: it also sets PB4..PB7 to input.
The following code also sets PB0..PB1 and CB2 to output and PB2..PB3 to input, but leaves the other lines unaffected.
pia.setLineDir( "PB0", 'o' ); pia.setLineDir( "PB1", 'o' ); pia.setLineDir( "CB2", 'o' ); pia.setLineDir( "PB2", 'i' ); pia.setLineDir( "PB3", 'i' );
To do the equivalent with the port-related functions you could write:
int32 dir = pia.getPortDir( "PB" ); pia.setPortDir( "PB", (dir & ~0x0F ) | 0x03 ); dir = pia.getPortDir( "CB" ); pia.setPortDir( "CB", dir | 0x02 );
With dir & ~0x0F
we first clear the bits for lines we want to define, PB0..PB3 (0x0F is 00001111 binary).
Note that for CB2 we just as well could write pia.setPortDir( "CB", 0x02 ) as before, since it is the only output-capable line of port CB (setting CB1's data-direction is silently ignored).
To address specific pins in port data, you need to use a bitmask. For example, a bitmask of 0x21
specifies pin 0 and pin 5. The mask can also be made with:
1 << 5 | 1 << 0
Having read direction or data, you use the bitmask to select the pin(s) you are interested in, for example:
char dir_pin5 = ( direction_read & (1 << 5) ) ? 'o' : 'i';
See par.cpp for an example program. It contains several bit-manipulation functions.
Public Member Functions | |
Construction | |
PiaVia (NameCref aName, Addr aAddr, Addr aWidth, Rack aRack) | |
virtual | ~PiaVia () |
destructor (empty) | |
Accessors -- generic ports | |
virtual int | getPortDir (CharCptr prt) |
get port data direction; may throw RulbusRangeError. | |
virtual int | getPortData (CharCptr ptr) |
get port data; may throw RulbusRangeError. | |
virtual char | getLineDir (CharCptr lin) |
get line direction; may throw RulbusRangeError. | |
virtual int | getLineLevel (CharCptr lin) |
get linelevel; may throw RulbusRangeError. | |
Accessors -- port A | |
virtual int | getDirPA () |
Port A: get data direction. | |
virtual int | getDataPA () |
Port A: get peripheral data. | |
virtual char | getLineDirPA (int pin) |
Port A: get peripheral line direction; may throw RulbusRangeError. | |
virtual int | getLineLevelPA (int pin) |
Port A: get peripheral line; may throw RulbusRangeError. | |
Accessors -- port B | |
virtual int | getDirPB () |
Port B: get data direction. | |
virtual int | getDataPB () |
Port B: get peripheral data. | |
virtual char | getLineDirPB (int pin) |
Port B: get peripheral line direction; may throw RulbusRangeError. | |
virtual int | getLineLevelPB (int pin) |
Port B: get peripheral line; may throw RulbusRangeError. | |
Accessors -- port CA | |
virtual int | getIrqCA1 ()=0 |
CA1 input: interrupt request pending. | |
virtual char | getEdgeCA1 ()=0 |
CA1 input: get active edge ['p','n']. | |
virtual int | getIntrCA1 ()=0 |
CA1 input: get interrupt enable state. | |
virtual char | getDirCA2 ()=0 |
CA2 i/o: get data direction ['i','o']. | |
virtual int | getLevelCA2 ()=0 |
CA2 i/o: get level [0,1]. | |
Accessors -- port CB | |
virtual int | getIrqCB1 ()=0 |
CB1 input: interrupt request pending. | |
virtual char | getEdgeCB1 ()=0 |
CB1 input: get active edge ['p','n']. | |
virtual int | getIntrCB1 ()=0 |
CB1 input: get interrupt enable state. | |
virtual char | getDirCB2 ()=0 |
CB2 i/o: get data direction ['i','o']. | |
virtual int | getLevelCB2 ()=0 |
CB2 i/o: get level [0,1]. | |
Mutators -- generic ports | |
virtual void | setPortDir (CharCptr prt, int msk) |
set port data direction; may throw RulbusRangeError. | |
virtual void | setPortData (CharCptr prt, int dat) |
set port data; may throw RulbusContextError (CA2, CB2), RulbusRangeError. | |
virtual void | setLineDir (CharCptr lin, char dir) |
set line direction; may throw RulbusRangeError. | |
virtual void | setLineLevel (CharCptr lin, int lvl) |
set specified ouput linelevel; may throw RulbusContextError, RulbusRangeError. | |
Mutators -- port A | |
virtual void | setDirPA (int msk) |
Port A: set data direction; may throw RulbusRangeError. | |
virtual void | setDataPA (int dat) |
Port A: set peripheral data; may throw RulbusRangeError. | |
virtual void | setLineDirPA (int pin, char dir) |
Port A: set peripheral line direction; may throw RulbusRangeError. | |
virtual void | setLineLevelPA (int pin, int lvl) |
Port A: set peripheral line; may throw RulbusContextError, RulbusRangeError. | |
Mutators -- port B | |
virtual void | setDirPB (int msk) |
Port B: set data direction; may throw RulbusRangeError. | |
virtual void | setDataPB (int dat) |
Port B: set peripheral data; may throw RulbusRangeError. | |
virtual void | setLineDirPB (int pin, char dir) |
Port B: set peripheral line direction; may throw RulbusRangeError. | |
virtual void | setLineLevelPB (int pin, int lvl) |
Port B: set peripheral line; may throw RulbusContextError, RulbusRangeError. | |
Mutators -- port CA | |
virtual void | setEdgeCA1 (char edge)=0 |
CA1 input: set active edge ['p','n']. | |
virtual int | setIntrCA1 (int enable)=0 |
CA1 input: enable/disable interrupt. | |
virtual void | setDirCA2 (char dir)=0 |
CA2 i/o: set data direction ['i','o']; may throw RulbusRangeError. | |
virtual void | setLevelCA2 (int lvl)=0 |
CA2 i/o: set level [0,!0]; may throw RulbusContextError. | |
Mutators -- port CB | |
virtual void | setEdgeCB1 (char edge)=0 |
CB1 input: set active edge ['p','n']; may throw RulbusRangeError. | |
virtual int | setIntrCB1 (int enable)=0 |
CB1 input: enable/disable interrupt. | |
virtual void | setDirCB2 (char dir)=0 |
CB2 i/o: set data direction ['i','o']; may throw RulbusRangeError. | |
virtual void | setLevelCB2 (int lvl)=0 |
CB2 i/o: set level [0,!0]; may throw RulbusContextError. | |
Protected Member Functions | |
Checkers | |
void | checkPin (int pin) |
check for valid pin ([0-7]; may throw RulbusRangeError | |
void | checkDir (char dir) |
check for valid dir ([iIoO]; may throw RulbusRangeError | |
void | checkData (int dat) |
check for valid data ([0-0xFF]; may throw RulbusRangeError | |
void | checkMask (int msk) |
check for valid mask ([0-0xFF]; may throw RulbusRangeError | |
Accessors -- port A, B | |
virtual int | getDDRA ()=0 |
Port A: get data direction register. | |
virtual int | getPDRA ()=0 |
Port A: get peripheral data register. | |
virtual int | getDDRB ()=0 |
Port B: get data direction register. | |
virtual int | getPDRB ()=0 |
Port B: get peripheral data register. | |
Mutators -- port A, B | |
virtual void | setDDRA (int dir)=0 |
Port A: set data directionregister. | |
virtual void | setPDRA (int dat)=0 |
Port A: set peripheral data register. | |
virtual void | setDDRB (int dir)=0 |
Port B: set data direction register. | |
virtual void | setPDRB (int dat)=0 |
Port B: set peripheral data register. |