Chapter 9. Old Documentation

Table of Contents

9.1. USB transfer requests
9.2. Other functions

This chapter currently contains a copy of the old Thomas Milius programming documentation. These have been edited to remove unnecessary information on writing a host driver (information of this can be found in the host driver writing book).

Warning

This chapter is provided for historical reference only and will be removed in future versions, use the information provided in other parts of the book in preference to the information contained here which may be out of date or simply inaccurate.

9.1. USB transfer requests

Isochronous Transfer

Isochronous transfer has the highest priority at USB. If requests on it are pending it can be done every USB frame. There is no acknowledgement whether the data has been transferred correctly. An isochronous transfer cannot been split up into several transaction, so the size of the data buffer must fit exactly to the data payload size. Note that Isochronous transfers can be only done on devices with normal speed. The frame repeat number must be set to 1.

Bulk Transfer

Bulk transfers have the lowest priority at USB. It is done if free capacity at the USB is available. There is an acknowledgement whether the data has been transferred correctly. The transfer can be split up into several transactions which can be processed over a lot of frames. Note that Bulk transfers can be only done on devices with normal speed. The frame repeat number must be set to 0.

Interrupt Transfer

Interrupt Transfers are similar to Bulk transfers but they have a priority immediately beyond Isochronous Transfer at USB. An interval of frames must be given after which the next transfer can be done. In detail this is meaning that if a new request has been set generated by the host software the transfer will be first done after USB frame has reached a value which is less or equal than the value calculated from the last frame number where an interrupt transfer was done at this endpoint by adding the interval of frames. Note that it can happen that a long time distance is passing between two requests. This may be based on a device which is responding with NAKs if there is no data. Therefore the last frame number can't be always taken as the base of calculation. USB module must check whether the last frame number is inside an interval between actual frame number minus repeat interval size and actual frame number. This may lead to a gap in worst case of one repeating interval but this will only happen at slow devices which won't respond regularly and this can be tolerated. There is an acknowledgement whether the data has been transferred correctly. The transfer can be split up into several transactions which can be processed over a lot of frames. If the frame number has been reached where an interrupt request can be processed it should be sorted into the queue of waiting interrupt requests by the frame number of next interval start of this interrupt pipe. Note that Interrupt transfers can be done on devices with low or normal speed.

9.2. Other functions

There are the following other functions:

  • USB_FastAccessInformation

Data Structures of application to USB Module communication

There are two fundamental data structures used at the communications between the programs and the USB module:

  • Data buffer structure

  • Waiting mode structure

Data buffer structure

Because access to data buffers must be done by the programs on the host, the USB-Module and the USB host controller driver (including. the USB Hardware in some cases) it is stored in memory with public address range like RMA or dynamic areas. It must be therefore allocated/released by special functions. Data buffers are generally owned by one program. The control is passed on to other parts of the USB software. Note that these software is only allowed to change the content of the data buffer but it is never allowed to release the buffer. A data buffer must always been passed back to the program which has allocated it.

To allow the usage of existing data structures inside RISCOS like buffers programs can declare a particular piece of memory from the public address space as an USB data buffer. There are two ways to generate such a buffer. You can use the normal functions and passing them the address of the beginning of the memory of the buffer. In this case only the additional information will be allocated from the memory by the USB_BufferMalloc function. Of course it will calculate the total size of the buffer space as a multiple of the data payload size of the related pipe. You must keep care that the buffer you passed to the function is large enough or you must change the size value. In the other case your application can generate a buffer of the format described below completely itself. However take care that the size is always a multiple of the data pay load size of the pipe you want to use. Of course you can change the buffer address inside the USB buffer structure as you like from request to request for eg implementing a device FS.

The waiting information is included into the buffer structure even the programs shall not try to access it directly but shall always use the according functions. This saves an acknowledgement from the program to the USB module that it has evaluated the result of a request.

Buffer reading

The number of bytes in the buffer which are really used should be set to the number of bytes which you are expecting to receive. An error will be generated if you will receive less or more bytes and an according flag has been set. If you are not expecting a fixed size so set this value to zero. It will be left unchanged during the whole transfer. So you are able to compare the received bytes inside the actual position with the expected size. A zero length buffer can be generated by setting the USB_TRANSACTION_EXACT_SIZE flag at request generating. The actual transfer position will be reset to zero automatically if request is started. At the end of the transfer it will pointing exactly one byte behind the received data. After the transfer has been done you can evaluate the data buffer content.

Buffer writing

Fill the data into the buffer and set the number of bytes which are really used with the according size. The actual transfer position will be reset to zero automatically if request is started. Note that this value remains unchanged after the transfer has been done. It is granted that actual transfer position is pointing directly to the beginning of the data which has not been sent if an error occurred. A zero length buffer can be generated by setting the number of bytes which are really used to zero and setting the USB_TRANSACTION_EXACT_SIZE flag at request generating.

Table 9.1. Format of data buffer structure

PositionData typeDescription
0x00unsigned longPointer to begin of buffer data. If data is included in this structure it will point behind the waiting structure else it must point to the piece of memory which is used as data buffer.
0x04unsigned longAllocated data buffer size in Bytes. If the offset is added to this value you are getting the whole size of the buffer structure.
0x08unsigned longNumber of Bytes in the buffer which are really used for data in the moment.
0x0Cunsigned longActual position of data transfer.
0x10unsigned longNumber of the frame in which the transaction has been completed. Must be filled by the USB host controller driver.
0x14unsigned longData toggle as the transaction has been completed. Must be filled by the USB host controller driver.
0x18various. Size may vary from version to versionWaiting structure. Exact structure see below.
... At later version here there may be additional information located.
(0x18 + Size of Waiting Structure) word allocated data of arbitrary size word aligned. Only if data buffer memory is hold inside this buffer. Not used if this memory is located elsewhere.

Waiting mode structure

Programs should only set the size (sizeof(waiting) in C), the waiting mode and additional parameters belonging to this mode. All other operations are done internally the USB-module. Note that a copy of your waiting structure is placed inside one buffer of a request. The setting of the size is needed to grant future compatibility. If an application mallocs a new buffer for USB requests the size of the waiting structure is automatically initialised.

Table 9.2. Format of Waiting structure

PositionData typeDescription
0x00intSize of this structure (actual 0x3C Bytes).
0x04intWaiting Mode
0x08intResult
0x0CintFlag that shows that no result has been received. That means that the waiting is still going on.

Table 9.3. additional data for WAITING_TYPE_MESSAGE

PositionData typeDescription
0x10PointerPointer to WIMP message block located in common address space.
0x14intDestination task handle
0x18intIcon handle

Table 9.4. Additional data for WAITING_TYPE_SWI

PositionData typeDescription
0x10intNumber of the SWI to call
0x14-0x3CintAn array of 10 register values passed to the SWI call.

Table 9.5. Additional data for WAITING_TYPE_APCS

PositionData typeDescription
0x10PointerPointer to APCS-Function located in common address space.
0x14-0x24intAn array of 4 register values passed to the APCS function call.

Waiting Constants

Please note that in all modes except WAITING_TYPE_RETURN the calling program is only informed that a request has been finished. It will be not informed whether the operation has been successful. It has to use USB_RequestGetState to get this information.

Table A.9