USB Device Classes

The USB classes available in Silicon Labs USB Device share some common characteristics. This section explains these characteristics and their interactions with the core layer.

For more information on a specific class, see the following:

About Class Instances

The USB classes available in USB Device implement the concept of class instances. A class instance represents one function within a device. The function can be described by one interface or by a group of interfaces and belongs to a specific class.

Each USB class implementation has some configurations and functions in common, based on the concept of class instance. The common configurations and functions are presented in the table below. In the column title 'Constants or Function', the placeholder XXXX can be replaced by the name of the class: CDC, HID, MSC, CDC_ACM or VENDOR (Vendor for function names).

Constant or FunctionDescription
SL_USBD_XXXX_CLASS_INSTANCE_QUANTITYConfigures the maximum number of class instances.
SL_USBD_XXXX_CONFIGURATION_QUANTITYConfigures the maximum number of configurations. During the class initialization, a created class instance will be added to one or more configurations.
sl_usbd_XXXX_create_instance()Creates a new class instance.
sl_usbd_XXXX_add_to_configuration()Adds an existing class instance to the specified device configuration.

In terms of code implementation, the class will declare a local global variable that contains a class control structure. This class control structure is associated with one class instance and will contain specific information to manage the class instance.

The following figures show several case scenarios. Each figure includes a code example that corresponds to the case scenario.

Figure - Multiple Class Instances - FS Device (1 Configuration with 1 Interface) represents a typical USB device. The device is Full-Speed (FS) and contains a single configuration. The function of the device is described by one interface composed of a pair of endpoints for data communication. One class instance is created and will allow you to manage the entire interface with its associated endpoint.

Figure - Multiple Class Instances - FS Device (1 Configuration with 1 Interface)

Figure - Multiple Class Instances - FS Device (1 Configuration with 1 Interface)

The code corresponding to Figure - Multiple Class Instances - FS Device (1 Configuration with 1 Interface) is shown in the example below.

Example - Multiple Class Instances - FS Device (1 Configuration with 1 Interface)
sl_status_t   status;
uint8_t       class_0;

void app_usbd_XXXX_enable(uint8_t class_nbr)
{
  /* Handle Class enable event. */
}

void app_usbd_XXXX_disable(uint8_t class_nbr)
{
  /* Handle Class disable event. */
}

sl_usbd_XXXX_callbacks_t class_callbacks = {                                                  (1)
  .enable = app_usbd_XXXX_enable,
  .disable = app_usbd_XXXX_disable
};

status = sl_usbd_XXXX_init();                                                                 (2)
if (status != SL_STATUS_OK) {
  /* $$$$ Handle the error. */
}

status = sl_usbd_XXXX_create_instance(&class_callbacks,                                       (3)
                                      &class_0);
if (status != SL_STATUS_OK) {
  /* $$$$ Handle the error. */
}

status = sl_usbd_XXXX_add_to_configuration(class_0, config_0);                                (4)
if (status != SL_STATUS_OK) {
  /* $$$$ Handle the error. */
}

(1) Every class offers a set of callback functions for device connect/disconnect events and for class specific events. The callback structure object is passed as argument when creating the class instance with sl_usbd_XXXX_create_instance() function.

(1) Initialize the class. All internal variables, structures, and class ports will be initialized. Note that the Init() function in some classes may take other arguments.

(2) Create the class instance, which is class_0. The function sl_usbd_XXXX_create_instance() allocates a class control structure associated with class_0. Depending on the class, sl_usbd_XXXX_create_instance() may have additional parameters aside from the class number that represent class-specific information stored in the class control structure.

(3) Add the class instance, class_0, to the specified configuration number, config_0. sl_usbd_XXXX_add_to_configuration() will create the interface 0 and its associated IN and OUT endpoints. As a result, the class instance encompasses the interface 0 and its endpoints. Any communication done on the interface 0 will use the class instance number, class_0.

Figure - Multiple Class Instances - FS Device (2 Configurations and Multiple Interfaces) represents a more complex example. A full-speed device is composed of two configurations. The device has two functions which belong to the same class, but each function is described by two interfaces and has a pair of bidirectional endpoints.

In this example, two class instances are created. Each class instance is associated with a group of interfaces as opposed to Figure - Multiple Class Instances - FS Device (1 Configuration with 1 Interface) and Figure - Multiple Class Instances - FS Device (2 Configurations and Multiple Interfaces) where the class instance was associated with a single interface.

Figure - Multiple Class Instances - FS Device (2 Configurations and Multiple Interfaces)

Figure - Multiple Class Instances - FS Device (2 Configurations and Multiple Interfaces)

The code corresponding to Figure - Multiple Class Instances - FS Device (2 Configurations and Multiple Interfaces) is shown in the example below. The error handling is omitted for clarity.

Example - Multiple Class Instances - FS Device (2 Configurations and Multiple Interfaces)
sl_status_t  status;
uint8_t      class_0;
uint8_t      class_1;

status = sl_usbd_XXXX_init();                                                                   (1)

status = sl_usbd_XXXX_create_instance(&class_0);                                                (2)
status = sl_usbd_XXXX_create_instance(&class_1);                                                (3)

status = sl_usbd_XXXX_add_to_configuration(class_0, cfg_0);                                     (4)
status = sl_usbd_XXXX_add_to_configuration(class_1, cfg_0);                                     (5)

status = sl_usbd_XXXX_add_to_configuration(class_0, cfg_1);                                     (6)
status = sl_usbd_XXXX_add_to_configuration(class_1, cfg_1);                                     (6)

(1) Initialize the class. Any internal variables, structures, and class ports will be initialized.

(2) Create the class instance, class_0. The function sl_usbd_XXXX_create_instance() allocates a class control structure associated with class_0.

(3) Create the class instance, class_1. The function sl_usbd_XXXX_create_instance() allocates another class control structure associated with class_1.

(4) Add the class instance, class_0, to the configuration, cfg_0. sl_usbd_XXXX_add_to_configuration() will create the interface 0, interface 1, alternate interfaces, and the associated IN and OUT endpoints. The class instance number, class_0, will be used for any data communication on interface 0 or interface 1.

(5) Add the class instance, class_1, to the configuration, cfg_0. sl_usbd_XXXX_add_to_configuration() will create the interface 2, interface 3 and their associated IN and OUT endpoints. The class instance number, class_1, will be used for any data communication on interface 2 or interface 3.

(6) Add the same class instances, class_0 and class_1, to the other configuration, cfg_1.

Every class defines structure of type sl_usbd_XXXX_callbacks_t. Its purpose is to give every class a set of callback functions to be called when event occurs. Two callback functions are present in each class. They are presented in the table bellow.

Table - Common Class Callback Functions
Fields Description Function signature
.enable Called when the USB class instance is enabled successfully. void app_usbd_XXXX_enable(uint8_t class_nbr);
.disable Called when the device is no longer in the configured state or if another configuration to which the class instance was not added has been selected by the host. void app_usbd_XXXX_disable(uint8_t class_nbr);