mirror of
https://github.com/azure-rtos/usbx.git
synced 2025-01-14 06:43:05 +08:00
Initial commit
This commit is contained in:
commit
15044435fb
41
.gitattributes
vendored
Normal file
41
.gitattributes
vendored
Normal 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
14
.gitignore
vendored
Executable 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
51
CMakeLists.txt
Executable 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
246
LICENSE.txt
Normal 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 Microsoft’s 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
|
||||
Microsoft’s 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 Microsoft’s 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
|
||||
Microsoft’s 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
|
||||
n’accorde 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, d’adéquation à un usage particulier
|
||||
et d’absence 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 d’une autre faute dans la limite
|
||||
autorisée par la loi en vigueur.
|
||||
|
||||
Elle s’applique également, même si Microsoft connaissait ou devrait connaître
|
||||
l’éventualité d’un tel dommage. Si votre pays n’autorise pas l’exclusion ou la
|
||||
limitation de responsabilité pour les dommages indirects, accessoires ou de
|
||||
quelque nature que ce soit, il se peut que la limitation ou l’exclusion
|
||||
ci-dessus ne s’appliquera pas à votre égard.
|
||||
|
||||
EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous
|
||||
pourriez avoir d’autres 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
16
LICENSED-HARDWARE.txt
Normal 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.
|
1804
common/CMakeLists.txt
Normal file
1804
common/CMakeLists.txt
Normal file
File diff suppressed because it is too large
Load Diff
208
common/core/CMakeLists.txt
Normal file
208
common/core/CMakeLists.txt
Normal 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
1983
common/core/inc/ux_api.h
Normal file
File diff suppressed because it is too large
Load Diff
137
common/core/inc/ux_dcd_sim_slave.h
Normal file
137
common/core/inc/ux_dcd_sim_slave.h
Normal 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
|
||||
|
101
common/core/inc/ux_device_class_dpump.h
Normal file
101
common/core/inc/ux_device_class_dpump.h
Normal 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
|
87
common/core/inc/ux_device_stack.h
Normal file
87
common/core/inc/ux_device_stack.h
Normal 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
|
||||
|
236
common/core/inc/ux_hcd_sim_host.h
Normal file
236
common/core/inc/ux_hcd_sim_host.h
Normal 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
|
||||
|
89
common/core/inc/ux_host_class_dpump.h
Normal file
89
common/core/inc/ux_host_class_dpump.h
Normal 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
|
116
common/core/inc/ux_host_stack.h
Normal file
116
common/core/inc/ux_host_stack.h
Normal 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
136
common/core/inc/ux_system.h
Normal 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
314
common/core/inc/ux_user.h
Normal 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
|
||||
|
234
common/core/inc/ux_utility.h
Normal file
234
common/core/inc/ux_utility.h
Normal 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
|
80
common/core/src/ux_dcd_sim_slave_address_set.c
Normal file
80
common/core/src/ux_dcd_sim_slave_address_set.c
Normal 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);
|
||||
}
|
||||
|
114
common/core/src/ux_dcd_sim_slave_endpoint_create.c
Normal file
114
common/core/src/ux_dcd_sim_slave_endpoint_create.c
Normal 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);
|
||||
}
|
||||
|
86
common/core/src/ux_dcd_sim_slave_endpoint_destroy.c
Normal file
86
common/core/src/ux_dcd_sim_slave_endpoint_destroy.c
Normal 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);
|
||||
}
|
||||
|
86
common/core/src/ux_dcd_sim_slave_endpoint_reset.c
Normal file
86
common/core/src/ux_dcd_sim_slave_endpoint_reset.c
Normal 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);
|
||||
}
|
||||
|
86
common/core/src/ux_dcd_sim_slave_endpoint_stall.c
Normal file
86
common/core/src/ux_dcd_sim_slave_endpoint_stall.c
Normal 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);
|
||||
}
|
||||
|
89
common/core/src/ux_dcd_sim_slave_endpoint_status.c
Normal file
89
common/core/src/ux_dcd_sim_slave_endpoint_status.c
Normal 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);
|
||||
}
|
||||
|
82
common/core/src/ux_dcd_sim_slave_frame_number_get.c
Normal file
82
common/core/src/ux_dcd_sim_slave_frame_number_get.c
Normal 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);
|
||||
}
|
||||
|
172
common/core/src/ux_dcd_sim_slave_function.c
Normal file
172
common/core/src/ux_dcd_sim_slave_function.c
Normal 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);
|
||||
}
|
||||
|
104
common/core/src/ux_dcd_sim_slave_initialize.c
Normal file
104
common/core/src/ux_dcd_sim_slave_initialize.c
Normal 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);
|
||||
}
|
||||
|
141
common/core/src/ux_dcd_sim_slave_initialize_complete.c
Normal file
141
common/core/src/ux_dcd_sim_slave_initialize_complete.c
Normal 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);
|
||||
}
|
||||
|
80
common/core/src/ux_dcd_sim_slave_state_change.c
Normal file
80
common/core/src/ux_dcd_sim_slave_state_change.c
Normal 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);
|
||||
}
|
||||
|
90
common/core/src/ux_dcd_sim_slave_transfer_abort.c
Normal file
90
common/core/src/ux_dcd_sim_slave_transfer_abort.c
Normal 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);
|
||||
}
|
||||
|
123
common/core/src/ux_dcd_sim_slave_transfer_request.c
Normal file
123
common/core/src/ux_dcd_sim_slave_transfer_request.c
Normal 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);
|
||||
}
|
||||
|
141
common/core/src/ux_device_class_dpump_activate.c
Normal file
141
common/core/src/ux_device_class_dpump_activate.c
Normal 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);
|
||||
}
|
||||
|
168
common/core/src/ux_device_class_dpump_change.c
Normal file
168
common/core/src/ux_device_class_dpump_change.c
Normal 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);
|
||||
}
|
||||
|
129
common/core/src/ux_device_class_dpump_deactivate.c
Normal file
129
common/core/src/ux_device_class_dpump_deactivate.c
Normal 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);
|
||||
}
|
||||
|
147
common/core/src/ux_device_class_dpump_entry.c
Normal file
147
common/core/src/ux_device_class_dpump_entry.c
Normal 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);
|
||||
}
|
||||
}
|
||||
|
100
common/core/src/ux_device_class_dpump_initialize.c
Normal file
100
common/core/src/ux_device_class_dpump_initialize.c
Normal 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);
|
||||
}
|
||||
|
||||
|
182
common/core/src/ux_device_class_dpump_read.c
Normal file
182
common/core/src/ux_device_class_dpump_read.c
Normal 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);
|
||||
}
|
||||
|
165
common/core/src/ux_device_class_dpump_thread.c
Normal file
165
common/core/src/ux_device_class_dpump_thread.c
Normal 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);
|
||||
}
|
||||
}
|
||||
|
186
common/core/src/ux_device_class_dpump_write.c
Normal file
186
common/core/src/ux_device_class_dpump_write.c
Normal 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);
|
||||
|
||||
}
|
||||
|
133
common/core/src/ux_device_stack_alternate_setting_get.c
Normal file
133
common/core/src/ux_device_stack_alternate_setting_get.c
Normal 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);
|
||||
}
|
||||
|
408
common/core/src/ux_device_stack_alternate_setting_set.c
Normal file
408
common/core/src/ux_device_stack_alternate_setting_set.c
Normal 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);
|
||||
}
|
||||
|
151
common/core/src/ux_device_stack_class_register.c
Normal file
151
common/core/src/ux_device_stack_class_register.c
Normal 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);
|
||||
}
|
||||
|
137
common/core/src/ux_device_stack_class_unregister.c
Normal file
137
common/core/src/ux_device_stack_class_unregister.c
Normal 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);
|
||||
}
|
||||
|
175
common/core/src/ux_device_stack_clear_feature.c
Normal file
175
common/core/src/ux_device_stack_clear_feature.c
Normal 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);
|
||||
}
|
||||
|
103
common/core/src/ux_device_stack_configuration_get.c
Normal file
103
common/core/src/ux_device_stack_configuration_get.c
Normal 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);
|
||||
}
|
||||
|
374
common/core/src/ux_device_stack_configuration_set.c
Normal file
374
common/core/src/ux_device_stack_configuration_set.c
Normal 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);
|
||||
}
|
||||
|
312
common/core/src/ux_device_stack_control_request_process.c
Normal file
312
common/core/src/ux_device_stack_control_request_process.c
Normal 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);
|
||||
}
|
||||
|
544
common/core/src/ux_device_stack_descriptor_send.c
Normal file
544
common/core/src/ux_device_stack_descriptor_send.c
Normal 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);
|
||||
}
|
||||
|
162
common/core/src/ux_device_stack_disconnect.c
Normal file
162
common/core/src/ux_device_stack_disconnect.c
Normal 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);
|
||||
}
|
||||
|
110
common/core/src/ux_device_stack_endpoint_stall.c
Normal file
110
common/core/src/ux_device_stack_endpoint_stall.c
Normal 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);
|
||||
}
|
||||
|
184
common/core/src/ux_device_stack_get_status.c
Normal file
184
common/core/src/ux_device_stack_get_status.c
Normal 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);
|
||||
}
|
||||
|
91
common/core/src/ux_device_stack_host_wakeup.c
Normal file
91
common/core/src/ux_device_stack_host_wakeup.c
Normal 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);
|
||||
}
|
||||
|
414
common/core/src/ux_device_stack_initialize.c
Normal file
414
common/core/src/ux_device_stack_initialize.c
Normal 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);
|
||||
}
|
||||
|
132
common/core/src/ux_device_stack_interface_delete.c
Normal file
132
common/core/src/ux_device_stack_interface_delete.c
Normal 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);
|
||||
}
|
||||
|
141
common/core/src/ux_device_stack_interface_get.c
Normal file
141
common/core/src/ux_device_stack_interface_get.c
Normal 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);
|
||||
}
|
||||
|
277
common/core/src/ux_device_stack_interface_set.c
Normal file
277
common/core/src/ux_device_stack_interface_set.c
Normal 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);
|
||||
}
|
||||
|
130
common/core/src/ux_device_stack_interface_start.c
Normal file
130
common/core/src/ux_device_stack_interface_start.c
Normal 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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
195
common/core/src/ux_device_stack_set_feature.c
Normal file
195
common/core/src/ux_device_stack_set_feature.c
Normal 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);
|
||||
}
|
||||
|
126
common/core/src/ux_device_stack_transfer_abort.c
Normal file
126
common/core/src/ux_device_stack_transfer_abort.c
Normal 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);
|
||||
}
|
||||
|
89
common/core/src/ux_device_stack_transfer_all_request_abort.c
Normal file
89
common/core/src/ux_device_stack_transfer_all_request_abort.c
Normal 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);
|
||||
}
|
||||
|
183
common/core/src/ux_device_stack_transfer_request.c
Normal file
183
common/core/src/ux_device_stack_transfer_request.c
Normal 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);
|
||||
|
||||
}
|
||||
|
122
common/core/src/ux_device_stack_uninitialize.c
Normal file
122
common/core/src/ux_device_stack_uninitialize.c
Normal 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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
79
common/core/src/ux_hcd_sim_host_asynch_queue_process.c
Normal file
79
common/core/src/ux_hcd_sim_host_asynch_queue_process.c
Normal 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;
|
||||
}
|
||||
|
126
common/core/src/ux_hcd_sim_host_asynch_schedule.c
Normal file
126
common/core/src/ux_hcd_sim_host_asynch_schedule.c
Normal 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));
|
||||
}
|
||||
|
122
common/core/src/ux_hcd_sim_host_asynchronous_endpoint_create.c
Normal file
122
common/core/src/ux_hcd_sim_host_asynchronous_endpoint_create.c
Normal 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);
|
||||
}
|
||||
|
121
common/core/src/ux_hcd_sim_host_asynchronous_endpoint_destroy.c
Normal file
121
common/core/src/ux_hcd_sim_host_asynchronous_endpoint_destroy.c
Normal 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);
|
||||
}
|
||||
|
102
common/core/src/ux_hcd_sim_host_ed_obtain.c
Normal file
102
common/core/src/ux_hcd_sim_host_ed_obtain.c
Normal 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);
|
||||
}
|
||||
|
96
common/core/src/ux_hcd_sim_host_ed_td_clean.c
Normal file
96
common/core/src/ux_hcd_sim_host_ed_td_clean.c
Normal 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;
|
||||
}
|
||||
}
|
||||
|
86
common/core/src/ux_hcd_sim_host_endpoint_reset.c
Normal file
86
common/core/src/ux_hcd_sim_host_endpoint_reset.c
Normal 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);
|
||||
}
|
||||
|
273
common/core/src/ux_hcd_sim_host_entry.c
Normal file
273
common/core/src/ux_hcd_sim_host_entry.c
Normal 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);
|
||||
}
|
||||
|
78
common/core/src/ux_hcd_sim_host_frame_number_get.c
Normal file
78
common/core/src/ux_hcd_sim_host_frame_number_get.c
Normal 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);
|
||||
}
|
||||
|
80
common/core/src/ux_hcd_sim_host_frame_number_set.c
Normal file
80
common/core/src/ux_hcd_sim_host_frame_number_set.c
Normal 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;
|
||||
}
|
||||
|
191
common/core/src/ux_hcd_sim_host_initialize.c
Normal file
191
common/core/src/ux_hcd_sim_host_initialize.c
Normal 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);
|
||||
}
|
||||
|
180
common/core/src/ux_hcd_sim_host_interrupt_endpoint_create.c
Normal file
180
common/core/src/ux_hcd_sim_host_interrupt_endpoint_create.c
Normal 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);
|
||||
}
|
||||
|
78
common/core/src/ux_hcd_sim_host_iso_queue_process.c
Normal file
78
common/core/src/ux_hcd_sim_host_iso_queue_process.c
Normal 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;
|
||||
}
|
||||
|
77
common/core/src/ux_hcd_sim_host_iso_schedule.c
Normal file
77
common/core/src/ux_hcd_sim_host_iso_schedule.c
Normal 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;
|
||||
}
|
||||
|
114
common/core/src/ux_hcd_sim_host_isochronous_endpoint_create.c
Normal file
114
common/core/src/ux_hcd_sim_host_isochronous_endpoint_create.c
Normal 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);
|
||||
}
|
||||
|
102
common/core/src/ux_hcd_sim_host_isochronous_td_obtain.c
Normal file
102
common/core/src/ux_hcd_sim_host_isochronous_td_obtain.c
Normal 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);
|
||||
}
|
||||
|
136
common/core/src/ux_hcd_sim_host_least_traffic_list_get.c
Normal file
136
common/core/src/ux_hcd_sim_host_least_traffic_list_get.c
Normal 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);
|
||||
}
|
||||
|
110
common/core/src/ux_hcd_sim_host_periodic_endpoint_destroy.c
Normal file
110
common/core/src/ux_hcd_sim_host_periodic_endpoint_destroy.c
Normal 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);
|
||||
}
|
||||
|
109
common/core/src/ux_hcd_sim_host_periodic_schedule.c
Normal file
109
common/core/src/ux_hcd_sim_host_periodic_schedule.c
Normal 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;
|
||||
}
|
||||
|
138
common/core/src/ux_hcd_sim_host_periodic_tree_create.c
Normal file
138
common/core/src/ux_hcd_sim_host_periodic_tree_create.c
Normal 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);
|
||||
}
|
||||
|
108
common/core/src/ux_hcd_sim_host_port_reset.c
Normal file
108
common/core/src/ux_hcd_sim_host_port_reset.c
Normal 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);
|
||||
}
|
||||
|
125
common/core/src/ux_hcd_sim_host_port_status_get.c
Normal file
125
common/core/src/ux_hcd_sim_host_port_status_get.c
Normal 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);
|
||||
}
|
||||
|
116
common/core/src/ux_hcd_sim_host_regular_td_obtain.c
Normal file
116
common/core/src/ux_hcd_sim_host_regular_td_obtain.c
Normal 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);
|
||||
}
|
||||
|
219
common/core/src/ux_hcd_sim_host_request_bulk_transfer.c
Normal file
219
common/core/src/ux_hcd_sim_host_request_bulk_transfer.c
Normal 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);
|
||||
}
|
||||
|
321
common/core/src/ux_hcd_sim_host_request_control_transfer.c
Normal file
321
common/core/src/ux_hcd_sim_host_request_control_transfer.c
Normal 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);
|
||||
}
|
||||
|
135
common/core/src/ux_hcd_sim_host_request_interupt_transfer.c
Normal file
135
common/core/src/ux_hcd_sim_host_request_interupt_transfer.c
Normal 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);
|
||||
}
|
||||
|
230
common/core/src/ux_hcd_sim_host_request_isochronous_transfer.c
Normal file
230
common/core/src/ux_hcd_sim_host_request_isochronous_transfer.c
Normal 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, ¤t_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);
|
||||
}
|
||||
|
124
common/core/src/ux_hcd_sim_host_request_transfer.c
Normal file
124
common/core/src/ux_hcd_sim_host_request_transfer.c
Normal 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);
|
||||
}
|
||||
|
97
common/core/src/ux_hcd_sim_host_timer_function.c
Normal file
97
common/core/src/ux_hcd_sim_host_timer_function.c
Normal 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
495
common/core/src/ux_hcd_sim_host_transaction_schedule.c
Normal file
495
common/core/src/ux_hcd_sim_host_transaction_schedule.c
Normal 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);
|
||||
}
|
||||
|
131
common/core/src/ux_hcd_sim_host_transfer_abort.c
Normal file
131
common/core/src/ux_hcd_sim_host_transfer_abort.c
Normal 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);
|
||||
}
|
||||
|
146
common/core/src/ux_host_class_dpump_activate.c
Normal file
146
common/core/src/ux_host_class_dpump_activate.c
Normal 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);
|
||||
}
|
||||
|
143
common/core/src/ux_host_class_dpump_configure.c
Normal file
143
common/core/src/ux_host_class_dpump_configure.c
Normal 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);
|
||||
}
|
||||
|
||||
|
136
common/core/src/ux_host_class_dpump_deactivate.c
Normal file
136
common/core/src/ux_host_class_dpump_deactivate.c
Normal 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);
|
||||
}
|
||||
|
163
common/core/src/ux_host_class_dpump_endpoints_get.c
Normal file
163
common/core/src/ux_host_class_dpump_endpoints_get.c
Normal 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);
|
||||
}
|
||||
|
121
common/core/src/ux_host_class_dpump_entry.c
Normal file
121
common/core/src/ux_host_class_dpump_entry.c
Normal 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
Loading…
x
Reference in New Issue
Block a user