Serial Software Functional Specification


    Distribution: COMPANY CONFIDENTIAL

    Project:      NC1
    Issue:        0.08
    Author(s): 	  Rich Buckley
    Date:         25-Oct-96
    Last Issue:   0.07
  

Contents.


History

  0.01 23-Apr-96 First created
  0.02 30-Apr-96 Modified following changes to FileSwitch
  0.03 03-May-96 Extended with ioctl reason codes
  0.04 10-May-96 Changed ioctl calling convention since we only have one register to play with.
  0.05 13-May-96 Added new ioctl for setting fifo trigger level.
  0.06 15-May-96 Changed information provided on *SerialInfo.
  0.07 14-Jun-96 Updated section on asynchronous events.
  0.08 25-Oct-96 Added ioctls to enumerate supported baud rates.

Outstanding issues

Overview

The Network Computer contains a combo chip supporting two serial ports, the interrupts from each of these serial ports are wired-ORed together to form a shared interrupt. If the combo chip is IrDA capable, the second serial port can be configured to operate in an IrDA compliant mode.

We have three potential uses for the two serial ports supplied with the NC.

It has been suggested that the smart card interface use serial port 1. Serial port two would then be used for either IrDA communications or traditional communications as per build option or application.

Traditionally RiscOS has only supported one serial port. The serial device driver would require significant alteration to support multiple ports and on a RiscPC, the interrupt from the second serial port is not connected to anything so nothing useful can be done with the port.

Technical background

Existing serial driver

Overview

In order to successfully use the second serial port on the Network Computer platform, the existing serial driver would require modification. The OS_SerialOp swi interface could be extended to allow a port number to be specified (using higher byte in reason code register) but the internals of the SerialDeviceDriver and SerialDeviceSupport would require major changes. For example the use of workspace to record current state information.

Send/receive data interface

There are too many different ways of sending and receiving data to/from the serial port. For example Having so many ways of doing the same thing requires work to be done behind the scenes to ensure all the buffer thresholding and handshaking works correctly for all cases. It also confuses developers who are unsure of the most efficient method of doing things.

Configuration interface

The swi interface to allow baud rates, data formats and handshaking to be configured is non-linear and at times completely confusing. (Jon says crap, and Ant says fundamentally flawed). There is no logical way of extending the swi interface to support multiple ports without the interface feeling cluttered.

Backwards compatability

Old style OS_Byte serial port operations are currently provided for backwards compatability with very early versions of RiscOS or even the BBC OS. These are no longer required on the NC.

Efficiency

The efficiency of the serial port interrupt handling code could be improved to reduce the number of swis called on every interrupt. Currently the swi OS_CallAVector is called once for every byte that is taken from the serial port. This could be improved by reading a block of bytes from the port into RAM and then performing a single swi to do a block write of this data into the buffer.

Proposed serial driver

It is proposed that a new module provide an interface to both serial ports on the combo chip. This module would arbitrate between both ports using the shared interrupt. The interface for configuration of these ports is documented in sections below.

A single data input/output interface will be provided to access the serial ports. This will be through the DeviceFS interface with data transfers analogous to file read/writes.

The new wizzo buffer manager internal calls will be used to insert/remove data to/from the buffers. This removes the overhead of calling swis and vectors for every byte of data transfered.

IOCtl support

The modules FileSwitch and DeviceFS have been altered to support IOCtl's. This allows a device driver to receive a control command from an application based on either an open file handle or a directory path in DeviceFS. The following modifications have taken place.

FileSwitch

A new OS_Arg reason code has been allocated OSArgs_IOCtl this has the following arguments.
	On entry
		r0 = 9 (reason code)
		r1 = file handle
		r2 -> ioctl parameter block
	On exit
		r0 preserved
		r1 preserved
		r2 preserved
A new bit has been allocated in the extra filing system information word (PRM 2-523) as follows
	Bit	Meaning if set
	3	Filing system supports OS_Arg IOCtl.
Filing systems should set this bit if they intend to support OS_Arg IOCtl. Existing filing systems will have this bit clear so will never be asked to handle this call.

If the registered filing system supports the IOCtl OS_Arg swi, the call will be dispatched using the normal entry point and reason code. It is up to the underlying filing system to impose a meaning on the registers r2-r7.

DeviceFS

DeviceFS now sets bit 3 in the extra filing system information word to indicate that it wants to handle OS_Arg IOCtl.

A new DeviceFS_CallDevice reason code has been allocated DeviceCall_IOCtl this has the following arguments when received.

DeviceDriver_Entry 14
		
	IOCtl
		
	On entry
		r0 = 14 (reason code)
		r1 = file handle
		r2 = stream handle
		r3 -> ioctl parameter block as passed in r2 of OS_Args call
	On exit
		r0 preserved
		r1 preserved
		r2 preserved
		r3 preserved
This call is dispatched to the underlying device driver whenever the OS_Arg IOCtl swi is called or the swi DeviceFS_CallDevice (14) is called.

Calling convention

The following calling convention should be adopted when using this ioctl interface. Fields have been taken from the unix ioctl implementation as shown below.
	On entry
		r2 -> ioctl parameter block
	On exit
		r2 preserved
where ioctl control block is a pointer to the following structure
	
	typedef struct {
		unsigned int reason   : 16; /* ioctl reason code */
		unsigned int group    : 8;  /* ioctl group code */
		unsigned int reserved : 6;  /* should be zero */
		unsigned int read     : 1;  /* read flag */
		unsigned int write    : 1;  /* write flag */
		unsigned int data;          /* actual data */
	} ioctl_t;
In the case of a ioctl called with both read and write flags set, the returned value will be the new or latest value of the parameter being accessed.

User interface

*SerialInfo

A *command will be provided to display internal serial driver statistics such as current configuration of each port.

	serial1
	   Baud (bps)  : <baud>
	   Data format : <length>.<start/stop>.<n|e|o>
	   Handshake   : <none|rts/cts|rtr/dsr|xon/xoff>
	serial2
	   Baud (bps)  : <baud>
	   Data format : <length>.<start/stop>.<n|e|o>
	   Handshake   : <none|rts/cts|rtr/dsr|xon/xoff>
More information such as buffer sizes, stream handles, etc will be provided if the module is compiled with the debug flag set to true.

Programmer interface

Introduction

The programmer interface to the serial ports will be via DeviceFS and file access. DeviceFS provides a standardised interface to device drivers within RiscOS. Some analogies can be made between DeviceFS files and unix special files. Currently the only devices to use the DeviceFS interface are the serial and parallel device drivers.

Input and/or output to DeviceFS streams should be made on the file path : devices:$.<stream name>

DeviceFS also establishes an environment variable to allow simpler access to this path. This would be constructed as : <stream name>:

Ports

The new device driver will register a number of streams (files) within then DeviceFS filing system. Any application wishing to see what ports are available would enumerate the contents of the directory devices:$. The following streams would be present for the proposed hardware combination on NCD1.

Configuration

The existing serial port configuration requires the calling of a number of swis to set baud rate, data format etc. These swis have interesting parameters which require the programmer to reference the PRMs every time they wish to use them.

The proposed driver works by having a configuration string passed to DeviceFS when the stream is opened for input/output. The position of this configuration string is demonstrated below :

devices#<configuration options>:$.serial1
Where <configuration options> can be made up of any of the following entries in order. Some fields may be omitted and this will leave the option unchanged. Currently due to a problem with DeviceFS, the options should be given in order. A semicolon ';' is used to separate option fields.
  1. baud<n> - baud rate in bps
  2. data<n> - data length in bits
  3. stop<n> - number of start/stop bits
  4. [noparity|even|odd] - type of parity required
  5. [nohandshake|rts|xon|dtr] - type of handshaking required
  6. size<n> - size of buffer
  7. thres<n> - buffer threshold point
For example '#baud19200;data8;stop1;noparity;size1024;thres32;rts'. In fact this is the default state of the driver on initialisation. Except the tx buffer will default to 512 bytes.

If any of the parameters are invalid, for example baud rate not supported, the request to open the stream is refused.

IOCtl configuration

Direct control of the serial port control lines can be achieved using the IOCtl interface described before. This will have the following reason codes.
  1. set/read baud rate :

  2. set/read data format :

  3. set/read handshaking :

  4. set/read buffer size :

  5. set/read rx/tx buffer threshold point :

  6. set/read control lines :

  7. set/read fifo trigger level :

  8. read number of supported baud rates :

  9. read baud rate associated with index :
    • This will return the baud rate associated with index . is an index between 0 and number of supported baud rates-1.

Data transfer

Once the DeviceFS stream has been chosen, data input/output is carried out using standard file access on the stream path name. For example : It should be noted that a single DeviceFS stream cannot be opened for read/write access. Two streams should be opened and maintained. If the second stream is opened with different line characteristics for example a different baud rate, the initial settings will be overwritten in preference of the latest.

To obtain the functionality of swi OS_Args 2 required a change to DeviceFS to allow this information to be returned. You therefore require version 0.31 of DeviceFS in order to implement this functionality.

Asynchronous notification

A scheme is required whereby modules and applications using the serial ports can receive notification of asynchronous events. Such notification would remove the need for constant polling of the streams when waiting to transmit/receive data. The following events are of concern to higher level programmer.

Data present

An upcall is dispatched whenever data enters a previously empty input buffer.
	On entry
		r0 = 15 (upcall code Upcall_DeviceRxDataPresent)
		r1 = stream handle

Threshold above

An upcall is dispatched whenever the amount of data in a stream exceeds the threshold value.
	On entry
		r0 = 16 (upcall code UpCall_DeviceThresAbove)
		r1 = stream handle

Threshold below

An upcall is dispatched whenever the amount of data in a stream falls below the threshold value.
	On entry
		r0 = 17 (upcall code UpCall_DeviceThresBelow)
		r1 = stream handle

Serial errors and line status changes

An event is generated whenever DSR or DCD change or when a line error (parity, framing, overrun) occurs.
	On entry
		r0 = 7 (event code Event_RS423Error)
		r1 = flags
			SerialEvent_Parity         bit 5
			SerialEvent_Overrun	   bit 4
			SerialEvent_Framing	   bit 3
			SerialEvent_DSR		   bit 2
			SerialEvent_DCD		   bit 1
		r2 = input stream handle

Standards

RS232 hardware handshaking using rts/cts, dtr/dsr lines and software handshaking using xon/xoff characters depending on configuration options.

Data interchange

There are no data interchange formats defined by this project.

Data formats

There are not data formats defined by this project.

External dependencies

NC hardware platform.

Acceptance test

Serial data transfer independantly through each serial port on the NC will be at least as good as, if not better than if the existing serial device drivers were to be used.

Development test strategy

Using available hardware (NC1, RiscPC, STB2, serial expansion card).

Product organisation

Standard RiscOS module written in ARM assembler. Module will be built as part of the Omega build tree for inclusion in main ROM.

Future enhancements

Integration of modem driver functionality as serial port 3 ?

References