Initial commit

This commit is contained in:
PProvost 2020-05-11 09:03:23 -06:00
commit 15044435fb
762 changed files with 131832 additions and 0 deletions

41
.gitattributes vendored Normal file
View File

@ -0,0 +1,41 @@
.git* export-ignore
.hooks* export-ignore
# Custom attribute to mark sources as using our C code style.
[attr]our-c-style whitespace=tab-in-indent eol=lf format.clang-format-6.0
# Custom attribute to mark sources as generated.
# Do not perform whitespace checks. Do not format.
[attr]generated whitespace=-tab-in-indent,-indent-with-non-tab -format.clang-format-6.0
bootstrap eol=lf
configure eol=lf
*.[1-9] eol=lf
*.bash eol=lf
*.sh eol=lf
*.sh.in eol=lf
*.bat eol=crlf
*.bat.in eol=crlf
*.sln eol=crlf
*.vcproj eol=crlf
*.inf eol=crlf
*.pfx -text
*.png -text
*.png.in -text
*.c our-c-style
*.cc our-c-style
*.cpp our-c-style
*.cu our-c-style
*.cxx our-c-style
*.h our-c-style
*.hh our-c-style
*.hpp our-c-style
*.hxx our-c-style
*.notcu our-c-style
*.cmake whitespace=tab-in-indent
*.rst whitespace=tab-in-indent conflict-marker-size=79
*.txt whitespace=tab-in-indent

14
.gitignore vendored Executable file
View File

@ -0,0 +1,14 @@
.vscode/
_deps/
build/
CMakeFiles/
CMakeScripts/
CMakeLists.txt.user
CMakeCache.txt
Testing
Makefile
cmake_install.cmake
install_manifest.txt
compile_commands.json
CTestTestfile.cmake

51
CMakeLists.txt Executable file
View File

@ -0,0 +1,51 @@
cmake_minimum_required(VERSION 3.0.0 FATAL_ERROR)
# Set up the project
project(usbx
VERSION 6.0.0
LANGUAGES C ASM
)
if(NOT DEFINED THREADX_ARCH)
message(FATAL_ERROR "Error: THREADX_ARCH not defined")
endif()
if(NOT DEFINED THREADX_TOOLCHAIN)
message(FATAL_ERROR "Error: THREADX_TOOLCHAIN not defined")
endif()
# Define our target library and an alias for consumers
add_library(${PROJECT_NAME})
add_library("azrtos::${PROJECT_NAME}" ALIAS ${PROJECT_NAME})
# Define any required dependencies between this library and others
target_link_libraries(${PROJECT_NAME} PUBLIC
"azrtos::threadx"
"azrtos::filex"
"azrtos::netxduo"
)
# A place for generated/copied include files
set(CUSTOM_INC_DIR ${CMAKE_CURRENT_BINARY_DIR}/custom_inc)
# Pick up the port specific stuff first
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/ports/${THREADX_ARCH}/${THREADX_TOOLCHAIN})
# Then the common files
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/common)
# If the user provided an override, copy it to the custom directory
if (NOT UX_USER_FILE)
message(STATUS "Using default ux_user.h file")
set(UX_USER_FILE ${CMAKE_CURRENT_LIST_DIR}/common/inc/ux_user_sample.h)
else()
message(STATUS "Using custom ux_user.h file from ${UX_USER_FILE}")
endif()
configure_file(${UX_USER_FILE} ${CUSTOM_INC_DIR}/ux_user.h COPYONLY)
target_include_directories(${PROJECT_NAME}
PUBLIC
${CUSTOM_INC_DIR}
)
target_compile_definitions(${PROJECT_NAME} PUBLIC "UX_INCLUDE_USER_DEFINE_FILE" )

246
LICENSE.txt Normal file
View File

@ -0,0 +1,246 @@
MICROSOFT SOFTWARE LICENSE TERMS
MICROSOFT AZURE RTOS
Shape
These license terms are an agreement between you and Microsoft Corporation (or
one of its affiliates). They apply to the software named above and any Microsoft
services or software updates (except to the extent such services or updates are
accompanied by new or additional terms, in which case those different terms
apply prospectively and do not alter your or Microsofts rights relating to
pre-updated software or services). IF YOU COMPLY WITH THESE LICENSE TERMS, YOU
HAVE THE RIGHTS BELOW. BY USING THE SOFTWARE, YOU ACCEPT THESE TERMS.
INSTALLATION AND USE RIGHTS.
General. You may install and use the software and the included Microsoft
applications solely for internal development, testing and evaluation purposes.
Any distribution or production use requires a separate license as set forth in
Section 2.
Contributions. Microsoft welcomes contributions to this software. In the event
that you make a contribution to this software you will be required to agree to a
Contributor License Agreement (CLA) declaring that you have the right to, and
actually do, grant Microsoft the rights to use your contribution. For details,
visit https://cla.microsoft.com.
Included Microsoft Applications. The software includes other Microsoft
applications which are governed by the licenses embedded in or made available
with those applications.
Third Party Components. The software may include third party components with
separate legal notices or governed by other agreements, as may be described
within the software or in the ThirdPartyNotices file(s) accompanying the
software.
Competitive Benchmarking. If you are a direct competitor, and you access or use
the software for purposes of competitive benchmarking, analysis, or intelligence
gathering, you waive as against Microsoft, its subsidiaries, and its affiliated
companies (including prospectively) any competitive use, access, and
benchmarking test restrictions in the terms governing your software to the
extent your terms of use are, or purport to be, more restrictive than
Microsofts terms. If you do not waive any such purported restrictions in the
terms governing your software, you are not allowed to access or use this
software, and will not do so.
DISTRIBUTION AND PRODUCTION USE. If you have obtained and/or are developing on
microprocessor(s) and/or microcontroller(s) (“hardware”) listed in the file
named “LICENSED-HARDWARE.txt” included in the repository and/or distributed with
the software you have the following rights in and to the software solely when
used in combination with the hardware. In the event hardware is not listed in
the LICENSED-HARDWARE.txt file, you do not have the rights in this Section 2.
Distribution and Production Use Rights.
You may use the software in production (e.g. program the modified or unmodified
software to devices you own or control) and distribute (i.e. make available to
third parties) the modified or unmodified binary image produced from this code.
You may permit your device distributors or developers to copy and distribute the
binary image as programmed or to be programmed to your devices.
You may redistribute the unmodified or modified source to your device
distributors or developers. Modifications must be clearly marked. Any
redistribution in source code form must contain this license and any other
licenses that accompany the software.
Requirements. For any code you distribute, you must:
when distributed in binary form, except as embedded in a device, include with
such distribution the terms of this agreement;
when distributed in source code form to distributors or developers of your
devices, include with such distribution the terms of this agreement; and
indemnify, defend and hold harmless Microsoft from any claims, including
attorneys fees, related to the distribution or use of your devices, except to
the extent that any claim is based solely on the unmodified software.
Restrictions. You may not:
use or modify the software to create a competing real time operating system
software;
remove any copyright notices or licenses contained in the software;
use Microsofts trademarks or trade dress in your application in any way that
suggests your device or application comes from or is endorsed by Microsoft;
transfer individual components, specific libraries, classes, functions or code
fragments of the software separately for purposes unrelated to the software; or
use or distribute the software in any way that would subject the software or
Microsofts intellectual property or technology to any other license terms.
SCOPE OF LICENSE. The software is licensed, not sold. Microsoft reserves all
other rights. Unless applicable law gives you more rights despite this
limitation, you will not (and have no right to):
remove, minimize, block, or modify any notices of Microsoft or its suppliers in
the software;
use the software in any way that is against the law or to create or propagate
malware; or
share, publish, distribute, or lease the software (except as permitted in
Section 2 above), or provide the software as a stand-alone offering for others
to use.
DATA. This software may interact with other Microsoft products that collect data
that is transmitted to Microsoft. To learn more about how Microsoft processes
personal data we collect, please see the Microsoft Privacy Statement at
https://go.microsoft.com/fwlink/?LinkId=248681.
EXPORT RESTRICTIONS. You must comply with all domestic and international export
laws and regulations that apply to the software, which include restrictions on
destinations, end users, and end use. For further information on export
restrictions, visit https://aka.ms/exporting.
SUPPORT SERVICES. Microsoft is not obligated under this agreement to provide any
support services for the software. Any support provided is “as is”, “with all
faults”, and without warranty of any kind.
UPDATES. Microsoft may periodically update the software. You may obtain updates
only from Microsoft or Microsoft-authorized sources. Updates may not include or
support all existing software features, services, or peripheral devices.
TERMINATION. Without prejudice to any other rights, Microsoft may terminate this
agreement if you fail to comply with any of its terms or conditions. In such
event, you must destroy all copies of the software and all of its component
parts.
ENTIRE AGREEMENT. This agreement, and any other terms Microsoft may provide for
supplements, updates, or third-party applications, is the entire agreement for
the software. To the extent you have entered into a separate agreement with
Microsoft relating specifically to the software, the terms in such agreement
shall control.
APPLICABLE LAW AND PLACE TO RESOLVE DISPUTES. If you acquired the software in
the United States or Canada, the laws of the state or province where you live
(or, if a business, where your principal place of business is located) govern
the interpretation of this agreement, claims for its breach, and all other
claims (including consumer protection, unfair competition, and tort claims),
regardless of conflict of laws principles. If you acquired the software in any
other country, its laws apply. If U.S. federal jurisdiction exists, you and
Microsoft consent to exclusive jurisdiction and venue in the federal court in
King County, Washington for all disputes heard in court. If not, you and
Microsoft consent to exclusive jurisdiction and venue in the Superior Court of
King County, Washington for all disputes heard in court.
CONSUMER RIGHTS; REGIONAL VARIATIONS. This agreement describes certain legal
rights. You may have other rights, including consumer rights, under the laws of
your state or country. Separate and apart from your relationship with Microsoft,
you may also have rights with respect to the party from which you acquired the
software. This agreement does not change those other rights if the laws of your
state or country do not permit it to do so. For example, if you acquired the
software in one of the below regions, or mandatory country law applies, then the
following provisions apply to you:
Australia. You have statutory guarantees under the Australian Consumer Law and
nothing in this agreement is intended to affect those rights.
Germany and Austria.
i.Warranty. The properly licensed software will perform substantially as
described in any Microsoft materials that accompany the software. However,
Microsoft gives no contractual guarantee in relation to the licensed software.
ii.Limitation of Liability. In case of intentional conduct, gross negligence,
claims based on the Product Liability Act, as well as, in case of death or
personal or physical injury, Microsoft is liable according to the statutory law.
Subject to the foregoing clause ii., Microsoft will only be liable for slight
negligence if Microsoft is in breach of such material contractual obligations,
the fulfillment of which facilitate the due performance of this agreement, the
breach of which would endanger the purpose of this agreement and the compliance
with which a party may constantly trust in (so-called "cardinal obligations").
In other cases of slight negligence, Microsoft will not be liable for slight
negligence.
DISCLAIMER OF WARRANTY. THE SOFTWARE IS LICENSED “AS IS.” YOU BEAR THE RISK OF
USING IT. MICROSOFT GIVES NO EXPRESS WARRANTIES, GUARANTEES, OR CONDITIONS. TO
THE EXTENT PERMITTED UNDER APPLICABLE LAWS, MICROSOFT EXCLUDES ALL IMPLIED
WARRANTIES, INCLUDING MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
NON-INFRINGEMENT.
LIMITATION ON AND EXCLUSION OF DAMAGES. IF YOU HAVE ANY BASIS FOR RECOVERING
DAMAGES DESPITE THE PRECEDING DISCLAIMER OF WARRANTY, YOU CAN RECOVER FROM
MICROSOFT AND ITS SUPPLIERS ONLY DIRECT DAMAGES UP TO U.S. $5.00. YOU CANNOT
RECOVER ANY OTHER DAMAGES, INCLUDING CONSEQUENTIAL, LOST PROFITS, SPECIAL,
INDIRECT, OR INCIDENTAL DAMAGES.
This limitation applies to (a) anything related to the software, services,
content (including code) on third party Internet sites, or third party
applications; and (b) claims for breach of contract, warranty, guarantee, or
condition; strict liability, negligence, or other tort; or any other claim; in
each case to the extent permitted by applicable law.
It also applies even if Microsoft knew or should have known about the
possibility of the damages. The above limitation or exclusion may not apply to
you because your state, province, or country may not allow the exclusion or
limitation of incidental, consequential, or other damages.
Please note: As this software is distributed in Canada, some of the clauses in
this agreement are provided below in French.
Remarque: Ce logiciel étant distribué au Canada, certaines des clauses dans ce
contrat sont fournies ci-dessous en français.
EXONÉRATION DE GARANTIE. Le logiciel visé par une licence est offert « tel quel
». Toute utilisation de ce logiciel est à votre seule risque et péril. Microsoft
naccorde aucune autre garantie expresse. Vous pouvez bénéficier de droits
additionnels en vertu du droit local sur la protection des consommateurs, que ce
contrat ne peut modifier. La ou elles sont permises par le droit locale, les
garanties implicites de qualité marchande, dadéquation à un usage particulier
et dabsence de contrefaçon sont exclues.
LIMITATION DES DOMMAGES-INTÉRÊTS ET EXCLUSION DE RESPONSABILITÉ POUR LES
DOMMAGES. Vous pouvez obtenir de Microsoft et de ses fournisseurs une
indemnisation en cas de dommages directs uniquement à hauteur de 5,00 $ US. Vous
ne pouvez prétendre à aucune indemnisation pour les autres dommages, y compris
les dommages spéciaux, indirects ou accessoires et pertes de bénéfices.
Cette limitation concerne:
•tout ce qui est relié au logiciel, aux services ou au contenu (y compris le
code) figurant sur des sites Internet tiers ou dans des programmes tiers; et
•les réclamations au titre de violation de contrat ou de garantie, ou au titre
de responsabilité stricte, de négligence ou dune autre faute dans la limite
autorisée par la loi en vigueur.
Elle sapplique également, même si Microsoft connaissait ou devrait connaître
léventualité dun tel dommage. Si votre pays nautorise pas lexclusion ou la
limitation de responsabilité pour les dommages indirects, accessoires ou de
quelque nature que ce soit, il se peut que la limitation ou lexclusion
ci-dessus ne sappliquera pas à votre égard.
EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous
pourriez avoir dautres droits prévus par les lois de votre pays. Le présent
contrat ne modifie pas les droits que vous confèrent les lois de votre pays si
celles-ci ne le permettent pas.

16
LICENSED-HARDWARE.txt Normal file
View File

@ -0,0 +1,16 @@
LICENSED HARDWARE LIST
Last Updated: 2020-05-08
Microsoft has entered into OEM Agreements with manufacturers of the following
microprocessors and microcontrollers (the “hardware”) to enable those
manufacturers to include and distribute Azure RTOS in certain hardware. If you
have obtained and/or are developing on microprocessor(s) and/or
microcontroller(s) (“hardware”) listed below you inherit the “Distribution and
Production Use” rights in Section 2 of the Microsoft Software License Terms for
Microsoft Azure RTOS. If hardware is not listed below, you do not have those
rights.
--------------------------------------------------------------------------------
More coming soon. Please check back frequently for updates.

1
README.md Executable file
View File

@ -0,0 +1 @@
# USBX

0
TODO Normal file
View File

1804
common/CMakeLists.txt Normal file

File diff suppressed because it is too large Load Diff

208
common/core/CMakeLists.txt Normal file
View File

@ -0,0 +1,208 @@
target_sources(${PROJECT_NAME} PRIVATE
# {{BEGIN_TARGET_SOURCES}}
${CMAKE_CURRENT_LIST_DIR}/src/ux_dcd_sim_slave_address_set.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_dcd_sim_slave_endpoint_create.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_dcd_sim_slave_endpoint_destroy.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_dcd_sim_slave_endpoint_reset.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_dcd_sim_slave_endpoint_stall.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_dcd_sim_slave_endpoint_status.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_dcd_sim_slave_frame_number_get.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_dcd_sim_slave_function.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_dcd_sim_slave_initialize.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_dcd_sim_slave_initialize_complete.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_dcd_sim_slave_state_change.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_dcd_sim_slave_transfer_abort.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_dcd_sim_slave_transfer_request.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_dpump_activate.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_dpump_change.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_dpump_deactivate.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_dpump_entry.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_dpump_initialize.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_dpump_read.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_dpump_thread.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_dpump_write.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_stack_alternate_setting_get.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_stack_alternate_setting_set.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_stack_class_register.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_stack_class_unregister.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_stack_clear_feature.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_stack_configuration_get.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_stack_configuration_set.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_stack_control_request_process.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_stack_descriptor_send.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_stack_disconnect.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_stack_endpoint_stall.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_stack_get_status.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_stack_host_wakeup.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_stack_initialize.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_stack_interface_delete.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_stack_interface_get.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_stack_interface_set.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_stack_interface_start.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_stack_microsoft_extension_register.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_stack_set_feature.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_stack_transfer_abort.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_stack_transfer_all_request_abort.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_stack_transfer_request.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_stack_uninitialize.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_hcd_sim_host_asynch_queue_process.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_hcd_sim_host_asynch_schedule.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_hcd_sim_host_asynchronous_endpoint_create.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_hcd_sim_host_asynchronous_endpoint_destroy.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_hcd_sim_host_ed_obtain.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_hcd_sim_host_ed_td_clean.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_hcd_sim_host_endpoint_reset.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_hcd_sim_host_entry.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_hcd_sim_host_frame_number_get.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_hcd_sim_host_frame_number_set.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_hcd_sim_host_initialize.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_hcd_sim_host_interrupt_endpoint_create.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_hcd_sim_host_iso_queue_process.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_hcd_sim_host_iso_schedule.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_hcd_sim_host_isochronous_endpoint_create.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_hcd_sim_host_isochronous_td_obtain.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_hcd_sim_host_least_traffic_list_get.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_hcd_sim_host_periodic_endpoint_destroy.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_hcd_sim_host_periodic_schedule.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_hcd_sim_host_periodic_tree_create.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_hcd_sim_host_port_reset.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_hcd_sim_host_port_status_get.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_hcd_sim_host_regular_td_obtain.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_hcd_sim_host_request_bulk_transfer.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_hcd_sim_host_request_control_transfer.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_hcd_sim_host_request_interupt_transfer.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_hcd_sim_host_request_isochronous_transfer.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_hcd_sim_host_request_transfer.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_hcd_sim_host_timer_function.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_hcd_sim_host_transaction_schedule.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_hcd_sim_host_transfer_abort.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_dpump_activate.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_dpump_configure.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_dpump_deactivate.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_dpump_endpoints_get.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_dpump_entry.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_dpump_ioctl.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_dpump_read.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_class_dpump_write.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_bandwidth_check.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_bandwidth_claim.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_bandwidth_release.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_class_call.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_class_device_scan.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_class_get.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_class_instance_create.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_class_instance_destroy.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_class_instance_get.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_class_instance_verify.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_class_interface_scan.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_class_register.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_configuration_descriptor_parse.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_configuration_enumerate.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_configuration_instance_create.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_configuration_instance_delete.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_configuration_interface_get.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_configuration_set.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_delay_ms.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_device_address_set.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_device_configuration_get.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_device_configuration_reset.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_device_configuration_select.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_device_descriptor_read.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_device_get.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_device_remove.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_device_resources_free.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_endpoint_instance_create.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_endpoint_instance_delete.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_endpoint_reset.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_endpoint_transfer_abort.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_enum_thread_entry.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_hcd_register.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_hcd_thread_entry.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_hcd_transfer_request.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_hnp_polling_thread_entry.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_initialize.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_interface_endpoint_get.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_interface_instance_create.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_interface_instance_delete.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_interface_set.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_interface_setting_select.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_interfaces_scan.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_new_configuration_create.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_new_device_create.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_new_device_get.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_new_endpoint_create.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_new_interface_create.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_rh_change_process.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_rh_device_extraction.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_rh_device_insertion.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_role_swap.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_transfer_request.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_host_stack_transfer_request_abort.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_system_error_handler.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_system_initialize.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_system_uninitialize.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_trace_event_insert.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_trace_event_update.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_trace_object_register.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_trace_object_unregister.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_utility_debug_callback_register.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_utility_debug_log.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_utility_delay_ms.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_utility_descriptor_pack.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_utility_descriptor_parse.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_utility_error_callback_register.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_utility_event_flags_create.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_utility_event_flags_delete.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_utility_event_flags_get.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_utility_event_flags_set.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_utility_long_get.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_utility_long_get_big_endian.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_utility_long_put.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_utility_long_put_big_endian.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_utility_memory_allocate.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_utility_memory_allocate_add_safe.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_utility_memory_allocate_mulc_safe.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_utility_memory_allocate_mulv_safe.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_utility_memory_compare.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_utility_memory_copy.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_utility_memory_free.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_utility_memory_free_block_best_get.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_utility_memory_set.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_utility_mutex_create.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_utility_mutex_delete.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_utility_mutex_off.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_utility_mutex_on.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_utility_pci_class_scan.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_utility_pci_read.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_utility_pci_write.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_utility_physical_address.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_utility_semaphore_create.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_utility_semaphore_delete.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_utility_semaphore_get.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_utility_semaphore_put.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_utility_set_interrupt_handler.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_utility_short_get.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_utility_short_get_big_endian.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_utility_short_put.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_utility_short_put_big_endian.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_utility_string_length_check.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_utility_string_length_get.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_utility_string_to_unicode.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_utility_thread_create.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_utility_thread_delete.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_utility_thread_identify.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_utility_thread_relinquish.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_utility_thread_resume.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_utility_thread_schedule_other.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_utility_thread_sleep.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_utility_thread_suspend.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_utility_timer_create.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_utility_unicode_to_string.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_utility_virtual_address.c
# {{END_TARGET_SOURCES}}
)
target_include_directories(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_LIST_DIR}/inc
)

1983
common/core/inc/ux_api.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,137 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Slave Simulator Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/* */
/* COMPONENT DEFINITION RELEASE */
/* */
/* ux_dcd_sim_slave.h PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This file contains all the header and extern functions used by the */
/* USBX slave simulator. It is designed to work ONLY with the USBX */
/* host simulator. */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
#ifndef UX_DCD_SIM_SLAVE_H
#define UX_DCD_SIM_SLAVE_H
/* Define USB slave simulator major equivalences. */
#define UX_DCD_SIM_SLAVE_SLAVE_CONTROLLER 98
#define UX_DCD_SIM_SLAVE_MAX_ED 16
/* Define USB slave simulator error code register bits. */
#define UX_DCD_SIM_SLAVE_ERROR_TRANSMISSION_OK 0x00000001
#define UX_DCD_SIM_SLAVE_ERROR_CODE_MASK 0x0000000e
#define UX_DCD_SIM_SLAVE_ERROR_CODE_SHIFT 0x00000001
#define UX_DCD_SIM_SLAVE_ERROR_CODE_PID_ERROR 0x00000001
#define UX_DCD_SIM_SLAVE_ERROR_CODE_PID_UNKNOWN 0x00000002
#define UX_DCD_SIM_SLAVE_ERROR_CODE_UNEXPECTED_PACKET 0x00000003
#define UX_DCD_SIM_SLAVE_ERROR_CODE_TOKEN_CRC 0x00000004
#define UX_DCD_SIM_SLAVE_ERROR_CODE_DATA_CRC 0x00000005
#define UX_DCD_SIM_SLAVE_ERROR_CODE_TIME_OUT 0x00000006
#define UX_DCD_SIM_SLAVE_ERROR_CODE_BABBLE 0x00000007
#define UX_DCD_SIM_SLAVE_ERROR_CODE_UNEXPECTED_EOP 0x00000008
#define UX_DCD_SIM_SLAVE_ERROR_CODE_NAK 0x00000009
#define UX_DCD_SIM_SLAVE_ERROR_CODE_STALLED 0x0000000a
#define UX_DCD_SIM_SLAVE_ERROR_CODE_OVERFLOW 0x0000000b
#define UX_DCD_SIM_SLAVE_ERROR_CODE_EMPTY_PACKET 0x0000000c
#define UX_DCD_SIM_SLAVE_ERROR_CODE_BIT_STUFFING 0x0000000d
#define UX_DCD_SIM_SLAVE_ERROR_CODE_SYNC_ERROR 0x0000000e
#define UX_DCD_SIM_SLAVE_ERROR_CODE_DATA_TOGGLE 0x0000000f
/* Define USB slave simulator physical endpoint status definition. */
#define UX_DCD_SIM_SLAVE_ED_STATUS_UNUSED 0
#define UX_DCD_SIM_SLAVE_ED_STATUS_USED 1
#define UX_DCD_SIM_SLAVE_ED_STATUS_TRANSFER 2
#define UX_DCD_SIM_SLAVE_ED_STATUS_STALLED 4
/* Define USB slave simulator physical endpoint structure. */
typedef struct UX_DCD_SIM_SLAVE_ED_STRUCT
{
ULONG ux_sim_slave_ed_status;
ULONG ux_sim_slave_ed_index;
ULONG ux_sim_slave_ed_payload_length;
ULONG ux_sim_slave_ed_ping_pong;
ULONG ux_sim_slave_ed_status_register;
ULONG ux_sim_slave_ed_configuration_value;
struct UX_SLAVE_ENDPOINT_STRUCT
*ux_sim_slave_ed_endpoint;
} UX_DCD_SIM_SLAVE_ED;
/* Define USB slave simulator DCD structure definition. */
typedef struct UX_DCD_SIM_SLAVE_STRUCT
{
struct UX_SLAVE_DCD_STRUCT
*ux_dcd_sim_slave_dcd_owner;
struct UX_DCD_SIM_SLAVE_ED_STRUCT
ux_dcd_sim_slave_ed[UX_DCD_SIM_SLAVE_MAX_ED];
UINT (*ux_dcd_sim_slave_dcd_control_request_process_hub)(UX_SLAVE_TRANSFER *transfer_request);
} UX_DCD_SIM_SLAVE;
/* Define slave simulator function prototypes. */
UINT _ux_dcd_sim_slave_address_set(UX_DCD_SIM_SLAVE *dcd_sim_slave, ULONG address);
UINT _ux_dcd_sim_slave_endpoint_create(UX_DCD_SIM_SLAVE *dcd_sim_slave, UX_SLAVE_ENDPOINT *endpoint);
UINT _ux_dcd_sim_slave_endpoint_destroy(UX_DCD_SIM_SLAVE *dcd_sim_slave, UX_SLAVE_ENDPOINT *endpoint);
UINT _ux_dcd_sim_slave_endpoint_reset(UX_DCD_SIM_SLAVE *dcd_sim_slave, UX_SLAVE_ENDPOINT *endpoint);
UINT _ux_dcd_sim_slave_endpoint_stall(UX_DCD_SIM_SLAVE *dcd_sim_slave, UX_SLAVE_ENDPOINT *endpoint);
UINT _ux_dcd_sim_slave_endpoint_status(UX_DCD_SIM_SLAVE *dcd_sim_slave, ULONG endpoint_index);
UINT _ux_dcd_sim_slave_frame_number_get(UX_DCD_SIM_SLAVE *dcd_sim_slave, ULONG *frame_number);
UINT _ux_dcd_sim_slave_function(UX_SLAVE_DCD *dcd, UINT function, VOID *parameter);
UINT _ux_dcd_sim_slave_initialize(VOID);
UINT _ux_dcd_sim_slave_initialize_complete(VOID);
UINT _ux_dcd_sim_slave_state_change(UX_DCD_SIM_SLAVE *dcd_sim_slave, ULONG state);
UINT _ux_dcd_sim_slave_transfer_request(UX_DCD_SIM_SLAVE *dcd_sim_slave, UX_SLAVE_TRANSFER *transfer_request);
UINT _ux_dcd_sim_slave_transfer_abort(UX_DCD_SIM_SLAVE *dcd_sim_slave, UX_SLAVE_TRANSFER *transfer_request);
/* Define Device Simulator Class API prototypes. */
#define ux_dcd_sim_slave_initialize _ux_dcd_sim_slave_initialize
#endif

View File

@ -0,0 +1,101 @@
/**************************************************************************/
/* */
/* 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 Data Pump Class */
/** */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/* */
/* COMPONENT DEFINITION RELEASE */
/* */
/* ux_device_class_dpump.h PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This file contains all the header and extern functions used by the */
/* USBX device dpump class. */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
#ifndef UX_DEVICE_CLASS_DPUMP_H
#define UX_DEVICE_CLASS_DPUMP_H
/* Define Storage Class USB Class constants. */
#define UX_SLAVE_CLASS_DPUMP_CLASS 0x99
#define UX_SLAVE_CLASS_DPUMP_SUBCLASS 0x99
#define UX_SLAVE_CLASS_DPUMP_PROTOCOL 0x99
/* Define Data Pump Class packet equivalences. */
#define UX_DEVICE_CLASS_DPUMP_PACKET_SIZE 128
/* Define Slave DPUMP Class Calling Parameter structure */
typedef struct UX_SLAVE_CLASS_DPUMP_PARAMETER_STRUCT
{
VOID (*ux_slave_class_dpump_instance_activate)(VOID *);
VOID (*ux_slave_class_dpump_instance_deactivate)(VOID *);
} UX_SLAVE_CLASS_DPUMP_PARAMETER;
/* Define Slave Data Pump Class structure. */
typedef struct UX_SLAVE_CLASS_DPUMP_STRUCT
{
UX_SLAVE_INTERFACE *ux_slave_class_dpump_interface;
UX_SLAVE_CLASS_DPUMP_PARAMETER ux_slave_class_dpump_parameter;
UX_SLAVE_ENDPOINT *ux_slave_class_dpump_bulkin_endpoint;
UX_SLAVE_ENDPOINT *ux_slave_class_dpump_bulkout_endpoint;
ULONG ux_slave_class_dpump_alternate_setting;
} UX_SLAVE_CLASS_DPUMP;
/* Define Device Data Pump Class prototypes. */
UINT _ux_device_class_dpump_initialize(UX_SLAVE_CLASS_COMMAND *command);
UINT _ux_device_class_dpump_activate(UX_SLAVE_CLASS_COMMAND *command);
UINT _ux_device_class_dpump_deactivate(UX_SLAVE_CLASS_COMMAND *command);
UINT _ux_device_class_dpump_entry(UX_SLAVE_CLASS_COMMAND *command);
UINT _ux_device_class_dpump_read(UX_SLAVE_CLASS_DPUMP *dpump, UCHAR *buffer,
ULONG requested_length, ULONG *actual_length);
UINT _ux_device_class_dpump_write(UX_SLAVE_CLASS_DPUMP *dpump, UCHAR *buffer,
ULONG requested_length, ULONG *actual_length);
UINT _ux_device_class_dpump_change(UX_SLAVE_CLASS_COMMAND *command);
/* Define Device DPUMP Class API prototypes. */
#define ux_device_class_dpump_entry _ux_device_class_dpump_entry
#define ux_device_class_dpump_read _ux_device_class_dpump_read
#define ux_device_class_dpump_write _ux_device_class_dpump_write
#endif

View File

@ -0,0 +1,87 @@
/**************************************************************************/
/* */
/* 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 Stack */
/** */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/* */
/* COMPONENT DEFINITION RELEASE */
/* */
/* ux_device_stack.h PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This file defines the equivalences for the USBX Device Stack */
/* component. */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
#ifndef UX_DEVICE_STACK_H
#define UX_DEVICE_STACK_H
/* Define USB Device Stack prototypes. */
UINT _ux_device_stack_alternate_setting_get(ULONG interface_value);
UINT _ux_device_stack_alternate_setting_set(ULONG interface_value, ULONG alternate_setting_value);
UINT _ux_device_stack_class_register(UCHAR *class_name,
UINT (*class_entry_function)(struct UX_SLAVE_CLASS_COMMAND_STRUCT *),
ULONG configuration_number,
ULONG interface_number,
VOID *parameter);
UINT _ux_device_stack_clear_feature(ULONG request_type, ULONG request_value, ULONG request_index);
UINT _ux_device_stack_configuration_get(VOID);
UINT _ux_device_stack_configuration_set(ULONG configuration_value);
UINT _ux_device_stack_control_request_process(UX_SLAVE_TRANSFER *transfer_request);
UINT _ux_device_stack_descriptor_send(ULONG descriptor_type, ULONG request_index, ULONG host_length);
UINT _ux_device_stack_disconnect(VOID);
UINT _ux_device_stack_endpoint_stall(UX_SLAVE_ENDPOINT *endpoint);
UINT _ux_device_stack_get_status(ULONG request_type, ULONG request_index, ULONG request_length);
UINT _ux_device_stack_host_wakeup(VOID);
UINT _ux_device_stack_initialize(UCHAR * device_framework_high_speed, ULONG device_framework_length_high_speed,
UCHAR * device_framework_full_speed, ULONG device_framework_length_full_speed,
UCHAR * string_framework, ULONG string_framework_length,
UCHAR * language_id_framework, ULONG language_id_framework_length,
UINT (*ux_system_slave_change_function)(ULONG));
UINT _ux_device_stack_interface_delete(UX_SLAVE_INTERFACE *interface);
UINT _ux_device_stack_interface_get(UINT interface_value);
UINT _ux_device_stack_interface_set(UCHAR * device_framework, ULONG device_framework_length,
ULONG alternate_setting_value);
UINT _ux_device_stack_interface_start(UX_SLAVE_INTERFACE *interface);
UINT _ux_device_stack_set_feature(ULONG request_type, ULONG request_value, ULONG request_index);
UINT _ux_device_stack_transfer_all_request_abort(UX_SLAVE_ENDPOINT *endpoint, ULONG completion_code);
UINT _ux_device_stack_transfer_request(UX_SLAVE_TRANSFER *transfer_request, ULONG slave_length, ULONG host_length);
UINT _ux_device_stack_transfer_abort(UX_SLAVE_TRANSFER *transfer_request, ULONG completion_code);
UINT _ux_device_stack_class_unregister(UCHAR *class_name, UINT (*class_entry_function)(struct UX_SLAVE_CLASS_COMMAND_STRUCT *));
UINT _ux_device_stack_microsoft_extension_register(ULONG vendor_request, UINT (*vendor_request_function)(ULONG, ULONG, ULONG, ULONG, UCHAR *, ULONG *));
UINT _ux_device_stack_uninitialize(VOID);
#endif

View File

@ -0,0 +1,236 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Host Simulator Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/* */
/* COMPONENT DEFINITION RELEASE */
/* */
/* ux_hcd_sim_host.h PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This file contains all the header and extern functions used by the */
/* USBX host simulator. It is designed to work ONLY with the USBX */
/* device (slave) simulator. */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
#ifndef UX_HCD_SIM_HOST_H
#define UX_HCD_SIM_HOST_H
/* Define simulator host generic definitions. */
#define UX_HCD_SIM_HOST_CONTROLLER 99
#define UX_HCD_SIM_HOST_MAX_PAYLOAD 4096
#define UX_HCD_SIM_HOST_FRAME_DELAY 4
#define UX_HCD_SIM_HOST_PERIODIC_ENTRY_NB 32
#define UX_HCD_SIM_HOST_PERIODIC_ENTRY_MASK 0x1f
#define UX_HCD_SIM_HOST_AVAILABLE_BANDWIDTH 6000
/* Define simulator host completion code errors. */
#define UX_HCD_SIM_HOST_NO_ERROR 0x00
#define UX_HCD_SIM_HOST_ERROR_CRC 0x01
#define UX_HCD_SIM_HOST_ERROR_BIT_STUFFING 0x02
#define UX_HCD_SIM_HOST_ERROR_DATA_TOGGLE 0x03
#define UX_HCD_SIM_HOST_ERROR_STALL 0x04
#define UX_HCD_SIM_HOST_ERROR_DEVICE_NOT_RESPONDING 0x05
#define UX_HCD_SIM_HOST_ERROR_PID_FAILURE 0x06
#define UX_HCD_SIM_HOST_ERROR_PID_UNEXPECTED 0x07
#define UX_HCD_SIM_HOST_ERROR_DATA_OVERRRUN 0x08
#define UX_HCD_SIM_HOST_ERROR_DATA_UNDERRUN 0x09
#define UX_HCD_SIM_HOST_ERROR_BUFFER_OVERRRUN 0x0c
#define UX_HCD_SIM_HOST_ERROR_BUFFER_UNDERRUN 0x0d
#define UX_HCD_SIM_HOST_NOT_ACCESSED 0x0e
#define UX_HCD_SIM_HOST_NAK 0x0f
/* Define simulator host structure. */
typedef struct UX_HCD_SIM_HOST_STRUCT
{
struct UX_HCD_STRUCT
*ux_hcd_sim_host_hcd_owner;
ULONG ux_hcd_sim_host_hcor;
UINT ux_hcd_sim_host_nb_root_hubs;
struct UX_HCD_SIM_HOST_ED_STRUCT
*ux_hcd_sim_host_ed_list;
struct UX_HCD_SIM_HOST_TD_STRUCT
*ux_hcd_sim_host_td_list;
struct UX_HCD_SIM_HOST_ISO_TD_STRUCT
*ux_hcd_sim_host_iso_td_list;
struct UX_HCD_SIM_HOST_ED_STRUCT
*ux_hcd_sim_host_asynch_head_ed;
struct UX_HCD_SIM_HOST_ED_STRUCT
*ux_hcd_sim_host_asynch_current_ed;
struct UX_HCD_SIM_HOST_ED_STRUCT
*ux_hcd_sim_host_iso_head_ed;
struct UX_HCD_SIM_HOST_ED_STRUCT
*ux_hcd_sim_host_interrupt_ed_list[32];
UINT ux_hcd_sim_host_queue_empty;
UINT ux_hcd_sim_host_periodic_scheduler_active;
UINT ux_hcd_sim_host_interruptible;
ULONG ux_hcd_sim_host_interrupt_count;
TX_TIMER ux_hcd_sim_host_timer;
} UX_HCD_SIM_HOST;
/* Define simulator host ED structure. */
typedef struct UX_HCD_SIM_HOST_ED_STRUCT
{
struct UX_HCD_SIM_HOST_TD_STRUCT
*ux_sim_host_ed_tail_td;
struct UX_HCD_SIM_HOST_TD_STRUCT
*ux_sim_host_ed_head_td;
struct UX_HCD_SIM_HOST_ED_STRUCT
*ux_sim_host_ed_next_ed;
struct UX_HCD_SIM_HOST_ED_STRUCT
*ux_sim_host_ed_previous_ed;
ULONG ux_sim_host_ed_status;
struct UX_ENDPOINT_STRUCT
*ux_sim_host_ed_endpoint;
ULONG ux_sim_host_ed_toggle;
ULONG ux_sim_host_ed_frame;
} UX_HCD_SIM_HOST_ED;
/* Define simulator host ED bitmap. */
#define UX_HCD_SIM_HOST_ED_STATIC 0x80000000
#define UX_HCD_SIM_HOST_ED_SKIP 0x40000000
/* Define simulator host TD structure. */
typedef struct UX_HCD_SIM_HOST_TD_STRUCT
{
UCHAR * ux_sim_host_td_buffer;
ULONG ux_sim_host_td_length;
struct UX_HCD_SIM_HOST_TD_STRUCT
*ux_sim_host_td_next_td;
struct UX_TRANSFER_STRUCT
*ux_sim_host_td_transfer_request;
struct UX_HCD_SIM_HOST_TD_STRUCT
*ux_sim_host_td_next_td_transfer_request;
struct UX_HCD_SIM_HOST_ED_STRUCT
*ux_sim_host_td_ed;
ULONG ux_sim_host_td_actual_length;
ULONG ux_sim_host_td_status;
ULONG ux_sim_host_td_direction;
ULONG ux_sim_host_td_toggle;
} UX_HCD_SIM_HOST_TD;
/* Define simulator host TD bitmap. */
#define UX_HCD_SIM_HOST_TD_SETUP_PHASE 0x00010000
#define UX_HCD_SIM_HOST_TD_DATA_PHASE 0x00020000
#define UX_HCD_SIM_HOST_TD_STATUS_PHASE 0x00040000
#define UX_HCD_SIM_HOST_TD_OUT 0x00000800
#define UX_HCD_SIM_HOST_TD_IN 0x00001000
#define UX_HCD_SIM_HOST_TD_ACK_PENDING 0x00002000
#define UX_HCD_SIM_HOST_TD_TOGGLE_FROM_ED 0x80000000
/* Define simulator host ISOCHRONOUS TD structure. */
typedef struct UX_HCD_SIM_HOST_ISO_TD_STRUCT
{
UCHAR * ux_sim_host_iso_td_buffer;
ULONG ux_sim_host_iso_td_length;
struct UX_HCD_SIM_HOST_ISO_TD_STRUCT
*ux_sim_host_iso_td_next_td;
struct UX_TRANSFER_STRUCT
*ux_sim_host_iso_td_transfer_request;
struct UX_HCD_SIM_HOST_ISO_TD_STRUCT
*ux_sim_host_iso_td_next_td_transfer_request;
struct UX_HCD_SIM_HOST_ED_STRUCT
*ux_sim_host_iso_td_ed;
ULONG ux_sim_host_iso_td_actual_length;
ULONG ux_sim_host_iso_td_status;
ULONG ux_sim_host_iso_td_direction;
} UX_HCD_SIM_HOST_ISO_TD;
/* Define simulator host function prototypes. */
VOID _ux_hcd_sim_host_asynch_queue_process(UX_HCD_SIM_HOST *hcd_sim_host);
VOID _ux_hcd_sim_host_asynch_schedule(UX_HCD_SIM_HOST *hcd_sim_host);
UINT _ux_hcd_sim_host_asynchronous_endpoint_create(UX_HCD_SIM_HOST *hcd_sim_host, UX_ENDPOINT *endpoint);
UINT _ux_hcd_sim_host_asynchronous_endpoint_destroy(UX_HCD_SIM_HOST *hcd_sim_host, UX_ENDPOINT *endpoint);
UX_HCD_SIM_HOST_ED
*_ux_hcd_sim_host_ed_obtain(UX_HCD_SIM_HOST *hcd_sim_host);
VOID _ux_hcd_sim_host_ed_td_clean(UX_HCD_SIM_HOST_ED *ed);
UINT _ux_hcd_sim_host_endpoint_reset(UX_HCD_SIM_HOST *hcd_sim_host, UX_ENDPOINT *endpoint);
UINT _ux_hcd_sim_host_entry(UX_HCD *hcd, UINT function, VOID *parameter);
UINT _ux_hcd_sim_host_frame_number_get(UX_HCD_SIM_HOST *hcd_sim_host, ULONG *frame_number);
VOID _ux_hcd_sim_host_frame_number_set(UX_HCD_SIM_HOST *hcd_sim_host, ULONG frame_number);
UINT _ux_hcd_sim_host_initialize(UX_HCD *hcd);
UINT _ux_hcd_sim_host_interrupt_endpoint_create(UX_HCD_SIM_HOST *hcd_sim_host, UX_ENDPOINT *endpoint);
VOID _ux_hcd_sim_host_iso_queue_process(UX_HCD_SIM_HOST *hcd_sim_host);
VOID _ux_hcd_sim_host_iso_schedule(UX_HCD_SIM_HOST *hcd_sim_host);
UINT _ux_hcd_sim_host_isochronous_endpoint_create(UX_HCD_SIM_HOST *hcd_sim_host, UX_ENDPOINT *endpoint);
UX_HCD_SIM_HOST_ISO_TD
*_ux_hcd_sim_host_isochronous_td_obtain(UX_HCD_SIM_HOST *hcd_sim_host);
UX_HCD_SIM_HOST_ED
*_ux_hcd_sim_host_least_traffic_list_get(UX_HCD_SIM_HOST *hcd_sim_host);
UINT _ux_hcd_sim_host_periodic_endpoint_destroy(UX_HCD_SIM_HOST *hcd_sim_host, UX_ENDPOINT *endpoint);
VOID _ux_hcd_sim_host_periodic_schedule(UX_HCD_SIM_HOST *hcd_sim_host);
UINT _ux_hcd_sim_host_periodic_tree_create(UX_HCD_SIM_HOST *hcd_sim_host);
ULONG _ux_hcd_sim_host_port_status_get(UX_HCD_SIM_HOST *hcd_sim_host, ULONG port_index);
UX_HCD_SIM_HOST_TD
*_ux_hcd_sim_host_regular_td_obtain(UX_HCD_SIM_HOST *hcd_sim_host);
UINT _ux_hcd_sim_host_request_bulk_transfer(UX_HCD_SIM_HOST *hcd_sim_host, UX_TRANSFER *transfer_request);
UINT _ux_hcd_sim_host_request_control_transfer(UX_HCD_SIM_HOST *hcd_sim_host, UX_TRANSFER *transfer_request);
UINT _ux_hcd_sim_host_request_interrupt_transfer(UX_HCD_SIM_HOST *hcd_sim_host, UX_TRANSFER *transfer_request);
UINT _ux_hcd_sim_host_request_isochronous_transfer(UX_HCD_SIM_HOST *hcd_sim_host, UX_TRANSFER *transfer_request);
UINT _ux_hcd_sim_host_request_transfer(UX_HCD_SIM_HOST *hcd_sim_host, UX_TRANSFER *transfer_request);
VOID _ux_hcd_sim_host_timer_function(ULONG hcd_sim_host_addr);
UINT _ux_hcd_sim_host_transaction_schedule(UX_HCD_SIM_HOST *hcd_sim_host, UX_HCD_SIM_HOST_ED *ed);
UINT _ux_hcd_sim_host_transfer_abort(UX_HCD_SIM_HOST *hcd_sim_host, UX_TRANSFER *transfer_request);
UINT _ux_hcd_sim_host_port_reset(UX_HCD_SIM_HOST *hcd_sim_host, ULONG port_index);
/* Define Device Simulator Class API prototypes. */
#define ux_hcd_sim_host_initialize _ux_hcd_sim_host_initialize
#endif

View File

@ -0,0 +1,89 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Host Data Pump Class */
/** */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/* */
/* COMPONENT DEFINITION RELEASE */
/* */
/* ux_host_class_dpump.h PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This file contains all the header and extern functions used by the */
/* USBX demo data pump class. */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
#ifndef UX_HOST_CLASS_DPUMP_H
#define UX_HOST_CLASS_DPUMP_H
/* Define Data Pump Class constants. */
#define UX_HOST_CLASS_DPUMP_CLASS_TRANSFER_TIMEOUT 300000
#define UX_HOST_CLASS_DPUMP_CLASS 0x99
#define UX_HOST_CLASS_DPUMP_SUBCLASS 0x99
#define UX_HOST_CLASS_DPUMP_PROTOCOL 0x99
/* Define Data Pump Class packet equivalences. */
#define UX_HOST_CLASS_DPUMP_PACKET_SIZE 128
/* Define Data Pump Class Ioctl functions. */
#define UX_HOST_CLASS_DPUMP_SELECT_ALTERNATE_SETTING 1
/* Define Data Pump Class string constants. */
#define UX_HOST_CLASS_DPUMP_GENERIC_NAME "USB DPUMP"
/* Define Printer Class function prototypes. */
UINT _ux_host_class_dpump_activate(UX_HOST_CLASS_COMMAND *command);
UINT _ux_host_class_dpump_configure(UX_HOST_CLASS_DPUMP *dpump);
UINT _ux_host_class_dpump_deactivate(UX_HOST_CLASS_COMMAND *command);
UINT _ux_host_class_dpump_endpoints_get(UX_HOST_CLASS_DPUMP *dpump);
UINT _ux_host_class_dpump_entry(UX_HOST_CLASS_COMMAND *command);
UINT _ux_host_class_dpump_read (UX_HOST_CLASS_DPUMP *dpump, UCHAR *data_pointer,
ULONG requested_length, ULONG *actual_length);
UINT _ux_host_class_dpump_write(UX_HOST_CLASS_DPUMP *dpump, UCHAR * data_pointer,
ULONG requested_length, ULONG *actual_length);
UINT _ux_host_class_dpump_ioctl(UX_HOST_CLASS_DPUMP *dpump, ULONG ioctl_function,
VOID *parameter);
#define ux_host_class_dpump_entry _ux_host_class_dpump_entry
#define ux_host_class_dpump_read _ux_host_class_dpump_read
#define ux_host_class_dpump_write _ux_host_class_dpump_write
#define ux_host_class_dpump_ioctl _ux_host_class_dpump_ioctl
#endif

View File

@ -0,0 +1,116 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Host Stack */
/** */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/* */
/* COMPONENT DEFINITION RELEASE */
/* */
/* ux_host_stack.h PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This file contains all the header and extern functions used by the */
/* USBX Host Stack component. */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
#ifndef UX_HOST_STACK_H
#define UX_HOST_STACK_H
/* Define Host Stack component function prototypes. */
VOID _ux_host_stack_bandwidth_release(UX_HCD *hcd, UX_ENDPOINT *endpoint);
VOID _ux_host_stack_bandwidth_claim(UX_HCD *hcd, UX_ENDPOINT *endpoint);
UINT _ux_host_stack_bandwidth_check(UX_HCD *hcd, UX_ENDPOINT *endpoint);
UX_HOST_CLASS * _ux_host_stack_class_call(UX_HOST_CLASS_COMMAND *class_command);
UINT _ux_host_stack_class_device_scan(UX_DEVICE *device);
UINT _ux_host_stack_class_get(UCHAR *class_name, UX_HOST_CLASS **class);
UINT _ux_host_stack_class_instance_destroy(UX_HOST_CLASS *class, VOID *class_instance);
UINT _ux_host_stack_class_instance_create(UX_HOST_CLASS *class, VOID *class_instance);
UINT _ux_host_stack_class_instance_get(UX_HOST_CLASS *class, UINT class_index, VOID **class_instance);
UINT _ux_host_stack_class_instance_verify(UCHAR *class_name, VOID *class_instance);
UINT _ux_host_stack_class_interface_scan(UX_DEVICE *device);
UINT _ux_host_stack_class_register(UCHAR *class_name,
UINT (*class_entry_function)(struct UX_HOST_CLASS_COMMAND_STRUCT *));
UINT _ux_host_stack_configuration_descriptor_parse(UX_DEVICE *device, UX_CONFIGURATION *configuration, UINT configuration_index);
UINT _ux_host_stack_configuration_enumerate(UX_DEVICE *device);
UINT _ux_host_stack_configuration_instance_create(UX_CONFIGURATION *configuration);
VOID _ux_host_stack_configuration_instance_delete(UX_CONFIGURATION *configuration);
UINT _ux_host_stack_configuration_interface_get(UX_CONFIGURATION *configuration,
UINT interface_index, UINT alternate_setting_index,
UX_INTERFACE **interface);
UINT _ux_host_stack_configuration_set(UX_CONFIGURATION *configuration);
VOID _ux_host_stack_delay_ms(ULONG time);
UINT _ux_host_stack_device_address_set(UX_DEVICE *device);
UINT _ux_host_stack_device_configuration_get(UX_DEVICE *device, UINT configuration_index,
UX_CONFIGURATION **configuration);
UINT _ux_host_stack_device_configuration_select(UX_CONFIGURATION *configuration);
UINT _ux_host_stack_device_configuration_reset(UX_DEVICE *device);
UINT _ux_host_stack_device_descriptor_read(UX_DEVICE *device);
UINT _ux_host_stack_device_get(ULONG device_index, UX_DEVICE **device);
UINT _ux_host_stack_device_remove(UX_HCD *hcd, UX_DEVICE *parent, UINT port_index);
UINT _ux_host_stack_device_resources_free(UX_DEVICE *device);
UINT _ux_host_stack_endpoint_instance_create(UX_ENDPOINT *endpoint);
VOID _ux_host_stack_endpoint_instance_delete(UX_ENDPOINT *endpoint);
UINT _ux_host_stack_endpoint_reset(UX_ENDPOINT *endpoint);
UINT _ux_host_stack_endpoint_transfer_abort(UX_ENDPOINT *endpoint);
VOID _ux_host_stack_enum_thread_entry(ULONG input);
UINT _ux_host_stack_hcd_register(UCHAR *hcd_name,
UINT (*hcd_init_function)(struct UX_HCD_STRUCT *), ULONG hcd_param1, ULONG hcd_param2);
VOID _ux_host_stack_hcd_thread_entry(ULONG input);
UINT _ux_host_stack_hcd_transfer_request(UX_TRANSFER *transfer_request);
UINT _ux_host_stack_initialize(UINT (*ux_system_host_change_function)(ULONG, UX_HOST_CLASS *, VOID *));
UINT _ux_host_stack_interface_endpoint_get(UX_INTERFACE *interface, UINT endpoint_index, UX_ENDPOINT **endpoint);
UINT _ux_host_stack_interface_instance_create(UX_INTERFACE *interface);
VOID _ux_host_stack_interface_instance_delete(UX_INTERFACE *interface);
UINT _ux_host_stack_interface_set(UX_INTERFACE *interface);
UINT _ux_host_stack_interface_setting_select(UX_INTERFACE *interface);
UINT _ux_host_stack_interfaces_scan(UX_CONFIGURATION *configuration, UCHAR * descriptor);
VOID _ux_host_stack_new_configuration_create(UX_DEVICE *device, UX_CONFIGURATION *configuration);
UX_DEVICE *_ux_host_stack_new_device_get(VOID);
UINT _ux_host_stack_new_device_create(UX_HCD *hcd, UX_DEVICE *device_owner,
UINT port_index, UINT device_speed,
UINT port_max_power);
UINT _ux_host_stack_new_endpoint_create(UX_INTERFACE *interface, UCHAR * interface_endpoint);
UINT _ux_host_stack_new_interface_create(UX_CONFIGURATION *configuration, UCHAR * descriptor, ULONG length);
VOID _ux_host_stack_rh_change_process(VOID);
UINT _ux_host_stack_rh_device_extraction(UX_HCD *hcd, UINT port_index);
UINT _ux_host_stack_rh_device_insertion(UX_HCD *hcd, UINT port_index);
UINT _ux_host_stack_transfer_request(UX_TRANSFER *transfer_request);
UINT _ux_host_stack_transfer_request_abort(UX_TRANSFER *transfer_request);
VOID _ux_host_stack_hnp_polling_thread_entry(ULONG id);
UINT _ux_host_stack_role_swap(UX_DEVICE *device);
#endif

136
common/core/inc/ux_system.h Normal file
View File

@ -0,0 +1,136 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** System */
/** */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/* */
/* COMPONENT DEFINITION RELEASE */
/* */
/* ux_system.h PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This file contains all the header and extern functions used by the */
/* USBX main system component. */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
#ifndef UX_SYSTEM_HOST_H
#define UX_SYSTEM_HOST_H
/* Define System component function prototypes. Note that since ux_api.h
includes this file, the APIs are only declared if this file is included
by internal code in order to prevent duplicate declarations for
applications. */
#ifdef UX_SOURCE_CODE
UINT _ux_system_initialize(VOID *regular_memory_pool_start, ULONG regular_memory_size,
VOID *cache_safe_memory_pool_start, ULONG cache_safe_memory_size);
UINT _ux_system_uninitialize(VOID);
#endif
/* Define System component external data references. */
extern UX_SYSTEM *_ux_system;
extern UX_SYSTEM_HOST *_ux_system_host;
extern UX_SYSTEM_SLAVE *_ux_system_slave;
extern UX_SYSTEM_OTG *_ux_system_otg;
extern UCHAR _ux_system_endpoint_descriptor_structure[];
extern UCHAR _ux_system_device_descriptor_structure[];
extern UCHAR _ux_system_configuration_descriptor_structure[];
extern UCHAR _ux_system_interface_descriptor_structure[];
extern UCHAR _ux_system_interface_association_descriptor_structure[];
extern UCHAR _ux_system_string_descriptor_structure[];
extern UCHAR _ux_system_dfu_functional_descriptor_structure[];
extern UCHAR _ux_system_hub_descriptor_structure[];
extern UCHAR _ux_system_hid_descriptor_structure[];
extern UCHAR _ux_system_class_audio_interface_descriptor_structure[];
extern UCHAR _ux_system_class_audio_input_terminal_descriptor_structure[];
extern UCHAR _ux_system_class_audio_output_terminal_descriptor_structure[];
extern UCHAR _ux_system_class_audio_feature_unit_descriptor_structure[];
extern UCHAR _ux_system_class_audio_streaming_interface_descriptor_structure[];
extern UCHAR _ux_system_class_audio_streaming_endpoint_descriptor_structure[];
extern UCHAR _ux_system_class_pima_storage_structure[];
extern UCHAR _ux_system_class_pima_object_structure[];
extern UCHAR _ux_system_ecm_interface_descriptor_structure[];
extern UINT _ux_system_host_hcd_periodic_tree_entries[32];
extern UCHAR _ux_system_host_class_hub_name[];
extern UCHAR _ux_system_host_class_printer_name[];
extern UCHAR _ux_system_host_class_storage_name[];
extern UCHAR _ux_system_host_class_hid_name[];
extern UCHAR _ux_system_host_class_audio_name[];
extern UCHAR _ux_system_host_class_cdc_acm_name[];
extern UCHAR _ux_system_host_class_cdc_dlc_name[];
extern UCHAR _ux_system_host_class_cdc_ecm_name[];
extern UCHAR _ux_system_host_class_prolific_name[];
extern UCHAR _ux_system_host_class_dpump_name[];
extern UCHAR _ux_system_host_class_pima_name[];
extern UCHAR _ux_system_host_class_asix_name[];
extern UCHAR _ux_system_host_class_swar_name[];
extern UCHAR _ux_system_host_class_gser_name[];
extern UCHAR _ux_system_host_class_hid_client_remote_control_name[];
extern UCHAR _ux_system_host_class_hid_client_mouse_name[];
extern UCHAR _ux_system_host_class_hid_client_keyboard_name[];
extern UCHAR _ux_system_host_hcd_ohci_name[];
extern UCHAR _ux_system_host_hcd_ehci_name[];
extern UCHAR _ux_system_host_hcd_isp1161_name[];
extern UCHAR _ux_system_host_hcd_isp1362_name[];
extern UCHAR _ux_system_host_hcd_sh2_name[];
extern UCHAR _ux_system_host_hcd_rx_name[];
extern UCHAR _ux_system_host_hcd_pic32_name[];
extern UCHAR _ux_system_host_hcd_stm32_name[];
extern UCHAR _ux_system_host_hcd_musb_name[];
extern UCHAR _ux_system_host_hcd_atm7_name[];
extern UCHAR _ux_system_host_hcd_simulator_name[];
extern UCHAR _ux_system_slave_class_storage_name[];
extern UCHAR _ux_system_slave_class_storage_vendor_id[];
extern UCHAR _ux_system_slave_class_storage_product_id[];
extern UCHAR _ux_system_slave_class_storage_product_rev[];
extern UCHAR _ux_system_slave_class_storage_product_serial[];
extern UCHAR _ux_system_slave_class_audio_name[];
extern UCHAR _ux_system_slave_class_cdc_acm_name[];
extern UCHAR _ux_system_slave_class_dpump_name[];
extern UCHAR _ux_system_slave_class_pima_name[];
extern UCHAR _ux_system_slave_class_hid_name[];
extern UCHAR _ux_system_slave_class_rndis_name[];
extern UCHAR _ux_system_slave_class_cdc_ecm_name[];
extern UCHAR _ux_system_slave_class_dfu_name[];
#endif

314
common/core/inc/ux_user.h Normal file
View File

@ -0,0 +1,314 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** User Specific */
/** */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/* */
/* PORT SPECIFIC C INFORMATION RELEASE */
/* */
/* ux_user.h PORTABLE C */
/* 6.0 */
/* */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This file contains user defines for configuring USBX in specific */
/* ways. This file will have an effect only if the application and */
/* USBX library are built with UX_INCLUDE_USER_DEFINE_FILE defined. */
/* Note that all the defines in this file may also be made on the */
/* command line when building USBX library and application objects. */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
#ifndef UX_USER_H
#define UX_USER_H
/* Define various build options for the USBX port. The application should either make changes
here by commenting or un-commenting the conditional compilation defined OR supply the defines
though the compiler's equivalent of the -D option. */
/* #define UX_THREAD_STACK_SIZE (2 * 1024) */
/* Define USBX Host Enum Thread Stack Size. The default is to use UX_THREAD_STACK_SIZE */
/*
#define UX_HOST_ENUM_THREAD_STACK_SIZE UX_THREAD_STACK_SIZE
*/
/* Define USBX Host Thread Stack Size. The default is to use UX_THREAD_STACK_SIZE */
/*
#define UX_HOST_HCD_THREAD_STACK_SIZE UX_THREAD_STACK_SIZE
*/
/* Define USBX Host HNP Polling Thread Stack Size. The default is to use UX_THREAD_STACK_SIZE */
/*
#define UX_HOST_HNP_POLLING_THREAD_STACK UX_THREAD_STACK_SIZE
*/
/* 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 how many ticks per seconds for a specific hardware platform.
The default is 1000 indicating 1 tick per millisecond. */
/* #define UX_PERIODIC_RATE 1000
*/
#define UX_PERIODIC_RATE (TX_TIMER_TICKS_PER_SECOND)
/* Defined, this value is the maximum number of classes that can be loaded by USBX. This value
represents the class container and not the number of instances of a class. For instance, if a
particular implementation of USBX needs the hub class, the printer class, and the storage
class, then the UX_MAX_CLASSES value can be set to 3 regardless of the number of devices
that belong to these classes. */
/* #define UX_MAX_CLASSES 3
*/
/* Defined, this value is the maximum number of classes in the device stack that can be loaded by
USBX. */
/* #define UX_MAX_SLAVE_CLASS_DRIVER 1
*/
/* Defined, this value is the maximum number of interfaces in the device framework. */
/* #define UX_MAX_SLAVE_INTERFACES 16
*/
/* Defined, this value represents the number of different host controllers available in the system.
For USB 1.1 support, this value will usually be 1. For USB 2.0 support, this value can be more
than 1. This value represents the number of concurrent host controllers running at the same time.
If for instance there are two instances of OHCI running, or one EHCI and one OHCI controller
running, the UX_MAX_HCD should be set to 2. */
/* #define UX_MAX_HCD 1
*/
/* Defined, this value represents the maximum number of devices that can be attached to the USB.
Normally, the theoretical maximum number on a single USB is 127 devices. This value can be
scaled down to conserve memory. Note that this value represents the total number of devices
regardless of the number of USB buses in the system. */
/* #define UX_MAX_DEVICES 127
*/
/* Defined, this value represents the current number of SCSI logical units represented in the device
storage class driver. */
/* #define UX_MAX_SLAVE_LUN 1
*/
/* Defined, this value represents the maximum number of SCSI logical units represented in the
host storage class driver. */
/* #define UX_MAX_HOST_LUN 1
*/
/* Defined, this value represents the maximum number of bytes received on a control endpoint in
the device stack. The default is 256 bytes but can be reduced in memory constraint environments. */
/* #define UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH 256
*/
/* Defined, this value represents the maximum number of bytes that can be received or transmitted
on any endpoint. This value cannot be less than the maximum packet size of any endpoint. The default
is 4096 bytes but can be reduced in memory constraint environments. For cd-rom support in the storage
class, this value cannot be less than 2048. */
#define UX_SLAVE_REQUEST_DATA_MAX_LENGTH (1024 * 2)
/* Defined, this value includes code to handle storage Multi-Media Commands (MMC). E.g., DVD-ROM.
*/
/* #define UX_SLAVE_CLASS_STORAGE_INCLUDE_MMC */
/* Defined, this value represents the maximum number of bytes that a storage payload can send/receive.
The default is 8K bytes but can be reduced in memory constraint environments. */
#define UX_HOST_CLASS_STORAGE_MEMORY_BUFFER_SIZE (1024 * 8)
/* Define USBX Mass Storage Thread Stack Size. The default is to use UX_THREAD_STACK_SIZE. */
/* #define UX_HOST_CLASS_STORAGE_THREAD_STACK_SIZE UX_THREAD_STACK_SIZE
*/
/* Defined, this value represents the maximum number of Ed, regular TDs and Isochronous TDs. These values
depend on the type of host controller and can be reduced in memory constraint environments. */
#define UX_MAX_ED 80
#define UX_MAX_TD 128
#define UX_MAX_ISO_TD 1
/* Defined, this value represents the maximum size of the HID decompressed buffer. This cannot be determined
in advance so we allocate a big block, usually 4K but for simple HID devices like keyboard and mouse
it can be reduced a lot. */
#define UX_HOST_CLASS_HID_DECOMPRESSION_BUFFER 4096
/* Defined, this value represents the maximum number of HID usages for a HID device.
Default is 2048 but for simple HID devices like keyboard and mouse it can be reduced a lot. */
#define UX_HOST_CLASS_HID_USAGES 2048
/* By default, each key in each HID report from the device is reported by ux_host_class_hid_keyboard_key_get
(a HID report from the device is received whenever there is a change in a key state i.e. when a key is pressed
or released. The report contains every key that is down). There are limitations to this method such as not being
able to determine when a key has been released.
Defined, this value causes ux_host_class_hid_keyboard_key_get to only report key changes i.e. key presses
and key releases. */
/* #define UX_HOST_CLASS_HID_KEYBOARD_EVENTS_KEY_CHANGES_MODE */
/* Works when UX_HOST_CLASS_HID_KEYBOARD_EVENTS_KEY_CHANGES_MODE is defined.
Defined, this value causes ux_host_class_hid_keyboard_key_get to only report key pressed/down changes;
key released/up changes are not reported.
*/
/* #define UX_HOST_CLASS_HID_KEYBOARD_EVENTS_KEY_CHANGES_MODE_REPORT_KEY_DOWN_ONLY */
/* Works when UX_HOST_CLASS_HID_KEYBOARD_EVENTS_KEY_CHANGES_MODE is defined.
Defined, this value causes ux_host_class_hid_keyboard_key_get to report lock key (CapsLock/NumLock/ScrollLock) changes.
*/
/* #define UX_HOST_CLASS_HID_KEYBOARD_EVENTS_KEY_CHANGES_MODE_REPORT_LOCK_KEYS */
/* Works when UX_HOST_CLASS_HID_KEYBOARD_EVENTS_KEY_CHANGES_MODE is defined.
Defined, this value causes ux_host_class_hid_keyboard_key_get to report modifier key (Ctrl/Alt/Shift/GUI) changes.
*/
/* #define UX_HOST_CLASS_HID_KEYBOARD_EVENTS_KEY_CHANGES_MODE_REPORT_MODIFIER_KEYS */
/* Defined, this value represents the maximum number of media for the host storage class.
Default is 8 but for memory contrained resource systems this can ne reduced to 1. */
#define UX_HOST_CLASS_STORAGE_MAX_MEDIA 2
/* Defined, this value includes code to handle storage devices that use the CB
or CBI protocol (such as floppy disks). It is off by default because these
protocols are obsolete, being superseded by the Bulk Only Transport (BOT) protocol
which virtually all modern storage devices use.
*/
/* #define UX_HOST_CLASS_STORAGE_INCLUDE_LEGACY_PROTOCOL_SUPPORT */
/* Defined, this value forces the memory allocation scheme to enforce alignement
of memory with the UX_SAFE_ALIGN field.
*/
/* #define UX_ENFORCE_SAFE_ALIGNMENT */
/* Defined, this value represents the number of packets in the CDC_ECM device class.
The default is 16.
*/
#define UX_DEVICE_CLASS_CDC_ECM_NX_PKPOOL_ENTRIES 4
/* Defined, this value represents the number of packets in the CDC_ECM host class.
The default is 16.
*/
/* #define UX_HOST_CLASS_CDC_ECM_NX_PKPOOL_ENTRIES 16 */
/* Defined, this value represents the number of milliseconds to wait for packet
allocation until invoking the application's error callback and retrying.
The default is 1000 milliseconds.
*/
/* #define UX_HOST_CLASS_CDC_ECM_PACKET_POOL_WAIT 10 */
/* Defined, this value represents the number of milliseconds to wait for packet
allocation until invoking the application's error callback and retrying.
*/
/* #define UX_DEVICE_CLASS_CDC_ECM_PACKET_POOL_WAIT 10 */
/* Defined, this value represents the the maximum length of HID reports on the
device.
*/
/* #define UX_DEVICE_CLASS_HID_EVENT_BUFFER_LENGTH 64 */
/* Defined, this value represents the the maximum number of HID events/reports
that can be queued at once.
*/
/* #define UX_DEVICE_CLASS_HID_MAX_EVENTS_QUEUE 8 */
/* Defined, this value will only enable the host side of usbx. */
/* #define UX_HOST_SIDE_ONLY */
/* Defined, this value will only enable the device side of usbx. */
/* #define UX_DEVICE_SIDE_ONLY */
/* Defined, this value will include the OTG polling thread. OTG can only be active if both host/device are present.
*/
#ifndef UX_HOST_SIDE_ONLY
#ifndef UX_DEVICE_SIDE_ONLY
/* #define UX_OTG_SUPPORT */
#endif
#endif
/* Defined, this value represents the maximum size of single tansfers for the SCSI data phase.
*/
#define UX_HOST_CLASS_STORAGE_MAX_TRANSFER_SIZE (1024 * 1)
/* Defined, this value represents the size of the log pool.
*/
#define UX_DEBUG_LOG_SIZE (1024 * 16)
/* DEBUG includes and macros for a specific platform go here. */
#ifdef UX_INCLUDE_USER_DEFINE_BSP
#include "usb_bsp.h"
#include "usbh_hcs.h"
#include "usbh_stdreq.h"
#include "usbh_core.h"
#endif
#endif

View File

@ -0,0 +1,234 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Utility */
/** */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/* */
/* COMPONENT DEFINITION RELEASE */
/* */
/* ux_utility.h PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This file contains all the header and extern functions used by the */
/* USBX components that utilize utility functions. */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
#ifndef UX_UTILITY_H
#define UX_UTILITY_H
/* Define Utility component function prototypes. */
VOID _ux_utility_descriptor_parse(UCHAR * raw_descriptor, UCHAR * descriptor_structure,
UINT descriptor_entries, UCHAR * descriptor);
VOID _ux_utility_descriptor_pack(UCHAR * descriptor, UCHAR * descriptor_structure,
UINT descriptor_entries, UCHAR * raw_descriptor);
ULONG _ux_utility_long_get(UCHAR * address);
VOID _ux_utility_long_put(UCHAR * address, ULONG value);
VOID _ux_utility_long_put_big_endian(UCHAR * address, ULONG value);
ULONG _ux_utility_long_get_big_endian(UCHAR * address);
VOID *_ux_utility_memory_allocate(ULONG memory_alignment,ULONG memory_cache_flag, ULONG memory_size_requested);
UINT _ux_utility_memory_compare(VOID *memory_source, VOID *memory_destination, ULONG length);
VOID _ux_utility_memory_copy(VOID *memory_destination, VOID *memory_source, ULONG length);
VOID _ux_utility_memory_free(VOID *memory);
ULONG _ux_utility_string_length_get(UCHAR *string);
UINT _ux_utility_string_length_check(UCHAR *input_string, UINT *string_length_ptr, UINT max_string_length);
UX_MEMORY_BLOCK *_ux_utility_memory_free_block_best_get(ULONG memory_cache_flag, ULONG memory_size_requested);
VOID _ux_utility_memory_set(VOID *destination, UCHAR value, ULONG length);
UINT _ux_utility_mutex_create(TX_MUTEX *mutex, CHAR *mutex_name);
UINT _ux_utility_mutex_delete(TX_MUTEX *mutex);
VOID _ux_utility_mutex_off(TX_MUTEX *mutex);
VOID _ux_utility_mutex_on(TX_MUTEX *mutex);
ULONG _ux_utility_pci_class_scan(ULONG pci_class, ULONG bus_number, ULONG device_number,
ULONG function_number, ULONG *current_bus_number,
ULONG *current_device_number, ULONG *current_function_number);
ULONG _ux_utility_pci_read(ULONG bus_number, ULONG device_number, ULONG function_number,
ULONG offset, UINT read_size);
VOID _ux_utility_pci_write(ULONG bus_number, ULONG device_number, ULONG function_number,
ULONG offset, ULONG value, UINT write_size);
VOID *_ux_utility_physical_address(VOID *virtual_address);
UINT _ux_utility_semaphore_create(TX_SEMAPHORE *semaphore, CHAR *semaphore_name, UINT initial_count);
UINT _ux_utility_semaphore_delete(TX_SEMAPHORE *semaphore);
UINT _ux_utility_semaphore_get(TX_SEMAPHORE *semaphore, ULONG semaphore_signal);
UINT _ux_utility_semaphore_put(TX_SEMAPHORE *semaphore);
VOID _ux_utility_set_interrupt_handler(UINT irq, VOID (*interrupt_handler)(VOID));
ULONG _ux_utility_short_get(UCHAR * address);
ULONG _ux_utility_short_get_big_endian(UCHAR * address);
VOID _ux_utility_short_put(UCHAR * address, USHORT value);
VOID _ux_utility_short_put_big_endian(UCHAR * address, USHORT value);
UINT _ux_utility_thread_create(TX_THREAD *thread_ptr, CHAR *name,
VOID (*entry_function)(ULONG), ULONG entry_input,
VOID *stack_start, ULONG stack_size,
UINT priority, UINT preempt_threshold,
ULONG time_slice, UINT auto_start);
UINT _ux_utility_thread_delete(TX_THREAD *thread_ptr);
VOID _ux_utility_thread_relinquish(VOID);
UINT _ux_utility_thread_schedule_other(UINT caller_priority);
UINT _ux_utility_thread_resume(TX_THREAD *thread_ptr);
UINT _ux_utility_thread_sleep(ULONG ticks);
UINT _ux_utility_thread_suspend(TX_THREAD *thread_ptr);
TX_THREAD *_ux_utility_thread_identify(VOID);
UINT _ux_utility_timer_create(TX_TIMER *timer, CHAR *timer_name, VOID (*expiration_function) (ULONG),
ULONG expiration_input, ULONG initial_ticks, ULONG reschedule_ticks,
UINT activation_flag);
VOID *_ux_utility_virtual_address(VOID *physical_address);
UINT _ux_utility_event_flags_create(TX_EVENT_FLAGS_GROUP *group_ptr, CHAR *name);
UINT _ux_utility_event_flags_delete(TX_EVENT_FLAGS_GROUP *group_ptr);
UINT _ux_utility_event_flags_get(TX_EVENT_FLAGS_GROUP *group_ptr, ULONG requested_flags,
UINT get_option, ULONG *actual_flags_ptr, ULONG wait_option);
UINT _ux_utility_event_flags_set(TX_EVENT_FLAGS_GROUP *group_ptr, ULONG flags_to_set,
UINT set_option);
VOID _ux_utility_unicode_to_string(UCHAR *source, UCHAR *destination);
VOID _ux_utility_string_to_unicode(UCHAR *source, UCHAR *destination);
VOID _ux_system_error_handler(UINT system_level, UINT system_context, UINT error_code);
VOID _ux_utility_debug_callback_register(VOID (*debug_callback)(UCHAR *, ULONG));
VOID _ux_utility_error_callback_register(VOID (*error_callback)(UINT system_level, UINT system_context, UINT error_code));
VOID _ux_utility_delay_ms(ULONG ms_wait);
#define UX_UTILITY_ADD_SAFE(add_a, add_b, result, status) do { \
if (UX_OVERFLOW_CHECK_ADD_ULONG(add_a, add_b)) \
status = UX_ERROR; \
else \
result = (add_a) + (add_b); \
} while(0)
#define UX_UTILITY_MULC_SAFE(mul_v, mul_c, result, status) do { \
if (UX_OVERFLOW_CHECK_MULC_ULONG(mul_v, mul_c)) \
status = UX_ERROR; \
else \
result = (mul_v) * (mul_c); \
} while(0)
#define UX_UTILITY_MULV_SAFE(mul_v0, mul_v1, result, status) do { \
if (UX_OVERFLOW_CHECK_MULC_ULONG(mul_v0, mul_v1)) \
status = UX_ERROR; \
else \
result = (mul_v0) * (mul_v1); \
} while(0)
#define UX_UTILITY_MEMORY_ALLOCATE_MULC_SAFE(align,cache,size_mul_v,size_mul_c) \
(UX_OVERFLOW_CHECK_MULC_ULONG(size_mul_v, size_mul_c) ? UX_NULL : _ux_utility_memory_allocate((align), (cache), (size_mul_v)*(size_mul_c)))
#define UX_UTILITY_MEMORY_ALLOCATE_MULV_SAFE(align,cache,size_mul_v0,size_mul_v1) \
(UX_OVERFLOW_CHECK_MULV_ULONG(size_mul_v0, size_mul_v1) ? UX_NULL : _ux_utility_memory_allocate((align), (cache), (size_mul_v0)*(size_mul_v1)))
#define UX_UTILITY_MEMORY_ALLOCATE_ADD_SAFE(align,cache,size_add_a,size_add_b) \
(UX_OVERFLOW_CHECK_ADD_ULONG(size_add_a, size_add_b) ? UX_NULL : _ux_utility_memory_allocate((align), (cache), (size_add_a)+(size_add_b)))
#ifdef UX_DISABLE_ARITHMETIC_CHECK
/* No arithmetic check, calculate directly. */
#define _ux_utility_memory_allocate_mulc_safe(align,cache,size_mul_v,size_mul_c) _ux_utility_memory_allocate((align), (cache), (size_mul_v)*(size_mul_c))
#define _ux_utility_memory_allocate_mulv_safe(align,cache,size_mul_v0,size_mul_v1) _ux_utility_memory_allocate((align), (cache), (size_mul_v0)*(size_mul_v1))
#define _ux_utility_memory_allocate_add_safe(align,cache,size_add_a,size_add_b) _ux_utility_memory_allocate((align), (cache), (size_add_a)+(size_add_b))
#else /* UX_DISABLE_ARITHMETIC_CHECK */
#ifdef UX_ENABLE_MEMORY_ARITHMETIC_OPTIMIZE
/* Uses macro to enable code optimization on compiling. */
#define _ux_utility_memory_allocate_mulc_safe(align,cache,size_mul_v,size_mul_c) UX_UTILITY_MEMORY_ALLOCATE_MULC_SAFE(align,cache,size_mul_v,size_mul_c)
#define _ux_utility_memory_allocate_mulv_safe(align,cache,size_mul_v0,size_mul_v1) UX_UTILITY_MEMORY_ALLOCATE_MULV_SAFE(align,cache,size_mul_v0,size_mul_v1)
#define _ux_utility_memory_allocate_add_safe(align,cache,size_add_a,size_add_b) UX_UTILITY_MEMORY_ALLOCATE_ADD_SAFE(align,cache,size_add_a,size_add_b)
#else /* UX_ENABLE_MEMORY_ARITHMETIC_OPTIMIZE */
/* Uses functions to be most flexible. */
VOID* _ux_utility_memory_allocate_mulc_safe(ULONG align,ULONG cache,ULONG size_mul_v,ULONG size_mul_c);
VOID* _ux_utility_memory_allocate_mulv_safe(ULONG align,ULONG cache,ULONG size_mul_v0,ULONG size_mul_v1);
VOID* _ux_utility_memory_allocate_add_safe(ULONG align,ULONG cache,ULONG size_add_a,ULONG size_add_b);
#endif /* UX_ENABLE_MEMORY_ARITHMETIC_OPTIMIZE */
#endif /* UX_DISABLE_ARITHMETIC_CHECK */
/* Define the system API mappings.
Note: this section is only applicable to
application source code, hence the conditional that turns off this
stuff when the include file is processed by the ThreadX source. */
#ifndef UX_SOURCE_CODE
#define ux_utility_descriptor_parse _ux_utility_descriptor_parse
#define ux_utility_descriptor_pack _ux_utility_descriptor_pack
#define ux_utility_long_get _ux_utility_long_get
#define ux_utility_long_put _ux_utility_long_put
#define ux_utility_long_put_big_endian _ux_utility_long_put_big_endian
#define ux_utility_long_get_big_endian _ux_utility_long_get_big_endian
#define ux_utility_memory_allocate _ux_utility_memory_allocate
#define ux_utility_memory_compare _ux_utility_memory_compare
#define ux_utility_memory_copy _ux_utility_memory_copy
#define ux_utility_memory_free _ux_utility_memory_free
#define ux_utility_string_length_get _ux_utility_string_length_get
#define ux_utility_string_length_check _ux_utility_string_length_check
#define ux_utility_memory_set _ux_utility_memory_set
#define ux_utility_mutex_create _ux_utility_mutex_create
#define ux_utility_mutex_delete _ux_utility_mutex_delete
#define ux_utility_mutex_off _ux_utility_mutex_off
#define ux_utility_mutex_on _ux_utility_mutex_on
#define ux_utility_pci_class_scan _ux_utility_pci_class_scan
#define ux_utility_pci_read _ux_utility_pci_read
#define ux_utility_pci_write _ux_utility_pci_write
#define ux_utility_physical_address _ux_utility_physical_address
#define ux_utility_semaphore_create _ux_utility_semaphore_create
#define ux_utility_semaphore_delete _ux_utility_semaphore_delete
#define ux_utility_semaphore_get _ux_utility_semaphore_get
#define ux_utility_semaphore_put _ux_utility_semaphore_put
#define ux_utility_set_interrupt_handler _ux_utility_set_interrupt_handler
#define ux_utility_short_get _ux_utility_short_get
#define ux_utility_short_get_big_endian _ux_utility_short_get_big_endian
#define ux_utility_short_put _ux_utility_short_put
#define ux_utility_short_put_big_endian _ux_utility_short_put_big_endian
#define ux_utility_thread_create _ux_utility_thread_create
#define ux_utility_thread_delete _ux_utility_thread_delete
#define ux_utility_thread_relinquish _ux_utility_thread_relinquish
#define ux_utility_thread_resume _ux_utility_thread_resume
#define ux_utility_thread_sleep _ux_utility_thread_sleep
#define ux_utility_thread_suspend _ux_utility_thread_suspend
#define ux_utility_thread_identify _ux_utility_thread_identify
#define ux_utility_timer_create _ux_utility_timer_create
#define ux_utility_event_flags_create _ux_utility_event_flags_create
#define ux_utility_event_flags_delete _ux_utility_event_flags_delete
#define ux_utility_event_flags_get _ux_utility_event_flags_get
#define ux_utility_event_flags_set _ux_utility_event_flags_set
#define ux_utility_unicode_to_string _ux_utility_unicode_to_string
#define ux_utility_string_to_unicode _ux_utility_string_to_unicode
#define ux_utility_delay_ms _ux_utility_delay_ms
#define ux_utility_error_callback_register _ux_utility_error_callback_register
#define ux_system_error_handler _ux_system_error_handler
#endif
#endif

View File

@ -0,0 +1,80 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Slave Simulator Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_dcd_sim_slave.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_dcd_sim_slave_address_set PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function will set the address of the device after we have */
/* received a SET_ADDRESS command from the host. */
/* */
/* INPUT */
/* */
/* dcd_sim_slave Pointer to device controller */
/* address Address to set */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Slave Simulator Controller Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_dcd_sim_slave_address_set(UX_DCD_SIM_SLAVE *dcd_sim_slave, ULONG address)
{
UX_PARAMETER_NOT_USED(dcd_sim_slave);
UX_PARAMETER_NOT_USED(address);
/* This function always succeeds. */
return(UX_SUCCESS);
}

View File

@ -0,0 +1,114 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Slave Simulator Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_dcd_sim_slave.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_dcd_sim_slave_endpoint_create PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function will create a physical endpoint. */
/* */
/* INPUT */
/* */
/* dcd_sim_slave Pointer to device controller */
/* endpoint Pointer to endpoint container */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Slave Simulator Controller Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_dcd_sim_slave_endpoint_create(UX_DCD_SIM_SLAVE *dcd_sim_slave, UX_SLAVE_ENDPOINT *endpoint)
{
UX_DCD_SIM_SLAVE_ED *ed;
ULONG sim_slave_endpoint_index;
/* The simulator slave controller has 16 endpoints maximum. Endpoint 0 is always control.
The other endpoints are generic. We can use the endpoint number as an index. */
sim_slave_endpoint_index = endpoint ->ux_slave_endpoint_descriptor.bEndpointAddress & ~(ULONG)UX_ENDPOINT_DIRECTION;
/* Fetch the address of the physical endpoint. */
ed = &dcd_sim_slave -> ux_dcd_sim_slave_ed[sim_slave_endpoint_index];
/* Check the endpoint status, if it is free, reserve it. If not reject this endpoint. */
if ((ed -> ux_sim_slave_ed_status & UX_DCD_SIM_SLAVE_ED_STATUS_USED) == 0)
{
/* We can use this endpoint. */
ed -> ux_sim_slave_ed_status |= UX_DCD_SIM_SLAVE_ED_STATUS_USED;
/* Keep the physical endpoint address in the endpoint container. */
endpoint -> ux_slave_endpoint_ed = (VOID *) ed;
/* And its mask. */
ed -> ux_sim_slave_ed_index = sim_slave_endpoint_index;
/* Save the endpoint pointer. */
ed -> ux_sim_slave_ed_endpoint = endpoint;
/* If this is endpoint 0, it is always ready for transactions. */
if ( sim_slave_endpoint_index == 0)
ed -> ux_sim_slave_ed_status |= UX_DCD_SIM_SLAVE_ED_STATUS_TRANSFER;
/* Enable this endpoint. */
return(UX_SUCCESS);
}
/* Notify application. */
_ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_DCD, UX_MEMORY_INSUFFICIENT);
/* Return error to caller. */
return(UX_NO_ED_AVAILABLE);
}

View File

@ -0,0 +1,86 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Slave Simulator Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_dcd_sim_slave.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_dcd_sim_slave_endpoint_destroy PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function will destroy a physical endpoint. */
/* */
/* INPUT */
/* */
/* dcd_sim_slave Pointer to device controller */
/* endpoint Pointer to endpoint container */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Slave Simulator Controller Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_dcd_sim_slave_endpoint_destroy(UX_DCD_SIM_SLAVE *dcd_sim_slave, UX_SLAVE_ENDPOINT *endpoint)
{
UX_DCD_SIM_SLAVE_ED *ed;
UX_PARAMETER_NOT_USED(dcd_sim_slave);
/* Keep the physical endpoint address in the endpoint container. */
ed = (UX_DCD_SIM_SLAVE_ED *) endpoint -> ux_slave_endpoint_ed;
/* We can free this endpoint. */
ed -> ux_sim_slave_ed_status = UX_DCD_SIM_SLAVE_ED_STATUS_UNUSED;
/* This function never fails. */
return(UX_SUCCESS);
}

View File

@ -0,0 +1,86 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Slave Simulator Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_dcd_sim_slave.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_dcd_sim_slave_endpoint_reset PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function will reset a physical endpoint. */
/* */
/* INPUT */
/* */
/* dcd_sim_slave Pointer to device controller */
/* endpoint Pointer to endpoint container */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Slave Simulator Controller Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_dcd_sim_slave_endpoint_reset(UX_DCD_SIM_SLAVE *dcd_sim_slave, UX_SLAVE_ENDPOINT *endpoint)
{
UX_DCD_SIM_SLAVE_ED *ed;
UX_PARAMETER_NOT_USED(dcd_sim_slave);
/* Get the physical endpoint address in the endpoint container. */
ed = (UX_DCD_SIM_SLAVE_ED *) endpoint -> ux_slave_endpoint_ed;
/* Set the state of the endpoint to not stalled. */
ed -> ux_sim_slave_ed_status &= ~(ULONG)UX_DCD_SIM_SLAVE_ED_STATUS_STALLED;
/* This function never fails. */
return(UX_SUCCESS);
}

View File

@ -0,0 +1,86 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Slave Simulator Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_dcd_sim_slave.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_dcd_sim_slave_endpoint_stall PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function will stall a physical endpoint. */
/* */
/* INPUT */
/* */
/* dcd_sim_slave Pointer to device controller */
/* endpoint Pointer to endpoint container */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Slave Simulator Controller Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_dcd_sim_slave_endpoint_stall(UX_DCD_SIM_SLAVE *dcd_sim_slave, UX_SLAVE_ENDPOINT *endpoint)
{
UX_DCD_SIM_SLAVE_ED *ed;
UX_PARAMETER_NOT_USED(dcd_sim_slave);
/* Get the physical endpoint address in the endpoint container. */
ed = (UX_DCD_SIM_SLAVE_ED *) endpoint -> ux_slave_endpoint_ed;
/* Set the state of the endpoint to stalled. */
ed -> ux_sim_slave_ed_status |= UX_DCD_SIM_SLAVE_ED_STATUS_STALLED;
/* This function never fails. */
return(UX_SUCCESS);
}

View File

@ -0,0 +1,89 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Slave Simulator Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_dcd_sim_slave.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_dcd_sim_slave_endpoint_status PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function will return the status of the endpoint. */
/* */
/* INPUT */
/* */
/* dcd_sim_slave Pointer to device controller */
/* endpoint_index Endpoint index */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Slave Simulator Controller Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_dcd_sim_slave_endpoint_status(UX_DCD_SIM_SLAVE *dcd_sim_slave, ULONG endpoint_index)
{
UX_DCD_SIM_SLAVE_ED *ed;
/* Fetch the address of the physical endpoint. */
ed = &dcd_sim_slave -> ux_dcd_sim_slave_ed[endpoint_index];
/* Check the endpoint status, if it is free, we have a illegal endpoint. */
if ((ed -> ux_sim_slave_ed_status & UX_DCD_SIM_SLAVE_ED_STATUS_USED) == 0)
return(UX_ERROR);
/* Check if the endpoint is stalled. */
if ((ed -> ux_sim_slave_ed_status & UX_DCD_SIM_SLAVE_ED_STATUS_STALLED) == 0)
return(UX_FALSE);
else
return(UX_TRUE);
}

View File

@ -0,0 +1,82 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Slave Simulator Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_dcd_sim_slave.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_dcd_sim_slave_frame_number_get PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function will return the frame number currently used by the */
/* controller. This function is mostly used for isochronous purposes. */
/* */
/* INPUT */
/* */
/* dcd_sim_slave Pointer to device controller */
/* frame_number Destination for frame number */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Slave Simulator Controller Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_dcd_sim_slave_frame_number_get(UX_DCD_SIM_SLAVE *dcd_sim_slave, ULONG *frame_number)
{
UX_PARAMETER_NOT_USED(dcd_sim_slave);
/* There is no frame number from the slave controller. */
*frame_number = 0;
/* This function never fails. */
return(UX_SUCCESS);
}

View File

@ -0,0 +1,172 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Slave Simulator Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_dcd_sim_slave.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_dcd_sim_slave_function PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function dispatches the DCD function internally to the */
/* slave simulator controller. */
/* */
/* INPUT */
/* */
/* dcd Pointer to device controller */
/* function Function requested */
/* parameter Pointer to parameter structure*/
/* */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* _ux_dcd_sim_slave_address_set Set address */
/* _ux_dcd_sim_slave_endpoint_create Create endpoint */
/* _ux_dcd_sim_slave_endpoint_destroy Destroy endpoint */
/* _ux_dcd_sim_slave_endpoint_reset Reset endpoint */
/* _ux_dcd_sim_slave_endpoint_stall Stall endpoint */
/* _ux_dcd_sim_slave_endpoint_status Get endpoint status */
/* _ux_dcd_sim_slave_frame_number_get Get frame number */
/* _ux_dcd_sim_slave_state_change Change state */
/* _ux_dcd_sim_slave_transfer_abort Abort transfer */
/* _ux_dcd_sim_slave_transfer_request Request transfer */
/* */
/* CALLED BY */
/* */
/* USBX Device Stack */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_dcd_sim_slave_function(UX_SLAVE_DCD *dcd, UINT function, VOID *parameter)
{
UINT status;
UX_DCD_SIM_SLAVE *dcd_sim_slave;
/* Check the status of the controller. */
if (dcd -> ux_slave_dcd_status == UX_UNUSED)
{
/* Error trap. */
_ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_DCD, UX_CONTROLLER_UNKNOWN);
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_CONTROLLER_UNKNOWN, 0, 0, 0, UX_TRACE_ERRORS, 0, 0)
return(UX_CONTROLLER_UNKNOWN);
}
/* Get the pointer to the Slave simulation DCD. */
dcd_sim_slave = (UX_DCD_SIM_SLAVE *) dcd -> ux_slave_dcd_controller_hardware;
/* Look at the function and route it. */
switch(function)
{
case UX_DCD_GET_FRAME_NUMBER:
status = _ux_dcd_sim_slave_frame_number_get(dcd_sim_slave, (ULONG *) parameter);
break;
case UX_DCD_TRANSFER_REQUEST:
status = _ux_dcd_sim_slave_transfer_request(dcd_sim_slave, (UX_SLAVE_TRANSFER *) parameter);
break;
case UX_DCD_TRANSFER_ABORT:
status = _ux_dcd_sim_slave_transfer_abort(dcd_sim_slave, (UX_SLAVE_TRANSFER *) parameter);
break;
case UX_DCD_CREATE_ENDPOINT:
status = _ux_dcd_sim_slave_endpoint_create(dcd_sim_slave, parameter);
break;
case UX_DCD_DESTROY_ENDPOINT:
status = _ux_dcd_sim_slave_endpoint_destroy(dcd_sim_slave, parameter);
break;
case UX_DCD_RESET_ENDPOINT:
status = _ux_dcd_sim_slave_endpoint_reset(dcd_sim_slave, parameter);
break;
case UX_DCD_STALL_ENDPOINT:
status = _ux_dcd_sim_slave_endpoint_stall(dcd_sim_slave, parameter);
break;
case UX_DCD_SET_DEVICE_ADDRESS:
status = _ux_dcd_sim_slave_address_set(dcd_sim_slave, (ULONG) (ALIGN_TYPE) parameter);
break;
case UX_DCD_CHANGE_STATE:
status = _ux_dcd_sim_slave_state_change(dcd_sim_slave, (ULONG) (ALIGN_TYPE) parameter);
break;
case UX_DCD_ENDPOINT_STATUS:
status = _ux_dcd_sim_slave_endpoint_status(dcd_sim_slave, (ULONG) (ALIGN_TYPE) parameter);
break;
default:
/* Error trap. */
_ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_DCD, UX_FUNCTION_NOT_SUPPORTED);
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_FUNCTION_NOT_SUPPORTED, 0, 0, 0, UX_TRACE_ERRORS, 0, 0)
status = UX_FUNCTION_NOT_SUPPORTED;
}
/* Return completion status. */
return(status);
}

View File

@ -0,0 +1,104 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Slave Simulator Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_dcd_sim_slave.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_dcd_sim_slave_initialize PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function initializes the USB simulation slave controller. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* _ux_utility_memory_allocate Allocate memory */
/* */
/* CALLED BY */
/* */
/* Slave Simulator Controller Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_dcd_sim_slave_initialize(VOID)
{
UX_SLAVE_DCD *dcd;
UX_DCD_SIM_SLAVE *dcd_sim_slave;
/* Get the pointer to the DCD. */
dcd = &_ux_system_slave -> ux_system_slave_dcd;
/* The controller initialized here is of Slave simulation type. */
dcd -> ux_slave_dcd_controller_type = UX_DCD_SIM_SLAVE_SLAVE_CONTROLLER;
/* Allocate memory for this Slave simulation DCD instance. */
dcd_sim_slave = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, sizeof(UX_DCD_SIM_SLAVE));
/* Check if memory was properly allocated. */
if(dcd_sim_slave == UX_NULL)
return(UX_MEMORY_INSUFFICIENT);
/* Set the pointer to the Slave simulation DCD. */
dcd -> ux_slave_dcd_controller_hardware = (VOID *) dcd_sim_slave;
/* Set the generic DCD owner for the Slave simulation DCD. */
dcd_sim_slave -> ux_dcd_sim_slave_dcd_owner = dcd;
/* Initialize the function collector for this DCD. */
dcd -> ux_slave_dcd_function = _ux_dcd_sim_slave_function;
/* Set the state of the controller to OPERATIONAL now. */
dcd -> ux_slave_dcd_status = UX_DCD_STATUS_OPERATIONAL;
/* This operation completed with success. */
return(UX_SUCCESS);
}

View File

@ -0,0 +1,141 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Slave Simulator Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_dcd_sim_slave.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_dcd_sim_slave_initialize_complete PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function completes the initialization of the slave controller */
/* simulator. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* (ux_slave_dcd_function) DCD dispatch function */
/* _ux_utility_descriptor_parse Parse descriptor */
/* */
/* CALLED BY */
/* */
/* Slave Simulator Controller Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_dcd_sim_slave_initialize_complete(VOID)
{
UX_SLAVE_DCD *dcd;
UX_SLAVE_DEVICE *device;
UCHAR * device_framework;
UX_SLAVE_TRANSFER *transfer_request;
/* Get the pointer to the DCD. */
dcd = &_ux_system_slave -> ux_system_slave_dcd;
/* Get the pointer to the device. */
device = &_ux_system_slave -> ux_system_slave_device;
/* Slave simulator is a Full speed controller. */
_ux_system_slave -> ux_system_slave_device_framework = _ux_system_slave -> ux_system_slave_device_framework_full_speed;
_ux_system_slave -> ux_system_slave_device_framework_length = _ux_system_slave -> ux_system_slave_device_framework_length_full_speed;
/* Get the device framework pointer. */
device_framework = _ux_system_slave -> ux_system_slave_device_framework;
/* And create the decompressed device descriptor structure. */
_ux_utility_descriptor_parse(device_framework,
_ux_system_device_descriptor_structure,
UX_DEVICE_DESCRIPTOR_ENTRIES,
(UCHAR *) &device -> ux_slave_device_descriptor);
/* Now we create a transfer request to accept the first SETUP packet
and get the ball running. First get the address of the endpoint
transfer request container. */
transfer_request = &device -> ux_slave_device_control_endpoint.ux_slave_endpoint_transfer_request;
/* Set the timeout to be for Control Endpoint. */
transfer_request -> ux_slave_transfer_request_timeout = MS_TO_TICK(UX_CONTROL_TRANSFER_TIMEOUT);
/* Adjust the current data pointer as well. */
transfer_request -> ux_slave_transfer_request_current_data_pointer =
transfer_request -> ux_slave_transfer_request_data_pointer;
/* Update the transfer request endpoint pointer with the default endpoint. */
transfer_request -> ux_slave_transfer_request_endpoint = &device -> ux_slave_device_control_endpoint;
/* The control endpoint max packet size needs to be filled manually in its descriptor. */
transfer_request -> ux_slave_transfer_request_endpoint -> ux_slave_endpoint_descriptor.wMaxPacketSize =
device -> ux_slave_device_descriptor.bMaxPacketSize0;
/* On the control endpoint, always expect the maximum. */
transfer_request -> ux_slave_transfer_request_requested_length =
device -> ux_slave_device_descriptor.bMaxPacketSize0;
/* Attach the control endpoint to the transfer request. */
transfer_request -> ux_slave_transfer_request_endpoint = &device -> ux_slave_device_control_endpoint;
/* Create the default control endpoint attached to the device.
Once this endpoint is enabled, the host can then send a setup packet
The device controller will receive it and will call the setup function
module. */
dcd -> ux_slave_dcd_function(dcd, UX_DCD_CREATE_ENDPOINT,
(VOID *) &device -> ux_slave_device_control_endpoint);
/* Ensure the control endpoint is properly reset. */
device -> ux_slave_device_control_endpoint.ux_slave_endpoint_state = UX_ENDPOINT_RESET;
/* A SETUP packet is a DATA IN operation. */
transfer_request -> ux_slave_transfer_request_phase = UX_TRANSFER_PHASE_DATA_IN;
/* We are now ready for the USB device to accept the first packet when connected. */
return(UX_SUCCESS);
}

View File

@ -0,0 +1,80 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Slave Simulator Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_dcd_sim_slave.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_dcd_sim_slave_state_change PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function will set the state of the controller to the desired */
/* value. */
/* */
/* INPUT */
/* */
/* dcd_sim_slave Pointer to device controller */
/* state Desired state */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Slave Simulator Controller Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_dcd_sim_slave_state_change(UX_DCD_SIM_SLAVE *dcd_sim_slave, ULONG state)
{
UX_PARAMETER_NOT_USED(dcd_sim_slave);
UX_PARAMETER_NOT_USED(state);
/* Nothing to do in simulation mode. */
return(UX_SUCCESS);
}

View File

@ -0,0 +1,90 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Slave Simulator Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_dcd_sim_slave.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_dcd_sim_slave_transfer_abort PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function will terminate a transfer. */
/* */
/* INPUT */
/* */
/* dcd_sim_slave Pointer to device controller */
/* transfer_request Pointer to transfer request */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Slave Simulator Controller Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_dcd_sim_slave_transfer_abort(UX_DCD_SIM_SLAVE *dcd_sim_slave, UX_SLAVE_TRANSFER *transfer_request)
{
UX_DCD_SIM_SLAVE_ED *ed;
UX_SLAVE_ENDPOINT *endpoint;
UX_PARAMETER_NOT_USED(dcd_sim_slave);
/* Get the pointer to the logical endpoint from the transfer request. */
endpoint = transfer_request -> ux_slave_transfer_request_endpoint;
/* Keep the physical endpoint address in the endpoint container. */
ed = (UX_DCD_SIM_SLAVE_ED *) endpoint -> ux_slave_endpoint_ed;
/* Turn off the transfer bit. */
ed -> ux_sim_slave_ed_status &= ~(ULONG)UX_DCD_SIM_SLAVE_ED_STATUS_TRANSFER;
/* This function never fails. */
return(UX_SUCCESS);
}

View File

@ -0,0 +1,123 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Slave Simulator Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_dcd_sim_slave.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_dcd_sim_slave_transfer_request PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function will initiate a transfer to a specific endpoint. */
/* If the endpoint is IN, the endpoint register will be set to accept */
/* the request. */
/* */
/* If the endpoint is IN, the endpoint FIFO will be filled with the */
/* buffer and the endpoint register set. */
/* */
/* INPUT */
/* */
/* dcd_sim_slave Pointer to device controller */
/* transfer_request Pointer to transfer request */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* _ux_utility_semaphore_get Get semaphore */
/* _ux_dcd_sim_slave_transfer_abort Abort transfer */
/* */
/* CALLED BY */
/* */
/* Slave Simulator Controller Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_dcd_sim_slave_transfer_request(UX_DCD_SIM_SLAVE *dcd_sim_slave, UX_SLAVE_TRANSFER *transfer_request)
{
UX_SLAVE_ENDPOINT *endpoint;
UX_DCD_SIM_SLAVE_ED *ed;
UINT status;
/* Get the pointer to the logical endpoint from the transfer request. */
endpoint = transfer_request -> ux_slave_transfer_request_endpoint;
/* Get the slave endpoint. */
ed = (UX_DCD_SIM_SLAVE_ED *) endpoint -> ux_slave_endpoint_ed;
/* We have a request for a OUT or IN transaction from the host.
If the endpoint is a Control endpoint, all this is happening under Interrupt and there is no
thread to suspend. */
if (ed -> ux_sim_slave_ed_index != 0)
{
/* Set the ED to TRANSFER status. */
ed -> ux_sim_slave_ed_status |= UX_DCD_SIM_SLAVE_ED_STATUS_TRANSFER;
/* We should wait for the semaphore to wake us up. */
status = _ux_utility_semaphore_get(&transfer_request -> ux_slave_transfer_request_semaphore,
transfer_request -> ux_slave_transfer_request_timeout);
/* Reset the ED to TRANSFER status. */
ed -> ux_sim_slave_ed_status &= ~(ULONG)UX_DCD_SIM_SLAVE_ED_STATUS_TRANSFER;
/* Check the completion code. */
if (status != UX_SUCCESS)
{
_ux_dcd_sim_slave_transfer_abort(dcd_sim_slave, transfer_request);
transfer_request -> ux_slave_transfer_request_status = UX_TRANSFER_STATUS_COMPLETED;
return(status);
}
/* Check the transfer request completion code. We may have had a BUS reset or
a device disconnection. */
if (transfer_request -> ux_slave_transfer_request_completion_code != UX_SUCCESS)
return(transfer_request -> ux_slave_transfer_request_completion_code);
}
/* Return to caller with success. */
return(UX_SUCCESS);
}

View File

@ -0,0 +1,141 @@
/**************************************************************************/
/* */
/* 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 Data Pump Class */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_device_class_dpump.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_dpump_activate PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function activates the USB dpump device. */
/* */
/* INPUT */
/* */
/* command Pointer to dpump command */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Device Data Pump Class */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_device_class_dpump_activate(UX_SLAVE_CLASS_COMMAND *command)
{
UX_SLAVE_INTERFACE *interface;
UX_SLAVE_CLASS_DPUMP *dpump;
UX_SLAVE_CLASS *class;
UX_SLAVE_ENDPOINT *endpoint;
/* Get the class container. */
class = command -> ux_slave_class_command_class_ptr;
/* Store the class instance in the container. */
dpump = (UX_SLAVE_CLASS_DPUMP *) class -> ux_slave_class_instance;
/* Get the interface that owns this instance. */
interface = (UX_SLAVE_INTERFACE *) command -> ux_slave_class_command_interface;
/* Store the class instance into the interface. */
interface -> ux_slave_interface_class_instance = (VOID *)dpump;
/* Now the opposite, store the interface in the class instance. */
dpump -> ux_slave_class_dpump_interface = interface;
/* Locate the endpoints. Interrupt for Control and Bulk in/out for Data. */
endpoint = interface -> ux_slave_interface_first_endpoint;
/* Parse all endpoints. */
while (endpoint != UX_NULL)
{
/* Check the endpoint direction, and type. */
if ((endpoint -> ux_slave_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION) == UX_ENDPOINT_IN)
{
/* Look at type. */
if ((endpoint -> ux_slave_endpoint_descriptor.bmAttributes & UX_MASK_ENDPOINT_TYPE) == UX_BULK_ENDPOINT)
/* We have found the bulk in endpoint, save it. */
dpump -> ux_slave_class_dpump_bulkin_endpoint = endpoint;
}
else
{
/* Look at type for out endpoint. */
if ((endpoint -> ux_slave_endpoint_descriptor.bmAttributes & UX_MASK_ENDPOINT_TYPE) == UX_BULK_ENDPOINT)
/* We have found the bulk out endpoint, save it. */
dpump -> ux_slave_class_dpump_bulkout_endpoint = endpoint;
}
/* Next endpoint. */
endpoint = endpoint -> ux_slave_endpoint_next_endpoint;
}
/* If there is a activate function call it. */
if (dpump -> ux_slave_class_dpump_parameter.ux_slave_class_dpump_instance_activate != UX_NULL)
{
/* Invoke the application. */
dpump -> ux_slave_class_dpump_parameter.ux_slave_class_dpump_instance_activate(dpump);
}
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_CLASS_DPUMP_ACTIVATE, dpump, 0, 0, 0, UX_TRACE_DEVICE_CLASS_EVENTS, 0, 0)
/* If trace is enabled, register this object. */
UX_TRACE_OBJECT_REGISTER(UX_TRACE_DEVICE_OBJECT_TYPE_INTERFACE, dpump, 0, 0, 0)
/* Return completion status. */
return(UX_SUCCESS);
}

View File

@ -0,0 +1,168 @@
/**************************************************************************/
/* */
/* 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 DPUMP Class */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_device_class_dpump.h"
#include "ux_device_stack.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_dpump_change PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function changes the interface of the DPUMP device */
/* */
/* INPUT */
/* */
/* command Pointer to dpump command */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* _ux_utility_memory_set Set memory */
/* _ux_device_stack_transfer_all_request_abort */
/* Abort request */
/* */
/* CALLED BY */
/* */
/* USBX Source Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_device_class_dpump_change(UX_SLAVE_CLASS_COMMAND *command)
{
UX_SLAVE_INTERFACE *interface;
UX_SLAVE_CLASS_DPUMP *dpump;
UX_SLAVE_CLASS *class;
UX_SLAVE_ENDPOINT *endpoint;
/* Get the class container. */
class = command -> ux_slave_class_command_class_ptr;
/* Get the class instance in the container. */
dpump = (UX_SLAVE_CLASS_DPUMP *) class -> ux_slave_class_instance;
/* Get the interface that owns this instance. */
interface = (UX_SLAVE_INTERFACE *) command -> ux_slave_class_command_interface;
/* Locate the endpoints. Control and Bulk in/out for data. */
endpoint = interface -> ux_slave_interface_first_endpoint;
/* Keep the alternate setting in the dpump structure. */
dpump -> ux_slave_class_dpump_alternate_setting = interface -> ux_slave_interface_descriptor.bAlternateSetting;
/* If the interface to mount has a non zero alternate setting, the class is really active with
the endpoints active. If the interface reverts to alternate setting 0, it needs to have
the pending transactions terminated. */
if (interface -> ux_slave_interface_descriptor.bAlternateSetting != 0)
{
/* Parse all endpoints. */
while (endpoint != UX_NULL)
{
/* Check the endpoint direction, and type. */
if ((endpoint -> ux_slave_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION) == UX_ENDPOINT_IN)
{
/* Look at type. */
if ((endpoint -> ux_slave_endpoint_descriptor.bmAttributes & UX_MASK_ENDPOINT_TYPE) == UX_BULK_ENDPOINT)
/* We have found the bulk in endpoint, save it. */
dpump -> ux_slave_class_dpump_bulkin_endpoint = endpoint;
}
else
{
/* Look at type for out endpoint. */
if ((endpoint -> ux_slave_endpoint_descriptor.bmAttributes & UX_MASK_ENDPOINT_TYPE) == UX_BULK_ENDPOINT)
/* We have found the bulk out endpoint, save it. */
dpump -> ux_slave_class_dpump_bulkout_endpoint = endpoint;
}
/* Next endpoint. */
endpoint = endpoint -> ux_slave_endpoint_next_endpoint;
}
/* Now check if all endpoints have been found. */
if (dpump -> ux_slave_class_dpump_bulkout_endpoint == UX_NULL || dpump -> ux_slave_class_dpump_bulkin_endpoint == UX_NULL)
/* Not all endpoints have been found. Major error, do not proceed. */
return(UX_ERROR);
/* Reset the endpoint buffers. */
_ux_utility_memory_set(dpump -> ux_slave_class_dpump_bulkout_endpoint -> ux_slave_endpoint_transfer_request.
ux_slave_transfer_request_data_pointer, 0, UX_SLAVE_REQUEST_DATA_MAX_LENGTH);
_ux_utility_memory_set(dpump -> ux_slave_class_dpump_bulkin_endpoint -> ux_slave_endpoint_transfer_request.
ux_slave_transfer_request_data_pointer, 0, UX_SLAVE_REQUEST_DATA_MAX_LENGTH);
/* Keep the alternate setting in the dpump structure. */
dpump -> ux_slave_class_dpump_alternate_setting = interface -> ux_slave_interface_descriptor.bAlternateSetting;
/* If there is an activate function call it. */
if (dpump -> ux_slave_class_dpump_parameter.ux_slave_class_dpump_instance_activate != UX_NULL)
/* Invoke the application. */
dpump -> ux_slave_class_dpump_parameter.ux_slave_class_dpump_instance_activate(dpump);
}
else
{
/* In this case, we are reverting to the Alternate Setting 0. We need to terminate the pending transactions. */
/* Terminate the transactions pending on the endpoints (bulk in, bulk out). */
_ux_device_stack_transfer_all_request_abort(dpump -> ux_slave_class_dpump_bulkin_endpoint, UX_TRANSFER_APPLICATION_RESET);
_ux_device_stack_transfer_all_request_abort(dpump -> ux_slave_class_dpump_bulkout_endpoint, UX_TRANSFER_APPLICATION_RESET);
}
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_CLASS_DPUMP_CHANGE, dpump, 0, 0, 0, UX_TRACE_DEVICE_CLASS_EVENTS, 0, 0)
/* If trace is enabled, register this object. */
UX_TRACE_OBJECT_REGISTER(UX_TRACE_DEVICE_OBJECT_TYPE_INTERFACE, dpump, 0, 0, 0)
/* Return completion status. */
return(UX_SUCCESS);
}

View File

@ -0,0 +1,129 @@
/**************************************************************************/
/* */
/* 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 Data Pump Class */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_device_class_dpump.h"
#include "ux_device_stack.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_dpump_deactivate PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function deactivate an instance of the dpump class. */
/* */
/* INPUT */
/* */
/* command Pointer to a class command */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* _ux_device_stack_transfer_all_request_abort Abort all transfers */
/* */
/* CALLED BY */
/* */
/* Device Data Pump Class */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_device_class_dpump_deactivate(UX_SLAVE_CLASS_COMMAND *command)
{
UX_SLAVE_INTERFACE *interface;
UX_SLAVE_CLASS_DPUMP *dpump;
UX_SLAVE_ENDPOINT *endpoint_in;
UX_SLAVE_ENDPOINT *endpoint_out;
UX_SLAVE_CLASS *class;
/* Get the class container. */
class = command -> ux_slave_class_command_class_ptr;
/* Store the class instance in the container. */
dpump = (UX_SLAVE_CLASS_DPUMP *) class -> ux_slave_class_instance;
/* We need the interface to the class. */
interface = dpump -> ux_slave_class_dpump_interface;
/* Locate the endpoints. */
endpoint_in = interface -> ux_slave_interface_first_endpoint;
/* Check the endpoint direction, if IN we have the correct endpoint. */
if ((endpoint_in -> ux_slave_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION) != UX_ENDPOINT_IN)
{
/* Wrong direction, we found the OUT endpoint first. */
endpoint_out = endpoint_in;
/* So the next endpoint has to be the IN endpoint. */
endpoint_in = endpoint_out -> ux_slave_endpoint_next_endpoint;
}
else
{
/* We found the endpoint IN first, so next endpoint is OUT. */
endpoint_out = endpoint_in -> ux_slave_endpoint_next_endpoint;
}
/* Terminate the transactions pending on the endpoints. */
_ux_device_stack_transfer_all_request_abort(endpoint_in, UX_TRANSFER_BUS_RESET);
_ux_device_stack_transfer_all_request_abort(endpoint_out, UX_TRANSFER_BUS_RESET);
/* If there is a deactivate function call it. */
if (dpump -> ux_slave_class_dpump_parameter.ux_slave_class_dpump_instance_deactivate != UX_NULL)
{
/* Invoke the application. */
dpump -> ux_slave_class_dpump_parameter.ux_slave_class_dpump_instance_deactivate(dpump);
}
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_CLASS_DPUMP_DEACTIVATE, dpump, 0, 0, 0, UX_TRACE_DEVICE_CLASS_EVENTS, 0, 0)
/* If trace is enabled, register this object. */
UX_TRACE_OBJECT_UNREGISTER(dpump);
/* Return completion status. */
return(UX_SUCCESS);
}

View File

@ -0,0 +1,147 @@
/**************************************************************************/
/* */
/* 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 Data Pump Class */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_device_class_dpump.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_class_device_dpump_entry PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function is the entry point of the device dpump class. It */
/* will be called by the device stack enumeration module when the */
/* host has sent a SET_CONFIGURATION command and the dpump interface */
/* needs to be mounted. */
/* */
/* INPUT */
/* */
/* command Pointer to class command */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* _ux_device_class_dpump_initialize Initialize dpump class */
/* _ux_device_class_dpump_activate Activate dpump class */
/* _ux_device_class_dpump_deactivate Deactivate dpump class */
/* _ux_device_class_dpump_change Alternate setting change */
/* */
/* CALLED BY */
/* */
/* Device Data Pump Class */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_device_class_dpump_entry(UX_SLAVE_CLASS_COMMAND *command)
{
UINT status;
/* The command request will tell us we need to do here, either a enumeration
query, an activation or a deactivation. */
switch (command -> ux_slave_class_command_request)
{
case UX_SLAVE_CLASS_COMMAND_INITIALIZE:
/* Call the init function of the DPUMP class. */
status = _ux_device_class_dpump_initialize(command);
/* Return the completion status. */
return(status);
case UX_SLAVE_CLASS_COMMAND_QUERY:
/* Check the CLASS definition in the interface descriptor. */
if (command -> ux_slave_class_command_class == UX_SLAVE_CLASS_DPUMP_CLASS)
return(UX_SUCCESS);
else
return(UX_NO_CLASS_MATCH);
case UX_SLAVE_CLASS_COMMAND_ACTIVATE:
/* The activate command is used when the host has sent a SET_CONFIGURATION command
and this interface has to be mounted. Both Bulk endpoints have to be mounted
and the dpump thread needs to be activated. */
status = _ux_device_class_dpump_activate(command);
/* Return the completion status. */
return(status);
case UX_SLAVE_CLASS_COMMAND_CHANGE:
/* The change command is used when the host has sent a SET_INTERFACE command
to go from Alternate Setting 0 to 1 or revert to the default mode. */
status = _ux_device_class_dpump_change(command);
/* Return the completion status. */
return(status);
case UX_SLAVE_CLASS_COMMAND_DEACTIVATE:
/* The deactivate command is used when the device has been extracted.
The device endpoints have to be dismounted and the dpump thread canceled. */
status = _ux_device_class_dpump_deactivate(command);
/* Return the completion status. */
return(status);
case UX_SLAVE_CLASS_COMMAND_REQUEST:
/* Return the completion status. */
return(UX_SUCCESS);
default:
/* Error trap. */
_ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_FUNCTION_NOT_SUPPORTED);
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_FUNCTION_NOT_SUPPORTED, 0, 0, 0, UX_TRACE_ERRORS, 0, 0)
/* Return an error. */
return(UX_FUNCTION_NOT_SUPPORTED);
}
}

View File

@ -0,0 +1,100 @@
/**************************************************************************/
/* */
/* 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 Data Pump Class */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_device_class_dpump.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_dpump_initialize PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function initializes the USB dpump device. */
/* */
/* INPUT */
/* */
/* command Pointer to dpump command */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* _ux_utility_memory_allocate Allocate memory */
/* */
/* CALLED BY */
/* */
/* Device Data Pump Class */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_device_class_dpump_initialize(UX_SLAVE_CLASS_COMMAND *command)
{
UX_SLAVE_CLASS_DPUMP *dpump;
UX_SLAVE_CLASS *class;
UX_SLAVE_CLASS_DPUMP_PARAMETER *dpump_parameter;
/* Get the class container. */
class = command -> ux_slave_class_command_class_ptr;
/* Create an instance of the device dpump class. */
dpump = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, sizeof(UX_SLAVE_CLASS_DPUMP));
/* Check for successful allocation. */
if (dpump == UX_NULL)
return(UX_MEMORY_INSUFFICIENT);
/* Save the address of the DPUMP instance inside the DPUMP container. */
class -> ux_slave_class_instance = (VOID *) dpump;
/* Get the pointer to the application parameters for the cdc class. */
dpump_parameter = command -> ux_slave_class_command_parameter;
/* Store the start and stop signals if needed by the application. */
dpump -> ux_slave_class_dpump_parameter.ux_slave_class_dpump_instance_activate = dpump_parameter -> ux_slave_class_dpump_instance_activate;
dpump -> ux_slave_class_dpump_parameter.ux_slave_class_dpump_instance_deactivate = dpump_parameter -> ux_slave_class_dpump_instance_deactivate;
/* Return completion status. */
return(UX_SUCCESS);
}

View File

@ -0,0 +1,182 @@
/**************************************************************************/
/* */
/* 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 DPUMP Class */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_device_class_dpump.h"
#include "ux_device_stack.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_dpump_read PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function reads from the DPUMP class. */
/* */
/* INPUT */
/* */
/* dpump Address of dpump class */
/* instance */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _ux_device_stack_transfer_request Request transfer */
/* _ux_utility_memory_copy Copy memory */
/* */
/* CALLED BY */
/* */
/* ThreadX */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_device_class_dpump_read(UX_SLAVE_CLASS_DPUMP *dpump, UCHAR *buffer,
ULONG requested_length, ULONG *actual_length)
{
UX_SLAVE_ENDPOINT *endpoint;
UX_SLAVE_DEVICE *device;
UX_SLAVE_TRANSFER *transfer_request;
UINT status;
ULONG local_requested_length;
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_CLASS_DPUMP_READ, dpump, 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. */
return(UX_CONFIGURATION_HANDLE_UNKNOWN);
}
/* Locate the OUT endpoint. */
endpoint = dpump -> ux_slave_class_dpump_bulkout_endpoint;
/* Check endpoint. If NULL, we have not yet received the proper SET_INTERFACE command. */
if (endpoint == UX_NULL)
{
/* Error trap. */
_ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_ENDPOINT_HANDLE_UNKNOWN);
return(UX_ENDPOINT_HANDLE_UNKNOWN);
}
/* All DPUMP reading are on the endpoint OUT, from the host. */
transfer_request = &endpoint -> ux_slave_endpoint_transfer_request;
/* Reset the actual length. */
*actual_length = 0;
/* Set return status to SUCCESS to make certain compilers happy. */
status = UX_SUCCESS;
/* Check if we need more transactions. */
while (device -> ux_slave_device_state == UX_DEVICE_CONFIGURED && requested_length != 0)
{
/* Check if we have enough in the local buffer. */
if (requested_length > UX_SLAVE_REQUEST_DATA_MAX_LENGTH)
/* We have too much to transfer. */
local_requested_length = UX_SLAVE_REQUEST_DATA_MAX_LENGTH;
else
/* We can proceed with the demanded length. */
local_requested_length = requested_length;
/* Send the request to the device controller. */
status = _ux_device_stack_transfer_request(transfer_request, local_requested_length, local_requested_length);
/* Check the status */
if (status == UX_SUCCESS)
{
/* We need to copy the buffer locally. */
_ux_utility_memory_copy(buffer, transfer_request -> ux_slave_transfer_request_data_pointer,
local_requested_length);
/* Next buffer address. */
buffer += transfer_request -> ux_slave_transfer_request_actual_length;
/* Set the length actually received. */
*actual_length += transfer_request -> ux_slave_transfer_request_actual_length;
/* Decrement what left has to be done. */
requested_length -= transfer_request -> ux_slave_transfer_request_actual_length;
}
else
/* We got an error. */
return(status);
}
/* Check why we got here, either completion or device was extracted. */
if (device -> ux_slave_device_state != UX_DEVICE_CONFIGURED)
{
/* 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)
/* Device must have been extracted. */
return (UX_TRANSFER_NO_ANSWER);
}
else
/* Simply return the last transaction result. */
return(status);
}

View File

@ -0,0 +1,165 @@
/**************************************************************************/
/* */
/* 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 Data Pump Class */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_device_class_dpump.h"
#include "ux_device_stack.h"
/* Remove compiling warning. */
VOID _ux_device_class_dpump_thread(ULONG dpump_class);
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_dpump_thread PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function is the thread of the dpump class. */
/* */
/* INPUT */
/* */
/* class Address of dpump class */
/* container */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _ux_device_stack_transfer_request Request transfer */
/* _ux_utility_memory_copy Copy memory */
/* _ux_utility_thread_suspend Suspend thread */
/* */
/* CALLED BY */
/* */
/* ThreadX */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
VOID _ux_device_class_dpump_thread(ULONG dpump_class)
{
UX_SLAVE_CLASS *class;
UX_SLAVE_CLASS_DPUMP *dpump;
UX_SLAVE_TRANSFER *transfer_request;
UX_SLAVE_DEVICE *device;
UX_SLAVE_INTERFACE *interface;
UX_SLAVE_ENDPOINT *endpoint_in;
UX_SLAVE_ENDPOINT *endpoint_out;
UINT status;
ULONG length;
/* This thread runs forever but can be suspended or resumed. */
while(1)
{
/* Cast properly the dpump instance. */
UX_THREAD_EXTENSION_PTR_GET(class, UX_SLAVE_CLASS, dpump_class)
/* Get the dpump instance from this class container. */
dpump = (UX_SLAVE_CLASS_DPUMP *) class -> ux_slave_class_instance;
/* Get the pointer to the device. */
device = &_ux_system_slave -> ux_system_slave_device;
/* This is the first time we are activated. We need the interface to the class. */
interface = dpump -> ux_slave_class_dpump_interface;
/* Locate the endpoints. */
endpoint_in = interface -> ux_slave_interface_first_endpoint;
/* Check the endpoint direction, if IN we have the correct endpoint. */
if ((endpoint_in -> ux_slave_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION) != UX_ENDPOINT_IN)
{
/* Wrong direction, we found the OUT endpoint first. */
endpoint_out = endpoint_in;
/* So the next endpoint has to be the IN endpoint. */
endpoint_in = endpoint_out -> ux_slave_endpoint_next_endpoint;
}
else
{
/* We found the endpoint IN first, so next endpoint is OUT. */
endpoint_out = endpoint_in -> ux_slave_endpoint_next_endpoint;
}
/* As long as the device is in the CONFIGURED state. */
while (device -> ux_slave_device_state == UX_DEVICE_CONFIGURED)
{
/* We prepare to receive from the host on the OUT endpoint. */
transfer_request = &endpoint_out -> ux_slave_endpoint_transfer_request;
/* Send the request to the device controller. */
status = _ux_device_stack_transfer_request(transfer_request, UX_DEVICE_CLASS_DPUMP_PACKET_SIZE, UX_DEVICE_CLASS_DPUMP_PACKET_SIZE);
/* Check the status */
if (status == UX_SUCCESS)
{
/* Obtain the length of the transaction. */
length = transfer_request -> ux_slave_transfer_request_actual_length;
/* Copy the buffer to the target in endpoint. */
_ux_utility_memory_copy(endpoint_in -> ux_slave_endpoint_transfer_request.ux_slave_transfer_request_data_pointer,
endpoint_out -> ux_slave_endpoint_transfer_request.ux_slave_transfer_request_data_pointer,
length);
/* Now we send the packet back to the host. On the endpoint In. */
transfer_request = &endpoint_in -> ux_slave_endpoint_transfer_request;
/* Sends the data payload back to the caller. */
status = _ux_device_stack_transfer_request(transfer_request, length, length);
/* Check error code. */
if (status != UX_SUCCESS)
/* Error trap. */
_ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, status);
}
}
/* We need to suspend ourselves. We will be resumed by the
device enumeration module. */
_ux_utility_thread_suspend(&class -> ux_slave_class_thread);
}
}

View File

@ -0,0 +1,186 @@
/**************************************************************************/
/* */
/* 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 DPUMP Class */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_device_class_dpump.h"
#include "ux_device_stack.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_dpump_write PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function writes to the DPUMP class. */
/* */
/* INPUT */
/* */
/* dpump Address of dpump class */
/* instance */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _ux_utility_memory_copy */
/* _ux_device_stack_transfer_request */
/* */
/* CALLED BY */
/* */
/* ThreadX */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_device_class_dpump_write(UX_SLAVE_CLASS_DPUMP *dpump, UCHAR *buffer,
ULONG requested_length, ULONG *actual_length)
{
UX_SLAVE_ENDPOINT *endpoint;
UX_SLAVE_DEVICE *device;
UX_SLAVE_TRANSFER *transfer_request;
ULONG local_requested_length;
UINT status;
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_CLASS_DPUMP_WRITE, dpump, 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. */
return(UX_CONFIGURATION_HANDLE_UNKNOWN);
}
/* Locate the IN endpoint. */
endpoint = dpump -> ux_slave_class_dpump_bulkin_endpoint;
/* Check endpoint. If NULL, we have not yet received the proper SET_INTERFACE command. */
if (endpoint == UX_NULL)
{
/* Error trap. */
_ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_ENDPOINT_HANDLE_UNKNOWN);
return(UX_ENDPOINT_HANDLE_UNKNOWN);
}
/* We are writing to the IN endpoint. */
transfer_request = &endpoint -> ux_slave_endpoint_transfer_request;
/* Reset the actual length. */
*actual_length = 0;
/* Set return status to SUCCESS to make certain compilers happy. */
status = UX_SUCCESS;
/* Check if we need more transactions. */
while (device -> ux_slave_device_state == UX_DEVICE_CONFIGURED && requested_length != 0)
{
/* Check if we have enough in the local buffer. */
if (requested_length > UX_SLAVE_REQUEST_DATA_MAX_LENGTH)
/* We have too much to transfer. */
local_requested_length = UX_SLAVE_REQUEST_DATA_MAX_LENGTH;
else
/* We can proceed with the demanded length. */
local_requested_length = requested_length;
/* 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,
buffer, local_requested_length);
/* Send the request to the device controller. */
status = _ux_device_stack_transfer_request(transfer_request, local_requested_length, local_requested_length);
/* Check the status */
if (status == UX_SUCCESS)
{
/* Next buffer address. */
buffer += transfer_request -> ux_slave_transfer_request_actual_length;
/* Set the length actually received. */
*actual_length += transfer_request -> ux_slave_transfer_request_actual_length;
/* Decrement what left has to be done. */
requested_length -= transfer_request -> ux_slave_transfer_request_actual_length;
}
else
/* We had an error, abort. */
return(status);
}
/* Check why we got here, either completion or device was extracted. */
if (device -> ux_slave_device_state != UX_DEVICE_CONFIGURED)
{
/* 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)
/* Device must have been extracted. */
return (UX_TRANSFER_NO_ANSWER);
}
else
/* Simply return the last transaction result. */
return(status);
}

View File

@ -0,0 +1,133 @@
/**************************************************************************/
/* */
/* 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 Stack */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_device_stack.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_device_stack_alternate_setting_get PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function gets the alternate setting for a specific interface. */
/* */
/* INPUT */
/* */
/* endpoint Pointer to endpoint */
/* interface_value Interface value */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* _ux_device_stack_transfer_request Process transfer request */
/* */
/* CALLED BY */
/* */
/* Application */
/* Device Stack */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_device_stack_alternate_setting_get(ULONG interface_value)
{
UX_SLAVE_TRANSFER *transfer_request;
UX_SLAVE_INTERFACE *interface;
UX_SLAVE_DEVICE *device;
UX_SLAVE_ENDPOINT *endpoint;
UINT status;
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_STACK_ALTERNATE_SETTING_GET, interface_value, 0, 0, 0, UX_TRACE_DEVICE_STACK_EVENTS, 0, 0)
/* Get the pointer to the device. */
device = &_ux_system_slave -> ux_system_slave_device;
/* If the device was in the configured state, there may be interfaces
attached to the configuration. */
if (device -> ux_slave_device_state == UX_DEVICE_CONFIGURED)
{
/* Obtain the pointer to the first interface attached. */
interface = device -> ux_slave_device_first_interface;
/* Start parsing each interface. */
while (interface != UX_NULL)
{
/* Check if this is the interface we have an inquiry for. */
if (interface -> ux_slave_interface_descriptor.bInterfaceNumber == interface_value)
{
/* Get the control endpoint of the device. */
endpoint = &device -> ux_slave_device_control_endpoint;
/* Get the pointer to the transfer request associated with the endpoint. */
transfer_request = &endpoint -> ux_slave_endpoint_transfer_request;
/* Set the value of the alternate setting in the buffer. */
*transfer_request -> ux_slave_transfer_request_data_pointer =
(UCHAR) interface -> ux_slave_interface_descriptor.bAlternateSetting;
/* Setup the length appropriately. */
transfer_request -> ux_slave_transfer_request_requested_length = 1;
/* Set the phase of the transfer to data out. */
transfer_request -> ux_slave_transfer_request_phase = UX_TRANSFER_PHASE_DATA_OUT;
/* Send the descriptor with the appropriate length to the host. */
status = _ux_device_stack_transfer_request(transfer_request, 1, 1);
/* Return the function status. */
return(status);
}
/* Get the next interface. */
interface = interface -> ux_slave_interface_next_interface;
}
}
/* Return error completion. */
return(UX_ERROR);
}

View File

@ -0,0 +1,408 @@
/**************************************************************************/
/* */
/* 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 Stack */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_device_stack.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_device_stack_alternate_setting_set PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function sets the alternate setting for a specific interface. */
/* The previous interface is unmounted and all the endpoints */
/* associated with the alternate setting are mounted. */
/* */
/* INPUT */
/* */
/* endpoint Pointer to endpoint */
/* interface_value Interface value */
/* alternate_setting_value Alternate setting value */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* (ux_slave_dcd_function) DCD dispatch function */
/* _ux_utility_descriptor_parse Parse descriptor */
/* _ux_device_stack_transfer_all_request_abort */
/* Abort transfer */
/* _ux_utility_memory_copy Copy memory */
/* */
/* CALLED BY */
/* */
/* Application */
/* Device Stack */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_device_stack_alternate_setting_set(ULONG interface_value, ULONG alternate_setting_value)
{
UX_SLAVE_DCD *dcd;
UX_SLAVE_TRANSFER *transfer_request;
UCHAR *device_framework;
ULONG device_framework_length;
ULONG descriptor_length;
UCHAR descriptor_type;
UX_CONFIGURATION_DESCRIPTOR configuration_descriptor;
UX_INTERFACE_DESCRIPTOR interface_descriptor;
UX_SLAVE_DEVICE *device;
UX_SLAVE_ENDPOINT *endpoint;
UX_SLAVE_ENDPOINT *next_endpoint;
UX_SLAVE_INTERFACE *interface;
UX_SLAVE_ENDPOINT *endpoint_link;
ULONG endpoints_pool_number;
UX_SLAVE_CLASS_COMMAND class_command;
UX_SLAVE_CLASS *class;
UINT status;
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_STACK_ALTERNATE_SETTING_SET, interface_value, alternate_setting_value, 0, 0, UX_TRACE_DEVICE_STACK_EVENTS, 0, 0)
/* Get the pointer to the DCD. */
dcd = &_ux_system_slave->ux_system_slave_dcd;
/* We may have multiple configurations! */
device_framework = _ux_system_slave -> ux_system_slave_device_framework;
device_framework_length = _ux_system_slave -> ux_system_slave_device_framework_length;
/* Get the pointer to the device. */
device = &_ux_system_slave -> ux_system_slave_device;
/* Protocol error must be reported when it's unconfigured */
if (device -> ux_slave_device_state != UX_DEVICE_CONFIGURED)
return UX_FUNCTION_NOT_SUPPORTED;
/* Find the current interface. */
interface = device -> ux_slave_device_first_interface;
/* Scan all interfaces if any. */
while (interface != UX_NULL)
{
if (interface -> ux_slave_interface_descriptor.bInterfaceNumber == interface_value)
break;
else
interface = interface -> ux_slave_interface_next_interface;
}
/* We must have found the interface pointer for the interface value
requested by the caller. */
if (interface == UX_NULL)
{
/* Error trap. */
_ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_INTERFACE_HANDLE_UNKNOWN);
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_INTERFACE_HANDLE_UNKNOWN, interface, 0, 0, UX_TRACE_ERRORS, 0, 0)
return(UX_INTERFACE_HANDLE_UNKNOWN);
}
/* If the host is requesting a change of alternate setting to the current one,
we do not need to do any work. */
if (interface -> ux_slave_interface_descriptor.bAlternateSetting == alternate_setting_value)
return(UX_SUCCESS);
/* Parse the device framework and locate a configuration descriptor. */
while (device_framework_length != 0)
{
/* Get the length of the current descriptor. */
descriptor_length = (ULONG) *device_framework;
/* And its length. */
descriptor_type =* (device_framework + 1);
/* Check if this is a configuration descriptor. */
if (descriptor_type == UX_CONFIGURATION_DESCRIPTOR_ITEM)
{
/* Parse the descriptor in something more readable. */
_ux_utility_descriptor_parse(device_framework,
_ux_system_configuration_descriptor_structure,
UX_CONFIGURATION_DESCRIPTOR_ENTRIES,
(UCHAR *) &configuration_descriptor);
/* Now we need to check the configuration value. */
if (configuration_descriptor.bConfigurationValue == device -> ux_slave_device_configuration_selected)
{
/* Limit the search in current configuration descriptor. */
device_framework_length = configuration_descriptor.wTotalLength;
/* We have found the configuration value that was selected by the host
We need to scan all the interface descriptors following this
configuration descriptor and locate the interface for which the alternate
setting must be changed. */
while (device_framework_length != 0)
{
/* Get the length of the current descriptor. */
descriptor_length = (ULONG) *device_framework;
/* And its type. */
descriptor_type = *(device_framework + 1);
/* Check if this is an interface descriptor. */
if (descriptor_type == UX_INTERFACE_DESCRIPTOR_ITEM)
{
/* Parse the descriptor in something more readable. */
_ux_utility_descriptor_parse(device_framework,
_ux_system_interface_descriptor_structure,
UX_INTERFACE_DESCRIPTOR_ENTRIES,
(UCHAR *) &interface_descriptor);
/* Check if this is the interface we are searching. */
if (interface_descriptor.bInterfaceNumber == interface_value &&
interface_descriptor.bAlternateSetting == alternate_setting_value)
{
/* We have found the right interface and alternate setting. Before
we mount all the endpoints for this interface, we need to
unmount the endpoints associated with the previous alternate setting. */
endpoint = interface -> ux_slave_interface_first_endpoint;
while (endpoint != UX_NULL)
{
/* Abort any pending transfer. */
_ux_device_stack_transfer_all_request_abort(endpoint, UX_TRANSFER_BUS_RESET);
/* The device controller must be called to destroy the endpoint. */
dcd -> ux_slave_dcd_function(dcd, UX_DCD_DESTROY_ENDPOINT, (VOID *) endpoint);
/* Get the next endpoint. */
next_endpoint = endpoint -> ux_slave_endpoint_next_endpoint;
/* Free the endpoint. */
endpoint -> ux_slave_endpoint_status = UX_UNUSED;
/* Make sure the endpoint instance is now cleaned up. */
endpoint -> ux_slave_endpoint_state = 0;
endpoint -> ux_slave_endpoint_next_endpoint = UX_NULL;
endpoint -> ux_slave_endpoint_interface = UX_NULL;
endpoint -> ux_slave_endpoint_device = UX_NULL;
/* Now we refresh the endpoint pointer. */
endpoint = next_endpoint;
}
/* Now clear the interface endpoint entry. */
interface -> ux_slave_interface_first_endpoint = UX_NULL;
/* Point beyond the interface descriptor. */
device_framework_length -= (ULONG) *device_framework;
device_framework += (ULONG) *device_framework;
/* Parse the device framework and locate endpoint descriptor(s). */
while (device_framework_length != 0)
{
/* Get the length of the current descriptor. */
descriptor_length = (ULONG) *device_framework;
/* And its type. */
descriptor_type = *(device_framework + 1);
/* Check if this is an endpoint descriptor. */
switch(descriptor_type)
{
case UX_ENDPOINT_DESCRIPTOR_ITEM:
/* Find a free endpoint in the pool and hook it to the
existing interface after it's created by DCD. */
endpoint = device -> ux_slave_device_endpoints_pool;
endpoints_pool_number = device -> ux_slave_device_endpoints_pool_number;
while (endpoints_pool_number != 0)
{
/* Check if this endpoint is free. */
if (endpoint -> ux_slave_endpoint_status == UX_UNUSED)
{
/* Mark this endpoint as used now. */
endpoint -> ux_slave_endpoint_status = UX_USED;
break;
}
/* Try the next endpoint. */
endpoint++;
/* Decrement the number of endpoints to scan from the pool. */
endpoints_pool_number--;
}
/* Did we find a free endpoint ? */
if (endpoints_pool_number == 0)
return(UX_MEMORY_INSUFFICIENT);
/* Parse the descriptor in something more readable. */
_ux_utility_descriptor_parse(device_framework,
_ux_system_endpoint_descriptor_structure,
UX_ENDPOINT_DESCRIPTOR_ENTRIES,
(UCHAR *) &endpoint -> ux_slave_endpoint_descriptor);
/* Now we create a transfer request to accept transfer on this endpoint. */
transfer_request = &endpoint -> ux_slave_endpoint_transfer_request;
/* We store the endpoint in the transfer request as well. */
transfer_request -> ux_slave_transfer_request_endpoint = endpoint;
/* By default the timeout is infinite on request. */
transfer_request -> ux_slave_transfer_request_timeout = UX_WAIT_FOREVER;
/* Attach the interface to the endpoint. */
endpoint -> ux_slave_endpoint_interface = interface;
/* Attach the device to the endpoint. */
endpoint -> ux_slave_endpoint_device = device;
/* Create the endpoint at the DCD level. */
status = dcd -> ux_slave_dcd_function(dcd, UX_DCD_CREATE_ENDPOINT, (VOID *) endpoint);
/* Do a sanity check on endpoint creation. */
if (status != UX_SUCCESS)
{
/* Error was returned, endpoint cannot be created. */
endpoint -> ux_slave_endpoint_status = UX_UNUSED;
return(status);
}
/* Attach this endpoint to the end of the endpoint chain. */
if (interface -> ux_slave_interface_first_endpoint == UX_NULL)
{
interface -> ux_slave_interface_first_endpoint = endpoint;
}
else
{
/* Multiple endpoints exist, so find the end of the chain. */
endpoint_link = interface -> ux_slave_interface_first_endpoint;
while (endpoint_link -> ux_slave_endpoint_next_endpoint != UX_NULL)
endpoint_link = endpoint_link -> ux_slave_endpoint_next_endpoint;
endpoint_link -> ux_slave_endpoint_next_endpoint = endpoint;
}
break;
case UX_CONFIGURATION_DESCRIPTOR_ITEM:
case UX_INTERFACE_DESCRIPTOR_ITEM:
/* We have found a new configuration or interface descriptor, this is the end of the current
interface. The search for the endpoints must be terminated as if it was the end of the
entire descriptor. */
device_framework_length = descriptor_length;
break;
default:
/* We have found another descriptor embedded in the interface. Ignore it. */
break;
}
/* Adjust what is left of the device framework. */
device_framework_length -= descriptor_length;
/* Point to the next descriptor. */
device_framework += descriptor_length;
}
/* The interface descriptor in the current class must be changed to the new alternate setting. */
_ux_utility_memory_copy(&interface -> ux_slave_interface_descriptor, &interface_descriptor, sizeof(UX_INTERFACE_DESCRIPTOR));
/* Get the class for the interface. */
class = _ux_system_slave -> ux_system_slave_interface_class_array[interface -> ux_slave_interface_descriptor.bInterfaceNumber];
/* Check if class driver is available. */
if (class == UX_NULL || class -> ux_slave_class_status == UX_UNUSED)
{
return (UX_NO_CLASS_MATCH);
}
/* The interface attached to this configuration must be changed at the class
level. */
class_command.ux_slave_class_command_request = UX_SLAVE_CLASS_COMMAND_CHANGE;
class_command.ux_slave_class_command_interface = (VOID *) interface;
/* And store it. */
class_command.ux_slave_class_command_class_ptr = class;
/* We can now memorize the interface pointer associated with this class. */
class -> ux_slave_class_interface = interface;
/* We have found a potential candidate. Call this registered class entry function to change the alternate setting. */
status = class -> ux_slave_class_entry_function(&class_command);
/* We are done here. */
return(status);
}
}
/* Adjust what is left of the device framework. */
device_framework_length -= descriptor_length;
/* Point to the next descriptor. */
device_framework += descriptor_length;
}
/* In case alter setting not found, report protocol error. */
break;
}
}
/* Adjust what is left of the device framework. */
device_framework_length -= descriptor_length;
/* Point to the next descriptor. */
device_framework += descriptor_length;
}
/* Return error completion. */
return(UX_ERROR);
}

View File

@ -0,0 +1,151 @@
/**************************************************************************/
/* */
/* 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 Stack */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_device_stack.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_device_stack_class_register PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function registers a slave class to the slave stack. */
/* */
/* Note: The C string of class_name must be NULL-terminated and the */
/* length of it (without the NULL-terminator itself) must be no larger */
/* than UX_MAX_CLASS_NAME_LENGTH. */
/* */
/* INPUT */
/* */
/* class_name Name of class */
/* class_function_entry Class entry function */
/* configuration_number Configuration # for this class*/
/* interface_number Interface # for this class */
/* parameter Parameter specific for class */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* _ux_utility_string_length_check Check C string and return */
/* its length if null-terminated */
/* _ux_utility_memory_copy Memory copy */
/* */
/* CALLED BY */
/* */
/* Application */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_device_stack_class_register(UCHAR *class_name,
UINT (*class_entry_function)(struct UX_SLAVE_CLASS_COMMAND_STRUCT *),
ULONG configuration_number,
ULONG interface_number,
VOID *parameter)
{
UX_SLAVE_CLASS *class;
ULONG class_index;
UINT status;
UX_SLAVE_CLASS_COMMAND command;
UINT class_name_length = 0;
/* Get the length of the class name (exclude null-terminator). */
status = _ux_utility_string_length_check(class_name, &class_name_length, UX_MAX_CLASS_NAME_LENGTH);
if (status)
return(status);
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_STACK_CLASS_REGISTER, class_name, interface_number, parameter, 0, UX_TRACE_DEVICE_STACK_EVENTS, 0, 0)
/* We need to parse the class table to find an empty spot. */
class = _ux_system_slave -> ux_system_slave_class_array;
for (class_index = 0; class_index < _ux_system_slave -> ux_system_slave_max_class; class_index++)
{
/* Check if this class is already used. */
if (class -> ux_slave_class_status == UX_UNUSED)
{
/* We have found a free container for the class. Copy the name (with null-terminator). */
_ux_utility_memory_copy(class -> ux_slave_class_name, class_name, class_name_length + 1);
/* Memorize the entry function of this class. */
class -> ux_slave_class_entry_function = class_entry_function;
/* Memorize the pointer to the application parameter. */
class -> ux_slave_class_interface_parameter = parameter;
/* Memorize the configuration number on which this instance will be called. */
class -> ux_slave_class_configuration_number = configuration_number;
/* Memorize the interface number on which this instance will be called. */
class -> ux_slave_class_interface_number = interface_number;
/* Build all the fields of the Class Command to initialize the class. */
command.ux_slave_class_command_request = UX_SLAVE_CLASS_COMMAND_INITIALIZE;
command.ux_slave_class_command_parameter = parameter;
command.ux_slave_class_command_class_ptr = class;
/* Call the class initialization routine. */
status = class_entry_function(&command);
/* Check the status. */
if (status != UX_SUCCESS)
return(status);
/* Make this class used now. */
class -> ux_slave_class_status = UX_USED;
/* Return successful completion. */
return(UX_SUCCESS);
}
/* Move to the next class. */
class++;
}
/* No more entries in the class table. */
return(UX_MEMORY_INSUFFICIENT);
}

View File

@ -0,0 +1,137 @@
/**************************************************************************/
/* */
/* 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 Stack */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_device_stack.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_device_stack_class_unregister PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function unregisters a slave class to the slave stack. */
/* */
/* Note: The C string of class_name must be NULL-terminated and the */
/* length of it (without the NULL-terminator itself) must be no larger */
/* than UX_MAX_CLASS_NAME_LENGTH. */
/* */
/* INPUT */
/* */
/* class_name Name of class */
/* class_function_entry Class entry function */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* _ux_utility_string_length_check Check C string and return */
/* its length if null-terminated */
/* _ux_utility_memory_compare Memory compare */
/* */
/* CALLED BY */
/* */
/* Application */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_device_stack_class_unregister(UCHAR *class_name,
UINT (*class_entry_function)(struct UX_SLAVE_CLASS_COMMAND_STRUCT *))
{
UX_SLAVE_CLASS *class;
ULONG class_index;
UINT status;
UX_SLAVE_CLASS_COMMAND command;
UINT class_name_length = 0;
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_STACK_CLASS_UNREGISTER, class_name, 0, 0, 0, UX_TRACE_DEVICE_STACK_EVENTS, 0, 0)
/* Get the length of the class name (exclude null-terminator). */
status = _ux_utility_string_length_check(class_name, &class_name_length, UX_MAX_CLASS_NAME_LENGTH);
if (status)
return(status);
/* We need to parse the class table to find the right class. */
class = _ux_system_slave -> ux_system_slave_class_array;
for (class_index = 0; class_index < _ux_system_slave -> ux_system_slave_max_class; class_index++)
{
/* Check if this class is the right one. */
if (class -> ux_slave_class_status == UX_USED)
{
/* We have found a used container with a class. Compare the name (include null-terminator). */
if (_ux_utility_memory_compare(class -> ux_slave_class_name, class_name, class_name_length + 1) == UX_SUCCESS)
{
/* Build all the fields of the Class Command to uninitialize the class. */
command.ux_slave_class_command_request = UX_SLAVE_CLASS_COMMAND_UNINITIALIZE;
command.ux_slave_class_command_class_ptr = class;
/* Call the class uninitialization routine. */
status = class_entry_function(&command);
/* Check the status. */
if (status != UX_SUCCESS)
return(status);
/* Make this class unused now. */
class -> ux_slave_class_status = UX_UNUSED;
/* Erase the instance of the class. */
class -> ux_slave_class_instance = UX_NULL;
/* Return successful completion. */
return(UX_SUCCESS);
}
}
/* Move to the next class. */
class++;
}
/* No class match. */
return(UX_NO_CLASS_MATCH);
}

View File

@ -0,0 +1,175 @@
/**************************************************************************/
/* */
/* 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 Stack */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_device_stack.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_device_stack_clear_feature PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function clears a specific feature (Device, Interface, */
/* Endpoint ....). */
/* */
/* INPUT */
/* */
/* request_type Request type */
/* request_value Request value */
/* request_index Request index */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* (ux_slave_dcd_function) DCD dispatch function */
/* */
/* CALLED BY */
/* */
/* Device Stack */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_device_stack_clear_feature(ULONG request_type, ULONG request_value, ULONG request_index)
{
UX_SLAVE_DCD *dcd;
UX_SLAVE_DEVICE *device;
UX_SLAVE_INTERFACE *interface;
UX_SLAVE_ENDPOINT *endpoint;
UX_SLAVE_ENDPOINT *endpoint_target;
UX_PARAMETER_NOT_USED(request_value);
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_STACK_CLEAR_FEATURE, request_type, request_value, request_index, 0, UX_TRACE_DEVICE_STACK_EVENTS, 0, 0)
/* Get the pointer to the DCD. */
dcd = &_ux_system_slave -> ux_system_slave_dcd;
/* Get the pointer to the device. */
device = &_ux_system_slave -> ux_system_slave_device;
/* Get the control endpoint for the device. */
endpoint = &device -> ux_slave_device_control_endpoint;
/* The request can be for either the device or the endpoint. */
switch (request_type & UX_REQUEST_TARGET)
{
case UX_REQUEST_TARGET_DEVICE:
/* Check if we have a DEVICE_REMOTE_WAKEUP Feature. */
if (request_value == UX_REQUEST_FEATURE_DEVICE_REMOTE_WAKEUP)
{
/* Check if we have the capability. */
if (_ux_system_slave -> ux_system_slave_remote_wakeup_capability)
{
/* Disable the feature. */
_ux_system_slave -> ux_system_slave_remote_wakeup_enabled = UX_FALSE;
}
else
/* Protocol error. */
return (UX_FUNCTION_NOT_SUPPORTED);
}
break;
case UX_REQUEST_TARGET_ENDPOINT:
/* The only clear feature for endpoint is ENDPOINT_STALL. This clears
the endpoint of the stall situation and resets its data toggle.
We need to find the endpoint through the interface(s). */
interface = device -> ux_slave_device_first_interface;
while (interface != UX_NULL)
{
/* Get the first endpoint for this interface. */
endpoint_target = interface -> ux_slave_interface_first_endpoint;
/* Parse all the endpoints. */
while (endpoint_target != UX_NULL)
{
/* Check the endpoint index. */
if (endpoint_target -> ux_slave_endpoint_descriptor.bEndpointAddress == request_index)
{
/* Reset the endpoint. */
dcd -> ux_slave_dcd_function(dcd, UX_DCD_RESET_ENDPOINT, endpoint_target);
/* Mark its state now. */
endpoint_target -> ux_slave_endpoint_state = UX_ENDPOINT_RESET;
/* Return the function status. */
return(UX_SUCCESS);
}
/* Next endpoint. */
endpoint_target = endpoint_target -> ux_slave_endpoint_next_endpoint;
}
/* Next interface. */
interface = interface -> ux_slave_interface_next_interface;
}
/* Intentional fallthrough and go into the default case. */
/* fall through */
/* We get here when the endpoint is wrong. Should not happen though. */
default:
/* We stall the command. */
dcd -> ux_slave_dcd_function(dcd, UX_DCD_STALL_ENDPOINT, endpoint);
/* No more work to do here. The command failed but the upper layer does not depend on it. */
return(UX_SUCCESS);
}
/* Return the function status. */
return(UX_SUCCESS);
}

View File

@ -0,0 +1,103 @@
/**************************************************************************/
/* */
/* 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 Stack */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_device_stack.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_device_stack_configuration_get PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function gets the current configuration for the device. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* _ux_device_stack_transfer_request Transfer request */
/* */
/* CALLED BY */
/* */
/* Application */
/* Device Stack */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_device_stack_configuration_get(VOID)
{
UX_SLAVE_TRANSFER *transfer_request;
UX_SLAVE_DEVICE *device;
UX_SLAVE_ENDPOINT *endpoint;
UINT status;
/* Get the pointer to the device. */
device = &_ux_system_slave -> ux_system_slave_device;
/* Get the control endpoint for the device. */
endpoint = &device -> ux_slave_device_control_endpoint;
/* Get the pointer to the transfer request associated with the endpoint. */
transfer_request = &endpoint -> ux_slave_endpoint_transfer_request;
/* Set the value of the configuration in the buffer. */
*transfer_request -> ux_slave_transfer_request_data_pointer =
(UCHAR) device -> ux_slave_device_configuration_selected;
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_STACK_CONFIGURATION_GET, device -> ux_slave_device_configuration_selected, 0, 0, 0, UX_TRACE_DEVICE_STACK_EVENTS, 0, 0)
/* Set the phase of the transfer to data out. */
transfer_request -> ux_slave_transfer_request_phase = UX_TRANSFER_PHASE_DATA_OUT;
/* Send the descriptor with the appropriate length to the host. */
status = _ux_device_stack_transfer_request(transfer_request, 1, 1);
/* Return the function status. */
return(status);
}

View File

@ -0,0 +1,374 @@
/**************************************************************************/
/* */
/* 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 Stack */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_device_stack.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_device_stack_configuration_set PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function sets the configuration from the host and will enable */
/* the default alternate setting 0 for all the interfaces attached to */
/* this configuration. */
/* */
/* INPUT */
/* */
/* endpoint Pointer to endpoint */
/* configuration_value Configuration selected */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* (ux_slave_class_entry_function) Device class entry function */
/* (ux_slave_dcd_function) DCD dispatch function */
/* _ux_device_stack_interface_delete Delete interface */
/* _ux_device_stack_interface_set Set interface */
/* _ux_utility_descriptor_parse Parse descriptor */
/* */
/* CALLED BY */
/* */
/* Application */
/* Device Stack */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_device_stack_configuration_set(ULONG configuration_value)
{
UX_SLAVE_DCD *dcd;
UCHAR * device_framework;
ULONG device_framework_length;
ULONG descriptor_length;
UCHAR descriptor_type;
UX_CONFIGURATION_DESCRIPTOR configuration_descriptor = { 0 };
UX_INTERFACE_DESCRIPTOR interface_descriptor;
UX_SLAVE_INTERFACE *interface;
UX_SLAVE_INTERFACE *next_interface;
UX_SLAVE_CLASS *class;
UX_SLAVE_CLASS *current_class = UX_NULL;
UX_SLAVE_CLASS_COMMAND class_command;
UX_SLAVE_DEVICE *device;
ULONG iad_flag;
ULONG iad_first_interface = 0;
ULONG iad_number_interfaces = 0;
ULONG class_index;
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_STACK_CONFIGURATION_SET, configuration_value, 0, 0, 0, UX_TRACE_DEVICE_STACK_EVENTS, 0, 0)
/* Get the pointer to the DCD. */
dcd = &_ux_system_slave -> ux_system_slave_dcd;
/* Get the pointer to the device. */
device = &_ux_system_slave -> ux_system_slave_device;
/* Reset the IAD flag. */
iad_flag = UX_FALSE;
/* If the configuration value is already selected, keep it. */
if (device -> ux_slave_device_configuration_selected == configuration_value)
return(UX_SUCCESS);
/* We may have multiple configurations !, the index will tell us what
configuration descriptor we need to return. */
device_framework = _ux_system_slave -> ux_system_slave_device_framework;
device_framework_length = _ux_system_slave -> ux_system_slave_device_framework_length;
/* Parse the device framework and locate a configuration descriptor. */
while (device_framework_length != 0)
{
/* Get the length of the current descriptor. */
descriptor_length = (ULONG) *device_framework;
/* And its type. */
descriptor_type = *(device_framework + 1);
/* Check if this is a configuration descriptor. */
if (descriptor_type == UX_CONFIGURATION_DESCRIPTOR_ITEM)
{
/* Parse the descriptor in something more readable. */
_ux_utility_descriptor_parse(device_framework,
_ux_system_configuration_descriptor_structure,
UX_CONFIGURATION_DESCRIPTOR_ENTRIES,
(UCHAR *) &configuration_descriptor);
/* Now we need to check the configuration value. It has
to be the same as the one specified in the setup function. */
if (configuration_descriptor.bConfigurationValue == configuration_value)
/* The configuration is found. */
break;
}
/* Adjust what is left of the device framework. */
device_framework_length -= descriptor_length;
/* Point to the next descriptor. */
device_framework += descriptor_length;
}
/* Configuration not found. */
if (device_framework_length == 0 && configuration_value != 0)
return(UX_ERROR);
/* We unmount the configuration if there is previous configuration selected. */
if (device -> ux_slave_device_configuration_selected)
{
/* Get the pointer to the first interface. */
interface = device -> ux_slave_device_first_interface;
/* Deactivate all the interfaces if any. */
while (interface != UX_NULL)
{
/* Build all the fields of the Class Command. */
class_command.ux_slave_class_command_request = UX_SLAVE_CLASS_COMMAND_DEACTIVATE;
class_command.ux_slave_class_command_interface = (VOID *) interface;
/* Get the pointer to the class container of this interface. */
class = interface -> ux_slave_interface_class;
/* Store the class container. */
class_command.ux_slave_class_command_class_ptr = class;
/* If there is a class container for this instance, deactivate it. */
if (class != UX_NULL)
/* Call the class with the DEACTIVATE signal. */
class -> ux_slave_class_entry_function(&class_command);
/* Get the next interface. */
next_interface = interface -> ux_slave_interface_next_interface;
/* Remove the interface and all endpoints associated with it. */
_ux_device_stack_interface_delete(interface);
/* Now we refresh the interface pointer. */
interface = next_interface;
}
}
/* No configuration is selected. */
device -> ux_slave_device_configuration_selected = 0;
/* Mark the device as attached now. */
device -> ux_slave_device_state = UX_DEVICE_ATTACHED;
/* The DCD needs to update the device state too. */
dcd -> ux_slave_dcd_function(dcd, UX_DCD_CHANGE_STATE, (VOID *) UX_DEVICE_ATTACHED);
/* If the host tries to unconfigure, we are done. */
if (configuration_value == 0)
return(UX_SUCCESS);
/* Memorize the configuration selected. */
device -> ux_slave_device_configuration_selected = configuration_value;
/* We have found the configuration value requested by the host.
Create the configuration descriptor and attach it to the device. */
_ux_utility_descriptor_parse(device_framework,
_ux_system_configuration_descriptor_structure,
UX_CONFIGURATION_DESCRIPTOR_ENTRIES,
(UCHAR *) &device -> ux_slave_device_configuration_descriptor);
/* Configuration character D6 is for Self-powered */
_ux_system_slave -> ux_system_slave_power_state = (configuration_descriptor.bmAttributes & 0x40) ? UX_DEVICE_SELF_POWERED : UX_DEVICE_BUS_POWERED;
/* Configuration character D5 is for Remote Wakeup */
_ux_system_slave -> ux_system_slave_remote_wakeup_capability = (configuration_descriptor.bmAttributes & 0x20) ? UX_TRUE : UX_FALSE;
/* Search only in current configuration */
device_framework_length = configuration_descriptor.wTotalLength;
/* We need to scan all the interface descriptors following this
configuration descriptor and enable all endpoints associated
with the default alternate setting of each interface. */
while (device_framework_length != 0)
{
/* Get the length of the current descriptor. */
descriptor_length = (ULONG) *device_framework;
/* And its type. */
descriptor_type = *(device_framework + 1);
/* Check if this is an interface association descriptor. */
if(descriptor_type == UX_INTERFACE_ASSOCIATION_DESCRIPTOR_ITEM)
{
/* Set the IAD flag. */
iad_flag = UX_TRUE;
/* Get the first interface we have in the IAD. */
iad_first_interface = (ULONG) *(device_framework + 2);
/* Get the number of interfaces we have in the IAD. */
iad_number_interfaces = (ULONG) *(device_framework + 3);
}
/* Check if this is an interface descriptor. */
if(descriptor_type == UX_INTERFACE_DESCRIPTOR_ITEM)
{
/* Parse the descriptor in something more readable. */
_ux_utility_descriptor_parse(device_framework,
_ux_system_interface_descriptor_structure,
UX_INTERFACE_DESCRIPTOR_ENTRIES,
(UCHAR *) &interface_descriptor);
/* If the alternate setting is 0 for this interface, we need to
memorize its class association and start it. */
if (interface_descriptor.bAlternateSetting == 0)
{
/* Are we in a IAD scenario ? */
if (iad_flag == UX_TRUE)
{
/* Check if this is the first interface from the IAD. In this case,
we need to match a class to this interface. */
if (interface_descriptor.bInterfaceNumber == iad_first_interface)
{
/* First interface. Scan the list of classes to find a match. */
class = _ux_system_slave -> ux_system_slave_class_array;
/* Parse all the class drivers. */
for (class_index = 0; class_index < _ux_system_slave -> ux_system_slave_max_class; class_index++)
{
/* Check if this class driver is used. */
if (class -> ux_slave_class_status == UX_USED)
{
/* Check if this is the same interface for the same configuration. */
if ((interface_descriptor.bInterfaceNumber == class -> ux_slave_class_interface_number) &&
(configuration_value == class -> ux_slave_class_configuration_number))
{
/* Memorize the class in the class/interface array. */
_ux_system_slave -> ux_system_slave_interface_class_array[interface_descriptor.bInterfaceNumber] = class;
/* And again as the current class. */
current_class = class;
/* We are done here. */
break;
}
}
/* Move to the next registered class. */
class++;
}
}
else
/* Memorize the class in the class/interface array. We use the current class. */
_ux_system_slave -> ux_system_slave_interface_class_array[interface_descriptor.bInterfaceNumber] = current_class;
/* Decrement the number of interfaces found in the same IAD. */
iad_number_interfaces--;
/* If none are left, get out of the IAD state machine. */
if (iad_number_interfaces == 0)
/* We have exhausted the interfaces within the IAD. */
iad_flag = UX_FALSE;
}
else
{
/* First interface. Scan the list of classes to find a match. */
class = _ux_system_slave -> ux_system_slave_class_array;
/* Parse all the class drivers. */
for (class_index = 0; class_index < _ux_system_slave -> ux_system_slave_max_class; class_index++)
{
/* Check if this class driver is used. */
if (class -> ux_slave_class_status == UX_USED)
{
/* Check if this is the same interface for the same configuration. */
if ((interface_descriptor.bInterfaceNumber == class -> ux_slave_class_interface_number) &&
(configuration_value == class -> ux_slave_class_configuration_number))
{
/* Memorize the class in the class/interface array. */
_ux_system_slave -> ux_system_slave_interface_class_array[interface_descriptor.bInterfaceNumber] = class;
/* We are done here. */
break;
}
}
/* Move to the next registered class. */
class++;
}
}
/* Set the interface. */
_ux_device_stack_interface_set(device_framework, device_framework_length, 0);
}
}
/* Adjust what is left of the device framework. */
device_framework_length -= descriptor_length;
/* Point to the next descriptor. */
device_framework += descriptor_length;
}
/* Mark the device as configured now. */
device -> ux_slave_device_state = UX_DEVICE_CONFIGURED;
/* The DCD needs to update the device state too. */
dcd -> ux_slave_dcd_function(dcd, UX_DCD_CHANGE_STATE, (VOID *) UX_DEVICE_CONFIGURED);
/* Configuration mounted. */
return(UX_SUCCESS);
}

View File

@ -0,0 +1,312 @@
/**************************************************************************/
/* */
/* 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 Stack */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_device_stack.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_device_stack_control_request_process PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function is called by the DCD when the device has received a */
/* SETUP packet. */
/* */
/* INPUT */
/* */
/* transfer_request Pointer to transfer request */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* (ux_slave_class_entry_function) Device class entry function */
/* (ux_slave_dcd_function) DCD dispatch function */
/* _ux_device_stack_transfer_request Transfer request */
/* _ux_device_stack_endpoint_stall Stall endpoint */
/* _ux_device_stack_alternate_setting_get */
/* Get alternate settings */
/* _ux_device_stack_alternate_setting_set */
/* Set alternate settings */
/* _ux_device_stack_clear_feature Clear feature */
/* _ux_device_stack_configuration_get Get configuration */
/* _ux_device_stack_configuration_set Set configuration */
/* _ux_device_stack_descriptor_send Send descriptor */
/* _ux_device_stack_get_status Get status */
/* _ux_device_stack_set_feature Set feature */
/* _ux_utility_short_get Get short value */
/* */
/* CALLED BY */
/* */
/* Device Stack */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_device_stack_control_request_process(UX_SLAVE_TRANSFER *transfer_request)
{
UX_SLAVE_DCD *dcd;
UX_SLAVE_DEVICE *device;
UX_SLAVE_CLASS *class;
UX_SLAVE_CLASS_COMMAND class_command;
ULONG request_type;
ULONG request;
ULONG request_value;
ULONG request_index;
ULONG request_length;
ULONG class_index;
UINT status = UX_ERROR;
UX_SLAVE_ENDPOINT *endpoint;
ULONG application_data_length;
/* Get the pointer to the DCD. */
dcd = &_ux_system_slave -> ux_system_slave_dcd;
/* Get the pointer to the device. */
device = &_ux_system_slave -> ux_system_slave_device;
/* Ensure that the Setup request has been received correctly. */
if (transfer_request -> ux_slave_transfer_request_completion_code == UX_SUCCESS)
{
/* Seems so far, the Setup request is valid. Extract all fields of
the request. */
request_type = *transfer_request -> ux_slave_transfer_request_setup;
request = *(transfer_request -> ux_slave_transfer_request_setup + UX_SETUP_REQUEST);
request_value = _ux_utility_short_get(transfer_request -> ux_slave_transfer_request_setup + UX_SETUP_VALUE);
request_index = _ux_utility_short_get(transfer_request -> ux_slave_transfer_request_setup + UX_SETUP_INDEX);
request_length = _ux_utility_short_get(transfer_request -> ux_slave_transfer_request_setup + UX_SETUP_LENGTH);
/* Filter for GET_DESCRIPTOR/SET_DESCRIPTOR commands. If the descriptor to be returned is not a standard descriptor,
treat the command as a CLASS command. */
if ((request == UX_GET_DESCRIPTOR || request == UX_SET_DESCRIPTOR) && (((request_value >> 8) & UX_REQUEST_TYPE) != UX_REQUEST_TYPE_STANDARD))
{
/* This request is to be handled by the class layer. */
request_type &= (UINT)~UX_REQUEST_TYPE;
request_type |= UX_REQUEST_TYPE_CLASS;
}
/* Check if there is a vendor registered function at the application layer. If the request
is VENDOR and the request match, pass the request to the application. */
if ((request_type & UX_REQUEST_TYPE) == UX_REQUEST_TYPE_VENDOR)
{
/* Check the request demanded and compare it to the application registered one. */
if (request == _ux_system_slave -> ux_system_slave_device_vendor_request)
{
/* This is a Microsoft extended function. It happens before the device is configured.
The request is passed to the application directly. */
status = _ux_system_slave -> ux_system_slave_device_vendor_request_function(request, request_value,
request_index, request_length,
transfer_request -> ux_slave_transfer_request_data_pointer,
&application_data_length);
/* Check the status from the application. */
if (status == UX_SUCCESS)
{
/* Get the control endpoint associated with the device. */
endpoint = &device -> ux_slave_device_control_endpoint;
/* Get the pointer to the transfer request associated with the control endpoint. */
transfer_request = &endpoint -> ux_slave_endpoint_transfer_request;
/* Set the direction to OUT. */
transfer_request -> ux_slave_transfer_request_phase = UX_TRANSFER_PHASE_DATA_OUT;
/* Perform the data transfer. */
_ux_device_stack_transfer_request(transfer_request, request_length, application_data_length);
/* We are done here. */
return(UX_SUCCESS);
}
else
{
/* The application did not like the vendor command format, stall the control endpoint. */
_ux_device_stack_endpoint_stall(&device -> ux_slave_device_control_endpoint);
/* We are done here. */
return(UX_SUCCESS);
}
}
}
/* Check the destination of the request. If the request is of type CLASS or VENDOR_SPECIFIC,
the function has to be passed to the class layer. */
if (((request_type & UX_REQUEST_TYPE) == UX_REQUEST_TYPE_CLASS) ||
((request_type & UX_REQUEST_TYPE) == UX_REQUEST_TYPE_VENDOR))
{
/* Build all the fields of the Class Command. */
class_command.ux_slave_class_command_request = UX_SLAVE_CLASS_COMMAND_REQUEST;
/* We need to find which class this request is for. */
for (class_index = 0; class_index < UX_MAX_SLAVE_INTERFACES; class_index ++)
{
/* Is the request target to an interface? */
if ((request_type & UX_REQUEST_TARGET) == UX_REQUEST_TARGET_INTERFACE)
{
/* Yes, so the request index contains the index of the interface
the request is for. So if the current index does not match
the request index, we should go to the next one. */
if ((request_index & 0xFF) != class_index)
continue;
}
/* Get the class for the interface. */
class = _ux_system_slave -> ux_system_slave_interface_class_array[class_index];
/* If class is not ready, try next. */
if (class == UX_NULL)
continue;
/* Memorize the class in the command. */
class_command.ux_slave_class_command_class_ptr = class;
/* We have found a potential candidate. Call this registered class entry function. */
status = class -> ux_slave_class_entry_function(&class_command);
/* The status simply tells us if the registered class handled the
command - if there was an issue processing the command, it would've
stalled the control endpoint, notifying the host (and not us). */
if (status == UX_SUCCESS)
/* We are done, break the loop! */
break;
/* Not handled, try next. */
}
/* If no class handled the command, then we have an error here. */
if (status != UX_SUCCESS)
/* We stall the command (request not supported). */
_ux_device_stack_endpoint_stall(&device -> ux_slave_device_control_endpoint);
/* We are done for class/vendor request. */
return(status);
}
/* At this point, the request must be a standard request that the device stack should handle. */
switch (request)
{
case UX_GET_STATUS:
status = _ux_device_stack_get_status(request_type, request_index, request_length);
break;
case UX_CLEAR_FEATURE:
status = _ux_device_stack_clear_feature(request_type, request_value, request_index);
break;
case UX_SET_FEATURE:
status = _ux_device_stack_set_feature(request_type, request_value, request_index);
break;
case UX_SET_ADDRESS:
/* Memorize the address. Some controllers memorize the address here. Some don't. */
dcd -> ux_slave_dcd_device_address = request_value;
/* Force the new address. */
status = dcd -> ux_slave_dcd_function(dcd, UX_DCD_SET_DEVICE_ADDRESS, (VOID *) (ALIGN_TYPE) request_value);
break;
case UX_GET_DESCRIPTOR:
status = _ux_device_stack_descriptor_send(request_value, request_index, request_length);
break;
case UX_SET_DESCRIPTOR:
status = UX_FUNCTION_NOT_SUPPORTED;
break;
case UX_GET_CONFIGURATION:
status = _ux_device_stack_configuration_get();
break;
case UX_SET_CONFIGURATION:
status = _ux_device_stack_configuration_set(request_value);
break;
case UX_GET_INTERFACE:
status = _ux_device_stack_alternate_setting_get(request_index);
break;
case UX_SET_INTERFACE:
status = _ux_device_stack_alternate_setting_set(request_index,request_value);
break;
case UX_SYNCH_FRAME:
status = UX_SUCCESS;
break;
default :
status = UX_FUNCTION_NOT_SUPPORTED;
break;
}
if (status != UX_SUCCESS)
/* Stall the control endpoint to issue protocol error. */
_ux_device_stack_endpoint_stall(&device -> ux_slave_device_control_endpoint);
}
/* Return the function status. */
return(status);
}

View File

@ -0,0 +1,544 @@
/**************************************************************************/
/* */
/* 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 Stack */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_device_stack.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_device_stack_descriptor_send PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function sends back the device descriptor required by the host.*/
/* */
/* INPUT */
/* */
/* descriptor_type Descriptor type */
/* descriptor_index Index of descriptor */
/* host_length Length requested by host */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* (ux_slave_dcd_function) DCD dispatch function */
/* _ux_device_stack_transfer_request Process transfer request */
/* _ux_utility_descriptor_parse Parse descriptor */
/* _ux_utility_memory_copy Memory copy */
/* _ux_utility_short_get Get short value */
/* */
/* CALLED BY */
/* */
/* Application */
/* Device Stack */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_device_stack_descriptor_send(ULONG descriptor_type, ULONG request_index, ULONG host_length)
{
UX_SLAVE_DCD *dcd;
UX_SLAVE_DEVICE *device;
ULONG descriptor_index;
ULONG parsed_descriptor_index;
UX_SLAVE_TRANSFER *transfer_request;
UX_CONFIGURATION_DESCRIPTOR configuration_descriptor;
UX_SLAVE_ENDPOINT *endpoint;
UCHAR *device_framework;
UCHAR *device_framework_end;
ULONG device_framework_length;
ULONG descriptor_length;
ULONG configuration_descriptor_length;
UINT status = UX_ERROR;
ULONG length;
UCHAR *string_memory;
UCHAR *string_framework;
ULONG string_framework_length;
ULONG string_length;
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_STACK_DESCRIPTOR_SEND, descriptor_type, request_index, 0, 0, UX_TRACE_DEVICE_STACK_EVENTS, 0, 0)
/* Get the pointer to the DCD. */
dcd = &_ux_system_slave -> ux_system_slave_dcd;
/* Get the pointer to the device. */
device = &_ux_system_slave -> ux_system_slave_device;
/* Get the control endpoint associated with the device. */
endpoint = &device -> ux_slave_device_control_endpoint;
/* Get the pointer to the transfer request associated with the endpoint. */
transfer_request = &endpoint -> ux_slave_endpoint_transfer_request;
/* Set the direction to OUT. */
transfer_request -> ux_slave_transfer_request_phase = UX_TRANSFER_PHASE_DATA_OUT;
/* Isolate the descriptor index. */
descriptor_index = descriptor_type & 0xff;
/* Reset the parsed index. */
parsed_descriptor_index = 0;
/* Shift the descriptor type in the low byte field. */
descriptor_type = (UCHAR) ((descriptor_type >> 8) & 0xff);
/* What type of descriptor do we need to return? */
switch (descriptor_type)
{
case UX_DEVICE_DESCRIPTOR_ITEM:
/* Setup the length appropriately. */
if (host_length > UX_DEVICE_DESCRIPTOR_LENGTH)
length = UX_DEVICE_DESCRIPTOR_LENGTH;
else
length = host_length;
/* Copy the device descriptor into the transfer request memory. */
_ux_utility_memory_copy(transfer_request -> ux_slave_transfer_request_data_pointer,
_ux_system_slave -> ux_system_slave_device_framework, length);
/* Perform the data transfer. */
status = _ux_device_stack_transfer_request(transfer_request, length, host_length);
break;
case UX_DEVICE_QUALIFIER_DESCRIPTOR_ITEM:
/* Setup the length appropriately. */
if (host_length > UX_DEVICE_QUALIFIER_DESCRIPTOR_LENGTH)
length = UX_DEVICE_QUALIFIER_DESCRIPTOR_LENGTH;
else
length = host_length;
/* We may or may not have a device qualifier descriptor. */
device_framework = _ux_system_slave -> ux_system_slave_device_framework;
device_framework_length = _ux_system_slave -> ux_system_slave_device_framework_length;
device_framework_end = device_framework + device_framework_length;
/* Parse the device framework and locate a device qualifier descriptor. */
while (device_framework < device_framework_end)
{
/* Get the type of the current descriptor. */
descriptor_type = *(device_framework + 1);
/* And its length. */
descriptor_length = (ULONG) *device_framework;
/* Check if this is a device qualifier descriptor. */
if (descriptor_type == UX_DEVICE_QUALIFIER_DESCRIPTOR_ITEM)
{
/* Copy the device qualifier descriptor into the transfer request memory. */
_ux_utility_memory_copy(transfer_request -> ux_slave_transfer_request_data_pointer,
device_framework, length);
/* Perform the data transfer. */
status = _ux_device_stack_transfer_request(transfer_request, length, host_length);
break;
}
/* Adjust what is left of the device framework. */
device_framework_length -= descriptor_length;
/* Point to the next descriptor. */
device_framework += descriptor_length;
}
break;
case UX_OTG_DESCRIPTOR_ITEM:
/* Setup the length appropriately. */
if (host_length > UX_OTG_DESCRIPTOR_LENGTH)
length = UX_OTG_DESCRIPTOR_LENGTH;
else
length = host_length;
/* We may or may not have a OTG descriptor. */
device_framework = _ux_system_slave -> ux_system_slave_device_framework;
device_framework_length = _ux_system_slave -> ux_system_slave_device_framework_length;
device_framework_end = device_framework + device_framework_length;
/* Parse the device framework and locate a OTG descriptor. */
while (device_framework < device_framework_end)
{
/* Get the type of the current descriptor. */
descriptor_type = *(device_framework + 1);
/* And its length. */
descriptor_length = (ULONG) *device_framework;
/* Check if this is a OTG descriptor. */
if (descriptor_type == UX_OTG_DESCRIPTOR_ITEM)
{
/* Copy the device OTG descriptor into the transfer request memory. */
_ux_utility_memory_copy(transfer_request -> ux_slave_transfer_request_data_pointer,
device_framework, length);
/* Perform the data transfer. */
status = _ux_device_stack_transfer_request(transfer_request, length, host_length);
break;
}
/* Adjust what is left of the device framework. */
device_framework_length -= descriptor_length;
/* Point to the next descriptor. */
device_framework += descriptor_length;
}
break;
case UX_OTHER_SPEED_DESCRIPTOR_ITEM:
/* This request is used by the host to find out the capability of this device
if it was running at full speed. The behavior is the same as in a GET_CONFIGURATIOn descriptor
but we do not use the current device framework but rather the full speed framework. */
device_framework = _ux_system_slave -> ux_system_slave_device_framework_full_speed;
device_framework_length = _ux_system_slave -> ux_system_slave_device_framework_length_full_speed;
device_framework_end = device_framework + device_framework_length;
/* Parse the device framework and locate a configuration descriptor. */
while (device_framework < device_framework_end)
{
/* Get the type of the current descriptor. */
descriptor_type = *(device_framework + 1);
/* And its length. */
descriptor_length = (ULONG) *device_framework;
/* Check if this is a configuration descriptor. We are cheating here. Instead of creating
a OTHER SPEED descriptor, we simply scan the configuration descriptor for the Full Speed
framework and return this configuration after we manually changed the configuration descriptor
item into a Other Speed Descriptor. */
if (descriptor_type == UX_CONFIGURATION_DESCRIPTOR_ITEM)
{
/* Check the index. It must be the same as the one requested. */
if (parsed_descriptor_index == descriptor_index)
{
/* Parse the configuration descriptor. */
_ux_utility_descriptor_parse(device_framework,
_ux_system_configuration_descriptor_structure,
UX_CONFIGURATION_DESCRIPTOR_ENTRIES,
(UCHAR *) &configuration_descriptor);
/* Get the length of entire configuration descriptor. */
configuration_descriptor_length = configuration_descriptor.wTotalLength;
/* Ensure the host does not demand a length beyond our descriptor (Windows does that)
and do not return more than what is allowed. */
if (configuration_descriptor_length < host_length)
length = configuration_descriptor_length;
else
length = host_length;
/* Check buffer length, since total descriptors length may exceed buffer... */
if (length > UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH)
{
/* Error trap. */
_ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_DEVICE_STACK, UX_MEMORY_INSUFFICIENT);
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_MEMORY_INSUFFICIENT, device, 0, 0, UX_TRACE_ERRORS, 0, 0)
/* Stall the endpoint. */
status = dcd -> ux_slave_dcd_function(dcd, UX_DCD_STALL_ENDPOINT, endpoint);
break;
}
/* Copy the device descriptor into the transfer request memory. */
_ux_utility_memory_copy(transfer_request -> ux_slave_transfer_request_data_pointer,
device_framework, length);
/* Now we need to hack the found descriptor because this request expect a OTHER_SPEED
descriptor instead of the regular CONFIGURATION descriptor. */
*(transfer_request -> ux_slave_transfer_request_data_pointer + 1) = UX_OTHER_SPEED_DESCRIPTOR_ITEM;
/* We can return the configuration descriptor. */
status = _ux_device_stack_transfer_request(transfer_request, length, host_length);
break;
}
else
{
/* There may be more configuration descriptors in this framework. */
parsed_descriptor_index++;
}
}
/* Adjust what is left of the device framework. */
device_framework_length -= descriptor_length;
/* Point to the next descriptor. */
device_framework += descriptor_length;
}
break;
case UX_CONFIGURATION_DESCRIPTOR_ITEM:
/* We may have multiple configurations !, the index will tell us what
configuration descriptor we need to return. */
device_framework = _ux_system_slave -> ux_system_slave_device_framework;
device_framework_length = _ux_system_slave -> ux_system_slave_device_framework_length;
device_framework_end = device_framework + device_framework_length;
/* Parse the device framework and locate a configuration descriptor. */
while (device_framework < device_framework_end)
{
/* Get the type of the current descriptor. */
descriptor_type = *(device_framework + 1);
/* And its length. */
descriptor_length = (ULONG) *device_framework;
/* Check if this is a configuration descriptor. */
if (descriptor_type == UX_CONFIGURATION_DESCRIPTOR_ITEM)
{
/* Check the index. It must be the same as the one requested. */
if (parsed_descriptor_index == descriptor_index)
{
/* Parse the configuration descriptor. */
_ux_utility_descriptor_parse(device_framework,
_ux_system_configuration_descriptor_structure,
UX_CONFIGURATION_DESCRIPTOR_ENTRIES,
(UCHAR *) &configuration_descriptor);
/* Get the length of entire configuration descriptor. */
configuration_descriptor_length = configuration_descriptor.wTotalLength;
/* Ensure the host does not demand a length beyond our descriptor (Windows does that)
and do not return more than what is allowed. */
if (configuration_descriptor_length < host_length)
length = configuration_descriptor_length;
else
length = host_length;
/* Check buffer length, since total descriptors length may exceed buffer... */
if (length > UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH)
{
/* Error trap. */
_ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_DEVICE_STACK, UX_MEMORY_INSUFFICIENT);
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_MEMORY_INSUFFICIENT, device, 0, 0, UX_TRACE_ERRORS, 0, 0)
/* Stall the endpoint. */
status = dcd -> ux_slave_dcd_function(dcd, UX_DCD_STALL_ENDPOINT, endpoint);
break;
}
/* Copy the device descriptor into the transfer request memory. */
_ux_utility_memory_copy(transfer_request -> ux_slave_transfer_request_data_pointer,
device_framework, length);
/* We can return the configuration descriptor. */
status = _ux_device_stack_transfer_request(transfer_request, length, host_length);
break;
}
else
{
/* There may be more configuration descriptors in this framework. */
parsed_descriptor_index++;
}
}
/* Adjust what is left of the device framework. */
device_framework_length -= descriptor_length;
/* Point to the next descriptor. */
device_framework += descriptor_length;
}
break;
case UX_STRING_DESCRIPTOR_ITEM:
/* We need to filter for the index 0 which is the language ID string. */
if (descriptor_index == 0)
{
/* We need to check request buffer size in case it's possible exceed. */
if (_ux_system_slave -> ux_system_slave_language_id_framework_length + 2 > UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH)
{
/* Error trap. */
_ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_DEVICE_STACK, UX_MEMORY_INSUFFICIENT);
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_MEMORY_INSUFFICIENT, device, 0, 0, UX_TRACE_ERRORS, 0, 0)
/* Stall the endpoint. */
status = dcd -> ux_slave_dcd_function(dcd, UX_DCD_STALL_ENDPOINT, endpoint);
break;
}
/* We have a request to send back the language ID list. Use the transfer request buffer. */
string_memory = transfer_request -> ux_slave_transfer_request_data_pointer;
/* Store the total length of the response. */
*string_memory = (UCHAR)(_ux_system_slave -> ux_system_slave_language_id_framework_length + 2);
/* Store the descriptor type. */
*(string_memory +1) = UX_STRING_DESCRIPTOR_ITEM;
/* Store the language ID into the buffer. */
_ux_utility_memory_copy(string_memory+2, _ux_system_slave -> ux_system_slave_language_id_framework,
_ux_system_slave -> ux_system_slave_language_id_framework_length);
/* Filter the length asked/required. */
if (host_length > _ux_system_slave -> ux_system_slave_language_id_framework_length + 2)
length = _ux_system_slave -> ux_system_slave_language_id_framework_length + 2;
else
length = host_length;
/* We can return the string language ID descriptor. */
status = _ux_device_stack_transfer_request(transfer_request, length, host_length);
}
else
{
/* The host wants a specific string index returned. Get the string framework pointer
and length. */
string_framework = _ux_system_slave -> ux_system_slave_string_framework;
string_framework_length = _ux_system_slave -> ux_system_slave_string_framework_length;
/* We search through the string framework until we find the right index.
The index is in the lower byte of the descriptor type. */
while (string_framework_length != 0)
{
/* Ensure we have the correct language page. */
if (_ux_utility_short_get(string_framework) == request_index)
{
/* Check the index. */
if (*(string_framework + 2) == descriptor_index)
{
/* We need to check request buffer size in case it's possible exceed. */
if (((*(string_framework + 3)*2) + 2) > UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH)
{
/* Error trap. */
_ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_DEVICE_STACK, UX_MEMORY_INSUFFICIENT);
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_MEMORY_INSUFFICIENT, device, 0, 0, UX_TRACE_ERRORS, 0, 0)
/* Stall the endpoint. */
status = dcd -> ux_slave_dcd_function(dcd, UX_DCD_STALL_ENDPOINT, endpoint);
break;
}
/* We have a request to send back a string. Use the transfer request buffer. */
string_memory = transfer_request -> ux_slave_transfer_request_data_pointer;
/* Store the length in the string buffer. The length
of the string descriptor is stored in the third byte,
hence the ' + 3'. The encoding must be in 16-bit
unicode, hence the '*2'. The length includes the size
of the length itself as well as the descriptor type,
hence the ' + 2'. */
*string_memory = (UCHAR)((*(string_framework + 3)*2) + 2);
/* Store the Descriptor type. */
*(string_memory + 1) = UX_STRING_DESCRIPTOR_ITEM;
/* Create the Unicode string. */
for (string_length = 0; string_length < *(string_framework + 3) ; string_length ++)
{
/* Insert a Unicode byte. */
*(string_memory + 2 + (string_length * 2)) = *(string_framework + 4 + string_length);
/* Insert a zero after the Unicode byte. */
*(string_memory + 2 + (string_length * 2) + 1) = 0;
}
/* Filter the length asked/required. */
if (host_length > (UINT)((*(string_framework + 3)*2) + 2))
length = (ULONG)((*(string_framework + 3)*2) + 2);
else
length = host_length;
/* We can return the string descriptor. */
status = _ux_device_stack_transfer_request(transfer_request, length, host_length);
break;
}
}
/* This is the wrong string descriptor, jump to the next. */
string_framework_length -= (ULONG) *(string_framework + 3) + 4;
string_framework += (ULONG) *(string_framework + 3) + 4;
}
/* Have we exhausted all the string descriptors? */
if (string_framework_length == 0)
{
/* Could not find the required string index. Stall the endpoint. */
dcd -> ux_slave_dcd_function(dcd, UX_DCD_STALL_ENDPOINT, endpoint);
return(UX_ERROR);
}
}
break;
default:
/* Stall the endpoint. */
dcd -> ux_slave_dcd_function(dcd, UX_DCD_STALL_ENDPOINT, endpoint);
return(UX_ERROR);
}
/* Return the status to the caller. */
return(status);
}

View File

@ -0,0 +1,162 @@
/**************************************************************************/
/* */
/* 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 Stack */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_device_stack.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_device_stack_disconnect PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function is called when the device gets disconnected from the */
/* host. All the device resources are freed. */
/* */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* (ux_slave_class_entry_function) Device class entry function */
/* (ux_slave_dcd_function) DCD dispatch function */
/* _ux_device_stack_interface_delete Delete interface */
/* */
/* CALLED BY */
/* */
/* Application */
/* Device Stack */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_device_stack_disconnect(VOID)
{
UX_SLAVE_DCD *dcd;
UX_SLAVE_DEVICE *device;
UX_SLAVE_INTERFACE *interface;
UX_SLAVE_INTERFACE *next_interface;
UX_SLAVE_CLASS *class;
UX_SLAVE_CLASS_COMMAND class_command;
UINT status = UX_ERROR;
/* Get the pointer to the DCD. */
dcd = &_ux_system_slave -> ux_system_slave_dcd;
/* Get the pointer to the device. */
device = &_ux_system_slave -> ux_system_slave_device;
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_STACK_DISCONNECT, device, 0, 0, 0, UX_TRACE_DEVICE_STACK_EVENTS, 0, 0)
/* If trace is enabled, register this object. */
UX_TRACE_OBJECT_UNREGISTER(device);
/* If the device was in the configured state, there may be interfaces
attached to the configuration. */
if (device -> ux_slave_device_state == UX_DEVICE_CONFIGURED)
{
/* Get the pointer to the first interface. */
interface = device -> ux_slave_device_first_interface;
/* Parse all the interfaces if any. */
while (interface != UX_NULL)
{
/* Build all the fields of the Class Command. */
class_command.ux_slave_class_command_request = UX_SLAVE_CLASS_COMMAND_DEACTIVATE;
class_command.ux_slave_class_command_interface = (VOID *) interface;
/* Get the pointer to the class container of this interface. */
class = interface -> ux_slave_interface_class;
/* Store the class container. */
class_command.ux_slave_class_command_class_ptr = class;
/* If there is a class container for this instance, deactivate it. */
if (class != UX_NULL)
/* Call the class with the DEACTIVATE signal. */
class -> ux_slave_class_entry_function(&class_command);
/* Get the next interface. */
next_interface = interface -> ux_slave_interface_next_interface;
/* Remove the interface and all endpoints associated with it. */
_ux_device_stack_interface_delete(interface);
/* Now we refresh the interface pointer. */
interface = next_interface;
}
/* Mark the device as attached now. */
device -> ux_slave_device_state = UX_DEVICE_ATTACHED;
}
/* If the device was attached, we need to destroy the control endpoint. */
if (device -> ux_slave_device_state == UX_DEVICE_ATTACHED)
/* Now we can destroy the default control endpoint. */
status = dcd -> ux_slave_dcd_function(dcd, UX_DCD_DESTROY_ENDPOINT,
(VOID *) &device -> ux_slave_device_control_endpoint);
/* We are reverting to configuration 0. */
device -> ux_slave_device_configuration_selected = 0;
/* Set the device to be non attached. */
device -> ux_slave_device_state = UX_DEVICE_RESET;
/* Check the status change callback. */
if(_ux_system_slave -> ux_system_slave_change_function != UX_NULL)
{
/* Inform the application if a callback function was programmed. */
_ux_system_slave -> ux_system_slave_change_function(UX_DEVICE_REMOVED);
}
/* Return the status to the caller. */
return(status);
}

View File

@ -0,0 +1,110 @@
/**************************************************************************/
/* */
/* 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 Stack */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_device_stack.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_device_stack_endpoint_stall PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function stalls an endpoint. The host will need to reissue */
/* a reset to clear the endpoint. */
/* */
/* INPUT */
/* */
/* endpoint Pointer to endpoint */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* (ux_slave_dcd_function) DCD dispatch function */
/* */
/* CALLED BY */
/* */
/* Application */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_device_stack_endpoint_stall(UX_SLAVE_ENDPOINT *endpoint)
{
TX_INTERRUPT_SAVE_AREA
UX_SLAVE_DCD *dcd;
UINT status;
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_STACK_ENDPOINT_STALL, endpoint, 0, 0, 0, UX_TRACE_DEVICE_STACK_EVENTS, 0, 0)
/* Get the pointer to the DCD. */
dcd = &_ux_system_slave -> ux_system_slave_dcd;
/* Assume device is in an invalid state here in order to reduce code in following
section where interrupts are disabled. */
status = UX_ERROR;
/* Ensure we don't change the endpoint's state after disconnection routine
resets it. */
TX_DISABLE
/* Check if the device is in a valid state; as soon as the device is out
of the RESET state, transfers occur and thus endpoints may be stalled. */
if (_ux_system_slave -> ux_system_slave_device.ux_slave_device_state != UX_DEVICE_RESET)
{
/* Stall the endpoint. */
status = dcd -> ux_slave_dcd_function(dcd, UX_DCD_STALL_ENDPOINT, endpoint);
/* Mark the endpoint state. */
endpoint -> ux_slave_endpoint_state = UX_ENDPOINT_HALTED;
}
/* Restore interrupts. */
TX_RESTORE
/* Return completion status. */
return(status);
}

View File

@ -0,0 +1,184 @@
/**************************************************************************/
/* */
/* 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 Stack */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_device_stack.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_device_stack_get_status PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function obtains the status of a USB component of the device */
/* such as device or endpoint. */
/* */
/* INPUT */
/* */
/* request_type Request type */
/* request_index Request index */
/* request_length Request length */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* _ux_device_stack_transfer_request Transfer request */
/* (ux_slave_dcd_function) DCD dispatch function */
/* */
/* CALLED BY */
/* */
/* Device Stack */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_device_stack_get_status(ULONG request_type, ULONG request_index, ULONG request_length)
{
UX_SLAVE_DCD *dcd;
UX_SLAVE_TRANSFER *transfer_request;
UX_SLAVE_DEVICE *device;
UX_SLAVE_ENDPOINT *endpoint;
UINT status;
ULONG data_length;
UX_PARAMETER_NOT_USED(request_length);
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_STACK_GET_STATUS, request_type, request_index, request_length, 0, UX_TRACE_DEVICE_STACK_EVENTS, 0, 0)
/* Get the pointer to the DCD. */
dcd = &_ux_system_slave -> ux_system_slave_dcd;
/* Get the pointer to the device. */
device = &_ux_system_slave -> ux_system_slave_device;
/* Get the control endpoint for the device. */
endpoint = &device -> ux_slave_device_control_endpoint;
/* Get the pointer to the transfer request associated with the endpoint. */
transfer_request = &endpoint -> ux_slave_endpoint_transfer_request;
/* Reset the status buffer. */
*transfer_request -> ux_slave_transfer_request_data_pointer = 0;
*(transfer_request -> ux_slave_transfer_request_data_pointer + 1) = 0;
/* The default length for GET_STATUS is 2, except for OTG get Status. */
data_length = 2;
/* The status can be for either the device or the endpoint. */
switch (request_type & UX_REQUEST_TARGET)
{
case UX_REQUEST_TARGET_DEVICE:
/* When the device is probed, it is either for the power/remote capabilities or OTG role swap.
We differentiate with the Windex, 0 or OTG status Selector. */
if (request_index == UX_OTG_STATUS_SELECTOR)
{
/* Set the data length to 1. */
data_length = 1;
#ifdef UX_OTG_SUPPORT
/* Store the Role Swap flag. */
*transfer_request -> ux_slave_transfer_request_data_pointer = (UCHAR) _ux_system_otg -> ux_system_otg_slave_role_swap_flag;
#endif
}
else
{
/* Store the current power state in the status buffer. */
if (_ux_system_slave -> ux_system_slave_power_state == UX_DEVICE_SELF_POWERED)
*transfer_request -> ux_slave_transfer_request_data_pointer = 1;
/* Store the remote wakeup capability state in the status buffer. */
if (_ux_system_slave -> ux_system_slave_remote_wakeup_enabled)
*transfer_request -> ux_slave_transfer_request_data_pointer |= 2;
}
break;
case UX_REQUEST_TARGET_ENDPOINT:
/* This feature returns the halt state of a specific endpoint. The endpoint index
is used to retrieve the endpoint container. */
status = dcd -> ux_slave_dcd_function(dcd, UX_DCD_ENDPOINT_STATUS, (VOID *)(ALIGN_TYPE)(request_index & (UINT)~UX_ENDPOINT_DIRECTION));
/* Check the status. We may have a unknown endpoint. */
if (status != UX_ERROR)
{
if (status == UX_TRUE)
*transfer_request -> ux_slave_transfer_request_data_pointer = 1;
}
else
{
/* We stall the command. Endpoint is wrong. */
dcd -> ux_slave_dcd_function(dcd, UX_DCD_STALL_ENDPOINT, endpoint);
/* No more work to do here. The command failed but the upper layer does not depend on it. */
return(UX_SUCCESS);
}
break;
default:
/* We stall the command. */
dcd -> ux_slave_dcd_function(dcd, UX_DCD_STALL_ENDPOINT, endpoint);
/* No more work to do here. The command failed but the upper layer does not depend on it. */
return(UX_SUCCESS);
}
/* Set the phase of the transfer to data out. */
transfer_request -> ux_slave_transfer_request_phase = UX_TRANSFER_PHASE_DATA_OUT;
/* Send the descriptor with the appropriate length to the host. */
status = _ux_device_stack_transfer_request(transfer_request, data_length, data_length);
/* Return the function status. */
return(status);
}

View File

@ -0,0 +1,91 @@
/**************************************************************************/
/* */
/* 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 Stack */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_device_stack.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_device_stack_host_wakeup PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function is called when the device wants to wake up the host. */
/* This command is only valid when the device is in suspend mode. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* (ux_slave_dcd_function) DCD dispatch function */
/* */
/* CALLED BY */
/* */
/* Application */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_device_stack_host_wakeup(VOID)
{
UX_SLAVE_DCD *dcd;
UINT status = UX_FUNCTION_NOT_SUPPORTED;
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_STACK_HOST_WAKEUP, 0, 0, 0, 0, UX_TRACE_DEVICE_STACK_EVENTS, 0, 0)
/* Get the pointer to the DCD. */
dcd = &_ux_system_slave -> ux_system_slave_dcd;
/* Check if DEVICE_REMOTE_WAKEUP feature is enabled. */
if (_ux_system_slave -> ux_system_slave_remote_wakeup_enabled)
/* Send the change signal to the controller driver. */
status = dcd -> ux_slave_dcd_function(dcd, UX_DCD_CHANGE_STATE, (VOID *) UX_DEVICE_REMOTE_WAKEUP);
/* Return the status to the caller. */
return(status);
}

View File

@ -0,0 +1,414 @@
/**************************************************************************/
/* */
/* 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 Stack */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_device_stack.h"
UX_COMPILE_TIME_ASSERT(!UX_OVERFLOW_CHECK_MULC_ULONG(sizeof(UX_SLAVE_CLASS), UX_MAX_SLAVE_CLASS_DRIVER), UX_MAX_SLAVE_CLASS_DRIVER_mul_ovf)
/* Define the names of all the USB Classes of USBX. */
UCHAR _ux_system_slave_class_storage_name[] = "ux_slave_class_storage";
UCHAR _ux_system_slave_class_cdc_acm_name[] = "ux_slave_class_cdc_acm";
UCHAR _ux_system_slave_class_dpump_name[] = "ux_slave_class_dpump";
UCHAR _ux_system_slave_class_pima_name[] = "ux_slave_class_pima";
UCHAR _ux_system_slave_class_hid_name[] = "ux_slave_class_hid";
UCHAR _ux_system_slave_class_rndis_name[] = "ux_slave_class_rndis";
UCHAR _ux_system_slave_class_cdc_ecm_name[] = "ux_slave_class_cdc_ecm";
UCHAR _ux_system_slave_class_dfu_name[] = "ux_slave_class_dfu";
UCHAR _ux_system_slave_class_audio_name[] = "ux_slave_class_audio";
/* Define USBX Host variable. */
UX_SYSTEM_SLAVE *_ux_system_slave;
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_device_stack_initialize PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function initializes the generic portion of the device side of */
/* USBX. */
/* */
/* INPUT */
/* */
/* device_framework_high_speed Pointer to high speed FW */
/* device_framework_length_high_speed Length of high speed FW */
/* device_framework_full_speed Pointer to full speed FW */
/* device_framework_length_full_speed Length of full speed FW */
/* string_framework Pointer to string FW */
/* string_framework_length Length of string FW */
/* language_id_framework Pointer to language ID FW */
/* language_id_framework_length Length of language ID FW */
/* (ux_system_slave_change_function) Pointer to callback function */
/* for device changes */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* _ux_utility_memory_allocate Allocate memory */
/* _ux_utility_memory_free Free memory */
/* _ux_utility_semaphore_create Create semaphore */
/* _ux_utility_semaphore_delete Delete semaphore */
/* */
/* CALLED BY */
/* */
/* Application */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_device_stack_initialize(UCHAR * device_framework_high_speed, ULONG device_framework_length_high_speed,
UCHAR * device_framework_full_speed, ULONG device_framework_length_full_speed,
UCHAR * string_framework, ULONG string_framework_length,
UCHAR * language_id_framework, ULONG language_id_framework_length,
UINT (*ux_system_slave_change_function)(ULONG))
{
UX_SLAVE_DEVICE *device;
UX_SLAVE_ENDPOINT *endpoints_pool;
UX_SLAVE_INTERFACE *interfaces_pool;
UX_SLAVE_TRANSFER *transfer_request;
UINT status;
ULONG interfaces_found;
ULONG local_interfaces_found;
ULONG endpoints_found;
ULONG local_endpoints_found;
ULONG endpoints_in_interface_found;
UCHAR *device_framework;
ULONG device_framework_length;
UCHAR descriptor_type;
ULONG descriptor_length;
UCHAR *memory;
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_STACK_INITIALIZE, 0, 0, 0, 0, UX_TRACE_DEVICE_STACK_EVENTS, 0, 0)
/* Get the pointer to the device. */
device = &_ux_system_slave -> ux_system_slave_device;
/* Store the high speed device framework address and length in the project structure. */
_ux_system_slave -> ux_system_slave_device_framework_high_speed = device_framework_high_speed;
_ux_system_slave -> ux_system_slave_device_framework_length_high_speed = device_framework_length_high_speed;
/* Store the string framework address and length in the project structure. */
_ux_system_slave -> ux_system_slave_device_framework_full_speed = device_framework_full_speed;
_ux_system_slave -> ux_system_slave_device_framework_length_full_speed = device_framework_length_full_speed;
/* Store the string framework address and length in the project structure. */
_ux_system_slave -> ux_system_slave_string_framework = string_framework;
_ux_system_slave -> ux_system_slave_string_framework_length = string_framework_length;
/* Store the language ID list in the project structure. */
_ux_system_slave -> ux_system_slave_language_id_framework = language_id_framework;
_ux_system_slave -> ux_system_slave_language_id_framework_length = language_id_framework_length;
/* Store the max number of slave class drivers in the project structure. */
_ux_system_slave -> ux_system_slave_max_class = UX_MAX_SLAVE_CLASS_DRIVER;
/* Store the device state change function callback. */
_ux_system_slave -> ux_system_slave_change_function = ux_system_slave_change_function;
/* Allocate memory for the classes.
* sizeof(UX_SLAVE_CLASS) * UX_MAX_SLAVE_CLASS_DRIVER) overflow is checked
* outside of the function.
*/
memory = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, sizeof(UX_SLAVE_CLASS) * UX_MAX_SLAVE_CLASS_DRIVER);
if (memory == UX_NULL)
return(UX_MEMORY_INSUFFICIENT);
/* Save this memory allocation in the USBX project. */
_ux_system_slave -> ux_system_slave_class_array = (UX_SLAVE_CLASS *) ((void *) memory);
/* Allocate some memory for the Control Endpoint. First get the address of the transfer request for the
control endpoint. */
transfer_request = &device -> ux_slave_device_control_endpoint.ux_slave_endpoint_transfer_request;
/* Acquire a buffer for the size of the endpoint. */
transfer_request -> ux_slave_transfer_request_data_pointer =
_ux_utility_memory_allocate(UX_NO_ALIGN, UX_CACHE_SAFE_MEMORY, UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH);
/* Ensure we have enough memory. */
if (transfer_request -> ux_slave_transfer_request_data_pointer == UX_NULL)
status = UX_MEMORY_INSUFFICIENT;
else
status = UX_SUCCESS;
/* Reset all values we are using during the scanning of the framework. */
interfaces_found = 0;
endpoints_found = 0;
/* Go on to scan interfaces if no error. */
if (status == UX_SUCCESS)
{
/* We need to determine the maximum number of interfaces and endpoints declared in the device framework.
This mechanism requires that both framework behave the same way regarding the number of interfaces
and endpoints. */
device_framework = _ux_system_slave -> ux_system_slave_device_framework_full_speed;
device_framework_length = _ux_system_slave -> ux_system_slave_device_framework_length_full_speed;
/* Reset all values we are using during the scanning of the framework. */
local_interfaces_found = 0;
local_endpoints_found = 0;
endpoints_in_interface_found = 0;
/* Parse the device framework and locate interfaces and endpoint descriptor(s). */
while (device_framework_length != 0)
{
/* Get the length of this descriptor. */
descriptor_length = (ULONG) *device_framework;
/* And its type. */
descriptor_type = *(device_framework + 1);
/* Check if this is an endpoint descriptor. */
switch(descriptor_type)
{
case UX_INTERFACE_DESCRIPTOR_ITEM:
/* Check if this is alternate setting 0. If not, do not add another interface found.
If this is alternate setting 0, reset the endpoints count for this interface. */
if (*(device_framework + 3) == 0)
{
/* Add the cumulated number of endpoints in the previous interface. */
local_endpoints_found += endpoints_in_interface_found;
/* Read the number of endpoints for this alternate setting. */
endpoints_in_interface_found = (ULONG) *(device_framework + 4);
/* Increment the number of interfaces found in the current configuration. */
local_interfaces_found++;
}
else
{
/* Compare the number of endpoints found in this non 0 alternate setting. */
if (endpoints_in_interface_found < (ULONG) *(device_framework + 4))
/* Adjust the number of maximum endpoints in this interface. */
endpoints_in_interface_found = (ULONG) *(device_framework + 4);
}
break;
case UX_CONFIGURATION_DESCRIPTOR_ITEM:
/* Check if the number of interfaces found in this configuration is the maximum so far. */
if (local_interfaces_found > interfaces_found)
/* We need to adjust the number of maximum interfaces. */
interfaces_found = local_interfaces_found;
/* We have a new configuration. We need to reset the number of local interfaces. */
local_interfaces_found = 0;
/* Add the cumulated number of endpoints in the previous interface. */
local_endpoints_found += endpoints_in_interface_found;
/* Check if the number of endpoints found in the previous configuration is the maximum so far. */
if (local_endpoints_found > endpoints_found)
/* We need to adjust the number of maximum endpoints. */
endpoints_found = local_endpoints_found;
/* We have a new configuration. We need to reset the number of local endpoints. */
local_endpoints_found = 0;
endpoints_in_interface_found = 0;
break;
default:
break;
}
/* Adjust what is left of the device framework. */
device_framework_length -= descriptor_length;
/* Point to the next descriptor. */
device_framework += descriptor_length;
}
/* Add the cumulated number of endpoints in the previous interface. */
local_endpoints_found += endpoints_in_interface_found;
/* Check if the number of endpoints found in the previous interface is the maximum so far. */
if (local_endpoints_found > endpoints_found)
/* We need to adjust the number of maximum endpoints. */
endpoints_found = local_endpoints_found;
/* Check if the number of interfaces found in this configuration is the maximum so far. */
if (local_interfaces_found > interfaces_found)
/* We need to adjust the number of maximum interfaces. */
interfaces_found = local_interfaces_found;
/* We do a sanity check on the finding. At least there must be one interface but endpoints are
not necessary. */
if (interfaces_found == 0)
{
/* Error trap. */
_ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_INIT, UX_DESCRIPTOR_CORRUPTED);
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_DESCRIPTOR_CORRUPTED, device_framework, 0, 0, UX_TRACE_ERRORS, 0, 0)
status = UX_DESCRIPTOR_CORRUPTED;
}
}
/* Go on to allocate endpoints pool if no error. */
if (status == UX_SUCCESS)
{
/* Memorize both pool sizes. */
device -> ux_slave_device_interfaces_pool_number = interfaces_found;
device -> ux_slave_device_endpoints_pool_number = endpoints_found;
/* We assign a pool for the interfaces. */
interfaces_pool = _ux_utility_memory_allocate_mulc_safe(UX_NO_ALIGN, UX_REGULAR_MEMORY, interfaces_found, sizeof(UX_SLAVE_INTERFACE));
if (interfaces_pool == UX_NULL)
status = UX_MEMORY_INSUFFICIENT;
else
/* Save the interface pool address in the device container. */
device -> ux_slave_device_interfaces_pool = interfaces_pool;
}
/* Do we need an endpoint pool ? */
if (endpoints_found != 0 && status == UX_SUCCESS)
{
/* We assign a pool for the endpoints. */
endpoints_pool = _ux_utility_memory_allocate_mulc_safe(UX_NO_ALIGN, UX_REGULAR_MEMORY, endpoints_found, sizeof(UX_SLAVE_ENDPOINT));
if (endpoints_pool == UX_NULL)
status = UX_MEMORY_INSUFFICIENT;
else
{
/* Save the endpoint pool address in the device container. */
device -> ux_slave_device_endpoints_pool = endpoints_pool;
/* We need to assign a transfer buffer to each endpoint. Each endpoint is assigned the
maximum buffer size. We also assign the semaphore used by the endpoint to synchronize transfer
completion. */
while (endpoints_pool < (device -> ux_slave_device_endpoints_pool + endpoints_found))
{
/* Obtain some memory. */
endpoints_pool -> ux_slave_endpoint_transfer_request.ux_slave_transfer_request_data_pointer =
_ux_utility_memory_allocate(UX_NO_ALIGN, UX_CACHE_SAFE_MEMORY, UX_SLAVE_REQUEST_DATA_MAX_LENGTH);
/* Ensure we could allocate memory. */
if (endpoints_pool -> ux_slave_endpoint_transfer_request.ux_slave_transfer_request_data_pointer == UX_NULL)
{
status = UX_MEMORY_INSUFFICIENT;
break;
}
/* Create the semaphore for the endpoint. */
status = _ux_utility_semaphore_create(&endpoints_pool -> ux_slave_endpoint_transfer_request.ux_slave_transfer_request_semaphore,
"ux_transfer_request_semaphore", 0);
/* Check completion status. */
if (status != UX_SUCCESS)
{
status = UX_SEMAPHORE_ERROR;
break;
}
/* Next endpoint. */
endpoints_pool++;
}
}
}
else
endpoints_pool = UX_NULL;
/* Return successful completion. */
if (status == UX_SUCCESS)
return(UX_SUCCESS);
/* Free resources when there is error. */
/* Free device -> ux_slave_device_endpoints_pool. */
if (endpoints_pool)
{
/* In error cases creating endpoint resources, endpoints_pool is endpoint that failed.
* Previously allocated things should be freed. */
while(endpoints_pool >= device -> ux_slave_device_endpoints_pool)
{
/* Delete ux_slave_transfer_request_semaphore. */
if (endpoints_pool -> ux_slave_endpoint_transfer_request.ux_slave_transfer_request_semaphore.tx_semaphore_id != 0)
_ux_utility_semaphore_delete(&endpoints_pool -> ux_slave_endpoint_transfer_request.ux_slave_transfer_request_semaphore);
/* Free ux_slave_transfer_request_data_pointer buffer. */
if (endpoints_pool -> ux_slave_endpoint_transfer_request.ux_slave_transfer_request_data_pointer)
_ux_utility_memory_free(endpoints_pool -> ux_slave_endpoint_transfer_request.ux_slave_transfer_request_data_pointer);
/* Move to previous endpoint. */
endpoints_pool --;
}
_ux_utility_memory_free(device -> ux_slave_device_endpoints_pool);
}
/* Free device -> ux_slave_device_interfaces_pool. */
if (device -> ux_slave_device_interfaces_pool)
_ux_utility_memory_free(device -> ux_slave_device_interfaces_pool);
/* Free device -> ux_slave_device_control_endpoint.ux_slave_endpoint_transfer_request.ux_slave_transfer_request_data_pointer. */
if (device -> ux_slave_device_control_endpoint.ux_slave_endpoint_transfer_request.ux_slave_transfer_request_data_pointer)
_ux_utility_memory_free(device -> ux_slave_device_control_endpoint.ux_slave_endpoint_transfer_request.ux_slave_transfer_request_data_pointer);
/* Free _ux_system_slave -> ux_system_slave_class_array. */
_ux_utility_memory_free(_ux_system_slave -> ux_system_slave_class_array);
/* Return completion status. */
return(status);
}

View File

@ -0,0 +1,132 @@
/**************************************************************************/
/* */
/* 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 Stack */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_device_stack.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_device_stack_interface_delete PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function deletes an interface. Semaphore and memory are */
/* released and the controller driver is invoked to disable the */
/* hardware endpoint. The interface is then removed from the */
/* configuration. */
/* */
/* INPUT */
/* */
/* interface Pointer to interface */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* (ux_slave_dcd_function) DCD dispatch function */
/* */
/* CALLED BY */
/* */
/* Application */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_device_stack_interface_delete(UX_SLAVE_INTERFACE *interface)
{
UX_SLAVE_DCD *dcd;
UX_SLAVE_DEVICE *device;
UX_SLAVE_ENDPOINT *endpoint;
UX_SLAVE_ENDPOINT *next_endpoint;
/* If trace is enabled, register this object. */
UX_TRACE_OBJECT_UNREGISTER(interface);
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_STACK_INTERFACE_DELETE, interface, 0, 0, 0, UX_TRACE_DEVICE_STACK_EVENTS, 0, 0)
/* Get the pointer to the device. */
device = &_ux_system_slave -> ux_system_slave_device;
/* Find the first endpoints associated with this interface. */
next_endpoint = interface -> ux_slave_interface_first_endpoint;
/* Parse all the endpoints. */
while (next_endpoint != UX_NULL)
{
/* Save this endpoint. */
endpoint = next_endpoint;
/* Find the next endpoint. */
next_endpoint = endpoint -> ux_slave_endpoint_next_endpoint;
/* Get the pointer to the DCD. */
dcd = &_ux_system_slave->ux_system_slave_dcd;
/* The endpoint must be destroyed. */
dcd -> ux_slave_dcd_function(dcd, UX_DCD_DESTROY_ENDPOINT, endpoint);
/* Free the endpoint. */
endpoint -> ux_slave_endpoint_status = UX_UNUSED;
/* Make sure the endpoint instance is now cleaned up. */
endpoint -> ux_slave_endpoint_state = 0;
endpoint -> ux_slave_endpoint_next_endpoint = UX_NULL;
endpoint -> ux_slave_endpoint_interface = UX_NULL;
endpoint -> ux_slave_endpoint_device = UX_NULL;
}
/* It's always from first one (to delete). */
/* Rebuild the first link. */
device -> ux_slave_device_first_interface = interface -> ux_slave_interface_next_interface;
/* The interface is removed from the link, its memory must be cleaned and returned to the pool. */
interface -> ux_slave_interface_class = UX_NULL;
interface -> ux_slave_interface_class_instance = UX_NULL;
interface -> ux_slave_interface_next_interface = UX_NULL;
interface -> ux_slave_interface_first_endpoint = UX_NULL;
interface -> ux_slave_interface_status = UX_UNUSED;
/* Return successful completion. */
return(UX_SUCCESS);
}

View File

@ -0,0 +1,141 @@
/**************************************************************************/
/* */
/* 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 Stack */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_device_stack.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_device_stack_interface_get PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function is deprecated, ux_device_stack_alternate_setting_get */
/* does the same thing and used by the core stack. */
/* */
/* This function gets the current alternate setting for an interface. */
/* */
/* INPUT */
/* */
/* interface_value Value of the interface */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* (ux_slave_dcd_function) DCD dispatch function */
/* */
/* CALLED BY */
/* */
/* Application */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_device_stack_interface_get(UINT interface_value)
{
UX_SLAVE_DCD *dcd;
UX_SLAVE_TRANSFER *transfer_request;
UX_SLAVE_INTERFACE *interface;
UX_SLAVE_DEVICE *device;
UX_SLAVE_ENDPOINT *endpoint;
UINT status;
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_STACK_INTERFACE_GET, interface_value, 0, 0, 0, UX_TRACE_DEVICE_STACK_EVENTS, 0, 0)
/* Get the pointer to the DCD. */
dcd = &_ux_system_slave -> ux_system_slave_dcd;
/* Get the pointer to the device. */
device = &_ux_system_slave -> ux_system_slave_device;
/* Get the control endpoint for the device. */
endpoint = &device -> ux_slave_device_control_endpoint;
/* If the device was in the configured state, there may be interfaces
attached to the configuration. */
if (device -> ux_slave_device_state == UX_DEVICE_CONFIGURED)
{
/* Get the pointer to the first interface. */
interface = device -> ux_slave_device_first_interface;
/* Parse the interfaces if any. */
while (interface != UX_NULL)
{
/* Check if this is the interface we have an inquiry for. */
if (interface -> ux_slave_interface_descriptor.bInterfaceNumber == interface_value)
{
/* Get the pointer to the transfer request associated with the endpoint. */
transfer_request = &endpoint -> ux_slave_endpoint_transfer_request;
/* Set the value of the alternate setting in the buffer. */
*transfer_request -> ux_slave_transfer_request_data_pointer =
(UCHAR) interface -> ux_slave_interface_descriptor.bAlternateSetting;
/* Setup the length appropriately. */
transfer_request -> ux_slave_transfer_request_requested_length = 1;
/* Set the phase of the transfer to data out. */
transfer_request -> ux_slave_transfer_request_phase = UX_TRANSFER_PHASE_DATA_OUT;
/* Send the descriptor with the appropriate length to the host. */
status = dcd -> ux_slave_dcd_function(dcd, UX_DCD_TRANSFER_REQUEST, transfer_request);
/* Return the function status code. */
return(status);
}
/* Get the next interface. */
interface = interface -> ux_slave_interface_next_interface;
}
}
/* The alternate setting value was not found, so we return a stall error. */
dcd -> ux_slave_dcd_function(dcd, UX_DCD_STALL_ENDPOINT, endpoint);
/* Return the status to the caller. */
return(UX_ERROR);
}

View File

@ -0,0 +1,277 @@
/**************************************************************************/
/* */
/* 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 Stack */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_device_stack.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_device_stack_interface_set PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function sets one alternate setting of one interface and */
/* enable all endpoints associated with this alternate setting. */
/* configuration. */
/* */
/* INPUT */
/* */
/* device_framework Address in device framework */
/* for selected alternate setting*/
/* device_framework_length Length of device framework */
/* alternate_setting_value Alternate setting */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* (ux_slave_dcd_function) DCD dispatch function */
/* _ux_device_stack_interface_start Start interface */
/* _ux_utility_descriptor_parse Parse descriptor */
/* */
/* CALLED BY */
/* */
/* Application */
/* Device Stack */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_device_stack_interface_set(UCHAR * device_framework, ULONG device_framework_length,
ULONG alternate_setting_value)
{
UX_SLAVE_DCD *dcd;
UX_SLAVE_DEVICE *device;
UX_SLAVE_TRANSFER *transfer_request;
UX_SLAVE_INTERFACE *interface;
UX_SLAVE_INTERFACE *interface_link;
UX_SLAVE_ENDPOINT *endpoint;
UX_SLAVE_ENDPOINT *endpoint_link;
ULONG descriptor_length;
UCHAR descriptor_type;
ULONG endpoints_pool_number;
ULONG interfaces_pool_number;
UINT status;
UX_PARAMETER_NOT_USED(alternate_setting_value);
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_STACK_INTERFACE_SET, alternate_setting_value, 0, 0, 0, UX_TRACE_DEVICE_STACK_EVENTS, 0, 0)
/* Get the pointer to the DCD. */
dcd = &_ux_system_slave -> ux_system_slave_dcd;
/* Get the pointer to the device. */
device = &_ux_system_slave -> ux_system_slave_device;
/* Find a free interface in the pool and hook it to the
existing interface. */
interface = device -> ux_slave_device_interfaces_pool;
interfaces_pool_number = device -> ux_slave_device_interfaces_pool_number;
while (interfaces_pool_number != 0)
{
/* Check if this interface is free. */
if (interface -> ux_slave_interface_status == UX_UNUSED)
{
/* Mark this interface as used now. */
interface -> ux_slave_interface_status = UX_USED;
break;
}
/* Try the next interface. */
interface++;
/* Decrement the number of interfaces left to scan in the pool. */
interfaces_pool_number--;
}
/* Did we find a free interface ? */
if (interfaces_pool_number == 0)
return(UX_MEMORY_INSUFFICIENT);
/* If trace is enabled, register this object. */
UX_TRACE_OBJECT_REGISTER(UX_TRACE_DEVICE_OBJECT_TYPE_INTERFACE, interface, 0, 0, 0)
/* Parse the descriptor in something more readable. */
_ux_utility_descriptor_parse(device_framework,
_ux_system_interface_descriptor_structure,
UX_INTERFACE_DESCRIPTOR_ENTRIES,
(UCHAR *) &interface -> ux_slave_interface_descriptor);
/* Attach this interface to the end of the interface chain. */
if (device -> ux_slave_device_first_interface == UX_NULL)
{
device -> ux_slave_device_first_interface = interface;
}
else
{
/* Multiple interfaces exist, so find the end of the chain. */
interface_link = device -> ux_slave_device_first_interface;
while (interface_link -> ux_slave_interface_next_interface != UX_NULL)
interface_link = interface_link -> ux_slave_interface_next_interface;
interface_link -> ux_slave_interface_next_interface = interface;
}
/* Point beyond the interface descriptor. */
device_framework_length -= (ULONG) *device_framework;
device_framework += (ULONG) *device_framework;
/* Parse the device framework and locate endpoint descriptor(s). */
while (device_framework_length != 0)
{
/* Get the length of the current descriptor. */
descriptor_length = (ULONG) *device_framework;
/* And its type. */
descriptor_type = *(device_framework + 1);
/* Check if this is an endpoint descriptor. */
switch(descriptor_type)
{
case UX_ENDPOINT_DESCRIPTOR_ITEM:
/* Find a free endpoint in the pool and hook it to the
existing interface after it's created by DCD. */
endpoint = device -> ux_slave_device_endpoints_pool;
endpoints_pool_number = device -> ux_slave_device_endpoints_pool_number;
while (endpoints_pool_number != 0)
{
/* Check if this endpoint is free. */
if (endpoint -> ux_slave_endpoint_status == UX_UNUSED)
{
/* Mark this endpoint as used now. */
endpoint -> ux_slave_endpoint_status = UX_USED;
break;
}
/* Try the next endpoint. */
endpoint++;
/* Decrement the number of endpoints to scan from the pool. */
endpoints_pool_number--;
}
/* Did we find a free endpoint ? */
if (endpoints_pool_number == 0)
return(UX_MEMORY_INSUFFICIENT);
/* Parse the descriptor in something more readable. */
_ux_utility_descriptor_parse(device_framework,
_ux_system_endpoint_descriptor_structure,
UX_ENDPOINT_DESCRIPTOR_ENTRIES,
(UCHAR *) &endpoint -> ux_slave_endpoint_descriptor);
/* Now we create a transfer request to accept transfer on this endpoint. */
transfer_request = &endpoint -> ux_slave_endpoint_transfer_request;
/* We store the endpoint in the transfer request as well. */
transfer_request -> ux_slave_transfer_request_endpoint = endpoint;
/* By default the timeout is infinite on request. */
transfer_request -> ux_slave_transfer_request_timeout = UX_WAIT_FOREVER;
/* Attach the interface to the endpoint. */
endpoint -> ux_slave_endpoint_interface = interface;
/* Attach the device to the endpoint. */
endpoint -> ux_slave_endpoint_device = device;
/* Create the endpoint at the DCD level. */
status = dcd -> ux_slave_dcd_function(dcd, UX_DCD_CREATE_ENDPOINT, (VOID *) endpoint);
/* Do a sanity check on endpoint creation. */
if (status != UX_SUCCESS)
{
/* Error was returned, endpoint cannot be created. */
endpoint -> ux_slave_endpoint_status = UX_UNUSED;
return(status);
}
/* Attach this endpoint to the end of the endpoint chain. */
if (interface -> ux_slave_interface_first_endpoint == UX_NULL)
{
interface -> ux_slave_interface_first_endpoint = endpoint;
}
else
{
/* Multiple endpoints exist, so find the end of the chain. */
endpoint_link = interface -> ux_slave_interface_first_endpoint;
while (endpoint_link -> ux_slave_endpoint_next_endpoint != UX_NULL)
endpoint_link = endpoint_link -> ux_slave_endpoint_next_endpoint;
endpoint_link -> ux_slave_endpoint_next_endpoint = endpoint;
}
break;
case UX_CONFIGURATION_DESCRIPTOR_ITEM:
case UX_INTERFACE_DESCRIPTOR_ITEM:
/* If the descriptor is a configuration or interface,
we have parsed and mounted all endpoints.
The interface attached to this configuration must be started at the class level. */
status = _ux_device_stack_interface_start(interface);
/* Return the status to the caller. */
return(status);
default:
break;
}
/* Adjust what is left of the device framework. */
device_framework_length -= descriptor_length;
/* Point to the next descriptor. */
device_framework += descriptor_length;
}
/* The interface attached to this configuration must be started at the class
level. */
status = _ux_device_stack_interface_start(interface);
/* Return the status to the caller. */
return(status);
}

View File

@ -0,0 +1,130 @@
/**************************************************************************/
/* */
/* 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 Stack */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_device_stack.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_device_stack_interface_start PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function starts an interface associated with the enabled */
/* configuration. */
/* */
/* INPUT */
/* */
/* interface Pointer to interface */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* (ux_slave_class_entry_function) Device class entry function */
/* */
/* CALLED BY */
/* */
/* Application */
/* Device Stack */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_device_stack_interface_start(UX_SLAVE_INTERFACE *interface)
{
UX_SLAVE_DEVICE *device;
UX_SLAVE_CLASS *class;
UINT status;
UX_SLAVE_CLASS_COMMAND class_command;
/* Get the class for the interface. */
class = _ux_system_slave -> ux_system_slave_interface_class_array[interface -> ux_slave_interface_descriptor.bInterfaceNumber];
/* Check if class driver is available. */
if (class == UX_NULL)
/* There is no class driver supported. */
return (UX_NO_CLASS_MATCH);
/* Get the pointer to the device. */
device = &_ux_system_slave -> ux_system_slave_device;
/* Build all the fields of the Class Command. */
class_command.ux_slave_class_command_request = UX_SLAVE_CLASS_COMMAND_QUERY;
class_command.ux_slave_class_command_interface = (VOID *)interface;
class_command.ux_slave_class_command_class = interface -> ux_slave_interface_descriptor.bInterfaceClass;
class_command.ux_slave_class_command_subclass = interface -> ux_slave_interface_descriptor.bInterfaceSubClass;
class_command.ux_slave_class_command_protocol = interface -> ux_slave_interface_descriptor.bInterfaceProtocol;
class_command.ux_slave_class_command_vid = device -> ux_slave_device_descriptor.idVendor;
class_command.ux_slave_class_command_pid = device -> ux_slave_device_descriptor.idProduct;
/* We can now memorize the interface pointer associated with this class. */
class -> ux_slave_class_interface = interface;
/* We have found a potential candidate. Call this registered class entry function. */
status = class -> ux_slave_class_entry_function(&class_command);
/* The status tells us if the registered class wants to own this class. */
if (status == UX_SUCCESS)
{
/* Store the class container. */
class_command.ux_slave_class_command_class_ptr = class;
/* Store the command. */
class_command.ux_slave_class_command_request = UX_SLAVE_CLASS_COMMAND_ACTIVATE;
/* Activate the class. */
status = class -> ux_slave_class_entry_function(&class_command);
/* If the class was successfully activated, set the class for the interface. */
if(status == UX_SUCCESS)
interface -> ux_slave_interface_class = class;
return(status);
}
/* There is no driver who want to own this class! */
return(UX_NO_CLASS_MATCH);
}

View File

@ -0,0 +1,86 @@
/**************************************************************************/
/* */
/* 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 Stack */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_device_stack.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_device_stack_microsoft_extension_register PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function registers the Microsoft extensions to support vendor */
/* commands before the device is configured. */
/* */
/* INPUT */
/* */
/* vendor_command Vendor Command. */
/* application_callback Application Callback */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_device_stack_microsoft_extension_register(ULONG vendor_request,
UINT (*vendor_request_function)(ULONG, ULONG, ULONG, ULONG, UCHAR *, ULONG *))
{
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_STACK_MICROSOFT_EXTENSION_REGISTER, 0, 0, 0, 0, UX_TRACE_DEVICE_STACK_EVENTS, 0, 0)
/* Store the vendor command. */
_ux_system_slave -> ux_system_slave_device_vendor_request = vendor_request;
_ux_system_slave -> ux_system_slave_device_vendor_request_function = vendor_request_function;
/* Return successful completion. */
return(UX_SUCCESS);
}

View File

@ -0,0 +1,195 @@
/**************************************************************************/
/* */
/* 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 Stack */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_device_stack.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_device_stack_set_feature PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function sets a specific feature (Device, Interface, */
/* Endpoint ....). */
/* */
/* INPUT */
/* */
/* request_type Request type */
/* request_value Request value */
/* request_index Request index */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* (ux_slave_dcd_function) DCD controller function */
/* */
/* CALLED BY */
/* */
/* Device Stack */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_device_stack_set_feature(ULONG request_type, ULONG request_value, ULONG request_index)
{
UX_SLAVE_DCD *dcd;
UX_SLAVE_DEVICE *device;
UX_SLAVE_INTERFACE *interface;
UX_SLAVE_ENDPOINT *endpoint;
UX_SLAVE_ENDPOINT *endpoint_target;
UX_PARAMETER_NOT_USED(request_value);
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_STACK_SET_FEATURE, request_value, request_index, 0, 0, UX_TRACE_DEVICE_STACK_EVENTS, 0, 0)
/* Get the pointer to the DCD. */
dcd = &_ux_system_slave -> ux_system_slave_dcd;
/* Get the pointer to the device. */
device = &_ux_system_slave -> ux_system_slave_device;
/* Get the control endpoint for the device. */
endpoint = &device -> ux_slave_device_control_endpoint;
/* The feature can be for either the device or the endpoint. */
switch (request_type & UX_REQUEST_TARGET)
{
case UX_REQUEST_TARGET_DEVICE:
/* Check if we have a DEVICE_REMOTE_WAKEUP Feature. */
if (request_value == UX_REQUEST_FEATURE_DEVICE_REMOTE_WAKEUP)
{
/* Check if we have the capability. */
if (_ux_system_slave -> ux_system_slave_remote_wakeup_capability)
{
/* Enable the feature. */
_ux_system_slave -> ux_system_slave_remote_wakeup_enabled = UX_TRUE;
/* OK. */
return (UX_SUCCESS);
}
else
/* Protocol error. */
return (UX_FUNCTION_NOT_SUPPORTED);
}
#ifdef UX_OTG_SUPPORT
/* Check if we have a A_HNP_SUPPORT Feature. This is set when the Host is HNP capable. */
if (request_value == UX_OTG_FEATURE_A_HNP_SUPPORT)
/* Store the A_HNP_SUPPORT flag. */
_ux_system_otg -> ux_system_otg_slave_set_feature_flag |= UX_OTG_FEATURE_A_HNP_SUPPORT;
else
{
/* Check if the host asks us to perform HNP. If also we become the host. */
if (request_value == UX_OTG_FEATURE_B_HNP_ENABLE)
{
/* The ISR will pick up the suspend event and check if we need to become IDLE or HOST. */
_ux_system_otg -> ux_system_otg_slave_set_feature_flag |= UX_OTG_FEATURE_B_HNP_ENABLE;
}
}
#endif
break;
case UX_REQUEST_TARGET_ENDPOINT:
/* The only set feature for endpoint is ENDPOINT_STALL. This forces
the endpoint to the stall situation.
We need to find the endpoint through the interface(s). */
interface = device -> ux_slave_device_first_interface;
while (interface != UX_NULL)
{
/* Get the first endpoint for this interface. */
endpoint_target = interface -> ux_slave_interface_first_endpoint;
/* Parse all the endpoints. */
while (endpoint_target != UX_NULL)
{
/* Check the endpoint index. */
if (endpoint_target -> ux_slave_endpoint_descriptor.bEndpointAddress == request_index)
{
/* Stall the endpoint. */
dcd -> ux_slave_dcd_function(dcd, UX_DCD_STALL_ENDPOINT, endpoint_target);
/* Return the function status. */
return(UX_SUCCESS);
}
/* Next endpoint. */
endpoint_target = endpoint_target -> ux_slave_endpoint_next_endpoint;
}
/* Next interface. */
interface = interface -> ux_slave_interface_next_interface;
}
/* We get here when the endpoint is wrong. Should not happen though. */
/* Intentionally fall through into the default case. */
/* fall through */
default:
/* We stall the command. */
dcd -> ux_slave_dcd_function(dcd, UX_DCD_STALL_ENDPOINT, endpoint);
/* No more work to do here. The command failed but the upper layer does not depend on it. */
return(UX_SUCCESS);
}
/* Return the function status. */
return(UX_SUCCESS);
}

View File

@ -0,0 +1,126 @@
/**************************************************************************/
/* */
/* 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 Stack */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_device_stack.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_device_stack_transfer_abort PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function aborts a pending transfer request that has been */
/* previously submitted. This function only cancels a specific */
/* transfer request. */
/* */
/* The call back to the function will have the */
/* UX_TRANSFER_STATUS_ABORT status */
/* */
/* INPUT */
/* */
/* transfer_request Pointer to transfer request */
/* completion_code Completion code */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* _ux_utility_semaphore_put Put semaphore */
/* */
/* CALLED BY */
/* */
/* Application */
/* Device Stack */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_device_stack_transfer_abort(UX_SLAVE_TRANSFER *transfer_request, ULONG completion_code)
{
TX_INTERRUPT_SAVE_AREA
UX_SLAVE_DCD *dcd;
UX_PARAMETER_NOT_USED(completion_code);
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_STACK_TRANSFER_ABORT, transfer_request, completion_code, 0, 0, UX_TRACE_DEVICE_STACK_EVENTS, 0, 0)
/* Get the pointer to the DCD. */
dcd = &_ux_system_slave -> ux_system_slave_dcd;
/* Sets the completion code due to bus reset. */
transfer_request -> ux_slave_transfer_request_completion_code = UX_TRANSFER_BUS_RESET;
/* Ensure we're not preempted by the transfer completion ISR. */
TX_DISABLE
/* It's possible the transfer already completed. Ensure it hasn't before doing the abort. */
if (transfer_request -> ux_slave_transfer_request_status == UX_TRANSFER_STATUS_PENDING)
{
/* Call the DCD if necessary for cleaning up the pending transfer. */
dcd -> ux_slave_dcd_function(dcd, UX_DCD_TRANSFER_ABORT, (VOID *) transfer_request);
/* Restore interrupts. Note that the transfer request should not be modified now. */
TX_RESTORE
/* We need to set the completion code for the transfer to aborted. Note
that the transfer request function cannot simultaneously modify this
because if the transfer was pending, then the transfer's thread is
currently waiting for it to complete. */
transfer_request -> ux_slave_transfer_request_status = UX_TRANSFER_STATUS_ABORT;
/* Wake up the device driver who is waiting on the semaphore. */
_ux_utility_semaphore_put(&transfer_request -> ux_slave_transfer_request_semaphore);
}
else
{
/* Restore interrupts. */
TX_RESTORE
}
/* This function never fails. */
return(UX_SUCCESS);
}

View File

@ -0,0 +1,89 @@
/**************************************************************************/
/* */
/* 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 Stack */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_device_stack.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_device_transfer_all_request_abort PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function cancels all the transfer requests attached to an */
/* endpoint. The endpoint is not reset and its toggle state is left */
/* the same. */
/* */
/* INPUT */
/* */
/* transfer_request Pointer to transfer request */
/* completion_code Completion code */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* _ux_device_stack_transfer_abort Transfer abort */
/* */
/* CALLED BY */
/* */
/* Device Stack */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_device_stack_transfer_all_request_abort(UX_SLAVE_ENDPOINT *endpoint, ULONG completion_code)
{
UX_SLAVE_TRANSFER *transfer_request;
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_STACK_TRANSFER_ALL_REQUEST_ABORT, endpoint, completion_code, 0, 0, UX_TRACE_DEVICE_STACK_EVENTS, 0, 0)
/* Get the transfer request for this endpoint. */
transfer_request = &endpoint -> ux_slave_endpoint_transfer_request;
/* Abort this request. */
_ux_device_stack_transfer_abort(transfer_request, completion_code);
/* Return successful completion. */
return(UX_SUCCESS);
}

View File

@ -0,0 +1,183 @@
/**************************************************************************/
/* */
/* 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 Stack */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_device_stack.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_device_stack_transfer_request PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function performs a USB transaction. On entry the */
/* transfer request gives the endpoint pipe selected for this */
/* transaction and the parameters associated with the transfer */
/* (data payload, length of transaction). */
/* */
/* INPUT */
/* */
/* transfer_request Pointer to transfer request */
/* slave_length Length returned by host */
/* host_length Length asked by host */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* (ux_slave_dcd_function) Slave DCD dispatch function */
/* _ux_utility_delay_ms Delay ms */
/* */
/* CALLED BY */
/* */
/* Application */
/* Device Stack */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_device_stack_transfer_request(UX_SLAVE_TRANSFER *transfer_request,
ULONG slave_length,
ULONG host_length)
{
TX_INTERRUPT_SAVE_AREA
UX_SLAVE_DCD *dcd;
UINT status;
UX_SLAVE_ENDPOINT *endpoint;
ULONG device_state;
/* Do we have to skip this transfer? */
if (transfer_request -> ux_slave_transfer_request_status_phase_ignore == UX_TRUE)
return(UX_SUCCESS);
/* Disable interrupts to prevent the disconnection ISR from preempting us
while we check the device state and set the transfer status. */
TX_DISABLE
/* Get the device state. */
device_state = _ux_system_slave -> ux_system_slave_device.ux_slave_device_state;
/* We can only transfer when the device is ATTACHED, ADDRESSED OR CONFIGURED. */
if ((device_state == UX_DEVICE_ATTACHED) || (device_state == UX_DEVICE_ADDRESSED)
|| (device_state == UX_DEVICE_CONFIGURED))
/* Set the transfer to pending. */
transfer_request -> ux_slave_transfer_request_status = UX_TRANSFER_STATUS_PENDING;
else
{
/* The device is in an invalid state. Restore interrupts and return error. */
TX_RESTORE
return(UX_TRANSFER_NOT_READY);
}
/* Restore interrupts. */
TX_RESTORE
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_STACK_TRANSFER_REQUEST, transfer_request, 0, 0, 0, UX_TRACE_DEVICE_STACK_EVENTS, 0, 0)
/* Get the pointer to the DCD. */
dcd = &_ux_system_slave -> ux_system_slave_dcd;
/* Get the endpoint associated with this transaction. */
endpoint = transfer_request -> ux_slave_transfer_request_endpoint;
/* If the endpoint is non Control, check the endpoint direction and set the data phase direction. */
if ((endpoint -> ux_slave_endpoint_descriptor.bmAttributes & UX_MASK_ENDPOINT_TYPE) != UX_CONTROL_ENDPOINT)
{
/* Check if the endpoint is STALLED. In this case, we must refuse the transaction until the endpoint
has been reset by the host. */
while (endpoint -> ux_slave_endpoint_state == UX_ENDPOINT_HALTED)
/* Wait for 100ms for endpoint to be reset by a CLEAR_FEATURE command. */
_ux_utility_delay_ms(100);
/* Isolate the direction from the endpoint address. */
if ((endpoint -> ux_slave_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION) == UX_ENDPOINT_IN)
transfer_request -> ux_slave_transfer_request_phase = UX_TRANSFER_PHASE_DATA_OUT;
else
transfer_request -> ux_slave_transfer_request_phase = UX_TRANSFER_PHASE_DATA_IN;
}
/* See if we need to force a zero length packet at the end of the transfer.
This happens on a DATA IN and when the host requested length is not met
and the last packet is on a boundary. If slave_length is zero, then it is
a explicit ZLP request, no need to force ZLP. */
if ((transfer_request -> ux_slave_transfer_request_phase == UX_TRANSFER_PHASE_DATA_OUT) &&
(slave_length != 0) && (host_length != slave_length) &&
(slave_length % endpoint -> ux_slave_endpoint_descriptor.wMaxPacketSize) == 0)
{
/* If so force Zero Length Packet. */
transfer_request -> ux_slave_transfer_request_force_zlp = UX_TRUE;
}
else
{
/* Condition is not met, do not force a Zero Length Packet. */
transfer_request -> ux_slave_transfer_request_force_zlp = UX_FALSE;
}
/* Reset the number of bytes sent/received. */
transfer_request -> ux_slave_transfer_request_actual_length = 0;
/* Determine how many bytes to send in this transaction. We keep track of the original
length and have a working length. */
transfer_request -> ux_slave_transfer_request_requested_length = slave_length;
transfer_request -> ux_slave_transfer_request_in_transfer_length = slave_length;
/* Save the buffer pointer. */
transfer_request -> ux_slave_transfer_request_current_data_pointer =
transfer_request -> ux_slave_transfer_request_data_pointer;
/* Call the DCD driver transfer function. */
status = dcd -> ux_slave_dcd_function(dcd, UX_DCD_TRANSFER_REQUEST, transfer_request);
/* And return the status. */
return(status);
}

View File

@ -0,0 +1,122 @@
/**************************************************************************/
/* */
/* 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 Stack */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_device_stack.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_device_stack_uninitialize PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function uninitializes the generic portion of the device side */
/* of USBX. */
/* */
/* INPUT */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* _ux_utility_memory_free Free */
/* _ux_utility_semaphore_delete Delete semaphore */
/* */
/* CALLED BY */
/* */
/* Application */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_device_stack_uninitialize(VOID)
{
UX_SLAVE_DEVICE *device;
UX_SLAVE_ENDPOINT *endpoints_pool;
UX_SLAVE_TRANSFER *transfer_request;
ULONG endpoints_found;
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_STACK_INITIALIZE, 0, 0, 0, 0, UX_TRACE_DEVICE_STACK_EVENTS, 0, 0)
/* Get the pointer to the device. */
device = &_ux_system_slave -> ux_system_slave_device;
/* Free class memory. */
_ux_utility_memory_free(_ux_system_slave -> ux_system_slave_class_array);
/* Allocate some memory for the Control Endpoint. First get the address of the transfer request for the
control endpoint. */
transfer_request = &device -> ux_slave_device_control_endpoint.ux_slave_endpoint_transfer_request;
/* Free memory for the control endpoint buffer. */
_ux_utility_memory_free(transfer_request -> ux_slave_transfer_request_data_pointer);
/* Get the number of endpoints found in the device framework. */
endpoints_found = device -> ux_slave_device_endpoints_pool_number;
/* Get the endpoint pool address in the device container. */
endpoints_pool = device -> ux_slave_device_endpoints_pool;
/* Parse all endpoints and fee memory and semaphore. */
while (endpoints_found-- != 0)
{
/* Free the memory for endpoint data pointer. */
_ux_utility_memory_free(endpoints_pool -> ux_slave_endpoint_transfer_request.ux_slave_transfer_request_data_pointer);
/* Remove the TX semaphore for the endpoint. */
_ux_utility_semaphore_delete(&endpoints_pool -> ux_slave_endpoint_transfer_request.ux_slave_transfer_request_semaphore);
/* Next endpoint. */
endpoints_pool++;
}
/* Free the endpoint pool address in the device container. */
_ux_utility_memory_free(device -> ux_slave_device_endpoints_pool);
/* Free memory for interface pool. */
_ux_utility_memory_free(device -> ux_slave_device_interfaces_pool);
/* Return successful completion. */
return(UX_SUCCESS);
}

View File

@ -0,0 +1,79 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Host Simulator Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_hcd_sim_host.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_hcd_sim_host_asynch_queue_process PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function process the asynchronous transactions that happened */
/* in the last frame. We read the ATL buffer and search for completed */
/* PTDs and reflect the completion in the higher level ED/TD. */
/* */
/* INPUT */
/* */
/* hcd_sim_host Pointer to host controller */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Host Simulator Controller Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
VOID _ux_hcd_sim_host_asynch_queue_process(UX_HCD_SIM_HOST *hcd_sim_host)
{
UX_PARAMETER_NOT_USED(hcd_sim_host);
/* Return to caller. */
return;
}

View File

@ -0,0 +1,126 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Host Simulator Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_hcd_sim_host.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_hcd_sim_host_asynch_schedule PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function schedules new transfers from the control/bulk lists. */
/* */
/* INPUT */
/* */
/* hcd_sim_host Pointer to host controller */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _ux_hcd_sim_host_transaction_schedule Schedule simulator transaction*/
/* */
/* CALLED BY */
/* */
/* Host Simulator Controller Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
VOID _ux_hcd_sim_host_asynch_schedule(UX_HCD_SIM_HOST *hcd_sim_host)
{
UX_HCD_SIM_HOST_ED *ed;
UX_HCD_SIM_HOST_ED *first_ed;
UINT status;
/* Get the pointer to the current ED in the asynchronous list. */
ed = hcd_sim_host -> ux_hcd_sim_host_asynch_current_ed;
/* Check if there is any ED candidate in the asynch list. */
if (ed == UX_NULL)
{
/* Check if there is any ED in the asynch list. If none, nothing to do. */
if (hcd_sim_host -> ux_hcd_sim_host_asynch_head_ed == UX_NULL)
return;
else
ed = hcd_sim_host -> ux_hcd_sim_host_asynch_head_ed;
}
/* Remember this ED. */
first_ed = ed;
/* In simulation, we are not tied to bandwidth limitation. */
do
{
/* Check if this ED has a tail and head TD different. */
if (ed -> ux_sim_host_ed_tail_td != ed -> ux_sim_host_ed_head_td)
{
/* Schedule this transaction with the device simulator. */
status = _ux_hcd_sim_host_transaction_schedule(hcd_sim_host, ed);
/* If the TD has been added to the list, we can memorize this ED has
being served and make the next ED as the one to be first scanned
at the next SOF. */
if (status == UX_SUCCESS)
{
if (ed -> ux_sim_host_ed_next_ed == UX_NULL)
hcd_sim_host -> ux_hcd_sim_host_asynch_current_ed = hcd_sim_host -> ux_hcd_sim_host_asynch_head_ed;
else
hcd_sim_host -> ux_hcd_sim_host_asynch_current_ed = ed -> ux_sim_host_ed_next_ed;
}
}
/* Point to the next ED in the list. Check if at end of list. */
if (ed -> ux_sim_host_ed_next_ed == UX_NULL)
ed = hcd_sim_host -> ux_hcd_sim_host_asynch_head_ed;
else
ed = ed -> ux_sim_host_ed_next_ed;
} while ((ed) && (ed != first_ed));
}

View File

@ -0,0 +1,122 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Host Simulator Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_hcd_sim_host.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_hcd_sim_host_asynchronous_endpoint_create PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function will create an asynchronous endpoint. The control */
/* and bulk endpoints fall into this category. */
/* */
/* INPUT */
/* */
/* hcd_sim_host Pointer to host controller */
/* endpoint Pointer to endpoint */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* _ux_hcd_sim_host_ed_obtain Obtain host ED */
/* _ux_hcd_sim_host_regular_td_obtain Obtain host regular TD */
/* */
/* CALLED BY */
/* */
/* Host Simulator Controller Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_hcd_sim_host_asynchronous_endpoint_create(UX_HCD_SIM_HOST *hcd_sim_host, UX_ENDPOINT *endpoint)
{
UX_HCD_SIM_HOST_ED *ed;
UX_HCD_SIM_HOST_ED *head_ed;
UX_HCD_SIM_HOST_TD *td;
/* We need to take into account the nature of the HCD to define the max size
of any transfer in the transfer request. */
endpoint -> ux_endpoint_transfer_request.ux_transfer_request_maximum_length = UX_HCD_SIM_HOST_MAX_PAYLOAD;
/* Obtain a ED for this new endpoint. This ED will live as long as the endpoint is active
and will be the container for the TDs. */
ed = _ux_hcd_sim_host_ed_obtain(hcd_sim_host);
if (ed == UX_NULL)
return(UX_NO_ED_AVAILABLE);
/* Obtain a dummy TD for terminating the ED transfer chain. */
td = _ux_hcd_sim_host_regular_td_obtain(hcd_sim_host);
if (td == UX_NULL)
{
ed -> ux_sim_host_ed_status = UX_UNUSED;
return(UX_NO_TD_AVAILABLE);
}
/* Attach the ED to the endpoint container. */
endpoint -> ux_endpoint_ed = (VOID *) ed;
/* Now do the opposite, attach the ED container to the physical ED. */
ed -> ux_sim_host_ed_endpoint = endpoint;
/* Hook the TD to both the tail and head of the ED. */
ed -> ux_sim_host_ed_tail_td = td;
ed -> ux_sim_host_ed_head_td = td;
/* Attach this ED to the asynch list. */
head_ed = hcd_sim_host -> ux_hcd_sim_host_asynch_head_ed;
ed -> ux_sim_host_ed_next_ed = head_ed;
hcd_sim_host -> ux_hcd_sim_host_asynch_head_ed = ed;
/* Build the back chaining pointer. The previous head ED needs to know about the
inserted ED. */
if (head_ed != UX_NULL)
head_ed -> ux_sim_host_ed_previous_ed = ed;
/* Return successful completion. */
return(UX_SUCCESS);
}

View File

@ -0,0 +1,121 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Host Simulator Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_hcd_sim_host.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_hcd_sim_host_asynchronous_endpoint_destroy PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function will destroy an asynchronous endpoint. The control */
/* and bulk endpoints fall into this category. */
/* */
/* INPUT */
/* */
/* hcd_sim_host Pointer to host controller */
/* endpoint Pointer to endpoint */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Host Simulator Controller Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_hcd_sim_host_asynchronous_endpoint_destroy(UX_HCD_SIM_HOST *hcd_sim_host, UX_ENDPOINT *endpoint)
{
UX_HCD_SIM_HOST_ED *ed;
UX_HCD_SIM_HOST_ED *previous_ed;
UX_HCD_SIM_HOST_ED *next_ed;
UX_HCD_SIM_HOST_TD *td;
/* From the endpoint container fetch the host simulator ED descriptor. */
ed = (UX_HCD_SIM_HOST_ED *) endpoint -> ux_endpoint_ed;
/* Get the previous ED in the list for this ED. */
previous_ed = ed -> ux_sim_host_ed_previous_ed;
/* Get the next ED in the list for this ED. */
next_ed = ed -> ux_sim_host_ed_next_ed;
/* If the previous ED is NULL, we are at trying to remove the head ED. */
if (previous_ed == UX_NULL)
/* Store the new endpoint in the control list. */
hcd_sim_host -> ux_hcd_sim_host_asynch_head_ed = next_ed;
else
/* The previous ED points now to the ED after the ED we are removing. */
previous_ed -> ux_sim_host_ed_next_ed = next_ed;
/* Update the previous ED pointer in the next ED if exists. */
if (next_ed != UX_NULL)
next_ed -> ux_sim_host_ed_previous_ed = previous_ed;
/* Determine if we need to adjust the current ED. */
if (hcd_sim_host -> ux_hcd_sim_host_asynch_current_ed == ed)
{
/* Move the current to the next. */
hcd_sim_host -> ux_hcd_sim_host_asynch_current_ed = next_ed;
}
/* We need to free the dummy TD that was attached to the ED. */
td = ed -> ux_sim_host_ed_tail_td;
td -> ux_sim_host_td_status = UX_UNUSED;
/* Now we can safely make the ED free. */
ed -> ux_sim_host_ed_status = UX_UNUSED;
/* Return successful completion. */
return(UX_SUCCESS);
}

View File

@ -0,0 +1,102 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Host Simulator Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_hcd_sim_host.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_hcd_sim_host_ed_obtain PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function obtains a free ED from the ED list. */
/* */
/* INPUT */
/* */
/* hcd_sim_host Pointer to host controller */
/* */
/* OUTPUT */
/* */
/* UX_HCD_SIM_HOST_ED * Pointer to ED */
/* */
/* CALLS */
/* */
/* _ux_utility_memory_set Set memory block */
/* */
/* CALLED BY */
/* */
/* Host Simulator Controller Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UX_HCD_SIM_HOST_ED *_ux_hcd_sim_host_ed_obtain(UX_HCD_SIM_HOST *hcd_sim_host)
{
UX_HCD_SIM_HOST_ED *ed;
ULONG ed_index;
/* Start the search from the beginning of the list. */
ed = hcd_sim_host -> ux_hcd_sim_host_ed_list;
for(ed_index = 0; ed_index < _ux_system_host -> ux_system_host_max_ed; ed_index++)
{
/* Check the ED status, a free ED is marked with the UNUSED flag. */
if (ed -> ux_sim_host_ed_status == UX_UNUSED)
{
/* The ED may have been used, so we reset all fields. */
_ux_utility_memory_set(ed, 0, sizeof(UX_HCD_SIM_HOST_ED));
/* This ED is now marked as USED. */
ed -> ux_sim_host_ed_status = UX_USED;
/* Return ED pointer. */
return(ed);
}
/* Point to the next ED. */
ed++;
}
/* There is no available ED in the ED list. */
return(UX_NULL);
}

View File

@ -0,0 +1,96 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Host Simulator Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_hcd_sim_host.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_hcd_sim_host_ed_td_clean PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function process cleans the ED of all TDs except the last */
/* dummy TD. */
/* */
/* INPUT */
/* */
/* ed Pointer to ED */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Host Simulator Controller Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
VOID _ux_hcd_sim_host_ed_td_clean(UX_HCD_SIM_HOST_ED *ed)
{
UX_HCD_SIM_HOST_TD *head_td;
UX_HCD_SIM_HOST_TD *tail_td;
/* Remove all the tds from this ED and leave the head and tail pointing
to the dummy TD. */
head_td = ed -> ux_sim_host_ed_head_td;
tail_td = ed -> ux_sim_host_ed_tail_td;
/* Free all tds attached to the ED. */
while (head_td != tail_td)
{
/* Mark the current head TD as free. */
head_td -> ux_sim_host_td_status = UX_UNUSED;
/* Update the head TD with the next TD. */
ed -> ux_sim_host_ed_head_td = head_td -> ux_sim_host_td_next_td;
/* Now the new head_td is the next TD in the chain. */
head_td = ed -> ux_sim_host_ed_head_td;
}
}

View File

@ -0,0 +1,86 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Host Simulator Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_hcd_sim_host.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_hcd_sim_host_endpoint_reset PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function will reset an endpoint. */
/* */
/* INPUT */
/* */
/* hcd_sim_host Pointer to host controller */
/* endpoint Pointer to endpoint */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Host Simulator Controller Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_hcd_sim_host_endpoint_reset(UX_HCD_SIM_HOST *hcd_sim_host, UX_ENDPOINT *endpoint)
{
UX_HCD_SIM_HOST_ED *ed;
UX_PARAMETER_NOT_USED(hcd_sim_host);
/* From the endpoint container fetch the host simulator ED descriptor. */
ed = (UX_HCD_SIM_HOST_ED *) endpoint -> ux_endpoint_ed;
/* Reset the data0/data1 toggle bit in the Head TD. */
ed -> ux_sim_host_ed_toggle = 0;
/* This operation never fails. */
return(UX_SUCCESS);
}

View File

@ -0,0 +1,273 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Host Simulator Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_hcd_sim_host.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_hcd_sim_host_entry PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function dispatch the HCD function internally to the simulator */
/* controller driver. */
/* */
/* INPUT */
/* */
/* hcd Pointer to HCD */
/* function Function for driver to perform*/
/* parameter Pointer to parameter(s) */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* _ux_hcd_sim_host_asynch_queue_process Process asynch queue */
/* _ux_hcd_sim_host_asynch_schedule Schedule async work */
/* _ux_hcd_sim_host_asynchronous_endpoint_create Create async endpoint */
/* _ux_hcd_sim_host_asynchronous_endpoint_destroy Destroy async endpoint */
/* _ux_hcd_sim_host_endpoint_reset Reset endpoint */
/* _ux_hcd_sim_host_frame_number_get Get frame number */
/* _ux_hcd_sim_host_interrupt_endpoint_create Create endpoint */
/* _ux_hcd_sim_host_iso_queue_process Process iso queue */
/* _ux_hcd_sim_host_iso_schedule Schedule iso work */
/* _ux_hcd_sim_host_isochronous_endpoint_create Create iso endpoint */
/* _ux_hcd_sim_host_periodic_endpoint_destroy Destroy endpoint */
/* _ux_hcd_sim_host_periodic_schedule Schedule periodic */
/* _ux_hcd_sim_host_port_status_get Get port status */
/* _ux_hcd_sim_host_port_reset Reset port */
/* _ux_hcd_sim_host_request_transfer Request transfer */
/* _ux_hcd_sim_host_transfer_abort Abort transfer */
/* */
/* CALLED BY */
/* */
/* Host Stack */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_hcd_sim_host_entry(UX_HCD *hcd, UINT function, VOID *parameter)
{
UINT status = 0;
UX_HCD_SIM_HOST *hcd_sim_host;
/* Check the status of the controller. */
if (hcd -> ux_hcd_status == UX_UNUSED)
{
/* Error trap. */
_ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_HCD, UX_CONTROLLER_UNKNOWN);
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_CONTROLLER_UNKNOWN, 0, 0, 0, UX_TRACE_ERRORS, 0, 0)
return(UX_CONTROLLER_UNKNOWN);
}
/* Get the pointer to the host simulator HCD. */
hcd_sim_host = (UX_HCD_SIM_HOST *) hcd -> ux_hcd_controller_hardware;
/* look at the function and route it. */
switch(function)
{
case UX_HCD_DISABLE_CONTROLLER:
status = UX_SUCCESS;
break;
case UX_HCD_GET_PORT_STATUS:
status = _ux_hcd_sim_host_port_status_get(hcd_sim_host, (ULONG) (ALIGN_TYPE) parameter);
break;
case UX_HCD_ENABLE_PORT:
status = UX_SUCCESS;
break;
case UX_HCD_DISABLE_PORT:
status = UX_SUCCESS;
break;
case UX_HCD_POWER_ON_PORT:
status = UX_SUCCESS;
break;
case UX_HCD_POWER_DOWN_PORT:
status = UX_SUCCESS;
break;
case UX_HCD_SUSPEND_PORT:
status = UX_SUCCESS;
break;
case UX_HCD_RESUME_PORT:
status = UX_SUCCESS;
break;
case UX_HCD_RESET_PORT:
status = _ux_hcd_sim_host_port_reset(hcd_sim_host, (ULONG) (ALIGN_TYPE) parameter);
break;
case UX_HCD_GET_FRAME_NUMBER:
status = _ux_hcd_sim_host_frame_number_get(hcd_sim_host, (ULONG *) parameter);
break;
case UX_HCD_SET_FRAME_NUMBER:
status = UX_SUCCESS;
break;
case UX_HCD_TRANSFER_REQUEST:
status = _ux_hcd_sim_host_request_transfer(hcd_sim_host, (UX_TRANSFER *) parameter);
break;
case UX_HCD_TRANSFER_ABORT:
status = _ux_hcd_sim_host_transfer_abort(hcd_sim_host, (UX_TRANSFER *) parameter);
break;
case UX_HCD_CREATE_ENDPOINT:
switch ((((UX_ENDPOINT*) parameter) -> ux_endpoint_descriptor.bmAttributes) & UX_MASK_ENDPOINT_TYPE)
{
case UX_CONTROL_ENDPOINT:
case UX_BULK_ENDPOINT:
status = _ux_hcd_sim_host_asynchronous_endpoint_create(hcd_sim_host, (UX_ENDPOINT*) parameter);
break;
case UX_INTERRUPT_ENDPOINT:
status = _ux_hcd_sim_host_interrupt_endpoint_create(hcd_sim_host, (UX_ENDPOINT*) parameter);
break;
case UX_ISOCHRONOUS_ENDPOINT:
status = _ux_hcd_sim_host_isochronous_endpoint_create(hcd_sim_host, (UX_ENDPOINT*) parameter);
break;
}
break;
case UX_HCD_DESTROY_ENDPOINT:
switch ((((UX_ENDPOINT*) parameter) -> ux_endpoint_descriptor.bmAttributes) & UX_MASK_ENDPOINT_TYPE)
{
case UX_CONTROL_ENDPOINT:
case UX_BULK_ENDPOINT:
status = _ux_hcd_sim_host_asynchronous_endpoint_destroy(hcd_sim_host, (UX_ENDPOINT*) parameter);
break;
case UX_INTERRUPT_ENDPOINT:
case UX_ISOCHRONOUS_ENDPOINT:
status = _ux_hcd_sim_host_periodic_endpoint_destroy(hcd_sim_host, (UX_ENDPOINT*) parameter);
break;
}
break;
case UX_HCD_RESET_ENDPOINT:
status = _ux_hcd_sim_host_endpoint_reset(hcd_sim_host, (UX_ENDPOINT*) parameter);
break;
case UX_HCD_PROCESS_DONE_QUEUE:
_ux_hcd_sim_host_iso_queue_process(hcd_sim_host);
_ux_hcd_sim_host_asynch_queue_process(hcd_sim_host);
_ux_hcd_sim_host_iso_schedule(hcd_sim_host);
_ux_hcd_sim_host_periodic_schedule(hcd_sim_host);
_ux_hcd_sim_host_asynch_schedule(hcd_sim_host);
status = UX_SUCCESS;
break;
default:
/* Error trap. */
_ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_HCD, UX_FUNCTION_NOT_SUPPORTED);
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_FUNCTION_NOT_SUPPORTED, 0, 0, 0, UX_TRACE_ERRORS, 0, 0)
/* Unknown request, return an error. */
status = UX_FUNCTION_NOT_SUPPORTED;
}
/* Return completion status. */
return(status);
}

View File

@ -0,0 +1,78 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Host Simulator Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_hcd_sim_host.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_hcd_sim_host_frame_number_get PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function will return the frame number currently used by the */
/* controller. This function is mostly used for isochronous purposes. */
/* */
/* INPUT */
/* */
/* hcd_sim_host Pointer to host controller */
/* frame_number Frame number to set */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Host Simulator Controller Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_hcd_sim_host_frame_number_get(UX_HCD_SIM_HOST *hcd_sim_host, ULONG *frame_number)
{
/* Pickup the frame number. */
*frame_number = hcd_sim_host -> ux_hcd_sim_host_interrupt_count;
return(UX_SUCCESS);
}

View File

@ -0,0 +1,80 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Host Simulator Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_hcd_sim_host.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_hcd_sim_host_frame_number_set PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function will set the current frame number to the one */
/* specified. This function is mostly used for isochronous purposes. */
/* */
/* INPUT */
/* */
/* hcd_sim_host Pointer to host controller */
/* frame_number Frame number to set */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Host Simulator Controller Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
VOID _ux_hcd_sim_host_frame_number_set(UX_HCD_SIM_HOST *hcd_sim_host, ULONG frame_number)
{
UX_PARAMETER_NOT_USED(hcd_sim_host);
UX_PARAMETER_NOT_USED(frame_number);
/* Return to caller. */
return;
}

View File

@ -0,0 +1,191 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Host Simulator Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_hcd_sim_host.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_hcd_sim_host_initialize PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function initializes the simulated host controller */
/* */
/* INPUT */
/* */
/* HCD Pointer to HCD */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* _ux_hcd_sim_host_periodic_tree_create Create periodic tree */
/* _ux_utility_memory_allocate Allocate memory block */
/* _ux_utility_semaphore_put Semaphore put */
/* _ux_utility_timer_create Create timer */
/* */
/* CALLED BY */
/* */
/* Host Simulator Controller Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_hcd_sim_host_initialize(UX_HCD *hcd)
{
UX_HCD_SIM_HOST *hcd_sim_host;
UINT status;
/* The controller initialized here is of host simulator type. */
hcd -> ux_hcd_controller_type = UX_HCD_SIM_HOST_CONTROLLER;
/* Allocate memory for this host simulator HCD instance. */
hcd_sim_host = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, sizeof(UX_HCD_SIM_HOST));
if (hcd_sim_host == UX_NULL)
return(UX_MEMORY_INSUFFICIENT);
/* Set the pointer to the host simulator HCD. */
hcd -> ux_hcd_controller_hardware = (VOID *) hcd_sim_host;
/* Set the generic HCD owner for the host simulator HCD. */
hcd_sim_host -> ux_hcd_sim_host_hcd_owner = hcd;
/* Initialize the function collector for this HCD. */
hcd -> ux_hcd_entry_function = _ux_hcd_sim_host_entry;
/* Initialize the max bandwidth for periodic endpoints. In simulation this is
not very important. */
hcd -> ux_hcd_available_bandwidth = UX_HCD_SIM_HOST_AVAILABLE_BANDWIDTH;
/* Set the state of the controller to HALTED first. */
hcd -> ux_hcd_status = UX_HCD_STATUS_HALTED;
/* Allocate the list of EDs. All EDs are allocated on 16 byte memory boundary. */
hcd_sim_host -> ux_hcd_sim_host_ed_list = _ux_utility_memory_allocate(UX_ALIGN_16, UX_REGULAR_MEMORY, (ULONG)sizeof(UX_HCD_SIM_HOST_ED) * _ux_system_host -> ux_system_host_max_ed);
if (hcd_sim_host -> ux_hcd_sim_host_ed_list == UX_NULL)
status = UX_MEMORY_INSUFFICIENT;
else
status = UX_SUCCESS;
/* Allocate the list of TDs. All TDs are allocated on 32 byte memory boundary. */
if (status == UX_SUCCESS)
{
hcd_sim_host -> ux_hcd_sim_host_td_list = _ux_utility_memory_allocate(UX_ALIGN_32, UX_REGULAR_MEMORY, (ULONG)sizeof(UX_HCD_SIM_HOST_TD) * _ux_system_host -> ux_system_host_max_td);
if (hcd_sim_host -> ux_hcd_sim_host_td_list == UX_NULL)
status = UX_MEMORY_INSUFFICIENT;
}
/* Allocate the list of isochronous TDs. All TDs are allocated on 32 byte memory boundary. */
if (status == UX_SUCCESS)
{
hcd_sim_host -> ux_hcd_sim_host_iso_td_list = _ux_utility_memory_allocate(UX_ALIGN_32, UX_REGULAR_MEMORY, (ULONG)sizeof(UX_HCD_SIM_HOST_ISO_TD) * _ux_system_host -> ux_system_host_max_iso_td);
if (hcd_sim_host -> ux_hcd_sim_host_iso_td_list == UX_NULL)
status = UX_MEMORY_INSUFFICIENT;
}
/* Initialize the periodic tree. */
if (status == UX_SUCCESS)
status = _ux_hcd_sim_host_periodic_tree_create(hcd_sim_host);
/* Initialize the scheduler. */
if (status == UX_SUCCESS)
{
/* Set the host controller into the operational state. */
hcd -> ux_hcd_status = UX_HCD_STATUS_OPERATIONAL;
/* The asynchronous queues are empty for now. */
hcd_sim_host -> ux_hcd_sim_host_queue_empty = UX_TRUE;
/* The periodic scheduler is not active. */
hcd_sim_host -> ux_hcd_sim_host_periodic_scheduler_active = 0;
/* We start a timer that will invoke the simulator every timer tick. */
status = _ux_utility_timer_create(&hcd_sim_host -> ux_hcd_sim_host_timer, "USBX Simulation Timer",
_ux_hcd_sim_host_timer_function, (ULONG) (ALIGN_TYPE) hcd_sim_host, 1, 1, TX_AUTO_ACTIVATE);
}
UX_TIMER_EXTENSION_PTR_SET(&(hcd_sim_host -> ux_hcd_sim_host_timer), hcd_sim_host)
/* Free up resources and return when there is error. */
if (status != UX_SUCCESS)
{
/* Set the host controller into the halt state. */
hcd -> ux_hcd_status = UX_HCD_STATUS_HALTED;
/* The last resource, timer is not created or created error,
* no need to delete. */
if (hcd_sim_host -> ux_hcd_sim_host_iso_td_list)
_ux_utility_memory_free(hcd_sim_host -> ux_hcd_sim_host_iso_td_list);
if (hcd_sim_host -> ux_hcd_sim_host_td_list)
_ux_utility_memory_free(hcd_sim_host -> ux_hcd_sim_host_td_list);
if (hcd_sim_host -> ux_hcd_sim_host_ed_list)
_ux_utility_memory_free(hcd_sim_host -> ux_hcd_sim_host_ed_list);
_ux_utility_memory_free(hcd_sim_host);
return(status);
}
/* Get the number of ports on the controller. The number of ports needs to be reflected both
for the generic HCD container and the local sim_host container. In the simulator,
the number of ports is hardwired to 1 only. */
hcd -> ux_hcd_nb_root_hubs = 1;
hcd_sim_host -> ux_hcd_sim_host_nb_root_hubs = 1;
/* Something happened on this port. Signal it to the root hub thread. */
hcd -> ux_hcd_root_hub_signal[0] = 1;
/* We need to simulate a Root HUB Status Change for the USB stack since the simulator
has not root HUB per se. */
status = _ux_utility_semaphore_put(&_ux_system_host -> ux_system_host_enum_semaphore);
if (status != UX_SUCCESS)
/* Resources are still ready but
* failed to simulate Root HUB change! */
return(UX_SEMAPHORE_ERROR);
/* Return successful completion. */
return(UX_SUCCESS);
}

View File

@ -0,0 +1,180 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Host Simulator Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_hcd_sim_host.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_hcd_sim_host_interrupt_endpoint_create PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function will create an interrupt endpoint. The interrupt */
/* endpoint has an interval of operation from 1 to 255. The host */
/* has no hardware scheduler but we still build an interrupt tree */
/* similar to the host simulator controller. */
/* */
/* This routine will match the best interval for the host */
/* simulator. It will also determine the best node to hook the */
/* endpoint based on the load that already exists on the horizontal */
/* ED chain. */
/* */
/* For the ones curious about this coding. The tricky part is to */
/* understand how the interrupt matrix is constructed. We have used */
/* EDs with the skip bit on to build a frame of anchor EDs. Each ED */
/* creates a node for an appropriate combination of interval frequency */
/* in the list. */
/* */
/* After obtaining a pointer to the list with the lowest traffic, we */
/* traverse the list from the highest interval until we reach the */
/* interval required. At that node, we anchor our real ED to the node */
/* and link the ED that was attached to the node to our ED. */
/* */
/* INPUT */
/* */
/* hcd_sim_host Pointer to host controller */
/* endpoint Pointer to endpoint */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* _ux_hcd_sim_host_ed_obtain Obtain ED */
/* _ux_hcd_sim_host_regular_td_obtain Obtain regular TD */
/* _ux_hcd_sim_host_least_traffic_list_get Get least traffic list */
/* */
/* CALLED BY */
/* */
/* Host Simulator Controller Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_hcd_sim_host_interrupt_endpoint_create(UX_HCD_SIM_HOST *hcd_sim_host, UX_ENDPOINT *endpoint)
{
UX_HCD_SIM_HOST_ED *ed;
UX_HCD_SIM_HOST_ED *ed_list;
UX_HCD_SIM_HOST_ED *next_ed;
UX_HCD_SIM_HOST_TD *td;
UINT interval;
UINT interval_index;
UINT interval_sim_host;
/* Obtain a ED for this new endpoint. This ED will live as long as
the endpoint is active and will be the container for the TDs. */
ed = _ux_hcd_sim_host_ed_obtain(hcd_sim_host);
if (ed == UX_NULL)
return(UX_NO_ED_AVAILABLE);
/* Obtain a dummy TD for terminating the ED transfer chain. */
td = _ux_hcd_sim_host_regular_td_obtain(hcd_sim_host);
if (td == UX_NULL)
{
ed -> ux_sim_host_ed_status = UX_UNUSED;
return(UX_NO_TD_AVAILABLE);
}
/* Attach the ED to the endpoint container. */
endpoint -> ux_endpoint_ed = (VOID *)ed;
/* Now do the opposite, attach the ED container to the physical ED. */
ed -> ux_sim_host_ed_endpoint = endpoint;
/* Hook the TD to both the tail and head of the ED. */
ed -> ux_sim_host_ed_tail_td = td;
ed -> ux_sim_host_ed_head_td = td;
/* Get the list index with the least traffic. */
ed_list = _ux_hcd_sim_host_least_traffic_list_get(hcd_sim_host);
/* Get the interval for the endpoint and match it to a host simulator list. We match anything
that is > 32ms to the 32ms interval list, the 32ms list is list 0, 16ms list is 1...
the 1ms list is number 5. */
interval = endpoint -> ux_endpoint_descriptor.bInterval;
interval_index = 1;
interval_sim_host = 5;
if (interval >= 32)
{
interval_sim_host = 0;
}
else
{
while (interval_index < 32)
{
if (interval&interval_index)
interval_sim_host--;
interval_index = interval_index << 1;
}
}
/* Now we need to scan the list of eds from the lowest load entry until we reach
the appropriate interval node. The depth index is the interval_sim_host value
and the 1st entry is pointed by the ED list entry. */
while (interval_sim_host--)
{
ed_list = ed_list -> ux_sim_host_ed_next_ed;
while (!(ed_list -> ux_sim_host_ed_status & UX_HCD_SIM_HOST_ED_STATIC))
ed_list = ed_list -> ux_sim_host_ed_next_ed;
}
/* We found the node entry of the ED pointer that will be the anchor for this interrupt
endpoint. Now we attach this endpoint to the anchor and rebuild the chain . */
next_ed = ed_list -> ux_sim_host_ed_next_ed;
/* Note that if there is a crash here, it is most likely due to an invalid bInterval. */
next_ed -> ux_sim_host_ed_previous_ed = ed;
ed -> ux_sim_host_ed_next_ed = next_ed;
ed -> ux_sim_host_ed_previous_ed = ed_list;
ed_list -> ux_sim_host_ed_next_ed = ed;
/* There is activity in the periodic tree, the scheduler has to be active all the time. */
hcd_sim_host -> ux_hcd_sim_host_periodic_scheduler_active++;
/* Return successful completion. */
return(UX_SUCCESS);
}

View File

@ -0,0 +1,78 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Host Simulator Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_hcd_sim_host.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_hcd_sim_host_iso_queue_process PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function process the isochronous transactions that happened */
/* in the last frame. */
/* */
/* INPUT */
/* */
/* hcd_sim_host Pointer to host controller */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Host Simulator Controller Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
VOID _ux_hcd_sim_host_iso_queue_process(UX_HCD_SIM_HOST *hcd_sim_host)
{
UX_PARAMETER_NOT_USED(hcd_sim_host);
/* Not implemented - just return. */
return;
}

View File

@ -0,0 +1,77 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Host Simulator Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_hcd_sim_host.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_hcd_sim_host_iso_schedule PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function schedules new transfers from isochronous list. */
/* */
/* INPUT */
/* */
/* hcd_sim_host Pointer to host controller */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Host Simulator Controller Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
VOID _ux_hcd_sim_host_iso_schedule(UX_HCD_SIM_HOST *hcd_sim_host)
{
UX_PARAMETER_NOT_USED(hcd_sim_host);
/* Not currently implemented - just return. */
return;
}

View File

@ -0,0 +1,114 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Host Simulator Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_hcd_sim_host.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_hcd_sim_host_isochronous_endpoint_create PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function creates an isochronous endpoint. */
/* */
/* INPUT */
/* */
/* hcd_sim_host Pointer to host controller */
/* endpoint Pointer to endpoint */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* _ux_hcd_sim_host_ed_obtain Obtain host ED */
/* _ux_hcd_sim_host_isochronous_td_obtain Obtain host ISO TD */
/* */
/* CALLED BY */
/* */
/* Host Simulator Controller Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_hcd_sim_host_isochronous_endpoint_create(UX_HCD_SIM_HOST *hcd_sim_host, UX_ENDPOINT *endpoint)
{
UX_HCD_SIM_HOST_ED *ed;
UX_HCD_SIM_HOST_ED *head_ed;
UX_HCD_SIM_HOST_ISO_TD *td;
/* Obtain a ED for this new endpoint. This ED will live as long as the endpoint is
active and will be the container for the TDs. */
ed = _ux_hcd_sim_host_ed_obtain(hcd_sim_host);
if (ed == UX_NULL)
return(UX_NO_ED_AVAILABLE);
/* Obtain a dummy isoch TD for terminating the ED transfer chain. */
td = _ux_hcd_sim_host_isochronous_td_obtain(hcd_sim_host);
if (td == UX_NULL)
{
ed -> ux_sim_host_ed_status = UX_UNUSED;
return(UX_NO_TD_AVAILABLE);
}
/* Attach the ED to the endpoint container. */
endpoint -> ux_endpoint_ed = (VOID *) ed;
/* Hook the TD to both the tail and head of the ED. */
ed -> ux_sim_host_ed_tail_td = (UX_HCD_SIM_HOST_TD *) ((void *) td);
ed -> ux_sim_host_ed_head_td = (UX_HCD_SIM_HOST_TD *) ((void *) td);
/* Attach this ED to the ISO list. */
head_ed = hcd_sim_host -> ux_hcd_sim_host_iso_head_ed;
ed -> ux_sim_host_ed_next_ed = head_ed;
hcd_sim_host -> ux_hcd_sim_host_iso_head_ed = ed;
/* Build the back chaining pointer. The previous head ED needs to know about the
inserted ED. */
if (head_ed != UX_NULL)
head_ed -> ux_sim_host_ed_previous_ed = ed;
/* Return successful completion. */
return(UX_SUCCESS);
}

View File

@ -0,0 +1,102 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Host Simulator Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_hcd_sim_host.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_hcd_sim_host_isochronous_td_obtain PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function obtains a free TD from the isochronous TD list. */
/* */
/* INPUT */
/* */
/* hcd_sim_host Pointer to host controller */
/* */
/* OUTPUT */
/* */
/* UX_HCD_SIM_HOST_ISO_TD * Pointer to host ISO ED */
/* */
/* CALLS */
/* */
/* _ux_utility_memory_set Set memory block */
/* */
/* CALLED BY */
/* */
/* Host Simulator Controller Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UX_HCD_SIM_HOST_ISO_TD *_ux_hcd_sim_host_isochronous_td_obtain(UX_HCD_SIM_HOST *hcd_sim_host)
{
UX_HCD_SIM_HOST_ISO_TD *td;
ULONG td_index;
/* Start the search from the beginning of the list. */
td = hcd_sim_host -> ux_hcd_sim_host_iso_td_list;
for (td_index = 0; td_index < _ux_system_host -> ux_system_host_max_iso_td; td_index++)
{
/* Check the TD status, a free TD is marked with the UX_USED flag. */
if (td -> ux_sim_host_iso_td_status == UX_UNUSED)
{
/* The TD may have been used, so we reset all fields. */
_ux_utility_memory_set(td, 0, sizeof(UX_HCD_SIM_HOST_ISO_TD));
/* This TD is now marked as USED. */
td -> ux_sim_host_iso_td_status = UX_USED;
/* Success, return pointer to TD. */
return(td);
}
/* Move to next TD. */
td++;
}
/* There is no available TD in the TD list, return a NULL. */
return(UX_NULL);
}

View File

@ -0,0 +1,136 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Host Simulator Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_hcd_sim_host.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_hcd_sim_host_least_traffic_list_get PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function return a pointer to the first ED in the periodic */
/* tree that has the least traffic registered. */
/* */
/* INPUT */
/* */
/* hcd_sim_host Pointer to host controller */
/* */
/* OUTPUT */
/* */
/* UX_HCD_SIM_HOST_ED * Pointer to host ED */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Host Simulator Controller Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UX_HCD_SIM_HOST_ED *_ux_hcd_sim_host_least_traffic_list_get(UX_HCD_SIM_HOST *hcd_sim_host)
{
UX_HCD_SIM_HOST_ED *min_bandwidth_ed;
UX_HCD_SIM_HOST_ED *begin_ed;
UX_HCD_SIM_HOST_ED *ed;
UX_ENDPOINT *endpoint;
UINT list_index;
ULONG min_bandwidth_used;
ULONG bandwidth_used;
/* Reset the min bandwidth used. */
min_bandwidth_used = 0;
/* The first ED is the list candidate for now. */
min_bandwidth_ed = hcd_sim_host -> ux_hcd_sim_host_interrupt_ed_list[0];
/* All list will be scanned. */
for (list_index = 0; list_index < 32; list_index++)
{
/* Reset the bandwidth for this list. */
bandwidth_used = 0;
/* Get the ED of the beginning of the list we parse now. */
ed = hcd_sim_host -> ux_hcd_sim_host_interrupt_ed_list[list_index];
/* We keep track of the first ED for the current list. */
begin_ed = ed;
/* Parse the EDs in the list. */
while (ed -> ux_sim_host_ed_next_ed != UX_NULL)
{
/* Get the endpoint pointer from the physical ED. */
endpoint = ed -> ux_sim_host_ed_endpoint;
if (endpoint != UX_NULL)
{
/* Add to the bandwidth used the max packet size pointed by this ED. */
bandwidth_used += (ULONG) endpoint -> ux_endpoint_descriptor.wMaxPacketSize;
}
/* Move to next ED. */
ed = ed -> ux_sim_host_ed_next_ed;
}
/* We have processed a list, check the bandwidth used by this list.
If this bandwidth is the minimum, we memorize the ED. */
if (bandwidth_used < min_bandwidth_used)
{
/* We have found a better list with a lower used bandwidth, memorize the bandwidth
for this list. */
min_bandwidth_used = bandwidth_used;
/* Memorize the begin ED for this list. */
min_bandwidth_ed = begin_ed;
}
}
/* Return the ED list with the lowest bandwidth. */
return(min_bandwidth_ed);
}

View File

@ -0,0 +1,110 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Host Simulator Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_hcd_sim_host.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_hcd_sim_host_periodic_endpoint_destroy PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function will destroy an interrupt or isochronous endpoint. */
/* */
/* INPUT */
/* */
/* hcd_sim_host Pointer to host controller */
/* endpoint Pointer to endpoint */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Host Simulator Controller Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_hcd_sim_host_periodic_endpoint_destroy(UX_HCD_SIM_HOST *hcd_sim_host, UX_ENDPOINT *endpoint)
{
UX_HCD_SIM_HOST_ED *ed;
UX_HCD_SIM_HOST_ED *previous_ed;
UX_HCD_SIM_HOST_ED *next_ed;
UX_HCD_SIM_HOST_TD *td;
/* From the endpoint container fetch the host simulator ED descriptor. */
ed = (UX_HCD_SIM_HOST_ED *) endpoint -> ux_endpoint_ed;
/* Get the previous ED in the list for this ED. */
previous_ed = ed -> ux_sim_host_ed_previous_ed;
/* Get the next ED in the list for this ED. */
next_ed = ed -> ux_sim_host_ed_next_ed;
/* The previous ED points now to the ED after the ED we are removing. */
if (previous_ed)
previous_ed -> ux_sim_host_ed_next_ed = next_ed;
/* Update the previous ED pointer in the next ED. */
if (next_ed)
next_ed -> ux_sim_host_ed_previous_ed = previous_ed;
/* We need to free the dummy TD that was attached to the ED. */
td = ed -> ux_sim_host_ed_tail_td;
td -> ux_sim_host_td_status = UX_UNUSED;
/* Now we can safely make the ED free. */
ed -> ux_sim_host_ed_status = UX_UNUSED;
/* Decrement the number of interrupt endpoints active. When the counter
reaches 0, the periodic scheduler will be turned off. */
hcd_sim_host -> ux_hcd_sim_host_periodic_scheduler_active--;
/* Return successful completion. */
return(UX_SUCCESS);
}

View File

@ -0,0 +1,109 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Host Simulator Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_hcd_sim_host.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_hcd_sim_host_periodic_schedule PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function schedules new transfers from the periodic interrupt */
/* list. */
/* */
/* INPUT */
/* */
/* hcd_sim_host Pointer to host controller */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _ux_hcd_sim_host_frame_number_get Get frame number */
/* _ux_hcd_sim_host_transaction_schedule Schedule the transaction */
/* */
/* CALLED BY */
/* */
/* Host Simulator Controller Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
VOID _ux_hcd_sim_host_periodic_schedule(UX_HCD_SIM_HOST *hcd_sim_host)
{
UX_HCD_SIM_HOST_ED *ed;
ULONG frame_number;
/* Get the current frame number. */
_ux_hcd_sim_host_frame_number_get(hcd_sim_host, &frame_number);
/* Isolate the low bits to match an entry in the upper periodic entry list. */
frame_number &= UX_HCD_SIM_HOST_PERIODIC_ENTRY_MASK;
/* Get the first ED in the periodic list. */
ed = hcd_sim_host -> ux_hcd_sim_host_interrupt_ed_list[frame_number];
/* Search for an entry in the periodic tree. */
while (ed != UX_NULL)
{
/* The ED has to be a real ED (not static) and has to have a different tail and head TD. */
if ((ed -> ux_sim_host_ed_status != UX_HCD_SIM_HOST_ED_STATIC) && (ed -> ux_sim_host_ed_tail_td != ed -> ux_sim_host_ed_head_td))
{
/* Ensure this ED does not have the SKIP bit set and no TD are in progress. */
if ((ed -> ux_sim_host_ed_head_td -> ux_sim_host_td_status & UX_HCD_SIM_HOST_TD_ACK_PENDING) == 0)
/* Insert this transfer in the list of scheduled TDs if possible. */
_ux_hcd_sim_host_transaction_schedule(hcd_sim_host, ed);
}
/* Point to the next ED in the list. */
ed = ed -> ux_sim_host_ed_next_ed;
}
/* Return to caller. */
return;
}

View File

@ -0,0 +1,138 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Host Simulator Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_hcd_sim_host.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_hcd_sim_host_periodic_tree_create PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function creates the periodic static tree for the interrupt */
/* and isochronous EDs. */
/* */
/* INPUT */
/* */
/* hcd_sim_host Pointer to host controller */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* _ux_hcd_sim_host_ed_obtain Obtain host ED */
/* */
/* CALLED BY */
/* */
/* Host Simulator Controller Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_hcd_sim_host_periodic_tree_create(UX_HCD_SIM_HOST *hcd_sim_host)
{
UX_HCD_SIM_HOST_ED *ed;
UINT list_index;
UINT list_entries;
UINT current_list_entry;
UX_HCD_SIM_HOST_ED *ed_list[32];
UX_HCD_SIM_HOST_ED *ed_start_list[32];
/* Start with the 1st list - it has 32 entries. */
list_entries = 32;
/* Create each list one by one starting from the 32ms list. */
for (list_index = 0; list_index < 6; list_index++)
{
for (current_list_entry = 0; current_list_entry < list_entries; current_list_entry++)
{
/* In each list, insert an static ED as the anchor. There should not
be any errors when obtaining a new ED, still we do a sanity check. */
ed = _ux_hcd_sim_host_ed_obtain(hcd_sim_host);
if (ed == UX_NULL)
return(UX_NO_ED_AVAILABLE);
/* Mark this anchor ED as static by putting it as SKIPPED, the host simulator controller will
not look into its tail and head list and will simply jump to the next ED. */
ed -> ux_sim_host_ed_status = UX_HCD_SIM_HOST_ED_STATIC;
/* Either we hook this new ED to the start list for further processing
or we hook it to the 2 successive entries in the previous list. */
if (list_index == 0)
{
ed_start_list[current_list_entry] = ed;
}
else
{
ed_list[current_list_entry * 2] -> ux_sim_host_ed_next_ed = ed;
ed_list[(current_list_entry * 2) + 1] -> ux_sim_host_ed_next_ed = ed;
}
/* Memorize this ED in the local list. We do this operation now, otherwise
we would erase the previous list EDs. */
ed_list[current_list_entry] = ed;
}
/* Shift the number of entries in the next list by 1 (i.e. divide by 2). */
list_entries = list_entries >> 1;
}
/* The tree has been completed but the entries in the interrupt list are in the wrong order.
We need to swap each entry according to the host simulator specified entry order list
so that we have a fair interval frequency for each periodic ED. The primary EDs are
fetched from the start list, and stored in the interrupt list. */
for (current_list_entry = 0; current_list_entry < 32; current_list_entry++)
{
ed = ed_start_list[_ux_system_host_hcd_periodic_tree_entries[current_list_entry]];
hcd_sim_host -> ux_hcd_sim_host_interrupt_ed_list[current_list_entry] = ed;
}
/* Return successful completion. */
return(UX_SUCCESS);
}

View File

@ -0,0 +1,108 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Host Simulator Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_hcd_sim_host.h"
#include "ux_dcd_sim_slave.h"
#include "ux_device_stack.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_hcd_sim_host_port_reset PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* Implements the PORT_RESET request. */
/* */
/* INPUT */
/* */
/* hcd_sim_host Pointer to host controller */
/* port_index Port index to reset */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* _ux_device_stack_disconnect Simulate device disconnection */
/* _ux_dcd_sim_slave_initialize_complete Complete device initialization*/
/* */
/* CALLED BY */
/* */
/* Host Simulator Controller Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_hcd_sim_host_port_reset(UX_HCD_SIM_HOST *hcd_sim_host, ULONG port_index)
{
UX_SLAVE_DEVICE *device;
UX_PARAMETER_NOT_USED(hcd_sim_host);
UX_PARAMETER_NOT_USED(port_index);
/* Get a pointer to the device. */
device = &_ux_system_slave -> ux_system_slave_device;
/* Is this a connection? */
if (device -> ux_slave_device_state == UX_DEVICE_RESET)
/* Complete the device initialization. Note that everytime the device
is disconnected, this must be called again for connection. */
_ux_dcd_sim_slave_initialize_complete();
else
{
/* Host sent a PORT_RESET when the device is Attached, Addressed, or
Configured. Per the USB spec, we should go back to the default state.
We do this by 1) simulating disconnect to get rid of class and device
resources and 2) recreating necessary entities for control transfers. */
_ux_device_stack_disconnect();
_ux_dcd_sim_slave_initialize_complete();
}
/* In either case, mark the device as default/attached now. */
device -> ux_slave_device_state = UX_DEVICE_ATTACHED;
/* This function should never fail. */
return(UX_SUCCESS);
}

View File

@ -0,0 +1,125 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Host Simulator Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_hcd_sim_host.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_hcd_sim_host_port_status_get PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function will return the status for each port attached to the */
/* root HUB. */
/* */
/* INPUT */
/* */
/* hcd_sim_host Pointer to host controller */
/* port_index Port index */
/* */
/* OUTPUT */
/* */
/* Host Simulator Port Status */
/* */
/* Where port status has the following format: */
/* */
/* bit 0 device connection status */
/* if 0 : no device connected */
/* if 1 : device connected to the port */
/* bit 1 port enable status */
/* if 0 : port disabled */
/* if 1 : port enabled */
/* bit 2 port suspend status */
/* if 0 : port is not suspended */
/* if 1 : port is suspended */
/* bit 3 port overcurrent status */
/* if 0 : port has no overcurrent condition */
/* if 1 : port has overcurrent condition */
/* bit 4 port reset status */
/* if 0 : port is not in reset */
/* if 1 : port is in reset */
/* bit 5 port power status */
/* if 0 : port power is off */
/* if 1 : port power is on */
/* bit 6-7 device attached speed */
/* if 00 : low speed device attached */
/* if 01 : full speed device attached */
/* if 10 : high speed device attached */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Host Simulator Controller Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
ULONG _ux_hcd_sim_host_port_status_get(UX_HCD_SIM_HOST *hcd_sim_host, ULONG port_index)
{
ULONG port_status;
/* Check to see if this port is valid on this controller. */
if (hcd_sim_host -> ux_hcd_sim_host_nb_root_hubs < port_index)
{
/* Error trap. */
_ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_HCD, UX_PORT_INDEX_UNKNOWN);
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_PORT_INDEX_UNKNOWN, port_index, 0, 0, UX_TRACE_ERRORS, 0, 0)
return(UX_PORT_INDEX_UNKNOWN);
}
/* The port is valid, build the status mask for this port. This function
returns always returned a device connected. */
port_status = UX_PS_CCS;
/* And this is a Full speed device. */
port_status |= UX_PS_DS_FS;
/* Return port status. */
return(port_status);
}

View File

@ -0,0 +1,116 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Host Simulator Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_hcd_sim_host.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_hcd_sim_host_regular_td_obtain PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function obtains a free TD from the regular TD list. */
/* */
/* INPUT */
/* */
/* hcd_sim_host Pointer to host controller */
/* */
/* OUTPUT */
/* */
/* UX_HCD_SIM_HOST_TD * Pointer to host TD */
/* */
/* CALLS */
/* */
/* _ux_utility_memory_set Set memory block */
/* _ux_utility_mutex_on Get mutex protection */
/* _ux_utility_mutex_off Release mutex protection */
/* */
/* CALLED BY */
/* */
/* Host Simulator Controller Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UX_HCD_SIM_HOST_TD *_ux_hcd_sim_host_regular_td_obtain(UX_HCD_SIM_HOST *hcd_sim_host)
{
UX_HCD_SIM_HOST_TD *td;
ULONG td_index;
/* Get the mutex as this is a critical section. */
_ux_utility_mutex_on(&_ux_system -> ux_system_mutex);
/* Start the search from the beginning of the list. */
td = hcd_sim_host -> ux_hcd_sim_host_td_list;
for (td_index = 0; td_index < _ux_system_host -> ux_system_host_max_td; td_index++)
{
/* Check the TD status, a free TD is marked with the UNUSED flag. */
if (td -> ux_sim_host_td_status == UX_UNUSED)
{
/* The TD may have been used, so we reset all fields. */
_ux_utility_memory_set(td, 0, sizeof(UX_HCD_SIM_HOST_TD));
/* This TD is now marked as USED. */
td -> ux_sim_host_td_status = UX_USED;
/* Release the mutex protection. */
_ux_utility_mutex_off(&_ux_system -> ux_system_mutex);
/* Return the TD pointer. */
return(td);
}
/* Move to next TD. */
td++;
}
/* There is no available TD in the TD list. */
/* Release the mutex protection. */
_ux_utility_mutex_off(&_ux_system -> ux_system_mutex);
/* Return a NULL pointer. */
return(UX_NULL);
}

View File

@ -0,0 +1,219 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Host Simulator Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_hcd_sim_host.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_hcd_sim_host_request_bulk_transfer PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function performs a bulk transfer request. A bulk transfer */
/* can be larger than the size of the sim_host buffer so it may be */
/* required to chain multiple TDs to accommodate this transfer */
/* request. A bulk transfer is non blocking, so we return before the */
/* transfer request is completed. */
/* */
/* INPUT */
/* */
/* hcd_sim_host Pointer to host controller */
/* transfer_request Pointer to transfer request */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* _ux_hcd_sim_host_regular_td_obtain Obtain regular TD */
/* */
/* CALLED BY */
/* */
/* Host Simulator Controller Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_hcd_sim_host_request_bulk_transfer(UX_HCD_SIM_HOST *hcd_sim_host, UX_TRANSFER *transfer_request)
{
UX_ENDPOINT *endpoint;
UX_HCD_SIM_HOST_TD *data_td;
UX_HCD_SIM_HOST_TD *start_data_td;
UX_HCD_SIM_HOST_TD *next_data_td;
UX_HCD_SIM_HOST_TD *previous_td;
UX_HCD_SIM_HOST_TD *tail_td;
UX_HCD_SIM_HOST_ED *ed;
ULONG transfer_request_payload_length;
ULONG bulk_packet_payload_length;
UCHAR * data_pointer;
/* Get the pointer to the Endpoint. */
endpoint = (UX_ENDPOINT *) transfer_request -> ux_transfer_request_endpoint;
/* Now get the physical ED attached to this endpoint. */
ed = endpoint -> ux_endpoint_ed;
/* Use the TD pointer by ed -> tail for the first TD of this transfer
and chain from this one on. */
data_td = ed -> ux_sim_host_ed_tail_td;
previous_td = data_td;
/* Reset the first obtained data TD in case there is a TD shortage while building
the list of TDs. */
start_data_td = 0;
/* It may take more than one TD if the transfer_request length is more than the
maximum length for a host simulator TD (this is irrelevant of the MaxPacketSize value
in the endpoint descriptor). Host simulator data payload has a maximum size of 4K. */
transfer_request_payload_length = transfer_request -> ux_transfer_request_requested_length;
data_pointer = transfer_request -> ux_transfer_request_data_pointer;
while (transfer_request_payload_length != 0)
{
if (transfer_request_payload_length > UX_HCD_SIM_HOST_MAX_PAYLOAD)
bulk_packet_payload_length = UX_HCD_SIM_HOST_MAX_PAYLOAD;
else
bulk_packet_payload_length = transfer_request_payload_length;
/* Store the beginning of the buffer address in the TD. */
data_td -> ux_sim_host_td_buffer = data_pointer;
/* Update the length of the transfer for this TD. */
data_td -> ux_sim_host_td_length = bulk_packet_payload_length;
/* Attach the endpoint and transfer_request to the TD. */
data_td -> ux_sim_host_td_transfer_request = transfer_request;
data_td -> ux_sim_host_td_ed = ed;
/* Adjust the data payload length and the data payload pointer. */
transfer_request_payload_length -= bulk_packet_payload_length;
data_pointer += bulk_packet_payload_length;
/* The direction of the transaction is set in the TD. */
if ((transfer_request -> ux_transfer_request_type & UX_REQUEST_DIRECTION) == UX_REQUEST_IN)
data_td -> ux_sim_host_td_direction = UX_HCD_SIM_HOST_TD_IN;
else
data_td -> ux_sim_host_td_direction = UX_HCD_SIM_HOST_TD_OUT;
/* Mark the TD with the DATA phase. */
data_td -> ux_sim_host_td_status |= UX_HCD_SIM_HOST_TD_DATA_PHASE;
/* The Toggle value is in the ED. */
data_td -> ux_sim_host_td_toggle = UX_HCD_SIM_HOST_TD_TOGGLE_FROM_ED;
/* Check if there will be another transaction. */
if (transfer_request_payload_length != 0)
{
/* Get a new TD to hook this payload. */
data_td = _ux_hcd_sim_host_regular_td_obtain(hcd_sim_host);
if (data_td == UX_NULL)
{
/* If there was already a TD chain in progress, free it. */
if (start_data_td != UX_NULL)
{
data_td = start_data_td;
while (data_td)
{
next_data_td = data_td -> ux_sim_host_td_next_td;
data_td -> ux_sim_host_td_status = UX_UNUSED;
data_td = next_data_td;
}
}
return(UX_NO_TD_AVAILABLE);
}
/* the first obtained TD in the chain has to be remembered. */
if (start_data_td == UX_NULL)
start_data_td = data_td;
/* Attach this new TD to the previous one. */
previous_td -> ux_sim_host_td_next_td = data_td;
previous_td -> ux_sim_host_td_next_td_transfer_request = data_td;
previous_td = data_td;
}
}
/* At this stage, the Head and Tail in the ED are still the same and the host simulator
controller will skip this ED until we have hooked the new tail TD. */
tail_td = _ux_hcd_sim_host_regular_td_obtain(hcd_sim_host);
if (tail_td == UX_NULL)
{
/* If there was already a TD chain in progress, free it. */
if (start_data_td != UX_NULL)
{
data_td = start_data_td;
while (data_td)
{
next_data_td = data_td -> ux_sim_host_td_next_td;
data_td -> ux_sim_host_td_status = UX_UNUSED;
data_td = next_data_td;
}
}
return(UX_NO_TD_AVAILABLE);
}
/* Attach the tail TD to the last data TD. */
data_td -> ux_sim_host_td_next_td = tail_td;
/* Store the new tail TD. */
ed -> ux_sim_host_ed_tail_td = tail_td;
/* Now we can tell the scheduler to wake up. */
hcd_sim_host -> ux_hcd_sim_host_queue_empty = UX_FALSE;
/* Return successful completion. */
return(UX_SUCCESS);
}

View File

@ -0,0 +1,321 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Host Simulator Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_hcd_sim_host.h"
#include "ux_host_stack.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_hcd_sim_host_request_control_transfer PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function performs a control transfer from a transfer request. */
/* The USB control transfer is in 3 phases (setup, data, status). */
/* This function will chain all phases of the control sequence before */
/* setting the sim_host endpoint as a candidate for transfer. */
/* */
/* INPUT */
/* */
/* hcd_sim_host Pointer to host controller */
/* transfer_request Pointer to transfer request */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* _ux_hcd_sim_host_regular_td_obtain Obtain regular TD */
/* _ux_host_stack_transfer_request_abort Abort transfer request */
/* _ux_utility_memory_allocate Allocate memory block */
/* _ux_utility_memory_free Release memory block */
/* _ux_utility_semaphore_get Get semaphore */
/* _ux_utility_short_put Write 16-bit value */
/* */
/* CALLED BY */
/* */
/* Host Simulator Controller Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_hcd_sim_host_request_control_transfer(UX_HCD_SIM_HOST *hcd_sim_host, UX_TRANSFER *transfer_request)
{
UX_ENDPOINT *endpoint;
UCHAR *setup_request;
UX_HCD_SIM_HOST_ED *ed;
UX_HCD_SIM_HOST_TD *setup_td;
UX_HCD_SIM_HOST_TD *chain_td;
UX_HCD_SIM_HOST_TD *data_td;
UX_HCD_SIM_HOST_TD *tail_td;
UX_HCD_SIM_HOST_TD *status_td;
UX_HCD_SIM_HOST_TD *start_data_td;
UX_HCD_SIM_HOST_TD *next_data_td;
UINT status;
ULONG transfer_request_payload_length;
ULONG control_packet_payload_length;
UCHAR *data_pointer;
/* Get the pointer to the endpoint. */
endpoint = (UX_ENDPOINT *) transfer_request -> ux_transfer_request_endpoint;
/* Now get the physical ED attached to this endpoint. */
ed = endpoint -> ux_endpoint_ed;
/* Build the SETUP packet (phase 1 of the control transfer). */
setup_request = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, UX_SETUP_SIZE);
if (setup_request == UX_NULL)
return(UX_MEMORY_INSUFFICIENT);
*setup_request = (UCHAR)transfer_request -> ux_transfer_request_function;
*(setup_request + UX_SETUP_REQUEST_TYPE) = (UCHAR)transfer_request -> ux_transfer_request_type;
*(setup_request + UX_SETUP_REQUEST) = (UCHAR)transfer_request -> ux_transfer_request_function;
_ux_utility_short_put(setup_request + UX_SETUP_VALUE, (USHORT)transfer_request -> ux_transfer_request_value);
_ux_utility_short_put(setup_request + UX_SETUP_INDEX, (USHORT)transfer_request -> ux_transfer_request_index);
_ux_utility_short_put(setup_request + UX_SETUP_LENGTH, (USHORT) transfer_request -> ux_transfer_request_requested_length);
/* Use the TD pointer by ed -> tail for our setup TD and chain from this one on. */
setup_td = ed -> ux_sim_host_ed_tail_td;
setup_td -> ux_sim_host_td_buffer = setup_request;
setup_td -> ux_sim_host_td_length = UX_SETUP_SIZE;
chain_td = setup_td;
/* Attach the endpoint and transfer_request to the TD. */
setup_td -> ux_sim_host_td_transfer_request = transfer_request;
setup_td -> ux_sim_host_td_ed = ed;
/* Setup is OUT. */
setup_td -> ux_sim_host_td_direction = UX_HCD_SIM_HOST_TD_OUT;
/* Mark TD toggle as being DATA0. */
setup_td -> ux_sim_host_td_toggle = 0;
/* Mark the TD with the SETUP phase. */
setup_td -> ux_sim_host_td_status |= UX_HCD_SIM_HOST_TD_SETUP_PHASE;
/* Check if there is a data phase, if not jump to status phase. */
data_td = UX_NULL;
start_data_td = UX_NULL;
/* Use local variables to manipulate data pointer and length. */
transfer_request_payload_length = transfer_request -> ux_transfer_request_requested_length;
data_pointer = transfer_request -> ux_transfer_request_data_pointer;
/* Data starts with DATA1. For the data phase, we use the ED to contain the toggle. */
ed -> ux_sim_host_ed_toggle = 1;
/* The Control data payload may be split into several smaller blocks. */
while (transfer_request_payload_length != 0)
{
/* Get a new TD to hook this payload. */
data_td = _ux_hcd_sim_host_regular_td_obtain(hcd_sim_host);
if (data_td == UX_NULL)
{
/* Free the Setup packet resources. */
_ux_utility_memory_free(setup_request);
/* If there was already a TD chain in progress, free it. */
if (start_data_td != UX_NULL)
{
data_td = start_data_td;
while (data_td)
{
next_data_td = data_td -> ux_sim_host_td_next_td;
data_td -> ux_sim_host_td_status = UX_UNUSED;
data_td = next_data_td;
}
}
return(UX_NO_TD_AVAILABLE);
}
/* Check the current payload requirement for the max size. */
if (transfer_request_payload_length > UX_HCD_SIM_HOST_MAX_PAYLOAD)
control_packet_payload_length = UX_HCD_SIM_HOST_MAX_PAYLOAD;
else
control_packet_payload_length = transfer_request_payload_length;
/* Store the beginning of the buffer address in the TD. */
data_td -> ux_sim_host_td_buffer = data_pointer;
/* Update the length of the transfer for this TD. */
data_td -> ux_sim_host_td_length = control_packet_payload_length;
/* Attach the endpoint and transfer request to the TD. */
data_td -> ux_sim_host_td_transfer_request = transfer_request;
data_td -> ux_sim_host_td_ed = ed;
/* Adjust the data payload length and the data payload pointer. */
transfer_request_payload_length -= control_packet_payload_length;
data_pointer += control_packet_payload_length;
/* The direction of the transaction is set in the TD. */
if ((transfer_request -> ux_transfer_request_type & UX_REQUEST_DIRECTION) == UX_REQUEST_IN)
data_td -> ux_sim_host_td_direction = UX_HCD_SIM_HOST_TD_IN;
else
data_td -> ux_sim_host_td_direction = UX_HCD_SIM_HOST_TD_OUT;
/* Mark the TD with the DATA phase. */
data_td -> ux_sim_host_td_status |= UX_HCD_SIM_HOST_TD_DATA_PHASE;
/* The Toggle value is in the ED. */
data_td -> ux_sim_host_td_toggle = UX_HCD_SIM_HOST_TD_TOGGLE_FROM_ED;
/* The first obtained TD in the chain has to be remembered. */
if (start_data_td == UX_NULL)
start_data_td = data_td;
/* Attach this new TD to the previous one. */
chain_td -> ux_sim_host_td_next_td = data_td;
chain_td -> ux_sim_host_td_next_td_transfer_request = data_td;
chain_td = data_td;
}
/* Now, program the status phase. */
status_td = _ux_hcd_sim_host_regular_td_obtain(hcd_sim_host);
if (status_td == UX_NULL)
{
_ux_utility_memory_free(setup_request);
if (data_td != UX_NULL)
{
data_td = start_data_td;
while (data_td)
{
next_data_td = data_td -> ux_sim_host_td_next_td;
data_td -> ux_sim_host_td_status = UX_UNUSED;
data_td = next_data_td;
}
}
return(UX_NO_TD_AVAILABLE);
}
/* Attach the endpoint and transfer request to the TD. */
status_td -> ux_sim_host_td_transfer_request = transfer_request;
status_td -> ux_sim_host_td_ed = ed;
/* Mark the TD with the STATUS phase. */
status_td -> ux_sim_host_td_status |= UX_HCD_SIM_HOST_TD_STATUS_PHASE;
/* The direction of the status phase is IN if data phase is OUT and
vice versa. */
if ((transfer_request -> ux_transfer_request_type&UX_REQUEST_DIRECTION) == UX_REQUEST_IN)
status_td -> ux_sim_host_td_direction = UX_HCD_SIM_HOST_TD_OUT;
else
status_td -> ux_sim_host_td_direction = UX_HCD_SIM_HOST_TD_IN;
/* No data payload for the status phase. */
status_td -> ux_sim_host_td_buffer = 0;
status_td -> ux_sim_host_td_length = 0;
/* Status Phase toggle is ALWAYS 1. */
status_td -> ux_sim_host_td_toggle = 1;
/* Hook the status phase to the previous TD. */
chain_td -> ux_sim_host_td_next_td = status_td;
/* Since we have consumed out tail TD for the setup packet, we must get another one
and hook it to the ED's tail. */
tail_td = _ux_hcd_sim_host_regular_td_obtain(hcd_sim_host);
if (tail_td == UX_NULL)
{
_ux_utility_memory_free(setup_request);
if (data_td != UX_NULL)
data_td -> ux_sim_host_td_status = UX_UNUSED;
status_td -> ux_sim_host_td_status = UX_UNUSED;
return(UX_NO_TD_AVAILABLE);
}
/* Hook the new TD to the status TD. */
status_td -> ux_sim_host_td_next_td = tail_td;
/* At this stage, the Head and Tail in the ED are still the same and
the host simulator controller will skip this ED until we have hooked the new
tail TD. */
ed -> ux_sim_host_ed_tail_td = tail_td;
/* Now we can tell the scheduler to wake up. */
hcd_sim_host -> ux_hcd_sim_host_queue_empty = UX_FALSE;
/* Wait for the completion of the transfer request. */
status = _ux_utility_semaphore_get(&transfer_request -> ux_transfer_request_semaphore, MS_TO_TICK(UX_CONTROL_TRANSFER_TIMEOUT));
/* If the semaphore did not succeed we probably have a time out. */
if (status != UX_SUCCESS)
{
/* All transfers pending need to abort. There may have been a partial transfer. */
_ux_host_stack_transfer_request_abort(transfer_request);
/* There was an error, return to the caller. */
transfer_request -> ux_transfer_request_completion_code = UX_TRANSFER_TIMEOUT;
/* Error trap. */
_ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_HCD, UX_TRANSFER_TIMEOUT);
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_TRANSFER_TIMEOUT, transfer_request, 0, 0, UX_TRACE_ERRORS, 0, 0)
}
/* Free the resources. */
_ux_utility_memory_free(setup_request);
/* Return completion to caller. */
return(transfer_request -> ux_transfer_request_completion_code);
}

View File

@ -0,0 +1,135 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Host Simulator Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_hcd_sim_host.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_hcd_sim_host_request_interrupt_transfer PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function performs an interrupt transfer request. An interrupt */
/* transfer can only be as large as the Maxpacket Field in the */
/* endpoint descriptor. This was verified at the USB layer and does */
/* not need to be reverified here. */
/* */
/* INPUT */
/* */
/* hcd_sim_host Pointer to host controller */
/* transfer_request Pointer to transfer request */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* _ux_hcd_sim_host_regular_td_obtain Obtain regular TD */
/* */
/* CALLED BY */
/* */
/* Host Simulator Controller Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_hcd_sim_host_request_interrupt_transfer(UX_HCD_SIM_HOST *hcd_sim_host, UX_TRANSFER *transfer_request)
{
UX_ENDPOINT *endpoint;
UX_HCD_SIM_HOST_ED *ed;
UX_HCD_SIM_HOST_TD *data_td;
UX_HCD_SIM_HOST_TD *tail_td;
/* Get the pointer to the Endpoint. */
endpoint = (UX_ENDPOINT *) transfer_request -> ux_transfer_request_endpoint;
/* Now get the physical ED attached to this endpoint. */
ed = endpoint -> ux_endpoint_ed;
/* Use the TD pointer by ed -> tail for the first TD of this transfer
and chain from this one on. */
data_td = ed -> ux_sim_host_ed_tail_td;
/* Set the direction of the transfer. */
if ((transfer_request -> ux_transfer_request_type & UX_REQUEST_DIRECTION) == UX_REQUEST_IN)
data_td -> ux_sim_host_td_direction = UX_HCD_SIM_HOST_TD_IN;
else
data_td -> ux_sim_host_td_direction = UX_HCD_SIM_HOST_TD_OUT;
/* Mark the TD with the DATA phase. */
data_td -> ux_sim_host_td_status |= UX_HCD_SIM_HOST_TD_DATA_PHASE;
/* The Toggle value is in the ED. */
data_td -> ux_sim_host_td_toggle = UX_HCD_SIM_HOST_TD_TOGGLE_FROM_ED;
/* Store the beginning of the buffer address in the TD. */
data_td -> ux_sim_host_td_buffer = transfer_request -> ux_transfer_request_data_pointer;
/* Update the length of the transfer for this TD. */
data_td -> ux_sim_host_td_length = transfer_request -> ux_transfer_request_requested_length;
/* Attach the endpoint and transfer request to the TD. */
data_td -> ux_sim_host_td_transfer_request = transfer_request;
data_td -> ux_sim_host_td_ed = ed;
/* At this stage, the Head and Tail in the ED are still the same and
the host simulator controller will skip this ED until we have hooked the new
tail TD. */
tail_td = _ux_hcd_sim_host_regular_td_obtain(hcd_sim_host);
if (tail_td == UX_NULL)
return(UX_NO_TD_AVAILABLE);
/* Attach the tail TD to the last data TD. */
data_td -> ux_sim_host_td_next_td = tail_td;
/* Store the new tail TD. */
ed -> ux_sim_host_ed_tail_td = tail_td;
/* Now we can tell the scheduler to wake up. */
hcd_sim_host -> ux_hcd_sim_host_queue_empty = UX_FALSE;
/* There is no need to wake up the sim_host controller on this transfer
since periodic transactions will be picked up when the interrupt
tree is scanned. */
return(UX_SUCCESS);
}

View File

@ -0,0 +1,230 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Host Simulator Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_hcd_sim_host.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_hcd_sim_host_request_isochronous_transfer PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function performs an isochronous transfer request. */
/* */
/* INPUT */
/* */
/* hcd_sim_host Pointer to host controller */
/* transfer_request Pointer to transfer request */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* _ux_hcd_sim_host_frame_number_get Get frame number */
/* _ux_hcd_sim_host_isochronous_td_obtain Obtain isochronous TD */
/* */
/* CALLED BY */
/* */
/* Host Simulator Controller Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_hcd_sim_host_request_isochronous_transfer(UX_HCD_SIM_HOST *hcd_sim_host, UX_TRANSFER *transfer_request)
{
UX_ENDPOINT *endpoint;
UX_HCD_SIM_HOST_ISO_TD *data_td;
UX_HCD_SIM_HOST_ISO_TD *start_data_td;
UX_HCD_SIM_HOST_ISO_TD *next_data_td;
UX_HCD_SIM_HOST_ISO_TD *previous_td;
UX_HCD_SIM_HOST_ISO_TD *tail_td;
UX_HCD_SIM_HOST_ED *ed;
ULONG transfer_request_payload_length;
ULONG isoch_packet_payload_length;
UCHAR * data_pointer;
ULONG current_frame_number;
/* Get the pointer to the Endpoint. */
endpoint = (UX_ENDPOINT *) transfer_request -> ux_transfer_request_endpoint;
/* Now get the physical ED attached to this endpoint. */
ed = endpoint -> ux_endpoint_ed;
/* If the transfer_request specifies a max packet length other than the endpoint
size, we force the transfer request value into the endpoint. */
if (transfer_request -> ux_transfer_request_packet_length == 0)
transfer_request -> ux_transfer_request_packet_length = (ULONG) endpoint -> ux_endpoint_descriptor.wMaxPacketSize;
/* Remember the packet length. */
isoch_packet_payload_length = transfer_request -> ux_transfer_request_packet_length;
/* Use the TD pointer by ed -> tail for the first TD of this transfer and chain from this one on. */
data_td = (UX_HCD_SIM_HOST_ISO_TD *) ((void *) ed -> ux_sim_host_ed_tail_td);
previous_td = data_td;
/* Reset the first obtained data TD in case there is a TD shortage while building the list of TDs. */
start_data_td = UX_NULL;
/* Calculate the frame number to be used to send this payload. If there are no current transfers,
we take the current frame number and add a safety value (2-5) to it. If here is pending transactions,
we use the frame number stored in the transfer request. */
if (ed -> ux_sim_host_ed_tail_td == ed -> ux_sim_host_ed_head_td)
{
_ux_hcd_sim_host_frame_number_get(hcd_sim_host, &current_frame_number);
ed -> ux_sim_host_ed_frame = current_frame_number + UX_HCD_SIM_HOST_FRAME_DELAY;
}
else
{
current_frame_number = ed -> ux_sim_host_ed_frame;
}
/* Load the start buffer address and URB length to split the URB in multiple TD transfer. */
transfer_request_payload_length = transfer_request -> ux_transfer_request_requested_length;
data_pointer = transfer_request -> ux_transfer_request_data_pointer;
while (transfer_request_payload_length != 0)
{
/* Set the direction of the TD. */
if ((transfer_request -> ux_transfer_request_type&UX_REQUEST_DIRECTION) == UX_REQUEST_IN)
data_td -> ux_sim_host_iso_td_direction = UX_HCD_SIM_HOST_TD_IN;
else
data_td -> ux_sim_host_iso_td_direction = UX_HCD_SIM_HOST_TD_OUT;
/* Set the frame number. */
ed -> ux_sim_host_ed_frame = current_frame_number;
/* Set the buffer address. */
data_td -> ux_sim_host_iso_td_buffer = data_pointer;
/* Update the length of the transfer for this TD. */
data_td -> ux_sim_host_iso_td_length = isoch_packet_payload_length;
/* Attach the endpoint and transfer request to the TD. */
data_td -> ux_sim_host_iso_td_transfer_request = transfer_request;
data_td -> ux_sim_host_iso_td_ed = ed;
/* Adjust the data payload length and the data payload pointer. */
transfer_request_payload_length -= isoch_packet_payload_length;
data_pointer += isoch_packet_payload_length;
/* Prepare the next frame for the next TD in advance. */
current_frame_number++;
/* Check if there will be another transaction. */
if (transfer_request_payload_length != 0)
{
/* Get a new TD to hook this payload. */
data_td = _ux_hcd_sim_host_isochronous_td_obtain(hcd_sim_host);
if (data_td == UX_NULL)
{
/* If there was already a TD chain in progress, free it. */
if (start_data_td != UX_NULL)
{
data_td = start_data_td;
while(data_td)
{
next_data_td = data_td -> ux_sim_host_iso_td_next_td;
data_td -> ux_sim_host_iso_td_status = UX_UNUSED;
data_td = next_data_td;
}
}
return(UX_NO_TD_AVAILABLE);
}
/* the first obtained TD in the chain has to be remembered. */
if (start_data_td == UX_NULL)
start_data_td = data_td;
/* Attach this new TD to the previous one. */
previous_td -> ux_sim_host_iso_td_next_td = data_td;
previous_td = data_td;
}
}
/* Memorize the next frame number for this ED. */
ed -> ux_sim_host_ed_frame = current_frame_number;
/* At this stage, the Head and Tail in the ED are still the same and the host simulator controller
will skip this ED until we have hooked the new tail TD. */
tail_td = _ux_hcd_sim_host_isochronous_td_obtain(hcd_sim_host);
if (tail_td == UX_NULL)
{
/* If there was already a TD chain in progress, free it. */
if (start_data_td != UX_NULL)
{
data_td = start_data_td;
while(data_td)
{
next_data_td = data_td -> ux_sim_host_iso_td_next_td;
data_td -> ux_sim_host_iso_td_status = UX_UNUSED;
data_td = next_data_td;
}
}
return(UX_NO_TD_AVAILABLE);
}
/* Attach the tail TD to the last data TD. */
data_td -> ux_sim_host_iso_td_next_td = tail_td;
/* Adjust the ED tail pointer, the controller can now start this transfer
at the chosen frame number. */
ed -> ux_sim_host_ed_tail_td = (UX_HCD_SIM_HOST_TD *) ((void *) tail_td);
/* Return successful completion. */
return(UX_SUCCESS);
}

View File

@ -0,0 +1,124 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Host Simulator Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_hcd_sim_host.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_hcd_sim_host_request_transfer PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function is the handler for all the transactions on the USB. */
/* The transfer request passed as parameter contains the endpoint and */
/* the device descriptors in addition to the type of transaction de */
/* be executed. This function routes the transfer request to */
/* according to the type of transfer to be executed. */
/* */
/* INPUT */
/* */
/* hcd_sim_host Pointer to host controller */
/* transfer_request Pointer to transfer request */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* _ux_hcd_sim_host_request_bulk_transfer Request bulk transfer */
/* _ux_hcd_sim_host_request_control_transfer Request control */
/* transfer */
/* _ux_hcd_sim_host_request_interrupt_transfer Request interrupt */
/* transfer */
/* _ux_hcd_sim_host_request_isochronous_transfer Request isochronous */
/* transfer */
/* */
/* CALLED BY */
/* */
/* Host Simulator Controller Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_hcd_sim_host_request_transfer(UX_HCD_SIM_HOST *hcd_sim_host, UX_TRANSFER *transfer_request)
{
UX_ENDPOINT *endpoint;
UINT status = 0;
/* Get the pointer to the Endpoint. */
endpoint = (UX_ENDPOINT *) transfer_request -> ux_transfer_request_endpoint;
/* We reset the actual length field of the transfer request as a safety measure. */
transfer_request -> ux_transfer_request_actual_length = 0;
/* Isolate the endpoint type and route the transfer request. */
switch ((endpoint -> ux_endpoint_descriptor.bmAttributes) & UX_MASK_ENDPOINT_TYPE)
{
case UX_CONTROL_ENDPOINT:
status = _ux_hcd_sim_host_request_control_transfer(hcd_sim_host, transfer_request);
break;
case UX_BULK_ENDPOINT:
status = _ux_hcd_sim_host_request_bulk_transfer(hcd_sim_host, transfer_request);
break;
case UX_INTERRUPT_ENDPOINT:
status = _ux_hcd_sim_host_request_interrupt_transfer(hcd_sim_host, transfer_request);
break;
case UX_ISOCHRONOUS_ENDPOINT:
status = _ux_hcd_sim_host_request_isochronous_transfer(hcd_sim_host, transfer_request);
break;
}
/* Note that it is physically impossible to have a wrong endpoint type here
so no error checking. */
return(status);
}

View File

@ -0,0 +1,97 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Host Simulator Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_hcd_sim_host.h"
#include "tx_timer.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_hcd_sim_host_timer_function PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function is the timer function of the simulator. It is */
/* invoked on a timer every tick. */
/* */
/* INPUT */
/* */
/* hcd_sim_host_addr Address of host controller */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _ux_utility_semaphore_put Put semaphore */
/* */
/* CALLED BY */
/* */
/* ThreadX */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
VOID _ux_hcd_sim_host_timer_function(ULONG hcd_sim_host_addr)
{
UX_HCD_SIM_HOST *hcd_sim_host;
UX_HCD *hcd;
/* Setup pointer to simulator host structure. */
UX_TIMER_EXTENSION_PTR_GET(hcd_sim_host, UX_HCD_SIM_HOST, hcd_sim_host_addr)
/* Get the pointers to the generic HCD areas. */
hcd = hcd_sim_host -> ux_hcd_sim_host_hcd_owner;
/* Increase the interrupt count. This indicates the controller is still alive. */
hcd_sim_host -> ux_hcd_sim_host_interrupt_count++;
/* Check if the controller is operational, if not, skip it. */
if (hcd -> ux_hcd_status == UX_HCD_STATUS_OPERATIONAL)
{
/* Wake up the thread for the controller transaction processing. */
hcd -> ux_hcd_thread_signal++;
_ux_utility_semaphore_put(&_ux_system_host -> ux_system_host_hcd_semaphore);
}
}

View File

@ -0,0 +1,495 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Host Simulator Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
#define UX_SOURCE_CODE
/* Include necessary system files. */
#include "ux_api.h"
#include "ux_hcd_sim_host.h"
#include "ux_dcd_sim_slave.h"
#include "ux_device_stack.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_hcd_sim_host_transaction_schedule PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function bridges a transaction from the host to the slave */
/* simulation controller. */
/* */
/* INPUT */
/* */
/* hcd_sim_host Pointer to host controller */
/* ed Pointer to ED */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* (ux_transfer_request_completion_function) */
/* Completion function */
/* _ux_device_stack_control_request_process */
/* Process request */
/* _ux_utility_memory_copy Copy memory block */
/* _ux_utility_semaphore_put Semaphore put */
/* */
/* CALLED BY */
/* */
/* Host Simulator Controller Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_hcd_sim_host_transaction_schedule(UX_HCD_SIM_HOST *hcd_sim_host, UX_HCD_SIM_HOST_ED *ed)
{
UX_DCD_SIM_SLAVE *dcd_sim_slave;
UX_HCD_SIM_HOST_TD *td;
UX_HCD_SIM_HOST_TD *head_td;
UX_HCD_SIM_HOST_TD *tail_td;
UX_HCD_SIM_HOST_TD *data_td;
UX_ENDPOINT *endpoint;
UX_SLAVE_ENDPOINT *slave_endpoint;
UX_DCD_SIM_SLAVE_ED *slave_ed;
ULONG slave_transfer_remaining;
UCHAR wake_host;
UCHAR wake_slave;
ULONG transaction_length;
UX_SLAVE_TRANSFER *slave_transfer_request;
UX_TRANSFER *transfer_request;
ULONG endpoint_index;
UX_SLAVE_DCD *dcd;
UX_PARAMETER_NOT_USED(hcd_sim_host);
/* Get the pointer to the DCD portion of the simulator. */
dcd = &_ux_system_slave -> ux_system_slave_dcd;
/* Check the state of the controller if OPERATIONAL . */
if (dcd -> ux_slave_dcd_status != UX_DCD_STATUS_OPERATIONAL)
return(UX_ERROR);
/* Get the pointer to the candidate TD on the host. */
td = ed -> ux_sim_host_ed_head_td;
/* Get the pointer to the endpoint. */
endpoint = ed -> ux_sim_host_ed_endpoint;
/* Get the pointer to the transfer_request attached with this TD. */
transfer_request = td -> ux_sim_host_td_transfer_request;
/* Get the index of the endpoint from the host. */
endpoint_index = endpoint -> ux_endpoint_descriptor.bEndpointAddress & ~(ULONG)UX_ENDPOINT_DIRECTION;
/* Get the address of the device controller. */
dcd_sim_slave = (UX_DCD_SIM_SLAVE *) dcd -> ux_slave_dcd_controller_hardware;
/* Get the endpoint as seen from the device side. */
slave_ed = &dcd_sim_slave -> ux_dcd_sim_slave_ed[endpoint_index];
/* Is this ED used? */
if ((slave_ed -> ux_sim_slave_ed_status & UX_DCD_SIM_SLAVE_ED_STATUS_USED) == 0)
return(UX_ERROR);
/* Is this ED ready for transaction or stalled ? */
if ((slave_ed -> ux_sim_slave_ed_status & (UX_DCD_SIM_SLAVE_ED_STATUS_TRANSFER | UX_DCD_SIM_SLAVE_ED_STATUS_STALLED)) == 0)
return(UX_ERROR);
/* Get the logical endpoint from the physical endpoint. */
slave_endpoint = slave_ed -> ux_sim_slave_ed_endpoint;
/* Get the pointer to the transfer request. */
slave_transfer_request = &slave_endpoint -> ux_slave_endpoint_transfer_request;
/* Check the phase for this transfer, if this is the SETUP phase, treatment is different. Explanation of how
control transfers are handled in the simulator: if the data phase is OUT, we handle it immediately, meaning we
send all the data to the device and remove the STATUS TD in the same scheduler call. If the data phase is IN, we
only take out the SETUP TD and handle the data phase like any other non-control transactions (i.e. the scheduler
calls us again with the DATA TDs). */
if (td -> ux_sim_host_td_status & UX_HCD_SIM_HOST_TD_SETUP_PHASE)
{
/* For control transfer, stall is for protocol error and it's cleared any time when SETUP is received */
slave_ed -> ux_sim_slave_ed_status &= ~(ULONG)UX_DCD_SIM_SLAVE_ED_STATUS_STALLED;
/* Set the length to the setup transaction buffer. */
slave_transfer_request -> ux_slave_transfer_request_actual_length = td -> ux_sim_host_td_length;
/* Move the buffer from the host TD to the device TD. */
_ux_utility_memory_copy(slave_transfer_request -> ux_slave_transfer_request_setup, td -> ux_sim_host_td_buffer,
td -> ux_sim_host_td_length);
/* The setup phase never fails. We acknowledge the transfer code here by taking the TD out of the endpoint. */
ed -> ux_sim_host_ed_head_td = td -> ux_sim_host_td_next_td;
/* Free the TD that was used here. */
td -> ux_sim_host_td_status = UX_UNUSED;
/* Check if the transaction is OUT from the host and there is data payload. */
if (((*slave_transfer_request -> ux_slave_transfer_request_setup & UX_REQUEST_IN) == 0) &&
(*(slave_transfer_request -> ux_slave_transfer_request_setup + 6) != 0 ||
*(slave_transfer_request -> ux_slave_transfer_request_setup + 7) != 0))
{
/* This is the case where there is a data payload OUT from host to device.
the data needs to be copied into the device buffer first before invoking the control
dispatcher. */
/* Get the length we expect from the SETUP packet. */
slave_transfer_request -> ux_slave_transfer_request_requested_length = _ux_utility_short_get(slave_transfer_request -> ux_slave_transfer_request_setup + 6);
/* Reset what we have received so far. */
slave_transfer_request -> ux_slave_transfer_request_actual_length = 0;
/* And reprogram the current buffer address to the beginning of the buffer. */
slave_transfer_request -> ux_slave_transfer_request_current_data_pointer = slave_transfer_request -> ux_slave_transfer_request_data_pointer;
/* Get the pointer to the first data TD. this is the TD right after the SETUP one. */
data_td = td -> ux_sim_host_td_next_td;
/* Get the data length we expect. */
transaction_length = slave_transfer_request -> ux_slave_transfer_request_requested_length;
/* It may have taken multiple TDs to send all the data. */
while (transaction_length != 0)
{
/* Do a sanity check. TD must be data. */
if (data_td -> ux_sim_host_td_status & UX_HCD_SIM_HOST_TD_DATA_PHASE)
{
/* Copy the amount of data in the td into the slave transaction buffer. */
_ux_utility_memory_copy(slave_transfer_request -> ux_slave_transfer_request_current_data_pointer, data_td -> ux_sim_host_td_buffer,
data_td -> ux_sim_host_td_length);
/* Add to the actual payload length. */
slave_transfer_request -> ux_slave_transfer_request_actual_length += data_td -> ux_sim_host_td_length;
/* Update the host transfer's actual length. */
transfer_request -> ux_transfer_request_actual_length += transaction_length;
/* Decrement the total length. */
transaction_length -= data_td -> ux_sim_host_td_length;
/* Update buffer pointer. */
slave_transfer_request -> ux_slave_transfer_request_current_data_pointer += data_td -> ux_sim_host_td_length;
/* Update the td in the head. */
ed -> ux_sim_host_ed_head_td = data_td;
/* Get the pointer to the next data TD. */
data_td = data_td -> ux_sim_host_td_next_td;
/* Free the TD that was used here. */
ed -> ux_sim_host_ed_head_td -> ux_sim_host_td_status = UX_UNUSED;
}
}
/* Make the head TD point to the STATUS TD. */
ed -> ux_sim_host_ed_head_td = ed -> ux_sim_host_ed_head_td -> ux_sim_host_td_next_td;
}
/* Is there no hub? */
if (dcd_sim_slave -> ux_dcd_sim_slave_dcd_control_request_process_hub == UX_NULL)
{
/* There's no hub to worry about. This control transfer is for the
device itself. */
/* Pass the transfer to the regular device stack. */
_ux_device_stack_control_request_process(slave_transfer_request);
}
else
{
/* There is a hub. We need to call the correct Control Transfer dispatcher.
If the device is a hub and this transfer is for one of the devices on the
hub, then we must invoke a separate Control Transfer dispatcher besides
the regular device stack's. This is because the current device stack doesn't
handle control transfers to device's other than itself. */
/* Is this meant for the device itself? */
if (/* If the device isn't ADDRESSED yet, then the address may be invalid since we don't
clear it upon disconnection/reconnection. So we assume that if the device is RESET
or ATTACHED, the control transfer is meant for the device itself. */
(_ux_system_slave->ux_system_slave_device.ux_slave_device_state == UX_DEVICE_RESET ||
_ux_system_slave->ux_system_slave_device.ux_slave_device_state == UX_DEVICE_ATTACHED) ||
/* If we get to this check, then the device has been ADDRESSED and we can compare addresses. */
endpoint -> ux_endpoint_device -> ux_device_address == dcd -> ux_slave_dcd_device_address)
{
/* Yes, this control transfer is meant for the device itself. */
/* Pass the transfer to the regular device stack. */
_ux_device_stack_control_request_process(slave_transfer_request);
}
else
{
/* No, this control transfer is meant for a device on the hub. */
/* Pass the transfer to the callback. */
dcd_sim_slave -> ux_dcd_sim_slave_dcd_control_request_process_hub(slave_transfer_request);
}
}
/* Check if the transaction is OUT from the host. */
if ((*slave_transfer_request -> ux_slave_transfer_request_setup & UX_REQUEST_IN) == 0)
{
/* Check if there is a problem with the endpoint (maybe stalled). */
if (slave_ed -> ux_sim_slave_ed_status & UX_DCD_SIM_SLAVE_ED_STATUS_STALLED)
{
/* Protocol error, stall the transaction. */
transfer_request -> ux_transfer_request_completion_code = UX_TRANSFER_STALLED;
if (transfer_request -> ux_transfer_request_completion_function != UX_NULL)
transfer_request -> ux_transfer_request_completion_function(transfer_request);
/* Error trap. */
_ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_HCD, UX_TRANSFER_STALLED);
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_TRANSFER_STALLED, transfer_request, 0, 0, UX_TRACE_ERRORS, 0, 0)
}
else
/* No error in simulation. */
transfer_request -> ux_transfer_request_completion_code = UX_SUCCESS;
/* In this case the transfer is completed! We take out the status TD. */
td = ed -> ux_sim_host_ed_head_td;
/* Adjust the ED. */
ed -> ux_sim_host_ed_head_td = td -> ux_sim_host_td_next_td;
/* Free the TD that was used here. */
td -> ux_sim_host_td_status = UX_UNUSED;
/* Then, we wake up the host. */
_ux_utility_semaphore_put(&transfer_request -> ux_transfer_request_semaphore);
}
}
else
{
/* Check if there is a problem with the endpoint (maybe stalled). */
if (slave_ed -> ux_sim_slave_ed_status & UX_DCD_SIM_SLAVE_ED_STATUS_STALLED)
{
/* Stall the transaction. */
transfer_request -> ux_transfer_request_completion_code = UX_TRANSFER_STALLED;
if (transfer_request -> ux_transfer_request_completion_function != UX_NULL)
transfer_request -> ux_transfer_request_completion_function(transfer_request);
/* Error trap. */
_ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_HCD, UX_TRANSFER_STALLED);
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_TRANSFER_STALLED, transfer_request, 0, 0, UX_TRACE_ERRORS, 0, 0)
/* Wake up the host side. */
_ux_utility_semaphore_put(&transfer_request -> ux_transfer_request_semaphore);
/* Clean up this ED. */
head_td = ed -> ux_sim_host_ed_head_td;
tail_td = ed -> ux_sim_host_ed_tail_td;
/* Free all TDs attached to the ED. */
while (head_td != tail_td)
{
/* Mark the current head TD as free. */
head_td -> ux_sim_host_td_status = UX_UNUSED;
/* Update the head TD with the next TD. */
ed -> ux_sim_host_ed_head_td = head_td -> ux_sim_host_td_next_td;
/* Now the new head_td is the next TD in the chain. */
head_td = ed -> ux_sim_host_ed_head_td;
}
}
else
{
slave_transfer_remaining = 0;
/* If the device tries to send a NULL packet, we don't reset the actual length to 0. */
if (slave_transfer_request -> ux_slave_transfer_request_requested_length != 0)
slave_transfer_remaining = slave_transfer_request -> ux_slave_transfer_request_requested_length - slave_transfer_request -> ux_slave_transfer_request_actual_length;
/* Get the transaction length to be transferred. It could be a ZLP condition. */
if (slave_transfer_remaining <= td -> ux_sim_host_td_length)
transaction_length = slave_transfer_remaining;
else
transaction_length = td -> ux_sim_host_td_length;
if (td -> ux_sim_host_td_direction == UX_HCD_SIM_HOST_TD_OUT)
/* Send the requested host data to the device. */
_ux_utility_memory_copy(slave_transfer_request -> ux_slave_transfer_request_current_data_pointer, td -> ux_sim_host_td_buffer,
transaction_length);
else
/* Send the requested host data to the device. */
_ux_utility_memory_copy(td -> ux_sim_host_td_buffer, slave_transfer_request -> ux_slave_transfer_request_current_data_pointer,
transaction_length);
/* Update buffers. */
td -> ux_sim_host_td_buffer += transaction_length;
slave_transfer_request -> ux_slave_transfer_request_current_data_pointer += transaction_length;
/* Update actual length values. */
td -> ux_sim_host_td_actual_length += transaction_length;
transfer_request -> ux_transfer_request_actual_length += transaction_length;
slave_transfer_request -> ux_slave_transfer_request_actual_length += transaction_length;
/* Update requested length values. */
td -> ux_sim_host_td_length -= transaction_length;
/* Are we done with this TD (It's possible for the TD to expect more data; for example, the slave
sent/received a smaller amount)? */
if (td -> ux_sim_host_td_length == 0)
{
/* Free the TD that was used here. */
td -> ux_sim_host_td_status = UX_UNUSED;
/* Adjust the ED. */
ed -> ux_sim_host_ed_head_td = td -> ux_sim_host_td_next_td;
}
/* Reset wake booleans. */
wake_host = UX_FALSE;
wake_slave = UX_FALSE;
/* Does the slave have absolutely no more data to send? */
if ((slave_transfer_request -> ux_slave_transfer_request_actual_length == slave_transfer_request -> ux_slave_transfer_request_requested_length &&
slave_transfer_request -> ux_slave_transfer_request_force_zlp == UX_TRUE) ||
(transaction_length == 0) ||
(transaction_length % slave_endpoint -> ux_slave_endpoint_descriptor.wMaxPacketSize))
{
wake_host = UX_TRUE;
wake_slave = UX_TRUE;
}
else
{
/* Is the host's transfer completed? */
if (transfer_request -> ux_transfer_request_actual_length == transfer_request -> ux_transfer_request_requested_length)
wake_host = UX_TRUE;
/* Is the slaves's transfer completed? */
if (slave_transfer_request -> ux_slave_transfer_request_actual_length == slave_transfer_request -> ux_slave_transfer_request_requested_length)
wake_slave = UX_TRUE;
}
if (wake_slave == UX_TRUE)
{
/* Set the completion code to no error. */
slave_transfer_request -> ux_slave_transfer_request_completion_code = UX_SUCCESS;
/* Set the transfer status to COMPLETED. */
slave_transfer_request -> ux_slave_transfer_request_status = UX_TRANSFER_STATUS_COMPLETED;
/* Is this not the control endpoint? */
if (slave_ed -> ux_sim_slave_ed_index != 0)
{
/* Reset the ED to NO TRANSFER status. */
slave_ed -> ux_sim_slave_ed_status &= ~(ULONG)UX_DCD_SIM_SLAVE_ED_STATUS_TRANSFER;
/* Wake up the slave side. */
_ux_utility_semaphore_put(&slave_transfer_request -> ux_slave_transfer_request_semaphore);
}
}
if (wake_host == UX_TRUE)
{
/* If the slave has less data to send than the host wants to receive, then there may still be
TDs left to free. Note that this should only happen for IN transactions, since the only way
an OUT transfer can complete is if all the data was sent i.e. all the TDs were sent and freed. */
if (ed -> ux_sim_host_ed_head_td != ed -> ux_sim_host_ed_tail_td)
{
/* Free all TDs associated with this transfer. Note that if this is a control transfer (which
means it must be IN), then this also gets rid of the STATUS phase, which is okay. Also note
that assumes that there is only one transfer occurring on this endpoint; if there were
multiple, then we'd erase that one's TDs as well. Luckily, with the way USBX is designed,
there should never be multiple transfers occurring simultaneously on a single endpoint
(tldr; data pointer for transfers is shared). */
head_td = ed -> ux_sim_host_ed_head_td;
while (head_td != ed -> ux_sim_host_ed_tail_td)
{
/* Free the TD that was used here. */
head_td -> ux_sim_host_td_status = UX_UNUSED;
/* Move to the next. */
head_td = head_td -> ux_sim_host_td_next_td;
}
/* Update the head and tail TD. */
ed -> ux_sim_host_ed_head_td = head_td;
ed -> ux_sim_host_ed_tail_td = head_td;
}
/* Set the completion code to no error. */
transfer_request -> ux_transfer_request_completion_code = UX_SUCCESS;
/* Set the transfer status to COMPLETED. */
transfer_request -> ux_transfer_request_status = UX_TRANSFER_STATUS_COMPLETED;
/* Is there a callback on the host? */
if (transfer_request -> ux_transfer_request_completion_function != UX_NULL)
transfer_request -> ux_transfer_request_completion_function(transfer_request);
/* Wake up the host side. */
_ux_utility_semaphore_put(&transfer_request -> ux_transfer_request_semaphore);
}
}
}
/* Return successful completion. */
return(UX_SUCCESS);
}

View File

@ -0,0 +1,131 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Host Simulator Controller Driver */
/** */
/**************************************************************************/
/**************************************************************************/
/* Include necessary system files. */
#define UX_SOURCE_CODE
#include "ux_api.h"
#include "ux_hcd_sim_host.h"
#include "ux_host_stack.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_hcd_sim_host_transfer_abort PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function will abort transactions attached to a transfer */
/* request. */
/* */
/* INPUT */
/* */
/* hcd_sim_host Pointer to host controller */
/* transfer_request Pointer to transfer request */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* _ux_utility_delay_ms Delay */
/* */
/* CALLED BY */
/* */
/* Host Simulator Controller Driver */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_hcd_sim_host_transfer_abort(UX_HCD_SIM_HOST *hcd_sim_host, UX_TRANSFER *transfer_request)
{
UX_ENDPOINT *endpoint;
UX_HCD_SIM_HOST_ED *ed;
UX_HCD_SIM_HOST_TD *head_td;
UX_HCD_SIM_HOST_TD *tail_td;
UX_PARAMETER_NOT_USED(hcd_sim_host);
/* Get the pointer to the endpoint associated with the transfer request. */
endpoint = (UX_ENDPOINT *) transfer_request -> ux_transfer_request_endpoint;
/* From the endpoint container, get the address of the physical endpoint. */
ed = (UX_HCD_SIM_HOST_ED *) endpoint -> ux_endpoint_ed;
/* Check if this physical endpoint has been initialized properly! */
if (ed == UX_NULL)
{
/* Error trap. */
_ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_HCD, UX_ENDPOINT_HANDLE_UNKNOWN);
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_ENDPOINT_HANDLE_UNKNOWN, endpoint, 0, 0, UX_TRACE_ERRORS, 0, 0)
return(UX_ENDPOINT_HANDLE_UNKNOWN);
}
/* The endpoint may be active. If so, set the skip bit. */
ed -> ux_sim_host_ed_status |= UX_HCD_SIM_HOST_ED_SKIP;
/* Wait for the controller to finish the current frame processing. */
_ux_utility_delay_ms(1);
/* Remove all the TDs from this ED and leave the head and tail pointing to the dummy TD. */
head_td = ed -> ux_sim_host_ed_head_td;
tail_td = ed -> ux_sim_host_ed_tail_td;
/* Free all TDs attached to the ED. */
while (head_td != tail_td)
{
/* Mark the current head TD as free. */
head_td -> ux_sim_host_td_status = UX_UNUSED;
/* Update the head TD with the next TD. */
ed -> ux_sim_host_ed_head_td = head_td -> ux_sim_host_td_next_td;
/* Now the new head TD is the next TD in the chain. */
head_td = ed -> ux_sim_host_ed_head_td;
}
/* Remove the reset bit in the ED. */
ed -> ux_sim_host_ed_status = (ULONG)~UX_HCD_SIM_HOST_ED_SKIP;
/* Return successful completion. */
return(UX_SUCCESS);
}

View File

@ -0,0 +1,146 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Host Data Pump Class */
/** */
/**************************************************************************/
/**************************************************************************/
/* Include necessary system files. */
#define UX_SOURCE_CODE
#include "ux_api.h"
#include "ux_host_class_dpump.h"
#include "ux_host_stack.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_host_class_dpump_activate PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function calls the USBX stack to activate the class. */
/* */
/* INPUT */
/* */
/* command Dpump class command pointer */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* _ux_host_class_dpump_configure Configure dpump class */
/* _ux_host_class_dpump_endpoints_get Get endpoints of dpump */
/* _ux_host_stack_class_instance_create Create class instance */
/* _ux_host_stack_class_instance_destroy Destroy the class instance */
/* _ux_utility_memory_allocate Allocate memory block */
/* _ux_utility_semaphore_create Create dpump semaphore */
/* */
/* CALLED BY */
/* */
/* _ux_host_class_dpump_entry Entry of dpump class */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_host_class_dpump_activate(UX_HOST_CLASS_COMMAND *command)
{
UX_INTERFACE *interface;
UX_HOST_CLASS_DPUMP *dpump;
UINT status;
/* The data pump is always activated by the interface descriptor and not the
device descriptor. */
interface = (UX_INTERFACE *) command -> ux_host_class_command_container;
/* Obtain memory for this class instance. */
dpump = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, sizeof(UX_HOST_CLASS_DPUMP));
if (dpump == UX_NULL)
return(UX_MEMORY_INSUFFICIENT);
/* Store the class container into this instance. */
dpump -> ux_host_class_dpump_class = command -> ux_host_class_command_class_ptr;
/* Store the interface container into the dpump class instance. */
dpump -> ux_host_class_dpump_interface = interface;
/* Store the device container into the dpump class instance. */
dpump -> ux_host_class_dpump_device = interface -> ux_interface_configuration -> ux_configuration_device;
/* This instance of the device must also be stored in the interface container. */
interface -> ux_interface_class_instance = (VOID *) dpump;
/* Create this class instance. */
status = _ux_host_stack_class_instance_create(dpump -> ux_host_class_dpump_class, (VOID *) dpump);
/* Configure the dpump. */
status = _ux_host_class_dpump_configure(dpump);
if (status != UX_SUCCESS)
{
_ux_host_stack_class_instance_destroy(dpump -> ux_host_class_dpump_class, (VOID *) dpump);
return(status);
}
/* Get the dpump endpoint(s). We will need to search for Bulk Out and Bulk In endpoints. Do not check for errors
here as the alternate setting for this interface may be 0 which has no endpoints. */
status = _ux_host_class_dpump_endpoints_get(dpump);
/* Create the semaphore to protect 2 threads from accessing the same dpump instance. */
status = _ux_utility_semaphore_create(&dpump -> ux_host_class_dpump_semaphore, "ux_dpump_semaphore", 1);
if (status != UX_SUCCESS)
return(UX_SEMAPHORE_ERROR);
/* Mark the dpump as live now. */
dpump -> ux_host_class_dpump_state = UX_HOST_CLASS_INSTANCE_LIVE;
/* If all is fine and the device is mounted, we may need to inform the application
if a function has been programmed in the system structure. */
if ((status == UX_SUCCESS) && (_ux_system_host -> ux_system_host_change_function != UX_NULL))
{
/* Call system change function. */
_ux_system_host -> ux_system_host_change_function(UX_DEVICE_INSERTION, dpump -> ux_host_class_dpump_class, (VOID *) dpump);
}
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_CLASS_DPUMP_ACTIVATE, dpump, 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, dpump, 0, 0, 0)
/* Return completion status. */
return(status);
}

View File

@ -0,0 +1,143 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Host Data Pump Class */
/** */
/**************************************************************************/
/**************************************************************************/
/* Include necessary system files. */
#define UX_SOURCE_CODE
#include "ux_api.h"
#include "ux_host_class_dpump.h"
#include "ux_host_stack.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_host_class_dpump_configure PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function calls the USBX stack to do a SET_CONFIGURATION to the */
/* dpump. Once the dpump is configured, its interface will be */
/* activated. The bulk endpoints enumerated(1 IN, 1 OUT ). */
/* */
/* INPUT */
/* */
/* dpump Pointer to dpump class */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* _ux_host_stack_configuration_interface_get Get interface */
/* _ux_host_stack_device_configuration_get Get configuration */
/* _ux_host_stack_device_configuration_select Select configuration */
/* */
/* CALLED BY */
/* */
/* _ux_host_class_dpump_activate Data Pump class activate */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_host_class_dpump_configure(UX_HOST_CLASS_DPUMP *dpump)
{
UINT status;
UX_CONFIGURATION *configuration;
UX_DEVICE *parent_device;
/* If the device has been configured already, we don't need to do it
again. */
if (dpump -> ux_host_class_dpump_device -> ux_device_state == UX_DEVICE_CONFIGURED)
return(UX_SUCCESS);
/* A dpump normally has one configuration. So retrieve the 1st configuration
only. */
status = _ux_host_stack_device_configuration_get(dpump -> ux_host_class_dpump_device, 0, &configuration);
if (status != UX_SUCCESS)
{
/* 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, dpump -> ux_host_class_dpump_device, 0, 0, UX_TRACE_ERRORS, 0, 0)
return(UX_CONFIGURATION_HANDLE_UNKNOWN);
}
/* Check the dpump power source and check the parent power source for
incompatible connections. */
if (dpump -> ux_host_class_dpump_device -> ux_device_power_source == UX_DEVICE_BUS_POWERED)
{
/* Get parent device pointer. */
parent_device = dpump -> ux_host_class_dpump_device -> ux_device_parent;
/* If the device is NULL, the parent is the root dpump and we don't have to worry
if the parent is not the root dpump, check for its power source. */
if ((parent_device != UX_NULL) && (parent_device -> ux_device_power_source == UX_DEVICE_BUS_POWERED))
{
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_CONNECTION_INCOMPATIBLE, dpump, 0, 0, UX_TRACE_ERRORS, 0, 0)
return(UX_CONNECTION_INCOMPATIBLE);
}
}
/* We have the valid configuration. Ask the USBX stack to set this configuration. */
status = _ux_host_stack_device_configuration_select(configuration);
if (status != UX_SUCCESS)
return(status);
/* If the operation went well, the dpump default alternate setting for the dpump interface is
active and the interrupt endpoint is now enabled. We have to memorize the first interface since
the interrupt endpoint is hooked to it. */
status = _ux_host_stack_configuration_interface_get(configuration, 0, 0, &dpump -> ux_host_class_dpump_interface);
if (status != UX_SUCCESS)
{
/* Store the instance in the interface container, this is for the USB stack
when it needs to invoke the class. */
dpump -> ux_host_class_dpump_interface -> ux_interface_class_instance = (VOID *) dpump;
}
/* Return completion status. */
return(status);
}

View File

@ -0,0 +1,136 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Host Data Pump Class */
/** */
/**************************************************************************/
/**************************************************************************/
/* Include necessary system files. */
#define UX_SOURCE_CODE
#include "ux_api.h"
#include "ux_host_class_dpump.h"
#include "ux_host_stack.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_host_class_dpump_deactivate PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function is called when this instance of the dpump has been */
/* removed from the bus either directly or indirectly. The bulk in\out */
/* pipes will be destroyed and the instanced removed. */
/* */
/* INPUT */
/* */
/* command Data Pump class command pointer */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* _ux_host_stack_class_instance_destroy Destroy the class instance */
/* _ux_host_stack_endpoint_transfer_abort Abort endpoint transfer */
/* _ux_utility_memory_free Free memory block */
/* _ux_utility_semaphore_get Get protection semaphore */
/* _ux_utility_semaphore_delete Delete protection semaphore */
/* _ux_utility_thread_sleep Sleep thread */
/* */
/* CALLED BY */
/* */
/* _ux_host_class_dpump_entry Entry of dpump class */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_host_class_dpump_deactivate(UX_HOST_CLASS_COMMAND *command)
{
UX_HOST_CLASS_DPUMP *dpump;
UINT status;
/* Get the instance for this class. */
dpump = (UX_HOST_CLASS_DPUMP *) command -> ux_host_class_command_instance;
/* The dpump is being shut down. */
dpump -> ux_host_class_dpump_state = UX_HOST_CLASS_INSTANCE_SHUTDOWN;
/* Protect thread reentry to this instance. */
status = _ux_utility_semaphore_get(&dpump -> ux_host_class_dpump_semaphore, UX_WAIT_FOREVER);
if (status != UX_SUCCESS)
{
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_HOST_CLASS_INSTANCE_UNKNOWN, dpump, 0, 0, UX_TRACE_ERRORS, 0, 0)
return(UX_HOST_CLASS_INSTANCE_UNKNOWN);
}
/* We need to abort transactions on the bulk Out pipe. */
_ux_host_stack_endpoint_transfer_abort(dpump -> ux_host_class_dpump_bulk_out_endpoint);
/* We need to abort transactions on the bulk In pipe. */
_ux_host_stack_endpoint_transfer_abort(dpump -> ux_host_class_dpump_bulk_in_endpoint);
/* If the class instance was busy, let it finish properly and not return. */
_ux_utility_thread_sleep(UX_ENUMERATION_THREAD_WAIT);
/* Destroy the instance. */
_ux_host_stack_class_instance_destroy(dpump -> ux_host_class_dpump_class, (VOID *) dpump);
/* Destroy the semaphore. */
_ux_utility_semaphore_delete(&dpump -> ux_host_class_dpump_semaphore);
/* 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)
{
/* Inform the application the device is removed. */
_ux_system_host -> ux_system_host_change_function(UX_DEVICE_REMOVAL, dpump -> ux_host_class_dpump_class, (VOID *) dpump);
}
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_CLASS_DPUMP_DEACTIVATE, dpump, 0, 0, 0, UX_TRACE_HOST_CLASS_EVENTS, 0, 0)
/* If trace is enabled, register this object. */
UX_TRACE_OBJECT_UNREGISTER(dpump);
/* Free the dpump instance memory. */
_ux_utility_memory_free(dpump);
/* Return successful status. */
return(UX_SUCCESS);
}

View File

@ -0,0 +1,163 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Host Data Pump Class */
/** */
/**************************************************************************/
/**************************************************************************/
/* Include necessary system files. */
#define UX_SOURCE_CODE
#include "ux_api.h"
#include "ux_host_class_dpump.h"
#include "ux_host_stack.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_host_class_dpump_endpoints_get PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function search for the handle of the bulk out and bulk in */
/* endpoints. */
/* */
/* INPUT */
/* */
/* dpump Pointer to dpump class */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* _ux_host_stack_interface_endpoint_get Get interface endpoint */
/* */
/* CALLED BY */
/* */
/* _ux_host_class_dpump_activate Activate dpump class */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_host_class_dpump_endpoints_get(UX_HOST_CLASS_DPUMP *dpump)
{
UINT status;
UINT endpoint_index;
UX_ENDPOINT *endpoint;
/* Search the bulk OUT endpoint. It is attached to the interface container. */
for (endpoint_index = 0; endpoint_index < dpump -> ux_host_class_dpump_interface -> ux_interface_descriptor.bNumEndpoints;
endpoint_index++)
{
/* Get interface endpoint. */
status = _ux_host_stack_interface_endpoint_get(dpump -> ux_host_class_dpump_interface, endpoint_index, &endpoint);
/* Check the completion status. */
if (status == UX_SUCCESS)
{
/* Check if endpoint is bulk and OUT. */
if (((endpoint -> ux_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION) == UX_ENDPOINT_OUT) &&
((endpoint -> ux_endpoint_descriptor.bmAttributes & UX_MASK_ENDPOINT_TYPE) == UX_BULK_ENDPOINT))
{
/* This transfer_request always have the OUT direction. */
endpoint -> ux_endpoint_transfer_request.ux_transfer_request_type = UX_REQUEST_OUT;
/* We have found the bulk endpoint, save it. */
dpump -> ux_host_class_dpump_bulk_out_endpoint = endpoint;
break;
}
}
}
/* The bulk out endpoint is mandatory. */
if (dpump -> ux_host_class_dpump_bulk_out_endpoint == UX_NULL)
{
/* Error trap. */
_ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_ENDPOINT_HANDLE_UNKNOWN);
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_ENDPOINT_HANDLE_UNKNOWN, dpump, 0, 0, UX_TRACE_ERRORS, 0, 0)
return(UX_ENDPOINT_HANDLE_UNKNOWN);
}
/* Search the bulk IN endpoint. It is attached to the interface container. */
for (endpoint_index = 0; endpoint_index < dpump -> ux_host_class_dpump_interface -> ux_interface_descriptor.bNumEndpoints;
endpoint_index++)
{
/* Get the endpoint handle. */
status = _ux_host_stack_interface_endpoint_get(dpump -> ux_host_class_dpump_interface, endpoint_index, &endpoint);
/* Check the completion status. */
if (status == UX_SUCCESS)
{
/* Check if endpoint is bulk and IN. */
if (((endpoint -> ux_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION) == UX_ENDPOINT_IN) &&
((endpoint -> ux_endpoint_descriptor.bmAttributes & UX_MASK_ENDPOINT_TYPE) == UX_BULK_ENDPOINT))
{
/* This transfer_request always have the IN direction. */
endpoint -> ux_endpoint_transfer_request.ux_transfer_request_type = UX_REQUEST_IN;
/* We have found the bulk endpoint, save it. */
dpump -> ux_host_class_dpump_bulk_in_endpoint = endpoint;
break;
}
}
}
/* The bulk in endpoint is mandatory. */
if (dpump -> ux_host_class_dpump_bulk_in_endpoint == UX_NULL)
{
/* Error trap. */
_ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_ENDPOINT_HANDLE_UNKNOWN);
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_ENDPOINT_HANDLE_UNKNOWN, dpump, 0, 0, UX_TRACE_ERRORS, 0, 0)
return(UX_ENDPOINT_HANDLE_UNKNOWN);
}
/* All endpoints have been mounted. */
return(UX_SUCCESS);
}

View File

@ -0,0 +1,121 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Host Data Pump Class */
/** */
/**************************************************************************/
/**************************************************************************/
/* Include necessary system files. */
#define UX_SOURCE_CODE
#include "ux_api.h"
#include "ux_host_class_dpump.h"
#include "ux_host_stack.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_host_class_dpump_entry PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function is the entry point of the dpump class. It will be */
/* called by the USBX stack enumeration module when there is a new */
/* dpump on the bus or when the USB dpump is removed. */
/* */
/* INPUT */
/* */
/* command Data pump class command */
/* */
/* OUTPUT */
/* */
/* Completion Status */
/* */
/* CALLS */
/* */
/* _ux_host_class_dpump_activate Activate dpump class */
/* _ux_host_class_dpump_deactivate Deactivate dpump class */
/* */
/* CALLED BY */
/* */
/* Data pump Class */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _ux_host_class_dpump_entry(UX_HOST_CLASS_COMMAND *command)
{
UINT status;
/* The command request will tell us we need to do here, either a enumeration
query, an activation or a deactivation. */
switch (command -> ux_host_class_command_request)
{
case UX_HOST_CLASS_COMMAND_QUERY:
/* The query command is used to let the stack enumeration process know if we want to own
this device or not. */
if((command -> ux_host_class_command_usage == UX_HOST_CLASS_COMMAND_USAGE_CSP) &&
(command -> ux_host_class_command_class == UX_HOST_CLASS_DPUMP_CLASS) &&
(command -> ux_host_class_command_subclass == UX_HOST_CLASS_DPUMP_SUBCLASS) &&
(command -> ux_host_class_command_protocol == UX_HOST_CLASS_DPUMP_PROTOCOL))
return(UX_SUCCESS);
else
return(UX_NO_CLASS_MATCH);
case UX_HOST_CLASS_COMMAND_ACTIVATE:
/* The activate command is used when the device inserted has found a parent and
is ready to complete the enumeration. */
status = _ux_host_class_dpump_activate(command);
return(status);
case UX_HOST_CLASS_COMMAND_DEACTIVATE:
/* The deactivate command is used when the device has been extracted either
directly or when its parents has been extracted. */
status = _ux_host_class_dpump_deactivate(command);
return(status);
default:
/* Error trap. */
_ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_FUNCTION_NOT_SUPPORTED);
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_FUNCTION_NOT_SUPPORTED, 0, 0, 0, UX_TRACE_ERRORS, 0, 0)
return(UX_FUNCTION_NOT_SUPPORTED);
}
}

Some files were not shown because too many files have changed in this diff Show More