USB Device Programming Guide#
This section explains how to use the USB Device module.
Initial Setup of USB Device Module#
This section describes the basic steps required to initialize the USB Device module and to add, prepare, and start a device.
Initializing the USB Device Module#
Initializing the USB Device Core#
Begin by initializing the USB device module core by calling the function USBD_Init().
Listing - Example of call to USBD_Init() in the Initial Setup of USB Device Module page shows an example of call to USBD_Init(). For more information on the configuration arguments to pass to USBD_Init(), see USB Device Run-Time Application-Specific Configuration .
Listing - Example of call to USBD Init()#
RTOS_ERR err;
USBD_QTY_CFG qty_cfg;
qty_cfg.DevQty = 1u;
qty_cfg.ConfigQty = 2u;
qty_cfg.IF_Qty = 2u;
qty_cfg.IF_AltQty = 2u;
qty_cfg.IF_GrpQty = 0u;
qty_cfg.EP_DescQty = 2u;
qty_cfg.URB_ExtraQty = 0u;
qty_cfg.StrQty = 5u;
qty_cfg.EP_OpenQty = 4u;
USBD_Init(&qty_cfg,
&err);
if (err.Code != RTOS_ERR_NONE) {
/* An error occurred. Error handling should be added here. */
}
Initializing the Class(es)#
Once the USB device module core has been initialized, you must initialize each class you intend to use. See section "Programming Guide" of your class(es) for more information.
Adding Your USB Device#
Once you successfully initialize the USB device module, you can start adding your device(s) by calling the function USBD_DevAdd(). This function must be called for each device you want to create/add.
Listing - Example of call to USBD_DevAdd() in the Initial Setup of USB Device Module page gives an example of call to USBD_DevAdd() using default arguments. This example adds a USB device controller called "usb0". For more information on configuring arguments to pass to USBD_DevAdd(), see USB Device and Device Controller Driver Configuration .
Listing - Example of call to USBD_DevAdd()#
RTOS_ERR err;
CPU_INT08U dev_nbr;
RTOS_TASK_CFG dev_task_cfg;
USBD_DEV_CFG dev_cfg;
USBD_DEV_DRV_CFG dev_drv_cfg;
dev_task_cfg.Prio = 8u;
dev_task_cfg.StkSizeElements = 1024u;
dev_task_cfg.StkPtr = DEF_NULL; /* Allocate task stack from general purpose heap. */
dev_cfg.VendorID = 0xFFFEu;
dev_cfg.ProductID = 0x0100u;
dev_cfg.DeviceBCD = 0x0100u;
dev_cfg.ManufacturerStrPtr = "Micrium inc";
dev_cfg.ProductStrPtr = "USB Demo Device";
dev_cfg.SerialNbrStrPtr = "0123456789ABCDEF";
dev_cfg.LangId = USBD_LANG_ID_ENGLISH_US;
dev_drv_cfg.EP_OpenQty = 5u;
dev_drv_cfg.URB_ExtraQty = 0u;
dev_nbr = USBD_DevAdd("usb0",
&dev_task_cfg,
&dev_cfg,
&dev_drv_cfg,
DEF_NULL,
&err);
if (err.Code != RTOS_ERR_NONE) {
/* An error occurred. Error handling should be added here. */
}
Building Your USB Device#
Adding Configuration(s)#
Once you successfully add your device, you can start adding the USB functions to it, starting with a new configuration. A device must have at least one configuration, and for a High-Speed device, you must add a configuration for each speed. To add configuration(s), call the function USBD_ConfigAdd() function. This function must be called for each configuration you want to add.
If you have a High-speed device, and you create a High-Speed and a Full-Speed configuration, and both have the same functionalities, you must link them together. This is necessary to comply with the Universal Serial Bus specification, revision 2.0. To link two configurations, call the function USBD_ConfigOtherSpeed() .
Listing - Adding configuration(s) to your device in the Initial Setup of USB Device Module page gives an example of how to add a Full-speed and a High-speed configuration to your device.If your USB device supports Full-Speed only, you don't need to make the second call to USBD_ConfigAdd().
Listing - Adding configuration(s) to your device#
RTOS_ERR err;
CPU_INT08U config_nbr_fs;
CPU_INT08U config_nbr_hs;
/* Adding a full-speed configuration to the device. */
config_nbr_fs = USBD_ConfigAdd(dev_nbr, /* Device number returned by USBD_DevAdd(). */
DEF_BIT_NONE, /* No special attributes to the configuration. */
100u, /* Max power consumption: 100mA. */
USBD_DEV_SPD_FULL, /* Full-Speed configuration. */
"Config Add Example Full-Speed config",
&err);
if (err.Code != RTOS_ERR_NONE) {
/* An error occured. Error handling should be added here. */
}
/* Adding a high-speed configuration to the device. */
config_nbr_hs = USBD_ConfigAdd(dev_nbr, /* Device number returned by USBD_DevAdd(). */
DEF_BIT_NONE, /* No special attributes to the configuration. */
100u, /* Max power consumption: 100mA. */
USBD_DEV_SPD_HIGH, /* High-Speed configuration. */
"Config Add Example High-Speed config",
&err);
if (err.Code != RTOS_ERR_NONE) {
/* An error occured. Error handling should be added here. */
}
/* Associate Full and High-speed configurations together ... */
/* ... since they will provide the same functionalities. */
USBD_ConfigOtherSpeed(dev_nbr, /* Device number returned by USBD_DevAdd(). */
config_nbr_fs,
config_nbr_hs,
&err);
if (err.Code != RTOS_ERR_NONE) {
/* An error occurred. Error handling should be added here. */
}
Adding USB Function(s)#
Once you have successfully added at least one configuration to your device, you can add the interfaces and endpoints to your device. Each USB class has its own needs in terms of interface and endpoints type, quantity, and other parameters. Micrium OS USB Device adds interfaces and endpoints in the classes it offers.
From your application, you can instantiate a USB class and add it to a configuration. For more information on the concept of USB device class instances, see USB Device Classes . Note that you can instantiate and add many different class instances to a configuration to create a multi-function (composite) device.
Listing - Adding a class instance to your device in the Initial Setup of USB Device Module page gives a generic example of how to create a class instance and add it to a configuration.
Listing - Adding a class instance to your device#
RTOS_ERR err;
CPU_INT08U class_nbr;
/* Create an instance of the class you want to use.*/
class_nbr = USBD_<class>_Add(&err);
if (err.Code != RTOS_ERR_NONE) {
/* An error occurred. Error handling should be added here. */
}
/* Add the class instance to the Full-Speed configuration.*/
USBD_<class>_ConfigAdd(class_nbr, /* Class number returned by USBD_<class>_Add(). */
dev_nbr, /* Device number returned by USBD_DevAdd(). */
config_nbr_fs, /* Configuration number returned by USBD_ConfigAdd(). */
&err);
if (err.Code != RTOS_ERR_NONE) {
/* An error occurred. Error handling should be added here. */
}
/* Add the class instance to the High-Speed configuration.*/
/* Only if you created a High-Speed configuration. */
USBD_<class>_ConfigAdd(class_nbr, /* Class number returned by USBD_<class>_Add(). */
dev_nbr, /* Device number returned by USBD_DevAdd(). */
config_nbr_hs, /* Configuration number returned by USBD_ConfigAdd(). */
&err);
if (err.Code != RTOS_ERR_NONE) {
/* An error occurred. Error handling should be added here. */
}
Starting Your USB Device#
At this point, the device is still not detectable by the host if it is already connected. Once you have built/prepared your device, you can start it and make it visible to the USB host. This is done by calling the function USBD_DevStart().You have to start each device you added individually.
Listing - Starting your device in the Initial Setup of USB Device Module page gives an example of how to start your device using the USBD_DevStart() function.
Listing - Starting your device#
RTOS_ERR err;
USBD_DevStart(dev_nbr, /* Device number returned by USBD_DevAdd(). */
&err)
if (err.Code != RTOS_ERR_NONE) {
/* An error occurred. Error handling should be added here. */
}