DIO1 DEMO PROGRAM - DOS
For programming the DIO1 digital I/O board in a DOS- based PC/104 embedded system, it is necessary to use compilers with direct hardware access runtime library functions. Most compilers offer some functions for writing bytes to I/O ports (byte output functions) and for reading bytes from I/O ports (byte input funtions) in the 80x86 I/O address space. With the byte output functions, you can write a bit pattern direct to the DIO1 ROUTL and ROUTH registers for switching the DIO1 relays on and off. For reading the current state of the DIO1 opto- isolated input channels, use the byte input functions for reading the DIO1 registers DINPL and DINPH.

The C demo sourcecode in this document shows the DIO1 usage in a DOS environment. The code is written for Borland C/C++ compilers (version 3.x). This Borland compilers offers a byte output function with the name outportb for writing a byte to a I/O port and the byte input function inportb for reading a byte from a I/O port in the 80x86 I/O address space. Download the C sourcecode and the DOS EXE files - 12.674 bytes WinZip file, see also "dio1demo.zip - More Information". If you are running the dio1demo.exe on your embedded PC, please note the command- line options. This program offers several command- line options that may be useful when running dio1demo.exe; these options are shown with the function UseHelp below:

void UseHelp ()
{
   printf ("\n   DIO1DEMO.EXE   Version 1.00   (c) SSV SOFTWARE SYSTEMS 1998");
   printf ("\n   ===========================================================");
   printf ("\n   Usage..= DIO1DEMO [/xxx] [/a]‹return›");
   printf ("\n   [/xxx].= Parameter, Option. xxx= DIO1 BaseAddr in Hex.");
   printf ("\n   [/a]...= Parameter, Option. AutoTestMode, no wait for keys");
   printf ("\n   Example= DIO1DEMO /320 /a   (BaseAddr= 0x320, AutoTestMode)");
   printf ("\n   Example= DIO1DEMO /320      (BaseAddr= 0x320)");
   printf ("\n   Example= DIO1DEMO           (Use Default BaseAddr= 0x300)");
   printf ("\n");
}

Square brackets indicate options that may be included in the command line. You may choose one or more options if you desire. Starting each option with a "/", separating the options with a blank space. One command- line option is the DIO1 base address (200h, 220h, 280h, 2A0h, 300h, 320h, 380h, or 3A0h). Without this option the program uses the default base address of 300h.


// File...: DIO1DEMO.C (c) SSV SOFTWARE SYSTEMS 1998
// Version: 1.00 (Build 3 - 16 Bit DOS)
// Date...: 27.Jul.1998

//              *** DISCLAIMER OF WARRENTY ***
// =======================================================                                                                       
// THIS  CODE AND INFORMATION IS PROVIDED "AS IS"  WITHOUT         
// A  WARRANTY OF  ANY KIND, EITHER  EXPRESSED OR  IMPLIED,        
// INCLUDING  BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF         
// MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.

// Typedefs

typedef unsigned char BYTE;
typedef unsigned int  WORD;

// Includes

#include ‹stdlib.h›
#include ‹stdio.h›
#include ‹graphics.h›
#include ‹conio.h›
#include ‹dos.h›
#include ‹bios.h›
#include ‹string.h›

// Defines

#ifdef __cplusplus
   #define __CPPARGS ...
#else
   #define __CPPARGS
#endif
#define TRUE                1
#define FALSE               0
#define DIO1BASE        0x300             // DIO1 Default Base Addr
#define ROUTL        DIO1BASE             // DIO1 ROUTL Register
#define ROUTH      DIO1BASE+1             // DIO1 ROUTH Register
#define DINPL      DIO1BASE+2             // DIO1 DINPL Register
#define DINPH      DIO1BASE+3             // DIO1 DINPH Register
#define MASTER_PIC       0x20             // Base Addr. Master PIC
#define SLAVE_PIC        0xa0             // Base Addr. Slave PIC
#define EOI              0x20             // PIC EndOfInterrupt Command
#define IRQ1                1             // Interrupt Request 1
#define IRQ2                2             // Interrupt Request 2
#define IRQ3                3             // Interrupt Request 3
#define IRQ4                4             // Interrupt Request 4
#define IRQ5                5             // Interrupt Request 5
#define IRQ6                6             // Interrupt Request 6
#define IRQ7                7             // Interrupt Request 7
#define IRQ8                8             // Interrupt Request 8
#define IRQ9                9             // Interrupt Request 9
#define IRQ10              10             // Interrupt Request 10
#define IRQ11              11             // Interrupt Request 11
#define IRQ12              12             // Interrupt Request 12
#define IRQ13              13             // Interrupt Request 13
#define IRQ14              14             // Interrupt Request 14
#define IRQ15              15             // Interrupt Request 15

// Internal Function Prototyps

BYTE           ReadPort   (WORD);
void           WritePort  (WORD, BYTE);
void           SendEOI    (BYTE);
void           EnableIRQ  (BYTE);
void           DisableIRQ (BYTE);
void           SetIRQ     (BYTE, void interrupt (*) ());
int            Dio1Test   (WORD, BYTE);
void           UseHelp    ();
int            CheckParam (char *);
void           main       (int, char * []);

//***************************************************************************

BYTE ReadPort (WORD wPortAddr)
{
   return (inportb (wPortAddr));
}

//***************************************************************************

void WritePort (WORD wPortAddr, BYTE bData)
{
   outportb (wPortAddr, bData);
}

//***************************************************************************

void SendEOI (BYTE  bIrqNumber)
{
   if (bIrqNumber › 7) WritePort (SLAVE_PIC, EOI);
   WritePort (MASTER_PIC, EOI);
}

//***************************************************************************

void EnableIRQ (BYTE bIrqNumber)
{
   int nPort;

   // Build PIC Mask Port Addr. (BaseAddr + 1)...

   nPort= (bIrqNumber ‹= 7) ? MASTER_PIC : SLAVE_PIC;
   nPort++;

   bIrqNumber &= 0x0007;
   WritePort (nPort, ReadPort (nPort) & ~(1 ‹‹ bIrqNumber));
}

//***************************************************************************

void DisableIRQ (BYTE bIrqNumber)
{
   int nPort;

   // Build PIC Mask Port Addr. (BaseAddr + 1)...

   nPort= (bIrqNumber ‹= 7) ? MASTER_PIC : SLAVE_PIC;
   nPort++;

   bIrqNumber &= 0x0007;
   WritePort (nPort, ReadPort (nPort) | (1 ‹‹ bIrqNumber));
}

//***************************************************************************

void SetIRQ (BYTE bIrqNumber, void interrupt (*IrqHandler) (__CPPARGS))
{
   switch (bIrqNumber) {
      case IRQ1 : setvect (0x09, IrqHandler); break;
      case IRQ2 : setvect (0x0a, IrqHandler); break;
      case IRQ3 : setvect (0x0b, IrqHandler); break;
      case IRQ4 : setvect (0x0c, IrqHandler); break;
      case IRQ5 : setvect (0x0d, IrqHandler); break;
      case IRQ6 : setvect (0x0e, IrqHandler); break;
      case IRQ7 : setvect (0x0f, IrqHandler); break;
      case IRQ8 : setvect (0x70, IrqHandler); break;
      case IRQ9 : setvect (0x71, IrqHandler); break;
      case IRQ10: setvect (0x72, IrqHandler); break;
      case IRQ11: setvect (0x73, IrqHandler); break;
      case IRQ12: setvect (0x74, IrqHandler); break;
      case IRQ13: setvect (0x75, IrqHandler); break;
      case IRQ14: setvect (0x76, IrqHandler); break;
      case IRQ15: setvect (0x77, IrqHandler); break;
      default   : break;
   }
}

//***************************************************************************

int Dio1Test (WORD wBaseAdr, BYTE bMode)
{
   BYTE bDinpl, bDinph;
   BYTE bOutValue[]= {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
   char szError[16];
   int  i, nErrorCount= 0;

   // Header Printout...

   printf ("\n  DIO1DEMO.EXE Vers. 1.00      DIO1 BaseAddr= 0x%02x", wBaseAdr);
   printf ("\n  =================================================");

   // Write TestPattern to DIO1 Outport LowByte and read Inport LowByte...

   WritePort (wBaseAdr+1, 0x00);
   for (i= 0; i ‹ 8; i++) {

      // Write TestPattern and wait...

      WritePort (wBaseAdr, bOutValue[i]);
      delay (200);

      // Read Inport and test BitPattern...

      bDinpl= ReadPort (wBaseAdr+2);
      bDinph= ReadPort (wBaseAdr+3);
      if (bDinpl == bOutValue[i] && bDinph == 0x00)
         strcpy (szError, "OK....");
      else {
	     nErrorCount++;
	     strcpy (szError, "ERROR.");
      }

      // Print Message OK/ERROR, wait for Key if NOT AutoTestMode...

      if (!bMode) printf ("\n  ROUTL= 0x%02x. DINPL= 0x%02x. %s Press any key...",
			  bOutValue[i], bDinpl, szError);
      else printf ("\n  ROUTL= 0x%02x. DINPL= 0x%02x. %s Auto Test Mode..",
		   bOutValue[i], bDinpl, szError);
      if (!bMode) getch ();
   }

   // Write TestPattern to DIO1 Outport HighByte and read Inport HighByte...

   WritePort (wBaseAdr, 0x00);
   for (i= 0; i ‹ 8; i++) {

      // Write TestPattern and wait...

      WritePort (wBaseAdr+1, bOutValue[i]);
      delay (200);

      // Read Inport and test BitPattern...

      bDinpl= ReadPort (wBaseAdr+2);
      bDinph= ReadPort (wBaseAdr+3);
      if (bDinph == bOutValue[i] && bDinpl == 0x00)
	     strcpy (szError, "OK....");
      else {
	     nErrorCount++;
	     strcpy (szError, "ERROR.");
      }

      // Print Message OK/ERROR, wait for Key if NOT AutoTestMode...

      if (!bMode) printf ("\n  ROUTH= 0x%02x. DINPH= 0x%02x. %s Press any key...",
			  bOutValue[i], bDinph, szError);
      else printf ("\n  ROUTH= 0x%02x. DINPH= 0x%02x. %s Auto Test Mode..",
		   bOutValue[i], bDinph, szError);
      if (!bMode) getch ();
   }

   // Trailer Printout...

   WritePort (wBaseAdr+1, 0x00);
   printf ("\n  =================================================");
   printf ("\n  %d Error(s).", nErrorCount);
   printf ("\n");
   return (nErrorCount);
}

//***************************************************************************

void UseHelp ()
{
   printf ("\n   DIO1DEMO.EXE   Version 1.00   (c) SSV SOFTWARE SYSTEMS 1998");
   printf ("\n   ===========================================================");
   printf ("\n   Usage..= DIO1DEMO [/xxx] [/a]‹return›");
   printf ("\n   [/xxx].= Parameter, Option. xxx= DIO1 BaseAddr in Hex.");
   printf ("\n   [/a]...= Parameter, Option. AutoTestMode, no wait for keys");
   printf ("\n   Example= DIO1DEMO /320 /a   (BaseAddr= 0x320, AutoTestMode)");
   printf ("\n   Example= DIO1DEMO /320      (BaseAddr= 0x320)");
   printf ("\n   Example= DIO1DEMO           (Use Default BaseAddr= 0x300)");
   printf ("\n");
}

//***************************************************************************

int CheckParam (char *szParam)
{
   if (strcmp (szParam, "/A") == 0 || strcmp (szParam, "/a") == 0) return (1);
   if (strcmp (szParam, "/200") == 0) return (2);
   if (strcmp (szParam, "/220") == 0) return (3);
   if (strcmp (szParam, "/280") == 0) return (4);
   if (strcmp (szParam, "/2a0") == 0 || strcmp (szParam, "/2A0") == 0) return (5);
   if (strcmp (szParam, "/300") == 0) return (6);
   if (strcmp (szParam, "/320") == 0) return (7);
   if (strcmp (szParam, "/380") == 0) return (8);
   if (strcmp (szParam, "/3a0") == 0 || strcmp (szParam, "/3A0") == 0) return (9);
   return (0);
}

//***************************************************************************

void main (int argc, char *argv[])
{
   int  i, nErrFlag= FALSE, nMode= 0;
   WORD wBaseAddr= 0x300;

   // Check ParameterCount...

   if (argc › 3) {
      UseHelp ();
      exit (1);
   }

   // Check Parameter and set BaseAddr and/or ModeFlag...

   for (i= 1; i ‹ argc; i++) {
      switch (CheckParam (argv[i])) {
         case  1: nMode= 1; break;
	 case  2: wBaseAddr= 0x200; break;
	 case  3: wBaseAddr= 0x220; break;
	 case  4: wBaseAddr= 0x280; break;
	 case  5: wBaseAddr= 0x2a0; break;
	 case  6: wBaseAddr= 0x300; break;
	 case  7: wBaseAddr= 0x320; break;
	 case  8: wBaseAddr= 0x380; break;
	 case  9: wBaseAddr= 0x3a0; break;
	 default: nErrFlag= TRUE; break;
      }
   }

   // Exit here if any ParameterError...

   if (nErrFlag == TRUE) {
      UseHelp ();
      exit (1);
   }

   // Execute DIO1 Test...

   exit (Dio1Test (wBaseAddr, (BYTE) nMode));
}


| Home Page | Back to top |

SSV SOFTWARE SYSTEMS PC/104 Products. Software Support. File: P138.HTM, Last Update: 12-Sept.-2000
Copyright (c) 1996 - 2000 WST. All rights reserved.