Skip to content

Commit

Permalink
Update usbx device stack
Browse files Browse the repository at this point in the history
  • Loading branch information
ayedm1 committed Jan 25, 2025
1 parent bc3571f commit ab21f18
Show file tree
Hide file tree
Showing 12 changed files with 2,354 additions and 558 deletions.
2 changes: 1 addition & 1 deletion rtos-docs/usbx/usbx-device-stack-1.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ The relationship between the USB layers is as follows:
- Responsive technical support
- Multiple class support
- Multiple class instances
- Integration of classes with ThreadX, FileX, and NetX Duo
- Integration of classes with ThreadX, FileX and NetX Duo
- Support for USB devices with multiple configurations
- Support for USB composite devices
- Support for USB power management
Expand Down
121 changes: 60 additions & 61 deletions rtos-docs/usbx/usbx-device-stack-2.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ The following is a list of several important files in the repository.

* ***ux_api.h***: This C header file contains all system equates, data structures, and service prototypes.
* ***ux_port.h***: This C header file contains all development-tool-specific data definitions and structures.
* ***ux.lib***: This is the binary version of the USBX C library. It is distributed with the standard package.
* ***demo_usbx.c***: The C file containing a simple USBX demo

All filenames are in lower-case. This naming convention makes it easier to convert the commands to Unix development platforms.
Expand Down Expand Up @@ -69,45 +68,52 @@ There are several configuration options for building the USBX library. All optio

The list below details each configuration option.

| Configuration Option | Description |
| --- | --- |
| **UX_PERIODIC_RATE** | This value represents how many ticks per seconds for a specific hardware platform. The default is 1000 indicating 1 tick per millisecond. |
| **UX_THREAD_STACK_SIZE** | This value is the size of the stack in bytes for the USBX threads. It can be typically 1024 bytes or 2048 bytes depending on the processor used and the host controller. |
| **UX_THREAD_PRIORITY_ENUM** | This is the ThreadX priority value for the USBX enumeration threads that monitors the bus topology. |
| **UX_THREAD_PRIORITY_CLASS** | This is the ThreadX priority value for the standard USBX threads. |
| **UX_THREAD_PRIORITY_KEYBOARD** | This is the ThreadX priority value for the USBX HID keyboard class. |
| **UX_THREAD_PRIORITY_DCD** | This is the ThreadX priority value for the device controller thread. |
| **UX_NO_TIME_SLICE** | This value actually defines the time slice that will be used for threads. For example, if defined to 0, the ThreadX target port does not use time slices. |
| **UX_MAX_SLAVE_CLASS_DRIVER** | This is the maximum number of USBX classes that can be registered via ux_device_stack_class_register. |
| **UX_MAX_SLAVE_LUN** | This value represents the current number of SCSI logical units represented in the device storage class driver. |
| **UX_SLAVE_CLASS_STORAGE_INCLUDE_MMC** | If defined, the storage class will handle Multi-Media Commands (MMC) that is, DVD-ROM. |
| **UX_DEVICE_CLASS_CDC_ECM_NX_PKPOOL_ENTRIES** | This value represents the number of NetX packets in the CDC-ECM class' packet pool. The default is 16. |
| **UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH** | This value represents the maximum number of bytes received on a control endpoint in the device stack. The default is 256 bytes but can be reduced in memory constraint environments. |
| **UX_DEVICE_CLASS_HID_EVENT_BUFFER_LENGTH** | This value represents the maximum length in bytes of a HID report. |
| **UX_DEVICE_CLASS_HID_MAX_EVENTS_QUEUE** | This value represents the maximum number of HID reports that can be queued at once. |
| **UX_SLAVE_REQUEST_DATA_MAX_LENGTH** | This value represents the maximum number of bytes received on a bulk endpoint in the device stack. The default is 4096 bytes but can be reduced in memory constraint environments. |
| **UX_DEVICE_BIDIRECTIONAL_ENDPOINT_SUPPORT** | If defined, the device side enables bi-directional-endpoints support, e.g., endpoints addressed 0x01 and 0x81. Otherwise (the default case), endpoint number must be unique in same configuration. Note the feature must be used with compatible DCD and peripheral. |
| Configuration Option | Description |
| ----------------------------------------------- | ----------- |
| **UX_PERIODIC_RATE** | This value represents how many ticks per seconds for a specific hardware platform. The default is 1000 indicating 1 tick per millisecond. |
| **UX_THREAD_STACK_SIZE** | This value is the size of the stack in bytes for the USBX threads. It can be typically 1024 bytes or 2048 bytes depending on the processor used and the host controller. |
| **UX_THREAD_PRIORITY_CLASS** | This is the ThreadX priority value for the standard USBX threads. |
| **UX_THREAD_PRIORITY_DCD** | This is the ThreadX priority value for the device controller thread. |
| **UX_ALIGN_MIN** | This value represents minimal allocated memory alignment in number of bytes. The default is UX_ALIGN_8 (0x07) to align allocated memory to 8 bytes. |
| **UX_ENFORCE_SAFE_ALIGNMENT** | This value forces the memory allocation scheme to enforce alignment of memory with the UX_SAFE_ALIGN field. |
| **UX_NO_TIME_SLICE** | This value actually defines the time slice that will be used for threads. For example, if defined to 0, the ThreadX target port does not use time slices. |
| **UX_MAX_SLAVE_CLASS_DRIVER** | This value is the maximum number of classes in the device stack that can be loaded by USBX. |
| **UX_MAX_SLAVE_INTERFACES** | This value is the maximum number of interfaces in the device framework. |
| **UX_DEVICE_ENDPOINT_BUFFER_OWNER** | This value represents the endpoint buffer owner. 0 The default, endpoint buffer is managed by core stack. Each endpoint takes UX_SLAVE_REQUEST_DATA_MAX_LENGTH bytes, 1 Endpoint buffer managed by classes. In this case not all endpoints consume UX_SLAVE_REQUEST_DATA_MAX_LENGTH bytes |
| **UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH** | This value represents the maximum number of bytes received on a control endpoint in the device stack. The default is 256 bytes but can be reduced in memory constrained environments. |
| **UX_SLAVE_REQUEST_DATA_MAX_LENGTH** | This value represents the maximum number of bytes that can be received or transmitted on any endpoint. This value cannot be less than the maximum packet size of any endpoint. The default is 4096 bytes but can be reduced in memory constrained environments. For cd-rom support in the storage class, this value cannot be less than 2048. |
| **UX_DEVICE_BIDIRECTIONAL_ENDPOINT_SUPPORT** | If defined, the device side enables bi-directional-endpoints support, e.g., endpoints addressed 0x01 and 0x81. Otherwise (the default case), endpoint number must be unique in same configuration. Note the feature must be used with compatible DCD and peripheral. |
| **UX_DEVICE_ALTERNATE_SETTING_SUPPORT_DISABLE** | This macro disables interface alternate setting support. |
| **UX_DEVICE_INITIALIZE_FRAMEWORK_SCAN_DISABLE** | This macro disables device framework scan, where max number of endpoints (except EP0) and max number of interfaces are calculated at runtime, as a base to allocate memory for interfaces and endpoints structures and their buffers. Undefined, the following two macros must be defined to initialize memory structures. |
| **UX_MAX_DEVICE_ENDPOINTS** | This value represents max number of endpoints (except EP0) activated at the same time. Works if UX_DEVICE_INITIALIZE_FRAMEWORK_SCAN_DISABLE is defined. |
| **UX_MAX_DEVICE_INTERFACES** | This value represents max number of interfaces activated at the same time. Works if UX_DEVICE_INITIALIZE_FRAMEWORK_SCAN_DISABLE is defined. |
| **UX_NAME_REFERENCED_BY_POINTER** | Defined, the _name in structs are referenced by pointer instead of by contents. By default the _name is an array of string that saves characters, the contents are compared to confirm match. If referenced by pointer the address pointer to const string is saved, the pointers are compared to confirm match. |
| **UX_DEVICE_SIDE_ONLY** | This value will only enable the device side of USBX. |
| **UX_STANDALONE** | This macro will enable the standalone mode of USBX. |
| **UX_DEBUG_LOG_SIZE** | This value represents the size of the log pool. |
| **UX_ENABLE_ASSERT** | This enables the assert checks inside USBX. |
| **UX_ENABLE_ERROR_CHECKING** | This option enables the basic USBX error checking. This define is typically used when the application is debugging and removed after the application is fully debugged. |

## Source Code Tree

The USBX files are provided in several directories.

![Source Code Tree](media/usbx-device-stack/source-code-tree.png)
![Source Code Tree](./media/usbx-device-stack/source-code-tree.png)

In order to make the files recognizable by their names, the following convention has been adopted:

| File Suffix Name | File description |
| ----------------- | ----------------------------------------- |
| ux_host_stack | usbx host stack core files |
| ux_host_class | usbx host stack classes files |
| ux_hcd | usbx host stack controller driver files |
| ux_device_stack | usbx device stack core files |
| ux_device_class | usbx device stack classes files |
| ux_dcd | usbx device stack controller driver files |
| ux_otg | usbx otg controller driver related files |
| ux_pictbridge | usbx pictbridge files |
| ux_utility | usbx utility functions |
| demo_usbx | demonstration files for USBX |
| ux_host_stack | usbx host stack core files |
| ux_host_class | usbx host stack classes files |
| ux_hcd | usbx host stack controller driver files |
| ux_device_stack | usbx device stack core files |
| ux_device_class | usbx device stack classes files |
| ux_dcd | usbx device stack controller driver files |
| ux_otg | usbx otg controller driver related files |
| ux_pictbridge | usbx pictbridge files |
| ux_utility | usbx utility functions |
| demo_usbx | demonstration files for USBX |

## Initialization of USBX resources

Expand All @@ -117,26 +123,24 @@ The following function initializes USBX memory resources with 128 K of regular m

```c
/* Initialize USBX Memory */
ux_system_initialize(memory_pointer,(128*1024),UX_NULL,0);
ux_system_initialize(memory_pointer, (128*1024), UX_NULL, 0);
```
The prototype for the ux_system_initialize is as follows:
```c
UINT ux_system_initialize(VOID *regular_memory_pool_start,
ULONG regular_memory_size,
VOID *cache_safe_memory_pool_start,
ULONG cache_safe_memory_size);
ULONG regular_memory_size,
VOID *cache_safe_memory_pool_start,
ULONG cache_safe_memory_size);
```

Input parameters:
Where:

| Parameter | Description |
| ---------------------------------- | --------------------------------------- |
| VOID *regular_memory_pool_start | Beginning of the regular memory pool |
| ULONG regular_memory_size | Size of the regular memory pool |
| VOID *cache_safe_memory_pool_start | Beginning of the cache safe memory pool |
| ULONG cache_safe_memory_size | Size of the cache safe memory pool |
- *regular_memory_pool_start*: Beginning of the regular memory pool.
- *regular_memory_size*: Size of the regular memory pool.
- *cache_safe_memory_pool_start*: Beginning of the cache safe memory pool.
- *cache_safe_memory_size*: Size of the cache safe memory pool.

Not all systems require the definition of cache safe memory. In such a system, the values passed during the initialization for the memory pointer will be set to UX_NULL and the size of the pool to 0. USBX will then use the regular memory pool in lieu of the cache safe pool.

Expand All @@ -147,8 +151,7 @@ In a system where the regular memory is not cache safe and a controller requires
USBX can be terminated by releasing its resources. Prior to terminating usbx, all classes and controller resources need to be terminated properly. The following function uninitializes USBX memory resources:

```c
/* Unitialize USBX Resources */

/* Uninitialize USBX Resources */
ux_system_uninitialize();
```

Expand All @@ -169,17 +172,14 @@ ux_dcd_controller_initialize(0x7BB00000, 0, 0xB7A00000);
The USB device initialization has the following prototype:

```c
UINT ux_dcd_controller_initialize(ULONG dcd_io,
ULONG dcd_irq, ULONG dcd_vbus_address);
UINT ux_dcd_controller_initialize(ULONG dcd_io, ULONG dcd_irq, ULONG dcd_vbus_address);
```
with the following parameters:
Where:
| Parameter | Description |
| ------------------------ | -------------------------------- |
| ULONG dcd_io | Address of the controller IO |
| ULONG dcd_irq | Interrupt used by the controller |
| ULONG dcd_vbus_address | Address of the VBUS GPIO |
- *dcd_io*: Address of the controller IO.
- *dcd_irq*: Interrupt used by the controller.
- *dcd_vbus_address*: Address of the VBUS GPIO .
The following example is the initialization of USBX in device mode with the storage device class and a generic controller:
Expand All @@ -189,11 +189,11 @@ The following example is the initialization of USBX in device mode with the stor
ux_system_initialize(memory_pointer,(128*1024), 0, 0);
/* The code below is required for installing the device portion of USBX */
status = ux_device_stack_initialize(&device_framework_high_speed,
DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED, &device_framework_full_speed,
DEVICE_FRAMEWORK_LENGTH_FULL_SPEED, &string_framework,
STRING_FRAMEWORK_LENGTH, &language_id_framework,
LANGUAGE_ID_FRAMEWORK_LENGTH, UX_NULL);
status = ux_device_stack_initialize(&device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
&device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
&string_framework, STRING_FRAMEWORK_LENGTH,
&language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,
UX_NULL);
/* If status equals UX_SUCCESS, installation was successful. */
Expand All @@ -205,13 +205,12 @@ storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage
storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_block_length = 512;
storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_type = 0;
storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_removable_flag = 0x80;
storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_read = tx_demo_thread_flash_media_read;
storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_write = tx_demo_thread_flash_media_write;
storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_status = tx_demo_thread_flash_media_status;
storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_read = demo_thread_flash_media_read;
storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_write = demo_thread_flash_media_write;
storage_parameter.ux_slave_class_storage_parameter_lun[0].ux_slave_class_storage_media_status = demo_thread_flash_media_status;
/* Initialize the device storage class. The class is connected with interface 0 */
status = ux_device_stack_class_register(ux_system_slave_class_storage_name ux_device_class_storage_entry,
ux_device_class_storage_thread,0, (VOID *)&storage_parameter);
status = ux_device_stack_class_register(ux_system_slave_class_storage_name ux_device_class_storage_entry, ux_device_class_storage_thread, 0, (VOID *)&storage_parameter);
/* Register the device controllers available in this system */
status = ux_dcd_controller_initialize(0x7BB00000, 0, 0xB7A00000);
Expand Down
Loading

0 comments on commit ab21f18

Please sign in to comment.