OPERATIONS MANUAL
PCM-UIO96A
WinSystems reserves the right to make changes in the circuitry
and specifications at any time without notice.
© Copyright 1999 by WinSystems. All rights Reserved.
WinSystems - "The Embedded Systems Authority"
REVISION HISTORY
P/N 403-0285-000
ECO Number
ORIGINATED
99-95
02-76
03-31
Date Code
990818
991104
021203
030410
Revision
A
A1
A2
A3
TABLE OF CONTENTS
Section
Number
Paragraph Title
Page
Number
1
General Information
1-1
1.1
1.2
1.3
Features
General Description
Specifications
1-1
1-1
1-2
2
PCM-UIO96A Technical Reference
2.1
2.2
2.3
2.4
2.5
2.6
2.7
Introduction
I/O Address Selection
Interrupt Routing Selection
I/O Connector Pinout
PC/104 Bus Interface
WS16C48 Register Definitions
Connector/Jumper Summary
3
PCM-UIO96A Programming Reference
3.1
3.2
3.3
Introduction
Function Definitions
Sample Programs
APPENDIX A
PCM-UIO96A Parts Placement Guide
APPENDIX B
PCM-UIO96A Parts List
APPENDIX C
I/O Routine & Sample Program Source Listings
APPENDIX D
PCM-UIO96A Schematic Diagrams
2-1
2-1
2-2
2-3
2-4
2-5
2-6
3-1
3-1
3-5
1
GENERAL INFORMATION
1.1
FEATURES
n
n
n
n
n
n
n
n
1.2
96 Digital I/O Lines
PC/104 16-bit interface
Each line can serve as an input or an output
Readback capability on all output lines
Programmable polarity event sense on 48 lines
Compatible with standard I/O racks
+5 Volt only operation
Extended temperature range -40°C to +85°C
GENERAL DESCRIPTION
The PCM-UIO96A is a highly versatile PC/104 module providing 96 lines of digital I/O. It is
unique in its ability to monitor 48 lines for both rising and falling digital edge transitions, latch them,
and then issue an interrupt to the host processor. The application interrupt service routine can quickly
determine, through a series of interrupt identification registers, the exact port(s) and bit(s) which have
transitioned. The PCM-UIO96A utilizes the WinSystems' WS16C48 ASIC High Density I/O Chip
(HDIO). The first 48 lines are capable of fully latched event sensing with the sense polarity being
software programmable. Four 50-pin I/O connectors allow for easy mating with industry standard I/O
racks.
030410
OPERATIONS MANUAL PCM-UIO96A
Page 1 - 1
WinSystems - "The Embedded Systems Authority"
1.3
SPECIFICATIONS
1.3.1
Electrical
Bus Interface :
PC/104 16-Bit
VCC :
+5V +/-5% @ 24mA typical with no I/O connections.
I/O Addressing :
12-bit user jumperable base address. Each board uses 32 consecutive
addresses
1.3.2
Mechanical
Dimensions :
3.6" X 3.8"
PC Board :
FR-4 Epoxy glass with 2 signal layers, 2 power planes, screened component
legend, and plated through holes.
Jumpers :
0.025" square posts on 0.100" centers
Connectors :
50 Pin 0.10" grid RN type IDH-50-LP
1.3.3
Environmental
Operating Temperature:
-40°C to +85° C
Non Condensing Humidity : 5% to 95%
Page 1 - 2
OPERATIONS MANUAL PCM-UIO96A
030410
2
PCM-UIO96A TECHNICAL REFERENCE
2.1
Introduction
This section of the manual is intended to provide the necessary information regarding configuration
and usage of the PCM-UIO96A. WinSystems maintains a Technical Support Group to help answer
questions regarding configuration, usage, or programming of the board. For answers to questions not
adequately addressed in this manual, contact Technical Support at (817) 274-7553 between 8AM and
5PM Central Time.
2.2
I/O Address Selection
I/O Address Select Jumper J5
J5
1o o2
3o o4
5o o6
7o o8
9 o o 10
11 o o 12
13 o o 14
15 o o 16
The PCM-UIO96A requires 32 consecutive I/O addresses beginning on a 32 byte boundary. The
jumper block at J5 allows for user selection of the base address. Address selection is made by placing a
jumper on the jumper pair for the address bit if a '0' is desired or leaving the address bit open if a '1' is
required for the desired address. U2 is located at the Base Address, U1 is located at the Base Address
plus ten Hex. The illustration below shows the relationship between the address bit and the jumper
positions and a sample jumpering for a base address of 200H.
I/O Base Address Select Jumper
J5 shown jumpered for 200H
030410
J5
1o
3o
5o
7o
9o
11 o
13 o
15 o
o 2
o 4
o 6
o 8
o10
o12
o14
o16
A5
A6
A7
A8
A9
A10
A11
A12
OPERATIONS MANUAL PCM-UIO96A
Page 2 - 1
WinSystems - "The Embedded Systems Authority"
2.3
Interrupt Routing Selection
U1
Interrupt routing jumpers J6 and J7
U2
J7
J6
Side A
1o
2o
Side B
2.3.1
1
o
o
o
1
2
o
o
o
2
3
o
o
o
3
4
o
o
o
4
5
o
o
o
5
6
o
o
o
6
7
o
o
o
7
8
o
o
o
8
9
o
o
o
9
Shared Interrupts
For shared interrupts on the PC/104 bus, J6 must be jumpered pins 1-2. For individual interrupts, J6
should remain unjumpered as shown below.
J6
J6
1o
2o
1o
2o
Individual
Shared
2.3.2
Interrupt Selection
When desired the PCM-UIO96A can generate an interrupt on up to 48 different lines each with its
own polarity select. This interrupt can be routed to the PC/104 bus via the jumper at J7. J7 is a three row
eleven pin interrupt routing block, side A directs interrupts to connector J4, side B directs interrupts to
connector J1, the center row connects directly to the PC/104 Bus interrupt inputs.
B J7
Side B : U1
(J1, or the base address plus 16)
1
2
3
4
5
6
7
8
9
10
11
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
J7 A
IRQ2
IRQ10
IRQ11
IRQ12
IRQ15
IRQ14
IRQ7
IRQ6
IRQ5
IRQ4
IRQ3
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o1
o2
o3
o4
o5
o6
o7
o8
o9
o 10
o 11
Side A : U2
(J4, or the base address)
The center row connects directly to
the PC/104 bus interrupt inputs
Page 2 - 2
OPERATIONS MANUAL PCM-UIO96A
030410
10
o
o
o
10
11
o
o
o
11
WinSystems - "The Embedded Systems Authority"
2.4
I/O Connector Pinout
The PCM-UIO96A routes its 96 lines to four 50-pin IDC connectors at J1, J2, J3, and J4. The pin
definitions for J1, J2, J3, and J4 are shown here :
U1
U2
J4
P2-7
P2-6
P2-5
P2-4
P2-3
P2-2
P2-1
P2-0
P1-7
P1-6
P1-5
P1-4
P1-3
P1-2
P1-1
P1-0
P0-7
P0-6
P0-5
P0-4
P0-3
P0-2
P0-1
P0-0
+5V
1
3
5
7
9
11
13
15
17
19
21
23
25
27
29
31
33
35
37
39
41
43
45
47
49
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
2
4
6
8
10
12
14
16
18
20
22
24
26
28
30
32
34
36
38
40
42
44
46
48
50
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
P5-7
P5-6
P5-5
P5-4
P5-3
P5-2
P5-1
P5-0
P4-7
P4-6
P4-5
P4-4
P4-3
P4-2
P4-1
P4-0
P3-7
P3-6
P3-5
P3-4
P3-3
P3-2
P3-1
P3-0
+5V
1
3
5
7
9
11
13
15
17
19
21
23
25
27
29
31
33
35
37
39
41
43
45
47
49
J3
o o
o o
o o
o o
o o
o o
o o
o o
o o
o o
o o
o o
o o
o o
o o
o o
o o
o o
o o
o o
o o
o o
o o
o o
o o
J1
J2
2
4
6
8
10
12
14
16
18
20
22
24
26
28
30
32
34
36
38
40
42
44
46
48
50
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
P5-7
P5-6
P5-5
P5-4
P5-3
P5-2
P5-1
P5-0
P4-7
P4-6
P4-5
P4-4
P4-3
P4-2
P4-1
P4-0
P3-7
P3-6
P3-5
P3-4
P3-3
P3-2
P3-1
P3-0
+5V
1
3
5
7
9
11
13
15
17
19
21
23
25
27
29
31
33
35
37
39
41
43
45
47
49
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
2
4
6
8
10
12
14
16
18
20
22
24
26
28
30
32
34
36
38
40
42
44
46
48
50
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
P2-7
P2-6
P2-5
P2-4
P2-3
P2-2
P2-1
P2-0
P1-7
P1-6
P1-5
P1-4
P1-3
P1-2
P1-1
P1-0
P0-7
P0-6
P0-5
P0-4
P0-3
P0-2
P0-1
P0-0
+5V
1
3
5
7
9
11
13
15
17
19
21
23
25
27
29
31
33
35
37
39
41
43
45
47
49
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
2
4
6
8
10
12
14
16
18
20
22
24
26
28
30
32
34
36
38
40
42
44
46
48
50
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
GND
NOTE : Pin 49 on each connector can supply +5V to the I/O rack. The supply on each connector is
protected from excessive current by a 1A miniature fuse F1 for J1 and J2, F2 for J3 and J4.
030410
OPERATIONS MANUAL PCM-UIO96A
Page 2 - 3
WinSystems - "The Embedded Systems Authority"
2.5
PC/104 Bus Interface
The PCM-UIO96A connects to the processor through the PC/104 bus connector at J8 and J9. The
pin definitions for the J8 and J9 connectors are shown here for reference :
J8
GND
RESET
+5V
IRQ9
-5V
DRQ2
-12V
0WS
+12V
GND
MEMW*
MEMR*
IOW*
IOR*
DACK3*
DRQ3
DACK1*
DRQ1
REFRESH*
SYSCLK
IRQ7
IRQ6
IRQ5
IRQ4
IRQ3
DACK2*
TC
BALE
+5V
OSC
GND
GND
Page 2 - 4
B1 o
B2 o
B3 o
B4 o
B5 o
B6 o
B7 o
B8 o
B9 o
B10 o
B11 o
B12 o
B13 o
B14 o
B15 o
B16 o
B17 o
B18 o
B19 o
B20 o
B21 o
B22 o
B23 o
B24 o
B25 o
B26 o
B27 o
B28 o
B29 o
B30 o
B31 o
B32 o
J9
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
A1
A2
A3
A4
A5
A6
A7
A8
A9
A10
A11
A12
A13
A14
A15
A16
A17
A18
A19
A20
A21
A22
A23
A24
A25
A26
A27
A28
A29
A30
A31
A32
IOCHK*
BD7
BD6
BD5
BD4
BD3
BD2
BD1
BD0
IOCHRDY
AEN
SA19
SA18
SA17
SA16
SA15
SA14
SA13
SA12
SA11
SA10
SA9
SA8
SA7
SA6
SA5
SA4
SA3
SA2
SA1
SA0
GND
GND
SBHE
LA23
LA22
LA21
LA20
LA19
LA18
LA17
MEMR*
MEMW*
SD8
SD9
SD10
SD11
SD12
SD13
SD14
SD15
KEY
OPERATIONS MANUAL PCM-UIO96A
C0
C1
C2
C3
C4
C5
C6
C7
C8
C9
C10
C11
C12
C13
C14
C15
C16
C17
C18
C19
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
D0
D1
D2
D3
D4
D5
D6
D7
D8
D9
D10
D11
D12
D13
D14
D15
D16
D17
D18
D19
GND
MEMCS16*
IOCS16*
IRQ10
IRQ11
IRQ12
IRQ15
IRQ14
DACK0*
DRQ0
DACK5*
DRQ5
DACK6*
DRQ6
DACK7*
DRQ7
VCC
MASTER*
GND
GND
030410
WinSystems - "The Embedded Systems Authority"
2.6
WS16C48 Register Definitions
The PCM-UIO96A uses two of the WinSystems' exclusive ASIC device, the WS16C48. This
device provides 96 lines of digital I/O. There are 17 unique registers within each WS16C48. The
following table summarizes the registers and the text that follows provides details on each of the
internal registers.
I/O Address
Page 0
Page 1
Page 2
Page 3
Offset
00H
Port 0 I/O
Port 0 I/O
Port 0 I/O
Port 0 I/O
01H
Port 1 I/O
Port 1 I/O
Port 1 I/O
Port 1 I/O
02H
Port 2 I/O
Port 2 I/O
Port 2 I/O
Port 2 I/O
03H
Port 3 I/O
Port 3 I/O
Port 3 I/O
Port 3 I/O
04H
Port 4 I/O
Port 4 I/O
Port 4 I/O
Port 4 I/O
05H
Port 5 I/O
Port 5 I/O
Port 5 I/O
Port 5 I/O
06H
INT_PENDING INT_PENDING INT_PENDING INT_PENDING
07H
Page/Lock
Page/Lock
Page/Lock
Page/Lock
08H
N/A
POL_0
ENAB_0
INT_ID0
09H
N/A
POL_1
ENAB_1
INT_ID1
0AH
N/A
POL_2
ENAB_2
INT_ID2
Register Details
Port 0-5 I/O - Each I/O bit in each of these 6 ports can be individually programmed for input or
output. Writing a '0' to a bit position causes the corresponding output pin to go to a High Impedance
state (pulled high by external 10K ohm resistors). This allows it to be used as an input. When used in the
input mode, a read reflects the inverted state of the I/O pin, such that a high on the pin will read as a '0' in
the register. Writing a '1' to a bit position causes the output pin to sink current (up to 12mA), effectively
pulling it low.
INT_PENDING - This read only register reflects the combined state of the INT_ID0 through
INT_ID2 registers. When any of the lower 3 bits are set, it indicates that an interrupt is pending on the
I/O port corresponding to the bit position(s) that are set. Reading this register allows an Interrupt
Service Routine to quickly determine if any interrupts are pending and which I/O port has an interrupt
pending.
PAGE/LOCK - This register serves two purposes. The upper two bits select the register page in use
as shown here :
D7 D6
0
0
1
1
030410
0
1
0
1
Page
Page 0
Page 1
Page 2
Page 3
OPERATIONS MANUAL PCM-UIO96A
Page 2 - 5
WinSystems - "The Embedded Systems Authority"
Bits 5-0 allow for locking of the I/O ports. A '1' written to the I/O port position will prohibit further
writes to the corresponding I/O port.
POL0 - POL3 - These registers are accessible when page 1 is selected. They allow interrupt
polarity selection on a port-by-port and bit-by-bit basis. Writing a '1' to a bit position selects rising edge
detection interrupts while writing a '0' to a bit position selects falling edge detection interrupts.
ENAB0 - ENAB3 - These registers are accessible when page 2 is selected. They allow for port-byport and bit-by-bit enabling of the edge detection interrupts. When set to a '1' the edge detection
interrupt is enabled for the corresponding port and bit. When cleared to a '0' the bit's edge detection
interrupt is disabled. Note that this register can be used to individually clear a pending interrupt by
disabling and reenabling the pending interrupt.
INT_ID0 - INT_ID2 - These registers are accessible when page 3 is selected. They are used to
identify currently pending edge interrupts. A bit when read as a '1' indicates that an edge of the polarity
programmed into the corresponding polarity register has been recognized. Note that a write to this
register (value ignored) clears ALL of the pending interrupts in this register.
2.7
Connector/Jumper Summary
Connector/
Jumper
Purpose
Page Reference
J1
J2
J3
J4
J5
J6
J7
J8
J9
Ports 0-2 I/O connector
Ports 3-5 I/O connector
Ports 9-11 I/O connector
Ports 6-8 I/O connector
Base I/O Address select jumper
Shared interrupt select jumper
Interrupt routing jumper
PC/104-8 bus connector
PC/104-16 bus connector
2-3
2-3
2-3
2-3
2-1
2-2
2-2
2-4
2-4
Page 2 - 6
OPERATIONS MANUAL PCM-UIO96A
030410
3
PCM-UIO96A Programming Reference
3.1
Introduction
This section provides basic documentation for the included I/O routines. It is intended that the
accompanying source code equip the programmer with a basic library of I/O functions for the PCMUIO96A or can serve as the basis from which application-specific code can be derived.
The sample I/O routines and sample programs were compiled and tested using the Borland C/C++
compiler Version 3.1. The routines should readily port to any compiler supporting basic port I/O
instructions.
These routines handle each WS16C48 as a separate “Chip Number”. The PCM-UIO96A has two
chips 1 and 2.
3.2
Function Definitions
This section briefly describes each of the functions contained in the driver. Where necessary, short
examples will be provided to illustrate usage. Any application making use of any of the driver functions
should include the header file “uio96.h”, which includes the function prototypes and the needed
constant definitions.
Note that all of the functions utilize the concept of a “bit_number”. The “bit_number” is a value
from 1 to 48 (1 to 24 for interrupt related functions) that correlates to a specific I/O pin. Bit_number 1 is
port 0 bit 0, and continues though to bit_number 48 at port 5 bit 7.
INIT_IO - Initialize I/O, set all ports to input
Syntax
void init_io(int chip_number, unsigned io_address);
Description
This function takes two arguments :
chip_number - the chip number 1 - 4
io_address - the I/O address of the WS16C48 chip.
030410
OPERATIONS MANUAL PCM-UIO96A
Page 3 - 1
WinSystems - "The Embedded Systems Authority"
There is no return value. This function initializes all I/O pins for input (sets them high), disables all
interrupt sensing, and sets the image values.
READ_BIT - Reads an I/O port Bit
Syntax
int read_bit(int chip_number, int bit_number);
Description
This function takes two arguments :
chip_number - The chip number 1- 4
bit_number - This is a value from 1 to 48 that indicates the I/O pin to read from.
This function returns the state of the I/O pin. A '1' is returned if the I/O pin is low and a '0' is returned
if the pin is high.
WRITE_BIT - Write a 1 or 0 to an I/O pin
Syntax
void write_bit(int chip_number, int bit_number, int value);
Description
This function takes three arguments
chip_number - The chip number 1 to 4
bit_number - This is a value from 1 to 48, which is the bit to be acted upon.
value - is either 1 or 0.
This function allows for the writing of a single bit to either a '0' or a '1' as specified by the third
argument. There is no return value and other bits in the I/O port are not affected.
SET_BIT - Set the specified I/O Bit
Syntax
void set_bit(int chip_number, int bit_number);
Page 3 - 2
OPERATIONS MANUAL PCM-UIO96A
030410
WinSystems - "The Embedded Systems Authority"
Description
This function takes a two arguments :
chip_number - The chip number 1 - 4
bit_number - a value between 1 and 48 specifying the port bit to set.
This function sets the specified I/O port bit. Note that setting a bit results in the I/O pin actually
going low. There is no return value and other bits in the same I/O port are unaffected.
CLR_BIT - Clear the specified I/O Bit
Syntax
void clr_bit(int chip_number, int bit_number);
Description
This function takes a two arguments :
chip_number - The chip number 1 - 4
bit_number
- This value from 1 to 48 indicates the bit number to clear.
This function clears the specified I/O bit. Note that clearing the I/O bit results in the actual I/O pin
going high. This function does not affect any bits other than the one specified.
ENAB_INT - Enable Edge Interrupt, select polarity
Syntax
void enab_int(int chip_number, int bit_number, int polarity);
Description
This function requires three arguments
chip_number - The chip number 1 - 4
bit_number - A value from 1 to 24 specifying the appropriate bit.
polarity - Specifies rising or falling edge polarity detect. The constants RISING and FALLING are
defined in “uio96.h”
030410
OPERATIONS MANUAL PCM-UIO96A
Page 3 - 3
WinSystems - "The Embedded Systems Authority"
This function enables the edge detection circuitry for the specified bit at the specified polarity. It
does not unmask the interrupt controller, install vectors, or handle interrupts when they occur. There is
no return value and only the specified bit is affected.
DISAB_INT - Disable Edge Detect Interrupt Detection
Syntax
void disab_int(int chip_number, int bit_number);
Description
This function requires a two arguments
chip_number - The chip number 1 - 4
bit_number -
A value from 1 to 24 specifying the appropriate bit.
This function shuts down the edge detection interrupts for the specified bit. There is no return value
and no harm is done by calling this function for a bit which did not have edge detection interrupts
enabled. There is no affect on any other bits.
CLR_INT - Clear the specified pending interrupt
Syntax
void clr_int(int chip_number, bit_number);
Description
This function requires a two arguments :
chip_number - The chip number 1 - 4
bit_number - The specified the bit number from 1 to 24 to reset the interrupt.
This function clears a pending interrupt on the specified bit. It does this by disabling and re-enabling
the interrupt. The net result after the call is that the interrupt is no longer pending and is rearmed for the
next transition of the same polarity. Calling this function on a bit that has not been enabled for interrupts
will result in its interrupt being enabled with an undefined polarity. Calling this function with no
interrupt currently pending will have no adverse affect. Only the specified bit is affected.
Page 3 - 4
OPERATIONS MANUAL PCM-UIO96A
030410
WinSystems - "The Embedded Systems Authority"
GET_INT - Retrieve bit number of pending interrupt
Syntax
int get_int(int chip_number);
Description
This function requires no arguments and returns either a '0' for no bit interrupts pending or a value
between 1 and 24 representing a bit number that has a pending edge detect interrupt. The routine returns
with the first interrupt found and begins its search at port 0 bit 0 proceeding through to port 2 bit 7. It is
necessary to use either clr_int() or disab_int() to avoid returning the same bit number continuously.
This function may either be used in an application's ISR or can be used in the foreground to poll for bit
transitions.
3.3
SAMPLE PROGRAMS
There are three sample programs in source code form included on the PCM-UIO96A diskette.
These programs are not useful by themselves but are provided to illustrate the usage of the I/O functions
provided in UIO96.C.
FLASH.C
This program was compiled with Borland C/C++ version 3.1 on the command line with :
bcc flash.c uio96.c
This program illustrates the most basic usage of the PCM-UIO96A board. It uses three functions
from the driver code. The init_io() function is used to initialize the I/O functions and the set_bit() and
clr_bit() functions are used to sequence through all 96 bits turning each on and then off in turn.
POLL.C
This program was compiled with Borland C/C++ version 3.1 on the command line with :
bcc poll.c uio96.c
This program illustrates additional features of the WS16C48 and the I/O library functions. It
programs the first 24 bits for input on each chip, arms them for falling edge detection and then polls the
I/O routine get_int() to determine if any transitions have taken place.
030410
OPERATIONS MANUAL PCM-UIO96A
Page 3 - 5
WinSystems - "The Embedded Systems Authority"
INT.C
This program was compiled and with Borland C/C++ version 3.1 on the command line with :
bcc int.c uio96.c
This program is identical in function to the “poll.c” program except that interrupts are active and all
updating of the transition counters is accomplished in the background during the interrupt service
routine.
Summary
The source code for all three sample programs, as well as the I/O routines, are included on the
accompanying diskette. The source code is also provided in printed form in Appendix C. These I/O
routines along with the sample programs should provide a good basis on which to build an application
utilizing the features of the PCM-UIO96A.
Page 3 - 6
OPERATIONS MANUAL PCM-UIO96A
030410
4
APPENDIX A
PCM-UIO96A Parts Placement Guide
5
APPENDIX B
PCM-UIO96A Parts List
08/18/99
Parts List
PAGE
1
13:29:23
WinSystems, Inc.
BEGINNING RANGE: PCM-UIO96A-16
ENDING RANGE: PCM-UIO96A-16
====================================================================================================================================
ITEM
BOM
OVHD ITEM
QTY
LEVEL ITEM KEY
DESCRIPTION
DESCRIPTION
LOC
KEY TYPE
REQUIRED
====================================================================================================================================
1 PCM-UIO96A-16
2
999-9999-001
2
0285-000-0000A
3
>999-9999-001
3
>603-1047-803
3
>603-1065-82D
3
>601-0102-503
3
>650-0084-002
3
>400-0285-000A
2
0285-001-0000A
3
>999-9999-001
3
>603-1047-803
3
>602-0103-512
3
>601-0103-503
3
>612-0688-002
3
>612-0004-001
3
>612-0032-001
2
0285-002-0000A
3
>999-9999-001
3
>999-9999-001
3
>501-0008-000
3
>201-0050-121
3
>201-0050-021
3
>201-0072-120
3
>999-9999-001
3
>201-0036-010
3
>999-9999-001
3
>200-0040-100
3
>200-0064-100
2
0285-100-0000A
3
>999-9999-001
3
>999-9999-001
3
>905-0030-000
3
>201-0002-000
3
>999-9999-001
3
>999-9999-001
2
KIT-PCM-STANDOFF-2
3
>999-9999-001
3
>500-0200-091
3
>500-0200-033
3
>500-0200-092
3
>525-0304-001
2
910-0024-000
2
950-0001-000
0
0
PC/104, 16-BIT, UNIVERSAL 96 LINE
SPECIAL NOTES
07-07-99 MEB (REV.A)
ASSY TOP SMT, PCM-UIO96A REV.A
SPECIAL NOTES
07-06-99 MEB (REV A)
CAP .1uF 50v 20% CER 0805
C1-C7,C9
CAP 10uF 25v 20% TAN 6032
C8
RES 1K Ohm 5% 1/10W 0805
R1,R2
SOCKET, 84 POSITION PLCC 213-08 U1,U2
PCB, PCM-UI096A REV 'A'
ASSY BOT SMT, PCM-UIO96A REV.A
SPECIAL NOTES
07-06-99 MEB (REV A)
CAP .1uF 50v 20% CER 0805
C10,C11,C12
RN 10K Oh, 5%, 2506/16 pin, Bus RP1
RES 10K Ohm 5% 1/10W 0805
R3-R98
IC, 74HCT688AF (SM)
U3
IC, 74HCT04
U4
IC, 74HCT32
U5
ASSY THRU HOLE, PCM-UIO96A REV.
SPECIAL NOTES
08-02-99 MEB(ECBOM,JUMPERS)
SPECIAL NOTES
07-06-99 MEB (REV A)
FUSE PC 1A MOUSER 504-MCR-1
F1,F2
HEADER RA 2X25 IDH50LP-SR3-TR/TG J1,J4
HDR 2X25 ST PRO IDH50LP-S3-TG/TR J2,J3
HDR 2X36 UN TSW-136-07-G-D
J5=2X8
SPECIAL NOTES
J7=2X11
HDR 1X36 UN TSW-136-07-G-S (SAM) J6=1X2
SPECIAL NOTES
J7B=1X11
SCKT 40 POS STK QPHF2-40-020-1Z J9
SCKT 64 POS STK QPHF2-64-020-1Z J8
SUB ASSY, PCM-UIO96A REV.A
SPECIAL NOTES
08-12-99 MEB (ECBOM,JUMPERS)
SPECIAL NOTES
07-06-99 MEB (REV A)
IC, UD27-PL84-M3B:D
U1,U2
PLUG JUMPER 999-19-310-00
*TEST JUMPERS:
SPECIAL NOTES
J7=9A,7B
SPECIAL NOTES
J5=1-2 5-6 7-8 11-12 13-14 15-16
PC/104 STANDOFF KIT CONSISTING O
SPECIAL NOTES
04-28-95 MEB (NEW BOM)
SPACER M/F RAF 4000-440-N-MODL.6 SPACER M/F RAF 4000-440-N-MODL.600
SCREW PPH 4-40 X 1/4"
SCREW PPH 4-40 X 1/4"
NUT HEX NYLON 4-40
NUT HEX NYLON 4-40
SIZE 3 COIN ENVLPE 2.5" X 4.25" SIZE 3 COIN ENVELOPE 2 1/2 X 4 1/4
LABEL, STATIC SENSITIVE 130-02
BAG STATIC BARRIER 07-0610 6X10
WARNING(S)
ERROR(S)
ARLIN
ARLIN
ARLIN
ARLIN
ARLIN
ARLIN
ARLIN
ARLIN
ARLIN
ARLIN
ARLIN
ARLIN
ARLIN
ARLIN
ARLIN
ARLIN
ARLIN
ARLIN
ARLIN
ARLIN
ARLIN
ARLIN
ARLIN
ARLIN
ARLIN
ARLIN
ARLIN
ARLIN
ARLIN
ARLIN
ARLIN
ARLIN
ARLIN
ARLIN
ARLIN
ARLIN
ARLIN
ARLIN
ARLIN
ARLIN
ARLIN
ARLIN
ARLIN
1
1
1
1
8
1
2
2
1
1
1
3
1
96
1
1
1
1
1
1
2
2
2
.53
1
.37
1
1
1
1
1
1
2
8
1
1
1
1
2
2
2
1
1
1
Inv
Inv
Inv
Inv
Inv
Inv
Inv
Inv
Inv
Inv
Inv
Inv
Inv
Inv
Inv
Inv
Inv
Inv
Inv
Inv
Inv
Inv
Inv
Inv
Inv
Inv
Inv
Inv
Inv
Inv
Inv
Inv
Inv
Inv
Inv
Inv
Inv
Inv
Inv
Inv
Inv
Inv
Inv
* Indicates no BOM Found for Item
REPORT PARAMETERS
----------------ASSEMBLY
RANGE
TYPE
: PCM-UIO96A-16
: RWF
to
PCM-UIO96A-16
COMPONENT
RANGE
TYPE
: <FIRST>
: RWF
to
<LAST>
MASKING
DESC LENGTH: ITEM
:
COMMENT :
LOCATION:
OVERHEAD:
32
40
0
0
NESTING INDENT LENGTH:
20
: Inv-Explode Specific Inv Items (No Masks)
TOTAL REPORT WIDTH
QUANTITY (TO EXPLODE): 1
:
132
6
APPENDIX C
I/O Routine & Sample Program Source Listings
/* FLASH.C
Copyright 1999 by WinSystems Inc.
Permission is hereby granted to the purchaser of the WinSystems
UIO cards and CPU products incorporating the UIO device, to distribute
any binary file or files compiled using this source code directly or
in any work derived by the user from this file. In no case may the
source code, original or derived from this file, be distributed to any
third party except by explicit permission of WinSystems. This file is
distributed on an "As-is" basis and no warranty as to performance,
fitness of purposes, or any other warranty is expressed or implied.
In no case shall WinSystems be liable for any direct or indirect loss
or damage, real or consequential resulting from the usage of this
source code. It is the user's sole responsibility to determine
fitness for any considered purpose.
*/
#include
#include
#include
#include
<stdio.h>
<conio.h>
<dos.h>
"uio96.h"
/* This is where we have our board jumpered to */
#define BASE_PORT 0x200
/* This is an utlra-simple demonstration program of some of the functions
available in the UIO96 source code library. This program simply sets and
clears each I/O line in succession. It was tested by hooking LEDs to all
of the I/O lines and wathching the lit one race through the bits.
*/
void main()
{
int x;
/* Initialize all I/O bits, and set then for input */
init_io(1,BASE_PORT);
init_io(2,BASE_PORT+16);
/* We'll repeat our sequencing until a key is pressed */
while(!kbhit())
{
/* We will light the LED attached to each of the 48 lines */
for(x=1; x <=48; x++)
{
/* Setting the bit lights the LED */
set_bit(1,x);
/* The wait time is subjective. We liked 100mS */
delay(100);
/* Now turn off the LED */
clr_bit(1,x);
}
/* Now move on to the second chip and repeat the pattern */
for(x=1; x <=48; x++)
{
/* Setting the bit lights the LED */
set_bit(2,x);
/* The wait time is subjective. We liked 100mS */
delay(100);
/* Now turn off the LED */
clr_bit(2,x);
}
}
getch();
}
/* INTS.C
Copyright 1996-1999 by WinSystems Inc.
Permission is hereby granted to the purchaser of the WinSystems
UIO cards and CPU products incorporating the UIO device, to distribute
any binary file or files compiled using this source code directly or
in any work derived by the user from this file. In no case may the
source code, original or derived from this file, be distributed to any
third party except by explicit permission of WinSystems. This file is
distributed on an "As-is" basis and no warranty as to performance,
fitness of purposes, or any other warranty is expressed or implied.
In no case shall WinSystems be liable for any direct or indirect loss
or damage, real or consequential resulting from the usage of this
source code. It is the user's sole responsibility to determine
fitness for any considered purpose.
*/
#include
#include
#include
#include
<stdio.h>
<dos.h>
<conio.h>
"uio96.h"
#define BASE_PORT 0x200
/* This program like the poll.c sample uses the edge detection interrupt
capability of the WS16C48 to count edge transitions. Unlike poll.c,
however this program actually uses interrupts and update all of the
transition counters in the background.
*/
/* Our transition totals are stored in this global array */
unsigned int_counts[2][25];
/* Function declarations for local functions */
void interrupt int_handler(void);
void interrupt (*old_handler)(void);
void main()
{
int x;
/* Initialize the I/O ports. Set all I/O pins to input */
init_io(1,BASE_PORT);
init_io(2,BASE_PORT+16); /* Initialize second chip */
/* Install an interrupt handler for the board */
/* We disable interrupts whenever we're changing the environment */
disable();
/* Disable interrupts during initialization */
/* Get the old handler and save it for later resoration */
old_handler = getvect(0x0d);
/* Hardwired for IRQ5 */
/* Install out new interrupt handler */
setvect(0x0d,int_handler);
/* Clear the transition count values and enable the falling edge
interrupts.
*/
for(x=1; x<25; x++)
{
int_counts[0][x] = 0;
int_counts[1][x] = 0;
enab_int(1,x,FALLING);
enab_int(2,x,FALLING);
/* Clear the counts */
/* Enable the falling edge interrupts */
}
/* Unmask the interrupt controller */
outportb(0x21,(inportb(0x21) & 0xdf));
/* Unmask IRQ 5 */
/* Reenable interrupts */
enable();
/* Set up the display */
clrscr();
/* Clear the Text Screen */
for(x=1; x<25; x++)
{
gotoxy(1,x);
printf("Bit Number %02d ",x);
gotoxy(39,x);
printf("Bit Number %02d ",x);
}
/* We will continuously print the transition totals until a
key is pressed */
/* All of the processing of the transition interrupts, including
updating the counts is done in the background when an interrupt
occurs.
*/
while(!kbhit())
{
for(x=1; x < 25; x++)
{
gotoxy(16,x);
printf("%05u",int_counts[0][x]);
gotoxy(55,x);
printf("%05u",int_counts[1][x]);
}
}
getch();
/* Disable interrupts while we restore things */
disable();
/* Mask off the interrupt at the interrupt controller */
outportb(0x21,inportb(0x21) | 0x20); /* Mask IRQ 5 */
/* Restore the old handler */
setvect(0x0d,old_handler);
/* Put back the old interrupt handler */
/* Reenable interrupts. Things are back they way they were before we
started.
*/
enable();
}
/* This function is executed when an edge detection interrupt occurs */
void interrupt int_handler(void)
{
int current1,current2;
/* Get the current interrupt pending. There really should be one
here or we shouldn't even be executing this function.
*/
while(1)
{
/* stay here till all handled */
current1 = get_int(1);
/* We will continue processing pending edge detect interrupts until
there are no more present. In which case current == 0
*/
if(current1)
{
clr_int(1,current1);
/* Tally up one for the current bit number */
++int_counts[0][current1];
}
/* Get the next one, if any others pending */
current2 = get_int(2);
if(current2)
{
clr_int(2,current2);
++int_counts[1][current2];
}
if((current1 == 0) && (current2 == 0))
{
current1 = get_int(1);
current2 = get_int(2);
if((current1 == 0) && (current2 == 0))
break;
}
}
/* Issue a non-specific end of interrupt command (EOI) to the
interrupt controller. This rearms it for the next shot.
*/
outportb(0x20,0x20);
}
/* Do non-specific EOI */
/* POLL.C
Copyright 1999 by WinSystems Inc.
Permission is hereby granted to the purchaser of the WinSystems
UIO cards and CPU products incorporating the UIO device, to distribute
any binary file or files compiled using this source code directly or
in any work derived by the user from this file. In no case may the
source code, original or derived from this file, be distributed to any
third party except by explicit permission of WinSystems. This file is
distributed on an "As-is" basis and no warranty as to performance,
fitness of purposes, or any other warranty is expressed or implied.
In no case shall WinSystems be liable for any direct or indirect loss
or damage, real or consequential resulting from the usage of this
source code. It is the user's sole responsibility to determine
fitness for any considered purpose.
*/
#include <stdio.h>
#include <conio.h>
#include "uio96.h"
#define BASE_PORT 0x200
/* This program uses the edge detection interrupt capability of the
WS16C48 to count transitions on the first 24 lines of each chip.
It does this however, not by using true interrupts, but by polling
for transitions using the get_int() function.
*/
/* Our transition totals are stored in this array */
unsigned int_counts[2][25];
/* Definitions for local functions */
void check_ints(void);
void main()
{
int x;
/* Initialize the I/O ports.
Set all I/O pins to input */
init_io(1,BASE_PORT);
init_io(2,BASE_PORT+16); /* Initialize the second chip as well */
/* Initialize our transition counts, and enable falling edge
transition interrupts.
*/
for(x=1; x<25; x++)
{
int_counts[0][x] = 0;
int_counts[1][x] = 0;
enab_int(1,x,FALLING);
enab_int(2,x,FALLING);
}
/* Clear the counts */
/* Enable the falling edge interrupts */
/* Clean up the screen for our display. Nothing fancy */
clrscr();
for(x=1; x<25; x++)
{
gotoxy(1,x);
printf("Bit number %02d ",x);
gotoxy(39,x);
printf("Bit number %02d ",x);
}
/* We will continue to display until any key is pressed */
while(!kbhit())
{
/* Retrieve any pending transitions and update the counts */
check_ints();
/* Display the current count values */
for(x=1; x < 25; x++)
{
gotoxy(16,x);
printf("%05u",int_counts[0][x]);
gotoxy(55,x);
printf("%05u",int_counts[1][x]);
}
}
getch();
}
void check_ints()
{
int current;
/* Get the bit number of a pending transition interrupt */
current = get_int(1);
/* If it's 0 there are none pending */
if(current != 0)
{
/* Clear and rearm this one so we can get it again */
clr_int(1,current);
/* Tally a transition for this bit */
++int_counts[0][current];
}
current = get_int(2);
/* If it's 0 there are none pending */
if(current != 0)
{
/* Clear and rearm this one so we can get it again */
clr_int(2,current);
/* Tally a transition for this bit */
++int_counts[1][current];
}
}
/* UIO96.C
Copyright 1996-1999 by WinSystems Inc.
Permission is hereby granted to the purchaser of the WinSystems
UIO cards and CPU products incorporating the UIO device, to distribute
any binary file or files compiled using this source code directly or
in any work derived by the user from this file. In no case may the
source code, original or derived from this file, be distributed to any
third party except by explicit permission of WinSystems. This file is
distributed on an "As-is" basis and no warranty as to performance,
fitness of purposes, or any other warranty is expressed or implied.
In no case shall WinSystems be liable for any direct or indirect loss
or damage, real or consequential resulting from the usage of this
source code. It is the user's sole responsibility to determine
fitness for any considered purpose.
*/
/**************************************************************************
*
Name
: uio96.c
*
*
Project : PCM-UIO96 Software Samples/Examples
*
*
Date
: August 20, 1993
*
*
Revision: 1.00
*
*
Author : Steve Mottin
*
****************************************************************************
*
*
Changes :
*
*
Date
Revision
Description
*
________
________
______________________________________________
*
08/20/99
1.00
Adapted from UIO48 code
*
*****************************************************************************
*/
#include <dos.h>
/* This global holds the base address of the UIO chip */
unsigned base_port[4] = {0,0,0,0};
/* This global array holds the image values of the last write to each I/O
ports. This allows bit manipulation routines to work without having to
actually do a read-modify-write to the I/O port.
*/
unsigned port_images[4][6];
/*===========================================================================
*
INIT_IO
*
* This function take two arguments :
*
*
* Chip_number :
Chip number 1 to 4;
* io_address :
This is the base I/O address of the 16C48 UIO Chip
*
on the board.
*
*
* This function initializes all I/O pins for input, disables all interrupt
* sensing, and sets the image values.
*
*===========================================================================*/
void init_io(int chip_number,unsigned io_address)
{
int x;
/* Zero adjust chip number */
--chip_number;
/* Save the specified address for later use */
base_port[chip_number] = io_address;
/* Clear all of the I/O ports. This also makes them inputs */
for(x=0; x < 7; x++)
outportb(base_port[chip_number]+x, 0);
/* Clear our image values as well */
for(x=0; x < 6; x++)
port_images[chip_number][x] = 0;
/* Set page 2 access, for interrupt enables */
outportb(base_port[chip_number]+7,0x80);
/* Clear all interrupt enables */
outportb(base_port[chip_number]+8,0);
outportb(base_port[chip_number]+9,0);
outportb(base_port[chip_number]+0x0a,0);
/* Restore normal page 0 register access */
outportb(base_port[chip_number]+7,0);
}
/*===========================================================================
*
*
READ_BIT
*
*
* This function takes two arguments :
*
* chip_number
: This argument specifies the chip number 1 to 4
*
* bit_number
: The integer argument specifies the bit number to read.
*
Valid arguments are from 1 to 48.
*
* return value : The current state of the specified bit, 1 or 0.
*
* This function returns the state of the current I/O pin specified by
* the argument bit_number.
*
*===========================================================================*/
int read_bit(int chip_number,int bit_number)
{
unsigned port;
int val;
/* Adjust chip number to zero based addressing */
--chip_number;
/* Adjust the bit_number to 0 to 47 numbering */
--bit_number;
/* Calculate the I/O port address based on the updated bit_number */
port = (bit_number / 8) + base_port[chip_number];
/* Get the current contents of the port */
val = inportb(port);
/* Get just the bit we specified */
val = val & (1 << (bit_number % 8));
/* Adjust the return for a 0 or 1 value */
if(val)
return 1;
return 0;
}
/*===========================================================================
*
*
WRITE_BIT
*
* This function takes three arguments :
*
*
* chip_number : The I/O Chip number 1 to 4
*
* bit_number : The I/O pin to access is specified by bit_number 1 to 48.
*
* val :
The setting for the specified bit, either 1 or 0.
*
* This function sets the specified I/O pin to either high or low as dictated
* by the val argument. A non zero value for val sets the bit.
*
*===========================================================================*/
void write_bit(int chip_number, int bit_number, int val)
{
unsigned port;
unsigned temp;
unsigned mask;
/* Adjust chip number for 0 based numbering */
--chip_number;
/* Adjust bit_number for 0 based numbering */
--bit_number;
/* Calculate the I/O address of the port based on the bit number */
port = (bit_number / 8) + base_port[chip_number];
/* Use the image value to avoid having to read the port first. */
temp = port_images[chip_number][bit_number / 8];
/* Get current value */
/* Calculate a bit mask for the specified bit */
mask = (1 << (bit_number % 8));
/* Check whether the request was to set or clear and mask accordingly */
if(val)
/* If the bit is to be set */
temp = temp | mask;
else
temp = temp & ~mask;
/* Update the image value with the value we're about to write */
port_images[chip_number][bit_number / 8] = temp;
/* Now actually update the port. Only the specified bit is affected */
outportb(port,temp);
}
/*===========================================================================
*
SET_BIT
*
*
* This function takes two arguments :
*
* chip_number : The chip number from 1 to 3
*
* bit_number : The bit number to set 1 to 48.
*
* This function sets the specified bit.
*
*===========================================================================*/
void set_bit(int chip_number,int bit_number)
{
write_bit(chip_number,bit_number,1);
}
/*===========================================================================
*
CLR_BIT
*
*
* This function takes two arguments :
*
* chip_number: Chip number 1 to 3
*
* bit_number : The bit number to clear.
*
* This function clears the specified bit.
*
*===========================================================================*/
void clr_bit(int chip_number,int bit_number)
{
write_bit(chip_number,bit_number,0);
}
/*===========================================================================
*
*
ENAB_INT
*
* This function takes three arguments :
*
* chip_number : The desired chip number 1 to 4
*
* bit_number : The bit number to enable intterups for. Range from 1 to 48.
*
* polarity
: This specifies the polarity of the interrupt. A non-zero
*
argument enables rising-edge interrupt. A zero argument
*
enables the interrupt on the flling edge.
*
* This function enables within the 16C48 an interrupt for the specified bit
* at the specified polarity. This function does not setup the interrupt
* controller, nor does it supply an interrupr handler.
*
*============================================================================*/
void enab_int(int chip_number,int bit_number, int polarity)
{
unsigned port;
unsigned temp;
unsigned mask;
/* Adjust chip number for 0 based numbering */
--chip_number;
/* Adjust for 0 based numbering */
--bit_number;
/* Calculate the I/O address based uppon the bit number */
port = (bit_number / 8) + base_port[chip_number] + 8;
/* Calculate a bit mask based on the specified bit number */
mask = (1 << (bit_number % 8));
/* Turn on page 2 access */
outportb(base_port[chip_number]+7,0x80);
/* Get the current state of the interrupt enable register */
temp = inportb(port);
/* Set the enable bit for our bit number */
temp = temp | mask;
/* Now update the interrupt enable register */
outportb(port,temp);
/* Turn on access to page 1 for polarity control */
outportb(base_port[chip_number]+7,0x40);
/* Get the current state of the polarity register */
temp = inportb(port);
/* Get current polarity settings */
/* Set the polarity according to the argument in the image value */
if(polarity)
/* If the bit is to be set */
temp = temp | mask;
else
temp = temp & ~mask;
/* Write out the new polarity value */
outportb(port,temp);
/* Set access back to Page 0 */
outportb(base_port[chip_number]+7,0x0);
}
/*===========================================================================
*
*
DISAB_INT
*
* This function takes two arguments :
*
* chip_number: Desired chip number 1 to 4
* bit_number : Specifies the bit number to act upon. Range is from 1 to 48.
*
* This function shuts off the interrupt enabled for the specified bit.
*
*===========================================================================*/
void disab_int(int chip_number,int bit_number)
{
unsigned port;
unsigned temp;
unsigned mask;
/* Adjust for 0 based addressing */
--chip_number;
/* Adjust the bit_number for 0 based numbering */
--bit_number;
/* Calculate the I/O Address for the enable port */
port = (bit_number / 8) + base_port[chip_number] + 8;
/* Calculate the proper bit mask for this bit number */
mask = (1 << (bit_number % 8));
/* Turn on access to page 2 registers */
outportb(base_port[chip_number]+7,0x80);
/* Get the current state of the enable register */
temp = inportb(port);
/* Clear the enable bit int the image for our bit number */
temp = temp & ~mask;
/* Update the enable register with the new information */
outportb(port,temp);
/* Set access back to page 0 */
outportb(base_port[chip_number]+7,0x0);
}
/*==========================================================================
*
*
CLR_INT
*
* This function takes two arguments :
*
* chip_number : The desired chip number 1 to 4
*
* bit_number : This argument specifies the bit interrupt to clear. Range
*
is 1 to 24.
*
*
* This function is use to clear a bit interrupt once it has been recognized.
* The interrupt left enabled.
*
*===========================================================================*/
void clr_int(int chip_number,int bit_number)
{
unsigned port;
unsigned temp;
unsigned mask;
/* Adjust chip number for 0 based */
--chip_number;
/* Adjust for 0 based numbering */
--bit_number;
/* Calculate the correct I/O address for our enable register */
port = (bit_number / 8) + base_port[chip_number] + 8;
/* Calculate a bit mask for this bit number */
mask = (1 << (bit_number % 8));
/* Set access to page 2 for the enable register */
outportb(base_port[chip_number]+7,0x80);
/* Get current state of the enable register */
temp = inportb(port);
/* Temporarily clear only OUR enable. This clears the interrupt */
temp = temp & ~mask;
/* clear the enable for this bit */
/* Write out the temporary value */
outportb(port,temp);
/* Re-enable our interrupt bit */
temp = temp | mask;
/* Write it out */
outportb(port,temp);
/* Set access back to page 0 */
outportb(base_port[chip_number]+7,0x0);
}
/*==========================================================================
*
*
GET_INT
*
* This function takes one arguments.
*
* chip_number : The desired chip number 1 to 4
*
* return value : The value returned is the highest level bit interrupt
*
currently pending. Range is 1 to 24.
*
* This function returns the highest level interrupt pending. If no interrupt
* is pending, a zero is returned. This function does NOT clear the interrupt.
*
*===========================================================================*/
int get_int(int chip_number)
{
int temp;
int x;
/* Adjust the chip number for zero based numbering */
--chip_number;
/* read the master interrupt pending register, mask off undefined bits */
temp = inportb(base_port[chip_number]+6) & 0x07;
/* If there are no interrupts pending, return a 0 */
if((temp & 7) == 0)
return(0);
/* There is something pending, now we need to identify what it is */
/* Set access to page 3 for interrupt id registers */
outportb(base_port[chip_number]+7,0xc0);
/* Read interrupt ID register for port 0 */
temp = inportb(base_port[chip_number]+8);
/* See if any bit set, if so return the bit number */
if(temp !=0)
{
for(x=0; x <=7; x++)
{
if(temp & (1 << x))
{
outportb(base_port[chip_number]+7,0);
/* Turn off access
*/
return(x+1);
/* Return bitnumber with active int */
}
}
}
/* None in Port 0, read port 1 interrupt ID register */
temp = inportb(base_port[chip_number]+9);
/* See if any bit set, if so return the bit number */
if(temp !=0)
{
for(x=0; x <=7; x++)
{
if(temp & (1 << x))
{
outportb(base_port[chip_number]+7,0);
/* Turn off access
*/
return(x+9);
/* Return bitnumber with active int */
}
}
}
/* Lastly, read status of port 2 int id */
temp = inportb(base_port[chip_number]+0x0a);
/* Read port 2 status */
/* If any pending, return the appropriate bit number */
if(temp !=0)
{
for(x=0; x <=7; x++)
{
if(temp & (1 << x))
{
outportb(base_port[chip_number]+7,0);
/* Turn off access
*/
return(x+17);
/* Return bitnumber with active int */
}
}
}
/* We should never get here unless the hardware is misbehaving but just
to be sure. We'll turn the page access back to 0 and return a 0 for
no interrupt found.
*/
outportb(base_port[chip_number]+7,0);
return 0;
}
/* UIO96.H
Copyright 1996-1999 by WinSystems Inc.
Permission is hereby granted to the purchaser of the WinSystems
UIO cards and CPU products incorporating the UIO device, to distribute
any binary file or files compiled using this source code directly or
in any work derived by the user from this file. In no case may the
source code, original or derived from this file, be distributed to any
third party except by explicit permission of WinSystems. This file is
distributed on an "As-is" basis and no warranty as to performance,
fitness of purposes, or any other warranty is expressed or implied.
In no case shall WinSystems be liable for any direct or indirect loss
or damage, real or consequential resulting from the usage of this
source code. It is the user's sole responsibility to determine
fitness for any considered purpose.
*/
/**************************************************************************
*
Name
: uio96.h
*
*
Project : PCM-UIO96 Software Samples/Examples
*
*
Date
: August 19, 1999
*
*
Revision: 1.00
*
*
Author : Steve Mottin
*
****************************************************************************
*
*
Changes :
*
*
Date
Revision
Description
*
________
________
__________________________________
*
10/30/96
1.00
Adpated from UIO48A code
*
*****************************************************************************
*/
#define RISING 1
#define FALLING 0
void init_io(int chip_number,unsigned io_address);
int read_bit(int chip_number,int bit_number);
void write_bit(int chip_number,int bit_number);
void set_bit(int chip_number,int bit_number);
void clr_bit(int chip_number,int bit_number);
void enab_int(int chip_number,int bit_number, int polarity);
void disab_int(int chip_number,int bit_number);
void clr_int(int chip_number,int bit_number);
int get_int(int chip_number);
7
APPENDIX D
PCM-UIO96A Schematic Diagrams
A
B
C
D
E
W[0..23]
X[0..23]
U4A
1
VCC
RESET
2
VCC
VCC
C10
.1
74HC04
C11
.1
VCC
C12
.1
VCC
C4
.1
VCC
C9
.1
VCC
VCC
C7
.1
VCC
C3
.1
C6
.1
VCC
C5
.1
W[0..23]
X[0..23]
VCC
C2
.1
Z[0..23]
Y[0..23]
Z[0..23]
Y[0..23]
C1
.1
J8
3
VCC
D7
D6
D5
D4
D3
D2
D1
D0
4
VCC
C8
10UF
AEN
A12
A11
A10
A9
A8
A7
A6
A5
A4
A3
A2
A1
A0
PC104
J9
GND
SBHE
LA23
LA22
LA21
LA20
LA19
LA18
LA17
MEMR
MEMW
SD8
SD9
SD10
SD11
SD12
SD13
SD14
SD15
KEY
GND
MEMCS16
IOCS16
IRQ10
IRQ11
IRQ12
IRQ15
IRQ14
DACK0
DRQ0
DACK5
DRQ5
DACK6
DRQ6
DACK7
DRQ7
VCC
MASTER
GND
GND
D0
D1
D2
D3
D4
D5
D6
D7
D8
D9
D10
D11
D12
D13
D14
D15
D16
D17
D18
D19
CS0
24
A0
A1
A2
A3
23
21
22
28
IOR
27
IOW
64
RESET
20
D0
D1
D2
D3
D4
D5
D6
D7
71
70
69
65
63
62
59
58
12
IRQ10
IRQ11
IRQ12
IRQ15
IRQ14
IOW
J7B
VCC
1
2
3
4
5
6
7
8
9
10
11
J7
IRQ2
IRQ10
IRQ11
IRQ12
IRQ15
IRQ14
IRQ7
IRQ6
IRQ5
IRQ4
IRQ3
1
3
5
7
9
11
13
15
17
19
21
2
4
6
8
10
12
14
16
18
20
22
30
72
73
74
U4B
4
3
29
R2
1K
/CS
A0
A1
A2
A3
/IORD
/IOWR
/RESET
D0
D1
D2
D3
D4
D5
D6
D7
NC
NC
NC
NC
NC
/INTRQ
74HC04
J6
1
2
C0
C1
C2
C3
C4
C5
C6
C7
C8
C9
C10
C11
C12
C13
C14
C15
C16
C17
C18
C19
U2
/P00
/P01
/P02
/P03
/P04
/P05
/P06
/P07
/P10
/P11
/P12
/P13
/P14
/P15
/P16
/P17
/P20
/P21
/P22
/P23
/P24
/P25
/P26
/P27
/P30
/P31
/P32
/P33
/P34
/P35
/P36
/P37
/P40
/P41
/P42
/P43
/P44
/P45
/P46
/P47
/P50
/P51
/P52
/P53
/P54
/P55
/P56
/P57
VCC
24
A0
A1
A2
A3
23
21
22
28
IOR
27
IOW
64
RESET
20
D0
D1
D2
D3
D4
D5
D6
D7
71
70
69
65
63
62
59
58
12
IOW
30
72
73
74
U4C
6
5
29
A0
A1
A2
A3
/IORD
/IOWR
/RESET
D0
D1
D2
D3
D4
D5
D6
D7
NC
NC
NC
NC
NC
/INTRQ
R1
1K
74HC04
VCC
1
15
2
14
3
13
4
12
5
11
6
10
7
8
9
AEN
17
2
15
4
13
6
11
8
P0
P1
P2
P3
P4
P5
P6
P7
1
G
Q0
Q1
Q2
Q3
Q4
Q5
Q6
Q7
P=Q
18
3
16
5
14
7
12
9
15
13
11
9
7
5
3
1
16
14
12
10
8
6
4
2
U5A
2
74HCT32
U5B
4
6
U5C
10
13
12
CS1
74HCT32
74HC04
10
74HCT32
U5D
74HC04
Title
PCM-UIO96A
12
11
19
5
1
8
A4
11
9
U4F
CS0
Size
B
13
Document Number
400-0285-000A
Rev
A
74HCT32
612-0688-002
Date:
A
2
1
9
74HC04
U4E
J5
AM3
AM7
AM2
AM6
AM1
AM5
AM0
AM4
3
3
8
AM7
AM6
AM5
AM4
AM3
AM2
AM1
AM0
U3
A8
A12
A7
A11
A6
A10
A5
A9
Y0
Y1
Y2
Y3
Y4
Y5
Y6
Y7
Y8
Y9
Y10
Y11
Y12
Y13
Y14
Y15
Y16
Y17
Y18
Y19
Y20
Y21
Y22
Y23
Z0
Z1
Z2
Z3
Z4
Z5
Z6
Z7
Z8
Z9
Z10
Z11
Z12
Z13
Z14
Z15
Z16
Z17
Z18
Z19
Z20
Z21
Z22
Z23
16C48
U4D
RP1
10K
1
U1
17
16
15
14
13
11
10
9
8
7
6
5
3
2
1
84
83
81
80
79
78
77
76
75
57
56
55
54
53
52
51
50
49
48
47
45
44
43
42
41
39
38
37
36
35
34
32
31
/P00
/P01
/P02
/P03
/P04
/P05
/P06
/P07
/P10
/P11
/P12
/P13
/P14
/P15
/P16
/P17
/P20
/P21
/P22
/P23
/P24
/P25
/P26
/P27
/P30
/P31
/P32
/P33
/P34
/P35
/P36
/P37
/P40
/P41
/P42
/P43
/P44
/P45
/P46
/P47
/P50
/P51
/P52
/P53
/P54
/P55
/P56
/P57
/CS
16
VCC
CS1
16C48
18
19
40
60
61
66
82
PC104-16
W0
W1
W2
W3
W4
W5
W6
W7
W8
W9
W10
W11
W12
W13
W14
W15
W16
W17
W18
W19
W20
W21
W22
W23
X0
X1
X2
X3
X4
X5
X6
X7
X8
X9
X10
X11
X12
X13
X14
X15
X16
X17
X18
X19
X20
X21
X22
X23
17
16
15
14
13
11
10
9
8
7
6
5
3
2
1
84
83
81
80
79
78
77
76
75
57
56
55
54
53
52
51
50
49
48
47
45
44
43
42
41
39
38
37
36
35
34
32
31
VCC
VCC
VCC
VPP
VCC
VCC
VCC
+
VCC
4
25
26
33
46
67
68
VCC
4
25
26
33
46
67
68
A1
A2
A3
A4
A5
A6
A7
A8
A9
A10
A11
A12
A13
A14
A15
A16
A17
A18
A19
A20
A21
A22
A23
A24
A25
A26
A27
A28
A29
A30
A31
A32
VCC
VCC
VCC
VPP
VCC
VCC
VCC
IOCHCK
SD7
SD6
SD5
SD4
SD3
SD2
SD1
SD0
IOCHRDY
AEN
SA19
SA18
SA17
SA16
SA15
SA14
SA13
SA12
SA11
SA10
SA9
SA8
SA7
SA6
SA5
SA4
SA3
SA2
SA1
SA0
GND
GND
GND
GND
GND
GND
MODE
GND
IRQ7
IRQ6
IRQ5
IRQ4
IRQ3
GND
RESET
+5V
IRQ2
-5V
DRQ2
-12V
OWS
+12V
GND
SMEMW
SMEMR
IOW
IOR
DACK3
DRQ3
DACK1
DRQ1
DACK0
CLK
IRQ7
IRQ6
IRQ5
IRQ4
IRQ3
DACK2
T/C
BALE
+5V
OSC
GND
GND
18
19
40
60
61
66
82
IOW
IOR
B1
B2
B3
B4
B5
B6
B7
B8
B9
B10
B11
B12
B13
B14
B15
B16
B17
B18
B19
B20
B21
B22
B23
B24
B25
B26
B27
B28
B29
B30
B31
B32
GND
GND
GND
GND
GND
MODE
GND
IRQ2 VCC
2
4
B
C
D
Tuesday, May 25, 1999
Sheet
E
1
of
2
A
4
B
X[0..23]
X[0..23]
W[0..23]
W[0..23]
C
3
R3
R4
R5
R6
R7
R8
R9
R10
R11
R12
R13
R14
R15
R16
R17
R18
R19
R20
R21
R22
R23
R24
R25
R26
W23
W22
W21
W20
W19
W18
W17
W16
W15
W14
W13
W12
W11
W10
W9
W8
W7
W6
W5
W4
W3
W2
W1
W0
W23
W22
W21
W20
W19
W18
W17
W16
W15
W14
W13
W12
W11
W10
W9
W8
W7
W6
W5
W4
W3
W2
W1
W0
1
3
5
7
9
11
13
15
17
19
21
23
25
27
29
31
33
35
37
39
41
43
45
47
49
2
4
6
8
10
12
14
16
18
20
22
24
26
28
30
32
34
36
38
40
42
44
46
48
50
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
R27
R28
R29
R30
R31
R32
R33
R34
R35
R36
R37
R38
R39
R40
R41
R42
R43
R44
R45
R46
R47
R48
R49
R50
X23
X22
X21
X20
X19
X18
X17
X16
X15
X14
X13
X12
X11
X10
X9
X8
X7
X6
X5
X4
X3
X2
X1
X0
X23
X22
X21
X20
X19
X18
X17
X16
X15
X14
X13
X12
X11
X10
X9
X8
X7
X6
X5
X4
X3
X2
X1
X0
1
3
5
7
9
11
13
15
17
19
21
23
25
27
29
31
33
35
37
39
41
43
45
47
49
J2
2
4
6
8
10
12
14
16
18
20
22
24
26
28
30
32
34
36
38
40
42
44
46
48
50
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
R98
R97
R96
R95
R94
R93
R92
R91
R90
R89
R88
R87
R86
R85
R84
R83
R82
R81
R80
R79
R78
R77
R76
R75
1
4
Y23
Y22
Y21
Y20
Y19
Y18
Y17
Y16
Y15
Y14
Y13
Y12
Y11
Y10
Y9
Y8
Y7
Y6
Y5
Y4
Y3
Y2
Y1
Y0
Y23
Y22
Y21
Y20
Y19
Y18
Y17
Y16
Y15
Y14
Y13
Y12
Y11
Y10
Y9
Y8
Y7
Y6
Y5
Y4
Y3
Y2
Y1
Y0
1
3
5
7
9
11
13
15
17
19
21
23
25
27
29
31
33
35
37
39
41
43
45
47
49
J4
2
4
6
8
10
12
14
16
18
20
22
24
26
28
30
32
34
36
38
40
42
44
46
48
50
R74
R73
R72
R71
R70
R69
R68
R67
R66
R65
R64
R63
R62
R61
R60
R59
R58
R57
R56
R55
R54
R53
R52
R51
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
Z23
Z22
Z21
Z20
Z19
Z18
Z17
Z16
Z15
Z14
Z13
Z12
Z11
Z10
Z9
Z8
Z7
Z6
Z5
Z4
Z3
Z2
Z1
Z0
Z23
Z22
Z21
Z20
Z19
Z18
Z17
Z16
Z15
Z14
Z13
Z12
Z11
Z10
Z9
Z8
Z7
Z6
Z5
Z4
Z3
Z2
Z1
Z0
1
3
5
7
9
11
13
15
17
19
21
23
25
27
29
31
33
35
37
39
41
43
45
47
49
J3
2
4
6
8
10
12
14
16
18
20
22
24
26
28
30
32
34
36
38
40
42
44
46
48
50
3
F2
F1
VCC
E
Z[0..23]
Z[0..23]
Y[0..23]
Y[0..23]
J1
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
VCC
D
2
VCC
1A
1
2
1A
2
2
1
1
Title
PCM-UIO96A
Size
B
Date:
A
B
C
D
Document Number
400-0285-000A
Tuesday, May 25, 1999
Rev
A
Sheet
E
2
of
2
Telephone: 817-274-7553 . . Fax: 817-548-1358
http://www.winsystems.com . . E-mail: info@winsystems.com
WARRANTY
WinSystems warrants that for a period of two (2) years from the date of shipment any Products and Software
purchased or licensed hereunder which have been developed or manufactured by WinSystems shall be free of any
material defects and shall perform substantially in accordance with WinSystems' specifications therefore. With
respect to any Products or Software purchased or licensed hereunder which have been developed or manufactured
by others, WinSystems shall transfer and assign to Customer any warranty of such manufacturer or developer held
by WinSystems, provided that the warranty, if any, may be assigned. The sole obligation of WinSystems for any
breach of warranty contained herein shall be, at its option, either (i) to repair or replace at its expense any materially
defective Products or Software, or (ii) to take back such Products and Software and refund the Customer the
purchase price and any license fees paid for the same. Customer shall pay all freight, duty, broker's fees, insurance
changes and other fees and charges for the return of any Products or Software to WinSystems under this warranty.
WinSystems shall pay freight and insurance charges for any repaired or replaced Products or Software thereafter
delivered to Customer within the United States. All fees and costs for shipment outside of the United States shall be
paid by Customer. The foregoing warranty shall not apply to any Products or Software which have been subject to
abuse, misuse, vandalism, accidents, alteration, neglect, unauthorized repair or improper installations.
THERE ARE NO WARRANTIES BY WINSYSTEMS EXCEPT AS STATED HEREIN. THERE ARE NO
OTHER WARRANTIES EXPRESS OR IMPLIED INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, IN NO
EVENT SHALL WINSYSTEMS BE LIABLE FOR CONSEQUENTIAL, INCIDENTAL, OR SPECIAL
DAMAGES INCLUDING, BUT NOT LIMITED TO, DAMAGES FOR LOSS OF DATA, PROFITS OR
GOODWILL. WINSYSTEMS' MAXIMUM LIABILITY FOR ANY BREACH OF THIS AGREEMENT OR
OTHER CLAIM RELATED TO ANY PRODUCTS, SOFTWARE, OR THE SUBJECT MATTER
HEREOF, SHALL NOT EXCEED THE PURCHASE PRICE OR LICENSE FEE PAID BY CUSTOMER
TO WINSYSTEMS FOR THE PRODUCTS OR SOFTWARE OR PORTION THEREOF TO WHICH
SUCH BREACH OR CLAIM PERTAINS.
WARRANTY SERVICE
All products returned to WinSystems must be assigned a Return Material Authorization (RMA) number. To obtain
this number, please call or FAX WinSystems' factory in Arlington, Texas and provide the following information:
1. Description and quantity of the product(s) to be returned including its serial number.
2. Reason for the return.
3. Invoice number and date of purchase (if available), and original purchase order number.
4. Name, address, telephone and FAX number of the person making the request.
5. Do not debit WinSystems for the repair. WinSystems does not authorize debits.
After the RMA number is issued, please return the products promptly. Make sure the RMA number is visible on the
outside of the shipping package.
The customer must send the product freight prepaid and insured. The product must be enclosed in an anti-static bag
to protect it from damage caused by static electricity. Each bag must be completely sealed. Packing material must
separate each unit returned and placed as a cushion between the unit(s) and the sides and top of the shipping
container. WinSystems is not responsible for any damage to the product due to inadequate packaging or static
electricity.