summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xREADME.md139
-rw-r--r--[-rwxr-xr-x]common/core/inc/ux_api.h26
-rw-r--r--common/core/inc/ux_user_sample.h25
-rw-r--r--common/core/src/ux_host_stack_configuration_instance_create.c28
-rw-r--r--common/core/src/ux_host_stack_configuration_instance_delete.c14
-rw-r--r--[-rwxr-xr-x]common/core/src/ux_host_stack_hcd_thread_entry.c0
-rw-r--r--[-rwxr-xr-x]common/core/src/ux_host_stack_hcd_unregister.c0
-rw-r--r--[-rwxr-xr-x]common/core/src/ux_host_stack_rh_change_process.c0
-rw-r--r--common/core/src/ux_host_stack_tasks_run.c39
-rw-r--r--common/core/src/ux_host_stack_transfer_request_abort.c11
-rw-r--r--[-rwxr-xr-x]common/core/src/ux_utility_delay_ms.c0
-rw-r--r--common/usbx_device_classes/CMakeLists.txt10
-rw-r--r--common/usbx_device_classes/inc/ux_device_class_audio.h49
-rw-r--r--common/usbx_device_classes/inc/ux_device_class_cdc_ecm.h14
-rw-r--r--common/usbx_device_classes/inc/ux_device_class_printer.h42
-rw-r--r--common/usbx_device_classes/inc/ux_device_class_rndis.h18
-rw-r--r--common/usbx_device_classes/inc/ux_device_class_video.h26
-rw-r--r--common/usbx_device_classes/src/ux_device_class_audio_activate.c11
-rw-r--r--common/usbx_device_classes/src/ux_device_class_audio_change.c21
-rw-r--r--common/usbx_device_classes/src/ux_device_class_audio_feedback_task_function.c164
-rw-r--r--common/usbx_device_classes/src/ux_device_class_audio_feedback_thread_entry.c11
-rw-r--r--common/usbx_device_classes/src/ux_device_class_audio_initialize.c58
-rw-r--r--common/usbx_device_classes/src/ux_device_class_audio_interrupt_send.c11
-rw-r--r--common/usbx_device_classes/src/ux_device_class_audio_interrupt_task_function.c198
-rw-r--r--common/usbx_device_classes/src/ux_device_class_audio_read_task_function.c188
-rw-r--r--common/usbx_device_classes/src/ux_device_class_audio_read_thread_entry.c7
-rw-r--r--common/usbx_device_classes/src/ux_device_class_audio_reception_start.c13
-rw-r--r--common/usbx_device_classes/src/ux_device_class_audio_tasks_run.c153
-rw-r--r--common/usbx_device_classes/src/ux_device_class_audio_transmission_start.c13
-rw-r--r--common/usbx_device_classes/src/ux_device_class_audio_write_task_function.c210
-rw-r--r--common/usbx_device_classes/src/ux_device_class_audio_write_thread_entry.c11
-rw-r--r--common/usbx_device_classes/src/ux_device_class_cdc_acm_read_run.c7
-rw-r--r--common/usbx_device_classes/src/ux_device_class_cdc_acm_tasks_run.c15
-rw-r--r--common/usbx_device_classes/src/ux_device_class_cdc_acm_write_run.c9
-rw-r--r--common/usbx_device_classes/src/ux_device_class_cdc_ecm_bulkin_thread.c31
-rw-r--r--common/usbx_device_classes/src/ux_device_class_cdc_ecm_bulkout_thread.c76
-rw-r--r--common/usbx_device_classes/src/ux_device_class_cdc_ecm_initialize.c34
-rw-r--r--common/usbx_device_classes/src/ux_device_class_cdc_ecm_uninitialize.c11
-rw-r--r--[-rwxr-xr-x]common/usbx_device_classes/src/ux_device_class_hid_control_request.c0
-rw-r--r--common/usbx_device_classes/src/ux_device_class_hid_initialize.c10
-rw-r--r--common/usbx_device_classes/src/ux_device_class_printer_initialize.c17
-rw-r--r--common/usbx_device_classes/src/ux_device_class_printer_read_run.c238
-rw-r--r--common/usbx_device_classes/src/ux_device_class_printer_soft_reset.c11
-rw-r--r--common/usbx_device_classes/src/ux_device_class_printer_uninitialize.c9
-rw-r--r--common/usbx_device_classes/src/ux_device_class_printer_write_run.c258
-rw-r--r--common/usbx_device_classes/src/ux_device_class_rndis_bulkin_thread.c44
-rw-r--r--common/usbx_device_classes/src/ux_device_class_rndis_bulkout_thread.c119
-rw-r--r--common/usbx_device_classes/src/ux_device_class_rndis_initialize.c38
-rw-r--r--common/usbx_device_classes/src/ux_device_class_storage_tasks_run.c24
-rw-r--r--common/usbx_device_classes/src/ux_device_class_video_activate.c13
-rw-r--r--common/usbx_device_classes/src/ux_device_class_video_change.c14
-rw-r--r--common/usbx_device_classes/src/ux_device_class_video_initialize.c28
-rw-r--r--common/usbx_device_classes/src/ux_device_class_video_read_task_function.c188
-rw-r--r--common/usbx_device_classes/src/ux_device_class_video_read_thread_entry.c6
-rw-r--r--common/usbx_device_classes/src/ux_device_class_video_reception_start.c19
-rw-r--r--common/usbx_device_classes/src/ux_device_class_video_tasks_run.c113
-rw-r--r--common/usbx_device_classes/src/ux_device_class_video_transmission_start.c22
-rw-r--r--common/usbx_device_classes/src/ux_device_class_video_write_task_function.c209
-rw-r--r--common/usbx_device_classes/src/ux_device_class_video_write_thread_entry.c11
-rw-r--r--common/usbx_host_classes/inc/ux_host_class_asix.h78
-rw-r--r--common/usbx_host_classes/inc/ux_host_class_cdc_ecm.h19
-rw-r--r--common/usbx_host_classes/inc/ux_host_class_hid_keyboard.h8
-rw-r--r--[-rwxr-xr-x]common/usbx_host_classes/inc/ux_host_class_storage.h0
-rw-r--r--common/usbx_host_classes/src/ux_host_class_asix_activate.c49
-rw-r--r--common/usbx_host_classes/src/ux_host_class_asix_deactivate.c23
-rw-r--r--common/usbx_host_classes/src/ux_host_class_asix_endpoints_get.c27
-rw-r--r--common/usbx_host_classes/src/ux_host_class_asix_entry.c43
-rw-r--r--common/usbx_host_classes/src/ux_host_class_asix_interrupt_notification.c59
-rw-r--r--common/usbx_host_classes/src/ux_host_class_asix_reception_callback.c10
-rw-r--r--common/usbx_host_classes/src/ux_host_class_asix_thread.c691
-rw-r--r--common/usbx_host_classes/src/ux_host_class_asix_transmission_callback.c54
-rw-r--r--common/usbx_host_classes/src/ux_host_class_asix_write.c124
-rw-r--r--common/usbx_host_classes/src/ux_host_class_cdc_ecm_activate.c189
-rw-r--r--common/usbx_host_classes/src/ux_host_class_cdc_ecm_deactivate.c19
-rw-r--r--common/usbx_host_classes/src/ux_host_class_cdc_ecm_mac_address_get.c19
-rw-r--r--common/usbx_host_classes/src/ux_host_class_cdc_ecm_thread.c113
-rw-r--r--common/usbx_host_classes/src/ux_host_class_cdc_ecm_transmission_callback.c26
-rw-r--r--common/usbx_host_classes/src/ux_host_class_cdc_ecm_write.c55
-rw-r--r--common/usbx_host_classes/src/ux_host_class_hid_keyboard_tasks_run.c24
-rw-r--r--common/usbx_host_classes/src/ux_host_class_hub_entry.c9
-rw-r--r--common/usbx_host_classes/src/ux_host_class_hub_tasks_run.c36
-rw-r--r--[-rwxr-xr-x]common/usbx_host_classes/src/ux_host_class_storage_entry.c0
-rw-r--r--common/usbx_host_classes/src/ux_host_class_storage_media_open.c15
-rw-r--r--[-rwxr-xr-x]common/usbx_host_classes/src/ux_host_class_storage_partition_read.c0
-rw-r--r--common/usbx_host_classes/src/ux_host_class_storage_tasks_run.c56
-rw-r--r--common/usbx_host_classes/src/ux_host_class_storage_transport_run.c13
-rw-r--r--common/usbx_host_classes/src/ux_host_class_video_activate.c16
-rw-r--r--[-rwxr-xr-x]common/usbx_host_classes/src/ux_host_class_video_frame_interval_get.c0
-rw-r--r--[-rwxr-xr-x]common/usbx_host_controllers/inc/ux_hcd_ehci.h0
-rw-r--r--[-rwxr-xr-x]common/usbx_host_controllers/inc/ux_hcd_ohci.h0
-rw-r--r--[-rwxr-xr-x]common/usbx_host_controllers/src/ux_hcd_ehci_asynchronous_endpoint_create.c0
-rw-r--r--[-rwxr-xr-x]common/usbx_host_controllers/src/ux_hcd_ehci_done_queue_process.c0
-rw-r--r--[-rwxr-xr-x]common/usbx_host_controllers/src/ux_hcd_ehci_hsisochronous_tds_process.c0
-rw-r--r--[-rwxr-xr-x]common/usbx_host_controllers/src/ux_hcd_ehci_interrupt_endpoint_create.c0
-rw-r--r--[-rwxr-xr-x]common/usbx_host_controllers/src/ux_hcd_ehci_interrupt_endpoint_destroy.c0
-rw-r--r--[-rwxr-xr-x]common/usbx_host_controllers/src/ux_hcd_ehci_isochronous_endpoint_create.c0
-rw-r--r--[-rwxr-xr-x]common/usbx_host_controllers/src/ux_hcd_ehci_isochronous_endpoint_destroy.c0
-rw-r--r--[-rwxr-xr-x]common/usbx_host_controllers/src/ux_hcd_ehci_least_traffic_list_get.c0
-rw-r--r--[-rwxr-xr-x]common/usbx_host_controllers/src/ux_hcd_ehci_periodic_tree_create.c0
-rw-r--r--[-rwxr-xr-x]common/usbx_host_controllers/src/ux_hcd_ehci_poll_rate_entry_get.c0
-rw-r--r--[-rwxr-xr-x]common/usbx_host_controllers/src/ux_hcd_ehci_request_control_transfer.c0
-rw-r--r--[-rwxr-xr-x]common/usbx_host_controllers/src/ux_hcd_ehci_transfer_abort.c0
-rw-r--r--[-rwxr-xr-x]common/usbx_host_controllers/src/ux_hcd_ohci_endpoint_error_clear.c0
-rw-r--r--[-rwxr-xr-x]common/usbx_host_controllers/src/ux_hcd_ohci_endpoint_reset.c0
-rw-r--r--[-rwxr-xr-x]common/usbx_host_controllers/src/ux_hcd_ohci_periodic_endpoint_destroy.c0
-rw-r--r--[-rwxr-xr-x]common/usbx_host_controllers/src/ux_hcd_ohci_port_resume.c0
-rw-r--r--[-rwxr-xr-x]common/usbx_host_controllers/src/ux_hcd_ohci_port_suspend.c0
-rw-r--r--[-rwxr-xr-x]common/usbx_host_controllers/src/ux_hcd_ohci_power_down_port.c0
-rw-r--r--[-rwxr-xr-x]common/usbx_host_controllers/src/ux_hcd_ohci_power_on_port.c0
-rw-r--r--[-rwxr-xr-x]common/usbx_host_controllers/src/ux_hcd_ohci_power_root_hubs.c0
-rw-r--r--[-rwxr-xr-x]common/usbx_host_controllers/src/ux_hcd_ohci_request_control_transfer.c0
-rw-r--r--[-rwxr-xr-x]common/usbx_host_controllers/src/ux_hcd_ohci_transfer_abort.c0
-rw-r--r--docs/usbx-features.pngbin0 -> 317752 bytes
-rw-r--r--ports/arm9/gnu/inc/ux_port.h2
-rw-r--r--ports/arm9/iar/inc/ux_port.h2
-rw-r--r--ports/cortex_a15/gnu/inc/ux_port.h2
-rw-r--r--ports/cortex_a5/gnu/inc/ux_port.h2
-rw-r--r--ports/cortex_a5/iar/inc/ux_port.h2
-rw-r--r--ports/cortex_a5x/ac6/inc/ux_port.h2
-rw-r--r--ports/cortex_a7/gnu/inc/ux_port.h2
-rw-r--r--ports/cortex_a7/iar/inc/ux_port.h2
-rw-r--r--ports/cortex_a8/gnu/inc/ux_port.h2
-rw-r--r--ports/cortex_a8/iar/inc/ux_port.h2
-rw-r--r--ports/cortex_a9/gnu/inc/ux_port.h2
-rw-r--r--ports/cortex_a9/iar/inc/ux_port.h2
-rw-r--r--ports/cortex_m0/gnu/inc/ux_port.h2
-rw-r--r--ports/cortex_m0/iar/inc/ux_port.h2
-rw-r--r--ports/cortex_m3/gnu/inc/ux_port.h2
-rw-r--r--ports/cortex_m3/iar/inc/ux_port.h2
-rw-r--r--ports/cortex_m4/gnu/inc/ux_port.h2
-rw-r--r--ports/cortex_m4/iar/inc/ux_port.h2
-rw-r--r--ports/cortex_m7/gnu/inc/ux_port.h2
-rw-r--r--ports/cortex_m7/iar/inc/ux_port.h2
-rw-r--r--ports/cortex_r4/gnu/inc/ux_port.h2
-rw-r--r--ports/cortex_r4/iar/inc/ux_port.h2
-rw-r--r--ports/cortex_r5/gnu/inc/ux_port.h2
-rw-r--r--ports/cortex_r5/iar/inc/ux_port.h2
-rw-r--r--ports/generic/inc/ux_port.h2
-rw-r--r--ports/linux/gnu/inc/ux_port.h2
139 files changed, 3938 insertions, 973 deletions
diff --git a/README.md b/README.md
index d0165cd..edf9d04 100755
--- a/README.md
+++ b/README.md
@@ -2,106 +2,105 @@
A high-performance USB host, device, and on-the-go (OTG) embedded stack, Azure RTOS USBX is fully integrated with Azure RTOS ThreadX and available for all Azure RTOS ThreadX–supported processors. Like Azure RTOS ThreadX, Azure RTOS USBX is designed to have a small footprint and high performance, making it ideal for deeply embedded applications that require an interface with USB devices.
-## Documentation
+Here are the key features and modules of USBX:
-Documentation for this library can be found here: http://docs.microsoft.com/azure/rtos/usbx
+![USBX Key Features](./docs/usbx-features.png)
-# Understanding inter-component dependencies
+## Getting Started
-The main components of Azure RTOS are each provided in their own repository, but there are dependencies between them--shown in the following graph--that are important to understand when setting up your builds.
+Azure RTOS USBX as part of Azure RTOS has been integrated to the semiconductor's SDKs and development environment. You can develop using the tools of choice from [STMicroelectronics](https://www.st.com/content/st_com/en/campaigns/x-cube-azrtos-azure-rtos-stm32.html), [NXP](https://www.nxp.com/design/software/embedded-software/azure-rtos-for-nxp-microcontrollers:AZURE-RTOS), [Renesas](https://github.com/renesas/azure-rtos) and [Microchip](https://mu.microchip.com/get-started-simplifying-your-iot-design-with-azure-rtos).
-![dependency graph](docs/deps.png)
+We also provide [samples](https://github.com/azure-rtos/samples) using hero development boards from semiconductors you can build and test with.
-# Building and using the library
+See [Overview of Azure RTOS USBX](https://learn.microsoft.com/azure/rtos/usbx/overview-usbx) for the high-level overview, and all documentation and APIs can be found in: [Azure RTOS USBX documentation](https://learn.microsoft.com/azure/rtos/usbx/).
-## Prerequisites
+## Repository Structure and Usage
-Install the following tools:
+### Directory layout
-* [CMake](https://cmake.org/download/) version 3.0 or later
-* [GCC compilers for arm-none-eabi](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads)
-* [Ninja](https://ninja-build.org/)
+ .
+ ├── cmake # CMakeList files for building the project
+ ├── common # Core USBX files
+ ├── ports # Architecture and compiler specific files
+ ├── samples # Sample codes
+ ├── support # Misc platform configurations file used by USBX
+ ├── LICENSE.txt # License terms
+ ├── LICENSE-HARDWARE.txt # Licensed hardware from semiconductors
+ ├── CONTRIBUTING.md # Contribution guidance
+ └── SECURITY.md # Microsoft repo security guidance
-## Cloning the repo
+### Branches & Releases
-```bash
-$ git clone https://github.com/azure-rtos/usbx.git
-```
+The master branch has the most recent code with all new features and bug fixes. It does not represent the latest General Availability (GA) release of the library. Each official release (preview or GA) will be tagged to mark the commit and push it into the Github releases tab, e.g. `v6.2-rel`.
-## Building as a static library
+## Component dependencies
-Each component of Azure RTOS comes with a composible CMake-based build system that supports many different MCUs and host systems. Integrating any of these components into your device app code is as simple as adding a git submodule and then including it in your build using the CMake command `add_subdirectory()`.
+The main components of Azure RTOS are each provided in their own repository, but there are dependencies between them, as shown in the following graph. This is important to understand when setting up your builds.
-While the typical usage pattern is to include threadx into your device code source tree to be built & linked with your code, you can compile this project as a standalone static library to confirm your build is set up correctly.
+![dependency graph](docs/deps.png)
-```bash
-$ cmake -Bbuild -DCMAKE_TOOLCHAIN_FILE=cmake/cortex_m4.cmake -GNinja .
+> You will have to take the dependency graph above into account when building anything other than ThreadX itself.
-$ cmake --build ./build
-```
+### Building and using the library
-NOTE: You will have to take the dependency graph above into account when building anything other than threadx itself.
+Instruction for building the USBX as static library using Arm GNU Toolchain and CMake. If you are using toolchain and IDE from semiconductor, you might follow its own instructions to use Azure RTOS components as explained in the [Getting Started](#getting-started) section.
-# Repository Structure and Usage
+1. Install the following tools:
-## Branches & Releases
+ * [CMake](https://cmake.org/download/) version 3.0 or later
+ * [Arm GNU Toolchain for arm-none-eabi](https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads)
+ * [Ninja](https://ninja-build.org/)
-The master branch has the most recent code with all new features and bug fixes. It does not represent the latest General Availability (GA) release of the library.
+1. Build the [ThreadX library](https://github.com/azure-rtos/threadx#building-and-using-the-library) as the dependency.
-## Releases
+1. Cloning the repo.
-Each official release (preview or GA) will be tagged to mark the commit and push it into the Github releases tab, e.g. `v6.0-rel`.
+ ```bash
+ $ git clone https://github.com/azure-rtos/usbx.git
+ ```
-## Directory layout
+1. Define the features and addons you need in `ux_user.h` and build together with the component source code. You can refer to [`ux_user_sample.h`](https://github.com/azure-rtos/usbx/blob/master/common/core/inc/ux_user_sample.h) as an example.
-```
-- cmake
-- common
- - inc
- - src
-- ports
- - cortex_m0/gnu
- - inc
- - src
- - cortex_m3/gnu
- - inc
- - src
- - cortex_m4/gnu
- - inc
- - src
- - cortex_m7/gnu
- - inc
- - src
-- samples
-```
+1. Building as a static library
-# Security
+ Each component of Azure RTOS comes with a composable CMake-based build system that supports many different MCUs and host systems. Integrating any of these components into your device app code is as simple as adding a git submodule and then including it in your build using the CMake `add_subdirectory()`.
-Azure RTOS provides OEMs with components to secure communication and to create code and data isolation using underlying MCU/MPU hardware protection mechanisms. It is ultimately the responsibility of the device builder to ensure the device fully meets the evolving security requirements associated with its specific use case.
+ While the typical usage pattern is to include USBX into your device code source tree to be built & linked with your code, you can compile this project as a standalone static library to confirm your build is set up correctly.
+
+ An example of building the library for Cortex-M4:
+
+ ```bash
+ $ cmake -Bbuild -GNinja -DCMAKE_TOOLCHAIN_FILE=cmake/cortex_m4.cmake .
+
+ $ cmake --build ./build
+ ```
-# Licensing
+## Professional support
-License terms for using Azure RTOS are defined in the LICENSE.txt file of this repo. Please refer to this file for all definitive licensing information. No additional license fees are required for deploying Azure RTOS on hardware defined in the LICENSED-HARDWARE.txt file. If you are using hardware not defined in the LICENSED-HARDWARE.txt file or have licensing questions in general, please contact Microsoft directly at https://aka.ms/azrtos-license.
+[Professional support plans](https://azure.microsoft.com/support/options/) are available from Microsoft. For community support and others, see the [Resources](#resources) section below.
-# Contribution, feedback, issues, and professional support
+## Licensing
-If you encounter any bugs, have suggestions for new features, or if you would like to become an active contributor to this project, please follow the instructions provided in the contribution guideline for the corresponding repo.
+License terms for using Azure RTOS are defined in the LICENSE.txt file of this repo. Please refer to this file for all definitive licensing information. No additional license fees are required for deploying Azure RTOS on hardware defined in the [LICENSED-HARDWARE.txt](./LICENSED-HARDWARE.txt) file. If you are using hardware not listed in the file or having licensing questions in general, please contact Microsoft directly at https://aka.ms/azrtos-license.
-For basic support, click Issues in the command bar or post a question to [Stack Overflow](http://stackoverflow.com/questions/tagged/azure-rtos+threadx) using the `threadx` and `azure-rtos` tags.
+## Resources
-Professional support plans (https://azure.microsoft.com/en-us/support/options/) are available from Microsoft.
+The following are references to additional Azure RTOS resources:
+
+- **Product introduction and white papers**: https://azure.com/rtos
+- **General technical questions**: https://aka.ms/QnA/azure-rtos
+- **Product issues and bugs, or feature requests**: https://github.com/azure-rtos/usbx/issues
+- **Licensing and sales questions**: https://aka.ms/azrtos-license
+- **Product roadmap and support policy**: https://aka.ms/azrtos/lts
+- **Blogs and videos**: http://msiotblog.com and https://aka.ms/iotshow
+- **Azure RTOS TraceX Installer**: https://aka.ms/azrtos-tracex-installer
+
+You can also check [previous questions](https://stackoverflow.com/questions/tagged/azure-rtos+usbx) or ask new ones on StackOverflow using the `azure-rtos` and `usbx` tags.
+
+## Security
+
+Azure RTOS provides OEMs with components to secure communication and to create code and data isolation using underlying MCU/MPU hardware protection mechanisms. It is ultimately the responsibility of the device builder to ensure the device fully meets the evolving security requirements associated with its specific use case.
-# Additional Resources
+## Contribution
-The following are references to additional Azure RTOS and Azure IoT in general:
-| Content | Link |
-|---|---|
-| TraceX Installer | https://aka.ms/azrtos-tracex-installer |
-| Azure RTOS Documentation and Guides: | https://docs.microsoft.com/azure/rtos |
-| Azure RTOS Website: | https://azure.microsoft.com/services/rtos/ |
-| Azure RTOS Sales Questions: | https://aka.ms/azrtos-license |
-| Azure RTOS Product Support Policy | https://aka.ms/azrtos/lts |
-| Azure RTOS Functional Safety Artifacts | https://aka.ms/azrtos/tuv |
-| For technical questions check out Microsoft Q/A for Azure IoT | https://aka.ms/QnA/azure-rtos |
-| Internet of Things Show for latest announcements and online training | https://aka.ms/iotshow |
-| IoT Tech Community | https://aka.ms/community/azure-rtos |
+Please follow the instructions provided in the [CONTRIBUTING.md](./CONTRIBUTING.md) for the corresponding repository.
diff --git a/common/core/inc/ux_api.h b/common/core/inc/ux_api.h
index b8f0c6e..cb83675 100755..100644
--- a/common/core/inc/ux_api.h
+++ b/common/core/inc/ux_api.h
@@ -26,7 +26,7 @@
/* APPLICATION INTERFACE DEFINITION RELEASE */
/* */
/* ux_api.h PORTABLE C */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -122,6 +122,12 @@
/* added shared device config */
/* descriptor for enum scan, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* added some ETH error codes, */
+/* allowed align minimal def, */
+/* added interface instance */
+/* creation strategy control, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
@@ -288,8 +294,8 @@ typedef signed char SCHAR;
/* Define basic constants for the USBX Stack. */
#define AZURE_RTOS_USBX
#define USBX_MAJOR_VERSION 6
-#define USBX_MINOR_VERSION 1
-#define USBX_PATCH_VERSION 12
+#define USBX_MINOR_VERSION 2
+#define USBX_PATCH_VERSION 0
/* Macros for concatenating tokens, where UX_CONCATn concatenates n tokens. */
@@ -1102,7 +1108,6 @@ VOID _ux_trace_event_update(TX_TRACE_BUFFER_ENTRY *event, ULONG timestamp, UL
#define UX_NO_ALIGN 0u
#define UX_ALIGN_16 0x0fu
-#define UX_ALIGN_MIN 0x0fu
#define UX_ALIGN_32 0x1fu
#define UX_ALIGN_64 0x3fu
#define UX_ALIGN_128 0x7fu
@@ -1113,6 +1118,9 @@ VOID _ux_trace_event_update(TX_TRACE_BUFFER_ENTRY *event, ULONG timestamp, UL
#define UX_ALIGN_4096 0xfffu
#define UX_SAFE_ALIGN 0xffffffffu
#define UX_MAX_SCATTER_GATHER_ALIGNMENT 4096
+#ifndef UX_ALIGN_MIN
+#define UX_ALIGN_MIN UX_ALIGN_16
+#endif
#define UX_MAX_USB_DEVICES 127
@@ -1483,6 +1491,10 @@ VOID _ux_trace_event_update(TX_TRACE_BUFFER_ENTRY *event, ULONG timestamp, UL
#define UX_HOST_CLASS_AUDIO_WRONG_FREQUENCY 0x82
#define UX_CLASS_CDC_ECM_LINK_STATE_DOWN_ERROR 0x90
+#define UX_CLASS_ETH_LINK_STATE_DOWN_ERROR 0x90
+#define UX_CLASS_ETH_PACKET_POOL_ERROR 0x91
+#define UX_CLASS_ETH_PACKET_ERROR 0x92
+#define UX_CLASS_ETH_SIZE_ERROR 0x93
/* Define USBX HCD API function constants. */
@@ -2049,6 +2061,12 @@ typedef struct UX_CONFIGURATION_STRUCT
ULONG ux_configuration_iad_protocol;
} UX_CONFIGURATION;
+#define UX_HOST_STACK_CONFIGURATION_INSTANCE_CREATE_ALL 0 /* Default: all things created. */
+#define UX_HOST_STACK_CONFIGURATION_INSTANCE_CREATE_OWNED 1 /* Owned: class owned things created. */
+#ifndef UX_HOST_STACK_CONFIGURATION_INSTANCE_CREATE_CONTROL
+#define UX_HOST_STACK_CONFIGURATION_INSTANCE_CREATE_CONTROL UX_HOST_STACK_CONFIGURATION_INSTANCE_CREATE_ALL
+#endif
+
/* Define USBX Interface Descriptor structure. */
diff --git a/common/core/inc/ux_user_sample.h b/common/core/inc/ux_user_sample.h
index 0df602e..72a7e5e 100644
--- a/common/core/inc/ux_user_sample.h
+++ b/common/core/inc/ux_user_sample.h
@@ -26,7 +26,7 @@
/* PORT SPECIFIC C INFORMATION RELEASE */
/* */
/* ux_user.h PORTABLE C */
-/* 6.1.12 */
+/* 6.2.0 */
/* */
/* AUTHOR */
/* */
@@ -83,6 +83,12 @@
/* added device CDC_ACM and */
/* printer write auto ZLP, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* deprecated ECM pool option, */
+/* added align minimal config, */
+/* added host stack instance */
+/* creation strategy control, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
@@ -116,6 +122,10 @@
/* Override various options with default values already assigned in ux_api.h or ux_port.h. Please
also refer to ux_port.h for descriptions on each of these options. */
+/* Defined, this value represents minimal allocated memory alignment in number of bytes.
+ The default is UX_ALIGN_16 (0x0f) to align allocated memory to 16 bytes. */
+/* #define UX_ALIGN_MIN UX_ALIGN_16 */
+
/* Defined, this value represents how many ticks per seconds for a specific hardware platform.
The default is 1000 indicating 1 tick per millisecond. */
@@ -317,7 +327,9 @@
/* #define UX_HOST_CLASS_CDC_ECM_PACKET_POOL_INSTANCE_WAIT 10 */
-/* Defined, this enables CDC ECM class to use the packet pool from NetX instance. */
+/* Defined, this enables CDC ECM class to use the packet pool from NetX instance.
+ It's deprecated, packet pool from NetX instance is always used now.
+ */
/* #define UX_HOST_CLASS_CDC_ECM_USE_PACKET_POOL_FROM_NETX */
@@ -427,6 +439,15 @@
/* Defined, host audio optional interrupt endpoint is support. */
/* #define UX_HOST_CLASS_AUDIO_INTERRUPT_SUPPORT */
+/* Defined, this value controls host configuration instance creation, include all
+ interfaces and endpoints physical resources.
+ Possible settings:
+ UX_HOST_STACK_CONFIGURATION_INSTANCE_CREATE_ALL (0) - The default, create all inside configuration.
+ UX_HOST_STACK_CONFIGURATION_INSTANCE_CREATE_OWNED (1) - Create things owned by class driver.
+ Not defined, default setting is applied.
+ */
+/* #define UX_HOST_STACK_CONFIGURATION_INSTANCE_CREATE_CONTROL UX_HOST_STACK_CONFIGURATION_INSTANCE_CREATE_OWNED */
+
/* Defined, this value will only enable the host side of usbx. */
/* #define UX_HOST_SIDE_ONLY */
diff --git a/common/core/src/ux_host_stack_configuration_instance_create.c b/common/core/src/ux_host_stack_configuration_instance_create.c
index 678b5b5..7d44c07 100644
--- a/common/core/src/ux_host_stack_configuration_instance_create.c
+++ b/common/core/src/ux_host_stack_configuration_instance_create.c
@@ -34,7 +34,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_host_stack_configuration_instance_create PORTABLE C */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -72,6 +72,10 @@
/* fixed parameter/variable */
/* names conflict C++ keyword, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* added interface instance */
+/* creation strategy control, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_host_stack_configuration_instance_create(UX_CONFIGURATION *configuration)
@@ -93,15 +97,21 @@ UINT status;
/* Check if we are dealing with the first alternate setting. */
if (interface_ptr -> ux_interface_descriptor.bAlternateSetting == 0)
{
- /* Create the interface. */
- status = _ux_host_stack_interface_instance_create(interface_ptr);
- /* Check status, the controller may have refused the endpoint creation. */
- if (status != UX_SUCCESS)
-
- /* An error occurred. The interface cannot be mounted. */
- return(status);
-
+#if UX_HOST_STACK_CONFIGURATION_INSTANCE_CREATE_CONTROL == UX_HOST_STACK_CONFIGURATION_INSTANCE_CREATE_OWNED
+
+ /* Create the interface, if it's usable. */
+ if (interface_ptr -> ux_interface_class || configuration -> ux_configuration_device -> ux_device_class)
+#endif
+ {
+ status = _ux_host_stack_interface_instance_create(interface_ptr);
+
+ /* Check status, the controller may have refused the endpoint creation. */
+ if (status != UX_SUCCESS)
+
+ /* An error occurred. The interface cannot be mounted. */
+ return(status);
+ }
}
/* Next interface. */
diff --git a/common/core/src/ux_host_stack_configuration_instance_delete.c b/common/core/src/ux_host_stack_configuration_instance_delete.c
index 9413c69..5834e0d 100644
--- a/common/core/src/ux_host_stack_configuration_instance_delete.c
+++ b/common/core/src/ux_host_stack_configuration_instance_delete.c
@@ -34,7 +34,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_host_stack_configuration_instance_delete PORTABLE C */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -72,6 +72,10 @@
/* fixed parameter/variable */
/* names conflict C++ keyword, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* added interface instance */
+/* creation strategy control, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
VOID _ux_host_stack_configuration_instance_delete(UX_CONFIGURATION *configuration)
@@ -102,7 +106,13 @@ ULONG current_alternate_setting;
if (interface_ptr -> ux_interface_descriptor.bAlternateSetting == current_alternate_setting)
{
- _ux_host_stack_interface_instance_delete(interface_ptr);
+
+#if UX_HOST_STACK_CONFIGURATION_INSTANCE_CREATE_CONTROL == UX_HOST_STACK_CONFIGURATION_INSTANCE_CREATE_OWNED
+
+ /* If interface is usable, remove physical creates. */
+ if (interface_ptr -> ux_interface_class || configuration -> ux_configuration_device -> ux_device_class)
+#endif
+ _ux_host_stack_interface_instance_delete(interface_ptr);
}
interface_ptr = interface_ptr -> ux_interface_next_interface;
diff --git a/common/core/src/ux_host_stack_hcd_thread_entry.c b/common/core/src/ux_host_stack_hcd_thread_entry.c
index 652035b..652035b 100755..100644
--- a/common/core/src/ux_host_stack_hcd_thread_entry.c
+++ b/common/core/src/ux_host_stack_hcd_thread_entry.c
diff --git a/common/core/src/ux_host_stack_hcd_unregister.c b/common/core/src/ux_host_stack_hcd_unregister.c
index 277cf1a..277cf1a 100755..100644
--- a/common/core/src/ux_host_stack_hcd_unregister.c
+++ b/common/core/src/ux_host_stack_hcd_unregister.c
diff --git a/common/core/src/ux_host_stack_rh_change_process.c b/common/core/src/ux_host_stack_rh_change_process.c
index ccce8e8..ccce8e8 100755..100644
--- a/common/core/src/ux_host_stack_rh_change_process.c
+++ b/common/core/src/ux_host_stack_rh_change_process.c
diff --git a/common/core/src/ux_host_stack_tasks_run.c b/common/core/src/ux_host_stack_tasks_run.c
index a867411..6363268 100644
--- a/common/core/src/ux_host_stack_tasks_run.c
+++ b/common/core/src/ux_host_stack_tasks_run.c
@@ -44,7 +44,7 @@ static inline VOID _ux_host_stack_pending_transfers_run(VOID);
/* FUNCTION RELEASE */
/* */
/* _ux_host_stack_tasks_run PORTABLE C */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -105,6 +105,11 @@ static inline VOID _ux_host_stack_pending_transfers_run(VOID);
/* used shared descriptor in */
/* device instance for enum, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* improved internal logic, */
+/* fixed activation issue on */
+/* no class linked interfaces, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_host_stack_tasks_run(VOID)
@@ -376,7 +381,12 @@ UX_INTERFACE *interface_inst;
device -> ux_device_class :
device -> ux_device_enum_inst.interface -> ux_interface_class;
command -> ux_host_class_command_request = UX_HOST_CLASS_COMMAND_ACTIVATE_WAIT;
- status = command -> ux_host_class_command_class_ptr -> ux_host_class_entry_function(command);
+
+ /* If there is no class linked, just next state. */
+ if (command -> ux_host_class_command_class_ptr != UX_NULL)
+ status = command -> ux_host_class_command_class_ptr -> ux_host_class_entry_function(command);
+ else
+ status = UX_STATE_NEXT;
/* No wait command or ready for next state. */
if (status == UX_FUNCTION_NOT_SUPPORTED ||
@@ -435,6 +445,7 @@ UX_TRANSFER *trans;
UX_CONFIGURATION *configuration;
UX_HOST_CLASS_COMMAND class_command;
UCHAR *buffer;
+INT immediate_state = UX_TRUE;
/* Check if the device enumeration should be processed. */
if ((device -> ux_device_flags & UX_DEVICE_FLAG_ENUM) == 0)
@@ -457,7 +468,7 @@ UCHAR *buffer;
}
UX_RESTORE
- while (1)
+ while (immediate_state)
{
switch (device -> ux_device_enum_state)
{
@@ -911,12 +922,17 @@ UCHAR *buffer;
class_command.ux_host_class_command_class_ptr =
device -> ux_device_enum_inst.interface -> ux_interface_class;
}
- status = class_command.ux_host_class_command_class_ptr ->
- ux_host_class_entry_function(&class_command);
- if (status != UX_SUCCESS)
+
+ /* If there class linked, start activation. */
+ if (class_command.ux_host_class_command_class_ptr != UX_NULL)
{
- device -> ux_device_enum_state = UX_HOST_STACK_ENUM_RETRY;
- continue;
+ status = class_command.ux_host_class_command_class_ptr ->
+ ux_host_class_entry_function(&class_command);
+ if (status != UX_SUCCESS)
+ {
+ device -> ux_device_enum_state = UX_HOST_STACK_ENUM_RETRY;
+ continue;
+ }
}
/* Class activate execute wait. */
@@ -1078,8 +1094,11 @@ UCHAR *buffer;
device -> ux_device_enum_state = UX_STATE_RESET;
}
- /* Run once anyway. */
- break;
+ /* Invalid unhandled state. */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_HOST_STACK, UX_INVALID_STATE);
+
+ /* Break the immediate state loop. */
+ immediate_state = UX_FALSE;
}
}
diff --git a/common/core/src/ux_host_stack_transfer_request_abort.c b/common/core/src/ux_host_stack_transfer_request_abort.c
index 58591e9..ad1c5f7 100644
--- a/common/core/src/ux_host_stack_transfer_request_abort.c
+++ b/common/core/src/ux_host_stack_transfer_request_abort.c
@@ -34,7 +34,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_host_stack_transfer_request_abort PORTABLE C */
-/* 6.1.10 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -83,6 +83,8 @@
/* 01-31-2022 Chaoqiong Xiao Modified comment(s), */
/* added standalone support, */
/* resulting in version 6.1.10 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_host_stack_transfer_request_abort(UX_TRANSFER *transfer_request)
@@ -104,14 +106,17 @@ ULONG completion_code;
/* Check pending transaction. */
if (transfer_request -> ux_transfer_request_completion_code == UX_TRANSFER_STATUS_PENDING)
{
-
+
/* Send the abort command to the controller. */
hcd -> ux_hcd_entry_function(hcd, UX_HCD_TRANSFER_ABORT, transfer_request);
/* Save the completion code since we're about to set it to ABORT. The
reason we can't just assume its value is PENDING is that in between
the completion code check and this line, it's possible that the transfer
- completed, which would've changed the completion code to SUCCESS.
+ completed (by HCD function call below, or ISR), which would've
+ changed the completion code to SUCCESS and put the semaphore.
+ Even it's recommended to keep completion code untouched to let things
+ changed later here.
Such a case is valid, and we want to make sure we don't put() the
transfer request's semaphore again. */
completion_code = transfer_request -> ux_transfer_request_completion_code;
diff --git a/common/core/src/ux_utility_delay_ms.c b/common/core/src/ux_utility_delay_ms.c
index 64a3add..64a3add 100755..100644
--- a/common/core/src/ux_utility_delay_ms.c
+++ b/common/core/src/ux_utility_delay_ms.c
diff --git a/common/usbx_device_classes/CMakeLists.txt b/common/usbx_device_classes/CMakeLists.txt
index f3c3867..5291d4b 100644
--- a/common/usbx_device_classes/CMakeLists.txt
+++ b/common/usbx_device_classes/CMakeLists.txt
@@ -10,14 +10,17 @@ target_sources(${PROJECT_NAME} PRIVATE
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_audio_feedback_get.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_audio_feedback_set.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_audio_feedback_thread_entry.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_audio_feedback_task_function.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_audio_frame_write.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_audio_initialize.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_audio_interrupt_send.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_audio_interrupt_thread_entry.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_audio_interrupt_task_function.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_audio_ioctl.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_audio_read_frame_free.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_audio_read_frame_get.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_audio_read_thread_entry.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_audio_read_task_function.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_audio_reception_start.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_audio_sample_read16.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_audio_sample_read24.c
@@ -30,6 +33,8 @@ target_sources(${PROJECT_NAME} PRIVATE
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_audio_write_frame_commit.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_audio_write_frame_get.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_audio_write_thread_entry.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_audio_write_task_function.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_audio_tasks_run.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_ccid_activate.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_ccid_auto_seq_done.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_ccid_auto_seq_start.c
@@ -144,9 +149,11 @@ target_sources(${PROJECT_NAME} PRIVATE
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_printer_initialize.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_printer_ioctl.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_printer_read.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_printer_read_run.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_printer_soft_reset.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_printer_uninitialize.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_printer_write.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_printer_write_run.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_rndis_activate.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_rndis_bulkin_thread.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_rndis_bulkout_thread.c
@@ -201,13 +208,16 @@ target_sources(${PROJECT_NAME} PRIVATE
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_video_max_payload_get.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_video_read_payload_free.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_video_read_payload_get.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_video_read_task_function.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_video_read_thread_entry.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_video_reception_start.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_video_stream_get.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_video_tasks_run.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_video_transmission_start.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_video_uninitialize.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_video_write_payload_commit.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_video_write_payload_get.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_video_write_task_function.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_video_write_thread_entry.c
# {{END_TARGET_SOURCES}}
diff --git a/common/usbx_device_classes/inc/ux_device_class_audio.h b/common/usbx_device_classes/inc/ux_device_class_audio.h
index 8ce47fa..4cc5be3 100644
--- a/common/usbx_device_classes/inc/ux_device_class_audio.h
+++ b/common/usbx_device_classes/inc/ux_device_class_audio.h
@@ -26,7 +26,7 @@
/* COMPONENT DEFINITION RELEASE */
/* */
/* ux_device_class_audio.h PORTABLE C */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -59,6 +59,9 @@
/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */
/* added interrupt support, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Yajun Xia Modified comment(s), */
+/* added standalone support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
@@ -310,6 +313,17 @@ extern "C" {
#define UX_DEVICE_CLASS_AUDIO_IOCTL_GET_ARG 1
+/* Define Audio Class Task states. */
+#define UX_DEVICE_CLASS_AUDIO_INTERRUPT_STOP (UX_STATE_RESET)
+#define UX_DEVICE_CLASS_AUDIO_INTERRUPT_START (UX_STATE_STEP + 1)
+#define UX_DEVICE_CLASS_AUDIO_INTERRUPT_WAIT (UX_STATE_STEP + 2)
+
+#define UX_DEVICE_CLASS_AUDIO_STREAM_RW_STOP (UX_STATE_RESET)
+#define UX_DEVICE_CLASS_AUDIO_STREAM_RW_START (UX_STATE_STEP + 1)
+#define UX_DEVICE_CLASS_AUDIO_STREAM_RW_WAIT (UX_STATE_STEP + 2)
+
+#define UX_DEVICE_CLASS_AUDIO_STREAM_FEEDBACK_RW_STOP (UX_STATE_RESET)
+#define UX_DEVICE_CLASS_AUDIO_STREAM_FEEDBACK_RW_WAIT (UX_STATE_STEP + 1)
/* Define Audio Class callback structure. */
@@ -336,11 +350,20 @@ typedef struct UX_DEVICE_CLASS_AUDIO_STREAM_CALLBACKS_STRUCT
typedef struct UX_DEVICE_CLASS_AUDIO_STREAM_PARAMETER_STRUCT
{
+#if !defined(UX_DEVICE_STANDALONE)
ULONG ux_device_class_audio_stream_parameter_thread_stack_size;
VOID (*ux_device_class_audio_stream_parameter_thread_entry)(ULONG id);
+#else
+ UINT (*ux_device_class_audio_stream_parameter_task_function)(struct UX_DEVICE_CLASS_AUDIO_STREAM_STRUCT*);
+#endif
+
#if defined(UX_DEVICE_CLASS_AUDIO_FEEDBACK_SUPPORT)
+#if !defined(UX_DEVICE_STANDALONE)
ULONG ux_device_class_audio_stream_parameter_feedback_thread_stack_size;
VOID (*ux_device_class_audio_stream_parameter_feedback_thread_entry)(ULONG id);
+#else
+ UINT (*ux_device_class_audio_stream_parameter_feedback_task_function)(struct UX_DEVICE_CLASS_AUDIO_STREAM_STRUCT*);
+#endif
#endif
UX_DEVICE_CLASS_AUDIO_STREAM_CALLBACKS ux_device_class_audio_stream_parameter_callbacks;
@@ -386,6 +409,10 @@ typedef struct UX_DEVICE_CLASS_AUDIO_STREAM_STRUCT
#if !defined(UX_DEVICE_STANDALONE)
UCHAR *ux_device_class_audio_stream_feedback_thread_stack;
UX_THREAD ux_device_class_audio_stream_feedback_thread;
+#else
+ UINT (*ux_device_class_audio_stream_feedback_task_function)(struct UX_DEVICE_CLASS_AUDIO_STREAM_STRUCT*);
+ UINT ux_device_class_audio_stream_feedback_task_state;
+ UINT ux_device_class_audio_stream_feedback_task_status;
#endif
#endif
@@ -394,11 +421,16 @@ typedef struct UX_DEVICE_CLASS_AUDIO_STREAM_STRUCT
#if !defined(UX_DEVICE_STANDALONE)
UCHAR *ux_device_class_audio_stream_thread_stack;
UX_THREAD ux_device_class_audio_stream_thread;
+#else
+ UINT (*ux_device_class_audio_stream_task_function)(struct UX_DEVICE_CLASS_AUDIO_STREAM_STRUCT*);
+ UINT ux_device_class_audio_stream_task_state;
+ UINT ux_device_class_audio_stream_task_status;
#endif
UCHAR *ux_device_class_audio_stream_buffer;
ULONG ux_device_class_audio_stream_buffer_size;
ULONG ux_device_class_audio_stream_frame_buffer_size;
+ ULONG ux_device_class_audio_stream_buffer_error_count;
UX_DEVICE_CLASS_AUDIO_FRAME *ux_device_class_audio_stream_transfer_pos;
UX_DEVICE_CLASS_AUDIO_FRAME *ux_device_class_audio_stream_access_pos;
@@ -429,6 +461,9 @@ typedef struct UX_DEVICE_CLASS_AUDIO_STRUCT
#if !defined(UX_DEVICE_STANDALONE)
UX_SEMAPHORE ux_device_class_audio_status_semaphore;
UX_MUTEX ux_device_class_audio_status_mutex;
+#else
+ UINT ux_device_class_audio_interrupt_task_state;
+ UINT ux_device_class_audio_interrupt_task_status;
#endif
#endif
} UX_DEVICE_CLASS_AUDIO;
@@ -452,7 +487,8 @@ UINT _ux_device_class_audio_stream_get(UX_DEVICE_CLASS_AUDIO *audio, ULONG st
VOID _ux_device_class_audio_write_thread_entry(ULONG audio_stream);
VOID _ux_device_class_audio_read_thread_entry(ULONG audio_stream);
-
+UINT _ux_device_class_audio_write_task_function(UX_DEVICE_CLASS_AUDIO_STREAM *stream);
+UINT _ux_device_class_audio_read_task_function(UX_DEVICE_CLASS_AUDIO_STREAM *stream);
UINT _ux_device_class_audio_reception_start(UX_DEVICE_CLASS_AUDIO_STREAM *audio);
UINT _ux_device_class_audio_sample_read8(UX_DEVICE_CLASS_AUDIO_STREAM *audio, UCHAR *sample);
UINT _ux_device_class_audio_sample_read16(UX_DEVICE_CLASS_AUDIO_STREAM *audio, USHORT *sample);
@@ -469,13 +505,18 @@ UINT _ux_device_class_audio_write_frame_get(UX_DEVICE_CLASS_AUDIO_STREAM *aud
UINT _ux_device_class_audio_write_frame_commit(UX_DEVICE_CLASS_AUDIO_STREAM *audio, ULONG length);
VOID _ux_device_class_audio_feedback_thread_entry(ULONG audio_stream);
+UINT _ux_device_class_audio_feedback_task_function(UX_DEVICE_CLASS_AUDIO_STREAM *stream);
UINT _ux_device_class_audio_feedback_set(UX_DEVICE_CLASS_AUDIO_STREAM *audio, UCHAR *encoded_feedback);
UINT _ux_device_class_audio_feedback_get(UX_DEVICE_CLASS_AUDIO_STREAM *audio, UCHAR *encoded_feedback);
ULONG _ux_device_class_audio_speed_get(UX_DEVICE_CLASS_AUDIO_STREAM *audio);
VOID _ux_device_class_audio_interrupt_thread_entry(ULONG audio_inst);
+UINT _ux_device_class_audio_interrupt_task_function(UX_DEVICE_CLASS_AUDIO *audio);
UINT _ux_device_class_audio_interrupt_send(UX_DEVICE_CLASS_AUDIO *audio, UCHAR *int_data);
+#if defined(UX_DEVICE_STANDALONE)
+UINT _ux_device_class_audio_tasks_run(VOID *instance);
+#endif
/* Define Device Class Audio API prototypes. */
@@ -484,6 +525,9 @@ UINT _ux_device_class_audio_interrupt_send(UX_DEVICE_CLASS_AUDIO *audio, UCHA
#define ux_device_class_audio_read_thread_entry _ux_device_class_audio_read_thread_entry
#define ux_device_class_audio_write_thread_entry _ux_device_class_audio_write_thread_entry
+#define ux_device_class_audio_read_task_function _ux_device_class_audio_read_task_function
+#define ux_device_class_audio_write_task_function _ux_device_class_audio_write_task_function
+
#define ux_device_class_audio_stream_get _ux_device_class_audio_stream_get
#define ux_device_class_audio_reception_start _ux_device_class_audio_reception_start
@@ -505,6 +549,7 @@ UINT _ux_device_class_audio_interrupt_send(UX_DEVICE_CLASS_AUDIO *audio, UCHA
#define ux_device_class_audio_speed_get _ux_device_class_audio_speed_get
#define ux_device_class_audio_feedback_thread_entry _ux_device_class_audio_feedback_thread_entry
+#define ux_device_class_audio_feedback_task_function _ux_device_class_audio_feedback_task_function
#define ux_device_class_audio_feedback_get _ux_device_class_audio_feedback_get
#define ux_device_class_audio_feedback_set _ux_device_class_audio_feedback_set
diff --git a/common/usbx_device_classes/inc/ux_device_class_cdc_ecm.h b/common/usbx_device_classes/inc/ux_device_class_cdc_ecm.h
index 3f662d8..54f3ac7 100644
--- a/common/usbx_device_classes/inc/ux_device_class_cdc_ecm.h
+++ b/common/usbx_device_classes/inc/ux_device_class_cdc_ecm.h
@@ -24,7 +24,7 @@
/* COMPONENT DEFINITION RELEASE */
/* */
/* ux_device_class_cdc_ecm.h PORTABLE C */
-/* 6.1.11 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -52,6 +52,9 @@
/* 04-25-2022 Chaoqiong Xiao Modified comment(s), */
/* fixed standalone compile, */
/* resulting in version 6.1.11 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* added wait definitions, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
@@ -274,6 +277,12 @@ VOID _ux_network_driver_link_down(VOID *ux_network_handle);
#define UX_DEVICE_CLASS_CDC_ECM_PACKET_POOL_WAIT 1000
#endif
+#ifndef UX_DEVICE_CLASS_CDC_ECM_PACKET_POOL_INST_WAIT
+#define UX_DEVICE_CLASS_CDC_ECM_PACKET_POOL_INST_WAIT 1000
+#endif
+
+#define UX_DEVICE_CLASS_CDC_ECM_LINK_CHECK_WAIT 10
+
/* Define Slave CDC_ECM Class Calling Parameter structure */
typedef struct UX_SLAVE_CLASS_CDC_ECM_PARAMETER_STRUCT
@@ -316,7 +325,6 @@ typedef struct UX_SLAVE_CLASS_CDC_ECM_STRUCT
UCHAR ux_slave_class_cdc_ecm_remote_node_id[UX_DEVICE_CLASS_CDC_ECM_NODE_ID_LENGTH];
ULONG ux_slave_class_cdc_ecm_nx_ip_address;
ULONG ux_slave_class_cdc_ecm_nx_ip_network_mask;
- UCHAR *ux_slave_class_cdc_ecm_pool_memory;
#if !defined(UX_DEVICE_STANDALONE)
NX_IP *ux_slave_class_cdc_ecm_nx_ip;
@@ -324,7 +332,7 @@ typedef struct UX_SLAVE_CLASS_CDC_ECM_STRUCT
NX_PACKET *ux_slave_class_cdc_ecm_xmit_queue;
NX_PACKET *ux_slave_class_cdc_ecm_xmit_queue_tail;
NX_PACKET *ux_slave_class_cdc_ecm_receive_queue;
- NX_PACKET_POOL ux_slave_class_cdc_ecm_packet_pool;
+ NX_PACKET_POOL *ux_slave_class_cdc_ecm_packet_pool;
#endif
#if !defined(UX_DEVICE_STANDALONE)
diff --git a/common/usbx_device_classes/inc/ux_device_class_printer.h b/common/usbx_device_classes/inc/ux_device_class_printer.h
index a77aff5..52ae8ce 100644
--- a/common/usbx_device_classes/inc/ux_device_class_printer.h
+++ b/common/usbx_device_classes/inc/ux_device_class_printer.h
@@ -24,7 +24,7 @@
/* COMPONENT DEFINITION RELEASE */
/* */
/* ux_device_class_printer.h PORTABLE C */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -44,6 +44,9 @@
/* resulting in version 6.1.11 */
/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Yajun xia Modified comment(s), */
+/* added standalone support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
@@ -92,6 +95,16 @@ extern "C" {
#define UX_DEVICE_CLASS_PRINTER_IOCTL_READ_TIMEOUT_SET 2
#define UX_DEVICE_CLASS_PRINTER_IOCTL_WRITE_TIMEOUT_SET 3
+#if defined(UX_DEVICE_STANDALONE)
+
+/* Printer read state machine states. */
+#define UX_DEVICE_CLASS_PRINTER_READ_START (UX_STATE_STEP + 1)
+#define UX_DEVICE_CLASS_PRINTER_READ_WAIT (UX_STATE_STEP + 2)
+
+/* Printer write state machine states. */
+#define UX_DEVICE_CLASS_PRINTER_WRITE_START (UX_STATE_STEP + 1)
+#define UX_DEVICE_CLASS_PRINTER_WRITE_WAIT (UX_STATE_STEP + 2)
+#endif
/* Define Device Printer Class Calling Parameter structure */
@@ -117,6 +130,21 @@ typedef struct UX_DEVICE_CLASS_PRINTER_STRUCT
#if !defined(UX_DEVICE_STANDALONE)
UX_MUTEX ux_device_class_printer_endpoint_out_mutex;
UX_MUTEX ux_device_class_printer_endpoint_in_mutex;
+#else
+ UCHAR *ux_device_class_printer_read_buffer;
+ ULONG ux_device_class_printer_read_requested_length;
+ ULONG ux_device_class_printer_read_transfer_length;
+ ULONG ux_device_class_printer_read_actual_length;
+ UINT ux_device_class_printer_read_status;
+ UINT ux_device_class_printer_read_state;
+
+ UCHAR *ux_device_class_printer_write_buffer;
+ ULONG ux_device_class_printer_write_transfer_length;
+ ULONG ux_device_class_printer_write_host_length;
+ ULONG ux_device_class_printer_write_requested_length;
+ ULONG ux_device_class_printer_write_actual_length;
+ UINT ux_device_class_printer_write_status;
+ UINT ux_device_class_printer_write_state;
#endif
} UX_DEVICE_CLASS_PRINTER;
@@ -139,7 +167,12 @@ UINT _ux_device_class_printer_read(UX_DEVICE_CLASS_PRINTER *printer, UCHAR *buf
UINT _ux_device_class_printer_ioctl(UX_DEVICE_CLASS_PRINTER *printer, ULONG ioctl_function,
VOID *parameter);
-
+#if defined(UX_DEVICE_STANDALONE)
+UINT _ux_device_class_printer_write_run(UX_DEVICE_CLASS_PRINTER *printer, UCHAR *buffer,
+ ULONG requested_length, ULONG *actual_length);
+UINT _ux_device_class_printer_read_run(UX_DEVICE_CLASS_PRINTER *printer, UCHAR *buffer,
+ ULONG requested_length, ULONG *actual_length);
+#endif
/* Define Device Printer Class API prototypes. */
@@ -148,6 +181,11 @@ UINT _ux_device_class_printer_ioctl(UX_DEVICE_CLASS_PRINTER *printer, ULONG ioc
#define ux_device_class_printer_write _ux_device_class_printer_write
#define ux_device_class_printer_ioctl _ux_device_class_printer_ioctl
+#if defined(UX_DEVICE_STANDALONE)
+#define ux_device_class_printer_read_run _ux_device_class_printer_read_run
+#define ux_device_class_printer_write_run _ux_device_class_printer_write_run
+#endif
+
/* Determine if a C++ compiler is being used. If so, complete the standard
C conditional started above. */
#ifdef __cplusplus
diff --git a/common/usbx_device_classes/inc/ux_device_class_rndis.h b/common/usbx_device_classes/inc/ux_device_class_rndis.h
index 7ac55d8..abcd833 100644
--- a/common/usbx_device_classes/inc/ux_device_class_rndis.h
+++ b/common/usbx_device_classes/inc/ux_device_class_rndis.h
@@ -24,7 +24,7 @@
/* COMPONENT DEFINITION RELEASE */
/* */
/* ux_device_class_rndis.h PORTABLE C */
-/* 6.1.11 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -52,6 +52,9 @@
/* 04-25-2022 Chaoqiong Xiao Modified comment(s), */
/* fixed standalone compile, */
/* resulting in version 6.1.11 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* added wait and length DEFs, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
@@ -478,6 +481,16 @@ VOID _ux_network_driver_link_down(VOID *ux_network_handle);
#define UX_DEVICE_CLASS_RNDIS_PACKET_POOL_WAIT 10
#endif
+#ifndef UX_DEVICE_CLASS_RNDIS_PACKET_POOL_INST_WAIT
+#define UX_DEVICE_CLASS_RNDIS_PACKET_POOL_INST_WAIT 100
+#endif
+
+/* Calculate message buffer length (not overflow). */
+#define UX_DEVICE_CLASS_RNDIS_MAX_MSG_LENGTH (UX_DEVICE_CLASS_RNDIS_MAX_PACKET_LENGTH + UX_DEVICE_CLASS_RNDIS_PACKET_HEADER_LENGTH)
+#if UX_DEVICE_CLASS_RNDIS_MAX_MSG_LENGTH > UX_SLAVE_REQUEST_DATA_MAX_LENGTH
+#error "Error: the maximum-sized RNDIS response cannot fit inside the control endpoint's data buffer. Increase UX_SLAVE_REQUEST_DATA_MAX_LENGTH."
+#endif
+
/* Calculate response buffer length. */
#define UX_DEVICE_CLASS_RNDIS_OID_SUPPORTED_RESPONSE_LENGTH (UX_DEVICE_CLASS_RNDIS_CMPLT_QUERY_INFO_BUFFER + UX_DEVICE_CLASS_RNDIS_OID_SUPPORTED_LIST_LENGTH * 4)
#define UX_DEVICE_CLASS_RNDIS_VENDOR_DESCRIPTION_MAX_RESPONSE_LENGTH (UX_DEVICE_CLASS_RNDIS_CMPLT_QUERY_INFO_BUFFER + UX_DEVICE_CLASS_RNDIS_VENDOR_DESCRIPTION_MAX_LENGTH)
@@ -544,7 +557,6 @@ typedef struct UX_SLAVE_CLASS_RNDIS_STRUCT
ULONG ux_slave_class_rndis_statistics_xmit_more_collisions;
UCHAR ux_slave_class_rndis_local_node_id[UX_DEVICE_CLASS_RNDIS_NODE_ID_LENGTH];
UCHAR ux_slave_class_rndis_remote_node_id[UX_DEVICE_CLASS_RNDIS_NODE_ID_LENGTH];
- UCHAR *ux_slave_class_rndis_pool_memory;
ULONG ux_slave_class_rndis_nx_ip_address;
ULONG ux_slave_class_rndis_nx_ip_network_mask;
@@ -553,7 +565,7 @@ typedef struct UX_SLAVE_CLASS_RNDIS_STRUCT
NX_INTERFACE *ux_slave_class_rndis_nx_interface;
NX_PACKET *ux_slave_class_rndis_xmit_queue;
NX_PACKET *ux_slave_class_rndis_receive_queue;
- NX_PACKET_POOL ux_slave_class_rndis_packet_pool;
+ NX_PACKET_POOL *ux_slave_class_rndis_packet_pool;
#endif
#if !defined(UX_DEVICE_STANDALONE)
diff --git a/common/usbx_device_classes/inc/ux_device_class_video.h b/common/usbx_device_classes/inc/ux_device_class_video.h
index 4c6d3e8..9851532 100644
--- a/common/usbx_device_classes/inc/ux_device_class_video.h
+++ b/common/usbx_device_classes/inc/ux_device_class_video.h
@@ -26,7 +26,7 @@
/* COMPONENT DEFINITION RELEASE */
/* */
/* ux_device_class_video.h PORTABLE C */
-/* 6.1.11 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -41,6 +41,9 @@
/* DATE NAME DESCRIPTION */
/* */
/* 04-25-2022 Chaoqiong Xiao Initial Version 6.1.11 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* added standalone support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
@@ -508,6 +511,12 @@ typedef struct UX_DEVICE_CLASS_VIDEO_PAYLOAD_HEADER_STRUCT
#define UX_DEVICE_CLASS_VIDEO_STREAM_ERROR_CODE_STILL_IMAGE_CAPTURE_ERROR 7
+/* Define Video Class Task states. */
+#define UX_DEVICE_CLASS_VIDEO_STREAM_RW_STOP (UX_STATE_RESET)
+#define UX_DEVICE_CLASS_VIDEO_STREAM_RW_START (UX_STATE_STEP + 1)
+#define UX_DEVICE_CLASS_VIDEO_STREAM_RW_WAIT (UX_STATE_STEP + 2)
+
+
/* Define Video Class callback structure. */
struct UX_DEVICE_CLASS_VIDEO_STREAM_STRUCT;
@@ -541,8 +550,12 @@ typedef struct UX_DEVICE_CLASS_VIDEO_PAYLOAD_STRUCT
typedef struct UX_DEVICE_CLASS_VIDEO_STREAM_PARAMETER_STRUCT
{
+#if defined(UX_DEVICE_STANDALONE)
+ UINT (*ux_device_class_video_stream_parameter_task_function)(struct UX_DEVICE_CLASS_VIDEO_STREAM_STRUCT*);
+#else
ULONG ux_device_class_video_stream_parameter_thread_stack_size;
VOID (*ux_device_class_video_stream_parameter_thread_entry)(ULONG id);
+#endif
UX_DEVICE_CLASS_VIDEO_STREAM_CALLBACKS ux_device_class_video_stream_parameter_callbacks;
ULONG ux_device_class_video_stream_parameter_max_payload_buffer_size;
@@ -572,8 +585,13 @@ typedef struct UX_DEVICE_CLASS_VIDEO_STREAM_STRUCT
#if !defined(UX_DEVICE_STANDALONE)
UCHAR *ux_device_class_video_stream_thread_stack;
UX_THREAD ux_device_class_video_stream_thread;
+#else
+ UINT (*ux_device_class_video_stream_task_function)(struct UX_DEVICE_CLASS_VIDEO_STREAM_STRUCT*);
+ UINT ux_device_class_video_stream_task_state;
+ UINT ux_device_class_video_stream_task_status;
#endif
+ ULONG ux_device_class_video_stream_buffer_error_count;
UCHAR *ux_device_class_video_stream_buffer;
ULONG ux_device_class_video_stream_buffer_size;
ULONG ux_device_class_video_stream_payload_buffer_size;
@@ -636,6 +654,9 @@ UINT _ux_device_class_video_transmission_start(UX_DEVICE_CLASS_VIDEO_STREAM *
UINT _ux_device_class_video_write_payload_get(UX_DEVICE_CLASS_VIDEO_STREAM *video, UCHAR **buffer, ULONG *max_length);
UINT _ux_device_class_video_write_payload_commit(UX_DEVICE_CLASS_VIDEO_STREAM *video, ULONG length);
+UINT _ux_device_class_video_tasks_run(VOID *instance);
+UINT _ux_device_class_video_read_task_function(UX_DEVICE_CLASS_VIDEO_STREAM *stream);
+UINT _ux_device_class_video_write_task_function(UX_DEVICE_CLASS_VIDEO_STREAM *stream);
/* Define Video Class API prototypes. */
@@ -663,6 +684,9 @@ UINT _ux_device_class_video_write_payload_commit(UX_DEVICE_CLASS_VIDEO_STREAM
#define ux_device_class_video_ioctl _ux_device_class_video_ioctl
+#define ux_device_class_video_read_task_function _ux_device_class_video_read_task_function
+#define ux_device_class_video_write_task_function _ux_device_class_video_write_task_function
+
/* Determine if a C++ compiler is being used. If so, complete the standard
C conditional started above. */
diff --git a/common/usbx_device_classes/src/ux_device_class_audio_activate.c b/common/usbx_device_classes/src/ux_device_class_audio_activate.c
index 53163cf..2f9b89d 100644
--- a/common/usbx_device_classes/src/ux_device_class_audio_activate.c
+++ b/common/usbx_device_classes/src/ux_device_class_audio_activate.c
@@ -33,7 +33,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_audio_activate PORTABLE C */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -70,6 +70,9 @@
/* names conflict C++ keyword, */
/* added interrupt support, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Yajun Xia Modified comment(s), */
+/* added standalone support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_device_class_audio_activate(UX_SLAVE_CLASS_COMMAND *command)
@@ -166,6 +169,12 @@ ULONG stream_index;
/* Store the class instance into the interface. */
stream_interface -> ux_slave_interface_class_instance = (VOID *)audio;
+#if defined(UX_DEVICE_STANDALONE)
+
+ /* Reset stream task state. */
+ stream -> ux_device_class_audio_stream_task_state = UX_STATE_RESET;
+ stream -> ux_device_class_audio_stream_task_state = UX_SUCCESS;
+#endif
}
/* If there is a activate function call it. */
diff --git a/common/usbx_device_classes/src/ux_device_class_audio_change.c b/common/usbx_device_classes/src/ux_device_class_audio_change.c
index 35d4a3a..9ac4e67 100644
--- a/common/usbx_device_classes/src/ux_device_class_audio_change.c
+++ b/common/usbx_device_classes/src/ux_device_class_audio_change.c
@@ -33,7 +33,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_audio_change PORTABLE C */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -81,6 +81,9 @@
/* rx full packet for */
/* feedback, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Yajun Xia Modified comment(s), */
+/* added standalone support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_device_class_audio_change(UX_SLAVE_CLASS_COMMAND *command)
@@ -137,8 +140,9 @@ ULONG endpoint_dir;
/* Parse all endpoints. */
#if defined(UX_DEVICE_STANDALONE)
- /* Standalone mode not supported. */
- endpoint_dir = 0;
+ endpoint_dir = (stream -> ux_device_class_audio_stream_task_function ==
+ _ux_device_class_audio_read_task_function) ?
+ UX_ENDPOINT_OUT: UX_ENDPOINT_IN;
#else
endpoint_dir = (stream -> ux_device_class_audio_stream_thread.tx_thread_entry ==
@@ -229,6 +233,15 @@ ULONG endpoint_dir;
return(UX_DESCRIPTOR_CORRUPTED);
}
+#if defined(UX_DEVICE_STANDALONE)
+
+ /* Reset background transfer state. */
+ stream -> ux_device_class_audio_stream_task_state = UX_STATE_RESET;
+#endif
+
+ /* Now reset payload buffer error count. */
+ stream -> ux_device_class_audio_stream_buffer_error_count = 0;
+
/* Now reset frame buffers. */
frame_buffer = stream -> ux_device_class_audio_stream_buffer;
while(frame_buffer < stream -> ux_device_class_audio_stream_buffer + stream -> ux_device_class_audio_stream_buffer_size)
@@ -243,7 +256,7 @@ ULONG endpoint_dir;
}
stream -> ux_device_class_audio_stream_transfer_pos = stream -> ux_device_class_audio_stream_access_pos;
-#if defined(UX_DEVICE_CLASS_AUDIO_FEEDBACK_SUPPORT)
+#if defined(UX_DEVICE_CLASS_AUDIO_FEEDBACK_SUPPORT) && !defined(UX_DEVICE_STANDALONE)
/* If feedback supported, resume the thread. */
if (stream -> ux_device_class_audio_stream_feedback_thread_stack)
diff --git a/common/usbx_device_classes/src/ux_device_class_audio_feedback_task_function.c b/common/usbx_device_classes/src/ux_device_class_audio_feedback_task_function.c
new file mode 100644
index 0000000..8bcf857
--- /dev/null
+++ b/common/usbx_device_classes/src/ux_device_class_audio_feedback_task_function.c
@@ -0,0 +1,164 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) Microsoft Corporation. All rights reserved. */
+/* */
+/* This software is licensed under the Microsoft Software License */
+/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+/* and in the root directory of this software. */
+/* */
+/**************************************************************************/
+
+/**************************************************************************/
+/**************************************************************************/
+/** */
+/** USBX Component */
+/** */
+/** Device Audio Class */
+/** */
+/**************************************************************************/
+/**************************************************************************/
+
+#define UX_SOURCE_CODE
+
+
+/* Include necessary system files. */
+
+#include "ux_api.h"
+#include "ux_device_class_audio.h"
+#include "ux_device_stack.h"
+
+
+#if defined(UX_DEVICE_CLASS_AUDIO_FEEDBACK_SUPPORT) && defined(UX_DEVICE_STANDALONE)
+/**************************************************************************/
+/* */
+/* FUNCTION RELEASE */
+/* */
+/* _ux_device_class_audio_feedback_task_function PORTABLE C */
+/* 6.2.0 */
+/* AUTHOR */
+/* */
+/* Yajun Xia, Microsoft Corporation */
+/* */
+/* DESCRIPTION */
+/* */
+/* This function is background task of ISO OUT/IN (feedback of IN/OUT) */
+/* for the Audio class. */
+/* */
+/* It's for standalone mode. */
+/* */
+/* INPUT */
+/* */
+/* stream Pointer to audio stream */
+/* */
+/* OUTPUT */
+/* */
+/* State machine status */
+/* UX_STATE_EXIT Device not configured */
+/* UX_STATE_IDLE No feedback transfer running */
+/* UX_STATE_WAIT Feedback transfer running */
+/* */
+/* CALLS */
+/* */
+/* _ux_system_error_handler System error trap */
+/* _ux_device_stack_transfer_run Run transfer state machine */
+/* */
+/* CALLED BY */
+/* */
+/* Audio Class (task) */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 10-31-2022 Yajun Xia Initial Version 6.2.0 */
+/* */
+/**************************************************************************/
+UINT _ux_device_class_audio_feedback_task_function(UX_DEVICE_CLASS_AUDIO_STREAM *stream)
+{
+
+UINT status;
+UX_SLAVE_DEVICE *device;
+UX_SLAVE_ENDPOINT *endpoint;
+UX_SLAVE_TRANSFER *transfer;
+ULONG transfer_length;
+
+
+ /* Get stack device instance. */
+ device = stream -> ux_device_class_audio_stream_audio -> ux_device_class_audio_device;
+
+ /* Check if the device is configured. */
+ if (device -> ux_slave_device_state != UX_DEVICE_CONFIGURED)
+ {
+
+ /* Error trap. */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_CONFIGURATION_HANDLE_UNKNOWN);
+
+ stream -> ux_device_class_audio_stream_feedback_task_state = UX_STATE_EXIT;
+ return(UX_STATE_EXIT);
+ }
+
+ /* Get endpoint instance. */
+ endpoint = stream -> ux_device_class_audio_stream_feedback;
+
+ /* Endpoint not available, maybe it's alternate setting 0. */
+ if (endpoint == UX_NULL)
+ {
+
+ /* Error trap. */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_ENDPOINT_HANDLE_UNKNOWN);
+
+ stream -> ux_device_class_audio_stream_feedback_task_state = UX_STATE_RESET;
+ return(UX_STATE_IDLE);
+ }
+
+ /* Get transfer instance. */
+ transfer = &endpoint -> ux_slave_endpoint_transfer_request;
+
+ /* Length is pre-set on interface alternate setting activate. */
+ transfer_length = transfer -> ux_slave_transfer_request_requested_length;
+
+ switch (stream -> ux_device_class_audio_stream_feedback_task_state)
+ {
+ case UX_STATE_RESET:
+ stream -> ux_device_class_audio_stream_feedback_task_state = UX_DEVICE_CLASS_AUDIO_STREAM_FEEDBACK_RW_WAIT;
+ stream -> ux_device_class_audio_stream_feedback_task_status = UX_TRANSFER_NO_ANSWER;
+
+ /* Fall through. */
+ case UX_DEVICE_CLASS_AUDIO_STREAM_FEEDBACK_RW_WAIT:
+
+ /* Issue transfer request. */
+ status = _ux_device_stack_transfer_run(transfer, transfer_length, transfer_length);
+
+ /* Any error or success case. */
+ if (status < UX_STATE_NEXT)
+ {
+
+ /* Error notification! */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_TRANSFER_ERROR);
+
+ stream -> ux_device_class_audio_stream_feedback_task_state = UX_STATE_RESET;
+ stream -> ux_device_class_audio_stream_feedback_task_status = transfer -> ux_slave_transfer_request_completion_code;
+ return(UX_STATE_EXIT);
+ }
+
+ /* Success case. */
+ if (status == UX_STATE_NEXT)
+ {
+ stream -> ux_device_class_audio_stream_feedback_task_state = UX_DEVICE_CLASS_AUDIO_STREAM_FEEDBACK_RW_WAIT;
+ stream -> ux_device_class_audio_stream_feedback_task_status = transfer -> ux_slave_transfer_request_completion_code;
+ }
+
+ /* Keep waiting. */
+ return(UX_STATE_WAIT);
+
+ default:
+ stream -> ux_device_class_audio_stream_feedback_task_state = UX_STATE_RESET;
+ stream -> ux_device_class_audio_stream_feedback_task_status = UX_INVALID_STATE;
+ break;
+ }
+
+ /* Error case. */
+ return(UX_STATE_EXIT);
+}
+#endif
diff --git a/common/usbx_device_classes/src/ux_device_class_audio_feedback_thread_entry.c b/common/usbx_device_classes/src/ux_device_class_audio_feedback_thread_entry.c
index 88525f1..f71c0bd 100644
--- a/common/usbx_device_classes/src/ux_device_class_audio_feedback_thread_entry.c
+++ b/common/usbx_device_classes/src/ux_device_class_audio_feedback_thread_entry.c
@@ -35,7 +35,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_audio_feedback_thread_entry PORTABLE C */
-/* 6.1.10 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -70,11 +70,17 @@
/* DATE NAME DESCRIPTION */
/* */
/* 01-31-2022 Chaoqiong Xiao Initial Version 6.1.10 */
+/* 10-31-2022 Yajun Xia Modified comment(s), */
+/* added standalone support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
VOID _ux_device_class_audio_feedback_thread_entry(ULONG audio_stream)
{
-
+#if defined(UX_DEVICE_STANDALONE)
+ UX_PARAMETER_NOT_USED(audio_stream);
+ return;
+#else
UINT status;
UX_DEVICE_CLASS_AUDIO_STREAM *stream;
UX_SLAVE_DEVICE *device;
@@ -128,5 +134,6 @@ ULONG transfer_length;
/* We need to suspend ourselves. We will be resumed by the device enumeration module or when a change of alternate setting happens. */
_ux_utility_thread_suspend(&stream -> ux_device_class_audio_stream_feedback_thread);
}
+#endif
}
#endif
diff --git a/common/usbx_device_classes/src/ux_device_class_audio_initialize.c b/common/usbx_device_classes/src/ux_device_class_audio_initialize.c
index 4887494..4ba297a 100644
--- a/common/usbx_device_classes/src/ux_device_class_audio_initialize.c
+++ b/common/usbx_device_classes/src/ux_device_class_audio_initialize.c
@@ -33,7 +33,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_audio_initialize PORTABLE C */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -84,14 +84,13 @@
/* added interrupt support, */
/* refined internal logic, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Yajun Xia Modified comment(s), */
+/* added standalone support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_device_class_audio_initialize(UX_SLAVE_CLASS_COMMAND *command)
{
-#if defined(UX_DEVICE_STANDALONE)
- UX_PARAMETER_NOT_USED(command);
- return(UX_FUNCTION_NOT_SUPPORTED);
-#else
UINT status = UX_SUCCESS;
UX_DEVICE_CLASS_AUDIO *audio;
@@ -153,8 +152,7 @@ ULONG i;
audio_parameter -> ux_device_class_audio_parameter_status_size;
audio -> ux_device_class_audio_status_queue_bytes = memory_size;
-#if defined(UX_DEVICE_STANDALONE)
-#else
+#if !defined(UX_DEVICE_STANDALONE)
if (UX_OVERFLOW_CHECK_ADD_ULONG(memory_size, UX_DEVICE_CLASS_AUDIO_INTERRUPT_THREAD_STACK_SIZE))
{
_ux_utility_memory_free(audio);
@@ -217,6 +215,15 @@ ULONG i;
audio -> ux_device_class_audio_status_queue =
(UCHAR *)audio_class -> ux_slave_class_thread_stack +
UX_DEVICE_CLASS_AUDIO_INTERRUPT_THREAD_STACK_SIZE;
+#else
+ audio -> ux_device_class_audio_status_queue = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, memory_size);
+
+ /* Check for successful allocation. */
+ if (audio -> ux_device_class_audio_status_queue == UX_NULL)
+ {
+ _ux_utility_memory_free(audio);
+ return(UX_MEMORY_INSUFFICIENT);
+ }
#endif
#endif
@@ -268,6 +275,8 @@ ULONG i;
stream -> ux_device_class_audio_stream_transfer_pos = (UX_DEVICE_CLASS_AUDIO_FRAME *)stream -> ux_device_class_audio_stream_buffer;
stream -> ux_device_class_audio_stream_access_pos = stream -> ux_device_class_audio_stream_transfer_pos;
+#if !defined(UX_DEVICE_STANDALONE)
+
/* Create memory block for streaming thread stack in addition. */
if (stream_parameter -> ux_device_class_audio_stream_parameter_thread_stack_size == 0)
memory_size = UX_DEVICE_CLASS_AUDIO_FEEDBACK_THREAD_STACK_SIZE;
@@ -298,13 +307,19 @@ ULONG i;
}
UX_THREAD_EXTENSION_PTR_SET(&(stream -> ux_device_class_audio_stream_thread), stream)
+#else
+
+ /* Save task function for streaming. */
+ stream -> ux_device_class_audio_stream_task_function = stream_parameter -> ux_device_class_audio_stream_parameter_task_function;
+#endif
#if defined(UX_DEVICE_CLASS_AUDIO_FEEDBACK_SUPPORT)
+#if !defined(UX_DEVICE_STANDALONE)
+
/* Check entry to confirm feedback is supported. */
if (stream_parameter -> ux_device_class_audio_stream_parameter_feedback_thread_entry)
{
-
/* Create memory block for streaming thread stack in addition. */
if (stream_parameter -> ux_device_class_audio_stream_parameter_feedback_thread_stack_size == 0)
memory_size = UX_THREAD_STACK_SIZE;
@@ -336,6 +351,14 @@ ULONG i;
UX_THREAD_EXTENSION_PTR_SET(&(stream -> ux_device_class_audio_stream_feedback_thread), stream)
}
+#else
+ if (stream_parameter -> ux_device_class_audio_stream_parameter_feedback_task_function)
+ {
+
+ /* Save task function for streaming. */
+ stream -> ux_device_class_audio_stream_feedback_task_function = stream_parameter -> ux_device_class_audio_stream_parameter_feedback_task_function;
+ }
+#endif
#endif
/* Save callbacks. */
@@ -365,6 +388,12 @@ ULONG i;
&audio_parameter -> ux_device_class_audio_parameter_callbacks,
sizeof(UX_DEVICE_CLASS_AUDIO_CALLBACKS)); /* Use case of memcpy is verified. */
+#if defined(UX_DEVICE_STANDALONE)
+
+ /* Link task function. */
+ audio_class -> ux_slave_class_task_function = _ux_device_class_audio_tasks_run;
+#endif
+
/* Return completion status. */
return(UX_SUCCESS);
}
@@ -377,24 +406,27 @@ ULONG i;
for (i = 0; i < audio -> ux_device_class_audio_streams_nb; i ++)
{
#if defined(UX_DEVICE_CLASS_AUDIO_FEEDBACK_SUPPORT)
+#if !defined(UX_DEVICE_STANDALONE)
if (stream -> ux_device_class_audio_stream_feedback_thread_stack)
{
_ux_device_thread_delete(&stream -> ux_device_class_audio_stream_feedback_thread);
_ux_utility_memory_free(stream -> ux_device_class_audio_stream_feedback_thread_stack);
}
#endif
+#endif
+#if !defined(UX_DEVICE_STANDALONE)
if (stream -> ux_device_class_audio_stream_thread_stack)
{
_ux_device_thread_delete(&stream -> ux_device_class_audio_stream_thread);
_ux_utility_memory_free(stream -> ux_device_class_audio_stream_thread_stack);
}
+#endif
if (stream -> ux_device_class_audio_stream_buffer)
_ux_utility_memory_free(stream -> ux_device_class_audio_stream_buffer);
stream ++;
}
#if defined(UX_DEVICE_CLASS_AUDIO_INTERRUPT_SUPPORT)
-#if defined(UX_DEVICE_STANDALONE)
-#else
+#if !defined(UX_DEVICE_STANDALONE)
if (audio_class -> ux_slave_class_thread_stack)
{
_ux_device_thread_delete(&audio_class -> ux_slave_class_thread);
@@ -403,10 +435,14 @@ ULONG i;
_ux_device_semaphore_delete(&audio -> ux_device_class_audio_status_semaphore);
_ux_device_mutex_delete(&audio -> ux_device_class_audio_status_mutex);
}
+#else
+ if (audio -> ux_device_class_audio_status_queue)
+ {
+ _ux_utility_memory_free(audio -> ux_device_class_audio_status_queue);
+ }
#endif
#endif
_ux_utility_memory_free(audio);
return(status);
-#endif
}
diff --git a/common/usbx_device_classes/src/ux_device_class_audio_interrupt_send.c b/common/usbx_device_classes/src/ux_device_class_audio_interrupt_send.c
index 72c51fb..eb5d438 100644
--- a/common/usbx_device_classes/src/ux_device_class_audio_interrupt_send.c
+++ b/common/usbx_device_classes/src/ux_device_class_audio_interrupt_send.c
@@ -34,7 +34,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_audio_interrupt_send PORTABLE C */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -68,6 +68,9 @@
/* DATE NAME DESCRIPTION */
/* */
/* 07-29-2022 Chaoqiong Xiao Initial Version 6.1.12 */
+/* 10-31-2022 Yajun Xia Modified comment(s), */
+/* added standalone support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_device_class_audio_interrupt_send(UX_DEVICE_CLASS_AUDIO *audio, UCHAR *int_data)
@@ -77,11 +80,6 @@ UINT _ux_device_class_audio_interrupt_send(UX_DEVICE_CLASS_AUDIO *audio, UCHA
UX_PARAMETER_NOT_USED(int_data);
return(UX_FUNCTION_NOT_SUPPORTED);
#else
-#if defined(UX_DEVICE_STANDALONE)
- UX_PARAMETER_NOT_USED(audio);
- UX_PARAMETER_NOT_USED(int_data);
- return(UX_FUNCTION_NOT_SUPPORTED);
-#else
UX_SLAVE_DEVICE *device;
UX_SLAVE_ENDPOINT *endpoint;
@@ -169,5 +167,4 @@ ULONG i;
/* Return success. */
return(UX_SUCCESS);
#endif
-#endif
}
diff --git a/common/usbx_device_classes/src/ux_device_class_audio_interrupt_task_function.c b/common/usbx_device_classes/src/ux_device_class_audio_interrupt_task_function.c
new file mode 100644
index 0000000..eeac5c2
--- /dev/null
+++ b/common/usbx_device_classes/src/ux_device_class_audio_interrupt_task_function.c
@@ -0,0 +1,198 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) Microsoft Corporation. All rights reserved. */
+/* */
+/* This software is licensed under the Microsoft Software License */
+/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+/* and in the root directory of this software. */
+/* */
+/**************************************************************************/
+
+/**************************************************************************/
+/**************************************************************************/
+/** */
+/** USBX Component */
+/** */
+/** Device Audio Class */
+/** */
+/**************************************************************************/
+/**************************************************************************/
+
+#define UX_SOURCE_CODE
+
+
+/* Include necessary system files. */
+
+#include "ux_api.h"
+#include "ux_device_class_audio.h"
+#include "ux_device_stack.h"
+
+#if defined(UX_DEVICE_STANDALONE) && defined(UX_DEVICE_CLASS_AUDIO_INTERRUPT_SUPPORT)
+/**************************************************************************/
+/* */
+/* FUNCTION RELEASE */
+/* */
+/* _ux_device_class_audio_interrupt_task_function PORTABLE C */
+/* 6.2.0 */
+/* AUTHOR */
+/* */
+/* Yajun Xia, Microsoft Corporation */
+/* */
+/* DESCRIPTION */
+/* */
+/* This function is task of INTERRUPT IN from the Audio class. */
+/* */
+/* It's for standalone mode. */
+/* */
+/* INPUT */
+/* */
+/* audio Address of audio instance */
+/* */
+/* OUTPUT */
+/* */
+/* State machine Status to check */
+/* UX_STATE_EXIT Abnormal, to reset state */
+/* UX_STATE_IDLE No interrupt transfer running */
+/* UX_STATE_WAIT Keep running, waiting */
+/* */
+/* CALLS */
+/* */
+/* _ux_system_error_handler System error trap */
+/* _ux_utility_memory_copy Copy memory */
+/* _ux_device_stack_transfer_run Run Transfer state machine */
+/* */
+/* CALLED BY */
+/* */
+/* Audio Class (task) */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 10-31-2022 Yajun Xia Initial Version 6.2.0 */
+/* */
+/**************************************************************************/
+UINT _ux_device_class_audio_interrupt_task_function(UX_DEVICE_CLASS_AUDIO *audio)
+{
+
+UINT status;
+UX_SLAVE_DEVICE *device;
+UX_SLAVE_ENDPOINT *endpoint;
+UX_SLAVE_TRANSFER *transfer;
+UCHAR *buff;
+
+
+ /* Get stack device instance. */
+ device = audio -> ux_device_class_audio_device;
+
+ /* Check if the device is configured. */
+ if (device -> ux_slave_device_state != UX_DEVICE_CONFIGURED)
+ {
+
+ /* Error trap. */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_CONFIGURATION_HANDLE_UNKNOWN);
+
+ audio -> ux_device_class_audio_interrupt_task_state = UX_STATE_EXIT;
+ return(UX_STATE_EXIT);
+ }
+
+ /* Get endpoint instance. */
+ endpoint = audio -> ux_device_class_audio_interrupt;
+
+ /* Endpoint not available, maybe it's alternate setting 0. */
+ if (endpoint == UX_NULL)
+ {
+
+ /* Error trap. */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_ENDPOINT_HANDLE_UNKNOWN);
+
+ audio -> ux_device_class_audio_interrupt_task_state = UX_STATE_RESET;
+ return(UX_STATE_IDLE);
+ }
+
+ /* No packet in queue */
+ if (audio -> ux_device_class_audio_status_queued == 0)
+ {
+ audio -> ux_device_class_audio_interrupt_task_state = UX_STATE_RESET;
+ audio -> ux_device_class_audio_interrupt_task_status = UX_TRANSFER_NOT_READY;
+ return(UX_STATE_EXIT);
+ }
+
+ /* Get transfer instance. */
+ transfer = &endpoint -> ux_slave_endpoint_transfer_request;
+
+ /* Handle state cases. */
+ switch(audio -> ux_device_class_audio_interrupt_task_state)
+ {
+ case UX_STATE_RESET:
+ audio -> ux_device_class_audio_interrupt_task_state = UX_DEVICE_CLASS_AUDIO_INTERRUPT_START;
+ audio -> ux_device_class_audio_interrupt_task_status = UX_TRANSFER_NO_ANSWER;
+
+ /* Fall through. */
+ case UX_DEVICE_CLASS_AUDIO_INTERRUPT_START:
+ if (audio -> ux_device_class_audio_status_size > transfer -> ux_slave_transfer_request_transfer_length)
+ {
+
+ /* Error trap. */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_TRANSFER_ERROR);
+
+ audio -> ux_device_class_audio_interrupt_task_state = UX_STATE_RESET;
+ audio -> ux_device_class_audio_interrupt_task_status = UX_ERROR;
+ return(UX_STATE_EXIT);
+ }
+
+ _ux_utility_memory_copy(transfer -> ux_slave_transfer_request_data_pointer,
+ audio -> ux_device_class_audio_status_tail, audio -> ux_device_class_audio_status_size); /* Use case of memcpy is verified. */
+
+ audio -> ux_device_class_audio_interrupt_task_state = UX_DEVICE_CLASS_AUDIO_INTERRUPT_WAIT;
+
+ /* Fall through. */
+ case UX_DEVICE_CLASS_AUDIO_INTERRUPT_WAIT:
+
+ /* Start frame transfer anyway. */
+ status = _ux_device_stack_transfer_run(transfer, audio -> ux_device_class_audio_status_size,
+ audio -> ux_device_class_audio_status_size);
+
+ /* Any error or success case. */
+ if (status < UX_STATE_NEXT)
+ {
+
+ /* Error notification! */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_TRANSFER_ERROR);
+
+ audio -> ux_device_class_audio_interrupt_task_state = UX_STATE_RESET;
+ audio -> ux_device_class_audio_interrupt_task_status =
+ transfer -> ux_slave_transfer_request_completion_code;
+ return(UX_STATE_EXIT);
+ }
+
+ /* Success case. */
+ if (status == UX_STATE_NEXT)
+ {
+ buff = audio -> ux_device_class_audio_status_tail;
+ buff += audio -> ux_device_class_audio_status_size;
+
+ if (buff >= (audio -> ux_device_class_audio_status_queue + audio -> ux_device_class_audio_status_queue_bytes))
+ buff = audio -> ux_device_class_audio_status_queue;
+
+ audio -> ux_device_class_audio_status_tail = buff;
+ audio -> ux_device_class_audio_status_queued -= audio -> ux_device_class_audio_status_size;
+ audio -> ux_device_class_audio_interrupt_task_state = UX_DEVICE_CLASS_AUDIO_INTERRUPT_START;
+ audio -> ux_device_class_audio_interrupt_task_status =
+ transfer -> ux_slave_transfer_request_completion_code;
+ }
+
+ /* Keep waiting. */
+ return(UX_STATE_WAIT);
+
+ default: /* Error. */
+ audio -> ux_device_class_audio_interrupt_task_state = UX_STATE_RESET;
+ audio -> ux_device_class_audio_interrupt_task_status = UX_INVALID_STATE;
+ break;
+ }
+
+ /* Error case. */
+ return(UX_STATE_EXIT);
+}
+#endif
diff --git a/common/usbx_device_classes/src/ux_device_class_audio_read_task_function.c b/common/usbx_device_classes/src/ux_device_class_audio_read_task_function.c
new file mode 100644
index 0000000..03d43d8
--- /dev/null
+++ b/common/usbx_device_classes/src/ux_device_class_audio_read_task_function.c
@@ -0,0 +1,188 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) Microsoft Corporation. All rights reserved. */
+/* */
+/* This software is licensed under the Microsoft Software License */
+/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+/* and in the root directory of this software. */
+/* */
+/**************************************************************************/
+
+/**************************************************************************/
+/**************************************************************************/
+/** */
+/** USBX Component */
+/** */
+/** Device Audio Class */
+/** */
+/**************************************************************************/
+/**************************************************************************/
+
+#define UX_SOURCE_CODE
+
+
+/* Include necessary system files. */
+
+#include "ux_api.h"
+#include "ux_device_class_audio.h"
+#include "ux_device_stack.h"
+
+
+#if defined(UX_DEVICE_STANDALONE)
+/**************************************************************************/
+/* */
+/* FUNCTION RELEASE */
+/* */
+/* _ux_device_class_audio_read_task_function PORTABLE C */
+/* 6.2.0 */
+/* AUTHOR */
+/* */
+/* Yajun Xia, Microsoft Corporation */
+/* */
+/* DESCRIPTION */
+/* */
+/* This function is the background task of the audio stream read. */
+/* */
+/* It's for standalone mode. */
+/* */
+/* INPUT */
+/* */
+/* stream Pointer to audio stream */
+/* */
+/* OUTPUT */
+/* */
+/* State machine status */
+/* UX_STATE_EXIT Device not configured */
+/* UX_STATE_IDLE No streaming transfer running */
+/* UX_STATE_WAIT Streaming transfer running */
+/* */
+/* CALLS */
+/* */
+/* _ux_device_stack_transfer_run Run transfer state machine */
+/* _ux_utility_memory_copy Copy memory */
+/* */
+/* CALLED BY */
+/* */
+/* USBX Device Stack */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 10-31-2022 Yajun Xia Initial Version 6.2.0 */
+/* */
+/**************************************************************************/
+UINT _ux_device_class_audio_read_task_function(UX_DEVICE_CLASS_AUDIO_STREAM *stream)
+{
+UX_SLAVE_DEVICE *device;
+UX_SLAVE_ENDPOINT *endpoint;
+UX_SLAVE_TRANSFER *transfer;
+UCHAR *next_pos;
+UX_DEVICE_CLASS_AUDIO_FRAME *next_frame;
+ULONG max_packet_size;
+ULONG actual_length;
+UINT status;
+
+
+ /* Get the pointer to the device. */
+ device = stream -> ux_device_class_audio_stream_audio -> ux_device_class_audio_device;
+
+ /* Check if the device is configured. */
+ if (device -> ux_slave_device_state != UX_DEVICE_CONFIGURED)
+ {
+ stream -> ux_device_class_audio_stream_task_state = UX_STATE_EXIT;
+ return(UX_STATE_EXIT);
+ }
+
+ /* Get the endpoint. */
+ endpoint = stream -> ux_device_class_audio_stream_endpoint;
+
+ /* No endpoint ready, maybe it's alternate setting 0. */
+ if (endpoint == UX_NULL)
+ return(UX_STATE_IDLE);
+
+ /* Check if background transfer task is started. */
+ if (stream -> ux_device_class_audio_stream_task_state == UX_DEVICE_CLASS_AUDIO_STREAM_RW_STOP)
+ return(UX_STATE_IDLE);
+
+ /* Get transfer instance. */
+ transfer = &endpoint -> ux_slave_endpoint_transfer_request;
+
+ /* If not started yet, reset transfer and start polling. */
+ if (stream -> ux_device_class_audio_stream_task_state == UX_DEVICE_CLASS_AUDIO_STREAM_RW_START)
+ {
+
+ /* Next state: transfer wait. */
+ stream -> ux_device_class_audio_stream_task_state = UX_DEVICE_CLASS_AUDIO_STREAM_RW_WAIT;
+
+ /* Reset transfer state. */
+ UX_SLAVE_TRANSFER_STATE_RESET(transfer);
+ }
+
+ /* Run transfer state machine. */
+ max_packet_size = endpoint -> ux_slave_endpoint_transfer_request.ux_slave_transfer_request_transfer_length;
+ status = _ux_device_stack_transfer_run(transfer, max_packet_size, max_packet_size);
+
+ /* Error case. */
+ if (status < UX_STATE_NEXT)
+ {
+
+ /* Error on background transfer task start. */
+ stream -> ux_device_class_audio_stream_task_state = UX_STATE_RESET;
+ stream -> ux_device_class_audio_stream_task_status =
+ transfer -> ux_slave_transfer_request_completion_code;
+
+ /* Error notification! */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_TRANSFER_ERROR);
+ return(UX_STATE_EXIT);
+ }
+
+ /* Success case. */
+ if (status == UX_STATE_NEXT)
+ {
+
+ /* Next state: start. */
+ stream -> ux_device_class_audio_stream_task_state = UX_DEVICE_CLASS_AUDIO_STREAM_RW_START;
+ stream -> ux_device_class_audio_stream_task_status =
+ transfer -> ux_slave_transfer_request_completion_code;
+
+ /* Get actual transfer length. */
+ actual_length = transfer -> ux_slave_transfer_request_actual_length;
+
+ /* Frame received, log it. */
+ stream -> ux_device_class_audio_stream_transfer_pos -> ux_device_class_audio_frame_length = actual_length;
+ stream -> ux_device_class_audio_stream_transfer_pos -> ux_device_class_audio_frame_pos = 0;
+ _ux_utility_memory_copy(stream -> ux_device_class_audio_stream_transfer_pos -> ux_device_class_audio_frame_data,
+ transfer -> ux_slave_transfer_request_data_pointer,
+ actual_length); /* Use case of memcpy is verified. */
+
+ /* For simple, do not advance the transfer position if there is overflow. */
+ next_pos = (UCHAR *)stream -> ux_device_class_audio_stream_transfer_pos;
+ next_pos += stream -> ux_device_class_audio_stream_frame_buffer_size;
+ if (next_pos >= stream -> ux_device_class_audio_stream_buffer + stream -> ux_device_class_audio_stream_buffer_size)
+ next_pos = stream -> ux_device_class_audio_stream_buffer;
+ next_frame = (UX_DEVICE_CLASS_AUDIO_FRAME *)next_pos;
+
+ /* Check overflow! */
+ if (next_frame -> ux_device_class_audio_frame_length > 0)
+ {
+
+ /* Error notification! */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_BUFFER_OVERFLOW);
+ stream -> ux_device_class_audio_stream_buffer_error_count ++;
+ }
+ else
+
+ /* Update transfer position. */
+ stream -> ux_device_class_audio_stream_transfer_pos = next_frame;
+
+ /* Invoke notification callback. */
+ if (stream -> ux_device_class_audio_stream_callbacks.ux_device_class_audio_stream_frame_done != UX_NULL)
+ stream -> ux_device_class_audio_stream_callbacks.ux_device_class_audio_stream_frame_done(stream, actual_length);
+ }
+
+ /* Keep waiting. */
+ return(UX_STATE_WAIT);
+}
+#endif
diff --git a/common/usbx_device_classes/src/ux_device_class_audio_read_thread_entry.c b/common/usbx_device_classes/src/ux_device_class_audio_read_thread_entry.c
index 6046051..8af97f0 100644
--- a/common/usbx_device_classes/src/ux_device_class_audio_read_thread_entry.c
+++ b/common/usbx_device_classes/src/ux_device_class_audio_read_thread_entry.c
@@ -34,7 +34,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_audio_read_thread_entry PORTABLE C */
-/* 6.1.10 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -81,6 +81,9 @@
/* 01-31-2022 Chaoqiong Xiao Modified comment(s), */
/* refined macros names, */
/* resulting in version 6.1.10 */
+/* 10-31-2022 Yajun Xia Modified comment(s), */
+/* added standalone support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
VOID _ux_device_class_audio_read_thread_entry(ULONG audio_stream)
@@ -133,6 +136,7 @@ ULONG actual_length;
/* Error notification! */
_ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_TRANSFER_ERROR);
+ stream -> ux_device_class_audio_stream_buffer_error_count ++;
break;
}
@@ -159,6 +163,7 @@ ULONG actual_length;
/* Error notification! */
_ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_BUFFER_OVERFLOW);
+ stream -> ux_device_class_audio_stream_buffer_error_count ++;
}
else
diff --git a/common/usbx_device_classes/src/ux_device_class_audio_reception_start.c b/common/usbx_device_classes/src/ux_device_class_audio_reception_start.c
index 120eb1e..078ce81 100644
--- a/common/usbx_device_classes/src/ux_device_class_audio_reception_start.c
+++ b/common/usbx_device_classes/src/ux_device_class_audio_reception_start.c
@@ -34,7 +34,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_audio_reception_start PORTABLE C */
-/* 6.1.10 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -70,6 +70,9 @@
/* 01-31-2022 Chaoqiong Xiao Modified comment(s), */
/* refined macros names, */
/* resulting in version 6.1.10 */
+/* 10-31-2022 Yajun Xia Modified comment(s), */
+/* added standalone support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_device_class_audio_reception_start(UX_DEVICE_CLASS_AUDIO_STREAM *stream)
@@ -103,7 +106,15 @@ UX_SLAVE_DEVICE *device;
if (stream -> ux_device_class_audio_stream_transfer_pos -> ux_device_class_audio_frame_length > 0)
return(UX_BUFFER_OVERFLOW);
+#if defined(UX_DEVICE_STANDALONE)
+
+ /* Start read task. */
+ if (stream -> ux_device_class_audio_stream_task_state == UX_DEVICE_CLASS_AUDIO_STREAM_RW_STOP)
+ stream -> ux_device_class_audio_stream_task_state = UX_DEVICE_CLASS_AUDIO_STREAM_RW_START;
+#else
+
/* Start read thread. */
_ux_device_thread_resume(&stream -> ux_device_class_audio_stream_thread);
+#endif
return(UX_SUCCESS);
}
diff --git a/common/usbx_device_classes/src/ux_device_class_audio_tasks_run.c b/common/usbx_device_classes/src/ux_device_class_audio_tasks_run.c
new file mode 100644
index 0000000..2518ef2
--- /dev/null
+++ b/common/usbx_device_classes/src/ux_device_class_audio_tasks_run.c
@@ -0,0 +1,153 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) Microsoft Corporation. All rights reserved. */
+/* */
+/* This software is licensed under the Microsoft Software License */
+/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+/* and in the root directory of this software. */
+/* */
+/**************************************************************************/
+
+/**************************************************************************/
+/**************************************************************************/
+/** */
+/** USBX Component */
+/** */
+/** Device Audio Class */
+/** */
+/**************************************************************************/
+/**************************************************************************/
+
+#define UX_SOURCE_CODE
+
+
+/* Include necessary system files. */
+
+#include "ux_api.h"
+#include "ux_device_class_audio.h"
+#include "ux_device_stack.h"
+
+
+#if defined(UX_DEVICE_STANDALONE)
+/**************************************************************************/
+/* */
+/* FUNCTION RELEASE */
+/* */
+/* _ux_device_class_audio_tasks_run PORTABLE C */
+/* 6.2.0 */
+/* AUTHOR */
+/* */
+/* Yajun Xia, Microsoft Corporation */
+/* */
+/* DESCRIPTION */
+/* */
+/* This function is the background task of the audio. */
+/* */
+/* It's for standalone mode. */
+/* */
+/* INPUT */
+/* */
+/* instance Pointer to audio class */
+/* */
+/* OUTPUT */
+/* */
+/* State machine status */
+/* UX_STATE_EXIT Device not configured */
+/* UX_STATE_IDLE No streaming transfer running */
+/* UX_STATE_WAIT Streaming transfer running */
+/* */
+/* CALLS */
+/* */
+/* (ux_device_class_audio_stream_task_function) */
+/* Run stream task */
+/* (ux_device_class_audio_stream_feedback_task_function) */
+/* Run stream feedback task */
+/* */
+/* CALLED BY */
+/* */
+/* USBX Device Stack */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 10-31-2022 Yajun Xia Initial Version 6.2.0 */
+/* */
+/**************************************************************************/
+UINT _ux_device_class_audio_tasks_run(VOID *instance)
+{
+UX_SLAVE_DEVICE *device;
+UX_DEVICE_CLASS_AUDIO *audio;
+UX_DEVICE_CLASS_AUDIO_STREAM *stream;
+ULONG stream_index;
+UINT status;
+#if defined(UX_DEVICE_CLASS_AUDIO_INTERRUPT_SUPPORT)
+ULONG interrupt_running_count = 0;
+#endif
+ULONG stream_running_count = 0;
+#if defined(UX_DEVICE_CLASS_AUDIO_FEEDBACK_SUPPORT)
+ULONG feedback_running_count = 0;
+#endif
+
+ /* Get audio instance. */
+ audio = (UX_DEVICE_CLASS_AUDIO *) instance;
+
+ /* Get the pointer to the device. */
+ device = &_ux_system_slave -> ux_system_slave_device;
+
+ /* Check if the device is configured. */
+ if (device -> ux_slave_device_state != UX_DEVICE_CONFIGURED)
+ return(UX_STATE_EXIT);
+
+#if defined(UX_DEVICE_CLASS_AUDIO_INTERRUPT_SUPPORT)
+
+ /* Run audio status tasks. */
+ status = _ux_device_class_audio_interrupt_task_function(audio);
+ if (status == UX_STATE_EXIT)
+ return(status);
+ if (status == UX_STATE_WAIT)
+ interrupt_running_count++;
+#endif
+
+ for (stream_index = 0;
+ stream_index < audio -> ux_device_class_audio_streams_nb;
+ stream_index ++)
+ {
+ stream = &audio -> ux_device_class_audio_streams[stream_index];
+ status = stream -> ux_device_class_audio_stream_task_function(stream);
+ if (status == UX_STATE_EXIT)
+ return(status);
+ if (status == UX_STATE_WAIT)
+ stream_running_count ++;
+
+#if defined(UX_DEVICE_CLASS_AUDIO_FEEDBACK_SUPPORT)
+ if (stream -> ux_device_class_audio_stream_feedback_task_function != UX_NULL)
+ {
+ status = stream -> ux_device_class_audio_stream_feedback_task_function(stream);
+ if (status == UX_STATE_EXIT)
+ return(status);
+ if (status == UX_STATE_WAIT)
+ feedback_running_count ++;
+ }
+#endif
+ }
+
+ if ((stream_running_count > 0)
+#if defined(UX_DEVICE_CLASS_AUDIO_INTERRUPT_SUPPORT)
+ || (interrupt_running_count > 0)
+#endif
+#if defined(UX_DEVICE_CLASS_AUDIO_FEEDBACK_SUPPORT)
+ || (feedback_running_count > 0)
+#endif
+ )
+ {
+ return UX_STATE_WAIT;
+ }
+ else
+ {
+ return UX_STATE_IDLE;
+ }
+}
+
+#endif \ No newline at end of file
diff --git a/common/usbx_device_classes/src/ux_device_class_audio_transmission_start.c b/common/usbx_device_classes/src/ux_device_class_audio_transmission_start.c
index 050390c..69b58c5 100644
--- a/common/usbx_device_classes/src/ux_device_class_audio_transmission_start.c
+++ b/common/usbx_device_classes/src/ux_device_class_audio_transmission_start.c
@@ -34,7 +34,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_audio_transmission_start PORTABLE C */
-/* 6.1.10 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -70,6 +70,9 @@
/* 01-31-2022 Chaoqiong Xiao Modified comment(s), */
/* refined macros names, */
/* resulting in version 6.1.10 */
+/* 10-31-2022 Yajun Xia Modified comment(s), */
+/* added standalone support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_device_class_audio_transmission_start(UX_DEVICE_CLASS_AUDIO_STREAM *stream)
@@ -103,7 +106,15 @@ UX_SLAVE_DEVICE *device;
if (stream -> ux_device_class_audio_stream_transfer_pos -> ux_device_class_audio_frame_length == 0)
return(UX_BUFFER_OVERFLOW);
+#if defined(UX_DEVICE_STANDALONE)
+
+ /* Start write task. */
+ if (stream -> ux_device_class_audio_stream_task_state == UX_DEVICE_CLASS_AUDIO_STREAM_RW_STOP)
+ stream -> ux_device_class_audio_stream_task_state = UX_DEVICE_CLASS_AUDIO_STREAM_RW_START;
+#else
+
/* Start write thread. */
_ux_device_thread_resume(&stream -> ux_device_class_audio_stream_thread);
+#endif
return(UX_SUCCESS);
}
diff --git a/common/usbx_device_classes/src/ux_device_class_audio_write_task_function.c b/common/usbx_device_classes/src/ux_device_class_audio_write_task_function.c
new file mode 100644
index 0000000..2c30a3c
--- /dev/null
+++ b/common/usbx_device_classes/src/ux_device_class_audio_write_task_function.c
@@ -0,0 +1,210 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) Microsoft Corporation. All rights reserved. */
+/* */
+/* This software is licensed under the Microsoft Software License */
+/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+/* and in the root directory of this software. */
+/* */
+/**************************************************************************/
+
+/**************************************************************************/
+/**************************************************************************/
+/** */
+/** USBX Component */
+/** */
+/** Device Audio Class */
+/** */
+/**************************************************************************/
+/**************************************************************************/
+
+#define UX_SOURCE_CODE
+
+
+/* Include necessary system files. */
+
+#include "ux_api.h"
+#include "ux_device_class_audio.h"
+#include "ux_device_stack.h"
+
+
+#if defined(UX_DEVICE_STANDALONE)
+/**************************************************************************/
+/* */
+/* FUNCTION RELEASE */
+/* */
+/* _ux_device_class_audio_write_task_function PORTABLE C */
+/* 6.2.0 */
+/* AUTHOR */
+/* */
+/* Yajun Xia, Microsoft Corporation */
+/* */
+/* DESCRIPTION */
+/* */
+/* This function is the background task of the audio stream write. */
+/* */
+/* It's for standalone mode. */
+/* */
+/* INPUT */
+/* */
+/* audio_class Address of audio class */
+/* container */
+/* */
+/* OUTPUT */
+/* */
+/* State machine status */
+/* UX_STATE_EXIT Device not configured */
+/* UX_STATE_IDLE No streaming transfer running */
+/* UX_STATE_WAIT Streaming transfer running */
+/* */
+/* CALLS */
+/* */
+/* _ux_device_stack_transfer_run Run transfer state machine */
+/* _ux_utility_memory_copy Copy memory */
+/* */
+/* CALLED BY */
+/* */
+/* USBX Device Stack */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 10-31-2022 Yajun Xia Initial Version 6.2.0 */
+/* */
+/**************************************************************************/
+UINT _ux_device_class_audio_write_task_function(UX_DEVICE_CLASS_AUDIO_STREAM *stream)
+{
+UX_SLAVE_DEVICE *device;
+UX_SLAVE_ENDPOINT *endpoint;
+UX_SLAVE_TRANSFER *transfer;
+UCHAR *next_pos;
+UX_DEVICE_CLASS_AUDIO_FRAME *next_frame;
+ULONG transfer_length;
+ULONG actual_length;
+UINT status;
+
+
+ /* Get the pointer to the device. */
+ device = stream -> ux_device_class_audio_stream_audio -> ux_device_class_audio_device;
+
+ /* Check if the device is configured. */
+ if (device -> ux_slave_device_state != UX_DEVICE_CONFIGURED)
+ {
+ stream -> ux_device_class_audio_stream_task_state = UX_STATE_EXIT;
+ return(UX_STATE_EXIT);
+ }
+
+ /* Get the endpoint. */
+ endpoint = stream -> ux_device_class_audio_stream_endpoint;
+
+ /* No endpoint ready, maybe it's alternate setting 0. */
+ if (endpoint == UX_NULL)
+ return(UX_STATE_IDLE);
+
+ /* Check if background transfer task is started. */
+ if (stream -> ux_device_class_audio_stream_task_state == UX_DEVICE_CLASS_AUDIO_STREAM_RW_STOP)
+ return(UX_STATE_IDLE);
+
+ /* Get transfer instance. */
+ transfer = &endpoint -> ux_slave_endpoint_transfer_request;
+
+ /* If not started yet, prepare data, reset transfer and start polling. */
+ if (stream -> ux_device_class_audio_stream_task_state == UX_DEVICE_CLASS_AUDIO_STREAM_RW_START)
+ {
+
+ /* Next state: transfer wait. */
+ stream -> ux_device_class_audio_stream_task_state = UX_DEVICE_CLASS_AUDIO_STREAM_RW_WAIT;
+
+ /* Start frame transfer anyway (even ZLP). */
+ transfer_length = stream -> ux_device_class_audio_stream_transfer_pos -> ux_device_class_audio_frame_length;
+ if (transfer_length)
+ _ux_utility_memory_copy(transfer -> ux_slave_transfer_request_data_pointer,
+ stream -> ux_device_class_audio_stream_transfer_pos -> ux_device_class_audio_frame_data, transfer_length); /* Use case of memcpy is verified. */
+
+ /* Reset transfer state. */
+ UX_SLAVE_TRANSFER_STATE_RESET(transfer);
+ }
+
+ /* Get current transfer length. */
+ transfer_length = stream -> ux_device_class_audio_stream_transfer_pos -> ux_device_class_audio_frame_length;
+
+ /* Run transfer states. */
+ status = _ux_device_stack_transfer_run(transfer, transfer_length, transfer_length);
+
+ /* Error case. */
+ if (status < UX_STATE_NEXT)
+ {
+
+ /* Error on background transfer task start. */
+ stream -> ux_device_class_audio_stream_task_state = UX_STATE_RESET;
+ stream -> ux_device_class_audio_stream_task_status =
+ transfer -> ux_slave_transfer_request_completion_code;
+
+ /* Error notification! */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_TRANSFER_ERROR);
+ return(UX_STATE_EXIT);
+ }
+
+ /* Success case. */
+ if (status == UX_STATE_NEXT)
+ {
+
+ /* Next state: start. */
+ stream -> ux_device_class_audio_stream_task_state = UX_DEVICE_CLASS_AUDIO_STREAM_RW_START;
+ stream -> ux_device_class_audio_stream_task_status =
+ transfer -> ux_slave_transfer_request_completion_code;
+
+ /* Frame sent, free it. */
+ stream -> ux_device_class_audio_stream_transfer_pos -> ux_device_class_audio_frame_length = 0;
+
+ /* Get actual transfer length. */
+ actual_length = transfer -> ux_slave_transfer_request_actual_length;
+
+ /* Calculate next position. */
+ next_pos = (UCHAR *)stream -> ux_device_class_audio_stream_transfer_pos;
+ next_pos += stream -> ux_device_class_audio_stream_frame_buffer_size;
+ if (next_pos >= stream -> ux_device_class_audio_stream_buffer + stream -> ux_device_class_audio_stream_buffer_size)
+ next_pos = stream -> ux_device_class_audio_stream_buffer;
+ next_frame = (UX_DEVICE_CLASS_AUDIO_FRAME *)next_pos;
+
+ /* Underflow check! */
+ if (transfer_length)
+ {
+
+ /* Advance position. */
+ stream -> ux_device_class_audio_stream_transfer_pos = next_frame;
+
+ /* Error trap! */
+ if (next_frame -> ux_device_class_audio_frame_length == 0)
+ {
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_BUFFER_OVERFLOW);
+ stream -> ux_device_class_audio_stream_buffer_error_count ++;
+ }
+ }
+ else
+ {
+
+ /* Advance position if next payload available. */
+ if (next_frame -> ux_device_class_audio_frame_length)
+ stream -> ux_device_class_audio_stream_transfer_pos = next_frame;
+ else
+ {
+
+ /* Error trap! */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_BUFFER_OVERFLOW);
+ stream -> ux_device_class_audio_stream_buffer_error_count ++;
+ }
+ }
+
+ /* Invoke notification callback. */
+ if (stream -> ux_device_class_audio_stream_callbacks.ux_device_class_audio_stream_frame_done != UX_NULL)
+ stream -> ux_device_class_audio_stream_callbacks.ux_device_class_audio_stream_frame_done(stream, actual_length);
+ }
+
+ /* Keep waiting. */
+ return(UX_STATE_WAIT);
+}
+#endif
+
diff --git a/common/usbx_device_classes/src/ux_device_class_audio_write_thread_entry.c b/common/usbx_device_classes/src/ux_device_class_audio_write_thread_entry.c
index f6c1cf0..ce6bd7b 100644
--- a/common/usbx_device_classes/src/ux_device_class_audio_write_thread_entry.c
+++ b/common/usbx_device_classes/src/ux_device_class_audio_write_thread_entry.c
@@ -34,7 +34,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_audio_write_thread_entry PORTABLE C */
-/* 6.1.10 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -75,6 +75,9 @@
/* 01-31-2022 Chaoqiong Xiao Modified comment(s), */
/* refined macros names, */
/* resulting in version 6.1.10 */
+/* 10-31-2022 Yajun Xia Modified comment(s), */
+/* added standalone support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
VOID _ux_device_class_audio_write_thread_entry(ULONG audio_stream)
@@ -153,7 +156,10 @@ ULONG actual_length;
/* Error trap! */
if (next_frame -> ux_device_class_audio_frame_length == 0)
+ {
+ stream -> ux_device_class_audio_stream_buffer_error_count ++;
_ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_BUFFER_OVERFLOW);
+ }
}
else
{
@@ -162,9 +168,12 @@ ULONG actual_length;
if (next_frame -> ux_device_class_audio_frame_length)
stream -> ux_device_class_audio_stream_transfer_pos = next_frame;
else
+ {
/* Error trap! */
_ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_BUFFER_OVERFLOW);
+ stream -> ux_device_class_audio_stream_buffer_error_count ++;
+ }
}
/* Invoke notification callback. */
diff --git a/common/usbx_device_classes/src/ux_device_class_cdc_acm_read_run.c b/common/usbx_device_classes/src/ux_device_class_cdc_acm_read_run.c
index 4086b03..e89212a 100644
--- a/common/usbx_device_classes/src/ux_device_class_cdc_acm_read_run.c
+++ b/common/usbx_device_classes/src/ux_device_class_cdc_acm_read_run.c
@@ -37,7 +37,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_cdc_acm_read_run PORTABLE C */
-/* 6.1.10 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -79,6 +79,9 @@
/* DATE NAME DESCRIPTION */
/* */
/* 01-31-2022 Chaoqiong Xiao Initial Version 6.1.10 */
+/* 10-31-2022 Yajun Xia Modified comment(s), */
+/* fixed return code, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_device_class_cdc_acm_read_run(UX_SLAVE_CLASS_CDC_ACM *cdc_acm,
@@ -200,7 +203,7 @@ UINT status = UX_SUCCESS;
cdc_acm -> ux_device_class_cdc_acm_read_state = UX_STATE_RESET;
cdc_acm -> ux_device_class_cdc_acm_read_status =
transfer_request -> ux_slave_transfer_request_completion_code;
- return(UX_STATE_EXIT);
+ return(UX_STATE_ERROR);
}
/* Success case. */
diff --git a/common/usbx_device_classes/src/ux_device_class_cdc_acm_tasks_run.c b/common/usbx_device_classes/src/ux_device_class_cdc_acm_tasks_run.c
index 63c4e8f..55f5ddd 100644
--- a/common/usbx_device_classes/src/ux_device_class_cdc_acm_tasks_run.c
+++ b/common/usbx_device_classes/src/ux_device_class_cdc_acm_tasks_run.c
@@ -31,8 +31,11 @@
#if defined(UX_DEVICE_STANDALONE)
+
+#ifndef UX_DEVICE_CLASS_CDC_ACM_TRANSMISSION_DISABLE
static inline VOID _ux_device_class_cdc_acm_transmission_read_run(UX_SLAVE_CLASS_CDC_ACM *cdc_acm);
static inline VOID _ux_device_class_cdc_acm_transmission_write_run(UX_SLAVE_CLASS_CDC_ACM *cdc_acm);
+#endif
/**************************************************************************/
@@ -40,7 +43,7 @@ static inline VOID _ux_device_class_cdc_acm_transmission_write_run(UX_SLAVE_CLAS
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_cdc_acm_tasks_run PORTABLE C */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -80,21 +83,23 @@ static inline VOID _ux_device_class_cdc_acm_transmission_write_run(UX_SLAVE_CLAS
/* names conflict C++ keyword, */
/* supported write auto ZLP, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* fixed compile warnings, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_device_class_cdc_acm_tasks_run(VOID *instance)
{
-UX_SLAVE_DEVICE *device;
-UX_SLAVE_CLASS_CDC_ACM *cdc_acm;
UINT status = UX_STATE_IDLE;
+#ifndef UX_DEVICE_CLASS_CDC_ACM_TRANSMISSION_DISABLE
+UX_SLAVE_DEVICE *device;
+UX_SLAVE_CLASS_CDC_ACM *cdc_acm;
/* Get CDC ACM instance. */
cdc_acm = (UX_SLAVE_CLASS_CDC_ACM*) instance;
-#ifndef UX_DEVICE_CLASS_CDC_ACM_TRANSMISSION_DISABLE
-
/* Check if transmission is started. */
if (!cdc_acm -> ux_slave_class_cdc_acm_transmission_status)
return(status);
diff --git a/common/usbx_device_classes/src/ux_device_class_cdc_acm_write_run.c b/common/usbx_device_classes/src/ux_device_class_cdc_acm_write_run.c
index 630bea7..35ea2ad 100644
--- a/common/usbx_device_classes/src/ux_device_class_cdc_acm_write_run.c
+++ b/common/usbx_device_classes/src/ux_device_class_cdc_acm_write_run.c
@@ -37,7 +37,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_cdc_acm_write_run PORTABLE C */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -83,6 +83,9 @@
/* names conflict C++ keyword, */
/* added auto ZLP support, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Yajun Xia Modified comment(s), */
+/* fixed return code, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_device_class_cdc_acm_write_run(UX_SLAVE_CLASS_CDC_ACM *cdc_acm,
@@ -125,7 +128,7 @@ UINT status = 0;
cdc_acm -> ux_device_class_cdc_acm_write_state = UX_STATE_RESET;
cdc_acm -> ux_device_class_cdc_acm_write_status = UX_CONFIGURATION_HANDLE_UNKNOWN;
- return(UX_CONFIGURATION_HANDLE_UNKNOWN);
+ return(UX_STATE_EXIT);
}
/* We need the interface to the class. */
@@ -224,7 +227,7 @@ UINT status = 0;
cdc_acm -> ux_device_class_cdc_acm_write_state = UX_STATE_RESET;
cdc_acm -> ux_device_class_cdc_acm_write_status =
transfer_request -> ux_slave_transfer_request_completion_code;
- return(UX_STATE_EXIT);
+ return(UX_STATE_ERROR);
}
/* Success case. */
diff --git a/common/usbx_device_classes/src/ux_device_class_cdc_ecm_bulkin_thread.c b/common/usbx_device_classes/src/ux_device_class_cdc_ecm_bulkin_thread.c
index a30a9bd..57968f6 100644
--- a/common/usbx_device_classes/src/ux_device_class_cdc_ecm_bulkin_thread.c
+++ b/common/usbx_device_classes/src/ux_device_class_cdc_ecm_bulkin_thread.c
@@ -35,7 +35,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_cdc_ecm_bulkin_thread PORTABLE C */
-/* 6.1.11 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -83,6 +83,9 @@
/* 04-25-2022 Chaoqiong Xiao Modified comment(s), */
/* fixed standalone compile, */
/* resulting in version 6.1.11 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* used NX API to copy data, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
VOID _ux_device_class_cdc_ecm_bulkin_thread(ULONG cdc_ecm_class)
@@ -95,8 +98,8 @@ UX_SLAVE_TRANSFER *transfer_request;
UINT status;
ULONG actual_flags;
NX_PACKET *current_packet;
-UCHAR *packet_header;
ULONG transfer_length;
+ULONG copied;
/* Cast properly the cdc_ecm instance. */
UX_THREAD_EXTENSION_PTR_GET(class_ptr, UX_SLAVE_CLASS, cdc_ecm_class)
@@ -148,24 +151,26 @@ ULONG transfer_length;
if (cdc_ecm -> ux_slave_class_cdc_ecm_link_state == UX_DEVICE_CLASS_CDC_ECM_LINK_STATE_UP)
{
- /* Load the address of the current packet header at the physical header. */
- packet_header = current_packet -> nx_packet_prepend_ptr;
-
/* Can the packet fit in the transfer requests data buffer? */
if (current_packet -> nx_packet_length <= UX_SLAVE_REQUEST_DATA_MAX_LENGTH)
{
/* Copy the packet in the transfer descriptor buffer. */
- _ux_utility_memory_copy(transfer_request -> ux_slave_transfer_request_data_pointer, packet_header, current_packet -> nx_packet_length); /* Use case of memcpy is verified. */
+ status = nx_packet_data_extract_offset(current_packet, 0,
+ transfer_request -> ux_slave_transfer_request_data_pointer,
+ current_packet -> nx_packet_length, &copied);
+ if (status == UX_SUCCESS)
+ {
- /* Calculate the transfer length. */
- transfer_length = current_packet -> nx_packet_length;
-
- /* If trace is enabled, insert this event into the trace buffer. */
- UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_CLASS_CDC_ECM_PACKET_TRANSMIT, cdc_ecm, 0, 0, 0, UX_TRACE_DEVICE_CLASS_EVENTS, 0, 0)
+ /* Calculate the transfer length. */
+ transfer_length = current_packet -> nx_packet_length;
+
+ /* If trace is enabled, insert this event into the trace buffer. */
+ UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_CLASS_CDC_ECM_PACKET_TRANSMIT, cdc_ecm, 0, 0, 0, UX_TRACE_DEVICE_CLASS_EVENTS, 0, 0)
- /* Send the request to the device controller. */
- status = _ux_device_stack_transfer_request(transfer_request, transfer_length, UX_DEVICE_CLASS_CDC_ECM_ETHERNET_PACKET_SIZE);
+ /* Send the request to the device controller. */
+ status = _ux_device_stack_transfer_request(transfer_request, transfer_length, UX_DEVICE_CLASS_CDC_ECM_ETHERNET_PACKET_SIZE + 1);
+ }
/* Check error code. */
if (status != UX_SUCCESS)
diff --git a/common/usbx_device_classes/src/ux_device_class_cdc_ecm_bulkout_thread.c b/common/usbx_device_classes/src/ux_device_class_cdc_ecm_bulkout_thread.c
index 6b0ba9f..8b1cc26 100644
--- a/common/usbx_device_classes/src/ux_device_class_cdc_ecm_bulkout_thread.c
+++ b/common/usbx_device_classes/src/ux_device_class_cdc_ecm_bulkout_thread.c
@@ -35,7 +35,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_cdc_ecm_bulkout_thread PORTABLE C */
-/* 6.1.11 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -83,6 +83,11 @@
/* 04-25-2022 Chaoqiong Xiao Modified comment(s), */
/* fixed standalone compile, */
/* resulting in version 6.1.11 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* fixed EP not ready issue, */
+/* used pool from NX IP inst, */
+/* used NX API to copy data, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
VOID _ux_device_class_cdc_ecm_bulkout_thread(ULONG cdc_ecm_class)
@@ -94,7 +99,7 @@ UX_SLAVE_DEVICE *device;
UX_SLAVE_TRANSFER *transfer_request;
UINT status;
NX_PACKET *packet;
-ULONG ip_given_length;
+USB_NETWORK_DEVICE_TYPE *ux_nx_device;
/* Cast properly the cdc_ecm instance. */
UX_THREAD_EXTENSION_PTR_GET(class_ptr, UX_SLAVE_CLASS, cdc_ecm_class)
@@ -113,8 +118,38 @@ ULONG ip_given_length;
while (device -> ux_slave_device_state == UX_DEVICE_CONFIGURED)
{
+ /* Check if packet pool is ready. */
+ if (cdc_ecm -> ux_slave_class_cdc_ecm_packet_pool == UX_NULL)
+ {
+
+ /* Get the network device handle. */
+ ux_nx_device = (USB_NETWORK_DEVICE_TYPE *)(cdc_ecm -> ux_slave_class_cdc_ecm_network_handle);
+
+ /* Get packet pool from IP instance (if available). */
+ if (ux_nx_device -> ux_network_device_ip_instance != UX_NULL)
+ {
+ cdc_ecm -> ux_slave_class_cdc_ecm_packet_pool = ux_nx_device -> ux_network_device_ip_instance -> nx_ip_default_packet_pool;
+ }
+ else
+ {
+
+ /* Error trap. */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_CLASS_ETH_PACKET_POOL_ERROR);
+
+ _ux_utility_delay_ms(UX_DEVICE_CLASS_CDC_ECM_PACKET_POOL_INST_WAIT);
+ continue;
+ }
+ }
+
+ /* Check if Bulk OUT endpoint is ready. */
+ if (cdc_ecm -> ux_slave_class_cdc_ecm_bulkout_endpoint == UX_NULL)
+ {
+ _ux_utility_delay_ms(UX_DEVICE_CLASS_CDC_ECM_LINK_CHECK_WAIT);
+ continue;
+ }
+
/* We can accept new reception. Get a NX Packet */
- status = nx_packet_allocate(&cdc_ecm -> ux_slave_class_cdc_ecm_packet_pool, &packet,
+ status = nx_packet_allocate(cdc_ecm -> ux_slave_class_cdc_ecm_packet_pool, &packet,
NX_RECEIVE_PACKET, UX_MS_TO_TICK(UX_DEVICE_CLASS_CDC_ECM_PACKET_POOL_WAIT));
if (status == NX_SUCCESS)
@@ -136,7 +171,7 @@ ULONG ip_given_length;
/* Send the request to the device controller. */
status = _ux_device_stack_transfer_request(transfer_request, UX_DEVICE_CLASS_CDC_ECM_MAX_PACKET_LENGTH,
UX_DEVICE_CLASS_CDC_ECM_MAX_PACKET_LENGTH);
-
+
/* Check the completion code. */
if (status == UX_SUCCESS)
{
@@ -147,26 +182,27 @@ ULONG ip_given_length;
/* Adjust the prepend pointer to take into account the non 3 bit alignment of the ethernet header. */
packet -> nx_packet_prepend_ptr += sizeof(USHORT);
-
- /* Set the prepend, length, and append fields. */
- packet -> nx_packet_length = transfer_request -> ux_slave_transfer_request_actual_length;
- packet -> nx_packet_append_ptr = packet -> nx_packet_prepend_ptr + transfer_request -> ux_slave_transfer_request_actual_length;
-
+ packet -> nx_packet_append_ptr += sizeof(USHORT);
+
/* Copy the received packet in the IP packet data area. */
- _ux_utility_memory_copy(packet -> nx_packet_prepend_ptr, transfer_request -> ux_slave_transfer_request_data_pointer, packet -> nx_packet_length); /* Use case of memcpy is verified. */
-
- /* Calculate the accurate packet length from ip header. */
- if((*(packet -> nx_packet_prepend_ptr + 12) == 0x08) &&
- (*(packet -> nx_packet_prepend_ptr + 13) == 0))
+ status = nx_packet_data_append(packet,
+ transfer_request -> ux_slave_transfer_request_data_pointer,
+ transfer_request -> ux_slave_transfer_request_actual_length,
+ cdc_ecm -> ux_slave_class_cdc_ecm_packet_pool,
+ UX_MS_TO_TICK(UX_DEVICE_CLASS_CDC_ECM_PACKET_POOL_WAIT));
+ if (status == NX_SUCCESS)
+ {
+
+ /* Send that packet to the NetX USB broker. */
+ _ux_network_driver_packet_received(cdc_ecm -> ux_slave_class_cdc_ecm_network_handle, packet);
+ }
+ else
{
- ip_given_length = _ux_utility_short_get_big_endian(packet -> nx_packet_prepend_ptr + 16) + UX_DEVICE_CLASS_CDC_ECM_ETHERNET_SIZE;
- packet -> nx_packet_length = ip_given_length ;
- packet -> nx_packet_append_ptr = packet -> nx_packet_prepend_ptr + ip_given_length;
+ /* We received a malformed packet. Report to application. */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_CLASS_MALFORMED_PACKET_RECEIVED_ERROR);
+ nx_packet_release(packet);
}
-
- /* Send that packet to the NetX USB broker. */
- _ux_network_driver_packet_received(cdc_ecm -> ux_slave_class_cdc_ecm_network_handle, packet);
}
else
diff --git a/common/usbx_device_classes/src/ux_device_class_cdc_ecm_initialize.c b/common/usbx_device_classes/src/ux_device_class_cdc_ecm_initialize.c
index f1723be..84ae21b 100644
--- a/common/usbx_device_classes/src/ux_device_class_cdc_ecm_initialize.c
+++ b/common/usbx_device_classes/src/ux_device_class_cdc_ecm_initialize.c
@@ -27,14 +27,13 @@
#include "ux_device_class_cdc_ecm.h"
#include "ux_device_stack.h"
-UX_DEVICE_CLASS_CDC_ECM_NX_ETHERNET_POOL_ALLOCSIZE_ASSERT
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_cdc_ecm_initialize PORTABLE C */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -61,8 +60,6 @@ UX_DEVICE_CLASS_CDC_ECM_NX_ETHERNET_POOL_ALLOCSIZE_ASSERT
/* _ux_utility_event_flags_delete Delete Flag group */
/* _ux_device_thread_create Create Thread */
/* _ux_device_thread_delete Delete Thread */
-/* nx_packet_pool_create Create NetX packet pool */
-/* nx_packet_pool_delete Delete NetX packet pool */
/* */
/* CALLED BY */
/* */
@@ -89,6 +86,9 @@ UX_DEVICE_CLASS_CDC_ECM_NX_ETHERNET_POOL_ALLOCSIZE_ASSERT
/* fixed parameter/variable */
/* names conflict C++ keyword, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* removed internal NX pool, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_device_class_cdc_ecm_initialize(UX_SLAVE_CLASS_COMMAND *command)
@@ -153,28 +153,6 @@ UINT status;
status = (UX_MEMORY_INSUFFICIENT);
}
- /* Allocate some packet pool for reception. */
- if (status == UX_SUCCESS)
- {
-
- /* UX_DEVICE_CLASS_CDC_ECM_NX_ETHERNET_POOL_ALLOCSIZE overflow has been checked by
- * UX_DEVICE_CLASS_CDC_ECM_NX_ETHERNET_POOL_ALLOCSIZE_ASSERT outside of function.
- */
- cdc_ecm -> ux_slave_class_cdc_ecm_pool_memory =
- _ux_utility_memory_allocate(UX_NO_ALIGN, UX_CACHE_SAFE_MEMORY, UX_DEVICE_CLASS_CDC_ECM_NX_ETHERNET_POOL_ALLOCSIZE);
-
- /* Check for successful allocation. */
- if (cdc_ecm -> ux_slave_class_cdc_ecm_pool_memory == UX_NULL)
- status = (UX_MEMORY_INSUFFICIENT);
- else
- {
- /* Create a packet pool. */
- status = nx_packet_pool_create(&cdc_ecm -> ux_slave_class_cdc_ecm_packet_pool, "CDC ECM Device Packet Pool",
- UX_DEVICE_CLASS_CDC_ECM_NX_PAYLOAD_SIZE, cdc_ecm -> ux_slave_class_cdc_ecm_pool_memory,
- UX_DEVICE_CLASS_CDC_ECM_NX_ETHERNET_POOL_ALLOCSIZE);
- }
- }
-
/* Interrupt endpoint treatment needs to be running in a different thread. So start
a new thread. We pass a pointer to the cdc_ecm instance to the new thread. This thread
does not start until we have a instance of the class. */
@@ -267,10 +245,6 @@ UINT status;
/* Free allocated resources. */
- if (cdc_ecm -> ux_slave_class_cdc_ecm_packet_pool.nx_packet_pool_id)
- nx_packet_pool_delete(&cdc_ecm -> ux_slave_class_cdc_ecm_packet_pool);
- if (cdc_ecm -> ux_slave_class_cdc_ecm_pool_memory)
- _ux_utility_memory_free(cdc_ecm -> ux_slave_class_cdc_ecm_pool_memory);
if (cdc_ecm -> ux_slave_class_cdc_ecm_bulkin_thread_stack)
_ux_utility_memory_free(cdc_ecm -> ux_slave_class_cdc_ecm_bulkin_thread_stack);
if (cdc_ecm -> ux_slave_class_cdc_ecm_interrupt_thread_stack)
diff --git a/common/usbx_device_classes/src/ux_device_class_cdc_ecm_uninitialize.c b/common/usbx_device_classes/src/ux_device_class_cdc_ecm_uninitialize.c
index c429632..43ae217 100644
--- a/common/usbx_device_classes/src/ux_device_class_cdc_ecm_uninitialize.c
+++ b/common/usbx_device_classes/src/ux_device_class_cdc_ecm_uninitialize.c
@@ -35,7 +35,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_cdc_ecm_uninitialize PORTABLE C */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -82,6 +82,9 @@
/* fixed parameter/variable */
/* names conflict C++ keyword, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* removed internal NX pool, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_device_class_cdc_ecm_uninitialize(UX_SLAVE_CLASS_COMMAND *command)
@@ -131,14 +134,8 @@ UX_SLAVE_CLASS *class_ptr;
/* Delete the interrupt thread sync event flags group. */
_ux_device_event_flags_delete(&cdc_ecm -> ux_slave_class_cdc_ecm_event_flags_group);
- /* Delete the reception packet pool. */
- nx_packet_pool_delete(&cdc_ecm -> ux_slave_class_cdc_ecm_packet_pool);
-
#endif
- /* Free the packet pool memory. */
- _ux_utility_memory_free(cdc_ecm -> ux_slave_class_cdc_ecm_pool_memory);
-
/* Free the resources. */
_ux_utility_memory_free(cdc_ecm);
}
diff --git a/common/usbx_device_classes/src/ux_device_class_hid_control_request.c b/common/usbx_device_classes/src/ux_device_class_hid_control_request.c
index 4d04c38..4d04c38 100755..100644
--- a/common/usbx_device_classes/src/ux_device_class_hid_control_request.c
+++ b/common/usbx_device_classes/src/ux_device_class_hid_control_request.c
diff --git a/common/usbx_device_classes/src/ux_device_class_hid_initialize.c b/common/usbx_device_classes/src/ux_device_class_hid_initialize.c
index 22f8e46..74fc89b 100644
--- a/common/usbx_device_classes/src/ux_device_class_hid_initialize.c
+++ b/common/usbx_device_classes/src/ux_device_class_hid_initialize.c
@@ -33,7 +33,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_hid_initialize PORTABLE C */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -85,6 +85,9 @@
/* fixed parameter/variable */
/* names conflict C++ keyword, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* fixed compile warnings, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_device_class_hid_initialize(UX_SLAVE_CLASS_COMMAND *command)
@@ -228,8 +231,13 @@ UINT status = UX_SUCCESS;
}
+#if !defined(UX_DEVICE_STANDALONE) || defined(UX_DEVICE_CLASS_HID_INTERRUPT_OUT_SUPPORT)
+
+ /* There is still initialization activities after array creation,
+ * and some error occurs in this stage. */
/* Free allocated event array memory. */
_ux_utility_memory_free(hid -> ux_device_class_hid_event_array);
+#endif
}
else
diff --git a/common/usbx_device_classes/src/ux_device_class_printer_initialize.c b/common/usbx_device_classes/src/ux_device_class_printer_initialize.c
index 1007d29..f07e446 100644
--- a/common/usbx_device_classes/src/ux_device_class_printer_initialize.c
+++ b/common/usbx_device_classes/src/ux_device_class_printer_initialize.c
@@ -33,7 +33,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_printer_initialize PORTABLE C */
-/* 6.1.11 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -69,19 +69,20 @@
/* 04-25-2022 Chaoqiong Xiao Modified comment(s), */
/* fixed standalone compile, */
/* resulting in version 6.1.11 */
+/* 10-31-2022 Yajun Xia Modified comment(s), */
+/* added standalone support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_device_class_printer_initialize(UX_SLAVE_CLASS_COMMAND *command)
{
-#if defined(UX_DEVICE_STANDALONE)
- UX_PARAMETER_NOT_USED(command);
- return(UX_FUNCTION_NOT_SUPPORTED);
-#else
UX_DEVICE_CLASS_PRINTER *printer;
UX_DEVICE_CLASS_PRINTER_PARAMETER *printer_parameter;
UX_SLAVE_CLASS *printer_class;
+#if !defined(UX_DEVICE_STANDALONE)
UINT status;
+#endif
/* Get the class container. */
printer_class = command -> ux_slave_class_command_class_ptr;
@@ -105,6 +106,7 @@ UINT status;
printer -> ux_device_class_printer_parameter.ux_device_class_printer_instance_deactivate = printer_parameter -> ux_device_class_printer_instance_deactivate;
printer -> ux_device_class_printer_parameter.ux_device_class_printer_soft_reset = printer_parameter -> ux_device_class_printer_soft_reset;
+#if !defined(UX_DEVICE_STANDALONE)
/* Create the Mutex for each endpoint as multiple threads cannot access each pipe at the same time. */
status = _ux_utility_mutex_create(&printer -> ux_device_class_printer_endpoint_in_mutex, "ux_device_class_printer_in_mutex");
@@ -135,11 +137,14 @@ UINT status;
/* Return fatal error. */
return(UX_MUTEX_ERROR);
}
+#else
+ printer -> ux_device_class_printer_write_state = UX_STATE_RESET;
+ printer -> ux_device_class_printer_read_state = UX_STATE_RESET;
+#endif
/* Reset port status. */
printer -> ux_device_class_printer_port_status = 0;
/* Return completion status. */
return(UX_SUCCESS);
-#endif
}
diff --git a/common/usbx_device_classes/src/ux_device_class_printer_read_run.c b/common/usbx_device_classes/src/ux_device_class_printer_read_run.c
new file mode 100644
index 0000000..acfb390
--- /dev/null
+++ b/common/usbx_device_classes/src/ux_device_class_printer_read_run.c
@@ -0,0 +1,238 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) Microsoft Corporation. All rights reserved. */
+/* */
+/* This software is licensed under the Microsoft Software License */
+/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+/* and in the root directory of this software. */
+/* */
+/**************************************************************************/
+
+/**************************************************************************/
+/**************************************************************************/
+/** */
+/** USBX Component */
+/** */
+/** Device Printer Class */
+/** */
+/**************************************************************************/
+/**************************************************************************/
+
+#define UX_SOURCE_CODE
+
+
+/* Include necessary system files. */
+
+#include "ux_api.h"
+#include "ux_device_class_printer.h"
+#include "ux_device_stack.h"
+
+
+#if defined(UX_DEVICE_STANDALONE)
+
+
+/**************************************************************************/
+/* */
+/* FUNCTION RELEASE */
+/* */
+/* _ux_device_class_printer_read_run PORTABLE C */
+/* 6.2.0 */
+/* AUTHOR */
+/* */
+/* Yajun Xia, Microsoft Corporation */
+/* */
+/* DESCRIPTION */
+/* */
+/* This function reads from the Printer class. */
+/* */
+/* It's for standalone mode. */
+/* */
+/* INPUT */
+/* */
+/* printer Address of printer class */
+/* instance */
+/* buffer Pointer to buffer to save */
+/* received data */
+/* requested_length Length of bytes to read */
+/* actual_length Pointer to save number of */
+/* bytes read */
+/* */
+/* OUTPUT */
+/* */
+/* State machine Status to check */
+/* UX_STATE_NEXT Transfer done, to next state */
+/* UX_STATE_EXIT Abnormal, to reset state */
+/* (others) Keep running, waiting */
+/* */
+/* CALLS */
+/* */
+/* _ux_device_stack_transfer_run Transfer request */
+/* _ux_utility_memory_copy Copy memory */
+/* */
+/* CALLED BY */
+/* */
+/* Application */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 10-31-2022 Yajun xia Initial Version 6.2.0 */
+/* */
+/**************************************************************************/
+UINT _ux_device_class_printer_read_run(UX_DEVICE_CLASS_PRINTER *printer, UCHAR *buffer,
+ ULONG requested_length, ULONG *actual_length)
+{
+
+UX_SLAVE_ENDPOINT *endpoint;
+UX_SLAVE_DEVICE *device;
+UX_SLAVE_TRANSFER *transfer_request;
+ULONG max_transfer_length;
+UINT status = UX_SUCCESS;
+
+ /* If trace is enabled, insert this event into the trace buffer. */
+ UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_CLASS_PRINTER_READ, printer, buffer, requested_length, 0, UX_TRACE_DEVICE_CLASS_EVENTS, 0, 0)
+
+ /* Get the pointer to the device. */
+ device = &_ux_system_slave -> ux_system_slave_device;
+
+ /* As long as the device is in the CONFIGURED state. */
+ if (device -> ux_slave_device_state != UX_DEVICE_CONFIGURED)
+ {
+
+ /* Error trap. */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_CONFIGURATION_HANDLE_UNKNOWN);
+
+ /* If trace is enabled, insert this event into the trace buffer. */
+ UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_CONFIGURATION_HANDLE_UNKNOWN, device, 0, 0, UX_TRACE_ERRORS, 0, 0)
+
+ /* Cannot proceed with command, the interface is down. */
+ printer -> ux_device_class_printer_read_state = UX_STATE_RESET;
+ printer -> ux_device_class_printer_read_status = UX_CONFIGURATION_HANDLE_UNKNOWN;
+
+ return(UX_STATE_EXIT);
+ }
+
+ /* Locate the endpoint. */
+ endpoint = printer -> ux_device_class_printer_endpoint_out;
+
+ /* All Printer reading are on the endpoint OUT, from the host. */
+ transfer_request = &endpoint -> ux_slave_endpoint_transfer_request;
+
+ /* Handle state cases. */
+ switch(printer -> ux_device_class_printer_read_state)
+ {
+ case UX_STATE_RESET:
+
+ /* If trace is enabled, insert this event into the trace buffer. */
+ UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_CLASS_PRINTER_READ, printer, buffer, requested_length, 0, UX_TRACE_DEVICE_CLASS_EVENTS, 0, 0)
+
+ printer -> ux_device_class_printer_read_state = UX_DEVICE_CLASS_PRINTER_READ_START;
+ printer -> ux_device_class_printer_read_status = UX_TRANSFER_NO_ANSWER;
+ printer -> ux_device_class_printer_read_buffer = buffer;
+ printer -> ux_device_class_printer_read_requested_length = requested_length;
+ printer -> ux_device_class_printer_read_actual_length = 0;
+
+ /* Fall through. */
+ case UX_DEVICE_CLASS_PRINTER_READ_START:
+
+ /* Get remaining transfer length. */
+ requested_length = printer -> ux_device_class_printer_read_requested_length -
+ printer -> ux_device_class_printer_read_actual_length;
+
+ /* There is nothing remaining, it's done. */
+ if (requested_length == 0)
+ {
+ *actual_length = printer -> ux_device_class_printer_read_actual_length;
+ printer -> ux_device_class_printer_read_state = UX_STATE_RESET;
+ printer -> ux_device_class_printer_read_status = UX_SUCCESS;
+ return(UX_STATE_NEXT);
+ }
+
+ printer -> ux_device_class_printer_read_transfer_length = requested_length;
+
+ /* Next state. */
+ printer -> ux_device_class_printer_read_state = UX_DEVICE_CLASS_PRINTER_READ_WAIT;
+ UX_SLAVE_TRANSFER_STATE_RESET(transfer_request);
+
+ /* Fall through. */
+ case UX_DEVICE_CLASS_PRINTER_READ_WAIT:
+
+ /* Get a full packet each time */
+ max_transfer_length = endpoint -> ux_slave_endpoint_descriptor.wMaxPacketSize;
+
+ /* Run the transfer state machine. */
+ status = _ux_device_stack_transfer_run(transfer_request,
+ max_transfer_length,
+ max_transfer_length);
+
+ /* Error case. */
+ if (status < UX_STATE_NEXT)
+ {
+ printer -> ux_device_class_printer_read_state = UX_STATE_RESET;
+ printer -> ux_device_class_printer_read_status =
+ transfer_request -> ux_slave_transfer_request_completion_code;
+ return(UX_STATE_ERROR);
+ }
+
+ /* Success case. */
+ if (status == UX_STATE_NEXT)
+ {
+ /* Check overflow */
+ if (printer -> ux_device_class_printer_read_transfer_length <
+ transfer_request -> ux_slave_transfer_request_actual_length)
+ {
+ printer -> ux_device_class_printer_read_state = UX_STATE_ERROR;
+ printer -> ux_device_class_printer_read_status = UX_TRANSFER_BUFFER_OVERFLOW;
+ return(UX_STATE_ERROR);
+ }
+
+ /* We need to copy the buffer locally. */
+ _ux_utility_memory_copy(printer -> ux_device_class_printer_read_buffer,
+ transfer_request -> ux_slave_transfer_request_data_pointer,
+ transfer_request -> ux_slave_transfer_request_actual_length); /* Use case of memcpy is verified. */
+
+ /* Next buffer address. */
+ printer -> ux_device_class_printer_read_buffer +=
+ transfer_request -> ux_slave_transfer_request_actual_length;
+
+ /* Set the length actually received. */
+ printer -> ux_device_class_printer_read_actual_length +=
+ transfer_request -> ux_slave_transfer_request_actual_length;
+
+ /* Last transfer status. */
+ printer -> ux_device_class_printer_read_status =
+ transfer_request -> ux_slave_transfer_request_completion_code;
+
+ /* Update actual length. */
+ *actual_length = printer -> ux_device_class_printer_read_actual_length;
+
+ /* Check short packet. */
+ if (transfer_request -> ux_slave_transfer_request_actual_length <
+ transfer_request -> ux_slave_transfer_request_requested_length)
+ {
+
+ /* It's done. */
+ printer -> ux_device_class_printer_read_state = UX_STATE_RESET;
+ return(UX_STATE_NEXT);
+ }
+
+ /* Next state. */
+ printer -> ux_device_class_printer_read_state = UX_DEVICE_CLASS_PRINTER_READ_START;
+ }
+
+ /* Keep waiting. */
+ return(UX_STATE_WAIT);
+
+ default: /* Error. */
+ printer -> ux_device_class_printer_read_state = UX_STATE_RESET;
+ printer -> ux_device_class_printer_read_status = UX_INVALID_STATE;
+ break;
+ }
+
+ /* Error cases. */
+ return(UX_STATE_EXIT);
+}
+
+#endif
diff --git a/common/usbx_device_classes/src/ux_device_class_printer_soft_reset.c b/common/usbx_device_classes/src/ux_device_class_printer_soft_reset.c
index fa96f3b..9d41d96 100644
--- a/common/usbx_device_classes/src/ux_device_class_printer_soft_reset.c
+++ b/common/usbx_device_classes/src/ux_device_class_printer_soft_reset.c
@@ -34,7 +34,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_printer_soft_reset PORTABLE C */
-/* 6.1.10 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -66,6 +66,9 @@
/* DATE NAME DESCRIPTION */
/* */
/* 01-31-2022 Chaoqiong Xiao Initial Version 6.1.10 */
+/* 10-31-2022 Yajun Xia Modified comment(s), */
+/* added standalone support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
VOID _ux_device_class_printer_soft_reset(UX_DEVICE_CLASS_PRINTER *printer)
@@ -76,11 +79,17 @@ UX_SLAVE_ENDPOINT *endpoint;
/* Stop OUT. */
endpoint = printer -> ux_device_class_printer_endpoint_out;
_ux_device_stack_transfer_all_request_abort(endpoint, UX_ENDPOINT_RESET);
+#if defined(UX_DEVICE_STANDALONE)
+ printer -> ux_device_class_printer_write_state = UX_STATE_RESET;
+#endif
/* Stop IN (optional). */
endpoint = printer -> ux_device_class_printer_endpoint_in;
if (endpoint != UX_NULL)
{
_ux_device_stack_transfer_all_request_abort(endpoint, UX_ENDPOINT_RESET);
+#if defined(UX_DEVICE_STANDALONE)
+ printer -> ux_device_class_printer_read_state = UX_STATE_RESET;
+#endif
}
}
diff --git a/common/usbx_device_classes/src/ux_device_class_printer_uninitialize.c b/common/usbx_device_classes/src/ux_device_class_printer_uninitialize.c
index 1ff77aa..6a4e956 100644
--- a/common/usbx_device_classes/src/ux_device_class_printer_uninitialize.c
+++ b/common/usbx_device_classes/src/ux_device_class_printer_uninitialize.c
@@ -34,7 +34,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_printer_uninitialize PORTABLE C */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -72,6 +72,9 @@
/* fixed parameter/variable */
/* names conflict C++ keyword, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Yajun Xia Modified comment(s), */
+/* added standalone support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_device_class_printer_uninitialize(UX_SLAVE_CLASS_COMMAND *command)
@@ -89,13 +92,13 @@ UX_SLAVE_CLASS *class_ptr;
/* Sanity check. */
if (printer != UX_NULL)
{
-
+#if !defined(UX_DEVICE_STANDALONE)
/* Delete the IN endpoint mutex. */
_ux_device_mutex_delete(&printer -> ux_device_class_printer_endpoint_in_mutex);
/* Out Mutex. */
_ux_device_mutex_delete(&printer -> ux_device_class_printer_endpoint_out_mutex);
-
+#endif
/* Free the resources. */
_ux_utility_memory_free(printer);
}
diff --git a/common/usbx_device_classes/src/ux_device_class_printer_write_run.c b/common/usbx_device_classes/src/ux_device_class_printer_write_run.c
new file mode 100644
index 0000000..d078cd4
--- /dev/null
+++ b/common/usbx_device_classes/src/ux_device_class_printer_write_run.c
@@ -0,0 +1,258 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) Microsoft Corporation. All rights reserved. */
+/* */
+/* This software is licensed under the Microsoft Software License */
+/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+/* and in the root directory of this software. */
+/* */
+/**************************************************************************/
+
+/**************************************************************************/
+/**************************************************************************/
+/** */
+/** USBX Component */
+/** */
+/** Device Printer Class */
+/** */
+/**************************************************************************/
+/**************************************************************************/
+
+#define UX_SOURCE_CODE
+
+
+/* Include necessary system files. */
+
+#include "ux_api.h"
+#include "ux_device_class_printer.h"
+#include "ux_device_stack.h"
+
+
+#if defined(UX_DEVICE_STANDALONE)
+
+/**************************************************************************/
+/* */
+/* FUNCTION RELEASE */
+/* */
+/* _ux_device_class_printer_write_run PORTABLE C */
+/* 6.2.0 */
+/* AUTHOR */
+/* */
+/* Yajun Xia, Microsoft Corporation */
+/* */
+/* DESCRIPTION */
+/* */
+/* This function writes to the Printer class. */
+/* */
+/* It's for standalone mode. */
+/* */
+/* INPUT */
+/* */
+/* printer Address of printer class */
+/* instance */
+/* buffer Pointer to data to write */
+/* requested_length Length of bytes to write, */
+/* set to 0 to issue ZLP */
+/* actual_length Pointer to save number of */
+/* bytes written */
+/* */
+/* OUTPUT */
+/* */
+/* State machine Status to check */
+/* UX_STATE_NEXT Transfer done, to next state */
+/* UX_STATE_EXIT Abnormal, to reset state */
+/* (others) Keep running, waiting */
+/* */
+/* CALLS */
+/* */
+/* _ux_device_stack_transfer_run Run Transfer state machine */
+/* _ux_utility_memory_copy Copy memory */
+/* */
+/* CALLED BY */
+/* */
+/* Application */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 10-31-2022 Yajun Xia Initial Version 6.2.0 */
+/* */
+/**************************************************************************/
+UINT _ux_device_class_printer_write_run(UX_DEVICE_CLASS_PRINTER *printer, UCHAR *buffer,
+ ULONG requested_length, ULONG *actual_length)
+{
+
+UX_SLAVE_ENDPOINT *endpoint;
+UX_SLAVE_DEVICE *device;
+UX_SLAVE_TRANSFER *transfer_request;
+UINT zlp = UX_FALSE;
+UINT status = 0;
+
+ /* If trace is enabled, insert this event into the trace buffer. */
+ UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_CLASS_PRINTER_WRITE, printer, buffer, requested_length, 0, UX_TRACE_DEVICE_CLASS_EVENTS, 0, 0)
+
+ /* Get the pointer to the device. */
+ device = &_ux_system_slave -> ux_system_slave_device;
+
+ /* As long as the device is in the CONFIGURED state. */
+ if (device -> ux_slave_device_state != UX_DEVICE_CONFIGURED)
+ {
+
+ /* Error trap. */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_CONFIGURATION_HANDLE_UNKNOWN);
+
+ /* If trace is enabled, insert this event into the trace buffer. */
+ UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_CONFIGURATION_HANDLE_UNKNOWN, device, 0, 0, UX_TRACE_ERRORS, 0, 0)
+
+ /* Cannot proceed with command, the interface is down. */
+ printer -> ux_device_class_printer_write_state = UX_STATE_RESET;
+ printer -> ux_device_class_printer_write_status = UX_CONFIGURATION_HANDLE_UNKNOWN;
+
+ return(UX_STATE_EXIT);
+ }
+
+ /* Locate the endpoints. */
+ endpoint = printer -> ux_device_class_printer_endpoint_in;
+
+ /* Check if it's available. */
+ if (endpoint == UX_NULL)
+ {
+ /* Error trap. */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_ENDPOINT_HANDLE_UNKNOWN);
+
+ printer -> ux_device_class_printer_write_state = UX_STATE_RESET;
+ printer -> ux_device_class_printer_write_status = UX_ENDPOINT_HANDLE_UNKNOWN;
+
+ return(UX_STATE_EXIT);
+ }
+
+ /* We are writing to the IN endpoint. */
+ transfer_request = &endpoint -> ux_slave_endpoint_transfer_request;
+
+ /* Handle state cases. */
+ switch(printer -> ux_device_class_printer_write_state)
+ {
+ case UX_STATE_RESET:
+ printer -> ux_device_class_printer_write_state = UX_DEVICE_CLASS_PRINTER_WRITE_START;
+ printer -> ux_device_class_printer_write_status = UX_TRANSFER_NO_ANSWER;
+ printer -> ux_device_class_printer_write_buffer = buffer;
+ printer -> ux_device_class_printer_write_requested_length = requested_length;
+ printer -> ux_device_class_printer_write_actual_length = 0;
+ printer -> ux_device_class_printer_write_host_length = UX_SLAVE_REQUEST_DATA_MAX_LENGTH;
+ if (requested_length == 0)
+ zlp = UX_TRUE;
+
+ /* Fall through. */
+ case UX_DEVICE_CLASS_PRINTER_WRITE_START:
+
+ /* Get remaining requested length. */
+ requested_length = printer -> ux_device_class_printer_write_requested_length -
+ printer -> ux_device_class_printer_write_actual_length;
+
+ /* There is no remaining, we are done. */
+ if (requested_length == 0 && !zlp)
+ {
+ *actual_length = printer -> ux_device_class_printer_write_actual_length;
+ printer -> ux_device_class_printer_write_state = UX_STATE_RESET;
+ printer -> ux_device_class_printer_write_status = UX_SUCCESS;
+ return(UX_STATE_NEXT);
+ }
+
+ /* Check if we have enough in the local buffer. */
+ if (requested_length > UX_SLAVE_REQUEST_DATA_MAX_LENGTH)
+
+ /* We have too much to transfer. */
+ printer -> ux_device_class_printer_write_transfer_length =
+ UX_SLAVE_REQUEST_DATA_MAX_LENGTH;
+
+ else
+ {
+
+ /* We can proceed with the demanded length. */
+ printer -> ux_device_class_printer_write_transfer_length = requested_length;
+
+#if !defined(UX_DEVICE_CLASS_PRINTER_WRITE_AUTO_ZLP)
+
+ /* Assume expected length and transfer length match. */
+ printer -> ux_device_class_printer_write_host_length = requested_length;
+#else
+
+ /* Assume expected more than transfer to let stack append ZLP if needed. */
+ printer -> ux_device_class_printer_write_host_length = UX_SLAVE_REQUEST_DATA_MAX_LENGTH + 1;
+#endif
+ }
+
+
+ /* On a out, we copy the buffer to the caller. Not very efficient but it makes the API
+ easier. */
+ _ux_utility_memory_copy(transfer_request -> ux_slave_transfer_request_data_pointer,
+ printer -> ux_device_class_printer_write_buffer,
+ printer -> ux_device_class_printer_write_transfer_length); /* Use case of memcpy is verified. */
+
+ /* Next state. */
+ printer -> ux_device_class_printer_write_state = UX_DEVICE_CLASS_PRINTER_WRITE_WAIT;
+ UX_SLAVE_TRANSFER_STATE_RESET(transfer_request);
+
+ /* Fall through. */
+ case UX_DEVICE_CLASS_PRINTER_WRITE_WAIT:
+
+ /* Send the request to the device controller. */
+ status = _ux_device_stack_transfer_run(transfer_request,
+ printer -> ux_device_class_printer_write_transfer_length,
+ printer -> ux_device_class_printer_write_host_length);
+
+ /* Error case. */
+ if (status < UX_STATE_NEXT)
+ {
+
+ printer -> ux_device_class_printer_write_state = UX_STATE_RESET;
+ printer -> ux_device_class_printer_write_status =
+ transfer_request -> ux_slave_transfer_request_completion_code;
+ return(UX_STATE_ERROR);
+ }
+
+ /* Success case. */
+ if (status == UX_STATE_NEXT)
+ {
+
+ /* Next buffer address. */
+ printer -> ux_device_class_printer_write_buffer +=
+ transfer_request -> ux_slave_transfer_request_actual_length;
+
+ /* Set the length actually received. */
+ printer -> ux_device_class_printer_write_actual_length +=
+ transfer_request -> ux_slave_transfer_request_actual_length;
+
+ /* Last transfer status. */
+ printer -> ux_device_class_printer_write_status =
+ transfer_request -> ux_slave_transfer_request_completion_code;
+
+ /* Update actual done length. */
+ *actual_length = printer -> ux_device_class_printer_write_actual_length;
+
+ /* Check ZLP case. */
+ if (printer -> ux_device_class_printer_write_requested_length == 0)
+ {
+ printer -> ux_device_class_printer_write_state = UX_STATE_RESET;
+ return(UX_STATE_NEXT);
+ }
+
+ /* Next state. */
+ printer -> ux_device_class_printer_write_state = UX_DEVICE_CLASS_PRINTER_WRITE_START;
+ }
+
+ /* Keep waiting. */
+ return(UX_STATE_WAIT);
+
+ default: /* Error. */
+ printer -> ux_device_class_printer_write_state = UX_STATE_RESET;
+ break;
+ }
+
+ /* Error case. */
+ return(UX_STATE_EXIT);
+}
+
+#endif
diff --git a/common/usbx_device_classes/src/ux_device_class_rndis_bulkin_thread.c b/common/usbx_device_classes/src/ux_device_class_rndis_bulkin_thread.c
index be900a9..92c1115 100644
--- a/common/usbx_device_classes/src/ux_device_class_rndis_bulkin_thread.c
+++ b/common/usbx_device_classes/src/ux_device_class_rndis_bulkin_thread.c
@@ -35,7 +35,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_rndis_bulkin_thread PORTABLE C */
-/* 6.1.11 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -85,6 +85,9 @@
/* 04-25-2022 Chaoqiong Xiao Modified comment(s), */
/* fixed standalone compile, */
/* resulting in version 6.1.11 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* used NX API to copy data, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
VOID _ux_device_class_rndis_bulkin_thread(ULONG rndis_class)
@@ -97,8 +100,8 @@ UX_SLAVE_TRANSFER *transfer_request;
UINT status;
ULONG actual_flags;
NX_PACKET *current_packet;
-UCHAR *packet_header;
ULONG transfer_length;
+ULONG copied;
/* Cast properly the rndis instance. */
UX_THREAD_EXTENSION_PTR_GET(class_ptr, UX_SLAVE_CLASS, rndis_class)
@@ -150,9 +153,6 @@ ULONG transfer_length;
if (rndis -> ux_slave_class_rndis_link_state == UX_DEVICE_CLASS_RNDIS_LINK_STATE_UP)
{
- /* Load the address of the current packet header at the physical header. */
- packet_header = current_packet -> nx_packet_prepend_ptr;
-
/* Calculate the transfer length. */
transfer_length = current_packet -> nx_packet_length + UX_DEVICE_CLASS_RNDIS_PACKET_HEADER_LENGTH;
@@ -161,21 +161,27 @@ ULONG transfer_length;
{
/* Copy the packet in the transfer descriptor buffer. */
- _ux_utility_memory_copy (transfer_request -> ux_slave_transfer_request_data_pointer + UX_DEVICE_CLASS_RNDIS_PACKET_HEADER_LENGTH, packet_header, current_packet -> nx_packet_length); /* Use case of memcpy is verified. */
-
- /* Add the RNDIS header to this packet. */
- _ux_utility_long_put(transfer_request -> ux_slave_transfer_request_data_pointer + UX_DEVICE_CLASS_RNDIS_PACKET_MESSAGE_TYPE, UX_DEVICE_CLASS_RNDIS_PACKET_HEADER_MSG);
- _ux_utility_long_put(transfer_request -> ux_slave_transfer_request_data_pointer + UX_DEVICE_CLASS_RNDIS_PACKET_MESSAGE_LENGTH, transfer_length);
- _ux_utility_long_put(transfer_request -> ux_slave_transfer_request_data_pointer + UX_DEVICE_CLASS_RNDIS_PACKET_DATA_OFFSET,
- UX_DEVICE_CLASS_RNDIS_PACKET_HEADER_LENGTH - UX_DEVICE_CLASS_RNDIS_PACKET_DATA_OFFSET);
- _ux_utility_long_put(transfer_request -> ux_slave_transfer_request_data_pointer + UX_DEVICE_CLASS_RNDIS_PACKET_DATA_LENGTH, current_packet -> nx_packet_length);
-
- /* If trace is enabled, insert this event into the trace buffer. */
- UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_CLASS_RNDIS_PACKET_TRANSMIT, rndis, 0, 0, 0, UX_TRACE_DEVICE_CLASS_EVENTS, 0, 0)
+ status = nx_packet_data_extract_offset(current_packet, 0,
+ transfer_request -> ux_slave_transfer_request_data_pointer +
+ UX_DEVICE_CLASS_RNDIS_PACKET_HEADER_LENGTH,
+ current_packet -> nx_packet_length, &copied);
+ if (status == NX_SUCCESS)
+ {
+
+ /* Add the RNDIS header to this packet. */
+ _ux_utility_long_put(transfer_request -> ux_slave_transfer_request_data_pointer + UX_DEVICE_CLASS_RNDIS_PACKET_MESSAGE_TYPE, UX_DEVICE_CLASS_RNDIS_PACKET_HEADER_MSG);
+ _ux_utility_long_put(transfer_request -> ux_slave_transfer_request_data_pointer + UX_DEVICE_CLASS_RNDIS_PACKET_MESSAGE_LENGTH, transfer_length);
+ _ux_utility_long_put(transfer_request -> ux_slave_transfer_request_data_pointer + UX_DEVICE_CLASS_RNDIS_PACKET_DATA_OFFSET,
+ UX_DEVICE_CLASS_RNDIS_PACKET_HEADER_LENGTH - UX_DEVICE_CLASS_RNDIS_PACKET_DATA_OFFSET);
+ _ux_utility_long_put(transfer_request -> ux_slave_transfer_request_data_pointer + UX_DEVICE_CLASS_RNDIS_PACKET_DATA_LENGTH, current_packet -> nx_packet_length);
+
+ /* If trace is enabled, insert this event into the trace buffer. */
+ UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_CLASS_RNDIS_PACKET_TRANSMIT, rndis, 0, 0, 0, UX_TRACE_DEVICE_CLASS_EVENTS, 0, 0)
+
+ /* Send the request to the device controller. */
+ status = _ux_device_stack_transfer_request(transfer_request, transfer_length, UX_DEVICE_CLASS_RNDIS_ETHERNET_PACKET_SIZE + 1);
+ }
- /* Send the request to the device controller. */
- status = _ux_device_stack_transfer_request(transfer_request, transfer_length, UX_DEVICE_CLASS_RNDIS_ETHERNET_PACKET_SIZE);
-
/* Check for error. */
if (status != UX_SUCCESS)
diff --git a/common/usbx_device_classes/src/ux_device_class_rndis_bulkout_thread.c b/common/usbx_device_classes/src/ux_device_class_rndis_bulkout_thread.c
index a569e5f..1fcc35a 100644
--- a/common/usbx_device_classes/src/ux_device_class_rndis_bulkout_thread.c
+++ b/common/usbx_device_classes/src/ux_device_class_rndis_bulkout_thread.c
@@ -35,7 +35,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_rndis_bulkout_thread PORTABLE C */
-/* 6.1.11 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -84,6 +84,10 @@
/* 04-25-2022 Chaoqiong Xiao Modified comment(s), */
/* fixed standalone compile, */
/* resulting in version 6.1.11 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* used NX API to copy data, */
+/* used linked NX IP pool, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
VOID _ux_device_class_rndis_bulkout_thread(ULONG rndis_class)
@@ -95,8 +99,8 @@ UX_SLAVE_DEVICE *device;
UX_SLAVE_TRANSFER *transfer_request;
UINT status;
NX_PACKET *packet;
-ULONG ip_given_length;
ULONG packet_payload;
+USB_NETWORK_DEVICE_TYPE *ux_nx_device;
/* Cast properly the rndis instance. */
UX_THREAD_EXTENSION_PTR_GET(class_ptr, UX_SLAVE_CLASS, rndis_class)
@@ -117,16 +121,39 @@ ULONG packet_payload;
/* As long as the device is in the CONFIGURED state. */
while (device -> ux_slave_device_state == UX_DEVICE_CONFIGURED)
{
-
+
+ /* Check if packet pool is ready. */
+ if (rndis -> ux_slave_class_rndis_packet_pool == UX_NULL)
+ {
+
+ /* Get the network device handle. */
+ ux_nx_device = (USB_NETWORK_DEVICE_TYPE *)(rndis -> ux_slave_class_rndis_network_handle);
+
+ /* Get packet pool from IP instance (if available). */
+ if (ux_nx_device -> ux_network_device_ip_instance != UX_NULL)
+ {
+ rndis -> ux_slave_class_rndis_packet_pool = ux_nx_device -> ux_network_device_ip_instance -> nx_ip_default_packet_pool;
+ }
+ else
+ {
+
+ /* Error trap. */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_CLASS_ETH_PACKET_POOL_ERROR);
+
+ _ux_utility_delay_ms(UX_DEVICE_CLASS_RNDIS_PACKET_POOL_INST_WAIT);
+ continue;
+ }
+ }
+
/* We can accept new reception. Get a NX Packet. */
- status = nx_packet_allocate(&rndis -> ux_slave_class_rndis_packet_pool, &packet,
+ status = nx_packet_allocate(rndis -> ux_slave_class_rndis_packet_pool, &packet,
NX_RECEIVE_PACKET, UX_MS_TO_TICK(UX_DEVICE_CLASS_RNDIS_PACKET_POOL_WAIT));
if (status == NX_SUCCESS)
{
/* And length. */
- transfer_request -> ux_slave_transfer_request_requested_length = UX_DEVICE_CLASS_RNDIS_MAX_PACKET_LENGTH;
+ transfer_request -> ux_slave_transfer_request_requested_length = UX_DEVICE_CLASS_RNDIS_MAX_MSG_LENGTH;
transfer_request -> ux_slave_transfer_request_actual_length = 0;
/* Memorize this packet at the beginning of the queue. */
@@ -136,8 +163,8 @@ ULONG packet_payload;
packet -> nx_packet_queue_next = UX_NULL;
/* Send the request to the device controller. */
- status = _ux_device_stack_transfer_request(transfer_request, UX_DEVICE_CLASS_RNDIS_MAX_PACKET_LENGTH + UX_DEVICE_CLASS_RNDIS_PACKET_HEADER_LENGTH,
- UX_DEVICE_CLASS_RNDIS_MAX_PACKET_LENGTH + UX_DEVICE_CLASS_RNDIS_PACKET_HEADER_LENGTH);
+ status = _ux_device_stack_transfer_request(transfer_request, UX_DEVICE_CLASS_RNDIS_MAX_MSG_LENGTH,
+ UX_DEVICE_CLASS_RNDIS_MAX_MSG_LENGTH);
/* Check the completion code. */
if (status == UX_SUCCESS)
@@ -147,63 +174,71 @@ ULONG packet_payload;
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_CLASS_RNDIS_PACKET_RECEIVE, rndis, 0, 0, 0, UX_TRACE_DEVICE_CLASS_EVENTS, 0, 0)
- /* Check the state of the transfer. If there is an error, we do not proceed with this report. Also ensure the header has a valid ID of 1. */
- if (_ux_utility_long_get(transfer_request -> ux_slave_transfer_request_data_pointer + UX_DEVICE_CLASS_RNDIS_PACKET_MESSAGE_TYPE) == UX_DEVICE_CLASS_RNDIS_PACKET_HEADER_MSG)
+ /* Check the state of the transfer. If there is an error, we do not proceed with this report.
+ Ensure this packet is at least larger than the header.
+ Also ensure the header has a valid ID of 1. */
+ if (transfer_request -> ux_slave_transfer_request_actual_length > UX_DEVICE_CLASS_RNDIS_PACKET_HEADER_LENGTH &&
+ _ux_utility_long_get(transfer_request -> ux_slave_transfer_request_data_pointer + UX_DEVICE_CLASS_RNDIS_PACKET_MESSAGE_TYPE) == UX_DEVICE_CLASS_RNDIS_PACKET_HEADER_MSG)
{
- /* Ensure this packet is at least larger than the header. */
- if (transfer_request -> ux_slave_transfer_request_actual_length > UX_DEVICE_CLASS_RNDIS_PACKET_HEADER_LENGTH)
- {
-
- /* Get the size of the payload. */
- packet_payload = _ux_utility_long_get(transfer_request -> ux_slave_transfer_request_data_pointer + UX_DEVICE_CLASS_RNDIS_PACKET_DATA_LENGTH);
-
- /* Ensure the length reported in the RNDIS header is not larger than it actually is.
- The reason we can't check to see if the length reported in the header and the
- actual length are exactly equal is because there might other data after the payload
- (padding, or even a message). */
- if (packet_payload <= transfer_request -> ux_slave_transfer_request_actual_length - UX_DEVICE_CLASS_RNDIS_PACKET_HEADER_LENGTH)
- {
+ /* Get the size of the payload. */
+ packet_payload = _ux_utility_long_get(transfer_request -> ux_slave_transfer_request_data_pointer + UX_DEVICE_CLASS_RNDIS_PACKET_DATA_LENGTH);
- /* Adjust the prepend pointer to take into account the non 3 bit alignment of the ethernet header. */
- packet -> nx_packet_prepend_ptr += sizeof(USHORT);
-
- /* Adjust the prepend, length, and append fields. */
- packet -> nx_packet_length = packet_payload;
- packet -> nx_packet_append_ptr = packet -> nx_packet_prepend_ptr + packet_payload;
-
+ /* Ensure the length reported in the RNDIS header is not larger than it actually is.
+ The reason we can't check to see if the length reported in the header and the
+ actual length are exactly equal is because there might other data after the payload
+ (padding, or even a message). */
+ if (packet_payload <= transfer_request -> ux_slave_transfer_request_actual_length - UX_DEVICE_CLASS_RNDIS_PACKET_HEADER_LENGTH)
+ {
- /* Copy the received packet in the IP packet data area. */
- _ux_utility_memory_copy(packet -> nx_packet_prepend_ptr, transfer_request -> ux_slave_transfer_request_data_pointer + UX_DEVICE_CLASS_RNDIS_PACKET_BUFFER, packet_payload); /* Use case of memcpy is verified. */
-
- /* Calculate the accurate packet length from ip header */
- if((*(packet -> nx_packet_prepend_ptr + 12) == 0x08) &&
- (*(packet -> nx_packet_prepend_ptr + 13) == 0))
- {
+ /* Adjust the prepend pointer to take into account the non 3 bit alignment of the ethernet header. */
+ packet -> nx_packet_prepend_ptr += sizeof(USHORT);
+ packet -> nx_packet_append_ptr += sizeof(USHORT);
- ip_given_length = _ux_utility_short_get_big_endian(packet -> nx_packet_prepend_ptr + 16) + UX_DEVICE_CLASS_RNDIS_ETHERNET_SIZE;
- packet -> nx_packet_length = ip_given_length ;
- packet -> nx_packet_append_ptr = packet -> nx_packet_prepend_ptr + ip_given_length;
- }
+ /* Copy the received packet in the IP packet data area. */
+ status = nx_packet_data_append(packet,
+ transfer_request -> ux_slave_transfer_request_data_pointer +
+ UX_DEVICE_CLASS_RNDIS_PACKET_BUFFER,
+ packet_payload,
+ rndis -> ux_slave_class_rndis_packet_pool,
+ UX_MS_TO_TICK(UX_DEVICE_CLASS_RNDIS_PACKET_POOL_WAIT));
+ if (status == UX_SUCCESS)
+ {
/* Send that packet to the NetX USB broker. */
_ux_network_driver_packet_received(rndis -> ux_slave_class_rndis_network_handle, packet);
}
else
+ {
- /* We received a malformed packet. Report to application. */
- _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_CLASS_MALFORMED_PACKET_RECEIVED_ERROR);
+ /* Error. */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_CLASS_ETH_PACKET_ERROR);
+ nx_packet_release(packet);
+ }
}
else
+ {
/* We received a malformed packet. Report to application. */
_ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_CLASS_MALFORMED_PACKET_RECEIVED_ERROR);
+ nx_packet_release(packet);
+ }
+ }
+ else
+ {
+
+ /* We received a malformed packet. Report to application. */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_CLASS_MALFORMED_PACKET_RECEIVED_ERROR);
+ nx_packet_release(packet);
}
}
else
+ {
/* Free the packet that was not successfully received. */
nx_packet_release(packet);
+ }
+
}
else
{
diff --git a/common/usbx_device_classes/src/ux_device_class_rndis_initialize.c b/common/usbx_device_classes/src/ux_device_class_rndis_initialize.c
index 8af7732..18604e8 100644
--- a/common/usbx_device_classes/src/ux_device_class_rndis_initialize.c
+++ b/common/usbx_device_classes/src/ux_device_class_rndis_initialize.c
@@ -78,7 +78,7 @@ ULONG ux_device_class_rndis_oid_supported_list[UX_DEVICE_CLASS_RNDIS_OID_SUPPORT
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_rndis_initialize PORTABLE C */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -136,6 +136,9 @@ ULONG ux_device_class_rndis_oid_supported_list[UX_DEVICE_CLASS_RNDIS_OID_SUPPORT
/* fixed parameter/variable */
/* names conflict C++ keyword, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* removed internal NX pool, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_device_class_rndis_initialize(UX_SLAVE_CLASS_COMMAND *command)
@@ -294,31 +297,6 @@ UINT status;
status = UX_EVENT_ERROR;
}
- /* Allocate some packet pool for reception. */
- if (status == UX_SUCCESS)
- {
-
- /* UX_DEVICE_CLASS_RNDIS_NX_ETHERNET_POOL_ALLOCSIZE overflow has been checked by
- * UX_DEVICE_CLASS_RNDIS_NX_ETHERNET_POOL_ALLOCSIZE_ASSERT outside of function.
- */
- rndis -> ux_slave_class_rndis_pool_memory = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_CACHE_SAFE_MEMORY, UX_DEVICE_CLASS_RNDIS_NX_ETHERNET_POOL_ALLOCSIZE);
-
- /* Check the completion status. */
- if (rndis -> ux_slave_class_rndis_pool_memory == UX_NULL)
- status = UX_MEMORY_INSUFFICIENT;
- }
-
- /* Create a packet pool. */
- if (status == UX_SUCCESS)
- {
- status = nx_packet_pool_create(&rndis -> ux_slave_class_rndis_packet_pool, "Rndis Device Packet Pool",
- UX_DEVICE_CLASS_RNDIS_NX_PAYLOAD_SIZE, rndis -> ux_slave_class_rndis_pool_memory, UX_DEVICE_CLASS_RNDIS_NX_ETHERNET_POOL_ALLOCSIZE);
-
- /* Check for pool creation error. */
- if (status != UX_SUCCESS)
- status = UX_MEMORY_INSUFFICIENT;
- }
-
/* Create a semaphore for protecting the driver entry. */
if (status == UX_SUCCESS)
{
@@ -338,14 +316,6 @@ UINT status;
if (rndis -> ux_slave_class_rndis_semaphore.tx_semaphore_id != 0)
_ux_device_semaphore_delete(&rndis -> ux_slave_class_rndis_semaphore);
- /* Delete the packet pool. */
- if (rndis -> ux_slave_class_rndis_packet_pool.nx_packet_pool_id != 0)
- nx_packet_pool_delete(&rndis -> ux_slave_class_rndis_packet_pool);
-
- /* Free rndis -> ux_slave_class_rndis_pool_memory. */
- if (rndis -> ux_slave_class_rndis_pool_memory)
- _ux_utility_memory_free(rndis -> ux_slave_class_rndis_pool_memory);
-
/* Delete rndis -> ux_slave_class_rndis_event_flags_group. */
if (rndis -> ux_slave_class_rndis_event_flags_group.tx_event_flags_group_id != 0)
_ux_utility_event_flags_delete(&rndis -> ux_slave_class_rndis_event_flags_group);
diff --git a/common/usbx_device_classes/src/ux_device_class_storage_tasks_run.c b/common/usbx_device_classes/src/ux_device_class_storage_tasks_run.c
index 2acafd4..a3652f6 100644
--- a/common/usbx_device_classes/src/ux_device_class_storage_tasks_run.c
+++ b/common/usbx_device_classes/src/ux_device_class_storage_tasks_run.c
@@ -65,7 +65,7 @@ static inline VOID _ux_device_class_storage_disk_error(UX_SLAVE_CLASS_STORAGE *s
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_storage_tasks_run PORTABLE C */
-/* 6.1.10 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -125,6 +125,9 @@ static inline VOID _ux_device_class_storage_disk_error(UX_SLAVE_CLASS_STORAGE *s
/* DATE NAME DESCRIPTION */
/* */
/* 01-31-2022 Chaoqiong Xiao Initial Version 6.1.10 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* improved internal logic, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_device_class_storage_tasks_run(VOID *instance)
@@ -148,13 +151,14 @@ static inline UINT _ux_device_class_storage_task_usb(UX_SLAVE_CLASS_STORAGE *sto
UX_SLAVE_DEVICE *device;
UCHAR state;
UINT status;
+INT immediate_state = UX_TRUE;
/* Get pointer to the device. */
device = &_ux_system_slave -> ux_system_slave_device;
/* Run states once. */
- while(1)
+ while(immediate_state)
{
/* General check for MSC ready. */
@@ -301,9 +305,12 @@ UINT status;
break;
}
- /* Unhandled, just do again by app call. */
- return(UX_STATE_EXIT);
+ /* Unhandled, just break the loop and do again by app call. */
+ immediate_state = UX_FALSE;
}
+
+ /* Unhandled state. */
+ return(UX_STATE_EXIT);
}
static inline VOID _ux_device_class_storage_cbw_receive(UX_SLAVE_CLASS_STORAGE *storage)
@@ -979,9 +986,10 @@ static inline VOID _ux_device_class_storage_task_disk(UX_SLAVE_CLASS_STORAGE *st
{
UCHAR state = storage -> ux_device_class_storage_disk_state;
UINT status;
+INT immediate_state = UX_TRUE;
/* Run states once. */
- while(1)
+ while(immediate_state)
{
/* Update state. */
@@ -1035,8 +1043,8 @@ UINT status;
break;
}
- /* Task run once. */
- return;
+ /* Task run once, break the loop. */
+ immediate_state = UX_FALSE;
}
}
static inline VOID _ux_device_class_storage_disk_start(UX_SLAVE_CLASS_STORAGE *storage)
@@ -1058,6 +1066,8 @@ ULONG max_n_blocks;
/* Max blocks for one buffer. */
block_size = storage -> ux_slave_class_storage_lun[storage -> ux_slave_class_storage_cbw_lun].
ux_slave_class_storage_media_block_length;
+ if (block_size == 0)
+ UX_ASSERT(UX_FALSE);
max_n_blocks = UX_SLAVE_CLASS_STORAGE_BUFFER_SIZE / block_size;
/* Prepare next disk read. */
diff --git a/common/usbx_device_classes/src/ux_device_class_video_activate.c b/common/usbx_device_classes/src/ux_device_class_video_activate.c
index 80e71f6..7d78048 100644
--- a/common/usbx_device_classes/src/ux_device_class_video_activate.c
+++ b/common/usbx_device_classes/src/ux_device_class_video_activate.c
@@ -33,7 +33,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_video_activate PORTABLE C */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -67,6 +67,9 @@
/* fixed parameter/variable */
/* names conflict C++ keyword, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* added standalone support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_device_class_video_activate(UX_SLAVE_CLASS_COMMAND *command)
@@ -154,6 +157,14 @@ ULONG stream_index;
/* Store the class instance into the interface. */
stream_interface -> ux_slave_interface_class_instance = (VOID *)video;
+
+#if defined(UX_DEVICE_STANDALONE)
+
+ /* Reset stream task state. */
+ stream -> ux_device_class_video_stream_task_state = UX_STATE_RESET;
+ stream -> ux_device_class_video_stream_task_status = UX_SUCCESS;
+#endif
+
}
/* If there is a activate function call it. */
diff --git a/common/usbx_device_classes/src/ux_device_class_video_change.c b/common/usbx_device_classes/src/ux_device_class_video_change.c
index 199fcc6..9bf5e01 100644
--- a/common/usbx_device_classes/src/ux_device_class_video_change.c
+++ b/common/usbx_device_classes/src/ux_device_class_video_change.c
@@ -33,7 +33,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_video_change PORTABLE C */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -67,6 +67,9 @@
/* fixed parameter/variable */
/* names conflict C++ keyword, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* added standalone support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_device_class_video_change(UX_SLAVE_CLASS_COMMAND *command)
@@ -160,6 +163,15 @@ ULONG stream_index;
return(UX_DESCRIPTOR_CORRUPTED);
}
+#if defined(UX_DEVICE_STANDALONE)
+
+ /* Reset background transfer state. */
+ stream -> ux_device_class_video_stream_task_state = UX_STATE_RESET;
+#endif
+
+ /* Now reset payload buffer error count. */
+ stream -> ux_device_class_video_stream_buffer_error_count = 0;
+
/* Now reset payload buffers. */
payload_buffer = stream -> ux_device_class_video_stream_buffer;
while(payload_buffer < stream -> ux_device_class_video_stream_buffer + stream -> ux_device_class_video_stream_buffer_size)
diff --git a/common/usbx_device_classes/src/ux_device_class_video_initialize.c b/common/usbx_device_classes/src/ux_device_class_video_initialize.c
index 8ffb9fe..625bc4f 100644
--- a/common/usbx_device_classes/src/ux_device_class_video_initialize.c
+++ b/common/usbx_device_classes/src/ux_device_class_video_initialize.c
@@ -33,7 +33,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_video_initialize PORTABLE C */
-/* 6.1.11 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -67,14 +67,13 @@
/* DATE NAME DESCRIPTION */
/* */
/* 04-25-2022 Chaoqiong Xiao Initial Version 6.1.11 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* added standalone support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_device_class_video_initialize(UX_SLAVE_CLASS_COMMAND *command)
{
-#if defined(UX_DEVICE_STANDALONE)
- UX_PARAMETER_NOT_USED(command);
- return(UX_FUNCTION_NOT_SUPPORTED);
-#else
UINT status = UX_SUCCESS;
UX_DEVICE_CLASS_VIDEO *video;
@@ -163,6 +162,9 @@ ULONG i;
stream -> ux_device_class_video_stream_transfer_pos = (UX_DEVICE_CLASS_VIDEO_PAYLOAD *)stream -> ux_device_class_video_stream_buffer;
stream -> ux_device_class_video_stream_access_pos = stream -> ux_device_class_video_stream_transfer_pos;
+
+#if !defined(UX_DEVICE_STANDALONE)
+
/* Create memory block for streaming thread stack in addition. */
if (stream_parameter -> ux_device_class_video_stream_parameter_thread_stack_size == 0)
memory_size = UX_DEVICE_CLASS_VIDEO_THREAD_STACK_SIZE;
@@ -189,6 +191,11 @@ ULONG i;
break;
UX_THREAD_EXTENSION_PTR_SET(&(stream -> ux_device_class_video_stream_thread), stream)
+#else
+
+ /* Save task function for streaming. */
+ stream -> ux_device_class_video_stream_task_function = stream_parameter -> ux_device_class_video_stream_parameter_task_function;
+#endif
/* Save callbacks. */
_ux_utility_memory_copy(&stream -> ux_device_class_video_stream_callbacks,
@@ -217,6 +224,12 @@ ULONG i;
&video_parameter -> ux_device_class_video_parameter_callbacks,
sizeof(UX_DEVICE_CLASS_VIDEO_CALLBACKS)); /* Use case of memcpy is verified. */
+#if defined(UX_DEVICE_STANDALONE)
+
+ /* Link task function. */
+ class_inst -> ux_slave_class_task_function = _ux_device_class_video_tasks_run;
+#endif
+
/* Return completion status. */
return(UX_SUCCESS);
}
@@ -228,10 +241,14 @@ ULONG i;
stream = video -> ux_device_class_video_streams;
for (i = 0; i < video -> ux_device_class_video_streams_nb; i ++)
{
+
+#if !defined(UX_DEVICE_STANDALONE)
if (stream -> ux_device_class_video_stream_thread.tx_thread_id)
_ux_utility_thread_delete(&stream -> ux_device_class_video_stream_thread);
if (stream -> ux_device_class_video_stream_thread_stack)
_ux_utility_memory_free(stream -> ux_device_class_video_stream_thread_stack);
+#endif
+
if (stream -> ux_device_class_video_stream_buffer)
_ux_utility_memory_free(stream -> ux_device_class_video_stream_buffer);
stream ++;
@@ -239,5 +256,4 @@ ULONG i;
_ux_utility_memory_free(video);
return(status);
-#endif
}
diff --git a/common/usbx_device_classes/src/ux_device_class_video_read_task_function.c b/common/usbx_device_classes/src/ux_device_class_video_read_task_function.c
new file mode 100644
index 0000000..a7422cc
--- /dev/null
+++ b/common/usbx_device_classes/src/ux_device_class_video_read_task_function.c
@@ -0,0 +1,188 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) Microsoft Corporation. All rights reserved. */
+/* */
+/* This software is licensed under the Microsoft Software License */
+/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+/* and in the root directory of this software. */
+/* */
+/**************************************************************************/
+
+/**************************************************************************/
+/**************************************************************************/
+/** */
+/** USBX Component */
+/** */
+/** Device Video Class */
+/** */
+/**************************************************************************/
+/**************************************************************************/
+
+#define UX_SOURCE_CODE
+
+
+/* Include necessary system files. */
+
+#include "ux_api.h"
+#include "ux_device_class_video.h"
+#include "ux_device_stack.h"
+
+
+#if defined(UX_DEVICE_STANDALONE)
+/**************************************************************************/
+/* */
+/* FUNCTION RELEASE */
+/* */
+/* _ux_device_class_video_read_task_function PORTABLE C */
+/* 6.2.0 */
+/* AUTHOR */
+/* */
+/* Chaoqiong Xiao, Microsoft Corporation */
+/* */
+/* DESCRIPTION */
+/* */
+/* This function is the background task of the video stream read. */
+/* */
+/* It's for standalone mode. */
+/* */
+/* INPUT */
+/* */
+/* stream Pointer to video stream */
+/* */
+/* OUTPUT */
+/* */
+/* State machine status */
+/* UX_STATE_EXIT Device not configured */
+/* UX_STATE_IDLE No streaming transfer running */
+/* UX_STATE_WAIT Streaming transfer running */
+/* */
+/* CALLS */
+/* */
+/* _ux_device_stack_transfer_run Run transfer state machine */
+/* _ux_utility_memory_copy Copy memory */
+/* */
+/* CALLED BY */
+/* */
+/* USBX Device Stack */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 10-31-2022 Chaoqiong Xiao Initial Version 6.2.0 */
+/* */
+/**************************************************************************/
+UINT _ux_device_class_video_read_task_function(UX_DEVICE_CLASS_VIDEO_STREAM *stream)
+{
+UX_SLAVE_DEVICE *device;
+UX_SLAVE_ENDPOINT *endpoint;
+UX_SLAVE_TRANSFER *transfer;
+UCHAR *next_pos;
+UX_DEVICE_CLASS_VIDEO_PAYLOAD *next_payload;
+ULONG max_packet_size;
+ULONG actual_length;
+UINT status;
+
+
+ /* Get the pointer to the device. */
+ device = stream -> ux_device_class_video_stream_video -> ux_device_class_video_device;
+
+ /* Check if the device is configured. */
+ if (device -> ux_slave_device_state != UX_DEVICE_CONFIGURED)
+ {
+ stream -> ux_device_class_video_stream_task_state = UX_STATE_EXIT;
+ return(UX_STATE_EXIT);
+ }
+
+ /* Get the endpoint. */
+ endpoint = stream -> ux_device_class_video_stream_endpoint;
+
+ /* No endpoint ready, maybe it's alternate setting 0. */
+ if (endpoint == UX_NULL)
+ return(UX_STATE_IDLE);
+
+ /* Check if background transfer task is started. */
+ if (stream -> ux_device_class_video_stream_task_state == UX_DEVICE_CLASS_VIDEO_STREAM_RW_STOP)
+ return(UX_STATE_IDLE);
+
+ /* Get transfer instance. */
+ transfer = &endpoint -> ux_slave_endpoint_transfer_request;
+
+ /* If not started yet, reset transfer and start polling. */
+ if (stream -> ux_device_class_video_stream_task_state == UX_DEVICE_CLASS_VIDEO_STREAM_RW_START)
+ {
+
+ /* Next state: transfer wait. */
+ stream -> ux_device_class_video_stream_task_state = UX_DEVICE_CLASS_VIDEO_STREAM_RW_WAIT;
+
+ /* Reset transfer state. */
+ UX_SLAVE_TRANSFER_STATE_RESET(transfer);
+ }
+
+ /* Run transfer state machine. */
+ max_packet_size = endpoint -> ux_slave_endpoint_transfer_request.
+ ux_slave_transfer_request_transfer_length;
+ status = _ux_device_stack_transfer_run(transfer, max_packet_size, max_packet_size);
+
+ /* Error case. */
+ if (status < UX_STATE_NEXT)
+ {
+
+ /* Error on background transfer task start. */
+ stream -> ux_device_class_video_stream_task_state = UX_STATE_RESET;
+ stream -> ux_device_class_video_stream_task_status =
+ transfer -> ux_slave_transfer_request_completion_code;
+
+ /* Error notification! */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_TRANSFER_ERROR);
+ return(UX_STATE_EXIT);
+ }
+
+ /* Success case. */
+ if (status == UX_STATE_NEXT)
+ {
+
+ /* Next state: start. */
+ stream -> ux_device_class_video_stream_task_state = UX_DEVICE_CLASS_VIDEO_STREAM_RW_START;
+ stream -> ux_device_class_video_stream_task_status =
+ transfer -> ux_slave_transfer_request_completion_code;
+
+ /* Get actual transfer length. */
+ actual_length = transfer -> ux_slave_transfer_request_actual_length;
+
+ /* Frame received, log it. */
+ stream -> ux_device_class_video_stream_transfer_pos -> ux_device_class_video_payload_length = actual_length;
+ _ux_utility_memory_copy(stream -> ux_device_class_video_stream_transfer_pos -> ux_device_class_video_payload_data,
+ transfer -> ux_slave_transfer_request_data_pointer,
+ actual_length); /* Use case of memcpy is verified. */
+
+ /* For simple, do not advance the transfer position if there is overflow. */
+ next_pos = (UCHAR *)stream -> ux_device_class_video_stream_transfer_pos;
+ next_pos += stream -> ux_device_class_video_stream_payload_buffer_size;
+ if (next_pos >= stream -> ux_device_class_video_stream_buffer + stream -> ux_device_class_video_stream_buffer_size)
+ next_pos = stream -> ux_device_class_video_stream_buffer;
+ next_payload = (UX_DEVICE_CLASS_VIDEO_PAYLOAD *)next_pos;
+
+ /* Check overflow! */
+ if (next_payload -> ux_device_class_video_payload_length > 0)
+ {
+
+ /* Error notification! */
+ stream -> ux_device_class_video_stream_buffer_error_count ++;
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_BUFFER_OVERFLOW);
+ }
+ else
+
+ /* Update transfer position. */
+ stream -> ux_device_class_video_stream_transfer_pos = next_payload;
+
+ /* Invoke notification callback. */
+ if (stream -> ux_device_class_video_stream_callbacks.ux_device_class_video_stream_payload_done != UX_NULL)
+ stream -> ux_device_class_video_stream_callbacks.ux_device_class_video_stream_payload_done(stream, actual_length);
+ }
+
+ /* Keep waiting. */
+ return(UX_STATE_WAIT);
+}
+#endif
diff --git a/common/usbx_device_classes/src/ux_device_class_video_read_thread_entry.c b/common/usbx_device_classes/src/ux_device_class_video_read_thread_entry.c
index e9cd669..060723d 100644
--- a/common/usbx_device_classes/src/ux_device_class_video_read_thread_entry.c
+++ b/common/usbx_device_classes/src/ux_device_class_video_read_thread_entry.c
@@ -35,7 +35,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_video_read_thread_entry PORTABLE C */
-/* 6.1.11 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -69,6 +69,9 @@
/* DATE NAME DESCRIPTION */
/* */
/* 04-25-2022 Chaoqiong Xiao Initial Version 6.1.11 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* added error statistics, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
VOID _ux_device_class_video_read_thread_entry(ULONG video_stream)
@@ -145,6 +148,7 @@ ULONG actual_length;
{
/* Error notification! */
+ stream -> ux_device_class_video_stream_buffer_error_count ++;
_ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_BUFFER_OVERFLOW);
}
else
diff --git a/common/usbx_device_classes/src/ux_device_class_video_reception_start.c b/common/usbx_device_classes/src/ux_device_class_video_reception_start.c
index 84be153..342b00e 100644
--- a/common/usbx_device_classes/src/ux_device_class_video_reception_start.c
+++ b/common/usbx_device_classes/src/ux_device_class_video_reception_start.c
@@ -34,7 +34,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_video_reception_start PORTABLE C */
-/* 6.1.11 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -65,14 +65,13 @@
/* DATE NAME DESCRIPTION */
/* */
/* 04-25-2022 Chaoqiong Xiao Initial Version 6.1.11 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* added standalone support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_device_class_video_reception_start(UX_DEVICE_CLASS_VIDEO_STREAM *stream)
{
-#if defined(UX_DEVICE_STANDALONE)
- UX_PARAMETER_NOT_USED(stream);
- return(UX_FUNCTION_NOT_SUPPORTED);
-#else
UX_SLAVE_ENDPOINT *endpoint;
UX_SLAVE_DEVICE *device;
@@ -102,8 +101,16 @@ UX_SLAVE_DEVICE *device;
if (stream -> ux_device_class_video_stream_transfer_pos -> ux_device_class_video_payload_length > 0)
return(UX_BUFFER_OVERFLOW);
+#if defined(UX_DEVICE_STANDALONE)
+
+ /* Start read task. */
+ if (stream -> ux_device_class_video_stream_task_state == UX_DEVICE_CLASS_VIDEO_STREAM_RW_STOP)
+ stream -> ux_device_class_video_stream_task_state = UX_DEVICE_CLASS_VIDEO_STREAM_RW_START;
+
+#else
/* Start read thread. */
_ux_utility_thread_resume(&stream -> ux_device_class_video_stream_thread);
- return(UX_SUCCESS);
#endif
+
+ return(UX_SUCCESS);
}
diff --git a/common/usbx_device_classes/src/ux_device_class_video_tasks_run.c b/common/usbx_device_classes/src/ux_device_class_video_tasks_run.c
new file mode 100644
index 0000000..24ca2ed
--- /dev/null
+++ b/common/usbx_device_classes/src/ux_device_class_video_tasks_run.c
@@ -0,0 +1,113 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) Microsoft Corporation. All rights reserved. */
+/* */
+/* This software is licensed under the Microsoft Software License */
+/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+/* and in the root directory of this software. */
+/* */
+/**************************************************************************/
+
+/**************************************************************************/
+/**************************************************************************/
+/** */
+/** USBX Component */
+/** */
+/** Device Video Class */
+/** */
+/**************************************************************************/
+/**************************************************************************/
+
+#define UX_SOURCE_CODE
+
+
+/* Include necessary system files. */
+
+#include "ux_api.h"
+#include "ux_device_class_video.h"
+#include "ux_device_stack.h"
+
+
+#if defined(UX_DEVICE_STANDALONE)
+/**************************************************************************/
+/* */
+/* FUNCTION RELEASE */
+/* */
+/* _ux_device_class_video_tasks_run PORTABLE C */
+/* 6.2.0 */
+/* AUTHOR */
+/* */
+/* Chaoqiong Xiao, Microsoft Corporation */
+/* */
+/* DESCRIPTION */
+/* */
+/* This function is the background task of the video. */
+/* */
+/* It's for standalone mode. */
+/* */
+/* INPUT */
+/* */
+/* instance Pointer to video class */
+/* */
+/* OUTPUT */
+/* */
+/* State machine status */
+/* UX_STATE_EXIT Device not configured */
+/* UX_STATE_IDLE No streaming transfer running */
+/* UX_STATE_WAIT Streaming transfer running */
+/* */
+/* CALLS */
+/* */
+/* (ux_device_class_video_stream_task_function) */
+/* Run stream task */
+/* */
+/* CALLED BY */
+/* */
+/* USBX Device Stack */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 10-31-2022 Chaoqiong Xiao Initial Version 6.2.0 */
+/* */
+/**************************************************************************/
+UINT _ux_device_class_video_tasks_run(VOID *instance)
+{
+UX_SLAVE_DEVICE *device;
+UX_DEVICE_CLASS_VIDEO *video;
+UX_DEVICE_CLASS_VIDEO_STREAM *stream;
+ULONG stream_index;
+UINT status;
+ULONG running_count;
+
+
+ /* Get Video instance. */
+ video = (UX_DEVICE_CLASS_VIDEO *) instance;
+
+ /* Get the pointer to the device. */
+ device = &_ux_system_slave -> ux_system_slave_device;
+
+ /* Check if the device is configured. */
+ if (device -> ux_slave_device_state != UX_DEVICE_CONFIGURED)
+ return(UX_STATE_EXIT);
+
+ /* Run video streaming tasks. */
+ running_count = 0;
+ for (stream_index = 0;
+ stream_index < video -> ux_device_class_video_streams_nb;
+ stream_index ++)
+ {
+ stream = &video -> ux_device_class_video_streams[stream_index];
+ status = stream -> ux_device_class_video_stream_task_function(stream);
+ if (status == UX_STATE_EXIT)
+ return(status);
+ if (status == UX_STATE_WAIT)
+ running_count ++;
+ }
+
+ /* Return state running. */
+ return (running_count > 0) ? (UX_STATE_WAIT) : (UX_STATE_IDLE);
+}
+#endif
diff --git a/common/usbx_device_classes/src/ux_device_class_video_transmission_start.c b/common/usbx_device_classes/src/ux_device_class_video_transmission_start.c
index 63a6c30..c01f117 100644
--- a/common/usbx_device_classes/src/ux_device_class_video_transmission_start.c
+++ b/common/usbx_device_classes/src/ux_device_class_video_transmission_start.c
@@ -34,7 +34,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_video_transmission_start PORTABLE C */
-/* 6.1.11 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -65,14 +65,13 @@
/* DATE NAME DESCRIPTION */
/* */
/* 04-25-2022 Chaoqiong Xiao Initial Version 6.1.11 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* added standalone support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_device_class_video_transmission_start(UX_DEVICE_CLASS_VIDEO_STREAM *stream)
{
-#if defined(UX_DEVICE_STANDALONE)
- UX_PARAMETER_NOT_USED(stream);
- return(UX_FUNCTION_NOT_SUPPORTED);
-#else
UX_SLAVE_ENDPOINT *endpoint;
UX_SLAVE_DEVICE *device;
@@ -102,8 +101,17 @@ UX_SLAVE_DEVICE *device;
if (stream -> ux_device_class_video_stream_transfer_pos -> ux_device_class_video_payload_length == 0)
return(UX_BUFFER_OVERFLOW);
+#if defined(UX_DEVICE_STANDALONE)
+
+ /* Start write task. */
+ if (stream -> ux_device_class_video_stream_task_state == UX_DEVICE_CLASS_VIDEO_STREAM_RW_STOP)
+ stream -> ux_device_class_video_stream_task_state = UX_DEVICE_CLASS_VIDEO_STREAM_RW_START;
+
+#else
+
/* Start write thread. */
- _ux_utility_thread_resume(&stream -> ux_device_class_video_stream_thread);
- return(UX_SUCCESS);
+ _ux_device_thread_resume(&stream -> ux_device_class_video_stream_thread);
#endif
+
+ return(UX_SUCCESS);
}
diff --git a/common/usbx_device_classes/src/ux_device_class_video_write_task_function.c b/common/usbx_device_classes/src/ux_device_class_video_write_task_function.c
new file mode 100644
index 0000000..55dba42
--- /dev/null
+++ b/common/usbx_device_classes/src/ux_device_class_video_write_task_function.c
@@ -0,0 +1,209 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) Microsoft Corporation. All rights reserved. */
+/* */
+/* This software is licensed under the Microsoft Software License */
+/* Terms for Microsoft Azure RTOS. Full text of the license can be */
+/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
+/* and in the root directory of this software. */
+/* */
+/**************************************************************************/
+
+/**************************************************************************/
+/**************************************************************************/
+/** */
+/** USBX Component */
+/** */
+/** Device Video Class */
+/** */
+/**************************************************************************/
+/**************************************************************************/
+
+#define UX_SOURCE_CODE
+
+
+/* Include necessary system files. */
+
+#include "ux_api.h"
+#include "ux_device_class_video.h"
+#include "ux_device_stack.h"
+
+
+#if defined(UX_DEVICE_STANDALONE)
+/**************************************************************************/
+/* */
+/* FUNCTION RELEASE */
+/* */
+/* _ux_device_class_video_write_task_function PORTABLE C */
+/* 6.2.0 */
+/* AUTHOR */
+/* */
+/* Chaoqiong Xiao, Microsoft Corporation */
+/* */
+/* DESCRIPTION */
+/* */
+/* This function is the background task of the video stream write. */
+/* */
+/* It's for standalone mode. */
+/* */
+/* INPUT */
+/* */
+/* video_class Address of video class */
+/* container */
+/* */
+/* OUTPUT */
+/* */
+/* State machine status */
+/* UX_STATE_EXIT Device not configured */
+/* UX_STATE_IDLE No streaming transfer running */
+/* UX_STATE_WAIT Streaming transfer running */
+/* */
+/* CALLS */
+/* */
+/* _ux_device_stack_transfer_run Run transfer state machine */
+/* _ux_utility_memory_copy Copy memory */
+/* */
+/* CALLED BY */
+/* */
+/* USBX Device Stack */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 10-31-2022 Chaoqiong Xiao Initial Version 6.2.0 */
+/* */
+/**************************************************************************/
+UINT _ux_device_class_video_write_task_function(UX_DEVICE_CLASS_VIDEO_STREAM *stream)
+{
+UX_SLAVE_DEVICE *device;
+UX_SLAVE_ENDPOINT *endpoint;
+UX_SLAVE_TRANSFER *transfer;
+UCHAR *next_pos;
+UX_DEVICE_CLASS_VIDEO_PAYLOAD *next_payload;
+ULONG transfer_length;
+ULONG actual_length;
+UINT status;
+
+
+ /* Get the pointer to the device. */
+ device = stream -> ux_device_class_video_stream_video -> ux_device_class_video_device;
+
+ /* Check if the device is configured. */
+ if (device -> ux_slave_device_state != UX_DEVICE_CONFIGURED)
+ {
+ stream -> ux_device_class_video_stream_task_state = UX_STATE_EXIT;
+ return(UX_STATE_EXIT);
+ }
+
+ /* Get the endpoint. */
+ endpoint = stream -> ux_device_class_video_stream_endpoint;
+
+ /* No endpoint ready, maybe it's alternate setting 0. */
+ if (endpoint == UX_NULL)
+ return(UX_STATE_IDLE);
+
+ /* Check if background transfer task is started. */
+ if (stream -> ux_device_class_video_stream_task_state == UX_DEVICE_CLASS_VIDEO_STREAM_RW_STOP)
+ return(UX_STATE_IDLE);
+
+ /* Get transfer instance. */
+ transfer = &endpoint -> ux_slave_endpoint_transfer_request;
+
+ /* If not started yet, prepare data, reset transfer and start polling. */
+ if (stream -> ux_device_class_video_stream_task_state == UX_DEVICE_CLASS_VIDEO_STREAM_RW_START)
+ {
+
+ /* Next state: transfer wait. */
+ stream -> ux_device_class_video_stream_task_state = UX_DEVICE_CLASS_VIDEO_STREAM_RW_WAIT;
+
+ /* Start payload transfer anyway (even ZLP). */
+ transfer_length = stream -> ux_device_class_video_stream_transfer_pos -> ux_device_class_video_payload_length;
+ if (transfer_length)
+ _ux_utility_memory_copy(transfer -> ux_slave_transfer_request_data_pointer,
+ stream -> ux_device_class_video_stream_transfer_pos -> ux_device_class_video_payload_data, transfer_length); /* Use case of memcpy is verified. */
+
+ /* Reset transfer state. */
+ UX_SLAVE_TRANSFER_STATE_RESET(transfer);
+ }
+
+ /* Get current transfer length. */
+ transfer_length = stream -> ux_device_class_video_stream_transfer_pos -> ux_device_class_video_payload_length;
+
+ /* Run transfer states. */
+ status = _ux_device_stack_transfer_run(transfer, transfer_length, transfer_length);
+
+ /* Error case. */
+ if (status < UX_STATE_NEXT)
+ {
+
+ /* Error on background transfer task start. */
+ stream -> ux_device_class_video_stream_task_state = UX_STATE_RESET;
+ stream -> ux_device_class_video_stream_task_status =
+ transfer -> ux_slave_transfer_request_completion_code;
+
+ /* Error notification! */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_TRANSFER_ERROR);
+ return(UX_STATE_EXIT);
+ }
+
+ /* Success case. */
+ if (status == UX_STATE_NEXT)
+ {
+
+ /* Next state: start. */
+ stream -> ux_device_class_video_stream_task_state = UX_DEVICE_CLASS_VIDEO_STREAM_RW_START;
+ stream -> ux_device_class_video_stream_task_status =
+ transfer -> ux_slave_transfer_request_completion_code;
+
+ /* Frame sent, free it. */
+ stream -> ux_device_class_video_stream_transfer_pos -> ux_device_class_video_payload_length = 0;
+
+ /* Get actual transfer length. */
+ actual_length = transfer -> ux_slave_transfer_request_actual_length;
+
+ /* Calculate next position. */
+ next_pos = (UCHAR *)stream -> ux_device_class_video_stream_transfer_pos;
+ next_pos += stream -> ux_device_class_video_stream_payload_buffer_size;
+ if (next_pos >= stream -> ux_device_class_video_stream_buffer + stream -> ux_device_class_video_stream_buffer_size)
+ next_pos = stream -> ux_device_class_video_stream_buffer;
+ next_payload = (UX_DEVICE_CLASS_VIDEO_PAYLOAD *)next_pos;
+
+ /* Underflow check! */
+ if (transfer_length)
+ {
+
+ /* Advance position. */
+ stream -> ux_device_class_video_stream_transfer_pos = next_payload;
+
+ /* Error trap! */
+ if (next_payload -> ux_device_class_video_payload_length == 0)
+ {
+ stream -> ux_device_class_video_stream_buffer_error_count ++;
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_BUFFER_OVERFLOW);
+ }
+ }
+ else
+ {
+
+ /* Advance position if next payload available. */
+ if (next_payload -> ux_device_class_video_payload_length)
+ stream -> ux_device_class_video_stream_transfer_pos = next_payload;
+ else
+ {
+
+ /* Error trap! */
+ stream -> ux_device_class_video_stream_buffer_error_count ++;
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_BUFFER_OVERFLOW);
+ }
+ }
+
+ /* Invoke notification callback. */
+ if (stream -> ux_device_class_video_stream_callbacks.ux_device_class_video_stream_payload_done != UX_NULL)
+ stream -> ux_device_class_video_stream_callbacks.ux_device_class_video_stream_payload_done(stream, actual_length);
+ }
+
+ /* Keep waiting. */
+ return(UX_STATE_WAIT);
+}
+#endif
diff --git a/common/usbx_device_classes/src/ux_device_class_video_write_thread_entry.c b/common/usbx_device_classes/src/ux_device_class_video_write_thread_entry.c
index 43006d6..3dce636 100644
--- a/common/usbx_device_classes/src/ux_device_class_video_write_thread_entry.c
+++ b/common/usbx_device_classes/src/ux_device_class_video_write_thread_entry.c
@@ -35,7 +35,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_video_write_thread_entry PORTABLE C */
-/* 6.1.11 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -69,6 +69,9 @@
/* DATE NAME DESCRIPTION */
/* */
/* 04-25-2022 Chaoqiong Xiao Initial Version 6.1.11 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* added error statistics, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
VOID _ux_device_class_video_write_thread_entry(ULONG video_stream)
@@ -147,7 +150,10 @@ ULONG actual_length;
/* Error trap! */
if (next_payload -> ux_device_class_video_payload_length == 0)
+ {
+ stream -> ux_device_class_video_stream_buffer_error_count ++;
_ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_BUFFER_OVERFLOW);
+ }
}
else
{
@@ -156,9 +162,12 @@ ULONG actual_length;
if (next_payload -> ux_device_class_video_payload_length)
stream -> ux_device_class_video_stream_transfer_pos = next_payload;
else
+ {
/* Error trap! */
+ stream -> ux_device_class_video_stream_buffer_error_count ++;
_ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_BUFFER_OVERFLOW);
+ }
}
/* Invoke notification callback. */
diff --git a/common/usbx_host_classes/inc/ux_host_class_asix.h b/common/usbx_host_classes/inc/ux_host_class_asix.h
index dac0f48..250fd20 100644
--- a/common/usbx_host_classes/inc/ux_host_class_asix.h
+++ b/common/usbx_host_classes/inc/ux_host_class_asix.h
@@ -26,7 +26,7 @@
/* COMPONENT DEFINITION RELEASE */
/* */
/* ux_host_class_asix.h PORTABLE C */
-/* 6.1.11 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -53,6 +53,13 @@
/* 04-25-2022 Chaoqiong Xiao Modified comment(s), */
/* fixed standalone compile, */
/* resulting in version 6.1.11 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* supported NX packet chain, */
+/* refined VID/PID check flow, */
+/* removed internal NX pool, */
+/* added some new definitions, */
+/* refined reception handling, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
@@ -93,6 +100,17 @@ extern "C" {
#define UX_HOST_CLASS_ASIX_VENDOR_FUJIEI_ID 0X0B95
#define UX_HOST_CLASS_ASIX_PRODUCT_FUJIEI_ID 0X772B
+#define UX_HOST_CLASS_ASIX_VENDOR_LINKSYS_ID 0X13B1
+#define UX_HOST_CLASS_ASIX_PRODUCT_LINKSYS_ID 0X0018
+
+/* Define ASIX supported VID and PID array (of 16-bits). */
+#ifndef UX_HOST_CLASS_ASIX_VID_PID_ARRAY
+#define UX_HOST_CLASS_ASIX_VID_PID_ARRAY \
+ UX_HOST_CLASS_ASIX_VENDOR_ID, UX_HOST_CLASS_ASIX_PRODUCT_ID, \
+ UX_HOST_CLASS_ASIX_VENDOR_FUJIEI_ID, UX_HOST_CLASS_ASIX_PRODUCT_FUJIEI_ID, \
+ UX_HOST_CLASS_ASIX_VENDOR_LINKSYS_ID, UX_HOST_CLASS_ASIX_PRODUCT_LINKSYS_ID
+#endif
+
#define UX_HOST_CLASS_ASIX_SPEED_SELECTED_100MPBS 0x100
#define UX_HOST_CLASS_ASIX_SPEED_SELECTED_10MPBS 0x10
#define UX_HOST_CLASS_ASIX_LINK_STATE_DOWN 0
@@ -107,14 +125,29 @@ extern "C" {
#define UX_HOST_CLASS_ASIX_ETHERNET_RARP 0x8035
#define UX_HOST_CLASS_ASIX_ETHERNET_PACKET_SIZE 1536
#define UX_HOST_CLASS_ASIX_NX_ALIGN_PADDING 2
-#ifndef UX_HOST_CLASS_ASIX_NX_PKPOOL_ENTRIES
-#define UX_HOST_CLASS_ASIX_NX_PKPOOL_ENTRIES 16
+#define UX_HOST_CLASS_ASIX_RX_HEADER_SIZE 4
+#define UX_HOST_CLASS_ASIX_OVERHEAD_SIZE (UX_HOST_CLASS_ASIX_NX_ALIGN_PADDING + UX_HOST_CLASS_ASIX_RX_HEADER_SIZE)
+
+#define UX_HOST_CLASS_ASIX_TRANSMIT_BUFFER_SIZE UX_HOST_CLASS_ASIX_NX_PAYLOAD_SIZE
+
+#ifndef UX_HOST_CLASS_ASIX_RECEIVE_BUFFER_SIZE
+#define UX_HOST_CLASS_ASIX_RECEIVE_BUFFER_SIZE 512 /* N*512. */
+#endif
+
+#ifdef NX_DISABLE_PACKET_CHAIN
+#undef UX_HOST_CLASS_ASIX_PACKET_CHAIN_SUPPORT
+#else
+#define UX_HOST_CLASS_ASIX_PACKET_CHAIN_SUPPORT
#endif
#define UX_HOST_CLASS_ASIX_NX_PACKET_SIZE sizeof(NX_PACKET)
-#define UX_HOST_CLASS_ASIX_NX_PAYLOAD_SIZE_ASSERT UX_COMPILE_TIME_ASSERT(!UX_OVERFLOW_CHECK_ADD_ULONG(UX_HOST_CLASS_ASIX_ETHERNET_PACKET_SIZE, UX_HOST_CLASS_ASIX_NX_ALIGN_PADDING), UX_HOST_CLASS_ASIX_NX_PAYLOAD_SIZE_calc_ovf)
-#define UX_HOST_CLASS_ASIX_NX_PAYLOAD_SIZE (UX_HOST_CLASS_ASIX_ETHERNET_PACKET_SIZE + UX_HOST_CLASS_ASIX_NX_ALIGN_PADDING)
+#define UX_HOST_CLASS_ASIX_NX_PAYLOAD_SIZE_ASSERT \
+ UX_COMPILE_TIME_ASSERT(!UX_OVERFLOW_CHECK_ADD_ULONG( \
+ UX_HOST_CLASS_ASIX_ETHERNET_PACKET_SIZE, \
+ UX_HOST_CLASS_ASIX_OVERHEAD_SIZE), \
+ UX_HOST_CLASS_ASIX_NX_PAYLOAD_SIZE_calc_ovf)
+#define UX_HOST_CLASS_ASIX_NX_PAYLOAD_SIZE (UX_HOST_CLASS_ASIX_ETHERNET_PACKET_SIZE + UX_HOST_CLASS_ASIX_OVERHEAD_SIZE)
#define UX_HOST_CLASS_ASIX_NX_BUFF_SIZE_ASSERT \
UX_HOST_CLASS_ASIX_NX_PAYLOAD_SIZE_ASSERT \
@@ -124,24 +157,15 @@ extern "C" {
UX_HOST_CLASS_ASIX_NX_BUFF_SIZE_calc_ovf)
#define UX_HOST_CLASS_ASIX_NX_BUFF_SIZE (UX_HOST_CLASS_ASIX_NX_PAYLOAD_SIZE + UX_HOST_CLASS_ASIX_NX_PACKET_SIZE)
-#define UX_HOST_CLASS_ASIX_NX_ETHERNET_POOL_ALLOCSIZE_ASSERT \
- UX_HOST_CLASS_ASIX_NX_BUFF_SIZE_ASSERT \
- UX_COMPILE_TIME_ASSERT(!UX_OVERFLOW_CHECK_MULC_ULONG( \
- UX_HOST_CLASS_ASIX_NX_PKPOOL_ENTRIES, \
- UX_HOST_CLASS_ASIX_NX_BUFF_SIZE), \
- UX_HOST_CLASS_ASIX_NX_ETHERNET_POOL_ALLOCSIZE_calc1_ovf) \
- UX_COMPILE_TIME_ASSERT(!UX_OVERFLOW_CHECK_ADD_ULONG( \
- UX_HOST_CLASS_ASIX_NX_PKPOOL_ENTRIES * \
- UX_HOST_CLASS_ASIX_NX_BUFF_SIZE, \
- 32), UX_HOST_CLASS_ASIX_NX_ETHERNET_POOL_ALLOCSIZE_calc2_ovf)
-#define UX_HOST_CLASS_ASIX_NX_ETHERNET_POOL_ALLOCSIZE (UX_HOST_CLASS_ASIX_NX_PKPOOL_ENTRIES * UX_HOST_CLASS_ASIX_NX_BUFF_SIZE + 32)
-
#define UX_HOST_CLASS_ASIX_ETHERNET_SIZE 14
#define UX_HOST_CLASS_ASIX_DEVICE_INIT_DELAY (1 * UX_PERIODIC_RATE)
#define UX_HOST_CLASS_ASIX_CLASS_TRANSFER_TIMEOUT 300000
#define UX_HOST_CLASS_ASIX_SETUP_BUFFER_SIZE 16
+#define UX_HOST_CLASS_ASIX_PACKET_POOL_WAIT 100
+#define UX_HOST_CLASS_ASIX_PACKET_ALLOCATE_WAIT 2000
+
/* Define NetX errors inside the Asix class. */
#define UX_HOST_CLASS_ASIX_NX_SUCCESS 0x00
#define UX_HOST_CLASS_ASIX_NX_NO_PACKET 0x01
@@ -206,6 +230,7 @@ extern "C" {
#define UX_HOST_CLASS_ASIX_REQ_OWN_SMI 0x06
#define UX_HOST_CLASS_ASIX_REQ_READ_PHY_REG 0x07
#define UX_HOST_CLASS_ASIX_REQ_WRITE_PHY_REG 0x08
+#define UX_HOST_CLASS_ASIX_REQ_READ_STATION_STATUS 0x09
#define UX_HOST_CLASS_ASIX_REQ_WHO_OWNS_SMI 0x09
#define UX_HOST_CLASS_ASIX_REQ_RELEASE_SMI 0x0a
#define UX_HOST_CLASS_ASIX_REQ_READ_SROM 0x0b
@@ -280,16 +305,25 @@ extern "C" {
#define UX_HOST_CLASS_ASIX_RXCR_AP 0x0020
#define UX_HOST_CLASS_ASIX_RXCR_SO 0x0080
+/* 88772. */
#define UX_HOST_CLASS_ASIX_RXCR_MFB_2048 0x0000
#define UX_HOST_CLASS_ASIX_RXCR_MFB_4096 0x0100
#define UX_HOST_CLASS_ASIX_RXCR_MFB_8192 0x0200
-#define UX_HOST_CLASS_ASIX_RXCR_MFB_16384 0x0300
+#define UX_HOST_CLASS_ASIX_RXCR_MFB_16384 0x0300 /* Default. */
+
+/* 88772B. */
+#define UX_HOST_CLASS_ASIX_RXCR_RH1M 0x0100 /* Default 1. */
+#define UX_HOST_CLASS_ASIX_RXCR_RH2M 0x0200 /* Default 0. */
+#define UX_HOST_CLASS_ASIX_RXCR_RH3M 0x0400 /* Default 0. */
+
/* Define ASIX Class packet equivalences. */
#define UX_HOST_CLASS_ASIX_PACKET_SIZE 128
#define UX_HOST_CLASS_ASIX_NODE_ID_LENGTH 6
+#define UX_HOST_CLASS_ASIX_RX_PACKET_LENGTH_MASK 0xFFF
+
/* Define ASIX PHY registers description. */
#define UX_HOST_CLASS_ASIX_PHY_REG_BMCR 0x00
@@ -391,10 +425,14 @@ typedef struct UX_HOST_CLASS_ASIX_STRUCT
ULONG ux_host_class_asix_link_state;
NX_PACKET *ux_host_class_asix_xmit_queue;
+#ifdef UX_HOST_CLASS_ASIX_PACKET_CHAIN_SUPPORT
+ UCHAR *ux_host_class_asix_xmit_buffer;
+#endif
NX_PACKET *ux_host_class_asix_receive_queue;
- NX_PACKET_POOL ux_host_class_asix_packet_pool;
+ UCHAR *ux_host_class_asix_receive_buffer;
+ NX_PACKET_POOL *ux_host_class_asix_packet_pool;
+ ULONG ux_host_class_asix_packet_available_min;
- UCHAR *ux_host_class_asix_pool_memory;
UCHAR ux_host_class_asix_node_id[UX_HOST_CLASS_ASIX_NODE_ID_LENGTH];
VOID (*ux_host_class_asix_device_status_change_callback)(struct UX_HOST_CLASS_ASIX_STRUCT *asix,
ULONG device_state);
diff --git a/common/usbx_host_classes/inc/ux_host_class_cdc_ecm.h b/common/usbx_host_classes/inc/ux_host_class_cdc_ecm.h
index 524656f..9a8b388 100644
--- a/common/usbx_host_classes/inc/ux_host_class_cdc_ecm.h
+++ b/common/usbx_host_classes/inc/ux_host_class_cdc_ecm.h
@@ -26,7 +26,7 @@
/* COMPONENT DEFINITION RELEASE */
/* */
/* ux_host_class_cdc_ecm.h PORTABLE C */
-/* 6.1.11 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -57,6 +57,9 @@
/* 04-25-2022 Chaoqiong Xiao Modified comment(s), */
/* fixed standalone compile, */
/* resulting in version 6.1.11 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* supported NX packet chain, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
@@ -144,12 +147,19 @@ extern "C" {
32), UX_HOST_CLASS_CDC_ECM_NX_ETHERNET_POOL_ALLOCSIZE_calc2_ovf)
#define UX_HOST_CLASS_CDC_ECM_NX_ETHERNET_POOL_ALLOCSIZE (UX_HOST_CLASS_CDC_ECM_NX_PKPOOL_ENTRIES * UX_HOST_CLASS_CDC_ECM_NX_BUFF_SIZE + 32)
+#ifdef NX_DISABLE_PACKET_CHAIN
+#undef UX_HOST_CLASS_CDC_ECM_PACKET_CHAIN_SUPPORT
+#else
+#define UX_HOST_CLASS_CDC_ECM_PACKET_CHAIN_SUPPORT
+#endif
+
#define UX_HOST_CLASS_CDC_ECM_ETHERNET_SIZE 14
#define UX_HOST_CLASS_CDC_ECM_DEVICE_INIT_DELAY (1 * UX_PERIODIC_RATE)
#define UX_HOST_CLASS_CDC_ECM_CLASS_TRANSFER_TIMEOUT 300000
#define UX_HOST_CLASS_CDC_ECM_SETUP_BUFFER_SIZE 16
+
/* Define NetX errors inside the CDC ECM class. */
#define UX_HOST_CLASS_CDC_ECM_NX_SUCCESS 0x00
#define UX_HOST_CLASS_CDC_ECM_NX_NO_PACKET 0x01
@@ -280,11 +290,10 @@ typedef struct UX_HOST_CLASS_CDC_ECM_STRUCT
ULONG ux_host_class_cdc_ecm_link_state;
NX_PACKET *ux_host_class_cdc_ecm_xmit_queue_head;
NX_PACKET *ux_host_class_cdc_ecm_xmit_queue_tail;
-#ifndef UX_HOST_CLASS_CDC_ECM_USE_PACKET_POOL_FROM_NETX
- NX_PACKET_POOL ux_host_class_cdc_ecm_packet_pool;
- UCHAR *ux_host_class_cdc_ecm_pool_memory;
-#else
NX_PACKET_POOL *ux_host_class_cdc_ecm_packet_pool;
+#ifdef UX_HOST_CLASS_CDC_ECM_PACKET_CHAIN_SUPPORT
+ UCHAR *ux_host_class_cdc_ecm_xmit_buffer;
+ UCHAR *ux_host_class_cdc_ecm_receive_buffer;
#endif
UCHAR ux_host_class_cdc_ecm_node_id[UX_HOST_CLASS_CDC_ECM_NODE_ID_LENGTH];
diff --git a/common/usbx_host_classes/inc/ux_host_class_hid_keyboard.h b/common/usbx_host_classes/inc/ux_host_class_hid_keyboard.h
index b805175..b331bf4 100644
--- a/common/usbx_host_classes/inc/ux_host_class_hid_keyboard.h
+++ b/common/usbx_host_classes/inc/ux_host_class_hid_keyboard.h
@@ -26,7 +26,7 @@
/* COMPONENT DEFINITION RELEASE */
/* */
/* ux_host_class_hid_keyboard.h PORTABLE C */
-/* 6.1.11 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -56,6 +56,10 @@
/* 04-25-2022 Chaoqiong Xiao Modified comment(s), */
/* fixed clients management, */
/* resulting in version 6.1.11 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* improved HID OUTPUT report */
+/* handling in standalone mode,*/
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
@@ -215,6 +219,8 @@ typedef struct UX_HOST_CLASS_HID_KEYBOARD_STRUCT
UX_THREAD ux_host_class_hid_keyboard_thread;
UX_SEMAPHORE ux_host_class_hid_keyboard_semaphore;
#else
+ UX_HOST_CLASS_HID_REPORT
+ *ux_host_class_hid_keyboard_out_report;
UINT ux_host_class_hid_keyboard_status;
UCHAR ux_host_class_hid_keyboard_enum_state;
UCHAR ux_host_class_hid_keyboard_next_state;
diff --git a/common/usbx_host_classes/inc/ux_host_class_storage.h b/common/usbx_host_classes/inc/ux_host_class_storage.h
index 8082256..8082256 100755..100644
--- a/common/usbx_host_classes/inc/ux_host_class_storage.h
+++ b/common/usbx_host_classes/inc/ux_host_class_storage.h
diff --git a/common/usbx_host_classes/src/ux_host_class_asix_activate.c b/common/usbx_host_classes/src/ux_host_class_asix_activate.c
index a243a07..760b59e 100644
--- a/common/usbx_host_classes/src/ux_host_class_asix_activate.c
+++ b/common/usbx_host_classes/src/ux_host_class_asix_activate.c
@@ -29,14 +29,13 @@
#include "ux_host_class_asix.h"
#include "ux_host_stack.h"
-UX_HOST_CLASS_ASIX_NX_ETHERNET_POOL_ALLOCSIZE_ASSERT
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_host_class_asix_activate PORTABLE C */
-/* 6.1.10 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -87,6 +86,11 @@ UX_HOST_CLASS_ASIX_NX_ETHERNET_POOL_ALLOCSIZE_ASSERT
/* 01-31-2022 Chaoqiong Xiao Modified comment(s), */
/* refined macros names, */
/* resulting in version 6.1.10 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* moved NX driver activate, */
+/* added reception buffer, */
+/* removed internal NX pool, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_host_class_asix_activate(UX_HOST_CLASS_COMMAND *command)
@@ -103,7 +107,10 @@ UX_DEVICE *device;
UX_HOST_CLASS_ASIX *asix;
UINT status;
UX_TRANSFER *transfer_request;
-
+ULONG physical_address_msw;
+ULONG physical_address_lsw;
+
+
/* We need to make sure that the value of the NX_PHYSICAL_HEADER is at least 20.
This should be changed in the nx_user.h file */
@@ -199,27 +206,28 @@ UX_TRANSFER *transfer_request;
status = _ux_host_stack_transfer_request(transfer_request);
}
- /* Allocate some packet pool for reception. */
+ /* Allocate some memory for reception. */
if (status == UX_SUCCESS)
{
-
- /* UX_HOST_CLASS_ASIX_NX_ETHERNET_POOL_ALLOCSIZE overflow has been checked by
- * UX_HOST_CLASS_ASIX_NX_ETHERNET_POOL_ALLOCSIZE_ASSERT outside of function.
- */
- asix -> ux_host_class_asix_pool_memory = _ux_utility_memory_allocate(UX_SAFE_ALIGN, UX_CACHE_SAFE_MEMORY, UX_HOST_CLASS_ASIX_NX_ETHERNET_POOL_ALLOCSIZE);
- if (asix -> ux_host_class_asix_pool_memory == UX_NULL)
+ asix -> ux_host_class_asix_receive_buffer = _ux_utility_memory_allocate(UX_SAFE_ALIGN, UX_CACHE_SAFE_MEMORY, UX_HOST_CLASS_ASIX_RECEIVE_BUFFER_SIZE);
+ if (asix -> ux_host_class_asix_receive_buffer == UX_NULL)
status = UX_MEMORY_INSUFFICIENT;
}
- /* Create a packet pool. */
+ /* Activate network driver. */
if (status == UX_SUCCESS)
{
- status = nx_packet_pool_create(&asix -> ux_host_class_asix_packet_pool, "Asix Packet Pool",
- UX_HOST_CLASS_ASIX_NX_PAYLOAD_SIZE, asix -> ux_host_class_asix_pool_memory, UX_HOST_CLASS_ASIX_NX_ETHERNET_POOL_ALLOCSIZE);
- /* Check for pool creation error. */
- if (status)
- status = UX_ERROR;
+ /* Setup the physical address of this IP instance. */
+ physical_address_msw = (ULONG)((asix -> ux_host_class_asix_node_id[0] << 8) | (asix -> ux_host_class_asix_node_id[1]));
+ physical_address_lsw = (ULONG)((asix -> ux_host_class_asix_node_id[2] << 24) | (asix -> ux_host_class_asix_node_id[3] << 16) |
+ (asix -> ux_host_class_asix_node_id[4] << 8) | (asix -> ux_host_class_asix_node_id[5]));
+
+ /* Register this interface to the NetX USB interface broker. */
+ status = _ux_network_driver_activate((VOID *) asix, _ux_host_class_asix_write,
+ &asix -> ux_host_class_asix_network_handle,
+ physical_address_msw,
+ physical_address_lsw);
}
/* Do final things if success. */
@@ -250,12 +258,9 @@ UX_TRANSFER *transfer_request;
/* There was a problem, so free the resources. */
- /* Last resource, asix -> ux_host_class_asix_packet_pool is not created or created error,
- no need to free. */
-
- /* Free asix -> ux_host_class_asix_pool_memory. */
- if (asix -> ux_host_class_asix_pool_memory)
- _ux_utility_memory_free(asix -> ux_host_class_asix_pool_memory);
+ /* Free asix -> ux_host_class_asix_receive_buffer. */
+ if (asix -> ux_host_class_asix_receive_buffer)
+ _ux_utility_memory_free(asix -> ux_host_class_asix_receive_buffer);
/* Free asix -> ux_host_class_asix_thread. */
if (asix -> ux_host_class_asix_thread.tx_thread_id)
diff --git a/common/usbx_host_classes/src/ux_host_class_asix_deactivate.c b/common/usbx_host_classes/src/ux_host_class_asix_deactivate.c
index 32853e5..20d5c61 100644
--- a/common/usbx_host_classes/src/ux_host_class_asix_deactivate.c
+++ b/common/usbx_host_classes/src/ux_host_class_asix_deactivate.c
@@ -36,7 +36,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_host_class_asix_deactivate PORTABLE C */
-/* 6.1.11 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -85,6 +85,11 @@
/* internal clean up, */
/* fixed standalone compile, */
/* resulting in version 6.1.11 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* supported NX packet chain, */
+/* added reception buffer, */
+/* removed internal NX pool, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_host_class_asix_deactivate(UX_HOST_CLASS_COMMAND *command)
@@ -196,12 +201,16 @@ UINT status;
/* free its stack memory. */
_ux_utility_memory_free(asix -> ux_host_class_asix_thread_stack);
- /* We may have allocated a packet pool. */
- if (asix -> ux_host_class_asix_pool_memory != UX_NULL)
-
- /* Free this pool of packets. */
- _ux_utility_memory_free(asix -> ux_host_class_asix_pool_memory);
-
+ /* Free receive buffer memory. */
+ _ux_utility_memory_free(asix -> ux_host_class_asix_receive_buffer);
+
+#ifdef UX_HOST_CLASS_ASIX_PACKET_CHAIN_SUPPORT
+
+ /* Free transmit buffer memory. */
+ if (asix -> ux_host_class_asix_xmit_buffer)
+ _ux_utility_memory_free(asix -> ux_host_class_asix_xmit_buffer);
+#endif
+
/* Before we free the device resources, we need to inform the application
that the device is removed. */
if (_ux_system_host -> ux_system_host_change_function != UX_NULL)
diff --git a/common/usbx_host_classes/src/ux_host_class_asix_endpoints_get.c b/common/usbx_host_classes/src/ux_host_class_asix_endpoints_get.c
index 0fae599..7e67670 100644
--- a/common/usbx_host_classes/src/ux_host_class_asix_endpoints_get.c
+++ b/common/usbx_host_classes/src/ux_host_class_asix_endpoints_get.c
@@ -35,7 +35,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_host_class_asix_endpoints_get PORTABLE C */
-/* 6.1.9 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -75,6 +75,10 @@
/* use pre-calculated value */
/* instead of wMaxPacketSize, */
/* resulting in version 6.1.9 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* removed packet RX callback, */
+/* refined INT EP start time, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_host_class_asix_endpoints_get(UX_HOST_CLASS_ASIX *asix)
@@ -156,9 +160,6 @@ UX_TRANSFER *transfer_request;
/* There is a callback function associated with the transfer request, so we need the class instance. */
endpoint -> ux_endpoint_transfer_request.ux_transfer_request_class_instance = (VOID *) asix;
- /* The transfer request has a callback function. */
- endpoint -> ux_endpoint_transfer_request.ux_transfer_request_completion_function = _ux_host_class_asix_reception_callback;
-
/* We have found the bulk endpoint, save it. */
asix -> ux_host_class_asix_bulk_in_endpoint = endpoint;
break;
@@ -220,22 +221,8 @@ UX_TRANSFER *transfer_request;
transfer_request -> ux_transfer_request_data_pointer = _ux_utility_memory_allocate(UX_SAFE_ALIGN, UX_CACHE_SAFE_MEMORY,
transfer_request -> ux_transfer_request_requested_length);
- /* If the endpoint is available and we have memory, we start the interrupt endpoint. */
- if (transfer_request -> ux_transfer_request_data_pointer != UX_NULL)
- {
-
- /* The transfer on the interrupt endpoint can be started. */
- status = _ux_host_stack_transfer_request(transfer_request);
-
- /* Check error, if endpoint interrupt IN transfer not successful, do not proceed. */
- if (status != UX_SUCCESS)
-
- /* Error, do not proceed. */
- return(status);
-
- }
-
- else
+ /* If the endpoint is available and we have memory, it's started later after setup. */
+ if (transfer_request -> ux_transfer_request_data_pointer == UX_NULL)
{
/* Error trap. */
diff --git a/common/usbx_host_classes/src/ux_host_class_asix_entry.c b/common/usbx_host_classes/src/ux_host_class_asix_entry.c
index 8d4716e..aba59b5 100644
--- a/common/usbx_host_classes/src/ux_host_class_asix_entry.c
+++ b/common/usbx_host_classes/src/ux_host_class_asix_entry.c
@@ -30,12 +30,17 @@
#include "ux_host_stack.h"
+#if !defined(UX_HOST_STANDALONE)
+static inline UINT _ux_host_class_asix_try_all_vid_pids(UX_HOST_CLASS_COMMAND *command);
+#endif
+
+
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_host_class_asix_entry PORTABLE C */
-/* 6.1.11 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -74,6 +79,10 @@
/* 04-25-2022 Chaoqiong Xiao Modified comment(s), */
/* fixed standalone compile, */
/* resulting in version 6.1.11 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* fixed compile warning, */
+/* refined VID/PID check flow, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_host_class_asix_entry(UX_HOST_CLASS_COMMAND *command)
@@ -97,17 +106,8 @@ UINT status;
this device or not. */
if(command -> ux_host_class_command_usage == UX_HOST_CLASS_COMMAND_USAGE_PIDVID)
{
-
- /* Try all the possible PID/VID. */
- if ((command -> ux_host_class_command_pid == UX_HOST_CLASS_ASIX_PRODUCT_ID) &&
- (command -> ux_host_class_command_vid == UX_HOST_CLASS_ASIX_VENDOR_ID ))
- return(UX_SUCCESS);
-
- /* Try all the possible PID/VID. */
- if ((command -> ux_host_class_command_pid == UX_HOST_CLASS_ASIX_PRODUCT_FUJIEI_ID) &&
- (command -> ux_host_class_command_vid == UX_HOST_CLASS_ASIX_VENDOR_FUJIEI_ID ))
- return(UX_SUCCESS);
-
+ if (_ux_host_class_asix_try_all_vid_pids(command) == UX_SUCCESS)
+ return(UX_SUCCESS);
}
/* No match. */
@@ -139,4 +139,23 @@ UINT status;
}
#endif
}
+#if !defined(UX_HOST_STANDALONE)
+static const USHORT _ux_host_class_asix_vid_pid_array[] =
+{
+ UX_HOST_CLASS_ASIX_VID_PID_ARRAY
+};
+static inline UINT _ux_host_class_asix_try_all_vid_pids(UX_HOST_CLASS_COMMAND *command)
+{
+UINT i, pos;
+UINT n_ids = sizeof(_ux_host_class_asix_vid_pid_array) >> 1;
+UINT n_id_pairs = n_ids >> 1;
+ for (i = 0, pos = 0; i < n_id_pairs; i ++, pos += 2)
+ {
+ if ((command -> ux_host_class_command_pid == _ux_host_class_asix_vid_pid_array[pos + 1]) &&
+ (command -> ux_host_class_command_vid == _ux_host_class_asix_vid_pid_array[pos ]))
+ return(UX_SUCCESS);
+ }
+ return(UX_NO_CLASS_MATCH);
+}
+#endif
diff --git a/common/usbx_host_classes/src/ux_host_class_asix_interrupt_notification.c b/common/usbx_host_classes/src/ux_host_class_asix_interrupt_notification.c
index 2a4437a..5717311 100644
--- a/common/usbx_host_classes/src/ux_host_class_asix_interrupt_notification.c
+++ b/common/usbx_host_classes/src/ux_host_class_asix_interrupt_notification.c
@@ -35,7 +35,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_host_class_asix_interrupt_notification PORTABLE C */
-/* 6.1.10 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -76,6 +76,10 @@
/* 01-31-2022 Chaoqiong Xiao Modified comment(s), */
/* refined macros names, */
/* resulting in version 6.1.10 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* refined link up/down flow, */
+/* refined interrupt flow, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
VOID _ux_host_class_asix_interrupt_notification(UX_TRANSFER *transfer_request)
@@ -127,6 +131,8 @@ UX_HOST_CLASS_ASIX *asix;
/* We need to inform the asix thread of this change. */
_ux_host_semaphore_put(&asix -> ux_host_class_asix_interrupt_notification_semaphore);
+ /* Reactivate interrupt pipe after link up handled. */
+ return;
}
}
else
@@ -138,53 +144,20 @@ UX_HOST_CLASS_ASIX *asix;
{
/* Memorize the new link state. */
- asix -> ux_host_class_asix_link_state = UX_HOST_CLASS_ASIX_LINK_STATE_PENDING_DOWN;
-
- /* We may have transaction pending on bulk in. Inform the class. */
- transfer_request = &asix -> ux_host_class_asix_bulk_in_endpoint -> ux_endpoint_transfer_request;
- if (transfer_request -> ux_transfer_request_completion_code == UX_TRANSFER_STATUS_PENDING)
- {
-
- /* Set the completion error code. */
- transfer_request -> ux_transfer_request_completion_code = UX_TRANSFER_NO_ANSWER;
-
- /* Error trap. */
- _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_TRANSFER_NO_ANSWER);
-
- /* If trace is enabled, insert this event into the trace buffer. */
- UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_TRANSFER_NO_ANSWER, transfer_request, 0, 0, UX_TRACE_ERRORS, 0, 0)
-
- /* Wake up the semaphore on which the transaction is waiting. */
- _ux_host_semaphore_put(&transfer_request -> ux_transfer_request_semaphore);
-
- }
-
- /* We may have transaction pending on bulk out. Inform the class. */
- transfer_request = &asix -> ux_host_class_asix_bulk_out_endpoint -> ux_endpoint_transfer_request;
- if (transfer_request -> ux_transfer_request_completion_code == UX_TRANSFER_STATUS_PENDING)
- {
+ asix -> ux_host_class_asix_link_state = UX_HOST_CLASS_ASIX_LINK_STATE_PENDING_DOWN;
- /* Set the completion error code. */
- transfer_request -> ux_transfer_request_completion_code = UX_TRANSFER_NO_ANSWER;
+ /* Abort possible pending bulk in requests. */
+ _ux_host_stack_endpoint_transfer_abort(asix -> ux_host_class_asix_bulk_in_endpoint);
- /* Error trap. */
- _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_TRANSFER_NO_ANSWER);
-
- /* If trace is enabled, insert this event into the trace buffer. */
- UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_TRANSFER_NO_ANSWER, transfer_request, 0, 0, UX_TRACE_ERRORS, 0, 0)
-
- /* Wake up the semaphore on which the transaction is waiting. */
- _ux_host_semaphore_put(&transfer_request -> ux_transfer_request_semaphore);
-
- }
-
-
/* We need to inform the asix thread of this change. */
_ux_host_semaphore_put(&asix -> ux_host_class_asix_interrupt_notification_semaphore);
+
+ /* Reactivate interrupt pipe after link down handled. */
+ return;
}
- }
- }
- }
+ }
+ }
+ }
/* Reactivate the ASIX interrupt pipe. */
_ux_host_stack_transfer_request(transfer_request);
diff --git a/common/usbx_host_classes/src/ux_host_class_asix_reception_callback.c b/common/usbx_host_classes/src/ux_host_class_asix_reception_callback.c
index 75ad2e9..e6bff4c 100644
--- a/common/usbx_host_classes/src/ux_host_class_asix_reception_callback.c
+++ b/common/usbx_host_classes/src/ux_host_class_asix_reception_callback.c
@@ -35,7 +35,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_host_class_asix_reception_callback PORTABLE C */
-/* 6.1.11 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -46,6 +46,8 @@
/* it is called when a full or partial transfer has been done for a */
/* bulk in transfer. It calls back the application. */
/* */
+/* It's deprecated. */
+/* */
/* INPUT */
/* */
/* transfer_request Pointer to transfer request */
@@ -76,6 +78,10 @@
/* 04-25-2022 Chaoqiong Xiao Modified comment(s), */
/* fixed standalone compile, */
/* resulting in version 6.1.11 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* deprecated, no RX callback, */
+/* modified pool reference, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
VOID _ux_host_class_asix_reception_callback (UX_TRANSFER *transfer_request)
@@ -125,7 +131,7 @@ UINT status;
nx_packet_transmit_release(packet);
/* We can accept new reception. Get a NX Packet */
- if (nx_packet_allocate(&asix -> ux_host_class_asix_packet_pool, &packet,
+ if (nx_packet_allocate(asix -> ux_host_class_asix_packet_pool, &packet,
NX_RECEIVE_PACKET, NX_NO_WAIT) == NX_SUCCESS)
{
diff --git a/common/usbx_host_classes/src/ux_host_class_asix_thread.c b/common/usbx_host_classes/src/ux_host_class_asix_thread.c
index 96f4803..9e301dd 100644
--- a/common/usbx_host_classes/src/ux_host_class_asix_thread.c
+++ b/common/usbx_host_classes/src/ux_host_class_asix_thread.c
@@ -31,12 +31,15 @@
#if !defined(UX_HOST_STANDALONE)
+
+static inline UINT _ux_host_class_asix_link_up_controls(UX_HOST_CLASS_ASIX *asix);
+
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_host_class_asix_thread PORTABLE C */
-/* 6.1.11 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -87,35 +90,49 @@
/* internal clean up, */
/* fixed standalone compile, */
/* resulting in version 6.1.11 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* removed internal NX pool, */
+/* moved NX driver activate, */
+/* refined control REQ flow, */
+/* refined reception flow, */
+/* refined interrupt flow, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
VOID _ux_host_class_asix_thread(ULONG parameter)
{
UX_HOST_CLASS_ASIX *asix;
-UCHAR *setup_buffer;
-UX_ENDPOINT *control_endpoint;
UX_TRANSFER *transfer_request;
NX_PACKET *packet;
NX_PACKET *current_packet;
NX_PACKET *next_packet;
+UCHAR *buffer;
+ULONG buffer_count;
+ULONG asix_length;
+ULONG asix_count;
+ULONG asix_remain;
+ULONG packet_discard;
+ULONG buffer_remain;
+ULONG copy_length;
UINT status;
-ULONG physical_address_msw;
-ULONG physical_address_lsw;
+UX_DEVICE *device;
+ULONG available0, available1;
+USB_NETWORK_DEVICE_TYPE *ux_nx_device;
+
/* Cast the parameter passed in the thread into the asix pointer. */
UX_THREAD_EXTENSION_PTR_GET(asix, UX_HOST_CLASS_ASIX, parameter)
- /* Loop forever waiting for changes signaled through the semaphore. */
+ /* Loop forever waiting for changes signaled through the semaphore. */
while (1)
- {
+ {
/* Wait for the semaphore to be put by the asix interrupt event. */
status = _ux_host_semaphore_get(&asix -> ux_host_class_asix_interrupt_notification_semaphore, UX_WAIT_FOREVER);
/* Check for successful completion. */
if (status != UX_SUCCESS)
-
return;
/* Protect Thread reentry to this instance. */
@@ -123,299 +140,323 @@ ULONG physical_address_lsw;
/* Check for successful completion. */
if (status != UX_SUCCESS)
-
return;
/* Check the link state. It is either pending up or down. */
if (asix -> ux_host_class_asix_link_state == UX_HOST_CLASS_ASIX_LINK_STATE_PENDING_UP)
{
- /* We need to get the default control endpoint transfer request pointer. */
- control_endpoint = &asix -> ux_host_class_asix_device -> ux_device_control_endpoint;
- transfer_request = &control_endpoint -> ux_endpoint_transfer_request;
-
- /* Need to allocate memory for the buffer. */
- setup_buffer = _ux_utility_memory_allocate(UX_SAFE_ALIGN, UX_CACHE_SAFE_MEMORY, UX_HOST_CLASS_ASIX_SETUP_BUFFER_SIZE);
- if (setup_buffer == UX_NULL)
+ /* Issue a list of control requests to setup link up. */
+ status = _ux_host_class_asix_link_up_controls(asix);
+ if (status != UX_SUCCESS)
{
/* Unprotect thread reentry to this instance. */
_ux_host_semaphore_put(&asix -> ux_host_class_asix_semaphore);
+ continue;
+ }
- return;
- }
+ /* Now the link is up. */
+ asix -> ux_host_class_asix_link_state = UX_HOST_CLASS_ASIX_LINK_STATE_UP;
- /* Request ownership of Serial Management Interface. */
- transfer_request -> ux_transfer_request_data_pointer = UX_NULL;
- transfer_request -> ux_transfer_request_requested_length = 0;
- transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_ASIX_REQ_OWN_SMI ;
- transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_VENDOR | UX_REQUEST_TARGET_DEVICE;
- transfer_request -> ux_transfer_request_value = 0;
- transfer_request -> ux_transfer_request_index = 0;
-
- /* Send request to HCD layer. */
- status = _ux_host_stack_transfer_request(transfer_request);
-
- /* Check status, if error, do not proceed. */
- if (status != UX_SUCCESS || transfer_request -> ux_transfer_request_completion_code != UX_SUCCESS)
- {
-
- /* Free all used resources. */
- _ux_utility_memory_free(setup_buffer);
+ /* Communicate the state with the network driver. */
+ _ux_network_driver_link_up(asix -> ux_host_class_asix_network_handle);
- /* Unprotect thread reentry to this instance. */
- _ux_host_semaphore_put(&asix -> ux_host_class_asix_semaphore);
+ /* Reactivate interrupt notification polling. */
+ _ux_host_stack_transfer_request(&asix -> ux_host_class_asix_interrupt_endpoint -> ux_endpoint_transfer_request);
- /* Return completion status. */
- return;
-
- }
-
- /* Get the value of the PHYIDR1 in the PHY register. */
- transfer_request -> ux_transfer_request_data_pointer = setup_buffer;
- transfer_request -> ux_transfer_request_requested_length = 2;
- transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_ASIX_REQ_READ_PHY_REG;
- transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_VENDOR | UX_REQUEST_TARGET_DEVICE;
- transfer_request -> ux_transfer_request_value = asix -> ux_host_class_asix_primary_phy_id;
- transfer_request -> ux_transfer_request_index = UX_HOST_CLASS_ASIX_PHY_REG_ANLPAR;
-
- /* Send request to HCD layer. */
- status = _ux_host_stack_transfer_request(transfer_request);
-
- /* Check status, if error, do not proceed. */
- if (status != UX_SUCCESS || transfer_request -> ux_transfer_request_completion_code != UX_SUCCESS ||
- transfer_request -> ux_transfer_request_actual_length != 2)
- {
-
- /* Free all used resources. */
- _ux_utility_memory_free(setup_buffer);
+ /* Unprotect thread reentry to this instance. */
+ _ux_host_semaphore_put(&asix -> ux_host_class_asix_semaphore);
- /* Unprotect thread reentry to this instance. */
- _ux_host_semaphore_put(&asix -> ux_host_class_asix_semaphore);
+ /* Re-check packet pool on link up. */
+ asix -> ux_host_class_asix_packet_pool = UX_NULL;
- /* Return completion status. */
- return;
-
- }
+ /* Keep polling if device is connected and link is up. */
- /* Release SMI ownership. */
- transfer_request -> ux_transfer_request_data_pointer = UX_NULL;
- transfer_request -> ux_transfer_request_requested_length = 0;
- transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_ASIX_REQ_RELEASE_SMI;
- transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_VENDOR | UX_REQUEST_TARGET_DEVICE;
- transfer_request -> ux_transfer_request_value = 0;
- transfer_request -> ux_transfer_request_index = 0;
-
- /* Send request to HCD layer. */
- status = _ux_host_stack_transfer_request(transfer_request);
-
- /* Check status, if error, do not proceed. */
- if (status != UX_SUCCESS || transfer_request -> ux_transfer_request_completion_code != UX_SUCCESS)
+ /* Initialize variables. */
+ device = asix -> ux_host_class_asix_device;
+ packet = UX_NULL;
+ buffer = UX_NULL;
+ asix_length = 0;
+ asix_count = 0;
+ buffer_count = 0;
+ packet_discard = UX_FALSE;
+ asix -> ux_host_class_asix_packet_available_min = 0xFFFFFFFF;
+
+ /* Polling loop. */
+ while(device -> ux_device_state == UX_DEVICE_CONFIGURED &&
+ asix -> ux_host_class_asix_link_state == UX_HOST_CLASS_ASIX_LINK_STATE_UP)
{
-
- /* Free all used resources. */
- _ux_utility_memory_free(setup_buffer);
- /* Unprotect thread reentry to this instance. */
- _ux_host_semaphore_put(&asix -> ux_host_class_asix_semaphore);
+ /* Check if packet pool is ready. */
+ if (asix -> ux_host_class_asix_packet_pool == UX_NULL)
+ {
- /* Return completion status. */
- return;
-
- }
-
- /* Check speed. */
- if (asix -> ux_host_class_asix_speed_selected == UX_HOST_CLASS_ASIX_SPEED_SELECTED_100MPBS)
-
- /* Set speed at 100MBPS. */
- transfer_request -> ux_transfer_request_value = UX_HOST_CLASS_ASIX_MEDIUM_PS;
-
- /* Write the value of the Medium Mode. */
- transfer_request -> ux_transfer_request_data_pointer = UX_NULL;
- transfer_request -> ux_transfer_request_requested_length = 0;
- transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_ASIX_REQ_WRITE_MEDIUM_MODE;
- transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_VENDOR | UX_REQUEST_TARGET_DEVICE;
- transfer_request -> ux_transfer_request_value |= (UX_HOST_CLASS_ASIX_MEDIUM_FD | UX_HOST_CLASS_ASIX_MEDIUM_BIT2 | UX_HOST_CLASS_ASIX_MEDIUM_RFC_ENABLED |
- UX_HOST_CLASS_ASIX_MEDIUM_TFC_ENABLED | UX_HOST_CLASS_ASIX_MEDIUM_RE_ENABLED);
- transfer_request -> ux_transfer_request_index = 0;
-
- /* Send request to HCD layer. */
- status = _ux_host_stack_transfer_request(transfer_request);
-
- /* Check status, if error, do not proceed. */
- if (status != UX_SUCCESS || transfer_request -> ux_transfer_request_completion_code != UX_SUCCESS)
- {
-
- /* Free all used resources. */
- _ux_utility_memory_free(setup_buffer);
+ /* Get the network device handle. */
+ ux_nx_device = (USB_NETWORK_DEVICE_TYPE *)(asix -> ux_host_class_asix_network_handle);
- /* Unprotect thread reentry to this instance. */
- _ux_host_semaphore_put(&asix -> ux_host_class_asix_semaphore);
+ /* Get packet pool from IP instance (if available). */
+ if (ux_nx_device -> ux_network_device_ip_instance != UX_NULL)
+ {
+ asix -> ux_host_class_asix_packet_pool = ux_nx_device -> ux_network_device_ip_instance -> nx_ip_default_packet_pool;
+ }
+ else
+ {
- /* Return completion status. */
- return;
-
- }
+ /* Error trap. */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_CLASS_ETH_PACKET_POOL_ERROR);
- /* Set the Rx Control register value. */
- transfer_request -> ux_transfer_request_data_pointer = UX_NULL;
- transfer_request -> ux_transfer_request_requested_length = 0;
- transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_ASIX_REQ_WRITE_RX_CTL;
- transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_VENDOR | UX_REQUEST_TARGET_DEVICE;
- transfer_request -> ux_transfer_request_value = (UX_HOST_CLASS_ASIX_RXCR_AM | UX_HOST_CLASS_ASIX_RXCR_AB |
- UX_HOST_CLASS_ASIX_RXCR_SO | UX_HOST_CLASS_ASIX_RXCR_MFB_2048);
- transfer_request -> ux_transfer_request_index = 0;
-
- /* Send request to HCD layer. */
- status = _ux_host_stack_transfer_request(transfer_request);
-
- /* Check status, if error, do not proceed. */
- if (status != UX_SUCCESS || transfer_request -> ux_transfer_request_completion_code != UX_SUCCESS)
- {
-
- /* Free all used resources. */
- _ux_utility_memory_free(setup_buffer);
-
- /* Unprotect thread reentry to this instance. */
- _ux_host_semaphore_put(&asix -> ux_host_class_asix_semaphore);
+ _ux_utility_delay_ms(UX_HOST_CLASS_ASIX_PACKET_POOL_WAIT);
+ continue;
+ }
+ }
- /* Return completion status. */
- return;
-
- }
-
- /* Set the multicast value. */
- transfer_request -> ux_transfer_request_data_pointer = setup_buffer;
- transfer_request -> ux_transfer_request_requested_length = 8;
- transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_ASIX_REQ_WRITE_MULTICAST_FILTER;
- transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_VENDOR | UX_REQUEST_TARGET_DEVICE;
- transfer_request -> ux_transfer_request_value = 0;
- transfer_request -> ux_transfer_request_index = 0;
+ /* Get transfer request for bulk in reception. */
+ transfer_request = &asix -> ux_host_class_asix_bulk_in_endpoint -> ux_endpoint_transfer_request;
- /* Fill in the multicast filter. */
- _ux_utility_memory_set(setup_buffer, 0, 8); /* Use case of memset is verified. */
- *(setup_buffer +1) = 0x40;
-
- /* Send request to HCD layer. */
- status = _ux_host_stack_transfer_request(transfer_request);
-
- /* Check status, if error, do not proceed. */
- if (status != UX_SUCCESS || transfer_request -> ux_transfer_request_completion_code != UX_SUCCESS ||
- transfer_request -> ux_transfer_request_actual_length != 8)
- {
-
- /* Free all used resources. */
- _ux_utility_memory_free(setup_buffer);
-
- /* Unprotect thread reentry to this instance. */
- _ux_host_semaphore_put(&asix -> ux_host_class_asix_semaphore);
+ /* If there is no buffer ready, read it. */
+ if (buffer == UX_NULL)
+ {
- /* Return completion status. */
- return;
-
- }
+ /* Set the data pointer. */
+ transfer_request -> ux_transfer_request_data_pointer = asix -> ux_host_class_asix_receive_buffer;
- /* Free all used resources. */
- _ux_utility_memory_free(setup_buffer);
+ /* And length. */
+ transfer_request -> ux_transfer_request_requested_length = UX_HOST_CLASS_ASIX_RECEIVE_BUFFER_SIZE;
+ transfer_request -> ux_transfer_request_actual_length = 0;
- /* Setup the physical address of this IP instance. */
- physical_address_msw = (ULONG)((asix -> ux_host_class_asix_node_id[0] << 8) | (asix -> ux_host_class_asix_node_id[1]));
- physical_address_lsw = (ULONG)((asix -> ux_host_class_asix_node_id[2] << 24) | (asix -> ux_host_class_asix_node_id[3] << 16) |
- (asix -> ux_host_class_asix_node_id[4] << 8) | (asix -> ux_host_class_asix_node_id[5]));
-
- /* Register this interface to the NetX USB interface broker. */
- status = _ux_network_driver_activate((VOID *) asix, _ux_host_class_asix_write,
- &asix -> ux_host_class_asix_network_handle,
- physical_address_msw,
- physical_address_lsw);
- if (status != UX_SUCCESS)
- {
+ /* Schedule a reception. */
+ status = _ux_host_stack_transfer_request(transfer_request);
- /* Unprotect thread reentry to this instance. */
- _ux_host_semaphore_put(&asix -> ux_host_class_asix_semaphore);
+ /* Check if it's started successfully. */
+ if (status != UX_SUCCESS)
+ {
- /* Return completion status. */
- return;
- }
+ /* If a packet (chain) is on-going, release it. */
+ if (packet != UX_NULL)
+ {
+ nx_packet_release(packet);
+ packet = UX_NULL;
+ }
+ continue;
+ }
- /* Now the link is up. */
- asix -> ux_host_class_asix_link_state = UX_HOST_CLASS_ASIX_LINK_STATE_UP;
+ /* Wait for transfer completion. */
+ _ux_host_semaphore_get_norc(&transfer_request -> ux_transfer_request_semaphore, UX_WAIT_FOREVER);
- /* Communicate the state with the network driver. */
- _ux_network_driver_link_up(asix -> ux_host_class_asix_network_handle);
-
- /* We can accept reception. Get a NX Packet */
- if (nx_packet_allocate(&asix -> ux_host_class_asix_packet_pool, &packet,
- NX_RECEIVE_PACKET, NX_NO_WAIT) == NX_SUCCESS)
- {
+ /* Check completion code. */
+ if (transfer_request -> ux_transfer_request_completion_code != UX_SUCCESS)
+ {
+ /* Abort transfer. */
+ _ux_host_stack_transfer_request_abort(transfer_request);
- /* Adjust the prepend pointer to take into account the non 3 bit alignment of the ethernet header. */
- packet -> nx_packet_prepend_ptr += sizeof(USHORT);
+ /* If a packet (chain) is on-going, release it. */
+ if (packet != UX_NULL)
+ {
+ nx_packet_release(packet);
+ packet = UX_NULL;
+ }
+ continue;
+ }
- /* We have a packet. Link this packet to the reception transfer request on the bulk in endpoint. */
- transfer_request = &asix -> ux_host_class_asix_bulk_in_endpoint -> ux_endpoint_transfer_request;
-
- /* Set the data pointer. */
- transfer_request -> ux_transfer_request_data_pointer = packet -> nx_packet_prepend_ptr;
+ /* If it's ZLP, reset buffer and ASIX packet and transfer again. */
+ if (transfer_request -> ux_transfer_request_actual_length == 0)
+ {
- /* And length. */
- transfer_request -> ux_transfer_request_requested_length = UX_HOST_CLASS_ASIX_NX_PAYLOAD_SIZE;
- transfer_request -> ux_transfer_request_actual_length = 0;
+ /* Packet should have been processed! */
+ if (packet != UX_NULL)
+ {
- /* Store the packet that owns this transaction. */
- transfer_request -> ux_transfer_request_user_specific = packet;
+ /* ASIX header corrupt? */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_DESCRIPTOR_CORRUPTED);
+ nx_packet_release(packet);
+ packet = UX_NULL;
+ }
- /* Memorize this packet at the beginning of the queue. */
- asix -> ux_host_class_asix_receive_queue = packet;
-
- /* Reset the queue pointer of this packet. */
- packet -> nx_packet_queue_next = UX_NULL;
+ buffer = UX_NULL;
+ buffer_count = 0;
+ asix_length = 0;
+ continue;
+ }
- /* Ask USB to schedule a reception. */
- status = _ux_host_stack_transfer_request(transfer_request);
+ /* Buffer is ready. */
+ buffer = asix -> ux_host_class_asix_receive_buffer;
+ }
- /* Check if the transaction was armed successfully. We do not wait for the packet to be sent here. */
- if (status != UX_SUCCESS)
+ /* There is data in buffer, extract the data to packets. */
+
+ /* If there is no packet, allocate it. */
+ if (packet == UX_NULL)
{
- /* Cancel the packet. */
- asix -> ux_host_class_asix_receive_queue = UX_NULL;
-
+ /* Get a free NX Packet. */
+ available0 = asix -> ux_host_class_asix_packet_pool -> nx_packet_pool_available;
+ status = nx_packet_allocate(asix -> ux_host_class_asix_packet_pool,
+ &packet, NX_RECEIVE_PACKET,
+ UX_MS_TO_TICK(UX_HOST_CLASS_ASIX_PACKET_ALLOCATE_WAIT));
+ available1 = asix -> ux_host_class_asix_packet_pool -> nx_packet_pool_available;
+ if (asix -> ux_host_class_asix_packet_available_min > available1)
+ asix -> ux_host_class_asix_packet_available_min = available1;
+ if (asix -> ux_host_class_asix_packet_available_min > available0)
+ asix -> ux_host_class_asix_packet_available_min = available0;
+ if (status != NX_SUCCESS)
+ {
+
+ /* Error trap. */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_CLASS_ETH_PACKET_ERROR);
+ continue;
+ }
+
+ /* Adjust the prepend pointer to take into account the non 3 bit alignment of the ethernet header. */
+ packet -> nx_packet_prepend_ptr += sizeof(USHORT);
+ packet -> nx_packet_append_ptr = packet -> nx_packet_prepend_ptr;
+
+ /* Log the packet. */
+
}
- }
+ /* Get remaining in buffer. */
+ buffer_remain = transfer_request -> ux_transfer_request_actual_length -
+ buffer_count;
- /* Unprotect thread reentry to this instance. */
- _ux_host_semaphore_put(&asix -> ux_host_class_asix_semaphore);
+ /* For new packet, get packet length from ASIX header. */
+ if (asix_length == 0)
+ {
- return;
- }
+ /* If remaining less than 2 bytes in buffer, read buffer again. */
+ if (buffer_remain < 2)
+ {
+ buffer = UX_NULL;
+ buffer_count = 0;
+ continue;
+ }
- /* Check the link state. It is either pending up or down. */
- if (asix -> ux_host_class_asix_link_state == UX_HOST_CLASS_ASIX_LINK_STATE_PENDING_DOWN)
+ /* Get ASIX packet length. */
+ asix_length = _ux_utility_short_get(buffer + buffer_count);
+ asix_length &= UX_HOST_CLASS_ASIX_RX_PACKET_LENGTH_MASK;
+ asix_count = 0;
+
+ /* If remaining 2-3 bytes, skip 2 of next buffer. */
+ if (buffer_remain < 4)
+ {
+ buffer = UX_NULL;
+ buffer_count = 2;
+ continue;
+ }
+
+ /* Skip header in buffer, it's not copied to NX packet. */
+ buffer_count += 4;
+ buffer_remain -= 4;
+ }
+
+ /* Get remaining in ASIX packet. */
+ asix_remain = asix_length - asix_count;
+
+ /* Get actual length to process. */
+ if (asix_remain <= buffer_remain)
+ copy_length = asix_remain;
+ else
+ copy_length = buffer_remain;
+
+ /* Check if the data is discarded. */
+ if (packet_discard == UX_FALSE && copy_length)
+ {
+
+ /* Append data to packet. */
+ status = nx_packet_data_append(packet,
+ buffer + buffer_count, copy_length,
+ asix -> ux_host_class_asix_packet_pool,
+ UX_MS_TO_TICK(UX_HOST_CLASS_ASIX_PACKET_ALLOCATE_WAIT));
+ if (status != NX_SUCCESS)
+ {
+
+ /* There is error, this ASIX packet is discarded. */
+ packet_discard = UX_TRUE;
+ }
+ }
+
+ /* Update counts. */
+ buffer_count += copy_length;
+ asix_count += copy_length;
+
+ /* If packet size is odd, padding one byte is ignored. */
+ if (asix_length & 0x1u)
+ buffer_count ++;
+
+ /* Check if buffer ends. */
+ if (buffer_count >= transfer_request -> ux_transfer_request_actual_length)
+ {
+ buffer = UX_NULL;
+ buffer_count = 0;
+ }
+
+ /* Check if ASIX packet ends.
+ * - ASIX count achieve its length.
+ * - Buffer achieve its end and it's a short packet.
+ */
+ if (asix_count >= asix_length ||
+ (buffer == UX_NULL &&
+ transfer_request -> ux_transfer_request_actual_length <
+ transfer_request -> ux_transfer_request_requested_length))
+ {
+
+ /* Check if packet is discarded. */
+ if (packet_discard)
+ {
+
+ packet_discard = UX_FALSE;
+
+ /* Re-allocate packet. */
+ nx_packet_release(packet);
+ packet = UX_NULL;
+ continue;
+ }
+
+ /* Send that packet to the NetX USB broker. */
+ _ux_network_driver_packet_received(asix -> ux_host_class_asix_network_handle, packet);
+ packet = UX_NULL;
+
+ /* Reset ASIX packet. */
+ asix_length = 0;
+
+ continue;
+ }
+
+ /* Buffer ends but packet continues. */
+ /* Buffer already reset to start reception again. */
+ }
+
+ /* Release packet not sent to NX. */
+ if (packet)
+ nx_packet_release(packet);
+ }
+ else
{
-
+
+ /* Abort pending transfers. */
+ _ux_host_stack_endpoint_transfer_abort(asix -> ux_host_class_asix_bulk_out_endpoint);
+
/* We need to free the packets that will not be sent. */
current_packet = asix -> ux_host_class_asix_xmit_queue;
-
+
/* Get the next packet associated with the first packet. */
next_packet = current_packet -> nx_packet_queue_next;
-
+
/* Parse all these packets that were scheduled. */
while (current_packet != UX_NULL)
{
-
+
/* Free the packet that was just sent. First do some housekeeping. */
- current_packet -> nx_packet_prepend_ptr = current_packet -> nx_packet_prepend_ptr + UX_HOST_CLASS_ASIX_ETHERNET_SIZE;
+ current_packet -> nx_packet_prepend_ptr = current_packet -> nx_packet_prepend_ptr + UX_HOST_CLASS_ASIX_ETHERNET_SIZE;
current_packet -> nx_packet_length = current_packet -> nx_packet_length - UX_HOST_CLASS_ASIX_ETHERNET_SIZE;
/* And ask Netx to release it. */
- nx_packet_transmit_release(current_packet);
-
+ nx_packet_transmit_release(current_packet);
+
/* Next packet becomes the current one. */
current_packet = next_packet;
-
+
/* Next packet now. */
if (current_packet != UX_NULL)
@@ -423,20 +464,176 @@ ULONG physical_address_lsw;
next_packet = current_packet -> nx_packet_queue_next;
}
-
+
+ /* Communicate the state with the network driver. */
+ _ux_network_driver_link_down(asix -> ux_host_class_asix_network_handle);
/* Now the link is down. */
asix -> ux_host_class_asix_link_state = UX_HOST_CLASS_ASIX_LINK_STATE_DOWN;
- /* Communicate the state with the network driver. */
- _ux_network_driver_link_down(asix -> ux_host_class_asix_network_handle);
-
+ /* Reactivate interrupt notification polling. */
+ _ux_host_stack_transfer_request(&asix -> ux_host_class_asix_interrupt_endpoint -> ux_endpoint_transfer_request);
+
/* Unprotect thread reentry to this instance. */
_ux_host_semaphore_put(&asix -> ux_host_class_asix_semaphore);
-
- return;
-
}
}
}
+
+static inline UINT _ux_host_class_asix_link_up_controls(UX_HOST_CLASS_ASIX *asix)
+{
+
+UCHAR *setup_buffer;
+UX_ENDPOINT *control_endpoint;
+UX_TRANSFER *transfer_request;
+UINT status;
+
+
+ /* We need to get the default control endpoint transfer request pointer. */
+ control_endpoint = &asix -> ux_host_class_asix_device -> ux_device_control_endpoint;
+ transfer_request = &control_endpoint -> ux_endpoint_transfer_request;
+
+ /* Need to allocate memory for the buffer. */
+ setup_buffer = _ux_utility_memory_allocate(UX_SAFE_ALIGN, UX_CACHE_SAFE_MEMORY, UX_HOST_CLASS_ASIX_SETUP_BUFFER_SIZE);
+ if (setup_buffer == UX_NULL)
+ return(UX_MEMORY_INSUFFICIENT);
+
+ /* Request ownership of Serial Management Interface. */
+ transfer_request -> ux_transfer_request_data_pointer = UX_NULL;
+ transfer_request -> ux_transfer_request_requested_length = 0;
+ transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_ASIX_REQ_OWN_SMI ;
+ transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_VENDOR | UX_REQUEST_TARGET_DEVICE;
+ transfer_request -> ux_transfer_request_value = 0;
+ transfer_request -> ux_transfer_request_index = 0;
+
+ /* Send request to HCD layer. */
+ status = _ux_host_stack_transfer_request(transfer_request);
+
+ /* Check status, if error, do not proceed. */
+ if (status != UX_SUCCESS || transfer_request -> ux_transfer_request_completion_code != UX_SUCCESS)
+ {
+
+ /* Free all used resources. */
+ _ux_utility_memory_free(setup_buffer);
+ return(UX_TRANSFER_ERROR);
+ }
+
+ /* Get the value of the PHYIDR1 in the PHY register. */
+ transfer_request -> ux_transfer_request_data_pointer = setup_buffer;
+ transfer_request -> ux_transfer_request_requested_length = 2;
+ transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_ASIX_REQ_READ_PHY_REG;
+ transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_VENDOR | UX_REQUEST_TARGET_DEVICE;
+ transfer_request -> ux_transfer_request_value = asix -> ux_host_class_asix_primary_phy_id;
+ transfer_request -> ux_transfer_request_index = UX_HOST_CLASS_ASIX_PHY_REG_ANLPAR;
+
+ /* Send request to HCD layer. */
+ status = _ux_host_stack_transfer_request(transfer_request);
+
+ /* Check status, if error, do not proceed. */
+ if (status != UX_SUCCESS || transfer_request -> ux_transfer_request_completion_code != UX_SUCCESS ||
+ transfer_request -> ux_transfer_request_actual_length != 2)
+ {
+
+ /* Free all used resources. */
+ _ux_utility_memory_free(setup_buffer);
+ return(UX_TRANSFER_ERROR);
+ }
+
+ /* Release SMI ownership. */
+ transfer_request -> ux_transfer_request_data_pointer = UX_NULL;
+ transfer_request -> ux_transfer_request_requested_length = 0;
+ transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_ASIX_REQ_RELEASE_SMI;
+ transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_VENDOR | UX_REQUEST_TARGET_DEVICE;
+ transfer_request -> ux_transfer_request_value = 0;
+ transfer_request -> ux_transfer_request_index = 0;
+
+ /* Send request to HCD layer. */
+ status = _ux_host_stack_transfer_request(transfer_request);
+
+ /* Check status, if error, do not proceed. */
+ if (status != UX_SUCCESS || transfer_request -> ux_transfer_request_completion_code != UX_SUCCESS)
+ {
+
+ /* Free all used resources. */
+ _ux_utility_memory_free(setup_buffer);
+ return(UX_TRANSFER_ERROR);
+ }
+
+ /* Check speed. */
+ if (asix -> ux_host_class_asix_speed_selected == UX_HOST_CLASS_ASIX_SPEED_SELECTED_100MPBS)
+
+ /* Set speed at 100MBPS. */
+ transfer_request -> ux_transfer_request_value = UX_HOST_CLASS_ASIX_MEDIUM_PS;
+
+ /* Write the value of the Medium Mode. */
+ transfer_request -> ux_transfer_request_data_pointer = UX_NULL;
+ transfer_request -> ux_transfer_request_requested_length = 0;
+ transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_ASIX_REQ_WRITE_MEDIUM_MODE;
+ transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_VENDOR | UX_REQUEST_TARGET_DEVICE;
+ transfer_request -> ux_transfer_request_value |= (UX_HOST_CLASS_ASIX_MEDIUM_FD | UX_HOST_CLASS_ASIX_MEDIUM_BIT2 | UX_HOST_CLASS_ASIX_MEDIUM_RFC_ENABLED |
+ UX_HOST_CLASS_ASIX_MEDIUM_TFC_ENABLED | UX_HOST_CLASS_ASIX_MEDIUM_RE_ENABLED);
+ transfer_request -> ux_transfer_request_index = 0;
+
+ /* Send request to HCD layer. */
+ status = _ux_host_stack_transfer_request(transfer_request);
+
+ /* Check status, if error, do not proceed. */
+ if (status != UX_SUCCESS || transfer_request -> ux_transfer_request_completion_code != UX_SUCCESS)
+ {
+
+ /* Free all used resources. */
+ _ux_utility_memory_free(setup_buffer);
+ return(UX_TRANSFER_ERROR);
+ }
+
+ /* Set the Rx Control register value. */
+ transfer_request -> ux_transfer_request_data_pointer = UX_NULL;
+ transfer_request -> ux_transfer_request_requested_length = 0;
+ transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_ASIX_REQ_WRITE_RX_CTL;
+ transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_VENDOR | UX_REQUEST_TARGET_DEVICE;
+ transfer_request -> ux_transfer_request_value = (UX_HOST_CLASS_ASIX_RXCR_AM | UX_HOST_CLASS_ASIX_RXCR_AB |
+ UX_HOST_CLASS_ASIX_RXCR_SO | UX_HOST_CLASS_ASIX_RXCR_MFB_2048);
+ transfer_request -> ux_transfer_request_index = 0;
+
+ /* Send request to HCD layer. */
+ status = _ux_host_stack_transfer_request(transfer_request);
+
+ /* Check status, if error, do not proceed. */
+ if (status != UX_SUCCESS || transfer_request -> ux_transfer_request_completion_code != UX_SUCCESS)
+ {
+
+ /* Free all used resources. */
+ _ux_utility_memory_free(setup_buffer);
+ return(UX_TRANSFER_ERROR);
+ }
+
+ /* Set the multicast value. */
+ transfer_request -> ux_transfer_request_data_pointer = setup_buffer;
+ transfer_request -> ux_transfer_request_requested_length = 8;
+ transfer_request -> ux_transfer_request_function = UX_HOST_CLASS_ASIX_REQ_WRITE_MULTICAST_FILTER;
+ transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_VENDOR | UX_REQUEST_TARGET_DEVICE;
+ transfer_request -> ux_transfer_request_value = 0;
+ transfer_request -> ux_transfer_request_index = 0;
+
+ /* Fill in the multicast filter. */
+ _ux_utility_memory_set(setup_buffer, 0, 8); /* Use case of memset is verified. */
+ *(setup_buffer +1) = 0x40;
+
+ /* Send request to HCD layer. */
+ status = _ux_host_stack_transfer_request(transfer_request);
+
+ /* Check status, if error, do not proceed. */
+ if (status != UX_SUCCESS || transfer_request -> ux_transfer_request_completion_code != UX_SUCCESS ||
+ transfer_request -> ux_transfer_request_actual_length != 8)
+ {
+
+ /* Free all used resources. */
+ _ux_utility_memory_free(setup_buffer);
+ return(UX_TRANSFER_ERROR);
+ }
+
+ /* Free all used resources. */
+ _ux_utility_memory_free(setup_buffer);
+ return(UX_SUCCESS);
+}
#endif
diff --git a/common/usbx_host_classes/src/ux_host_class_asix_transmission_callback.c b/common/usbx_host_classes/src/ux_host_class_asix_transmission_callback.c
index 204af59..13f2967 100644
--- a/common/usbx_host_classes/src/ux_host_class_asix_transmission_callback.c
+++ b/common/usbx_host_classes/src/ux_host_class_asix_transmission_callback.c
@@ -35,7 +35,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_host_class_asix_transmission_callback PORTABLE C */
-/* 6.1.11 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -77,6 +77,10 @@
/* 04-25-2022 Chaoqiong Xiao Modified comment(s), */
/* fixed standalone compile, */
/* resulting in version 6.1.11 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* supported NX packet chain, */
+/* fixed empty queue handling, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
VOID _ux_host_class_asix_transmission_callback (UX_TRANSFER *transfer_request)
@@ -89,6 +93,9 @@ UX_HOST_CLASS_ASIX *asix;
NX_PACKET *current_packet;
NX_PACKET *next_packet;
UCHAR *packet_header;
+#ifdef UX_HOST_CLASS_ASIX_PACKET_CHAIN_SUPPORT
+ULONG copied;
+#endif
/* Get the class instance for this transfer request. */
asix = (UX_HOST_CLASS_ASIX *) transfer_request -> ux_transfer_request_class_instance;
@@ -110,7 +117,19 @@ UCHAR *packet_header;
/* Check if there is another transfer for this pipe. */
current_packet = asix -> ux_host_class_asix_xmit_queue;
-
+ if (current_packet == UX_NULL)
+ return;
+
+ /* Check if a ZLP is needed. */
+ if ((transfer_request -> ux_transfer_request_actual_length > 0) &&
+ ((transfer_request -> ux_transfer_request_actual_length %
+ transfer_request -> ux_transfer_request_packet_length) == 0))
+ {
+ transfer_request -> ux_transfer_request_requested_length = 0;
+ _ux_host_stack_transfer_request(transfer_request);
+ return;
+ }
+
/* Get the next packet associated with the first packet. */
next_packet = current_packet -> nx_packet_queue_next;
@@ -132,10 +151,33 @@ UCHAR *packet_header;
/* Store the negative length of the payload in the first USHORT. */
_ux_utility_short_put(packet_header+ sizeof(USHORT), (USHORT)(~next_packet -> nx_packet_length));
-
- /* Prepare the values for this new transmission. */
- transfer_request -> ux_transfer_request_data_pointer = packet_header;
- transfer_request -> ux_transfer_request_requested_length = next_packet -> nx_packet_length + (ULONG)sizeof(USHORT) * 2;
+
+#ifdef UX_HOST_CLASS_ASIX_PACKET_CHAIN_SUPPORT
+
+ /* Check if the packets are chained. */
+ if (next_packet -> nx_packet_next)
+ {
+
+ next_packet -> nx_packet_length += sizeof(USHORT) * 2;
+ next_packet -> nx_packet_prepend_ptr -= sizeof(USHORT) * 2;
+ nx_packet_data_extract_offset(next_packet, 0, asix -> ux_host_class_asix_xmit_buffer, next_packet -> nx_packet_length, &copied);
+
+ /* Setup the transaction parameters. */
+ transfer_request -> ux_transfer_request_requested_length = next_packet -> nx_packet_length;
+ transfer_request -> ux_transfer_request_data_pointer = asix -> ux_host_class_asix_xmit_buffer;
+
+ /* Restore packet status. */
+ next_packet -> nx_packet_length -= sizeof(USHORT) * 2;
+ next_packet -> nx_packet_prepend_ptr += sizeof(USHORT) * 2;
+ }
+ else
+#endif
+ {
+
+ /* Prepare the values for this new transmission. */
+ transfer_request -> ux_transfer_request_data_pointer = packet_header;
+ transfer_request -> ux_transfer_request_requested_length = next_packet -> nx_packet_length + (ULONG)sizeof(USHORT) * 2;
+ }
/* Store the packet that owns this transaction. */
transfer_request -> ux_transfer_request_user_specific = next_packet;
diff --git a/common/usbx_host_classes/src/ux_host_class_asix_write.c b/common/usbx_host_classes/src/ux_host_class_asix_write.c
index d30bf62..175e9b6 100644
--- a/common/usbx_host_classes/src/ux_host_class_asix_write.c
+++ b/common/usbx_host_classes/src/ux_host_class_asix_write.c
@@ -35,7 +35,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_host_class_asix_write PORTABLE C */
-/* 6.1.11 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -77,6 +77,11 @@
/* 04-25-2022 Chaoqiong Xiao Modified comment(s), */
/* fixed standalone compile, */
/* resulting in version 6.1.11 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* supported NX packet chain, */
+/* added queue modify protect, */
+/* improved error check, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_host_class_asix_write(VOID *asix_class, NX_PACKET *packet)
@@ -87,12 +92,17 @@ UINT _ux_host_class_asix_write(VOID *asix_class, NX_PACKET *packet)
return(UX_FUNCTION_NOT_SUPPORTED);
#else
+UX_INTERRUPT_SAVE_AREA
UX_TRANSFER *transfer_request;
UINT status;
NX_PACKET *current_packet;
NX_PACKET *next_packet;
UCHAR *packet_header;
UX_HOST_CLASS_ASIX *asix;
+ULONG adjusted_length;
+#ifdef UX_HOST_CLASS_ASIX_PACKET_CHAIN_SUPPORT
+ULONG copied;
+#endif
/* Proper class casting. */
asix = (UX_HOST_CLASS_ASIX *) asix_class;
@@ -100,6 +110,9 @@ UX_HOST_CLASS_ASIX *asix;
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_CLASS_ASIX_WRITE, asix, 0, 0, 0, UX_TRACE_HOST_CLASS_EVENTS, 0, 0)
+ /* Critical enter. */
+ UX_DISABLE
+
/* Ensure the instance is valid. */
if (asix -> ux_host_class_asix_state != UX_HOST_CLASS_INSTANCE_LIVE)
{
@@ -110,9 +123,28 @@ UX_HOST_CLASS_ASIX *asix;
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_HOST_CLASS_INSTANCE_UNKNOWN, asix, 0, 0, UX_TRACE_ERRORS, 0, 0)
+ /* Critical exit. */
+ UX_RESTORE;
return(UX_HOST_CLASS_INSTANCE_UNKNOWN);
}
+ /* Ensure link state is OK. */
+ if (asix -> ux_host_class_asix_link_state != UX_HOST_CLASS_ASIX_LINK_STATE_UP)
+ {
+
+ /* Critical exit. */
+ UX_RESTORE;
+
+ /* Release the packet. */
+ packet -> nx_packet_prepend_ptr = packet -> nx_packet_prepend_ptr + NX_ETHERNET_SIZE;
+ packet -> nx_packet_length = packet -> nx_packet_length - NX_ETHERNET_SIZE;
+ nx_packet_transmit_release(packet);
+
+ /* Report error to application. */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_CLASS_ETH_LINK_STATE_DOWN_ERROR);
+ return(UX_CLASS_ETH_LINK_STATE_DOWN_ERROR);
+ }
+
/* Load the address of the current packet header at the physical header. */
packet_header = packet -> nx_packet_prepend_ptr;
@@ -120,16 +152,38 @@ UX_HOST_CLASS_ASIX *asix;
packet_header -= sizeof(USHORT) * 2;
#if defined(UX_HOST_CLASS_ASIX_HEADER_CHECK_ENABLE)
+
/* Check packet compatibility to avoid writing to unexpected area. */
if (packet_header < packet -> nx_packet_data_start)
{
/* Error trap. */
_ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_HOST_CLASS_MEMORY_ERROR);
+
+ UX_RESTORE;
return(UX_HOST_CLASS_MEMORY_ERROR);
}
#endif
+ /* Packet length validation. */
+ if (UX_OVERFLOW_CHECK_ADD_ULONG(packet -> nx_packet_length, sizeof(USHORT) * 2))
+ {
+
+ /* Error trap. */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_MATH_OVERFLOW);
+ UX_RESTORE
+ return(UX_MATH_OVERFLOW);
+ }
+ adjusted_length = packet -> nx_packet_length + sizeof(USHORT) * 2;
+ if (adjusted_length > UX_HOST_CLASS_ASIX_TRANSMIT_BUFFER_SIZE)
+ {
+
+ /* Error trap. */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_CLASS_ETH_SIZE_ERROR);
+ UX_RESTORE
+ return(UX_CLASS_ETH_SIZE_ERROR);
+ }
+
/* Store the length of the payload in the first USHORT. */
_ux_utility_short_put(packet_header, (USHORT)(packet -> nx_packet_length));
@@ -140,14 +194,57 @@ UX_HOST_CLASS_ASIX *asix;
if (asix -> ux_host_class_asix_xmit_queue == UX_NULL)
{
+ /* Reset the queue pointer of this packet. */
+ packet -> nx_packet_queue_next = UX_NULL;
+
+ /* Memorize this packet at the beginning of the queue. */
+ asix -> ux_host_class_asix_xmit_queue = packet;
+
+ UX_RESTORE
+
/* Nothing is in the queue. We need to arm this transfer. */
/* Get the pointer to the bulk out endpoint transfer request. */
transfer_request = &asix -> ux_host_class_asix_bulk_out_endpoint -> ux_endpoint_transfer_request;
- /* Setup the transaction parameters. */
- transfer_request -> ux_transfer_request_data_pointer = packet_header;
- transfer_request -> ux_transfer_request_requested_length = packet -> nx_packet_length + (ULONG)sizeof(USHORT) * 2;
-
+#ifdef UX_HOST_CLASS_ASIX_PACKET_CHAIN_SUPPORT
+
+ /* Check if the packets are chained. */
+ if (packet -> nx_packet_next)
+ {
+
+ /* Create buffer. */
+ if (asix -> ux_host_class_asix_xmit_buffer == UX_NULL)
+ {
+ asix -> ux_host_class_asix_xmit_buffer = _ux_utility_memory_allocate(UX_NO_ALIGN,
+ UX_CACHE_SAFE_MEMORY, UX_HOST_CLASS_ASIX_TRANSMIT_BUFFER_SIZE);
+ if (asix -> ux_host_class_asix_xmit_buffer == UX_NULL)
+ {
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_MEMORY_INSUFFICIENT);
+ return(UX_MEMORY_INSUFFICIENT);
+ }
+ }
+
+ packet -> nx_packet_length = adjusted_length;
+ packet -> nx_packet_prepend_ptr -= sizeof(USHORT) * 2;
+ nx_packet_data_extract_offset(packet, 0, asix -> ux_host_class_asix_xmit_buffer, packet -> nx_packet_length, &copied);
+
+ /* Setup the transaction parameters. */
+ transfer_request -> ux_transfer_request_requested_length = packet -> nx_packet_length;
+ transfer_request -> ux_transfer_request_data_pointer = asix -> ux_host_class_asix_xmit_buffer;
+
+ /* Restore packet status. */
+ packet -> nx_packet_length -= sizeof(USHORT) * 2;
+ packet -> nx_packet_prepend_ptr += sizeof(USHORT) * 2;
+ }
+ else
+#endif
+ {
+
+ /* Setup the transaction parameters. */
+ transfer_request -> ux_transfer_request_data_pointer = packet_header;
+ transfer_request -> ux_transfer_request_requested_length = adjusted_length;
+ }
+
/* Store the packet that owns this transaction. */
transfer_request -> ux_transfer_request_user_specific = packet;
@@ -155,22 +252,13 @@ UX_HOST_CLASS_ASIX *asix;
status = _ux_host_stack_transfer_request(transfer_request);
/* Check if the transaction was armed successfully. We do not wait for the packet to be sent here. */
- if (status == UX_SUCCESS)
+ if (status != UX_SUCCESS)
{
-
- /* Memorize this packet at the beginning of the queue. */
- asix -> ux_host_class_asix_xmit_queue = packet;
-
- /* Reset the queue pointer of this packet. */
- packet -> nx_packet_queue_next = UX_NULL;
-
- }
-
- else
/* Could not arm this transfer. */
+ asix -> ux_host_class_asix_xmit_queue = UX_NULL;
return(UX_ERROR);
-
+ }
}
else
@@ -199,6 +287,8 @@ UX_HOST_CLASS_ASIX *asix;
/* The packet to be sent is the last in the chain. */
packet -> nx_packet_queue_next = NX_NULL;
+
+ UX_RESTORE
}
/* We are done here. */
diff --git a/common/usbx_host_classes/src/ux_host_class_cdc_ecm_activate.c b/common/usbx_host_classes/src/ux_host_class_cdc_ecm_activate.c
index 3d1dfde..f261331 100644
--- a/common/usbx_host_classes/src/ux_host_class_cdc_ecm_activate.c
+++ b/common/usbx_host_classes/src/ux_host_class_cdc_ecm_activate.c
@@ -37,7 +37,7 @@ UX_HOST_CLASS_CDC_ECM_NX_ETHERNET_POOL_ALLOCSIZE_ASSERT
/* FUNCTION RELEASE */
/* */
/* _ux_host_class_cdc_ecm_activate PORTABLE C */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -100,6 +100,10 @@ UX_HOST_CLASS_CDC_ECM_NX_ETHERNET_POOL_ALLOCSIZE_ASSERT
/* fixed parameter/variable */
/* names conflict C++ keyword, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* deprecated ECM pool option, */
+/* supported NX packet chain, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_host_class_cdc_ecm_activate(UX_HOST_CLASS_COMMAND *command)
@@ -208,19 +212,7 @@ UX_INTERFACE *cur_interface;
if (cdc_ecm -> ux_host_class_cdc_ecm_thread_stack == UX_NULL)
status = UX_MEMORY_INSUFFICIENT;
}
-#ifndef UX_HOST_CLASS_CDC_ECM_USE_PACKET_POOL_FROM_NETX
- if (status == UX_SUCCESS)
- {
- /* Allocate some packet pool for reception.
- * UX_HOST_CLASS_CDC_ECM_NX_ETHERNET_POOL_ALLOCSIZE overflow has been checked by
- * UX_HOST_CLASS_CDC_ECM_NX_ETHERNET_POOL_ALLOCSIZE_ASSERT outside of function.
- */
- cdc_ecm -> ux_host_class_cdc_ecm_pool_memory = _ux_utility_memory_allocate(UX_SAFE_ALIGN, UX_CACHE_SAFE_MEMORY, UX_HOST_CLASS_CDC_ECM_NX_ETHERNET_POOL_ALLOCSIZE);
- if (cdc_ecm -> ux_host_class_cdc_ecm_pool_memory == UX_NULL)
- status = UX_MEMORY_INSUFFICIENT;
- }
-#endif
if (status == UX_SUCCESS)
{
@@ -240,126 +232,110 @@ UX_INTERFACE *cur_interface;
status = _ux_host_semaphore_create(&cdc_ecm -> ux_host_class_cdc_ecm_interrupt_notification_semaphore, "host CDC-ECM interrupt notification semaphore", 0);
if (status == UX_SUCCESS)
{
-#ifndef UX_HOST_CLASS_CDC_ECM_USE_PACKET_POOL_FROM_NETX
- /* Create a packet pool. */
- status = nx_packet_pool_create(&cdc_ecm -> ux_host_class_cdc_ecm_packet_pool, "host CDC-ECM packet pool",
- UX_HOST_CLASS_CDC_ECM_NX_PAYLOAD_SIZE, cdc_ecm -> ux_host_class_cdc_ecm_pool_memory, UX_HOST_CLASS_CDC_ECM_NX_ETHERNET_POOL_ALLOCSIZE);
+
+ /* Create the cdc_ecm class thread. We do not start it yet. */
+ status = _ux_utility_thread_create(&cdc_ecm -> ux_host_class_cdc_ecm_thread,
+ "ux_host_cdc_ecm_thread", _ux_host_class_cdc_ecm_thread,
+ (ULONG) (ALIGN_TYPE) cdc_ecm,
+ cdc_ecm -> ux_host_class_cdc_ecm_thread_stack,
+ UX_THREAD_STACK_SIZE,
+ UX_THREAD_PRIORITY_CLASS,
+ UX_THREAD_PRIORITY_CLASS,
+ UX_NO_TIME_SLICE, UX_DONT_START);
if (status == UX_SUCCESS)
{
-#endif
- /* Create the cdc_ecm class thread. We do not start it yet. */
- status = _ux_utility_thread_create(&cdc_ecm -> ux_host_class_cdc_ecm_thread,
- "ux_host_cdc_ecm_thread", _ux_host_class_cdc_ecm_thread,
- (ULONG) (ALIGN_TYPE) cdc_ecm,
- cdc_ecm -> ux_host_class_cdc_ecm_thread_stack,
- UX_THREAD_STACK_SIZE,
- UX_THREAD_PRIORITY_CLASS,
- UX_THREAD_PRIORITY_CLASS,
- UX_NO_TIME_SLICE, UX_DONT_START);
+
+ UX_THREAD_EXTENSION_PTR_SET(&(cdc_ecm -> ux_host_class_cdc_ecm_thread), cdc_ecm)
+
+ /* We now need to retrieve the MAC address of the node which is embedded in the ECM descriptor.
+ We will parse the entire configuration descriptor of the device and look for the ECM Ethernet Networking Functional Descriptor. */
+ status = _ux_host_class_cdc_ecm_mac_address_get(cdc_ecm);
+
if (status == UX_SUCCESS)
{
- UX_THREAD_EXTENSION_PTR_SET(&(cdc_ecm -> ux_host_class_cdc_ecm_thread), cdc_ecm)
+ /* Setup the physical address of this IP instance. */
+ physical_address_msw = (ULONG)((cdc_ecm -> ux_host_class_cdc_ecm_node_id[0] << 8) | (cdc_ecm -> ux_host_class_cdc_ecm_node_id[1]));
+ physical_address_lsw = (ULONG)((cdc_ecm -> ux_host_class_cdc_ecm_node_id[2] << 24) | (cdc_ecm -> ux_host_class_cdc_ecm_node_id[3] << 16) |
+ (cdc_ecm -> ux_host_class_cdc_ecm_node_id[4] << 8) | (cdc_ecm -> ux_host_class_cdc_ecm_node_id[5]));
- /* We now need to retrieve the MAC address of the node which is embedded in the ECM descriptor.
- We will parse the entire configuration descriptor of the device and look for the ECM Ethernet Networking Functional Descriptor. */
- status = _ux_host_class_cdc_ecm_mac_address_get(cdc_ecm);
+ /* The ethernet link is down by default. */
+ cdc_ecm -> ux_host_class_cdc_ecm_link_state = UX_HOST_CLASS_CDC_ECM_LINK_STATE_DOWN;
+ }
- if (status == UX_SUCCESS)
- {
+ if (status == UX_SUCCESS)
+ {
- /* Setup the physical address of this IP instance. */
- physical_address_msw = (ULONG)((cdc_ecm -> ux_host_class_cdc_ecm_node_id[0] << 8) | (cdc_ecm -> ux_host_class_cdc_ecm_node_id[1]));
- physical_address_lsw = (ULONG)((cdc_ecm -> ux_host_class_cdc_ecm_node_id[2] << 24) | (cdc_ecm -> ux_host_class_cdc_ecm_node_id[3] << 16) |
- (cdc_ecm -> ux_host_class_cdc_ecm_node_id[4] << 8) | (cdc_ecm -> ux_host_class_cdc_ecm_node_id[5]));
+ /* Register this interface to the NetX USB interface broker. */
+ status = _ux_network_driver_activate((VOID *) cdc_ecm, _ux_host_class_cdc_ecm_write,
+ &cdc_ecm -> ux_host_class_cdc_ecm_network_handle,
+ physical_address_msw, physical_address_lsw);
+ }
- /* The ethernet link is down by default. */
- cdc_ecm -> ux_host_class_cdc_ecm_link_state = UX_HOST_CLASS_CDC_ECM_LINK_STATE_DOWN;
- }
+ if (status == UX_SUCCESS)
+ {
- if (status == UX_SUCCESS)
+ /* Mark the cdc_ecm data instance as live now. */
+ cdc_ecm -> ux_host_class_cdc_ecm_state = UX_HOST_CLASS_INSTANCE_LIVE;
+
+ /* This instance of the device must also be stored in the interface container. */
+ interface_ptr -> ux_interface_class_instance = (VOID *) cdc_ecm;
+
+ /* Create this class instance. */
+ _ux_host_stack_class_instance_create(cdc_ecm -> ux_host_class_cdc_ecm_class, (VOID *) cdc_ecm);
+
+ /* Start the interrupt pipe now if it exists. */
+ if (cdc_ecm -> ux_host_class_cdc_ecm_interrupt_endpoint != UX_NULL)
{
- /* Register this interface to the NetX USB interface broker. */
- status = _ux_network_driver_activate((VOID *) cdc_ecm, _ux_host_class_cdc_ecm_write,
- &cdc_ecm -> ux_host_class_cdc_ecm_network_handle,
- physical_address_msw, physical_address_lsw);
+ /* Obtain the transfer request from the interrupt endpoint. */
+ transfer_request = &cdc_ecm -> ux_host_class_cdc_ecm_interrupt_endpoint -> ux_endpoint_transfer_request;
+ status = _ux_host_stack_transfer_request(transfer_request);
}
if (status == UX_SUCCESS)
{
- /* Mark the cdc_ecm data instance as live now. */
- cdc_ecm -> ux_host_class_cdc_ecm_state = UX_HOST_CLASS_INSTANCE_LIVE;
+ /* Activation is complete. */
- /* This instance of the device must also be stored in the interface container. */
- interface_ptr -> ux_interface_class_instance = (VOID *) cdc_ecm;
+ /* Now we can start the CDC-ECM thread. */
+ _ux_utility_thread_resume(&cdc_ecm -> ux_host_class_cdc_ecm_thread);
- /* Create this class instance. */
- _ux_host_stack_class_instance_create(cdc_ecm -> ux_host_class_cdc_ecm_class, (VOID *) cdc_ecm);
-
- /* Start the interrupt pipe now if it exists. */
- if (cdc_ecm -> ux_host_class_cdc_ecm_interrupt_endpoint != UX_NULL)
+ /* We need to inform the application if a function has been programmed
+ in the system structure. */
+ if (_ux_system_host -> ux_system_host_change_function != UX_NULL)
{
-
- /* Obtain the transfer request from the interrupt endpoint. */
- transfer_request = &cdc_ecm -> ux_host_class_cdc_ecm_interrupt_endpoint -> ux_endpoint_transfer_request;
- status = _ux_host_stack_transfer_request(transfer_request);
+
+ /* Call system change function. Note that the application should
+ wait until the link state is up until using this instance. The
+ link state is changed to up by the CDC-ECM thread, which isn't
+ started until after the data interface has been processed. */
+ _ux_system_host -> ux_system_host_change_function(UX_DEVICE_INSERTION, cdc_ecm -> ux_host_class_cdc_ecm_class, (VOID *) cdc_ecm);
}
+
+ /* If trace is enabled, insert this event into the trace buffer. */
+ UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_CLASS_CDC_ECM_ACTIVATE, cdc_ecm, 0, 0, 0, UX_TRACE_HOST_CLASS_EVENTS, 0, 0)
- if (status == UX_SUCCESS)
- {
-
- /* Activation is complete. */
-
- /* Now we can start the CDC-ECM thread. */
- _ux_utility_thread_resume(&cdc_ecm -> ux_host_class_cdc_ecm_thread);
-
- /* We need to inform the application if a function has been programmed
- in the system structure. */
- if (_ux_system_host -> ux_system_host_change_function != UX_NULL)
- {
-
- /* Call system change function. Note that the application should
- wait until the link state is up until using this instance. The
- link state is changed to up by the CDC-ECM thread, which isn't
- started until after the data interface has been processed. */
- _ux_system_host -> ux_system_host_change_function(UX_DEVICE_INSERTION, cdc_ecm -> ux_host_class_cdc_ecm_class, (VOID *) cdc_ecm);
- }
-
- /* If trace is enabled, insert this event into the trace buffer. */
- UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_CLASS_CDC_ECM_ACTIVATE, cdc_ecm, 0, 0, 0, UX_TRACE_HOST_CLASS_EVENTS, 0, 0)
-
- /* If trace is enabled, register this object. */
- UX_TRACE_OBJECT_REGISTER(UX_TRACE_HOST_OBJECT_TYPE_INTERFACE, cdc_ecm, 0, 0, 0)
+ /* If trace is enabled, register this object. */
+ UX_TRACE_OBJECT_REGISTER(UX_TRACE_HOST_OBJECT_TYPE_INTERFACE, cdc_ecm, 0, 0, 0)
- /* Activation was successful. */
- return(UX_SUCCESS);
- }
+ /* Activation was successful. */
+ return(UX_SUCCESS);
+ }
- /* Error starting interrupt endpoint. */
+ /* Error starting interrupt endpoint. */
- /* Destroy this class instance. */
- _ux_host_stack_class_instance_destroy(cdc_ecm -> ux_host_class_cdc_ecm_class, (VOID *) cdc_ecm);
+ /* Destroy this class instance. */
+ _ux_host_stack_class_instance_destroy(cdc_ecm -> ux_host_class_cdc_ecm_class, (VOID *) cdc_ecm);
- /* Unmount instance. */
- interface_ptr -> ux_interface_class_instance = UX_NULL;
- }
-
- /* Delete CDC-ECM thread. */
- _ux_utility_thread_delete(&cdc_ecm -> ux_host_class_cdc_ecm_thread);
+ /* Unmount instance. */
+ interface_ptr -> ux_interface_class_instance = UX_NULL;
}
-#ifndef UX_HOST_CLASS_CDC_ECM_USE_PACKET_POOL_FROM_NETX
- /* Delete packet pool. */
- nx_packet_pool_delete(&cdc_ecm -> ux_host_class_cdc_ecm_packet_pool);
- }
- else
- {
- /* Packet pool creation failed. Notify application. */
- _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_ENUMERATOR, status);
+ /* Delete CDC-ECM thread. */
+ _ux_utility_thread_delete(&cdc_ecm -> ux_host_class_cdc_ecm_thread);
}
-#endif
+
/* Delete interrupt notification semaphore. */
_ux_host_semaphore_delete(&cdc_ecm -> ux_host_class_cdc_ecm_interrupt_notification_semaphore);
}
@@ -378,10 +354,7 @@ UX_INTERFACE *cur_interface;
if (cdc_ecm -> ux_host_class_cdc_ecm_interrupt_endpoint != UX_NULL &&
cdc_ecm -> ux_host_class_cdc_ecm_interrupt_endpoint -> ux_endpoint_transfer_request.ux_transfer_request_data_pointer != UX_NULL)
_ux_utility_memory_free(cdc_ecm -> ux_host_class_cdc_ecm_interrupt_endpoint -> ux_endpoint_transfer_request.ux_transfer_request_data_pointer);
-#ifndef UX_HOST_CLASS_CDC_ECM_USE_PACKET_POOL_FROM_NETX
- if (cdc_ecm -> ux_host_class_cdc_ecm_pool_memory != UX_NULL)
- _ux_utility_memory_free(cdc_ecm -> ux_host_class_cdc_ecm_pool_memory);
-#endif
+
if (cdc_ecm -> ux_host_class_cdc_ecm_thread_stack != UX_NULL)
_ux_utility_memory_free(cdc_ecm -> ux_host_class_cdc_ecm_thread_stack);
diff --git a/common/usbx_host_classes/src/ux_host_class_cdc_ecm_deactivate.c b/common/usbx_host_classes/src/ux_host_class_cdc_ecm_deactivate.c
index ec561e9..3273259 100644
--- a/common/usbx_host_classes/src/ux_host_class_cdc_ecm_deactivate.c
+++ b/common/usbx_host_classes/src/ux_host_class_cdc_ecm_deactivate.c
@@ -36,7 +36,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_host_class_cdc_ecm_deactivate PORTABLE C */
-/* 6.1.11 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -89,6 +89,10 @@
/* internal clean up, */
/* fixed standalone compile, */
/* resulting in version 6.1.11 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* deprecated ECM pool option, */
+/* supported NX packet chain, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_host_class_cdc_ecm_deactivate(UX_HOST_CLASS_COMMAND *command)
@@ -191,13 +195,16 @@ UX_TRANSFER *transfer_request;
/* Destroy the notification semaphore. */
_ux_host_semaphore_delete(&cdc_ecm -> ux_host_class_cdc_ecm_interrupt_notification_semaphore);
-#ifndef UX_HOST_CLASS_CDC_ECM_USE_PACKET_POOL_FROM_NETX
- /* Delete the packet pool. */
- nx_packet_pool_delete(&cdc_ecm -> ux_host_class_cdc_ecm_packet_pool);
- /* Free this pool of packets. */
- _ux_utility_memory_free(cdc_ecm -> ux_host_class_cdc_ecm_pool_memory);
+#ifdef UX_HOST_CLASS_CDC_ECM_PACKET_CHAIN_SUPPORT
+
+ /* Free packet transmission memories. */
+ if (cdc_ecm -> ux_host_class_cdc_ecm_receive_buffer)
+ _ux_utility_memory_free(cdc_ecm -> ux_host_class_cdc_ecm_receive_buffer);
+ if (cdc_ecm -> ux_host_class_cdc_ecm_xmit_buffer)
+ _ux_utility_memory_free(cdc_ecm -> ux_host_class_cdc_ecm_xmit_buffer);
#endif
+
/* Before we free the device resources, we need to inform the application
that the device is removed. */
if (_ux_system_host -> ux_system_host_change_function != UX_NULL)
diff --git a/common/usbx_host_classes/src/ux_host_class_cdc_ecm_mac_address_get.c b/common/usbx_host_classes/src/ux_host_class_cdc_ecm_mac_address_get.c
index 6a65d57..ea9f968 100644
--- a/common/usbx_host_classes/src/ux_host_class_cdc_ecm_mac_address_get.c
+++ b/common/usbx_host_classes/src/ux_host_class_cdc_ecm_mac_address_get.c
@@ -35,7 +35,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_host_class_cdc_ecm_mac_address_get PORTABLE C */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -74,6 +74,9 @@
/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */
/* checked MAC string length, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* checked descriptor length, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_host_class_cdc_ecm_mac_address_get(UX_HOST_CLASS_CDC_ECM *cdc_ecm)
@@ -168,6 +171,20 @@ UCHAR element_hexa_lower;
descriptor_length = *descriptor;
descriptor_type = *(descriptor + 1);
descriptor_subtype = *(descriptor + 2);
+
+ /* Descriptor length validation. */
+ if (descriptor_length < 3 || descriptor_length > total_configuration_length)
+ {
+
+ /* Error trap. */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_DESCRIPTOR_CORRUPTED);
+
+ /* Free descriptor memory. */
+ _ux_utility_memory_free(start_descriptor);
+
+ /* Return error. */
+ return(UX_DESCRIPTOR_CORRUPTED);
+ }
/* Check the type for an interface descriptor and the subtype for a ECM functional descriptor. */
if ((descriptor_type == UX_HOST_CLASS_CDC_ECM_CS_INTERFACE) && (descriptor_subtype == UX_HOST_CLASS_CDC_ECM_FUNCTIONAL_DESCRIPTOR))
diff --git a/common/usbx_host_classes/src/ux_host_class_cdc_ecm_thread.c b/common/usbx_host_classes/src/ux_host_class_cdc_ecm_thread.c
index 24a36e8..fbed582 100644
--- a/common/usbx_host_classes/src/ux_host_class_cdc_ecm_thread.c
+++ b/common/usbx_host_classes/src/ux_host_class_cdc_ecm_thread.c
@@ -36,7 +36,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_host_class_cdc_ecm_thread PORTABLE C */
-/* 6.1.11 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -94,6 +94,11 @@
/* 04-25-2022 Chaoqiong Xiao Modified comment(s), */
/* fixed standalone compile, */
/* resulting in version 6.1.11 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* no length from IP header, */
+/* deprecated ECM pool option, */
+/* supported NX packet chain, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
VOID _ux_host_class_cdc_ecm_thread(ULONG parameter)
@@ -102,11 +107,10 @@ VOID _ux_host_class_cdc_ecm_thread(ULONG parameter)
UX_HOST_CLASS_CDC_ECM *cdc_ecm;
UX_TRANSFER *transfer_request;
NX_PACKET *packet;
-ULONG ip_given_length;
UINT status;
-#ifdef UX_HOST_CLASS_CDC_ECM_USE_PACKET_POOL_FROM_NETX
USB_NETWORK_DEVICE_TYPE *usb_network_device_ptr;
-#endif
+ULONG packet_buffer_size;
+
/* Cast the parameter passed in the thread into the cdc_ecm pointer. */
UX_THREAD_EXTENSION_PTR_GET(cdc_ecm, UX_HOST_CLASS_CDC_ECM, parameter)
@@ -132,7 +136,6 @@ USB_NETWORK_DEVICE_TYPE *usb_network_device_ptr;
while ((cdc_ecm -> ux_host_class_cdc_ecm_link_state == UX_HOST_CLASS_CDC_ECM_LINK_STATE_UP) &&
(cdc_ecm -> ux_host_class_cdc_ecm_device -> ux_device_state == UX_DEVICE_CONFIGURED))
{
-#ifdef UX_HOST_CLASS_CDC_ECM_USE_PACKET_POOL_FROM_NETX
/* Check if we have packet pool available. */
if (cdc_ecm -> ux_host_class_cdc_ecm_packet_pool == UX_NULL)
@@ -152,7 +155,7 @@ USB_NETWORK_DEVICE_TYPE *usb_network_device_ptr;
{
/* IP instance is not available, wait for application to attach the interface. */
- _ux_utility_delay_ms(UX_HOST_CLASS_CDC_ECM_PACKET_POOL_INSTANCE_WAIT);
+ _ux_utility_delay_ms(UX_MS_TO_TICK(UX_HOST_CLASS_CDC_ECM_PACKET_POOL_INSTANCE_WAIT));
}
continue;
}
@@ -160,13 +163,7 @@ USB_NETWORK_DEVICE_TYPE *usb_network_device_ptr;
/* We can accept reception. Get a NX Packet. */
status = nx_packet_allocate(cdc_ecm -> ux_host_class_cdc_ecm_packet_pool, &packet,
NX_RECEIVE_PACKET, UX_MS_TO_TICK(UX_HOST_CLASS_CDC_ECM_PACKET_POOL_WAIT));
-#else
-
- /* We can accept reception. Get a NX Packet. */
- status = nx_packet_allocate(&cdc_ecm -> ux_host_class_cdc_ecm_packet_pool, &packet,
- NX_RECEIVE_PACKET, UX_MS_TO_TICK(UX_HOST_CLASS_CDC_ECM_PACKET_POOL_WAIT));
-#endif
if (status == NX_SUCCESS)
{
@@ -175,10 +172,46 @@ USB_NETWORK_DEVICE_TYPE *usb_network_device_ptr;
/* We have a packet. Link this packet to the reception transfer request on the bulk in endpoint. */
transfer_request = &cdc_ecm -> ux_host_class_cdc_ecm_bulk_in_endpoint -> ux_endpoint_transfer_request;
-
- /* Set the data pointer. */
- transfer_request -> ux_transfer_request_data_pointer = packet -> nx_packet_prepend_ptr;
-
+
+#ifdef UX_HOST_CLASS_CDC_ECM_PACKET_CHAIN_SUPPORT
+
+ /* Check packet buffer size, if too small chain is used. */
+ packet_buffer_size = (ULONG)(packet -> nx_packet_data_end - packet -> nx_packet_prepend_ptr);
+ if (packet_buffer_size < UX_HOST_CLASS_CDC_ECM_NX_PAYLOAD_SIZE)
+ {
+ if (cdc_ecm -> ux_host_class_cdc_ecm_receive_buffer == UX_NULL)
+ {
+ cdc_ecm -> ux_host_class_cdc_ecm_receive_buffer =
+ _ux_utility_memory_allocate(UX_SAFE_ALIGN, UX_CACHE_SAFE_MEMORY,
+ UX_HOST_CLASS_CDC_ECM_NX_PAYLOAD_SIZE);
+ if (cdc_ecm -> ux_host_class_cdc_ecm_receive_buffer == UX_NULL)
+ {
+
+ /* Memory allocation fail. */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_MEMORY_INSUFFICIENT);
+
+ /* Release packet. */
+ nx_packet_release(packet);
+
+ /* Delay to let other threads to run. */
+ _ux_utility_delay_ms(1);
+ continue;
+ }
+
+ }
+
+ /* Set the data pointer. */
+ transfer_request -> ux_transfer_request_data_pointer = cdc_ecm -> ux_host_class_cdc_ecm_receive_buffer;
+ }
+ else
+#endif
+ {
+
+ /* Set the data pointer. */
+ transfer_request -> ux_transfer_request_data_pointer = packet -> nx_packet_prepend_ptr;
+
+ }
+
/* And length. */
transfer_request -> ux_transfer_request_requested_length = UX_HOST_CLASS_CDC_ECM_NX_PAYLOAD_SIZE;
transfer_request -> ux_transfer_request_actual_length = 0;
@@ -216,21 +249,43 @@ USB_NETWORK_DEVICE_TYPE *usb_network_device_ptr;
if (transfer_request -> ux_transfer_request_completion_code == UX_SUCCESS)
{
- /* Get the packet length. */
- packet -> nx_packet_length = transfer_request -> ux_transfer_request_actual_length;
-
- /* Adjust the prepend, length, and append fields. */
- packet -> nx_packet_append_ptr =
- packet->nx_packet_prepend_ptr + transfer_request -> ux_transfer_request_actual_length;
-
- /* Calculate the accurate packet length from ip header */
- if ((*(packet -> nx_packet_prepend_ptr + 12) == 0x08) &&
- (*(packet -> nx_packet_prepend_ptr + 13) == 0))
+#ifdef UX_HOST_CLASS_CDC_ECM_PACKET_CHAIN_SUPPORT
+
+ /* Check if transfer buffer is used. */
+ if (packet -> nx_packet_prepend_ptr !=
+ transfer_request -> ux_transfer_request_data_pointer)
{
- ip_given_length = _ux_utility_short_get_big_endian(packet -> nx_packet_prepend_ptr + 16) + UX_HOST_CLASS_CDC_ECM_ETHERNET_SIZE;
- packet->nx_packet_length = ip_given_length ;
- packet->nx_packet_append_ptr = packet->nx_packet_prepend_ptr + ip_given_length;
+ /* Adjust append_ptr for copy. */
+ packet -> nx_packet_append_ptr = packet -> nx_packet_prepend_ptr;
+
+ /* Append data to packet. */
+ status = nx_packet_data_append(packet,
+ transfer_request -> ux_transfer_request_data_pointer,
+ transfer_request -> ux_transfer_request_actual_length,
+ cdc_ecm -> ux_host_class_cdc_ecm_packet_pool,
+ UX_MS_TO_TICK(UX_HOST_CLASS_CDC_ECM_PACKET_POOL_WAIT));
+ if (status != NX_SUCCESS)
+ {
+
+ /* Release packet. */
+ nx_packet_release(packet);
+
+ /* Error trap. */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_CLASS_ETH_PACKET_ERROR);
+ continue;
+ }
+ }
+ else
+#endif
+ {
+
+ /* Get the packet length. */
+ packet -> nx_packet_length = transfer_request -> ux_transfer_request_actual_length;
+
+ /* Adjust the prepend, length, and append fields. */
+ packet -> nx_packet_append_ptr =
+ packet->nx_packet_prepend_ptr + transfer_request -> ux_transfer_request_actual_length;
}
/* Send that packet to the NetX USB broker. */
diff --git a/common/usbx_host_classes/src/ux_host_class_cdc_ecm_transmission_callback.c b/common/usbx_host_classes/src/ux_host_class_cdc_ecm_transmission_callback.c
index 506097e..157f95d 100644
--- a/common/usbx_host_classes/src/ux_host_class_cdc_ecm_transmission_callback.c
+++ b/common/usbx_host_classes/src/ux_host_class_cdc_ecm_transmission_callback.c
@@ -35,7 +35,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_host_class_cdc_ecm_transmission_callback PORTABLE C */
-/* 6.1.11 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -80,6 +80,9 @@
/* 04-25-2022 Chaoqiong Xiao Modified comment(s), */
/* fixed standalone compile, */
/* resulting in version 6.1.11 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* supported NX packet chain, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
VOID _ux_host_class_cdc_ecm_transmission_callback(UX_TRANSFER *transfer_request)
@@ -92,6 +95,9 @@ UX_HOST_CLASS_CDC_ECM *cdc_ecm;
NX_PACKET *current_packet;
NX_PACKET *next_packet;
UCHAR *packet_header;
+#ifdef UX_HOST_CLASS_CDC_ECM_PACKET_CHAIN_SUPPORT
+ULONG copied;
+#endif
/* Get the data and control class instances for this transfer request. */
cdc_ecm = (UX_HOST_CLASS_CDC_ECM *) transfer_request -> ux_transfer_request_class_instance;
@@ -150,8 +156,22 @@ UCHAR *packet_header;
if (next_packet != UX_NULL)
{
- /* Load the address of the current packet header at the physical header. */
- packet_header = next_packet -> nx_packet_prepend_ptr;
+#ifdef UX_HOST_CLASS_CDC_ECM_PACKET_CHAIN_SUPPORT
+
+ if (next_packet -> nx_packet_next != UX_NULL)
+ {
+
+ /* Put packet to continuous buffer to transfer. */
+ packet_header = cdc_ecm -> ux_host_class_cdc_ecm_xmit_buffer;
+ nx_packet_data_extract_offset(next_packet, 0, packet_header, next_packet -> nx_packet_length, &copied);
+ }
+ else
+#endif
+ {
+
+ /* Load the address of the current packet header at the physical header. */
+ packet_header = next_packet -> nx_packet_prepend_ptr;
+ }
/* Prepare the values for this new transmission. */
transfer_request -> ux_transfer_request_data_pointer = packet_header;
diff --git a/common/usbx_host_classes/src/ux_host_class_cdc_ecm_write.c b/common/usbx_host_classes/src/ux_host_class_cdc_ecm_write.c
index f88878e..76667e1 100644
--- a/common/usbx_host_classes/src/ux_host_class_cdc_ecm_write.c
+++ b/common/usbx_host_classes/src/ux_host_class_cdc_ecm_write.c
@@ -36,7 +36,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_host_class_cdc_ecm_write PORTABLE C */
-/* 6.1.11 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -81,6 +81,9 @@
/* 04-25-2022 Chaoqiong Xiao Modified comment(s), */
/* fixed standalone compile, */
/* resulting in version 6.1.11 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* supported NX packet chain, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_host_class_cdc_ecm_write(VOID *cdc_ecm_class, NX_PACKET *packet)
@@ -92,6 +95,9 @@ UX_TRANSFER *transfer_request;
UINT status;
UCHAR *packet_header;
UX_HOST_CLASS_CDC_ECM *cdc_ecm;
+#ifdef UX_HOST_CLASS_CDC_ECM_PACKET_CHAIN_SUPPORT
+ULONG copied;
+#endif
/* Get the instance. */
cdc_ecm = (UX_HOST_CLASS_CDC_ECM *) cdc_ecm_class;
@@ -124,6 +130,22 @@ UX_HOST_CLASS_CDC_ECM *cdc_ecm;
return(UX_HOST_CLASS_INSTANCE_UNKNOWN);
}
+ /* Validate packet length. */
+ if (packet -> nx_packet_length > UX_HOST_CLASS_CDC_ECM_NX_PAYLOAD_SIZE)
+ {
+
+ /* Restore interrupts. */
+ UX_RESTORE
+
+ /* Error trap. */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_CLASS_ETH_SIZE_ERROR);
+
+ /* If trace is enabled, insert this event into the trace buffer. */
+ UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_CLASS_ETH_SIZE_ERROR, cdc_ecm, packet -> nx_packet_length, 0, UX_TRACE_ERRORS, 0, 0)
+
+ return(UX_CLASS_ETH_SIZE_ERROR);
+ }
+
/* Are we in a valid state? */
if (cdc_ecm -> ux_host_class_cdc_ecm_link_state == UX_HOST_CLASS_CDC_ECM_LINK_STATE_UP)
{
@@ -147,8 +169,35 @@ UX_HOST_CLASS_CDC_ECM *cdc_ecm;
/* Get the pointer to the bulk out endpoint transfer request. */
transfer_request = &cdc_ecm -> ux_host_class_cdc_ecm_bulk_out_endpoint -> ux_endpoint_transfer_request;
- /* Load the address of the current packet header at the physical header. */
- packet_header = packet -> nx_packet_prepend_ptr;
+#ifdef UX_HOST_CLASS_CDC_ECM_PACKET_CHAIN_SUPPORT
+
+ if (packet -> nx_packet_next != UX_NULL)
+ {
+
+ /* Create buffer. */
+ if (cdc_ecm -> ux_host_class_cdc_ecm_xmit_buffer == UX_NULL)
+ {
+ cdc_ecm -> ux_host_class_cdc_ecm_xmit_buffer = _ux_utility_memory_allocate(UX_NO_ALIGN,
+ UX_CACHE_SAFE_MEMORY, UX_HOST_CLASS_CDC_ECM_NX_PAYLOAD_SIZE);
+ if (cdc_ecm -> ux_host_class_cdc_ecm_xmit_buffer == UX_NULL)
+ {
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_MEMORY_INSUFFICIENT);
+ return(UX_MEMORY_INSUFFICIENT);
+ }
+ }
+
+ /* Put packet to continuous buffer to transfer. */
+ packet_header = cdc_ecm -> ux_host_class_cdc_ecm_xmit_buffer;
+ nx_packet_data_extract_offset(packet, 0, packet_header, packet -> nx_packet_length, &copied);
+ }
+ else
+#endif
+ {
+
+ /* Load the address of the current packet header at the physical header. */
+ packet_header = packet -> nx_packet_prepend_ptr;
+
+ }
/* Setup the transaction parameters. */
transfer_request -> ux_transfer_request_data_pointer = packet_header;
diff --git a/common/usbx_host_classes/src/ux_host_class_hid_keyboard_tasks_run.c b/common/usbx_host_classes/src/ux_host_class_hid_keyboard_tasks_run.c
index 37aa1e7..3fdd9d1 100644
--- a/common/usbx_host_classes/src/ux_host_class_hid_keyboard_tasks_run.c
+++ b/common/usbx_host_classes/src/ux_host_class_hid_keyboard_tasks_run.c
@@ -37,7 +37,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_host_class_hid_keyboard_tasks_run PORTABLE C */
-/* 6.1.10 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -71,6 +71,10 @@
/* DATE NAME DESCRIPTION */
/* */
/* 01-31-2022 Chaoqiong Xiao Initial Version 6.1.10 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* improved HID OUTPUT report */
+/* handling in standalone mode,*/
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
VOID _ux_host_class_hid_keyboard_tasks_run(UX_HOST_CLASS_HID_CLIENT *client)
@@ -108,12 +112,22 @@ UINT status;
UX_HID_KEYBOARD_STATE_MASK_LOCK;
/* We need to find the OUTPUT report for the keyboard LEDs. */
- report_id.ux_host_class_hid_report_get_report = UX_NULL;
- report_id.ux_host_class_hid_report_get_type = UX_HOST_CLASS_HID_REPORT_TYPE_OUTPUT;
- status = _ux_host_class_hid_report_id_get(hid, &report_id);
+ if (keyboard -> ux_host_class_hid_keyboard_out_report == UX_NULL)
+ {
+
+ report_id.ux_host_class_hid_report_get_report = UX_NULL;
+ report_id.ux_host_class_hid_report_get_type = UX_HOST_CLASS_HID_REPORT_TYPE_OUTPUT;
+ status = _ux_host_class_hid_report_id_get(hid, &report_id);
+ if (status != UX_SUCCESS)
+ {
+ keyboard -> ux_host_class_hid_keyboard_status = status;
+ return;
+ }
+ keyboard -> ux_host_class_hid_keyboard_out_report = report_id.ux_host_class_hid_report_get_report;
+ }
/* Build a RAW client report. */
- client_report.ux_host_class_hid_client_report = report_id.ux_host_class_hid_report_get_report;
+ client_report.ux_host_class_hid_client_report = keyboard -> ux_host_class_hid_keyboard_out_report;
client_report.ux_host_class_hid_client_report_flags = UX_HOST_CLASS_HID_REPORT_RAW;
client_report.ux_host_class_hid_client_report_length = 1;
client_report.ux_host_class_hid_client_report_buffer = &keyboard -> ux_host_class_hid_keyboard_led_mask;
diff --git a/common/usbx_host_classes/src/ux_host_class_hub_entry.c b/common/usbx_host_classes/src/ux_host_class_hub_entry.c
index abc4770..9a968d8 100644
--- a/common/usbx_host_classes/src/ux_host_class_hub_entry.c
+++ b/common/usbx_host_classes/src/ux_host_class_hub_entry.c
@@ -41,7 +41,7 @@ static inline UINT _ux_host_class_hub_activate_wait(UX_HOST_CLASS_COMMAND *comma
/* FUNCTION RELEASE */
/* */
/* _ux_host_class_hub_entry PORTABLE C */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -80,7 +80,10 @@ static inline UINT _ux_host_class_hub_activate_wait(UX_HOST_CLASS_COMMAND *comma
/* resulting in version 6.1 */
/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */
/* added standalone support, */
-/* resulting in version 6.1 */
+/* resulting in version 6.1.12 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* fixed power on delay calc, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_host_class_hub_entry(UX_HOST_CLASS_COMMAND *command)
@@ -356,7 +359,7 @@ ULONG current_ms, elapsed_ms;
/* Delay a while (as described by hub descriptor). */
hub -> ux_host_class_hub_wait_start = _ux_utility_time_get();
- hub -> ux_host_class_hub_wait_ms = hub -> ux_host_class_hub_descriptor.bPwrOn2PwrGood;
+ hub -> ux_host_class_hub_wait_ms = UX_MS_TO_TICK_NON_ZERO(hub -> ux_host_class_hub_descriptor.bPwrOn2PwrGood << 1);
hub -> ux_host_class_hub_enum_state = UX_HOST_CLASS_HUB_ENUM_TRANS_WAIT;
hub -> ux_host_class_hub_next_state = UX_HOST_CLASS_HUB_ENUM_PORT_POWER_ON;
diff --git a/common/usbx_host_classes/src/ux_host_class_hub_tasks_run.c b/common/usbx_host_classes/src/ux_host_class_hub_tasks_run.c
index c0363f3..2702c39 100644
--- a/common/usbx_host_classes/src/ux_host_class_hub_tasks_run.c
+++ b/common/usbx_host_classes/src/ux_host_class_hub_tasks_run.c
@@ -40,7 +40,7 @@ static inline VOID _ux_host_class_hub_inst_tasks_run(UX_HOST_CLASS_HUB *hub);
/* FUNCTION RELEASE */
/* */
/* _ux_host_class_hub_tasks_run PORTABLE C */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -87,6 +87,9 @@ static inline VOID _ux_host_class_hub_inst_tasks_run(UX_HOST_CLASS_HUB *hub);
/* DATE NAME DESCRIPTION */
/* */
/* 07-29-2022 Chaoqiong Xiao Initial Version 6.1.12 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* fixed reset speed handling, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_host_class_hub_tasks_run(UX_HOST_CLASS *hub_class)
@@ -209,9 +212,11 @@ USHORT port_change = hub -> ux_host_class_hub_run_port_change;
}
static inline VOID _ux_host_class_hub_inst_tasks_run(UX_HOST_CLASS_HUB *hub)
{
+UX_HCD *hcd;
UX_DEVICE *device;
UX_DEVICE *hub_device = hub -> ux_host_class_hub_device;
UX_ENDPOINT *ep0 = &hub_device -> ux_device_control_endpoint;
+UX_ENDPOINT *dev_ep0;
UX_TRANSFER *trans0 = &ep0 -> ux_endpoint_transfer_request;
UINT status;
@@ -385,16 +390,41 @@ UINT status;
/* Save status and speed. */
device -> ux_device_enum_port_status = (UCHAR)hub -> ux_host_class_hub_run_port_status;
+ /* Append speed information. */
+ switch(hub -> ux_host_class_hub_run_port_status &
+ (UX_HOST_CLASS_HUB_PORT_STATUS_LOW_SPEED | UX_HOST_CLASS_HUB_PORT_STATUS_HIGH_SPEED))
+ {
+ case 0: /* It's Full speed. */
+ device -> ux_device_enum_port_status |= UX_PS_DS_FS;
+ device -> ux_device_speed = UX_FULL_SPEED_DEVICE;
+ break;
+
+ case UX_HOST_CLASS_HUB_PORT_STATUS_HIGH_SPEED: /* It's high speed. */
+ device -> ux_device_enum_port_status |= UX_PS_DS_HS;
+ device -> ux_device_speed = UX_HIGH_SPEED_DEVICE;
+ break;
+
+ default: /* It's Low speed. */
+ device -> ux_device_speed = UX_LOW_SPEED_DEVICE;
+ break;
+ }
+
/* Return device address to 0. */
+ hcd = UX_DEVICE_HCD_GET(device);
if (device -> ux_device_address)
{
/* Free the address. */
- UX_DEVICE_HCD_GET(device) ->
- ux_hcd_address[(device -> ux_device_address-1) >> 3] &=
+ hcd -> ux_hcd_address[(device -> ux_device_address-1) >> 3] &=
(UCHAR)(1u << ((device -> ux_device_address-1) & 7u));
+
}
+ /* Assume speed change, re-create EP0 at the HCD level. */
+ dev_ep0 = &device -> ux_device_control_endpoint;
+ hcd -> ux_hcd_entry_function(hcd, UX_HCD_DESTROY_ENDPOINT, (VOID *)dev_ep0);
+ hcd -> ux_hcd_entry_function(hcd, UX_HCD_CREATE_ENDPOINT, (VOID *)dev_ep0);
+
/* Wait a while and set address. */
device -> ux_device_enum_next_state = UX_HOST_STACK_ENUM_DEVICE_ADDR_SET;
device -> ux_device_enum_state = UX_HOST_STACK_ENUM_WAIT;
diff --git a/common/usbx_host_classes/src/ux_host_class_storage_entry.c b/common/usbx_host_classes/src/ux_host_class_storage_entry.c
index 68c68a4..68c68a4 100755..100644
--- a/common/usbx_host_classes/src/ux_host_class_storage_entry.c
+++ b/common/usbx_host_classes/src/ux_host_class_storage_entry.c
diff --git a/common/usbx_host_classes/src/ux_host_class_storage_media_open.c b/common/usbx_host_classes/src/ux_host_class_storage_media_open.c
index 3da9480..7124376 100644
--- a/common/usbx_host_classes/src/ux_host_class_storage_media_open.c
+++ b/common/usbx_host_classes/src/ux_host_class_storage_media_open.c
@@ -35,7 +35,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_host_class_storage_media_open PORTABLE C */
-/* 6.1 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -81,6 +81,9 @@
/* class specific structured */
/* data, */
/* resulting in version 6.1 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* added buffer size check, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_host_class_storage_media_open(UX_HOST_CLASS_STORAGE *storage, ULONG hidden_sectors)
@@ -127,6 +130,16 @@ UX_HOST_CLASS *class_inst;
/* Save the Sector size in the storage media instance. */
storage_media -> ux_host_class_storage_media_sector_size = storage -> ux_host_class_storage_sector_size;
+ /* Check if media setting can support the sector size. */
+ if (storage -> ux_host_class_storage_sector_size > UX_HOST_CLASS_STORAGE_MEMORY_BUFFER_SIZE)
+ {
+ /* Error trap. */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_HOST_CLASS_MEMORY_ERROR);
+
+ /* Required memory is over system setting. */
+ return(UX_HOST_CLASS_MEMORY_ERROR);
+ }
+
/* Save the storage media instance in the user reserved area in the UX_MEDIA structure. */
ux_media_reserved_for_user_set(media, storage_media);
diff --git a/common/usbx_host_classes/src/ux_host_class_storage_partition_read.c b/common/usbx_host_classes/src/ux_host_class_storage_partition_read.c
index c3e17fa..c3e17fa 100755..100644
--- a/common/usbx_host_classes/src/ux_host_class_storage_partition_read.c
+++ b/common/usbx_host_classes/src/ux_host_class_storage_partition_read.c
diff --git a/common/usbx_host_classes/src/ux_host_class_storage_tasks_run.c b/common/usbx_host_classes/src/ux_host_class_storage_tasks_run.c
index 80fe330..ca0c6bf 100644
--- a/common/usbx_host_classes/src/ux_host_class_storage_tasks_run.c
+++ b/common/usbx_host_classes/src/ux_host_class_storage_tasks_run.c
@@ -53,7 +53,7 @@ static inline UINT _ux_host_class_storage_transport_sense_check(UX_HOST_CLASS_ST
/* FUNCTION RELEASE */
/* */
/* _ux_host_class_storage_tasks_run PORTABLE C */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -99,6 +99,9 @@ static inline UINT _ux_host_class_storage_transport_sense_check(UX_HOST_CLASS_ST
/* fixed parameter/variable */
/* names conflict C++ keyword, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* improved internal logic, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_host_class_storage_tasks_run(UX_HOST_CLASS *storage_class)
@@ -132,6 +135,7 @@ ULONG tick_now, tick_elapsed;
UINT status;
UX_TRANSFER *trans;
UX_INTERFACE *interface_ptr;
+INT immediate_state;
/* If storage not live, start initialize. */
if (storage -> ux_host_class_storage_state == UX_HOST_CLASS_INSTANCE_MOUNTING)
@@ -187,7 +191,8 @@ UX_INTERFACE *interface_ptr;
}
/* Handle main states. */
- while(1)
+ immediate_state = UX_TRUE;
+ while(immediate_state)
{
/* Get current state. */
@@ -498,11 +503,15 @@ UX_INTERFACE *interface_ptr;
}
UX_RESTORE
- case UX_STATE_RESET:
+ /* Fall through. */
+
+ case UX_STATE_RESET: /* Fall through. */
default:
break;
}
- break;
+
+ /* Break the loop. */
+ immediate_state = UX_FALSE;
}
}
@@ -730,30 +739,31 @@ INT media_index;
{
/* Skip used storage media slots. */
- if (storage_media -> ux_host_class_storage_media_status == UX_USED)
- continue;
+ if (storage_media -> ux_host_class_storage_media_status != UX_USED)
+ {
- /* Use this free storage media slot. */
- storage_media -> ux_host_class_storage_media_status = UX_USED;
- storage_media -> ux_host_class_storage_media_storage = storage;
+ /* Use this free storage media slot. */
+ storage_media -> ux_host_class_storage_media_status = UX_USED;
+ storage_media -> ux_host_class_storage_media_storage = storage;
- /* Save media information. */
- storage_media -> ux_host_class_storage_media_lun = (UCHAR)storage -> ux_host_class_storage_lun;
- storage_media -> ux_host_class_storage_media_sector_size = (USHORT)storage -> ux_host_class_storage_sector_size;
- storage_media -> ux_host_class_storage_media_number_sectors = storage -> ux_host_class_storage_last_sector_number + 1;
+ /* Save media information. */
+ storage_media -> ux_host_class_storage_media_lun = (UCHAR)storage -> ux_host_class_storage_lun;
+ storage_media -> ux_host_class_storage_media_sector_size = (USHORT)storage -> ux_host_class_storage_sector_size;
+ storage_media -> ux_host_class_storage_media_number_sectors = storage -> ux_host_class_storage_last_sector_number + 1;
- /* Invoke callback for media insertion. */
- if (_ux_system_host -> ux_system_host_change_function != UX_NULL)
- {
+ /* Invoke callback for media insertion. */
+ if (_ux_system_host -> ux_system_host_change_function != UX_NULL)
+ {
- /* Call system change function. */
- /* In standalone mode, no state running (read/write) expected in callback. */
- _ux_system_host -> ux_system_host_change_function(UX_STORAGE_MEDIA_INSERTION,
- storage -> ux_host_class_storage_class, (VOID *) storage_media);
- }
+ /* Call system change function. */
+ /* In standalone mode, no state running (read/write) expected in callback. */
+ _ux_system_host -> ux_system_host_change_function(UX_STORAGE_MEDIA_INSERTION,
+ storage -> ux_host_class_storage_class, (VOID *) storage_media);
+ }
- /* Media saved OK. */
- return;
+ /* Media saved OK. */
+ return;
+ }
}
/* No free slot. */
diff --git a/common/usbx_host_classes/src/ux_host_class_storage_transport_run.c b/common/usbx_host_classes/src/ux_host_class_storage_transport_run.c
index 26a09ee..90cd2b9 100644
--- a/common/usbx_host_classes/src/ux_host_class_storage_transport_run.c
+++ b/common/usbx_host_classes/src/ux_host_class_storage_transport_run.c
@@ -63,7 +63,7 @@ static inline VOID _ux_host_class_storage_transport_ep_reset(UX_HOST_CLASS_STORA
/* FUNCTION RELEASE */
/* */
/* _ux_host_class_storage_transport_run PORTABLE C */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -101,13 +101,18 @@ static inline VOID _ux_host_class_storage_transport_ep_reset(UX_HOST_CLASS_STORA
/* fixed parameter/variable */
/* names conflict C++ keyword, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* improved internal logic, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_host_class_storage_transport_run(UX_HOST_CLASS_STORAGE *storage)
{
UINT status;
UCHAR state;
- while(1)
+INT immediate_state = UX_TRUE;
+
+ while(immediate_state)
{
state = storage -> ux_host_class_storage_trans_state;
switch(state)
@@ -192,7 +197,9 @@ UCHAR state;
default:
break;
}
- break;
+
+ /* Invalid unhandled state, break the loop. */
+ immediate_state = UX_FALSE;
}
/* Unexpected state, fatal error. */
diff --git a/common/usbx_host_classes/src/ux_host_class_video_activate.c b/common/usbx_host_classes/src/ux_host_class_video_activate.c
index 66e5aff..6634324 100644
--- a/common/usbx_host_classes/src/ux_host_class_video_activate.c
+++ b/common/usbx_host_classes/src/ux_host_class_video_activate.c
@@ -87,6 +87,13 @@ UCHAR *baInterfaceNr;
/* Check if this the VC interface is expected. */
bInCollection = packed_entity_descriptor[11];
baInterfaceNr = packed_entity_descriptor + 12;
+
+ /* Validation:
+ * baInterfaceNr not exceeding current descriptor.
+ */
+ if (packed_entity_descriptor[0] + packed_entity_descriptor < baInterfaceNr + bInCollection)
+ return(1);
+
while(bInCollection)
{
@@ -97,6 +104,10 @@ UCHAR *baInterfaceNr;
parser -> parsed_flags |= UX_HOST_CLASS_VIDEO_DESCRIPTORS_PARSER_VC_HEADER;
return(0);
}
+
+ /* Next interface number in descriptor. */
+ baInterfaceNr ++;
+ bInCollection --;
}
}
@@ -159,7 +170,7 @@ UCHAR *baInterfaceNr;
/* FUNCTION RELEASE */
/* */
/* _ux_host_class_video_activate PORTABLE C */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -217,6 +228,9 @@ UCHAR *baInterfaceNr;
/* fixed parameter/variable */
/* names conflict C++ keyword, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* improved VC header check, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_host_class_video_activate(UX_HOST_CLASS_COMMAND *command)
diff --git a/common/usbx_host_classes/src/ux_host_class_video_frame_interval_get.c b/common/usbx_host_classes/src/ux_host_class_video_frame_interval_get.c
index 2bb2b3c..2bb2b3c 100755..100644
--- a/common/usbx_host_classes/src/ux_host_class_video_frame_interval_get.c
+++ b/common/usbx_host_classes/src/ux_host_class_video_frame_interval_get.c
diff --git a/common/usbx_host_controllers/inc/ux_hcd_ehci.h b/common/usbx_host_controllers/inc/ux_hcd_ehci.h
index 036bbf0..036bbf0 100755..100644
--- a/common/usbx_host_controllers/inc/ux_hcd_ehci.h
+++ b/common/usbx_host_controllers/inc/ux_hcd_ehci.h
diff --git a/common/usbx_host_controllers/inc/ux_hcd_ohci.h b/common/usbx_host_controllers/inc/ux_hcd_ohci.h
index acfb4e4..acfb4e4 100755..100644
--- a/common/usbx_host_controllers/inc/ux_hcd_ohci.h
+++ b/common/usbx_host_controllers/inc/ux_hcd_ohci.h
diff --git a/common/usbx_host_controllers/src/ux_hcd_ehci_asynchronous_endpoint_create.c b/common/usbx_host_controllers/src/ux_hcd_ehci_asynchronous_endpoint_create.c
index 0d03bbd..0d03bbd 100755..100644
--- a/common/usbx_host_controllers/src/ux_hcd_ehci_asynchronous_endpoint_create.c
+++ b/common/usbx_host_controllers/src/ux_hcd_ehci_asynchronous_endpoint_create.c
diff --git a/common/usbx_host_controllers/src/ux_hcd_ehci_done_queue_process.c b/common/usbx_host_controllers/src/ux_hcd_ehci_done_queue_process.c
index 7c2dfec..7c2dfec 100755..100644
--- a/common/usbx_host_controllers/src/ux_hcd_ehci_done_queue_process.c
+++ b/common/usbx_host_controllers/src/ux_hcd_ehci_done_queue_process.c
diff --git a/common/usbx_host_controllers/src/ux_hcd_ehci_hsisochronous_tds_process.c b/common/usbx_host_controllers/src/ux_hcd_ehci_hsisochronous_tds_process.c
index 2c5fc4d..2c5fc4d 100755..100644
--- a/common/usbx_host_controllers/src/ux_hcd_ehci_hsisochronous_tds_process.c
+++ b/common/usbx_host_controllers/src/ux_hcd_ehci_hsisochronous_tds_process.c
diff --git a/common/usbx_host_controllers/src/ux_hcd_ehci_interrupt_endpoint_create.c b/common/usbx_host_controllers/src/ux_hcd_ehci_interrupt_endpoint_create.c
index 21de45b..21de45b 100755..100644
--- a/common/usbx_host_controllers/src/ux_hcd_ehci_interrupt_endpoint_create.c
+++ b/common/usbx_host_controllers/src/ux_hcd_ehci_interrupt_endpoint_create.c
diff --git a/common/usbx_host_controllers/src/ux_hcd_ehci_interrupt_endpoint_destroy.c b/common/usbx_host_controllers/src/ux_hcd_ehci_interrupt_endpoint_destroy.c
index 3e7284e..3e7284e 100755..100644
--- a/common/usbx_host_controllers/src/ux_hcd_ehci_interrupt_endpoint_destroy.c
+++ b/common/usbx_host_controllers/src/ux_hcd_ehci_interrupt_endpoint_destroy.c
diff --git a/common/usbx_host_controllers/src/ux_hcd_ehci_isochronous_endpoint_create.c b/common/usbx_host_controllers/src/ux_hcd_ehci_isochronous_endpoint_create.c
index ef068a0..ef068a0 100755..100644
--- a/common/usbx_host_controllers/src/ux_hcd_ehci_isochronous_endpoint_create.c
+++ b/common/usbx_host_controllers/src/ux_hcd_ehci_isochronous_endpoint_create.c
diff --git a/common/usbx_host_controllers/src/ux_hcd_ehci_isochronous_endpoint_destroy.c b/common/usbx_host_controllers/src/ux_hcd_ehci_isochronous_endpoint_destroy.c
index 8fa5720..8fa5720 100755..100644
--- a/common/usbx_host_controllers/src/ux_hcd_ehci_isochronous_endpoint_destroy.c
+++ b/common/usbx_host_controllers/src/ux_hcd_ehci_isochronous_endpoint_destroy.c
diff --git a/common/usbx_host_controllers/src/ux_hcd_ehci_least_traffic_list_get.c b/common/usbx_host_controllers/src/ux_hcd_ehci_least_traffic_list_get.c
index 6297762..6297762 100755..100644
--- a/common/usbx_host_controllers/src/ux_hcd_ehci_least_traffic_list_get.c
+++ b/common/usbx_host_controllers/src/ux_hcd_ehci_least_traffic_list_get.c
diff --git a/common/usbx_host_controllers/src/ux_hcd_ehci_periodic_tree_create.c b/common/usbx_host_controllers/src/ux_hcd_ehci_periodic_tree_create.c
index df4a1b1..df4a1b1 100755..100644
--- a/common/usbx_host_controllers/src/ux_hcd_ehci_periodic_tree_create.c
+++ b/common/usbx_host_controllers/src/ux_hcd_ehci_periodic_tree_create.c
diff --git a/common/usbx_host_controllers/src/ux_hcd_ehci_poll_rate_entry_get.c b/common/usbx_host_controllers/src/ux_hcd_ehci_poll_rate_entry_get.c
index 5e3c229..5e3c229 100755..100644
--- a/common/usbx_host_controllers/src/ux_hcd_ehci_poll_rate_entry_get.c
+++ b/common/usbx_host_controllers/src/ux_hcd_ehci_poll_rate_entry_get.c
diff --git a/common/usbx_host_controllers/src/ux_hcd_ehci_request_control_transfer.c b/common/usbx_host_controllers/src/ux_hcd_ehci_request_control_transfer.c
index 8277267..8277267 100755..100644
--- a/common/usbx_host_controllers/src/ux_hcd_ehci_request_control_transfer.c
+++ b/common/usbx_host_controllers/src/ux_hcd_ehci_request_control_transfer.c
diff --git a/common/usbx_host_controllers/src/ux_hcd_ehci_transfer_abort.c b/common/usbx_host_controllers/src/ux_hcd_ehci_transfer_abort.c
index 24d821d..24d821d 100755..100644
--- a/common/usbx_host_controllers/src/ux_hcd_ehci_transfer_abort.c
+++ b/common/usbx_host_controllers/src/ux_hcd_ehci_transfer_abort.c
diff --git a/common/usbx_host_controllers/src/ux_hcd_ohci_endpoint_error_clear.c b/common/usbx_host_controllers/src/ux_hcd_ohci_endpoint_error_clear.c
index e3bfbaf..e3bfbaf 100755..100644
--- a/common/usbx_host_controllers/src/ux_hcd_ohci_endpoint_error_clear.c
+++ b/common/usbx_host_controllers/src/ux_hcd_ohci_endpoint_error_clear.c
diff --git a/common/usbx_host_controllers/src/ux_hcd_ohci_endpoint_reset.c b/common/usbx_host_controllers/src/ux_hcd_ohci_endpoint_reset.c
index bb32a5a..bb32a5a 100755..100644
--- a/common/usbx_host_controllers/src/ux_hcd_ohci_endpoint_reset.c
+++ b/common/usbx_host_controllers/src/ux_hcd_ohci_endpoint_reset.c
diff --git a/common/usbx_host_controllers/src/ux_hcd_ohci_periodic_endpoint_destroy.c b/common/usbx_host_controllers/src/ux_hcd_ohci_periodic_endpoint_destroy.c
index bd4777d..bd4777d 100755..100644
--- a/common/usbx_host_controllers/src/ux_hcd_ohci_periodic_endpoint_destroy.c
+++ b/common/usbx_host_controllers/src/ux_hcd_ohci_periodic_endpoint_destroy.c
diff --git a/common/usbx_host_controllers/src/ux_hcd_ohci_port_resume.c b/common/usbx_host_controllers/src/ux_hcd_ohci_port_resume.c
index e66ead6..e66ead6 100755..100644
--- a/common/usbx_host_controllers/src/ux_hcd_ohci_port_resume.c
+++ b/common/usbx_host_controllers/src/ux_hcd_ohci_port_resume.c
diff --git a/common/usbx_host_controllers/src/ux_hcd_ohci_port_suspend.c b/common/usbx_host_controllers/src/ux_hcd_ohci_port_suspend.c
index 4cb5639..4cb5639 100755..100644
--- a/common/usbx_host_controllers/src/ux_hcd_ohci_port_suspend.c
+++ b/common/usbx_host_controllers/src/ux_hcd_ohci_port_suspend.c
diff --git a/common/usbx_host_controllers/src/ux_hcd_ohci_power_down_port.c b/common/usbx_host_controllers/src/ux_hcd_ohci_power_down_port.c
index 4b33668..4b33668 100755..100644
--- a/common/usbx_host_controllers/src/ux_hcd_ohci_power_down_port.c
+++ b/common/usbx_host_controllers/src/ux_hcd_ohci_power_down_port.c
diff --git a/common/usbx_host_controllers/src/ux_hcd_ohci_power_on_port.c b/common/usbx_host_controllers/src/ux_hcd_ohci_power_on_port.c
index 9eb639c..9eb639c 100755..100644
--- a/common/usbx_host_controllers/src/ux_hcd_ohci_power_on_port.c
+++ b/common/usbx_host_controllers/src/ux_hcd_ohci_power_on_port.c
diff --git a/common/usbx_host_controllers/src/ux_hcd_ohci_power_root_hubs.c b/common/usbx_host_controllers/src/ux_hcd_ohci_power_root_hubs.c
index fbefb34..fbefb34 100755..100644
--- a/common/usbx_host_controllers/src/ux_hcd_ohci_power_root_hubs.c
+++ b/common/usbx_host_controllers/src/ux_hcd_ohci_power_root_hubs.c
diff --git a/common/usbx_host_controllers/src/ux_hcd_ohci_request_control_transfer.c b/common/usbx_host_controllers/src/ux_hcd_ohci_request_control_transfer.c
index 9379e3b..9379e3b 100755..100644
--- a/common/usbx_host_controllers/src/ux_hcd_ohci_request_control_transfer.c
+++ b/common/usbx_host_controllers/src/ux_hcd_ohci_request_control_transfer.c
diff --git a/common/usbx_host_controllers/src/ux_hcd_ohci_transfer_abort.c b/common/usbx_host_controllers/src/ux_hcd_ohci_transfer_abort.c
index 63fb74f..63fb74f 100755..100644
--- a/common/usbx_host_controllers/src/ux_hcd_ohci_transfer_abort.c
+++ b/common/usbx_host_controllers/src/ux_hcd_ohci_transfer_abort.c
diff --git a/docs/usbx-features.png b/docs/usbx-features.png
new file mode 100644
index 0000000..de5edef
--- /dev/null
+++ b/docs/usbx-features.png
Binary files differ
diff --git a/ports/arm9/gnu/inc/ux_port.h b/ports/arm9/gnu/inc/ux_port.h
index 28c881b..180adbf 100644
--- a/ports/arm9/gnu/inc/ux_port.h
+++ b/ports/arm9/gnu/inc/ux_port.h
@@ -239,7 +239,7 @@ VOID outpl(ULONG,ULONG);
#ifdef UX_SYSTEM_INIT
CHAR _ux_version_id[] =
- "Copyright (c) Microsoft Corporation. All rights reserved. * USBX ARM9/GNU Version 6.1.12 *";
+ "Copyright (c) Microsoft Corporation. All rights reserved. * USBX ARM9/GNU Version 6.2.0 *";
#else
extern CHAR _ux_version_id[];
#endif
diff --git a/ports/arm9/iar/inc/ux_port.h b/ports/arm9/iar/inc/ux_port.h
index 2a5e11e..b9fd63f 100644
--- a/ports/arm9/iar/inc/ux_port.h
+++ b/ports/arm9/iar/inc/ux_port.h
@@ -246,7 +246,7 @@ VOID outpl(ULONG,ULONG);
#ifdef UX_SYSTEM_INIT
CHAR _ux_version_id[] =
- "Copyright (c) Microsoft Corporation. All rights reserved. * USBX ARM9/IAR Version 6.1.12 *";
+ "Copyright (c) Microsoft Corporation. All rights reserved. * USBX ARM9/IAR Version 6.2.0 *";
#else
extern CHAR _ux_version_id[];
#endif
diff --git a/ports/cortex_a15/gnu/inc/ux_port.h b/ports/cortex_a15/gnu/inc/ux_port.h
index d9ea85a..058f509 100644
--- a/ports/cortex_a15/gnu/inc/ux_port.h
+++ b/ports/cortex_a15/gnu/inc/ux_port.h
@@ -235,7 +235,7 @@ VOID outpl(ULONG,ULONG);
#ifdef UX_SYSTEM_INIT
CHAR _ux_version_id[] =
- "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-A15/GNU Version 6.1.12 *";
+ "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-A15/GNU Version 6.2.0 *";
#else
extern CHAR _ux_version_id[];
#endif
diff --git a/ports/cortex_a5/gnu/inc/ux_port.h b/ports/cortex_a5/gnu/inc/ux_port.h
index 742ad9b..46babf4 100644
--- a/ports/cortex_a5/gnu/inc/ux_port.h
+++ b/ports/cortex_a5/gnu/inc/ux_port.h
@@ -242,7 +242,7 @@ VOID outpl(ULONG,ULONG);
#ifdef UX_SYSTEM_INIT
CHAR _ux_version_id[] =
- "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-A5/GNU Version 6.1.12 *";
+ "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-A5/GNU Version 6.2.0 *";
#else
extern CHAR _ux_version_id[];
#endif
diff --git a/ports/cortex_a5/iar/inc/ux_port.h b/ports/cortex_a5/iar/inc/ux_port.h
index 54c8d5c..d1b6118 100644
--- a/ports/cortex_a5/iar/inc/ux_port.h
+++ b/ports/cortex_a5/iar/inc/ux_port.h
@@ -242,7 +242,7 @@ VOID outpl(ULONG,ULONG);
#ifdef UX_SYSTEM_INIT
CHAR _ux_version_id[] =
- "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-A5/IAR Version 6.1.12 *";
+ "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-A5/IAR Version 6.2.0 *";
#else
extern CHAR _ux_version_id[];
#endif
diff --git a/ports/cortex_a5x/ac6/inc/ux_port.h b/ports/cortex_a5x/ac6/inc/ux_port.h
index 1c677a5..887c2b0 100644
--- a/ports/cortex_a5x/ac6/inc/ux_port.h
+++ b/ports/cortex_a5x/ac6/inc/ux_port.h
@@ -259,7 +259,7 @@ VOID outpl(ULONG,ULONG);
#ifdef UX_SYSTEM_INIT
CHAR _ux_version_id[] =
- "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-A5x/AC6 Version 6.1.12 *";
+ "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-A5x/AC6 Version 6.2.0 *";
#else
extern CHAR _ux_version_id[];
#endif
diff --git a/ports/cortex_a7/gnu/inc/ux_port.h b/ports/cortex_a7/gnu/inc/ux_port.h
index c937a33..86edca6 100644
--- a/ports/cortex_a7/gnu/inc/ux_port.h
+++ b/ports/cortex_a7/gnu/inc/ux_port.h
@@ -246,7 +246,7 @@ VOID outpl(ULONG,ULONG);
#ifdef UX_SYSTEM_INIT
CHAR _ux_version_id[] =
- "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-A7/GNU Version 6.1.12 *";
+ "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-A7/GNU Version 6.2.0 *";
#else
extern CHAR _ux_version_id[];
#endif
diff --git a/ports/cortex_a7/iar/inc/ux_port.h b/ports/cortex_a7/iar/inc/ux_port.h
index 3ef6d48..dd01a95 100644
--- a/ports/cortex_a7/iar/inc/ux_port.h
+++ b/ports/cortex_a7/iar/inc/ux_port.h
@@ -246,7 +246,7 @@ VOID outpl(ULONG,ULONG);
#ifdef UX_SYSTEM_INIT
CHAR _ux_version_id[] =
- "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-A7/IAR Version 6.1.12 *";
+ "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-A7/IAR Version 6.2.0 *";
#else
extern CHAR _ux_version_id[];
#endif
diff --git a/ports/cortex_a8/gnu/inc/ux_port.h b/ports/cortex_a8/gnu/inc/ux_port.h
index 9453e58..5cda0b8 100644
--- a/ports/cortex_a8/gnu/inc/ux_port.h
+++ b/ports/cortex_a8/gnu/inc/ux_port.h
@@ -242,7 +242,7 @@ VOID outpl(ULONG,ULONG);
#ifdef UX_SYSTEM_INIT
CHAR _ux_version_id[] =
- "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-A8/GNU Version 6.1.12 *";
+ "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-A8/GNU Version 6.2.0 *";
#else
extern CHAR _ux_version_id[];
#endif
diff --git a/ports/cortex_a8/iar/inc/ux_port.h b/ports/cortex_a8/iar/inc/ux_port.h
index 7a0ee0d..30249c4 100644
--- a/ports/cortex_a8/iar/inc/ux_port.h
+++ b/ports/cortex_a8/iar/inc/ux_port.h
@@ -242,7 +242,7 @@ VOID outpl(ULONG,ULONG);
#ifdef UX_SYSTEM_INIT
CHAR _ux_version_id[] =
- "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-A8/IAR Version 6.1.12 *";
+ "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-A8/IAR Version 6.2.0 *";
#else
extern CHAR _ux_version_id[];
#endif
diff --git a/ports/cortex_a9/gnu/inc/ux_port.h b/ports/cortex_a9/gnu/inc/ux_port.h
index 7af6f39..e2c45f7 100644
--- a/ports/cortex_a9/gnu/inc/ux_port.h
+++ b/ports/cortex_a9/gnu/inc/ux_port.h
@@ -242,7 +242,7 @@ VOID outpl(ULONG,ULONG);
#ifdef UX_SYSTEM_INIT
CHAR _ux_version_id[] =
- "Copyright (c) Microsoft Corporation. All rights reserved. * USBX ARM9/GNU Version 6.1.12 *";
+ "Copyright (c) Microsoft Corporation. All rights reserved. * USBX ARM9/GNU Version 6.2.0 *";
#else
extern CHAR _ux_version_id[];
#endif
diff --git a/ports/cortex_a9/iar/inc/ux_port.h b/ports/cortex_a9/iar/inc/ux_port.h
index 2564a8a..7cbff01 100644
--- a/ports/cortex_a9/iar/inc/ux_port.h
+++ b/ports/cortex_a9/iar/inc/ux_port.h
@@ -242,7 +242,7 @@ VOID outpl(ULONG,ULONG);
#ifdef UX_SYSTEM_INIT
CHAR _ux_version_id[] =
- "Copyright (c) Microsoft Corporation. All rights reserved. * USBX ARM9/IAR Version 6.1.12 *";
+ "Copyright (c) Microsoft Corporation. All rights reserved. * USBX ARM9/IAR Version 6.2.0 *";
#else
extern CHAR _ux_version_id[];
#endif
diff --git a/ports/cortex_m0/gnu/inc/ux_port.h b/ports/cortex_m0/gnu/inc/ux_port.h
index b22c35b..a015ba1 100644
--- a/ports/cortex_m0/gnu/inc/ux_port.h
+++ b/ports/cortex_m0/gnu/inc/ux_port.h
@@ -240,7 +240,7 @@ VOID outpl(ULONG,ULONG);
#ifdef UX_SYSTEM_INIT
CHAR _ux_version_id[] =
- "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-M0/GNU Version 6.1.12 *";
+ "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-M0/GNU Version 6.2.0 *";
#else
extern CHAR _ux_version_id[];
#endif
diff --git a/ports/cortex_m0/iar/inc/ux_port.h b/ports/cortex_m0/iar/inc/ux_port.h
index b1d10d5..8c6241a 100644
--- a/ports/cortex_m0/iar/inc/ux_port.h
+++ b/ports/cortex_m0/iar/inc/ux_port.h
@@ -242,7 +242,7 @@ VOID outpl(ULONG,ULONG);
#ifdef UX_SYSTEM_INIT
CHAR _ux_version_id[] =
- "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-M0/IAR Version 6.1.12 *";
+ "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-M0/IAR Version 6.2.0 *";
#else
extern CHAR _ux_version_id[];
#endif
diff --git a/ports/cortex_m3/gnu/inc/ux_port.h b/ports/cortex_m3/gnu/inc/ux_port.h
index 11ddb42..a26b679 100644
--- a/ports/cortex_m3/gnu/inc/ux_port.h
+++ b/ports/cortex_m3/gnu/inc/ux_port.h
@@ -240,7 +240,7 @@ VOID outpl(ULONG,ULONG);
#ifdef UX_SYSTEM_INIT
CHAR _ux_version_id[] =
- "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-M3/GNU Version 6.1.12 *";
+ "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-M3/GNU Version 6.2.0 *";
#else
extern CHAR _ux_version_id[];
#endif
diff --git a/ports/cortex_m3/iar/inc/ux_port.h b/ports/cortex_m3/iar/inc/ux_port.h
index d3807ae..a32cb28 100644
--- a/ports/cortex_m3/iar/inc/ux_port.h
+++ b/ports/cortex_m3/iar/inc/ux_port.h
@@ -242,7 +242,7 @@ VOID outpl(ULONG,ULONG);
#ifdef UX_SYSTEM_INIT
CHAR _ux_version_id[] =
- "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-M3/IAR Version 6.1.12 *";
+ "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-M3/IAR Version 6.2.0 *";
#else
extern CHAR _ux_version_id[];
#endif
diff --git a/ports/cortex_m4/gnu/inc/ux_port.h b/ports/cortex_m4/gnu/inc/ux_port.h
index 7113f32..c1eb4ac 100644
--- a/ports/cortex_m4/gnu/inc/ux_port.h
+++ b/ports/cortex_m4/gnu/inc/ux_port.h
@@ -240,7 +240,7 @@ VOID outpl(ULONG,ULONG);
#ifdef UX_SYSTEM_INIT
CHAR _ux_version_id[] =
- "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-M4/GNU Version 6.1.12 *";
+ "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-M4/GNU Version 6.2.0 *";
#else
extern CHAR _ux_version_id[];
#endif
diff --git a/ports/cortex_m4/iar/inc/ux_port.h b/ports/cortex_m4/iar/inc/ux_port.h
index 28f56e7..22f4250 100644
--- a/ports/cortex_m4/iar/inc/ux_port.h
+++ b/ports/cortex_m4/iar/inc/ux_port.h
@@ -242,7 +242,7 @@ VOID outpl(ULONG,ULONG);
#ifdef UX_SYSTEM_INIT
CHAR _ux_version_id[] =
- "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-M4/IAR Version 6.1.12 *";
+ "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-M4/IAR Version 6.2.0 *";
#else
extern CHAR _ux_version_id[];
#endif
diff --git a/ports/cortex_m7/gnu/inc/ux_port.h b/ports/cortex_m7/gnu/inc/ux_port.h
index 62e9567..a8e50f6 100644
--- a/ports/cortex_m7/gnu/inc/ux_port.h
+++ b/ports/cortex_m7/gnu/inc/ux_port.h
@@ -240,7 +240,7 @@ VOID outpl(ULONG,ULONG);
#ifdef UX_SYSTEM_INIT
CHAR _ux_version_id[] =
- "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-M7/GNU Version 6.1.12 *";
+ "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-M7/GNU Version 6.2.0 *";
#else
extern CHAR _ux_version_id[];
#endif
diff --git a/ports/cortex_m7/iar/inc/ux_port.h b/ports/cortex_m7/iar/inc/ux_port.h
index dd8f892..813bd4e 100644
--- a/ports/cortex_m7/iar/inc/ux_port.h
+++ b/ports/cortex_m7/iar/inc/ux_port.h
@@ -242,7 +242,7 @@ VOID outpl(ULONG,ULONG);
#ifdef UX_SYSTEM_INIT
CHAR _ux_version_id[] =
- "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-M7/IAR Version 6.1.12 *";
+ "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-M7/IAR Version 6.2.0 *";
#else
extern CHAR _ux_version_id[];
#endif
diff --git a/ports/cortex_r4/gnu/inc/ux_port.h b/ports/cortex_r4/gnu/inc/ux_port.h
index 09c1130..ba0a5cf 100644
--- a/ports/cortex_r4/gnu/inc/ux_port.h
+++ b/ports/cortex_r4/gnu/inc/ux_port.h
@@ -238,7 +238,7 @@ VOID outpl(ULONG,ULONG);
#ifdef UX_SYSTEM_INIT
CHAR _ux_version_id[] =
- "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-R4/GNU Version 6.1.12 *";
+ "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-R4/GNU Version 6.2.0 *";
#else
extern CHAR _ux_version_id[];
#endif
diff --git a/ports/cortex_r4/iar/inc/ux_port.h b/ports/cortex_r4/iar/inc/ux_port.h
index 932e71a..2d5dc12 100644
--- a/ports/cortex_r4/iar/inc/ux_port.h
+++ b/ports/cortex_r4/iar/inc/ux_port.h
@@ -242,7 +242,7 @@ VOID outpl(ULONG,ULONG);
#ifdef UX_SYSTEM_INIT
CHAR _ux_version_id[] =
- "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-R4/IAR Version 6.1.12 *";
+ "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-R4/IAR Version 6.2.0 *";
#else
extern CHAR _ux_version_id[];
#endif
diff --git a/ports/cortex_r5/gnu/inc/ux_port.h b/ports/cortex_r5/gnu/inc/ux_port.h
index 6654a7b..940d729 100644
--- a/ports/cortex_r5/gnu/inc/ux_port.h
+++ b/ports/cortex_r5/gnu/inc/ux_port.h
@@ -242,7 +242,7 @@ VOID outpl(ULONG,ULONG);
#ifdef UX_SYSTEM_INIT
CHAR _ux_version_id[] =
- "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-R5/GNU Version 6.1.12 *";
+ "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-R5/GNU Version 6.2.0 *";
#else
extern CHAR _ux_version_id[];
#endif
diff --git a/ports/cortex_r5/iar/inc/ux_port.h b/ports/cortex_r5/iar/inc/ux_port.h
index 03829eb..c8a1bbf 100644
--- a/ports/cortex_r5/iar/inc/ux_port.h
+++ b/ports/cortex_r5/iar/inc/ux_port.h
@@ -242,7 +242,7 @@ VOID outpl(ULONG,ULONG);
#ifdef UX_SYSTEM_INIT
CHAR _ux_version_id[] =
- "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-R5/IAR Version 6.1.12 *";
+ "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Cortex-R5/IAR Version 6.2.0 *";
#else
extern CHAR _ux_version_id[];
#endif
diff --git a/ports/generic/inc/ux_port.h b/ports/generic/inc/ux_port.h
index 4973c2a..8ac0137 100644
--- a/ports/generic/inc/ux_port.h
+++ b/ports/generic/inc/ux_port.h
@@ -242,7 +242,7 @@ VOID outpl(ULONG,ULONG);
#ifdef UX_SYSTEM_INIT
CHAR _ux_version_id[] =
- "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Generic Version 6.1.12 *";
+ "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Generic Version 6.2.0 *";
#else
extern CHAR _ux_version_id[];
#endif
diff --git a/ports/linux/gnu/inc/ux_port.h b/ports/linux/gnu/inc/ux_port.h
index 0ebd923..5795435 100644
--- a/ports/linux/gnu/inc/ux_port.h
+++ b/ports/linux/gnu/inc/ux_port.h
@@ -244,7 +244,7 @@ ULONG outpl(ULONG,ULONG);
#ifdef UX_SYSTEM_INIT
CHAR _ux_version_id[] =
- "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Linux/GNU Version 6.1.12 *";
+ "Copyright (c) Microsoft Corporation. All rights reserved. * USBX Linux/GNU Version 6.2.0 *";
#else
extern CHAR _ux_version_id[];
#endif