Latest News
!System updates

Development tools
C/C++ Tools

Writing 32-bit code
32-bit introduction
32-bit overview
32-bit technical
Memory issues
Developer tools
Paul Skirrow's Guide (PDF)
Download area

32-bit APIs
API changes
CallASWI
FileCore

RISC OS 5
Overview
BBC BASIC
CDFS driver
OS_ClaimDeviceVector behaviour
CDFS
Draw clipping
GraphicsV
HAL
Internet
UTF8 & Japanese support
International IME support
MIMEMap
Module PostInit/Final
PCI Manager
PDumper
Podules
Resource allocation
SCSI
Service Calls
UCS fonts
USB
WIMP API Changes
WIMP Flags

IYONIX pc
DDR memory
Help system
Keyboard layout
Miscellaneous
PCI slots

Opportunities

Iyonix Ltd
IYONIX home page
Contact details

   

USB API

This API details the programming interface through which device drivers can communicate with devices via the USB bus.

Versions

Version  Date  Author  Change
0.92  27/9/2003  JWB  Added link to header file USBDevFS.txt
0.91  11/4/2003  JWB  Minor corrections.
0.90  10/4/2003  JWB  Major modifications to reflect the capabilities
      built into RISC OS 5 and the IYONIX pc. This
      reflects a significant change in the manner in
      which the USB driver is called, but does lead to
      a significant simplification of the whole
      process.

Where differences in the current implementations exist, these are noted.

Introduction

Sections:
  • DeviceFS interface
  • DeviceFS calls
  • Service calls
  • Alias matching
  • Commands

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 variety of different USB host adaptor cards within the RISCOS environment. This document describes such an API which is compatible with both RISCOS 5 as shipped on the IYONIX pc, and version 0.90 and later of Castle's 4 port USB podule.

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.

The naming convention used for devices is USBxxnnn, where all device names start USB, followed by 0 or more vendor specific characters (nn) and a number (nnn) in the range 0 to 999.

The IYONIX pc uses "USBnnn" e.g. "USB2". Castle's USB podule uses "USBDnnn" e.g. "USBD2". Examples given in this document use "USBD" as the driver name.

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 can have some or all of the following:
Value  Meaning  IYONIX?  Podule?
interface/N  Interface to use. Defaults to the first suitable one.  Yes  Yes
alternate/N  Interface alternate to use. Defaults to the first suitable  Yes  Yes
  one.    
endpoint/N  Desired endpoint. Defaults to the first suitable one.  Yes  Yes
report/N  Desired HID report. If specified,only this information will  Yes  No
  be made available.    
control  The type of transfer required. Defaults to bulk, or what a  Yes  Yes
isochronous  specified endpoint requires. (Isochronous is not fully    
bulk  supported at present.)    
interrupt/S      
nosync  Synchronisation type. Only relevant to isochronous  No  No
async  transfers.    
adaptive      
sync/S      
data  Only relevant to isochronous transfers.  No  No
feedback      
implicit/S      
usbtimeout/N  Command timeout in milliseconds. Default is no timeout.  Yes  No
size/N  The preferred stream buffer size to use. Some devices may  Yes  Yes
  benefit from a larger buffer than the default.    

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.
Value  IOCTL  Action IYONIX? Podule?
Nosleep  4  true/false. Any DeviceFS stream, if opened with the special Yes No
sleep/S    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 Yes No
    error if it sleeps for too long. The default is 0 meaning
    sleep for ever.

Each USB device, when plugged in, is "enumerated" and a separate device is created within DeviceFS. Each time a device is "enumerated" it has a new device number created. Devices thus range from "USBD0" to "USBD999" (or "USB0" to "USB999") before starting at 0 again.

Examples:

To open an interrupt in connection to USBD3 endpoint 1 from BASIC:

port% = OPENIN"devices#interrupt;endpoint1:usbd3"

To open a bulk (by default) out connection to USB3 endpoint 2 from BASIC:

out% = OPENOUT"devices#endpoint2:usb3"

To open a bulk (by default) in connection from USBD3 endpoint 1 from BASIC:

in% = OPENIN"devices#endpoint1:usbd3"

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.
Register Value  Entry  IYONIX?  Podule?
USB Control Request    Yes  Yes
R0 1<<31 + 0  Send request to a device's default control pipe and    
  return the reply.    
R1  Device name eg "usbd"    
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.    
Check buffer space    Yes  Yes
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  Device name eg "usbd"    
R2  Stream handle as returned by fileswitch.    
Returns:R3  Bytes available in buffer    
Returns:R4  Bytes free in buffer    
Return handles    Yes  Yes
R0 1<<31 + 3  Return the buffer handle and DeviceFS stream    
  handle for this stream    
R1  Device name eg "usbd"    
R2  Stream handle as returned by fileswitch.    
Returns:R3  Buffer handle    
Returns:R4  DeviceFS stream handle    
Get Location    Yes  No
R0 1<<31 + 4  Get Device Location on bus.    
R1  Device name eg "usbd"    
R3  Pointer to 6 byte block.    
Returns:  Block filled in with 6 byte array: bus, port1, port2,    
  port3, port4, port5. This indicates the physical    
  location of the usb device. This provides a method    
  of identifying the same device across reboots.    

Note: The Check Buffer Space call has been added to enable users to code simple drivers in higher level languages such as BASIC. On RISC OS 4 and earlier, commands such as BGET of BPUT will not return if there is no data or space in the stream's buffer. With this call the user can only make such blocking calls when they wont be blocked.

Command completion status

(Podule only)
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
Register  Value  Meaning
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.
R2  name  Name driver uses (reason codes 3 and 4) e.g. "USB"
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 is specified
    in the USBDevFS.txt header file . The current version
    of this header file is 0.75 (8 March 2003). 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. (not used) 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. Note that this call is
    not used. Since each USB device is a unique DeviceFS
    device, the DeviceFS_DeviceDead service call will
    provide this information.
R0  3  USB driver module starting.
R0  4  USB driver module dying.

Aliases and Alias Matching

A powerful Alias matching system is employed to provide a system for locating and launching specific applications and tools when relevant USB devices become available. Once a device is connected and "enumerated" several things happen:
  • A device is created for it within DeviceFS.
  • The USB_Connected service call is issued.
  • An Alias is created for it with just vendor and product IDs in place.
  • A check is made for a matching alias, and if found it is launched.
  • If no alias was launched, a second Alias is created with additional configuration information.
  • A new check is made for an alias match.

The alias created is of the form USB$Device_LL_SS_TT_VVVV_PPPP_CC_II_RRRR_USBDnnn (or USBnnn)
Code  Meaning  Value at first check  Value at second check  
LL  class  00  class  
SS  subclass  00  subclass  
TT  protocol  00  protocol  
VVVV  vendorID  vendorID  vendorID  
PPPP  productID  productID  productID  
CC  current  -1  configuration  
  configuration      
II  interface  -1  interface  
RRRR  release number  -1  product release number  
nnn  device number  usb device number  usb device number  

When first created this is set to the number nnn. The second time around it has 3 numbers: nnn interface alternate. In the descriptions and examples below device USBDnnn is used. This is correct for the podule. IYONIX uses USBnnn.

Aliases are searched in accordance with the USB Common Class Specification (revision 1.0). This means that the following searches shall be done:

Alias@USBD$Device_*_*_*_V_P___R
Alias@USBD$Device_*_*_*_V_P___*
Alias@USBD$Device_L_S_T_V_*___*
Alias@USBD$Device_L_S_*_V_*___*
Alias@USBD$Device_L_S_T_*_*___*
Alias@USBD$Device_L_S_*_*_*___*

If a driver is found at that stage then it can participate in choosing the configuration for the driver. Otherwise the system software chooses an appropriate configuration and the search is proceeded using the following, taking each interface in turn, taking the class and subclass data from the interface descriptor:

Alias$@USBD$Device_*_*_*_V_P_C_I_R
Alias$@USBD$Device_*_*_*_V_P_C_I_*
Alias$@USBD$Device_L_S_T_V_*_*_*_*
Alias$@USBD$Device_L_S_*_V_*_*_*_*
Alias$@USBD$Device_L_S_T_*_*_*_*_*
Alias$@USBD$Device_L_S_*_*_*_*_*_*

If a match is made, the alias will be executed. This permits (e.g.) an obey file to be created containing lines such as:

   Alias @USBDDevice____03F0_0417____ Do Path HPLJ1220 USBD%%0#usbtimeout10000;size16384:|mUSBDSetInterface %%0 0 1|m||%%*0

   If "<USBD$Device_*_*_*_03F0_0417_*_*_*_*>" <> "" Then Do @usbddevice____03F0_0417____ <USBD$Device_*_*_*_03F0_0417_*_*_*_*>

Note that though each command appears to take 2 or more lines, each is one line only.

The first line sets up an alias for a device (vendor)03F0 and (product)0417 (which is an HPLJ1220C printer) which will create a path variable "HPLJ1220:" and choose interface 0 alternate 1 as the desired interface to use. The second line will execute the alias if it is already set up when the obey file is run.

Commands

Command  Usage  IYONIX?  Podule?  
USBDBuses  Displays a list of available USB buses  Yes  No  
USBBuses        
USBDDevices  Displays a list of available USB devices  Yes  No  
USBDevices        
USBDDevInfo <n>  Displays device information on device <n>  Yes  No  
USBdevInfo        
USBDConfInfo <n>  Displays configuration information on device <n>  Yes  No  
USBConfInfo        
USBDSetConfig <n><m>  Set configuration value for device <n> to  Yes  Yes  
USBSetConfig  configuration <m>      
USBDSetInterface <n><m><p>  Set device <n> to interface <m>  Yes  Yes  
USBSetInterface  and alternate <p>      
USBDReset <n>  Force device <n> to be reset and  Yes  No  
USBReset  "enumerated" again.      

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 (or 5) 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.

© 2006 IYONIX Ltd 32-bit RISC OS