United Kingdom:One Omega Drive, River Bend Technology Centre
ISO 9002 CertifiedNorthbank, Irlam, Manchester
M44 5BD United Kingdom
TEL: +44 (0)161 777 6611FAX: +44 (0)161 777 6622
Toll Free in United Kingdom: 0800-488-488
e-mail: sales@omega.co.uk
OMEGAnet®Online Service Internet e-mail
www.omega.com info@omega.com
It is the policy of OMEGA to comply with all worldwide safety and EMC/EMI regulations that
apply. OMEGA is constantly pursuing certification of its products to the European New Approach
Directives. OMEGA will add the CE mark to every appropriate device upon certification.
The information contained in this document is believed to be correct, but OMEGA Engineering, Inc. accepts
no liability for any errors it contains, and reserves the right to alter specifications without notice.
WARNING: These products are not designed for use in, and should not be used for, patient-connected applications.
The OME-PIO-D48 provides 48 TTL digital I/O lines. The OME-PIO-D48
consists of two 24-bit bi-direction ports. Each 24-bit port supports three 8-bit
groups A, B, C. Each 8-bit group can be configured to function as either inputs
or latched outputs. All groups are configured as inputs upon power-up or reset.
Outputs of the I/O buffers are pulled up through 10K resistors to +5VDC.
Outputs can be changed to pull-down by jumper selection on the board. This
pull-up/pull-down mechanism assures that there are no erroneous outputs at
power-up until the board is initialized by application software.
The OME-PIO-D48 has one D-Sub connector and one 50-pin flat-cable
header. The header can be connected to a 50-pin flat-cable. The flat-cable can
be connected to OME-ADP-37/PCI or OME-ADP-50/PCI adapters. The adapter
can be fixed on the chassis. It can be installed in a 5 V PCI bus and supports
“Plug & Play”.
1.1 Features
• PCI Bus
• Up to 48 channels of digital I/O
• All I/O lines buffered on the board
• Eight-bit groups independently selectable for I/O on each 24-bit port
• Input/Output programmable I/O ports under software control
• SMD, short card, power saving
• Connects directly to OME-DB-24P, OME-DB-24R, OME-DB-24PR, OME-
In addition to this manual, the package includes the following items:
• one piece of OME-PIO-D48 card
• one piece of software floppy diskette or CD
• one piece of release note
It is recommended to read the release note first. All important information will be given
in release note as following:
1. Where you can find the software driver & utility?
2. How to install software & utility?
3. Where is the diagnostic program?
4. FAQ
Attention !
If any of these items are missing or damaged, contact Omega Engineering
immediately. Save the shipping materials and the box in case you want to ship or store
the product in the future.
OME-PIO-D48 User Manual, Sep/2000, V2.1 ----- 5
Page 8
2. Hardware configuration
2.1 Board Layout & Default Setting
PCI BUS
JP3 (port-1)
3=pull-low
2
1=pull-High
PC=port-2
JP4 (port-2)
3=pull-low
PA=port-0
PB=port-1
2
1=pull-High
ome-DB-37
CN1
JP2 (port-0)
1=pull-High
2
3=pull-low
OME-PIO-D48
PCI BUS
JP7 (port-5)
3=pull-low
2
1=pull-High
JP6 (port-4)
3=pull-low
2
PA=port-3
PB=port-4
PC=port-5
1=pull-High
JP5 (port-3)
3=pull-low
CN2
50-pin
2
1=pull-High
Default Setting: JP2/3/4/5/6/7=2-3 short=pull-low
OME-PIO-D48 User Manual, Sep/2000, V2.1 ----- 6
Page 9
2.2 I/O Port Location
There are six 8-bit I/O ports in the OME-PIO-D48. Every I/O port can be
programmed as D/I or D/O port. When the PC is first power-up, all six ports are
configured as D/I port. These D/I ports can be pull-high or pull-low selected by JP2 ~
JP7. These I/O port locations are given as following:
Connector of OME-PIO-D48 PA0 to PA7 PB0 to PB7 PC0 to PC7
CN1
(OME-DB-37)
CN2
(50-pin head)
• Note 1: Refer to Sec. 2.1 for board layout & I/O port location.
• Note 2: Refer to Sec. 2.1 for JP 2 ~ 7 pull-high/pull-low.
port-0
(pull-high/low
by JP2)
port-3
(pull-high/low
by JP5)
port-1
(pull-high/low
by JP3)
port-4
(pull-high/low
by JP6)
port-2
(pull-high/low by
JP4)
port-5
(pull-high/low by
JP7)
2.3 I/O Port Initialization Operation
When the PC is powered-up, all operations of D/I/O port are disabled. The
enable/disable of D/I/O is controlled by the RESET\ signal. Refer to Sec. 3.3.1 for more
information about RESET\ signal. The power-up states are given as following:
• All D/I/O are disabled
• All six D/I/O ports are configured as D/I port
• All D/O latch register outputs are at high impedance.(refer to Sec. 2.4)
The user has to perform some initialization before using these D/I/Os. The
recommended steps are given as following:
Step 1: find address-mapping of PIO/PISO cards (refer to Sec. 3.1)
Step 2: enable all D/I/O (refer to Sec. 3.3.1)
Step 3: configure the first three ports to their expected D/I/O state & send the
initial value to all D/O ports (refer to Sec. 3.3.7)
Step 4: configure the other three ports to their expected D/I/O state & send the
initial value to all D/O ports (refer to Sec. 3.3.7)
OME-PIO-D48 User Manual, Sep/2000, V2.1 ----- 7
Page 10
The sample program is given as following:
/* step 1: find address-mapping of PIO/PISO cards */
clrscr();
wRetVal=PIO_DriverInit(&wBoards,0x80,0x01,0x30); /* for OME-PIO-D48 */
printf("\nThrer are %d PIO_D48 Cards in this PC",wBoards);
if (wBoards==0) exit(0);
printf("\n------------ The Configuration Space ----------------");
for(i=0; i<wBoards; i++)
{
PIO_GetConfigAddressSpace(i,&wBase,&wIrq,&wSubVendor,
&wSubDevice,&wSubAux,&wSlotBus,&wSlotDevice);
default: all JPs are in 2-3-short Æ select pull-low
2
10K
GND
(pull low)
(1-2-ON=pull-high, 2-3-ON=pull-low)
• If D/I/O is configured as D/O port Æ D/I = read back of D/O
• If D/I/O is configured as D/I port Æ send to D/O will change the D/O latch register
only. The D/I & external input signal will not change.
OME-PIO-D48 User Manual, Sep/2000, V2.1 ----- 9
Page 12
2.5 Interrupt Operation
There are four interrupt sources in OME-PIO-D48. These four signals are named as
INT_CHAN_0, INT_CHAN_1, INT_CHAN_2 and INT_CHAN_3. Their signal sources
are given as following:
INT_CHAN_0: PC3/PC7 from port-2(refer to Sec. 2.5.2)
INT_CHAN_1: PC3/PC7 from port-5(refer to Sec. 2.5.3)
INT_CHAN_2: Cout0(refer to Sec. 2.5.4)
INT_CHAN_3: Cout2(refer to Sec. 2.5.5)
If only one interrupt signal source is used, the interrupt service routine does not
have to identify the interrupt source. Refer to DEMO4.C, DEMO7.C, DEMO8.C,
DEMO9.C and DEMO10.C for more information.
If there are more than one interrupt source, the interrupt service routine has to
identify the active signals as following: (refer to DEMO11.C)
1. Read the new status of all interrupt signal sources(refer to Sec 3.3.5)
2. Compare the new status with the old status to identify the active signals
3. If INT_CHAN_0 is active, service it
4. If INT_CHAN_1 is active, service it
5. If INT_CHAN_2 is active, service it
6. If INT_CHAN_3 is active, service it
7. Update interrupt status
Note: If the interrupt signal is too short, the new status may be as same as old
status. In that condition the interrupt service routine can not identify which
interrupt source is active. So the interrupt signal must have hold_active long
enough until the interrupt service routine is executed. This hold_time is different
for different O.S. The hold_time can be as short as micro-second or as long as
second. In general, 20ms is enough for all O. S.
OME-PIO-D48 User Manual, Sep/2000, V2.1 ----- 10
Page 13
2.5.1 Interrupt Block Diagram of OME-PIO-D48
INT_CHAN_0
INT\
Level_trigger
The interrupt output signal of OME-PIO-D48, INT\, is
Active_Low
PC once a time. If the INT\ is fixed in low level, the OME-PIO-D48 will interrupt the
PC continuously. So the INT_CHAN_0/1/2/3 must be controlled in a pulse_type
signals. They must be fixed in low level state normally and must generate
. If the INT\ generate a low-pulse, the OME-PIO-D48 will interrupt the
INT_CHAN_1
INT_CHAN_2
INT_CHAN_3
initial_low
active_high
level-trigger &
a high_pulse to interrupt the PC.
The priority of INT_CHAN_0/1/2/3 is the same. If all these four signals are
active at the same time, then INT\ will be active only once a time. So the interrupt
service routine has to read the status of all interrupt channels for multi-channel interrupt.
Refer to Sec. 2.5 for more information.
DEMO11.C Æ for both INT_CHAN_0 & INT_CHAN_1
If only one interrupt source is used, the interrupt service routine does not have to
read the status of interrupt source. The demo programs; DEMO4.C to DEMO10.C; are
designed for single-channel interrupt demo as following:
DEMO4.C Æ for INT_CHAN_3 only
DEMO7.C Æ for INT_CHAN_2 only
DEMO8.C Æ for INT_CHAN_0 only
DEMO9.C Æ for INT_CHAN_0 only
DEMO10.C Æ for INT_CHAN_1 only
OME-PIO-D48 User Manual, Sep/2000, V2.1 ----- 11
Page 14
2.5.2 INT_CHAN_0
INT_CHAN_0
The INT_CHAN_0 must be fixed in low level state normally and
generate a high_pulse to interrupt the PC.
The INT_CHAN_0 can be equal to PC3&!PC7 or PC3 programmable as
following:(refer to Sec. 3.3.9)
01
00
10
PC3&!PC7(port-2)
Disable
PC3(port-2)
Inverted/Noninverted select
(INV0)
Enable/Disable select
(EN0)
CTRL_D3=0, CTRL_D2=1 Æ INT_CHAN_0=disable
CTRL_D3=1, CTRL_D2=0 Æ INT_CHAN_0=PC3 of port-2
CTRL_D3=0, CTRL_D2=0 Æ INT_CHAN_0=PC3&!PC7 of port-2
The EN0 can be used to enable/disable the INT_CHAN_0 as following: (refer to
Sec. 3.3.4)
EN0=0 Æ INT_CHAN_0=disable
EN0=1 Æ INT_CHAN_0=enable
The INV0 can be used to invert/non-invert the PC3 or PC3&!PC7 as following:
(Refer to Sec. 3.3.6)
INV0=0 Æ INT_CHAN_0=inverted state of (PC3 or PC3&!PC7 of port-2)
INV0=1 Æ INT_CHAN_0=non-inverted state of (PC3 or PC3&!PC7 of port-2)
Refer to demo program for more information as following:
DEMO8.C Æ for INT_CHAN_0 only (PC3 of port-2)
DEMO9.C Æ for INT_CHAN_0 only (PC3&!PC7 of port-2)
OME-PIO-D48 User Manual, Sep/2000, V2.1 ----- 12
Page 15
If the PC3 is a level signal, the interrupt service routine should use INV0 to
inverted/non-inverted the PC3 for high_pulse generation as following:
void interrupt irq_service()/* this ISR is in DEMO8.C */
{
if (now_int_state==1) /* now PC3 is changed to LOW */(a)
{ /* --> INT_CHAN_3=!PC3=HIGH now */
COUNT++; /* find a LOW_pulse (PC3) */
If((inport(wBase+7)&1)==0)/* the PC3 is still fixed in LOW */
Æ
{ /*
outportb(wBase+0x2a,1);/* INV0 select the non-inverted input */(b)
/* INT_CHAN_0=PC3=LOW --> */
/* INT_CHAN_0 generate a high_pulse */
now_int_state=0; /* now PC3=LOW */
}
else now_int_state=1; /* now PC3=HIGH */
/* (no need to generate high_pulse) */
}
else /* now PC3 is changed to HIGH */(c)
{ /* --> INT_CHAN_0=PC3=HIGH now */
/* find a HIGH_pulse (PC3) */
If((inport(wBase+7)&1)==1)/* the PC3 is still fixed in HIGH */
{ /* need to generate a high_pulse */
outportb(wBase+0x2a,0);/* INV0 select the inverted input */(d)
/* INT_CHAN_0=!PC3=LOW --> */
/* INT_CHAN_0 generate a high_pulse */
now_int_state=1; /* now PC3=HIGH */
}
else now_int_state=0; /* now PC3=LOW */
/* (no need to generate high_pulse) */
}
if (wIrq>=8) outportb(A2_8259,0x20);
outportb(A1_8259,0x20);
}
PC3
INV0
INT_CHAN_0
(a)(b)(c)(d)
need to generate a high_pulse */
OME-PIO-D48 User Manual, Sep/2000, V2.1 ----- 13
Page 16
2.5.3 INT_CHAN_1
INT_CHAN_1
01
00
10
Inverted/Noninverted select
The INT_CHAN_1 must be fixed in low level state normally and
must generate a high_pulse to interrupt the PC.
The INT_CHAN_1 can be equal to PC3&!PC7 or PC3 programmable as
following:(refer to Sec. 3.3.9)
Disable
PC3&!PC7(port-5)
PC3(port-5)
(INV1)
Enable/Disable select
(EN1)
CTRL_D5=0, CTRL_D4=1 Æ INT_CHAN_1=disable
CTRL_D5=1, CTRL_D4=0 Æ INT_CHAN_1=PC3 of port-5
CTRL_D5=0, CTRL_D4=0 Æ INT_CHAN_1=PC3&!PC7 of port-5
The EN1 can be used to enable/disable the INT_CHAN_1 as following: (refer to
Sec. 3.3.4)
EN1=0 Æ INT_CHAN_1=disable
EN1=1 Æ INT_CHAN_1=enable
The INV1 can be used to invert/non-invert the PC3 or PC3&!PC7 as following:
(Refer to Sec. 3.3.6)
INV1=0 Æ INT_CHAN_1=inverted state of (PC3 or PC3&!PC7 of port-5)
INV1=1 Æ INT_CHAN_1=non-inverted state of (PC3 or PC3&!PC7 of port-5)
Refer to demo program for more information as following:
DEMO10.C Æ for INT_CHAN_1 only (PC3&!PC7 of port-5)
NOTE: refer to Sec. 2.5.2 for active high-pulse generation.
OME-PIO-D48 User Manual, Sep/2000, V2.1 ----- 14
Page 17
2.5.4 INT_CHAN_2
INT_CHAN_2
Cout0
PC0
(port-2)
The INT_CHAN_2 must be fixed in low level state normally and
must generate a high_pulse to interrupt the PC.
The PC0 (port-2) can be inverted/non-inverted programmable as following:
(refer to Sec. 3.3.9)
CTRL_D1=0 Æ Cin0=PC0 of port-2
CTRL_D1=1 Æ Cin0=!PC0 of port-2
Inverted/Noninverted
select
(CTRL-D1))
Inverted/Noninverted
select
(INV2)
Enable/Disable
select
(EN2)
The EN2 can be used to enable/disable the INT_CHAN_2 as following: (refer to
Sec. 3.3.4)
EN2=0 Æ INT_CHAN_2=disable
EN2=1 Æ INT_CHAN_2=enable
The INV2 can be used to invert/non-invert the Cout0 as following: (Refer to Sec.
3.3.6)
INV2=0 Æ INT_CHAN_2=inverted state of (Cout0)
INV2=1 Æ INT_CHAN_2=non-inverted state of (Cout0)
Refer to demo program for more information as following:
DEMO7.C Æ for INT_CHAN_2 only (Cout0)
NOTE: refer to Sec. 2.5.2 for active high-pulse generation.
OME-PIO-D48 User Manual, Sep/2000, V2.1 ----- 15
Page 18
2.5.5 INT_CHAN_3
INT_CHAN_3
The INT_CHAN_3 must be fixed in low level state normally and
Cout2
Cout1
2M/32768 Hz
select
(CTRL-D0)
Inverted/Noninverted
select
(INV3)
Enable/Disable
select
(EN3)
generated a high_pulse to interrupt the PC.
The Cin1 can be 2M/32768Hz programmable as following: (refer to Sec. 3.3.9)
CTRL_D0=0 Æ Cin1=2M clock source
CTRL_D0=1 Æ Cin1=32768 Hz clock source
The EN3 can be used to enable/disable the INT_CHAN_3 as following: (refer to
Sec. 3.3.4)
EN3=0 Æ INT_CHAN_3=disable
EN3=1 Æ INT_CHAN_3=enable
The INV3 can be used to invert/non-invert the Cout0 as following: (Refer to Sec.
3.3.6)
INV2=3 Æ INT_CHAN_3=inverte of (Cout2)
INV2=3 Æ INT_CHAN_3=non-inverte of (Cout2)
Refer to demo program for more information as following:
DEMO4.C Æ for INT_CHAN_3 only (Cout2)
NOTE: refer to Sec. 2.5.2 for active high-pulse generation.
OME-PIO-D48 User Manual, Sep/2000, V2.1 ----- 16
Page 19
2.6 Daughter Boards
2.6.1 OME-DB-37
The OME-DB-37 is a general purpose daughter board for D-sub 37 pins. It is
designed for easy wire connection.
2.6.2 OME-DN-37 & OME-DN-50
The OME-DN-37 is a general purpose daughter board for OME-DB-37 with DIN-Rail
Mounting. The OME-DN-50 is designed for 50-pin flat-cable header. Those boards are
designed for easy wire connection. Both have Din-Rail mounting.
37pin cable
OME-DN-37
2.6.3 OME-DB-8125
The OME-DB-8125 is a general purpose screw terminal board designed for ease of
wiring. There are one DB-37 & two 20-pin flat-cable headers in the OME-DB-8125.
37pin cable
OME-DB-8125
(OME-DB-37 or
20-pin flat-cable header)
OME-PIO-D48 User Manual, Sep/2000, V2.1 ----- 17
Page 20
2.6.4 OME-ADP-37/PCI & OME-ADP-50/PCI
The OME-ADP-37/PCI & OME-ADP-50/PCI are extender for 50-pin header.
One side of OME-ADP-37/PCI & OME-ADP-50/PCI can be connected to a 50-pin
header. The other side can be mounted on the PC chassis as following:
OME-ADP-37/PCI: 50-pin header to OME-DB-37 extender.
OME-ADP-50/PCI: 50-pin header to 50-pin header extender.
NOTE: The user can choose the suitable extender for his own applications.
OME-PIO-D48 User Manual, Sep/2000, V2.1 ----- 18
Page 21
2.6.5 OME-DB-24P/PD Isolated Input Board
The OME-DB-24P/DB-24PD is a 24-channel isolated digital input daughter board.
The optically isolated inputs of the OME-DB-24P/DB-24PD, consists of a bi-directional
opto-coupler with a resistor for current sensing. You can use the OME-DB-24P/DB-
24PD to sense DC signal from TTL levels up to 24V or use the DB-24P to sense a wide
range of AC signals. You can use this board to isolate the computer from large common-
mode voltage, ground loops and transient voltage spike that often occur in industrial
environments.
OME-PIO-D48
Opto-Isolated
OME-PIO-D48
50Pin cable
OME-DB-24P
AC or DC Signal
0V to 24V
+
-
OME-DB-24P OME-DB-24PD
50-pin flat-cable header Yes Yes
D-sub 37-pin header No Yes
Other specifications Same
OME-PIO-D48 User Manual, Sep/2000, V2.1 ----- 19
Page 22
2.6.6 OME-DB-24R/RD Relay Board
The OME-DB-24R/DB-24RD, 24-channel relay output board, consists of 24 Form
C relays for efficient switch of load by programmed control. The relay are energized by
apply 12V/24V signal to the appropriated relay channel on the 50-pin flat connector.
There are 24 enunciator LEDs for each relay, light when their associated relay is
activated.
From C Relay
50Pin cable
OME-PIO-D48
Normal Open
Normal Close
Com
OME-DB-24R
Note:
Channel : 24 From C Relays
Relay : Switching up to 0.5A at 110ACV
or 1A at 24DCV
OME-DB-24R OME-DB-24RD
50-pin flat-cable header Yes Yes
D-sub 37-pin header No Yes
Other specifications Same
The other output daughter boards are given as following:
OME-DB-24R, OME-DB-24RD 24*Relay (120V, 0.5A)
OME-DB-24PR, OME-DB-24PRD 24* Power Relay (250V, 5A)
It is recommended to read the release note first. All important information will be given
in release note as following:
1. where you can find the software driver & utility
2. how to install software & utility
3. where is the diagnostic program
4. FAQ
There are many demo program given in the company floppy disk or CD. After
the software installation, the driver will be installed into disk as following:
• \TC\*.* Æ for Turbo C 2.xx or above
• \MSC\*.* Æ for MSC 5.xx or above
• \BC\*.* Æ for BC 3.xx or above
• \TC\LIB\*.* Æ for TC library
• \TC\DEMO\*.* Æ for TC demo program
• \TC\LIB\Large\*.* Æ TC large model library
• \TC\LIB\Huge\*.* Æ TC huge model library
• \TC\LIB\Large\PIO.H Æ TC declaration file
• \TC\\LIB\Large\TCPIO_L.LIB Æ TC large model library file
• \TC\LIB\Huge\PIO.H Æ TC declaration file
• \TC\\LIB\Huge\TCPIO_H.LIB Æ TC huge model library file
• \MSC\LIB\Large\PIO.H Æ MSC declaration file
• \MSC\LIB\Large\MSCPIO_L.LIB Æ MSC large model library file
• \MSC\LIB\Huge\PIO.H Æ MSC declaration file
• \MSC\\LIB\Huge\MSCPIO_H.LIB Æ MSC huge model library file
• \BC\LIB\Large\PIO.H Æ BC declaration file
• \BC\LIB\Large\BCPIO_L.LIB Æ BC large model library file
• \BC\LIB\Huge\PIO.H Æ BC declaration file
• \BC\\LIB\Huge\BCPIO_H.LIB Æ BC huge model library file
NOTE: The library is validated for all OME-PIO/PISO series cards.
OME-PIO-D48 User Manual, Sep/2000, V2.1 ----- 38
Page 41
4.1 PIO_PISO
/* ------------------------------------------------------------ */
/* Find all PIO_PISO series cards in this PC system */
/* step 1 : plug all PIO_PISO cards into PC */
/* step 2 : run PIO_PISO.EXE */
/* ------------------------------------------------------------ */
#include "PIO.H"
WORD wBase,wIrq;
WORD wBase2,wIrq2;
int main()
{
int i,j,j1,j2,j3,j4,k,jj,dd,j11,j22,j33,j44;
WORD wBoards,wRetVal;
WORD wSubVendor,wSubDevice,wSubAux,wSlotBus,wSlotDevice;
char c;
float ok,err;
clrscr();
wRetVal=PIO_DriverInit(&wBoards,0xff,0xff,0xff); /*for PIO-PISO*/
printf("\nThrer are %d PIO_PISO Cards in this PC",wBoards);
if (wBoards==0 ) exit(0);
NOTE: the PIO_PISO.EXE is valid for all PIO/PISO cards. The user can execute the
PIO_PISO.EXE to get the following information:
• List all PIO/PISO cards installed in this PC
• List all resources allocated to every PIO/PISO cards
• List the wSlotBus & wSlotDevice for specified PIO/PISO card identification.
(refer to Sec. 3.2 for more information)
OME-PIO-D48 User Manual, Sep/2000, V2.1 ----- 39
Page 42
4.1.1 PIO_PISO.EXE for Windows
User can find this utility in the software floppy disk or CD. It is useful for all
PIO/PISO series card.
After executing the utility, detailed information for all OME-PIO/PISO cards that
installed in the PC will be show as following:
OME-PIO-D48 User Manual, Sep/2000, V2.1 ----- 40
Page 43
4.2 DEMO1
/* ------------------------------------------------------------ */
/* demo1 : D/O demo for OME-PIO-D48 */
/* step 1 : connect CN1 of OME-PIO-D48 to OME-DB-24C */
/* step 2 : connect CN2 of OME-PIO-D48 to another OME-DB-24C */
/* step 3 : run DEMO1.EXE */
/* ------------------------------------------------------------ */
#include "PIO.H"
WORD wBase,wIrq;
WORD wBase2,wIrq2;
int main()
{
int i,j,k,jj,dd;
WORD wBoards,wRetVal;
WORD wSubVendor,wSubDevice,wSubAux,wSlotBus,wSlotDevice;
WORD t1,t2,t3,t4,t5;
char c;
/* step 1: find address-mapping of PIO/PISO cards */
clrscr();
wRetVal=PIO_DriverInit(&wBoards,0x80,0x01,0x30); /* for OME-PIO-D48 */
printf("\nThrer are %d PIO_D48 Cards in this PC",wBoards);
if (wBoards==0) exit(0);
printf("\n------------ The Configuration Space ----------------");
for(i=0; i<wBoards; i++)
{
PIO_GetConfigAddressSpace(i,&wBase,&wIrq,&wSubVendor,
&wSubDevice,&wSubAux,&wSlotBus,&wSlotDevice);
/* step 2: enable all D/I/O port */
outportb(wBase,1); /* enable D/I/O */
/* step 3: program 8255-1-PA-PB-PC as output port */
outportb(wBase+0xcc,0x80);/* 8255-1-PA,PB,PC are all output port*/
outportb(wBase+0xc0,0); /* 8255-1-PA initial=0 */
outportb(wBase+0xc4,0); /* 8255-1-PB initial=0 */
outportb(wBase+0xc8,0); /* 8255-1-PB initial=0 */
/* step 4: program 8255-2-PA-PB-PC as output port */
outportb(wBase+0xdc,0x80);/* 8255-2-PA,PB,PC are all output port*/
outportb(wBase+0xd0,0); /* 8255-2-PA initial=0 */
outportb(wBase+0xd4,0); /* 8255-2-PB initial=0 */
outportb(wBase+0xd8,0); /* 8255-2-PB initial=0 */
OME-PIO-D48 User Manual, Sep/2000, V2.1 ----- 41
Page 44
printf("\n----------- Test D/O (DB-24C)--------------");
i=1;
for (;;)
{
/* send test pattern to CN1 of PIO_D48 */
outportb(wBase+0xc0,i); printf("\nOutput=%x",i);
outportb(wBase+0xc4,i);
outportb(wBase+0xc8,i);
/* send test pattern to CN2 of PIO_D48 */
outportb(wBase+0xd0,i);
outportb(wBase+0xd4,i);
outportb(wBase+0xd8,i);
delay(1000);
if (kbhit()!=0)
{
c=getch(); if ((c=='q') || (c=='Q')) return;
}
i=i<<1; /* next bit */
if (i>0x80)
{
i=1;
c=getch();
if ((c=='Q') || (c=='q')) return;
printf("\n----------- Test D/O (DB-24C)--------------");
}
}
PIO_DriverClose();
}
OME-PIO-D48 User Manual, Sep/2000, V2.1 ----- 42
Page 45
4.3 DEMO2
/* ------------------------------------------------------------ */
/* demo1 : D/O demo for OME-PIO-D48 */
/* step 1 : connect CN1 of OME-PIO-D48 to OME-DB-24P */
/* step 2 : connect CN2 of OME-PIO-D48 to another OME-DB-24P */
/* step 3 : run DEMO2.EXE */
/* ------------------------------------------------------------ */
#include "PIO.H"
WORD wBase,wIrq;
WORD wBase2,wIrq2;
int main()
{
int i,j,j1,j2,j3,j4,k,jj,dd,j11,j22,j33,j44;
WORD wBoards,wRetVal,t1,t2,t3,t4,t5;
WORD wSubVendor,wSubDevice,wSubAux,wSlotBus,wSlotDevice;
char c;
float ok,err;
/* step 1: find address-mapping of PIO/PISO cards */
.
.
/* select card_0 */
.
.
/* step 2: enable all D/I/O port */
.
.
/* step 3: program 8255-1-PA-PB-PC as input port */
outportb(wBase+0xcc,0x9B);/* 8255-1-PA,PB,PC are all input port */
/* step 4: program 8255-2-PA-PB-PC as input port */
outportb(wBase+0xdc,0x9B);/* 8255-2-PA,PB,PC are all input port */
printf("\n----------- Test D/I (DB-24P)--------------");
i=1; ok=err=0.0;
for (;;)
{
j1=inportb(wBase+0xc0); /*read D/I data from CN1 of PIO_D48*/
j2=inportb(wBase+0xc4);
j3=inportb(wBase+0xc8);
j11=inportb(wBase+0xd0); /*read D/I data from CN2 of PIO_D48*/
j22=inportb(wBase+0xd4);
j33=inportb(wBase+0xd8);
/* step 6: program 8255-1-PA-PB-PC as input port */
outportb(wBase+0xcc,0x9B);/*8255-1-PA,PB,PC are all output port */
/* step 7: program 8255-2-PA-PB-PC as outport port */
outportb(wBase+0xdc,0x80);/* 8255-2-PA,PB,PC are all input port */
outportb(wBase+0xd0,0); /* 8255-1-PA initial=0 */
outportb(wBase+0xd4,0); /* 8255-1-PB initial=0 */
outportb(wBase+0xd8,0); /* 8255-1-PB initial=0 */
/* step 8: read/write test pattern */
i=1;
for (;;)
{
/* send test pattern to CN2 of PIO_D48 */
outportb(wBase+0xd0,i);
outportb(wBase+0xd4,i);
printf("\nCN1=input, CN2=output, Output=%x",i);
outportb(wBase+0xd8,i);
delay(1000); /* delay for D/O settle time */
/* read test pattern to CN1 of PIO_D48 */
j1=inportb(wBase+0xc0);
j2=inportb(wBase+0xc4);
j3=inportb(wBase+0xc8);
printf(" , DI=[%2x,%2x,%2x]",j1,j2,j3);
delay(1000);
if (kbhit()!=0)
{
c=getch(); if ((c=='q') || (c=='Q')) break;
}
i=i<<1; /* next bit */
if (i>0x80)
{
i=1;
c=getch();
if ((c=='Q') || (c=='q')) return;
printf("\n----------- Test2: D/I/O CN1-CN2 ------------");
}
}
PIO_DriverClose();
}
OME-PIO-D48 User Manual, Sep/2000, V2.1 ----- 46
Page 49
DEMO4
/* ------------------------------------------------------------ */
/* demo 4 : INT_CHAN_3, timer interrupt, demo */
/* (it is designed to be a machine independent timer) */
/* step 1 : run demo4.exe */
/* ------------------------------------------------------------ */
#include "PIO.H"
WORD init_high();
WORD wBase,wIrq;
WORD pio_d48_c0(char cConfig, char cLow, char cHigh);
WORD pio_d48_c1(char cConfig, char cLow, char cHigh);
WORD pio_d48_c2(char cConfig, char cLow, char cHigh);
static void interrupt irq_service();
int COUNT,irqmask,now_int_state;
int main()
{
int i,j;
WORD wBoards,wRetVal,t1,t2,t3,t4,t5;
WORD wSubVendor,wSubDevice,wSubAux,wSlotBus,wSlotDevice;
char c;
DWORD dwVal;
/* step 1: find address-mapping of PIO/PISO cards */
.
.
/* step 2: enable all D/I/O port */
.
.
init_high(); /* interrupt initialize, INIT_CHAN_3 is HIGH now */
COUNT=0;
printf("\n*** show the count of Low_pulse ***\n");
for (;;)
{
printf("\nLow Pulse Count=%d (one low pulse every second)",
COUNT);
if (kbhit()!=0) {getch(); break;}
}
outportb(wBase+5,0); /* disable all interrupt */
PIO_DriverClose();
}
OME-PIO-D48 User Manual, Sep/2000, V2.1 ----- 47
Page 50
/* ------------------------------------------------------------ */
/* Use INT_CHAN_3 as external interrupt signal */
/* program OUT1 to 2 Hz */
pio_d48_c1(0x76,0,0x40); /* COUNTER1,MODE-3,32768/0x4000=2 Hz */
/* program OUT2 to 1 Hz */
/* note: the 8254 need extra 2-clock for initialization */
pio_d48_c2(0xb6,2,0); /* COUNTER2,MODE-3,2/2=1Hz */
for (;;) /* wait COUT2=HIGH */
{
if ((inportb(wBase+7)&8)!=0) break;
}
/* Note: now the COUT2 is HIGH */
/* --> INV3 must select the inverted COUT2 */
/* --> INT_CHAN_3=!COUT2=init_LOW, active_HIGH */
outportb(wBase+0x2a,0); /* select the inverted COUT2 */
/* INT_CHAN_3=!COUT2
now_int_state=1; /* now COUT2 is high */
outportb(wBase+5,8); /* enable INT_CHAN_3 interrupt */
enable();
}
OME-PIO-D48 User Manual, Sep/2000, V2.1 ----- 48
Page 51
void interrupt irq_service()
{
if (now_int_state==1) /* now COUT2 is changed to LOW */
{ /* --> INT_CHAN_3=!COUT2=HIGH now */
COUNT++; /* find a LOW_pulse (COUT2) */
if((inportb(wBase+7)&8)==0) /* the COUT2 is still fixed in LOW */
{ /* --> need to generate a high_pulse*/
outportb(wBase+0x2a,8); /* INV3 select the non-inverted input*/
/* INT_CHAN_3=COUT2=LOW --> */
/* INT_CHAN_3 generate a high_pulse */
now_int_state=0; /* now COUT2=LOW */
}
else now_int_state=1; /* now COUT2=HIGH */
/* (no need to generate high_pulse ) */
}
else /* now COUT2 is changed to HIGH */
{ /* --> INT_CHAN_3=COUT2=HIGH now */
/* find a HIGH_pulse (COUT2) */
if((inportb(wBase+7)&8)==8) /* the COUT2 is still fixed in HIGH */
{ /* --> need to generate a high_pulse */
outportb(wBase+0x2a,0); /* INV3 select the inverted input */
/* INT_CHAN_3=!COUT2=LOW --> */
/* INT_CHAN_3 generate a high_pulse */
now_int_state=1; /* now COUT2=HIGH
*/
}
else now_int_state=0; /* now COUT2=LOW */
/* (no need to generate high_pulse ) */
}
if (wIrq>=8) outportb(A2_8259,0x20);
outportb(A1_8259,0x20);
}
WORD pio_d48_c0(char cConfig, char cLow, char cHigh);
WORD pio_d48_c1(char cConfig, char cLow, char cHigh);
WORD pio_d48_c2(char cConfig, char cLow, char cHigh);
int main()
{
int i,j;
WORD wBoards,wRetVal,t1,t2,t3,t4,t5;
WORD wSubVendor,wSubDevice,wSubAux,wSlotBus,wSlotDevice;
char c;
DWORD dwVal;
unsigned int high,low,count;
/* step 1: find address-mapping of PIO/PISO cards */
.
.
/* step 2: enable all D/I/O port */
.
.
/* step 3: select PC0 of port2 as init_HIGH & active_LOW sinal */
outportb(wBase+0xf0,0); /* CTRL_D1=0 -> init_HIGH, active_LOW */
/* step 4: latch&read COUNTER-0 to compute low-pulse-count */
printf("\n*** 16-bit event down counter ***\n");
/* NOTE : The 8254 need the extra starting two event_clock to */
/* initialize So the counter value before the starting */
/* two clock is error */
pio_d48_c0(0x30,0xff,0xff);/* COUNTER0,mode-0 down count 0xffff */
for (;;)
{
outportb(wBase+0xec,0x00); /* latch counter_0 */
low=inportb(wBase+0xe0); /* read low-count */
high=inportb(wBase+0xe0); /* read high-count */
count=(0xff-high)*256+(0xff-low)+2; /* add the starting */
/* two clock */
printf("\nhigh=%x,low=%x,LOW_pulse_count=%u",high,low,count);
if (kbhit()!=0) {getch(); break;}
}
outportb(wBase+5,0); /* disable all interrupt */
PIO_DriverClose();
}
OME-PIO-D48 User Manual, Sep/2000, V2.1 ----- 50
Page 53
DEMO6
/* ------------------------------------------------------------ */
/* demo 6:INT_CHAN_2, 16-bit event counter (no interrupt) */
/* step 1:apply a init_LOW & active_HIGH signal to PC0 of port-2*/
/* step 2:run demo6.exe */
/* ------------------------------------------------------------ */
#include "PIO.H"
WORD init_high();
WORD wBase,wIrq;
WORD pio_d48_c0(char cConfig, char cLow, char cHigh);
WORD pio_d48_c1(char cConfig, char cLow, char cHigh);
WORD pio_d48_c2(char cConfig, char cLow, char cHigh);
int main()
{
int i,j;
WORD wBoards,wRetVal,t1,t2,t3,t4,t5;
WORD wSubVendor,wSubDevice,wSubAux,wSlotBus,wSlotDevice;
char c;
DWORD dwVal;
unsigned int high,low,count;
/* step 1: find address-mapping of PIO/PISO cards */
.
.
/* step 2: enable all D/I/O port */
.
.
/* step 3: select PC0 of port_2 as init_LOW & active_HIGH sinal */
outportb(wBase+0xf0,2); /* CTRL_D1=1 --> init_LOW, active_HIGH */
/* step 4: latch&read COUNTER-0 to compute HIGH_pulse_count */
printf("\n*** 16-bit event down counter ***\n");
/* NOTE : The 8254 need the extra starting two event_clock to */
/* initialize So the counter value before the starting */
/* two clock is error */
pio_d48_c0(0x30,0xff,0xff);/* COUNTER0,mode-0 down count 0xffff */
for (;;)
{
outportb(wBase+0xec,0x00); /* latch counter_0 */
low=inportb(wBase+0xe0); /* read low-count */
high=inportb(wBase+0xe0); /* read high-count */
count=(0xff-high)*256+(0xff-low)+2; /* add the starting two */
/* clock */
printf("\nhigh=%x,low=%x,HIGH_pulse_count=%u",high,low,count);
if (kbhit()!=0) {getch(); break;}
}
outportb(wBase+5,0); /* disable all interrupt */
PIO_DriverClose();
}
DEMO7
/* ------------------------------------------------------------ */
/* demo 7:INT_CHAN_2, 16-bit down-counter (using interrupt) */
/* step 1:apply a init_HIGH & active_LOW signal to PC0 of port-2*/
WORD pio_d48_c0(char cConfig, char cLow, char cHigh);
WORD pio_d48_c1(char cConfig, char cLow, char cHigh);
WORD pio_d48_c2(char cConfig, char cLow, char cHigh);
static void interrupt irq_service();
int COUNT,irqmask,now_int_state;
int main()
{
int i,j;
WORD wBoards,wRetVal,t1,t2,t3,t4,t5;
WORD wSubVendor,wSubDevice,wSubAux,wSlotBus,wSlotDevice;
char c;
DWORD dwVal;
/* step 1: find address-mapping of PIO/PISO cards */
.
.
/* step 2: enable all D/I/O port */
.
.
init_low(); /*interrupt initialize,INT_CHAN_2 now is initial LOW*/
COUNT=0;
printf("\n*** show the count of Low_pulse **\n");
for (;;)
{
printf("\nInterrupt Count=%d (one interrupt=5 low_pulse)"
,COUNT);
if (kbhit()!=0) {getch(); break;}
}
outportb(wBase+5,0); /* disable all interrupt */
PIO_DriverClose();
}
OME-PIO-D48 User Manual, Sep/2000, V2.1 ----- 52
Page 55
/* Use INT_CHAN_2 as external interrupt signal */
WORD init_low()
{
DWORD dwVal;
{
if (now_int_state==0) /* now COUT0 is changed to HIGH */
{ /* --> INT_CHAN_2=COUT0=HIGH now */
COUNT++; /* find a HIGH_pulse (COUT0) */
pio_d48_c0(0x30,3,0); /* COUNTER0,mode-0 down count 3+2=5 */
/* now INT_CHAN_2=COUT0=LOW now --> */
/* INT_CHAN_2 generate a HIGH_pulse */
now_int_state=0; /* now COUT0=LOW */
}
if (wIrq>=8) outportb(A2_8259,0x20);
outportb(A1_8259,0x20);
}
OME-PIO-D48 User Manual, Sep/2000, V2.1 ----- 53
Page 56
DEMO8
/* ------------------------------------------------------------ */
/* demo 8:INT_CHAN_0, interrupt demo */
/* step 1:apply a init_HIGH & active_LOW signal to PC3 of port-2*/
/* (note: PC7 of port-2 is don't care */
/* step 2: run demo8.exe */
/* -------------------------------------------------------------*/
#include "PIO.H"
WORD init_high();
WORD wBase,wIrq;
WORD pio_d48_c0(char cConfig, char cLow, char cHigh);
WORD pio_d48_c1(char cConfig, char cLow, char cHigh);
WORD pio_d48_c2(char cConfig, char cLow, char cHigh);
static void interrupt irq_service();
int COUNT,irqmask,now_int_state;
int main()
{
int i,j;
WORD wBoards,wRetVal,t1,t2,t3,t4,t5;
WORD wSubVendor,wSubDevice,wSubAux,wSlotBus,wSlotDevice;
char c;
DWORD dwVal;
/* step 1: find address-mapping of PIO/PISO cards */
.
/* step 2: enable all D/I/O port */
.
init_high(); /* interrupt initialize, INIT_CHAN_0 is HIGH now */
COUNT=0;
printf("\n*** show the count of Low_pulse **\n");
for (;;)
{
printf("\nLow Pulse Count=%d (initial is HIGH, active is LOW)"
,COUNT);
if (kbhit()!=0) {getch(); break;}
}
outportb(wBase+5,0); /* disable all interrupt */
PIO_DriverClose();
}
/* Use INT_CHAN_0 as external interrupt signal */
WORD init_high()
{
DWORD dwVal;
disable();
outportb(wBase+5,0); /* disable all interrupt */
if (wIrq<8)
{
irqmask=inportb(A1_8259+1);
outportb(A1_8259+1,irqmask & (0xff ^ (1 << wIrq)));
setvect(wIrq+8, irq_service);
}
else
{
irqmask=inportb(A1_8259+1);
outportb(A1_8259+1,irqmask & 0xfb); /* IRQ2 */
outportb(A1_8259+1,irqmask & (0xff ^ (1 << wIrq)));
OME-PIO-D48 User Manual, Sep/2000, V2.1 ----- 54
Page 57
irqmask=inportb(A2_8259+1);
outportb(A2_8259+1,irqmask & (0xff ^ (1 << (wIrq-8))));
setvect(wIrq-8+0x70, irq_service);
}
/* select PC3 of port_2 as interrupt signal */
outportb(wBase+0xf0,0x18); /* CTRL_D3=1,CTRL_D2=0 --> */
/* INT_CHAN_0=PC3 of port_2 */
for (;;) /* wait PC3=HIGH */
{
if ((inportb(wBase+7)&1)!=0) break;
printf("\nWait PC3=HIGH");
}
/* Note: now the PC3 of port-2 is HIGH */
/* --> INV0 must select the inverted PC3 */
/* --> INT_CHAN_0=!PC3=init_LOW, active_HIGH */
outportb(wBase+0x2a,0); /* select the inverted PC3 */
/* INT_CHAN_0=!PC3
now_int_state=1; /* now PC3 is high */
outportb(wBase+5,1); /* enable INT_CHAN_0 interrupt */
enable();
}
void interrupt irq_service()
{
if (now_int_state==1) /* now PC3 is changed to LOW
*/
{ /* --> INT_CHAN_3=!PC3=HIGH now */
COUNT++; /* find a LOW_pulse (PC3)
*/
if((inportb(wBase+7)&1)==0) /* the PC3 is still fixed in LOW */
{ /* --> need to generate a high_pulse */
outportb(wBase+0x2a,1); /* INV0 select the non-inverted input*/
/* INT_CHAN_0=PC3=LOW -->
*/
/* INT_CHAN_0 generate a high_pulse */
now_int_state=0; /* now PC3=LOW
*/
}
else now_int_state=1; /* now PC3=HIGH */
/* (no need to generate high_pulse ) */
}
else /* now PC3 is changed to HIGH */
{ /* --> INT_CHAN_0=PC3=HIGH now */
/* find a HIGH_pulse (PC3)
*/
if((inportb(wBase+7)&1)==1) /* the PC3 is still fixed in HIGH */
{ /* --> need to generate a high_pulse */
outportb(wBase+0x2a,0); /* INV0 select the inverted input */
/* INT_CHAN_0=!PC3=LOW --> */
/* INT_CHAN_0 generate a high_pulse */
now_int_state=1; /* now PC3=HIGH */
}
else now_int_state=0; /* now PC3=LOW */
/* (no need to generate high_pulse ) */
}
if (wIrq>=8) outportb(A2_8259,0x20);
outportb(A1_8259,0x20);
}
OME-PIO-D48 User Manual, Sep/2000, V2.1 ----- 55
Page 58
DEMO9
/*--------------------------------------------------------------*/
/*demo 9:INT_CHAN_0, interrupt demo */
/*step 1:apply a init_HIGH & active_LOW signal to PC3 of port-2 */
/* note: The PC7 of port_2 is used to enable the interrupt*/
/* operation, if PC7=GND --> PC3_interrupt is enable */
/* if PC7=VCC --> PC3_interrupt is disable */
/*----------------- or -----------------------------------------*/
/*step 1:apply a init_LOW & active_HIGH signal to PC7 of port-2 */
/* note: The PC3 of port_2 is used to enable the interrupt*/
/* operation, if PC3=VCC --> PC7_interrupt is enable */
/* if PC3=GND --> PC7_interrupt is disable) */
/*----------------------- --------------------------------------*/
/*step 2:run demo9.exe */
/*--------------------------------------------------------------*/
#include "PIO.H"
WORD init_high();
WORD wBase,wIrq;
WORD pio_d48_c0(char cConfig, char cLow, char cHigh);
WORD pio_d48_c1(char cConfig, char cLow, char cHigh);
WORD pio_d48_c2(char cConfig, char cLow, char cHigh);
static void interrupt irq_service();
int COUNT,irqmask,now_int_state;
int main()
{
int i,j;
WORD wBoards,wRetVal,t1,t2,t3,t4,t5;
WORD wSubVendor,wSubDevice,wSubAux,wSlotBus,wSlotDevice;
char c;
DWORD dwVal;
/* step 1: find address-mapping of PIO/PISO cards */
.
.
/* step 2: enable all D/I/O port */
.
.
init_high(); /* interrupt initialize, INIT_CHAN_0 is HIGH now */
COUNT=0;
printf("\n*** show the count of Low_pulse **\n");
for (;;)
{
printf("\nLow Pulse Count=%d (initial is HIGH, active is LOW)"
,COUNT);
if (kbhit()!=0) {getch(); break;}
}
outportb(wBase+5,0); /* disable all interrupt */
PIO_DriverClose();
}
OME-PIO-D48 User Manual, Sep/2000, V2.1 ----- 56
Page 59
/* Use INT_CHAN_0 as external interrupt signal */
WORD init_high()
{
DWORD dwVal;
/* select PC3 & PC7 of port_2 as interrupt signal */
outportb(wBase+0xf0,0x10); /* CTRL_D3=0,CTRL_D2=0 --> */
/* INT_CHAN_0=PC3&!PC7 -> */
/* PC7 can enable/disable PC3 */
/* PC3 can enable/disable PC7 */
/* Note: In this demo, assume the PC3 is init_HIGH & active_LOW */
/* the PC7 is used to enable/disable PC3 --> */
/* PC7=VCC --> PC3-interrupt is disable */
/* PC7=GND --> PC3-interrupt is enable */
/* ------------------------------------------------------------ */
/* now the PC3 of port-2 is HIGH */
/* --> INV0 must select the inverted PC3 */
/* --> INT_CHAN_0=!PC3=init_LOW, active_HIGH */
outportb(wBase+0x2a,0); /* select the inverted PC3 */
/* INT_CHAN_0=!PC3 */
now_int_state=1; /* now PC3 is high */
outportb(wBase+5,1); /* enable INT_CHAN_0 interrupt */
for (;;) /* wait PC3&!PC7=HIGH */
{
if ((inportb(wBase+7)&1)!=0) break;
printf("\nWait PC3&!PC7=HIGH");
}
enable();
}
OME-PIO-D48 User Manual, Sep/2000, V2.1 ----- 57
Page 60
void interrupt irq_service()
{
if (now_int_state==1) /* now PC3 is changed to LOW
*/
{ /* --> INT_CHAN_3=!PC3=HIGH now */
COUNT++; /* find a LOW_pulse (PC3)
*/
if((inportb(wBase+7)&1)==0) /* the PC3 is still fixed in LOW */
{ /* --> need to generate a high_pulse */
outportb(wBase+0x2a,1); /* INV0 select the non-inverted input*/
/* INT_CHAN_0=PC3=LOW --> */
/* INT_CHAN_0 generate a high_pulse */
now_int_state=0; /* now PC3=LOW
*/
}
else now_int_state=1; /* now PC3=HIGH */
/* (no need to generate high_pulse ) */
}
else /* now PC3 is changed to HIGH */
{ /* --> INT_CHAN_0=PC3=HIGH now */
/* find a HIGH_pulse (PC3)
*/
if((inportb(wBase+7)&1)==1) /* the PC3 is still fixed in HIGH */
{ /* --> need to generate a high_pulse */
outportb(wBase+0x2a,0); /* INV0 select the inverted input */
/* INT_CHAN_0=!PC3=LOW --> */
/* INT_CHAN_0 generate a high_pulse */
now_int_state=1; /* now PC3=HIGH */
}
else now_int_state=0; /* now PC3=LOW */
/* (no need to generate high_pulse ) */
}
if (wIrq>=8) outportb(A2_8259,0x20);
outportb(A1_8259,0x20);
}
/*--------------------------------------------------------------*/
/*demo 10:INT_CHAN_1, interrupt demo */
/*step 1 :apply a init_HIGH & active_LOW signal to PC3 of port-5*/
/* note:The PC7 of port_5 is used to enable the interrupt*/
/* operation, if PC7=GND --> PC3_interrupt is enable */
/* if PC7=VCC --> PC3_interrupt is disable) */
/*step 2 :run demo10.exe */
/*--------------------------------------------------------------*/
#include "PIO.H"
WORD init_high();
WORD wBase,wIrq;
WORD pio_d48_c0(char cConfig, char cLow, char cHigh);
WORD pio_d48_c1(char cConfig, char cLow, char cHigh);
WORD pio_d48_c2(char cConfig, char cLow, char cHigh);
static void interrupt irq_service();
int COUNT,irqmask,now_int_state;
int main()
{
int i,j;
WORD wBoards,wRetVal,t1,t2,t3,t4,t5;
WORD wSubVendor,wSubDevice,wSubAux,wSlotBus,wSlotDevice;
char c;
DWORD dwVal;
/* step 1: find address-mapping of PIO/PISO cards */
.
.
/* step 2: enable all D/I/O port */
.
.
init_high(); /* interrupt initialize, INIT_CHAN_1 is HIGH now */
COUNT=0;
printf("\n*** show the count of Low_pulse **\n");
for (;;)
{
printf("\nLow Pulse Count=%d (initial is HIGH, active is LOW)"
,COUNT);
if (kbhit()!=0) {getch(); break;}
}
outportb(wBase+5,0); /* disable all interrupt */
PIO_DriverClose();
}
/* select PC3 & !PC7 of port_5 as interrupt signal */
outportb(wBase+0xf0,0x04); /* CTRL_D5=0,CTRL_D4=0 --> */
/* INT_CHAN_1=PC3&!PC7 -> */
/* PC7 can enable/disable PC3 */
/* Note: In this demo, assume the PC3 is init_HIGH & active_LOW */
/* the PC7 is used to enable/disable PC3 --> */
/* PC7=VCC --> PC3-interrupt is disable */
/* PC7=GND --> PC3-interrupt is enable */
/* ------------------------------------------------------------ */
/* now the PC3 of port-5 is HIGH */
/* --> INV1 must select the inverted PC3 */
/* --> INT_CHAN_1=!PC3=init_LOW, active_HIGH */
outportb(wBase+0x2a,0); /* select the inverted PC3 */
/* INT_CHAN_1=!PC3 */
now_int_state=1; /* now PC3 is high */
outportb(wBase+5,2); /* enable INT_CHAN_1 interrupt */
for (;;) /* wait PC3&!PC7=HIGH */
{
if ((inportb(wBase+7)&2)!=0) break;
printf("\nWait PC3&!PC7=HIGH");
}
enable();
}
OME-PIO-D48 User Manual, Sep/2000, V2.1 ----- 60
Page 63
void interrupt irq_service()
{
if (now_int_state==1) /* now PC3 is changed to LOW
*/
{ /* --> INT_CHAN_1=!PC3=HIGH now */
COUNT++; /* find a LOW_pulse (PC3)
*/
if((inportb(wBase+7)&2)==0) /* the PC3 is still fixed in LOW */
{ /* --> need to generate a high_pulse */
outportb(wBase+0x2a,2); /* INV1 select the non-inverted input*/
/* INT_CHAN_1=PC3=LOW --> */
/* INT_CHAN_1 generate a high_pulse */
now_int_state=0; /* now PC3=LOW
*/
}
else now_int_state=1; /* now PC3=HIGH */
/* (no need to generate high_pulse ) */
}
else /* now PC3 is changed to HIGH */
{ /* --> INT_CHAN_1=PC3=HIGH now */
/* find a HIGH_pulse (PC3) */
if((inportb(wBase+7)&2)==2) /* the PC3 is still fixed in LOW */
{ /* --> need to generate a high_pulse */
outportb(wBase+0x2a,0); /* INV1 select the inverted input */
/* INT_CHAN_1=!PC3=LOW --> */
/* INT_CHAN_1 generate a high_pulse */
now_int_state=1; /* now PC3=HIGH */
}
else now_int_state=0; /* now PC3=HIGH */
/* (no need to generate high_pulse ) */
}
if (wIrq>=8) outportb(A2_8259,0x20);
outportb(A1_8259,0x20);
}
/* --------------------------------------------------------------- */
/* demo 11 : INT_CHAN_0 & INT_CHAN_1 interrupt demo */
/* step 1 : apply a init_HIGH & active_LOW signal to PC3 of port-2 */
/* (note: PC7 of port-2 is don't care */
/* step 2 : apply a init_HIGH & active_LOW signal to PC3 of port-5 */
/* (note: PC7 of port-5 is don't care */
/* step 3 : run demo11.exe */
/* --------------------------------------------------------------- */
WORD pio_d48_c0(char cConfig, char cLow, char cHigh);
WORD pio_d48_c1(char cConfig, char cLow, char cHigh);
WORD pio_d48_c2(char cConfig, char cLow, char cHigh);
static void interrupt irq_service();
int irqmask,now_int_state,invert,new_int_state,int_c;
int INT0_H,INT0_L,INT1_H,INT1_L;
int main()
{
int i,j;
WORD wBoards,wRetVal,t1,t2,t3,t4,t5;
WORD wSubVendor,wSubDevice,wSubAux,wSlotBus,wSlotDevice;
char c;
DWORD dwVal;
/* step 1: find address-mapping of PIO/PISO cards */
clrscr();
wRetVal=PIO_DriverInit(&wBoards,0x80,0x01,0x30); /* for OME-PIO-D48
*/
printf("\nThrer are %d PIO_D48 Cards in this PC",wBoards);
if (wBoards==0) exit(0);
/* select PC3 of port_2 & PC3 of port_5 as interrupt signal */
outportb(wBase+0xf0,0x28); /* CTRL_D5/4/3/2=1010 --> */
/* INT_CHAN_0=PC3 of port_2 */
/* INT_CHAN_1=PC3 of port_5 */
/* Note: now both PC3 are HIGH */
/* --> INV0, INV1 must select the inverted PC3 */
/* --> INT_CHAN_0=!PC3 of port_2=init_LOW, active_HIGH */
/* --> INT_CHAN_1=!PC3 of port_5=init_LOW, active_HIGH */
invert=0;
outportb(wBase+0x2a,invert); /* select the inverted PC3 */
/* INT_CHAN_0=!PC3 of port_2 */
/* INT_CHAN_1=!PC3 of port_5 */
now_int_state=3; /* now both PC3 are high */
outportb(wBase+5,3); /* enable INT_CHAN_0 & INT_CHAN_1 */
for (;;) /* wait both PC3 are HIGH */
{
if ((inportb(wBase+7)&3)!=0) break;
printf("\nWait PC3 of port-2 & PC3 of port-5 are HIGH");
}
/* NOTE:1.The hold-time of INT_CHAN_0&INT_CHAN_1 must long enough.*/
/* 2.The ISR must read the interrupt status again to */
/* the active interrupt sources. */
/* 3.The INT_CHAN_0&INT_CHAN_1 can be active at the same */
/* time. */
/* -------------------------------------------------------------- */
void interrupt irq_service()
{
/* now ISR can not know which interrupt is active */
new_int_state=inportb(wBase+7)&0x03; /* read all interrupt */
/* signal states */
int_c=new_int_state ^ now_int_state; /* compare new_state to */
/* old_state */
/* INT_CHAN_0 & INT_CHAN_1 can be active at the same time */
if ((int_c&0x01) !=0 ) /* INT_CHAN_0 is active */
{
if ((new_int_state&1)==0)/* now INT_CHAN_0 is changed to LOW */
{
INT0_L++;
}
else /* now INT_CHAN_0 is changed to HIGH */
{
INT0_H++;
}
invert=invert^1; /* to generate a HIGH_pulse */
}
if ((int_c&0x02) !=0 ) /* INT_CHAN_1 is active */
{
if ((new_int_state&2)==0)/* now INT_CHAN_1 is changed to LOW */
{
INT1_L++;
}
else /* now INT_CHAN_1 is changed to HIGH */
{
INT1_H++;
}
invert=invert^2; /* to generate a HIGH_pulse */
}
now_int_state=new_int_state;/* update interrupt status */
outportb(wBase+0x2a,invert);/* generate a HIGH_pulse */
if (wIrq>=8) outportb(A2_8259,0x20);
outportb(A1_8259,0x20);
}
OME-PIO-D48 User Manual, Sep/2000, V2.1 ----- 64
Page 67
WARRANTY/DISCLAIMER
OMEGA ENGINEERING, INC. warrants this unit to be free of defects in materials and workmanship for a
period of 13 months from date of purchase. OMEGA’s WARRANTY adds an additional one (1) month
grace period to the normal one (1) year product warranty to cover handling and shipping time. This
ensures that OMEGA’s customers receive maximum coverage on each product.
If the unit malfunctions, it must be returned to the factory for evaluation. OMEGA’s Customer Service
Department will issue an Authorized Return (AR) number immediately upon phone or written request.
Upon examination by OMEGA, if the unit is found to be defective, it will be repaired or replaced at no
charge. OMEGA’s WARRANTY does not apply to defects resulting from any action of the purchaser,
including but not limited to mishandling, improper interfacing, operation outside of design limits,
improper repair, or unauthorized modification. This WARRANTY is VOID if the unit shows evidence of
having been tampered with or shows evidence of having been damaged as a result of excessive corrosion;
or current, heat, moisture or vibration; improper specification; misapplication; misuse or other operating
conditions outside of OMEGA’s control. Components which wear are not warranted, including but not
limited to contact points, fuses, and triacs.
OMEGA is pleased to offer suggestions on the use of its various products. However,
OMEGA neither assumes responsibility for any omissions or errors nor assumes liability for any
damages that result from the use of its products in accordance with information provided by
OMEGA, either verbal or written. OMEGA warrants only that the parts manufactured by it will be
as specified and free of defects. OMEGA MAKES NO OTHER WARRANTIES OR
REPRESENTATIONS OF ANY KIND WHATSOEVER, EXPRESS OR IMPLIED, EXCEPT THAT OF TITLE,
AND ALL IMPLIED WARRANTIES INCLUDING ANY WARRANTY OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. LIMITATION OF
LIABILITY: The remedies of purchaser set forth herein are exclusive, and the total liability of
OMEGA with respect to this order, whether based on contract, warranty, negligence,
indemnification, strict liability or otherwise, shall not exceed the purchase price of the
component upon which liability is based. In no event shall OMEGA be liable for
consequential, incidental or special damages.
CONDITIONS: Equipment sold by OMEGA is not intended to be used, nor shall it be used: (1) as a “Basic
Component” under 10 CFR 21 (NRC), used in or with any nuclear installation or activity; or (2) in medical
applications or used on humans. Should any Product(s) be used in or with any nuclear installation or
activity, medical application, used on humans, or misused in any way, OMEGA assumes no responsibility
as set forth in our basic WARRANTY/ DISCLAIMER language, and, additionally, purchaser will indemnify
OMEGA and hold OMEGA harmless from any liability or damage whatsoever arising out of the use of the
Product(s) in such a manner.
RETURN REQUESTS/INQUIRIES
Direct all warranty and repair requests/inquiries to the OMEGA Customer Service Department. BEFORE
RETURNING ANY PRODUCT(S) TO OMEGA, PURCHASER MUST OBTAIN AN AUTHORIZED RETURN
(AR) NUMBER FROM OMEGA’S CUSTOMER SERVICE DEPARTMENT (IN ORDER TO AVOID
PROCESSING DELAYS). The assigned AR number should then be marked on the outside of the return
package and on any correspondence.
The purchaser is responsible for shipping charges, freight, insurance and proper packaging to prevent
breakage in transit.
FOR W
ARRANTY
RETURNS, please have the
following information available BEFORE
contacting OMEGA:
1. Purchase Order number under which the product
was PURCHASED,
2. Model and serial number of the product under
warranty, and
3. Repair instructions and/or specific problems
relative to the product.
FOR NON-W
ARRANTY
REPAIRS,
consult OMEGA
for current repair charges. Have the following
information available BEFORE contacting OMEGA:
1. Purchase Order number to cover the COST
of the repair,
2. Model and serial number of the product, and
3. Repair instructions and/or specific problems
relative to the product.
OMEGA’s policy is to make running changes, not model changes, whenever an improvement is possible. This affords
our customers the latest in technology and engineering.
reproduced, translated, or reduced to any electronic medium or machine-readable form, in whole or in part, without the
prior written consent of OMEGA ENGINEERING, INC.