usbdrvce.h

#include <usbdrvce.h>

The usbdrvce library is used for interacting with the USB peripheral in either host or device mode.

Currently this library is a work-in-progress, so some functionality may not behave as expected. In particular, the following items are known to not work:

  • All timer-related functions

  • Isochronous transfers

Because of these limitations, future library versions may create backwards-incompatible changes - however the likelihood of this is rather low as long as you use the library in a reasonable manner.

Tip

Be sure to look at the provided examples for guidance on how to use this library correctly. Hopefully in the future this page will include more documentation as the library becomes more complete.

API Documentation

This is a library for interfacing with the calculator’s USB port. It is very low-level, similar to libusb, with the intention that higher-level libraries can be built on top of it.

Author

Jacob “jacobly” Young

Warning

This library requires general-purpose timer 2, so TIMER2 things from tice.h can’t be used between calls to usb_Init() and usb_Cleanup(). However, this library exposes a safe way to read the timer 2 counter, which is setup to count up with the CPU clock via usb_GetCycleCounter() et al.

Warning

If you enable timer 3 interrupts via the interrupt controller the OS will try to do USB stuff and corrupt this library’s data. As a safety measure, many routines will return USB_ERROR_SYSTEM if this happens.

Defines

USB_INIT_FLSZ(x)
USB_INIT_ASST(x)
USB_INIT_EOF1(x)
USB_INIT_EOF2(x)
usb_RootHub()

Root hub device.

usb_callback_data_t

A pointer to usb_callback_data_t is passed to the usb_event_callback_t.

The default is void *, but this can be changed by doing:

#define usb_callback_data_t struct my_usb_callback_data
#include <usbdrvce.h>

usb_device_data_t

A pointer to usb_device_data_t can be associated with devices.

The default is void *, but this can be changed by doing:

#define usb_device_data_t struct my_usb_device_data
#include <usbdrvce.h>

usb_endpoint_data_t

A pointer to usb_endpoint_data_t can be associated with endpoints.

The default is void *, but this can be changed by doing:

#define usb_endpoint_data_t struct my_usb_endpoint_data
#include <usbdrvce.h>

usb_transfer_data_t

A pointer to usb_transfer_data_t is passed to usb_transfer_callback_t.

The default is void *, but this can be changed by doing:

#define usb_transfer_data_t struct my_usb_transfer_data
#include <usbdrvce.h>

usb_GetDeviceDescriptor(device, descriptor, length, transferred)

Macro of usb_GetDescriptor() using USB_DEVICE_DESCRIPTOR for the type.

usb_GetConfigurationDescriptor(device, index, descriptor, length, transferred)

Macro of usb_GetDescriptor() using USB_CONFIGURATION_DESCRIPTOR for the type.

usb_SetDeviceDescriptor(device, descriptor, length)

Macro of usb_SetDescriptor() using USB_DEVICE_DESCRIPTOR for the type.

usb_SetConfigurationDescriptor(device, index, descriptor, length)

Macro of usb_SetDescriptor() using USB_CONFIGURATION_DESCRIPTOR for the type.

usb_DefaultControlTransfer(device, setup, buffer, retries, transferred)

Schedules a control transfer to the default control pipe of device, in the direction indicated by setup->bmRequestType, using buffer as the data buffer, setup->wLength as the buffer length, and then waits for it to complete.

If acting as usb host, setup is used as the setup packet, otherwise all fields not mentioned above are ignored.

Parameters
  • device – The device to communicate with.

  • setup – Indicates the transfer direction and buffer length. If acting as usb host, also used as the setup packet to send.

  • buffer – Data to transfer that must reside in RAM and be at least setup->wLength bytes.

  • retries – How many times to retry the transfer before timing out. If retries is USB_RETRY_FOREVER, the transfer never times out.

  • transferred – NULL or returns the number of bytes actually received.

Returns

USB_SUCCESS if the transfer succeeded or an error.

usb_BulkTransfer

Macro duplicate of the usb_Transfer() function with the same arguments.

See also

usb_Transfer()

usb_InterruptTransfer

Macro duplicate of the usb_Transfer() function with the same arguments.

See also

usb_Transfer()

usb_IsochronousTransfer

Macro duplicate of the usb_Transfer() function with the same arguments.

See also

usb_Transfer()

usb_ScheduleDefaultControlTransfer(device, setup, buffer, handler, data)

Schedules a control transfer to the default control pipe of device, in the direction indicated by setup->bmRequestType, using buffer as the data buffer, and setup->wLength as the buffer length.

If acting as usb host, setup is used as the setup packet, otherwise all fields not mentioned above are ignored.

Parameters
  • device – The device to communicate with.

  • setup – Indicates the transfer direction and buffer length. If acting as usb host, also used as the setup packet to send.

  • buffer – Data to transfer that must reside in RAM. This buffer must remain valid until the callback is called i.e. it cannot be modified or freed.

  • handler – Function to be called when the transfer finishes.

  • data – Opaque pointer to be passed to the handler.

Returns

USB_SUCCESS if the transfer was scheduled or an error.

usb_ScheduleBulkTransfer

Macro duplicate of the usb_ScheduleTransfer() function with the same arguments.

usb_ScheduleInterruptTransfer

Macro duplicate of the usb_ScheduleTransfer() function with the same arguments.

usb_ScheduleIsochronousTransfer

Macro duplicate of the usb_ScheduleTransfer() function with the same arguments.

usb_StartTimerMs(timer, timeout_ms)

Starts a timer that expires timeout_ms after calling this function.

Note

May be called from within timer->handler itself.

Parameters
  • timer – A user allocated struct with timer->handler already initialized.

  • timeout_ms – Timeout in milliseconds.

usb_RepeatTimerMs(timer, timeout_ms)

Starts a timer that expires timeout_ms after it last expired.

Note

May be called from within timer->handler itself.

Parameters
  • timer – A user allocated struct with timer->handler already initialized.

  • timeout_ms – Repeat interval in milliseconds.

Typedefs

typedef enum usb_init_flags usb_init_flags_t
typedef enum usb_event usb_event_t
typedef enum usb_error usb_error_t
typedef enum usb_transfer_status usb_transfer_status_t
typedef enum usb_device_flags usb_device_flags_t
typedef enum usb_find_device_flags usb_find_device_flags_t
typedef enum usb_endpoint_flags usb_endpoint_flags_t
typedef enum usb_role usb_role_t
typedef enum usb_speed usb_speed_t
typedef enum usb_transfer_direction usb_transfer_direction_t
typedef enum usb_request_type usb_request_type_t
typedef enum usb_recipient usb_recipient_t
typedef enum usb_request usb_request_t
typedef enum usb_feature usb_feature_t
typedef enum usb_device_status usb_device_status_t
typedef enum usb_endpoint_status usb_endpoint_status_t
typedef enum usb_descriptor_type usb_descriptor_type_t
typedef enum usb_class usb_class_t
typedef enum usb_configuration_attributes usb_configuration_attributes_t
typedef enum usb_usage_type usb_usage_type_t
typedef enum usb_synchronization_type usb_synchronization_type_t
typedef enum usb_transfer_type usb_transfer_type_t
typedef struct usb_control_setup usb_control_setup_t
typedef struct usb_descriptor usb_descriptor_t
typedef struct usb_device_descriptor usb_device_descriptor_t
typedef struct usb_device_qualifier_descriptor usb_device_qualifier_descriptor_t
typedef struct usb_configuration_descriptor usb_configuration_descriptor_t
typedef struct usb_configuration_descriptor usb_other_speed_configuration_t
typedef struct usb_interface_descriptor usb_interface_descriptor_t
typedef struct usb_endpoint_descriptor usb_endpoint_descriptor_t
typedef struct usb_string_descriptor usb_string_descriptor_t
typedef struct usb_standard_descriptors usb_standard_descriptors_t
typedef struct usb_device *usb_device_t

opaque device handle

typedef struct usb_endpoint *usb_endpoint_t

opaque endpoint handle

typedef usb_error_t (*usb_event_callback_t)(usb_event_t event, void *event_data, void *callback_data)

Type of the function to be called when a usb device event occurs.

Param event

Event type.

Param event_data

Event specific data.

Param callback_data

Opaque pointer passed to usb_Init(). By default is of type void *, but that can be changed by doing:

#define usb_device_callback_data_t struct mystruct
#include <usbdrvce.h>

Return

Return USB_SUCCESS to initialize the device, USB_IGNORE to ignore it without erroring, or any other value to abort and return from usb_ProcessEvents() with that value.

typedef usb_error_t (*usb_transfer_callback_t)(usb_endpoint_t endpoint, usb_transfer_status_t status, size_t transferred, void *data)

Type of the function to be called when a transfer finishes.

Param endpoint

The transfer endpoint.

Param status

Status of the transfer.

Param data

Opaque pointer passed to usb_Schedule*Transfer(). By default is of type void *, but that can be changed by doing:

#define usb_transfer_callback_data_t struct mystruct
#include <usbdrvce.h>

Param transferred

The number of bytes transferred. Only valid if status was USB_TRANSFER_COMPLETED.

Return

Return USB_SUCCESS to free the transfer. Return USB_IGNORE to restart it, which is only possible if USB_TRANSFER_FAILED is set. Return any other value to abort and return from usb_ProcessEvents() with that value.

typedef struct usb_timer usb_timer_t

This struct represents a timed callback.

It must be allocated by the user. The only public member is handler, which must be initialized before use. If you want to access other data from the callback, allocate a larger struct with this struct as its first member and cast like in the usb_timer example.

typedef usb_error_t (*usb_timer_callback_t)(usb_timer_t *timer)

Type of the function to be called when a timer expires.

Param timer

Timer pointer.

Return

Return USB_SUCCESS or any other value to abort and return from usb_ProcessEvents() with that error.

Enums

enum usb_init_flags

Values:

enumerator USB_USE_C_HEAP = 1 << 0

Use part of the default C heap.

Warning

Do not use this unless you changed your program’s bss/heap to end at 0xD10000!

enumerator USB_USE_OS_HEAP = 1 << 1

Use the application heap area.

enumerator USB_INIT_FLSZ_1024 = (((0) & 3) << 2)

Init Frame List Size to 1024.

enumerator USB_INIT_FLSZ_512 = (((1) & 3) << 2)

Init Frame List Size to 512.

enumerator USB_INIT_FLSZ_256 = (((2) & 3) << 2)

Init Frame List Size to 256.

enumerator USB_INIT_FLSZ_0 = (((3) & 3) << 2)

Disable Frame List.

Warning

This also disables support for periodic transfers and hubs!

enumerator USB_INIT_ASST_0 = (((0) & 3) << 8)

Init Async Sched Sleep Timer to 0.

enumerator USB_INIT_ASST_1 = (((1) & 3) << 8)

Init Async Sched Sleep Timer to 1.

enumerator USB_INIT_ASST_2 = (((2) & 3) << 8)

Init Async Sched Sleep Timer to 2.

enumerator USB_INIT_ASST_3 = (((3) & 3) << 8)

Init Async Sched Sleep Timer to 3.

enumerator USB_INIT_EOF1_0 = (((0) & 3) << 10)

Init EOF 1 Timing to 0.

enumerator USB_INIT_EOF1_1 = (((1) & 3) << 10)

Init EOF 1 Timing to 1.

enumerator USB_INIT_EOF1_2 = (((2) & 3) << 10)

Init EOF 1 Timing to 2.

enumerator USB_INIT_EOF1_3 = (((3) & 3) << 10)

Init EOF 1 Timing to 3.

enumerator USB_INIT_EOF2_0 = (((0) & 3) << 12)

Init EOF 2 Timing to 0.

enumerator USB_INIT_EOF2_1 = (((1) & 3) << 12)

Init EOF 2 Timing to 1.

enumerator USB_INIT_EOF2_2 = (((2) & 3) << 12)

Init EOF 2 Timing to 2.

enumerator USB_INIT_EOF2_3 = (((3) & 3) << 12)

Init EOF 2 Timing to 3.

enumerator USB_INIT_UNKNOWN = 1 << 15
enumerator USB_DEFAULT_INIT_FLAGS = USB_USE_OS_HEAP | USB_INIT_FLSZ_256 | USB_INIT_ASST_1 | USB_INIT_EOF1_3 | USB_INIT_EOF2_0 | USB_INIT_UNKNOWN
enum usb_event

Values:

enumerator USB_ROLE_CHANGED_EVENT

event_data Pointer to the new usb_role_t state.

enumerator USB_DEVICE_DISCONNECTED_EVENT

event_data The usb_device_t that was disconnected.

enumerator USB_DEVICE_CONNECTED_EVENT

event_data The usb_device_t that was connected.

enumerator USB_DEVICE_DISABLED_EVENT

event_data The usb_device_t that was disabled.

enumerator USB_DEVICE_ENABLED_EVENT

event_data The usb_device_t that was enabled.

enumerator USB_HUB_LOCAL_POWER_GOOD_EVENT

event_data The usb_device_t for the hub that stopped using bus power.

enumerator USB_HUB_LOCAL_POWER_LOST_EVENT

event_data The usb_device_t for the hub that started using bus power.

enumerator USB_DEVICE_RESUMED_EVENT

event_data The usb_device_t that was resumed.

enumerator USB_DEVICE_SUSPENDED_EVENT

event_data The usb_device_t that was suspended.

enumerator USB_DEVICE_OVERCURRENT_DEACTIVATED_EVENT

event_data The usb_device_t that deactivated overcurrent condition.

enumerator USB_DEVICE_OVERCURRENT_ACTIVATED_EVENT

event_data The usb_device_t that activated overcurrent condition.

enumerator USB_DEFAULT_SETUP_EVENT

This event triggers when a host sends a control setup packet. Return USB_IGNORE if you scheduled a response manually. Return USB_SUCCESS to have standard requests handled automatically (You can modify the setup first, but that probably isn’t useful). event_data The usb_control_setup_t * that was sent by the host.

enumerator USB_HOST_CONFIGURE_EVENT

This event triggers when the calculator is configured by a host. event_data The const usb_configuration_descriptor_t * that was selected by the host.

enumerator USB_DEVICE_INTERRUPT
enumerator USB_DEVICE_CONTROL_INTERRUPT
enumerator USB_DEVICE_DEVICE_INTERRUPT
enumerator USB_OTG_INTERRUPT
enumerator USB_HOST_INTERRUPT
enumerator USB_CONTROL_ERROR_INTERRUPT
enumerator USB_CONTROL_ABORT_INTERRUPT
enumerator USB_FIFO0_SHORT_PACKET_INTERRUPT
enumerator USB_FIFO1_SHORT_PACKET_INTERRUPT
enumerator USB_FIFO2_SHORT_PACKET_INTERRUPT
enumerator USB_FIFO3_SHORT_PACKET_INTERRUPT
enumerator USB_DEVICE_ISOCHRONOUS_ERROR_INTERRUPT
enumerator USB_DEVICE_ISOCHRONOUS_ABORT_INTERRUPT
enumerator USB_DEVICE_DMA_FINISH_INTERRUPT
enumerator USB_DEVICE_DMA_ERROR_INTERRUPT
enumerator USB_DEVICE_IDLE_INTERRUPT
enumerator USB_DEVICE_WAKEUP_INTERRUPT
enumerator USB_B_SRP_COMPLETE_INTERRUPT
enumerator USB_A_SRP_DETECT_INTERRUPT
enumerator USB_A_VBUS_ERROR_INTERRUPT
enumerator USB_B_SESSION_END_INTERRUPT
enumerator USB_OVERCURRENT_INTERRUPT
enumerator USB_HOST_PORT_CONNECT_STATUS_CHANGE_INTERRUPT
enumerator USB_HOST_PORT_ENABLE_DISABLE_CHANGE_INTERRUPT
enumerator USB_HOST_PORT_OVERCURRENT_CHANGE_INTERRUPT
enumerator USB_HOST_PORT_FORCE_PORT_RESUME_INTERRUPT
enumerator USB_HOST_SYSTEM_ERROR_INTERRUPT
enum usb_error

Values:

enumerator USB_SUCCESS
enumerator USB_IGNORE
enumerator USB_ERROR_SYSTEM
enumerator USB_ERROR_INVALID_PARAM
enumerator USB_ERROR_SCHEDULE_FULL
enumerator USB_ERROR_NO_DEVICE
enumerator USB_ERROR_NO_MEMORY
enumerator USB_ERROR_NOT_SUPPORTED
enumerator USB_ERROR_OVERFLOW
enumerator USB_ERROR_TIMEOUT
enumerator USB_ERROR_FAILED
enumerator USB_USER_ERROR = 100
enum usb_transfer_status

Values:

enumerator USB_TRANSFER_COMPLETED = 0

The transfer completed successfully.

Note

A transfer will complete when the end of a packet is detected, or the buffer is full, whichever happens first. Therefore just because a transfer completes doesn’t mean the entire buffer’s worth of data was transferred.

enumerator USB_TRANSFER_STALLED = 1 << 0

The transfer stalled.

If this is a control transfer, then this request is not supported, and any pending requests continue as normal. Otherwise, the endpoint’s halt condition is automatically cleared and any pending transfers are cancelled.

enumerator USB_TRANSFER_NO_DEVICE = 1 << 1

Lost the connection with the device.

It was probably unplugged. This always counts as a cancellation.

enumerator USB_TRANSFER_HOST_ERROR = 1 << 2

The results of the transaction were missed due to host hold-off.

Note

This probably indicates a bug in this library.

enumerator USB_TRANSFER_ERROR = 1 << 3

This is caused by multiple consecutive usb bus errors.

It is reasonable in this case to keep retrying the transfer until some timeout condition occurs.

enumerator USB_TRANSFER_OVERFLOW = 1 << 4

More bytes were received than can fit in the transfer buffer and were lost.

Note

This can be avoided by ensuring that receive buffer lengths are always a multiple of the endpoint’s maximum packet length.

enumerator USB_TRANSFER_BUS_ERROR = 1 << 5

The memory bus could not be accessed in a timely enough fashion to transfer the data.

Note

This probably means that non-default cpu speed or lcd parameters are in effect.

enumerator USB_TRANSFER_FAILED = 1 << 6

The transfer failed for some reason, usually indicated by another bit.

enumerator USB_TRANSFER_CANCELLED = 1 << 7

The transfer was cancelled.

In that case, any other set bits refer to the transfer that caused the cancellation. If no other bits are set, then it was manually cancelled.

enum usb_device_flags

Values:

enumerator USB_IS_DISABLED = 1 << 0

Device is disabled.

enumerator USB_IS_ENABLED = 1 << 1

Device is enabled.

enumerator USB_IS_DEVICE = 1 << 2

Device is not a hub.

enumerator USB_IS_HUB = 1 << 3

Device is a hub.

enum usb_find_device_flags

Values:

enumerator USB_SKIP_NONE = 0

Return all devices

enumerator USB_SKIP_DISABLED = 1 << 0

Don’t return disabled devices.

enumerator USB_SKIP_ENABLED = 1 << 1

Don’t return enabled devices.

enumerator USB_SKIP_DEVICES = 1 << 2

Don’t return non-hubs.

enumerator USB_SKIP_HUBS = 1 << 3

Don’t return hubs.

enumerator USB_SKIP_ATTACHED = 1 << 4

Only return devices directly attached to

enum usb_endpoint_flags

Values:

enumerator USB_MANUAL_TERMINATE = 0 << 0

For transfers that are a multiple of

enumerator USB_AUTO_TERMINATE = 1 << 0

the endpoint’s maximum packet length,

don’t automatically terminate outgoing

ones with a zero-length packet and

don’t require incoming ones to be

terminated with a zero-length packet.

Note

This allows you to send or

receive partial transfers in multiples

of the endpoint’s maximum packet

length, but requires that transfers

which are a multiple of the endpoint’s

maximum packet length to be manually

terminated with an explicit zero-length transfer.

For transfers that are a multiple of

enum usb_role

Values:

enumerator USB_ROLE_HOST = 0 << 4

Acting as usb host.

enumerator USB_ROLE_DEVICE = 1 << 4

Acting as usb device.

enumerator USB_ROLE_A = 0 << 5

Plug A plugged in.

enumerator USB_ROLE_B = 1 << 5

Plug B plugged in.

enum usb_speed

Values:

enumerator USB_SPEED_UNKNOWN = -1
enumerator USB_SPEED_FULL = 0 << 4

12 Mb/s

enumerator USB_SPEED_LOW = 1 << 4

1.5 Mb/s

enum usb_transfer_direction

Values:

enumerator USB_HOST_TO_DEVICE = 0 << 7
enumerator USB_DEVICE_TO_HOST = 1 << 7
enum usb_request_type

Values:

enumerator USB_STANDARD_REQUEST = 0 << 5
enumerator USB_CLASS_REQUEST = 1 << 5
enumerator USB_VENDOR_REQUEST = 2 << 5
enum usb_recipient

Values:

enumerator USB_RECIPIENT_DEVICE
enumerator USB_RECIPIENT_INTERFACE
enumerator USB_RECIPIENT_ENDPOINT
enumerator USB_RECIPIENT_OTHER
enum usb_request

Values:

enumerator USB_GET_STATUS_REQUEST
enumerator USB_CLEAR_FEATURE_REQUEST
enumerator USB_SET_FEATURE_REQUEST = 3
enumerator USB_SET_ADDRESS_REQUEST = 5
enumerator USB_GET_DESCRIPTOR_REQUEST
enumerator USB_SET_DESCRIPTOR_REQUEST
enumerator USB_GET_CONFIGURATION_REQUEST
enumerator USB_SET_CONFIGURATION_REQUEST
enumerator USB_GET_INTERFACE_REQUEST
enumerator USB_SET_INTERFACE_REQUEST
enumerator USB_SYNC_FRAME_REQUEST
enum usb_feature

Values:

enumerator USB_ENDPOINT_HALT_FEATURE
enumerator USB_DEVICE_REMOTE_WAKEUP_FEATURE
enumerator USB_DEVICE_TEST_MODE_FEATURE
enum usb_device_status

Values:

enumerator USB_DEVICE_SELF_POWERED_STATUS = 1 << 0
enumerator USB_DEVICE_REMOTE_WAKEUP_STATUS = 1 << 1
enum usb_endpoint_status

Values:

enumerator USB_ENDPOINT_HALT_STATUS = 1 << 0
enum usb_descriptor_type

Values:

enumerator USB_DEVICE_DESCRIPTOR = 1
enumerator USB_CONFIGURATION_DESCRIPTOR
enumerator USB_STRING_DESCRIPTOR
enumerator USB_INTERFACE_DESCRIPTOR
enumerator USB_ENDPOINT_DESCRIPTOR
enumerator USB_HUB_DESCRIPTOR = 0x29
enum usb_class

Values:

enumerator USB_INTERFACE_SPECIFIC_CLASS
enumerator USB_AUDIO_CLASS
enumerator USB_COMM_CLASS
enumerator USB_HID_CLASS
enumerator USB_PHYSICAL_CLASS = 5
enumerator USB_IMAGE_CLASS
enumerator USB_PRINTER_CLASS
enumerator USB_STORAGE_CLASS
enumerator USB_HUB_CLASS
enumerator USB_CDC_DATA_CLASS
enumerator USB_SMART_CARD_CLASS
enumerator USB_CONTENT_SECURITY_CLASS
enumerator USB_VIDEO_CLASS
enumerator USB_PERSONAL_HEALTCARE_CLASS
enumerator USB_AUDIO_VIDEO_CLASS
enumerator USB_BILLBOARD_CLASS
enumerator USB_TYPE_C_BRIDGE_CLASS
enumerator USB_DIAGNOSTIC_DEVICE_CLASS = 0xDC
enumerator USB_WIRELESS_CONTROLLER_CLASS = 0xE0
enumerator USB_MISCELLANEOUS_CLASS = 0xEF
enumerator USB_APPLICATION_SPECIFIC_CLASS = 0xFE
enumerator USB_VENDOR_SPECIFIC_CLASS = 0xFF
enum usb_configuration_attributes

Values:

enumerator USB_NO_REMOTE_WAKEUP = 0 << 5
enumerator USB_REMOTE_WAKEUP = 1 << 5
enumerator USB_BUS_POWERED = 0 << 6
enumerator USB_SELF_POWERED = 1 << 6
enumerator USB_CONFIGURATION_ATTRIBUTES = 1 << 7
enum usb_usage_type

Values:

enumerator USB_DATA_ENDPOINT = 0 << 4
enumerator USB_FEEDBACK_ENDPOINT = 1 << 4
enumerator USB_IMPLICIT_FEEDBACK_DATA_ENDPOINT = 2 << 4
enum usb_synchronization_type

Values:

enumerator USB_NO_SYNCHRONIZATION = 0 << 2
enumerator USB_ASYNCHRONOUS = 1 << 2
enumerator USB_ADAPTIVE = 2 << 2
enumerator USB_SYNCHRONOUS = 3 << 2
enum usb_transfer_type

Values:

enumerator USB_UNKNOWN_TRANSFER = -1
enumerator USB_CONTROL_TRANSFER
enumerator USB_ISOCHRONOUS_TRANSFER
enumerator USB_BULK_TRANSFER
enumerator USB_INTERRUPT_TRANSFER
enum [anonymous]

Values:

enumerator USB_RETRY_FOREVER = 0xFFFFFFu

Functions

usb_error_t usb_Init(usb_event_callback_t handler, void *data, const usb_standard_descriptors_t *device_descriptors, usb_init_flags_t flags)

Initializes the usb driver.

Note

This must be called before any other function, and can be called again to cancel all transfers and disable all devices.

Parameters
  • handler – Function to be called when a usb event happens.

  • data – Opaque pointer to be passed to handler.

  • device_descriptors – A pointer to the device descriptors to use, or NULL to use the calculator’s defaults.

  • flags – Which areas of memory to use.

Returns

USB_SUCCESS if initialization succeeded.

void usb_Cleanup(void)

Uninitializes the usb driver.

Note

This must be called after calling usb_Init() and before the program exits, even if usb_Init returns an error, or else TIOS gets angry.

usb_error_t usb_PollTransfers(void)

This calls any transfer callbacks that have triggered.

It is not necessary to call this function, because completed transfers will trigger in any other event dispatch function at the end of the frame. However, this function may be useful for polling for transfers that may complete early in a frame, without having to wait for the frame to end. For reference, a frame lasts 1ms.

Returns

An error returned by a callback or USB_SUCCESS.

usb_error_t usb_HandleEvents(void)

Calls any device or transfer callbacks that have triggered.

Returns

An error returned by a callback or USB_SUCCESS.

usb_error_t usb_WaitForEvents(void)

Waits for any device or transfer events to occur, then calls their associated callbacks.

Returns

An error returned by a callback or USB_SUCCESS.

usb_error_t usb_WaitForInterrupt(void)

Waits for any interrupt or usb event to occur, then calls any device or transfer callbacks that may have triggered.

Returns

An error returned by a callback or USB_SUCCESS.

usb_device_t usb_RefDevice(usb_device_t device)

This function may be called to prevent device from being automatically freed after its correspending USB_DEVICE_DISCONNECTED_EVENT returns.

This allows you to continue passing it to other API functions, although many will error with USB_ERROR_NO_DEVICE.

Parameters

device – The device to increase the reference count of.

Returns

device

usb_device_t usb_UnrefDevice(usb_device_t device)

Once this function has been called the same number of times that usb_RefDevice() was called on device and the event callback has returned from processing a corresponding USB_DEVICE_DISCONNECTED_EVENT, device becomes an invalid pointer and may no longer be passed to any API function.

Parameters

device – The device to decrease the reference count of.

Returns

NULL

usb_device_t usb_GetDeviceHub(usb_device_t device)

Gets the hub that device is attached to, or NULL if device is the root hub.

Parameters

device – Device to get the hub of.

Returns

The hub device or NULL.

void usb_SetDeviceData(usb_device_t device, void *data)

Sets the user data associated with device.

Parameters
  • device – Device to set the user data of.

  • data – Data to set.

void *usb_GetDeviceData(usb_device_t device)

Gets the user data associated with device.

Parameters

device – Device to get the user data of.

Returns

The user data last set with usb_SetDeviceData.

usb_device_flags_t usb_GetDeviceFlags(usb_device_t device)

This returns the same flags that are used by usb_FindDevice() for a given device.

Note that USB_SKIP_ATTACHED is not part of these flags.

Parameters

device – The device to get the flags of.

Returns

The usb_device_flags_t flags associated with device.

usb_device_t usb_FindDevice(usb_device_t root, usb_device_t from, usb_find_device_flags_t flags)

Finds the next device connected through root after from satisfying flags, or NULL if no more matching devices.

To enumerate all devices, excluding all hubs:

usb_device_t device = NULL;
while ((device = usb_FindDevice(NULL, device, USB_SKIP_HUBS))) {
  handle(device);
}

To enumerate all hubs and devices, including the root hub:

usb_device_t device = NULL;
while ((device = usb_FindDevice(NULL, device, USB_SKIP_NONE))) {
  handle(device);
}

To enumerate all hubs and devices except the root hub:

usb_device_t device = NULL; // same as using usb_RootHub()
while ((device = usb_FindDevice(usb_RootHub(), device, USB_SKIP_NONE))) {
  handle(device);
}

To enumerate all devices below a specific hub:

usb_device_t device = NULL; // same as using hub
while ((device = usb_FindDevice(hub, device, USB_SKIP_NONE))) {
  handle(device);
}

To enumerate all disabled hubs directly attached to a specific hub:

usb_device_t device = NULL; // must not use hub or else USB_SKIP_ATTACHED
                            // will skip all devices attached to hub!
while ((device = usb_FindDevice(hub, device, USB_SKIP_ENABLED |
                                USB_SKIP_DEVICES | USB_SKIP_ATTACHED))) {
  handle(device);
}

Parameters
  • root – Hub below which to limit search, or NULL to search all devices including the root hub.

  • from – The device to start the search from, or NULL to start from root and include devices attached to root even with USB_SKIP_ATTACHED.

  • flags – What kinds of devices to return.

Returns

The next device connected through root after from satisfying flags or NULL if none.

usb_error_t usb_ResetDevice(usb_device_t device)

Performs an asynchronous usb reset on a device.

This triggers a device enabled event when the reset is complete.

Parameters

device – The device to reset.

Returns

USB_SUCCESS if the transfer succeeded or an error.

usb_error_t usb_DisableDevice(usb_device_t device)

Forces a device to become disabled.

This triggers a device disabled event when it finishes.

Parameters

device – The device to disable.

Returns

USB_SUCCESS if the transfer succeeded or an error.

uint8_t usb_GetDeviceAddress(usb_device_t device)

Gets the usb address of a device, or 0 if disabled.

Parameters

device – The device to communicate with.

Returns

The usb address or 0.

int8_t usb_GetDeviceSpeed(usb_device_t device)

Gets the speed of a device, or USB_SPEED_UNKNOWN if unknown.

Parameters

device – The device to communicate with.

Returns

The usb_speed_t.

size_t usb_GetConfigurationDescriptorTotalLength(usb_device_t device, uint8_t index)

Determines how large of a buffer would be required to receive the complete configuration descriptor at index.

Note

Blocks while the configuration descriptor is fetched.

Parameters
  • device – The device to communicate with.

  • index – Which configuration descriptor to query.

Returns

The total length in bytes of the combined configuration descriptor or 0 on error.

usb_error_t usb_GetDescriptor(usb_device_t device, usb_descriptor_type_t type, uint8_t index, void *descriptor, size_t length, size_t *transferred)

Gets the descriptor of a device of type at index.

Note

Blocks while the descriptor is fetched.

Parameters
  • device – The device to communicate with.

  • type – The usb_descriptor_type_t to fetch.

  • index – Descriptor index to fetch.

  • descriptor – Returns the fetched descriptor.

  • length – The maximum number of bytes to receive. The descriptor buffer must be at least this large.

  • transferred – NULL or returns the number of bytes actually received.

Returns

USB_SUCCESS if the transfer succeeded or an error.

usb_error_t usb_SetDescriptor(usb_device_t device, usb_descriptor_type_t type, uint8_t index, const void *descriptor, size_t length)

Changes the descriptor at index.

Note

Blocks while the descriptor is changed.

Note

Devices do not usually support this.

Parameters
  • device – The device to communicate with.

  • type – The usb_descriptor_type_t to change.

  • index – The descriptor index to change.

  • descriptor – The new descriptor.

  • length – The number of bytes in the new descriptor. The descriptor buffer must be this large.

Returns

USB_SUCCESS if the transfer succeeded or an error.

usb_error_t usb_GetStringDescriptor(usb_device_t device, uint8_t index, uint16_t langid, usb_string_descriptor_t *descriptor, size_t length, size_t *transferred)

Gets the string descriptor at index and langid.

Note

Blocks while the descriptor is fetched.

Parameters
  • device – The device to communicate with.

  • index – Descriptor index to fetch.

  • langid – Language ID to fetch.

  • descriptor – Returns the fetched descriptor.

  • length – The number of bytes to transfer. The descriptor buffer must be at least this large.

  • transferred – NULL or returns the number of bytes actually received.

Returns

USB_SUCCESS if the transfer succeeded or an error.

usb_error_t usb_SetStringDescriptor(usb_device_t device, uint8_t index, uint16_t langid, const usb_string_descriptor_t *descriptor, size_t length)

Sets the string descriptor at index and langid.

Note

Blocks while the descriptor is changed.

Note

Devices do not usually support this.

Parameters
  • device – The device to communicate with.

  • index – Descriptor index to change.

  • langid – Language ID to change.

  • descriptor – The new descriptor.

  • length – The number of bytes to transfer. The descriptor buffer must be this large.

Returns

USB_SUCCESS if the transfer succeeded or an error.

usb_error_t usb_GetConfiguration(usb_device_t device, uint8_t *index)

Gets the currently active configuration of a device.

Parameters
  • device – The device to communicate with.

  • index – Returns the current configuration value, or 0 if unconfigured.

Returns

USB_SUCCESS if the transfer succeeded or an error.

usb_error_t usb_SetConfiguration(usb_device_t device, const usb_configuration_descriptor_t *descriptor, size_t length)

Selects the configuration specified by the configuration_descriptor.

This must be called before pipes other than the default control pipe can be accessed. Calling this function invalidates all usb_endpoint_t pointers corresponding with device except for any referring to its default control pipe.

Parameters
  • device – The device to communicate with.

  • descriptor – A complete combined configuration descriptor fetched with usb_GetDescriptor().

  • length – The total length of the configuration descriptor.

Returns

USB_SUCCESS if the transfer succeeded or an error.

usb_error_t usb_GetInterface(usb_device_t device, uint8_t interface, uint8_t *alternate_setting)

Gets the current alternate setting in use on the specified interface.

Parameters
  • device – The device to communicate with.

  • interface – Interface index to query.

  • alternate_setting – Returns the alternate setting in use.

Returns

USB_SUCCESS if the transfer succeeded or an error.

usb_error_t usb_SetInterface(usb_device_t device, const usb_interface_descriptor_t *descriptor, size_t length)

Sets the alternate setting to use for its corresponding interface.

Calling this function invalidates any usb_endpoint_t pointers corresponding with the endpoints that were part of the previously selected alternate setting.

Parameters
  • device – The device to communicate with.

  • descriptor – The interface descriptor describing the alternate setting to select within a configuration descriptor.

  • length – The remaining length of the configuration descriptor after the beginning of the interface_descriptor.

Returns

USB_SUCCESS if the transfer succeeded or an error.

usb_error_t usb_SetEndpointHalt(usb_endpoint_t endpoint)

Sets halt condition on endpoint.

This is only supported by bulk and interrupt endpoints. If acting as usb host, this may only be called if there are no pending transfers. This also has the sife effect of asynchronously cancelling all pending transfers to endpoint.

Parameters

endpoint – The endpoint to set the halt condition of.

Returns

USB_SUCCESS if the transfer succeeded or an error.

usb_error_t usb_ClearEndpointHalt(usb_endpoint_t endpoint)

Clears halt condition on endpoint.

This is only supported by bulk and interrupt endpoints. If acting as usb host, this may only be called if there are no pending transfers. If any non-control transfer stalls, this is called automatically, so you only need to call this if you need to clear an endpoint halt for a reason other than a stalled transfer. This function blocks until the halt condition is cleared.

Parameters

endpoint – The endpoint to clear the halt condition of.

Returns

USB_SUCCESS if the transfer succeeded or an error.

usb_endpoint_t usb_GetDeviceEndpoint(usb_device_t device, uint8_t address)

Gets the endpoint of a device with a given address, or NULL if that address is unused.

Parameters
  • device – Device to get the user data of.

  • address – Address of the endpoint to get.

Returns

The specified endpoint or NULL.

usb_device_t usb_GetEndpointDevice(usb_endpoint_t endpoint)

Gets the device that endpoint is connected to.

Parameters

endpoint – Endpoint to get the device of.

Returns

The device for an endpoint.

void usb_SetEndpointData(usb_endpoint_t endpoint, void *data)

Sets the user data associated with endpoint.

Parameters
  • endpoint – Endpoint to set the user data of.

  • data – Data to set.

void *usb_GetEndpointData(usb_endpoint_t endpoint)

Gets the user data associated with endpoint.

Parameters

endpoint – Endpoint to get the user data of.

Returns

The user data last set with usb_SetEndpointData.

uint8_t usb_GetEndpointAddress(usb_endpoint_t endpoint)

Gets the address of an endpoint.

Parameters

endpoint – The endpoint to get the address of.

Returns

The address of an endpoint or 0xFF on error.

int8_t usb_GetEndpointTransferType(usb_endpoint_t endpoint)

Gets the transfer type of an endpoint.

Parameters

endpoint – The endpoint to get the transfer type of.

Returns

The usb_transfer_type of an endpoint.

size_t usb_GetEndpointMaxPacketSize(usb_endpoint_t endpoint)

Gets the maximum packet size of an endpoint.

Parameters

endpoint – The endpoint to get the maximum packet size of.

Returns

The wMaxPacketSize of an endpoint.

uint8_t usb_GetEndpointInterval(usb_endpoint_t endpoint)

Gets the interval of an endpoint.

Parameters

endpoint – The endpoint to get the endpoint of.

Returns

The actual bInterval of an endpoint, which is rounded down to the nearest power of two from the descriptor, or 0 for asynchronous endpoints.

void usb_SetEndpointFlags(usb_endpoint_t endpoint, usb_endpoint_flags_t flags)

Sets the flags for an endpoint.

Parameters
  • endpoint – The endpoint to set the flags of.

  • flags – The usb_endpoint_flags_t to set.

usb_endpoint_flags_t usb_GetEndpointFlags(usb_endpoint_t endpoint)

Gets the flags for an endpoint.

Parameters

endpoint – The endpoint to get the flags of.

Returns

The usb_endpoint_flags_t last set with usb_SetEndpointFlags.

usb_role_t usb_GetRole(void)

Returns the current role the usb hardware is operating in.

Returns

The usb_role_t of the current role.

unsigned usb_GetFrameNumber(void)

Returns the current 11-bit frame number, as last broadcast by the current host, multiplied by 8.

This value ranges from 0x0000 to 0x3FF8, increases by 8 every 1 ms, is truncated to 14 bits, and is synchronized with the host usb clock.

Note

If the hardware supported full speed usb, the lower 3 bits would be the microframe number.

Warning

The bottom 3 bits are usually 0, but this is not guaranteed because random mmio writes could affect those bits.

Returns

usb_frame_number << 3

usb_error_t usb_ControlTransfer(usb_endpoint_t endpoint, const usb_control_setup_t *setup, void *buffer, unsigned retries, size_t *transferred)

Schedules a transfer to the pipe connected to endpoint, in the direction indicated by setup->bmRequestType, using buffer as the data buffer, setup->wLength as the buffer length, and then waits for it to complete.

If acting as usb host and using a control pipe, setup is used as the setup packet, otherwise all fields not mentioned above are ignored.

Parameters
  • endpoint – The endpoint to communicate with, which also specifies the direction for non-control transfers.

  • setup – Indicates the transfer direction and buffer length. If acting as usb host and using a control pipe, also used as the setup packet to send.

  • buffer – Data to transfer that must reside in RAM and have room for at least setup->wLength bytes.

  • retries – How many times to retry the transfer before timing out. If retries is USB_RETRY_FOREVER, the transfer never times out.

  • transferred – NULL or returns the number of bytes actually received.

Returns

USB_SUCCESS if the transfer succeeded or an error.

usb_error_t usb_Transfer(usb_endpoint_t endpoint, void *buffer, size_t length, unsigned retries, size_t *transferred)

Schedules a transfer to the pipe connected to endpoint, using length as the buffer length, and waits for it to complete.

If acting as usb host and using a control pipe, uses the beginning of buffer as the setup packet to send, its bmRequestType for the transfer direction, and the rest of buffer as the data buffer. Otherwise, uses endpoint for transfer direction and the whole buffer as the data buffer.

Parameters
  • endpoint – The endpoint to communicate with, which also specifies the direction for non-control transfers.

  • buffer – Data to transfer that must reside in RAM. When acting as usb host and using a control pipe, starts with a usb_control_setup_t.

  • length – Number of bytes to transfer. The buffer must be at least this large. However, this is ignored for control transfers when acting as usb host where the wLength of the setup packet is used instead.

  • retries – How many times to retry the transfer before timing out. If retries is USB_RETRY_FOREVER, the transfer never times out.

  • transferred – NULL or returns the number of bytes actually received. NULL means don’t return anything.

Returns

USB_SUCCESS if the transfer succeeded or an error.

usb_error_t usb_ScheduleControlTransfer(usb_endpoint_t endpoint, const usb_control_setup_t *setup, void *buffer, usb_transfer_callback_t handler, void *data)

Schedules a transfer to the pipe connected to endpoint, in the direction indicated by setup->bmRequestType, using buffer as the data buffer, and setup->wLength as the buffer length.

If acting as usb host and using a control pipe, setup is used as the setup packet, otherwise all fields not mentioned above are ignored.

Parameters
  • endpoint – The endpoint to communicate with, which also specifies the direction for non-control transfers.

  • setup – Indicates the transfer direction and buffer length. If acting as usb host and using a control pipe, also used as the setup packet to send.

  • buffer – Data to transfer that must reside in RAM. This buffer must remain valid until the callback is called i.e. it cannot be modified or freed.

  • handler – Function to be called when the transfer finishes.

  • data – Opaque pointer to be passed to the handler.

Returns

USB_SUCCESS if the transfer was scheduled or an error.

usb_error_t usb_ScheduleTransfer(usb_endpoint_t endpoint, void *buffer, size_t length, usb_transfer_callback_t handler, void *data)

If endpoint is not a control endpoint, schedules a transfer of the endpoint’s transfer type.

If the endpoint is a control endpoint, schedules a control transfer interpreting the beginning of buffer as the usb_control_setup_t and using the rest of the buffer as the transfer buffer.

Parameters
  • endpoint – The endpoint to communicate with, which also specifies the direction for non-control transfers.

  • buffer – Data to transfer that must reside in RAM. When acting as usb host and using a control pipe, starts with a usb_control_setup_t. This buffer must remain valid until the callback is called i.e. it cannot be modified or freed.

  • length – Number of bytes to transfer. The buffer must be at least this large. However, this is ignored for control transfers when acting as usb host where the wLength of the setup packet is used instead.

  • handler – Function to be called when the transfer finishes.

  • data – Opaque pointer to be passed to the handler.

Returns

USB_SUCCESS if the transfer was scheduled or an error.

uint32_t usb_MsToCycles(uint16_t ms)

Converts milliseconds to cpu cycles.

Returns

ms * 48000

void usb_StopTimer(usb_timer_t *timer)

Stops a timer.

Note

May be called from within timer->handler itself.

void usb_StartTimerCycles(usb_timer_t *timer, uint32_t timeout_cycles)

Starts a timer that expires timeout_cycles after calling this function.

Note

May be called from within timer->handler itself.

Parameters
  • timer – A user allocated struct with timer->handler already initialized.

  • timeout_cycles – Timeout in cpu cycles.

void usb_RepeatTimerCycles(usb_timer_t *timer, uint32_t interval_cycles)

Starts a timer that expires interval_cycles after it last expired.

Note

May be called from within timer->handler itself.

Parameters
  • timer – A user allocated struct with timer->handler already initialized.

  • interval_cycles – Repeat interval in cpu cycles.

uint32_t usb_GetCycleCounter(void)

Returns a counter that increments once every cpu cycle, or 48000 times every millisecond.

This counter overflows every 90 seconds or so.

Returns

Cpu cycle counter.

uint24_t usb_GetCounter(void)

Returns a counter that increments once every 256 cpu cycles, or 375 times every 2 milliseconds.

This is the high 24 bits of the same counter returned by usb_GetCycleCounter().

Returns

Cpu cycle counter >> 8.

struct usb_control_setup

Public Members

uint8_t bmRequestType

direction, type, and recipient

uint8_t bRequest

usb_request_t

uint16_t wValue

request specific

uint16_t wIndex

request specific

uint16_t wLength

transfer length

struct usb_descriptor

Public Members

uint8_t bLength

The length of this descriptor.

uint8_t bDescriptorType

A usb_descriptor_type_t.

uint8_t data[]

The rest of the descriptor

struct usb_device_descriptor

Public Members

uint8_t bLength

18

uint8_t bDescriptorType

USB_DEVICE_DESCRIPTOR

uint16_t bcdUSB

usb specification version

uint8_t bDeviceClass

usb_class_t

uint8_t bDeviceSubClass

usb class specific

uint8_t bDeviceProtocol

usb class specific

uint8_t bMaxPacketSize0

8, 16, 32, or 64

uint16_t idVendor

usb assigned vendor id

uint16_t idProduct

usb assigned product id

uint16_t bcdDevice

device version

uint8_t iManufacturer

index of manufacturer string descriptor

uint8_t iProduct

index of product string descriptor

uint8_t iSerialNumber

index of serial number string descriptor

uint8_t bNumConfigurations

how many valid configuration indices

struct usb_device_qualifier_descriptor

Public Members

uint8_t bLength

10

uint8_t bDescriptorType

USB_DEVICE_QUALIFIER_DESCRIPTOR

uint16_t bcdUSB

usb specification version

uint8_t bDeviceClass

usb_class_t

uint8_t bDeviceSubClass

usb class specific

uint8_t bDeviceProtocol

usb class specific

uint8_t bMaxPacketSize0

8, 16, 32, or 64

uint8_t bNumConfigurations

how many valid configuration indices

uint8_t bReserved

must be 0

struct usb_configuration_descriptor

Public Members

uint8_t bLength

9

uint8_t bDescriptorType

USB_CONFIGURATION_DESCRIPTOR

uint16_t wTotalLength

total length of combined descriptors

uint8_t bNumInterfaces

how many interface descriptors follow

uint8_t bConfigurationValue

value used to select this configuration

uint8_t iConfiguration

index of description string descriptor

uint8_t bmAttributes

usb_configuration_attributes_t

uint8_t bMaxPower

units of 2mA

struct usb_interface_descriptor

Public Members

uint8_t bLength

9

uint8_t bDescriptorType

USB_INTERFACE_DESCRIPTOR

uint8_t bInterfaceNumber

zero-based interface index

uint8_t bAlternateSetting

value used to select this alt setting

uint8_t bNumEndpoints

how many endpoint descriptors follow

uint8_t bInterfaceClass

usb_class_t

uint8_t bInterfaceSubClass

usb class specific

uint8_t bInterfaceProtocol

usb class specific

uint8_t iInterface

index of description string descriptor

struct usb_endpoint_descriptor

Public Members

uint8_t bLength

7

uint8_t bDescriptorType

USB_ENDPOINT_DESCRIPTOR

uint8_t bEndpointAddress

endpoint direction and number

uint8_t bmAttributes

usb_usage_type_t |

uint16_t wMaxPacketSize

usb_synchronization_type_t |

usb_transfer_type_t

uint8_t bInterval

transfer type specific

struct usb_string_descriptor

Public Members

uint8_t bLength

byte length, not character length

uint8_t bDescriptorType

USB_STRING_DESCRIPTOR

wchar_t bString[]

UTF-16 string, no null termination

struct usb_standard_descriptors

Public Members

const usb_device_descriptor_t *device

Pointer to device descriptor which must be in RAM.

const usb_configuration_descriptor_t *const *configurations

Pointer to array of device->bNumConfigurations pointers to complete configuration descriptors. Each one should point to {(*configurations)[i]->wTotalLength} bytes of RAM.

const usb_string_descriptor_t *langids

Pointer to array of langids, formatted like a string descriptor, with each wchar_t containing a langid, and which must be in RAM.

uint8_t numStrings

Number of strings per langid.

const usb_string_descriptor_t *const *strings

Pointer to array of {numStrings * (langids->bLength / 2 - 1)} pointers to string descriptors, each of which must be in RAM, starting with numStrings pointers for the first langid, then for the next langid, etc.

struct usb_timer

Public Members

uint32_t tick

private

usb_timer_t *next

private

usb_timer_callback_t handler