Programming API

for low level access to USB interfaces within RISCOS

J Ballance, Castle Technology Ltd.

 

This API details the programming interface by means of which device drivers can communicate with devices via the USB bus

 

 

 

Version

Author

 

0.67 17/08/02

JWB

The DeviceCall &80000000 entry has been modified to permit optional background completion of control channel commands. Setting r6 on entry to 0 leaves it operating as before.

0.66 5/08/02

JWB

Return buffer handle call extended to return DeviceFS stream handle too (useful for issuing DeviceFS_DeviceCall_WakeRx or Tx).

0.65 16/07/02

JWB

Extended Service_USB to include details of the hub address and port to which a device connects.

0.58 04/07/02

JWB

Added reason code USB_DeviceGone to Service_USB to report the de-activation of a previously announced USB device.

0.57 19/06/02

JWB

Modified, by popular request, Service_USB service call to return a linked list of RMA chunks with information within, similar to internet network drivers; it is the caller's responsibility to free this.

0.56 16/06/02

JWB

Modified SWI USBOp_ReportConnected details. Extended the service call definintion to cover the SWI functionality in a way that permits multiple USB card/vendor presence.

0.55 14/06/02

JWB

Added SWI USBOp_ReportConnected details

0.54 12/06/02

JWB

Added Service_USB info and some DeviceFS info

0.53 18/05/02

JWB

Added initial Service call information

0.52 15/05/02

JWB

Pre show release

0.51 27/04/02

JWB

 

0.5 25/4/02

JWB

Initial Draft release

Introduction

 

The Universal Serial Bus (USB) is a simple interconnect system widely standardised and for which a large range of devices is available. For use on RISCOS specific drivers will (always) need to be adapted or written. It is useful, however, to provide a relatively simple programming interface(API) that will permit developers of device drivers to create drivers that will operate on a vaiety of different USB host adaptor cards within the RISCOS environment. This document describes such an API.

 

No attempt is made to describe how to control devices over the USB bus using USB protocols. It merely describes the low level interface through which these commands may be issued in a manner that is not directly dependant on the hardware providing the USB host interface.

 

Note: examples given in this document use usbd as the driver name. Other driver names using this style of DeviceFS interfacing are believed to exist, e.g. phci

 

 

DeviceFS interface

Device specific drivers communicate with the low level USB host driver, and thence the USB hardware and attached devices, via FileSwitch and DeviceFS_CallDevice. Streams are opened to or from an endpoint using special fields to define requirements.

 

The special field decoding string is (spaces added for clarity):

address/N endpoint/N control,isochronous,bulk,interrupt/S nosync,async,adaptive,synch/S data,feedback,implicit/ maxpacket/N interval/N full,low/S

( /N : number needed. /S : select one of these keywords)

Field

Meaning

address/N

device address

endpoint/N

the endpoint number in the device

control,isochronous,bulk,interrupt/S

The type of transfer. (Isochronous is not supported in some low level drivers.)

nosync,async,adaptive,synch/S

Synchronisation type. Only relevent to isochronous transfers.

data,feedback,implicit/S

Only relevant to isochronous transfers.

maxpacket/N

The maximum packet size.

interval/N

The interval for polling the endpoint for data transfers in (micro)frames. (1ms for low and full speed connections)

full,low/S

Transfer speed: not supported in some low level drivers, but should be specified to ensure future compatibility

Numbers are converted using OS_ReadUnsigned so if the string starts with base_, this base is used or if the string starts with & then it is hexadecimal. If there is no prefix then it is decimal.

Two special fields have been added that are acted on by later versions of DeviceFS. The same functionality is also available via an IOCTL call. The addition to the decoding string is:

nosleep,sleep/S timeout/N

Special

IOCTL

Action

Nosleep,sleep/S

4

true/false. Any DeviceFS stream, if opened with the special field entry 'sleep' will issue OS_UpCall 6 when it would otherwise block thus allowing Taskwindows to continue multitasking. Default nosleep. (Note.. in currently available versions of DeviceFS, without this sleep ability, the same effect can be achieved by polling the buffer associated with the stream and only making such a 'blocking' call if there is data (or space as relevant) in the buffer. if no data/space is available, then an UpCall 6 can be issued. See later for details of a call to provide this information)

timeout/N

5

Time in cs This will cause the stream to issue a timeout error if it sleeps for too long. The default is 0 meaning sleep for ever.


Example, to open a connection to the root hub endpoint 1 from BASIC:
control% = OPENIN"usbd#sleep;address"+STR$(address%)+";interrupt;endpoint1;maxpacket1;interval100:"

The root hub has address 1. The hub driver uses USB protocols to control the root hub. The USB controller acts on the USB control transfers to address 1 to control the hardware. Thus the same hub driver can be used for both the root hub and remote hubs.

 

DeviceFS_CallDevice

 

There are 4 extension calls into the DeviceFS driver which are passed directly to the USB driver and are shown in the table below.

Issue a USB Request to Device

Register

Value

Entry

R0

1<<31 + 0

Send request to a device and return the reply. Usually this will be to the devices default control pipe.

R1

Driver handle or pointer to path. eg "usbd"

Acted on by DeviceFS and ignored by this driver.

R2

Stream handle as returned by fileswitch.

 

R3

Byte 0

BmRequestType

Byte 1

BRequest

Bytes 2, 3

WValue

R4

Bytes 0, 1

WIndex

Bytes 2, 3

WLength

R5

Pointer to data buffer.

 

R6

0

Return on command completion, command failure, or command timeout.

Bit 0 = 1

Return after commencing the command with R7 containing the address of a pollable status byte. See below for details of return values

Bit 1 = 1

On entry, R7 contains the address of a routine to be called on command completion. R8 will contain the value to be used for the R12 value when this is called. See below for details of this call.

R7

Callback address if R6 bit 1 set.

R8

Private word for Callback address in R7 if R6 bit 1 set.

Allocate a new device address

R0

1<<31 + 1

Send request to the driver module for a new address.

R1

Driver handle or pointer to path. eg "usbd"

Acted on by DeviceFS and ignored by this driver.

R2

Stream handle as returned by fileswitch.

 

Returns:R3

Address

Check buffer space

R0

1<<31 + 2

Interrogate the free space and data available in the buffer associated with a DeviceFS stream. (note: not all drivers will implement this, as the information can be directly discovered)

R1

Driver handle or pointer to path. eg "usbd"

Acted on by DeviceFS and ignored by this driver.

R2

Stream handle as returned by fileswitch.

Returns:R3

Bytes available in buffer

Returns:R4

Bytes free in buffer

Return buffer handle and DeviceFS stream handle

R0

1<<31 + 3

Return the buffer handle and DeviceFS stream handle for this stream

R1

Driver handle or pointer to path. eg "usbd"

Acted on by DeviceFS and ignored by this driver.

R2

Stream handle as returned by fileswitch.

Returns:R3

Buffer handle

Returns:R4

DeviceFS stream handle

 

Note: the Check buffer space call has been added to enable users ot code simple drivers in higher level languages such as BASIC. Commands such as BGET of BPUT will not return if there is no data or space in the streams buffer. With this call the user can only make such blocking calls when they wont be blocked.

 

Command completion status
There are currently 2 defined status values detectable in the pollable byte.
0 .. command not completed
1 .. command completed successfully
2 .. command currently receiving a NAK
3 .. command has received a STALL and finished
4 .. command retrying
5 .. command has received a USB timeout
6 .. command is set inactive

If a callback on completion is requested, the routine will be called back with registers set as follows:
R0 .. completion status as above
R12.. set to the value passed through in R8 when the callback was requested
Your routine may be called within an interrupt service routine, so care should be taken to ensure that non re-entrant SWIs are not called, and that you spend the minimum time in your callback routine.

 

 

Service calls

 

There is 1 defined service call at present, Service_USB (0xD2). It has 3 variants, distinguished by the value in R0 on entry. It is issued by the hub controller within the driver, once it has successfully 'enumerated' a device, to report the presence of a newly connected device. It can also be issued by other parties wishing to find what devices are available if they are unable to receive service calls (e.g are applications), or if they arrived after a device was connected.

Service_USB

R1

0xD2

Service_USB service call number. R1 should be passed onwards without claiming the call. The value in R0 determines the usage of this.

R0

0 - New device connected

Issued by the USB controller, this call reports that a new device has been connected and is available for use. R2 is a pointer to a structure of type USBServiceCall. The format of this can be derived from the h.USBDevFS header file in any of the supplied examples. The current version of this header file is 0.65,16/7/02. Access to a device can be claimed by opening a file for that device/endpoint. Please see the sample drivers for an example of this.

R0

1 - Report connected devices

Issued with R2 set to zero. Each controller adds USBServiceAnswer pointers in a linked list. If R2 = NULL, then the controller sets R2 to point to a chunk of RMA containing a USBServiceAnswer structure, with the link field set to NULL. Subsequent devices are reported by scanning the list of pointers until a NULL next pointer is found and replacing the NULL with a pointer to a further chunk of RMA, with its link pointer set to NULL. It is the responsibility of the issuer of this service call to free the memory chunks returned.

R0

2 - Device has gone

R2 is a pointer to a structure of type USBServiceCall, such as would have been issued when the device was originally announced using reason code 0 - New device connected. This call announces the fact that the device is no longer available for use.

 

SWIs

 

There is 1 defined SWI at present in the Castle USB system, USBOp_ReportConnected, &54bc0. This is a Castle specific SWI, and users should use the service call method above in preference. It implements the same functionality as entry code 1 in the service call definition above. Entry values and return values for R0 and R2 are the same as for the service call above

 

DeviceFS issues

 

This is for others intending to provide a devicefs interface to their USB cards..When writing a devicefs driver the devicefs driver entry 0 (initialise) is missing a vital parameter on versions of devicefs prior to that shipped with RISC OS 4. The RISC OS 4 entry provides the fileswitch stream handle in R4. For earlier devicefs versions, this handle may be found as a 32 bit value at offset 44 from the pointer supplied in R2.