Comtrol API 6508 User Manual

1
RocketPort/ISA
API (6508) for the MS-DOS
Operating System
First Edition, December 1993 Revised April 1994
Copyright © 1993, 1994, 1995, 1996. Comtrol Corporation. All Rights Reserved. Comtrol Corporation makes no representations or warranties with regard to
the contents of this guide or to the suitability of the Comtrol controllers for any particular purpose.
RocketPort
Trademarks
The Comtrol logo is a registered trademark of Control Systems, Inc. Comtrol is a trademark of Comtrol Corporation. The RocketPort series is a registered trademark of Comtrol Corporation. Borland is a registered trademark of Borland International, Inc. Microsoft and Product names mentioned herein may be trademarks and/or registered
trademarks of their respective companies.
MS-DOS are registered trademarks of Microsoft Corporation.
Document Number: 6508D1.
ELE
2
Before You Begin
Scope
This guide describes the following information about the DOS application program interface (
Installing the software and hardware
Running the sample application
Developing applications
Note: If you want to install the Interrupt 14 device driver, see the Reference
Card.
API) for RocketPort controllers:
Purpose
This guide explains installing and using the API functions.
Audience
This guide is for people who develop applications for the MS-DOS system.
Prerequisites
This guide assumes that you are running an ISA-based personal computer with the following:
MS-DOS operating system (level 5.0 or higher)
One of the following compilers:
®
- A Borland
- A Microsoft
C++ compiler (level 3.1 and higher)
®
C/C++ compiler (level 7.0 and higher)
Organization
Section 1. Installing RocketPort Systems
Provides you with the following information:
Product introduction
Software and hardware installation overview
Installing the software and hardware
Configuring controllers
Running the sample application
Section 2. Developing Applications
Provides you with information about how to develop applications using the
Section 3. Troubleshooting and Technical Support
Provides you with troubleshooting and technical support information for your RocketPort series controller.
Appendix A.
Contains the
Appendix B. Double Buffering Example
Illustrates the double buffering example on your diskette.
API Functions
API asynchronous functions available for writing the application.
API.
Software or Document Changes
For information that is not in this guide, see the README.API file on the software diskette. If this file is empty, that means that this guide reflects the
API on the diskette.
Suggestions
Use Chapter 1 to install the API. Use Chapter 2 and AppendixA to develop applications that run with the
API. If you have any problems, see Chapter 3.
3
Table of Contents
Before You Begin
Scope ...........................................................................................2
Purpose........................................................................................2
Audience......................................................................................2
Prerequisites...............................................................................2
Suggestions.................................................................................2
Organization...............................................................................2
Software or Document Changes ................................................2
Table of Contents
Examples.....................................................................................3
Flowchart....................................................................................4
Tables..........................................................................................4
Section 1. Installing RocketPort Systems
1.1. Product Introduction.........................................................5
1.2. Software and Hardware Installation Procedures............5
1.3. Installing the Software.....................................................5
1.4. Installing the Controller...................................................7
1.5. Running the Sample Application .....................................8
Section 2. Developing Applications
API Features......................................................................9
2.1.
API Functions ....................................................................9
2.2.
2.3. Writing the Configuration File.......................................10
2.4. Flowchart for Using the
2.5. Application Example.......................................................11
2.6. Include Files (Step 3)......................................................12
2.7. Configuring RocketPort Controllers (Step4).................12
2.8. Using
2.9. Writing Serial Data.........................................................15
2.10. Exiting the Application...................................................15
2.11. Reading Serial Data........................................................15
2.12. Installing and Detecting Events.....................................15
2.13. Double Buffering Transmit and Receive Data .............17
API Calls (Step 5)..................................................12
2.8.1. Understanding Device Numbers.........................13
2.8.2. Configuration Parameters for Serial Devices ....13
2.8.2.1. Open Type Parameter...........................13
2.8.2.2. Baud Parameter ....................................14
2.8.2.3. Parity Parameter...................................14
2.8.2.4. Data Bits Parameter .............................14
2.8.2.5. Stop Bits Parameter..............................14
2.8.2.6. Flow Control Parameter........................14
2.8.2.7. Detection Enable Parameter.................15
2.8.2.8. Modem Control Parameter ...................15
API...........................................11
2.14. Building Applications (Step 6).......................................17
Section 3. Troubleshooting and Technical Support
3.1. Resolving Installation Problems....................................18
3.2. Placing a Support Call....................................................19
3.3. Retrieving Future Software Updates ............................20
Appendix A.
Appendix B. Double Buffering Example
API Functions
aaChangeModemState....................................22
aaClose.............................................................22
aaEnPeriodicEvent..........................................23
aaExit...............................................................23
aaFlush ............................................................24
aaGetCtlStatus................................................24
aaGetModemStatus.........................................25
aaGetRxCount.................................................25
aaGetRxStatus ................................................26
aaGetTxCount .................................................26
aaInit................................................................27
aaInstallCtrlCHandler....................................27
aaInstallMdmChgEvent..................................28
aaInstallPeriodicEvent ...................................28
aaInstallRxEvent ............................................29
aaOpen.............................................................29
aaRead .............................................................30
aaReadWithStatus ..........................................31
aaReconfigure..................................................31
aaSendBreak ...................................................32
aaSetCloseDelay..............................................33
aaWrite ........................................................... 33
EvModemChange ............................................34
EvPeriodic........................................................35
EvRxData.........................................................35
Examples
Example 2-1. Sample Event Function....................................16
4
Flowcharts
Tables
Flowchart 1-1. Hardware and Software Installation
Overview ...........................................................5
Flowchart 2-1. How to Use the
API.........................................11
Table 1-1. Common Switch Settings.......................................6
Table 2-1.
API Functions..........................................................9
Table 2-2. Configuration File Parameters............................10
Table 2-3. Mapping Device Numbers....................................13
Table 2-4. Open Type Flags...................................................13
Table 2-5. Baud Flags............................................................13
Table 2-6. Parity Flags ..........................................................14
Table 2-7. Data Bits Flags.....................................................14
Table 2-8. Stop Bits Flags......................................................14
Table 2-9. Flow Control Flags ...............................................14
Table 2-10. Detection Enable Flags ........................................15
Table 2-11. Modem Control Output Flags..............................15
Table 3-1. System Table 3-2. System
I/O Addresses – Up to 3FF ......................18
I/O Address Aliases – Above 3FF............18
Table 3-3. Support Call Information.....................................19
Table A-1.
API Function Reference........................................21
5 Installating RocketPort/ISA Systems
Section 1. Installating RocketPort/ISA Systems
This section contains a product overview and discusses installing the API for your system. The
DOS API and Interrupt 14 device driver are delivered on one
diskette.
Note: See the Int 14 Reference Card for Interrupt 14 information.
1.1. Product Introduction
The RocketPort multiport serial controller series fits into a 16-bit ISA slot of a personal computer. The RocketPort series uses a 36 designed to process asynchronous serial communications, thereby maximizing performance and eliminating bottlenecks.
RocketPort series uses Application Specific Integrated Circuits ( technology to replace most hardware components, including:
The processor
Serial controller
Bus interface logic and other miscellaneous logic The RocketPort series is The RocketPort series supports
I/O mapped eliminating memory mapping conflicts.
RS-232 or RS-422 mode and connects easily to
the interface box or your peripherals, depending on the type of RocketPort controller you purchased.
The device driver supports up to four RocketPort controllers (128 ports) in one
PC. You can install any combination of the series, which includes the following:
Name
Number
of Ports
RocketPort 4* 4 Requires interface box RocketPort 4J 4 RJ45 cables not included
RocketPort Quadcable* 4
Includes a fanout cable with standard DB25 or
DB9 connectors
RocketPort 8 8 Requires interface box RocketPort 8J 8 RJ11 cables not included
RocketPort Octacable 8
RocketPort 16 16
RocketPort 32 32
Includes a fanout cable with standard DB25 or
DB9 connectors
Requires 16-port interface box (Standard DB25 or Rack Mount RJ45 available)
Requires two 16-port interface boxes (Standard
DB25 or Rack Mount RJ45 available)
The RocketPort series is easy to install using Subsection 1.2.
MHz processor specifically
ASICs)
Interface Type
1.2. Software and Hardware Installation Procedures
Use Flowchart1-1 for an overview of installing a RocketPort series system.
Install the API (see 1.3).
Set the switches on the controller and install the controller (see 1.4).
Update the
Connect the interface box to the controller your peripherals to the interface box (if you have not already done so). For specific cabling information, see the appropriate Hardware Reference Card.
Develop applications using Section 2 and Appendix A.
AUTOEXEC.BAT file.
(if applicable) and
Flowchart 1-1. Hardware and Software Installation Overview
Note: If you have an installation or operations problem, see Chapter 3.
1.3. Installing the Software
You may want to install the API in a directory named \ROCKET so that the examples illustrated in this guide match your environment.
The following shows a sample installation onto your hard disk (assuming the hard disk is drive C):
1. Insert the Comtrol appropriate drive.
2. Change to the drive that you installed the diskette on.
3. Enter the following:
install
4. Select the API button by pressing <Enter> or <Click>. <Click> means that you should move the cursor over the item and press the mouse button.
API and Device Driver for MS-DOS diskette into the
6 Installating RocketPort/ISA Systems
Installating RocketPort/ISA Systems
ON
1 2 3 4 5 6 7 8
ON
1 2 3 4 5 6 7 8
ON
1 2 3 4 5 6 7 8
ON
1 2 3 4 5 6 7 8
Controller #3 Controller #4
ON
ON
ON
ON
Note: Press <F1> on any item for button-sensitive Help.
5. Select the a. Use the<Tab> key and the <
<click> on the arrow next to the
I/O address range for each RocketPort series controller.
ALT> <Down Arrow> key combination or
I/O Address Range box to view the I/O
address ranges.
b. Use an <Arrow> key or the mouse cursor to highlight the
I/O range you
want to select.
c. Press <Enter> or <Click> to execute the selection.
I/O address identifies the location in the system’s I/O space used to pass
The control information between the system and the controller.
For the first controller, you will select a 68-byte
I/O address range. For
subsequent controllers, you will select a 64-byte range. Most peripherals use
I/O address ranges between 0 and 3FF hexadecimal.
If you have peripherals installed above 400h, you may experience an conflict.
RocketPort controllers use
I/O address range. Make sure that other peripherals in the system do not
use these
I/O usage.
I/O address ranges. See Table3-1 for information about common
4. Enter a path name for the default path,
5. Select an interrupt (
\ROCKET.
IRQ) for the controller that does not conflict with an
I/O address ranges at 400h intervals above the
API directory, if you do not want to use the
existing interrupt.
6. Select <Ok to Install>.
7. Select <
8. Set the
OK> at the confirmation screen.
DIP switches on the controller as directed in the summary screen.
You may want to fill in the blank switches provided for you or place a check mark in Table 1-1, which illustrates common
Press <
ENTER> to view the DIP switch settings for additional controllers.
I/O ranges.
I/O
if you do not set them at this time.
9. Make sure that you note the line that you must add to the
AUTOEXEC.BAT
file. For example:
SET ROCKETCFG=C:\ROCKET\CONFIG.DAT
This path is the same path where the
API is installed.
Note: After you create your own applications, you may need to change the
configuration file (see Subsection 2.3).
10. When your cursor returns to the
DOS prompt, remove the diskette from the
drive.
11. Edit the
AUTOEXEC.BAT file as directed in Step 9.
Go to the next subsection to install the controller.
Table 1-1. Common Switch Settings
Controller #1
I/O Address
Range
100 - 143 hex
140 - 183 hex
1st ISA 2nd ISA
3rd ISA 4th ISA
1st ISA 2nd ISA
3rd ISA 4th ISA
DIP Switch Settings
Controller #1 determines other
controller settings
1 2 3 4 5 6 7 8
ON
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8
ON
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8
ON
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8
ON
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8
Controller #1 Controller #2
Notes:You may want to set the
DIP switches for the controllers while
180 - 1C3 hex (Default)
1st ISA 2nd ISA
3rd ISA 4th ISA
ON
1 2 3 4 5 6 7 81 2 3 4 5 6 7 8
ON
looking at the summary screen. You can also use the
\ROCKET\INSTALL.LOG file to set the switches,
Installating RocketPort/ISA Systems
O
ON
ON
ON
ON
ON
ON
3rd ISA
4th ISA
ON
ON
Table 1-1. Common Switch Settings (Continued)
Controller #1
I/O Address
Range
200 - 243 hex
240 - 283 hex
280 - 2C3 hex
300 - 343 hex
340 - 383 hex
1st ISA 2nd ISA
3rd ISA 4th ISA
1st ISA 2nd ISA
3rd ISA 4th ISA
1st ISA 2nd ISA
3rd ISA 4th ISA
1st ISA 2nd ISA
3rd ISA 4th ISA
1st ISA 2nd ISA
DIP Switch Settings
Controller #1 determines other
controller settings
1 2 3 4 5 6 7 8
ON
1 2 3 4 5 6 7 81 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8
ON
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8
ON
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8
ON
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8
ON
1 2 3 4 5 6 7 81 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8
N
1 2 3 4 5 6 7 8
ON
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8
ON
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8
ON
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8
ON
Table 1-1. Common Switch Settings (Continued)
Controller #1
I/O Address
Range
380 - 3C3 hex
1st ISA 2nd ISA
3rd ISA 4th ISA
DIP Switch Settings
Controller #1 determines other
controller settings
1 2 3 4 5 6 7 8
ON
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8
ON
1 2 3 4 5 6 7 8
1.4. Installing the Controller
To prepare your controller for installation, you may need to set the I/O address
DIP switch. The default I/O address range is 180 through 1C3. You must
change the select the default address range.
If you did not set the software installation, do so at this time. Make sure that you set each controller as advised during the software installation or use the information in the
\ROCKET\INSTALL.LOG file.
After you set the following steps to install the controller:
1. Turn the power switch for the system unit to the
2. Remove the system unit cover.
3. Select a slot to install the controller.
4. Remove the expansion slot cover.
5. Insert the controller in the expansion slot, make sure that it is properly seated.
6. Attach the controller to the chassis with the expansion slot screw. Repeat Steps3 through 5 for each controller.
7. Replace the cover on the system unit.
If connecting a system with an interface box:
a. Attach the male end of the RocketPort cable to the controller and the
Note: If you have a RocketPort 32, the connector labelled J1 corresponds to
b. Connect the peripherals to the interface box.
Note: The ports on the interface box are numbered from 0 to 3, 7, or 15 on the
I/O address settings on any additional controllers, even if you
DIP switch on the controller or controllers during the
I/O DIP switch, you are ready to install the controller. Use the
OFF position.
female end to the connector on the interface box labeled Host.
ports 0 through 15 on the interface box and the connector labeled J2 (closest to the bus) corresponds to ports 16 through 31.
standard
DB25 interface. The Rack Mount RJ45 interface is numbered
Installating RocketPort/ISA Systems 7
8 Installating RocketPort/ISA Systems
Installating RocketPort/ISA Systems
from 1 to 16.
c. If applicable, set each port to the appropriate communications mode
RS-232 or RS-422) for your peripheral using the slide switch.
(
If connecting a system with a Quad/Octacable:
a. Attach the male end of the Quad/Octacable to the controller. b. Connect the Quad/Octacable to the peripherals.
If connecting a RocketPort
a. Connect your peripheral devices to the
4J or 8J controller:
RJ style connector on the
controller.
After installing and configuring the controller, you are ready to attach your peripherals. Refer to the Hardware Reference Card if you need information about the pinouts for the connectors.
After connecting the peripherals, you can go to the next subsection to run the sample application. The sample application shows you how to use the
API.
Use Section 2 and Appendix A to develop applications.
1.5. Running the Sample Application
The sample program, TERM, is a simple terminal emulator program which uses one RocketPort port at a time. port 0 of the Comtrol interface box with an for both transmit and receive. The terminal should be configured for 9,600 baud, 8 data bits, 1 stop bit, and no parity.
Optionally, if you do not have an available terminal to run the sample application, you can use the loopback plug that came with your controller.
Note: If your configuration is different, you must change the parameters in the
aaOpen call to match your requirements. Make sure you recompile before running the sample program.
Use the following procedure to run the sample program: At the
12. Type
DOS prompt, change to the c:\ROCKET\SAMPLE directory.
TERM at the DOS prompt. The following displays:
Serial Device Number:
Optionally, insert the loopback plug in Port 0 of the interface box.
TERM uses an ASCII terminal connected to
RS-232 cable. This allows testing
13. Type 0 and then press <Enter>. The following displays:
Serial Device Number 0 Hit F10 to Quit
The
TERM application allows you to type any character on the PC keyboard
and have it appear on the terminal, and type any character on the terminal and have it appear on the
PC screen.
Optionally, if you are using the loopback plug, any character that you type on the keyboard appears on the screen.
14. Enter several characters using the keystrokes appear on the
ASCII terminal.
15. Enter several characters using the see these keystrokes appear on the
PC keyboard. You should see these
ASCII terminal keyboard. You should
PC screen.
If the sample fails, see Section 3. Use Section 2 and Appendix A to develop applications.
9 Developing Applications
Section 2. Developing Applications
This section describes the following topics:
API features and functions
Writing the configuration file
Using the
Include files
Configuring the controllers
Using
- Understanding device numbers
- Configuration parameters for serial devices
Writing serial data
Exiting the application
Reading serial data
Installing and detecting events
Building applications
API (flowchart and example)
API calls to write the application
2.1. API Features
The API contains the following features:
Supports up to 4 RocketPort controllers in a
Supports up to 32 serial devices per controller.
Provides baud rates from 50 to 230.4 K baud.
Supports all modem control lines available on the controller.
Provides detection of modem control line changes.
Provides direct control of modem control outputs.
Provides direct read of modem control inputs.
Provides detection of receive errors:
- Parity
- Receiver overrun
- Framing
- Buffer overflow
Supports buffering.
Supports hardware (
Supports software (
Provides read counts of buffered transmit and receive data.
1K bytes of receive data buffering and 256 bytes of transmit data
RTS/CTS) flow control.
XON/XOFF) flow control.
PC.
Provides send break and receive break detection.
Provides installable event functions for the following:
- Receive data available
- Modem control changes
- Periodic event
For information about event functions see Subsection 2.12.
2.2. API Functions
Table2-1 lists API functions that are available to a system application. For detailed information about the functions, see AppendixA.
Table 2-1.
Function Name Description
aaChangeModemState Changes the state of modem
aaClose Closes a device. aaEnPeriodicEvent Enables/disables dispatching of
aaExit Performs cleanup when exiting
aaFlush Flushes transmit or receive
aaGetCtlStatus Gets controller status. aaGetModemStatus Gets modem status. aaGetRxCount Gets count of data bytes available
aaGetRxStatus Gets status of receive buffer. aaGetTxCount Gets count of data bytes in
aaInit Executes controller and
aaInstallCtrlCHandler Installs a handler for the
API Functions
output lines.
periodic event function.
application.
buffer, or both.
in receive buffer.
transmit buffer.
API
initialization.
CTRL+C
key interrupt.
10 Developing Applications
Table 2-1.
API Functions (Continued)
Function Name Description
aaInstallMdmChgEvent Installs an event function to
handle modem change events.
aaInstallPeriodicEvent Installs a periodic event function. aaInstallRxEvent Installs an event function to
handle Rx data available events.
aaOpen Opens a device for reading or
writing, or both.
aaRead Reads serial data. aaReadWithStatus Reads serial data and status. aaReconfigure Reconfigures communication
parameters.
aaSendBreak Sends a break signal. aaSetCloseDelay Sets the maximum aaClose()
transmit drain delay.
aaWrite Writes serial data. EvModemChange* Modem control input change
event function.
EvPeriodic* Periodic event function. EvRxData* Receive data available event
function.
* These are not part of the API, but are part of the application.
2.3. Writing the Configuration File
The configuration file is used by the aaInit() function to obtain information about all the RocketPort controllers installed in the system. The aaInit() function checks the and path of this file.
When you installed the were instructed to place the following line in your AUTOEXEC.BAT file:
SET ROCKETCFG=filepath
where filepath is the complete path to the configuration file. This path is the same path where the
ROCKETCFG environment variable to determine the name
API, the configuration file was created for you, and you
API was installed.
The initial configuration file allows you to run the sample application program (
TERM), but when you create and distribute your own application you may wish
to use a different configuration file. The configuration file contains between two and five lines:
The first line gives the
IRQ number that is used by all RocketPort
controllers.
The second through fifth lines give the starting
I/O addresses for the first
through the fourth controllers
The first controller uses a 68-byte block of controllers use 64-byte blocks.
I/O address lines should be placed in the file only
I/O address space, subsequent
for controllers that are actually installed in the system. Table2-2 summarizes this information.
Table 2-2. Configuration File Parameters
Line
Number
1
Parameter Allowable Values
IRQ number 3, 4, 5, 9, 10, 11, 12,
Block
Size
NA
15
2 Ctrl 1 I/O 100, 140, 180, 1C0,
68 bytes 200, 240, 280, 2C0, 300, 340, 380
3 Ctrl 2
I/O 100, 140, 180, 1C0,
64 bytes 200, 240, 280, 2C0, 300, 340, 380
4 Ctrl 3
I/O 100, 140, 180, 1C0,
64 bytes 200, 240, 280, 2C0, 300, 340, 380
5 Ctrl 4
I/O 100, 140, 180, 1C0,
64 bytes 200, 240, 280, 2C0, 300, 340, 380
Each RocketPort controller uses up to three additional “alias”
I/O address
ranges located at 400h intervals above the address ranges described above. For example, if the first controller is addressed at 100, the
I/O address ranges
used by that controller are:
100 - 143
500 - 543
900 - 943
D00 - D43 This is normally of no concern because
I/O addressing, meaning they are limited to addresses below 400h.
ISA peripherals often use only 10 bits of
Note: In order for your application to locate the configuration file, the
ETCFG SET
environment variable must point to it. This is done with the DOS
command, usually placed in the AUTOEXEC.BAT file.
ROCK-
Step 1
Step 2
Create a new subdirectory called
Copy the appropriate make file from the
\ROCKET\SAMPLE directory into the \ROCKET\CUSTOM directory.
Developing Applications
\ROCKET\CUSTOM.
2.4. Flowchart for Using the API
This subsection contains the steps required to write and execute an application program using the in the following subsections.
The remainder of this chapter assumes that the named directory called
\ROCKET, and that you will place your application source code in a new
\ROCKET\CUSTOM.
You may wish to create your own directory structure for source code. In that case, these instructions and the make files must be adjusted accordingly. A complete application demonstrating the use of the
\ROCKET\SAMPLE directory.
API. Each of these steps are described in detail
API is installed in a directory
API is provided in the
Step 3
Step 4
Step 5
Step 6
Step 7
Write the application source files. Make sure that you provide #include statements for the
The first action in the main() is to call the aaInstallCtrlCHandler() and aaInit() functions.
Write the remainder of your application using API calls to access the serial devices as needed: * Open, reconfigure, and close * Write and read serial data * Modem control outputs * Receive and modem change events * Call aaExit() before leaving the application
Build the application.
Execute the application.
Flowchart 2-1. How to Use the
API.H file.
API
2.5. Application Example
The following application corresponds to the previous flowchart and the following subsections explain specific steps in detail.
#include <stdio.h> #include <dos.h> #include <process.h> #include <stdlib.h> #include <conio.h> #include "api.h" Step 3
main(void) { unsigned int InitReturn; char Buf[80]; int i,Dev,Cnt,Err;
(2.6)
Developing Applications 11
12 Developing Applications
Developing Applications
/* Initialize API */ aaInstallCtrlCHandler(); if((InitReturn = aaInit()) != { (2.7) printf("Init fail: %x\n",InitReturn); aaExit(); exit(1); }
/* Get serial device and display terminal emulator screen */ printf("Serial Device Number (0-15): "); gets(Buf); /* get serial device */ Step 5 sscanf(Buf,"%d",&Dev); (2.8­ system("cls"); /* clear screen */ 2.12) printf("Serial Device Number %d\t\t\tHit F10 to Quit\n",Dev);
/* Open the device */ if((Err = aaOpen(Dev,
COM_TX | COM_RX, COM_BAUD_9600, COM_PAR_NONE, COM_DATABIT_8, COM_STOPBIT_1, COM_FLOW_NONE, COM_DEN_PARITY | COM_DEN_RXOVR | COM_DEN_FRAME, COM_MDM_DTR)) != 0)
{ printf("Failure - Could not open device number %d, Error %d\n",Dev,Err); aaExit(); /* required exit(1); (2.13) } /* Infinite loop to handle console while(1) { /* Attempt to read char from serial device and write to screen */ if((Cnt = aaRead(Dev,80,(unsigned char *)Buf)) > 0) { for(i = 0;i < Cnt;i++) putch(Buf[i]); }
/* Attempt to read char from keyboard and write to serial device */ if((bdos(11,0,0) & 0xff) == 0xFF) /* if char waiting */ { Buf[0] = bdos(8,0,0) & 0xff; /* read keybd char */ if((Buf[0] == '\0') && ((bdos(11,0,0)&0xff) == 0xff)) /* 2 char key */ { Buf[1] = bdos(8,0,0) & 0xff; /* 2nd key */ if(Buf[1] == 0x44) /* F10 = quit */ break; } aaWrite(Dev,1,(unsigned char *)Buf); /* write char to serial device */ } }
NO_ERR) Step 4
API call before exiting */ Step 6
I/O and serial I/O */
aaClose(Dev, aaExit(); /* required return(0); }
COM_MDM_RTS | COM_MDM_DTR); /* close device */
API call before exiting */
2.6. Include Files (Step 3)
The API.H file must be included in the .C source code files.
2.7. Configuring RocketPort Controllers (Step4)
Configuration of the RocketPort controllers and the API is done using aaInit(), as shown in the previous example. The aaInit() function must be called once before any other
API function (except aaInstallCtrlCHandler()) can be called. It
performs the configuration using the information in the configuration file given in the
ROCKETCFG environment variable. See Subsection 2.3 for
information about the format and placement of the configuration file.from the system configuration. See Subsection 2.3 for information about the system configuration.
Many applications also require that the
DOS default CTRL+C key handler be
replaced with a handler that calls aaExit() (see Subsection 2.10). This is done using aaInstallCtrlCHandler(). Once installed, this handler calls aaExit() if the user terminates the application by pressing the
CTRL+C or CTRL+BREAK keys.
If the application prevents program termination with these keys, the aaIntallCtrlCHandler() function does not need to be called.
2.8. Using API Calls (Step 5)
The following subsections provide details about Step 5 of the API sample. The topics include:
Device numbers
Configuration parameters for opening, closing, and reconfiguring serial devices
- Open type
- Baud
- Parity
- Data bits
- Stop bits
- Flow control
- Detect enable
Modem Control (output only)
Developing Applications
2.8.1. Understanding Device Numbers
Each serial device is identified by a device number. Most
API functions take
the device number as a parameter. The number of ports that exist on each controller determines which device numbers map to which serial ports on which controllers.
The device numbers always count sequentially from 0, with the first port on the first controller in the configuration file assigned device number 0. Each subsequent controller in the configuration file begins counting where the previous controller left off. If there are more than one RocketPort controllers in the system, the controller in the lowest numbered slot is the first controller.
For example, if there are three controllers located in slots 2, 4, and 5, having 8, 16, and 8 ports respectively, the device numbers would map out as shown in Table2-3.
Table 2-3. Mapping Device Numbers
Device Number
Controller
Number
Slot
Port Number on
the Controller
0 through 7 1 2 0 through 7 8 through 23 2 4 0 through 15 24 through 31 3 5 0 through 7
You can determine how many controllers are installed in your system, the first device number on each controller, and the number of devices on each controller with the aaGetCtlStatus() function.
2.8.2. Configuration Parameters for Serial Devices
Before the application can use a serial device, it must be opened with aaOpen(). To change the communication parameters while the device is open, use aaReconfigure(). Once the line is no longer in use it should be closed with aaClose().
There are a number of communication parameters used with one or more of the aaOpen(), aaReconfigure(), and aaClose() functions. Each of these parameters is described in the following subsections.
2.8.2.1. Open Type Parameter
The open type parameter is used in aaOpen() to identify whether the line is being opened for transmit, receive, or both. The flags used for open type are given in Table2-4. This parameter is declared as follows:
unsigned int OpenType;
Table 2-4. Open Type Flags
Flag Meaning When the Flag is Set
COM_TX COM_RX
Open for transmit Open for receive
2.8.2.2. Baud Parameter
The baud parameter is used with aaOpen() and aaReconfigure() to set the baud rate that the channel will operate at. You can assign only one of the flags shown in Table2-5 to the baud parameter. The baud parameter is declared as follows:
unsigned char Baud;
Table 2-5. Baud Flags
Flag
COM_BAUD_50 COM_BAUD_75 COM_BAUD_110 COM_BAUD_134 COM_BAUD_150 COM_BAUD_200 COM_BAUD_300 COM_BAUD_600 COM_BAUD_1200 COM_BAUD_1800 COM_BAUD_2400 COM_BAUD_3600 COM_BAUD_4800
Meaning When the
Flag is Set
50 baud 75 baud 110 baud 134 baud 150 baud 200 baud 300 baud 600 baud 1,200 baud 1,800 baud 2,400 baud 3,600 baud 4,800 baud
Developing Applications 13
14 Developing Applications
Developing Applications
Table 2-5. Baud Flags (Continued)
Flag
COM_BAUD_7200 COM_BAUD_9600 COM_BAUD_19200 COM_BAUD_38400 COM_BAUD_57600 COM_BAUD_76800 COM_BAUD_115200 COM_BAUD_230400
Meaning When the
Flag is Set
7,200 baud 9,600 baud 19,200 baud 38,400 baud 57,600 baud 76,800 baud 115,200 baud 230,400 baud
2.8.2.3. Parity Parameter
The parity parameter is used by aaOpen() and aaReconfigure() to set the type of parity checking done on receive and parity generation done on transmit. You can assign only one of the flags shown in Table2-6 to the parity parameter. The parity parameter is declared as follows:
unsigned char Parity;
Table 2-6. Parity Flags
Table 2-7. Data Bits Flags
Flag
COM_DATABIT_7 7 data bits COM_DATABIT_8
Meaning When
Flag is Set
8 data bits
2.8.2.5. Stop Bits Parameter
The stop bits parameter is used by aaOpen() and aaReconfigure() to set the number of stop bits used in the framing of each transmitted and received character. You can assign only one of the flags shown in Table2-8 to the stop bits parameter. The stop bits parameter is declared as follows:
unsigned char StopBits;
Table 2-8. Stop Bits Flags
Flag
COM_STOPBIT_1 COM_STOPBIT_2
Meaning When
Flag Set
1 stop bit 2 stop bits
Flag
COM_PAR_NONE COM_PAR_EVEN Even parity
Meaning When
Flag is Set
No parity
2.8.2.6. Flow Control Parameter
The flow control parameter is used by aaOpen() and aaReconfigure() to set the flow control method. You can assign either
COM_FLOW_NONE or any
combination of the remaining flags shown in Table2-9 to the flow control parameter.
COM_PAR_ODD
Odd parity
The flow control parameter is declared as follows:
unsigned int FlowCtl;
2.8.2.4. Data Bits Parameter
The data bits parameter is used by aaOpen() and aaReconfigure() to set the number of data bits in each transmitted and received character. You can assign only one of the flags shown in Table2-7 to the data bits parameter. The data bits parameter is declared as follows:
unsigned DataBits
COM_FLOW_NONE COM_FLOW_IS COM_FLOW_IH
Table 2-9. Flow Control Flags
Flag Meaning When Flag Set
No flow control Enable input software flow control Enable input hardware flow control
RTS
using
Developing Applications
Table 2-9. Flow Control Flags (Continued)
Flag Meaning When Flag Set
COM_FLOW_OS COM_FLOW_OH
COM_FLOW_OXANY
Enable output software flow control Enable output hardware flow control
CTS
using Enable restart output on any Rx
character
2.8.2.7. Detection Enable Parameter
The detection enable parameter is used by aaOpen() and aaReconfigure() to set which events are detected by the
API.
If a detection enable flag is set, an event function within the application is dispatched when that event is detected. This assumes that the application has installed the event function. See Subsection 2.12 for information about event functions.
You can assign any combination of the flags shown in Table2-10 to the detection enable parameter. The detection enable parameter is declared as follows:
unsigned int DetectEn;
Table 2-10. Detection Enable Flags
Flag Meaning When Flag Set
COM_DEN_NONE COM_DEN_MDM
No event detection enabled Enable modem control
change detection
COM_DEN_RDA
Enable receive data available detection
2.8.2.8. Modem Control Parameter
The modem control parameter is used by aaOpen() to determine the initial state of the modem control outputs. If a flag is set, the modem control line is turned
ON; otherwise it is OFF.
It is also used by aaClose() to determine which modem control outputs must be cleared. If a flag is set, that modem control line is turned
OFF; otherwise it is
not changed. The modem control output flags are given in Table2-11. The modem control
parameter is declared as follows:
unsigned ModemCtl;
Table 2-11. Modem Control Output Flags
Flag Modem Control Line
COM_MDM_RTS Request to send COM_MDM_DTR
Data terminal ready
2.9. Writing Serial Data
After a device is open, serial data can be written to it using aaWrite(). The number of data bytes from previous aaWrite() calls that are still awaiting transmission can be obtained with aaGetTxCount().
2.10.Exiting the Application
You must call aaExit() before exiting an application. This does final cleanup, including removing the interrupt service routine (
ISR) used by the API.
2.11.Reading Serial Data
After a device is open serial data can be read from it using aaRead(). The number of receive data bytes that are buffered by the device can be obtained with aaGetRxCount().
Using aaRead() by itself does not return any receive error information. If error information is needed, you can determine if there are any errors in the device’s receive buffer by calling aaGetRxStatus(). If errors exist, you can obtain the error status of each receive data byte by reading the data with aaReadWithStatus().
2.12.Installing and Detecting Events
When the controller needs to notify the system that something important has occurred, it generates an interrupt and causes an event function to execute on the system.
Event functions tell you what has happened and provide the appropriate information for that event, which you can then process as needed.
The following receive events can occur on the system:
Modem change event, one of the modem lines has changed for a serial device.
Receive data event, data has been received on a serial device.
Periodic event, occurs 274 times per second.
You need a way to tie your application to these events. This is accomplished by calling the aaInstallxxxEvent functions. By using an aaInstallxxxEvent function,
Developing Applications 15
16 Developing Applications
Developing Applications
you can give the system software the name of an application program function that executes when a particular event occurs. The following aaInstallxxxEvent functions are available:
aaInstallMdmChangeEvent
aaInstallPeriodicEvent
aaInstallRxEvent
Example2-1 provides event function examples and shows how to install event functions. Notice that installing event functions is done shortly after the controller is initialized.
Even after an event function is installed, it will not be dispatched unless that event has been enabled. Modem change and receive data events are enabled or disabled using the DetectEn parameter in the aaOpen() function. Periodic events are enabled or disabled using the aaEnPeriodicEvent() function.
Example 2-1. Sample Event Function
#define NUMDEV 32 /* max number devices this app supports */ int FirstDev, MaxDev; /* first and maximum device numbers */
unsigned char unsigned char ModemState[
main() /* application main() fragment */ { int NumDev;
/* Initialize controller */ aaInstallCtrlCHandler(); if(aaInit() != { printf("Initialization Failure\n"); aaExit(); exit(1); }
/* Get device number range for 1 controller */ if(aaGetCtlStatus(0,&FirstDev,&NumDev) != { printf("Controller Status Failure\n"); aaExit(); exit(1); } }
MaxDev = FirstDev + NumDev - 1; /* Set up application event functions */
aaInstallRxEvent(EvRxData); aaInstallMdmChangeEvent(aaModemChg); aaInstallPeriodicEvent(EvPeriodic); aaEnPeriodicEvent( .
.
. }
CD_Change[NUMDEV]; /* indicates changes to CD modem input */
NUMDEV]; /* state of modem inputs for each device */
NO_ERR)
NO_ERR)
TRUE);
#pragma check_stack(off) /* Microsoft C only */ void ExRxData(int Dev) /* receive event function */
{ int Count;
Count = aaGetRxCount(Dev); /* get number bytes available */ if(Count > Count = GetRxData(Dev,Count); /* application function to read the data */ }
void EvMdmChg(int Dev,unsigned char MdmChange,unsigned char MdmState) { if(MdmChange & {
CD_Change[Dev]++; /* indicate change occurred */
} ModemState[Dev] = MdmState; /* save current state of modem inputs */ }
void EvPeriodic(void) /* periodic event function */ { int Dev;
for(Dev = FirstDev;Dev <= MaxDev;Dev++) /* check all devs for Tx data*/ { SendTxData(Dev); /* application function to transmit data */ } }
#pragma check_stack(on) /* Microsoft C only */
BUF_SIZE)
BUF_SIZE);
COM_MDM_CD) /* CD changed */
Each of the previously described event functions require different parameters. For example, the receive data event function only passes a device number to the application, whereas the modem change event function passes a device, a modem state, and a modem change parameter to the application’s event function.
These parameters are described in Appendix A under the function names prefixed with Ev.
The periodic event is different from the other events in that it occurs on regular intervals regardless of what is occurring on the controller. One use for the periodic event function is to allow the application to write data to devices in the background. See Subsection 2.13 for more information.
Warnings: The event functions you write for your applications are actually
executing during a system interrupt service routine (
ISR). It is very
important that you keep these event functions as short as possible. Also, there are many standard C library functions that do not work within an
ISR, such as printf(). Using these functions can cause
unpredictable results and can even hang your system. If using the Microsoft C compiler, stack checking must be disabled
Developing Applications
during event functions and any functions called by event functions. Stack checking can be turned off and on with:
#pragma check_stack(off) #pragma check_stack(on)
2.13. Double Buffering Transmit and Receive Data
Each serial device on the RocketPort controller internally provides 250 bytes of buffering for transmit data and 1K bytes of buffering for receive data. In some applications this may not be sufficient.
For example, an application program may need to write large blocks of data at infrequent intervals. If the application calls aaWrite() directly, only 250 bytes are taken, and the device's internal transmit buffer may empty before the next aaWrite() call occurs, leaving a period of time where no data is being transmitted.
In cases like the one described above, additional buffering is needed. To accomplish this, the data can be double buffered using event functions (see Subsection 2.12). This allows the application to move serial data to and from the buffers rather than directly accessing the device using aaWrite() and aaRead(). The event function handles moving data between the device and the buffer. Double buffering as described in this subsection adds additional overhead, so it should only be done when an application requires it.
A sample program ( buffering. Also included is a Borland C++ make file called source code is reproduced in this guide in Appendix B .
For double buffering of transmit data, use the periodic event function. This function polls each device's buffer for data, and if data is available writes it to the device using aaWrite(). The EvPeriodic() function in this.
The EnqTxData() is used in application calls EnqTxData() instead of writing directly to the device with aaWrite(). Notice that EnqTxData() disables interrupts while manipulating the write buffer pointers. This is necessary because EvPeriodic() is part of an interrupt service routine ( change these pointers until you are completely done updating them.
For double buffering of receive data, the receive event function should be used. This event function is not called unless the device has receive data available. The event function then reads the data with aaRead() or aaReadWithStatus() and places it in the receive buffer. A simple example using only aaRead() is shown in the EvRxData() function in
The DeqRxData() function is used in buffer. The application calls DeqRxData() instead of reading directly from the device with aaRead(). Notice that DeqRxData() disables interrupts while manipulating the read buffer pointers. EvRxData() is part of an necessary for the same reason interrupts were disabled in EnqTxData().
\ROCKET\SAMPLE\DBUF.C) shows an example of double
MAKEDBUF.BC. The
DBUF.C shows how to do
DBUF.C to write data into the transmit buffer. The
ISR) and you do not want it to suddenly interrupt and
DBUF.C.
DBUF.C to read data from the receive
ISR, so this is
2.14.Building Applications (Step 6)
The application is built by executing the compiler’s make utility and a make file. The make file contains the rules that the make utility uses to build the application. If the application is contained entirely in a single source file
TERM.C, then the make file copied in from the \ROCKET\SAMPLE
called directory can be used as is. Otherwise, you must modify the make file to build using your application source file names.
Developing Applications 17
18 Troubleshooting
Section 3. Troubleshooting
3.1. Resolving Installation Problems
If installation fails or you are trying to resolve a problem, you should try the following before calling the Comtrol technical support line:
Check the signals between your peripherals and the interface box to verify that they match (if applicable). See the appropriate Hardware Reference Card for information.
Check to make sure the serial and interface cables are connected properly.
Check to see if the /ROCKET/INSTALL.LOG file with an editor against the settings on each controller.
Reseat the controller in the slot.
Make sure that the expansion slot screw was replaced after inserting the controller.
Reinstall the For possible
Table3-1 defines the 64-byte known uses. Table3-2 defines the 64-byte FFFh and their known uses.
Table 3-1. System
Address
Block
000 – 03F Reserved for Motherboard 040 – 07F Reserved for Motherboard
DIP switch is set to the desired address by checking the
API, selecting a different I/O address range for the controller.
I/O address conflicts, see Tables3-1 and 3-2.
I/O address blocks from 0 through 3FFh and their
I/O address blocks from 400 through
I/O Addresses – Up to 3FF
Addresses
Used
Description
Table 3-1. System I/O Addresses – Up to 3FF(Continued)
Address
Block
240 – 27F 278 – 27F
Addresses
Used
Description
LPT2, IDE controllers,
multifunction boards (game ports)
280 – 2BF
2C0 – 2FF
2E8 – 2EF 2F8 – 2FF
COM4 COM2
300 – 33F 340 – 37F 378 – 37F
LPT1
380 – 3BF 3B0 – 3BF Monochrome Display and LPT3
3C0 – 3FF
3D0 – 3DF 3E8 – 3EF 3F0 – 3F7 3F8 – 3FF
Graphics Monitor Adapter
COM3
Floppy Disk Controller
COM1
Table 3-2. System I/O Address Aliases – Above 3FF
Address
Block
1st Alias 2nd Alias 3rd Alias
080 – 0BF Reserved for Motherboard 0C0 – 0FF Reserved for Motherboard 100 – 13F 140 – 17F 180 – 1BF 1C0 – 1FF 1F0 – 1F8 Fixed Disk 200 – 23F
000 – 03F 400 – 43F 800 – 83F C00 – C3F 040 – 07F 440 – 47F 840 – 87F C40 – C7F 080 – 0BF 480 – 4BF 880 – 8BF C80 – CBF 0C0 – 0FF 4C0 – 4FF 8C0 – 8FF CC0 – CFF 100 – 13F 500 – 53F 900 – 93F D00 – D3F 140 – 17F 540 – 57F 940 – 97F D40 – D7F 180 – 1BF 580 – 5BF 980 – 9BF D80 – DBF
Troubleshooting
Controller #3
ON
1 2 3 4 5 6 7 8
ON
1 2 3 4 5 6 7 8
Controller #4
ON
1 2 3 4 5 6 7 8
ON
1 2 3 4 5 6 7 8
Table 3-2. System I/O Address Aliases – Above 3FF (Continued)
Address
Block
1C0 – 1FF 5C0 – 5FF 9C0 – 9FF DC0 – DFF 200 – 23F 600 – 63F A00 – A3F E00 – E3F 240 – 27F 640 – 67F A40 – A7F E40 – E7F 280 – 2BF 680 – 6BF A80 – ABF E80 – EBF 2C0 – 2FF 6C0 – 6FF AC0 – AFF EC0 – EFF 300 – 33F 700 – 73F B00 – B3F F00 – F3F 340 – 37F 740 – 77F B40 – B7F F40 – F7F 380 – 3BF 780 –7BF B80 – ABF F80 – FBF 3C0 – 3FF 7C0 – 7FF BC0 – BFF FC0 – FFF
1st Alias 2nd Alias 3rd Alias
3.2. Placing a Support Call
Before you place a technical support call to Comtrol, please make sure that you have the following information.
Table 3-3. Support Call Information
Item Your System Information
Controller type
Interface type Mark your I/O address
selections
Controller #1
Operating system type and release
4-port, 8-port, 16-port, or 32-port model
DB25, RJ45, or RJ11
Controller #2
Device driver release number (to verify, view the
VERSION.DAT file)
PC make, model, and speed
List of other devices in the
PC and their addresses
Troubleshooting 19
20 Troubleshooting
Troubleshooting
Contact Comtrol using one of the following methods.
Corporate Headquarters:
email: support@comtrol.com
FAX: (612) 631-8117
Phone: (612) 631-7654
BBS: (612) 631-8310 (for device driver updates)
FTP Site: ftp://ftp.comtrol.com
Note: The
BBS supports modem speeds up to 28.8Kbps with 8 bits, and no
parity.
Comtrol Europe:
email: support@comtrol.co.uk
FAX: +44 (0) 1 869-323-211
Phone: +44 (0) 1 869-323-220
BBS: +44 (0) 1 869-243-687
3.3. Retrieving Future Software Updates
Comtrol supports a BBS that provides software updates for our customers.
Note: The
BBS: (612) 631-8310
BBS supports modem speeds up to 14.4Kbps with 8 bits and no
parity.
21 Troubleshooting
Appendix A. API Functions
This appendix contains reference pages for the RocketPort API. TableA-4 lists all of the
API functions.
Table A-4. API Function Reference
Function Description
aaChangeModemState Changes the state of modem
output lines.
aaClose Closes a device. aaEnPeriodicEvent Enables or disables dispatching of
the periodic event function.
aaExit Performs cleanup when exiting
from an application program.
aaFlush Flushes the transmit or receive
aaGetCtlStatus Gets controller status. aaGetModemStatus Gets a device’s modem status. aaGetRxCount Gets the count of data bytes
aaGetRxStatus Gets the status of the device’s
aaGetTxCount Gets the count of data bytes in the
aaInit Executes controller and
aaInstallCtrlCHandler Installs a handler for the
aaInstallMdmChgEvent Installs an application level event
aaInstallPeriodicEvent Installs a periodic application
buffer, or both for a device.
available in the receive buffer.
receive buffer.
transmit buffer waiting to be transmitted.
API
initialization.
CTRL+C
key interrupt.
function to handle modem change events.
level event function.
Table A-4. API Function Reference
Function Description
aaInstallRxEvent Installs an application level event
aaOpen Open a device for reading or
aaRead Reads serial data from a device. aaReadWithStatus Reads serial data and status from
aaReconfigure Reconfigures a device’s
aaSendBreak Sends a break signal. aaSetCloseDelay Sets the maximum time aaClose()
aaWrite Writes serial data out to a device. EvModemChange* Modem control input change event
EvPeriodic* Periodic event function. EvRxData* Receive data available event
* These are not part of the application.
function to handle receive data available events.
writing, or both.
a device.
communications parameters.
waits for a device’s transmit buffer to drain before flushing the transmit buffer and completing the close.
function.
function.
API, but are part of the
22 API Functions
aaChangeModemState
Function
Purpose
Call
Return
Function
Purpose
Call
Return
Comments
Warning
aaChangeModemState
Changes the state of modem output lines.
aaChangeModemState(Dev,
RTSState,DTRState)
int Dev Device number
RTSState State of RTS line: ON, OFF, or
int
NOCHANGE
int DTRState State of DTR line: ON, OFF, or
NOCHANGE
int: NO_ERR if successful
ERR_DEV if device out of range
aaClose
Closes a device.
aaClose(Dev,ModemCtl) int Dev Device number unsigned char ModemCtl Modem control lines to turn
OFF, can be COM_MDM_RTS or COM_MDM_DTR. If the flag
is not set the state of the modem line is not changed.
NO_ERR if successful
int:
ERR_DEV if device number out of range ERR_MDMCTL if invalid modem control flag ERR_NOTOPEN if device not open
This function waits for the device’s transmit buffer to drain before completing the close. The maximum wait time defaults to
CLOSE_TBEDLY, but can be changed
with the aaSetCloseDelay() function. This function disables and enables interrupts.
23 API Functions
aaEnPeriodicEvent
Function
Purpose
Call
Return
Comments
Warning
Purpose
Call
Return
Comments
Warning
aaEnPeriodicEvent
Enables or disables dispatching of the periodic event function.
aaEnPeriodicEvent(State) int State
TRUE to enable dispatching of
the periodic event function,
FALSE to disable dispatching.
void
The periodic event function is called 274 times a second. Once installed, the periodic event function is not dispatched until it is enabled with the aaEnPeriodicEvent() function. The aaEnPeriodicEvent() function can also be used to disable dispatching of the periodic event function.
The event function must be installed with
aaInstallPeriodicEvent() before enabling dispatching.
aaExit
Performs cleanup when exiting from an application program.
aaExit() void
This function does cleanup tasks required when exiting from an application, such as halting controller interrupts and restoring the
IRQ vector used by the
controller. Once aaInit() has been called, aaExit() must be called
before exiting the application program. If the application program can be exited using the
CTRL+C or CTRL+BREAK keys, then the default DOS CTRL+C
handler must be replaced with a handler that calls aaExit(). You can use the aaInstallCtrlCHandler() function for this purpose.
24 API Functions
aaFlush
Function
Purpose
Call
Return
Function
Purpose
Call
Return
Comments
aaFlush
Flushes the transmit or receive buffer, or both for a device.
aaFlush(Dev,FlushFlags) int Dev Device number unsigned char FlushFlags
NO_ERR if successful
int:
ERR_DEV if device is out of range ERR_OPENTYPE if FlushFlags is out of range
COM_TX or COM_RX, or both
aaGetCtlStatus
Gets controller status, including the first device number on the controller and the number of devices on the controller.
aaGetCtlStatus(CtlNum,FirstDevP,NumDevP) int CtlNum Controller number to get status on. int *FirstDevP Pointer to variable where first
device number on this controller will be returned.
int *NumDevP Pointer to variable where number
of devices on this controller will be returned
NO_ERR Controller is installed
int:
ERR_NOCTL Controller is not installed
The CtlNum parameter identifies which RocketPort controller to get the status of. Controllers are numbered sequentially beginning with 0. Controller 0 will be the first controller whose address appears in the configuration file given by the
ROCKETCFG
environment variable. The contents of the FirstDevP and NumDevP parameters are modified only if
NO_ERR
is returned.
25 API Functions
aaGetModemStatus
Function
Purpose
Call
Return
Function
Purpose
Call
Return
aaGetModemStatus
Gets a device’s modem status.
aaGetModemStatus(Dev) int Dev: Device number
unsigned char State of the modem control inputs
using the
COM_MDM_DSR, and COM_MDM_CD flags. If a flag is set
that modem line is not set that modem line is
COM_MDM_CTS,
ON, if a flag is
OFF.
aaGetRxCount
Gets the count of data bytes available in the receive buffer.
aaGetRxCount(Dev) int Dev Device number
int: Receive byte count
26 API Functions
aaGetRxStatus
Function
Purpose
Call
Return
Comments
Function
Purpose
Call
Return
aaGetRxStatus
Gets the status of the device’s receive buffer.
aaGetRxStatus(Dev) int Dev Device number
NO_ERR if there are no errors in the
int:
device’s receive buffer
ERR_RX if there are errors in the
device’s receive buffer
ERR_DEV if device number out of range ERR_NOTOPEN if device not open for receive
If there are errors in the device’s receive buffer, the exact error and the errored data byte can be determined using the aaReadWithStatus() function.
aaGetTxCount
Gets the count of data bytes in the transmit buffer waiting to be transmitted.
aaGetTxCount(Dev) int Dev Device number
int: Transmit byte count
27 API Functions
aaInit
Function
Purpose
Call
Return
Comments
Warning
Function
Purpose
Call
Return
Comments
Warning
aaInit
Executes controller and
API initialization.
aaInit()
unsigned int
NO_ERR if no initialization
errors
ERR_ALLOCDEV if it can not
allocate device structure
ERR_CTLINIT if controller
initialization error
ERR_CHANINIT if channel
initialization error
ERR_DEVSIZE if invalid number
of devices found
ERR_CTLSIZE if invalid number
of controllers found
This function must be called once before calling any
API function except aaInstallCtrlCHandler(). The
other controller initialization parameters is obtained from the configuration file given by environment variable
ROCKETCFG.
Once aaInit() has been called, aaExit() must be called before exiting the application program.
If the application program can be exited using the
CTRL+C or CTRL+BREAK keys, then the default DOS CTRL+C handler must be replaced with a handler that
calls aaExit(). You can use the aaInstallCtrlCHandler() function can be used for this purpose.
aaInstallCtrlCHandler
Installs a handler for the
CTRL+C key interrupt.
aaInstallCtrlCHandler() void
This function replaces the existing
CTRL+C (interrupt
23H) handler with a handler that performs the following actions:
1. Calls aaExit().
2. Sets the carry flag to signal
DOS to terminate the
application.
3. Executes a far return.
DOS restores the original CTRL+C handler when
terminating the application. aaInstallCtrlCHandler() is the only
API function that can
be called before calling aaInit(). If you plan on using the aaInstallCtrlCHandler() function, we recommend calling it either immediately before or immediately after the call to the aaInit() function.
If you want different write and install your own custom Refer to the Microsoft
CTRL+C processing, you must
CTRL+C handler.
MS-DOS Programmer's Reference
for more information. To aid in writing your own handler, the source code for aaInstallCtrlCHandler() and the handler it installs are given below:
void aaInstallCtrlCHandler(void) { dos_setvect(0x23,(void (interrupt far *)())aaCtrlCIntHandler); }
void far aaCtrlCIntHandler(void) { aaExit(); asm stc; }
If the application program can be exited using the
CTRL+C or CTRL+BREAK keys, then the default DOS CTRL+C handler must be replaced with a handler that
calls aaExit(). You can use the aaInstallCtrlCHandler() function for this purpose.
28 API Functions
aaInstallMdmChgEvent
Function
Purpose
Call
Return
Comments
Warning
Function
Purpose
Call
Return
Comments
Comments
Warning
aaInstallMdmChgEvent
Installs an application level event function to handle modem change events.
aaInstallMdmChgEvent(EvFuncP) void (*evFuncP)(Dev,unsigned char MdmChange,
unsigned char MdmState) Ptr to the event
function
void
See the EvModemChange() function for a description of the event function.
The function installed here is called during an interrupt service routine (ISR). Keep your code short and remember that many standard C library calls do not work in ISRs, such as printf().
If using the Microsoft C compiler, stack checking must be disabled during the event function and any functions called by the event function.
Stack checking can be turned off and on with:
#pragma check_stack(off) #pragma check_stack(on)
aaInstallPeriodicEvent
Installs a periodic application level event function.
aaInstallPeriodicEvent(EvFuncP) void (*EvFuncP)(void) Ptr to the event function.
void
The periodic event function is called 274 times a second. Once installed, the periodic event function is not dispatched until it is enabled with aaEnPeriodicEvent(). The aaEnPeriodicEvent() function can also be used to disable dispatching of the periodic event function.
See the EvPeriodic() function for a description of the event function.
The function installed here will be called during an interrupt service routine (
ISR). Keep your code short
and remember that many standard C library calls do not work in
ISRs, such as printf().
If using the Microsoft C compiler, stack checking must be disabled during the event function and any functions called by the event function.
Stack checking can be turned off and on with:
#pragma check_stack(off)
#pragma check_stack(on)
29 API Functions
aaInstallRxEvent
Function
Purpose
Call
Comments
Return
Warning
Function
Purpose
Call
aaInstallRxEvent
Installs an application level event function to handle receive data available events.
aaInstallRxEvent(EvFuncP) void (*EvFuncP)(int Dev); Ptr to the event
function.
See the EvRxData() function for a description of the event function.
void
The function installed here is called during an interrupt service routine (
ISR). Keep your code short
and remember that many standard C library calls do not work in
ISRs, such as printf().
If using the Microsoft C compiler, stack checking must be disabled during the event function and any functions called by the event function.
Stack checking can be turned off and on with:
#pragma check_stack(off) #pragma check_stack(on)
aaOpen
Open a device for reading or writing, or both.
aaOpen(Dev,OpenType,Baud,Parity,DataBits,StopBits,Flow
Ctl, DetectEn,ModemCtl)
int Dev Device Number unsigned int OpenType
unsigned char Baud One of the unsigned char Parity One of:
unsigned char DataBits One of unsigned char StopBits One of
COM_TX for transmit or COM_RX for receive, or both.
COM_BAUD_XX flags
defined in
COM_PAR_EVEN, COM_PAR_ODD.
COM_DATABIT_8. COM_STOPBIT_2.
API.H.
COM_PAR_NONE,
COM_DATABIT_7, COM_STOPBIT_1,
unsigned int FlowCtl Flow control flag, can be
COM_FLOW_NONE or any
combination of
COM_FLOW_NONE, COM_FLOW_IS, COM_FLOW_OS, COM_FLOW_IH, COM_FLOW_OH, COM_FLOW_OXANY.
unsigned int DetectEn Detection enable flags, can be
any combination of the following:
COM_DEN_NONE No error
detection enabled
COM_DEN_RDA Enable Rx
data available detection
CON_DEN_MDM Enable
modem input
DSR, CD,
(
CTS)
or change detection
unsigned char ModemCtl Modem control lines to turn
ON, can be COM_MDM_RTS or
30 API Functions
aaRead
Return
Comments
Warning
Function
Purpose
Call
Return
Comments
Warning
COM_MDM_DTR, or both. If
the flag is not set the line is
OFF. If hardware flow control
is in use for a modem line, it’s flag has no effect.
int: NO_ERR if successful
ERR_DEV if device number out of range ERR_OPENTYPE if invalid open type flag ERR_BAUDRATE if invalid baud rate flag ERR_PAR if invalid parity bits flag ERR_DATAB if invalid data bits flag ERR_STOPB if invalid stop bits flag ERR_FLOW if invalid flow control bits flag ERR_DETECT if invalid detect enable flag ERR_MDMCTL if invalid modem control flag ERR_ALREADYOPEN if device already open error
flag
If this device has been opened previously and is still open, this function fails and returns an
ERR_ALREADYOPEN error.
This function disables and enables interrupts.
aaRead
Reads serial data from a device.
aaRead(Dev,Cnt,Buf) int Dev Device number int Cnt Maximum number of bytes
that can be read
unsigned char *Buf Buffer to store the data in int: Number of bytes readif successful
0 if no data available to be read
ERR_DEV if device number out of range ERR_NOTOPEN if device not open for receive
This function reads data from the device’s receive buffer without checking for receive errors. If receive error information is needed, use the aaGetRxStatus() and aaReadWithStatus() functions.
The Cnt parameter should not be greater than the size of the Buf receive buffer.
31 API Functions
aaReadWithStatus
Function
Purpose
Call
Return
Warning
Function
Purpose
Call
Return
aaReadWithStatus
Reads serial data and status from a device.
aaReadWithStatus(Dev,Cnt,Buf) int Dev Device number int Cnt Max number of bytes that can
be read
unsigned int *Buf Buffer to store the data and
status. The low byte of each array element in Buf contains the data byte, and the high byte contains the status for that data byte. The status may be 0 indicating no error, or any combination of the following flags:
ERR_PARITY parity error ERR_OVRRUN receiver over
run error
ERR_FRAME framing error ERR_BREAK break
int: Number of bytes read if successful
0 if no data available to be
read
ERR_DEV if device number out of
range
ERR_NOTOPEN if device not open for receive
The Cnt parameter should not be greater than the number of array elements in the Buf receive buffer.
aaReconfigure
Reconfigures a device’s communications parameters.
Reconfigure(Dev,Baud,Parity,DataBits,StopBits,FlowCtl,Detect
aa
En
);
int dev; Device Number unsigned char Baud One of the baud rate flags
unsigned char Parity One of:
defined in
COM_PAR_EVEN, COM_PAR_ODD
unsigned char DataBits One of
COM_DATABIT_8
unsigned char StopBits One of
COM_STOPBIT_2
API.H.
COM_PAR_NONE,
.
COM_DATABIT_7,
.
COM_STOPBIT_1,
.
unsigned int FlowCtl Flow control flag, can be
COM_FLOW_NONE or any
combination of:
COM_FLOW_IS, COM_FLOW_OS, COM_FLOW_IH, COM_FLOW_OH, COM_FLOW_OXANY.
unsigned int DetectEn Detection enable flags, can be
any combination of the following:
COM_DEN_NONE No error
detection enabled
COM_DEN_ RDA
Enable Rx data available detection
COM_DEN_MDM Enable
modem input
DSR,CD, or
(
CTS)
change detection
NO_ERR if successful
int:
ERR_DEV if device number out of range ERR_BAUDRATE if invalid baud rate flag
32 API Functions
aaSendBreak
Warning
Function
Purpose
Call
Return
ERR_PAR if invalid parity bits flag ERR_DATAB if invalid data bits flag ERR_STOPB if invalid stop bits flag ERR_FLOW if invalid flow control bits flag ERR_DETECT if invalid detect enable flag ERR_NOTOPEN if device not open error flag
This function disables and enables interrupts.
aaSendBreak
Sends a break signal.
aaSendBreak(Dev,Time) int Dev Device number int Time Time in milliseconds to send the
break
NO_ERR if successful
int:
ERR_DEV if device is out of range.
33 API Functions
aaSetCloseDelay
Function
Purpose
Call
Return
Comments
Function
Purpose
Call
Return
Warning
aaSetCloseDelay
Sets the maximum time aaClose() waits for a device’s transmit buffer to drain before flushing the transmit buffer and completing the close.
aaSetCloseDelay(Dev,MaxDelay) int Dev Device number int MaxDelay Maximum time aaClose will
wait for a device’s transmit buffer to drain in seconds. For no delay use 0. Maximum value is 32,767 seconds.
NO_ERR if successful.
int:
ERR_DEV if device number out of range.
The device does not need to be open to execute this function.
aaWrite
Writes serial data out a device.
aaWrite(Dev,Cnt,Buf) int Dev: Device number int Cnt: Number of bytes to be
written
unsigned char *Buf: Buffer of data to write int: Number of bytes written if successful
0 if no data bytes written ERR_DEV if dev number out of
range ERR_NOTOPEN if dev not open for transmit
The Cnt parameter should not be greater than the size of the Buf transmit buffer.
34 API Functions
EvModemChange
Function
Purpose
Call
Return
Comments
Warning
EvModemChange
Application modem input change event function
EvModemChange(Dev,unsigned char
MdmChange,unsigned char MdmState)
int Dev Device number unsigned char MdmChange Modem input lines which
changed. Can be any combination of the flags:
COM_MDM_DSR, COM_MDM_CTS, or COM_MDM_CD.
If a flag is set that modem line is changed, if a flag is not set that modem line did not change.
unsigned char MdmState Current state of the modem
inputs. Can be any combination of the
COM_MDM_CTS, COM_MDM_DSR, and COM_MDM_CD flags. If a
flag is set that modem line
ON, if a flag is not set
is that modem line is
OFF.
void
This function is not part of the
API, it must be written
by the developer as part of the application program. The function name EvModemChange is an example
name only, this event function can be given any name desired.
This function is not called directly by the application. Instead, it is dispatched by the
API’s internal ISR
(interrupt service routine) when it detects that receive data is available. Before this function will be dispatched it must be installed with aaInstallMdmChgEvent(), and modem input change detection must be enabled. Detection is enabled using the DetectEn parameter of aaOpen() or aaReconfigure().
The function installed here is called during an interrupt service routine (
ISR). Keep your code short
and remember that many standard C library calls do
not work in ISRs, such as printf(). If using the Microsoft C compiler, stack checking must
be disabled during the event function and any functions called by the event function.
Stack checking can be turned off and on with:
#pragma check_stack(off) #pragma check_stack(on)
35 API Functions
EvPeriodic
Function
Purpose
Call
Return
Warning
Warning
Function
Purpose
Call
Return
Warning
Warning
EvPeriodic
Application periodic event function
EvPeriodic() void
This function is not part of the
API, it must be written
by the developer as part of the application program. The function name EvPeriodic is an example name only,
this event function can be given any name desired. This function is not called directly by the application.
Instead it is dispatched by the
API’s internal ISR
(interrupt service routine) when it detects that receive data is available. Before this function will be dispatched it must be installed with aaInstallPeriodicEvent(), and periodic events must be enabled with aaEnPeriodicEvent().
Once installed and enabled, the periodic event function is called 274 times a second regardless of the state of controller.
The function installed here is called during an interrupt service routine (
ISR). Keep your code short
and remember that many standard C library calls do not work in
ISRs, such as printf().
If using the Microsoft C compiler, stack checking must be disabled during the event function and any functions called by the event function.
Stack checking can be turned off and on with:
#pragma check_stack(off) #pragma check_stack(on)
EvRxData
Application receive data available event function
EvRxData(Dev) int Dev: Device number
void
This function is not part of the
API, it must be written
by the developer as part of the application program. The function name EvRxData is an example name only,
this event function can be given any name desired. This function is not called directly by the application.
Instead, it is dispatched by the
API’s internal ISR
(interrupt service routine) when it detects that receive data is available. Before this function will be dispatched it must be installed with aaInstallRxEvent(), and receive data available detection must be enabled. Detection is enabled using the DetectEn parameter of aaOpen() or aaReconfigure().
The function installed here is called during an interrupt service routine (
ISR). Keep your code short
and remember that many standard C library calls do not work in
ISRs, such as printf().
If using the Microsoft C compiler, stack checking must be disabled during the event function and any functions called by the event function.
Stack checking can be turned off and on with:
#pragma check_stack(off) #pragma check_stack(on)
36 Troubleshooting
Appendix B. Double Buffering Example
This appendix contains a copy of the \ROCKET\SAMPLE\DBUF.C file for your convenience.
File: DBUF.C Project: RocketPort Purpose: Double buffering sample program Comments: This program shows how to use the periodic event function to
double buffer Tx data, and how to use the receive event function to double buffer Rx data. The double buffering is done in a pair of queues for each device, these are defined in the
Operation: Install a loopback plug on port 0. At the
DBUF." Each time transmit data is enqueued to the device 0, the
" Tx buffer the count is displayed. Each time data is dequeued from the device 0; the Rx buffer, the count, and Rx string are displayed.
********************************************************/
#include <stdio.h> #include <process.h> #include <stdlib.h> #include <mem.h> #include <string.h> #include <conio.h> #include <dos.h> #include "api.h"
#define NUMDEV 8 /* num devices this app supports */ #define TXBUF_SIZE 1024 /* transmit buffer size */ #define RXBUF_SIZE 1024 /* receive buffer size */
void EvRxData(int); /* function prototypes */ void EvPeriodic(void); int EnqTxData(int,unsigned char *,int); int DeqRxData(int,unsigned char *,int);
typedef struct‘ /* transmit and receive queues */ { int OpenTx; /* TRUE if device open for Tx */ int TxIn; /* index to add Tx data at */
DOS API
Q_T structure.
DOS command line type
int TxOut; /* index to remove Tx data at */ unsigned char TxBuf[TXBUF_SIZE]; /* buffer for Tx data */ int RxIn; /* index to add Rx data at */ int RxOut; /* index to remove Rx data at */ unsigned char RxBuf[RXBUF_SIZE]; /* buffer to Rx data */ } Q_T; Q_T q[NUMDEV];/* Tx and Rx queues for each dev */
/******************************************************** Function: main Purpose: Initialization, test Tx and Rx double buffering. */ main() { int Dev; int Err; unsigned char Buf[100]; int Cnt;
/* Initialize controller */ aaInstallCtrlCHandler(); if((Err = aaInit()) != NO_ERR) { printf("Initialization Failure %x\n",Err); aaExit(); exit(1); }
/* Clear queues */ for(Dev = 0;Dev < NUMDEV;Dev++) { q[Dev].OpenTx = FALSE; q[Dev].TxIn = 0; q[Dev].TxOut = 0; q[Dev].RxIn = 0; q[Dev].RxOut = 0; }
/* Set up application event functions */ aaInstallRxEvent(EvRxData); aaInstallPeriodicEvent(EvPeriodic);
aaEnPeriodicEvent(TRUE); /* Test background transmit and receive on device 0. A loopback
plug can be installed on device 0 so that all transmitted data is received on the same device. */ printf("To stop test press any key\n"); if((Err = aaOpen(0, COM_TX | COM_RX, COM_BAUD_38400, COM_PAR_NONE, COM_DATABIT_8, COM_STOPBIT_1, COM_FLOW_NONE, COM_DEN_RDA, COM_MDM_RTS | COM_MDM_DTR)) != 0) { printf("Open Failure - Device %d, Error %d\n","0",Err); aaExit(); exit(1); } q[0].OpenTx = TRUE;
while(!kbhit()) /* test loop */ { Cnt = EnqTxData(0, (unsigned char *)"This string is being written to device 0",
40); if(Cnt > 0) printf("Tx %d bytes\n",Cnt);
delay(100); /* wait for loopback data */ Cnt = DeqRxData(0,Buf,RXBUF_SIZE-1);
/* dequeue all Rx data available */ Buf[Cnt] = NULL; /* null terminate received string */ if(Cnt > 0) printf("Rx %d bytes, String = %s\n",Cnt,Buf); } getch();
Troubleshooting
/******************************************************** Function: EnqTxData Purpose: Add data to a Tx queue. Call: EnqTxData(Dev,Buf,Cnt)
int Dev; Device number unsigned char *Buf; Buffer with data to add
int Cnt; Count of bytes to add Return: int: Number of bytes added to Tx queue */ int EnqTxData(int Dev,unsigned char *Buf,int Cnt) { int i; /* balance of bytes to copy after q wrap */ int NumOpen; /* num bytes open in Tx buffer */ int In; /* In index into Tx buffer */
asm cli; /* no interrupts until done, do not want
periodic event function modifying q while we are working on it */
In = q[Dev].TxIn; /* local copy of In index */ /* Get number bytes open in Tx buffer */
if((NumOpen = q[Dev].TxOut - In - 1) < 0) NumOpen += TXBUF_SIZE; /* adjust for q wrap */ if(NumOpen > Cnt) NumOpen = Cnt; /* don't move more than are incoming */ if(NumOpen == 0) return(0); /* no room in Tx buffer */ i = NumOpen - (TXBUF_SIZE - In); /* i = whats left after wrap around */ if (i < 0) i = 0;
/* Copy to end of Tx buffer */ memcpy(&q[Dev].TxBuf[In],Buf,NumOpen - i);
/* Update In index, pnt to beginning of buff if already at end of it */ In = (In + (NumOpen - i)) % TXBUF_SIZE;
/* Exit application */ q[0].OpenTx = FALSE; aaClose(0,COM_MDM_RTS | COM_MDM_DTR); aaExit(); return(0); }
Troubleshooting 37
/* Copy the rest of the buffer, if any left */ if (i != 0) { memcpy(q[Dev].TxBuf,&Buf[NumOpen - i],i); In = i; }
38 Troubleshooting
Troubleshooting
/* Update Tx queue In index */ q[Dev].TxIn = In; asm sti; /* enable interrupts */ return(NumOpen); }
/* Copy the rest of the buffer, if any left */ if (i != 0) { memcpy(&Buf[BCnt - i],q[Dev].RxBuf,i); Out = i; }
/******************************************************** Function: DeqRxData Purpose: Remove data from a Rx queue. Call: DeqRxData(Dev,Buf,Cnt)
int Dev; Device number unsigned char *Buf;
Buffer takes data removed from Rx queue. int Cnt; Count of bytes to remove Return: int: Number of bytes removed from Rx queue */ int DeqRxData(int Dev,unsigned char *Buf,int Cnt) { int i; /* balance of bytes to copy after q wrap */ int Out; /* Out index into Rx buffer */ int BCnt; /* count of bytes copied */
asm cli; /* no interrupts until done, do not want
periodic event function modifying q
while we are working on it */ Out = q[Dev].RxOut;/* local copy of Out index */
/* Get number of bytes in Rx buffer */ if((BCnt = q[Dev].RxIn - Out) < 0) BCnt += RXBUF_SIZE; /* adjust for queue wrap */ else if(BCnt == 0) return(BCnt); /* nothing in Rx buffer */ if(Cnt < BCnt) BCnt = Cnt; /* do not move more than asked for */ i = BCnt - (RXBUF_SIZE - Out); /* i = whats left after wrap around */ if(i < 0) i = 0;
/* Update Rx queue Out index */ q[Dev].RxOut = Out; asm sti; /* enable interrupts */ return(BCnt); }
/******************************************************** Function: EvRxData Purpose: Receive event function, read data from a serial device
and add it to a Rx queue.
Call EvRxData(Dev)
int Dev; Device number Return: void */ void EvRxData(int Dev) /* receive event function */ { int i; /* balance of bytes to copy after q wrap */ int NumOpen; /* num bytes open in Rx buffer */ int In; /* In index into Rx buffer */ int Cnt; /* total count of bytes read */
In = q[Dev].RxIn; /* local copy of In index */ /* Get number bytes open in Rx buffer */
if((NumOpen = q[Dev].RxOut - In - 1) < 0) NumOpen += RXBUF_SIZE; /* adjust for q wrap */ if(NumOpen == 0) return; /* no room in Rx buffer */ i = NumOpen - (RXBUF_SIZE - In); /* i = whats left after wrap around */ if (i < 0) i = 0;
/* Copy to end of Rx buffer */ memcpy(Buf,&q[Dev].RxBuf[Out],BCnt - i);
/* Updata Out index, point to beginning of buffer if already at end of it */ Out = (Out + (BCnt - i)) % RXBUF_SIZE;
/* Read data in up to end of Rx buffer */ Cnt = aaRead(Dev,NumOpen - i,&q[Dev].RxBuf[In]);
/* Update In index, point to beginning of buffer if already at end of it */ In = (In + Cnt) % RXBUF_SIZE;
Troubleshooting
/* Read more data if any room left at front of buffer and if device wasn't already emptied */ if((i != 0) && (Cnt == NumOpen - i)) { In = aaRead(Dev,i,q[Dev].RxBuf); /* read balance of data */ }
/* Update Rx queue In index */ q[Dev].RxIn = In; }
/******************************************************** Function: EvPeriodic Purpose: Periodic event function, remove data from Tx queues
and write it to serial devices. Call: EvPeriodic(void) Return: void */ void EvPeriodic(void) { int Dev; /* device number */ int i; /* balance of bytes to copy after q wrap */ int Out; /* Out index into Tx buffer */ int Cnt; /* number of bytes to write */ int WCnt; /* number of bytes actually written */
/* Updata Out index, point to start of buffer if already at end of it */ Out = (Out + WCnt) % TXBUF_SIZE;
/* Write more data if any left at front of buffer and if device wasn't already filled */ if((i != 0) && (WCnt == Cnt - i)) { Out = aaWrite(Dev,i,q[Dev].TxBuf); /* write balance of data */ }
/* Update Tx queue Out index */ q[Dev].TxOut = Out; } }
for(Dev = 0;Dev < NUMDEV;Dev++) /* check all devs for data to Tx */ { if(!q[Dev].OpenTx) /* device not open for Tx */ continue; Out = q[Dev].TxOut; /* local copy of Out index */
/* Get number of bytes in Tx buffer */ if((Cnt = q[Dev].TxIn - Out) < 0) Cnt += TXBUF_SIZE; /* adjust for queue wrap */ else if(Cnt == 0) return; /* nothing in Tx buffer */ i = Cnt - (TXBUF_SIZE - Out); /* i = whats left after wrap around */ if(i < 0) i = 0;
/* Write data to end of Tx buffer */ WCnt = aaWrite(Dev,Cnt - i,&q[Dev].TxBuf[Out]);
Troubleshooting 39
Loading...