    How to Use the FryeCom Driver
         19 July 2011 -med

The following calls are available in FryeCom.
All calls use the Stdcall calling convention.

 CallFryers       index 1,  //compatible Fryers32 format call
 CallFryers_C     index 2,  //compatible Fryers32 format call

 OpenPort         index 3,  //Open the port
 ClosePort        index 4,  //close the current port
 GetPortStatus    index 5,  //get operational status of the com port

 SendReady        index 6,  //check if Ready to send
 SendCmdArray     index 7,  //send a command array
 RspReady         index 8,  //check if a response is available
 GetRspArray      index 9,  //get a response array

 SetNoPollTimeout index 10, //set new poll timeout value
 GetNoPollTimeout index 11, //get current poll timeout value

 GetFcomVersion   index 12, //get the version number of the driver
 MaxComPort       index 13, //get the max possible available com port
 GetDebugStatus   index 14; //get extended debug status
 CancelCmd        index 15; //cancel current command event
 SetPortMode      index 16; //set port operating mode
 GetPortMode      index 17; //get port operating mode

Note: FryeCom and Fryers32 allow the use of multiple comports at the same time
(multiple attached Fonix instruments). 

The Comport number is the Fryers handle that is used to direct the commands 
to the associated com port. When you open a port with the OpenPort API call,
that comport number is to be used with the other API calls so that FryeCom
will know which port it is to use. You can call OpenPort multiple times
with different com ports. Each opened com port uses the com port number as
the reference handle in the FryeCom API calls. 

The error numbers listed are returned by the FryeCom DLL.
If you use the example Frye FIPP interface code, you may also
see additional possible return codes from the interface code.
(see the FComDefs.h file).

For a description of the FIPP commands that can be sent to Fonix instruments,
see the separate FIPP Commands documents and instrumentation notes.


Call API Descriptions:

-------------------------------------------------------------
Export #1
procedure CallFryers(var IRegs:F_RegsType); stdcall;
typedef void __stdcall (*tCallFryers)(F_RegsType* IRegs);

Export #2
procedure CallFryers_C(var IRegs:F_RegsType); cdecl;
typedef void __cdecl (*tCallFryers_C)(F_RegsType* IRegs);

This is a pass-thru call that goes directly to the Fryers32.DLL
FryeCom.DLL loads the Fryers32.DLL internally. You should not load
Fryers32.DLL yourself as that will create another separate instance of the DLL.
If you are using the FryeCom.DLL, you should use the CallFryers pass-thru
call if you need to communicate directly with the Fryers32.DLL driver.
See the separate documentation for the Fryers32.DLL for information
on communicating directly with the Fryers32.DLL driver.
See FRYEREGS.INC for the structure definition of F_RegsType.

Because CallFryers is compatible to the older Fryers32 DLL, it does
not pass back a return value (procedure based rather than a function call).
The purpose of this call is to retain backwards compatibility to older
software that uses the CallFryers interface. (Which itself was compatible
to the older MSDOS interrupt register call interface.) In most cases you
can simply change the DLL that you access from Fryers32.DLL to FryeCom.DLL
and your software will still work. The CallFryers_C export is a special
cdecl version of the CallFryers interface. This call method is obsolete
and should not be used. You should use the Windows API stdcall interface method.
The CallFryers_C interface is provided for backwards compatibility only.
The new added calls use only the stdcall interface method.

When you do decide to switch over to the new API interface provided by the
FryeCom DLL, you should switch over completely, especially for the
Initialization, Send and Receive API calls which rely on internal data
controls to manage the functions. You can still bypass these calls with
direct calls to CallFryers, but you may experience problems if you do.
Some calls like $FFFF (Get Version) and $FF13 (Get Status) will be perfectly
fine and not interfer with the operation. Other calls like $FF12 (Send Command
Array) may cause troubles because the mid-level FryeCom driver code will not 
be aware that it was bypassed and may get confused about the transfer. 
You should definately not mix the call methods.

That being said, it is still ok to use functions that directly call the
status ($FF13) and other similar API calls via CallFryers that only look
at the status information of the low-level Fryers32 operations. Looking at
the status will not disrupt the DLL. But calls that engage the data transfer
API calls (such as $FF10, $FF11 and $FF12) should not be used if you are
using the new OpenPort, ClosePort, SendReady, SendCmdArray, RspReady and
GetRspArray API calls.

-------------------------------------------------------------
Export #3
typedef int __stdcall (*tOpenPort)(int ComPort, int PortControl, int Baudrate,
                                   TfcCallback Callback);
function OpenPort(ComPort:integer; PortControl:integer; Baudrate:integer;
                  Callback : TfcCallback):integer; stdcall export;

Use OpenPort to open the com port number you want to use to communicate
with the Fonix instrument.

The ComPort value is the Port you wish to open 0=COM1, 1=COM2, etc...
Values are COM1 (0) through COM256 (255).

If you know the baudrate that the Fonix instrument is using, set the
Baudrate value to that baudrate (9600 to 115200) and set PortControl to 
FCOM_USE_NO_SEEK (0). If you do not know the baudrate, set Baudrate to 9600 
and PortControl to FCOM_USE_BAUD_SEEK. When autobaud is enabled the OpenPort 
procedure will seek out the baudrate of the attached Fonix instrument. 
Note: If an invalid baudrate is given it will be ignored and the baudrate 
will be set to the default baudrate of 9600. Valid Baudrates are 9600, 
19200, 38400, 57600 and 115200. If the computer and the attached instrument 
support it 230400 is also possible (this is a future option).  
If autobaud is enabled, these baudrates will be automatically detected.

If you expect the baudrate of the Fonix instrument to change while you are
communicating with the instrument, you can set Baudrate to the known baudrate
(or 9600 if you don't know it) and set PortControl to FCOM_USE_BAUD_SEEK. 
The driver will automatically seek out the new baudrate if it changes. 
Note: Using autobaud can potentially cause long periods of communication 
deadtime (several seconds or up to a minute) if the baudrate is detected to 
have changed as the new baudrate is being searched out.

We recommend using the autobaud feature as it has been found to be useful
and generally eliminates the need to ask the user to specify the baudrate
which for most users is an unknown answer.

The PortControl parameter selects how the port is opened.
If the parameter is set to FCOM_USE_NO_SEEK, the port is opened blind and the 
call immediately returns. There is no attempt to detect if an instrument is
attached or not and the autobaud feature is not enabled. 
If the port could not be opened (because Windows rejected the request) 
the function will return FCOM_PORT_NOT_FOUND. If you place a call to one 
of the other API routines when a port has not been opened, it will return 
an error of FCOM_PORT_NOT_OPEN.

If PortControl is set to AUTO_SEEK_PORT, the call will automatically try to
look for an attached Fonix instrument. If a com port was found, but no
Fonix instrument found, the OpenPort() function will return FCOM_PORT_NOT_OPEN.
If Windows disallowed the port to be accessed, the function will return
FCOM_PORT_NOT_FOUND. If you use the FCOM_USE_PORT_SEEK feature, you should also
use the FCOM_USE_BAUD_SEEK as well, otherwise the Fonix instrument may not be
found if it is operating at a different baudrate than specified in the call.
(Example: PortControl = FCOM_USE_PORT_SEEK + FCOM_USE_BAUD_SEEK;)

If you don't know the ComPort that the Fonix instrument is attached to,
you can search for it by opening each ComPort in sequence until you find
it or all the possible com ports have been tried. If you are searching for
a Fonix instrument, you should turn on both the FCOM_USE_PORT_SEEK and the
FCOM_USE_BAUD_SEEK features, otherwise the Fonix instrument may not be found.
Normally you should use FCOM_USE_BAUD_SEEK unless you have a reason not to.
If you use the FCOM_USE_PORT_SEEK feature, the Fonix instrument must be 
connected and running so that the computer can communicate with it. If you 
don't use the FCOM_USE_PORT_SEEK feature, the port will be opened without 
testing for an attached instrument.

If you have only one Fonix instrument attached to the computer, OpenPort can
be used to find the instrument. If you have two or more Fonix instruments
attached to the computer, you will need to either use OpenPort to specify 
the specific port, or add some complexity to the OpenPort call to seek out 
the specific instrument you want to talk to using the FIPP GetVersion command 
to detect which instrument was detected by OpenPort.

The FCOM_AUTO_PORT_SEEK and FCOM_USE_BAUD_SEEK are only valid in polled packet
transfer mode (selecting either or both values automatically sets the port 
into polled packet mode. The SEEK functions cannot be used in DEMAND mode 
or CHAR mode.

The FCOM_USE_DEMAND_PORT selection is intended for use with future Ethernet 
support. It changes the port operation from a polled packet transfer to a
demand based packet transfer. 

The FCOM_USE_CHAR_PORT selection allows the use of the port to transfer 
single bytes (similar to the operation of an RS232 serial port).
Selecting CHAR mode converts the Send and Recieve calls to single byte
transfer use. 

The callback function allows you to cancel the OpenPort function should it
take too long and to be able to do other activities while waiting for it
to be completed. If you do not want to use this feature, pass a NIL/NULL(0)
value in the callback pointer. The Callback is only called if the
FCOM_USE_PORT_SEEK feature is used (it is called periodically about once every
100ms while the port is being tested for an attached Fonix instrument).

Be careful using the Callback function. While FryeCom can handle some
re-entrant issues (getting status information), it is generally not
re-entrant with regard to sending and receiving commands. Sending another
command array to an instrument while one is currently in progress will
disrupt the command protocol.

If OpenPort is successful, it will return FCOM_SUCCESS.
Otherwise it will return the error code for the failure.

If you open a com port with OpenPort but then decide not to use it,
be sure to call ClosePort to release the com port back into the wild.

Possible errors:
FCOM_PORT_RANGE_ERROR, FCOM_GENERIC_ERROR, FCOM_PORT_NOT_FOUND,
FCOM_PORT_NOT_OPEN, FCOM_CANCEL

-------------------------------------------------------------
Export #4
typedef int __stdcall (*tClosePort)(int ComPort);
function ClosePort; stdcall export;

When you are done, but before you exit your program, you can call
ClosePort to close the port you are using. This allows other programs
to use the port.

Note that only one program can use a com port device while the program has
it open. You can call ClosePort at any time, but you will have to call
OpenPort to reopen the port to again communicate with the Fonix instrument
(this can take up to a second or so to establish a connection, so repeated
open and closing is not a desirable action).

When the program that uses FryeCom.dll closes down and unloads FryeCom.dll,
the FryeCom.dll driver will automatically close the port for you.
Remember that as long as you have the port open, no other program can
have access to the port (Com Ports are non-shared devices).

If you call ClosePort on a port that is already closed, ClosePort will
ignore the call and return a success result.

If ClosePort is successful, it will return FCOM_SUCCESS.
Otherwise it will return the error code for the failure.

Possible errors:
FCOM_PORT_RANGE_ERROR

-------------------------------------------------------------
Export #5
typedef int __stdcall (*tGetShortStatus)(int ComPort, tPortStatusRec* PortStatus);
function GetPortStatus(ComPort:integer; var PortStatus:tPortStatusRec):integer; stdcall export;

This call will return the current status of the Fryers driver on this comport.
The call will return the information shown below.
You can call this function at anytime. It will not disrupt any on-going activity.
This command can be used to determine the current operational state of the
FryeCom driver.

This function is callback safe.

type tPortStatusRec = packed record
  ComPort : integer;       //this com port
  PortState : integer;     //0=Comport is active, neg=inactive (number=error), nz=busy
  FcomVersion : integer;   //FryeCom version number
  FcomDate : DWORD;        //FryeCom version date (Packed Frye Date format)
  MaxPort : integer;       //Maximum available comport
  SeekState : integer;     //1=Attempting to sync to the port, 2=baudrate seek, 0=not seeking
  PortMode : integer;      //0=char, 1=polled packet, 2=demand packet
  Baudrate : integer;      //Current active baudrate
  NoPollTimeout : integer; //current No Poll timeout setting in milliseconds
  PacketStatus : integer;  //current PacketStatus of Fryers driver see Regs.AX
  PacketControl : integer; //current PacketControl of Fryers driver see Regs.CX
  PacketState : integer;   //current PacketState of Fryers driver ses Regs.DX
  Timer : integer;         //current Packet timer value see Regs.BX in $FF13
  LastCommand : integer;   //last known Fryers command number that was sent
  LastResponse : integer;  //last known Fryers response number that was received
  LastCommandSize : integer;  //size of last known Fryers command that was sent
  LastResponseSize : integer; //size of last known Fryers response that was received
  AsciiStatus : integer;      //Char mode status (only valid in char mode)
  AsciiCount : integer;       //Number of characters in char mode buffer waiting to be read
  Spare : integer;         //spare parameter for future use
end;

ComPort is the com port for which this status was collected.
This is also the handle FryeCom uses to manage the comport.

PortState is the current state of the com port. A negative number is the last
known error that happened with this port. A non-zero value indicats that the
port is busy performing a command. A zero value indicates that the port is
enabled and available for use (not actively performing a command).

FcomVersion is the version number of the FryeCom DLL. This is the same number 
that is returned by the GetFcomVersion command.

FcomDate is the date this version of the FryeCom DLL was release.
The Frye Packed Date format is a DWORD value in the form; dd:ee:yyy:m
 where "yyy" = year, "m"=month, "dd"=day, "ee"=expire
"dd" is the most siginificant bits, and "m" is the least significant bits.
Each letter shown is 4 bits (eg "dd" is eight bits total).
(See FT_UnpackCalDate() to unpack the date.)

MaxPort is the last possible available com port that FryeCom DLL can access.
This is not the same as the number of actually present com ports.
There is no way to know what com ports are physically available until it
is specifically requested and Windows returns either a success or failure
to the attempt to access the com port. A failure doesn't mean that the com port
doesn't exist, it only means that Windows has denied access to the com port.

SeekState indicates the current status of the FryeCom DLL when it is searching
for a com port or new baudrate. A value of 1 indicates it is searching for
a com port with an attached Fonix instrument. A value of 2 indicates it is
searching for the baudrate of the com port with an attached Fonix instrument.
A value of 3 indicates it is doing both actions.

PortMode is the current operating mode of the port 0=character mode,
1=polled packet mode, 2=demand packet mode

Baudrate is the current operating baudrate of the com port. This will be
either the specified baudrate given with the OpenPort command, or the
detected baudrate if autobaud was enabled. 

NoPollTimeout is the current specified No Poll Timeout period in milliseconds.
OpenPort will set this to 5 seconds (5000) initially. This is the same value
that is returned by the GetNoPollTimeout command. The value can be changed
with the SetNoPollTimeout command.

PacketStatus, PacketControl, PacketState and Timer are the values that are
returned from the old $FF13 GetPacketStatus command. These contain detailed
status flags that indicate the current operational state of the underlaying
Fryers driver. See the separate documentation for the Fryers32 DLL for
details on what the flags indicate.

LastCommand is the first element of the last command array that was sent.
LastCommandSize is the second element of the array.
LastResponse is the first element of the last response array that was received.
LastResponseSize is the second element of the array.

AsciiStatus is only valid when in char mode. It returns the last known character 
transfer status of the port (see $03xx Fryers cmd). Only three bits are valid
F_CHAR_RXRDY ($2000), F_CHAR_TXRDY ($0100) and F_CHAR_TMOUT ($8000).  

AsciiCount is only valid when in char mode. It returns the number of bytes 
currently waiting to be read from the character mode receive buffer.

Spare is undefined and reserved for future use. Normally it will
return a zero value, but may return other values in the future.

If your application program compiler does not support packed record structures,
the port status can be read as an array of 32bit integers instead.

Possible errors:
FCOM_PORT_RANGE_ERROR, FCOM_PORT_NOT_OPEN, FCOM_INVALID_FORMAT


=============================================================
Sending commands to the instrument and getting responses:

-------------------------------------------------------------
Export #6
typedef int __stdcall (*tSendReady)(int ComPort, TfcCallback Callback);
function SendReady(ComPort:integer; Callback:TfcCallback):integer; stdcall export;

Use the SendReady command to determine if the system is ready to send a
command to the Fonix instrument.

ComPort is the comport that was used to open the port with OpenPort.
This is the handle for this call and must match the number that was used with
OpenPort. Do not change it. If you wish to use a different port, close the
current port and open the new desired port.

SendReady will return FCOM_SUCCESS (0) if the Fryers driver is ready to
accept a command to be sent to the Fonix instrument.

If the driver is not ready, a FCOM_NOT_READY response will be
returned. If there is a problem, an error will be returned.
See the error list for possible error codes returned.

Note: If auto-baud seek (see OpenPort) is enabled and the baudrate changes,
this command may take some time (up to a second or more) to return as the
Fryers driver seeks out the new baudrate. The Callback allows the calling
program to monitor the driver during this time and to cancel the operation
if it takes too long or is causing some other problem.

If the Callback value passed is NIL/NULL(0), the callback is not performed.
However if the auto-baud feature is enabled, the baudrate seek will still
be performed. If the auto-baud seek feature is not enabled, the SendReady 
command returns immediately with the status result and the Callback function 
is never performed (the passed Callback address is ignored). In this case,
the baudrate is set to the value specified. If it does not match the baudrate
of the attached Fonix instrument, you will not be able to communicate with
the Fonix instrument. Also if the user changes the baudrate of the instrument
the Fryers driver will not be able to remain synchronized to the Fonix
instrument and thus not be able to communicate with the instrument. 
It is best to use the auto-baud feature unless you have a reason not to use it. 

The auto-baud seek is performed during the OpenPort call and during the SendReady 
call (when auto-baud seek is enabled). The seek is only performed if the Fryers
driver determines that the baudrate has changed (this is done by analyzing the 
polls from the instrument as they are received). If the Fryers driver determines 
that there is a baudrate sync error, it will attempt to find the new baudrate.

When in FCOM_CHAR_MODE, this command will return the status of character mode 
send status instead of the packet mode send status (FCOM_NOT_READY=send port 
is busy, and FCOM_SUCCESS=port is ready to send a character). 

Possible errors:
FCOM_PORT_RANGE_ERROR, FCOM_GENERIC_ERROR, FCOM_PORT_NOT_OPEN,
FCOM_AUTOBAUD_FAILED, FCOM_GENERIC_ERROR, FCOM_CANCEL,
FCOM_NOT_READY, FCOM_NO_POLL

-------------------------------------------------------------
#export #7
typedef int __stdcall (*tSendCmdArray)(int ComPort, TfcArray* pData);
function SendCmdArray(ComPort:integer; pData:pCmdArray):integer; stdcall export;

Use this call to send a command to the attached Fonix instrument.
The passed array pointer is a pointer to an array of 16bit integers
containing the command for the instrument. (See the FIPP command documents
for details.)

This call returns immediately after loading the Fryers Send command array.
Once this call returns, the data array you provided is no longer needed and 
can be discarded if so desired. The Data being sent is retained inside the 
Fryers driver until the send is completed.

SendCmdArray will return FCOM_SUCCESS (0) if the Fryers driver
accepted the command to be sent to the Fonix instrument.
If there is a problem, an error will be returned.

Use the SendReady call first to determine if the FryeCom driver can accept 
a SendCmdArray call. If you try to send a command while another one is 
in progress, you will get a FCOM_SEND_OVERRUN error and the new command 
will not be sent.

In char mode, this command becomes a Send Character command. Currently only 
the first byte of the passed array is sent out the port. The Size parameter 
is ignored. To send multiple characters, you should call the SendReady() 
command to wait for the port to become ready, followed by the SendCmdArray() 
to send each character. Only one byte at a time can be sent. If more data 
is provided in the send array, it is ignored. The data is expected to be 
in the Data portion of the command array. While the Size parameter of the 
command array is currently ignored, it is recommended that you set the value 
to "1" for future use. The Cmd portion of the command array is ignored in
this mode.

Possible errors:
FCOM_PORT_RANGE_ERROR, FCOM_GENERIC_ERROR, FCOM_PORT_NOT_OPEN,
FCOM_GENERIC_ERROR, FCOM_SEND_OVERRUN, FCOM_SEND_ERROR,
FCOM_INVALID_FORMAT

-------------------------------------------------------------
export #8
typedef int __stdcall (*tRspReady)(int ComPort);
function RspReady(ComPort:integer):integer; stdcall export;

After a command has been sent with SendCmdArray, use the RspReady call to
determine when the instrument has returned it's response to the command 
that was sent, or to determine if a character byte has been recieved when 
in CHAR mode. 

This call returns immediately with the current response status.
If the response is not ready, a FCOM_NOT_READY response will be
returned. If there is a problem, an error will be returned.

When in CHAR_MODE, this command will return the status of character mode 
receive status instead of the packet mode rsp status 
(FCOM_NOT_READY=no data, and FCOM_SUCCESS=a character is available to read). 
The Data byte is returned in the Data portion of the command array. 
The Size paramter will be returned as "1" to indicate the byte was read, 
or "0" if no data was returned.
The Cmd portion of the command array is ignored in this mode.
Note: You can use the AsciiCount parameter in the PortStatus to determine
how many bytes of data are currently in the receive buffer.
The AsciiCount is continuously updated as new data comes in when in 
CHAR mode.

Possible errors:
FCOM_PORT_RANGE_ERROR, FCOM_GENERIC_ERROR, FCOM_PORT_NOT_OPEN,
FCOM_GENERIC_ERROR, FCOM_NO_POLL, FCOM_SEND_OVERRUN, FCOM_SEND_ERROR,
FCOM_NO_RESPONSE, FCOM_RESPONSE_ERROR, FCOM_RESPONSE_OVERRUN,
FCOM_NAK_RESPONSE

-------------------------------------------------------------
Export #9
typedef int __stdcall (*tGetRspArray)(int ComPort, TfcArray* pData);
function GetRspArray(ComPort:integer; pData:pRspArray):integer; stdcall export;

Use the GetRspArray call to get the response sent by the instrument.
The passed array pointer is a pointer to an array of 16bit integers
in which the response will be placed.

If there is a problem, an error will be returned.
Use the RspReady call first to determine when the response data is ready.
See the error list for possible error codes returned.

If you call GetRspArray when there is no response ready to be read 
as would happen without calling SendCmdArray first, or before the
response has come back, the previous command response will be returned 
in the array and a FCOM_NO_REPONSE error will be returned in the 
function result.

If you send a new command before the reponse to the previous command
has been read, the new response will overwrite the old unread response, 
and you will get a FCOM_RESPONSE_OVERRUN error.

Note: In polled mode all commands except QuickRelease will have a response 
by the instrument. In Demand mode, QuickRelease will provide an ACK response.
You should always check for the response to prevent command synchronization 
issues and to make sure that the attached instrument actually received and 
accepted the command.

In char mode, this command becomes a Receive Character command. Only one 
byte of data at a time can be read from the port with this command. 
To read multiple characters, you should call the RspReady() command to wait 
for the port data to become ready, followed by the GetRspArray() to read the 
character from the port. You can read the AsciiCount variable in PortStatus 
to see if there are any characters waiting in the char mode receive buffer.
The AsciiCount variable is only valid when in CHAR mode.

Possible errors:
FCOM_PORT_RANGE_ERROR, FCOM_GENERIC_ERROR, FCOM_PORT_NOT_OPEN,
FCOM_GENERIC_ERROR, FCOM_SEND_OVERRUN, FCOM_SEND_ERROR,
FCOM_RESPONSE_ERROR, FCOM_RESPONSE_OVERRUN, FCOM_NAK_RESPONSE,
FCOM_ILL_RESPONSE, FCOM_POLL_RESPONSE, FCOM_INVALID_FORMAT
FCOM_NO_RESPONSE

-------------------------------------------------------------
Export #10
typedef int __stdcall (*tSetNoPollTimeout)(int ComPort, int Value);
function SetNoPollTimeout(ComPort:integer; Value:integer):integer; stdcall export;

You can change the No poll timeout using this call. 
Do not set the time too short (less than one second), or the communication 
interface may not function properly.

The purpose of this command is to prevent poll timeout errors (No Poll Error)
caused by commands that take an excessive amount of time to complete in the
Fonix instrument (such as a pure tone sweep with 16x noise reduction)
which can take longer than the default timeout of 5 seconds.

The best time to send this commmand is immediately after you use the
SendCmdArray command. Set the No Poll timeout to the amount of time that
you expect the command to take plus a safety margin. The default timeout
period is 5 seconds. 

See the FippCore source code for an example of how to implement the use 
of the NoPollTimeout feature. You can use the FippCore example as the 
starting point for your own programming. 

The purpose of the no poll timeout is to help identify when an instrument
is not attached to the com port or is no longer communicating.
The Fryers driver uses the poll requests from the instrument to recognize
when a Fonix instrument is attached to the com port. If Fryers does not
see a poll request within the specified timeout period, it assumes that
the instrument is not there and raises the No Poll flag to notify the
application.

The No Poll is normally detected during the SendReady call to determine if
the port is ready. If the Fonix instrument does not send a poll request
within the specified timeout period, the SendReady call will return a
FCOM_NO_POLL response. You can either act on this if it is important, or
wait for the error condition to go away if the instrument is present, but 
doing something that is taking longer than the timeout period that was 
specified. As long as the No Poll condition exists, the SendCmdArray cannot 
send a command since it requires the Poll request from the instrument to 
know that the instrument is out there and ready to accept the command.

The Value is in milliseconds (example: 5 seconds = 5000).

Note: The underlaying Fryers32 driver uses the old MSDOS system tick count
resolution time (55 millisecond increments). You should be aware of this 
difference if you are upgrading existing programming or placing calls directly 
to the underlaying Fryers driver. 

If the call was successful, it will return FCOM_SUCCESS.
If there is a problem, an error will be returned.
See the error list for possible error codes returned.

This function is only valid for the FCOM_MODE_POLLED port mode.

Possible errors:
FCOM_PORT_RANGE_ERROR, FCOM_GENERIC_ERROR, FCOM_PORT_NOT_OPEN

-------------------------------------------------------------
Export #11
typedef int __stdcall (*tGetNoPollTimeout)(int ComPort, int* Value);
function GetNoPollTimeout(ComPort:integer; var Value:integer):integer; stdcall export;

GetNoPollTimeout can be used to get the current No poll timeout so that
it can be restored if desired after using the SetNoPollTime call.

The Value is in milliseconds (example: 5 seconds = 5000).

If the call was successful, it will return FCOM_SUCCESS and Value will
be updated with the current Poll Timeout value.
If there is a problem, an error will be returned.
See the error list for possible error codes returned.

This function is callback safe.
This function is only valid for the FCOM_MODE_POLLED port mode.

Possible errors:

FCOM_PORT_RANGE_ERROR, FCOM_GENERIC_ERROR, FCOM_PORT_NOT_OPEN,
FCOM_INVALID_FORMAT

-------------------------------------------------------------
Export #12
typedef int __stdcall (*tGetFcomVersion)(int *FcomVersion);
function GetFcomVersion(var FcomVersion:integer); stdcall export;

Some functions, especially those those that need to be compatible to
older systems need to know what version of Fryers is being used.
The GetFcomVersion call can be used to get the version number
of the FryeCom DLL.

Note: FryeCom will return a version of 7.00 or higher.
Versions of the Fryers32 DLLs return lower numbers.
(You can use the CallFryers function 0xFFFF or 0xFFFE commands
to request a version number of the underlaying Fryers32 driver.)

The GetFcomVersion call does not require a ComPort Number and
will not interfer with any command being processed.

If the GetFcomVersion variable is passed with a bad address (NIL),
the Error FCOM_INVALID_FORMAT will be returned, otherwise
FCOM_SUCCESS will be returned and FcomVersion will be updated with
the FryeCom Version number.

This function is callback safe.

Possible errors:
FCOM_INVALID_FORMAT

-------------------------------------------------------------
Export #13
typedef int __stdcall (*tMaxComPort)(int *MaxPort);
function MaxComPort(var MaxPort:integer); stdcall export;

Depending on the system configuration, the last available comport may
change. Currently FryeCom supports COM1 (0) through COM100 (99).
You can use MaxComPort to determine the last available comport.

If the MaxPort variable is passed with a bad address (NIL),
the Error FCOM_INVALID_FORMAT will be returned, otherwise
FCOM_SUCCESS will be returned.

MaxPort does not require that a Fonix instrument be attached, nor
does it require a comport to be open and will not interfer with any
command currently in progress.

This function is callback safe.

Possible errors:
FCOM_INVALID_FORMAT

-------------------------------------------------------------
Export #14
typedef int __stdcall (*tGetDebugStatus)(int ComPort, tDebugStatusRec* PortStatus);
function GetDebugStatus(ComPort:integer; var DebugStatus:tDebugStatusRec):integer; stdcall export;

This call will return internal detail status of the Fryers driver for
the specified comport. The call will return the information shown below.
This is primarily intended for debugging, however the information can be used
for any purpose. You can call this function at anytime. It will not disrupt any
on-going activity.

This function is callback safe.

type tDebugStatusRec = packed record
  ComPort : integer;       //this com port
  PortState : integer;     //see PortStatus.PortState
  Handle : integer;          //Windows comport resource handle
  ReadPortCount : integer;   //Number of port accesses since port was opened
  ReadFailCount : integer;   //Number of failed port reads since port was opened
  CmdSendCount : integer;    //Number of commands sent since port was opened
  FailedRspCount : integer;  //Number of failed responses since port was opened
  ValidPollCount : integer;  //Number of successful polls since port was opened
  FailedPollCount : integer; //Number of failed polls since port was opened
  TotalBytesRead : integer;  //Number of successful bytes read since port was opened
  DebugState : integer;      //used to passback state conditions during debugging
  PortOpenControl : integer; //Operational control port was opened with (0,1,2,3,4)
  Spare2 : integer;          //spare parameter for future use
  Spare3 : integer;          //spare parameter for future use
  Spare4 : integer;          //spare parameter for future use
  Spare5 : integer;          //spare parameter for future use
end;

ComPort and PortState are the same values as returned by the GetPortStatus command.

Handle is the Windows handle that was returned when the FryeCom driver requested
the comport resource from Windows. This can be used during debugging to gain
access to the Windows comport information. Extreme care should be used though
as directly accessing the comport (bypassing FryeCom) can disrupt the FryeCom driver.

ReadPortCount and ReadFailCount return the number of comport read accesses
that have occured since the port was opened with the OpenPort command.
CmdSendCount is the number of commands that have been sent since the port
was opened. FailedRspCount is the number of failed responses that have occured
since the port was opened. ValidPollCount is the number of poll requests that
have been sent by the attached Fonix instrument since the comport was opened.
FailedPollCount is the number of failed poll requests that have occured since
the comport was opened. TotalBytesRead is the number of bytes that have been
read from the port since the comport was opened.

It is normal for there to be some error counts present as they normally occur
during synchronization of the port. Also it is normal for occasional errors
to occur during operation. The FryeCom driver and the underlaying Fryers
driver have extensive error handling to correct for communication errors that
can occur with any communications that operates with real-world devices.
These values are primarily used during development to monitor the driver
status during the stress testing of the driver.

DebugState does not return a specified value, it is used during development
debugging to peek under the hood. Spare1->Spare5 are undefined and reserved
for future use. Normally they will return zero values, but may return
other values in the future.

PortOpenControl is a copy of the PortControl paramter passed to the OpenPort
command. Note: if the port is opened with autobaud enabled, it will be rememebered
and the driver will use autobaud whenever the port mode is set to FCOM_MODE_POLLED.
(Autobaud only works in Polled packet mode.)

If your application program compiler does not support packed record structures,
the debug status can be read as an array of 32bit integers instead.

Possible errors:
FCOM_PORT_RANGE_ERROR, FCOM_PORT_NOT_OPEN, FCOM_INVALID_FORMAT


-------------------------------------------------------------
Export #15
typedef int __stdcall (*tCancelCmd)(int ComPort);
function CancelCmd(ComPort:integer); stdcall export;

This function will attempt to cancel a command in progress if it exists.
Normally you should not need to call this. If things are truely messed up, 
a safer way is to close the port, then reopen it as that will re-initialize
everything on the port. 

This function is only valid for the FCOM_MODE_POLLED and FCOM_MODE_DEMAND port modes.

Possible errors:
FCOM_PORT_RANGE_ERROR, FCOM_PORT_NOT_OPEN, FCOM_GENERIC_ERROR, FCOM_INVALID_FORMAT


-------------------------------------------------------------
Export #16
typedef int __stdcall (*tSetPortMode)(int ComPort, int NewPortMode);
function SetPortMode(ComPort:integer; NewPortMode:integer); stdcall export;

This function will attempt to change the port operation mode.
Possible modes are:
FCOM_MODE_CHAR   : (0) character mode (single byte transfers)
FCOM_MODE_POLLED : (1) polled mode (default mode of operation)
FCOM_MODE_DEMAND : (2) demand mode (non-polled operation)

Polled mode is the normal state that the FryeCom driver is started in. 
You can set the driver to DEMAND mode or CHAR mode, but care should be used
with these modes. CHAR mode is intended for single byte transfers. 
DEMAND mode is intended for use with future Ethernet operation.
The normal mode of operation with Fonix equipment using serial mode operation
is to use the POLLED mode. 

Note: Automatic port detection and baudrate synchronization can only be done 
in POLLED mode (the polling mechanism is used for the detection and synchronization). 
When you change to POLLED mode from CHAR or DEMAND mode, the previously used
PORT_SEEK and BAUD_SEEK parameters are used. If you wish to change them, you 
must close the port and reopen it with the new parameters. This command will
fail if the port is not open.

Possible errors:
FCOM_PORT_RANGE_ERROR, FCOM_PORT_NOT_OPEN, FCOM_GENERIC_ERROR, FCOM_INVALID_FORMAT


-------------------------------------------------------------
Export #17
typedef int __stdcall (*tSetPortMode)(int ComPort, int CurrentPortMode);
function GetPortMode(ComPort:integer; CurrentPortMode:integer); stdcall export;

This function will return the current driver port operation mode.
Possible modes are:
FCOM_MODE_CHAR   : (0) character mode (single byte transfers)
FCOM_MODE_POLLED : (1) polled mode (default mode of operation)
FCOM_MODE_DEMAND : (2) demand mode (non-polled operation)

Possible errors:
FCOM_PORT_RANGE_ERROR, FCOM_PORT_NOT_OPEN, FCOM_GENERIC_ERROR, FCOM_INVALID_FORMAT


-------------------------------------------------------------
Error codes returned by FryeCom commands:

//common errors
#define SUCCESS 0                    //successful operation
#define CANCEL -1                    //user canceled operation (via callback)
#define FCOM_CANCEL  CANCEL          //operation was canceled
#define FCOM_SUCCESS SUCCESS         //successful operation
#define FCOM_BUSY 4                  //Com port is busy sending/receiving a command
#define FCOM_NOT_READY FCOM_BUSY     //Same definition as FCOM_BUSY

//FryeCom/Fryers Code Access Errors are -1000 series numbers
#define FCOM_FILE_NOT_FOUND -1000    //device driver file not found
#define FCOM_ENTRY_NOT_FOUND -1001   //entry point to fryers driver not found
#define FCOM_GENERIC_ERROR -1002     //unknown error - something bad happened

//FryeCom Packet Communication errors use the -9000 series
#define FCOM_GENERIC_ERROR -9000;     //generic unknown error
#define FCOM_PORT_RANGE_ERROR -9001;  //not a valid comport selection (out of range)
#define FCOM_PORT_NOT_FOUND -9002;    //Requested port not available
#define FCOM_PORT_NOT_OPEN -9003;     //Requested port not open for communication
#define FCOM_AUTOBAUD_FAILED -9004;   //could not find baudrate

#define FCOM_NO_POLL -9010;           //no polls from the instrument
#define FCOM_SEND_OVERRUN -9011;      //trying to send another command before old one done.
#define FCOM_SEND_ERROR -9012;        //error while trying to send the command

#define FCOM_NO_RESPONSE -9020;       //no response received
#define FCOM_RESPONSE_ERROR -9021;    //error while receiving the response
#define FCOM_RESPONSE_OVERRUN -9022;  //current response overwrote previous response
#define FCOM_NAK_RESPONSE -9023;       //NAK rcvd as a respond
#define FCOM_ILL_RESPONSE -9024;      //illegal command rcvd as a response
#define FCOM_POLL_RESPONSE -9025;     //poll rcvd as a response
#define FCOM_CMD_FAIL -9026;          //unexpected response to a command
#define FCOM_UNEXPECTED_ACK -9027;    //unexpected ACK response to a command

#define FCOM_INVALID_FORMAT -9999;    //The passed format is invalid (missing pointer?)

-------------------------------------------------------------

