Files
sibo-playground/docs/2-03 IO Devices Reference 2.30_djvu.txt
2026-07-06 18:30:29 +01:00

14946 lines
370 KiB
Plaintext
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
SIBO 'C' Software Development Kit
I/O DEVICES REFERENCE
Version 2.30
March 1, 1999
(C) Copyright Psion PLC 1990-97
All rights reserved. This manual and the programs referred to herein are copyrighted works of Psion PLC,
London, England. Reproduction in whole or in part, including utilization in machines capable of
reproduction or retrieval, without express written permission of Psion PLC, is prohibited. Reverse
engineering is also prohibited.
The information in this document is subject to change without notice.
Psion and the Psion logo are registered trademarks, and Psion, Psion MC, Psion HC, Psion Series 3, Psion
Series 3a, Psion Series 3c, Psion Siena and Psion Workabout are trademarks of Psion PLC.
TopSpeed is a registered trademark of Clarion Software Corporation. Intel 8086 and 80286 are registered
trademarks of Intel Corporation. IBM, IBM XT and IBM AT are registered trademarks of International
Business Machines Corp. Microsoft and MS-DOS are registered trademarks of Microsoft Corporation.
Apple and Macintosh are registered trademarks of Apple Computer Inc. VAX and VMS are registered
trademarks of Digital Equipment Corporation. Brief is a registered trademark of Underware Inc. Psion
PLC acknowledges that some other names referred to are registered trademarks.
Contents
1 Introduction
Conventions used in this manual
2 Console
Introduction
Automatic opening of a console channel
Explicit opening of a console channel
P_FSET service call convention
Panics
Console services
Open the console (p_open)
Close the console (p_close)
Write to the console (p_write)
Read a keypress (P_LFREAD)
Cancel an outstanding read (P_FCANCEL)
Test for outstanding keypresses (P_FTEST)
Flush keyboard buffer (P_FFLUSH)
Edit a string (P_FEDIT)
Sense console data (P_FSENSE)
Set the console window size (P_FSET, P_SCR_WSET)
Scroll the window content (P_LSCR_SCROLL)
Clear a rectangle (P_FSET, P_SCR_CLR)
Position cursor to next line (P_FSET, P_SCR_NEL)
Set the cursor position (absolute) (P_LFSET, P_SCR_POSA)
Set the cursor position (relative) (P_LFSET, P_SCR_POSR)
Turn the cursor on or off (P_FSET, P_SCR_CURSOR)
Set scroll lock (P_LFSET, P_LSCR_SLOCK)
Set auto wrap (P_FSET, P_SCR_WLOCK)
Set escape on or off (P_FSET, P_SCR_ESCAPE)
Set compatibility on or off (P_FSET, P_LSCR_COMPATIBILITY)
Set the use of grey on or off (P_LFSET, P_LSCR_GREY)
Additional console services
Read an event (PLEVENT_READ)
Test for outstanding event (P_LEVENT_TEST)
Get console data (P_FINQ)
Flush window server buffer (P_FWFLUSH)
Set the console output rectangle (P_FSET, P_SCR_CSET)
Set character attributes (P_FSET, P_SCR_ATTRB)
Set the screen font (P_FSET, P_SCR_FONT)
Set the last line wrap (P_FSET, P_SCR_LAST_LINE_WRAP)
Set window server flushing (P_FSET, P_SCR_FLUSH)
Disable reads (P_FSET, P_SCR_DISABLE READS)
Bring to foreground (P_FSET, P_SCR_CLIENT_FOREGROUND)
Capture a key (P_LFSET, P_SCR_CAPTURE_KEY)
Cancel a key capture (P_LFSET, PLSCR_CANCEL_CAPTURE_KEY)
Example
3 Parallel Port
Introduction
Parallel port device names
Panics
Ww &
ae es
Parallel port services
Open a parallel port (p_open)
Close a parallel port (p_close)
Write to a parallel port (P_FWRITE)
Cancel a write request (P_FCANCEL)
Sense the input control lines (P_FSENSE)
Write the output control lines (P_FSET)
Example
Introduction
Serial port device names
Panics
Serial port parameters
Baud rate
Character frame
Parity
Handshaking
Control flags
Terminator characters
Serial port errors
Serial port services
Open a serial port (p_open)
Close a serial port (p_close)
Read from the serial port (P_FREAD)
Write to the serial port (P_FWRITE)
Cancel any outstanding requests (P_FCANCEL)
Sense the serial port characteristics (P_FSENSE)
Set the serial port characteristics (P_FSET)
Flush the read buffer (P_FFLUSH)
Test for received characters (P_FTEST)
Test and set control lines (P_FCTRL)
Inquire supported serial characteristics (P_FINQ)
Introduction
Sound on MC and HC machines
Sound on Series 3 machines
Sound on Series 3a machines
Panics
Sound services
Open the sound channel (p_open)
Close the sound channel (p_close)
Cancel a write request (P_FCANCEL)
Sense sound characteristics (P_FSENSE)
Set sound characteristics (P_FSET)
Write alarm note sequence (E_LFALARM)
HC, MC and Series 3a additional sound service
Write to voice n (E_LFSSOUNDCHANNELn)
Series 3 and Series 3a additional sound service
Write DTMF dial tones (E_FDIAL)
Example
1/0 DEVICES REFERENCE
WwW WW WW WwW W
WNHONNNR RR
4 Serial Port
5 Sound
NNANAAnAnNnaannannnnnann
r
ABRRBOBBWNNHNNHNNHNKRHR SEE
ii
CONTENTS
6 The Alarm Device Driver 6-1
Introduction 6-1
Panics 6-2
Series 3, Series 3a and MC alarm services 6-2
Open the alarm channel (p_open) 6-2
Close the alarm channel (p_close) 6-2
Cancel an alarm request (P_FCANCEL) 6-2
Queue a timed alarm (A_FTIMED) 6-2
Queue an untimed alarm (A_FUNTIMED) 6-3
Series 3a additional alarm services 6-3
Queue a Series 3a timed alarm (A_FTIMED_X) 6-3
Queue a Series 3a untimed alarm (A_FUNTIMED_X) 6-4
7 The Free-Running Counter 7-1
Introduction 7-1
FRC services 7-1
Open the FRC channel (p_open) 7-1
Close the FRC channel (p_close) 7-2
Cancel the FRC request (P_FCANCEL) 7-2
Start the free-running counter (A_FTIMED) 7-2
Read the elapsed time in ELFRC_COUNTING mode (P_FREAD) 7-2
Read the elapsed time in E_-FRC_REPEATING mode (P_FREAD) 7-3
8 The Series 3 World Database 8-1
Introduction 8-1
Mode 8-1
Series 3 and Series 3a World database services 8-2
Open the World channel (p_open) 8-2
Close the World channel (p_close) 8-2
Cancel a World request (P_FCANCEL) 8-2
Find by city (WR_FIND_CITY) 8-2
Find by country (WR_FIND_COUNTRY) 8-2
Find by city and country (WR_FIND_EXACT) 8-3
Find next city (WR_NEXT) 8-3
Find previous city (WR_BACK) 8-3
Find home city (WR_GET_HOME) 8-3
Set home city (WR_SET_HOME) 8-3
Find default country (WR_GET_DEFAULT_COUNTRY) 8-4
Set default country (WR_SET_DEFAULT_COUNTRY) 8-4
Get dial string (WR_GET_DIAL_STRING) 8-4
Open file for additional data (WR_SET_EXTRA) 8-5
Modify additional data (WR_EXTRA) 8-5
Read city data (WR_GET_CITY_DATA) 8-6
Read city data (WR_GET_COUNTRY_DATA) 8-7
Calculate distance, sunrise and sunset (WR_CALC) 8-8
Read next city name (WR_NEXT_LOCK) 8-9
World file types and their locations 8-9
Main World file 8-9
World Extension file 8-9
World File format 8-9
World Extension File format 8-10
File header 8-10
Data block 8-10
iii
I/O DEVICES REFERENCE
9 Xmodem and Ymodem
Introduction
Data transfer protocols overview
One byte checksum
Two byte Cyclic Redundancy Check (CRC)
The Xmodem protocol
Link establishment
The data transfer phase
Link termination
Checksum data flow showing error recovery
The CRC variant
CRC data flow showing error recovery
The 1K variant
The 1K option data flow
Abandoning a transfer
The Ymodem protocol
Link establishment
The data transfer phase
Link termination
Ymodem file transfer data flow
The 1K variant
The G variant
Ymodem-G file transfer data flow
Abandoning a transfer
Protocol problems
Xmodem/Ymodem services
Open an Xmodem/Ymodem channel (p_open)
Close the Xmodem channel (p_close)
Connect to the remote computer (P_FCONNECT)
Disconnect from the remote computer P_FDISCONNECT)
Read data from the remote computer (P_FREAD)
Write data to the remote computer (P_FWRITE)
10 NCP and Link
iv
Introduction
Panics
The Psion logical link layer protocol
The SYS$NCP process
Connection establishment
Data transfer
The LINK process
NCP services
Open an NCP channel (p_open)
Close the NCP channel (p_close)
Connect to a remote process (P_FCONNECT)
Disconnect from the remote process (P_FDISCONNECT)
Read data from the remote process (P_LFREAD)
Write data to the remote process (P_FWRITE)
Cancel any outstanding request (P_FCANCEL)
Read supervisory information (P_FRSUPER)
Respond to a supervisory message (P_FINQ)
Sense the current channel activity (P_FSENSE)
Request the SYS$NCP terminate (P_FSTOP)
Example
°
XO 0 0 O_O OO O_O SOO SO 0 XO
BBWWWWNNN DN RRR
Ne)
I I I I I I I
aN
KH HB woeomOUNUUADAUUY
So
Neo
11 Cradle and Docking Station
Introduction
Cradle/Docking Station services
Open the device (p_open)
Close the channel (p_close)
Read from the device (P_FREAD)
Cancel a read (P_LFCANCEL)
Set the device type (P_FSET)
Sense the device type (P_FSENSE)
12 HC Magnetic Card Reader
Introduction
Open the MCR device (p_open)
Close the channel (p_close)
Read from the MCR device (P_FREAD)
Cancel a read (P_LFCANCEL)
Set the pull-up resistors (P_FSET)
13 HC Bar Code Reader
Hardware Description
The Bar code reader interface module
The bar code reader wand.
Device drivers
Bar code driver services
Open the bar code device (p_open)
Close the channel (p_close)
Read from the MCR device (P_FREAD)
Cancel a read (P_LFCANCEL)
14 HC Intelligent Bar Code Reader/RS232 Port
RS232/intelligent bar code reader module
The RS232 serial port interface
Power consumption
Powering the HC from an external power source
DSR auto wakeup switch
The bar code interface
Power consumption
Powering a bar code wand from the HC
Bar code symbologies
Code 128
Codabar
Interleaved 2 of 5
Code 39
The UPC/EAN bar code formats
UPC E
UPC E + 2 digits
UPC E + 5 digits
EAN 8 bar code format
EAN 8 + 2 digits
EAN 8 + 5 digits
EAN 13
EAN 13 + 2 digits
EAN 13 + 5 digits
UPC A
UPC A + 2 digits
UPC A + 5 digits
CONTENTS
I/O DEVICES REFERENCE
Bar code commands
Multiple options in a command
Issuing multiple commands
Serial intercharacter delay
Hard reset
Select bar code symbology
Check character options
Decoding options
Single read mode
Single read control
Set Interleaved 2 of 5 length
Set termination string
Code ID characters
Status request
Scanner enable
RS232 port/bar code driver services
Open the device (p_open)
Close the channel (p_close)
Sense serial port characteristics (P_FSENSE)
Set serial port characteristics (P_FSET)
Read from device (P_FREAD)
Write to device (P_FWRITE)
An example program
15 Introduction to Psion Infrared Communications
About this chapter
The IrDA protocol layer model
Introduction to Psion infrared communications
The Psion protocol layer model
The physical layer
Port geometry
Data transfer rate
Data link layer
Primary and secondary stations
IrLAP services
The network layer
IAS application logging
Discovery
Multiplexing
Link Control
The Psion IR Communications application
Third party applications
System resources
Keypresses
The IR printer port device driver
16 The AccessIr API
Using the AccessIr API
Prerequisites
Introduction to using the AccessIr API
Initialising the IR protocol stack
Opening and closing a channel to the IR device
Discovery
Selection
Connection
Sending and accepting data
Disconnection
Constants
CONTENTS
Opening and closing a channel to the IR device 16-3
Open a channel to the IR device (p_open) 16-3
Close a channel to the IR device (p_close) 16-4
Discovery, selection and connection 16-4
Discover IR enabled machines (P_FIRDISCOVER) 16-4
Select remote machine to connect to (P_FIRSELECT) 16-4
Connect to selected machine (P_FIRMAKECONNECT) 16-5
Wait for remote connect (primary) (P_FIRAWAITCONNECT) 16-5
Send and accept data 16-6
Accept data from selected remote machine (P_FREAD) 16-6
Send data to the selected remote machine (P_FWRITE) 16-6
Disconnection 16-6
Disconnect from remote machine (P_FIRDISCONNECT) 16-6
Example application 16-7
17 The IrMUX API 17-1
Using the IrMUX API 17-1
Prerequisites 17-1
Introduction to using the ITMUX API 17-1
Initialising the IR protocol stack 17-1
Logging on to and logging off from the ITMUX server 17-2
Registering/unregistering applications with the LM-IAS server 17-2
LM-IAS services 17-2
The IAS Get Value By Class message frame 17-3
The IAS Get Value By Class reply frame 17-3
Connectionless calls 17-3
Reading and writing data 17-3
Connection-oriented calls 17-3
Discovery 17-4
Connection - first time 17-4
Disconnecting - first time 17-4
Connection - second time 17-4
Reading and writing data 17-4
Disconnecting - second time 17-4
Using Exclusive mode 17-4
The IrMUX API 17-5
IrMUX message format 17-5
Log on to the IrMUX server (LM_Logon) 17-5
Log off from the ITMUX server (LM_Logoff) 17-5
Register a port number with the LM-IAS server (LM_RegisterPort) 17-5
Free registered port with LM-IAS server (LM_UnRegisterPort) 17-6
Queue a connectionless read request (LM_CLReadRequest) 17-6
Queue a connectionless write request (LM_CLWriteRequest) 17-7
Return info on in-range machines (LM_DiscoverDevicesRequest) 17-7
Attempt to connect to a remote machine (LM_ConnectRequest) 17-7
Wait for remote machine to connect (LM_WaitForConnection) 17-8
Return the status of the link (LM_StatusRequest) 17-9
Queue a read request on a connection (LM_ReadRequest) 17-9
Queue a write request on a connection (LM_WriteRequest) 17-10
Queue an unreliable read request (LM_UReadRequest) 17-10
Queue an unreliable write request (LM_UWriteRequest) 17-11
Obtain/release exclusive access (LM_AccessModeRequest) 17-11
Place the connection into Idle/Active mode (LM_IdleRequest) 17-12
Set retries on each data frame (LM_SetHandshakingLevel) 17-12
Disconnect (LM_DisconnectRequest) 17-13
1/0 DEVICES REFERENCE
18 Fast Charger
Introduction
Docking Station services
HC/Workabout docking station fast charger services
Fast charging batteries
Measuring battery capacity
Rated charge capacity of standard Psion battery packs
Example calculations
Open the fast charger device (p_open)
Close the channel (p_close)
Set the battery charge mode (FCHG_SETCHARGEMODE)
Charging Psion battery packs
Charging custom battery packs
Read battery charge mode (FCHG_READCHARGEMODE)
Read the battery status (FCHG_READSTATUS)
Read the battery status asynchronously (FCHG_ASYNCHREAD)
Cancel an asynchronous read (FCHG_CANCEL)
Fast charge the main battery (FCHG_FASTCHARGE1)
Fast charge the spare battery (FCHG_FASTCHARGE2)
Discharge the main battery (FCHG_DISCHARGE1)
Example program
18-1
18-1
18-1
18-2
18-3
18-3
18-3
18-3
18-4
18-4
18-4
18-5
18-6
18-6
18-7
18-7
18-7
18-7
18-8
18-8
CHAPTER 1
INTRODUCTION
This manual describes the I/O device drivers that have been written by Psion, except for the files device
driver and the the asynchronous timer device driver which are described in the Files and the Time,
Timers and Dates chapters of the PLIB Reference manual.
Before using any of the devices described in this manual the reader should be familiar with the contents of
the Asynchronous Requests and Semaphores and the I/O System chapters of the PLIB Reference manual.
Conventions used in this manual
I/O devices support a number of services, each specified by a function number of the form P_Fxxxx
(defined in p_file.h). For example, to write to a channel opened with a control block at *pcb, you may call:
p_ioc(pcb,P_FWRITE, additional parameters) ;
The notation p_ioc(P_FWRITE) or, more simply, P_FWRITE is used to refer to this function call.
All I/O function requests are asynchronous in principle. In practice, however, many I/O requests are
implemented synchronously, that is, the I/O operation will complete before the service call returns. For
example, the P_FCLOSE service is always implemented synchronously but the p_rREaD service is commonly
implemented asynchronously.
The description of a service that is implemented synchronously gives either the specific synchronous call
(such as p_open or p_close) or the p_iow service call prototype. Services implemented synchronously are
prototyped using only the p_iow I/O primitive, since there is no advantage in calling them
asynchronously.
A service that is implemented asynchronously may be called synchronously or asynchronously. The
description gives both the synchronous call (as described above) and the asynchronous p_ioc service call
prototype. Such a service may be called using the p_iow, p_ioc or p_ioa primitives. Note that the use of
p_ioc is in almost all cases preferable to the use of p_ioa (since the former will complete even in the
event of an error).
Note that smaller code will be generated by use of the primitives:
p_iow2, p_iow3, p_iow4, p_iow5,
p_ioc3, p_ioc4, p_ioc5d,
p_ioa3, p_ioa4, p_ioad.
Again the use of, for example, p_ioc3 is in almost all cases preferable to the use of p_ioa3. The same
statement applies to the other two variants of each function.
CHAPTER 2
CONSOLE
Introduction
The console (con: ) device provides a basic set of screen and keyboard services, suitable for use by
relatively simple character-based C application programs. OPL programs automatically open a console
channel to provide support for the screen display and keyboard commands.
The console device is implemented differently on different machines in the SIBO range:
e on the HC and Series 3 machines the console device connects directly to the window server.
e onthe MC 200 and MC 400 machines the console device is implemented by an intermediate
sysscons display process.
There are also some differences in the services that are available on different machines. These differences
are stated in the description of the particular service to which they apply.
Some of the console functions use the P_PoINT, P_RECT and P_REcTP structures. They are defined in
p_graf.h (which is included by p_cons.h) as:
typedef struct
{
WORD x; /* x coordinate */
WORD y; /* y coordinate */
} P_POINT;
typedef struct
{
P_POINT tl; /* top left coordinates */
P_POINT br; /* bottom right coordinates */
} P_RECT;
typedef struct
{
P_RECT r; /* rectangle */
P_POINT p; /* point */
} P_RECTP;
Co-ordinates are measured from the top left corner of the window (0, 0), and increment to the right (x)
and down (y). Co-ordinates are measured in character units.
When rectangles are specified the top left point is included in the rectangle and the bottom right corner is
just outside the rectangle. If a rectangle extends outside the console window then it is clipped to fit inside
the window (this feature may be used to save sensing the size of the window when a scroll or clear is
required up to the right/bottom edge of the window).
Versions of EPOC prior to version 2.32 do not support the opening of a console device when the
application program's total memory usage exceeds 32k.
I/O DEVICES REFERENCE
Automatic opening of a console channel
A channel to the console device is opened automatically during the start-up initialisation of a C program
built with the CLIB start-up module. This does not occur in the case of programs built with the PLIB
start-up module.
In PLIB programs, however, the console (if not already open) is opened automatically by the first use of
one of the PLIB simple console I/O functions (p_getch, p_printf, etc.) described in the //O System
chapter of the PLIB Reference manual.
The console channel handle of an automatically opened console device channel is stored in the pre-
defined static winHandle.
An automatically opened console is set to a size appropriate for the SIBO machine on which the
application is running. In a PLIB program you may, however, specify the window size of an automatically
opened console by setting the global p_REcT structure _DefScreenRect, as follows:
GLDEF_D _DefScreenRect;
_DefScreenRect.tl.x=0;
_DefScreenRect.tl.y=0;
_DefScreenRect.tl1.x=40; /* 40 columns */
_DefScreenRect.tl.x=8; /* 8 rows */
An automatically opened console is also set to the native mode of the machine. On the Series 3a machine
the console is opened in non-compatibility, with access to grey. In a PLIB program you may modify the
console mode by setting the global variable _pefscreenMode. The possible modes that may be set are:
use the native mode of the machine - this is the default value
compatibility mode, allowing Series 3 software to run on the Series 3a
non-compatibility mode, with grey enabled
compatibility mode, but with grey enabled
WN FO
Thus, compatibility mode may be set as follows:
GLDEF_D INT _DefScreenMode;
_DefScreenMode=1;
Values that are not relevant to a particular type of machine are simply ignored.
If used, the values of _DefScreenRect and _DefScreenMode must be set before the first usage of any
function that causes the console to be opened. Ignore the duplication message generated by the linker
when this code is included in your application.
In CLIB programs you can prevent the automatic opening of a console channel by defining the function
p_xwind in your code, as in the following example:
extern void *winHandle;
void p_xwind (void)
{
winHandle=(void *)1;
}
int main(void)
{
return (0);
}
You should ignore the warning, given during the linking of your program, that the symbol _p_xwind is
duplicated.
2 CONSOLE
If you use this technique, your CLIB program should not, of course, make any reference to stdin, stdout
or stderr, unless you have redirected them. Setting winHandle to | (an illegal value for a handle) will
guarantee that any such reference will fail with a panic.
Explicit opening of a console channel
In a PLIB program you may, if you wish, explicitly open a console channel by means of p_open. The
console channel handle must be stored in the pre-defined static winHandle that is used for an
automatically opened console channel. For example:
GLREF_D VOID *winHandle;
p_open (&winHandle, "CON:",-1);
This is particularly important if your program uses any of the PLIB simple console I/O functions.
Otherwise you may inadvertently attempt to open two console channels from the same process and your
process will be panicked.
After explicitly opening the console and before making any other use of its services you must make it
visible by setting its size with the p_rseEt service, using the p_scr_wset function code.
Compatibility mode and the availability of grey can be set by means of the p_Fset service, using the
P_SCR_COMPATIBILITY and p_scr_GRey function codes.
P_FSET service call convention
The p_rset function provides a number of services, determined by a function code. The function code is
assigned to a uworp whose address is passed as the third parameter to the p_iow function. The convention:
INT p_iow(VOID *pcb, P_FSET, &P_SCR_CLR, P_RECT *prect);
is used to denote this. It should be interpreted as:
UWORD function;
function = P_SCR_CLR;
p_iow (pcb, P_FSET, &function,prect) ;
or equivalent.
Panics
All services (with the exception of p_open) will cause the calling process to be panicked if the passed
channel handle is not valid. Other panics are described under the particular service to which they apply.
SSS ee
Console services
p_open(CON:) Open the console
INT p_open(VOID **ppcb, CON:, -1);
Open a channel to the console device, writing the channel handle to *ppcb if successful. The console
window is not made visible until its size has been set by the p_rset service with a function code of
P_SCR_WSET.
When first opened the console properties are:
e auto wrap on
e auto flushing on
e — scroll lock off
e cursor display off
e pause key sequence enabled
e exit key sequence enabled (escape on)
e last line wrap (not available on MC) off
I/O DEVICES REFERENCE
It is recommended that ppcb should be the address of the pre-defined static winHandle, as in the
following example:
GLREF_D VOID *winHandle;
LOCAL_D UWORD func;
LOCAL_D INT err;
if ((err=p_open (&winHandle, "CON:",-1)) !=0)
{
fail:
p_notifyerr(err,"Failed to open console",NULL, NULL, NULL) ;
p_exit (0);
}
/* set the screen size */
rect.tl.x = rect.tl.y = 0;
rect.br.x 257
rect.br.y = 9;
func = P_SCR_WSET;
if ((err=p_iow4 (winHandle, P_FSET, &func, &rect) ) !=0)
{
p_close(winHandle) ;
goto fail;
}
You should not open the console yourself if your program is built with the CLIB start-up module.
The calling process is panicked if it already has an open channel to the console.
Returns zero if successful, or the negative error E_FILE_ALLOc if it failed to allocate memory for the
channel control block. In versions of EPOC prior to version 2.32, p_open("con:") will fail (and return a
negative number) if the total application memory usage exceeds 32k.
p_close Close the console
INT p_close(VOID *pcb) ;
Close the channel to the console.
Returns zero.
p_write Write to the console
INT p_write(VOID *pcb, UBYTE *buf, UWORD len);
Write len bytes of data from buf to the screen, starting at the current column (x coordinate) in the current
line (y coordinate). The value of 1en must be less than or equal to 255.
The request will always return immediately (but the text may not appear immediately if auto flushing is
turned off) and there is no advantage in calling this service in any way other than with p_write.
Characters are printed directly on the screen unless they are one of:
BELL sound the bell (buzzer)
TAB go to the next tab stop (tabs are every 8 characters)
BS backspace
CR move the cursor to the beginning of the current line
LF, VT move the cursor down one line
FF move the cursor down one screen
2 CONSOLE
If there are more characters in buf than will fit on the current line, the writing of the additional characters
depends on the auto wrap and scroll states as set by the p_rsEt service with function codes p_scR_WLOCK
and p_SCR_SLOCK:
e if auto wrap is on then any additional characters in buf are written from character position zero
in the following line. If this following line is off the screen then the screen will first be scrolled
up by one line, provided scroll lock is off.
e if auto wrap is off then the additional characters in buf successively overwrite the last character
in the line. On completion of the write request the last character in the row will therefore be the
final character in but. This assumes, of course, that there are no cursor movement characters in
buf.
The request cannot fail and so the function call always returns zero.
P_ FREAD Read a keypress
INT p_iow(VOID *pcb, P_FREAD, P_CON_KBREC *kbrec);_.VOID p_ioc(VOID *pcb, P_FREAD, WORD
*pstat, P_CON_KBREC *kbrec) ;
RRead a keypress record into the p_con_KBRECc struct pointed to by kbrec. The p_con_KBREC Struct is
defined in p_cons.h as:
typedef struct
{
UWORD keycode; /* Code for the key pressed */
UBYTE modifiers; /* State shift keys etc */
UBYTE count; /* Used to accumulate auto-repeat counts */
} P_CON_KBREC;
The content of modifiers is a set of bit flags indicating which modifier keys were held down when a key
was pressed:
W_SHIFT_MODIFIER SHIFT key down
W_CTRL_MODIFIER CONTROL key down
W_PSION_MODIFIER PSION key down
W_CAPS_MODIFIER Caps lock on
W_NUM_LOCK_MODIFIER Num lock on
The content of keycode for a standard keypress is simply its ASCII character code. There are also many
special values that the keycode can provide, corresponding to particular keypresses or keypress
combinations. These are fully described in the Events chapter of the Window Server Reference manual.
A P_FREAD request will not complete until either there is an outstanding keypress to read or the request is
cancelled. A synchronous request may therefore take an indefinitely long time to return. A prior
p_iow(P_FTEST) call will determine if there is an outstanding keypress.
The calling process is panicked if pcb is not a valid channel handle, or if there is an outstanding p_rFREAD
(Or P_EVENT_READ) request.
The completion status code is returned by the synchronous p_iow(P_FREAD) and written to *pstat by
asynchronous calls. The completion status code is zero if the p_rREAD request completed successfully, or
the negative error &_FILE_CANCEL if the request was cancelled by a p_FcaANCEL request.
P_FCANCEL Cancel an outstanding read
INT p_iow(VOID *pcb, P_FCANCEL) ;
Cancel an outstanding read; the request is harmless if there are no reads outstanding.
The request cannot fail and always returns zero.
P_FTEST Test for outstanding keypresses
INT p_iow(VOID *pcb, P_FTEST, UWORD *pflag);
Set *pflag to TRUE if there are any keypresses outstanding, otherwise set it to FALSE.
The request cannot fail and always returns zero.
1/0 DEVICES REFERENCE
P_FFLUSH Flush keyboard buffer
INT p_iow(VOID *pcb, P_FFLUSH) ;
Flush the keyboard buffer, all key presses held in the buffer are discarded.
The request cannot fail and always returns zero.
P_FEDIT Edit a string
INT p_iow(VOID *pcb, P_FEDIT, P_CEDIT *cedit, UWORD *plen);
Edit a string. The p_cepiT struct is defined in p_screen.h as:
typedef struct
{
UBYTE cursorpos; /* not used */
UBYTE trap; /* trap input errors or not */
UBYTE string[P_MAXEDITSTR]; /* string to edit */
} P_CEDIT;
Allows the user to edit the text in string. The cursor is initially positioned at the end of the string. The
user is not allowed to expand the string beyond *plen characters (string must be initially not more than
*plen characters in length). Since *plen does not include the terminating zero, its value must be Jess than
P_MAXEDITSTR (256).
Pressing the left or right arrow keys moves the cursor one character to the left or right in the string. The
HOME and END keys move the cursor to the start and end of the string.
Pressing Esc clears the content of the string. The value of trap determines what happens if Esc is pressed
when the string is already clear. If trap is TRUE, then the editing operation will complete with string
unchanged, if trap is FALSE then nothing will happen.
Returns zero, or E_LFILE_CANCEL if editing is terminated by pressing Esc.
P_FSENSE Sense console data
INT p_iow(VOID *pcb, P_FSENSE, P_RECTP *prectp) ;
Write the cursor position to (prectp->p.x,prectp->p.y) and write the window co-ordinates to prectp-
>x. The window co-ordinates are those specified by the most recent prior call to P_rsET with function code
P_SCR_WSET or P_SCR_CSET.
For example:
LOCAL_C VOID SenseConsole (VOID)
{
P_RECTP rectp;
WORD x_pos, y_pos, width, height;
p_iow (winHandle, P_FSENSE, &rectp) ;
X_pos = rectp.p.x;
y_pos = rectp.p.y;
width = rectp.r.br.x - rectp.r.tl.x;
height = rectp.r.br.y - rectp.r.tl.y;
/* do something with the coordinates here */
}
The request cannot fail and always returns zero.
2 CONSOLE
P_FSET, P_SCR_WSET Set the console window size
INT p_iow(VOID *pcb, P_FSET, &P_SCR_WSET, P_RECT *prect);
Set the console window size. A p_rEcT structure is used for historical reasons; in practice prect-
>rect .t1 should always be (0,0). For example, to set the console size to 9 lines high by 25 columns wide
(the full screen size for HC machines) you should use:
P_RECT rect;
UWORD func;
rect.tl.x rect.tl.y = 0;
rect.br.x = 25;
rect.br.y = 9;
func = P_SCR_WSET;
p_iow(winHandle, P_FSET, &func, &rect) ;
Returns zero if successful, otherwise the error =_GEN_NomEmory if unable to create a window of the new size.
P_FSET, P_SCR_SCROLL Scroll the window content
INT p_iow(VOID *pcb, P_FSET, &P_SCR_SCROLL, P_RECTP *pscrl)j;
Scroll the rectangle pscri->r by the vector amount (pscr1->p.x,pscrl->p.y). The area left behind the
trailing edge(s) is cleared. Scrolling a rectangle is not affected by setting or clearing the scroll lock.
pscrl->r describes the rectangle to scroll;
pscrl->p.x gives the horizontal distance to scroll (negative left, positive right);
pscrl->p.y gives the vertical distance to scroll (negative up, positive down).
For example:
LOCAL_C VOID scroll(WORD amnt_v, WORD amnt_h)
/* scroll the whole window vertically amnt_v and horizontally amnt_h */
{
UWORD func;
P_RECTP scrl;
p_iow(winHandle, P_FSENSE, &scrl);
scrl.r.br.x -= scrl.r.tl.x;
scrilsr.br vy == serlar.tl.y;
scrl.r.tl.x = 0;
scrl.r.tl.y = 0;
scrl.p.x = amnt_h;
scrl.p.y = amnt_v;
func = P_SCR_SCROLL;
p_iow(winHandle, P_FSET, &éfunc, &éscrl) ;
}
Returns zero.
P_FSET, P_SCR_CLR Clear a rectangle
INT p_iow(VOID *pcb, P_FSET, &P_SCR_CLR, P_RECT *prect);
Clear the rectangle *prect. If *prect extends outside the console window then it is clipped so that only
the part that intersects with the window is cleared.
For example:
LOCAL_C VOID clear(P_RECT *prect)
{
INT func;
func = P_SCR_CLR;
p_iow(winHandle, P_FSET, &éfunc,prect) ;
}
Returns zero.
I/O DEVICES REFERENCE
P_ FSET, P_SCR_NEL Position cursor to next line
INT p_iow(VOID *pcb, P_FSET, &P_SCR_NEL) ;
Move the cursor position to the first column on the next line. If the current row is the bottom row then,
provided scroll lock is not set, the window image scrolls up.
Returns zero.
P_FSET, P_SCR_POSA Set the cursor position (absolute)
INT p_iow(VOID *pcb, P_FSET, &P_SCR_POSA, P_POINT *ppoint);
Position the cursor to the point *ppoint. If *ppoint is outside the window the cursor moves to the the
position in the window closest to *ppoint.
Returns zero.
P_FSET, P_SCR_POSR Set the cursor position (relative)
INT p_iow(VOID *pcb, P_FSET, &P_SCR_POSR, P_POINT *ppoint);
Position the cursor by adding the displacement *ppoint to its current co-ordinates. If *ppoint is outside
the window the cursor moves to the the position in the window closest to *ppoint.
Returns zero.
P_FSET, P SCR_CURSOR Turn the cursor on or off
INT p_iow(VOID *pcb, P_FSET, &P_SCR_CURSOR, UWORD *pflag);
Turn the cursor off if *pflag is FALSE, turn it on if *pflag is TRUE.
Turning the cursor on or off has no affect on the screen driver output other than enabling or disabling the
display of the cursor.
Returns zero.
P_FSET, P_ SCR_SLOCK Set scroll lock
INT p_iow(VOID *pcb, P_FSET, &P_SCR_SLOCK, UWORD *pflag);
Turn scroll lock off if *pflag is FALSE, turn it on if *pflag is TRUE.
When scroll lock is on scrolling of the console (caused by either P_scR_NEL or p_write) is disabled. It has
no effect on scrolling by means of P_rsET with function code P_SCR_SCROLL.
Returns zero.
P_FSET, P_SCR_WLOCK Set auto wrap
INT p_iow(VOID *pcb, P_FSET, &P_SCR_WLOCK, UWORD *pflag);
Turn auto wrap off if *pflag is FALSE, turn it on if *pflag 1s TRUE.
If auto wrap is off then character printing by p_write stops at the right margin, with further characters
successively overwriting the last character in the line. If auto wrap is on then trying to write a character
beyond the end of the line causes the cursor to move to the start of the next line. If the cursor is in the last
line of the window (and scroll lock is off) this will cause a scroll.
Returns zero.
2 CONSOLE
P_FSET, P_ SCR_ESCAPE Set escape on or off
INT p_iow(VOID *pcb, P_FSET, &P_SCR_ESCAPE, UWORD *pflag);
Turn escape handling off if *pf1ag is FALSE, turn it on if *pflag iS TRUE.
If escape handling is off then the user will not be able to use the exit key sequence to exit the console
application. The exit key sequence is PSION-ESC on HC and Series 3 machines, PSION-E on (English-
language) MC machines (PSION-? on foriegn language MCs, where ? is a character that depends on the
language). Additionally, on MC machines, the stop menu button will be disabled when escape is off.
Escape handling is initially on.
Returns zero.
P_FSET, P_SCR_COMPATIBILITY Set compatibility on or off
INT p_iow(VOID *pcb, P_FSET, &P_SCR_COMPATIBILITY, UWORD *pflag);
This function code is only available on machines that contain version 4, or later, of the window server.
Turn compatibility off if *pf1ag is FALSE, turn it on if *pflag iS TRUE.
If compatibility is turned on, all drawing to the screen of the Series 3a is performed in double pixel mode.
On Series 3a machines, compatibility mode is initially on.
Returns zero.
Note: A tru value of *pf1ag must be the value 1. Any other non-zero value may be interpreted differently
on future machines.
P_FSET, P_SCR_GREY Set the use of grey on or off
INT p_iow(VOID *pcb, P_FSET, &P_SCR_GREY, UWORD *pflag);
This function code is only available on machines that contain version 4, or later, of the window server.
Turn the use of grey off if *pfiag 1s FALSE, turn it on if *pflag iS TRUE.
On Series 3a machines, the use of grey is initially off.
Returns zero.
Additional console services
The following services have been implemented to support OPL/g on HC and Series 3 machines. They are
not available on machines in the MC range.
If your application is sufficiently complex to require these services it is recommended that you consider
writing it as a window server application rather than using the console device.
P_EVENT READ Read an event
INT p_iow(VOID *pcb, P_EVENT_READ, P_CON_KBREC *kbrec) ;
VOID p_ioc(VOID *pcb, P_EVENT_READ, WORD *pstat, P_CON_KBREC *kbrec) ;
RRead an event record (including keypress events) into the p_con_KBrREc struct pointed to by kbrec. The
P_CON_KBREC Struct is defined in p_cons.h as:
typedef struct
{
UWORD keycode; /* Code for the key pressed */
UBYTE modifiers; /* State shift keys etc */
UBYTE count; /* Used to accumulate auto-repeat counts */
} P_CON_KBREC;
I/O DEVICES REFERENCE
If the event was a keypress (a wM_KEy event) the result is exactly as for a P_FREAD request, described
earlier.
Other window server events result in one of the following values being written to keycode:
CONS_EVENT_FOREGROUND received a WM_FOREGROUND event
CONS_EVENT_BACKGROUND received a WM_BACKGROUND event
CONS_EVENT_ON_OFF received a WM_ON event
CONS_EVENT_COMMAND received a WM_COMMAND event
Future versions of the console device may report additional event types. Applications should be written to
ignore event types other than those listed above.
A P_EVENT_READ request will not complete until either an event is received or the request is cancelled. A
synchronous request may therefore take an indefinitely long time to return. A prior p_iow (P_EVENT_TEST)
call will determine if there is an outstanding event to be read.
The calling process is panicked if pcb is not a valid channel handle, or if there is an outstanding
P_EVENT_READ (or P_FREAD) request.
The completion status code is returned by the synchronous p_iow(P_EVENT_READ) and written to *pstat
by asynchronous calls. The completion status code is zero if the P_LEVENT_READ request completed
successfully, or the negative error E_LFILE_CANCEL if the request was cancelled by a P_FcANCEL request.
P_EVENT_ TEST Test for outstanding event
INT p_iow(VOID *pcb, P_EVENT_TEST, UWORD *pflag);
Set *pflag to TRUE if there are any events (including keypress events) outstanding, otherwise set it to
FALSE.
The request cannot fail and always returns zero.
P_FINQ Get console data
INT p_iow(VOID *pcb, P_FINQ, CONSOLE_INFO *pinfo);
Return information about the window server resources used by the console. coNSOLE_iInFo is defined in
p_cons.has:
typedef struct
{
UINT window_handle; /* window server id of the console window */
UINT font_handle; /* window server id of the console font */
UINT line_height; /* pixel height of a console line - font height + leading */
UINT char_width; /* pixel width of a monospaced console character */
} CONSOLE_INFO;
Returns zero.
P_FWFLUSH Flush window server buffer
INT p_iow(VOID *pcb, P_FWFLUSH) ;
Flush the commands buffered to the window server - has no effect when auto flushing is on.
Returns zero.
P_FSET, P_SCR_CSET Set the console output rectangle
INT p_iow(VOID *pcb, P_FSET, &P_SCR_CSET, P_RECT *prect);
Set the console output rectangle. All subsequent output is restricted (and wrapped) to the rectangle
described by prect within the console window.
Returns zero if successful, or E_GEN_aRG if any part of prect is outside the console window (i.e. either of
prect->tl.x Or prect->t1.y is less than zero, or prect->br.x Of prect->br.y respectively exceed the
width or height of the console window).
2-10
2 CONSOLE
P_FSET, P_SCR_ATTRB Set character attributes
INT p_iow(VOID *pcb, P_FSET, &P_SCR_ATTRB, UWORD *pattrib);
Set the character attributes (style) to be used to display future characters written to the console. This
service permits the mixing of a number of different styles in the console window.
The value of *pattrib may be
P_SCR_NORMAL No additional style
or any combination of the bit flags:
P_SCR_BOLD Bold
P_SCR_REVERSE Reverse video
P_SCR_UNDLINE Underlined
P_SCR_BLINK Blinking
P_SCR_ITALIC Italics
It is not guaranteed that all the above attributes are supported in all versions of the console for the HC and
Series 3, but unsupported attributes are harmlessly ignored.
Any attribute which would have the effect of changing the width of a displayed character (such as
P_SCR_BOLD in current machines) is ignored. At the time of writing, no machine supports p_scR_BLINK.
For example:
UWORD func;
UWORD attrib;
p_printf("This is normal");
func = P_SCR_ATTRB;
attrib = P_SCR_UNDLINE;
p_iow (winHandle, P_FSET, &func, &attrib) ;
p_printf("This is underlined");
attrib = P_SCR_NORMAL;
p_iow (winHandle, P_FSET, &func, &attrib) ;
p_printf ("Back to normal text");
Returns zero.
P_FSET, P SCR_FONT Set the screen font
INT p_iow(VOID *pcb, P_FSET, &P_SCR_FONT, P_SCR_SET_FONT *pfont);
Set the console font and style for the entire window to those specified by the content of the
P_SCR_SET_FONT Struct pointed to by pfont. The struct is defined in p_cons.h as:
typedef struct
{
UWORD id; /* font id */
UWORD style; /* font style */
} P_SCR_SET_FONT;
The allowed values for the font ia and style are those that are appropriate for setting a window server
graphics context (see the Window Server Reference manual). Note that the font must be monospaced; if
you set id to be the font id of a proportional font you should also include G_sty_mono in style.
For example:
UWORD func;
P_SCR_SET_FONT font;
font.id = WS_FONT_BASE;
font.style = G_STY_MONO|G_STY_DOUBLE;
func = P_SCR_FONT;
p_iow(winHandle, P_FSET, &func, &font) ;
Since the size of the console window may be altered by changing the font, a call to p_rserT with function
code p_scr_Font will automatically clear and resize the console.
I/O DEVICES REFERENCE
It is not possible to mix different fonts and/or styles in the console window by means of this service.
Certain aspects of the font style may be changed using the P_FsET service with function code
P_SCR_ATTRB.
Returns zero.
P_FSET, P_SCR_LAST_ LINE WRAP Set the last line wrap
INT p_iow(VOID *pcb, P_FSET, &P_LAST_LINE_WRAP, UWORD *pflag);
Turn last line wrap on if *pflag is TRUE, turn it off if *pflag is FALSE.
If last line wrap is off then the display immediately wraps and scrolls (provided wrapping and scrolling
are not disabled) when a character is printed to the bottom right position in the console.
Last line wrap is initially off.
Returns zero.
P_FSET, P_SCR_FLUSH Set window server flushing
INT p_iow(VOID *pcb, P_FSET, &P_SCR_FLUSH, UWORD *pflag);
Disable auto-flushing if *pflag is FALSE, enable it if *pflag is TRUE.
Auto-flushing is initially enabled.
When auto-flushing is enabled each window server function call is flushed immediately.
If auto-flushing is disabled, one or more window server function calls may be buffered. Execution of a
window server function may therefore be deferred until after the initiating function call has returned. In
such a case a function may return a window server error that was caused by an earlier, but buffered,
function call.
Returns zero.
P_FSET, P_SCR_DISABLE_READS Disable reads
INT p_iow(VOID *pcb, P_FSET, &P_SCR_DISABLE_READS, UWORD *pflag) ;
Disable reads if *pflag is TRUE, enable reads if *pflag iS FALSE.
A console application which needs to receive events directly from the window server, by calling
wGetEvent, should first disable reads. Otherwise all events are preferentially reported to the console.
No P_FREAD Of P_EVENT_READ request should be outstanding when this service is called and no more reads
may be performed until reads are re-enabled.
Initially reads are enabled.
Returns zero.
P_FSET, P_SCR_CLIENT_FOREGROUND Bring to foreground
INT p_iow(VOID *pcb, P_FSET, &P_SCR_CLIENT_FOREGROUND, UWORD *pid);
Make the process with process ID *pid the foreground process. Use a value of zero for «pid to bring the
current process to the foreground.
The service does nothing if the process specified by *pid does not exist.
Returns zero.
2 CONSOLE
P_FSET, P_SCR_CAPTURE KEY Capture a key
INT p_iow(VOID *pcb, P_FSET, &P_SCR_CAPTURE_KEY, CONSOLE_CAPTURE_KEY *pcapt) ;
Specify a keypress that is to be sent to the calling process, irrespective of its foreground/background status.
The keypress combination to be captured is specified by the content of the consoLE_CAPTURE_KEY Struct,
defined in p_cons.h as:
typedef struct
{
UWORD code;
UBYTE modifier_mask;
UBYTE dont_care_mask;
} CONSOLE_CAPTURE_KEY;
Every time a key is pressed the window server evaluates
(key_pressed==code) && ((key_pressed_modifiersédont_care_mask) ==modifier_mask)
and if the result is TRuz then the keyboard event is sent to the process that specified the capture.
For example,
UWORD func;
CONSOLE_CAPTURE_KEY capture;
capture.code = W_SPECIAL_KEY|'a';
capture.modifier_mask = W_PSION_MODIFIER;
capture.dont_care_mask = W_PSION_MODIFIER|W_SHIFT_MODIFIER;
func=P_SCR_CAPTURE_KEY;
p_iow (winHandle, P_FSET, &func, &capture) ;
captures PSION+A and PSION+CTRL+A.
See also the equivalent window server function wcapturekey, described in the Window Server Reference
manual. The struct elements code, modifier_mask and dont_care_mask correspond to the wcaptureKey
parameters keycode, modifiers and modifier_mask respectively.
Returns zero if successful, or =_FILE_ExIst if the specified keycode/modifier combination is currently
captured by any process.
P_FSET, P_SCR_CANCEL_CAPTURE_KEY Cancel a key capture
INT p_iow(VOID *pcb, P_FSET, &P_SCR_CANCEL_CAPTURE_KEY, CONSOLE_CAPTURE_KEY *pcapt) ;
Cancel a key capture set up by p_rset with function code p_scR_caPTURE_KEY. The content of pcapt must
exactly match that used to initiate the capture.
Returns zero if successful, or E_F1LE_nx1st 1f the keycode/modifier combination is not marked as
captured.
I/O DEVICES REFERENCE
Example
The following short program exercises many of the services described above. It consists of two parts, the
first of which simply receives keys typed by the user and reports them by type on the screen. The second
part enables the user to scroll a part of the display and to set the console attributes (scroll lock, line wrap
etc) to see how they affect the way typed characters are displayed.
#include <plib.h>
#include <p_cons.h>
#include <wskeys.h>
GLREF_D VOID *winHandle;
LOCAL_D P_RECTP RectP;
#define CON_HEIGHT 9
#define CON_WIDTH 25
LOCAL_C VOID doSetMode (UWORD mode, VOID *al)
/*
Shell to P_FSET
Hf,
{
INT err;
if ((err=p_iow4 (winHandle, P_FSET, &mode, al) ) !=0)
p_notifyerr(err,"Set service failed",NULL,NULL, NULL) ;
LOCAL_C VOID clear_line (VOID)
/*
position cursor to begining of the line and clear the line
*/
{
P_RECTP rectp;
p_iow3 (winHandle, P_FSENSE, &rectp) ;
rectp.p.x = 0;
doSetMode (P_SCR_POSA, &rectp.p) ;
rectp.r.tl.x = 0;
rectp.r.br.x = CON_WIDTH;
rectp.r.tl.y = rectp.p.y;
rect.r.br.y = rectp.p.y + 1;
doSetMode (P_SCR_CLR, &rectp.r);
}
LOCAL_C VOID ReportKey (VOID)
{
P_CON_KBREC kbrec;
p_printf ("Press Any Key (ESC quits)\r\n");
FOREVER
{
p_iow3 (winHandle, P_FREAD, &kbrec) ;
clear_line();
if (kbrec.modifiers&W_PSION_MODIFIER)
p_printf ("Psion key %x",kbrec.keycode) ;
else if (p_isprint (kbrec.keycode) )
p_printf ("Normal key %c",kbrec.keycode) ;
else if (kbrec. keycode==W_KEY_ESCAPE)
break;
else
p_printf("Non printable key %x",kbrec.keycode) ;
LOCAL_C VOID TryModes (VOID)
{
INT wrap_lock,scroll_lock, escape;
P_RECTP rectp;
P_CON_KBREC kbrec;
escape = TRUE; /* set toggle flags to default values */
wrap_lock = TRUE;
scroll_lock = FALSE;
rectp.r.tl.x = 5; /* define a rectangle for scrolling */
rectp.r.tl.y = 1;
rectp.r.br.x = 20;
rectp.r.br.y = 6;
FOREVER
{
p_iow3 (winHandle, P_FREAD, &kbrec) ;
if (! (kbrec.modifiers&W_PSION_MODIFIER) )
{
if (p_isprint (kbrec.keycode) )
p_putch (kbrec.keycode) ;
else if (kbrec.keycode==W_KEY_RETURN)
doSetMode (P_SCR_NEL, 0);
else if (kbrec.keycode=='\b')
/* make backspace destructive */
p_print("\b \b");
else if (kbrec.keycode==W_KEY_ESCAPE)
break;
}
else
{
kbrec.keycodeé&=(~W_SPECIAL_KEY) ;
switch (kbrec. keycode)
{
case W_KEY_LEFT:
rectp.p.x = (-1);
rectp.p.y = (-1);
scroll: doSetMode (P_SCR_SCROLL, &rectp) ;
break;
case W_KEY_RIGHT:
rectp.p.x = (1);
rectp.p.y = (1);
goto scroll;
case W_KEY_DOWN:
rectp.p.x = 1;
rectp.p.y = 0;
goto scroll;
case W_KEY_UP:
rectp.p.x = (-1);
rectp.p.y = 0;
goto scroll;
case 'w': /* PSION modifier always gives lower case key */
wrap_lock = !wrap_lock;
doSetMode (P_SCR_WLOCK, &wrap_lock) ;
break;
case 's':
scroll_lock = !scroll_lock;
doSetMode (P_SCR_SLOCK, &scroll_lock) ;
break;
case 'q':
escape = !escape;
doSetMode (P_SCR_ESCAPE, &escape) ;
break;
default: /* do nothing */
break;
}
2 CONSOLE
I/O DEVICES REFERENCE
GLDEF_C INT main(VOID)
/*
Allow user to type characters etc
xf
{
INT err;
P_RECT rect;
if ((err=p_open (&winHandle, "CON:",-1)) !=0)
{
p_notifyerr(err,"No Console device",NULL, NULL, NULL) ;
p_exit (0);
}
rect.tl.x = rect.tl.y = 0; /* set the screen size */
rect.br.x = CON_WIDTH;
rect.br.y = CON_HEIGHT;
doSetMode (P_SCR_WSET, &rect) ;
p_printf ("Simple console program") ;
ReportKey ();
p_putch(0x0c) ; /* form feed to clear screen */
p_printf ("Type characters or:");
p_printf ("Psion <- scrolls left/up");
p_printf ("Psion -> scrolls rght/dn");
p_printf("Psion Down scrolls down");
p_printf("Psion Up scrolls up");
p_printf("Psion W toggles wrap lock");
p_printf("Psion S toggles scrl lock");
p_printf("Psion Q toggles escape");
TryModes () ;
p_close(winHandle) ;
return(0);
}
CHAPTER 3
PARALLEL PORT
Pc 9 EEEEEEEEEEE—— Ss
Introduction
One or more standard centronics parallel ports are available on all SIBO machines, in the form of either a
dual serial/parallel expansion module (for example, the HC and MC ranges) or a parallel expansion
module (such as the parallel 3-link for the Series 3). The HC cradle provides a third parallel port.
Parallel port device names
Depending on the number and location of ports available, the port device names are "PAR:A", "PAR:B" and
"PAR:C". For example, the Series 3 recognises only "PaAR:a", but an MC fitted with two serial/parallel
expansion modules recognises "Ppar:a" (left hand module, looking from the front of the machine) and
"PAR:B" (right hand module, looking from the front of the machine).
The parallel port driver is an output-only device driver that does not support a read service.
Panics
All services (with the exception of p_open) will cause the calling process to be panicked if the passed
channel handle is not valid. Other panics are described under the particular service to which they apply.
Parallel port services
p_open(PAR:) Open a parallel port
INT p_open(VOID **pcb, TEXT *pname, -1);
Open a channel to the parallel port *pname, where pname points to the string "PAR:A", "PAR:B" OF
"PAR:C", writing the address of the channel control block to *pcb.
The parallel port lines are powered up and all control lines are cleared low. The port will continue to
consume power until the channel is closed.
Returns zero if successful, or one of the following negative error numbers:
E_FILE_ALLOC failed to allocate memory for the control block
E_FILE_DEVICE the port does not exist
E_FILE_LOCKED or the port is already open
E_GEN_INUSE
p_close Close a parallel port
INT p_close(VOID *pcb);
Power down the parallel port lines and close the port channel corresponding to the specified control block,
first cancelling any outstanding Pp_FwRITE request.
Returns zero.
1/0 DEVICES REFERENCE
P_FWRITE Write to a parallel port
INT p_iow(VOID *pcb, P_FWRITE, VOID *buf, UWORD *plen);
VOID p_ioc(VOID *pcb, P_FWRITE, WORD *pstat, VOID *buf, UWORD *plen)j;
Write *plen bytes of data from buffer buf to the parallel port. It is the user's responsibility to preserve the
data at *pbuf and *plen until the write request completes.
The write request will never complete if the parallel port is not physically connected to a functioning
receiver. It is therefore advisable always to write asynchronously to the parallel port, and to use a timer
that provides a timeout on each write, as illustrated in the example at the end of this chapter.
Panics if a P_FWRITE request is currently outstanding, or if pcb is not a valid channel handle.
The completion status code is returned by the synchronous p_iow(P_FWRITE) and written to *pstat by
asynchronous calls. The completion status code is zero if the P_FWRITE request completed successfully, or
one of the following negative error numbers:
E_FILE_WRITE failed to write
E_FILE_CANCEL the write was cancelled by a call to the P_FcANCcEL service
P_FCANCEL Cancel a write request
INT p_iow(VOID *pcb, P_FCANCEL) ;
Cancel any outstanding P_FwRITE request, causing it to complete with an E_FILE_CANCEL completion code.
If a write request is outstanding then an indeterminate amount of data will have been written to the
parallel port before the request is cancelled.
Performing a cancel is harmless if no write request is outstanding.
Returns zero.
P_FSENSE Sense the input control lines
INT p_iow(VOID *pcb, P_FSENSE, UWORD *port);
This service is not, at the time of writing, available for any version of either the Series 3 or the Series 3a.
It is only available for machines in the HC and MC ranges that contain EPOC with a version number of
2.30 or later.
Write the current values of the centronics port input control lines to *port (all control lines are cleared
low when the port is opened).
The input control line values are defined, in p_par.h, according to the following table, where the pin
numbers are those appropriate for a 25-way D-type connector.
Symbol Control line Pin number
S_BUSY Busy 11
S_ACK Acknlg 10
S_ERROR Error 15
S_PE Paper error 12
Following the call, the values of the remaining bits at *port are undefined.
Returns zero.
P_FSET Write the output control lines
INT p_iow(VOID *pcb, P_FSET, UWORD *type, UWORD *port);
This service is not, at the time of writing, available for any version of either the Series 3 or the Series 3a.
It is only available for machines in the HC and MC ranges that contain EPOC with a version number of
2.30 or later.
Set or clear the centronics output control lines (all control lines are cleared low when the port is opened).
3-2
3 PARALLEL PORT
If *t ype is 1 then the control lines corresponding to the bits set in *port will be set high.
If *t ype is 0 then the control lines corresponding to the bits set in *port will be cleared low.
The output control line values are defined, in p_par.h, according to the following table, where the pin
numbers are those appropriate for a 25-way D-type connector.
Symbol Control line Pin number
S_SPARE === See below
S_INIT Init 16
S_AUTOFD Autofeed 14
S_SELECT Select 17
Any other bits set in *port are ignored.
The s_sparz bit is not available on the centronics connector. It may be of use in custom hardware designs
as it corresponds to pin 42 of the Psion-specific custom peripheral chip, astcs5. Changing this bit will
have no effect on the standard RS232/parallel expansion module.
Returns zero.
EEE
Example
The following example copies one or more files to a parallel port. It uses many of the parallel port
services, and illustrates the use of a timer to provide a timeout in conjunction with the p_rwRITE service.
include <p_std.h>
include <p_sys.h>
include <p_file.h>
include <epoc.h>
LOCAL_D VOID *fcb=NULL;
LOCAL_D VOID *pcb=NULL;
LOCAL_D VOID *tcb=NULL;
LOCAL_C VOID Report (INT err)
TEXT buf [E_MAX_ERROR_TEXT_SIZE];
p_errs (&buf[0],err);
p_printf("%s", &buf[0]);
}
LOCAL_C INT BufToParallel (VOID)
{
WORD len;
WORD pstat,tstat;
ULONG time;
TEXT buf [64];
len=p_read(fcb, &buf[0], 64);
if (len>=0)
{
p_ioc5 (pcb, P_FWRITE, &pstat, &buf[0],é&len) ;
time=50; /* 5 second timeout */
p_ioc4 (tcb, P_FRELATIVE, &tstat, &time) ;
p_iowait ();
if (pstat==E_FILE_PENDING) /* timer timed out */
{
p_iow2 (pcb, P_FCANCEL) ;
p_waitstat (&pstat) ;
return (E_FILE_CANCEL) ;
}
p_iow2 (tcb,P_FCANCEL); /* cancel timer */
p_waitstat (&tstat) ;
}
return (len);
}
1/0 DEVICES REFERENCE
LOCAL_C VOID FileToParallel (VOID)
{
INT err;
if ((err=p_open(&pcb, "PAR:A",-1))<0) /* open parallel port */
{
Report (err) ;
return;
}
FOREVER
{
if ((err=BufToParallel()) <0)
{
if (err!=E_FILE_EOF)
Report (err) ;
break;
}
}
p_close (pcb);
pcb=NULL;
}
GLDEF_C INT main(VOID)
{
INT err;
TEXT bb[P_FNAMESIZE];
if ((err=p_open(&tcb,"TIM:",-1))<0) /* open timer for timeouts */
{
Report (err) ;
return (0);
}
while (p_getl("Enter file name:
{
if ((err=p_open (&fcb, &bb[0],P_FOPEN|P_FSTREAM) ) <0) /* open a file */
{
Report (err);
continue;
}
FileToParallel();
p_close(fcb);
}
p_close(tcb);
return(0);
}
Note that this example is based on the assumption that the only two asynchronous events that can occur
are the completion of a write to the parallel port and the expiry of the timer. For further discussion of a
more general case, see the description of p_ioc in the PLIB Reference manual.
", &bb[0],P_FNAMESIZE) )
CHAPTER 4
SERIAL PORT
eee ————————>>>——EE—————>>>>eE~— Ss
Introduction
The serial driver in the EPOC operating system supports a fully interrupt driven industry-standard RS-232
serial link.
The driver consists of two cooperating layers. The lower driver is a physical device driver (PDD). It
provides a set of services that hide any hardware dependencies from the upper layer.
The upper layer of the driver is a logical device driver (LDD). It provides the logical (hardware
independent) services that are described in this chapter. Incoming data is buffered at this level.
Serial port device names
The first serial port on a SIBO machine has the device name "Tty:a". Many machines in the SIBO range
have more than one serial port available; a second port has the device name "TTy:8". For example, a
Series 3 fitted with a 3 Link (RS232) recognises only "tty:a", but an MC fitted with two serial/parallel
expansion modules recognises "TTy:a" and "tTy:B" (left and right hand modules respectively, looking
from the front). HC machines have a third port, on the cradle, with the device name "TTy:c".
HC machines also support serial ports with TTL level signals with device names "TTY:D", "TTY:E",
"TTy:F" (direct TTL levels) and "tTv:c", "TTy:H", "TTY:1" (inverted TTL levels). These ports are not
described in this chapter.
Panics
All services (with the exception of p_open) will cause the calling process to be panicked if the passed
channel handle is not valid. Other panics are described under the particular service to which they apply.
eee
Serial port parameters
The serial port parameters are set and sensed with the aid of a p_sRcuar struct, defined in p_serial.h as:
typedef struct
UBYTE tbaud; /* transmit baud rate */
UBYTE rbaud; /* receive baud rate */
UBYTE frame; /* number of data, parity and stop bits */
UBYTE parity; /* parity type */
UBYTE hand; /* handshake flags */
UBYTE xon; /* XON character */
UBYTE xoff; /* XOFF character */
UBYTE flags; /* controlling flags */
ULONG tmask; /* terminator mask */
} P_SRCHAR;
The possible settings are described in the following subsections.
One of the major problems with serial communications is ensuring that both ends of a physical link are
using the same port parameters. Typically, if one or more of the parameters differ, some data may be
transferred successfully whilst other data may not. This can make it difficult to determine which
parameter is incorrect.
1/0 DEVICES REFERENCE
Baud rate (tbaud, rbaud)
The Baud rate is, strictly speaking, a measure of the electrical signalling rate (the frequency of electrical
impulses) of a communications link. In practice, however, it is used to specify the data transfer rate, in
bits per second. The Baud rate and the data transfer rate are equal if one bit of data is encoded in each
signalling period.
For back-to-back serial communications the Baud rate and the data transfer rate are equivalent. It is only
when considering data transfer over a modem that the Baud rate and data transfer rate may differ.
Typically, modems that transfer data at a rate higher than 1200 bits per second encode more than | bit of
data into a single signalling period. For such a modem the Baud rate will differ from the data transfer
rate.
The transmit and receive Baud rates (tbaud and rbaud respectively) may be set to one of the following
values, which are defined in p_serial.h:
P_BA
P_BA
P_BA
P_BA
P_BA
P_BA
P_BA
P_BA
P_BA
P_BA
P_BA
P_BA
P_BA
P_BA
P_BA
P_BA
P_BA
P_BA
D_50
D_75
D_110
D_134
D_150
D_300
D_600
D_1200
D_1800
D_2000
D_2400
D_3600
D_4800
D_7200
D_9600
D_19200
D_38400
D_56000
U
U
U
U
U
U
U
U
U
U
U
U
U
U
U
U
U
U
The default value for both tbaud and rbaud is P_BAuD_9600. None of the SIBO serial port hardware
currently supports split Baud rates (separate transmit and receive Baud rates).
All machines in the SIBO range support Baud of rates of P_BAUD_50 to P_BAUD_9600 inclusive. In addition
the MC 200, MC 400 and Series 3a machines support a rate of P_BAUD_19200. The HC and Series 3
machines can also be set to use P_BAUD_19200. However, the clock speed on current machines is slightly
too slow to handle this rate of data transfer, and overrun errors occur fairly frequently. Error correcting
protocols (eg Link) will run on the HC and Series 3 at 19200 Baud but, because of the high number of
retransmissions, they are slower than if they were run at 9600 Baud.
At 19200 Baud an interrupt occurs approximately every 500 microseconds. The following table shows the
number of instruction cycles available on a range of machines between two interrupts occurring at this
rate.
Machine Clock speed Instruction cycles
HC 3.84MHz 480
Series 3 3.84MHz 480
Series 3a 7.68MHz 960
IBM PC/AT 4.77MHz 596
MC 200/400 7.68MHz 960
Character frame (¢rame)
The basic unit of transmission is the RS-232 asynchronous character frame. This is a sequence of bits
which consists of one start bit, between five and eight data bits, an optional parity bit and one or two stop
bits.
The start and stop bits are used to synchronise the data transmission.
The number of data bits required largely depends on the nature of the data that is being transferred. For
example, eight data bits are needed to transmit arbitrary binary data bytes, but seven bits are sufficient to
transmit text, containing only ASCII character codes with values not exceeding Ox7F.
Including a parity bit provides for an elementary degree of error detection in the transmitted data.
4-2
4 SERIAL PORT
The value of frame describes the character frame. It may contain one of one of the following values,
defined in p_serial.h:
P_DATA_5 5 data bits
P_DATA_6 6 data bits
P_DATA_7 7 data bits
P_DATA_8 8 data bits
The value in frame may be ored with any combination of:
P_TWOSTOP 2 stop bits if set, 1 if clear
P_PARITY parity bit is present if set
All SIBO machines support all of the above settings. The default value of frame is
P_DATA_8
for eight data bits, one stop bit and no parity.
In the majority of cases the total number of bits needed to transmit a single character is close to ten (for
example, one start bit, seven data bits, one parity bit and one stop bit). As a result, a reasonable estimate
of the character transfer rate is usually found by dividing the Baud rate by ten.
Parity (parity)
If present, the parity bit may be set or cleared to ensure that the combined sum of the set data and parity
bits is either odd (odd parity) or even (even parity). Alternatively it may be always set (mark parity) or
always clear (space parity). If the p_parrty bit is set in fiela, then parity should be set to one of the
following values, defined in p_serial.h:
P_PAR_EVEN even parity
P_PAR_ODD odd parity
P_PAR_MARK mark parity
P_PAR_SPACE space parity
Provided that p_partty is set in frame, the parity bit is generated (for transmission) and verified (on
receipt) by the port hardware. Reporting of parity errors may be suppressed by setting p_IGNORE_PARITY in
flags (see below).
The default value of parity is zero. No machine in the SIBO range supports either mark or space parity.
Handshaking (xon, xoff, hand)
Handshaking (also called flow control or buffer control) is a mechanism by which either end of a
communications link can pause and restart data transmission from the other end. There are two basic
forms:
e software handshaking
e hardware handshaking
Handshaking is required to prevent one end from sending data faster than the receiving end can process it.
For example, you may be able to send data to a printer at 9600 Baud, but it is unlikely that the printer is
capable of printing 960 characters per second. The printer will use handshaking to suspend the
transmission of data from time to time (when its internal buffer becomes full) and restart it when it is able
to receive more characters (some buffer space becomes available).
Software handshaking involves the transmission of particular characters, one to suspend and one to
resume transmission. This is usually called XON/XOFF handshaking, since the characters normally
selected to suspend and resume transmission are XOFF (0x13, pc3) and XON (0x11, pDc1) respectively.
Other characters may be used, provided that both ends of the communications link agree.
Software handshaking can sensibly be used only to transfer data that has pure textual content. Arbitrary
binary data may include bytes with values equal to one or other of the handshaking control characters.
The remote end will not be able to distinguish between such a character being sent as data or as a
handshaking control. For example, a WordStar file may contain the binary value 0x13 (XOFF) as an
underscore range marker. On receipt of this character the remote end will not transfer any data until it
receives an XON and so the transfer process may hang. More importantly, the XOFF character will be
removed from incoming data, being interpreted as a control character rather than as data. Thus, in the
above example, underscore range markers will be lost during the transfer.
The character codes used to resume and suspend transmission in software handshaking are stored in xon
and xoff. The default values are DC1 (0x11) and DC3 (0x13) respectively.
I/O DEVICES REFERENCE
Hardware handshaking involves the setting of a particular electrical state on specific control lines. It
usually involves a pair of lines, the output from one end being the input to the other, and vice versa. A
common cause of failure of hardware handshaking is the use of an improperly wired cable. Various
control line combinations may be used, as listed below.
DSR/DTR This form of handshaking uses the RS-232 control lines Data Set Ready (DSR)
and Data Terminal Ready (DTR). These lines were not originally intended for
use as data flow control lines, but were meant to be used to indicate the
presence or absence of a remote machine. However, many printers use
DSR/DTR handshaking to control the flow of data from a computer.
The receiver's output line (DTR) is held inactive (-ve) to suspend data transfer
and set active (+ve) to resume data transfer. This signal is expected to arrive
on the remote (sending) machine's DSR input line.
RTS/CTS This form uses the RS-232 control lines Request To Send (RTS) and Clear To
Send (CTS). These lines are the ones originally intended for use to control data
flow from either end. RTS/CTS handshaking is normally used for hardware
handshaking with a modem, and the DSR and DTR lines are used for their
originally intended purposes of indicating that a remote machine exists and the
port is open.
The output line (RTS) is held inactive (-ve) to suspend data transfer and set
active (+ve) to resume data transfer. This signal is received by the remote
machine via the CTS input line (ie its now Clear To Send data).
The Data Carrier Detect (DCD) line is not a control of flow handshaking line as described above. It is a
condition indicator from a modem to indicate that a connection now exists with a remote modem. The
DCD signal is an input only signal and there is no corresponding output line.
The form of handshaking to be used is specified by the value of hana. It should contain a combination of
the following bits, defined in p_serial.h:
P_OBEY_XOFF If set, receipt of the characters specified in xoff and xon suspend and resume
data transmission. If clear, these characters are treated as ordinary data. This
controls input XON/XOFF handshaking, which is independent of output
XON/XOFF handshaking.
P_SEND_XOFF If set, the characters specified in xoff and xon are transmitted to the remote
device to suspend and resume data transmission from the remote device. This
controls output XON/XOFF handshaking, which is independent of input
XON/XOFF handshaking.
P_IGN_CTS If clear, the driver will set its RTS line inactive to suspend transmission from
the remote device, and transmission will be suspended when the remote device
sets its RTS (incoming CTS) line inactive (RTS/CTS handshaking). If set, then
RTS is permanently active and the state of the input CTS line is ignored.
P_OBEY_DSR If set, transmission will be suspended when the remote device sets its DTR
(incoming DSR) line inactive (DTR/DSR handshaking). If clear, the state of
the incoming DSR line is ignored. In all cases the DTR line is held
permanently active while the seial port is powered up and open.
P_FAIL_DSR This is ignored unless p_oBEY_pDsR is set. If P_FAIL_DsR is set and the remote
device sets its DTR line inactive then any outstanding P_FWRITE or P_FREAD
request is completed with an E_FILE_LINE error (rather than simply suspending
transmission). The CCITT recommendations state that a serial port should hold
its DTR line active while the port is powered up and active. Setting
P_FAIL_psR allows application code to detect that a conforming remote device
has been removed or the connection broken.
P_OBEY_DCD If set, then transmission is suspended if the remote device sets the incoming
DCD line inactive. If clear, the state of the DCD line is ignored.
P_FAIL_DCD This is ignored unless P_oBEY_pDcD is set. If P_FAIL_pcp is set and the remote
device sets the incoming DCD line inactive then any outstanding P_FWRITE or
P_FREAD request is completed with an &_FILE_LINE error (rather than simply
suspending transmission).
4 SERIAL PORT
The default value of hana is zero, setting RTS/CTS handshaking.
In addition to using the control lines for hardware data flow control (which is transparent to the
application code), the serial port services allow the explicit testing of the state of the control lines or, for
example, to wait for the DCD line to be driven by a modem.
Control flags (¢1ags)
The control flags specify how the device driver should handle certain events. At the time of writing there
is only one control flag, defined in p_serial.h:
P_IGNORE_PARITY The presence or absence of a parity bit in received data is not under the
receiver's control. Setting p_1GNoRE_PaRITy causes the serial driver to discard
any parity errors on received data. A character received with a parity error is
placed in the receive buffer and treated as a normal character, even though it
may be in error.
For future compatibility the remaining bits of £1ags should be zero.
The default value of £1ags is zero.
Terminator characters (tmask)
A receiver has no universally reliable way of knowing when the transmitter has no more data to send.
Once some data has been received, the receiver may be entitled to assume that a period (say, five seconds)
in which no data arrives means that no further data will arrive. Clearly, this is not foolproof.
This problem may be solved provided that the transmitter cooperates with the receiver to the extent of
sending mutually agreed terminating characters.
One or more terminating characters may be specified by setting one or more bits of tmask. This consists of
32 bit flags, each corresponding (in order, from bit zero to bit 31) to a terminating character code in the
range 0x00 to ox1f inclusive.
Thus, setting bit zero (0x00000001) selects character code 0x00 to be a terminating character and setting
bit 26 (0x04000000) selects crru—z. An important use is to set bit 13 and/or bit 10 to select cr and/or Lr.
This allows text to be read a line at a time from a serial port.
The default value of tmask is zero, to select no terminating characters.
Serial port errors
Several errors can arise from a serial port that do not occur elsewhere. They include:
E_FILE_PARITY A parity error means that the received electrical signal corresponding to the
parity bit does not match the parity value calculated from the received data
bits. This is typically caused by electrical noise and usually indicates that the
data has been corrupted in transmission. Parity error detection is not
particularly robust, since many errors pass undetected.
E_FILE_FRAME A framing error means that the received electrical signal does not match the
start and stop bits. This most commonly occurs if data is being sent at a Baud
rate which differs from that which the receiver is expecting. Alternatively it
may mean that the number of stop bits expected by the receiver is greater than
the number being sent by the transmitter.
E_FILE_OVERRUN An overrun error occurs when the received electrical signal does not match the
stop bits. Overrun and framing errors are very similar and it is often difficult to
differentiate between them. Some devices may not report them as different
errors.
E_FILE_LINE A line error is generated when the hardware detects an inactive signal on an
input control line that the receiver requires to be permanently active (see also
Handshaking in the Serial port parameters section).
I/O DEVICES REFERENCE
I a SS SS 8 tev oo _TT_|vam_J =]
Serial port services
p_open(TTY:) Open a serial port
INT p_open(VOID **ppcb, TEXT *pname,-1) ;
Open a channel to the serial port *pname, where pname points to a serial port device name, as specified
earlier. If successful, write the channel to *ppcb and return zero.
For example:
if (!p_open(&pSerial, "TTY:A",-1) )
{
p_close(pSerial);
}
If successful the port will be powered up and the DTR line will be driven active to indicate to a connected
remote device that the port is open.
When opened a serial port will adopt its default characteristics of
e =©Baud
e data bits, no parity, 1 stop bit
e ~=RTS/CTS handshaking
e DCl1 is the XON, DC3 is the XOFF character
e Parity errors are not ignored
e No terminator characters
These characteristics may be incorrect for the required usage. To ensure that no received data is lost from,
say, a buffered modem, the RTS line will not be driven active until either the first P_rFREAD request or the
setting of some serial characteristics. (This, of course, assumes that the remote device is using RTS/CTS
handshaking.)
The call to p_open returns zero if successful, or a negative error. Errors include:
E_GEN_NOMEMORY there is not enough memory available to open the device
E_GEN_INUSE the specified port is currently in use
E_FILE_DEVICE an illegal or non-existent device is specified
E_FILE_LOCKED attempting to open too many channels to the device driver
p_close Close a serial port
INT p_close(VOID *pcb) ;
Close the specified channel to the serial driver.
The internal receive data buffer is flushed. If a character is currently being transmitted, the P_FCLOSE
request waits until its transmission is complete. The transmit data register becomes empty.
Any outstanding serial driver P_FREAD or P_FWRITE requests are cancelled.
The RTS and DTR lines are set inactive to indicate that the serial port is no longer in use and the serial
port is powered down.
Returns zero.
4 SERIAL PORT
P_FREAD Read from the serial port
INT p_iow(VOID *pcb, P_FREAD, VOID *buf, UWORD *plen);
VOID p_ioc(VOID *pcb, P_FREAD, WORD *pstat, VOID *buf, UWORD *plen)j;
Read up to *pien bytes to *buf from the serial port. The supplied buffer is assumed to be at least *pien
bytes long. The only limit to the amount of data that can be received in one call is the size of the data
buffer at but. It is the user's responsibility to preserve the data space pointed to by buf and plen until the
P_FREAD request completes.
The p_rreap request will typically take a significant length of time to complete and should normally be
called asynchronously in a quality system.
The request will complete when one of the following occurs:
@ *plen bytes have been received and transferred to *but. The request completes with zero
completion status code.
e areceive error is detected. The number of bytes received before the the error occurred is written
to *plen and these bytes transferred to *buf. The request completes with a negative error
completion status code.
¢ one of the terminating characters specified by the tmask field of the serial characteristcs is
received. The number of bytes received, including the terminating character, is written to *plen
and these bytes transferred to *buf. The request completes with zero completion status code.
e the request is cancelled. The number of bytes so far transferred to *buf is written to *plen.
The request completes with the —_F1LE_caNcEL completion status code.
The buffering mechanism at the serial driver's logical device driver level means that, following a
P_FCANCEL request, more characters may be available that have not yet been transferred to *but. The user
should test for this by calling the p_rtEst service and, if necessary, calling the p_rREAD service
synchronously to extract the remaining characters, as in the following example.
len=100;
p_ioc(pSerial,P_FREAD, &stat, &buf[0],&len) ;
p_iow(pSerial, P_FCANCEL) ;
p_waitstat (&stat); /* use up P_FREAD signal */
p_printf("Buf[] contains %d bytes",len);
p_iow(pSerial, P_FTEST, &len) ;
if (len)
p_read(pSerial,&buf[0],len); /* will complete immediately */
p_printf("There are %d more bytes available",len);
The calling process is panicked if a p_FREaD request is already outstanding or if pcb is not a valid channel
handle.
The completion status code is returned by the synchronous p_iow(P_FREAD) and written to *pstat by
asynchronous calls. The completion status code is zero if the p_rREaD request completed successfully,
otherwise it is a negative error number. Errors include:
E_FILE_PARITY a parity error occurred while receiving a character. This error will only be
reported if the user has not set p_IGNORE_PARITY in the serial characteristics.
Otherwise the error is discarded and the character (although in error) will
simply be transferred to *buE.
E_FILE_FRAME a serial framing error has occurred.
E_FILE_OVERRUN a serial overrun error has occurred.
E_FILE_LINE a line failure has occurred.
E_GEN_OVER the internal serial driver buffer has become full and further incoming
characters have been discarded. Some form of handshaking is required to slow
the transmitter down.
1/0 DEVICES REFERENCE
E_FILE_RECORD a terminator mask has been set, *plen bytes have been received and written
into *pbuf but no terminator character has been received. No characters have
been lost or received in error but the data format being received is not as
expected. This may or may not be regarded as an error, depending on the
application.
P_FWRITE Write to the serial port
INT p_iow(VOID *pcb, P_FWRITE, VOID *buf, UWORD *plen);
VOID p_ioc(VOID *pcb, P_FWRITE, WORD *pstat, VOID *buf, UWORD *plen)j;
Transmit *plen characters from the buffer at buf, obeying the currently selected handshaking.
The only limit to the amount of data that can be transmitted in one call is the size of the data buffer at buf.
A value of zero for *plen is permissible. It is the user's responsibility to preserve the data space pointed to
by buf and plen until the write request completes.
A P_FWRITE request will typically take a significant length of time to complete and should normally be
called asynchronously in a quality system.
A P_FWRITE request may be cancelled by using the P_FcANCEL service. The P_FWRITE request will complete
with the E_FILE_CANCEL completion status code. The serial driver does not report how many bytes have
been transmitted before the request was cancelled.
The P_FWRITE service can be used to wait for changes in hardware flow control lines. For example, a
physical link to a remote PC could be deemed to be established when the DSR line is set active. A
P_FWRITE request of zero bytes with handshaking set to P_OBEy_psR will only complete when the DSR line
is set active, as in the following example:
P_SRCHAR serChar;
p_iow(pSerial, P_FSENSE, &serChar) ;
serChar.hand|=P_OBEY_DSR;
p_iow(pSerial, P_FSET, &serChar) ;
len=0;
if (!p_iow(pSerial,P_FWRITE, &ébuf[0],é&len) )
{ /* DSR now being driven */
serChar.hand|=P_FAIL_DSR;
p_iow(pSerial,P_FSET, &serChar) ;
}
serChar.hand&=~ (P_OBEY. DSR|P FAIL_DSR) ;
p_iow(pSerial, P_FSET, &serChar) ;
In this example the serial handshaking is first set so that the first P_FWRITE request will wait until the
remote machine's DTR (incoming DSR) line is set active, at which time connection is deemed to have
been established. The handshaking is then set to cause any following read or write requests to fail if the
connection is lost (incoming DSR line set inactive). Finally, the handshaking is restored to its original
state.
The calling process is panicked if a P_FwRITE request is already outstanding, or if pcb is not a valid
channel handle.
The completion status code is returned by the synchronous p_iow(P_FWRITE) and written to *pstat by
asynchronous calls. The completion status code is zero if the P_FWRITE request completed successfully,
otherwise it is a negative error number. Errors include:
E_FILE_LINE a line failure has occurred.
P_FCANCEL Cancel any outstanding requests
INT p_iow(VOID *pcb, P_FCANCEL) ;
Cancel any outstanding P_FREAD and P_FWRITE requests, causing them to complete with the
E_FILE_CANCEL completion status code.
See the descriptions of the p_FREAD and P_FwRITE services for their behavior with respect to P_FCANCEL.
The p_FCANCEL service 1s harmless if no P_FREAD Or P_FWRITE requests are outstanding.
The P_FCANCEL service cannot fail and returns zero.
4-8
4 SERIAL PORT
P_FSENSE Sense the serial port characteristics
INT p_iow(VOID *pcb, P_FSENSE, P_SRCHAR *pch) ;
Write the current serial characteristics to the p_sRcHar struct pointed to by pch.
The p_FSENSE service cannot fail and returns zero.
P_FSET Set the serial port characteristics
INT p_iow(VOID *pcb, P_FSET, P_SRCHAR *pch) ;
Set the serial port characteristics to those passed in the p_srcuar struct pointed to by pch.
An application which wishes to change the serial port characteristics will normally first sense the current
characteristics, using the p_rsENsE service. It will then make the required change and use the p_rsEt
service to apply the new characteristics.
The calling process is panicked if there is an outstanding Pp_FREAD or P_FWRITE request or if pcb is not a
valid channel handle.
Returns zero if the p_rsrET request completed successfully, otherwise a negative error. Errors include:
E_GEN_ARG one or more of the values specified in the p_srcuar struct is illegal. The
current characteristics are not changed.
E_GEN_NSUP one of the required characteristics is not supported by this particular driver.
The current characteristics are not changed.
E_FILE_LINE either DSR is inactive and p_ratL_psr has been specified or DCD is inactive
and p_rarL_pcp has been specified (or both).
P_FFLUSH Flush the read buffer
INT p_iow(VOID *pcb, P_FFLUSH) ;
Discard the current contents of the internal serial read buffer (at the logical device driver level) and clear
any outstanding error status. Any handshaking that has paused transmission from the remote device is
cleared so that the remote device is free to resume transmission.
The p_FFLuSH service cannot fail and returns zero.
P_FTEST Test for received characters
INT p_iow(VOID *pcb, P_FTEST, UWORD *plen);
Set *pien to the number of bytes that are currently available in the serial driver's internal buffer.
Following the call it is guaranteed that there are at least *p1en bytes available. These bytes may be read
synchronously, since a synchronous p_REaD request to read *pien bytes will complete immediately.
By the time the p_rrest request has completed there may be more than *pien bytes available, since data
is received under interrupt control.
The calling process is panicked if there is an outstanding p_rREaD request or if pcb is not a valid channel
handle.
The p_Ftest service cannot fail and returns zero.
P_FCTRL Test and set control lines
INT p_iow(VOID *pcb, P_FCTRL, UBYTE *pctrl);
Read the current state of the CTS, DSR and DCD input control lines to *pctr1 as a bit mask and,
optionally, set the DTR output control line.
I/O DEVICES REFERENCE
The following bit flags are defined in p_serial.h:
P_SRCTRL_CTS if set CTS is active, otherwise it is inactive
P_SRCTRL_DSR if set DSR is active, otherwise it is inactive
P_SRCTRL_DCD if set DCD is active, otherwise it is inactive
If the byte pointed to by * (pctr1+1) is non-zero it is used to set the state of the DTR output line. If non-
zero it should take one of the following values, defined in p_serial.h:
P_SRDTR_ON to set DTR active
P_SRDTR_OFF to set DTR inactive
Returns zero if the p_FcTRL request completed successfully, otherwise a negative error number. Errors
include:
E_GEN_NSUP this driver does not support the setting of the DTR line. All current SIBO
machines support the setting of the DTR line.
P_FINQ Inquire supported serial characteristics
INT p_iow(VOID *pcb, P_FINQ, UWORD *pmask) ;
Write three words, into *pmask, * (pmask+1) and * (pmask+2), containing the serial characteristics that the
driver supports. Each word consists of a set of bit flags with each bit set indicating a supported
characteristic.
The first word, at *pmask, indicates a combination of the following potentially supported Baud rates,
defined in p_serial.h:
P_SRINQ_50
P_SRINQ_75
P_SRINQ_110
P_SRINQ_134
P_SRINQ_150
P_SRINQ_300
P_SRINQ_600
P_SRINQ_1200
P_SRINQ_1800
P_SRINQ_2000
P_SRINQ_2400
P_SRINQ_3600
P_SRINQ_4800
P_SRINQ_7200
P_SRINQ_9600
P_SRINQ_19200
The serial driver in all SIBO machines reports that all the above Baud rates are suppported, however see
Baud rate in the earlier Serial port parameters section for a discussion of the use of 19200 Baud.
The second word, at * (pmask+1), indicates a combination of the following potentially supported Baud
rates, defined in p_serial.h:
P_SRINQ_38400
P_SRINQ_56000
SIBO machines do not currently support either of these Baud rates.
The third word, at * (pmask+2), indicates support for a combination of the following characteristics,
defined in p_serial.h:
P_SRINQ_DATAS supports 5 data bits
P_SRINQ_DATA6 supports 6 data bits
P_SRINQ_DATA7 supports 7 data bits
P_SRINQ_DATA8 supports 8 data bits
P_SRINQ_STOP2 supports sending 2 stop bits
P_SRINQ_PAREVEN supports even parity
P_SRINQ_PARODD supports odd parity
P_SRINQ_PARMARK supports mark parity
4 SERIAL PORT
P_SRINQ_PARSPACE supports space parity
P_SRINQ_SETDTR supports the setting of DTR
P_SRINQ_SPLIT supports the setting of split Baud rates
The SIBO machines support all of the above except p_sRINQ_PARMARK, P_SRINQ_PARSPACE and
P_SRINQ_SPLIT.
The p_Fing service cannot fail and returns zero.
ee
Example
The following example, which assumes that the serial port is connected to a modem, uses many of the
serial services described above.
After opening a console it sends a dialling string to the modem and waits for a connection to a remote
modem. It then receives text records transmitted by the remote modem and displays them in the console
window. This continues until the user exits the program by pressing the ESCAPE key.
include <plib.h>
include <p_serial.h>
include <p_keyb.h>
define OPEN_TIMER 0
define OPEN_PORT 1
define DTR_HAND 2
define DIALLING 3
define LINE_FEED 0x0a
LOCAL_D VOID *pTimer=0; /* Timer channel handle */
LOCAL_D WORD timStat; /* Timer completion status */
LOCAL_D VOID *pSerial=0; /* Serial channel handle */
LOCAL_D WORD serWriteStat; /* Serial write completion status */
LOCAL_D WORD serReadStat; /* Serial read completion status */
GLREF_D VOID *winHandle; /* Console channel handle */
LOCAL_D WORD winStat; /* Console completion status */
LOCAL_C VOID reportError(INT func, INT error)
UBYTE bb[100];
switch (func)
{
case OPEN_TIMER:
p_puts("Failed to open timer channel");
break;
case OPEN_PORT:
p_puts("Failed to open serial port");
break;
case DTR_HAND:
p_puts ("Modem not driving DSR");
break;
case DIALLING:
p_puts ("Failed to connect to remote Modem") ;
break;
default:
p_puts ("Unknown function error");
}
p_errs(&bb[0],error);
p_puts (&bb[0]);
p_close(pSerial) ;
p_close(pTimer) ;
p_exit (1);
}
I/O DEVICES REFERENCE
LOCAL_C VOID QueueTimer (ULONG timeout)
{
p_ioc(pTimer,P_FREAD, &timStat, &timeout) ;
}
LOCAL_C VOID CancelTimer (VOID)
{
p_iow(pTimer,P_FCANCEL) ;
p_waitstat (&timStat) ;
}
LOCAL_C VOID QueueSerialWrite(UBYTE *buf,UWORD *plen)
p_ioc(pSerial,P_FWRITE, &serWriteStat,buf,plen) ;
LOCAL_C VOID CancelSerialWrite (VOID)
p_iow(pSerial,P_FCANCEL) ;
p_waitstat (&serWriteStat) ;
LOCAL_C setHand(INT clrflag, INT setflag)
P_SRCHAR sch;
p_iow(pSerial,P_FSENSE, &sch) ;
sch. hand&=clrflag;
sch.hand|=set flag;
return (p_iow(pSerial,P_FSET, &sch) );
}
LOCAL_C VOID resetModem (VOID)
/*
Reset a modem by driving DTR low for 2 seconds
x
{
UBYTE bb[2];
bb [1]=P_SRDTR_OFF;
p_iow(pSerial,P_FCTRL, &bb[0]);
p_sleep(20L);
bb [1]=P_SRDTR_ON;
p_iow(pSerial,P_FCTRL, &ébb[0]);
}
LOCAL_C dialNumber (VOID)
/*
Returns zero if successful, else -ve error number
ey.
{
UWORD len;
INT ret;
len=11;
QueueSerialWrite ("ATD9, 123456", &len) ;
QueueTimer(50L); /* 5 secs to send dial string */
p_iowait ();
if (serWriteStat !=E_FILE_PENDING)
{ /* sent dial string */
CancelTimer();
if (!serWriteStat)
{ /* sent dial string Ok */
if ((ret=setHand(-1,P_OBEY_DCD) ) !=0)
return (ret);
len=0;
QueueSerialWrite("",&len); /* Wait for DCD */
QueuveTimer(1200L); /* 2 mins to get through */
p_iowait ();
if (serWriteStat !=E_FILE_PENDING)
{
CancelTimer ();
if (!serWriteStat)
{
if ((ret=setHand(-1,P_FAIL_DCD) ) !=0)
return (ret);
}
else
CancelSerialWrite();
}
else /* timeout sending dial string */
CancelSerialWrite();
return (serWriteStat) ;
}
4 SERIAL PORT
I/O DEVICES REFERENCE
GLDEF_C main (VOID)
{
INT ret;
UWORD len;
P_SRCHAR sch;
P_CON_KBREC kbrec;
UBYTE key[2];
UBYTE buf [128+2];
p_puts("Serial Driver Example"); /* opens a console */
if ((ret=p_open (&pTimer, "TIM:",-1)) !=0)
reportError (OPEN_TIMER, ret) ;
if ((ret=p_open(&pSerial,"TTY:A",-1)) !=0)
reportError (OPEN_PORT, ret) ;
resetModem () ;
if ((ret=setHand(-1,P_OBEY DSR|P FAIL_DSR) ) !=0)
reportError (DTR_HAND, ret);
if ((ret=dialNumber () ) !=0)
reportError (DIALLING, ret) ;
p_iow(pSerial,P_FSENSE, &sch) ;
sch.tmask=(1<<LINE_FEED); /* read a record at a time */
p_iow(pSerial,P_FSET, é&sch) ;
len=128;
p_ioc(pSerial,P_FREAD, &éserReadStat, &buf[0],é&len);
p_ioc(winHandle, P_FREAD, &winStat, &kbrec) ;
FOREVER
{
p_iowait ();
if (serReadStat !=E_FILE_PENDING)
{ /* serial read completed */
if (!serReadStat || serReadStat==E_FILE_RECORD)
{
buf [len]=0;
p_puts(&buf[0]); /* display that record */
len=128;
p_ioc(pSerial,P_FREAD, &serReadStat, &buf[0],&len);
continue;
}
p_iow (winHandle, P_FCANCEL) ;
p_waitstat (&winStat) ;
break; /* Comms failure */
}
if (kbrec.keycode==P_KB_ESCAPE)
{ /* Nominated exit key */
p_iow(pSerial,P_FCANCEL) ;
p_waitstat (&serReadStat) ;
break;
}
key [0] =kbrec. keycode;
p_write(pSerial, &key[0],1);
p_ioc (winHandle, P_FREAD, &winStat, &kbrec) ;
}
resetModem () ;
p_close(pSerial) ;
p_close(pTimer) ;
return (0);
}
CHAPTER 5
SOUND
Pm S_ |
Introduction
On all machines sound can be generated from an internal speaker driven by the snp: device driver.
In addition all machines, with the exception of the Series 3a, include a built-in piezo-electric buzzer that
can be used for emitting warning beeps and other simple sounds. The Series 3a contains software that
emulates a buzzer, emitting the sound via the speaker. Using the buzzer has the advantage that (except on
the Series 3a) much less power is needed to drive it. In all cases the buzzer (or the buzzer emulator) is
controlled by means of the p_sound routine.
In all machines output to the sound channel is disabled if either the E_sounp_DEvice bit of the sound flag
is clear or the E_SOUND_DISABLE bit of the sound flag is set. These flags are manipulated by the p_get snd
and p_setsnd functions, described in the PLIB Reference manual.
Sound on MC and HC machines
MC and HC machines can emit sound from either a piezo-electric buzzer or an amplifier-driven
loudspeaker. In normal circumstances the buzzer output is controlled by the PLIB p_souna function and
the snp: sound device driver controls output to the speaker.
AS a power-conserving strategy, all sound output is directed to the buzzer if the main battery voltage is
less than the warning voltage level and no mains supply is connected.
The speaker is a two voice output device, that is, it can play two-note chords. This means that DTMF tone
dialing is possible.
The sound services provide for the generation of a wide range of notes or note sequences.
Sound on Series 3 machines
The Series 3 can emit sound from either a piezo-electric buzzer or an amplifier-driven loudspeaker. In all
circumstances the buzzer output is controlled by the PLIB p_souna function and the snp: sound device
driver controls output to the speaker.
The Series 3 sound device driver services are limited to providing either DTMF dialling tones or simple
alarm sounds. The user who wishes to generate more complex sounds must load a suitable device driver -
a simple example, SVDFRC.LDD, can be found on the SIBOSDK disk included with this manual.
Sound on Series 3a machines
The Series 3a can emit sounds from an amplifier-driven loudspeaker, using either the snp: sound device
driver or the built-in buzzer emulator. In all circumstances the buzzer emulator output is controlled by the
PLIB p_sound function. The Series 3a speaker is a two voice output device that can play two distinct notes
at the same time. The snp: sound device driver provides the same services as on the HC and MC
machines, thus allowing for the generation of a wide range of notes or note sequences.
The Series 3a can also record and play .wve digital sound files - see the General System Services chapter
of the Plib Reference manual. These are especially useful for adding custom alarm sounds.
Panics
All services (with the exception of p_open) will cause the calling process to be panicked if the passed
channel handle is not valid. Other panics are described under the particular service to which they apply.
5-1
I/O DEVICES REFERENCE
—E—EE—Ee——————— ee.
Sound services
The services listed in this section are available on all SIBO machines.
p_open(SND:) Open the sound channel
INT p_open(VOID **pcb, "SND:", -1);
Open a channel to sound device.
Returns zero if successful, or one of the following errors:
E_FILE_ALLOC failed to allocate memory for the control block
E_GEN_FAIL sound device is disabled
E_FILE_LOCKED or port is already open or in use
E_GEN_INUSE
p_close Close the sound channel
INT p_close(VOID *pcb) ;
Close the sound channel.
Returns zero.
P_FCANCEL Cancel a write request
INT p_iow(VOID *pcb, P_FCANCEL) ;
Cancel any outstanding write request. Performing a cancel is harmless if no write request is outstanding.
Returns zero.
P_FSENSE Sense sound characteristics
INT p_iow(VOID *pcb, P_FSENSE, E_SOUND *psound) ;
Sense the sound channel characteristics. The &_sounp struct is defined in epoc.h as:
typedef struct
{
UBYTE beatsPerMinute;
UBYTE volume;
} E_SOUND;
The value of beat sPerMinute has no significance for the Series 3 machine. On HC, MC and Series 3a
machines beat sPerMinute may vary from E_SOUND_MIN_BPM (2) to E_SOUND_MaAx_BpM (240). The default
value is 120.
On HC, MC and Series 3a machines volume may vary from E_SOUND_MAx_VOLUME (0) to
E_SOUND_MIN_VOLUME (5). On Series 3 machines the value is restricted to the range | to 4 inclusive. On the
Series 3a volumes | and 2 are identical, as are 4 and 5 - there are thus only four actual volumes. In all
cases a smaller value of volume gives a louder sound. The default value is 1.
Returns zero.
P_FSET Set sound characteristics
INT p_iow(VOID *pcb, P_FSET, E_SOUND *psound);
Set the sound channel characteristics from the data in the E_souNp struct, as described for the P_FSENSE
service. Setting a value for beat sPerMinute has no effect for the Series 3 machine.
5 SOUND
To set one sound characteristic without changing the other you should call p_rsense before p_rset. For
example:
E_SOUND sound;
p_iow (pcb, P_FSENSE, &sound) ;
sound.volume = 2;
p_iow (pcb, P_FSET, &sound) ;
will set volume without changing beat sPerMinute.
Returns zero if successful, or =_ceN_azc if either of the characteristics is out of range.
E FALARM Write alarm note sequence
VOID p_ioc(VOID *pcb, E_FALARM, WORD *pstat, UWORD *palarm) ;
INT p_iow(VOID *pcb, E_FALARM, UWORD *palarm) ;
Write one of the two standard alarm note sequences.
The alarm note sequence is selected by *palarn:
0 rings sequence
1 chimes sequence
For example,
UWORD alarm;
alarm=1;
p_iow (pcb, E_FALARM, é&alarm) ;
Panics if an E_FALARM, E_FSSOUNDCHANNELn Of E_FDIAL request is currently outstanding, or if pcb 1s not a
valid channel handle.
The completion status code is returned by the synchronous p_iow(E_FALARM) and written to *pstat by
asynchronous calls. The completion status code is zero if the p_rwrITE request completed successfully, or
E_FILE_CANCEL if the write was cancelled by a call to the p_rcancEL service.
HC, MC and Series 3a additional sound service
This service is available only on HC, MC and Series 3a machines.
E FSSOUNDCHANNELn Write to voice n
VOID p_ioc(VOID *pcb, E_FSSOUNDCHANNELn, WORD *pstat, WORD *pnotes, WORD *plen);
Write *plen notes to voice n (n may be | or 2) of the sound channel. The value of *pien must be less than
or equal to 16384 (0x4000).
The parameter pnotes should point to an array of *pien notes. A note consists of two worps, the first
giving the note frequency in Hz (middle A is 440Hz) and the second gives the note duration in beats. By
default there are 120 beats per minute, but this value may be changed using p_rset. A zero frequency
corresponds to silence.
To allow the output to both voices to be synchronised, neither output will start until both
E_FSSOUNDCHANNEL1 and E_FSSOUNDCHANNEL2 Services have been called.
Panics if an E_FSSOUNDCHANNELn (on the same channel) or an F_FALARM request is currently outstanding,
or if pcb is not a valid channel handle.
The completion status code is written to *pstat. It is zero if the request completed successfully, otherwise
it is a negative error code.
If you only require to use one of the voices you must still call both services but can, for example, set the
value pointed to by pien to zero for the =_FSOUNDCHANNEL2 service.
I/O DEVICES REFERENCE
Note: the sound and volume should always be sensed, and then set, immediately after opening the sound
channel and before playing sound. This is required even if you wish to play sound at the default volume
and beats per minute.
The following example will output a rising and falling scale (known as the ice-cream van at Psion):
#include <plib.h>
LOCAL_C VOID PlaySound(VOID *pcb)
{
WORD notesl1[] = {1048,24,524,12};
WORD notes2[] = {1048,4,1320,4,1568,4,2092,4,1568,4,1320,4,1048,12};
WORD sndstat1,sndstat2;
WORD lenl,len2;
INT i;
lenl = sizeof (notes1) /4;
len2 = sizeof (notes2) /4;
p_ioc5 (pcb, E_FSSOUNDCHANNEL1, ésndstat1, &notes1[0],é&lenl);
p_ioc5 (pcb, E_FSSOUNDCHANNEL2, &ésndstat2, &notes2[0],&len2) ;
i= -1;
do
{
p_iowait ();
itt;
} while (sndstatl == E_FILE_PENDING && sndstat2 == E_FILE_PENDING) ;
if (sndstatl == E_FILE_PENDING)
p_waitstat (&sndstatl);
else
p_waitstat (&sndstat2) ;
while (i--)
p_iosignal();
}
GLDEF_C INT main(VOID)
{
VOID *pcb;
E_SOUND sound;
p_open(&pcb, "SND:",-1);
p_iow (pcb, P_FSENSE, &sound) ;
p_iow (pcb, P_FSET, &sound) ;
PlaySound (pcb) ;
p_close (pcb);
return (0);
}
Series 3 and Series 3a additional sound service
This service is available only on Series 3 and Series 3a machines.
E FDIAL Write DTMF dial tones
VOID p_ioc(VOID *pcb, E_FDIAL, WORD *pstat, TEXT *pstr, E_DIAL *pdial);
INT p_iow(VOID *pcb, E_FDIAL, TEXT *pstr, E_DIAL *pdial);
Write a DTMF tone sequence from the zero terminated string *pstr, with timing as specified by the
content of the E_DIAL struct pointed to by pdial. This struct is defined in epoc.h as:
typedef struct
{
UBYTE toneLengthTicks; /* tone length in 1/32 sec */
UBYTE delayLengthTicks; /* inter-tone delay in 1/32 sec */
UWORD pauseLengthTicks; /* pause length in 1/32 sec */
} E_DIAL;
5 SOUND
DTMF tones are produced for the following valid characters:
e the digits 0 to 9
e upper or lower case alphabetic characters in the range A to F
e the characters # (0x23) and * (0x2A) which are converted to F and E respectively.
Space and comma characters generate a pause of length specified by the &_p1at struct element
pauseLengthTicks. All other characters are ignored.
The string at pstr may be of any length, but the total number of valid tone and pause generating characters
characters in it may not exceed 26.
For example, assuming a dial-out code of 9,
E_DIAL dial;
TEXT digits[10];
dial.toneLengthTicks=8;
dial.delayLengthTicks=8;
dial.pauseLengthTicks=48;
p_scpy (&digits[0],"9,0711234") ;
p_iow(pcb,E_FDIAL, &digits[0],&dial) ;
will emit the DTMF dialling tones to dial the external number 071 1234.
Panics if an E_FDIAL Of E_FALARM request is currently outstanding, or if pcb is not a valid channel handle.
The completion status code is returned by the synchronous p_iow(E_FDIAL) service and written to *pstat
by an asynchronous call. The completion status code is zero if the E_Fp1aL request completed successfully,
or one of the following errors:
E_FILE_CANCEL the write was cancelled by a call to the p_rcancEL service
E_GEN_ARG the string contains too many valid characters
a ———
Example
The following code implements a simple tone dialing system for HC, MC or Series 3a machines.
#include <plib.h>
#include <p_cons.h>
#include <wskeys.h>
GLREF_D VOID *winHandle;
LOCAL_D WORD tones1[] =
941,1,697,1,697,1,697,1,770,1,770,1,770,1, 852,1, 852,1,852,1,941,1,941,1};
LOCAL_D WORD tones2[] =
1336,1,1209,1,1336,1,1447,1,1209,1,1336,1,1447,1,1209,1,1336,1,1447,1,1209,1,1477,1};
LOCAL_C VOID dial(VOID *psoundcb, INT tone)
WORD len = 1;
WORD sl_status;
WORD *ptonel, *ptone2;
if(tone >= 0 && tone <= 11)
{
ptonel = &tones1[0] + tone*2;
ptone2 = &tones2[0] + tone*2;
p_ioc5 (psoundcb, E_FSSOUNDCHANNEL1, &sl1_status,ptonel, &len) ;
p_iow4 (psoundcb, E_FSSOUNDCHANNEL2, ptone2, &len) ;
p_waitstat (&sl_status) ;
}
IEVICES REFERENCE
VOD
GLDEF_C INT main(VOID)
{
INT c,tone,err;
VOID *psoundcb;
UWORD func;
P_RECT rect;
E_SOUND sound;
if ((err=p_open (&winHandle, "CON:",-1)) !=0)
{
p_notifyerr(err,"No Console device",NULL, NULL, NULL) ;
p_exit (1);
}
rect.tl.x
rect.tl.y = 0; /* set the screen size */
rect.br.x = 25;
rect.br.y = 9;
func = P_SCR_WSET;
p_iow4 (winHandle, P_FSET, &func, &rect) ;
p_printf ("Tone dial demo");
if ((err=p_open (&psoundcb, "SND:",-1)) !=0)
{
p_notifyerr(err,"Cannot open sound device",NULL, NULL, NULL) ;
p_close (winHandle) ;
p_exit (1);
}
sound.volume = 3;
sound.beatsPerMinute = 76;
p_iow3 (psoundcb, P_FSET, &sound) ;
FOREVER
{
c = p_getch();
if (c==W_KEY_RETURN) ;
break;
p_putch (c);
if (c=='"*')
tone = 10;
else if (c=='#"')
tone = 11;
else
tone =c - '0O';
dial (psoundcb, tone) ;
}
p_close (psoundcb) ;
p_printf("\r\nDemo finished");
p_printf ("Press any key to exit");
p_getch ();
p_close(winHandle) ;
return (0);
}
CHAPTER 6
THE ALARM DEVICE DRIVER
Introduction
The atm: device driver supplied on Series 3, Series 3a and MC machines provides support for alarms
(as used in the Agenda application). A process may specify an alarm sound (Series 3a only), an alarm
message and an appointment time.
The following picture illustrates the screen display for an untimed alarm on a Series 3a machine.
Alarm (Agenda) 12:32:18 pm
Alarm: Mon 18th Oct
Finish the alarm server chapter ...
Clear alarm Snooze Silence
Note that the appointment date is displayed but not the appointment time.
The following picture illustrates the screen display for a timed alarm on a Series 3a machine.
Alarm (Agenda) 12:58:89 pm
Alarm: Mon 18th Oct 2:46 pm
Finish the alarm server chapter ...
Clear alarm Snooze Silence
—Enter_|
Both the time and the date of the appointment are displayed.
An alarm is set by sending an alarm request to the alarm device driver (atu: ). This request may be made
synchronously, using p_iow, or asynchronously, by using p_ioc, for example.
Note that the alarm server holds a copy of the data relating to an outstanding alarm request. An
outstanding alarm can therefore survive the termination of its parent, that is, the process that made the
alarm request. Such an alarm is referred to as an orphaned alarm.
An orphaned alarm is automatically reparented when an identical alarm request is made. This feaure is
used by, for example, the Agenda application. Thus, even if an Agenda file is repeatedly closed and
reopened, an entry with an alarm will not be marked with a large number of identical alarm requests.)
I/O DEVICES REFERENCE
Panics
An application will be panicked if it makes an alarm request before any previous alarm request from that
application has completed. All services (with the exception of p_open) will cause the calling process to be
panicked if the passed channel handle is not valid.
The #defines and structs for the alarm server device are in the header file hasrv.h.
Series 3, Series 3a and MC alarm services
The Series 3a also has additional services that are described in the following section.
Note that all alarm services are provided by the Time application that is built into Series 3 and Series 3a
machines, rather than being an integral part of the operating system.
p_open(ALM:) Open the alarm channel
INT p_open(VOID **pcb, "ALM:", -1);
Open a channel to the alarm device.
Returns zero if the alarm device is opened successfully, otherwise one of the following errors:
E_GEN_OPEN
E_GEN_NOMEMORY
E_FILE_NXIST
p_close Close the alarm channel
INT p_close(VOID *pcb);
Close the alarm device channel.
Returns zero.
P_FCANCEL Cancel an alarm request
INT p_iow(VOID *pcb, P_FCANCEL) ;
Cancel any outstanding alarm request. Performing a cancel is harmless if no alarm request is outstanding.
Returns zero.
A_FTIMED Queue a timed alarm
VOID p_ioc(VOID *pcb, A_FTIMED, WORD *pstat, A_DETAILS *pd, TEXT *pm) ;
Queue a timed alarm specified by a pointer to an A_DETAILS struct, and a pointer to a zero terminated text
message.
The A_DETAILS struct would be defined as follows:
typedef struct
{
ULONG absTime;
ULONG dueTime;
} A_DETAILS;
¢ absTime is the alarm time as a system time.
¢ dueTime is the appointment time as a system time.
The appointment time should not be earlier than the time of the alarm.
The text message pointed to by pm should be a zero terminated string of not more than 65 characters
including the zero terminator. If no text message is required then pm should point to the null string.
The completion status is written to *pstat. The status is zero if the service completed successfully
otherwise a negative error number.
6-2
6 THE ALARM DEVICE DRIVER
A_FUNTIMED Queue an untimed alarm
VOID p_ioc(VOID *pcb, A_FUNTIMED, WORD *pstat, A_DETAILS *pd, TEXT *pm);
Queue an untimed alarm specified by a pointer to an a_DETAILSs Struct, and a pointer to a zero terminated
text message.
This service is identical to a_rTIMED (see above) except that only the day and month of the appointment
time are displayed, the hours and minutes being omitted.
Series 3a additional alarm services
The services listed in this section are only available on the Series 3a machine.
A_FTIMED X Queue a Series 3a timed alarm
VOID p_ioc(VOID *pcb, A_FTIMED_X, WORD *pstat, AXDATA *pa, TEXT *pm);
Queue a timed alarm specified by a pointer to an axpata struct, and a pointer to a zero terminated text
message.
The axpara struct is defined in hasrv.h as follows:
typedef struct
{
ULONG absTime;
ULONG dueTime;
SE_SND sound;
} AXDATA;
@ absTime 1s the alarm time as a system time.
@ dueTime is the appointment time as a system time.
® sound is the alarm sound (see below).
The se_swp struct defines the sound to be made and is defined in hasrv.h as follows:
typedef struct
{
UBYTE len;
TEXT name[8];
UBYTE zero_term;
} SE_SND;
¢ en is the length of the string in the name field.
¢ name specifies the name of the alarm sound (see below).
@ zero_term is the nuut character.
The element name in the sE_swp struct can have one of the following values:
e asingle byte containing a value between | and 16 inclusive. Currently only 1, 2 and 16 are used,
corresponding to the rings, chimes and silent alarms respectively. The contents of following
unused bytes are not significant. For example:
AXDATA axdata
axdata.sound.len=1;
axdata.sound.name[0]=1;
would set the rings sound.
I/O DEVICES REFERENCE
¢ anon-zero-terminated string specifying one of the .wve digital sound files resident in the ROM.
Currently these are: SYS$ALO/ for a 'Fanfare', SYS$AL02 for 'Soft bells' and SYS$AL03 for
Church bells. For example:
AXDATA axdata
axdata.sound.len=8;
p_scopy (&axdata.sound.name[0],"SYSSAL03") ;
would set the 'Church bells' sound.
¢ anon-zero-terminated string specifying a .wve sound file resident in a local \wve\ directory. The
contents of following unused bytes are not significant. For example:
AXDATA axdata
axdata.sound.len=p_slen("mysound") ;
p_scopy (&axdata.sound.name[0],"mysound") ;
would set the sound to be that contained in a \wve\mysound.wve file.
The message pointed to by pm should be a zero terminated string of not more than 161 characters,
including the zero terminator. If no text message is required, then pm should point to a null string.
The completion status is written to *pstat. The status is zero if the service completed successfully
otherwise a negative error number.
A_FUNTIMED X Queue a Series 3a untimed alarm
VOID p_ioc(VOID *pcb, A_FUNTIMED_X, WORD *pstat, AXDATA *pa, TEXT *pm);
Queue an untimed alarm specified by a pointer to an axpata struct, and an associated text message.
This service is identical to the A_FTIMED_x service (see above) except that only the day and month of the
appointment time are displayed, the hours and minutes being omitted.
CHAPTER 7
THE FREE-RUNNING COUNTER
Introduction
The Series 3a and Workabout machines are supplied with a device driver for a built in free-running
counter (FRC). This device driver may be accessed by applications and provides for the measurement of
elapsed time with an accuracy of +/- 2ppm (corresponding to 2.6 seconds per month) and a resolution of
1/1024 seconds.
The free-running counter device driver may be used in one of three ways:
e to provide a value that increments once every 1/1024 second, effectively a relative clock. An
application can read the value at any time, without resetting it.
e to trigger an event after a specified interval, in units of 1/1024 second. In effect this provides the
same function as a relative timer, except that the free-running counter works to a higher
resolution.
e to provide a value that increments once every specified time interval, in units of 1/1024 second.
This allows an application to create a relative clock, with the resolution tailored to the
application's requirements. The value is reset to zero each time that it is read.
As the FRC device driver can support only one process at any one time, applications should use it for no
longer than is absolutely necessary.
An application that only needs to work with time intervals with a resolution of 1/32 second or greater
should not use the FRC, but should use either a relative or an absolute timer: details of these timers can be
found in the Time, Timers and Dates chapter of the Plib Reference manual.
FRC services
The FRC: device driver is specific to the Series 3a and Workabout machines.
All services (with the exception of p_open) will cause the calling process to be panicked if the passed
channel handle is not valid. Other panics are described under the particular service to which they apply.
p_open(FRC:) Open the FRC channel
INT p_open(VOID **pcb, "FRC:", -1);
Open a channel to the FRC device.
Returns zero if the device was opened successfully, otherwise a negative error code. Errors include:
E_FILE_OPEN The device can not be accessed as it is in use.
E_GEN_NOMEMORY There is insufficient memory to allow a channel to be opened.
I/O DEVICES REFERENCE
p_close Close the FRC channel
INT p_close(VOID *pcb) ;
Close the device channel, first cancelling any outstanding read request.
Returns zero.
P_FCANCEL Cancel the FRC request
INT p_iow(VOID *pcb, P_FCANCEL) ;
Cancel any outstanding request. Performing a cancel is harmless if no request is outstanding.
Returns zero.
P_FSTART Start the free-running counter
INT p_iow(VOID *pcb, P_FSTART, UWORD *pmode, UWORD *pint);
Start the free-running counter.
The uworp pointed to by pmode must specify one of the following modes, defined in epoc.h:
E_FRC_COUNTING a counter increments every 1/1024 seconds from an initial value of zero. The
value of pint is ignored.
E_FRC_REPEATING a counter increments every *pint multiple of 1/1024 seconds, starting from
zero. The value of *pint should be in the range 10 to 65535, representing time
intervals approximately in the range of 0.01 to 64 seconds.
Any outstanding P_FREAD request will be cancelled and the counter reset to zero.
Returns zero if the request completed successfully, otherwise returns a negative error number. Errors
include:
E_GEN_NSUP an invalid mode was specified.
E_GEN_RANGE the specified repeat interval is not valid, i.e. it is in the range 0 to 9 inclusive.
P_ FREAD Read the elapsed time in E_ FRC_COUNTING mode
VOID p_ioc(VOID *pcb, P_FREAD, WORD *pstat, ULONG *argl);
INT p_iow(VOID *pcb, P_FREAD, ULONG *argl1);
Sense the current counter value, following a previous P_FSTART request that set E_LFRC_COUNTING mode.
The value written to *arg1 is the time, in units of 1/1024 seconds, since the last P_rsTarT request. The
value is not reset by the P_FREAD request.
The application will be panicked if an earlier P_FREAD request is outstanding.
The completion status is written to *pstat for p_ioc and returned by p_iow. It is zero if the request
completed successfully. Otherwise it is a negative error number. Errors include:
E_GEN_OVER the elapsed number of repeat intervals is too large to be written to *arg1.
E_FILE_CANCEL the P_FREAD request was cancelled before it completed.
E_FILE_READ either the counter was not running, or the machine was switched off while the
counter was running.
7 FRC
P_ FREAD Read the elapsed time in E_ FRC_REPEATING mode
VOID p_ioc(VOID *pcb, P_FREAD, WORD *pstat);
INT p_iow(VOID *pcb, P_FREAD) ;
Sense the current counter value, following a previous p_rstTarT request that set E_FRC_REPEATING mode.
The completion status value that results from a successful call to this service is the number of complete
time intervals (as specified by the earlier p_rstart request) that have elapsed since the last request for
either a P_FSTART Of a P_FREAD Service. The service will not complete until one time interval has elapsed,
otherwise completion is immediate. Time is not lost between successive P_FREAD requests, since the FRC
hardware is not reset.
The application will be panicked if an earlier p_rREaD request is outstanding.
The completion status is written to *pstat for p_ioc and returned by p_iow. It is a positive value if the
request completed successfully. Otherwise it is a negative error number. Errors include:
E_GEN_OVER the elapsed number of repeat intervals exceeds 32767.
E_FILE_CANCEL the p_FREAD request was cancelled before it completed.
E_FILE_READ either the counter was not running, or the machine was switched off while the
counter was running.
CHAPTER 8
THE SERIES 3 WORLD DATABASE
Introduction
The World database is supported by all of the Series 3 range of machines. It stores a range of data for a
large number of countries - in practice only small or very recently created countries are not present.
Further data is stored for the larger cities in each country.
The wip: device driver allows an application to navigate the database by means of a number of search
services. A successful search sets the current city and/or country for other services that can access or
update the constituent data according to specific requirements. It supports multiple channels.
The services of this device driver are provided by the World application that is built into the ROM of all
machines in the Series 3 range.
The data stored in the database includes various codes required for dialling as follows:
e the national code for each country.
e the international prefix code for each country.
e the national prefix for long distance calls.
The database also includes the following data for each city:
e the deviation of the local time from Greenwich Mean Time.
e the times of sunset and sunrise expressed as a local time (these are actually calculated).
e the latitude and the longitude of the city.
e the coordinates of the city on the World map.
e the zone for daylight saving time (DST).
An application may also:
e set its home city.
e set its default country.
The database supports the creation of a file containing extra items which may be either new cities, or
replacement data for existing cities: only 32 extra items may be included in any one file. (A greater
number of extra items would significantly degrade the performance of the database search operations.)
Mode
A minority of services change the mode of the the database which can effect the operation of subsequent
services. Thus the wR_NEXT service moves to the next city if the database is in city mode. Otherwise the
WR_NEXT Service moves to the next country.
A service is assumed not to change the mode unless it is explictly stated to the contrary.
1/0 DEVICES REFERENCE
Series 3 and Series 3a World database services
Note that these services are provided by the World application that is built into Series 3 and Series 3a
machines, rather than being an integral part of the operating system.
p_open(WLD:) Open the World channel
INT p_open(VOID **ppcb, "WLD:", Oxffff);
Open a channel to the World database and write the handle of the channel to «ppcb.
Returns zero on success, otherwise a negative error code including the following:
E_FILE_ALLOC failed to allocate memory for the control block.
p_close Close the World channel
INT p_close(VOID *pcb) ;
Close the channel to the World database specified by pcb.
Returns zero on success.
P_FCANCEL Cancel a World request
INT p_iow(VOID *pcb, P_FCANCEL) ;
Cancel any outstanding World request on channel pcb and return zero - performing a cancel is harmless if
there is no outstanding request.
The P_FCANCEL request cannot fail.
WR_FIND_CITY Find by city
INT p_iow(VOID *pcb, WR_FIND_CITY, TEXT *match, WR_FIND_RES *result) ;
Find the first city that matches the string at address match writing the name of the matching city and the
associated country to the WR_FIND_RES struct pointed to by result - the matching is not case sensitive.
The WR_FIND_RES struct is defined as follows:
typedef struct
{
TEXT city [WR_MAX_NAME+1];
TEXT country [WR_MAX_NAME+1];
} WR_FIND_RES;
The significance of the members of the WwR_FIND_RES struct is as follows:
city the name of the matching city expressed as a zero terminated string.
country the name of the associated country expressed as a zero terminated string.
Returns WR_FOUND on success, Or WR_NOT_FOUND otherwise.
WR_FIND_COUNTRY Find by country
INT p_iow(VOID *pcb, WR_FIND_COUNTRY, TEXT *match, WR_FIND_RES *result);
Find the first country that matches the string at address match writing the name of the matching country
and its capital city to the wR_FIND_RES struct pointed to by result - the matching is not case sensitive.
8 SERIES 3 WORLD DATABASE
The wR_FIND_RES Struct is defined as follows:
typedef struct
{
TEXT city [WR_MAX_NAME+1];
TEXT country [WR_MAX_NAME+1];
} WR_FIND_RES;
The significance of the members of the wR_FIND_REs struct is as follows:
city the name of the capital city of the matching country expressed as a zero
terminated string.
country the name of the matching country expressed as a zero terminated string.
Returns wR_FOUND on success, Or WR_NOT_FOUND otherwise.
WR_FIND_EXACT Find by city and country
INT p_iow(VOID *pcb, WR_FIND_EXACT, WR_FIND_RES *match) ;
Find the country that exactly matches the city specified in match->city, or if this is NuLL, the country
specified in match->country - the matching is not case sensitive.
For a description of the wR_FIND_REs Struct, see the above descriptions of the wR_Finp_crTy and
WR_FIND_COUNTRY Services.
Returns wR_FOUND on success, Or WR_NOT_FOUND otherwise.
WR_NEXT Find next city
VOID p_iow(VOID *pcb, WR_NEXT, WR_FIND_RES *result) ;
Write the names of the next city and the associated country, or the next country and its capital city,
depending on the mode, to the wR_FIND_REs struct pointed to by result.
The service is always successful.
WR_BACK Find previous city
VOID p_iow(VOID *pcb, WR_BACK, WR_FIND_RES *result);
Write the name of the previous city and the associated country, or the previous country and its capital city,
depending on the mode, to the wR_FIND_REs struct pointed to by result.
The service is always successful.
WR_GET_HOME Find home city
VOID p_iow(VOID *pcb, WR_GET_HOME, WR_FIND_RES *result);
Write the names of the home city and the associated country to the wR_FIND_REs struct pointed to by
result.
The service is always successful.
WR_SET HOME Set home city
INT p_iow(VOID *pcb, WR_SET_HOME) ;
Set the home city to the current city.
This is a system wide setting.
Returns zero on success, or WR_NOTVALID_ERR if the current city is no longer valid 1.e. the current city has
been deleted.
1/0 DEVICES REFERENCE
WR_GET_DEFAULT_ COUNTRY Find default country
VOID p_iow(VOID *pcb, WR_GET_DEFAULT_COUNTRY, WR_FIND_RES *result);
Write the name of the default country and its capital city to the wR_FIND_RES struct pointed to by result.
Note that the service sets the database to city mode.
The service is always successful.
WR_SET_ DEFAULT COUNTRY Set default country
INT p_iow(VOID *pcb, WR_SET_DEFAULT_COUNTRY) ;
Set the default country current country to the current country.
Note that the service sets the database to country mode.
Returns zero on success, Or E_GEN_UNDER if the current city is no longer valid i.e. the current country has
been deleted.
WR_GET_DIAL_STRING Get dial string
INT p_iow(VOID *pcb, WR_GET_DIAL_STRING, TEXT *inString, TEXT *outString);
Convert the string pointed to by inst ring into a dial string, written to the buffer pointed to by out string.
The output string may be played using the sound device: for futher details of tone dialling see the Sound
chapter of the I/O Devices Reference manual.
During the conversion, both spaces and hyphens are removed, but commas are left unchanged. A full stop
is interpreted as marking the end of the input string. For the significance of commas see the Sound
chapter of the //O Devices Reference manual. As an example, 0-171,123 4567.89 would be converted to
0171,1234567.
Returns zero on success, otherwise one of the following negative error codes:
E_GEN_ARG either the input string includes only one square bracket, or the country
specified in square brackets does not match a country in the database.
E_GEN_OVER at some stage in the conversion, the output string exceeded the maximum
allowed length of wR_MaAx_DIAL_STRING characters.
The conversion is illustrated by the following examples:
009 44 171 234 5678
009 is an international access code which indicates that an international call is being made. The example
international access code is that of Denmark. In the United Kingdom the international access code is 001.
44 is a country code which indicates the destination country. The example country code is that of the
United Kingdom.
171 is an area code - in this case it is the Inner London code.
234 5678 is the local telephone number.
For this example the service simply outputs 009441712345678.
009 44 (0) 171 234 5678
(0) is the national prefix and is enclosed in brackets to indicate that it is not required for international
calls.
the other components are as described above.
the output string is 009441712345678. In this case the number corresponds to calling London from
Denmark.
+44 171 234 5678
+ is an abbreviation for the international access code.
44 is the country code for the United Kingdom.
171 is the area code.
234 5678 is the local number.
8-4
8 SERIES 3 WORLD DATABASE
the interpretation of the string depends on the home country. When this is Denmark, the service replaces
the plus character with the international access code of Denmark giving 009441712345678. On the other
hand, when the home country is the United Kingdom, the plus character and the country code are replaced
with the national prefix and the output string is 01712345678.
171 234 5678 [United Kingdom]
171 is the area code.
234 5678 is the local number.
[United Kingdom] is a convenient means of specifying the destination country: note the space between the
last digit and the first bracket and that the country is specified in full.
When the home country is Denmark, the output string is 009441712345678.
When the home country is the United Kingdom, the output string is 01712345678.
0 171 234 5678
0 is the national prefix - sometimes referred to as the STD prefix - and is omitted on international calls.
the output string is 0171 234 5678.
WR_SET_EXTRA Open file for additional data
INT p_iow(VOID *pcb, WR_SET_EXTRA, WORD *flag, TEXT *name) ;
Open a file to store extra cities where name should point to the full file specification stored as a zero
terminated string and f1ag should always be set to p_FoPEN.
The filename is parsed with an extension of . wip.
The service will fail if the file does not exist.
Returns zero on success, otherwise £_GEN_1macE if the file is either badly formatted, or has a different
database version number, or a system error code.
WR_EXTRA Modify additional data
INT p_iow(VOID *pcb, WR_EXTRA, WORD *func, WR_EXTRA_DATA *data);
Add, update or delete database entries in the file opened by the earlier wR_sET_ExTRa call.
The service assumes that an extra World database file has been opened using the wR_sET_EXTRA Service.
The func argument may take one of the following values:
WR_EXTRA_ADD_CITY specifies that a city should be added to the World database - the data is read
from the wR_EXTRA_DATA union pointed to by data. The city must be in an
existing country.
The wR_EXTRA_DATA union is defined as follows:
typedef union
{
WR_CITY_DATA ci;
WR_COUNTRY_DATA co;
} WR_EXTRA_DATA;
For further details of the wr_crTy_pata struct, see the description of the
WR_GET_CITY_DATA service.
WR_EXTRA_UPDATE_CITY specifies that a city in the World database should be updated - the new data is
read from the wR_EXTRA_DATA union pointed to by data. The city must be in an
existing country.
For details of the wR_ExTRA_DATA union see above. For details of the
WR_COUNTRY_DATA Struct see the description of the wR_GET_COUNTRY_DATA
service.
I/O DEVICES REFERENCE
WR_EXTRA_DELETE_CITY delete a city in the extra database file - the name of the city and the name of
the country are read from the wR_EXTRA_DATA union pointed to by data.
WR_EXTRA_UPDATE_COUNTRY — update a country in the World database - the data associated with the country is
read from the WR_EXTRA_DATA union pointed to by data. Renaming a country
does not delete or otherwise modify the member countries
On success, the service returns either zero or one of the following values:
WR_REVERTED the city has reverted to its original built-in data.
WR_DELETED the city has been deleted.
Otherwise the service returns a negative error code which includes the following:
E_GEN_ARG tried to update a non-existent country, or specified a non-existent city as the
capital of a country.
WR_TOO_MANY_ERR attempted to exceed the maximum allowed number of items in the extra World
database file. The maximum number of allowed items is 32.
WR_DUPLICATE_ERR the new name for a city/country matches an already existing name.
WR_NOT_VALID attempted to delete a built-in city.
WR_DELHOME_ERR attempted to delete the home city.
WR_DEL_CAPITAL_ERR attempted to delete a capital city.
WR_GET_ CITY DATA Read city data
INT p_iow(VOID *pcb, WR_GET_CITY_DATA, WR_CITY_DATA *result);
Write data associated with the current city to the wR_cITy_pata struct pointed to by result.
The wR_c1tTy_pata struct is defined as follows:
typedef struct
{
WR_FIND_RES f;
UBYTE units;
UBYTE DST;
WORD GMT;
LATL latl;
TEXT dial [WR_MAX_DIAL+1];
TEXT STD[WR_MAX_CODE+1];
P_POINT pos;
} WR_CITY_DATA;
The members of the wR_cr1Ty_pata struct have the following significance:
£ the names of the current city and the associated country: for further details see
the description of the WwR_FIND_CITY service.
units may be one of the following values:
WR_UNITS_MILES the units of distance are to be miles.
WR_UNITS_KILOMETERS the units of distance are to be kilometers.
WR_UNITS_NAUTICAL the units of distance are to be nautical miles.
DST may be one of the following values:
0x00 the daylight saving time is to be constant.
0x02 the daylight saving time is to be European.
0x04 the daylight saving time is to be American.
0x08 the daylight saving time is to be Southern.
8 SERIES 3 WORLD DATABASE
GMT the local time - this is expressed as a deviation from Greenwich Mean Time in
units of minutes.
latl the Lat struct is defined as follows:
typedef struct
{
WORD iLat;
WORD iLong;
} LATL;
the iat member gives the latitude of the city in units of minutes of arc.
Positive values correspond to northern latitudes.
the iLtong member gives the longitude of the city in units of minutes of arc.
Positive values correspond to western longitudes.
dial the city dialling code - stored as a zero terminated string.
STD the city area code - stored as a zero terminated string.
pos the coordinates of the city on the World map: used, for example, by the World
application.
Returns zero on success, otherwise WR_NOTVALID_ERR if the item is no longer valid, for example, if the
current city has been deleted or renamed.
WR_GET_COUNTRY_DATA Read city data
INT p_iow(VOID *pcb, WR_GET_COUNTRY_DATA, WR_CITY_DATA *result);
Write the data for the current country to the wR_counTRY_pata Struct pointed to by result.
The wR_countRy_pata struct is defined as follows:
typedef struct
{
WR_FIND_RES f;
UBYTE baseGMT;
UBYTE DST;
WORD GMT;
CO_DIAL dial;
} WR_COUNTRY_DATA;
The members of the wR_counrry_para struct have the following significance:
£ contains the names of the current country and the associated capital city: for
further details see the description of the wR_FIND_COUNTRY Service.
baseGMT reserved for internal use.
DST may be one of the following values:
0x00 the daylight saving time is to be constant.
0x02 the daylight saving time is to be European.
0x04 the daylight saving time is to be American.
oxos the daylight saving time is to be Southern.
GMT the local time - this is expressed as the deviation from Greenwich Mean Time
in units of minutes.
dial the country dialling code information (see below).
The co_prat struct is defined as follows:
typedef struct
{
TEXT dialIntra[WR_MAX_INTRA+1];
TEXT dialInter [WR_MAX_INTER+1];
TEXT dial [WR_MAX_CODE+1;
UBYTE dummy;
} CO_DIAL;
1/0 DEVICES REFERENCE
The significant members of the co_p1at struct have the following meaning:
dialintra a zero terminated string of up to four digits, containing the national dialling
prefix.
dialiInter a zero terminated string of up to four digits, containing the international
dialling prefix.
dial a zero terminated string of up to eight digits, containing the national code.
Returns zero on success, otherwise WR_NOTVALID_ERR indicating that the current country is no longer
valid, for example, if the current country has been renamed.
WR_CALC Calculate distance, sunrise and sunset
VOID p_ioc(VOID *pcb, WR_CALC, WORD *pstat, WORD *state, WR_CALC_DATA *calc);
INT p_iow(VOID *pcb, WR_CALC, WORD *state, WR_CALC_DATA *calc);
Obtain the distance of the target city from the home city and the local sunrise and sunset times.
The calculation proceeds in stages in order that it may be discontinued as and when required.
The first time the wR_catc service is called, *state must be set to WR_START_STATE. The service should
then be repeatedly called until *st ate is equal to WR_END_STATE indicating that the calculation is
complete.
The wR_cALc_paArTa struct is defined as follows:
typedef struct
{
WR_CITY_DATA in;
WR_CALC_OUT out;
} WR_CALC_DATA;
The members of the wR_catc_pata struct have the following significance:
in specifies the data for the target city: for further details of the wR_cITy_paTa
struct see the description of the wR_GET_CITY_DATA service.
out the result of the calculation: the wR_caLc_out struct is defined as follows:
typedef struct
{
WORD distance;
WORD sunRise;
WORD sunSet;
WORD always;
} WR_CALC_OUT
the distance member specifies the distance from the home city in the
specified units.
the sunRise member specifies the time of sunrise - this is a local time in units
of minutes.
the sunSet member specifies the time of sunset - this is a local time in units of
minutes.
the always member specifies whether the city is always dark (-1), always light
(1) or neither (0).
The completion status code is returned by the synchronous p_iow and written to *pstat by the
asynchronous p_ioc.
The completion status code is zero if the request completed successfully, otherwise a negative error code.
8 SERIES 3 WORLD DATABASE
WR_NEXT_ LOCK Read next city name
INT p_iow(VOID *pcb, WR_NEXT_LOCK, WR_FIND_RES *result);
Writes the name of the next city as a zero terminated string to the city member of the wR_FIND_REs struct
pointed to by result.
The name of the associated country is also written to the country member of the wR_FIND_REs struct
pointed to by result.
Returns zero on success, otherwise a negative error.
World file types and their locations
This section gives a summary of the file structures used by the World Server. The main bulk of the data is
stored using a complex compression algorithm. This cannot be duplicated realistically by a third party
developer, and the functionality is available through the World Server device driver, so it is not given in
detail.
Main World file
The main World database file is stored in the ROM. For a single-language ROM it is:
ROM::WORLD.DAT
For a multi-lingual ROM is:
ROM::WORLD._<lang>
where lang is the language number selected as returned by p_get language, formatted as a 2-digit number,
left-filled with 0 if the language number is <10.
For English the filename of the World file in a multi-lingual ROM is ROM::WORLD.DAT. In a multi-
lingual ROM you are obviously going to have a number of such World files.
World Extension file
Users by default get an extension file World.dat created, but they can make their own world extension
files with different names. These files contain changes to the main data (city additions and changes, and
country changes), which the World Server reads to override the main world database file.
World File format
First 2 bytes The World file variant signature. This is a scrambled combination of the file version
and language. (Each language can have up to 15 versions; these correspond to new
releases.)
Next 30 bytes 15 two-byte table pointers. These point to tables, or key positions within tables
Remaining data Various tables, including a decode table, because all the data following is encoded.
I/O DEVICES REFERENCE
World Extension File format
File header
A World Extension File has a header of 32 bytes:
First 16 bytes World Extension File signature worldFileType**<0x0>
17-18th bytes World file variant signature. On creation is copied from the main database file. Files
which are opened which do not match the main database file are rejected.
19-20th bytes Unsigned WORD containing size of extra data block
21st-32nd bytes Not used, filled with oxo bytes
Data block
The extra data block follows, which is a string of leading byte count data blocks. Each contains either
city or country alteration information. With the Series 3a and its newer brothers, there is a limit on the
number of blocks to 32 (excluding the final, empty, field). This data block is at least one byte long
(0x0, i.e. a leading byte count list terminator).
CHAPTER 9
XMODEM AND YMODEM
Introduction
All Psion SIBO machines include an Xmodem/Ymodem device driver which implements the industry
standard Xmodem and Ymodem data transfer protocols. Only the data transfer protocols are implemented.
The applications perform the required file I/O.
The Psion SIBO Xmodem/Ymodem device driver is attached to a lower level driver which must support
the services provided by the Psion SIBO serial device driver. As it is an attached driver it can run over any
serial channel without modification.
There are numerous variations of both the Xmodem and the Ymodem protocols. The following are
supported:
e Xmodem Checksum
e Xmodem CRC
e Xmodem CRC (1K)
e Ymodem
e Ymodem (1K)
e Ymodem-G
e Ymodem-G (1K)
I _
Data transfer protocols overview
The Xmodem and Ymodem protocols were established to allow two way error correcting data transfers
between remote computers. The protocols define the data as a series of data blocks each of which is
transmitted with a check for data corruption (a few other bytes are also added - see later sections). The
Xmodem/Y modem device driver supports either a one byte checksum or a two byte CRC data integrity
check.
One byte checksum
The one byte checksum is the sum of the bytes in the data block with the carries discarded. A one byte
checksum is not as reliable an integrity check as a two byte CRC.
Two byte Cyclic Redundancy Check (CRC)
The two byte CRC is the remainder after the datablock (treated as a large binary number) is divided by a
sixteen bit number. The supplied device driver uses the CRC sixteen bit divisor recommended by the
CCITT (in polynomial form this is x!° + x!? + x> + 1). The reader should be aware that other CRCs are
also in widespread use (the CRC-16 polynomial for example).
I/O DEVICES REFERENCE
The Xmodem protocol
The Xmodem data transfer protocol was developed in the late seventies as a 'quick hack' for transferring
data between dissimilar machines. It was written on and for machines that had eight bit UARTS
(Universal Asynchronous Receivers and Transmitters) and is thus an eight bit data transfer protocol.
The protocol is very simple and thus easy to port to other machines. This and the fact that the original
implementation was placed in the public domain very early in its life has meant that the Xmodem protocol
has become a defacto industry standard data transfer protocol.
The protocol lacks many features considered mandatory in modern data transfer protocols including full
duplex transfer and windowing. Worse still it is not robust: corruption of acknowledgement characters or
the data frame header characters can fool the protocol into adopting the wrong state.
The file transfer facilities provided by applications that use the protocol simply send the body of the file as
data in data frames. Since the protocol was originally developed on CP/M machines, text files should
consist of lines of printable ASCII terminated by the CRLF (0x0d 0x0a) character sequence, with the file
terminated with the SUB (0x1a) character. It is the responsibility of the application to perform the
required file translation. The SIBO filing system allows text files to be opened in 'stream' mode (i.e. as a
constant data stream with each text record delimited by CRLF characters), see the P_FSTREAM_TEXT
section within the Files chapter of the PLIB Reference Manual. The local filing system of machines in the
SIBO range store data in the same format as MSDOS. Thus a text file can be opened using the P_FsTREAM
mode and still present CRLF delimited data. However a remote filing system, that of the Macintosh for
example, would not necessarily store data in the same format.
Binary files can be transferred with the Xmodem protocol. In this case no format is implied. All the data
should be written to file as it is presented in the Xmodem data frames.
Link establishment
The Xmodem protocol does not define a distinct link establishment phase. The sender of the data waits for
a link establishment character (NAK) and then sends the first data frame. When the first data frame is
received the link is established and both sides are in the data transfer phase.
If the sender (receiver) does not receive the expected NAK character (data frame) within a reasonable time
(two minutes for example) it should quit. The receiver will continue sending NAK characters at regular
intervals until either the first data frame is received or the allowed time period has elapsed.
The data transfer phase
The sender transmits a series of Xmodem Checksum data frames. These consist of:
SOH the start of header character (0x01).
Block number a one byte binary number labelling each data block. The number wraps to zero
at Oxff.
oxff - block number the one's complement of the block number. This validates the block number.
Data block a block of 128 data bytes.
One byte checksum the sum of the data bytes with the carrys discarded.
Each frame must contain exactly 132 bytes. Thus when there is insufficient data to fill the data block
padding must be added. Typically the padding consists of end of file (SUB) characters, although NULL
characters would probably be better when sending binary files.
If the data and the block number have not been corrupted the receiver will send a positive
acknowledgement character (ACK) requesting the sender to transmit the next data frame. Otherwise the
receiver will transmit a negative acknowledgement character (NAK) requesting the sender to retransmit
the previous (corrupted) data frame.
Link termination
An Xmodem link termination phase does not exist separately to the data transfer phase. When the last
data frame has been transmitted the sender transmits a one byte EOT character that informs the receiver
that there is no more data. The receiver should acknowledge this in the same way that a normal data
frame is acknowledged, that is with either ACK or NAK characters. Once successfully acknowledged the
link has terminated.
9-2
9 XMODEM AND YMODEM
Checksum data flow showing error recovery
Sender Receiver
NAK
<timeout>
NAK
SOH,0x01,0xFE,<128bytes>,CHK
NAK
SOH,0x01,0xFE,<128bytes>,CHK
ACK
SOH,0x02,0xFp,<128bytes>,CHK
ACK
SOH,0x03,0xFc,<128bytes>,CHK
<timeout>
SOH,0x03,0xFc,<128bytes>,CHK
ACK
EOT
NAK
EOT
ACK
The CRC variant
Xmodem CRC differs from the Xmodem Checksum protocol only in the data integrity check and the link
establishment character.
The Xmodem CRC protocol data frames include a two byte CRC data integrity check (with the high byte
being sent before the low byte) in place of the one byte checksum. This gives an improved data integrity
check at the expense of an extra byte of non-data - data frames are thus 133 bytes long. The PLIB function
p_crce will generate the required CRC.
The receiver establishes an Xmodem CRC link by sending a C (0x43) link establishment character. The
link establishment will fail if the sender does not support the CRC mode.
CRC data flow showing error recovery
Sender Receiver
C
<timeout>
Cc
SOH, 0x01,0xFE,<128 bytes>,CRCHI,CRCLO
ACK
SOH,0x02,0xFD,<128 bytes>,CRCHI,CRCLO
NAK
SOH,0x02,0xFpD,<128 bytes>,CRCHI,CRCLO
<timeout>
SOH,0x02,0xFD,<128 bytes>,CRCHI,CRCLO
ACK
EOT
ACK
The 1K variant
The 1K variant allows the sender to transmit 1024 bytes of data per data frame. Each 1K data frame starts
with an STX character (not an SOH character) and is otherwise identical to an Xmodem CRC data frame.
The link establishment, data transmission and link termination phases are the same as for the Xmodem
CRC protocol.
The 1K option allows 1024 byte data frames to be intermixed with 128 byte data frames, with the
restriction that a retransmitted frame must be the same size as the originally transmitted frame.
1K data frames are more sensitive to corruption (remember that the whole data block is destroyed by the
corruption of only one data byte). Thus 1K protocols should not be used when the transmission line is
noisy.
The 1K Xmodem variant supports only a two byte CRC data integrity check. It is inadvisable to use a one
byte checksum with 1K data frames and this option is not supported by the supplied driver.
I/O DEVICES REFERENCE
The 1K option data flow
Sender Receiver
C
STX,0x01,0xFE,<1024 bytes>,CRCHI,CRCLO
ACK
STX,0x02,0xFD,<1024 bytes>,CRCHI,CRCLO
NAK
STX,0x02,0xFD,<1024 bytes>,CRCHI,CRCLO
<timeout>
STX,0x02,0xFD,<1024 bytes>,CRCHI,CRCLO
ACK
SOH,0x03,0xFc,<128 bytes>,CRCHI,CRCLO
ACK
STX,0x04,0xFB,<1024 bytes>,CRCHI,CRCLO
ACK
EOT
ACK
Abandoning a transfer
The Xmodem specification does not explicitly provide for abandoning a data transfer session. In practice
various implementations will request link abandonment by sending a series of CAN (0x18) characters.
This method does not work well when the sender is currently transmitting a data frame. The safest option
is to continue sending the data frame and afterwards transmit the CAN characters. For a high quality
interface this alternative implies an unacceptable wait (for the 1K protocol with a 1200 baud transmission
rate the wait would be about eight seconds). The second alternative is to quit data frame transmission
immediately and send a series of CAN characters (which could be misinterpreted as belonging to the
abandoned data frame). Even if the receiver misinterprets some CAN characters the session will
eventually be abandoned.
When sending data the supplied driver will simply stop transmitting the current data frame and send a
CAN character immediately.
When receiving data the supplied driver will send a CAN character.
If a CAN character is received by the driver (except as part of a data frame) it will fail any outstanding
request with the E_FILE_CANCEL completion status.
The Ymodem protocol
The Ymodem protocol was developed from the realisation that the Xmodem protocol has several
weaknesses:
e Only one file can be transferred per command. The file name must be entered at both ends of the
link implying that the user has direct or indirect access to both computers (in addition to the
Xmodem link).
e The transferred files can contain up to 127 (or even 1023) useless bytes. These are added to pad
out the last data block.
e The time and date that the file was last modified are lost.
Some of the other weaknesses of the original specification had already been resolved by developing
variants of the Xmodem protocol. These variants (discussed in the previous section) allow for a more
sophisticated data integrity check (the CRC variant) and larger data frames (the 1K variant).
The three weaknesses in the above list are all concerned with file transfer rather than data transfer. Unlike
Xmodem, the Ymodem protocol is specifically designed for file transfer.
The Ymodem protocol does not attempt to overcome problems with or enhance the actual data flow
protocol. Thus Ymodem is subject to the same data corruption problems as Xmodem.
All Ymodem variants use CRCs.
9 XMODEM AND YMODEM
Link establishment
The Link establishment phase is identical to that for Xmodem CRC except that the first data frame
transmitted has a block number of zero rather than one. This block contains file information as follows:
e A zero terminated name. This is either the fully specified path name for the file to be transferred
or (more commonly) the file name with no path specified. In either case the name must be
acceptable to both the sender's and receiver's filing systems (in general machines that have
different filing systems will accept only the file name). This field is mandatory.
e = The file length. This is stored as a sequence of decimal digits immediately following the zero
terminated name. The receiver may use the file length to set the end of file position at the end of
the transfer. If further fields are present the file length must be present. If there are no further
fields the file length is optional.
e = The file modification date. This is stored as a sequence of octal digits specifying the time at
which the file was last modified in seconds from 00:00:00, January 1, 1970 (Unix time). A
single space character separates the file modification date from the file length. If further fields
are present the file modification date must be present. If there are no further fields the file
modification date is optional.
e The mode. This is stored as a sequence of octal digits and specifies the file mode. Unless the file
was sent from a Unix machine the mode is set to zero. Files sent from Unix machines that have
the mode set to 0x8000 are assumed to be a Unix type regular file. The mode field is separated
from the file modification date by a single space character. If further fields are present the mode
must be present. If there are no further fields the mode is optional.
e Serial number. This is stored as a sequence of octal digits and specifies the serial number of the
sender's software. The receiver's use of this number is optional. The serial number field is
separated from the mode field by a single space character. This field is optional.
All undefined fields, and the remaining bytes of the data frame, should be set to zero to allow for future
compatibility.
The following code fragment generates the first data frame containing the required Ymodem information
for filename, length and modification date.
p_bfil(&buf[0],128,0);
p_finfo(pFilename, &info) ;
p=p_scpy (&buf[0],pFilename) +1;
pt=p_gltob(p,info.size,10);
*ptt=" ';
pt=p_gltob(p,info.modst, 8);
When the first frame arrives the receiver should attempt to open the specified file. If the open request is
successful the receiver should send back an ACK to continue with the transfer, otherwise a CAN to cancel
the transfer.
When there are no more files to transfer the link connection should be re-established with a zero length
file name, after which the batch file transfer ends.
The data transfer phase
The data transfer phase is identical to the Xmodem CRC data transfer phase.
Link termination
The Ymodem file transfer termination phase does not exist separately from the data transfer phase. When
the file has been transmitted a one byte EOT character is sent to the receiver. The receiver should
acknowledge this in the same way that a normal data frame is acknowledged using either ACK or NAK
characters. The transfer of the file is now complete. When one or more additional files are to be sent the
sender must reestablish a link with the receiver and send the next file in exactly the same manner. When
all files have been sent the sender must send an initial (block number zero) data frame containing a zero
length file name.
I/O DEVICES REFERENCE
Ymodenm file transfer data flow
Sender Receiver
C
SOH, 0x00,0xFF,<filename,len...>,CRCHI,CRCLO
ACK
SOH,0x01,0xFE,<128bytes>,CRCHI,CRCLO
ACK
SOH,0x02,0xFD,<128bytes>,CRCHI,CRCLO
ACK
EOT
ACK
C
SOH,0x00,0xf£,<file name,len...>,CRCHI,CRCLO
ACK
SOH,0x01,0xFE,<128bytes>,CRCHI,CRCLO
ACK
SOH,0x02,0xFD,<128bytes>,CRCHI,CRCLO
ACK
EOT
ACK
C
SOH,0x00,0xf£,<null file name>,CRCHI,CRCLO
ACK
The 1K variant
The 1K variant allows the sender to transmit 1024 bytes of data per frame. The 1K variant data frames are
identical to Xmodem 1K data frames (with the exception of the first frame as discussed earlier).
The G variant
The Ymodem-G protocol does not have any specified way of reporting an error to the sender, or more
specifically of requesting a re-transmission of a broken data frame. The only advantages over straight
ASCII transfer is that the receiver can detect errors (although nothing can be done about them) and
multiple files can be transferred. The design philosophy seems to have been that error correcting modems
guarantee that the files are not corrupted during transfer and that the inclusion of software error corection
severely reduces the modem's throughput. However error correcting modems only ensure that the data is
not corrupted during the transfer from one modem to another.They do not check for corruption of the data
while it is being sent from the computer to the modem, and vice versa. A typical problem can occur with
PCs connected to networks where some network software insists on disabling interrupts for extended
periods of time, certainly long enough to get serial overrun errors. The Ymodem-G protocol is highly
susceptible to such errors.
A Ymodem-G link is established by the receiver sending a G (0x47) character.
The Ymodem-G protocol only has acknowledgement characters after the first data frame (indicating that
the file was successfully opened) and after the EOT character (indicating that the file was successfully
closed).
The supplied device driver will send a CAN character if an error was detected while in Ymodem-G mode.
This will typically abort the entire transfer.
9 XMODEM AND YMODEM
Ymodem.-G file transfer data flow
Sender Receiver
G
SOH, 0x00,0xFr,<filename,len...>,CRCHI,CRCLO
G
SOH,0x01,0xFE,<128bytes>,CRCHI,CRCLO
SOH,0x02,0xFp,<128bytes>,CRCHI,CRCLO
EOT
ACK
G
SOH,0x00,0xf£,<file name,len...>,CRCHI,CRCLO
G
SOH,0x01,0xFE,<128bytes>,CRCHI,CRCLO
SOH,0x02,0xFpD,<128bytes>,CRCHI,CRCLO
EOT
ACK
G
SOH,o0x00,0xf£,<null file name>,CRCHI,CRCLO
Abandoning a transfer
The Ymodem specification does not explicitly provide for abandoning a data transfer session. Various
implementations will send CAN (0x18) characters in an attempt to inform the remote computer that the
data transfer session should be abandoned.
When sending data the supplied driver will simply stop transmitting the current data frame and send a
CAN character immediately.
When receiving data the supplied driver will send a CAN character.
If a CAN character is received by the driver (except as part of a data frame) it will fail any outstanding
request with the E_FILE_CANCEL completion status.
Protocol problems
The primary task of any data transfer protocol is to ensure that the data sent is the same as the data
received. If the physical media being used could not corrupt the data then ASCII file transfer would be
ideal since no overheads are required in validating the data.
Although the Xmodem and Ymodem protocols address the majority of problems concerned various holes
in the error recovery have been pointed out. For example:
e Synchronisation will be lost if the NAK character sent by the receiver is corrupted to an ACK
character. The transfer will thus fail.
e = The use of different link establishment and acknowledgement characters for Xmodem, Ymodem
and Ymodem-G protocols can lead to confusion if the character is corrupted. For example, the
Ymodem protocol attempts to establish the link by sending a C character. Corruption of the
C to aG would fool the receiver into connecting in Ymodem-G mode.
e The use of anonymous acknowledgement characters for requesting data frame (re)transmission
can cause timing problems. For example, consider a receiver that sends an ACK or NAK
character requesting transmission of a data frame and finds that the sender is preoccupied. The
protocol allows for the receiver to wait for a specified time interval and then send another ACK
or NAK character. This will work fine unless the sender replies after transmission of the second
ACK or NAK character, and before its receipt. In this case the receiver will assume that the
transmitted data frame corresponds to the second ACK or NAK character and thus
synchronisation will be lost.
In actual field usage the Xmodem and Ymodem protocols perform more than adequately.
I/O DEVICES REFERENCE
ee en
Xmodem/Ymodem services
p_open(XMD:) Open an Xmodem/Ymodem channel
INT p_open(VOID **ppXmodem, "XMD:", —-1);
Attach the Xmodem/Ymodem driver to the open channel specified by ppxmodem. All I/O requests on that
channel will now be routed to the Xmodem/Ymodem device driver.
The passed channel is assumed to support the set of services provided by the serial driver. Currently only
the try: driver supports the serial services.
For example:
VOID *pcb;
if (!p_open(&pcb, "TTY:A",-1) )
{
if (!p_open(&pcb, "XMD:",-1) )
{
p_close (pcb);
}
p_close (pcb)
}
Note that two calls to p_close are required, one to close the channel to the Xmodem/Ymodem driver and
the second to close the channel to the serial driver.
The Xmodem/Ymodem driver senses the current serial driver's characteristics, removes any XON/XOFF
handshaking, sets the terminator mask to zero and sets the framing to eight bits, no parity and one stop
bit. The original serial characteristics are restored when the driver is closed.
Once a channel to the Xmodem/Ymodem driver has been opened, the application must connect to the
computer at the remote end. This done with the p_FconNECT service.
The calling process will be panicked if the serial driver to which the Xmodem/Ymodem driver is attached
has any outstanding requests on it.
Returns zero if the request completed successfully otherwise a negative error number.
p_close Close the Xmodem channel
INT p_close(VOID *pXmodem) ;
Close the Xmodem channel specified by pXmodem. The device driver should be closed when the file
transfer has completed. All I/O requests on the driver channel will then be routed to the underlying serial
driver.
Every outstanding request on the Xmodem/Ymodem driver will be completed, its completion status word
will be set to E_FILE_CANCEL and a signal will be generated.
The characteristics of the serial driver are restored to the values held before the Xmodem/Ymodem driver
was opened.
The p_FCLOSE request cannot fail and returns zero.
P_FCONNECT Connect to the remote computer
VOID p_ioc(VOID *pXmodem, P_FCONNECT, WORD *pstat, UWORD &type, UWORD &mode) ;
INT p_iow(VOID *pXmodem, P_FCONNECT, UWORD &type, UWORD &mode) ;
Obtain a connection to a computer assumed to be running some Xmodem/Ymodem software.
The connection type can be established as one of:
@ =P_XMDM_ACCP
e P_XMDM_INIT
9-8
9 XMODEM AND YMODEM
where p_xmpmM_accp would be used to accept a connection (the application wishes to transmit a file or
files) and p_xmpM_1nrtT would be used to initiate the connection (the application wishes to receive a file or
files).
The connection mode determines the file transfer mode and can be one of:
P_XMDM_CRCORCHECKSuUM _ the connection should be established in either Xmodem checksum or Xmodem
CRC mode depending on which mode is supported by the remote computer.
The driver has a bias towards CRC mode. When transmitting connection
request characters it sends two CRC connection request characters (C,0x43) to
every checksum connection request character (NAK,0x15). When accepting a
connection it will throw away the first NAK character it receives while waiting
for a potential C character.
P_XMDM_CHECKSUMMODE the connection should be established in Xmodem checksum mode only. This
will connect to a remote computer that is using checksum mode faster than the
P_XMDM_CRCORCHECKSUM option. (If the remote computer is trying to establish a
connection in CRC mode a connection will still be established. This fact will
be reported to the caller.)
P_XMDM_CRCMODE the connection should be established in Xmodem CRC mode only. If the
remote computer does not support CRC mode no connection will be
established.
P_YMODEM_MODE the connection should be established using the Ymodem batch protocol.
P_YMODEM_G_MODE the connection should be established using the Ymodem-G batch protocol.
As an option on any of the protocols that support CRC error checking (Xmodem CRC and all the
Ymodem variants) the p_xmpM_onz_x flag can be ored into mode to indicate that data frames of size 1K
can be transmitted and received.
For example:
mode=P_XMDM_CRCMODE | P_XMDM_ONE_K;
When this flag is not set the Xmodem/Ymodem driver will refuse to accept 1K data frames and will
instead reply with NAK characters. This will eventually cause the data transfer to fail.
When a connection cannot be established, the reason for the failure will be written back to the completion
status word.
If the connection is successfully established the completion status word will contain zero and the actual
connection mode will be written back to mode.
For example:
type=P_XMDM_INIT;
mode=P_XMDM_CRCORCHECKSUM;
if (!p_iow(pXmodem, P_FCONNECT, &type, &mode) )
{
if (mode==P_XMDM_CRCMODE)
p_puts ("CRC mode")
else if (mode==P_XMDM_CHECKSUMMODE)
p_puts ("Checksum mode")
}
Note that the data space for mode must be preserved until the connection request completes.
In general the connection request will take an extended time. Thus the request should be made
asynchronously. The connection request can be cancelled with the p_FDISCONNECT service.
If the p_FconnEcT request was started successfully the I/O request returns either zero or a negative error
number.
The completion status word is returned by the synchronous p_iow request and written to *pstat by the
asynchronous p_ioc request. It is set to =_FILE_PENDING while the request is outstanding and zero on
successful completion. If the request fails to complete it is set to a negative error number.
The calling process will be panicked if there is an outstanding p_rcoNnNECcT request.
I/O DEVICES REFERENCE
Examples
To receive files using the Xmodem-CRC 1K protocol:
type=P_XMDM_INIT;
mode=P_XMDM_CRCMODE | P_XMDM_ONE_K;
if (!p_iow(pXmodem, P_FCONNECT, &type, &mode) )
{
}
To send files using the Ymodem batch protocol:
type=P_XMDM_ACCP;
mode=P_YMODEM_MODE;
if (!p_iow(pXmodem, P_FCONNECT, &type, &mode) )
{
}
To send files using the Ymodem-G 1K batch protocol:
type=P_XMDM_ACCP;
mode=P_YMODEM_G MODE |P XMYM_ONE_K;
if (!p_iow(pXmodem, P_FCONNECT, &type, &mode) )
{
P_FDISCONNECT Disconnect from the remote
INT p_iow(VOID *pXmodem, P_FDISCONNECT) ;
Disconnect from the remote computer.
The P_FDISCONNECT request can also be used to abandon the Xmodem/Ymodem session during the
connection establishment or data transfer phases.
If a connection has already been established then the p_rp1IscoNnNEcT request will cause a CAN character
to be transmitted to the remote computer. This may or may not be picked up by the remote
Xmodem/Ymodem implementation to indicate that the data transfer phase is being abandoned. The
Xmodem/Ymodem protocols do not have any standard mechanism for abandoning data transfer.
If no connection has been established yet, or if the transfer is now complete, no characters will be
transmitted to the remote computer.
Any outstanding asynchronous requests will be cancelled by the p_FpIsconnEcT request, and their
completion status words set to E_FILE_CANCEL. For each outstanding request a signal will be generated
and must be used up by the application.
Typically the p_FDISCONNECT request would be called synchronously.
The P_FDISCONNECT request can not fail and returns zero.
Example
type=P_XMDM_INIT;
mode=P_XMDM_CRCORCHECKSUM;
p_ioc (pXmodem, P_FCONNECT, &xStat, &type, &mode) ;
p_ioc(pConsole, P_FREAD, &kStat, &kbr) ;
p_iowait();
if (xStat!=E_FILE_PENDING)
{ /* Xmodem connect completed */
}
else
{ /* key press occurred - cancel P_FCONNECT */
p_iow (pXmodem, P_FDISCONNECT) ;
p_waitstat (&xStat);
9 XMODEM AND YMODEM
P_FREAD Read data from the remote computer
VOID p_ioc(VOID *pXmodem, P_FREAD, WORD *pstat, UBYTE *buffer, UWORD *plen)j;
INT p_iow(VOID *pXmodem, P_FREAD, UBYTE *buffer, UWORD *plen);
Read data from the remote computer. If the connection was not established with a type of p_xmpm_rntT the
request will fail with the negative error E_FILE_DISc.
When data is available it will be written to the buffer pointed to by buffer and the length of the data will
be written to *plen.
When the end of data indicator (EOT) from the remote computer is received the p_rreap request will be
completed with the (negative) z_F1ILE_zoF error number.
The application is responsible for supplying a buffer large enough to hold the largest data frame that can
arrive. If the p_xmpM_onz_k mode flag was set in the p_rconnecT request this is 1024 bytes otherwise it is
128 bytes.
If the Ymodem protocols are being used the first data frame read will contain the Ymodem file
information.
If the p_rREAD request was started successfully the synchronous I/O request returns zero otherwise it
returns a negative error number.
Whilst an asynchronous P_FREAD request is outstanding the completion status word is set to
E_FILE_PENDING. On completion the status word is set to zero if the read request completed successfully
otherwise a negative error number. In particular the completion code is set to E_F1LE_zoF if there is no
more data to read.
The calling process will be panicked if there is an outstanding p_rREapD request.
Examples
Receiving multiple files using the Ymodem protocol:
type=P_XMDM_INIT;
mode=P_YMODEM_G_MODE;
FOREVER
{
if (ret=p_iow(pXmodem, P_FCONNECT, &type, &mode) )
break;
if (ret=p_iow(pXmodem, P_FREAD, &fileinfo[0],élen) )
break;
if (!p_slen(&fileinfo[0]))
{ /* finished multi-file receive */
ret=0;
break;
}
p_open (&pFile, &fileinfo[0],P_FUPDATE|P_FSTREAM|P_FREPLACE) ;
while (! (ret=p_iow(pXmodem, P_FREAD, &buf[0],&len) ) )
{
if (ret=p_write (pFile, ébuf[0],1len) )
break;
}
if (ret==E_FILE_EOF)
{
/* Truncate the file as specified in fileinfo[] */
}
p_close(pFile) ;
/* set the file modification date */
if (ret!=E_FILE_EOF)
break;
}
p_iow (pXmodem, P_FDISCONNECT) ;
if (ret)
p_puts ("Error receiving files");
I/O DEVICES REFERENCE
Receiving a single file using the Xmodem protocol:
type=P_XMDM_INIT;
mode=P_XMDM_CRCORCHECKSUM;
if (!p_iow(pXmodem, P_FCONNECT, &type, &mode) )
{ /* Xmodem connect completed */
p_open (&pFile, "temp.tmp", P_FUPDATE |P_FSTREAM|P_FREPLACE) ;
while (! (ret=p_iow(pXmodem, P_FREAD, &buf[0],&len) ) )
{
if (ret=p_write(pFile, ébuf[0],1len) )
break;
}
p_close(pFile) ;
p_iow (pXmodem, P_FDISCONNECT) ;
if (ret!=E_FILE_EOF)
p_puts ("Error occurred");
P_FWRITE Write data to the remote computer
VOID p_ioc(VOID *pXmodem, P_FWRITE, WORD *pstat, VOID *buffer, UWORD *plen);
INT p_iow(VOID *pXmodem, P_FWRITE, VOID *buffer, UWORD *plen);
Write data to the remote computer. If the connection was not established with a type of P_xmpM_accp the
request will fail with the negative error E_FILE_DISc.
Data can be written in buffers of 128 or 1024 bytes, although the device driver does not check whether or
not the connect request specified the p_xmpm_onE_x flag. If the receiver has not been set up to receive
1024 byte frames (the 1k option) it will in general fail to accept the data.
The 1K option specification allows the user to intermix the transmission of 128 and 1024 byte frames, this
driver conforms to that specification.
If the write request is for fewer than 128 bytes the internal transmit buffer is padded to 128 bytes with
SUB (0x1a) characters. If the request is for more than 128 but fewer than 1024 characters, the internal
buffer will similarly be padded with SUB characters.
As an exception to the above, if a write request of zero length is received this is taken to indicate that the
end of text marker should be transmitted to the remote computer, thus completing that data transfer.
Unlike for many device drivers the application does not have to preserve the data buffer or the length word
data spaces until data transmission has completed.
If the Ymodem protocols are being used the first data frame to be written is assumed to contain the
Ymodem file information.
If the p_rwRITE request was started successfully the I/O request returns zero otherwise it returns a negative
error number.
Whilst an asynchronous P_FWRITE request is outstanding the completion status word is set to
E_FILE_PENDING. On completion the status word is set to zero if the write request completed successfully
otherwise, it is set to a negative error number.
The calling process will be panicked if there is an outstanding P_FwRITE request.
9 XMODEM AND YMODEM
Examples
Sending a single file using the Xmodem protocol:
type=P_XMDM_ACCP;
mode=P_XMDM_CRCMODE;
if (!p_iow(pXmodem, P_FCONNECT, &type, &mode) )
{ /* Xmodem connect completed */
p_open (&pFile, "temp.tmp", P_FOPEN|P_FSTREAM|P_FSHARE) ;
while ((len=p_read(pFile, &ébuf[0],128) )>0)
{
if (ret=p_iow(pXmodem, P_FWRITE, &buf[0],&len) )
break;
}
if (!ret && (!len || len==E_FILE_EOF) )
{
len=0; /* Force EOT to be sent */
p_iow (pXmodem, P_FWRITE, &buf[0],&len);
}
p_close(pFile) ;
p_iow (pXmodem, P_FDISCONNECT) ;
if (ret)
p_puts ("Error occurred") ;
Sending multiple files using the Ymodem protocol:
type=P_XMDM_INIT;
mode=P_YMODEM MODE |P XMDM_ONE_K;
FOREVER
{
if (ret=p_iow(pXmodem, P_FCONNECT, &type, &mode) )
break;
if (! (ret=getNextFileName (&name[0]) ) )
break; /* gets Ymodem 1st frame info */
len=128;
if (ret=p_iow(pXmodem, P_FWRITE, &name[0],&len);
break;
p_open (&pFile, gname[0],P_FOPEN|P_FSTREAM|P_FSHARE) ;
while ((len=p_read(pFile, &buf[0],1024) )>0)
if (ret=p_iow(pXmodem, P_FWRITE, &buf [0], &len) )
break;
if (!ret && (!len || len==E_FILE_EOF) )
len=0; /* Force EOT to be sent */
p_iow (pXmodem, P_FWRITE, &buf[0],&len);
p_close(pFile);
if (ret)
break;
}
p_iow (pXmodem, P_FDISCONNECT) ;
if (ret)
p_puts ("Error sending files");
CHAPTER 10
NCP AND LINK
Introduction
This chapter describes the Psion Link application and the peer to peer data transfer services that are
provided to enable client server type applications to communicate with each other when the client and
server processes exist on different machines.
The basic Link application consists of two processes: LINK and syssncp. The Linx process varies from
machine to machine and provides only the user interface and one basic service. The syss$ncpP process is
identical on all machines and handles the physical connection and data transfer services.
The Link application is organised in four layers, each of which is responsible for a particular job:
e Physical Layer: for example the Serial Driver. This layer provides a set of services that hide any
hardware dependencies from the Logical Layer.
e Logical Link Layer. This layer provides the logical (hardware independent) services required by
the third layer.
e Data Transport and Multiplexing Layer
e = Application Layer
The first three layers are contained within the syssncp process, whose services are accessed via the NcP:
device driver. The syssncp process provides the data transport mechanism that allows client server
processes on different machines to communicate with each other.
There are many possible application layers, one of which is the LINK process. Client and server processes
are also examples of application layer processes.
Panics
All services (with the exception of p_open) will cause the calling process to be panicked if the passed
channel handle is not valid. Other panics are described under the particular service to which they apply.
The Psion logical link layer protocol
The Psion Link protocol provides the logical link layer services required by the syssncp process. The
services provided are fairly primitive. The syssncp process adds value to these services. A brief summary
of the protocol is presented here to aid in the explanation of the overall system.
The Psion Link protocol is a proprietary protocol based on the MNP protocol. It provides a symmetrical
error-free link between computers including:
e Full duplex data transmission.
e 16 bit CRC error detection.
e Multiple retransmissions.
e Dataframe sequencing.
e Variable dataframe size up to a maximum of 300 bytes per dataframe.
e A window size of one.
10-1
I/O DEVICES REFERENCE
One of the major design criteria of the protocol was that it could be implemented in a very small amount
of code and required a small working set. Thus features such as large data frames (eg 1K) and windowing
were rejected.
The protocol is a data transfer protocol, not a file transfer protocol. The file transfer or more accurately
file access and management services are provided by application layer processes.
The SYS$NCP process
The two primary functions of the syssncp process are connection establishment and data transfer.
Connection establishment
A connection is established when the following criteria have been met:
e A physical link has been established.
e A logical link has been established.
e The syssncp process has successfully exchanged logon messages with its remote counterpart.
If any of the above fail or the remote counterpart is not compatible a connection will not be established.
A physical link is deemed to have been established when the local machine detects that the remote
machine is driving the DTR (local machines DSR) hardware handshaking line (for further details see the
Serial Port chapter).
When establishing a modem link, a physical link is deemed to have been established when a modem
driver reports that an incoming call has arrived or that the dial request has been sucessful.
A logical link is deemed to have been established when the Pp_FconneEcT request on the link layer protocol
driver completes sucessfully.
The syssncp processes exchange logon messages that contain a version number and the time at which the
process was started.
The version numbers are checked to ensure compatibility (for possible future expansion).
The communicating sys$NncP processes exchange the time at which each was started so as to allow
connection re-establishment in the event of an error at either the logical or physical layer. The re-
establishment of the application layer connections (if present) will be transparent to the applications.
Data transfer
The syssncp process creates eight separate logical (software implemented) channels through which
applications can communicate. The first channel, channel zero, is used by the sys$ncp process, leaving
seven channels free for client server applications. When sending data the syssncp process multiplexes the
eight logical channels into one physical channel. Conversely, when receiving data the process
demultiplexes the data from one physical channel to eight logical channels.
The transferred data can be divided into control data and application data.
Control data is the data exchanged between communicating syssNcp processes that concerns application
connection, disconnection and data flow control.
Application data is the data exchanged between connected applications. It is transparent to the sys$ncP
process (which places no significance on any of the transferred bytes). Full 8 bit data transfer is available.
The syssncp process simply ensures that the data sent on a particular channel is routed to the correct
destination process.
The syssncp process removes a limitation of the logical link layer, namely the data frame size. The
SYSSNCP process will 'segment' application data such that the only frame size limitation is that of the
particular application.
10-2
10 NCP AND LINK
The LINK process
The three primary tasks of the LINK process are:
e to provide a user interface for the Link application
e to respond to state changes in the syssncp process
e to set up the remote filing system, after successful connection establishment.
On both the Series 3 and the HC, the Link application has no visible user interface: the application is
started and stopped by the system process. For example, on the Series 3 the user turns the Link application
on or off and sets the baud rate by selecting the Remote link option on the Special menu. The system
process launches or terminates the application accordingly.
Since there is no user interface on the Series 3 and the HC, all state changes are handled without
prompting the user for a response. See the p_rFRsuPER and P_FINQ services described below.
When the syssncp informs the L1nx process that a connection has been established the L1nx process at
each end runs a process called syssrrsv (the remote file server process). The syssrrsv process provides
remote file access and management services. The L1nx process then adds the REM-:: filing system PDD
(Physical Device Driver) to the file server, thus creating a client server pair.
The 1nx process also sets itself up as an IPC (InterProcess Communication) message receiver. An
application may send the following messages to the LINK process:
LNKMSG_TERMINATE request that the Link application terminate. This involves removing the remote
file system client server pair, and informing the syssncp process that it should
terminate. Instead of sending a message directly an application can use the
p_pterminate system service to send this message indirectly.
LNKMSG_LOADREMOTE request that a message to load and run a specified process be sent to the remote
LINK process. The message is assumed to contain up to E_Max_NamE + 2 bytes.
The message consists of the name of the remote process that is to be loaded
followed by an optional leading byte count command line. If a command line
is required then the process name must be padded out to z_max_namE + 2 bytes
(with NULLS) for compatiblity purposes. The name is parsed with .JMG and
the resultant file name (no device or path) taken as the match pattern for a
search that will firstly look in the default directory of the remote LINK process
(typically LOC::M:\) then in the root directory of any devices that exist on the
remote machine and finally in the ROM. If a process is sucessfully loaded it
will be resumed immediately, the remote L1nx process will force a context
switch to allow the newly loaded process to run, typically for long enough to
open a channel on the nce: device. The resultant process id and full process
name are sent from the remote L1Nnx to the local tnx process. The local L1nk
process will write back the full process name into the buffer passed and
complete the IPC message send with the positive remote process id or negative
error number, very similar to the return values for p_execc.
LNKMSG_CONFIG request that the L1nx process inform the syssncp process to change its driver
configuration. The message parameter is the full pvrs struct to be passed to the
SYSSNCP process.
The tnxmsc_... message numbers can be found in link_def.h and the pvrs struct definition is in sys$ncp.h.
NCP services
p_open(NCP:) Open an NCP channel
INT p_open(VOID **ppNcp,"NCP:",-1);
Requests that a channel to the SYS$NCP process be opened and a channel allocated to the calling process
in preparation for connection to, and communication with, a remote process.
10-3
I/O DEVICES REFERENCE
The nep: device driver is a root device driver, it does not require any opened channels to be passed to the
p_open request. All I/O requests on the allocated channel will be routed to the sys$ncp process by this
device driver automatically.
Opening a channel does not cause any data to be transferred to the remote machine.
A single process may open as many channels on the ncp: device as it likes.
If a process terminates for any reason without closing the channel to the ncp: device the syssNncP process
will tidy up, reporting to any remotely connected channel that this channel has now been closed.
Returns zero if the open request completed sucessfully otherwise a negative error number. A typical error
is that the syssncp process is not currently running in which case the E_FILE_NxIST error value will be
returned.
Example
if (!p_open(&pNcp, "NCP:",-1) )
{
p_close(pNcp) ;
}
p_close() Close the NCP channel
INT p_close(VOID *pNcp) ;
Requests that the currently opened channel to the syssncp process be closed.
Any outstanding I/O requests will be completed with the E_FILE_CANCEL completion status and a signal
will be generated.
If the process is still connected to a remote process the remote process will be informed that the
connection has been closed, any outstanding requests the remote process has will be completed with the
E_FILE_DIsc completion status.
The close request cannot fail and always returns zero.
P_FCONNECT Connect to a remote process
VOID p_ioc(VOID *pNcp, P_FCONNECT, WORD *pstat, UBYTE *pname, UWORD *plen);
INT p_iow(VOID *pNcp, P_FCONNECT, UBYTE *pname, UWORD *plen);
Requests that the channel be connected to a remote channel that has been opened by the named process.
In a typical client server application only the client process would make a p_FCoNNECT request. The server
process would typically open an nce: channel and queue a P_FREAD request awaiting its first command
from a client.
If both processes of an application attempt to obtain a connection they should ensure that their counterpart
is running and has an nce: channel open before making the P_FCONNECT request otherwise the request will
fail with the E_FILE_NxIstT completion status. Obviously if the connection request fails with the
E_FILE_NXIST completion status the request can be retried. The number of retries should, however, be
limited.
If an open channel is already connected to a remote channel the request will complete sucessfully.
In the Link application both of the L1nx processes attempt to obtain a connection. In this case both of
these processes will be running and have an ncp: channel open, since they launch the syssncpP process in
the first place.
The pname parameter is a pointer to a buffer containing the name of the remote process to connect with.
The name is used as the match parameter to the p_pidfind service on the remote machine. If that process
does not exist or does not have an opened syssncp channel the request will fail with the =_FILE_NxIsT
completion status. The data space pointed at is assumed to remain valid until the completion of the
P_FCONNECT request.
10-4
10 NCP AND LINK
The plen parameter points to a word containing the length of the buffer at pname including the zero
terminator. The data space pointed at is not required to remain valid until the completion of the
P_FCONNECT request.
The p_Fconnect request will typically take a significant length of time and as such should be called
asynchronously in a quality system.
The p_FconnectT request may be cancelled by using the p_FcanceEt service, the original request will be
completed with r_FILE_CANCEL completion status and a signal generated.
How the remote process came to be running in the first place is of no concern to the syssncp process, it is
however of great concern to an application writer.
Three primary methods are available to get the remote process running:
e Inturnkey systems the remote process may be automatically loaded by the system initialisation.
e The user may be prompted to run the remote process from the command shell or system
applications.
e An application can request that the Linx process run the remote process on its behalf.
The latter of these three methods is the most general and is best explained by an example as given below.
The completion status is written to *pstat by an asynchronous request and returned by a synchronous
request. The status is zero if the service completed successfully, otherwise it is a negative error number.
Errors include:
E_FILE_NXIST the named process does not have a channel open on the remote syssncp.
E_FILE_DISC the link is disconnected, there is no data path available to talk to the remote
SYSSNCP.
E_FILE_LINE the link was disconnected whilst attempting to send data to the remote
SYSSNCP.
E_FILE_RETRAN the retransmission threshold was reached because the link has been
disconnected.
Example
Simple connection to a currently running remote process:
if ('!p_open(&pNcp, "NCP:",-1) )
{
len=8; /* incl zero terminator */
if (!p_iow(pNcp, P_FCONNECT, "RPROC.*", &len) )
{
p_iow(pNcp, P_FDISCONNECT) ;
}
p_close (pNcp) ;
}
Connection to a remote process that is not currently running:
if ((linkPid=p_pidfind("LINK.*") ) <0)
p_exit (1);
p_scpy (&bb[0],"RPROC.IMG"); /* name only, no paths */
p=(&bb[0]);
if (p_msendreceivew (linkPid, LNKMSG_LOADREMOTE, &p) <0)
p_exit (1);
len=p_slen(&bb[0])+1; /* full process name here now */
if (!p_iow(pNcp, P_FCONNECT, &bb[0], &len) )
{
p_iow(pNcp, P_FDISCONNECT) ;
}
10-5
I/O DEVICES REFERENCE
P_FDISCONNECT Disconnect from the remote process
INT p_iow(VOID *pNcp, P_FDISCONNECT) ;
Requests that the current connection to a remote process be broken. An application may use the channel to
connect to the same remote process or a different remote process if required.
Any outstanding P_FREAD or P_FWRITE requests will be completed with the E_FILE_CANCEL completion
status and a signal generated.
A P_FDISCONNECT request is harmless if no connection has been established or the current connection is
temporarily disconnected.
The p_FDISCONNECT request cannot fail and returns zero.
P_ FREAD Read data from the remote process
VOID p_ioc(VOID *pNcp, P_FREAD, WORD *pstat, UBYTE *buf, UWORD *plen);
INT p_iow(VOID *pNcp, P_FREAD, UBYTE *buf, UWORD *plen);
Requests that the next 'message' sent by the remote process be placed in the buffer provided, the length of
which be written to *plen.
A message is the data sent by the remote application process in a P_FWRITE request. The contents of the
message and its format are entirely determined by the application using the ncp: channel.
The buffer provided must be large enough to hold the largest message that can be sent by the remote
application at this point in time (it does not necessarily follow that this is the largest possible message that
can be sent). The syssncp process does not check that the buffer provided is large enough, it simply writes
the message into the buffer. If the buffer is not large enough then other data will invaribly become
corrupted.
The data space pointed at by both the buf and plen parameters must be preserved until the P_FREAD
request completes.
The p_FREAD request will typically take a significant length of time and as such should be called
asynchronously in a quality system.
The p_FREAD request may be cancelled by using the P_FcaNcEt service, the original request will be
completed with E_FILE_CANCEL completion status and a signal generated.
A channel connection does not have to exist for a process to queue a P_FREAD request on the channel. In a
typical client-server application the client would run the remote server process which would open an NcP:
channel and queue a P_FREAD request. The client would queue a P_FCONNECT request and when complete
send the server any messages as required using the P_FWRITE service.
The calling process will be panicked if a p_FREAD request is currently outstanding or if pNcp is not a valid
channel handle.
The completion status is written to *pstat by an asynchronous request and returned by a synchronous
request. The status is zero if the service completed successfully, otherwise it is a negative error number.
Errors include:
E_FILE_LINE the physical link has failed. This is typically caused by the remote machine
or switching off or the pack doors being opened. The application process if a
E_FILE_RETRAN server Can re-queue a P_FREAD request awaiting the next message. Typically
the server should preserve the current state awaiting the next request. A client
would typically report the error and await user input before retrying the
operation.
E_FILE_DISC the channel has become disconnected because the remote application process
has terminated (either normally or abnormally). The application should tidy up
any resources and terminate.
E_GEN_RECEIVER the remote syss$NcpP process is terminating or a new one has attempted to
connect to the local syssncp process. The application should tidy up any
resources and terminate.
Example
See the client-server example at the end of this chapter.
10 - 6
10 NCP AND LINK
P_FWRITE Write data to the remote process
VOID p_ioc(VOID *pNcp, P_FWRITE, WORD *pstat, UBYTE *buf, UWORD *plen);
INT p_iow(VOID *pNcp, P_FWRITE, UBYTE *buf, UWORD *plen)j;
Requests that the 'message' contained in the buffer of length *pien be sent to the connected process.
The data space pointed to by buf must be preserved until the p_rwriTE request completes.
The syssncp process contains a flow control mechanism such that if a process sends data to a connected
process faster than it can handle it, backwards pressure is applied to the sending process by the local
syssncp process. This mechanism is transparent to both the sender and receiver of the message. This flow
control is such that a sending process may send data as fast as it likes without the receiver ever being
swamped.
The amount of data that can be sent in one message is only restricted to the size of the sending processes
data space (64K less the stack, static variables and other allocated cells) however, the receiving process
must have a buffer as large as the largest message that can be sent.
A channel must be connected to a remote channel before a p_FwritTE request is made, if not the request
will complete with z_r1LE_p1sc completion status.
When the p_FwRITE request completes sucessfully this indicates that the remote process to which the
message has been sent has received that message. It does not indicate that the remote process has
sucessfully processed that message.
The p_FrwrRITE request will typically take a significant length of time and as such should be called
asynchronously in a quality system.
The p_FwrITE request may be cancelled by using the p_FcanceEt service, the original request will be
completed with &_FILE_CANCEL completion status and a signal generated.
The calling process will be panicked if a p_rwRitE request is currently outstanding or if pNcp is not a valid
channel handle.
The completion status is written to *pstat by an asynchronous request and returned by a synchronous
request. The status is zero if the service completed successfully, otherwise it is a negative error number.
Errors include £_FILE_LINE, E_FILE_RETRAN, E_FILE_DISsc and E_GEN_RECEIVER, all of which have the
same meaning as for the p_rREAD service.
Example
See the client-server example at the end of this chapter.
P_FCANCEL Cancel any outstanding request
INT p_iow(VOID *pNcp, P_FCANCEL)
Requests that any outstanding requests be cancelled, the outstanding requests will complete with the
E_FILE_CANCEL completion status and a signal be generated. It is indeterminate as to how much of the
message being sent to the remote process (using P_FWRITE) has actually been sent.
The p_rcancex request should typically only be used to cancel requests immediatly before the application
terminates.
The p_FcancEL request cannot fail and returns zero.
P_FRSUPER Read supervisory information
INT p_iow(VOID *pNcp, P_FRSUPER, NCLINK_INFO *pinfo, UWORD *plen);
This function should only be called by a process that replaces the L1nxK process.
Requests that the next state change be written back to the supplied buffer.
One process in the system is responsible for receiving the state change messages and responding to them.
In the supplied system this is the tnx process. In order for the process receiving the state change
messages to ensure that it does not miss any of the messages (and cause potential system deadlock) it
should have a process priority higher than that of the syssncp process. A priority of OxBO is adequate.
10-7
I/O DEVICES REFERENCE
A connection does not have to exist (and infact should not exist before the first request is made) for this
request to be queued sucessfully.
Some state changes are purely informational and can be used as such as required, others require some
action before the syssNncp process can continue. The action may be hard coded into the LINK process
(typically the non user interface versions) or prompt the user for a solution to the new state.
The following informational state changes are reported:
PHYS_PHYS_LINK_ESTABLISHED, a physical link has been sucessfully established. The L1nx
process on the Series 3 and HC ignores this message.
PHYS_WAITING_FOR_CALL, the physical layer is waiting for an incoming call from the modem
driver in order to obtain a physical connection. The L1nx process on the Series 3 cannot receive
this status message as there is no modem driver available. On an HC the message is ignored.
PHYS_DIALLING_NUMBER, the physical layer is currently dialing a phone number in order to obtain
a physical connection. The phone number that is being dialled is in the 'phoneno' field of the
Dvrs struct. The LINK process on the Series 3 cannot receive this status message as there is no
modem driver available. On an HC the message is ignored.
PHYS_CONFIGURING_MODEM, the physical layer is currently waiting for the modem driver to finish
sending modem configuration commands. The Linx process on the Series 3 cannot receive this
status message as there is no modem driver available. On an HC the message is ignored.
PHYS_NCP_LINK_ESTAB_OK, a connnection to a remote sys$ncp process has been established or re
established if the physical or logical connections have previously failed. The L1Nx process on the
Series 3 and HC ignores this message. The connection details are contained in the pvrs struct.
PHYS_NCP_LINK_ESTAB_NEW_NCP, a connection to a remote sys$ncp process has been established,
however the remote sys$ncp is different to the one we were connected to earlier. The connection
details, eg port and baud rate are contained in the pvrs struct. The LINK process on the Series 3
and HC should respond by sending a NCLINK_CTRL_NEW_NCP_OK response.
The following error state changes are reported, they all require some action, the response is sent back to
the syssncp process via the P_FINQ service.
10-8
PHYS_NCP_LINK_ESTAB_INVALID_VER, the remote sys$ncp is version 1.0. We cannot continue
with the session since the operation of the two sys$ncp's is significantly different. There are very
few version 1.0 syssncp's. The local end should terminate by responding with the appropriate
p_FINQ message.
PHYS_NCP_LINK_END, the remote syssncp is terminating, the local end should either prompt for
continuation or termination and respond to the sys$ncpP with the appropriate p_FINQ message.
PHYS_SERCONFIG_FAILED, the physical layer has reported that the serial port the user has
specified does not exist. The local end should report the error to the user and typically terminate
by sending the appropriate p_FINQ message.
PHYS_CHARS_FAILED, the physical layer has reported that an attempt to set the serial
characteristics failed, presmably because the serial driver does not support the specified
configuration. The local end should report the error to the user and typically terminate by
sending the appropriate p_FINQ message.
PHYS_LINK_FAILED, the logical link layer driver has reported that the link has failed. If the
physical connection was over a modem link or a previous logical link connection has been made
the local end should ask the user for confirmation to re-try for a physical connection. If no link
has ever been established (no pHys_NCP_LINK_ESTAB_OK status message been received) the local
end should simply ask the syssNcp process to retry for a link.
PHYS_CONNECT_FAILED, the waiting for a physical connection has failed, typically this is caused
by a modem being removed from the serial port whilst waiting for an incoming call to arrive.
The local end should either exit or request the physical action be re-tried by sending the
appropriate P_FINQ response.
10 NCP AND LINK
@ PHYS_INIT_FAILED, the physical layer has reported that the initialisation of the modem failed,
presumably because of an invalid modem configuration string. The local end should either exit
or request the physical action be re-tried by sending the appropriate p_r1No response.
@ PHYS_DIAL_FAILED, the physical layer has reported that dialling the phone number failed. The
local end should either exit or request the physical action be re-tried by sending the appropriate
P_FINQ response.
@ PHYS_MDMCONFIG_FAILED, the physical layer has reported that sending additional modem
configuration strings has failed. The local end should either exit or request the physical action be
re-tried by sending the appropriate p_F1Nno response.
The p_FRsupPER request will typically take a significant length of time. In a high quality system it should
be called asynchronously.
The p_FRSUPER request may be cancelled by using the p_rcancet service. The original request will be
completed with k_FILE_CANCEL completion status and a signal generated.
All syssncp defines and structure definitions can be found in sys$ncp.h.
The calling process will be panicked if a p_rFRsuPER request is currently outstanding or if pNcp is not a
valid channel handle.
The p_rRsuPER request cannot fail and returns zero.
P_FINQ Respond to a supervisory message
INT p_iow(VOID *pNcp, P_FINQ, INT response, DVRS *pdvr) ;
This function should only be called by a process that replaces the LINK process.
In response to a P_FRSUPER event the state change process handler (typically L1nk) must send back a
response.
A response message may be one of the following:
@ NCLINK_CTRL_RETRY, to retry the action that failed. This would typically retry for a link
connection or a physical connection depending on which event occured earlier. The pdvr
parameter is irrelevant for this message type.
@ NCLINK_CTRL_EXIT, to request that all channels be closed, the local syssncp process inform the
remote syssncp process that it is about to terminate and actually break the physical and logical
connections. The pavr parameter is irrelevant for this message type.
@ NCLINK_CTRL_NEW_NCP_oK, to inform the syssncp process that the different remote syssncp
process is acceptable and that the controlling process (L1nx) has sorted out any channels that it is
responsible for (the remote filing system channels). The pdvr parameter is irrelevant for this
message type.
At any point in time a proces may inform the syssncp process that it should restart with new parameters
by sending it the following message
¢ NCLINK_CTRL_NEW_CONFIG, restart the syssncp process with the new configuaration as specified
in pavr. If any of the parameters are illegal or the request fails then a subsequent P_FRSUPER
request will received the failure state.
The p_ring request cannot fail and returns zero.
All syssncp defines and structure definitions can be found in sys$ncp.h.
10-9
1/0 DEVICES REFERENCE
P_FSENSE Sense the current channel activity
INT p_iow(VOID *pNcp, P_FSENSE, NCLINK_SREC *prec);
If an application wishes to determine the channel activity occuring within the syssNncpP process the
statistical information contained in an NCLINK_sREC structure can be obtained.
The prec parameter is assumed to point to an aray of 8 NCLINK_SREC structures, one for each of the
possible channels that the syssncp process can handle. Channel 0 is used by the syssncp process and the
information in that array entry should be discarded.
All syssncp defines and structure definitions can be found in sys$ncp.h.
The P_FSENSE request cannot fail and returns zero.
P_FSTOP Request the SYS$NCP terminate
INT p_iow(VOID *pNcp, P_FSTOP);
If an application process wishes to terminate the syssncp process and all connected client server
applications it should use the P_FsTop service.
When the syssncp process receives this request it will fail all outstanding requests on all open channels
immediately with a E_FILE_D1Isc completion status then tell the remote syssncp process that it is about to
terminate. Any further requests made by any application proces on any channel will fail with the
E_GEN_NOPROC completion status.
The syssncp process will not terminate until all channels have been closed by all the application
processes.
Server processes will typically always have an outstanding P_FREAD request or be processing a request the
result of which is required to be sent back to the client. In both cases it will make a request on the ncP:
channel that will fail. If the error handling is as suggested in the P_rFREAD and P_FWRITE error section then
the server will terminate gracefully.
Client processes on the other hand tend not to make any requests until user input requires them to, hence
typically do not have any outstanding or make any requests on the ncp: channel.
In a high quality system the client should close its cp: channel as soon as it is informed that the syssncp
process is about to terminate.
If the client process is the one that makes the p_rstop request is not too much of a problem for it to know
to close its channel.
If the client does not make the request it will not know to close its channel. A solution to this is for a
client process to always have a P_FREAD request outstanding even though it may never read any data from
the remote process. If it does read data from the remote process (presumably after writing a request to the
remote process to make the data available) then it can still use the outstanding p_rReap to read this data.
nn EEE
Example
This example is for a client server application which allows a process to be run on a remote machine. The
full path name is specified. The connection establishment and data transfer phases are illustrated in as
simple a manner as is possible. For clarity the code does not implement the full error handling required in
a working application.
10 - 10
The client side
GLDEF_C VOID main(VOID)
{
WORD len,nlen, pid;
VOID *pNcp;
TEXT *p;
TEXT srvName [20];
TEXT cmd[80]
if (pid=p_pidfind("LINK.*") ) <0)
p_exit (1);
if (p_open(&pNcp, "NCP:",-1) )
p_exit (1);
p_scpy (&srvName[0],"EXECSRV") ;
p=(&srvName[0]);
if (p_msendreceivew (pid, LNKMSG_LOADREMOTE, &p) <0)
p_exit (1);
len=p_get1l("Name and command line", &cmd[0],80);
if (len)
{
nlen=p_slen(&srvName[0])+1;
if (!p_iow(pNcp, P_FCONNECT, &ésrvName[0], &nlen) )
{
if (!p_iow(pNcp, P_FWRITE, &cmd[0], &len) )
{
if (!p_iow(pNcp, P_FREAD, &cmd[0], &len) )
{
pid=cmd[0]+(cmd[1]<<8);
if (pid>0)
p_printf("Remote pid %x",pid);
else
p_puts ("No such process");
}
p_iow (pNcp, P_FDISCONNECT) ;
}
}
p_close(pNcp) ;
p_exit (0);
}
The server side
GLDEF_C VOID main(VOID)
{
WORD len, pid;
VOID *pNcp;
TEXT *pname, *pcmd;
TEXT cmd[80]
if (p_open(&pNcp, "NCP:",-1) )
p_exit (1);
if (!p_iow(pNcp,P_FREAD, &cmd[0], &len) )
{
pname=p_skipwh (&cmd[0]);
pcemd=p_skipch (pname) ;
if (*pcmd)
{
*pcmd++=0; /* zero terminate proc name */
pemd=p_skipch (pcmd) ;
}
pid=p_exec (pname, pcmd, p_slen(pcmd) ) ;
cmd [0]=pid;
cmd[1]=pid>>8; /* return pid or error */
len=2;
p_iow(pNcp, P_FWRITE, &cmd[0],é&len) ;
}
p_close(pNcp);
p_exit (0);
}
10 NCP AND LINK
10-11
CHAPTER 11
CRADLE AND DOCKING STATION
Introduction
This chapter refers to two units: the HC cradle and the docking station for HC and Workabout computers.
In this document the term Cradle refers to the HC cradle, (which connects to the side pins of older HC
models). The term Docking Station refers both to the HC docking station, (which connects to an HC LIF
interface fitted to the bottom of the HC), and to the Workabout docking station. The term computer
refers to an HC or Workabout.
This chapter describes the services which are supported by the Cradle/Docking Station device driver
(crD:). The Fast Charger services provided by the Docking Station are described in the Fast Charger
chapter.
The Cradle/Docking Station device driver (cRD:) reports changes of state when a computer is inserted or
removed from the Cradle or Docking Station. It is supplied to allow a program to perform specific
operations automatically when the computer is inserted into the Cradle or Docking Station and to tidy up'
when the computer is removed.
Notes:
1. the Cradle/Docking Station device does not have to be open to use the Cradle/Docking
Station expansion port. The operating system will automatically stop and start active devices
in the cradle.
2. the "Cradle/Docking Station in" signal is generated when the computer first touches the
connector, but software running on the computer must wait until the connection is fully
home before attempting to access any device in the Cradle/Docking Station.
If a user inserts the computer into the cradle slowly, EPOC may not recognise that the
Cradle/Docking Station expansion port is present. It such a case it may be prudent to open
and close an expansion device using the Cradle/Docking Station device as an indicator of the
connection state. If an attempt to open a device when the computer is inserted into the
Cradle/Docking Station fails, a retry can be attempted after a delay of, say, two seconds.
Cradle/Docking Station services
p_open(CRD:) Open the device
INT p_open(VOID **ppcb,"CRD:",-1);
Open a channel to the current Cradle or Docking Station device, as set by any previous call to the P_FsET
service. If there has been no previous call to this service, or if the machine has just been reset, it will open
a channel to the Cradle/Docking Station.
Returns zero if the device is opened successfully, otherwise a negative error. Errors include:
E_GEN_NOMEMORY failed to allocate memory for control block
E_FILE_LOCKED or port is already open or
E_GEN_INUSE in use
11-1
I/O DEVICES REFERENCE
p_close Close the channel
INT p_close(VOID *pcb)
Close the channel. Returns zero.
P_FREAD Read from the device
VOID p_ioc(VOID *pcb, P_FREAD, WORD *pstat, UWORD *pcstate);
INT p_iow(VOID *pcb, P_FREAD, UWORD *pcstate) ;
Read a change of state from the Cradle/Docking Station, writing the new state to *pcstate.
When called for the first time after opening the device it will complete immediately, reporting the current
state. Thereafter it will complete whenever the computer is removed from or inserted into the
Cradle/Docking Station.
On completion *pcstate is TRUE if the computer is currently in the Cradle/Docking Station and Fats if
the computer is out of the Cradle/Docking Station.
Panics if a P_FREAD request is currently outstanding, or if pcb is not a valid channel handle.
The completion status code is returned by the synchronous p_iow(P_FREAD) and written to *pstat by
asynchronous calls. The completion status code is zero if the P_FREAD request completed successfully, or
E_FILE_CANCEL if the read was cancelled.
P_FCANCEL Cancel a read
INT p_iow(VOID *pcb,P_FCANCEL) ;
Cancel any outstanding P_FREAD request. Performing a cancel is harmless if no read request is
outstanding.
Returns zero.
P_FSET Set the device type
INT p_iow(VOID *pcb,P_FSET,WORD *pctype) ;
If *pctype 1s TRUE, sets all future cRD: operations to apply to the Docking Station and all accesses to port
C and related ports to apply to any expansion fitted into the Docking Station. It will also check that a valid
Docking Station expansion is fitted to the bottom of the HC. Since this call requires use of the high speed
serial channel on the bottom if the HC and affects all port C devices, it will fail with E_cEN_1nusE if
anything is open on port B or port C.
If *pctype is FALSE, sets all future cRD: operations to apply to the Cradle and all accesses to port C and
related ports to apply to any expansion fitted into the Cradle. Since this call affects all port C devices, it
will fail with E_cEN_InusE if anything is open on port C.
Note: This setting will remain even after the crp: device is closed. It will remain in force until it is
changed by another call to p_FsEt, or until the machine is reset. It is envisaged that one call will be made
to this function when an application first runs, and that this will set the device type for the life of the
application.
E_GEN_NOMEMORY failed to allocate memory for the control block
E_GEN_INUSE the port is in use (e.g. TT Y:B is open when trying to set to the Docking Station,
or TTY:C in the Docking Station is open when trying to set to the Cradle)
P_FSENSE Sense the device type
INT p_iow(VOID *pcb,P_FSENSE,WORD *pctype) ;
The current device type is returned in *pctype. If set to TRUE then the Docking Station is the current type,
if set to FALSE then the Cradle is the current type.
Note: This service does not check if the hardware is actually present (e.g. if an HC LIF interface is fitted)
and therefore may be called at any time. To check if the hardware is present, use the P_FSET service.
Returns zero.
11-2
CHAPTER 12
HC MAGNETIC CARD READER
Introduction
The HC Magnetic Card Reader (vcr: ) device driver is built into the HC's operating system.
The MCR interface may be fitted to the top (wcr:a) or bottom (Mcr:8B) of the HC, or in the cradle (wcr:c).
MCR services
p_open(MCR:) Open the MCR device
INT p_open(VOID **ppcb, "MCR:A",-1);
Open a channel to a Magnetic Card Reader device.
Returns zero if the device was opened successfully, otherwise a negative error. Errors include:
E_GEN_NOMEMORY failed to allocate memory for control block
E_FILE_DEVICE no interface found in specified slot
E_FILE_NAME invalid device name
E_FILE_LOCKED or port is already open or
E_GEN_INUSE in use
p_close Close the channel
INT p_close(VOID *pcb)
Close the Magnetic Card Reader device channel.
Returns zero.
P_FREAD Read from the MCR device
VOID p_ioc(VOID *pcb, P_FREAD, WORD *pstat, UBYTE *bufl, UBYTE *buf2);
INT p_iow(VOID *pcb, P_FREAD, UBYTE *bufl, UBYTE *buf2);
Read either or both tracks of a card. Track 1 is read into *bufi and track 2 into *buf2, where each buffer
must be at least 256 bytes long. The data in each buffer is written as leading byte count ASCII text. The
leading byte count is zero if the read was not successful.
Either buf1 or buf2 may be passed as NULL to disable reading of the relevant track. For example, to read
only track 2:
UWORD stat;
UBYTE buf[256];
p_ioc(pcb, P_FREAD, &stat, NULL, &buf[0]);
p_waitstat (&stat);
I/O DEVICES REFERENCE
Track 1 usually contains alphanumeric data (card holder's name and account number) while track 2
contains numeric data only. The most common MCRs read only track 2.
Panics if a P_FREAD request is currently outstanding, or if pcb is not a valid channel handle.
The completion status code is returned by the synchronous p_iow(P_FREAD) and written to *pstat by
asynchronous calls. The completion status code is zero if the P_FREAD request completed successfully, or
one of the following negative error numbers:
E_FILE_READ an error was detected decoding the data
E_GEN_OVER device driver buffer overflow
E_FILE_CANCEL the read was cancelled
P_FCANCEL Cancel a read
INT p_iow(VOID *pcb,P_FCANCEL) ;
Cancel any outstanding P_FREAD request. Performing a cancel is harmless if no read request is
outstanding.
Returns zero.
P_FSET Set the pull-up resistors
VOID p_iow(VOID *pcb, P_FSET, UWORD *mask);
This service is only available in EPOC versions 2.32 or later.
Set the programmable pull-up/pull-down resistors on the five MCR reader lines.
The MCR device contains programmable 100k ohm pull-up/pull-down resistors on each of the reader
lines DATA1, CLK1, DATA2, CLK2 and cus. By default when the MCR device is opened these are set to pull
down.
The resistor on each line is controlled by a bit in «mask. If the bit is set to 1 the resistor is programmed to
pull-up, if the bit is cleared to 0 the resistor is programmed to pull-down.
The bits which control each line should be defined in the application source file, according to the
following table:
Symbol Value (binary) Line
M_DATA1PU 00000001 Track 1 data
M_CLK1PU 00000010 Track 1 clock
M_DATA2PU 00000100 Track 2 data
M_CLK2PU 00001000 Track 2 clock
M_CLSPU 00010000 Card present signal
All other bits are ignored.
12-2
CHAPTER 13
HC BAR CODE READER
Hardware Description
The Bar code reader interface module
The bar code interface module is a grey plastic moulding which is designed to fit into one of the slots at
either end of the HC. To insert the module you will need to open the rear door of the HC, and unlock one
of the interface slots to remove the existing module or blank. Place the bar code reader module into the
slot and gently ease it home making sure it fits snugly. Once this is done you will need to lock the module
in place by moving the black switch into the locked position. After this close the door again otherwise the
HC will refuse to switch on.
The interface may be fitted to the top (BaR:a) or bottom (BaR:8B) of the HC.
The bar code reader wand.
The bar code wand is supplied with a locking mini-din plug which fits into the mini-din socket in the top
of the bar code module. Simply lining up the grooves and pushing the plug home will lock the plug into
place. The locking plug type is used so that if the HC is accidentally suspended by the bar code reader
cable, the machine will not come off the connector. To remove the wand from the module grip the plastic
moulding which surrounds the plug and pull gently. The plastic cover will slide back slightly releasing its
grip on the module. From there the plug should easily slide out.
[Me a Sees
Device drivers
At the time of writing, there is no bar code device driver or decoding software built into the HC's
operating system. Bar code readers are supported by separate device driver files which must be loaded by
the application code, by means of either the PLIB p_toadida function or the OPL DevLoadLpp call.
There are currently five combined decoder/device drivers:
BAREAN . LDD supports EAN8, EAN13, UPC and UPCE decoding
BARC39.LDD supports CODE 39 decoding
BARITF.LDD supports Interleaved 2 of 5 (ITF) decoding
BAR128.LDD supports CODE 128 decoding
BARMPLES . LDD supports Modified Plessey decoding
BARRAW. LDD supports raw decoding
None of the currently available drivers supports auto discrimination of bar codes.
Installing the LDD optional component of the SDK copies these files into the \sibosdkNlib directory. The
required LDD must be copied into the appropriate directory on the HC using MCLINK.
A device driver may be loaded, for example, by:
p_loadldd("BARC39.LDD") ;
To remove the device (and free the memory it uses) you should call
p_devdel ("BAR") ;
or the equivalent OPL DevDelete call.
The bar code device driver software is updated from time to time; update information is available from
Psion Support.
13-1
1/0 DEVICES REFERENCE
SSS ee |
Bar code driver services
p_open(BAR:) Open the bar code device
INT p_open(VOID **ppcb, "BAR:",-1);
Open a channel to a bar code device by means of a previously loaded bar code device driver.
Returns zero if the device was opened successfully, otherwise a negative error. Errors include:
E_GEN_NOMEMORY failed to allocate memory for control block
E_FILE_DEVICE no interface found in specified slot
E_FILE_NAME invalid device name
E_FILE_LOCKED or port is already open or in use
E_GEN_INUSE
p_close Close the channel
INT p_close(VOID *pcb)
Close the bar code device channel.
Returns zero.
P_FREAD Read from the MCR device
VOID p_ioc(VOID *pcb, P_FREAD, WORD *pstat, UBYTE *buf);
INT p_iow(VOID *pcb, P_FREAD, UBYTE *buf) ;
Read a bar code into *buf, which must be at least 256 bytes long. The data is written as leading byte count
ASCII text. The leading byte count is zero if the read was not successful. The first character of the text
indicates the type of the bar code:
EAN8 or EAN13
UPC
Code 39
ITF
Code 128
Modified Plessey
UPCE
az 7t0aNwS
The remainder of the text is the decoded bar code data.
Panics if a P_FREAD request is currently outstanding, or if pcb is not a valid channel handle.
The completion status code is returned by the synchronous p_iow(P_FREAD) and written to *pstat by
asynchronous calls. It is zero if the P_FREAD request completed successfully, or one of the following
negative error numbers:
E_GEN_OVER device driver buffer overflow
E_FILE_CANCEL the read was cancelled
P_FCANCEL Cancel a read
INT p_iow(VOID *pcb,P_FCANCEL) ;
Cancel any outstanding p_FREAD request. Performing a cancel is harmless if no read request is
outstanding.
Returns zero.
13-2
CHAPTER 14
HC INTELLIGENT BAR CODE READER/RS232 PORT
See the HC Bar Code Reader chapter, for the description of the device driver for an alternative HC bar
code reader expansion module.
RS232/intelligent bar code reader module
The RS232/intelligent bar code reader is an expansion module which contains an intelligent bar decoding
micro controller. The module is fully compatible with the HC, HC-DOS and RWAN series of computers.
The expansion module provides one serial port connection to the HC computer, and this port is shared
between the two interfaces. The serial port may be configured by software to open a channel either to the
PC-AT style RS232 interface, or to the intelligent bar code scanner interface; both interfaces cannot be
used simultaneously. This module has been designed to allow an HC computer to read bar code labels,
using a wand attached to the bar code reader interface. Data collected from bar code scans may then be
transferred to an external computer (such as an IBM PC-AT compatible machine) from the HC computer,
via the RS232 serial port interface.
The bar code reader interface contains an intelligent micro controller that will automatically read and
decode data from a bar code wand (or a wand emulator) connected to the expansion module. The unit can
read and automatically discriminate between the following bar code formats:
e EAN/JAN 8
e EAN/JAN 13
e UPCA
e UPCE
e Codabar
© Code 128
e Interleaved 2 of 5
e Code 39 (standard or extended)
The interface may be programmed to verify scanned data against check digits/characters on bar code
labels and to read, or to ignore any supplement digits in a bar code, as required.
The micro controller will transmit bar code data to the HC computer as an ASCII string of characters:
i.e. each digit or character read from a bar code label will be transmitted to the HC computer as one
ASCII-coded character. The order of the bar code data will always be transmitted to the HC computer in
the correct order (i.e. reading from left to right across the bar code label), irrespective of the direction that
the bar code label was actually scanned. By default, the end of each complete bar code scan will be marked
by a single ASCII carriage return character.
The micro controller inside the expansion module is programmable. It may be instructed to decode only a
subset of the bar code symbologies that it recognises, to transmit check digits and check characters with
each bar code scan, read or ignore supplement digits, as well as many other bar code symbology-specific
options. The micro controller can also be programmed to mark the end of each scan with a customised
ASCT terminating string of up to four characters, in place of the default carriage return termination
character. This document contains detailed information on how to program the micro controller from
C, and from OPL programs.
14-1
I/O DEVICES REFERENCE
You may connect this expansion module either to the top slot, or to the bottom slot of an HC computer.
When the expansion module has been plugged into the top slot on the computer, the RS232 port can be
accessed by opening TTy:a, and the bar code interface may be accessed by opening TTy:p; if the module
has been connected to the bottom slot on the computer, then the RS232 port can be accessed by opening
TTy:B and the bar code interface may be accessed by opening TTyY:E.
The bar code interface communicates to the host computer at the following (standard HC Comms)
settings:
e Baud
e data bits
e — stop bit
e Xon/Xoff handshaking (No hardware handshaking)
The expansion module possesses two, male 9-pin D-type connectors: the RS232 connector is a standard
PC-AT type connector!; the bar code interface connector is a standard click-lock D-type connector for a
bar code wand.
To reduce power consumption, the bar code interface and the RS232 port interface are only powered up
when the channel to the serial port is open.
The RS232 serial port interface
The RS232 interface provides standard RS232 level signals to a 9-pin D-type male connector. The
connector is PC-AT compatible, although pin 9 (normally the Rr pin) is not driven by the interface. When
the interface unit has been connected to the top slot of the HC, then the RS232 port may be accessed by
opening the try:a device. If the unit has been connected to the bottom slot of the HC, then the RS232 port
may be accessed by opening TTY:B.
The table below displays the pinout for the PC-AT type RS232 serial port.
DCD input
RX input
TX output
DTR output
Ground (ov)
DSR input
RTS output
CTS input
Optional vsup connection
OMANDNKRWNKH
Power consumption
The RS232 port is only powered up when the appropriate channel is open. The interface will draw
approximately 10mA, plus the current drawn by the device connected to the other end of the RS232 cable.
If the remote device is a PC-AT type computer, then the total current drawn by the interface will typically
be 20mA, although this figure may vary from one PC to another.
When the HC computer is also powering an external device through the RS232 port, then that external
device should not draw more than:
e =250mA from the HC if no other expansion modules are attached to the HC, or
e 200mA from the HC if another expansion module is attached to the HC and is powered up.
Please note also that external device will draw current from the HC computer even when the HC computer
has been switched off. Consequently, the external device ought to have its own on/off switch, and to avoid
excessive battery drain, the external device should be switched off when it is not in use.
'The ringing indicator (Rt) pin has not been implemented on the RS232 port. It may, however, be
connected permanently to the HC computer vsup power supply rail, if required. This action will allow an
external unit such as an infrared laser scanner to have power supplied to it through the RI connection in
the serial link cable, from the HC computer.
14-2
14 HC INTELLIGENT BAR CODE READER/RS232 PORT
Powering the HC from an external power source
The HC computer may be powered by an external source through pin 9 of the RS232 interface. To do this, a
2-pin header on the RS232/bar code interface expansion module PCB should be shorted together with a jumper.
(The 2-pin header is located at the extreme bottom left-hand side of the PCB, if the expansion module is oriented
so that the electrical components are uppermost and the two D-type connectors face upwards.)
This alteration will route the vsup main power supply rail from pin 9 of the serial port to the HC
computer. The external vsup power supply should be in the range of 7-10v. The external power supply
should be diode-isolated from the HC to prevent any power drain from the HC computer.
Please note that the main battery inside the HC computer will not be charged if power is supplied to the
HC from the RS232 port.
DSR auto wakeup switch
If required, the interface and HC computer may be woken up by an external device whenever the psp pin
of the RS232 link is asserted. To enable this facility, move the PCB switch (located at the bottom left-hand
corner of the circuit board) to the left-hand position. (If you hold the module with the component side of
the PCB facing you and the D-type connectors facing upwards, the switch is located to the bottom left
hand corner of the PCB.)
The bar code interface
The bar code reader interface contains a Hewlett-Packard HBCR-1610 series bar decoding micro
controller which is capable of reading and discriminating between the following bar code formats:
EAN/JAN 8, EAN/JAN 13, UPC A, UPC E, Codabar, Code 128, Interleaved 2 of 5 and standard or
extended Code 39 bar labels.
The interface possesses a 9-pin D-type click-lock male connector which may be attached to many standard
digital wands and wand emulating scanner units. However undecoded laser scanners (HHLC) are not
supported by this interface.
When the interface unit has been connected to the top slot of the HC, then the bar code port may be
accessed by opening the rry:p device. If the unit has been connected to the bottom slot of the HC, then the
bar code port may be accessed by opening trv:&. To conserve power, the bar code interface is only
powered up while the serial port is open.
The bar code interface communicates to the host computer with the following settings:
e Baud
e data bits, no parity and 1 stop bit
e Parity errors are not ignored
These are the default serial port settings for the HC computer. However, in addition, the bar code port
must also be set up so that:
e the tmask parameter of the serial port characteristics identifies the last character in the
terminating string for each incoming message, from the bar code interface. The default
terminating string is a single carriage return character: i.e. tmask=2000.
e the cts/rts handshaking protocol is disabled, by setting the 1cn_cts flag.
Full details are given later in this section, which describe how tmask and 1cN_cts may be set from within
a C or an OPL program. Please note that these two settings are only required to configure the bar code
ports Try:p and rry:& for the bar code interface; they do not apply to the RS232 ports rry:a and Try:B.
The table below displays the pinout for the two expansion module ports.
DCD input
Bar data input
Not connected
Switched vsup output
DSR input
DTR output
Ground (ov)
Ground (ov)
Switched 5v regulated output
OMDANANDNHRWNF
I/O DEVICES REFERENCE
Power consumption
External units should not draw more than:
e =250mA from the HC if no other expansion modules are attached to the HC, or
e 200mA from the HC if another expansion module is attached to the HC, and is powered up.
The bar code port draws an idle current of 1OmA, and typically 24mA when a scan is in progress. This
figure does not include the additional current drawn by the wand, or scanner, attached to the interface. To
conserve power, the RS232 interface is only powered up while the serial port is open.
Powering a bar code wand from the HC
The HC computer can supply a 5v ( +5%) regulated supply and a vsup (6-10v) supply to an external bar
code wand, or a wand emulating device (such as an RS232 laser scanner). These two power supplies are
available on pin 9 and pin 4, respectively, on the bar code interface connector.
To allow the HC to supply power an external unit a simple adjustment must be made to the expansion
module: a 2-pin header on the PCB of the RS232/bar code interface expansion module must be shorted
together with a jumper. (The 2-pin header is located at the extreme bottom left-hand side of the PCB, if
the expansion module is oriented so that the electrical components are uppermost and the two D-type
connectors are facing upwards.)
The two power supply outputs on the bar code interface (and the decoding IC) are switched on only when
the port is open. As a result, the power will be switched off when the HC computer powers down - if it is
left unused for longer than the timeout period. Please note that all of the custom settings programmed into
the bar code interface with escape sequences will be lost when the port is closed, or if the HC auto-powers
down.
Please note that the 2-pin header should only be taken if the external unit must be powered by the HC, or
if the HC must be powered by the external device.
[eyeee TS
Bar code symbologies
The bar code reader interface will transmit data from each bar code scan as a stream of ASCII text data.
Each data stream will be terminated by the default termination string (a carriage return character, 00d).
Alternatively, the interface may be programmed to terminate each stream of scan data with a custom
termination string of up to four characters.
Bar code data will always be transmitted to the host computer in the correct order (i.e. from left to right),
irrespective of the direction in which the bar label was originally scanned. Bar code labels containing
supplement digits can only be scanned in the forwards direction (i.e. from left to right); all other bar code
labels may be scanned either forwards or backwards. The interface may be programmed to include, or
strip out, check characters and ID characters in the transmitted data, as desired. The maximum scanning
rate for any bar code format is 30 ips
The remainder of this section will now describe each bar code format that may be scanned by the
interface. In each case, the programmable options that are associated with each format will also be
described.
Code 128
Code 128 labels contain a variable number of digits, and one check character. There are three types of
Code 128 bar code labels that may be decoded by the bar code interface: code A, code B and code C. Both
Code A and Code B labels may contain a maximum of 31 characters; Code C labels may contain a
maximum of 62 characters.
No user-definable options are available to alter Code 128 bar code data. The bar code reader interface will
always check the label data against the check character on the bar code label, but the check character will
never be transmitted as part of the scanned data.
14-4
14 HC INTELLIGENT BAR CODE READER/RS232 PORT
Codabar
Codabar labels contain one start character, a number of digits and one stop character. Only one user-
definable option exists with Codabar format data: the bar code reader interface may be programmed to
transmit, or to ignore any start and stop characters in the label data.
The start and stop characters may be any of the following four upper case characters: 'A', 'B', 'C, or 'D'. A
start character does not have to be the same as the stop character.
The table below illustrates the effect that each Codabar option will have on the output data from the bar
code interface.
Start/stop chars Input label data Output data
Transmit A123456B 123456
Ignore A123456B A123456B
Interleaved 2 of 5
An Interleaved 2 of 5 bar code will always contain an even number of digits (including the check digit)
and no characters. It may also contain a number of additional check sum digits also. The maximum
number of digits that may be contained within a label is 32; the minimum number is 2. The interface may
be programmed to read either:
e any Interleaved 2 of 5 labels containing any even number of digits within the range of 2 and 32
digits,
e only Interleaved 2 of 5 labels containing 6 or 14 digits, or
e only Interleaved 2 of 5 labels containing a preset, even number of digits.
There will always be one check digit at the end of the bar code label. The bar code scanner interface may
be programmed to verify the scanned data against this check digit, and it may also be programmed either
to transmit the check digit as part of the output data string, or to omit the check digit from the output data.
In the table below, 123456 represents a bar code scan containing the valid check digit 6 and 123457
represents a scan that contains the invalid check digit 7. The output generated by the bar code interface is
displayed in the right-hand column.
Input data Verify the check Transmit the check digit ? Output data
digit?
23456 No Yes or No 23456
123457 No Yes or No 23457
123456 Yes No 2345
123457 Yes No No output
23456 Yes Yes 23456
123457 Yes Yes No output
Code 39
A Code 39 bar code label may contain a minimum of one character and a maximum of 32 characters. It
will contain no digits. The bar code reader interface may be programmed to verify the label check
character, and to transmit the check character in the output data message, or strip the check character
from the output data.
In the following table, ancx represents a Code 39 label containing the valid check character x, and the
string apcp represents a Code 39 label containing an invalid check character p.
14-5
1/0 DEVICES REFERENCE
Input label data Verify the check Transmit the check Output data
character? character
ABCD No Yes or No ABCD
ABCX No Yes or No ABCX
ABCD Yes No No output
ABCX Yes No ABC
ABCD Yes Yes No output
ABCX Yes Yes ABCX
The user interface may be programmed in Code 39 scans may be converted as character pairs (as defined
by the Code 39 symbology) or alternatively, each character in the scan may be decoded individually.
The UPC/EAN bar code formats
The UPC/EAN bar code family all contain a fixed number of digits, and all contain one check digit. The
bar code reader interface may be programmed to verify this check digit against the rest of the scanned
data. The interface may also be programmed to transmit the check digit as part of the bar code, or to omit
the check digit from the output data.
There twelve variants in the UPC/EAN family of bar codes. Note that JAN 8 labels are equivalent to EAN
8 format labels and JAN 13 labels are equivalent to EAN 13 format labels.
UPC E
The UPC E bar code label format contains a leading ID character, one number system digit, six data digits
and one check digit. The leading ID character must be an ASCII 'E. The check digit will be followed by 2
supplement digits in UPC E + 2 digit labels, and with 5 supplement digits in UPC E + 5 digit labels.
The bar code interface may be programmed to remove the ID character, or the check digit from the data
transmitted to the host computer. UPC E bar code label data may also be expanded into UPC A bar code
format automatically by the interface unit - in which case the six existing data digits will be expanded to
ten digits, and the leading ID character will become an ASCII'A'. Refer to the UPC A section in this
chapter for more information about this label format.
The following table displays the four different user-definable options available for modifying the output
data from UPC E scans.
Transmit ID char Transmit check digit Standard output (UPC E) Expanded output (UPC A)
No No dddddd ndddddddddd
Yes No Endddddd Andddddddddd
No Yes dddddd nddddddddddc
Yes Yes Endddddd Anddddddddddc
where
gE = an ID character 'E' (0x45)
a =an ID character 'A' (0x41)
d= one data digit
n = one number system digit
= one check digit
Q
a
= one supplement digit
14 HC INTELLIGENT BAR CODE READER/RS232 PORT
UPC E + 2 digits
As its name suggests, the UPC E + 2 bar code label format contains a leading ID character, one number
system digit, six data digits, one check digit and two supplement digits. The leading ID character must be
an ASCIL'E'. UPC E bar code label data may also be expanded into UPC A bar code format automatically
by the interface unit - in which case the six existing data digits will be expanded to ten digits, and the
leading ID character will become an ASCII 'A.
The bar code interface may be programmed to remove the ID character, or the check digit from the output
data transmitted to the host computer. The following table displays the four different options available:
Transmit ID char Transmit check digit Standard output (UPC E) Expanded output (UPC A)
No No ddddddss nddddddddddss
Yes No Enddddddss Anddddddddddss
No Yes ddddddss nddddddddddcss
Yes Yes Enddddddss Anddddddddddcss
where:
gE = an ID character 'E' (0x45)
a =an ID character 'A' (0x41)
a = one data digit
n = one number system digit
c = one check digit
s = one supplement digit
UPC E + 5 digits
As its name suggests, the UPC E + 5 bar code label format contains a leading ID character, one number
system digit, six data digits, one check digit and five supplement digits. The leading ID character must be
an ASCII 'E'. UPC E bar code label data may also be expanded into UPC A bar code format automatically
by the interface unit - in which case the six existing data digits will be expanded to ten digits, and the
leading ID character will become an ASCII 'A.
The bar code interface may be programmed to remove the ID character, or the check digit from the output
data transmitted to the host computer. The following table displays the four different options available:
Transmit ID char Transmit check digit Standard output (UPC E) Expanded output (UPC A)
No No ddddddsssss nddddddddddsssss
Yes No Enddddddsssss Anddddddddddsssss
No Yes ddddddsssss nddddddddddesssss
Yes Yes Enddddddsssss Anddddddddddcsssss
where:
gE = an ID character 'E' (0x45)
a=an ID character 'A' (0x41)
d = one data digit
n = one number system digit
c = one check digit
s = one supplement digit
14-7
I/O DEVICES REFERENCE
EAN 8 bar code format
The EAN 8 bar code label format contains the following components: two leading ID characters, two flag
digits, five data digits and one check digit. The two leading ID characters will be the upper case string:
"ER w t.
The bar code interface may be programmed to remove the two ID characters, or the check digit from the
output data transmitted to the host computer. The following table displays the four different options
available:
Transmit ID chars Transmit check digit Output
No No ffddddd
Yes No FFf£fddddd
No Yes ffddddde
Yes Yes FF £fdddddc
where:
F = an ID character 'F' (0x46)
f = one flag digit
d = one data digit
c = one check digit
EAN 8 + 2 digits
The EAN 8 + 2 bar code label format contains the following components: two leading ID characters, two
flag digits, five data digits, one check digit and two supplement digits. The two leading ID characters will
be the upper case string "FF".
The bar code interface may be programmed to remove the two ID characters, or the check digit from the
output data transmitted to the host computer. The following table displays the four different options
available:
Transmit ID chars Transmit check digit Output
No No ffdddddss
Yes No FFf£fdddddss
No Yes ffdddddess
Yes Yes FFf£fdddddcss
where:
F = an ID character 'F' (0x46)
£ = one flag digit
d = one data digit
c = one check digit
s = one supplement digit
EAN 8 + 5 digits
The EAN 8 + 5 bar code label format contains the following components: two leading ID characters, two
flag digits, five data digits, one check digit and five supplement digits. The two leading ID characters will
be the upper case string "FF".
14 HC INTELLIGENT BAR CODE READER/RS232 PORT
The bar code interface may be programmed to remove the two ID characters, or the check digit from the
output data transmitted to the host computer. The following table displays the four different options
available:
Transmit ID chars Transmit check digit Output
No No ffdddddsssss
Yes No FFffdddddsssss
No Yes ffdddddcsssss
Yes Yes FFf£ffdddddcsssss
where:
Fr = an ID character 'F' (0x46)
f = one flag digit
a = one data digit
c = one check digit
s = one supplement digit
EAN 13
The EAN 13 bar code label format contains the following components: a leading ID character, two flag
digits, ten data digits and one check digit. The leading ID character will be an ASCII upper case 'F.
The bar code interface may be programmed to remove the ID character, or the check digit from the output
data transmitted to the host computer. The following table displays the four different options available:
Transmit ID char Transmit check digit Output
No No ffdddddddddd
Yes No Fff£dddddddddd
No Yes ffddddddddddc
Yes Yes Ff fdddddddddde
where:
Fr =an ID character 'F' (0x46)
f = one flag digit
ad = one data digit
c = one check digit
EAN 13 + 2 digits
The EAN 13 + 2 bar code label format contains the following components: a leading ID character, two
flag digits, ten data digits, one check digit and two supplement digits. The leading ID character will be an
ASCII upper case 'F.
The bar code interface may be programmed to remove the ID character, or the check digit from the output
data transmitted to the host computer. The following table displays the four different options available:
Transmit ID char Transmit check digit Output
No No ffddddddddddss
Yes No Fffddddddddddss
No Yes ffddddddddddess
Yes Yes Fffddddddddddecss
14-9
I/O DEVICES REFERENCE
where:
F = an ID character 'F' (0x46)
£ = one flag digit
d = one data digit
c = one check digit
s = one supplement digit
EAN 13 + 5 digits
The EAN 13 + 5 bar code label format contains the following components: a leading ID character, two
flag digits, ten data digits, one check digit and five supplement digits. The leading ID character will be an
ASCII upper case 'F.
The bar code interface may be programmed to remove the ID character, or the check digit from the output
data transmitted to the host computer. The following table displays the four different options available:
Transmit ID chars Transmit check digit Output
No No ffddddddddddsssss
Yes No Fffddddddddddsssss
No Yes ffddddddddddesssss
Yes Yes Fffddddddddddesssss
where:
F = an ID character 'F' (0x46)
f = one flag digit
d = one data digit
c = one check digit
s = one supplement digit
UPCA
The UPC A bar code label format contains a leading ID character, one number system digit, ten data
digits and one check digit. The leading ID character must be an ASCII 'A.
The bar code interface may be programmed to remove the ID character, or the check digit from the output
data transmitted to the host computer. The following table displays the four different options available:
Transmit ID chars Transmit check digit Output
No No ndddddddddd
Yes No Andddddddddd
No Yes ndddddddddde
Yes Yes Anddddddddddc
where:
a=an ID character 'A' (0x41)
n = one number system digit
d = one data digit
c = one check digit
14-10
14 HC INTELLIGENT BAR CODE READER/RS232 PORT
UPC A + 2 digits
The UPC A + 2 bar code label format contains a leading ID character, one number system digit, ten data
digits, one check digit and two supplement digits. The leading ID character must be an ASCII 'A.
The bar code interface may be programmed to remove the ID character, or the check digit from the output
data transmitted to the host computer. The following table displays the four different options available:
Transmit ID chars Transmit check digit Output
No No nddddddddddss
Yes No Anddddddddddss
No Yes nddddddddddcss
Yes Yes Anddddddddddcss
where:
a =an ID character 'A' (0x41)
n = one number system digit
a = one data digit
c = one check digit
s = one supplement digit
UPC A + 5 digits
The UPC A +5 bar code label format contains a leading ID character, one number system digit, ten data
digits, one check digit and five supplement digits. The leading ID character must be an ASCII 'A.
The bar code interface may be programmed to remove the ID character, or the check digit from the output
data transmitted to the host computer. The following table displays the four different options available:
Transmit ID chars Transmit check digit Output
No No nddddddddddsssss
Yes No Anddddddddddsssss
No Yes nddddddddddesssss
Yes Yes Anddddddddddcsssss
where:
a=an ID character 'A' (0x41)
n = one number system digit
d = one data digit
c = one check digit
s = one supplement digit
Bar code commands
This section describes the commands that may be used to program the HC bar code reader interface.
The bar code interface is programmed by writing an escape sequence to the interface unit via a serial port.
With two exceptions, each escape sequence consists of a short text string in the following format:
<Esc>-y<code><command>
14-11
I/O DEVICES REFERENCE
1. <Esc> is the escape character (0x1b)
2. - isa'-' character (0x2d)
3. y isa'y' character (0x79) or a'y' character (0x59)
4
<code> is a parameter to the command, consisting of sequence of one to three numeric digit,
representing a decimal number between zero and 255.
5. <command> is an upper case alphabetic character identifying the command to be executed.
The two exceptions are the hard reset command:
<ESc>E
and the command to set the data termination string, which includes additional text following the letter
that identifies the command:
<Esc>-y<code><command><text>
In all cases the escape sequence must not contain any embedded spaces.
Commands to the bar code reader interface do not have to be issued individually. The /ssuing multiple
commands section in this chapter describes how several commands may be issued as a multiple escape
sequence, within one text string.
Multiple options in a command
Many of the bar code interface commands offer more than one option, selected by the <code> value. To
select multiple options from a single command, simply sum all the required individual <code> values
together, and then pass this summed value as the <code> value within the escape sequence.
For example, the Select bar code symbology command <Esc>-y<code>F (described later in this chapter)
contains options to select five different bar code formats. For example, a <code> value of | selects Code
39, a value of 4 selects Codabar and a value of 8 selects UPC/EAN. You can select all three formats in a
single command by setting the <code> value to 1+4+8 = 13, as follows:
<Esc>-y13F
Issuing multiple commands
Several individual escape sequence commands may be concatenated together and be transmitted to the bar
code interface as a single escape sequence. To do this, append one or more additional <code><command>
character sequences to the end of a standard, single, escape sequence.
When issuing multiple commands, all of the intermediate <command> ASCII characters must be lower case
letters, and the terminating <command> character must be an upper case ASCII character.
As with a single command, the escape sequence must not contain any embedded spaces.
For example, following three commands:
<Esc>-y13F Select Codabar, UPC/EAN and Code 39 symbologies
<Esc>-y2H Do not transmit Codabar start and stop characters
<Esc>-y1D Insert a 10 ms delay between each data character
may be concatenated into a single escape sequence:
<Esc>-y13£2h1D
The order of issuing commands is usually not important, so that the following three escape sequences are
all functionally identical:
<Esc>-y13f£2h1D
<Esc>-y2h1d13F
<Esc>-y1d13£2H
Exceptions to this rule are mentioned explicitly in the following descriptions of the individual commands.
14-12
14 HC INTELLIGENT BAR CODE READER/RS232 PORT
Serial intercharacter delay <Esc>-y<code>D
Enable or disable a ten millisecond delay between the transmission of each data character in the bar code
data string.
<code> Option
0 No delay
1 Turn 10 millisecond delay on
The default value is equivalent to the command <zsc>-yop.
Hard reset <Esc>E
Perform a hard reset and run a self-test.
A hard reset will take approximately one second to complete. During this time, the bar code reader
interface will not react to any further commands that may be written to it.
All previous escape sequence commands sent to the bar code interface will be aborted when a hard reset is
executed. After the reset has taken place, all of the interface options will revert to their default values.
If the interface has failed its self-test, it will immediately transmit one of the following four messages:
ROM SELF TEST FAILED<CR><LF>
PROCESSOR SELF TEST FAILED<CR><LF>
LOWER RAM SELF TEST FAILED<CR><LF>
UPPER RAM SELF TEST FAILED<CR><LF>
No message will be issued if the interface has passed the self-test.
Note that the diagnostic messages will always be terminated by a carriage return (0x0d) and line feed
(0x0a) character pair, regardless of any previous command to set the termination characters.
All subsequent messages from the interface will be terminated with a (default) single carriage return
character.
A Hard Reset will not normally be issued as part of a multiple instruction escape sequence, because it will
cause all prior commands to be overridden by default settings, and all subsequent commands within the
escape sequence to be ignored by the bar code reader interface while it resets itself.
Select bar code symbology <Esc>-y<code>F
Set the barcode reader to recognise one or more barcode formats, as indicated in the following table:
<code> Enable bar code format:
1 Code 39
2 Interleaved 2 of 5
4 UPC/EAN
8 Codabar
16 Code 128
For example, to read Code 39 and UPC/EAN bar codes only, use:
<Esc>-y5F
If a bar code format has not been enabled, then the bar code reader will ignore all scans in that code
format.
The default setting for this option is equivalent to the command <zsc>-y31F.
Note that it may be necessary to set additional interface options to enable the interface to read certain bar
code formats.
14 - 13
1/0 DEVICES REFERENCE
Check character options <Esc>-y<code>G
Enable or disable verification/check digits and check characters within bar code scans. The precise action
of this command is dependent upon the bar code format being scanned, as indicated below.
The default state corresponds to the command <Esc>-y0c.
Code 39 and Interleaved 2 of 5
For Code 39 and Interleaved 2 of 5 bar codes, the bar code reader may be programmed to verify, or to
ignore check characters in the bar code scan. In addition, the bar code reader may be programmed to
transmit, or to omit the verification character from the scan data when it is transmitted to the host
computer.
<code> Option
0 Do not verify check characters
1 Verify Code 39 check characters
2 Verify Interleaved 2 of 5 check characters
8 Transmit Code 39 and Interleaved 2 of 5 check characters
UPC/EAN
The contents of UPC/EAN bar code scans are always checked against the check digit. However, the bar
code reader may be programmed to transmit, or to omit the check digit when the scan data is transmitted
to the host computer. Note that the check digit in a UPC E bar code is never transmitted to the host
computer.
The bar code reader may also be programmed to decode UPC E 0 bar codes, or it may be programmed to
automatically discriminate between UPC E 0 and UPC E 1 version bar codes.
<code> Option
0 Read UPC E 0 only, transmit UPC/EAN check digit
32 Do not transmit UPC/EAN check digit
64 Read both UPC E 0 and UPC E 1
Decoding options <Esc>-y<code>H
This command provides several assorted programming options to the programmer. For UPC/EAN bar
code scans, the bar code reader may be programmed to accept (zero, two or five) supplemental digits in
the code, and to expand UPC E bar codes automatically into a UPC A code format, if required.
The bar code reader may also be programmed using this command to decode Code 39 bar codes in
standard, or in extended mode. If the extended option is selected, then the bar code reader will encode
each character pair into the corresponding ASCII characters; if standard mode is selected, then each
character in the scan data is decoded individually.
The bar code reader may also be programmed to retain (or discard) Codabar start and stop characters in
the scan data it transmits to the host computer.
<code> Option
1 Extended Code 39
0 Standard Code 39
2 Do not transmit Codabar start and stop characters
0 Transmit Codabar start and stop characters
4 Read UPC bar codes only
0 Read both UPC and EAN bar codes
8 Decode UPC/EAN 2 digit supplement data
0 Do not decode UPC/EAN 2 digit supplement data
16 Decode UPC/EAN 5 digit supplement data
0 Do not decode UPC/EAN 5 digit supplement data
32 Expand UPC E bar codes into UPC A bar codes
14-14
14 HC INTELLIGENT BAR CODE READER/RS232 PORT
0 Do not expand UPC E bar codes
64 Auto discriminate UPC/EAN supplementals
0 Require UPC/EAN supplementals
128 Transmit UPC/EAN ID characters
0 Do not transmit UPC/EAN ID characters
The default setting is equivalent to the command <zsc>-y0H.
Notes
When the option is set to decode UPC/EAN 2 digit (or 5 digit) supplement data, then the bar code label
must be scanned in the forwards direction only.
Only UPC/EAN bar codes containing supplement digits may be read by the interface if either, or both of
these options has been enabled. Both the 2 digit and 5 digit options may be enabled together to allow both
types of bar code scans to be read by the interface, if required.
If the supplement digit options are not enabled by this command, then bar code labels containing
supplement digits may still be scanned, and they may be scanned in both directions (i.e. forwards or
backwards). However the supplement digit data is not transmitted to the host computer.
Single read mode <Esc>-y<code>J
This command will force the bar code reader to abort any current scan and not transmit that scan data to
the HC.
Enabling Single read mode means that the bar code reader will read a single bar code label each time a
Single read control command is issued.
When Single read mode is disabled, the bar code reader will attempt to read a bar code label whenever a
label is scanned.
<code> Option
1 Single read mode is enabled
0 Single read mode is disabled
The default value is equivalent to the command <zsc>-you.
Single read control <Esc>-y<code>K
This command will force the bar code reader to abort any current scan and not transmit that scan data to
the HC.
When Single read mode has been enabled (see above), the-Single read control may be used to enable the
bar code reader, so that it then will read one scan.
<code> Option
1 Read next scan
Set Interleaved 2 of 5 length <Esc>-y<code>M
This command presets the length of Interleaved 2 of 5 bar code read by the bar code reader.
There are three length checking options available:
<code> Option
0 The bar code may have a variable length, between 4 and 32 digits
1..32 The bar code is <code> digits long (even values only)
33 The bar code may only contain either 6 or 14 digits
The default setting is equivalent to the command <zsc>-yom.
14-15
I/O DEVICES REFERENCE
Notes
Although the Interleaved 2 of 5 bar code length may be set to the minimum setting (i.e. two digits), short
Interleaved 2 of 5 bar codes may well appear in other, longer bar codes. As a result, false readings may be
given when other formats of bar code label are scanned, which may be misinterpreted as two digit
Interleaved 2 of 5 labels. Consequently, the minimum setting of 2 digits in this option is not
recommended.
An Interleaved 2 of 5 bar label must contain an even number of digits. If <code> is set to an odd number
between one and thirty one, then the micro controller will automatically round up the value to the next
higher even number.
Set termination string <Esc>-y<code>O<string>
This command will force the bar code reader to abort any current scan and not transmit that scan data to
the HC.
Append the termination string <string> to the end of every bar code data message transmitted to the
HC computer by the micro controller, to mark the end of that message.
The default termination string is a single carriage return character (0x0a). However, a user-defined
termination string may be defined with this command, which will be used to terminate all subsequent
message transmitted by the bar code reader interface. An example escape sequence, which substitutes the
characters "stop" as the terminating string in place of the default value, is:
<Esc>-y4Ostop
A termination string may contain a maximum of four characters and a minimum of zero characters. The
total number of characters contained within the termination string must be passed as the <code> argument
of the escape sequence.
The default termination string transmitted by the bar code reader is a single carriage return character
(0x0d).
Unlike all other sequence commands described in this document, the ASCII characters for the termination
string follow the command identifier character that normally terminates a command. As a result this
command must be positioned last, if issued within an escape sequence that contains more than one
command (even if the terminating string contains zero characters).
For example, consider the commands:
<Esc>-y4Ostop Set the termination string to "stop"
<Esc>-y1D Insert a 10 ms delay between each data character
If these commands are combined in a single escape sequence, that sequence must be:
<Esc>-yl1d40stop
Code ID characters <Esc>-y<code>Q
Instruct the bar code reader to add a lower case ID character to the data message transmitted to the HC, to
identify the symbology of the bar code. This ID code character is transmitted before the bar label data.
The following values will enable, and disable this option:
<code> Option
1 Transmit ID characters
0) Do not transmit ID characters
The table below displays which lower case ASCII character ('a' - 'e') is used to identify each type of bar
code label:
ID character Bar code format
Code 39
Interleaved 2 of 5
UPC/EAN/JAN
Codabar
Code 128
o0oaadaas ow
The default state is equivalent to the command <Esc>-y0o.
14 - 16
14 HC INTELLIGENT BAR CODE READER/RS232 PORT
Status request <Esc>-y<code>S
This command will force the bar code reader to abort any current scan and not transmit that scan data to
the HC.
Return a data string to the host computer, containing information about the status of the firmware inside
the bar code reader.
<code> Option
1 Transmit the status message
The status message that is transmitted back to the HC in response to this instruction is:
HBCR-161X Version 15.x
followed by the current termination string, where "15.x" represents the present revision level of the
firmware inside the bar code reader interface.
Scanner enable <Esc>-y<code>W
This command will force the bar code reader to abort any current scan and not transmit that scan data to
the HC.
Enable or disable the bar code reader.
When disabled, the bar code scanner will not read data from any bar code labels.
<code> Option
1 Enable the bar code scanner
0 Disable the bar code scanner
The default is for the bar code scanner to be enabled.
RS232 port/bar code driver services
The RS232 port/bar code device driver supports all the services that are described in the Serial Port
chapter of this manual. This section describes only those services that provide modified or additional
behaviour when used with the bar code reader interface. These include services to open the port, write
data to the bar code interface and read data from a bar code wand connected to the port.
p_open(TTY:) Open the device
INT p_open(VOID **ppcb, "TTY:B",-1);
Open a channel to the RS232 port/bar code device.
The table below displays which device should be accessed to open the RS232 port or the bar code reader
interface, when the expansion module has been inserted into either of the the top and bottom slots of the HC.
Slot RS232 port _Bar code port
Top TTY:A TTY2¢
Bottom TTY:B TTY:D
On opening a channel, RS232 port, the bar code reader interface and any connected wand or scanner will
all be powered up automatically.
Returns zero if the device was opened successfully, otherwise a negative error.
For example, the following code fragment illustrates the opening of a channel to the bar code interface
with the device in the top slot of the HC.
LOCAL_D VOID *pHandle;
INT result;
result=p_open (&pHandle, "TTY:D",-1);
14-17
1/0 DEVICES REFERENCE
p_close Close the channel
INT p_close (VOID *pcb)
Close the channel to the RS232 port/bar code device.
Returns zero.
Closing the channel will also cause the RS232 port/bar code interface to be powered down. To save battery
power, a device should be closed as soon as it is no longer required.
Note that when the device is closed, or when the HC automatically powers down, all of the information
programmed into the bar code interface will be lost. If you do not wish to use the default settings of the
bar code reader interface, then you will need to reprogram your custom settings back into the interface
when the device is next opened.
P_FSENSE Sense serial port characteristics
INT p_iow(VOID *pcb, P_FSENSE, P_SRCHAR *pserial);
Sense the serial port characteristics, writing them to the P_sRcuar struct (defined in p_serial.h) pointed to
by pserial.
The P_FSENSE service cannot fail and returns zero.
If using the bar code interface, the serial port characteristics must be altered once a channel is opened, to
allow the interface to communicate successfully with the HC. See the description of the P_Fset service for
further details.
P_FSET Set serial port characteristics
INT p_iow(VOID *pcb, P_FSET, P_SRCHAR *pserial);
Set the serial port characteristics from the P_sRcHar struct (defined in p_serial.h) pointed to by pserial.
Returns zero if the P_FSET service completed successfully, otherwise returns a negative error.
If using the bar code interface, the serial port characteristics must be altered once a channel is opened, to
allow the interface to communicate successfully with the HC. Since the bar code interface does not use
RTS/cTS handshaking, the cts line in the serial port must be disabled.
The following code fragment illustrates the use of the P_FsENSE and P_FSET services to disable RTS/cTS
handshaking:
#include <p_serial.h>
LOCAL_D P_SRCHAR srChar;
LOCAL_D VOID *pHandle;
f_leave (p_open (&pHandle, "TTY:D",-1));
p_iow(pHandle,P_FSENSE,&srChar); /* read default settings into srChar */
srChar.hand=P_IGN_CTS; /* suspend RTS/CTS handshaking */
p_iow (pHandle, P_FSET, &srChar) ; /* set up port with new settings */
Note that this code assumes that it is called under the protection of p_enter.
P_FREAD Read from device
VOID p_iow (VOID *pcb, INT P_FREAD,VOID *buf,UINT *plen)j;
VOID p_ioc (VOID *pcb, INT P_FREAD,WORD *pfstat,VOID *buf,UINT *plen)j;
Read up to *plen bytes of data from the device into the buffer pointed to by buf. The buffer is assumed to
be of sufficient length to receive the data. If using an asynchronous P_FREAD service, it is the caller's
responsibility to preserve the data space pointed to by buf and plen until the service completes.
The result is returned by a call to p_iow and written to *pfstat by the asynchronous call. The result is
zero if the service completed successfully, otherwise it is a negative error.
14 - 18
14 HC INTELLIGENT BAR CODE READER/RS232 PORT
A read operation may take an indefinite time to complete and it should therefore be executed
asynchronously within a quality system. For clarity, the following example code uses synchronous reads.
define MAX_BARCODE 128
define TERMINATE_CHAR 0x0d
VOID *pHandle;
TEXT *p;
NT len;
UINT count;
TEXT buf [MAX_BARCODE+2];
len=0;
count=1;
p=ébuf [0];
FOREVER
{
p_iow(pHandle,P_FREAD,p, &count) ;
lent+=1;
if ( (*p++==TERMINATE_CHAR) | | (len>=MAX_BARCODE_LEN) )
{
*--p=0; /* convert to a zero-terminated string */
len-=1;
break;
}
}
p_printf("Bar code is %s, containing %d bytes", &ébuf[0],len);
P_FWRITE Write to device
INT p_iow(VOID *pcb, INT P_FWRITE,VOID *buf,UINT *plen);
VOID p_ioc(VOID *pcb, INT P_FWRITE,WORD *pfstat,VOID *buf,UINT *plen);
Write up to *pien bytes of data from the buffer pointed to by buf to the device. If using an asynchronous
P_FWRITE Service, it is the caller's responsibility to preserve the data space pointed to by buf and plen
until the service completes.
The result is returned by a call to p_iow and written to *pfstat by the asynchronous call. The result is
zero if the service completed successfully, otherwise it is a negative error.
A write operation may take an indefinite time to complete and should therefore be executed
asynchronously within a quality system. For clarity, the following example uses a synchronous write.
The following code fragment transmits the escape sequence <Esc>—y1d24f2u to the bar code reader
interface:
#define MAX COMMAND 64
VOID *pHandle;
UINT len;
UBYTE command [MAX_COMMAND+2];
p_scpy (&command[0],"\033-y1d24f£2H") ;
len=p_slen(&command[0]) ;
p_iow (pHandle, &command [0], &len) ;
14-19
I/O DEVICES REFERENCE
An example program
The program listed below will operate a bar code interface connected to either the top, or the bottom of the
HC. The program will read scanned bar code data from the reader interface, display that information on
the screen and then await a key press. The scanning operation may be repeated as many times as required.
Press the X key after a scan to exit the program; pressing the V key will display the firmware status of the
software inside the bar code interface.
This program is only given here as a simple example of how to program the micro controller and read
scan data: a quality system should carry out more rigorous testing for errors, and should also use
asynchronous operations to read and write the data.
#include <plib.h>
#include <p_serial.h>
#define MAX _STRING 128
LOCAL_D VOID *pHandle;
GLDEF_C INT main (void)
{
P_SRCHAR srChar;
INT len, onebyte,result, reply;
TEXT buffer [MAX_STRING+2];
/* Try to open a port */
if (p_open(&pHandle, "TTY:D",-1) <0)
{
if ((result=p_open (&pHandle, "TTY:E",-1) ) <0)
p_panic(result);
}
/* Set up serial port characteristics */
p_iow (pHandle, P_FSENSE, &srChar) ;
srChar.hand=P_IGN_CTS;
p_iow (pHandle, P_FSET, &srChar) ;
buffer[0]='\0';
onebyte=1;
do
{
/* Display menu on screen */
p_printf(" BAR CODE SCANNER") ;
p_printf("%s",buffer) ;
p_printf("\npress V for Version,");
p_printf Le X to eXit");
p_printf (* or any other key");
p_printf Cy to scan a label");
reply=p_tofold(p_getch());
if (reply=='V')
p_write (pHandle, "\033-y1S",5);
if (reply!='X"')
{ /* Read input from the bar code interface */
len=0;
do
{
p_iow (pHandle, P_FREAD, &buffer[len],é&onebyte) ;
} while (buffer[lent+]!=13 && len<MAX_STRING) ;
len--;
buffer [len]=0;
p_sound (5,300);
}
14 - 20
14 HC INTELLIGENT BAR CODE READER/RS232 PORT
if (reply!='X"')
{
if (reply!='V')
p_printf ("CODE %s",buffer) ;
else
{
p_printf(" Version:\n &$s",buffer);
p_printf("Press key to continue");
p_getch();
}
}
} while (reply !='X');
p_close (pHandle) ;
return (0);
}
14-21
CHAPTER 15
INTRODUCTION TO PSION
INFRARED COMMUNICATIONS
Note: This document is a beta version and may be subject to change.
About this chapter
The use of infrared (IR) as a medium allows devices to communicate without using a connecting cable.
The Psion Series 3c (S3c) and Psion Siena both run an Infrared Communications (“Beaming”)
application. This application sits on top of a communications protocol stack that implements the standards
set by the Infrared Data Association (IrDA), (see http://www.irda.org/irda/irdabout.html). These standards
specify both the physical and the link layer. This chapter describes the application programming interface
to the Psion implementation of the IrDA standards, and gives details of the standards only where relevant.
For a full understanding of infrared communications you should read the IrDA standards documents,
copies of which are downloadable from the IrDA website, (http://www. irda.org/irda/standrd.html). The
three relevant standards employed by Psion are tabulated below:
IrDA standard Communications layer
Serial Infrared Link Management Protocol (IrLMP) Network layer (OSI layer 3)
Serial Infrared Link Access Protocol (IrLAP) Data link layer (OSI layer 2)
Serial Infrared Physical Layer Link Specification (SIR) Physical layer (OSI layer 1)
The IrDA protocol layer model
Application Software
Client side Process
Boundary
Server side Transport entities
e.g. IrDA IR “Tiny” TP
IrDA Link Management Protocol Layer (IrLMP)
IrDA Link Access Protocol Layer (IrLAP)
IrDA Serial Infrared Layer (SIR)
The IrDA protocol stack
15-1
1/0 DEVICES REFERENCE
Introduction to Psion infrared communications
Important note:
The Psion S3a and Psion Siena IR ports are designed only for IDA compliant communication. They are
not suitable for communication with machines that use other standards.
The Psion protocol layer model
Application Software
C/OPL SDK Examples Psion IR Printing Psion IR Communications
Accesslr API
= “IRP” API
“IRP:”
. ; Accesslr : “AIR:”
Client side IPC
IrMUX API
Server side
Link Management Protocol Layer (IrLMP)
Link Access Protocol Layer (IrLAP)
Serial Infrared Layer (SIR)
The Psion infrared protocol stack
The physical layer
The Serial Infrared Device Driver (SIR) provides services to the layer above it (IrLAP), and directly
controls the Psion computers hardware.
Port geometry
The Psion serial infrared software supports a link between two machines from zero to at least one metre
apart as shown below. These machines can be two Psions (S3c or Siena) or a Psion and another device
such as a printer with an IrDA compliant interface. The ports on the two machines do not need be aligned
perfectly.
Infrared
Ports
Machine 1
Length of
link
Otoim
Machine 2
The port geometry for two machines using IrDA infrared communications
Internally the Psion IR port is configured as below:
15 -2
15 INTRODUCTION TO PSION INFRARED COMMUNICATIONS
lie a F Output i
Driver
Encoder & LED
Encoder/ IR
Decoder Transducer
Module Module
IR Receive Detector &
Condor chip
Psion Active
data bus Output
Interface
IR In
Decoder MH Receiver i Active
james Input
Interface
The internal organization of the Psion serial infrared
communications port
The Condor chip contains a UART which handles both standard wire based RS232 communications and
IR communications. The device is switched between these two modes and cannot handle both at the same
time.
Data transfer rate
The Psion serial infrared communications port operates at the standard IrDA speed of 9600 Baud. It can
also work at other speeds on the S3c and Siena, (these are optional to the IrDA standard):
Speed (Baud) S3c Siena
2,400 Yes Yes
9,600 Yes Yes
19,200 Yes Yes
38,400 Yes No
57,600 Yes No
115,200 Yes No
Data link layer
The IrDA data link layer protocol (IrLAP) is based on the standard asynchronous HDLC and SDLC half
duplex protocols.
It has the following extra features, (mostly to handle the mobile, ad-hoc nature of the medium):
e Extended addressing
e Dynamic address conflict resolution
e Extended error recovery mechanisms
e Dynamic station discovery/identification
e Extended connection setup, (so that stations can negotiate to establish the best connection speed
that both connecting machines can support)
e Any station can contend to become a primary station
e Extended rules for medium access, (to resolve contention between stations competing for control
of the medium).
IrLAP uses services provided by the physical layer (SIR), and provides services to the layer above it (ITLMP).
15 -3
I/O DEVICES REFERENCE
Primary and secondary stations
At any given instant there may be at most one IrLAP connection between a given pair of stations (IrDA
compliant machines). One of the machines must assume the role of IrLAP primary station while the other
must assume the role of IrLAP secondary station.
An IrDA primary station is a machine that takes responsibility for data flow control and for unrecoverable
data link errors.
An IrDA secondary station is any station that has an IrLAP connection active and that has not assumed
the role an IrLAP primary station.
IrLAP services
IrLAP provides two general types of services:
e Connectionless services
e Connection-oriented services
A connectionless service involves either the general broadcast of a message from a station, and/or the
general reception of a message by a station, without the necessity of identifying the other station (if any)
involved. Connectionless messages (datagrams) are sent with the expectation that they will be received
correctly; there is no acknowledgement of correct receipt. If a message is received incorrectly, a higher
layer must ask for re-transmission.
A connection-oriented service requires that both stations involved in the message transfer have knowledge
of the others characteristics. A logical session is set up between the primary and secondary station, and
there is acknowledgement that messages are correct.
The network layer
The IrDA Link Management Protocol (IrLMP) uses services provided by the data-link layer beneath it
(IrLAP) and provides services to clients above (i.e., transport entities and/or applications).
IrLMP consists of two parts, both of which are accessible by the Psion IrMUX API using IPC:
e LM-IAS (Link Management Information Access Service)
e LM-MUX (Link Management Multiplexer)
AccessIr is an API added by Psion to simplify IR communications - it is not part of the IrDA protocol
standard - and sits above IrLMP on the client side. It uses the AIR: device driver.
An application developer can choose to use either the API to AccessIr (recommended) or the API to
IrMUX. Whichever one is used the sequence of operations required to set up, use and close down an IR
link is similar.
For a connection-oriented service the link management process involves several stages:
e IAS application logging (secondary station)
e discovery (primary sation)
e §=multiplexing the link (primary sation)
e controlling the link (primary sation)
e closing down the link (primary sation)
IAS application logging
The IAS works by each IrDA device keeping a database of the services (IR enabled applications) that the
device currently has available. Applications must register with the IAS server on their station so that they
are added to this database. Software on one machine can then find out the services available on another
machine by querying the database of services on that machine. Applications can also remove themselves
from the IAS database.
15-4
Discovery
15 INTRODUCTION TO PSION INFRARED COMMUNICATIONS
Discovery is the process whereby the IrDA primary station sets up a database of the secondary stations
that are currently within IR communication range. This database is distinct from the IAS database.
Each record in the discovery log is a DISCovERY_LOG struct:
typedef struct
{
UINT solicited;
UINT sniff;
ULONG devAddr;
UINT lapVersion;
UBYTE info[32];
} DISCOVERY_LOG;
The piscovery_toe fields are:
solicited
sniff
devAddr
lapVersion
info
If TRUE, indicates that the discovered information was solicited by an explicit discovery
request by the host station. If FALSE, indicates that the discovered information was
unsolicited (i.e. responding to a previously received discovery XID CMD frame).
If TRUE, indicates that the remote (discovered) device is a sniffing device.
The remote (discovered) stations 32-bit device address.
The 16-bit IrDA version number of the remote (discovered) IrLap layer. Should hold oxoo
indicating that the remote machine conforms to the IrDA IrLAP 1.00 specification
32 bytes of user-defined data passed from the remote (discovered) station to the host
station. This discovery information is used by peer MUX layers for identification
purposes. At the current default baud of 9600, only 23 bytes of the discovery info field can
actually be used.
For a Psion machine info will contain the non-zero-terminated string “Psion Series3” or
“Psion Siena” for an S3c or Siena respectively.
The info field also contains the following bytes:
byte
2 bytes
Character set
Service hint
Indicates the character set supported by the remote machine; 0xoo here indicates
ASCII
Give an indication as to the level of IrLMP support provided by the discovered
device.
The service hint bitfields are as follows:
BYTEI1:
Bit
0
6
q
Function
PnP Compatible
PDA/Palmtop
Computer
Printer
Modem
Fax
LAN Access
Extension
6
7
Function
Telephony
File Server
IrCOMM
reserved
reserved
reserved
reserved
Extension
Full details can be found in the IrDA IrLAP specification.
15-5
I/O DEVICES REFERENCE
Multiplexing
Multiplexing the link allows independent applications (services) to exchange data using a single IrLAP
link. Software on one machine can discover the services available on another machine by querying the
database of services on that machine.
Link Control
Managing the use of the multiplexed link is called Link Control. This includes allowing certain client
applications to take exclusive control of the IrLAP link connection, (Exclusive mode).
The Psion IR Communications application
The Psion IR Communications application (sometimes called IR Beaming) uses the Psion Link Paste
mechanism when sending data, (see the Link Paste chapter in the OLIB Reference manual). The IR
Communications application takes whatever data was highlighted in the most recent application to declare
itself to be the Link Paste Server (or the selected file in a System Screen file list or directory), and uses
that as the data/file to send. Receiving data over IR works independently of the Link Paste mechanism.
Third party applications
Any existing application that supports the Link Paste mechanism will work with the Psion IR
Communications application to send data. In general this means that it must be an HWIM program,
because it uses the ATS mechanism. To modify an HWIM program so that it can use IR Receive:
e add the Bring keycode (21) to the accelerator list
e map the Bring keycode to the command manager method used to implement “bring”
functionality
It is much more involved to add IR Receive capability to non-HWIM applications, such as HWIF ones.
They could be made to explicitly look for the IPC messages relating to the Bring keycode, but this is not
SO easy.
System resources
A SYS_IR_POWER_LEVEL resource has been added, giving the text “High” and “Low” for Infrared power
levels.
A syYS_PRINTER_IR resource has been added, giving the text “Infrared” as a printer type.
Keypresses
Normally, IR-related keys are captured by the built-in IR data transfer application. If the user disables IR,
by selecting another mode of communication, these keypresses are absorbed by the ws_process_key
method of any applications instance of wsERv. As a general service to the user, the method also displays
an “Infrared not enabled” information message.
The ws_process_key method of the wsserv class performs the following additional action on the Series 3c:
e if the keypress is w_kEY_IR_LINK, 0x142 (which would normally be captured by the infrared
file/record transfer software) display an information message to the effect that Infrared is disabled
The ws_process_key method of the wserv class performs the following additional action on the Siena:
e if the keypress is one of w_kEY_IR_BRING, 0x140 Of W_KEY_IR_SEND, 0x141 (which would
normally be captured by the infrared file/record transfer software) display an information
message to the effect that Infrared is disabled.
15 INTRODUCTION TO PSION INFRARED COMMUNICATIONS
The IR printer port device driver
Psion Series 3c machines are capable of point and shoot printing using IR, to IrDA compliant printers.
Infrared enabled printers on the market at the time of writing include:
e HPLaserJet 5P
e ~=6HP DeskJet 340
e §6©Citizen PN60
The Psion IR printer port device driver rrp: is an example of a device driver that sits logically above AIR:
on the client side. It works in exactly the same way as the normal par: parallel port device driver. The
IRP: device driver automatically starts the IR protocol stack.
Siena models do not have the driver in ROM. The driver JRLPT.LDD is installed in \SIBOSDK\LIB as
part of the LDD component of the optional disk, to be loaded onto a Siena if required.
15-7
CHAPTER 16
THE ACCESSIR API
Note: This document is a beta version and may be subject to change.
Using the Accesslr API
Prerequisites
It is essential that the Introduction to Psion Infrared Communications chapter has been read before this
chapter.
Introduction to using the Accesslr API
The AccessIr API facilitates Infrared communication between two Psion machines (Series 3c and/or
Siena), using the AIR: device driver, accessir.ldd. This API is much easier to use than the IrMUX API,
but gives less flexibility. It is therefore recommended that the AccessIr API is used for all simple IR
communication applications. It is not present in the Siena ROM, but is installed in the \S/BOSDK\LIB
directory as part of the LDD component of the SIBO C SDK Optional disk, to be loaded onto a Siena if
required.
The AIR: device driver is not present in the ROM of Siena machines, and is 1.7KB in size. It must be
loaded first (after transfer onto the machines internal drive) by using:
p_loadldd(“ACCESSIR.LDD”)
The AIR: device driver must be unloaded at the end on the Siena using:
p_devdel (“ACCESSIR”, E_LDD)
Otherwise there are no differences between using the AccessIr API on the Siena and on the Series 3c.
Only a connection-oriented option is available.
AccessIr requires the IR protocol stack to be started first (as it must be when using the TMUX API).
There are then seven steps in the communication process for the primary station:
1. Open a channel to the AccessIr device driver
Discover and log the remote machines
Select a remote machine
Connect to the selected remote machine
Send or accept data
Disconnect
SP NE Ps, Ee IBS
Close the channel to its IR device
16-1
I/O DEVICES REFERENCE
There are five steps in the process for the secondary station:
1. Open achannel to the AccessIr device driver
2. Wait for the primary station to connect
3. Send or accept data
4. Optional Disconnect
5. Close the channel to the AccessIr device driver
In all the code examples and function call prototypes below, either p_iow(), p_ioa() Of p_ioc() may be
used where p_iow() is given. The constants used in the AccessIr API are defined in the p_file.h PLIB
include file.
Initialising the IR protocol stack
Before the IR protocol stack can be used it must be initialized, by doing a p_execc. The protocol stack is
started as a separate process.
The argument *name is sys$IRDA.1IMc in the example code segment below:
LOCAL_C HANDLE loadIRDAserver (TEXT *name)
{
INT err;
TEXT serverPath[P_FNAMESIZE];
HANDLE server_pid=NULL;
/* Start the IR process & store its server_pid in property */
if (E_FILE_NXIST==(server_pid=p_pidfind (name) ) )
{ /* Load from M, then from wherever we are... */
f_fparse (name, "LOC: :M:\\", &serverPath[0],NULL) ;
if ((server_pid=p_execc(&serverPath[0],
(UBYTE*) &Server_pid,
sizeof (server_pid) )) <0)
{
f_fparse (name, "ROM::\\",&serverPath[0],NULL) ;
if ((server_pid=p_execc(&serverPath[0],
(UBYTE*) &Server_pid,
sizeof (server_pid) )) <0)
{ /* Error...no irda! */
return (0);
}
}
if (0!=(err=p_presume (server_pid) ) )
return (0);
}
p_sleept (5L); /* Give IRDA a chance to get going! */
return (server_pid);
}
Opening and closing a channel to the IR device
Before a connection can be made, a channel must first be opened to the IR device using p_open(*AIR:”).
This channel must be closed when IR operations have ceased, using p_close().
Example
if (!p_open(&pIR,”AIR:”,0) )
{
p_close(pIR);
}
Discovery
Secondly, a log must be obtained of all remote machines that it is possible to communicate with, using
p_iow (P_FIRDISCOVER) .
Selection
The machine to connect to is then selected from the log, using p_iow (P_FIRSELECT).
16-2
16 THE ACCESSIR API
Connection
Connection is then made by the primary station to the selected secondary station, using
p_iow (P_FIRMAKECONNECT). The secondary station sends a zero terminated string of up to 56 bytes of
connect data to the primary station, when the connection is accepted.
The remote machine must be awaiting connection; it is put in this state by using
p_iow (P_FIRAWAITCONNECT). The primary station then sends a zero terminated string of up to 56 bytes of
connect data to the secondary station when connection is successful.
Sending and accepting data
The primary station may then either send data, using p_iow(P_FWRITE), or accept data from the secondary
station using p_iow(P_FREAD).
Likewise the secondary station may either accept data from the primary station, using p_iow(P_FREAD), OF
send data using p_iow(P_FWRITE).
Disconnection
Once data transfer is complete the connection between the two stations must be discontinued by the
primary station or secondary station, using p_iow(P_FIRDISCONNECT).
Constants
The constants used in the function calls below have the following numerical equivalents:
P_FREAD 1
P_FWRITE
P_FIRDISCONNECT
P_FIRDISCOVER
P_FIRSELECT
2
4
P_FITRAWAITCONNECT 5
6
i
8
P_FIRMAKECONNECT
Opening and closing a channel to the IR device
p_open(“AIR:”) Open a channel to the IR device
INT p_open(VOID *pcb,”AIR:”,0);
Open a channel to the IR device, (IrDA Open function).
If successful the port will be powered up.
Arguments
VOID *pcb Handle
“AIR:” Device name
0 Mode
Return value
INT Zero if the channel was opened successfully; else a
negative error code
Possible errors include:
E_GEN_INUSE Port in use by another client
E_GEN_NOMEMORY Insuffient memory to make connection
16 -3
1/0 DEVICES REFERENCE
Example
if (!p_open(&pIR,”AIR:”,0) )
{
is cies (pIR) ;
}
p_close Close a channel to the IR device
INT p_close(VOID *pcb) ;
Close an open channel to the IR device, (IrDA Close function).
The internal receive data buffer is flushed. If a frame of data is currently being transmitted then
transmission is completed before closure. The transmit data buffer becomes empty. Any outstanding IR
driver read or write requests are cancelled.
Arguments
VOID *pcb Handle
Return value
INT Zero
Example
p_close (pcb) ;
Discovery, selection and connection
p_iow(P_FIRDISCOVER) Discover IR enabled machines
INT p_iow(VOID *pcb,P_FIRDISCOVER, VOID *buf,UWORD *pNslots) ;
Obtain the log of remote machines, (IrDA Discover function).
Arguments
VOID *pcb Handle
P_FIRDISCOVER IR service
VOID *buf Buffer to receive discovery list; on return
contains the list of machines found
UWORD *pNslots Pointer to word containing the number of slots; on
return contains the number of machines found
Return value
INT Maximum number of machines to find
Example
p_iow (pcb, P_FIRDISCOVER, Buffer, pNslots) ;
p_iow(P_FIRSELECT) Select remote machine to connect to
INT p_iow(VOID *pcb,P_FIRSELECT,VOID *Address) ;
Select a machine to connect to, (IrDA Select function).
Arguments
VOID *pcb Handle
P_FIRSELECT IR service
VOID *Address Pointer to long containing machine address
16-4
16 THE ACCESSIR API
Return value
INT Zero
Example
p_iow (pcb, P_FIRSELECT, &Address) ;
p_iow(P_FIRMAKECONNECT) Connect to selected machine
INT p_iow(VOID *pcb,P_FIRMAKECONNECT, TEXT *pname,VOID *buf[0]);
Connect to the selected remote machine, IrDA Make Connect function), where pname points to a string
containing the name of the application to connect to.
Arguments
VOID *pcb Handle
P_FIRMAKECONNECT IR service
TEXT *pname Name of application to connect to. This is a
zero terminated string, maximum 25 characters
long (excluding terminator).
VOID *buf [0] Zero terminated string. On return contains up
to sixty bytes of connect data from remote
machine, if successful
Return value
INT Maximum data send size or negative error
Example
Either p_iow(), p_ioc() OF p_ioa() can be used, e.g.:
p_iow (pcb, P_FIRMAKECONNECT,”Bobs Chat program”, &Buffer[0]);
IOW (Handle%, 8, #UADD (ADDR (Name$) , 1) , }UADD (ADDR (Buf fer$) , 1) )
Note: contents of Name$ and Buffer$ must be zero terminated
p_iow(P_FIRAWAITCONNECT) Wait for remote connect (primary)
INT p_iow(VOID *pcb,P_FIRAWAITCONNECT, TEXT *pname,VOID *buf[0]);
Wait for a remote machine to connect as the primary station, IrDA Accept Connection function), where
pname points to a string containing the name of the application to connect to on the local machine.
Arguments
VOID *pcb Handle
P_FIRAWAITCONNECT IR service
TEXT *pname Name of your application
VOID *buf[0] Zero terminated string. On return contains up
to 56 bytes of connect data from remote
machine, if successful
Return value
INT Maximum data send size or negative error
Example
Either p_iow(), p_ioc() OF p_ioa() can be used, e.g.:
p_iow (pcb, P_FIRAWAITCONNECT,”Bobs Chat program”, &Buffer[0]);
16-5
1/0 DEVICES REFERENCE
Send and accept data
p_iow(P_FREAD)
Accept data from selected remote machine
INT p_iow(VOID *pcb,P_FREAD,VOID *Data[0],UWORD *Length) ;
Accept data from the remote machine (IrDA Read function).
Arguments
VOID *pcb
P_FREAD
VOID *Data[0]
UWORD *Length
Return value
INT
Example
Handle
IR service
Buffer to receive data
Pointer to word to receive data length. On
return contains the amount of data received
Zero or negative error,
Either p_iow(), p_ioc() OF p_ioa() can be used, e.g.:
p_iow (pcb, P_FREAD, &Data[0],&Length) ;
p_iow(P_FWRITE) Send data to the selected remote machine
INT p_iow(VOID *pcb,P_FWRITE, VOID *Data[0],UWORD *Length) ;
Send data to the remote machine (IrDA Write function).
Arguments
VOID *pcb Handle
P_FWRITE IR service
VOID *Data[0]
UWORD *Length
Buffer of data to be sent
Pointer to word to containing data length
Return value
INT Zero or negative error
Example
Either p_iow(), p_ioc() OF p_ioa() can be used, e.g.:
p_iow (pcb, P_FWRITE, &Data[0],&Length) ;
SSS SSS SS |
Disconnection
p_iow(P_FIRDISCONNECT) Disconnect from remote machine
INT p_iow(VOID *pcb,P_FIRDISCONNECT) ;
Disconnect from the connected remote machine and cancel all requests, (IrDA Disconnect function).
Arguments
VOID *pcb Handle
P_FIRDISCONNECT IR service
Return value
INT Zero or negative error,
Example
p_iow (pcb, P_FIRDISCONNECT) ;
IOW (Handle%, 4, #0, #0)
16 - 6
16 THE ACCESSIR API
Example application
The following application allows one Psion machine to act like a sending teletype (constantly queueing IR
write calls) and another Psion to act like a receiving teletype (constantly queueing IR read calls).
/* MODULE - ACCESSIR.C
Copyright (C) Psion PLC 1995/6
*/
include <plib.h>
ifndef EPOC
GLREF_D P_DEVICE p_serial,p_file,p_keyb,p_timer;
endif
LOCAL_D VOID *pIr;
LOCAL_D UBYTE buf[256];
LOCAL_D TEXT connData[64]=" ";
LOCAL_D TEXT printstring[24]="Welcome to IR printing!";
LOCAL_D UWORD slots;
LOCAL_D INT readlen,writelen,ret,i;
LOCAL_D UBYTE devName [24];
LOCAL_D ULONG devAddr;
LOCAL_C HANDLE LoadIrdaServer (TEXT *name)
INT err;
TEXT serverPath[P_FNAMESIZE];
HANDLE serverPid=NULL;
/* Start the IRDA stack as a separate process and store its pid */
p_printf ("Trying to start %s",name) ;
if ((serverPid=p_pidfind(name) ) ==E_FILE_NXIST)
{/* Try to load irda from M first */
f_fparse (name, "LOC: :M:\\", &serverPath[0],NULL) ;
if ((serverPid=p_execc(&serverPath[0],
(UBYTE *)&serverPid, sizeof (serverPid) ) ) <0)
{/* Try to load irda from ROM */
f_fparse (name, "ROM::\\",&serverPath[0],NULL) ;
if ((serverPid=p_execc(&serverPath[0],
(UBYTE *)&serverPid, sizeof (serverPid) ) ) <0)
{/* Error ! No irda */
return (0);
}
}
if ((err=p_presume (serverPid) ) <0)
return (0);
}
p_sleept (5L); /* Give irda a chance to get going */
return (serverPid) ;
}
LOCAL_C VOID PrintMenu ()
{
D2 PLEINCE (MAREE ARE RES REA A ERIN) 7
p_printf ("Press \'p\' to make station primary");
p_printf ("Press \'s\' to make station secondary");
p_printf ("Press \'q\' to quit");
Pp DLLME ECU AREER EAR ARR RRR EAE HRI MY ;
}
16-7
1/0 DEVICES REFERENCE
LOCAL_C INT DiscoverDevices ()
{
p_printf ("Doing a discovery");
slots=6;
p_iow(pIr, 6, &buf[0],&slots); /* P_FIRDISCOVER */
p_printf ("Devices found = %d",slots);
if (slots>0)
{/* We have discovered at least one device */
devAddr= *((ULONG *) (&buf[4]));
/* Discovery nickname is last 23 bytes of info */
p_bcpy (devName, &buf[12],23);
i=0;
while (devName[i]>=0x20 && i<23)
itt+;
devName[i]='\0';
p_printf ("Remote devAddr = 0x%08X",devAddr) ;
p_printf ("Remote device = %s",devName) ;
return (0);
}
else
p_printf ("Trying again");
return (-1);
LOCAL_C INT ConnectToFirstDevice()
{
p_printf ("Selecting machine");
ret=p_iow(pIr,7,&devAddr); /* P_FIRSELECT */
p_printf ("Connecting to machine %08X",devAddr) ;
if ((ret=p_iow(pIr,8,"Test",&connData[0]) ) <0) /* P_FIRMAKECONNECT */
{
p_printf("Connect failed with ret = %d",ret);
p_getch();
return (0);
}
p_printf ("Successfully connected machine") ;
}
LOCAL_C VOID TransmitData()
{
INT ret;
p_printf ("Writing keypresses to IR port - ESC to cancel");
writelen=1;
while ((ret=p_getch()) !=27)
{/* OK as long as not escape */
buf [0]=ret;
p_iow(pIr,2, &buf[0],&writelen) ; /* P_FWRITE */
p_print ("%s", &buf[0]);
}
LOCAL_C INT WaitForConnect ()
{
INT ret;
p_printf ("Connecting as a secondary");
if ((ret=p_iow(pIr,5,"Test",&connData[0])) <0) /* P_FIRAWAITCONNECT */
{
p_printf ("Wait for connect failed with ret = %d",ret);
p_getch ();
return(-1);
}
p_printf ("Accepted a connection");
}
16-8
16 THE ACCESSIR API
LOCAL_C INT ReadData()
{
readlen=1;
if ((ret=p_iow(pIr,1,é&buf[0],&readlen) ) <0) /* P_FREAD */
{
p_printf ("Error on reading");
if (ret==DisconnectErr)
p_printf ("Primary has disconnected") ;
return (ret);
}
p_print ("%s", &buf[0]);
return (1);
}
LOCAL_C VOID Disconnect ()
p_printf ("Disconnecting") ;
p_iow(pIr,4); /* P_FIRDISCONNECT */
GLDEF_C INT main(VOID)
TEXT servername[20]="SYSSIRDA.IMG";
#ifndef EPOC
p_inst (&p_file, &ép_serial, &p_keyb, &p_timer, NULL) ;
#endif
p_printf("Psion Software (c) October 1996");
PUPBENEL (MAA AAAAAAAK AAA RAK AKA RAK KAA RA RAK ARE RARE ) -
p_printf("Starting simple AccessIr beaming app");
if ((ret=LoadIrdaServer (servername) ) ==NULL)
{
p_printf ("Problem loading Irda stack");
p_getch();
return (0);
}
p_printf ("Successfully kicked open the irda stack as separate process");
if ((ret=p_open(&pIr, "AIR:",-1)) <0)
{
p_printf ("Cannot open AccessIr driver ret = %d",ret);
p_getch();
return (0);
}
p_printf ("Successfully opened AccessIr driver");
startLoop:
PrintMenu () ;
ret=p_getch();
switch (ret)
{
case 'p!:
case 'P';
/* PRIMARY STATION - TRANSMITTER */
if ((ret=DiscoverDevices ()) <0)
goto startLoop;
ConnectToFirstDevice () ;
TransmitData();
Disconnect ();
break;
16-9
1/0 DEVICES REFERENCE
case 's!':
case 'S':
/* SECONDARY STATION - RECEIVER */
if ((ret=WaitForConnect () ) <0)
break;
while ((ret=ReadData())>0)
/* Keep reading until failure */ ;
break;
case 'q':
case 'Q':
p_printf ("Terminating program") ;
break;
default:
goto startLoop;
break;
}
p_close(pIr); /* This also kills the IrDA process */
p_printf("End of program — Hit key to esc");
p_getch();
return (0);
}
16 - 10
CHAPTER 17
THE IRMUX API
Using the IrMUX API
Prerequisites
It is essential that the Introduction to Psion Infrared Communications chapter has been read before this
chapter.
Introduction to using the IrMUX API
The IrMUX API facilitates Infrared communication between two Psion machines (Series 3c and/or Siena).
This section explains how to use each call that can be made to the IrMUX server using IPC on a SIBO
(EPOC/16) based computer system. This API is more difficult to use than the AccessIr API, but
potentially gives more flexibility. For simple IR communication applications it is recommended that the
AccessIr API is used.
With the IrMUX API connectionless or connection-oriented calls are available.
This set of protocols uses machine addresses and port IDs (rather than application names as for the
AccessIr API).
The packets of data used must be exactly the right size, there is no error correction and there is no
guarantee of transfer.
Initialising the IR protocol stack
Before the IR protocol stack can be used it must be initialized, by doing a p_execc. The protocol stack is
started as a separate process. This is done in exactly the same way as when using the AccessIr API. When
the last application has logged off, the protocol stack will clean up and terminate itself automatically.
17-1
I/O DEVICES REFERENCE
The argument *name is SySSIRDA. IMG in the example code segment below:
LOCAL_C HANDLE loadIRDAserver (TEXT *name)
{
INT err;
TEXT serverPath[P_FNAMESIZE];
HANDLE server_pid=NULL;
/* Start the IR process & store its server_pid in property */
if (E_FILE_NXIST==(server_pid=p_pidfind (name) ) )
{ /* Load from M, then from wherever we are... */
f_fparse (name, "LOC: :M:\\", &serverPath[0],NULL) ;
if ((server_pid=p_execc(&serverPath[0],
(UBYTE*) &server_pid,
sizeof (server_pid) ) ) <0)
{
f_fparse (name, "ROM::\\",&serverPath[0],NULL) ;
if ((server_pid=p_execc(&serverPath[0],
(UBYTE*) &Server_pid,
sizeof (server_pid) )) <0)
{ /* Error...no irda! */
return (0);
}
}
if (0!=(err=p_presume (server_pid) ) )
return (0);
}
p_sleept (5L); /* Give IRDA a chance to get going! */
return (server_pid);
}
Logging on to and logging off from the IrMUX server
Before an application can use IrMUX services it must log on. When it has finished it must log off.
Logging on to the IrMUX server
The LM_Logon function call is used to log on to the ITMUX server.
Logging off from the IrMUX server
The tm_Logof¢ function call is used to log off from the IrMUX server.
Registering/unregistering applications with the LM-IAS server
This is independent of the process of sending or receiving data. An application can either:
e register iself in the LM-IAS database
¢ unregister iself from the LM-IAS database
Registering the port with the LM-IAS server
The tM_RegisterPort function call is used to register the application with the LM-IAS server.
Unregistering the port with the LM-IAS server
The LM_UnRegisterPort function call is used to unregister the application with the LM-IAS server.
LM-IAS services
The LM_GetValueByClass message has not been implemented as a direct IPC service, but an IAS Get
Value By Class frame must be passed from the LM-IAS server of the primary station to the LM-IAS
server of the secondary station. The secondary station replies with another specially formatted frame of
data.
The LM-IAS server on a remote machine is reached by starting a connection to the remote machine,
(using the LM_connectRequest function), with a remote port of zero.
17-2
17 THE IRMUX API
The IAS Get Value By Class service can only be used with a connection to a remote LM-IAS server.
Direct read and write access to a remote LM-IAS port has not been blocked in order to allow future
expansion. A client should not attempt to send frames directly to a remote LM-IAS connection (other than
the Get Value By Class message) without a full understanding of the implications of such actions.
Developers should study the IrDA IrLMP specification.
The IAS Get Value By Class message frame
The format of the frame that must be sent from the primary station is:
byte 0x84
byte name length
n bytes application name, not including zero terminator
byte 0x12
byte “IrDA: IrLMP:LsapSel”
The IAS Get Value By Class reply frame
The format of the frame returned by the LM-IAS server on the secondary station is:
byte AND with ox3r and compare with 4; if not equal to 4, failed
byte 0
byte non-zero
byte dont care
byte dont care
byte dont care
byte 1
byte 0
word 0
byte port number
Connectionless calls
Data may either be sent or received in a connectionless manner. This process involves one step:
e Queue a connectionless read or write request
The first application to read the transmitted data is the one that gets it.
Reading and writing data
The LM_cLReadRequest function call is used to queue a connectionless read request.
The LM_cLwriteRequest function call is used to queue a connectionless write request.
Connection-oriented calls
The steps in the process for a secondary station are:
1. Register the application with the secondary stations LM-IAS server
2. Wait for the primary station to connect
The steps in the process for a primary station are:
1. Discover and log the remote machines
2. Connect to the LM-IAS server on the selected remote machine
3. Ask for a particular registered application (by preparing and sending a LM_GetvalueByClass
message)
4. Wait for the reply (the secondary station returns a port ID for the required application)
5. Close the LM-IAS connection
17-3
I/O DEVICES REFERENCE
6. Reconnect using the port ID previously returned for the required application on the
secondary station
7. Send or accept data (either reliably or unreliably)
8. Disconnect
Discovery
The LM_DiscoverDevicesRequest function call is used by the primary station to return information about
machines within transmission range.
Connection - first time
The bm_connectRequest function call is used by the primary station (with a remote port of zero) to
attempt to connect to the LM-IAS server of the remote machine.
If successful the primary station sends an IAS Get Value By Class frame to the secondary station. The
secondary station sends back a frame containing the ID of the port for the application required (previously
registered by the secondary station with its LM-IAS server).
Disconnecting - first time
The LM_DisconnectRequest function call is used by the primary station to disconnect the two
communicating machines, before subsequent reconnection.
Connection - second time
The bm_connectRequest function call is used by the primary station to attempt to re-connect to the remote
machine, using the port ID for the required application, returned previously.
Reading and writing data
Reading and writing data may be done either reliably or unreliably. If unreliable red/write is used then the
data is only sent once.
The LM_ReadRequest function call is used to queue a connection-oriented read request.
The LM_writeRequest function call is used to queue a connection-oriented write request.
The tM_UReadRequest function call is used to queue an unreliable connection-oriented write request.
The bM_UwriteRequest function call is used to queue an unreliable connection-oriented write request.
Disconnecting - second time
The bM_DisconnectRequest function call is used by the primary station to disconnect the two
communicating machines.
Using Exclusive mode
If an application on the primary station wants to be sure of control over the link then it should use
Exclusive mode. A call to bM_AccessModeRequest gives exclusive access to ITMUX. This means that only
that one application can talk, and all other applications are blocked.
If you want to stop other applications from placing IrMUX into Exclusive mode, then the connection
(which always starts in Idle mode) can be put into Active mode, by using the LM_IdleRequest function
call. This should only be done during critical periods of communication. The connection should be put
back in Idle mode when the critical period has finished, by using another call to LM_tdleRequest.
When in Exclusive mode, if the client application is not responding to incoming data quickly enough, the
number of retries to be used on each data frame can be changed (from the default of 1), using the
LM_SetHandshakingLevel function call. The number of retries must be set back to 1 when IrMUX leaves
Exclusive mode.
When exclusive use of IrMUX is no longer required, another call to bm_AccessModeRequest should be
made.
The current status of the link can be found with a call to tM_statusRequest.
17-4
17 THE IRMUX API
The IrMUX API
IrMUX message format
The muxmessace struct has the format shown below.
typedef struct
{
E_MESSAGE Mess; // Message Control
VOID * MessConn; // Connection Handle
VOID * MessArgl; // Argument 1
VOID * MessArg2; // Argument 2
UINT MessArg3; // Argument 3
} MUXMESSAGE
The £_messace struct has the format shown below.
typedef struct message
{
struct message next;
UBYTE *status;
UINT type; // Message Number
HANDLE pid;
} E_MESSAGE;
The Message Number specified for each function below should be used as the type 1n an E_MESSAGE
struct, itself used as the mess field of a muxmEssacE struct.
Argument 1, Argument 2 and Argument 3 refer to the three muxmessace fields MessArg1, MessArg1 and
MessArgl.
For a full description of how to use these structs with the server function p_mreceive, see the chapter
Processes and Inter-Process Messaging in the PLIB Reference manual, and also the chapter Inter-Process
Communication in the OLIB Reference manual.
Unless specified below the argument values are unchanged when the function call returns.
Errors from IrLAP (returned in the status element of the z_messace struct) are documented in the IrDA
Serial Infrared Link Access Protocol (IrLAP) standard document.
LM_Logon Log on to the IrMUX server
Message Number 1
Use this function call to log on to the IrMUX server.
LM_Logoff Log off from the IrMUX server
Message Number 2
Use this function call to log off from the ITMUX server. This will stop any connections still held open by
the client.
LM_RegisterPort Register a port number with the LM-IAS server
Message Number 10
Use this function call to register an application with the LM-IAS server.
The application name must be less than twenty five characters in length and zero terminated.
17-5
1/0 DEVICES REFERENCE
Arguments
Connection Handle Pointer to a vorp*; on return contains the LM-
IAS entry handle
Argument 1 Pointer to a buffer containing the application
name
Argument 2 Irrelevant
Argument 3 The port number
Value of status in the E_MESSAGE struct on return:
OKAY Register successful
E_GEN_NOMEMORY No memory to complete request
E_GEN_RANGE Errors from IrLAP
LM_UnRegisterPort Free registered port with LM-IAS server
Message Number 11
Use this function call to free a registered port number with the LM-IAS server.
Arguments
Connection Handle Entry handle
Argument | Pointer to buffer containing class name
Argument 2 Irrelevant
Argument 3 Irrelevant
LM_CLReadRequest Queue a connectionless read request
Message Number 4
Use this function call to queue a connectionless read request.
It should be noted that in the case of all reads, if a frame is received which is longer than the requested
data size the frame will be truncated and data will be lost. If a received frame is smaller than the length
requested the actual amount of data received will be placed into the urnt pointed to by argument2.
Arguments
Connection Handle Irrelevant
Argument | Pointer to a buffer to receive the data; on return
contains the received data
Argument 2 Pointer to a uInT containing the number of
bytes required; on return the urnt contains the
actual amount of data returned
Argument 3 Irrelevant
Value of status in the = _mMEeSSAGE Struct on return:
OKAY Read complete
E_GEN_INUSE Read already queued
E_MUX_ABORT IrMUX has been destroyed
17 - 6
LM_CLWriteRequest
Message Number 5
17 THE IRMUX API
Queue a connectionless write request
Use this function call to queue a connectionless write request.
Arguments
Connection Handle
Argument 1
Argument 2
Argument 3
Value of status in the E_MESSAGE struct on return:
OKAY
E_GEN_NOMEMORY
(various)
LM_DiscoverDevicesRequest
Message Number 6
Irrelevant
Pointer to a buffer containing the data to send;
Pointer to a uInT containing the number of
bytes to send
Irrelevant
Write successful
No memory to complete request
Errors from IrLAP
Return info on in-range machines
Use this function call to return information about machines within transmission range.
IrMUX will either instruct IrLAP to perform a discovery operation or will return the results of a previous
discovery.
Arguments
Connection Handle
Argument 1
Argument 2
Argument 3
Value of status in the E_MESSAGE struct on return:
MUX_DISCOVERY_COMPLETE
MUX_CACHE_USED
E_GEN_NOMEMORY
E_MUX_ABORT
LM_ConnectRequest
Message Number 9
Irrelevant
Pointer to a buffer of size at least
slots*sizeof (DISCOVERY_LOG) ; on return
contains the discovery log
Pointer toa urnT containing the number of
slots; on return contains the number of
discoveries
Irrelevant
Discovery complete
Results of previous discovery used
Could not complete request
IrMux has been destroyed
Attempt to connect to a remote machine
Use this function call to attempt to connect to a remote machine. Supplying a home Port number of -1 will
cause IrMUX to generate one for you. A remote port number of zero is used to connect to the remote LM-
IAS server. See the appropriate IrDA IrLAP document for details of the connect_stRuct and how to set
port numbers and other connection parameters.
17-7
1/0 DEVICES REFERENCE
Arguments
Connection Handle Pointer to a vorp* to receive the connection
handle on return
Argument | Pointer to a CONNECT_STRUCT containing
connect parameters; on return the
CONNECT_STRUCT contains the actual connection
parameters
Argument 2 Pointer to a buffer of 60 bytes of connection
data; on return the buffer contains connection
data from the other machine
Argument 3 Irrelevant
Value of status in the E_MESSAGE struct on return:
OKAY Connection complete
E_GEN_NSUP Unsupported parameters or port number
E_GEN_INUSE Port number in use by another client
E_MUX_BUSY A discovery is in process
E_MUX_EXCLUSIVE Another connection already has exclusive
access to IrMUX
E_GEN_NOMEMORY Insuffient Memory to make connection
E_MUX_REMOTEDISCONNECT Remote forced disconnection
E_MUX_TIMOUTDISCONNECT Forced disconnection, timout
E_MUX_LOGOFFDISCONNECT Forced disconnection, client logoff
E_MUX_USERDISCONNECT User cancelled connection
E_MUX_LAP IrLAP cannot complete this request
LM_WaitForConnection Wait for remote machine to connect
Message Number 8
Use this function call to get a remote machine to wait for connection through a specified port number.
Arguments
Connection Handle Pointer to vorp* to receive connection handle
on return
Argument | Pointer to a CONNECT_STRUCT containing
connect parameters; on return the
CONNECT_STRUCT contains the actual connection
parameters
Argument 2 Pointer to a buffer of 60 bytes of connection
data; on return the buffer contains connection
data from the other machine
Argument 3 Irrelevant
17-8
Value of status in the E_MEeSSAGE Struct on return:
OKAY
E_GEN_NSUP
E_GEN_INUSE
E_GEN_NOMEMORY
E_MUX_REMOTEDISCONNECT
E_MUX_TIMOUTDISCONNECT
E_MUX_LOGOFFDISCONNECT
E_MUX_USERDISCONNECT
LM_StatusRequest
Message Number 21
17 THE IRMUX API
Connection complete
Unsupported parameters or port number
Port number in use by another client
Insuffient memory to make connection
Remote forced disconnection
Forced disconnection, timout
Forced disconnection, client logoff
User cancelled connection
Return the status of the link
Use this function call to return the status of the link and where abouts IrLAP is holding un-ACKed data.
Arguments
Connection Handle
Argument 1
Argument 2
Argument 3
Value of status in the E_MESSAGE struct on return:
OKAY
E_MUX_NOCONNECTION
LM_ReadRequest
Message Number 24
Connection handle
Pointer to an rntT to hold the link quality on
return
Pointer to an int to hold the number of un-
ACKed frames on return
Irrelevant
Request complete
Connection handle invalid or connection
removed by other end
Queue a read request on a connection
Use this function call to queue a read request on a connection.
This function will panic the client process if a read is already queued on that connection.
Arguments
Connection Handle
Argument 1
Argument 2
Argument 3
Connection handle
Pointer to a buffer to receive the data on return
Pointer to a uINT containing the number of
bytes required; on return the urnt contains the
amount of data returned
Irrelevant
17-9
1/0 DEVICES REFERENCE
Value of status in the = _mMesSAGE Struct on return:
OKAY Read complete
E_MUX_REMOTEDISCONNECT Remote forced disconnection
E_MUX_TIMOUTDISCONNECT Forced disconnection, timout
E_MUX_LOGOFFDISCONNECT Forced disconnection, client logoff
E_MUX_USERDISCONNECT User cancelled connection
E_MUX_NOCONNECTION Connection handle invalid or connection
removed by other end
E_MUX_ABORT IrMUX has been destroyed
LM_WriteRequest Queue a write request on a connection
Message Number 25
Use this function call to queue a write request on a connection.
The maximum length of a data frame that can be sent is returned as part of the connection
parameters from a connect request. Do not exceed this length.
Arguments
Connection Handle Connection handle
Argument | Pointer to a buffer containing the data to send
Argument 2 Pointer to a uInT containing the number of
bytes to send
Argument 3 TRUE if more data is to follow
Value of status in the = _mMesSAGE Struct on return:
OKAY Write successful
E_GEN_NOMEMORY No memory to complete request
E_MUX_NOCONNECTION Connection handle invalid or connection
removed by other end
(various) Errors from IrLAP
LM_UReadRequest Queue an unreliable read request
Message Number 26
Use this function call to queue an unreliable read request on a connection.
In unreliable reading, data is sent only once.
This function will panic the client process if a read is already queued on that connection.
Arguments
Connection Handle Connection handle
Argument | Pointer to a buffer to receive the data on return
Argument 2 Pointer to a urnT containing the number of
bytes required; on return the urnt contains the
actual amount of data returned
Argument 3 Irrelevant
17 - 10
17 THE IRMUX API
Value of status in the = _mMesSSAGE Struct on return:
OKAY Read complete
E_MUX_REMOTEDISCONNECT Remote forced disconnection
E_MUX_TIMOUTDISCONNECT Forced disconnection, timout
E_MUX_LOGOFFDISCONNECT Forced disconnection, client logoff
E_MUX_USERDISCONNECT User cancelled connection
E_MUX_NOCONNECTION Connection handle invalid or connection
removed by other end
E_MUX_ABORT IrMUX has been destroyed
LM_UWriteRequest Queue an unreliable write request
Message Number 27
Use this function call to queue an unreliable write request on a connection.
In unreliable writing, data is sent only once.
Arguments
Connection Handle Connection handle
Argument | Pointer to a buffer containing the data to send
Argument 2 Pointer to a uInT containing the number of
bytes to send
Argument 3 TRUE if more data to follow
Value of status in the = _MESSAGE Struct on return:
OKAY Write successful
E_GEN_NOMEMORY No memory to complete request
E_MUX_NOCONNECTION Connection handle invalid or connection
removed by other end
(various) Errors from IrLAP
LM_AccessModeRequest Obtain/release exclusive access
Message Number 22
Use this function call to obtain/release exclusive access to ITMUX.
Arguments
Connection Handle Connection handle
Argument 1 LM_ExclusiveMode to obtain exclusive access or
LM_Mult iplexMode to release exclusive access
to IrMUX
Argument 2 Irrelevant
Argument 3 Irrelevant
17-11
1/0 DEVICES REFERENCE
Value of status in the = _MESSAGE Struct on return:
OKAY Request complete
E_GEN_MEMORY Not enough memory to complete the request
E_GEN_INUSE Unable to enter exclusive mode
E_MUX_BUSY Another client is attempting to enter exclusive
mode
E_MUX_EXCLUSIVE Another client already has exclusive access
E_MUX_NOCONNECTION Connection handle invalid or connection
removed by other end
E_MUX_ABORT IrMUX is being destroyed
E_GEN_NSUP Argument | does not contain either
LM_ExclusiveMode Of LM_MultiplexMode
E_MUX_REMOTEDISCONNECT Remote forced disconnection
E_MUX_TIMOUTDISCONNECT Forced disconnection, timout
E_MUX_LOGOFFDISCONNECT Forced disconnection, client logoff
E_MUX_USERDISCONNECT User cancelled connection
LM_IdleRequest Place the connection into Idle/Active mode
Message Number 23
Use this function call to place the connection into Idle/Active mode.
This implementation does not follow the IrMUX specification in that communication can be carried out in
both Active and Idle modes. Being in active mode simply acts as a block to other clients placing IIMUX
into Exclusive mode.
A connection always starts in Idle mode. To stop other clients gaining exclusive access to I1MUX by
entering Active mode, a client must put its own connection into Active mode. It is recommend that Active
mode is only used during critical periods of data communication.
Arguments
Connection Handle Connection handle
Argument 1 Irrelevant
Argument 2 Irrelevant
Argument 3 TRUE for Idle mode, ratse for Active mode
Value of status in the E_MESSAGE struct on return:
OKAY Mode change successful
E_MUX_BUSY Connection busy
E_MUX_NOCONNECTION Connection handle invalid or connection
removed by other end
LM_SetHandshakingLevel Set retries on each data frame
Message Number 28.
Use this function call to set the number of retries on each data frame, if the client application is not
responding to incoming data quickly enough.
This should only be enabled when in Exclusive mode. When use of exclusive mode has finished
LM_SetHandshakingLevel should be used to reset the number of retries to 1.
17 - 12
Arguments
Connection Handle
Argument 1
Argument 2
Argument 3
LM_DisconnectRequest
Message Number 20
17 THE IRMUX API
Connection handle
Irrelevant
Irrelevant
The number of times to resend each frame,
0 (zero) for inactive.
Disconnect
Use this function call to disconnect. This will cancel any requests on the connection.
Arguments
Connection Handle
Argument 1
Argument 2
Argument 3
Value of status in the = _mMEesSSAGE Struct on return:
OKAY
E_MUX_NOCONNECTION
E_MUX_BUSY
Connection handle
Irrelevant
Irrelevant
Irrelevant
Disconnect complete
Connection handle invalid or connection
removed by other end
IrMUX is busy. The application shoul wait a
short time and try again. May be ignored if
logging off.
17 - 13
CHAPTER 18
FAST CHARGER
Introduction
This chapter describes Fast Charger services for the HC and Workabout docking stations.
In this document the term Docking Station refers both to the HC docking station, (which connects to an
HC LIF interface fitted to the bottom of the HC), and to the Workabout docking station. The term
computer refers to an HC or Workabout.
Docking Station services
There are two variants of the docking station: one model has been designed for the HC computer and one
model has been designed for the Workabout computer. The docking station may be used to fast charge the
battery inside the "docked" computer.
The docking station Fcc: device driver may be used to charge (or discharge) the main battery under the
direct control of an HC/Workabout computer which has been inserted in the docking station holster. The
device driver may also be used to supply that computer with information about the battery charge status.
Notes:
1. the HC/Workabout docking station expansion port cannot be used whilst using the (Fcc:).
2. the HC/Workabout docking station will charge batteries without any external software
control from a docked computer.
See also the Cradle and Docking Station chapter for details of the cradle device driver crp:.
Using the Docking Station
Use of the Docking Station is complicated by the fact that one high speed serial channel is used to
communicate to three possible interfaces.
1. The interface in the bottom of the HC (1.e. Barcode, RS232 etc.)
2. The electronics in the device
3. Any expansion fitted to the device.
As a result of this, only one interface at a time can be opened on this channel, 1.e. either the RS232 in the
HC bottom expansion (port TTY:B) or the RS232 in the Docking Station expansion slot (port TTY:C).
HC/Workabout docking station fast charger services
The Fcc: device driver will allow a C application running on a machine in the docking station holster to
monitor and control the state of the docking station fast charger circuitry. The docking station is capable
of charging , discharging and performing a capacity check of the main battery inside the computer in a
variety of operating modes. It may also be used to charge (but not discharge) a spare battery installed in
the spare battery compartment of the docking station.
Important note: the fast charger circuit in the docking station will charge batteries automatically without
requiring any explicit calls to the rcc: device driver; only in a few circumstances should it actually be
18-1
I/O DEVICES REFERENCE
necessary to use FCG: (as described in this chapter) to give implicit instructions to the docking station. In
normal circumstances, it is not necessary to run software on the SIBO machine to control or monitor the
battery charging/discharging process.
There are two variants of the fast charger device driver, where each driver is tailored for use with one
specific SIBO computer and docking station. The fast charger device driver which may be used with an
HC computer is called sys$chgh.ldd; the fast charger device driver which may be used with a Workabout
computer is called sys$fchg.ldd. Both device drivers may be found in the path \sibosdk\lib\ on installation
of the relevant SIBO C Software Development Kit optional components onto your PC (from the /dd.zip
file).
The library file fcharge.h (located in the path \sibosdk\include\) contains C constant declarations which
may be used with either the sys$chgh.ldd or the sys$fchg.ldd device driver.
The fast charger does not allow a direct measurement of the status of each battery. As a result, the Fcc:
device drive will determine the status of each battery indirectly by measuring the charge pulses applied
by the charger circuitry to the battery pack over a short period of time. For this reason, some of the Fcc:
I/O operations may take a number of seconds to complete.
The fast charger device driver will only run if the Psion computer is resting in the docking station holster.
Fast charging batteries
The docking station may be used to charge the battery inside the "docked" computer, or a battery located
in the spare battery compartment on the top of the docking station. Only one battery pack can be charged
at any one time.
The fast charge circuitry possesses four modes of charging:
fast charge charge the battery pack with a preset current, and for a preset charge period (or
shorter, depending upon the charge status of the battery).
top off the battery pack is now 90-95% fully-charged; supply a lower current (typically C/10)
after completion of the fast charge, to fully-charge the cells
trickle charge supply a small charge current (typically C/30) to maintain the charge in a fully-
charged battery pack
discharge discharge the main battery at a fixed discharge current
If you wish to control the fast charger explicitly from a C program running on the "docked" Psion
computer, then the program should carry out the following steps:
1. open a channel to the fast charger device driver with the call p_open(voID **ppcb,
"PCG:A",-1);
2. set up the charge current and maximum charging time period with a call to
FCHG_SETCHARGEMODE (if this step is omitted, then default settings will be used).
3. instruct the device driver to charge the main battery (or the spare battery) with
FCHG_FASTCHARGEx. This command will commence the charging of the battery at a default
current and over a default time period.
4. close the channel to Fcc: with p_close (VOID *pcb)
Whilst the Fcc: channel is open, the C program may also monitor the progress of the charging process, if
required. Calls to FCHG_FASTCHARGEx may be omitted if the C program wishes only to monitor the progress
of the charging process.
The maximum charge time period set with a FCHG_SETCHARGEMODE call is used as a backup safety feature
to ensure that the fast charging process terminates before any damage can occur to the battery pack. For
this reason, it is essential that the charge time is set correctly, in relation to the charge rate which
you wish to use. The two main terminators used by the fast charge circuitry to detect the end of the
charging process are voltage and temperature slope. These two terminators are managed by the fast
charger hardware.
IMPORTANT: Never charge a standard Psion battery pack with a charge rate that exceeds 1C
without first contacting the battery supplier for advice. High charge rates in excess of 1C will
reduce the life of the battery pack and may create a risk of explosion or fire.
18 -2
18 FAST CHARGER
Measuring battery capacity
The Fcc: device driver may be used to determine the charge capacity of a battery pack. If the time taken to
fully-discharge a fully-charged battery pack is measured, then the relative battery charge capacity may be
determined from the following equation:
M=(10* T, *I-)/(*C,)
where:
e M-= the reduction in battery charge capacity of the battery under test (%)
e Ty, = measured discharge time (minutes)
e I. =discharge current (mA)
e C, =rated battery capacity of battery under test (mAh)
Rated charge capacity of standard Psion battery packs
The rated charge capacity for the standard Psion HC and Workabout battery packs is displayed in the
table below. This table also contains the standard discharge time and the standard discharge current for
each variant of the docking station. .
Docking station Rated capacity C; (mAh) Discharge time T,, (mins) Discharge current I,
(mA)
HC 650 130 300
Workabout 845 175 290
Example calculations
Example 1: If a fully-charged HC battery pack takes 100 minutes to discharge, at the (fixed) discharge
current of 300mA, then the measured capacity of that HC battery pack is 77%.
ie. M= (10 * T,)* 1,)/ (6 * C. ) = (10 * 100 * 300) / (6 * 650) = 77%
Example 2: If a fully-charged Workabout battery pack takes 120 minutes to discharge, at the (fixed)
discharge current of 290mA, then the measured capacity of that Workabout battery pack is 69%,
Le. M=(10 * 120 * 290) / (6 * 845) = 69%
The charge capacity of custom batteries may also be determined using the same equation. Care must be
taken to use the correct value of I, in the equation, where I, is defined by the docking station variant that
is being used to discharge the custom battery pack.
p_open(FCG:A) Open the fast charger device
INT p_open(VOID **ppcb,"FCG:A",-1);
Open a channel to the docking station fast charger device.
Returns zero if the device is opened successfully, otherwise a negative error. The p_open operation will
fail if the docking station is not present.
If the channel is opened successsfully, the charging current and charging time will be preset to the default
settings. The device driver will then immediately begin polling the status of the battery. This polling
operation may take up to forty seconds to complete.
Errors include:
E_GEN_NOMEMORY failed to allocate memory for control block
E_FILE_LOCKED port is already open
E_GEN_INUSE port in use
E_FILE_DEVICE device does not exist
1/0 DEVICES REFERENCE
p_close Close the channel
INT p_close (VOID *pcb) ;
Close the fast charger device channel.
Any outstanding FCHG_xxx operations will be cancelled by p_close.
Returns zero.
FCHG_SETCHARGEMODE Set battery charge mode
#include “fcharge.h”
INT p_iow(VOID *pcb,FCHG_SETCHARGEMODE, WORD *pmode) ;
Set the charge current and the maximum charging time period.
Two pieces of information must be passed to the docking station fast charger circuitry (in pmode):
e the current which will be used to charge the battery
e the maximum period of time which the battery will be charged.
The contents of pmode should contain a value which is constructed from two integers. The three least
significant bits in pmode should identify the charge time period; the four most significant bits in pmode
should identify the charge current. (The present charge mode may be read by calling the
FCHG_READCHARGEMODE function.)
This information may be selected from the fixed options that are supported by the docking station. The
minimum charging current that one could select should not be less than a quarter of the battery capacity
(unless the battery pack is known to be already partially charged).
Example: The capacity of the standard Workabout battery is 850mA. The minimum charging current that
one could use is 0.25 X 850 = 212mA (approx. 200mA = FcHG_ccLow2).
Please refer to the tables below for information about the discrete charge currents which may be supplied
by the docking station. This table also contains the names of the C constants, defined in fcharge.h, that
are associated with each charge current setting for the docking station.
Charging Psion battery packs
The following tables display suggested combinations of charge current and charge times that are suitable
for the standard Psion HC and Workabout battery packs:
Charge period Charge current for standard Charge current for standard
Psion HC battery pack Psion Workabout battery pack
1C 700mA 850mA
C/2 350mA 500mA
C/4 175mA 200mA
The above charge period/charge currents correspond to the following C constants in fcharge.h:
Charge period Charge current for standard Charge current for standard
Psion HC battery pack Psion Workabout battery pack
FCH_CTIME1C FCHG_DEFAULTCC FCHG_DEFAULTCC
FCH_CTIMEC2 FCH_CC350mA FCH_CC500mA
FCH_CTIMEC4 FCH_CCLOW2 FCH_CCLOW2
High charging currents should only be selected in situations where special, high capacity, fast charge
battery packs are being used. Lower charging currents are recommended in circumstances where the
ambient temperature is above 35°C, or where lower capacity battery packs are used.
The minimum charging current that may be selected should not be less than a quarter of the battery
capacity (unless the battery pack is known to be already partially-charged). Incorrect settings will result in
under-charge or damage to batteries.
18-4
18 FAST CHARGER
Charging custom battery packs
The docking station may also be used to charge custom battery packs with different charge-current
requirements.
The fast charger device driver and docking station support the following charge times:
Charge period Jfcharge.h constant Maximum charge period (minutes)
2C FCHG_CTIME2C 45
1C FCHG_CTIME1C 90
C/2 FCHG_CTIMEC2 180
C/4 FCHG_CTIMEC4 360
The fast charger device driver and docking station support the following charge currents:
fcharge.h constant HC docking station current Workabout docking station current
FCHG_CCLOW1 100mA 130mA
FCHG_CCLOW2 175mA 200mA
FCHG_CC350mA 350mA 350mA
FCHG_CC500mA 500mA 500mA
FCHG_CC650mA 650mA 650mA
FCHG_DEFAULTCC 700mA 850mA
FCHG_CC850mA 850mA 850mA
FCHG_CC1000mA 1A 1A
FCHG_CC1100mA LIA LIA
FCHG_CCHIGH1 1.2A 1.3A
FCHG_CCHIGH2 1.4A 1.5A
IMPORTANT: Never charge a standard Psion battery pack with a charge rate that exceeds 1C
without first contacting the battery supplier for advice. High charge rates in excess of 1C will
reduce the life of the battery pack and may create a risk of explosion or fire.
Notes:
1. The standard power supply that is provided with the Workabout docking cradle has a
maximum current rating of 1A. As a result, battery charge currents in excess of 850 mA
cannot be supported by the standard power supply provided with the docking station.
If you wish to fast charge batteries using currents greater than 850 mA, a 2A power supply
must be used with the Workabout docking station. Suitable power supplies are available
from Psion; for further details please contact the Psion Sales staff.
The HC docking station is provided with a 2A power supply and hence is capable of
handling the entire charge current range supported by the device driver.
2. Charging currents below or equal to 200mA have a tolerance of + 30% and
currents greater then 300mA have a tolerance of + 15%.
18-5
I/O DEVICES REFERENCE
FCHG_READCHARGEMODE Read battery charge mode
#include “fcharge.h”
INT p_iow(VOID *pcb,FCHG_READCHARGEMODE,WORD *pmode) ;
Read the charge current and the maximum charging time period settings.
The present charge rate and the required charging period will be returned to pmode.
The contents of pmode will contain a value which is constructed from two integers. The three least
significant bits in pmode will identify the charge time period; the four most significant bits in pmode will
identify the charge current. The charge mode may be altered by calling the FcHc_SETCHARGEMODE function.
The table that appears in the FcHG_SETCHARGEMODE section (above) contains all of the valid combinations
of charge current/charge period settings for HC and Workabout machines.
Zero is returned if the FcHG_SETCHARGEMODE request completed successfully, or a negative value if an error
has occurred.
FCHG_READSTATUS Read the battery status
#include “fcharge.h”
INT p_iow(VOID *pcb, FCHG_READSTATUS,WORD *pstatel,WORD *pstate2);
Read the present charge status of each battery from the docking station device, writing the new charge
states to pstatel and pstate2.
The status of the main battery inside the computer held in the holster is returned in pst ate1; if a spare
battery has been inserted in the spare battery compartment of the docking station, then the status of this
battery will be returned to pstate2.
On completion, pstate1 and pstate2 may contain one of the following integer values:
FCHG_UNKNOWN the battery is in an unknown state
FCHG_NOTCHARGING the battery is not charging.
If the docking station has been instructed to discharge the main battery, then
FCHG_READSTATUS will return a FCHG_NOTCHARGING value to indicate that the
battery is indeed being discharged
FCHG_FASTCHARGING The battery is fast charging
FCHG_TOPPINGOFF The battery is now charged to 90-95% of its maximum capacity and it is now
being topped off by the fast charger circuitry
FCHG_TRICKLE The battery is being trickle charged
The Fcc: device driver calculates the present charge status of a battery by measuring the duration of
charge pulses that the battery receives from the docking station. A charge pulse from the docking station
may last 40 seconds; as a result, it is possible that a call to FcHc_READSTATUS may not be able to determine
the present charge status of a battery at the precise moment in time when the call is made.
In this situation, a FCHG_UNKNowN status message will be returned for the status of that battery. This does
not mean that the battery charge status is indeterminate; another FCHG_READSTATUS call in the future may,
however, be able to return a valid status value for the charge status of that battery.
Zero is returned if the FcHG_READSTATUS request completed successfully, or a negative value if an error has
occurred.
18 - 6
18 FAST CHARGER
FCHG_ASYNCHREAD Read the battery status asynchronously
#include “fcharge.h”
INT p_ioc(VOID *pcb,FCHG_ASYNCHREAD, WORD *pstatel,WORD *pstate2);
Read the present charge status of each battery from the docking station device asynchronously, writing the
new charge states to pstate1 and pstate2 when the charge status of either battery alters.
The rFcHG_ASYNCHREAD operation may be cancelled at any time by a call to FcHG_CANCEL.
FCHG_ASYNCHREAD Will return immediately after initiating a request to receive battery status information
when the status of either battery changes. At some time in the future, the new status of the main battery
inside the computer in the holster will be returned in pstate1; if a spare battery has been fitted inside the
compartment in the top of the docking station, then the status of this battery will be returned to pstate2.
Panics if pcb is not a valid channel handle, or if an FcHG_ASYNCHREAD operation is outstanding.
Returns zero if the rcHG_ASYNCHREAD request completed successfully, or a negative value if an error has
occurred.
FCHG_CANCEL Cancel an asynchronous read
#include “fcharge.h”
INT p_iow(VOID *pcb,FCHG_CANCEL) ;
Cancel any outstanding rcHG_ASYNCHREAD request. Performing a cancel is harmless if no read request is
outstanding.
Returns zero.
FCHG_FASTCHARGE1 Fast charge the main battery
#include “fcharge.h”
INT p_iow(VOID *pcb, FCHG_FASTCHARGE1) ;
Begin fast charging the main battery that is inside the computer fitted to the docking station holster.
The present settings for the charge current and charge time period (as set by p_open or
FCHG_SETCHARGEMODE) will be used by the fast charger circuitry to charge the battery.
FCHG_FASTCHARGE1 will return zero if it completes successfully, or a negative value if an error occurs.
Please note: only one battery may be charged at any one time; 1.e. the main battery cannot be charged
while a battery in the spare battery compartment is being charged.
If you wish to charge the main battery and the spare battery, then the software which calls rce: should
charge one battery, sense when that battery is charged sufficiently, and then charge the second battery.
FCHG_FASTCHARGE2 Fast charge the spare battery
#include “fcharge.h”
INT p_iow(VOID *pcb, FCHG_FASTCHARGEZ2) ;
Begin fast charging the battery that is in the spare battery compartment of the docking station.
The present settings for the charge current and charge time period (as set by p_open or
FCHG_SETCHARGEMODE) will be used by the fast charger circuitry to charge the battery.
FCHG_FASTCHARGE2 will return zero if it completes successfully, or a negative value if an error occurs.
Please note: only one battery may be charged at any one time; i.e. a battery in the spare battery
compartment cannot be charged while the main battery is being charged.
If you wish to charge the main battery and the spare battery, then the software which calls rce: should
charge one battery, sense when that battery is charged sufficiently, and then charge the second battery.
Note: if the main battery is charging and the spare battery is waiting, then the rcuc_FASTCHARGE2 function
will over-ride the status of the main battery and start charging the spare battery instead.
18 -7
I/O DEVICES REFERENCE
FCHG_DISCHARGE1 Discharge the main battery
#include “fcharge.h”
INT p_iow(VOID *pcb, FCHG_DISCHARGE1) ;
Begin discharging the main battery fitted inside the computer fitted to the docking station holster.
The FCHG_DISCHARGE1 command will initiate a sequence of operations which will take a few seconds to
complete. If any additional calls are made to Fcc: in this period, those commands will return a negative
completion code and the instructions will be ignored.
The discharging current is fixed by the fast charger circuitry and may therefore not be altered by software.
The discharge current for the HC docking station is set to 300 mA +3%. The discharge current for the
Workabout docking station is set to 290 mA +3%.
FCHG_DISCHARGE1 will return zero if it completes successfully, or a negative value if an error occurs.
Notes:
1. when the docking station has been instructed to discharge a battery, subsequent
FCHG_READSTATUS operations will each return a FCHG_NOTCHARGING status code - which
should be interpreted as meaning that the battery is discharging (as expected).
2. The spare battery cannot be discharged by Fce:.
Example program
An example C application may be found in the file path \sibosdk\wkdemo\, on installation of this SDK
onto your PC.
charger.c is a Workabout computer program which monitors and controls the fast charger circuitry in the
docking station. This program allows the main battery, or spare battery to be charged, or the main battery
to be discharged, and the status of both batteries to be monitored.
Note: This program will only run if the Workabout computer has been placed into the holster of a docking
station.
/* Fastcharger for Workabout */
/* Example application */
/* (C) Copyright Psion Software PLC 1997 */
include <p_std.h>
include <p_file.h>
include <p_sys.h>
include <p_keyb.h>
include <epoc.h>
include "fcharge.h"
GLREF_D VOID *winHandle;
LOCAL_C VOID State(WORD Val)
switch (Val)
{
case 0:
p_printf(" Unknown") ;
break;
case l:
p_printf(" Not Charging") ;
break;
case 2:
p_printf(" Fast Charging");
break;
case 3:
p printf (" Topping Off");
break;
default:
p_printf(" Trickle");
18-8
GLDEF_C VOID main(VOID)
/*
{
VOID *pcb;
WORD One, OldOne;
WORD Two, OldTwo;
WORD KStat,Disch;
WORD LogOne[100];
WORD LogTwo[100];
WORD P1=0,P2=0, Temp;
ULONG TTime;
P_CON_KBREC Key;
TEXT X1Str[1l];
WORD X1=0;
ULONG XE=0,DischTime;
TEXT *X1Ptr;
INT Item;
for (Item=0; Item<100; Item++)
{
LogOne [Item] =0;
LogTwo [Item] =0;
}
p_devdel ("FCG",E_LDD) ;
p_printf ("Loading");
if (p_loadldd("m:\\sys$fchg.1dd") <0)
p_panic(0);
p_printf ("Opening test");
if (p_open (&pcb, "FCG:A",-1) <0)
p_panic(1);
p_printf ("Closing test");
if (p_close (pcb) <0)
p_panic(2);
p_printf ("Opening test part II");
if (p_open (&pcb, "FCG:A",-1) <0)
p_panic (3);
p_printf ("Cant remove test");
if (p_devdel ("FCG:",E_LDD) >=0)
p_panic(4);
p_printf ("Setting the charge Mode");
p_iow (pcb, P_FCHG_READCHARGEMODE, &One) ;
if (One!=(P_FCHG_DEFAULTCC | P_FCHG_CTIME1C) )
p_panic(5);
p_printf ("Test the charge Mode");
if (p_iow (pcb, P_FCHG_SETCHARGEMODE, &One) !=0)
p_panic(6);
p_printf("Set Rubbish charge Mode");
One=-1;
if (p_iow (pcb, P_FCHG_SETCHARGEMODE, &One) ==0)
p_panic(7);
p_iow (pcb, P_FCHG_READSTATUS, &One, &Two) ;
p_print ("Battery one:");
State (One) ;
p_print ("Battery two:");
State (Two) ;
p_printf("Asynch test1");
p_iow (pcb, P_FCHG_ASYNCHREAD, &One, &Two) ;
p_print ("Battery one:");
State (One) ;
p_print ("Battery two:");
State (Two) ;
p_printf("Asynch test2");
p_iow (pcb, P_FCHG_ASYNCHREAD, &One, &Two) ;
p_print ("Battery one:");
State (One) ;
p_print ("Battery two:");
State (Two) ;*
18 FAST CHARGER
18-9
1/0 DEVICES REFERENCE
18 - 10
p_ioc4 (winHandle, P_FREAD, &KStat, &Key) ;
TTime=p_date();
Disch=0;
DischTime=0;
FOREVER
{
if (KStat!=E_FILE_PENDING) /* Was it the keyboard */
{
p_iowait(); /* not really the way to do this -oh well */
if (Key.keycode=='Q' | | Key. keycode=='q'
p_exit (0);
|| Key.keycode==27)
else if (Key.keycode=='D' | | Key. keycode=='d"')
{
p_printf ("Start discharge");
TIime=p_date();
if (p_iow(pcb,P_FCHG_DISCHARGE) )
p_panic(8);
Disch=1;
}
else if (Key.keycode=='F' || Key.keycode=='f')
p_printf("Start Fastchargel") ;
TTime=p_date();
if (p_iow(pcb,P_FCHG_FASTCHARGE1) )
p_panic (9);
else if (Key. keycode=='G' | | Key. keycode=='g')
p_printf("Start Fastcharge2") ;
TTime=p_date();
if (p_iow(pcb,P_FCHG_FASTCHARGEZ2) )
p_panic(9);
else if (Key. keycode=='C'! | | Key. keycode=='c"')
p_getl("Current: ",&X1Str[0],10);
X1Ptr=&X1Str[0];
p_stoi(&X1Ptr,&X1);
}
else if (Key.keycode=='/' | | Key. keycode=='?')
{
if (Disch==1)
p_printf("Discharging: %d", (p_date()-TTime) );
else
{
p_printf("Discharge Time: %d1",DischTime) ;
if (X1>0 && DischTime>0)
{
XE= (850*60*60*10) /X1;
XE= (DischTime*100*10) /XE;
p_printf("Capacity (Cell) %d%%", (UWORD) (XE) );
}
}
else if (Key. keycode=='1')
{
p_printf("Battery one Log");
Temp=0;
while (Temp<P1)
if (LogOne[Temp++]>0)
State (LogOne[Temp-1]);
}
else if (Key. keycode=='2')
{
p_printf ("Battery two Log");
Temp=0;
while (Temp<P2)
if (LogTwo[Temp++]>0)
State (LogTwo[Temp-1]);
18 FAST CHARGER
else if (Key.keycode=='H' | | Key.keycode=="'h' | | Key. keycode==290 | |
Key. keycode==291)
{
p_printf£("");
p_printf("C...Enter Discharge current");
p_printf("D...Start Discharge");
p_printf("F...Fastcharge Batteryl");
p_printf("G...Fastcharge Battery2");
p_printf("?...Show Discharge time");
p_printf("1...Show Batteryl Log");
p_printf("2...Show Battery2 Log");
poipraent ft ((C"On-. 2QUrt™): 3.
p_printf£("");
}
p_ioc4 (winHandle, P_FREAD, &KStat, &Key) ;
}
OldOne=One;
OldTwo=Two;
p_iow (pcb, P_FCHG_READSTATUS, &One, &Two) ;
if (OldOne!=One || OldTwo!=Two)
{
if (OldOne==1 && Disch==1 && One!=1)
{
Disch=0;
DischTime=(p_date()-TTime) ;
p_printf ("Discharge Time: %d",DischTime) ;
}
p_printf("Time: %d", (p_date()-TTime) );
if (One!=O0ldOne)
{
if (P1>50)
P1=0;
LogOne [P1++]=One;
}
if (Two!=OldTwo)
{
if (P2>50)
P2=0;
LogTwo [P2++]=Two;
}
p_print ("Battery one:");
State (One) ;
p_print ("Battery two:");
State (Two) ;
}
18 - 11
INDEX
.wve files
digital sound files, 5-1
A_FTIMED
alarm device, 6-2
A_FTIMED_X
alarm device, 6-3
A_FUNTIMED
alarm device, 6-3
A_FUNTIMED_X
alarm device, 6-4
AccessIr
infrared API, 16-1
AccessIr API
infrared, 15-4
AIR:
infrared device, 15-4, 16-1, 16-2
loading on Siena, 16-1
alarm
device I/O introduction, 6-1
note sequence SND: device, 5-3
alarm device
A_FTIMED, 6-2
A_FTIMED_X, 6-3
A_FUNTIMED, 6-3
A_FUNTIMED_X, 6-4
ALM: introduction, 6-1
p_close, 6-2
P_FCANCEL, 6-2
p_open(ALM:), 6-2
panics, 6-2
services additional S3a, 6-3
services $3 S3a & MC, 6-2
alarm services
time application $3 S3a, 6-2
ALM: device
introduction, 6-1
see alarm device, 6-1
asynchronous
I/O functions, 1-1
bar code
Codabar start and stop characters, 14-5
maximum scanning rate, 14-4
supplement digits, 14-4
bar code command syntax
HC bar code/RS232 module, 14-11
bar code commands
HC bar code/RS232 module, 14-11
bar code formats UPC/EAN
HC bar code/RS232 module, 14-6
bar code interface
comms settings, 14-2
HC bar code/RS232 module, 14-3
bar code symbologies
HC bar code/RS232 module, 14-4
bar code wand connector
HC bar code/RS232 module, 14-2
BAR: device
see HC bar code reader, 13-1
battery capacity
docking station fast charger, 18-3
HC, 18-3
Workabout, 18-3
baud rates
infrared, 15-3
beaming
infrared communications application,
15-6
bottom slot
HC bar code/RS232 module, 14-2
CLIB
programs CON: device use of, 2-1
Codabar
start and stop characters, 14-5
communications
infrared application, 15-6
CON: device
automatic opening, 2-1
CLIB based programs, 2-1
example code, 2-14
explicit opening, 2-3
handle of, 2-2
introduction, 2-1
OPL programs, 2-1
PLIB based programs, 2-2
see console device, 2-1
Condor chip
serial infrared, 15-3
connection
second time (LM-IAS server)
infrared, 17-4
connection first time (LM-IAS server)
infrared, 17-4
connectionless calls
infrared, 17-3
connectionless read request
infrared, 17-3
connectionless write request
infrared, 17-3
connection-oriented calls
infrared, 17-3
console device
automatic opening of CON: device, 2-1
example code, 2-14
explicit opening of CON: device, 2-3
handle of, 2-2
I/O, 2-1
p_close, 2-4
P_EVENT_READ, 2-9
P_EVENT_TEST, 2-10
P_FCANCEL, 2-5
P_FEDIT, 2-6
P_FFLUSH, 2-6
P_FINQ, 2-10
P_FREAD, 2-5
P_FSENSE, 2-6
1/0 DEVICES REFERENCE
P_FSET service call convention, 2-3
P_FTEST, 2-5
P_FWFLUSH, 2-10
p_open(CON:), 2-3
P_SCR_ATTRB, 2-11
P_SCR_CANCEL_CAPTURE_KEY,
2-13
P_SCR_CAPTURE KEY, 2-13
P_SCR_CLIENT_FOREGROUND, 2-12
P_SCR_CLR, 2-7
P_SCR_COMPATIBILITY, 2-9
P_SCR_CSET, 2-10
P_SCR_CURSOR, 2-8
P_SCR_DISABLE_READS, 2-12
P_SCR_ESCAPE, 2-9
P_SCR_FLUSH, 2-12
P_SCR_FONT, 2-11
P_SCR_GREY, 2-9
P_SCR_LAST_LINE_WRAP, 2-12
P_SCR_NEL, 2-8
P_SCR_POSA, 2-8
P_SCR_POSR, 2-8
P_SCR_SCROLL, 2-7
P_SCR_SLOCK, 2-8
P_SCR_WLOCK, 2-8
P_SCR_WSET, 2-7
p_write, 2-4
panics, 2-3
services, 2-3
services additional, 2-9
cradle device
introduction, 11-1
introduction HC, 11-1
p_close(CRD:), 11-2
P_FCANCEL, 11-2
P_FREAD, 11-2
P_FSENSE, 11-2
P_FSET, 11-2
p_open(CRD:), 11-1
services, 11-1
CRC
XYmodem device, 9-1
CRD: device
introduction, 11-1
see cradle device, 11-1
services, 11-1
data transfer
link I/O, 10-1
database
world application services $3 S3a, 8-2
device driver
FCG: docking station, 18-2
infrared accessir.ldd, 16-1
serial port LDD, 4-1
serial port PDD, 4-1
Siena infrared printing, 15-7
devices
AJR: infrared, 15-4, 16-1, 16-2
alarm I/O introduction, 6-1
ALM: introduction, 6-1
BAR: introduction, 13-1
CON: introduction, 2-1
console I/O, 2-1
ii
CRD: introduction, 11-1
FCG: docking station, 18-1
FRC: I/O introduction, 7-1
FRC: introduction, 7-1
HC bar code reader I/O introduction, 13-1
HC bar code/RS232 module, 14-1
HC cradle I/O introduction, 11-1
HC docking station I/O introduction, 11-1
HC intelligent bar code Reader, 14-1
HC magnetic card reader I/O, 12-1
I/O introduction, 1-1
I/O Introduction, 1-1
IRP: infrared printing, 15-7
MCR: introduction, 12-1
NCP I/O introduction, 10-1
PAR: introduction, 3-1
parallel port I/O, 3-1
serial port I/O introduction, 4-1
SIR: infrared, 15-2, 15-3
SND: introduction, 5-1
sound I/O introduction, 5-1
TTY: introduction, 4-1
WLD: introduction, 8-1
Workabout docking station I/O
introduction, 11-1
world database I/O introduction, 8-1
XMD: introduction, 9-1
Xmodem I/O introduction, 9-1
Ymodem I/O introduction, 9-1
dial tones
sound device DTMF, 5-4
disconnecting first time (LM-IAS server)
infrared, 17-4
disconnecting second time
infrared, 17-4
discovery
infrared, 15-5, 17-4
DISCOVERY_LOG
structure infrared, 15-5
docking station
battery capacity calculations, 18-3
device introduction HC, 11-1
device introduction Workabout, 11-1
fast charger, 18-1
FCG: device, 18-1
FCG: device driver, 18-2
FCHG_ASYNCHREAD, 18-7
FCHG_CANCEL, 18-7
FCHG_DISCHCHARGE, 18-8
FCHG_FASTCHARGE 1, 18-7
FCHG_FASTCHARGE2, 18-7
FCHG_READCHARGEMODE, 18-6
FCHG_READSTATUS, 18-6
FCHG_SETCHARGEMODE, 18-4
p_close, 18-4
p_open, 18-3
docking station device
p_close(CRD:), 11-2
P_FCANCEL, 11-2
P_FREAD, 11-2
P_FSENSE, 11-2
P_FSET, 11-2
p_open(CRD:), 11-1
INDEX
services, 11-1
DTMF
sound device dial tones, 5-4
E_FALARM
sound device, 5-3
E_FDIAL
sound device, 5-4
E_FSSOUNDCHANNELn
sound device, 5-3
E_MESSAGE struct
structure infrared, 17-5
example application
infrared transfer, 16-7
example program
fast charger Workabout, 18-8
infrared transfer, 16-7
exclusive mode
infrared, 17-4
expansion module
HC bar code/RS232 module, 14-2
extension file
world database, 8-9
fast charger
docking station, 18-1
example program Workabout, 18-8
FCHG_ASYNCHREAD, 18-7
FCHG_CANCEL, 18-7
FCHG_FASTCHARGE I, 18-7
FCHG_FASTCHARGE2, 18-7
FCHG_FASTDISCHARGE I, 18-8
FCHG_READCHARGEMODE, 18-6
FCHG_READSTATUS, 18-6
FCHG_SETCHARGEMODE, 18-4
introduction, 18-1
p_close(FCG:A), 18-4
p_open(FCG:A), 18-3
services, 18-1
FCG:
device, 18-1
FCHG_ASYNCHREAD
fast charger, 18-7
FCHG_CANCEL
fast charger, 18-7
FCHG_FASTCHARGE1
fast charger, 18-7
FCHG_FASTCHARGE2
fast charger, 18-7
FCHG_FASTDISCHARGE1
fast charger, 18-8
FCHG_READCHARGEMODE
fast charger, 18-6
FCHG_READSTATUS
fast charger, 18-6
FCHG_SETCHARGEMODE
fast charger, 18-4
file format
world database, 8-9
world database extension, 8-10
FRC: device
I/O introduction, 7-1
introduction, 7-1
p_close, 7-2
P_FCANCEL, 7-2
P_FREAD, 7-2, 7-3
P_FSTART, 7-2
p_open(FRC:), 7-1
services $3a & Workabout, 7-1
free running counter
see FRC: device, 7-1
get value by class frame
infrared, 17-2
infrared IAS, 17-3
get value by class reply frame
infrared IAS, 17-3
handshaking level
infrared, 17-4
HC
battery capacity calculation, 18-3
HC bar code device
p_close, 13-2
P_FCANCEL, 13-2
P_FREAD, 13-2
p_open(BAR:), 13-2
HC bar code reader
device driver, 13-1
hardware description, 13-1
interface module, 13-1
services, 13-2
wand, 13-1
HC bar Code reader
device I/O introduction, 13-1
HC bar code/RS232 module
2-pin header, 14-3, 14-4
5v regulated power supply, 14-4
auto power-off HC, 14-4
bar code command syntax, 14-11
bar code commands, 14-11
bar code formats UPC/EAN, 14-6
bar code symbologies, 14-4
bar code wand connector, 14-2
bottom slot, 14-2, 14-3
charging the main battery, 14-3
CTS input, 14-2
DCD input, 14-2, 14-3
device introduction, 14-1
diode isolation, 14-3
DSR auto wakeup switch, 14-3
DSR input, 14-2, 14-3
DTR output, 14-2, 14-3
example code, 14-20
expansion module, 14-2
HBCR-1610 series micro controller, 14-3
idle current of interface, 14-4
IGN_CTS serial port characteristic, 14-3
interface comms settings, 14-3
losing micro controller program data,
14-4
maximum output current, 14-2
optional Vsup connection, 14-2
p_close, 14-18
P_FREAD, 14-18
P_FSENSE, 14-18
P_FSET, 14-18
P_FWRITE, 14-19
p_open(TTY:), 14-17
power consumption, 14-2
1/0 DEVICES REFERENCE
power consumption wand, 14-4
powering an external device, 14-4
programming, 14-1
RI pin of the RS232 port, 14-2
RS232 port pinout table, 14-2
RTS output, 14-2
RTS/CTS handshaking protocol, 14-3
RX input, 14-2
scanning current for the interface, 14-4
services, 14-17
switched Sv regulated output, 14-3
switched Vsup output, 14-3
switching off the external unit, 14-2
tmask serial port characteristics, 14-3
top slot, 14-2, 14-3
TTY:A, 14-2
TTY:B, 14-2
TTY:D, 14-2, 14-3
TTY:E, 14-2, 14-3
TX output, 14-2
undecoded laser scanners, 14-3
Vsup input voltage supply range, 14-3
wand emulator, 14-1
Xon/Xoff handshaking, 14-2
HC cradle device
introduction, 11-1
see cradle device, 11-1
HC docking station
device introduction, 11-1
HC intelligent bar code reader
device introduction, 14-1
see HC bar code/RS232 module, 14-1
HC magnetic card device
introduction, 12-1
p_close, 12-1
P_FCANCEL, 12-2
P_FREAD, 12-1
P_FSET, 12-2
p_open(MCR:), 12-1
services, 12-1
HC magnetic card reader
device I/O, 12-1
HWIM
infrared applications, 15-6
I/O devices
introduction, 1-1
see devices, 1-1
I/O function
asynchronous, 1-1
p_ioc, 1-1
p_ioca, 1-1
p_iow, 1-1
synchronous, 1-1
TAS
infrared, 15-4
idle mode
infrared, 17-4
include file
infrared constants p_file.h, 16-2
infrared
AccessIr API, 15-4, 16-1
AIR: device, 15-4, 16-1, 16-2
AIR: device on Siena, 16-1
iv
baud rates, 15-3
beaming communications application,
15-6
communications AccessIr API, 16-1
communications application, 15-6
communications IrMUX API, 17-1
Condor serial chip, 15-3
connection first time (LM-IAS server),
17-4
connection second time (LM-IAS server),
17-4
connectionless calls, 17-3
connectionless read request, 17-3
connectionless services IrLAP, 15-4
connectionless write request, 17-3
connection-oriented calls, 17-3
connection-oriented services IrLAP, 15-4
constant P_FIRAWAITCONNECT, 16-3
constant P_FIRDISCONNECT, 16-3
constant P_FIRDISCOVER, 16-3
constant P_ FIRMAKECONNECT, 16-3
constant P_FIRSELECT, 16-3
constant P_FREAD, 16-3
constant P_FWRITE, 16-3
constants p_file.h, 16-2
device driver accessir.ldd, 16-1
disconnecting first time (LM-IAS server),
17-4
disconnecting second time, 17-4
discovery, 15-5, 17-4
example application, 16-7
exclusive mode, 17-4
handshaking level, 17-4
HWIM applications, 15-6
TAS, 15-4
IAS get value by class frame, 17-2, 17-3
IAS get value by class reply frame, 17-3
idle mode, 17-4
IPCS methods, 17-1
IrDA protocol model, 15-1
IrDA standard, 15-1
IrLAP, 15-1
IrLAP layer, 15-2, 15-3
IrLAP services, 15-4
IrLMP, 15-1, 15-4
IrLMP layer, 15-3
IrMUX API, 15-4, 17-1
IrMUX message format, 17-5
IrMUX server logoff, 17-2
IrMUX server logon, 17-2
ISO OSI layers, 15-1
link control, 15-6
link paste, 15-6
LM_AccessModeRequest, 17-4, 17-11
LM_CLReadRequest, 17-6
LM_CLWriteRequest, 17-7
LM_ConnectRequest, 17-2, 17-4, 17-7
LM_DisconnectRequest, 17-4, 17-13
LM_DiscoverDevicesRequest, 17-4, 17-7
LM_GetValueByClass, 17-2
LM_IdleRequest, 17-12
LM_Logoff, 17-2, 17-5
LM_Logon, 17-2, 17-5
INDEX
LM_ReadRequest, 17-4, 17-9
LM_RegisterPort, 17-2, 17-5
LM_SetHandshakingLevel, 17-4, 17-12
LM_StatusRequest, 17-9
LM_UnRegisterPort, 17-2, 17-6
LM_UReadRequest, 17-4, 17-10
LM_UWriteRequest, 17-4, 17-11
LM_WaitForConnection, 17-8
LM_WriteRequest, 17-4, 17-10
LM-IAS, 15-4
LM-IAS server registering, 17-2
LM-IAS server unregistering, 17-2
LM-MUxX, 15-4
loadIRDAserver() example code, 16-2
message number | (IrMUX), 17-5
message number 10 (IrMUX), 17-5
message number 11 (rMUX), 17-6
message number 2 (IrMUX), 17-5
message number 20 (IrMUX), 17-13
message number 21 (IrMUX), 17-9
message number 22 (IrMUX), 17-11
message number 23 (IrMUX), 17-12
message number 24 (IrMUX), 17-9
message number 25 (IrMUX), 17-10
message number 26 (IrMUX), 17-10
message number 27 (IrMUX), 17-11
message number 28 (IrMUX), 17-12
message number 4 (IrMUX), 17-6
message number 5 (IrMUX), 17-7
message number 6 (IrMUX), 17-7
message number 8 (IrMUX), 17-8
message number 9 (IrMUX), 17-7
multiplexing, 15-6
MUXMESSAGE structure, 17-5
OSI layers, 15-1
p_close, 16-2, 16-4
P_FIRAWAITCONNECT, 16-3, 16-5
P_FIRDISCONNECT, 16-3, 16-6
P_FIRDISCOVER, 16-2, 16-4
P_FIRMAKECONNECT, 16-3, 16-5
P_FIRSELECT, 16-2, 16-4
P_FREAD, 16-3, 16-6
P_FWRITE, 16-3, 16-6
p_mreceive, 17-5
p_open(AIR:), 16-2, 16-3
primary station, 15-4
printer IRP: device, 15-7
printer IRP: device Siena, 15-7
protocol stack - initializing, 17-1
protocol stack example code, 17-2
protocol stack SYS$IRDA.IMG, 16-2,
17-2
Psion protocol model, 15-2
read request, 17-4
read request unreliable, 17-4
retries, 17-4
secondary station, 15-4
SIR, 15-1
SIR: device, 15-2, 15-3
SYS_IR_POWER_LEVEL, 15-6
SYS_PRINTER_IR, 15-6
unreliable read request, 17-4
unreliable write request, 17-4
write request, 17-4
write request unreliable ), 17-4
infrared communication
introduction to Psion IR, 15-1
IPCS
infrared methods, 17-1
IrDA
infrared protocol model, 15-1
standard, 15-1
IrLAP
infrared, 15-1
infrared layer, 15-2, 15-3
IrLAP services
infrared, 15-4
IrLMP
infrared, 15-1, 15-4
infrared layer, 15-3
IrmMUxX
infrared API, 17-1
IrMUX API
infrared, 15-4
IrMUX message format
infrared, 17-5
IrMUX server
infrared logoff, 17-2
infrared logon, 17-2
IRP:
infrared printer device, 15-7
ISO OST layers
infrared, 15-1
key code
W_KEY_IR_BRING, 15-6
W_KEY_IR_LINK, 15-6
W_KEY_IR_SEND, 15-6
Link
data transfer, 10-1
example code, 10-10
inter-process messages, 10-3
panics, 10-1
process, 10-1
protocol, 10-1
protocol I/O introduction, 10-1
LINK
process, 10-3
link control
infrared, 15-6
link paste
infrared, 15-6
LM_AccessModeRequest
infrared, 17-4, 17-11
LM_CLReadRequest
infrared, 17-6
LM_CLWriteRequest
infrared, 17-7
LM_ConnectRequest
infrared, 17-2, 17-4, 17-7
LM_DisconnectRequest
infrared, 17-4, 17-13
LM_DiscoverDevicesRequest
infrared, 17-4, 17-7
LM_GetValueByClass
infrared, 17-2
I/O DEVICES REFERENCE
LM_IdleRequest
infrared, 17-12
LM_Logoff
infrared, 17-2, 17-5
LM_Logon
infrared, 17-2, 17-5
LM_ReadRequest
infrared, 17-4, 17-9
LM_RegisterPort
infrared, 17-2, 17-5
LM_SetHandshakingLevel
infrared, 17-4, 17-12
LM_StatusRequest
infrared, 17-4, 17-9
LM_UnRegisterPort
infrared, 17-2, 17-6
LM_UReadRequest
infrared, 17-4, 17-10
LM_UWriteRequest
infrared, 17-4, 17-11
LM_WaitForConnection
infrared, 17-8
LM_WriteRequest
infrared, 17-4, 17-10
LM-IAS
infrared, 15-4
LM-IAS server
LM-MUX
infrared, 15-4
loadIRDAserver()
infrared example code, 16-2
magic static
CON: device handle winHandle, 2-2
magnetic card device
see HC magnetic card device, 12-1
main world file
location, 8-9
maximum scanning rate
bar codes, 14-4
MCR: device
introduction, 12-1
see HC magnetic card device, 12-1
multiplexing
infrared, 15-6
MUXMESSAGE structure
infrared, 17-5
NCP
panics, 10-1
NCP device
I/O introduction, 10-1
NCP: device
example code, 10-10
p_close, 10-4
P_FCANCEL, 10-7
P_FCONNECT, 10-4
P_FDISCONNECT, 10-6
P_FINQ, 10-9
P_FREAD, 10-6
infrared registering, 17-2
infrared unregistering, 17-2
process SYS$NCP, 10-1
P_FRSUPER, 10-7
P_FSENSE, 10-10
P_FSTOP, 10-10
P_FWRITE, 10-7
p_open(NCP:), 10-3
process SYS$NCP, 10-2
services, 10-3
note sequence
SND: device, 5-3
OPL
CON: device use of, 2-1
OSI layers
infrared, 15-1
p_close
alarm device, 6-2
console device, 2-4
FRC: device, 7-2
HC bar code device, 13-2
HC bar code/RS232 module, 14-18
HC magnetic card device, 12-1
infrared, 16-2, 16-4
NCP: device, 10-4
parallel port, 3-1
serial port, 4-6
sound device, 5-2
world device, 8-2
XYmodem device, 9-8
p_close(CRD:)
close device, 11-2
p_close(FCG:A)
fast charger device, 18-4
P_EVENT_READ
console device, 2-9
P_EVENT_TEST
console device, 2-10
P_FCANCEL
alarm device, 6-2
cancel read from device, 11-2
console device, 2-5
FRC: device, 7-2
HC bar code device, 13-2
HC magnetic card device, 12-2
NCP: device, 10-7
parallel port, 3-2
serial port, 4-8
sound device, 5-2
world device, 8-2
P_FCONNECT
NCP: device, 10-4
XYmodem device, 9-8
P_FCTRL
serial port, 4-9
P_FDISCONNECT
NCP: device, 10-6
XYmodem device, 9-10
P_FEDIT
console device, 2-6
P_FFLUSH
console device, 2-6
serial port, 4-9
p_file.h
infrared constants, 16-2
INDEX
P_FINQ
console device, 2-10
NCP: device, 10-9
serial port, 4-10
P_FIRAWAITCONNECT
infrared, 16-3, 16-5
infrared constant, 16-3
P_FIRDISCONNECT
infrared, 16-3, 16-6
infrared constant, 16-3
P_FIRDISCOVER
infrared, 16-2, 16-4
infrared constant, 16-3
P_FIRMAKECONNECT
infrared, 16-3, 16-5
infrared constant, 16-3
P_FIRSELECT
infrared, 16-2, 16-4
infrared constant, 16-3
P_FREAD
console device, 2-5
FRC: device, 7-2, 7-3
HC bar code device, 13-2
HC bar code/RS232 module, 14-18
HC magnetic card device, 12-1
infrared, 16-3, 16-6
infrared constant, 16-3
NCP: device, 10-6
read from device, 11-2
serial port, 4-7
XYmodem device, 9-11
P_FRSUPER
NCP: device, 10-7
P_FSENSE
console device, 2-6
HC bar code/RS232 module, 14-18
NCP: device, 10-10
parallel port, 3-2
sense the device type, 11-2
serial port, 4-9
sound device, 5-2
P_FSET
HC bar code/RS232 module, 14-18
HC magnetic card device, 12-2
parallel port, 3-2
serial port, 4-9
service call convension, 2-3
set the device type, 11-2
sound device, 5-2
P_FSTART
FRC: device, 7-2
P_FSTOP
NCP: device, 10-10
P_FTEST
console device, 2-5
serial port, 4-9
P_FWFLUSH
console device, 2-10
P_FWRITE
HC bar code/RS232 module, 14-19
infrared, 16-3, 16-6
infrared constant, 16-3
NCP: device, 10-7
parallel port, 3-2
serial port, 4-8
XYmodem device, 9-12
p_ioc
I/O function, 1-1
p_ioca
I/O function, 1-1
p_iow
I/O function, 1-1
p_mreceive
infrared, 17-5
p_open(AIR:
infrared)
infrared, 16-2
p_open(AIR:)
infrared, 16-3
p_open(ALM:)
alarm device, 6-2
p_open(BAR:)
HC bar code device, 13-2
p_open(CON:)
console device, 2-3
p_open(CRD:)
open device, 11-1
p_open(FCG:A)
fast charger device, 18-3
p_open(FRC:)
FRC: device, 7-1
p_open(MCR:)
HC magnetic card device, 12-1
p_open(NCP:)
NCP: device, 10-3
p_open(PAR:)
parallel port, 3-1
p_open(SND:)
sound device, 5-2
p_open(TTY:)
HC bar code/RS232 module, 14-17
serial port, 4-6
p_open(WLD:)
world device, 8-2
p_open(XMD:)
XYmodem device, 9-8
P_SCR_ATTRB
console device, 2-11
P_SCR_CANCEL_CAPTURE_KEY
console device, 2-13
P_SCR_CAPTURE KEY
console device, 2-13
P_SCR_CLIENT_FOREGROUND
console device, 2-12
P_SCR_CLR
console device, 2-7
P_SCR_COMPATIBILITY
console device, 2-9
P_SCR_CSET
console device, 2-10
P_SCR_CURSOR
console device, 2-8
P_SCR_DISABLE_READS
console device, 2-12
P_SCR_ESCAPE
console device, 2-9
I/O DEVICES REFERENCE
P_SCR_FLUSH
console device, 2-12
P_SCR_FONT
console device, 2-11
P_SCR_GREY
console device, 2-9
P_SCR_LAST_LINE_WRAP
console device, 2-12
P_SCR_NEL
console device, 2-8
P_SCR_POSA
console device, 2-8
P_SCR_POSR
console device, 2-8
P_SCR_SCROLL
console device, 2-7
P_SCR_SLOCK
console device, 2-8
P_SCR_WLOCK
console device, 2-8
P_SCR_WSET
console device, 2-7
p_write
console device, 2-4
panics
alarm device, 6-2
console device, 2-3
Link, 10-1
NCP, 10-1
parallel port device, 3-1
serial port device, 4-1
sound device, 5-1
PAR: device
example code, 3-3
introduction, 3-1
see parallel port, 3-1
parallel port
device I/O, 3-1
example code, 3-3
p_close, 3-1
P_FCANCEL, 3-2
P_FSENSE, 3-2
P_FSET, 3-2
P_FWRITE, 3-2
p_open(PAR:), 3-1
panics, 3-1
parity errors
HC bar code/RS232 module, 14-3
PC-AT style RS232 port
HC bar code/RS232 module, 14-1
PLIB
programs CON: device use of, 2-2
power consumption
HC bar code/RS232 module, 14-4
primary station
infrared, 15-4
printer device
IRP: infrared, 15-7
protocol
Link introduction, 10-1
protocol stack
infrared - initializing, 17-1
Psion infrared
protocol model, 15-2
read request
infrared, 17-4
read request unreliable
infrared, 17-4
retries
infrared, 17-4
RI pin of the RS232 port
HC bar code/RS232 module, 14-2
RS232 device
see serial port, 4-1
RS232 port pinout table
HC bar code/RS232 module, 14-2
secondary station
infrared, 15-4
serial infrared
Condor chip, 15-3
serial port
baud rate, 4-2
character frame, 4-2
control flags, 4-5
device driver LDD, 4-1
device driver PDD, 4-1
device I/O introduction, 4-1
errors, 4-5
example code, 4-11
handshaking, 4-3
HC TTL levels, 4-1
p_close, 4-6
P_FCANCEL, 4-8
P_FCTRL, 4-9
P_FFLUSH, 4-9
P_FINQ, 4-10
P_FREAD, 4-7
P_FSENSE, 4-9
P_FSET, 4-9
P_FTEST, 4-9
P_FWRITE, 4-8
p_open(TTY:), 4-6
panics, 4-1
parameters, 4-1
parity, 4-3
services, 4-6
terminator characters, 4-5
Siena infrared
printer IRP: device driver, 15-7
SIR
infrared, 15-1
SIR:
infrared device, 15-2, 15-3
SND: device
example code, 5-5
introduction, 5-1
see sound device, 5-1
sound
buzzer emulator, 5-1
buzzer piezo, 5-1
device I/O introduction, 5-1
digital files, 5-1
HC machines, 5-1
MC machines, 5-1
INDEX
S3 machines, 5-1
S$3a machines, 5-1
sound device
E_FALARM, 5-3
E_FSSOUNDCHANNEL1, 5-3
example code, 5-5
p_close, 5-2
P_FCANCEL, 5-2
P_FSENSE, 5-2
P_FSET, 5-2
p_open(SND:), 5-2
panics, 5-1
services, 5-2
services additional HC MC S3a, 5-3
services additional S3 S3a, 5-4
SND: introduction, 5-1
structures
DISCOVERY_LOG infrared, 15-5
E_MESSAGE infrared, 17-5
MUXMESSAGE infrared, 17-5
supplement digits
bar codes, 14-4
synchronous
I/O functions, 1-1
SYS$IRDA.IMG
infrared protocol stack, 16-2, 17-2
SYS$NCP
process, 10-1, 10-2
SYS_IR_POWER_LEVEL
infrared, 15-6
SYS_PRINTER_IR
infrared, 15-6
time application
alarm services $3 S3a, 6-2
top slot
HC bar code/RS232 module, 14-2
TTY: device
example code, 4-11
introduction, 4-1
parameters, 4-1
see serial port, 4-1
TTY:A
HC bar code/RS232 module, 14-2
TTY:B
HC bar code/RS232 module, 14-2
TTY sD
HC bar code/RS232 module, 14-2
TTY:E
HC bar code/RS232 module, 14-2
unreliable read request
infrared, 17-4
unreliable write request
infrared, 17-4
W_KEY_IR_BRING
key code, 15-6
W_KEY_IR_LINK
key code, 15-6
W_KEY_IR_ SEND
key code, 15-6
wand emulator
HC bar code/RS232 module, 14-1
winHandle
magic static CON: device handle, 2-2
WLD: device
introduction, 8-1
see world device, 8-1
Workabout
battery capacity calculation, 18-3
Workabout docking station
device introduction, 11-1
see docking station device, 11-1
world application
database S3 S3a, 8-2
world database
contents, 8-1
file extension, 8-9
file format, 8-9
file format extension file, 8-10
file types and locations, 8-9
see also world device, 8-1
world database device
see world device, 8-1
world device
database contents, 8-1
file extension, 8-9
file format, 8-9
file format extension file, 8-10
file types and locations, 8-9
I/O introduction, 8-1
introduction, 8-1
mode, 8-1
p_close, 8-2
P_FCANCEL, 8-2
p_open(WLD:), 8-2
services, 8-2
WR_BACK, 8-3
WR_CALC, 8-8
WR_EXTRA, 8-5
WR_FIND_CITY, 8-2
WR_FIND_COUNTRY, 8-2
WR_FIND_EXACT, 8-3
WR_GET_CITY_DATA, 8-6
WR_GET_COUNTRY_DATA, 8-7
WR_GET_DEFAULT_COUNTRY, 8-4
WR_GET_DIAL_STRING, 8-4
WR_GET_HOME, 8-3
WR_NEXT, 8-3
WR_NEXT_LOCK, 8-9
WR_SET_DEFAULT_COUNTRY, 8-4
WR_SET_EXTRA, 8-5
WR_SET_HOME, 8-3
world file
extension, 8-9
format, 8-9
format extension file, 8-10
main, 8-9
world.dat
location, 8-9
WR_BACK
world device, 8-3
WR_CALC
world device, 8-8
WR_EXTRA
world device, 8-5
WR_FIND_CITY
world device, 8-2
ix
I/O DEVICES REFERENCE
WR_FIND_COUNTRY
world device, 8-2
WR_FIND_EXACT
world device, 8-3
WR_GET_CITY_DATA
world device, 8-6
WR_GET_COUNTRY_DATA
world device, 8-7
WR_GET_DEFAULT_COUNTRY
world device, 8-4
WR_GET_DIAL_STRING
world device, 8-4
WR_GET_HOME
world device, 8-3
WR_NEXT
world device, 8-3
WR_NEXT_LOCK
world device, 8-9
WR_SET_DEFAULT_COUNTRY
world device, 8-4
WR_SET_EXTRA
world device, 8-5
WR_SET_HOME
world device, 8-3
write request
infrared, 17-4
write request unreliable
infrared), 17-4
XMD: device
introduction, 9-1
see XYmodem device, 9-1
Xmodem device
I/O introduction, 9-1
see XYmodem device, 9-1
Xon/Xoff handshaking
HC bar code/RS232 module, 14-2
XYmodem device
checksum CRC, 9-1
checksum one byte, 9-1
device driver, 9-1
device I/O, 9-1
example connect code, 9-10
example disconnect code, 9-10
example file receive code, 9-11
example file recieve code, 9-12
example file send code, 9-10, 9-13
p_close, 9-8
P_FCONNECT, 9-8
P_FDISCONNECT, 9-10
P_FREAD, 9-11
P_FWRITE, 9-12
p_open(XMD:), 9-8
protocol problems, 9-7
protocols, 9-1
services, 9-8
Xmodem protocol, 9-2
Ymodem protocol, 9-4
Ymodem device
I/O introduction, 9-1
see XYmodem device, 9-1