14946 lines
370 KiB
Plaintext
Executable File
14946 lines
370 KiB
Plaintext
Executable File
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, ¬es1[0],é&lenl);
|
||
p_ioc5 (pcb, E_FSSOUNDCHANNEL2, &ésndstat2, ¬es2[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 computer’s 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 other’s 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) station’s 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 application’s 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 machine’s 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,”Bob’s 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,”Bob’s 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 don’t care
|
||
|
||
byte don’t care
|
||
|
||
byte don’t 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 station’s 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
|
||
|
||
|