mirror of
https://github.com/azure-rtos/usbx.git
synced 2025-01-14 06:43:05 +08:00
Add regression tests. (#126)
Add regression tests (auto triggered on PR, manually triggered in forked branch).
This commit is contained in:
parent
26585e42dc
commit
6ed7092b77
61
.github/workflows/regression_test.yml
vendored
Normal file
61
.github/workflows/regression_test.yml
vendored
Normal file
@ -0,0 +1,61 @@
|
||||
name: USBX Regression Test
|
||||
|
||||
# Controls when the action will run. Triggers the workflow on push or pull request
|
||||
# events but only for the master branch
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
tests_to_run:
|
||||
description: 'all, single or multiple of default_build_coverage error_check_build_full_coverage tracex_enable_build device_buffer_owner_build device_zero_copy_build nofx_build_coverage optimized_build standalone_device_build_coverage standalone_device_buffer_owner_build standalone_device_zero_copy_build standalone_host_build_coverage standalone_build_coverage generic_build otg_support_build memory_management_build_coverage msrc_rtos_build msrc_standalone_build'
|
||||
required: false
|
||||
default: 'default_build_coverage'
|
||||
skip_coverage:
|
||||
required: false
|
||||
type: boolean
|
||||
default: false
|
||||
coverage_name:
|
||||
required: false
|
||||
default: 'default_build_coverage'
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
|
||||
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
|
||||
jobs:
|
||||
|
||||
manual_tests:
|
||||
if: github.event_name == 'workflow_dispatch'
|
||||
permissions:
|
||||
contents: read
|
||||
issues: read
|
||||
checks: write
|
||||
pull-requests: write
|
||||
pages: write
|
||||
id-token: write
|
||||
|
||||
uses: azure-rtos/threadx/.github/workflows/regression_template.yml@master
|
||||
with:
|
||||
cmake_path: ./test/cmake/usbx
|
||||
build_script: ./scripts/build.sh ${{ inputs.tests_to_run }}
|
||||
test_script: ./scripts/test.sh ${{ inputs.tests_to_run }}
|
||||
coverage_name: ${{ inputs.coverage_name }}
|
||||
skip_coverage: ${{ !!inputs.skip_coverage }}
|
||||
|
||||
auto_tests:
|
||||
if: github.event_name != 'workflow_dispatch'
|
||||
permissions:
|
||||
contents: read
|
||||
issues: read
|
||||
checks: write
|
||||
pull-requests: write
|
||||
pages: write
|
||||
id-token: write
|
||||
|
||||
uses: azure-rtos/threadx/.github/workflows/regression_template.yml@master
|
||||
with:
|
||||
cmake_path: ./test/cmake/usbx
|
||||
build_script: ./scripts/build.sh default_build_coverage
|
||||
test_script: ./scripts/test.sh default_build_coverage
|
||||
coverage_name: default_build_coverage
|
||||
skip_coverage: false
|
2
scripts/build.sh
Executable file
2
scripts/build.sh
Executable file
@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
$(dirname `realpath $0`)/../test/cmake/usbx/run.sh build $@
|
25
scripts/install.sh
Executable file
25
scripts/install.sh
Executable file
@ -0,0 +1,25 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Install necessary softwares for Ubuntu.
|
||||
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y \
|
||||
gcc-multilib \
|
||||
git \
|
||||
g++ \
|
||||
python3-pip \
|
||||
ninja-build \
|
||||
unifdef \
|
||||
p7zip-full \
|
||||
tofrodos \
|
||||
gawk \
|
||||
software-properties-common
|
||||
|
||||
wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | sudo apt-key add -
|
||||
CODENAME=$(lsb_release -c | cut -f2 -d':' | sed 's/\t//')
|
||||
sudo apt-add-repository -y "deb https://apt.kitware.com/ubuntu/ $CODENAME main"
|
||||
sudo apt-get -y install cmake
|
||||
|
||||
python3 -m pip install --upgrade pip
|
||||
pip3 install gcovr==4.1
|
||||
pip3 install --upgrade cmake
|
2
scripts/test.sh
Executable file
2
scripts/test.sh
Executable file
@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
CTEST_PARALLEL_LEVEL=4 $(dirname `realpath $0`)/../test/cmake/usbx/run.sh test $@
|
37
test/cmake/libs/CMakeLists.txt
Normal file
37
test/cmake/libs/CMakeLists.txt
Normal file
@ -0,0 +1,37 @@
|
||||
cmake_minimum_required(VERSION 3.13 FATAL_ERROR)
|
||||
|
||||
project(libs LANGUAGES C)
|
||||
|
||||
if($ENV{ENABLE_64})
|
||||
message(STATUS "Building for 64bit")
|
||||
set(NX_USER_FILE ${CMAKE_CURRENT_SOURCE_DIR}/nx_user.h)
|
||||
else()
|
||||
add_compile_options(-m32)
|
||||
add_link_options(-m32)
|
||||
message(STATUS "Building for 32bit")
|
||||
endif()
|
||||
message(STATUS "Using toolchain file: ${CMAKE_TOOLCHAIN_FILE}.")
|
||||
|
||||
get_filename_component(externals ${CMAKE_CURRENT_SOURCE_DIR}/../../../externals
|
||||
ABSOLUTE)
|
||||
add_subdirectory(${externals}/threadx threadx)
|
||||
add_subdirectory(${externals}/netxduo netxduo)
|
||||
add_subdirectory(${externals}/filex filex)
|
||||
target_compile_options(threadx PRIVATE -DTX_ENABLE_EVENT_TRACE)
|
||||
if(NOT DEFINED ENV{ENABLE_IDLE})
|
||||
target_compile_options(threadx PRIVATE -DTX_LINUX_NO_IDLE_ENABLE)
|
||||
endif()
|
||||
target_compile_options(filex PRIVATE -DFX_ENABLE_EXFAT)
|
||||
|
||||
target_compile_options(netxduo PRIVATE -DTX_ENABLE_EVENT_TRACE -DNX_PHYSICAL_HEADER=20)
|
||||
|
||||
foreach(lib threadx netxduo filex)
|
||||
get_target_property(dirs ${lib} INCLUDE_DIRECTORIES)
|
||||
execute_process(COMMAND mkdir -p ${CMAKE_BINARY_DIR}/inc)
|
||||
foreach(dir ${dirs})
|
||||
file(GLOB header_files ${dir}/*.h)
|
||||
foreach(header_file ${header_files})
|
||||
execute_process(COMMAND ln -sf ${header_file} ${CMAKE_BINARY_DIR}/inc)
|
||||
endforeach()
|
||||
endforeach()
|
||||
endforeach()
|
87
test/cmake/libs/nx_user.h
Normal file
87
test/cmake/libs/nx_user.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. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** NetX Component */
|
||||
/** */
|
||||
/** User Specific */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* PORT SPECIFIC C INFORMATION RELEASE */
|
||||
/* */
|
||||
/* nx_user.h PORTABLE C */
|
||||
/* 6.0 */
|
||||
/* */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Yuxin Zhou, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This file contains user defines for configuring NetX in specific */
|
||||
/* ways. This file will have an effect only if the application and */
|
||||
/* NetX library are built with NX_INCLUDE_USER_DEFINE_FILE defined. */
|
||||
/* Note that all the defines in this file may also be made on the */
|
||||
/* command line when building NetX library and application objects. */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef NX_USER_H
|
||||
#define NX_USER_H
|
||||
|
||||
/* Define the extension to hold the control block for 64-bit mode. */
|
||||
#define NX_THREAD_EXTENSION_PTR_SET(a, b) { \
|
||||
TX_THREAD *thread_ptr; \
|
||||
thread_ptr = (TX_THREAD *) (a); \
|
||||
(thread_ptr -> tx_thread_extension_ptr) = (VOID *)(b); \
|
||||
}
|
||||
#define NX_THREAD_EXTENSION_PTR_GET(a, b, c) { \
|
||||
NX_PARAMETER_NOT_USED(c); \
|
||||
TX_THREAD *thread_ptr; \
|
||||
thread_ptr = tx_thread_identify(); \
|
||||
while(1)\
|
||||
{ \
|
||||
if (thread_ptr -> tx_thread_extension_ptr) \
|
||||
{ \
|
||||
(a) = (b *)(thread_ptr -> tx_thread_extension_ptr); \
|
||||
break; \
|
||||
} \
|
||||
tx_thread_sleep(1); \
|
||||
} \
|
||||
}
|
||||
#define NX_TIMER_EXTENSION_PTR_SET(a, b) { \
|
||||
TX_TIMER *timer_ptr; \
|
||||
timer_ptr = (TX_TIMER *) (a); \
|
||||
(timer_ptr -> tx_timer_internal.tx_timer_internal_extension_ptr) = (VOID *)(b); \
|
||||
}
|
||||
#define NX_TIMER_EXTENSION_PTR_GET(a, b, c) { \
|
||||
NX_PARAMETER_NOT_USED(c); \
|
||||
if (!_tx_timer_expired_timer_ptr -> tx_timer_internal_extension_ptr) \
|
||||
return; \
|
||||
(a) = (b *)(_tx_timer_expired_timer_ptr -> tx_timer_internal_extension_ptr); \
|
||||
}
|
||||
|
||||
#endif
|
||||
|
437
test/cmake/usbx/CMakeLists.txt
Normal file
437
test/cmake/usbx/CMakeLists.txt
Normal file
@ -0,0 +1,437 @@
|
||||
cmake_minimum_required(VERSION 3.13 FATAL_ERROR)
|
||||
cmake_policy(SET CMP0054 NEW)
|
||||
cmake_policy(SET CMP0057 NEW)
|
||||
cmake_policy(SET CMP0077 NEW)
|
||||
|
||||
project(usbx_test LANGUAGES C)
|
||||
|
||||
# Use customized ux_user.h
|
||||
set(UX_USER_FILE ${CMAKE_CURRENT_SOURCE_DIR}/ux_user.h)
|
||||
|
||||
# Copy files instead of using symlink
|
||||
# libs/ -> ../libs/
|
||||
file(MAKE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/libs)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../libs/CMakeLists.txt
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/libs/CMakeLists.txt COPYONLY)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../libs/nx_user.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/libs/nx_user.h COPYONLY)
|
||||
|
||||
# Set build configurations
|
||||
# TODO: add when available : standalone_otg_build
|
||||
set(BUILD_CONFIGURATIONS
|
||||
default_build_coverage
|
||||
error_check_build_full_coverage
|
||||
tracex_enable_build
|
||||
device_buffer_owner_build
|
||||
device_zero_copy_build
|
||||
nofx_build_coverage
|
||||
optimized_build
|
||||
standalone_device_build_coverage
|
||||
standalone_device_buffer_owner_build
|
||||
standalone_device_zero_copy_build
|
||||
standalone_host_build_coverage
|
||||
standalone_build_coverage
|
||||
generic_build
|
||||
otg_support_build
|
||||
memory_management_build_coverage
|
||||
msrc_rtos_build
|
||||
msrc_standalone_build
|
||||
)
|
||||
|
||||
set(CMAKE_CONFIGURATION_TYPES
|
||||
${BUILD_CONFIGURATIONS}
|
||||
CACHE STRING "list of supported configuration types" FORCE)
|
||||
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
|
||||
${CMAKE_CONFIGURATION_TYPES})
|
||||
list(GET CMAKE_CONFIGURATION_TYPES 0 BUILD_TYPE)
|
||||
if((NOT CMAKE_BUILD_TYPE) OR (NOT ("${CMAKE_BUILD_TYPE}" IN_LIST
|
||||
CMAKE_CONFIGURATION_TYPES)))
|
||||
set(CMAKE_BUILD_TYPE
|
||||
"${BUILD_TYPE}"
|
||||
CACHE STRING "Build Type of the project" FORCE)
|
||||
endif()
|
||||
|
||||
message(STATUS "Build for usbx")
|
||||
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
|
||||
message(STATUS "Using toolchain file: ${CMAKE_TOOLCHAIN_FILE}.")
|
||||
|
||||
set(default_build_coverage
|
||||
-DNX_PHYSICAL_HEADER=20
|
||||
# -DUX_SLAVE_REQUEST_CONTROL_MAX_LENGTH=512
|
||||
# -DUX_DEVICE_BIDIRECTIONAL_ENDPOINT_SUPPORT
|
||||
# -DUX_HOST_DEVICE_CLASS_CODE_VALIDATION_ENABLE
|
||||
# -DUX_DEVICE_CLASS_HID_INTERRUPT_OUT_SUPPORT
|
||||
# -DUX_HOST_CLASS_HID_INTERRUPT_OUT_SUPPORT
|
||||
-DUX_DISABLE_ASSERT
|
||||
##############################################FeedBack Test Start
|
||||
# -DUX_DEVICE_CLASS_AUDIO_FEEDBACK_SUPPORT
|
||||
# -DUX_MAX_DEVICE_ENDPOINTS=6
|
||||
# -DUX_DEVICE_BIDIRECTIONAL_ENDPOINT_SUPPORT
|
||||
# -DUX_SLAVE_REQUEST_CONTROL_MAX_LENGTH=512
|
||||
##############################################FeedBack Test end
|
||||
# -DUX_HOST_CLASS_AUDIO_2_SUPPORT
|
||||
# -DUX_HOST_CLASS_AUDIO_FEEDBACK_SUPPORT
|
||||
# -DUX_HOST_CLASS_AUDIO_DISABLE_CONTROLS
|
||||
# -DUX_HOST_CLASS_AUDIO_INTERRUPT_SUPPORT
|
||||
# -DUX_DEVICE_CLASS_PRINTER_WRITE_AUTO_ZLP
|
||||
# -DUX_DEVICE_CLASS_CDC_ACM_WRITE_AUTO_ZLP
|
||||
# -DUX_DEVICE_CLASS_AUDIO_INTERRUPT_SUPPORT
|
||||
-DUX_HOST_STACK_CONFIGURATION_INSTANCE_CREATE_CONTROL=0
|
||||
-DUX_DEVICE_ENABLE_GET_STRING_WITH_ZERO_LANGUAGE_ID
|
||||
)
|
||||
|
||||
set(error_check_build_full_coverage
|
||||
${default_build_coverage}
|
||||
-DUX_ENABLE_ASSERT
|
||||
-DUX_ENABLE_ERROR_CHECKING
|
||||
-DUX_PIMA_WITH_MTP_SUPPORT
|
||||
)
|
||||
|
||||
set(msrc_rtos_build
|
||||
${error_check_build_full_coverage}
|
||||
-DUX_SLAVE_REQUEST_CONTROL_MAX_LENGTH=512
|
||||
-DUX_HOST_CLASS_AUDIO_2_SUPPORT
|
||||
-DUX_HOST_CLASS_AUDIO_INTERRUPT_SUPPORT
|
||||
)
|
||||
set(msrc_standalone_build
|
||||
${msrc_rtos_build}
|
||||
-DUX_STANDALONE
|
||||
)
|
||||
|
||||
set(tracex_enable_build
|
||||
-DNX_PHYSICAL_HEADER=20
|
||||
-DTX_ENABLE_EVENT_TRACE
|
||||
-DUX_TRACE_INSERT_MACROS
|
||||
)
|
||||
|
||||
set(device_buffer_owner_build
|
||||
-DNX_PHYSICAL_HEADER=20
|
||||
# -DUX_ENABLE_ASSERT
|
||||
-DTX_ENABLE_EVENT_TRACE
|
||||
-DUX_TRACE_INSERT_MACROS
|
||||
-DUX_SLAVE_REQUEST_CONTROL_MAX_LENGTH=512
|
||||
-DUX_DEVICE_ENDPOINT_BUFFER_OWNER=1
|
||||
# -DUX_DEVICE_CLASS_CDC_ACM_TRANSMISSION_DISABLE
|
||||
-DUX_DEVICE_CLASS_HID_INTERRUPT_OUT_SUPPORT
|
||||
-DUX_DEVICE_CLASS_AUDIO_FEEDBACK_SUPPORT
|
||||
-DUX_DEVICE_CLASS_AUDIO_INTERRUPT_SUPPORT
|
||||
)
|
||||
set(device_zero_copy_build
|
||||
${device_buffer_owner_build}
|
||||
-DUX_DEVICE_CLASS_CDC_ACM_ZERO_COPY
|
||||
-DUX_DEVICE_CLASS_CDC_ACM_WRITE_AUTO_ZLP
|
||||
-DUX_DEVICE_CLASS_HID_ZERO_COPY
|
||||
-DUX_DEVICE_CLASS_CDC_ECM_ZERO_COPY
|
||||
-DUX_DEVICE_CLASS_RNDIS_ZERO_COPY
|
||||
-DUX_DEVICE_CLASS_PRINTER_ZERO_COPY
|
||||
)
|
||||
|
||||
set(nofx_build_coverage
|
||||
-DNX_PHYSICAL_HEADER=20
|
||||
-DUX_HOST_CLASS_STORAGE_NO_FILEX
|
||||
)
|
||||
set(standalone_build_coverage
|
||||
-DNX_PHYSICAL_HEADER=20
|
||||
-DUX_STANDALONE
|
||||
# -DTX_ENABLE_EVENT_TRACE
|
||||
)
|
||||
set(standalone_device_build_coverage
|
||||
-DUX_DEVICE_STANDALONE
|
||||
# -DUX_DEVICE_CLASS_HID_INTERRUPT_OUT_SUPPORT
|
||||
-DUX_SLAVE_REQUEST_CONTROL_MAX_LENGTH=512
|
||||
##############################################FeedBack Test Start
|
||||
# -DUX_DEVICE_CLASS_AUDIO_FEEDBACK_SUPPORT
|
||||
# -DUX_MAX_DEVICE_ENDPOINTS=6
|
||||
# -DUX_DEVICE_BIDIRECTIONAL_ENDPOINT_SUPPORT
|
||||
##############################################FeedBack Test End
|
||||
# -DUX_DEVICE_CLASS_AUDIO_INTERRUPT_SUPPORT
|
||||
-DUX_ENABLE_ERROR_CHECKING
|
||||
)
|
||||
set(standalone_device_buffer_owner_build
|
||||
${device_buffer_owner_build}
|
||||
${standalone_device_build_coverage}
|
||||
)
|
||||
set(standalone_device_zero_copy_build
|
||||
${device_zero_copy_build}
|
||||
${standalone_device_build_coverage}
|
||||
)
|
||||
set(standalone_host_build_coverage
|
||||
-DUX_HOST_STANDALONE
|
||||
# -DUX_HOST_CLASS_HID_INTERRUPT_OUT_SUPPORT
|
||||
-DUX_ENABLE_ERROR_CHECKING
|
||||
)
|
||||
set(standalone_otg_build
|
||||
-DUX_OTG_STANDALONE
|
||||
)
|
||||
set(optimized_build
|
||||
-DNX_PHYSICAL_HEADER=20
|
||||
-DUX_NAME_REFERENCED_BY_POINTER
|
||||
-DUX_MAX_HCD=1
|
||||
-DUX_MAX_ISO_TD=0
|
||||
-DUX_MAX_TD=20
|
||||
-DUX_MAX_CLASS_DRIVER=1
|
||||
-DUX_MAX_DEVICES=1
|
||||
-DUX_HOST_CLASS_STORAGE_MEMORY_BUFFER_SIZE=512
|
||||
-DUX_HOST_CLASS_STORAGE_MAX_TRANSFER_SIZE=512
|
||||
-DUX_HOST_CLASS_STORAGE_MAX_MEDIA=1
|
||||
-DUX_DEVICE_INITIALIZE_FRAMEWORK_SCAN_DISABLE
|
||||
-DUX_MAX_DEVICE_ENDPOINTS=2
|
||||
-DUX_MAX_DEVICE_INTERFACES=1
|
||||
-DUX_MAX_SLAVE_INTERFACES=1
|
||||
-DUX_MAX_SLAVE_CLASS_DRIVER=1
|
||||
-DUX_MAX_SLAVE_LUN=1
|
||||
-DUX_SLAVE_REQUEST_DATA_MAX_LENGTH=512
|
||||
-DUX_DEVICE_ALTERNATE_SETTING_SUPPORT_DISABLE
|
||||
)
|
||||
set(generic_build
|
||||
-DUX_HCD_EHCI_SPLIT_TRANSFER_ENABLE
|
||||
-DUX_HOST_CLASS_STORAGE_INCLUDE_LEGACY_PROTOCOL_SUPPORT
|
||||
-DUX_SLAVE_CLASS_STORAGE_INCLUDE_MMC
|
||||
############################################## warning check: CDC ACM
|
||||
-DUX_DEVICE_CLASS_CDC_ACM_TRANSMISSION_DISABLE
|
||||
############################################## warning check: DFU
|
||||
# -DUX_DEVICE_CLASS_DFU_UPLOAD_DISABLE
|
||||
# -DUX_DEVICE_CLASS_DFU_ERROR_GET_ENABLE
|
||||
-DUX_DEVICE_CLASS_DFU_STATUS_MODE=1 #0/1
|
||||
-DUX_DEVICE_CLASS_DFU_STATUS_POLLTIMEOUT=0
|
||||
# -DUX_DEVICE_CLASS_DFU_CUSTOM_REQUEST_ENABLE
|
||||
-DUX_HOST_STACK_CONFIGURATION_INSTANCE_CREATE_CONTROL=1
|
||||
)
|
||||
set(otg_support_build
|
||||
-DNX_PHYSICAL_HEADER=20
|
||||
-DUX_OTG_SUPPORT=
|
||||
)
|
||||
set(memory_management_build_coverage
|
||||
${default_build_coverage}
|
||||
-DUX_ENFORCE_SAFE_ALIGNMENT
|
||||
-DUX_ENABLE_MEMORY_STATISTICS
|
||||
-DUX_ENABLE_MEMORY_POOL_SANITY_CHECK
|
||||
)
|
||||
# Control if USBX is static or shared
|
||||
if($ENV{USBX_STATIC})
|
||||
message(STATUS "Building STATIC usbx")
|
||||
set(BUILD_SHARED_LIBS OFF)
|
||||
else()
|
||||
message(STATUS "Building usbx BUILD_SHARED_LIBS: ${BUILD_SHARED_LIBS}")
|
||||
endif()
|
||||
if(NOT BUILD_SHARED_LIBS)
|
||||
if(CMAKE_BUILD_TYPE MATCHES ".*_coverage")
|
||||
add_link_options(-fprofile-arcs)
|
||||
add_link_options(-lgcov)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Control if it's for 64 bit or 32 bit
|
||||
if($ENV{ENABLE_64})
|
||||
message(STATUS "Building for 64bit")
|
||||
else()
|
||||
add_compile_options(-m32)
|
||||
add_link_options(-m32)
|
||||
message(STATUS "Building for 32bit")
|
||||
endif()
|
||||
add_compile_options(
|
||||
-std=c99
|
||||
-ggdb
|
||||
-g3
|
||||
-gdwarf-2
|
||||
-fdiagnostics-color
|
||||
-DUX_USE_IO_INSTRUCTIONS
|
||||
#-DUX_DEVICE_CLASS_DFU_CUSTOM_REQUEST_ENABLE
|
||||
#-DUX_DEVICE_CLASS_DFU_STATUS_MODE=1
|
||||
${${CMAKE_BUILD_TYPE}})
|
||||
|
||||
enable_testing()
|
||||
|
||||
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../../../ usbx)
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "generic_build")
|
||||
add_test(fake_test true)
|
||||
else()
|
||||
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/regression regression)
|
||||
endif()
|
||||
|
||||
# TODO: Unmask after adding sample for STANDALONE
|
||||
if(NOT (CMAKE_BUILD_TYPE MATCHES "standalone.*"))
|
||||
add_subdirectory(../usbx/samples samples)
|
||||
endif()
|
||||
|
||||
# Coverage
|
||||
if(CMAKE_BUILD_TYPE MATCHES ".*_coverage")
|
||||
target_compile_options(usbx PRIVATE -fprofile-arcs -ftest-coverage)
|
||||
target_link_options(usbx PRIVATE -fprofile-arcs -ftest-coverage)
|
||||
endif()
|
||||
|
||||
# Build ThreadX library once
|
||||
execute_process(COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/run.sh build_libs)
|
||||
add_custom_target(build_libs ALL COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/run.sh
|
||||
build_libs)
|
||||
|
||||
add_dependencies(usbx build_libs)
|
||||
target_include_directories(usbx PUBLIC ${CMAKE_BINARY_DIR}/../libs/inc)
|
||||
|
||||
add_library(threadx SHARED IMPORTED GLOBAL)
|
||||
add_library("azrtos::threadx" ALIAS threadx)
|
||||
set_target_properties(
|
||||
threadx PROPERTIES IMPORTED_LOCATION
|
||||
${CMAKE_BINARY_DIR}/../libs/threadx/libthreadx.so)
|
||||
|
||||
add_library(netxduo SHARED IMPORTED GLOBAL)
|
||||
add_library("azrtos::netxduo" ALIAS netxduo)
|
||||
set_target_properties(
|
||||
netxduo PROPERTIES IMPORTED_LOCATION
|
||||
${CMAKE_BINARY_DIR}/../libs/netxduo/libnetxduo.so)
|
||||
|
||||
add_library(filex SHARED IMPORTED GLOBAL)
|
||||
add_library("azrtos::filex" ALIAS filex)
|
||||
set_target_properties(
|
||||
filex PROPERTIES IMPORTED_LOCATION
|
||||
${CMAKE_BINARY_DIR}/../libs/filex/libfilex.so)
|
||||
|
||||
target_compile_options(
|
||||
usbx
|
||||
PRIVATE -Werror
|
||||
-Wall
|
||||
-Wextra
|
||||
-pedantic
|
||||
-fmessage-length=0
|
||||
-fsigned-char
|
||||
-ffunction-sections
|
||||
-fdata-sections
|
||||
-Wunused
|
||||
-Wuninitialized
|
||||
-Wmissing-declarations
|
||||
-Wconversion
|
||||
-Wpointer-arith
|
||||
-Wshadow
|
||||
-Wlogical-op
|
||||
-Waggregate-return
|
||||
-Wfloat-equal
|
||||
-DFX_ENABLE_EXFAT)
|
||||
|
||||
# Remove includes and files not needed from usbx build
|
||||
set(UX_STANDALONE_HOST_EXCLUDES
|
||||
# ux_host_class_asix
|
||||
# ux_host_class_audio
|
||||
# ux_host_class_cdc_acm
|
||||
# ux_host_class_cdc_ecm
|
||||
# ux_host_class_gser
|
||||
# ux_host_class_hid
|
||||
# ux_host_class_hub
|
||||
# ux_host_class_pima
|
||||
# ux_host_class_printer
|
||||
# ux_host_class_prolific
|
||||
# ux_host_class_storage
|
||||
# ux_host_class_swar
|
||||
# ux_host_class_video
|
||||
# ux_hcd_ehci
|
||||
# ux_hcd_ohci
|
||||
)
|
||||
set(UX_STANDALONE_DEVICE_EXCLUDES
|
||||
# ux_device_class_audio
|
||||
# ux_device_class_cdc_acm
|
||||
# ux_device_class_cdc_ecm
|
||||
# ux_device_class_dfu
|
||||
# ux_device_class_hid
|
||||
# ux_device_class_pima
|
||||
# ux_device_class_rndis
|
||||
# ux_device_class_ccid
|
||||
# ux_device_class_printer
|
||||
# ux_device_class_video
|
||||
)
|
||||
set(UX_STANDALONE_UTILITY_EXCLUDES
|
||||
# ux_utility_event
|
||||
# ux_utility_delay
|
||||
# ux_utility_mutex
|
||||
# ux_utility_semaphore
|
||||
# ux_utility_thread
|
||||
# ux_utility_timer
|
||||
)
|
||||
set(UX_STANDALONE_PICTBRIDGE_EXCLUDES
|
||||
# ux_pictbridge
|
||||
)
|
||||
set(UX_STANDALONE_NX_EXCLUDES
|
||||
# ux_network_driver
|
||||
)
|
||||
set(UX_STANDALONE_FX_EXCLUDES
|
||||
# ux_host_class_storage_driver_entry
|
||||
usbx_ux_host_class_storage_fx_driver
|
||||
)
|
||||
if(CMAKE_BUILD_TYPE MATCHES "standalone.*")
|
||||
get_target_property(test_utility_SOURCES_LIST test_utility SOURCES)
|
||||
get_target_property(SOURCES_LIST usbx SOURCES)
|
||||
get_target_property(INCLUDES_LIST usbx INCLUDE_DIRECTORIES)
|
||||
|
||||
if("${CMAKE_BUILD_TYPE}" STREQUAL "standalone_build_coverage")
|
||||
# TODO: enable when STANDALONE implement is done
|
||||
# Remove files not support STANDALONE yet
|
||||
foreach(EXCLUDE_VAL ${UX_STANDALONE_HOST_EXCLUDES}
|
||||
${UX_STANDALONE_DEVICE_EXCLUDES}
|
||||
${UX_STANDALONE_UTILITY_EXCLUDES}
|
||||
${UX_STANDALONE_PICTBRIDGE_EXCLUDES}
|
||||
${UX_STANDALONE_NX_EXCLUDES}
|
||||
${UX_STANDALONE_FX_EXCLUDES})
|
||||
list(FILTER test_utility_SOURCES_LIST EXCLUDE REGEX ".*${EXCLUDE_VAL}.*")
|
||||
list(FILTER SOURCES_LIST EXCLUDE REGEX ".*${EXCLUDE_VAL}.*")
|
||||
endforeach()
|
||||
# Update includes to remove TX,FX,NX libs
|
||||
list(FILTER INCLUDES_LIST EXCLUDE REGEX ".*externals.*")
|
||||
list(FILTER INCLUDES_LIST EXCLUDE REGEX ".*/libs/inc.*")
|
||||
# Update library links to remove TX,FX,NX libs
|
||||
set_target_properties(usbx PROPERTIES LINK_LIBRARIES "")
|
||||
set_target_properties(usbx PROPERTIES INTERFACE_LINK_LIBRARIES "")
|
||||
|
||||
elseif("${CMAKE_BUILD_TYPE}" STREQUAL "standalone_device_build_coverage")
|
||||
# Only device part linked with STANDALONE
|
||||
# Remove files not support STANDALONE yet
|
||||
foreach(EXCLUDE_VAL ${UX_STANDALONE_DEVICE_EXCLUDES})
|
||||
list(FILTER SOURCES_LIST EXCLUDE REGEX ".*${EXCLUDE_VAL}.*")
|
||||
list(FILTER test_utility_SOURCES_LIST EXCLUDE REGEX ".*${EXCLUDE_VAL}.*")
|
||||
endforeach()
|
||||
|
||||
elseif("${CMAKE_BUILD_TYPE}" STREQUAL "standalone_host_build_coverage")
|
||||
# Only host part linked with STANDALONE
|
||||
# Remove files not support STANDALONE yet
|
||||
foreach(EXCLUDE_VAL ${UX_STANDALONE_HOST_EXCLUDES})
|
||||
list(FILTER SOURCES_LIST EXCLUDE REGEX ".*${EXCLUDE_VAL}.*")
|
||||
list(FILTER test_utility_SOURCES_LIST EXCLUDE REGEX ".*${EXCLUDE_VAL}.*")
|
||||
endforeach()
|
||||
|
||||
elseif("${CMAKE_BUILD_TYPE}" STREQUAL "standalone_otg_build")
|
||||
# Only some stack file linked with STANDALONE
|
||||
# No file list change for now
|
||||
endif()
|
||||
|
||||
# Commit sources and includes changes
|
||||
set_target_properties(test_utility PROPERTIES SOURCES "${test_utility_SOURCES_LIST}")
|
||||
set_target_properties(usbx PROPERTIES SOURCES "${SOURCES_LIST}")
|
||||
set_target_properties(usbx PROPERTIES INCLUDE_DIRECTORIES "${INCLUDES_LIST}")
|
||||
endif()
|
||||
|
||||
# Remove files not compatible with optimized build
|
||||
set(UX_OPTIMIZED_EXCLUDES
|
||||
ux_device_class_rndis # buffer smaller than message size
|
||||
)
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "optimized_build")
|
||||
get_target_property(test_utility_SOURCES_LIST test_utility SOURCES)
|
||||
get_target_property(SOURCES_LIST usbx SOURCES)
|
||||
|
||||
# Remove files not support STANDALONE yet
|
||||
foreach(EXCLUDE_VAL ${UX_OPTIMIZED_EXCLUDES})
|
||||
list(FILTER test_utility_SOURCES_LIST EXCLUDE REGEX ".*${EXCLUDE_VAL}.*")
|
||||
list(FILTER SOURCES_LIST EXCLUDE REGEX ".*${EXCLUDE_VAL}.*")
|
||||
endforeach()
|
||||
|
||||
# Commit sources and includes changes
|
||||
set_target_properties(test_utility PROPERTIES SOURCES "${test_utility_SOURCES_LIST}")
|
||||
set_target_properties(usbx PROPERTIES SOURCES "${SOURCES_LIST}")
|
||||
endif()
|
||||
|
||||
# Use generic port file for generic build.
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "generic_build")
|
||||
get_target_property(INCLUDES_LIST usbx INCLUDE_DIRECTORIES)
|
||||
set(NEW_INCLUDES_LIST "")
|
||||
foreach(INCLUDE_LIST ${INCLUDES_LIST})
|
||||
string(REPLACE "ports/linux/gnu" "ports/generic" INCLUDE_LIST ${INCLUDE_LIST})
|
||||
list(APPEND NEW_INCLUDES_LIST "${INCLUDE_LIST}")
|
||||
endforeach()
|
||||
set_target_properties(usbx PROPERTIES INCLUDE_DIRECTORIES "${NEW_INCLUDES_LIST}")
|
||||
endif()
|
124
test/cmake/usbx/coverage.sh
Executable file
124
test/cmake/usbx/coverage.sh
Executable file
@ -0,0 +1,124 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
cd $(dirname $0)
|
||||
root_path=$(cd ../../../common; pwd)
|
||||
|
||||
# Exclude strings
|
||||
exclude_file_list=" $root_path/*/src/*_class_asix*"
|
||||
exclude_file_list+=" $root_path/*/src/*_class_audio*"
|
||||
exclude_file_list+=" $root_path/*/src/*_class_ccid*"
|
||||
exclude_file_list+=" $root_path/*/src/*_class_dfu*"
|
||||
exclude_file_list+=" $root_path/*/src/*_class_gser*"
|
||||
exclude_file_list+=" $root_path/*/src/*_class_pima*"
|
||||
exclude_file_list+=" $root_path/*/src/*_class_rndis*"
|
||||
exclude_file_list+=" $root_path/*/src/*_class_printer*"
|
||||
exclude_file_list+=" $root_path/*/src/*_class_prolific*"
|
||||
exclude_file_list+=" $root_path/*/src/*_class_swar*"
|
||||
exclude_file_list+=" $root_path/*/src/*_class_video*"
|
||||
exclude_file_list+=" $root_path/*/src/*_hnp_*"
|
||||
exclude_file_list+=" $root_path/*/src/*_role_*"
|
||||
exclude_file_list+=" $root_path/*/src/ux_utility_set_interrupt_handler.c"
|
||||
exclude_file_list+=" $root_path/*/src/*dcd_sim_slave*"
|
||||
exclude_file_list+=" $root_path/*/src/*device_class_dpump*"
|
||||
exclude_file_list+=" $root_path/*/src/*hcd_sim_host*"
|
||||
exclude_file_list+=" $root_path/*/src/*host_class_dpump*"
|
||||
exclude_file_list+=" $root_path/*/src/*ux_network_driver*"
|
||||
|
||||
# Device HID interrupt OUT related
|
||||
exclude_file_list+=" $root_path/*/src/ux_device_class_hid_read.c"
|
||||
exclude_file_list+=" $root_path/*/src/ux_device_class_hid_receiver*"
|
||||
|
||||
# CB/CBI related
|
||||
exclude_file_list+=" $root_path/*/src/*_storage*_cb.c"
|
||||
exclude_file_list+=" $root_path/*/src/*_storage*_cbi.c"
|
||||
|
||||
# CD/DVD related things
|
||||
exclude_file_list+=" $root_path/*/src/*_storage_get_status*"
|
||||
exclude_file_list+=" $root_path/*/src/*_storage_get_configuration*"
|
||||
exclude_file_list+=" $root_path/*/src/*_storage_get_performance*"
|
||||
exclude_file_list+=" $root_path/*/src/*_storage_read_disk_information*"
|
||||
exclude_file_list+=" $root_path/*/src/*_storage_report_key*"
|
||||
exclude_file_list+=" $root_path/*/src/*_storage_read_dvd*"
|
||||
exclude_file_list+=" $root_path/*/src/*_storage_read_toc*"
|
||||
|
||||
# Obsolete
|
||||
exclude_file_list+=" $root_path/*/src/ux_device_stack_interface_get.c"
|
||||
exclude_file_list+=" $root_path/*/src/ux_host_stack_delay_ms.c"
|
||||
|
||||
# Host controllers
|
||||
exclude_file_list+=" $root_path/usbx_host_controllers/src/*"
|
||||
|
||||
# Pictbridge related files
|
||||
exclude_file_list+=" $root_path/usbx_pictbridge/src/*"
|
||||
|
||||
# Host related files
|
||||
exclude_host_list=" $root_path/*/src/*_host_*"
|
||||
|
||||
# Device related files
|
||||
exclude_device_list=" $root_path/*/src/*_device_*"
|
||||
|
||||
# RTOS related files
|
||||
exclude_rtos_list=" $root_path/*/src/*_thread*"
|
||||
exclude_rtos_list+=" $root_path/*/src/*_event_*"
|
||||
exclude_rtos_list+=" $root_path/*/src/*_mutex_*"
|
||||
exclude_rtos_list+=" $root_path/*/src/*_semaphore_*"
|
||||
exclude_rtos_list+=" $root_path/*/src/*_timer_*"
|
||||
|
||||
exclude_rtos_list+=" $root_path/*/src/*_cdc_ecm_*"
|
||||
|
||||
exclude_rtos_list+=" $root_path/*/src/*_hub_*"
|
||||
|
||||
exclude_rtos_list+=" $root_path/*/src/*_cdc_acm_capabilities_get.c"
|
||||
exclude_rtos_list+=" $root_path/*/src/*_cdc_acm_configure.c"
|
||||
|
||||
exclude_rtos_list+=" $root_path/*/src/*_hid_configure.c"
|
||||
exclude_rtos_list+=" $root_path/*/src/*_hid_descriptor_parse.c"
|
||||
exclude_rtos_list+=" $root_path/*/src/*_hid_report_descriptor_get.c"
|
||||
|
||||
exclude_rtos_list+=" $root_path/*/src/*_storage_configure.c"
|
||||
exclude_rtos_list+=" $root_path/*/src/*_storage_media_mount.c"
|
||||
exclude_rtos_list+=" $root_path/*/src/*_storage_media_open.c"
|
||||
exclude_rtos_list+=" $root_path/*/src/*_storage_partition_read.c"
|
||||
exclude_rtos_list+=" $root_path/*/src/*_storage_transport.c"
|
||||
|
||||
# Standalone related files
|
||||
exclude_standalone_list=" $root_path/*/src/*_run.c"
|
||||
|
||||
if [[ $1 = *"_full_coverage" ]]; then
|
||||
|
||||
exclude_options=""
|
||||
else
|
||||
|
||||
exclude_options=""
|
||||
for f in $exclude_file_list;do
|
||||
exclude_options+=" -e $f"
|
||||
done
|
||||
|
||||
if [[ $1 = *"_device_"* ]]; then
|
||||
for f in $exclude_host_list;do
|
||||
exclude_options+=" -e $f"
|
||||
done
|
||||
fi
|
||||
|
||||
if [[ $1 = *"_host_"* ]]; then
|
||||
for f in $exclude_device_list;do
|
||||
exclude_options+=" -e $f"
|
||||
done
|
||||
fi
|
||||
|
||||
if [[ $1 = "standalone_"* ]]; then
|
||||
for f in $exclude_rtos_list;do
|
||||
exclude_options+=" -e $f"
|
||||
done
|
||||
else
|
||||
for f in $exclude_standalone_list;do
|
||||
exclude_options+=" -e $f"
|
||||
done
|
||||
fi
|
||||
fi
|
||||
|
||||
mkdir -p coverage_report/$1
|
||||
gcovr --object-directory=build/$1/usbx/CMakeFiles/usbx.dir/common -r ../../../common $exclude_options --xml-pretty --output coverage_report/$1.xml
|
||||
gcovr --object-directory=build/$1/usbx/CMakeFiles/usbx.dir/common -r ../../../common $exclude_options --html --html-details --html-high-threshold 100.0 --output coverage_report/$1/index.html
|
740
test/cmake/usbx/regression/CMakeLists.txt
Normal file
740
test/cmake/usbx/regression/CMakeLists.txt
Normal file
@ -0,0 +1,740 @@
|
||||
cmake_minimum_required(VERSION 3.0.0 FATAL_ERROR)
|
||||
cmake_policy(SET CMP0057 NEW)
|
||||
|
||||
project(regression_test LANGUAGES C)
|
||||
|
||||
get_filename_component(SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/../../../regression
|
||||
ABSOLUTE)
|
||||
|
||||
set(ux_class_dfu_test_cases
|
||||
${SOURCE_DIR}/usbx_device_dfu_basic_test.c
|
||||
${SOURCE_DIR}/usbx_uxe_device_dfu_test.c
|
||||
)
|
||||
|
||||
set(ux_class_hub_test_cases
|
||||
${SOURCE_DIR}/usbx_host_class_hub_port_change_connection_process_coverage_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hub_descriptor_get_coverage_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hub_status_get_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hub_transfer_request_completed_test.c
|
||||
${SOURCE_DIR}/usbx_hub_hub_status_get_invalid_length_test.c
|
||||
${SOURCE_DIR}/usbx_hub_no_power_switching_test.c
|
||||
${SOURCE_DIR}/usbx_hub_get_hub_status_fails_during_port_reset_test.c
|
||||
${SOURCE_DIR}/usbx_hub_port_never_reset_test.c
|
||||
${SOURCE_DIR}/usbx_hub_port_change_reset_test.c
|
||||
${SOURCE_DIR}/usbx_hub_port_change_over_current_test.c
|
||||
${SOURCE_DIR}/usbx_hub_port_change_suspend_test.c
|
||||
${SOURCE_DIR}/usbx_hub_get_hub_status_fails_during_hub_device_enum_test.c
|
||||
${SOURCE_DIR}/usbx_hub_basic_test.c
|
||||
${SOURCE_DIR}/usbx_hub_basic_memory_test.c
|
||||
${SOURCE_DIR}/usbx_hub_get_status_fails_during_configuration_test.c
|
||||
${SOURCE_DIR}/usbx_hub_invalid_hub_descriptor_length_test.c
|
||||
${SOURCE_DIR}/usbx_bus_powered_hub_conn_to_self_and_bus_powered_hub_test.c
|
||||
${SOURCE_DIR}/usbx_hub_full_speed_hub_test.c
|
||||
${SOURCE_DIR}/usbx_hub_multiple_tt_test.c
|
||||
${SOURCE_DIR}/usbx_hub_invalid_device_protocol_test.c
|
||||
${SOURCE_DIR}/usbx_hub_request_to_hub_itself_test.c
|
||||
${SOURCE_DIR}/usbx_hub_single_tt_too_many_hub_ports_test.c
|
||||
${SOURCE_DIR}/usbx_hub_multiple_tt_too_many_hub_ports_test.c
|
||||
${SOURCE_DIR}/usbx_hub_no_endpoints_test.c
|
||||
${SOURCE_DIR}/usbx_hub_interrupt_out_endpoint_test.c
|
||||
${SOURCE_DIR}/usbx_hub_non_interrupt_in_endpoint_test.c
|
||||
${SOURCE_DIR}/usbx_hub_hub_device_connect_test.c
|
||||
${SOURCE_DIR}/usbx_hub_hub_device_disconnect_test.c
|
||||
${SOURCE_DIR}/usbx_hub_quick_hub_device_reconnection_test.c
|
||||
${SOURCE_DIR}/usbx_hub_hub_device_enumeration_keeps_failing_test.c
|
||||
${SOURCE_DIR}/usbx_hub_port_reset_fails_during_hub_device_enum_test.c
|
||||
${SOURCE_DIR}/usbx_hub_get_port_status_fails_during_hub_device_enum_test.c
|
||||
${SOURCE_DIR}/usbx_hub_low_speed_hub_device_test.c
|
||||
${SOURCE_DIR}/usbx_hub_full_speed_hub_device_test.c
|
||||
${SOURCE_DIR}/usbx_hub_quick_hub_device_disconnection_test.c
|
||||
${SOURCE_DIR}/usbx_hub_port_change_enable_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hub_entry_test.c)
|
||||
|
||||
set(ux_class_hub_standalone_test_cases
|
||||
${SOURCE_DIR}/usbx_hub_basic_test.c
|
||||
${SOURCE_DIR}/usbx_hub_basic_memory_test.c
|
||||
)
|
||||
|
||||
set(ux_class_audio_test_cases
|
||||
${SOURCE_DIR}/usbx_audio10_device_basic_test.c
|
||||
${SOURCE_DIR}/usbx_audio10_device_feedback_test.c
|
||||
${SOURCE_DIR}/usbx_audio10_iad_device_basic_test.c
|
||||
${SOURCE_DIR}/usbx_audio10_iad_device_control_test.c
|
||||
${SOURCE_DIR}/usbx_audio10_iad_device_interrupt_test.c
|
||||
${SOURCE_DIR}/usbx_audio20_device_basic_test.c
|
||||
${SOURCE_DIR}/usbx_audio20_device_controls_test.c
|
||||
${SOURCE_DIR}/usbx_audio20_device_feedback_test.c
|
||||
${SOURCE_DIR}/usbx_audio10_iad_host_basic_test.c
|
||||
${SOURCE_DIR}/usbx_audio20_host_basic_test.c
|
||||
${SOURCE_DIR}/usbx_uxe_device_audio_test.c
|
||||
${SOURCE_DIR}/usbx_uxe_host_audio_test.c
|
||||
)
|
||||
|
||||
set(ux_class_audio_device_standalone_test_cases
|
||||
${SOURCE_DIR}/usbx_audio10_device_basic_test.c
|
||||
${SOURCE_DIR}/usbx_audio20_device_basic_test.c
|
||||
${SOURCE_DIR}/usbx_audio10_device_feedback_test.c
|
||||
${SOURCE_DIR}/usbx_audio20_device_feedback_test.c
|
||||
${SOURCE_DIR}/usbx_audio10_iad_device_interrupt_test.c
|
||||
)
|
||||
|
||||
set(ux_class_rndis_test_cases ${SOURCE_DIR}/usbx_rndis_basic_test.c)
|
||||
|
||||
set(ux_class_cdc_ecm_test_cases
|
||||
${SOURCE_DIR}/usbx_cdc_ecm_basic_test.c
|
||||
${SOURCE_DIR}/usbx_cdc_ecm_basic_ipv6_test.c
|
||||
${SOURCE_DIR}/usbx_cdc_ecm_nx_packet_chain_test.c
|
||||
${SOURCE_DIR}/usbx_cdc_ecm_disconnect_and_reconnect_test.c
|
||||
${SOURCE_DIR}/usbx_cdc_ecm_alternate_setting_change_to_zero_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_cdc_ecm_transmission_callback_test.c
|
||||
${SOURCE_DIR}/usbx_cdc_ecm_host_bulko_transfer_arming_during_link_dn_test.c
|
||||
${SOURCE_DIR}/usbx_cdc_ecm_host_bulk_out_transfer_fail_test.c
|
||||
${SOURCE_DIR}/usbx_cdc_ecm_host_bulki_arm_err_dueto_link_dn_thread_wait_test.c
|
||||
${SOURCE_DIR}/usbx_cdc_ecm_host_non_ip_packet_received_test.c
|
||||
${SOURCE_DIR}/usbx_cdc_ecm_host_bulk_in_transfer_fail_test.c
|
||||
${SOURCE_DIR}/usbx_cdc_ecm_host_thread_link_down_before_transfer_test.c
|
||||
${SOURCE_DIR}/usbx_cdc_ecm_host_thread_packet_allocate_fail_test.c
|
||||
${SOURCE_DIR}/usbx_cdc_ecm_host_thread_packet_append_fail_test.c
|
||||
${SOURCE_DIR}/usbx_cdc_ecm_mac_address_test.c
|
||||
${SOURCE_DIR}/usbx_cdc_ecm_mac_address_invalid_length_test.c
|
||||
${SOURCE_DIR}/usbx_cdc_ecm_no_functional_descriptor_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_cdc_ecm_mac_address_get_test.c
|
||||
${SOURCE_DIR}/usbx_cdc_ecm_host_bulk_in_transfer_arming_during_link_down_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_cdc_ecm_interrupt_notification_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_cdc_ecm_entry_test.c
|
||||
${SOURCE_DIR}/usbx_cdc_ecm_host_bulk_in_transfer_arming_during_deactivate_test.c
|
||||
${SOURCE_DIR}/usbx_cdc_ecm_host_first_interrupt_transfer_fail_test.c
|
||||
${SOURCE_DIR}/usbx_cdc_ecm_host_packet_pool_create_fail_test.c
|
||||
${SOURCE_DIR}/usbx_cdc_ecm_host_thread_create_fail_test.c
|
||||
${SOURCE_DIR}/usbx_cdc_ecm_host_int_notification_semaphore_create_fail_test.c
|
||||
${SOURCE_DIR}/usbx_cdc_ecm_host_bulk_out_semaphore_create_fail_test.c
|
||||
${SOURCE_DIR}/usbx_cdc_ecm_host_bulk_in_semaphore_create_fail_test.c
|
||||
${SOURCE_DIR}/usbx_cdc_ecm_control_interface_no_interrupt_endpoint_test.c
|
||||
${SOURCE_DIR}/usbx_cdc_ecm_data_iface_non_bulko_and_non_bulki_endpt_test.c
|
||||
${SOURCE_DIR}/usbx_cdc_ecm_basic_memory_test.c
|
||||
${SOURCE_DIR}/usbx_cdc_ecm_data_interface_setting_select_fails_test.c
|
||||
${SOURCE_DIR}/usbx_cdc_ecm_non_data_iface_after_zero_endpt_data_iface_test.c
|
||||
${SOURCE_DIR}/usbx_cdc_ecm_invalid_alt_setting_after_zero_endpt_data_iface_test.c
|
||||
${SOURCE_DIR}/usbx_cdc_ecm_default_data_interface_setting_with_endpoints_test.c
|
||||
${SOURCE_DIR}/usbx_cdc_ecm_one_data_interface_with_no_endpoints_test.c
|
||||
${SOURCE_DIR}/usbx_cdc_ecm_no_control_interface_test.c
|
||||
${SOURCE_DIR}/usbx_cdc_ecm_interface_before_control_interface_test.c
|
||||
${SOURCE_DIR}/usbx_cdc_ecm_data_interface_no_bulk_out_endpoint_test.c
|
||||
${SOURCE_DIR}/usbx_cdc_ecm_data_interface_no_bulk_in_endpoint_test.c
|
||||
${SOURCE_DIR}/usbx_cdc_ecm_link_down_while_ongoing_transfers_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_cdc_ecm_write_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_cdc_ecm_activate_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_cdc_ecm_bulkin_thread_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_cdc_ecm_bulkout_thread_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_cdc_ecm_control_request_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_cdc_ecm_change_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_cdc_ecm_entry_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_cdc_ecm_deactivate_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_cdc_ecm_initialize_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_cdc_ecm_interrupt_thread_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_cdc_ecm_uninitialize_test.c)
|
||||
|
||||
set(ux_class_hid_test_cases
|
||||
${SOURCE_DIR}/usbx_ux_device_class_hid_basic_memory_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_hid_activate_test2.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_hid_activate_test3.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_hid_control_request_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_hid_initialize_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_hid_interrupt_thread_test2.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_hid_read_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_hid_receiver_memory_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_hid_receiver_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_hid_report_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_hid_report_set_test2.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_hid_idle_rate_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_hid_wMaxPacketSize_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hid_client_register_test2.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hid_deactivate_test3.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hid_report_descriptor_get_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hid_report_descriptor_get_test4.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hid_idle_get_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hid_interrupt_endpoint_search_int_out_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hid_interrupt_endpoint_search_test2.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hid_keyboard_callback_test2.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hid_keyboard_ioctl_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hid_main_item_parse_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hid_main_item_parse_test2.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hid_mouse_entry_test2.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hid_mouse_entry_test3.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hid_periodic_report_start_test2.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hid_remote_control_activate_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hid_remote_control_activate_test2.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hid_remote_control_entry_test2.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hid_remote_control_entry_test3.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hid_report_get_test2.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hid_transfer_request_completed_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hid_deactivate_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hid_descriptor_parse_coverage_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hid_descriptor_parse_test2.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hid_descriptor_parse_test4.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hid_descriptor_parse_test5.c
|
||||
${SOURCE_DIR}/usbx_hid_keyboard_extraction_test2.c
|
||||
${SOURCE_DIR}/usbx_hid_mouse_extraction_test2.c
|
||||
${SOURCE_DIR}/usbx_hid_remote_control_extraction_test2.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hid_keyboard_thread_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hid_keyboard_thread_test2.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_hid_activate_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_hid_deactivate_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_hid_entry_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hid_activate_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hid_configure_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hid_descriptor_parse_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hid_entry_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hid_idle_set_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hid_interrupt_endpoint_search_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hid_keyboard_activate_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hid_keyboard_entry_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hid_local_item_parse_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hid_mouse_activate_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hid_mouse_buttons_get_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hid_mouse_entry_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hid_mouse_positions_get_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hid_mouse_wheel_get_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hid_periodic_report_start_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hid_periodic_report_stop_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hid_remote_control_entry_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hid_remote_control_usage_get_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hid_report_add_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hid_report_callback_register_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hid_report_id_get_test.c
|
||||
${SOURCE_DIR}/usbx_hid_interrupt_endpoint_get_report_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_hid_event_get_AND_set_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hid_client_register_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hid_client_search_test.c
|
||||
${SOURCE_DIR}/usbx_control_transfer_stall_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_hid_descriptor_send_test.c
|
||||
${SOURCE_DIR}/usbx_hid_keyboard_key_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_hid_interrupt_thread_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_hid_report_set_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hid_report_get_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hid_report_set_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hid_report_set_int_out_test.c
|
||||
${SOURCE_DIR}/usbx_hid_keyboard_key_get_test.c
|
||||
${SOURCE_DIR}/usbx_hid_transfer_request_completed_decompressed_test.c
|
||||
${SOURCE_DIR}/usbx_hid_transfer_request_completed_raw_test.c
|
||||
${SOURCE_DIR}/usbx_hid_transfer_request_completed_test.c
|
||||
${SOURCE_DIR}/usbx_hid_remote_control_extraction_test.c
|
||||
${SOURCE_DIR}/usbx_hid_report_descriptor_compress_test.c
|
||||
${SOURCE_DIR}/usbx_hid_report_descriptor_compress_array_test.c
|
||||
${SOURCE_DIR}/usbx_hid_report_descriptor_compress_and_decompress_test.c
|
||||
${SOURCE_DIR}/usbx_hid_keyboard_extraction_test.c
|
||||
${SOURCE_DIR}/usbx_hid_keyboard_basic_test.c
|
||||
${SOURCE_DIR}/usbx_hid_mouse_basic_test.c
|
||||
${SOURCE_DIR}/usbx_hid_mouse_extraction_test.c
|
||||
${SOURCE_DIR}/usbx_hid_remote_control_tests.c
|
||||
${SOURCE_DIR}/usbx_hid_report_descriptor_collection_overflow_test.c
|
||||
${SOURCE_DIR}/usbx_hid_report_descriptor_decompress_array_test.c
|
||||
${SOURCE_DIR}/usbx_hid_report_descriptor_decompress_test.c
|
||||
${SOURCE_DIR}/usbx_hid_report_descriptor_delimiter_nested_close_test.c
|
||||
${SOURCE_DIR}/usbx_hid_report_descriptor_delimiter_nested_open_test.c
|
||||
${SOURCE_DIR}/usbx_hid_report_descriptor_delimiter_test.c
|
||||
${SOURCE_DIR}/usbx_hid_report_descriptor_delimiter_unknown_test.c
|
||||
${SOURCE_DIR}/usbx_hid_report_descriptor_end_collection_error_test.c
|
||||
${SOURCE_DIR}/usbx_hid_report_descriptor_example_andisplay_test.c
|
||||
${SOURCE_DIR}/usbx_hid_report_descriptor_example_delimit_test.c
|
||||
${SOURCE_DIR}/usbx_hid_report_descriptor_example_digit_test.c
|
||||
${SOURCE_DIR}/usbx_hid_report_descriptor_example_display_test.c
|
||||
${SOURCE_DIR}/usbx_hid_report_descriptor_example_joystk_test.c
|
||||
${SOURCE_DIR}/usbx_hid_report_descriptor_example_keybrd_test.c
|
||||
${SOURCE_DIR}/usbx_hid_report_descriptor_example_monitor_test.c
|
||||
${SOURCE_DIR}/usbx_hid_report_descriptor_example_mouse_test.c
|
||||
${SOURCE_DIR}/usbx_hid_report_descriptor_example_remote_test.c
|
||||
${SOURCE_DIR}/usbx_hid_report_descriptor_example_tele_test.c
|
||||
${SOURCE_DIR}/usbx_hid_report_descriptor_get_zero_length_item_data_test.c
|
||||
${SOURCE_DIR}/usbx_hid_report_descriptor_global_item_persist_test.c
|
||||
${SOURCE_DIR}/usbx_hid_report_descriptor_global_item_test.c
|
||||
${SOURCE_DIR}/usbx_hid_report_descriptor_incoherent_usage_min_max_test.c
|
||||
${SOURCE_DIR}/usbx_hid_report_descriptor_invalid_item_test.c
|
||||
${SOURCE_DIR}/usbx_hid_report_descriptor_invalid_length_test.c
|
||||
${SOURCE_DIR}/usbx_hid_report_descriptor_item_size_test.c
|
||||
${SOURCE_DIR}/usbx_hid_report_descriptor_multiple_collections_test.c
|
||||
${SOURCE_DIR}/usbx_hid_report_descriptor_multiple_fields_and_reports_test.c
|
||||
${SOURCE_DIR}/usbx_hid_report_descriptor_multiple_fields_test.c
|
||||
${SOURCE_DIR}/usbx_hid_report_descriptor_multiple_reports_feature_test.c
|
||||
${SOURCE_DIR}/usbx_hid_report_descriptor_multiple_reports_input_test.c
|
||||
${SOURCE_DIR}/usbx_hid_report_descriptor_multiple_reports_output_test.c
|
||||
${SOURCE_DIR}/usbx_hid_report_descriptor_pop_underflow_test.c
|
||||
${SOURCE_DIR}/usbx_hid_report_descriptor_push_overflow_test.c
|
||||
${SOURCE_DIR}/usbx_hid_report_descriptor_push_pop_test.c
|
||||
${SOURCE_DIR}/usbx_hid_report_descriptor_report_count_overflow_test.c
|
||||
${SOURCE_DIR}/usbx_hid_report_descriptor_report_size_overflow_test.c
|
||||
${SOURCE_DIR}/usbx_hid_report_descriptor_unknown_global_tag_test.c
|
||||
${SOURCE_DIR}/usbx_hid_report_descriptor_unknown_local_tag_test.c
|
||||
${SOURCE_DIR}/usbx_hid_report_descriptor_usages_min_max_test.c
|
||||
${SOURCE_DIR}/usbx_hid_report_descriptor_usages_single_test.c
|
||||
${SOURCE_DIR}/usbx_hid_report_multiple_reports_ids_test.c
|
||||
${SOURCE_DIR}/usbx_uxe_device_hid_test.c
|
||||
${SOURCE_DIR}/usbx_uxe_host_hid_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hid_logitech_pro_x_superlight_test.c
|
||||
)
|
||||
set(ux_class_hid_device_standalone_test_cases
|
||||
${SOURCE_DIR}/usbx_hid_mouse_basic_test.c
|
||||
${SOURCE_DIR}/usbx_hid_keyboard_basic_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_hid_basic_memory_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_hid_control_request_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_hid_read_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_hid_receiver_memory_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_hid_receiver_test.c
|
||||
${SOURCE_DIR}/usbx_uxe_device_hid_test.c
|
||||
)
|
||||
set(ux_class_hid_host_standalone_test_cases
|
||||
${SOURCE_DIR}/usbx_class_hid_basic_test.c
|
||||
${SOURCE_DIR}/usbx_class_hid_keyboard_basic_test.c
|
||||
${SOURCE_DIR}/usbx_class_hid_mouse_basic_test.c
|
||||
${SOURCE_DIR}/usbx_class_hid_remote_control_basic_test.c
|
||||
${SOURCE_DIR}/usbx_class_hid_basic_memory_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_hid_report_set_int_out_test.c
|
||||
${SOURCE_DIR}/usbx_uxe_host_hid_test.c
|
||||
)
|
||||
set(ux_class_hid_standalone_test_cases
|
||||
)
|
||||
|
||||
set(ux_class_cdc_acm_test_cases
|
||||
${SOURCE_DIR}/usbx_cdc_acm_basic_test.c
|
||||
${SOURCE_DIR}/usbx_cdc_acm_basic_memory_test.c
|
||||
${SOURCE_DIR}/usbx_cdc_acm_configure_test.c
|
||||
${SOURCE_DIR}/usbx_cdc_acm_device_dtr_rts_reset_on_disconnect_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_cdc_acm_activate_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_cdc_acm_deactivate_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_cdc_acm_ioctl_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_cdc_acm_transmission_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_cdc_acm_write_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_cdc_acm_timeout_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_cdc_acm_activate_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_cdc_acm_capabilities_get_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_cdc_acm_deactivate_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_cdc_acm_endpoints_get_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_cdc_acm_entry_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_cdc_acm_read_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_cdc_acm_transfer_request_completed_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_cdc_acm_write_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_cdc_acm_bulkout_thread_test.c
|
||||
)
|
||||
|
||||
set(ux_class_gser_test_cases
|
||||
${SOURCE_DIR}/usbx_uxe_host_gser_test.c
|
||||
)
|
||||
set(ux_class_prolific_test_cases
|
||||
${SOURCE_DIR}/usbx_uxe_host_prolific_test.c
|
||||
)
|
||||
set(ux_class_swar_test_cases
|
||||
${SOURCE_DIR}/usbx_uxe_host_swar_test.c
|
||||
)
|
||||
|
||||
set(ux_dpump_test_cases ${SOURCE_DIR}/usbx_dpump_basic_test.c)
|
||||
|
||||
set(ux_device_class_storage_tx_test_cases ${SOURCE_DIR}/usbx_storage_tests.c)
|
||||
|
||||
set(ux_class_storage_test_cases
|
||||
${SOURCE_DIR}/usbx_host_class_storage_max_lun_get_coverage_test.c
|
||||
${SOURCE_DIR}/usbx_host_class_storage_entry_coverage_test.c
|
||||
${SOURCE_DIR}/usbx_storage_basic_memory_test.c
|
||||
${SOURCE_DIR}/usbx_storage_multi_lun_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_storage_request_sense_coverage_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_storage_control_request_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_storage_entry_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_storage_format_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_storage_initialize_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_storage_inquiry_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_storage_mode_select_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_storage_mode_sense_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_storage_prevent_allow_media_removal_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_storage_read_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_storage_request_sense_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_storage_start_stop_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_storage_synchronize_cache_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_storage_test_ready_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_storage_thread_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_storage_uninitialize_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_storage_verify_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_storage_vendor_strings_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_storage_write_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_storage_invalid_lun_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_storage_configure_coverage_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_storage_request_sense_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_storage_media_capacity_get_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_storage_max_lun_get_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_storage_configure_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_storage_activate_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_storage_device_support_check_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_storage_device_initialize_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_storage_media_mount_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_storage_media_open_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_storage_media_read_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_storage_media_write_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_storage_media_protection_check_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_storage_media_recovery_sense_get_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_storage_start_stop_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_storage_transport_bo_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_storage_driver_entry_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_storage_entry_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_storage_thread_entry_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_storage_fats_exfat_test.c
|
||||
${SOURCE_DIR}/usbx_uxe_device_storage_test.c
|
||||
${SOURCE_DIR}/usbx_uxe_host_storage_test.c
|
||||
)
|
||||
set(ux_class_memory_management_test_cases
|
||||
${SOURCE_DIR}/usbx_ux_host_device_basic_memory_tests.c
|
||||
${SOURCE_DIR}/usbx_ux_utility_memory_safe_test.c
|
||||
${SOURCE_DIR}/usbx_ux_utility_memory_test.c
|
||||
${SOURCE_DIR}/usbx_ux_utility_basic_memory_management_test.c
|
||||
${SOURCE_DIR}/usbx_hub_basic_memory_test.c
|
||||
${SOURCE_DIR}/usbx_cdc_ecm_basic_memory_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_hid_basic_memory_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_class_hid_receiver_memory_test.c
|
||||
${SOURCE_DIR}/usbx_class_hid_basic_memory_test.c
|
||||
${SOURCE_DIR}/usbx_cdc_acm_basic_memory_test.c
|
||||
${SOURCE_DIR}/usbx_storage_basic_memory_test.c
|
||||
)
|
||||
set(ux_class_storage_device_standalone_test_cases
|
||||
${SOURCE_DIR}/usbx_standalone_device_storage_basic_test.c
|
||||
${SOURCE_DIR}/usbx_standalone_device_storage_read_write_test.c
|
||||
${SOURCE_DIR}/usbx_standalone_device_storage_error_cv_test.c
|
||||
)
|
||||
set(ux_class_storage_host_standalone_test_cases
|
||||
${SOURCE_DIR}/usbx_standalone_host_storage_basic_test.c
|
||||
${SOURCE_DIR}/usbx_standalone_host_storage_read_write_test.c
|
||||
${SOURCE_DIR}/usbx_standalone_host_storage_insert_eject_test.c
|
||||
${SOURCE_DIR}/usbx_uxe_host_storage_test.c
|
||||
)
|
||||
set(ux_class_storage_standalone_test_cases
|
||||
)
|
||||
|
||||
set(ux_stack_cdc_acm_test_cases
|
||||
${SOURCE_DIR}/usbx_ux_host_device_basic_tests.c
|
||||
${SOURCE_DIR}/usbx_ux_host_device_basic_memory_tests.c
|
||||
${SOURCE_DIR}/usbx_ux_host_device_initialize_tests.c
|
||||
${SOURCE_DIR}/usbx_ux_host_stack_class_instance_verify_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_stack_interface_setting_select_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_stack_new_configuration_create_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_stack_new_device_create_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_stack_new_interface_create_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_stack_rh_change_process_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_stack_endpoint_reset_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_stack_standard_request_tests.c
|
||||
${SOURCE_DIR}/usbx_ux_device_stack_descriptor_send_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_stack_remote_wakeup_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_stack_vendor_request_test.c
|
||||
${SOURCE_DIR}/usbx_uxe_device_cdc_acm_test.c
|
||||
${SOURCE_DIR}/usbx_uxe_host_cdc_acm_test.c
|
||||
)
|
||||
set(ux_class_cdc_acm_device_standalone_test_cases
|
||||
# ${SOURCE_DIR}/usbx_standalone_device_cdc_acm_basic_memory_test.c
|
||||
${SOURCE_DIR}/usbx_standalone_cdc_acm_basic_memory_test.c
|
||||
# ${SOURCE_DIR}/usbx_standalone_device_cdc_acm_basic_test.c
|
||||
${SOURCE_DIR}/usbx_standalone_cdc_acm_basic_test.c
|
||||
${SOURCE_DIR}/usbx_standalone_device_cdc_acm_transmission_test.c
|
||||
${SOURCE_DIR}/usbx_uxe_device_cdc_acm_test.c
|
||||
)
|
||||
set(ux_class_cdc_acm_host_standalone_test_cases
|
||||
${SOURCE_DIR}/usbx_standalone_cdc_acm_basic_memory_test.c
|
||||
${SOURCE_DIR}/usbx_standalone_cdc_acm_basic_test.c
|
||||
)
|
||||
|
||||
set(ux_stack_test_cases
|
||||
${SOURCE_DIR}/usbx_host_stack_class_unregister_coverage_test.c
|
||||
${SOURCE_DIR}/usbx_host_stack_new_endpoint_create_coverage_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_stack_uninitialize_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_stack_hcd_unregister_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_stack_bandwidth_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_stack_device_address_set_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_stack_device_configuration_activate_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_stack_device_configuration_reset_coverage_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_stack_device_get_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_stack_device_remove_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_stack_new_device_get_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_stack_class_device_scan_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_stack_class_get_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_stack_class_instance_destroy_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_stack_class_instance_get_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_stack_class_interface_scan_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_stack_class_register_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_stack_configuration_descriptor_parse_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_stack_configuration_enumerate_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_stack_configuration_instance_delete_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_stack_configuration_interface_get_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_stack_configuration_set_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_stack_device_descriptor_read_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_stack_endpoint_instance_create_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_stack_endpoint_instance_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_stack_hcd_register_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_stack_hcd_transfer_request_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_stack_interfaces_scan_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_stack_interface_endpoint_get_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_stack_rh_device_insertion_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_stack_device_configuration_get_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_stack_device_configuration_reset_select_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_stack_hcd_thread_entry_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_stack_transfer_request_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_stack_enum_bMaxPacketSize0_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_stack_enum_wMaxPacketSize_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_stack_transfer_request_abort_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_stack_class_register_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_stack_class_unregister_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_stack_set_feature_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_stack_alternate_setting_get_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_stack_alternate_setting_set_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_stack_configuration_set_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_stack_control_request_process_coverage_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_stack_control_request_process_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_stack_class_control_request_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_stack_interface_delete_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_stack_interface_set_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_stack_interface_start_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_stack_transfer_request_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_stack_endpoint_stall_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_stack_bos_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_stack_initialize_test.c
|
||||
${SOURCE_DIR}/usbx_ux_device_stack_clear_feature_coverage_test.c
|
||||
${SOURCE_DIR}/usbx_uxe_system_test.c
|
||||
${SOURCE_DIR}/usbx_uxe_device_stack_test.c
|
||||
${SOURCE_DIR}/usbx_uxe_host_stack_test.c
|
||||
)
|
||||
set(ux_stack_test_cases_hid
|
||||
${SOURCE_DIR}/usbx_ux_device_stack_get_status_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_stack_class_unregister_test.c
|
||||
)
|
||||
set(ux_stack_test_cases_cdc
|
||||
)
|
||||
set(ux_utility_test_cases
|
||||
${SOURCE_DIR}/usbx_ux_api_tracex_id_test.c
|
||||
${SOURCE_DIR}/usbx_ux_utility_descriptor_pack_test.c
|
||||
${SOURCE_DIR}/usbx_ux_utility_descriptor_parse_test.c
|
||||
${SOURCE_DIR}/usbx_ux_utility_descriptor_struct_test.c
|
||||
${SOURCE_DIR}/usbx_ux_utility_memory_safe_test.c
|
||||
${SOURCE_DIR}/usbx_ux_utility_memory_test.c
|
||||
${SOURCE_DIR}/usbx_ux_utility_pci_write_test.c
|
||||
${SOURCE_DIR}/usbx_ux_utility_pci_read_test.c
|
||||
${SOURCE_DIR}/usbx_ux_utility_pci_class_scan_test.c
|
||||
${SOURCE_DIR}/usbx_ux_utility_physical_address_test.c
|
||||
${SOURCE_DIR}/usbx_ux_utility_string_length_check_test.c
|
||||
${SOURCE_DIR}/usbx_ux_utility_unicode_to_string_test.c
|
||||
)
|
||||
set(ux_utility_os_test_cases
|
||||
${SOURCE_DIR}/usbx_ux_utility_event_flags_test.c
|
||||
${SOURCE_DIR}/usbx_ux_utility_mutex_test.c
|
||||
${SOURCE_DIR}/usbx_ux_utility_semaphore_test.c
|
||||
${SOURCE_DIR}/usbx_ux_utility_thread_create_test.c
|
||||
${SOURCE_DIR}/usbx_ux_utility_thread_schedule_other_test.c
|
||||
${SOURCE_DIR}/usbx_ux_utility_thread_suspend_test.c
|
||||
${SOURCE_DIR}/usbx_ux_utility_thread_identify_test.c
|
||||
${SOURCE_DIR}/usbx_ux_utility_timer_test.c
|
||||
)
|
||||
|
||||
set(ux_class_video_test_cases
|
||||
${SOURCE_DIR}/usbx_ux_device_class_video_basic_tests.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_video_basic_tests.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_video_dwMaxPayloadTransferSize_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_video_format_frame_based_test.c # device control buffer > 512
|
||||
${SOURCE_DIR}/usbx_ux_host_class_video_format_h264_test.c # device control buffer > 512
|
||||
${SOURCE_DIR}/usbx_uxe_device_video_test.c
|
||||
${SOURCE_DIR}/usbx_uxe_host_video_test.c
|
||||
)
|
||||
|
||||
set(ux_class_video_device_standalone_test_cases
|
||||
${SOURCE_DIR}/usbx_ux_device_class_video_basic_tests.c
|
||||
${SOURCE_DIR}/usbx_uxe_device_video_test.c
|
||||
)
|
||||
|
||||
set(ux_class_print_test_cases
|
||||
${SOURCE_DIR}/usbx_class_printer_basic_tests.c
|
||||
${SOURCE_DIR}/usbx_uxe_device_printer_test.c
|
||||
${SOURCE_DIR}/usbx_uxe_host_printer_test.c
|
||||
)
|
||||
|
||||
set(ux_class_printer_device_standalone_test_cases
|
||||
${SOURCE_DIR}/usbx_class_printer_device_standalone_basic_tests.c
|
||||
${SOURCE_DIR}/usbx_uxe_device_printer_test.c
|
||||
)
|
||||
|
||||
set(ux_msrc_test_cases
|
||||
${SOURCE_DIR}/usbx_msrc_69702_dfu_dnload_test.c
|
||||
${SOURCE_DIR}/usbx_msrc_71934_dfu_upload_test.c
|
||||
)
|
||||
set(ux_msrc_test_cases_rtos
|
||||
${SOURCE_DIR}/usbx_msrc_66679_test.c
|
||||
${SOURCE_DIR}/usbx_msrc_72427_ecm_host_mac_test.c
|
||||
${SOURCE_DIR}/usbx_msrc_72525_host_pima_obj_handles_get_test.c
|
||||
${SOURCE_DIR}/usbx_msrc_72619_host_pima_stor_ids_get_test.c
|
||||
${SOURCE_DIR}/usbx_msrc_72526_pictbridge_dps_host_start_test.c
|
||||
${SOURCE_DIR}/usbx_msrc_72227_host_pima_read_test.c
|
||||
${SOURCE_DIR}/usbx_msrc_73386_host_storage_media_open_buffer_test.c
|
||||
${SOURCE_DIR}/usbx_msrc_73716_cdc_ecm_mac_get_desc_check.c
|
||||
${SOURCE_DIR}/usbx_msrc_73492_host_vc_header_parse.c
|
||||
${SOURCE_DIR}/usbx_msrc_80947_device_cdc_ecm_rx_length_less_than_14.c
|
||||
${SOURCE_DIR}/usbx_msrc_81024_host_cdc_ecm_rx_length_less_than_14.c
|
||||
${SOURCE_DIR}/usbx_msrc_80991_device_rndis_rx_length_less_than_14_test.c
|
||||
${SOURCE_DIR}/usbx_msrc_81251_host_hid_report_add_fail_mem_test.c
|
||||
${SOURCE_DIR}/usbx_msrc_81206_81225_ecm_multiple_data_reject_test.c
|
||||
${SOURCE_DIR}/usbx_msrc_81230_host_asix_inst_free_tests.c
|
||||
${SOURCE_DIR}/usbx_msrc_81231_host_prolific_inst_free_tests.c
|
||||
${SOURCE_DIR}/usbx_msrc_81232_host_gser_inst_free_tests.c
|
||||
${SOURCE_DIR}/usbx_msrc_81233_host_swar_inst_free_tests.c
|
||||
${SOURCE_DIR}/usbx_msrc_81112_host_cdc_ecm_endpoints_get_tests.c
|
||||
${SOURCE_DIR}/usbx_msrc_81142_host_storage_endpoints_get_tests.c
|
||||
${SOURCE_DIR}/usbx_msrc_81143_host_cdc_acm_endpoints_get_tests.c
|
||||
${SOURCE_DIR}/usbx_msrc_81108_pictbridge_object_parse_test.c
|
||||
${SOURCE_DIR}/usbx_msrc_81325_host_hid_remote_control_free_callback_test.c
|
||||
${SOURCE_DIR}/usbx_msrc_81326_host_hid_keyboard_free_callback_test.c
|
||||
${SOURCE_DIR}/usbx_msrc_81327_host_hid_mouse_free_callback_test.c
|
||||
${SOURCE_DIR}/usbx_msrc_81109_pictbridge_array_element_to_hexa_test.c
|
||||
${SOURCE_DIR}/usbx_msrc_81292_host_pima_deactivate_semaphore_test.c
|
||||
${SOURCE_DIR}/usbx_msrc_81323_host_pima_deactivate_no_int_ep_test.c
|
||||
${SOURCE_DIR}/usbx_msrc_81184_host_audio_desc_validate_test.c
|
||||
${SOURCE_DIR}/usbx_msrc_81426_host_audio_type_get_fail_ac_link_test.c
|
||||
${SOURCE_DIR}/usbx_msrc_81428_81429_host_audio_ac_search_test.c
|
||||
)
|
||||
set(ux_msrc_test_cases_standalone
|
||||
${SOURCE_DIR}/usbx_msrc_81489_81570_host_cdc_acm_standalone_ac_search_test.c
|
||||
${SOURCE_DIR}/usbx_msrc_81572_standalone_host_printer_allocated_enum_free_test.c
|
||||
${SOURCE_DIR}/usbx_msrc_81573_standalone_host_hub_allocated_enum_free_test.c
|
||||
${SOURCE_DIR}/usbx_msrc_81574_standalone_host_hid_allocated_enum_free_test.c
|
||||
${SOURCE_DIR}/usbx_msrc_81575_standalone_host_cdc_acm_allocated_enum_free_test.c
|
||||
${SOURCE_DIR}/usbx_msrc_81691_standalone_host_stack_enum_double_free_test.c
|
||||
)
|
||||
|
||||
set(ux_class_ccid_test_cases
|
||||
${SOURCE_DIR}/usbx_device_class_ccid_basic_tests.c
|
||||
${SOURCE_DIR}/usbx_device_class_ccid_busy_abort_tests.c
|
||||
${SOURCE_DIR}/usbx_uxe_device_ccid_test.c
|
||||
)
|
||||
|
||||
set(ux_basic_test_cases
|
||||
${SOURCE_DIR}/usbx_class_device_enumeration_test.c
|
||||
${SOURCE_DIR}/usbx_class_interface_enumeration_test.c
|
||||
${SOURCE_DIR}/usbx_class_multi_interface_enumeration_test.c
|
||||
${SOURCE_DIR}/usbx_ux_host_stack_device_string_get_test.c
|
||||
)
|
||||
|
||||
set(ux_class_pima_test_cases
|
||||
${SOURCE_DIR}/usbx_pima_basic_test.c
|
||||
${SOURCE_DIR}/usbx_pictbridge_basic_test.c
|
||||
${SOURCE_DIR}/usbx_uxe_device_pima_test.c
|
||||
${SOURCE_DIR}/usbx_uxe_host_pima_test.c
|
||||
)
|
||||
|
||||
|
||||
if("-DNX_BSD_ENABLE" IN_LIST ${CMAKE_BUILD_TYPE})
|
||||
|
||||
endif()
|
||||
|
||||
set(test_utility_files
|
||||
${SOURCE_DIR}/usbxtestcontrol.c
|
||||
${SOURCE_DIR}/ux_test.c
|
||||
${SOURCE_DIR}/ux_host_class_dummy.c
|
||||
${SOURCE_DIR}/ux_host_class_dummy.h
|
||||
${SOURCE_DIR}/ux_device_class_dummy.c
|
||||
${SOURCE_DIR}/ux_device_class_dummy.h
|
||||
${SOURCE_DIR}/ux_device_class_dummy_hub.c
|
||||
${SOURCE_DIR}/ux_device_class_dummy_hub.h
|
||||
# ${SOURCE_DIR}/ux_device_class_dummy_printer.c
|
||||
# ${SOURCE_DIR}/ux_device_class_dummy_printer.h
|
||||
${SOURCE_DIR}/ux_test_utility_sim_no_overriding.c
|
||||
${SOURCE_DIR}/ux_test_race_condition_overrides.c
|
||||
${SOURCE_DIR}/ux_test_dcd_sim_slave.c
|
||||
${SOURCE_DIR}/ux_test_hcd_sim_host.c
|
||||
${SOURCE_DIR}/ux_test_utility_sim.c
|
||||
${SOURCE_DIR}/ux_test_standalone_references.c
|
||||
${SOURCE_DIR}/usbx_ux_host_class_storage_fx_driver.c)
|
||||
add_library(test_utility ${test_utility_files})
|
||||
target_link_libraries(test_utility PUBLIC azrtos::usbx azrtos::threadx azrtos::netxduo azrtos::filex)
|
||||
target_compile_definitions(test_utility PUBLIC CTEST FX_ENABLE_EXFAT)
|
||||
|
||||
if (CMAKE_BUILD_TYPE MATCHES "msrc_rtos_build")
|
||||
set(test_cases
|
||||
${ux_msrc_test_cases}
|
||||
${ux_msrc_test_cases_rtos}
|
||||
)
|
||||
elseif (CMAKE_BUILD_TYPE MATCHES "msrc_standalone_build")
|
||||
set(test_cases
|
||||
${ux_msrc_test_cases}
|
||||
${ux_msrc_test_cases_standalone}
|
||||
)
|
||||
elseif(NOT (CMAKE_BUILD_TYPE MATCHES "standalone.*"))
|
||||
if (CMAKE_BUILD_TYPE MATCHES "nofx_.*")
|
||||
set(test_cases
|
||||
${ux_class_storage_test_cases}
|
||||
)
|
||||
elseif (CMAKE_BUILD_TYPE MATCHES "memory_management_.*")
|
||||
set(test_cases
|
||||
${ux_class_memory_management_test_cases}
|
||||
)
|
||||
else()
|
||||
set(test_cases
|
||||
${ux_basic_test_cases}
|
||||
${ux_utility_test_cases}
|
||||
${ux_utility_os_test_cases}
|
||||
${ux_stack_test_cases}
|
||||
${ux_dpump_test_cases}
|
||||
${ux_class_hub_test_cases}
|
||||
${ux_device_class_storage_tx_test_cases}
|
||||
${ux_class_dfu_test_cases}
|
||||
${ux_class_print_test_cases}
|
||||
${ux_class_ccid_test_cases}
|
||||
)
|
||||
if(NOT (CMAKE_BUILD_TYPE MATCHES "optimized.*"))
|
||||
list(APPEND test_cases
|
||||
${ux_stack_test_cases_hid}
|
||||
${ux_stack_test_cases_cdc}
|
||||
${ux_stack_cdc_acm_test_cases}
|
||||
${ux_class_cdc_acm_test_cases}
|
||||
${ux_class_audio_test_cases}
|
||||
${ux_class_rndis_test_cases}
|
||||
${ux_class_cdc_ecm_test_cases}
|
||||
${ux_class_hid_test_cases}
|
||||
${ux_class_video_test_cases}
|
||||
${ux_class_storage_test_cases}
|
||||
${ux_class_pima_test_cases}
|
||||
${ux_class_gser_test_cases}
|
||||
${ux_class_prolific_test_cases}
|
||||
${ux_class_swar_test_cases}
|
||||
${ux_msrc_test_cases}
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
set(test_cases
|
||||
${ux_basic_test_cases}
|
||||
${ux_utility_test_cases}
|
||||
${ux_dpump_test_cases}
|
||||
)
|
||||
if (CMAKE_BUILD_TYPE MATCHES "standalone_device.*")
|
||||
list(APPEND test_cases
|
||||
${ux_utility_os_test_cases}
|
||||
${ux_class_storage_device_standalone_test_cases}
|
||||
${ux_class_cdc_acm_device_standalone_test_cases}
|
||||
${ux_class_video_device_standalone_test_cases}
|
||||
${ux_class_hid_device_standalone_test_cases}
|
||||
${ux_class_dfu_test_cases}
|
||||
${ux_msrc_test_cases}
|
||||
${ux_class_printer_device_standalone_test_cases}
|
||||
${ux_class_audio_device_standalone_test_cases}
|
||||
${ux_class_ccid_test_cases}
|
||||
)
|
||||
elseif (CMAKE_BUILD_TYPE MATCHES "standalone_host.*")
|
||||
list(APPEND test_cases
|
||||
${ux_utility_os_test_cases}
|
||||
${ux_class_storage_host_standalone_test_cases}
|
||||
${ux_class_cdc_acm_host_standalone_test_cases}
|
||||
${ux_class_hid_host_standalone_test_cases}
|
||||
${ux_class_print_test_cases}
|
||||
${ux_class_hub_standalone_test_cases}
|
||||
)
|
||||
else ()
|
||||
list(APPEND test_cases
|
||||
${ux_class_dfu_test_cases}
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
foreach(test_case ${test_cases})
|
||||
get_filename_component(test_name ${test_case} NAME_WE)
|
||||
add_executable(${test_name} ${test_case})
|
||||
target_link_libraries(${test_name} PRIVATE test_utility)
|
||||
add_test(${CMAKE_BUILD_TYPE}::${test_name} ${test_name})
|
||||
endforeach()
|
17
test/cmake/usbx/run.sh
Executable file
17
test/cmake/usbx/run.sh
Executable file
@ -0,0 +1,17 @@
|
||||
#!/bin/bash
|
||||
|
||||
cd $(dirname $0)
|
||||
|
||||
# Checkout externals
|
||||
[ -d externals] || mkdir ../../externals
|
||||
git clone https://github.com/azure-rtos/threadx.git ../../externals/threadx
|
||||
git clone https://github.com/azure-rtos/netxduo.git ../../externals/netxduo
|
||||
git clone https://github.com/azure-rtos/filex.git ../../externals/filex
|
||||
|
||||
# Add junit output for ctest generation
|
||||
if ! grep -q "\-\-output\-junit \$1.xml" ../../externals/threadx/scripts/cmake_bootstrap.sh; then
|
||||
sed -i 's/ctest $parallel --timeout 1000 -O $1.txt/& --output-junit $1.xml/g' ../../externals/threadx/scripts/cmake_bootstrap.sh
|
||||
fi
|
||||
|
||||
[ -f .run.sh ] || ln -sf ../../externals/threadx/scripts/cmake_bootstrap.sh .run.sh
|
||||
./.run.sh $*
|
15
test/cmake/usbx/samples/CMakeLists.txt
Normal file
15
test/cmake/usbx/samples/CMakeLists.txt
Normal file
@ -0,0 +1,15 @@
|
||||
cmake_minimum_required(VERSION 3.0.0 FATAL_ERROR)
|
||||
cmake_policy(SET CMP0057 NEW)
|
||||
|
||||
project(samples LANGUAGES C)
|
||||
|
||||
set(SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/../../../../samples)
|
||||
|
||||
set(sample_files
|
||||
${SOURCE_DIR}/demo_usbx.c)
|
||||
|
||||
foreach(sample_file ${sample_files})
|
||||
get_filename_component(sample_file_name ${sample_file} NAME_WE)
|
||||
add_executable(${sample_file_name} ${sample_file} fake.c)
|
||||
target_link_libraries(${sample_file_name} PRIVATE azrtos::usbx)
|
||||
endforeach()
|
11
test/cmake/usbx/samples/fake.c
Normal file
11
test/cmake/usbx/samples/fake.c
Normal file
@ -0,0 +1,11 @@
|
||||
#include "ux_api.h"
|
||||
|
||||
UCHAR inpb(ULONG addr){return(0);}
|
||||
USHORT inpw(ULONG addr){return(0);}
|
||||
ULONG inpl(ULONG addr){return(0);}
|
||||
|
||||
UCHAR outpb(ULONG addr, UCHAR b){return(b);}
|
||||
USHORT outpw(ULONG addr, USHORT w){return(w);}
|
||||
ULONG outpl(ULONG addr, ULONG l){return(l);}
|
||||
|
||||
void ux_test_assert_hit(char* file, INT line){};
|
345
test/cmake/usbx/ux_user.h
Normal file
345
test/cmake/usbx/ux_user.h
Normal file
@ -0,0 +1,345 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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.x */
|
||||
/* */
|
||||
/* 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 */
|
||||
/* 09-30-2020 Chaoqiong Xiao Modified comment(s), */
|
||||
/* resulting in version 6.1 */
|
||||
/* xx-xx-xxxx Chaoqiong Xiao Modified comment(s), */
|
||||
/* added standalone supoort, */
|
||||
/* resulting in version 6.x */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
#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
|
||||
*/
|
||||
#ifdef TX_TIMER_TICKS_PER_SECOND
|
||||
#define UX_PERIODIC_RATE (TX_TIMER_TICKS_PER_SECOND)
|
||||
#else
|
||||
#define UX_PERIODIC_RATE (100ul)
|
||||
#endif
|
||||
|
||||
/* 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. */
|
||||
|
||||
#ifndef UX_MAX_HOST_LUN
|
||||
#define UX_MAX_HOST_LUN 2 /* for test. */
|
||||
#endif
|
||||
|
||||
|
||||
/* 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. */
|
||||
|
||||
#ifndef UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH
|
||||
#define UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH 248 /* for test. */
|
||||
#endif
|
||||
|
||||
|
||||
/* 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. */
|
||||
|
||||
#ifndef UX_MAX_ED
|
||||
#define UX_MAX_ED 80 /* for test */
|
||||
#endif
|
||||
#ifndef UX_MAX_TD
|
||||
#define UX_MAX_TD 128 /* for test */
|
||||
#endif
|
||||
#ifndef UX_MAX_ISO_TD
|
||||
#define UX_MAX_ISO_TD 8 /* for test */
|
||||
#endif
|
||||
|
||||
/* 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. */
|
||||
|
||||
#ifndef UX_HOST_CLASS_STORAGE_MAX_MEDIA
|
||||
#define UX_HOST_CLASS_STORAGE_MAX_MEDIA 2 /* for test. */
|
||||
#endif
|
||||
|
||||
/* 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)
|
||||
|
||||
|
||||
/* Defined, this disables the assert checks inside usbx. */
|
||||
#ifndef UX_DISABLE_ASSERT
|
||||
#define UX_ENABLE_ASSERT
|
||||
#endif
|
||||
|
||||
/* Defined, this defines the assert action taken when failure detected. By default
|
||||
it halts without any output. */
|
||||
void ux_test_assert_hit(char* file, int line);
|
||||
#define UX_ASSERT_FAIL ux_test_assert_hit(__FILE__, __LINE__);
|
||||
|
||||
|
||||
/* 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
|
||||
|
1252
test/regression/usbx_audio10_device_basic_test.c
Normal file
1252
test/regression/usbx_audio10_device_basic_test.c
Normal file
File diff suppressed because it is too large
Load Diff
1344
test/regression/usbx_audio10_device_feedback_test.c
Normal file
1344
test/regression/usbx_audio10_device_feedback_test.c
Normal file
File diff suppressed because it is too large
Load Diff
1222
test/regression/usbx_audio10_iad_device_basic_test.c
Normal file
1222
test/regression/usbx_audio10_iad_device_basic_test.c
Normal file
File diff suppressed because it is too large
Load Diff
1106
test/regression/usbx_audio10_iad_device_control_test.c
Normal file
1106
test/regression/usbx_audio10_iad_device_control_test.c
Normal file
File diff suppressed because it is too large
Load Diff
1103
test/regression/usbx_audio10_iad_device_interrupt_test.c
Normal file
1103
test/regression/usbx_audio10_iad_device_interrupt_test.c
Normal file
File diff suppressed because it is too large
Load Diff
1404
test/regression/usbx_audio10_iad_host_basic_test.c
Normal file
1404
test/regression/usbx_audio10_iad_host_basic_test.c
Normal file
File diff suppressed because it is too large
Load Diff
1397
test/regression/usbx_audio20_device_basic_test.c
Normal file
1397
test/regression/usbx_audio20_device_basic_test.c
Normal file
File diff suppressed because it is too large
Load Diff
1265
test/regression/usbx_audio20_device_controls_test.c
Normal file
1265
test/regression/usbx_audio20_device_controls_test.c
Normal file
File diff suppressed because it is too large
Load Diff
1517
test/regression/usbx_audio20_device_feedback_test.c
Normal file
1517
test/regression/usbx_audio20_device_feedback_test.c
Normal file
File diff suppressed because it is too large
Load Diff
1631
test/regression/usbx_audio20_host_basic_test.c
Normal file
1631
test/regression/usbx_audio20_host_basic_test.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,110 @@
|
||||
/* This tests the case where a bus-powered hub is connected to a self-powered hub. */
|
||||
|
||||
#include "usbx_ux_test_hub.h"
|
||||
|
||||
static unsigned char device_framework_bus_powered[] = {
|
||||
|
||||
/* Device Descriptor */
|
||||
0x12, /* bLength */
|
||||
0x01, /* bDescriptorType */
|
||||
0x00, 0x02, /* bcdUSB */
|
||||
0x09, /* bDeviceClass - Hub */
|
||||
0x00, /* bDeviceSubClass */
|
||||
0x01, /* bDeviceProtocol */
|
||||
0x40, /* bMaxPacketSize0 */
|
||||
0x24, 0x04, /* idVendor */
|
||||
0x12, 0x24, /* idProduct */
|
||||
0xb2, 0x0b, /* bcdDevice */
|
||||
0x00, /* iManufacturer */
|
||||
0x00, /* iProduct */
|
||||
0x00, /* iSerialNumber */
|
||||
0x01, /* bNumConfigurations */
|
||||
|
||||
/* Configuration Descriptor */
|
||||
0x09, /* bLength */
|
||||
0x02, /* bDescriptorType */
|
||||
0x19, 0x00, /* wTotalLength */
|
||||
0x01, /* bNumInterfaces */
|
||||
0x01, /* bConfigurationValue */
|
||||
0x00, /* iConfiguration */
|
||||
0xa0, /* bmAttributes - Bus-powered */
|
||||
0x01, /* bMaxPower */
|
||||
|
||||
/* Interface Descriptor */
|
||||
0x09, /* bLength */
|
||||
0x04, /* bDescriptorType */
|
||||
0x00, /* bInterfaceNumber */
|
||||
0x00, /* bAlternateSetting */
|
||||
0x01, /* bNumEndpoints */
|
||||
0x09, /* bInterfaceClass - Hub */
|
||||
0x00, /* bInterfaceSubClass */
|
||||
0x00, /* bInterfaceProtocol */
|
||||
0x00, /* iInterface */
|
||||
|
||||
/* Endpoint Descriptor */
|
||||
0x07, /* bLength */
|
||||
0x05, /* bDescriptorType */
|
||||
0x81, /* bEndpointAddress */
|
||||
0x03, /* bmAttributes - Interrupt */
|
||||
0x02, 0x00, /* wMaxPacketSize */
|
||||
0x0c, /* bInterval */
|
||||
|
||||
};
|
||||
|
||||
static DEVICE_INIT_DATA device_init_data = {
|
||||
.framework = device_framework_bus_powered,
|
||||
.framework_length = sizeof(device_framework_bus_powered),
|
||||
};
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_bus_powered_hub_connected_to_self_and_bus_powered_hub_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
/* Inform user. */
|
||||
#if UX_MAX_DEVICES > 1
|
||||
printf("Running Hub Bus Powered Hub Connected....Test....................... ");
|
||||
#else
|
||||
printf("Running Hub Bus Powered Hub Connected....Skip max 1 device.......... SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
return;
|
||||
#endif
|
||||
|
||||
stepinfo("\n");
|
||||
|
||||
initialize_hub_with_device_init_data(first_unused_memory, &device_init_data);
|
||||
}
|
||||
|
||||
static void post_init_host()
|
||||
{
|
||||
#if UX_MAX_DEVICES > 1
|
||||
UX_DEVICE parent;
|
||||
|
||||
stepinfo("test this hub connected to a self-powered hub\n");
|
||||
|
||||
parent.ux_device_power_source = UX_DEVICE_SELF_POWERED;
|
||||
|
||||
g_hub_host->ux_host_class_hub_device->ux_device_parent = &parent;
|
||||
UX_TEST_CHECK_SUCCESS(_ux_host_class_hub_configure(g_hub_host));
|
||||
|
||||
/* Should've been null originally. */
|
||||
g_hub_host->ux_host_class_hub_device->ux_device_parent = UX_NULL;
|
||||
|
||||
stepinfo("test this hub connected to a bus-powered hub\n");
|
||||
|
||||
parent.ux_device_power_source = UX_DEVICE_BUS_POWERED;
|
||||
|
||||
g_hub_host->ux_host_class_hub_device->ux_device_parent = &parent;
|
||||
ux_test_add_action_to_main_list(create_error_match_action(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_HUB, UX_CONNECTION_INCOMPATIBLE));
|
||||
UX_TEST_CHECK_NOT_SUCCESS(_ux_host_class_hub_configure(g_hub_host));
|
||||
|
||||
/* Should've been null originally. */
|
||||
g_hub_host->ux_host_class_hub_device->ux_device_parent = UX_NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void post_init_device()
|
||||
{
|
||||
}
|
854
test/regression/usbx_cdc_acm_basic_memory_test.c
Normal file
854
test/regression/usbx_cdc_acm_basic_memory_test.c
Normal file
@ -0,0 +1,854 @@
|
||||
/* This test is designed to test the simple dpump host/device class operation. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
#include "ux_api.h"
|
||||
#include "ux_system.h"
|
||||
#include "ux_utility.h"
|
||||
|
||||
#include "fx_api.h"
|
||||
|
||||
#include "ux_device_class_cdc_acm.h"
|
||||
#include "ux_device_stack.h"
|
||||
#include "ux_host_class_cdc_acm.h"
|
||||
|
||||
#include "ux_test_dcd_sim_slave.h"
|
||||
#include "ux_test_hcd_sim_host.h"
|
||||
#include "ux_test_utility_sim.h"
|
||||
|
||||
/* Define constants. */
|
||||
#define UX_DEMO_DEBUG_SIZE (4096*8)
|
||||
#define UX_DEMO_STACK_SIZE 1024
|
||||
#define UX_DEMO_BUFFER_SIZE (UX_SLAVE_REQUEST_DATA_MAX_LENGTH + 1)
|
||||
#define UX_DEMO_XMIT_BUFFER_SIZE 512
|
||||
#define UX_DEMO_RECEPTION_BUFFER_SIZE 512
|
||||
#define UX_DEMO_FILE_BUFFER_SIZE 512
|
||||
#define UX_DEMO_RECEPTION_BLOCK_SIZE 64
|
||||
#define UX_DEMO_MEMORY_SIZE (64*1024)
|
||||
#define UX_DEMO_FILE_SIZE (128 * 1024)
|
||||
#define UX_RAM_DISK_MEMORY (256 * 1024)
|
||||
|
||||
/* Define local/extern function prototypes. */
|
||||
static TX_THREAD ux_test_thread_host_simulation;
|
||||
static TX_THREAD ux_test_thread_slave_simulation;
|
||||
static void ux_test_thread_host_simulation_entry(ULONG);
|
||||
static void ux_test_thread_slave_simulation_entry(ULONG);
|
||||
|
||||
static VOID test_cdc_instance_activate(VOID *cdc_instance);
|
||||
static VOID test_cdc_instance_deactivate(VOID *cdc_instance);
|
||||
static VOID test_cdc_instance_parameter_change(VOID *cdc_instance);
|
||||
|
||||
static VOID ux_test_hcd_entry_set_cfg(UX_TEST_ACTION *action, VOID *params);
|
||||
|
||||
/* Define global data structures. */
|
||||
static UCHAR usbx_memory[UX_DEMO_MEMORY_SIZE + (UX_DEMO_STACK_SIZE * 2)];
|
||||
static UX_HOST_CLASS *class_driver;
|
||||
static UX_HOST_CLASS_CDC_ACM *cdc_acm_host_control;
|
||||
static UX_HOST_CLASS_CDC_ACM *cdc_acm_host_data;
|
||||
|
||||
static UX_SLAVE_CLASS_CDC_ACM *cdc_acm_slave;
|
||||
static UCHAR cdc_acm_slave_change;
|
||||
static UX_SLAVE_CLASS_CDC_ACM_PARAMETER parameter;
|
||||
|
||||
static ULONG set_cfg_counter;
|
||||
|
||||
static ULONG rsc_mem_alloc_cnt_on_set_cfg;
|
||||
static ULONG rsc_sem_on_set_cfg;
|
||||
static ULONG rsc_sem_get_on_set_cfg;
|
||||
static ULONG rsc_mutex_on_set_cfg;
|
||||
|
||||
static ULONG rsc_enum_sem_usage;
|
||||
static ULONG rsc_enum_sem_get_count;
|
||||
static ULONG rsc_enum_mutex_usage;
|
||||
static ULONG rsc_enum_mem_alloc_count;
|
||||
|
||||
static ULONG rsc_cdc_sem_usage;
|
||||
static ULONG rsc_cdc_sem_get_count;
|
||||
static ULONG rsc_cdc_mutex_usage;
|
||||
static ULONG rsc_cdc_mem_alloc_count;
|
||||
|
||||
static ULONG interaction_count;
|
||||
|
||||
static UCHAR error_callback_ignore = UX_TRUE;
|
||||
static ULONG error_callback_counter;
|
||||
|
||||
/* Define device framework. */
|
||||
|
||||
#define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED 93
|
||||
#define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED 103
|
||||
#define STRING_FRAMEWORK_LENGTH 47
|
||||
#define LANGUAGE_ID_FRAMEWORK_LENGTH 2
|
||||
|
||||
static unsigned char device_framework_full_speed[] = {
|
||||
|
||||
/* Device descriptor 18 bytes
|
||||
0x02 bDeviceClass: CDC class code
|
||||
0x00 bDeviceSubclass: CDC class sub code
|
||||
0x00 bDeviceProtocol: CDC Device protocol
|
||||
|
||||
idVendor & idProduct - http://www.linux-usb.org/usb.ids
|
||||
*/
|
||||
0x12, 0x01, 0x10, 0x01,
|
||||
0xEF, 0x02, 0x01,
|
||||
0x08,
|
||||
0x84, 0x84, 0x00, 0x00,
|
||||
0x00, 0x01,
|
||||
0x01, 0x02, 03,
|
||||
0x01,
|
||||
|
||||
/* Configuration 1 descriptor 9 bytes */
|
||||
0x09, 0x02, 0x4b, 0x00,
|
||||
0x02, 0x01, 0x00,
|
||||
0x40, 0x00,
|
||||
|
||||
/* Interface association descriptor. 8 bytes. */
|
||||
0x08, 0x0b, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,
|
||||
|
||||
/* Communication Class Interface Descriptor Requirement. 9 bytes. */
|
||||
0x09, 0x04, 0x00,
|
||||
0x00,
|
||||
0x01,
|
||||
0x02, 0x02, 0x01,
|
||||
0x00,
|
||||
|
||||
/* Header Functional Descriptor 5 bytes */
|
||||
0x05, 0x24, 0x00,
|
||||
0x10, 0x01,
|
||||
|
||||
/* ACM Functional Descriptor 4 bytes */
|
||||
0x04, 0x24, 0x02,
|
||||
0x0f,
|
||||
|
||||
/* Union Functional Descriptor 5 bytes */
|
||||
0x05, 0x24, 0x06,
|
||||
0x00, /* Master interface */
|
||||
0x01, /* Slave interface */
|
||||
|
||||
/* Call Management Functional Descriptor 5 bytes */
|
||||
0x05, 0x24, 0x01,
|
||||
0x03,
|
||||
0x01, /* Data interface */
|
||||
|
||||
/* Endpoint 0x83 descriptor 7 bytes */
|
||||
0x07, 0x05, 0x83,
|
||||
0x03,
|
||||
0x08, 0x00,
|
||||
0xFF,
|
||||
|
||||
/* Data Class Interface Descriptor Requirement 9 bytes */
|
||||
0x09, 0x04, 0x01,
|
||||
0x00,
|
||||
0x02,
|
||||
0x0A, 0x00, 0x00,
|
||||
0x00,
|
||||
|
||||
/* Endpoint 0x02 descriptor 7 bytes */
|
||||
0x07, 0x05, 0x02, /* @ 93 - 14 + 2 = 81 */
|
||||
0x02,
|
||||
0x40, 0x00,
|
||||
0x00,
|
||||
|
||||
/* Endpoint 0x81 descriptor 7 bytes */
|
||||
0x07, 0x05, 0x81, /* @ 93 - 7 + 2 = 88 */
|
||||
0x02,
|
||||
0x40, 0x00,
|
||||
0x00,
|
||||
|
||||
};
|
||||
|
||||
#define DEVICE_FRAMEWORK_EPA_POS_1_FS (DEVICE_FRAMEWORK_LENGTH_FULL_SPEED - 14 + 2)
|
||||
#define DEVICE_FRAMEWORK_EPA_POS_2_FS (DEVICE_FRAMEWORK_LENGTH_FULL_SPEED - 7 + 2)
|
||||
|
||||
static unsigned char device_framework_high_speed[] = {
|
||||
|
||||
/* Device descriptor
|
||||
0x02 bDeviceClass: CDC class code
|
||||
0x00 bDeviceSubclass: CDC class sub code
|
||||
0x00 bDeviceProtocol: CDC Device protocol
|
||||
|
||||
idVendor & idProduct - http://www.linux-usb.org/usb.ids
|
||||
*/
|
||||
0x12, 0x01, 0x00, 0x02,
|
||||
0xEF, 0x02, 0x01,
|
||||
0x40,
|
||||
0x84, 0x84, 0x00, 0x00,
|
||||
0x00, 0x01,
|
||||
0x01, 0x02, 03,
|
||||
0x01,
|
||||
|
||||
/* Device qualifier descriptor */
|
||||
0x0a, 0x06, 0x00, 0x02,
|
||||
0x02, 0x00, 0x00,
|
||||
0x40,
|
||||
0x01,
|
||||
0x00,
|
||||
|
||||
/* Configuration 1 descriptor */
|
||||
0x09, 0x02, 0x4b, 0x00,
|
||||
0x02, 0x01, 0x00,
|
||||
0x40, 0x00,
|
||||
|
||||
/* Interface association descriptor. */
|
||||
0x08, 0x0b, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,
|
||||
|
||||
/* Communication Class Interface Descriptor Requirement */
|
||||
0x09, 0x04, 0x00,
|
||||
0x00,
|
||||
0x01,
|
||||
0x02, 0x02, 0x01,
|
||||
0x00,
|
||||
|
||||
/* Header Functional Descriptor */
|
||||
0x05, 0x24, 0x00,
|
||||
0x10, 0x01,
|
||||
|
||||
/* ACM Functional Descriptor */
|
||||
0x04, 0x24, 0x02,
|
||||
0x0f,
|
||||
|
||||
/* Union Functional Descriptor */
|
||||
0x05, 0x24, 0x06,
|
||||
0x00,
|
||||
0x01,
|
||||
|
||||
/* Call Management Functional Descriptor */
|
||||
0x05, 0x24, 0x01,
|
||||
0x00,
|
||||
0x01,
|
||||
|
||||
/* Endpoint 0x83 descriptor */
|
||||
0x07, 0x05, 0x83,
|
||||
0x03,
|
||||
0x08, 0x00,
|
||||
0xFF,
|
||||
|
||||
/* Data Class Interface Descriptor Requirement */
|
||||
0x09, 0x04, 0x01,
|
||||
0x00,
|
||||
0x02,
|
||||
0x0A, 0x00, 0x00,
|
||||
0x00,
|
||||
|
||||
/* Endpoint 0x02 descriptor */
|
||||
0x07, 0x05, 0x02, /* @ 103 - 14 + 2 = 91 */
|
||||
0x02,
|
||||
0x40, 0x00,
|
||||
0x00,
|
||||
|
||||
/* Endpoint 0x81 descriptor */
|
||||
0x07, 0x05, 0x81, /* @ 103 - 7 + 2 = 98 */
|
||||
0x02,
|
||||
0x40, 0x00,
|
||||
0x00,
|
||||
|
||||
};
|
||||
|
||||
#define DEVICE_FRAMEWORK_EPA_POS_1_HS (DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED - 14 + 2)
|
||||
#define DEVICE_FRAMEWORK_EPA_POS_2_HS (DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED - 7 + 2)
|
||||
|
||||
static unsigned char string_framework[] = {
|
||||
|
||||
/* Manufacturer string descriptor : Index 1 - "Express Logic" */
|
||||
0x09, 0x04, 0x01, 0x0c,
|
||||
0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
|
||||
0x6f, 0x67, 0x69, 0x63,
|
||||
|
||||
/* Product string descriptor : Index 2 - "EL Composite device" */
|
||||
0x09, 0x04, 0x02, 0x13,
|
||||
0x45, 0x4c, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x6f,
|
||||
0x73, 0x69, 0x74, 0x65, 0x20, 0x64, 0x65, 0x76,
|
||||
0x69, 0x63, 0x65,
|
||||
|
||||
/* Serial Number string descriptor : Index 3 - "0001" */
|
||||
0x09, 0x04, 0x03, 0x04,
|
||||
0x30, 0x30, 0x30, 0x31
|
||||
};
|
||||
|
||||
|
||||
/* Multiple languages are supported on the device, to add
|
||||
a language besides english, the unicode language code must
|
||||
be appended to the language_id_framework array and the length
|
||||
adjusted accordingly. */
|
||||
static unsigned char language_id_framework[] = {
|
||||
|
||||
/* English. */
|
||||
0x09, 0x04
|
||||
};
|
||||
|
||||
/* Setup requests */
|
||||
|
||||
static UX_TEST_SETUP _SetConfigure = UX_TEST_SETUP_SetConfigure;
|
||||
|
||||
static UX_TEST_HCD_SIM_ACTION log_on_SetCfg[] = {
|
||||
/* function, request to match,
|
||||
port action, port status,
|
||||
request action, request EP, request data, request actual length, request status,
|
||||
status, additional callback,
|
||||
no_return */
|
||||
{ UX_HCD_TRANSFER_REQUEST, &_SetConfigure,
|
||||
UX_FALSE, UX_TEST_PORT_STATUS_DISC,
|
||||
UX_TEST_SETUP_MATCH_REQ, 0, UX_NULL, 0, 0,
|
||||
UX_SUCCESS, ux_test_hcd_entry_set_cfg,
|
||||
UX_TRUE}, /* Invoke callback & continue */
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
/* Define the ISR dispatch. */
|
||||
|
||||
extern VOID (*test_isr_dispatch)(void);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
/* Define the ISR dispatch routine. */
|
||||
|
||||
static void test_isr(void)
|
||||
{
|
||||
|
||||
/* For further expansion of interrupt-level testing. */
|
||||
}
|
||||
|
||||
static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
|
||||
{
|
||||
|
||||
error_callback_counter ++;
|
||||
|
||||
if (!error_callback_ignore)
|
||||
{
|
||||
{
|
||||
/* Failed test. */
|
||||
printf("Error #%d, system_level: %d, system_context: %d, error_code: 0x%x\n", __LINE__, system_level, system_context, error_code);
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static UINT sleep_break_on_error(VOID)
|
||||
{
|
||||
|
||||
if (error_callback_counter >= 3)
|
||||
return error_callback_counter;
|
||||
|
||||
return UX_SUCCESS;
|
||||
}
|
||||
|
||||
static UINT demo_class_cdc_acm_get(void)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
UX_HOST_CLASS *class;
|
||||
UX_HOST_CLASS_CDC_ACM *cdc_acm_host;
|
||||
|
||||
|
||||
/* Find the main cdc_acm container */
|
||||
status = ux_host_stack_class_get(_ux_system_host_class_cdc_acm_name, &class);
|
||||
if (status != UX_SUCCESS)
|
||||
return(status);
|
||||
|
||||
/* We get the first instance of the cdc_acm device */
|
||||
do
|
||||
{
|
||||
|
||||
status = ux_host_stack_class_instance_get(class, 0, (void **) &cdc_acm_host);
|
||||
tx_thread_sleep(10);
|
||||
} while (status != UX_SUCCESS);
|
||||
|
||||
/* We still need to wait for the cdc_acm status to be live */
|
||||
while (cdc_acm_host -> ux_host_class_cdc_acm_state != UX_HOST_CLASS_INSTANCE_LIVE)
|
||||
tx_thread_sleep(10);
|
||||
|
||||
/* Isolate both the control and data interfaces. */
|
||||
if (cdc_acm_host -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_DATA_CLASS)
|
||||
{
|
||||
/* This is the data interface. */
|
||||
cdc_acm_host_data = cdc_acm_host;
|
||||
|
||||
/* In that case, the second one should be the control interface. */
|
||||
status = ux_host_stack_class_instance_get(class, 1, (void **) &cdc_acm_host);
|
||||
|
||||
/* Check error. */
|
||||
if (status != UX_SUCCESS)
|
||||
return(status);
|
||||
|
||||
/* Check for the control interfaces. */
|
||||
if (cdc_acm_host -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS)
|
||||
{
|
||||
|
||||
/* This is the control interface. */
|
||||
cdc_acm_host_control = cdc_acm_host;
|
||||
|
||||
return(UX_SUCCESS);
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check for the control interfaces. */
|
||||
if (cdc_acm_host -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS)
|
||||
{
|
||||
|
||||
/* This is the control interface. */
|
||||
cdc_acm_host_control = cdc_acm_host;
|
||||
|
||||
/* In that case, the second one should be the data interface. */
|
||||
status = ux_host_stack_class_instance_get(class, 1, (void **) &cdc_acm_host);
|
||||
|
||||
/* Check error. */
|
||||
if (status != UX_SUCCESS)
|
||||
return(status);
|
||||
|
||||
/* Check for the data interface. */
|
||||
if (cdc_acm_host -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_DATA_CLASS)
|
||||
{
|
||||
|
||||
/* This is the data interface. */
|
||||
cdc_acm_host_data = cdc_acm_host;
|
||||
|
||||
return(UX_SUCCESS);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Return ERROR. */
|
||||
return(UX_ERROR);
|
||||
}
|
||||
|
||||
static UINT demo_system_host_change_function(ULONG event, UX_HOST_CLASS *cls, VOID *inst)
|
||||
{
|
||||
|
||||
UX_HOST_CLASS_CDC_ACM *cdc_acm = (UX_HOST_CLASS_CDC_ACM *) inst;
|
||||
|
||||
switch(event)
|
||||
{
|
||||
|
||||
case UX_DEVICE_INSERTION:
|
||||
|
||||
if (cdc_acm -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS)
|
||||
cdc_acm_host_control = cdc_acm;
|
||||
else
|
||||
cdc_acm_host_data = cdc_acm;
|
||||
break;
|
||||
|
||||
case UX_DEVICE_REMOVAL:
|
||||
|
||||
if (cdc_acm -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS)
|
||||
cdc_acm_host_control = UX_NULL;
|
||||
else
|
||||
cdc_acm_host_data = UX_NULL;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static VOID test_cdc_instance_activate(VOID *cdc_instance)
|
||||
{
|
||||
|
||||
/* Save the CDC instance. */
|
||||
cdc_acm_slave = (UX_SLAVE_CLASS_CDC_ACM *) cdc_instance;
|
||||
}
|
||||
static VOID test_cdc_instance_deactivate(VOID *cdc_instance)
|
||||
{
|
||||
|
||||
/* Reset the CDC instance. */
|
||||
cdc_acm_slave = UX_NULL;
|
||||
}
|
||||
|
||||
static VOID test_cdc_instance_parameter_change(VOID *cdc_instance)
|
||||
{
|
||||
|
||||
/* Set CDC parameter change flag. */
|
||||
cdc_acm_slave_change = UX_TRUE;
|
||||
}
|
||||
|
||||
static VOID test_swap_framework_bulk_ep_descriptors(VOID)
|
||||
{
|
||||
UCHAR tmp;
|
||||
|
||||
tmp = device_framework_full_speed[DEVICE_FRAMEWORK_EPA_POS_1_FS];
|
||||
device_framework_full_speed[DEVICE_FRAMEWORK_EPA_POS_1_FS] = device_framework_full_speed[DEVICE_FRAMEWORK_EPA_POS_2_FS];
|
||||
device_framework_full_speed[DEVICE_FRAMEWORK_EPA_POS_2_FS] = tmp;
|
||||
|
||||
tmp = device_framework_high_speed[DEVICE_FRAMEWORK_EPA_POS_1_HS];
|
||||
device_framework_high_speed[DEVICE_FRAMEWORK_EPA_POS_1_HS] = device_framework_high_speed[DEVICE_FRAMEWORK_EPA_POS_2_HS];
|
||||
device_framework_high_speed[DEVICE_FRAMEWORK_EPA_POS_2_HS] = tmp;
|
||||
}
|
||||
|
||||
static VOID test_slave_cdc_acm_transfer_disconnect(UX_SLAVE_CLASS_CDC_ACM *cdc_acm, ULONG ep_dir)
|
||||
{
|
||||
|
||||
UX_SLAVE_ENDPOINT *endpoint;
|
||||
UX_SLAVE_DEVICE *device;
|
||||
UX_SLAVE_INTERFACE *interface;
|
||||
UX_SLAVE_TRANSFER *transfer_request;
|
||||
|
||||
/* 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 = cdc_acm -> ux_slave_class_cdc_acm_interface;
|
||||
|
||||
/* Locate the endpoints. */
|
||||
endpoint = interface -> ux_slave_interface_first_endpoint;
|
||||
|
||||
/* Check the endpoint direction, if OUT we have the correct endpoint. */
|
||||
if ((endpoint -> ux_slave_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION) != ep_dir)
|
||||
{
|
||||
|
||||
/* So the next endpoint has to be the OUT endpoint. */
|
||||
endpoint = endpoint -> ux_slave_endpoint_next_endpoint;
|
||||
}
|
||||
|
||||
/* All CDC reading are on the endpoint OUT, from the host. */
|
||||
transfer_request = &endpoint -> ux_slave_endpoint_transfer_request;
|
||||
|
||||
/* Continue transfer. */
|
||||
transfer_request -> ux_slave_transfer_request_actual_length = endpoint -> ux_slave_endpoint_descriptor.wMaxPacketSize;
|
||||
|
||||
/* Change device state. */
|
||||
device -> ux_slave_device_state = UX_DEVICE_ATTACHED;
|
||||
|
||||
/* Inform hcd. */
|
||||
_ux_utility_semaphore_put(&transfer_request -> ux_slave_transfer_request_semaphore);
|
||||
|
||||
/* Wait a while for transfer request handling. */
|
||||
tx_thread_sleep(50);
|
||||
|
||||
/* Change device state. */
|
||||
device -> ux_slave_device_state = UX_DEVICE_CONFIGURED;
|
||||
}
|
||||
|
||||
static VOID ux_test_hcd_entry_set_cfg(UX_TEST_ACTION *action, VOID *_params)
|
||||
{
|
||||
|
||||
set_cfg_counter ++;
|
||||
|
||||
rsc_mem_alloc_cnt_on_set_cfg = ux_test_utility_sim_mem_alloc_count();
|
||||
|
||||
rsc_sem_on_set_cfg = ux_test_utility_sim_sem_create_count();
|
||||
rsc_sem_get_on_set_cfg = ux_test_utility_sim_sem_get_count();
|
||||
rsc_mutex_on_set_cfg = ux_test_utility_sim_mutex_create_count();
|
||||
}
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_cdc_acm_basic_memory_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR * stack_pointer;
|
||||
CHAR * memory_pointer;
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running CDC ACM Basic Memory Test................................... ");
|
||||
|
||||
/* Reset testing counts. */
|
||||
ux_test_utility_sim_mem_alloc_log_enable(UX_TRUE);
|
||||
ux_test_utility_sim_mem_alloc_count_reset();
|
||||
ux_test_utility_sim_mutex_create_count_reset();
|
||||
ux_test_utility_sim_sem_create_count_reset();
|
||||
ux_test_utility_sim_sem_get_count_reset();
|
||||
/* Reset error generations */
|
||||
ux_test_utility_sim_sem_error_generation_stop();
|
||||
ux_test_utility_sim_mutex_error_generation_stop();
|
||||
ux_test_utility_sim_sem_get_error_generation_stop();
|
||||
|
||||
/* Initialize the free memory pointer */
|
||||
stack_pointer = (CHAR *) usbx_memory;
|
||||
memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
|
||||
|
||||
/* Initialize USBX Memory */
|
||||
status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the error callback. */
|
||||
_ux_utility_error_callback_register(error_callback);
|
||||
|
||||
/* The code below is required for installing the host portion of USBX */
|
||||
status = ux_host_stack_initialize(demo_system_host_change_function);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register CDC-ACM class. */
|
||||
status = ux_host_stack_class_register(_ux_system_host_class_cdc_acm_name, ux_host_class_cdc_acm_entry);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* The code below is required for installing the device portion of USBX. No call back for
|
||||
device status change in this example. */
|
||||
status = ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
|
||||
device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
|
||||
string_framework, STRING_FRAMEWORK_LENGTH,
|
||||
language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Set the parameters for callback when insertion/extraction of a CDC device. */
|
||||
parameter.ux_slave_class_cdc_acm_instance_activate = test_cdc_instance_activate;
|
||||
parameter.ux_slave_class_cdc_acm_instance_deactivate = test_cdc_instance_deactivate;
|
||||
parameter.ux_slave_class_cdc_acm_parameter_change = test_cdc_instance_parameter_change;
|
||||
|
||||
/* Initialize the device cdc class. This class owns both interfaces starting with 0. */
|
||||
status = ux_device_stack_class_register(_ux_system_slave_class_cdc_acm_name, ux_device_class_cdc_acm_entry,
|
||||
1,0, ¶meter);
|
||||
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Initialize the simulated device controller. */
|
||||
status = _ux_dcd_sim_slave_initialize();
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register all the USB host controllers available in this system */
|
||||
status = ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize,0,0);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the main host simulation thread. */
|
||||
status = tx_thread_create(&ux_test_thread_host_simulation, "tx demo host simulation", ux_test_thread_host_simulation_entry, 0,
|
||||
stack_pointer, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the main slave simulation thread. */
|
||||
status = tx_thread_create(&ux_test_thread_slave_simulation, "tx demo slave simulation", ux_test_thread_slave_simulation_entry, 0,
|
||||
stack_pointer + UX_DEMO_STACK_SIZE, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #9\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
void ux_test_thread_host_simulation_entry(ULONG arg)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
UX_SLAVE_CLASS_CDC_ACM * cdc_acm_slave_bak;
|
||||
UX_HOST_CLASS_CDC_ACM * cdc_acm_host_ctrl_bak;
|
||||
UX_HOST_CLASS_CDC_ACM * cdc_acm_host_data_bak;
|
||||
ULONG test_n;
|
||||
ULONG mem_free;
|
||||
ULONG retry;
|
||||
|
||||
stepinfo("\n");
|
||||
|
||||
/* Find the cdc_acm class and wait for the link to be up. */
|
||||
status = demo_class_cdc_acm_get();
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
/* CDC ACM basic test error. */
|
||||
printf("ERROR #10\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Save slave instance for later tests. */
|
||||
cdc_acm_slave_bak = cdc_acm_slave;
|
||||
/* Save host instances for later tests. */
|
||||
cdc_acm_host_ctrl_bak = cdc_acm_host_control;
|
||||
cdc_acm_host_data_bak = cdc_acm_host_data;
|
||||
|
||||
/* Test disconnect. */
|
||||
ux_test_dcd_sim_slave_disconnect();
|
||||
ux_test_hcd_sim_host_disconnect();
|
||||
|
||||
/* Reset testing counts. */
|
||||
ux_test_utility_sim_mem_alloc_count_reset();
|
||||
ux_test_utility_sim_mutex_create_count_reset();
|
||||
ux_test_utility_sim_sem_create_count_reset();
|
||||
ux_test_utility_sim_sem_get_count_reset();
|
||||
ux_test_hcd_sim_host_set_actions(log_on_SetCfg);
|
||||
|
||||
/* Save free memory usage. */
|
||||
mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
|
||||
ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
|
||||
ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
|
||||
for (retry = 0; (retry < 10) && (cdc_acm_host_control == UX_NULL || cdc_acm_host_data == UX_NULL); retry ++)
|
||||
tx_thread_sleep(10);
|
||||
|
||||
/* Log create counts for further tests. */
|
||||
rsc_enum_mutex_usage = rsc_mutex_on_set_cfg;
|
||||
rsc_enum_sem_usage = rsc_sem_on_set_cfg;
|
||||
rsc_enum_mem_alloc_count = rsc_mem_alloc_cnt_on_set_cfg;
|
||||
/* Log create counts when instances active for further tests. */
|
||||
rsc_cdc_mutex_usage = ux_test_utility_sim_mutex_create_count() - rsc_enum_mutex_usage;
|
||||
rsc_cdc_sem_usage = ux_test_utility_sim_sem_create_count() - rsc_enum_sem_usage;
|
||||
rsc_cdc_mem_alloc_count = ux_test_utility_sim_mem_alloc_count() - rsc_enum_mem_alloc_count;
|
||||
|
||||
/* Lock log base for tests. */
|
||||
ux_test_utility_sim_mem_alloc_log_lock();
|
||||
|
||||
stepinfo("enum mem: %ld\n", rsc_enum_mem_alloc_count);
|
||||
stepinfo("cdc mem : %ld\n", rsc_cdc_mem_alloc_count);
|
||||
stepinfo("mem free: %ld, %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available, _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_CACHE_SAFE] -> ux_byte_pool_available);
|
||||
|
||||
/* Simulate detach and attach for FS enumeration,
|
||||
and check if there is memory error in normal enumeration.
|
||||
*/
|
||||
stepinfo(">>>>>>>>>>>> Enumeration test\n");
|
||||
mem_free = (~0);
|
||||
for (test_n = 0; test_n < 3; test_n++)
|
||||
{
|
||||
stepinfo("%4ld / 2\n", test_n);
|
||||
|
||||
/* Disconnect. */
|
||||
ux_test_dcd_sim_slave_disconnect();
|
||||
ux_test_hcd_sim_host_disconnect();
|
||||
|
||||
/* Update memory free level (disconnect) */
|
||||
if (mem_free == (~0))
|
||||
mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
|
||||
else if (mem_free != _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available)
|
||||
{
|
||||
|
||||
printf("ERROR #11.%ld: Memory level different after re-enumerations %ld <> %ld\n", test_n, mem_free, _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Connect. */
|
||||
error_callback_counter = 0;
|
||||
ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
|
||||
ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
|
||||
|
||||
/* Wait and break on error. */
|
||||
ux_test_breakable_sleep(100, sleep_break_on_error);
|
||||
|
||||
/* Check */
|
||||
if (!cdc_acm_host_control || !cdc_acm_host_data)
|
||||
{
|
||||
|
||||
printf("ERROR #12.%ld: Enumeration fail\n", test_n);
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Simulate detach and attach for FS enumeration,
|
||||
and test possible memory allocation error handlings.
|
||||
*/
|
||||
if (rsc_cdc_mem_alloc_count) stepinfo(">>>>>>>>>>>> Memory errors enumeration test\n");
|
||||
mem_free = (~0);
|
||||
for (test_n = 0; test_n < rsc_cdc_mem_alloc_count; test_n ++)
|
||||
{
|
||||
|
||||
stepinfo("%4ld / %4ld\n", test_n, rsc_cdc_mem_alloc_count - 1);
|
||||
|
||||
/* Disconnect. */
|
||||
ux_test_dcd_sim_slave_disconnect();
|
||||
ux_test_hcd_sim_host_disconnect();
|
||||
|
||||
/* Update memory free level (disconnect) */
|
||||
if (mem_free == (~0))
|
||||
mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
|
||||
else if (mem_free != _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available)
|
||||
{
|
||||
|
||||
printf("ERROR #11.%ld: Memory level different after re-enumerations %ld <> %ld\n", test_n, mem_free, _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Set memory error generation */
|
||||
ux_test_utility_sim_mem_alloc_error_generation_start(test_n + rsc_enum_mem_alloc_count);
|
||||
|
||||
/* Connect. */
|
||||
error_callback_counter = 0;
|
||||
ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
|
||||
ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
|
||||
|
||||
/* Wait and break on errors. */
|
||||
ux_test_breakable_sleep(100, sleep_break_on_error);
|
||||
|
||||
/* Check error */
|
||||
if (cdc_acm_host_control && cdc_acm_host_data)
|
||||
{
|
||||
|
||||
printf("ERROR #12.%ld: device detected when there is memory error\n", test_n);
|
||||
test_control_return(1);
|
||||
}
|
||||
stepinfo("mem free: %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
|
||||
}
|
||||
ux_test_utility_sim_mem_alloc_error_generation_stop();
|
||||
if (rsc_cdc_mem_alloc_count) stepinfo("\n");
|
||||
|
||||
/* Finally disconnect the device. */
|
||||
ux_device_stack_disconnect();
|
||||
|
||||
/* And deinitialize the class. */
|
||||
status = ux_device_stack_class_unregister(_ux_system_slave_class_cdc_acm_name, ux_device_class_cdc_acm_entry);
|
||||
|
||||
/* Deinitialize the device side of usbx. */
|
||||
_ux_device_stack_uninitialize();
|
||||
|
||||
/* And finally the usbx system resources. */
|
||||
_ux_system_uninitialize();
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
|
||||
}
|
||||
|
||||
void ux_test_thread_slave_simulation_entry(ULONG arg)
|
||||
{
|
||||
|
||||
while(1)
|
||||
{
|
||||
/* Sleep so ThreadX on Win32 will delete this thread. */
|
||||
tx_thread_sleep(10);
|
||||
}
|
||||
}
|
3086
test/regression/usbx_cdc_acm_basic_test.c
Normal file
3086
test/regression/usbx_cdc_acm_basic_test.c
Normal file
File diff suppressed because it is too large
Load Diff
860
test/regression/usbx_cdc_acm_configure_test.c
Normal file
860
test/regression/usbx_cdc_acm_configure_test.c
Normal file
@ -0,0 +1,860 @@
|
||||
/* This test is designed to test the simple dpump host/device class operation. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
#include "ux_api.h"
|
||||
#include "ux_system.h"
|
||||
#include "ux_utility.h"
|
||||
|
||||
#include "fx_api.h"
|
||||
|
||||
#include "ux_device_class_cdc_acm.h"
|
||||
#include "ux_device_stack.h"
|
||||
|
||||
#include "ux_host_class_cdc_acm.h"
|
||||
|
||||
#include "ux_test_dcd_sim_slave.h"
|
||||
#include "ux_test_hcd_sim_host.h"
|
||||
#include "ux_test_utility_sim.h"
|
||||
|
||||
#include "ux_host_stack.h"
|
||||
|
||||
/* Define constants. */
|
||||
#define UX_DEMO_DEBUG_SIZE (4096*8)
|
||||
#define UX_DEMO_STACK_SIZE 1024
|
||||
#define UX_DEMO_BUFFER_SIZE (UX_SLAVE_REQUEST_DATA_MAX_LENGTH + 1)
|
||||
#define UX_DEMO_XMIT_BUFFER_SIZE 512
|
||||
#define UX_DEMO_RECEPTION_BUFFER_SIZE 512
|
||||
#define UX_DEMO_FILE_BUFFER_SIZE 512
|
||||
#define UX_DEMO_RECEPTION_BLOCK_SIZE 64
|
||||
#define UX_DEMO_MEMORY_SIZE (64*1024)
|
||||
#define UX_DEMO_FILE_SIZE (128 * 1024)
|
||||
#define UX_RAM_DISK_MEMORY (256 * 1024)
|
||||
|
||||
/* Define local/extern function prototypes. */
|
||||
static VOID test_thread_entry(ULONG);
|
||||
static TX_THREAD tx_test_thread_host_simulation;
|
||||
static TX_THREAD tx_test_thread_slave_simulation;
|
||||
static VOID tx_test_thread_host_simulation_entry(ULONG);
|
||||
static VOID tx_test_thread_slave_simulation_entry(ULONG);
|
||||
static VOID test_cdc_instance_activate(VOID *cdc_instance);
|
||||
static VOID test_cdc_instance_deactivate(VOID *cdc_instance);
|
||||
static VOID test_cdc_instance_parameter_change(VOID *cdc_instance);
|
||||
|
||||
/* Define global data structures. */
|
||||
UCHAR usbx_memory[UX_DEMO_MEMORY_SIZE + (UX_DEMO_STACK_SIZE * 2)];
|
||||
UX_HOST_CLASS *class_driver;
|
||||
UX_HOST_CLASS_CDC_ACM *cdc_acm_host_control;
|
||||
UX_HOST_CLASS_CDC_ACM *cdc_acm_host_data;
|
||||
|
||||
UX_SLAVE_CLASS_CDC_ACM *cdc_acm_slave;
|
||||
UCHAR cdc_acm_slave_change;
|
||||
UX_SLAVE_CLASS_CDC_ACM_PARAMETER parameter;
|
||||
|
||||
ULONG error_counter;
|
||||
|
||||
ULONG set_cfg_counter;
|
||||
|
||||
ULONG rsc_mem_free_on_set_cfg;
|
||||
ULONG rsc_sem_on_set_cfg;
|
||||
ULONG rsc_sem_get_on_set_cfg;
|
||||
ULONG rsc_mutex_on_set_cfg;
|
||||
|
||||
ULONG rsc_enum_sem_usage;
|
||||
ULONG rsc_enum_sem_get_count;
|
||||
ULONG rsc_enum_mutex_usage;
|
||||
ULONG rsc_enum_mem_usage;
|
||||
|
||||
/* Define device framework. */
|
||||
|
||||
#define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED 161
|
||||
#define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED 171
|
||||
#define STRING_FRAMEWORK_LENGTH 47
|
||||
#define LANGUAGE_ID_FRAMEWORK_LENGTH 2
|
||||
|
||||
static unsigned char device_framework_full_speed[] = {
|
||||
|
||||
/* Device descriptor 18 bytes
|
||||
0x02 bDeviceClass: CDC class code
|
||||
0x00 bDeviceSubclass: CDC class sub code
|
||||
0x00 bDeviceProtocol: CDC Device protocol
|
||||
|
||||
idVendor & idProduct - http://www.linux-usb.org/usb.ids
|
||||
*/
|
||||
0x12, 0x01, 0x10, 0x01,
|
||||
0xEF, 0x02, 0x01,
|
||||
0x08,
|
||||
0x84, 0x84, 0x00, 0x00,
|
||||
0x00, 0x01,
|
||||
0x01, 0x02, 03,
|
||||
0x02, /* bNumConfigurations */
|
||||
|
||||
/* Configuration 1 descriptor 9 bytes, total 68 bytes */
|
||||
0x09, 0x02, 0x44, 0x00, /* ,,wTotalLength */
|
||||
0x02, 0x01, 0x00, /* ,bConfigurationValue, */
|
||||
0x40, 0x00,
|
||||
|
||||
/* Interface association descriptor. 8 bytes. */
|
||||
0x08, 0x0b, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,
|
||||
|
||||
/* Communication Class Interface Descriptor Requirement. 9 bytes. */
|
||||
0x09, 0x04, 0x00, /* ,,bInterfaceNumber */
|
||||
0x00, /* bAlternateSetting */
|
||||
0x00, /* bNumEndpoints */
|
||||
0x02, 0x02, 0x01, /* bInterfaceClass,SubClass,Protocol */
|
||||
0x00,
|
||||
|
||||
/* Header Functional Descriptor 5 bytes */
|
||||
0x05, 0x24, 0x00,
|
||||
0x10, 0x01,
|
||||
|
||||
/* ACM Functional Descriptor 4 bytes */
|
||||
0x04, 0x24, 0x02,
|
||||
0x0f,
|
||||
|
||||
/* Union Functional Descriptor 5 bytes */
|
||||
0x05, 0x24, 0x06,
|
||||
0x00, /* Master interface */
|
||||
0x01, /* Slave interface */
|
||||
|
||||
/* Call Management Functional Descriptor 5 bytes */
|
||||
0x05, 0x24, 0x01,
|
||||
0x03,
|
||||
0x01, /* Data interface */
|
||||
|
||||
/* Data Class Interface Descriptor Requirement 9 bytes */
|
||||
0x09, 0x04, 0x01,
|
||||
0x00,
|
||||
0x02,
|
||||
0x0A, 0x00, 0x00,
|
||||
0x00,
|
||||
|
||||
/* Endpoint 0x81 descriptor 7 bytes */
|
||||
0x07, 0x05, 0x81,
|
||||
0x02,
|
||||
0x40, 0x00,
|
||||
0x00,
|
||||
|
||||
/* Endpoint 0x02 descriptor 7 bytes */
|
||||
0x07, 0x05, 0x02,
|
||||
0x02,
|
||||
0x40, 0x00,
|
||||
0x00,
|
||||
|
||||
/* Configuration 2 descriptor 9 bytes, total 75 bytes */
|
||||
0x09, 0x02, 0x4b, 0x00, /* ,,wTotalLength */
|
||||
0x02, 0x02, 0x00, /* ,bConfigurationValue, */
|
||||
0x40, 0xFA, /* bmAttributes,bMaxPower () */
|
||||
|
||||
/* Interface association descriptor. 8 bytes. */
|
||||
0x08, 0x0b, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,
|
||||
|
||||
/* Communication Class Interface Descriptor Requirement. 9 bytes. */
|
||||
0x09, 0x04, 0x00, /* ,,bInterfaceNumber */
|
||||
0x00, /* bAlternateSetting */
|
||||
0x01, /* bNumEndpoints */
|
||||
0x02, 0x02, 0x01, /* bInterfaceClass,SubClass,Protocol */
|
||||
0x00,
|
||||
|
||||
/* Header Functional Descriptor 5 bytes */
|
||||
0x05, 0x24, 0x00,
|
||||
0x10, 0x01,
|
||||
|
||||
/* ACM Functional Descriptor 4 bytes */
|
||||
0x04, 0x24, 0x02,
|
||||
0x0f,
|
||||
|
||||
/* Union Functional Descriptor 5 bytes */
|
||||
0x05, 0x24, 0x06,
|
||||
0x00, /* Master interface */
|
||||
0x01, /* Slave interface */
|
||||
|
||||
/* Call Management Functional Descriptor 5 bytes */
|
||||
0x05, 0x24, 0x01,
|
||||
0x03,
|
||||
0x01, /* Data interface */
|
||||
|
||||
/* Endpoint 0x83 descriptor 7 bytes */
|
||||
0x07, 0x05, 0x83, /* ,,bEndpointAddress */
|
||||
0x03,
|
||||
0x08, 0x00,
|
||||
0xFF,
|
||||
|
||||
/* Data Class Interface Descriptor Requirement 9 bytes */
|
||||
0x09, 0x04, 0x01,
|
||||
0x00,
|
||||
0x02,
|
||||
0x0A, 0x00, 0x00,
|
||||
0x00,
|
||||
|
||||
/* Endpoint 0x81 descriptor 7 bytes */
|
||||
0x07, 0x05, 0x81,
|
||||
0x02,
|
||||
0x40, 0x00,
|
||||
0x00,
|
||||
|
||||
/* Endpoint 0x02 descriptor 7 bytes */
|
||||
0x07, 0x05, 0x02,
|
||||
0x02,
|
||||
0x40, 0x00,
|
||||
0x00,
|
||||
};
|
||||
|
||||
#define DEVICE_FRAMEWORK_EPA_POS_1_FS (DEVICE_FRAMEWORK_LENGTH_FULL_SPEED - 14 + 2)
|
||||
#define DEVICE_FRAMEWORK_EPA_POS_2_FS (DEVICE_FRAMEWORK_LENGTH_FULL_SPEED - 7 + 2)
|
||||
|
||||
static unsigned char device_framework_high_speed[] = {
|
||||
|
||||
/* Device descriptor
|
||||
0x02 bDeviceClass: CDC class code
|
||||
0x00 bDeviceSubclass: CDC class sub code
|
||||
0x00 bDeviceProtocol: CDC Device protocol
|
||||
|
||||
idVendor & idProduct - http://www.linux-usb.org/usb.ids
|
||||
*/
|
||||
0x12, 0x01, 0x00, 0x02,
|
||||
0xEF, 0x02, 0x01,
|
||||
0x40,
|
||||
0x84, 0x84, 0x00, 0x00,
|
||||
0x00, 0x01,
|
||||
0x01, 0x02, 03,
|
||||
0x02, /* bNumConfigurations */
|
||||
|
||||
/* Device qualifier descriptor */
|
||||
0x0a, 0x06, 0x00, 0x02,
|
||||
0x02, 0x00, 0x00,
|
||||
0x40,
|
||||
0x01,
|
||||
0x00,
|
||||
|
||||
/* Configuration 1 descriptor 9 bytes, total 68 bytes */
|
||||
0x09, 0x02, 0x44, 0x00, /* ,,wTotalLength */
|
||||
0x02, 0x01, 0x00, /* ,bConfigurationValue, */
|
||||
0x40, 0x00,
|
||||
|
||||
/* Interface association descriptor. 8 bytes. */
|
||||
0x08, 0x0b, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,
|
||||
|
||||
/* Communication Class Interface Descriptor Requirement. 9 bytes. */
|
||||
0x09, 0x04, 0x00, /* ,,bInterfaceNumber */
|
||||
0x00, /* bAlternateSetting */
|
||||
0x00, /* bNumEndpoints */
|
||||
0x02, 0x02, 0x01, /* bInterfaceClass,SubClass,Protocol */
|
||||
0x00,
|
||||
|
||||
/* Header Functional Descriptor 5 bytes */
|
||||
0x05, 0x24, 0x00,
|
||||
0x10, 0x01,
|
||||
|
||||
/* ACM Functional Descriptor 4 bytes */
|
||||
0x04, 0x24, 0x02,
|
||||
0x0f,
|
||||
|
||||
/* Union Functional Descriptor 5 bytes */
|
||||
0x05, 0x24, 0x06,
|
||||
0x00, /* Master interface */
|
||||
0x01, /* Slave interface */
|
||||
|
||||
/* Call Management Functional Descriptor 5 bytes */
|
||||
0x05, 0x24, 0x01,
|
||||
0x03,
|
||||
0x01, /* Data interface */
|
||||
|
||||
/* Data Class Interface Descriptor Requirement 9 bytes */
|
||||
0x09, 0x04, 0x01,
|
||||
0x00,
|
||||
0x02,
|
||||
0x0A, 0x00, 0x00,
|
||||
0x00,
|
||||
|
||||
/* Endpoint 0x81 descriptor 7 bytes */
|
||||
0x07, 0x05, 0x81,
|
||||
0x02,
|
||||
0x40, 0x00,
|
||||
0x00,
|
||||
|
||||
/* Endpoint 0x02 descriptor 7 bytes */
|
||||
0x07, 0x05, 0x02,
|
||||
0x02,
|
||||
0x40, 0x00,
|
||||
0x00,
|
||||
|
||||
/* Configuration 2 descriptor 9 bytes, total 75 bytes */
|
||||
0x09, 0x02, 0x4b, 0x00, /* ,,wTotalLength */
|
||||
0x02, 0x02, 0x00, /* ,bConfigurationValue, */
|
||||
0x40, 0x00,
|
||||
|
||||
/* Interface association descriptor. 8 bytes. */
|
||||
0x08, 0x0b, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,
|
||||
|
||||
/* Communication Class Interface Descriptor Requirement. 9 bytes. */
|
||||
0x09, 0x04, 0x00, /* ,,bInterfaceNumber */
|
||||
0x00, /* bAlternateSetting */
|
||||
0x01, /* bNumEndpoints */
|
||||
0x02, 0x02, 0x01, /* bInterfaceClass,SubClass,Protocol */
|
||||
0x00,
|
||||
|
||||
/* Header Functional Descriptor 5 bytes */
|
||||
0x05, 0x24, 0x00,
|
||||
0x10, 0x01,
|
||||
|
||||
/* ACM Functional Descriptor 4 bytes */
|
||||
0x04, 0x24, 0x02,
|
||||
0x0f,
|
||||
|
||||
/* Union Functional Descriptor 5 bytes */
|
||||
0x05, 0x24, 0x06,
|
||||
0x00, /* Master interface */
|
||||
0x01, /* Slave interface */
|
||||
|
||||
/* Call Management Functional Descriptor 5 bytes */
|
||||
0x05, 0x24, 0x01,
|
||||
0x03,
|
||||
0x01, /* Data interface */
|
||||
|
||||
/* Endpoint 0x83 descriptor 7 bytes */
|
||||
0x07, 0x05, 0x83, /* ,,bEndpointAddress */
|
||||
0x03,
|
||||
0x08, 0x00,
|
||||
0xFF,
|
||||
|
||||
/* Data Class Interface Descriptor Requirement 9 bytes */
|
||||
0x09, 0x04, 0x01,
|
||||
0x00,
|
||||
0x02,
|
||||
0x0A, 0x00, 0x00,
|
||||
0x00,
|
||||
|
||||
/* Endpoint 0x81 descriptor 7 bytes */
|
||||
0x07, 0x05, 0x81,
|
||||
0x02,
|
||||
0x40, 0x00,
|
||||
0x00,
|
||||
|
||||
/* Endpoint 0x02 descriptor 7 bytes */
|
||||
0x07, 0x05, 0x02,
|
||||
0x02,
|
||||
0x40, 0x00,
|
||||
0x00,
|
||||
};
|
||||
|
||||
#define DEVICE_FRAMEWORK_EPA_POS_1_HS (DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED - 14 + 2)
|
||||
#define DEVICE_FRAMEWORK_EPA_POS_2_HS (DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED - 7 + 2)
|
||||
|
||||
static unsigned char string_framework[] = {
|
||||
|
||||
/* Manufacturer string descriptor : Index 1 - "Express Logic" */
|
||||
0x09, 0x04, 0x01, 0x0c,
|
||||
0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
|
||||
0x6f, 0x67, 0x69, 0x63,
|
||||
|
||||
/* Product string descriptor : Index 2 - "EL Composite device" */
|
||||
0x09, 0x04, 0x02, 0x13,
|
||||
0x45, 0x4c, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x6f,
|
||||
0x73, 0x69, 0x74, 0x65, 0x20, 0x64, 0x65, 0x76,
|
||||
0x69, 0x63, 0x65,
|
||||
|
||||
/* Serial Number string descriptor : Index 3 - "0001" */
|
||||
0x09, 0x04, 0x03, 0x04,
|
||||
0x30, 0x30, 0x30, 0x31
|
||||
};
|
||||
|
||||
|
||||
/* Multiple languages are supported on the device, to add
|
||||
a language besides english, the unicode language code must
|
||||
be appended to the language_id_framework array and the length
|
||||
adjusted accordingly. */
|
||||
static unsigned char language_id_framework[] = {
|
||||
|
||||
/* English. */
|
||||
0x09, 0x04
|
||||
};
|
||||
|
||||
static UX_TEST_SETUP _SetConfigure = UX_TEST_SETUP_SetConfigure;
|
||||
|
||||
static UX_TEST_HCD_SIM_ACTION error_on_SetCfg[] = {
|
||||
/* function, request to match,
|
||||
port action, port status,
|
||||
request action, request EP, request data, request actual length, request status,
|
||||
status, additional callback,
|
||||
no_return */
|
||||
{ UX_HCD_TRANSFER_REQUEST, &_SetConfigure,
|
||||
UX_FALSE, UX_TEST_PORT_STATUS_DISC,
|
||||
UX_TEST_SETUP_MATCH_REQ, 0, UX_NULL, 0, 0,
|
||||
UX_ERROR, UX_NULL}, /* Error */
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static UX_CONFIGURATION *cfg_2_modify;
|
||||
static VOID ux_test_hcd_entry_interaction_set_cfg(UX_TEST_ACTION *action, VOID *_params)
|
||||
{
|
||||
|
||||
if (cfg_2_modify)
|
||||
cfg_2_modify -> ux_configuration_handle = 0;
|
||||
}
|
||||
|
||||
static UX_TEST_HCD_SIM_ACTION corrupt_configuration_on_SetCfg[] = {
|
||||
/* function, request to match,
|
||||
port action, port status,
|
||||
request action, request EP, request data, request actual length, request status,
|
||||
status, additional callback,
|
||||
no_return */
|
||||
{ UX_HCD_TRANSFER_REQUEST, &_SetConfigure,
|
||||
UX_FALSE, UX_TEST_PORT_STATUS_DISC,
|
||||
UX_TEST_SETUP_MATCH_REQ, 0, UX_NULL, 0, 0,
|
||||
UX_SUCCESS, ux_test_hcd_entry_interaction_set_cfg,
|
||||
UX_TRUE}, /* Go on */
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
/* Define the ISR dispatch. */
|
||||
|
||||
extern VOID (*test_isr_dispatch)(void);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
/* Define the ISR dispatch routine. */
|
||||
|
||||
static void test_isr(void)
|
||||
{
|
||||
|
||||
/* For further expansion of interrupt-level testing. */
|
||||
}
|
||||
|
||||
static UINT test_host_change_function(ULONG event, UX_HOST_CLASS *cls, VOID *inst)
|
||||
{
|
||||
|
||||
UX_HOST_CLASS_CDC_ACM *cdc_acm = (UX_HOST_CLASS_CDC_ACM *) inst;
|
||||
|
||||
switch(event)
|
||||
{
|
||||
|
||||
case UX_DEVICE_INSERTION:
|
||||
|
||||
if (cdc_acm -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS)
|
||||
cdc_acm_host_control = cdc_acm;
|
||||
else
|
||||
cdc_acm_host_data = cdc_acm;
|
||||
break;
|
||||
|
||||
case UX_DEVICE_REMOVAL:
|
||||
|
||||
if (cdc_acm -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS)
|
||||
cdc_acm_host_control = UX_NULL;
|
||||
else
|
||||
cdc_acm_host_data = UX_NULL;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static VOID test_cdc_instance_activate(VOID *cdc_instance)
|
||||
{
|
||||
|
||||
/* Save the CDC instance. */
|
||||
cdc_acm_slave = (UX_SLAVE_CLASS_CDC_ACM *) cdc_instance;
|
||||
}
|
||||
static VOID test_cdc_instance_deactivate(VOID *cdc_instance)
|
||||
{
|
||||
|
||||
/* Reset the CDC instance. */
|
||||
cdc_acm_slave = UX_NULL;
|
||||
}
|
||||
|
||||
static VOID test_cdc_instance_parameter_change(VOID *cdc_instance)
|
||||
{
|
||||
|
||||
/* Set CDC parameter change flag. */
|
||||
cdc_acm_slave_change = UX_TRUE;
|
||||
}
|
||||
|
||||
static VOID test_ux_error_callback(UINT system_level, UINT system_context, UINT error_code)
|
||||
{
|
||||
}
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_cdc_acm_configure_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR * stack_pointer;
|
||||
CHAR * memory_pointer;
|
||||
|
||||
printf("Running CDC ACM Configure Test...................................... ");
|
||||
|
||||
/* Reset testing counts. */
|
||||
ux_test_utility_sim_mutex_create_count_reset();
|
||||
ux_test_utility_sim_sem_create_count_reset();
|
||||
ux_test_utility_sim_sem_get_count_reset();
|
||||
/* Reset error generations */
|
||||
ux_test_utility_sim_sem_error_generation_stop();
|
||||
ux_test_utility_sim_mutex_error_generation_stop();
|
||||
ux_test_utility_sim_sem_get_error_generation_stop();
|
||||
|
||||
/* Initialize the free memory pointer */
|
||||
stack_pointer = (CHAR *) usbx_memory;
|
||||
memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
|
||||
|
||||
|
||||
/* Initialize USBX Memory */
|
||||
status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL, 0);
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the error callback. */
|
||||
_ux_utility_error_callback_register(test_ux_error_callback);
|
||||
|
||||
/* The code below is required for installing the host portion of USBX */
|
||||
status = ux_host_stack_initialize(test_host_change_function);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register CDC ACM class */
|
||||
status = ux_host_stack_class_register(_ux_system_host_class_cdc_acm_name, ux_host_class_cdc_acm_entry);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* The code below is required for installing the device portion of USBX. No call back for
|
||||
device status change in this example. */
|
||||
status = ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
|
||||
device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
|
||||
string_framework, STRING_FRAMEWORK_LENGTH,
|
||||
language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Set the parameters for callback when insertion/extraction of a CDC device. */
|
||||
parameter.ux_slave_class_cdc_acm_instance_activate = test_cdc_instance_activate;
|
||||
parameter.ux_slave_class_cdc_acm_instance_deactivate = test_cdc_instance_deactivate;
|
||||
parameter.ux_slave_class_cdc_acm_parameter_change = test_cdc_instance_parameter_change;
|
||||
|
||||
/* Initialize the device cdc class. This class owns both interfaces starting with 0. */
|
||||
status = ux_device_stack_class_register(_ux_system_slave_class_cdc_acm_name, ux_device_class_cdc_acm_entry,
|
||||
1,0, ¶meter);
|
||||
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Initialize the simulated device controller. */
|
||||
status = _ux_test_dcd_sim_slave_initialize();
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register HCD for test */
|
||||
status = ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize,0,0);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the main host simulation thread. */
|
||||
status = tx_thread_create(&tx_test_thread_host_simulation, "tx test host simulation", tx_test_thread_host_simulation_entry, 0,
|
||||
stack_pointer, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the main slave simulation thread. */
|
||||
status = tx_thread_create(&tx_test_thread_slave_simulation, "tx test slave simulation", tx_test_thread_slave_simulation_entry, 0,
|
||||
stack_pointer + UX_DEMO_STACK_SIZE, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
void tx_test_thread_host_simulation_entry(ULONG arg)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
ULONG test_n;
|
||||
ULONG mem_free;
|
||||
UX_HOST_CLASS_COMMAND class_command;
|
||||
UX_CONFIGURATION *configuration;
|
||||
UX_HOST_CLASS_CDC_ACM *cdc_control;
|
||||
UX_HOST_CLASS_CDC_ACM *cdc_data;
|
||||
UX_DEVICE *device;
|
||||
UX_DEVICE *parent_device;
|
||||
UX_INTERFACE *interface;
|
||||
|
||||
stepinfo("\n");
|
||||
|
||||
/* Test connect. */
|
||||
stepinfo(">>>>>>>>>>>>>>>> Test connect\n");
|
||||
ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
|
||||
tx_thread_sleep(100);
|
||||
if (cdc_acm_host_control == UX_NULL || cdc_acm_host_data == UX_NULL || cdc_acm_slave == UX_NULL)
|
||||
{
|
||||
|
||||
printf("ERROR #%d: connection not detected\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
|
||||
cdc_control = cdc_acm_host_control;
|
||||
cdc_data = cdc_acm_host_data;
|
||||
|
||||
/* Test disconnect. */
|
||||
stepinfo(">>>>>>>>>>>>>>>> Test disconnect\n");
|
||||
ux_test_dcd_sim_slave_disconnect();
|
||||
ux_test_hcd_sim_host_disconnect();
|
||||
test_n = 10;
|
||||
while((cdc_acm_host_control || cdc_acm_host_data || cdc_acm_slave) && test_n --)
|
||||
tx_thread_sleep(10);
|
||||
|
||||
if (cdc_acm_host_control || cdc_acm_host_data || cdc_acm_slave)
|
||||
{
|
||||
|
||||
printf("ERROR #%d: instance not removed when disconnect, %p %p %p\n", __LINE__, cdc_acm_host_control, cdc_acm_host_data, cdc_acm_slave);
|
||||
test_control_return(1);
|
||||
}
|
||||
if (_ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available <= mem_free)
|
||||
{
|
||||
|
||||
printf("ERROR #%d: memory not freed when disconnect\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Test configure function */
|
||||
stepinfo(">>>>>>>>>>>>>>>> Test Configure\n");
|
||||
ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
|
||||
/* Now connect, configuration stopped because power issue */
|
||||
ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
|
||||
tx_thread_sleep(100);
|
||||
/* Find device */
|
||||
status = _ux_host_stack_device_get(0, &device);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
/* Reset configuration */
|
||||
status = ux_host_stack_device_configuration_reset(device);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
/* Find configuration */
|
||||
status = _ux_host_stack_device_configuration_get(device, 0, &configuration);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
/* Force power source */
|
||||
device -> ux_device_power_source = UX_DEVICE_BUS_POWERED;
|
||||
/* Activate interfaces */
|
||||
class_command.ux_host_class_command_request = UX_HOST_CLASS_COMMAND_ACTIVATE;
|
||||
/* Control interface */
|
||||
interface = configuration -> ux_configuration_first_interface;
|
||||
class_command.ux_host_class_command_container = (VOID *)interface;
|
||||
class_command.ux_host_class_command_class_ptr = interface->ux_interface_class;
|
||||
status = interface->ux_interface_class->ux_host_class_entry_function(&class_command);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
/* Data interface */
|
||||
interface = configuration -> ux_configuration_first_interface->ux_interface_next_interface;
|
||||
class_command.ux_host_class_command_container = (VOID *)interface;
|
||||
class_command.ux_host_class_command_class_ptr = interface->ux_interface_class;
|
||||
status = interface->ux_interface_class->ux_host_class_entry_function(&class_command);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
stepinfo(">>>>>>>>>>>>>>>> Test Configure ERROR\n");
|
||||
ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
|
||||
/* Now connect, configuration stopped because power issue */
|
||||
ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
|
||||
tx_thread_sleep(100);
|
||||
/* Find device */
|
||||
status = _ux_host_stack_device_get(0, &device);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
/* Reset configuration */
|
||||
status = ux_host_stack_device_configuration_reset(device);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
/* Find configuration */
|
||||
status = _ux_host_stack_device_configuration_get(device, 0, &configuration);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
#if UX_MAX_DEVICES > 1
|
||||
stepinfo(">>>>>>>>>>>>>>>> Test Configure ERROR - Parent power fail\n");
|
||||
/* Get a device */
|
||||
parent_device = _ux_host_stack_new_device_get();
|
||||
/* Use this device as parent */
|
||||
parent_device -> ux_device_power_source = UX_DEVICE_BUS_POWERED;
|
||||
device -> ux_device_parent = parent_device;
|
||||
/* Force power source */
|
||||
device -> ux_device_power_source = UX_DEVICE_BUS_POWERED;
|
||||
/* Activate interfaces */
|
||||
class_command.ux_host_class_command_request = UX_HOST_CLASS_COMMAND_ACTIVATE;
|
||||
/* Control interface */
|
||||
interface = configuration -> ux_configuration_first_interface;
|
||||
class_command.ux_host_class_command_container = (VOID *)interface;
|
||||
class_command.ux_host_class_command_class_ptr = interface->ux_interface_class;
|
||||
status = interface->ux_interface_class->ux_host_class_entry_function(&class_command);
|
||||
if (status != UX_CONNECTION_INCOMPATIBLE)
|
||||
{
|
||||
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
stepinfo(">>>>>>>>>>>>>>>> Test Configure ERROR - Configuration handler\n");
|
||||
device -> ux_device_handle = 0;
|
||||
status = interface->ux_interface_class->ux_host_class_entry_function(&class_command);
|
||||
if (status != UX_CONFIGURATION_HANDLE_UNKNOWN)
|
||||
{
|
||||
|
||||
printf("ERROR %d: expect UX_CONFIGURATION_HANDLE_UNKNOWN but got 0x%x\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
device -> ux_device_handle = (ULONG) (ALIGN_TYPE) device;
|
||||
|
||||
stepinfo(">>>>>>>>>>>>>>>> Test Configure ERROR - Parent power OK but SetConfigure error\n");
|
||||
parent_device -> ux_device_power_source = UX_DEVICE_SELF_POWERED;
|
||||
ux_test_hcd_sim_host_set_actions(error_on_SetCfg);
|
||||
status = interface->ux_interface_class->ux_host_class_entry_function(&class_command);
|
||||
if (status == UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR %d: expect fail\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
#endif
|
||||
stepinfo(">>>>>>>>>>>>>>>> Test Configure ERROR - Device power OK but SetConfigure error\n");
|
||||
device -> ux_device_power_source = UX_DEVICE_SELF_POWERED;
|
||||
ux_test_hcd_sim_host_set_actions(error_on_SetCfg);
|
||||
status = interface->ux_interface_class->ux_host_class_entry_function(&class_command);
|
||||
if (status == UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR %d: expect fail\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
stepinfo(">>>>>>>>>>>>>>>> Test Configure ERROR - SetConfigure\n");
|
||||
UX_DEVICE_PARENT_SET(device, UX_NULL);
|
||||
ux_test_hcd_sim_host_set_actions(error_on_SetCfg);
|
||||
status = interface->ux_interface_class->ux_host_class_entry_function(&class_command);
|
||||
if (status == UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
stepinfo(">>>>>>>>>>>>>>>> Test Configure ERROR - Interface get\n");
|
||||
/* Break the configuration */
|
||||
cfg_2_modify = configuration;
|
||||
ux_test_hcd_sim_host_set_actions(corrupt_configuration_on_SetCfg);
|
||||
status = interface->ux_interface_class->ux_host_class_entry_function(&class_command);
|
||||
if (status == UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d: %x\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
/* Restore */
|
||||
cfg_2_modify = UX_NULL;
|
||||
configuration->ux_configuration_handle = (ULONG)(ALIGN_TYPE)configuration;
|
||||
|
||||
/* Deinitialize the class. */
|
||||
status = ux_device_stack_class_unregister(_ux_system_slave_class_cdc_acm_name, ux_device_class_cdc_acm_entry);
|
||||
|
||||
/* Deinitialize the device side of usbx. */
|
||||
_ux_device_stack_uninitialize();
|
||||
|
||||
/* And finally the usbx system resources. */
|
||||
_ux_system_uninitialize();
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
|
||||
}
|
||||
|
||||
void tx_test_thread_slave_simulation_entry(ULONG arg)
|
||||
{
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Sleep so ThreadX on Win32 will delete this thread. */
|
||||
tx_thread_sleep(10);
|
||||
}
|
||||
}
|
@ -0,0 +1,526 @@
|
||||
/* This test is designed to test the simple dpump host/device class operation. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
#include "ux_api.h"
|
||||
#include "ux_system.h"
|
||||
#include "ux_utility.h"
|
||||
|
||||
#include "fx_api.h"
|
||||
|
||||
#include "ux_device_class_cdc_acm.h"
|
||||
#include "ux_device_stack.h"
|
||||
#include "ux_host_class_cdc_acm.h"
|
||||
#include "ux_test_dcd_sim_slave.h"
|
||||
#include "ux_test.h"
|
||||
|
||||
/* Define constants. */
|
||||
#define UX_DEMO_DEBUG_SIZE (4096*8)
|
||||
#define UX_DEMO_STACK_SIZE 1024
|
||||
#define UX_DEMO_BUFFER_SIZE 2048
|
||||
#define UX_DEMO_XMIT_BUFFER_SIZE 512
|
||||
#define UX_DEMO_RECEPTION_BUFFER_SIZE 512
|
||||
#define UX_DEMO_FILE_BUFFER_SIZE 512
|
||||
#define UX_DEMO_RECEPTION_BLOCK_SIZE 64
|
||||
#define UX_DEMO_MEMORY_SIZE (64*1024)
|
||||
#define UX_DEMO_FILE_SIZE (128 * 1024)
|
||||
#define UX_RAM_DISK_MEMORY (256 * 1024)
|
||||
|
||||
/* Define local/extern function prototypes. */
|
||||
static void demo_thread_entry(ULONG);
|
||||
static TX_THREAD tx_demo_thread_host_simulation;
|
||||
static TX_THREAD tx_demo_thread_slave_simulation;
|
||||
static void tx_demo_thread_host_simulation_entry(ULONG);
|
||||
static void tx_demo_thread_slave_simulation_entry(ULONG);
|
||||
static void demo_thread_host_reception_callback(UX_HOST_CLASS_CDC_ACM *cdc_acm, UINT status, UCHAR *reception_buffer, ULONG reception_size);
|
||||
static VOID demo_cdc_instance_activate(VOID *cdc_instance);
|
||||
static VOID demo_cdc_instance_deactivate(VOID *cdc_instance);
|
||||
static UINT demo_usbx_simulator_cdc_acm_host_send_at_command(UCHAR *string, ULONG length);
|
||||
static UINT tx_demo_thread_slave_simulation_response(UCHAR *string, ULONG length);
|
||||
|
||||
|
||||
/* Define global data structures. */
|
||||
static UCHAR usbx_memory[UX_DEMO_MEMORY_SIZE + (UX_DEMO_STACK_SIZE * 2)];
|
||||
static UX_HOST_CLASS *class_driver;
|
||||
static UX_HOST_CLASS_CDC_ACM *cdc_acm_host_control;
|
||||
static UX_HOST_CLASS_CDC_ACM *cdc_acm_host_data;
|
||||
static ULONG command_received_count;
|
||||
static UCHAR cdc_acm_reception_buffer[UX_DEMO_RECEPTION_BUFFER_SIZE];
|
||||
static UCHAR cdc_acm_xmit_buffer[UX_DEMO_XMIT_BUFFER_SIZE];
|
||||
static UX_HOST_CLASS_CDC_ACM_RECEPTION cdc_acm_reception;
|
||||
static UCHAR *global_reception_buffer;
|
||||
static ULONG global_reception_size;
|
||||
|
||||
static UX_SLAVE_CLASS_CDC_ACM *cdc_acm_slave;
|
||||
static UX_SLAVE_CLASS_CDC_ACM_PARAMETER parameter;
|
||||
static UCHAR buffer[UX_DEMO_BUFFER_SIZE];
|
||||
static ULONG echo_mode;
|
||||
|
||||
static ULONG error_counter;
|
||||
|
||||
|
||||
/* Define device framework. */
|
||||
|
||||
#define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED 93
|
||||
#define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED 103
|
||||
#define STRING_FRAMEWORK_LENGTH 47
|
||||
#define LANGUAGE_ID_FRAMEWORK_LENGTH 2
|
||||
|
||||
static unsigned char device_framework_full_speed[] = {
|
||||
|
||||
/* Device descriptor 18 bytes
|
||||
0x02 bDeviceClass: CDC class code
|
||||
0x00 bDeviceSubclass: CDC class sub code
|
||||
0x00 bDeviceProtocol: CDC Device protocol
|
||||
|
||||
idVendor & idProduct - http://www.linux-usb.org/usb.ids
|
||||
*/
|
||||
0x12, 0x01, 0x10, 0x01,
|
||||
0xEF, 0x02, 0x01,
|
||||
0x08,
|
||||
0x84, 0x84, 0x00, 0x00,
|
||||
0x00, 0x01,
|
||||
0x01, 0x02, 03,
|
||||
0x01,
|
||||
|
||||
/* Configuration 1 descriptor 9 bytes */
|
||||
0x09, 0x02, 0x4b, 0x00,
|
||||
0x02, 0x01, 0x00,
|
||||
0x40, 0x00,
|
||||
|
||||
/* Interface association descriptor. 8 bytes. */
|
||||
0x08, 0x0b, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,
|
||||
|
||||
/* Communication Class Interface Descriptor Requirement. 9 bytes. */
|
||||
0x09, 0x04, 0x00,
|
||||
0x00,
|
||||
0x01,
|
||||
0x02, 0x02, 0x01,
|
||||
0x00,
|
||||
|
||||
/* Header Functional Descriptor 5 bytes */
|
||||
0x05, 0x24, 0x00,
|
||||
0x10, 0x01,
|
||||
|
||||
/* ACM Functional Descriptor 4 bytes */
|
||||
0x04, 0x24, 0x02,
|
||||
0x0f,
|
||||
|
||||
/* Union Functional Descriptor 5 bytes */
|
||||
0x05, 0x24, 0x06,
|
||||
0x00, /* Master interface */
|
||||
0x01, /* Slave interface */
|
||||
|
||||
/* Call Management Functional Descriptor 5 bytes */
|
||||
0x05, 0x24, 0x01,
|
||||
0x03,
|
||||
0x01, /* Data interface */
|
||||
|
||||
/* Endpoint 1 descriptor 7 bytes */
|
||||
0x07, 0x05, 0x83,
|
||||
0x03,
|
||||
0x08, 0x00,
|
||||
0xFF,
|
||||
|
||||
/* Data Class Interface Descriptor Requirement 9 bytes */
|
||||
0x09, 0x04, 0x01,
|
||||
0x00,
|
||||
0x02,
|
||||
0x0A, 0x00, 0x00,
|
||||
0x00,
|
||||
|
||||
/* First alternate setting Endpoint 1 descriptor 7 bytes*/
|
||||
0x07, 0x05, 0x02,
|
||||
0x02,
|
||||
0x40, 0x00,
|
||||
0x00,
|
||||
|
||||
/* Endpoint 2 descriptor 7 bytes */
|
||||
0x07, 0x05, 0x81,
|
||||
0x02,
|
||||
0x40, 0x00,
|
||||
0x00,
|
||||
|
||||
};
|
||||
|
||||
static unsigned char device_framework_high_speed[] = {
|
||||
|
||||
/* Device descriptor
|
||||
0x02 bDeviceClass: CDC class code
|
||||
0x00 bDeviceSubclass: CDC class sub code
|
||||
0x00 bDeviceProtocol: CDC Device protocol
|
||||
|
||||
idVendor & idProduct - http://www.linux-usb.org/usb.ids
|
||||
*/
|
||||
0x12, 0x01, 0x00, 0x02,
|
||||
0xEF, 0x02, 0x01,
|
||||
0x40,
|
||||
0x84, 0x84, 0x00, 0x00,
|
||||
0x00, 0x01,
|
||||
0x01, 0x02, 03,
|
||||
0x01,
|
||||
|
||||
/* Device qualifier descriptor */
|
||||
0x0a, 0x06, 0x00, 0x02,
|
||||
0x02, 0x00, 0x00,
|
||||
0x40,
|
||||
0x01,
|
||||
0x00,
|
||||
|
||||
/* Configuration 1 descriptor */
|
||||
0x09, 0x02, 0x4b, 0x00,
|
||||
0x02, 0x01, 0x00,
|
||||
0x40, 0x00,
|
||||
|
||||
/* Interface association descriptor. */
|
||||
0x08, 0x0b, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,
|
||||
|
||||
/* Communication Class Interface Descriptor Requirement */
|
||||
0x09, 0x04, 0x01,
|
||||
0x00,
|
||||
0x01,
|
||||
0x02, 0x02, 0x01,
|
||||
0x00,
|
||||
|
||||
/* Header Functional Descriptor */
|
||||
0x05, 0x24, 0x00,
|
||||
0x10, 0x01,
|
||||
|
||||
/* ACM Functional Descriptor */
|
||||
0x04, 0x24, 0x02,
|
||||
0x0f,
|
||||
|
||||
/* Union Functional Descriptor */
|
||||
0x05, 0x24, 0x06,
|
||||
0x00,
|
||||
0x01,
|
||||
|
||||
/* Call Management Functional Descriptor */
|
||||
0x05, 0x24, 0x01,
|
||||
0x00,
|
||||
0x01,
|
||||
|
||||
/* Endpoint 1 descriptor */
|
||||
0x07, 0x05, 0x83,
|
||||
0x03,
|
||||
0x08, 0x00,
|
||||
0xFF,
|
||||
|
||||
/* Data Class Interface Descriptor Requirement */
|
||||
0x09, 0x04, 0x01,
|
||||
0x00,
|
||||
0x02,
|
||||
0x0A, 0x00, 0x00,
|
||||
0x00,
|
||||
|
||||
/* First alternate setting Endpoint 1 descriptor */
|
||||
0x07, 0x05, 0x02,
|
||||
0x02,
|
||||
0x40, 0x00,
|
||||
0x00,
|
||||
|
||||
/* Endpoint 2 descriptor */
|
||||
0x07, 0x05, 0x81,
|
||||
0x02,
|
||||
0x40, 0x00,
|
||||
0x00,
|
||||
|
||||
};
|
||||
|
||||
static unsigned char string_framework[] = {
|
||||
|
||||
/* Manufacturer string descriptor : Index 1 - "Express Logic" */
|
||||
0x09, 0x04, 0x01, 0x0c,
|
||||
0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
|
||||
0x6f, 0x67, 0x69, 0x63,
|
||||
|
||||
/* Product string descriptor : Index 2 - "EL Composite device" */
|
||||
0x09, 0x04, 0x02, 0x13,
|
||||
0x45, 0x4c, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x6f,
|
||||
0x73, 0x69, 0x74, 0x65, 0x20, 0x64, 0x65, 0x76,
|
||||
0x69, 0x63, 0x65,
|
||||
|
||||
/* Serial Number string descriptor : Index 3 - "0001" */
|
||||
0x09, 0x04, 0x03, 0x04,
|
||||
0x30, 0x30, 0x30, 0x31
|
||||
};
|
||||
|
||||
|
||||
/* Multiple languages are supported on the device, to add
|
||||
a language besides english, the unicode language code must
|
||||
be appended to the language_id_framework array and the length
|
||||
adjusted accordingly. */
|
||||
static unsigned char language_id_framework[] = {
|
||||
|
||||
/* English. */
|
||||
0x09, 0x04
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/* Define the ISR dispatch. */
|
||||
|
||||
extern VOID (*test_isr_dispatch)(void);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
/* Define the ISR dispatch routine. */
|
||||
|
||||
static void test_isr(void)
|
||||
{
|
||||
|
||||
/* For further expansion of interrupt-level testing. */
|
||||
}
|
||||
|
||||
|
||||
static UINT demo_class_cdc_acm_get(void)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
UX_HOST_CLASS *class;
|
||||
UX_HOST_CLASS_CDC_ACM *cdc_acm_host;
|
||||
|
||||
|
||||
/* Find the main cdc_acm container */
|
||||
status = ux_host_stack_class_get(_ux_system_host_class_cdc_acm_name, &class);
|
||||
if (status != UX_SUCCESS)
|
||||
return(status);
|
||||
|
||||
/* We get the first instance of the cdc_acm device */
|
||||
do
|
||||
{
|
||||
|
||||
status = ux_host_stack_class_instance_get(class, 0, (void **) &cdc_acm_host);
|
||||
tx_thread_sleep(10);
|
||||
} while (status != UX_SUCCESS);
|
||||
|
||||
/* We still need to wait for the cdc_acm status to be live */
|
||||
while (cdc_acm_host -> ux_host_class_cdc_acm_state != UX_HOST_CLASS_INSTANCE_LIVE)
|
||||
tx_thread_sleep(10);
|
||||
|
||||
/* Isolate both the control and data interfaces. */
|
||||
if (cdc_acm_host -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_DATA_CLASS)
|
||||
{
|
||||
/* This is the data interface. */
|
||||
cdc_acm_host_data = cdc_acm_host;
|
||||
|
||||
/* In that case, the second one should be the control interface. */
|
||||
status = ux_host_stack_class_instance_get(class, 1, (void **) &cdc_acm_host);
|
||||
|
||||
/* Check error. */
|
||||
if (status != UX_SUCCESS)
|
||||
return(status);
|
||||
|
||||
/* Check for the control interfaces. */
|
||||
if (cdc_acm_host -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS)
|
||||
{
|
||||
|
||||
/* This is the control interface. */
|
||||
cdc_acm_host_control = cdc_acm_host;
|
||||
|
||||
return(UX_SUCCESS);
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check for the control interfaces. */
|
||||
if (cdc_acm_host -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_CONTROL_CLASS)
|
||||
{
|
||||
|
||||
/* This is the control interface. */
|
||||
cdc_acm_host_control = cdc_acm_host;
|
||||
|
||||
/* In that case, the second one should be the data interface. */
|
||||
status = ux_host_stack_class_instance_get(class, 1, (void **) &cdc_acm_host);
|
||||
|
||||
/* Check error. */
|
||||
if (status != UX_SUCCESS)
|
||||
return(status);
|
||||
|
||||
/* Check for the data interface. */
|
||||
if (cdc_acm_host -> ux_host_class_cdc_acm_interface -> ux_interface_descriptor.bInterfaceClass == UX_HOST_CLASS_CDC_DATA_CLASS)
|
||||
{
|
||||
|
||||
/* This is the data interface. */
|
||||
cdc_acm_host_data = cdc_acm_host;
|
||||
|
||||
return(UX_SUCCESS);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Return ERROR. */
|
||||
return(UX_ERROR);
|
||||
}
|
||||
|
||||
static VOID demo_cdc_instance_activate(VOID *cdc_instance)
|
||||
{
|
||||
|
||||
/* Save the CDC instance. */
|
||||
cdc_acm_slave = (UX_SLAVE_CLASS_CDC_ACM *) cdc_instance;
|
||||
}
|
||||
static VOID demo_cdc_instance_deactivate(VOID *cdc_instance)
|
||||
{
|
||||
|
||||
/* Don't Reset the CDC instance. We need to use it after disconnection to
|
||||
check for the line state values. */
|
||||
//cdc_acm_slave = UX_NULL;
|
||||
}
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_cdc_acm_device_dtr_rts_reset_on_disconnect_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
CHAR * stack_pointer;
|
||||
CHAR * memory_pointer;
|
||||
UINT status;
|
||||
|
||||
/* Initialize the free memory pointer */
|
||||
stack_pointer = (CHAR *) usbx_memory;
|
||||
memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
|
||||
|
||||
/* Initialize USBX. Memory */
|
||||
status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running CDC ACM Basic Functionality Test............................ ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* The code below is required for installing the host portion of USBX */
|
||||
status = ux_host_stack_initialize(UX_NULL);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running CDC ACM Basic Functionality Test............................ ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register CDC-ACM class. */
|
||||
status = ux_host_stack_class_register(_ux_system_host_class_cdc_acm_name, ux_host_class_cdc_acm_entry);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running CDC ACM Basic Functionality Test............................ ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register all the USB host controllers available in this system */
|
||||
status = ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, ux_hcd_sim_host_initialize,0,0);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running CDC ACM Basic Functionality Test............................ ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* The code below is required for installing the device portion of USBX. No call back for
|
||||
device status change in this example. */
|
||||
status = ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
|
||||
device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
|
||||
string_framework, STRING_FRAMEWORK_LENGTH,
|
||||
language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running CDC ACM Basic Functionality Test............................ ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Set the parameters for callback when insertion/extraction of a CDC device. */
|
||||
parameter.ux_slave_class_cdc_acm_instance_activate = demo_cdc_instance_activate;
|
||||
parameter.ux_slave_class_cdc_acm_instance_deactivate = demo_cdc_instance_deactivate;
|
||||
|
||||
/* Initialize the device cdc class. This class owns both interfaces starting with 0. */
|
||||
status = ux_device_stack_class_register(_ux_system_slave_class_cdc_acm_name, ux_device_class_cdc_acm_entry,
|
||||
1,0, ¶meter);
|
||||
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running CDC ACM Basic Functionality Test............................ ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Initialize the simulated device controller. */
|
||||
status = _ux_dcd_sim_slave_initialize();
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running CDC ACM Basic Functionality Test............................ ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the main host simulation thread. */
|
||||
status = tx_thread_create(&tx_demo_thread_host_simulation, "tx demo host simulation", tx_demo_thread_host_simulation_entry, 0,
|
||||
stack_pointer, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running CDC ACM Basic Functionality Test............................ ERROR #9\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
static void tx_demo_thread_host_simulation_entry(ULONG arg)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
UX_SLAVE_CLASS_CDC_ACM_LINE_STATE_PARAMETER line_state_slave;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Device CDC-ACM DTR/RTS Reset on Disconnect Test............. ");
|
||||
|
||||
/* Find the cdc_acm class and wait for the link to be up. */
|
||||
status = demo_class_cdc_acm_get();
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
/* DPUMP basic test error. */
|
||||
printf("ERROR #10\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
while (!cdc_acm_slave);
|
||||
|
||||
/* Wait for RTS and DTR. */
|
||||
do
|
||||
{
|
||||
UX_TEST_CHECK_SUCCESS(ux_device_class_cdc_acm_ioctl(cdc_acm_slave, UX_SLAVE_CLASS_CDC_ACM_IOCTL_GET_LINE_STATE, &line_state_slave));
|
||||
}
|
||||
while (line_state_slave.ux_slave_class_cdc_acm_parameter_dtr == 0 ||
|
||||
line_state_slave.ux_slave_class_cdc_acm_parameter_rts == 0);
|
||||
|
||||
/* Now disconnect. */
|
||||
ux_test_disconnect_slave();
|
||||
ux_test_disconnect_host_wait_for_enum_completion();
|
||||
|
||||
/* Now make sure DTR and RTS are reset. */
|
||||
UX_TEST_CHECK_SUCCESS(ux_device_class_cdc_acm_ioctl(cdc_acm_slave, UX_SLAVE_CLASS_CDC_ACM_IOCTL_GET_LINE_STATE, &line_state_slave));
|
||||
UX_TEST_ASSERT(line_state_slave.ux_slave_class_cdc_acm_parameter_dtr == 0 &&
|
||||
line_state_slave.ux_slave_class_cdc_acm_parameter_rts == 0);
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
/* This tests the case where the host sets the device's alternate setting to
|
||||
zero. */
|
||||
|
||||
#include "usbx_ux_test_cdc_ecm.h"
|
||||
#include "ux_host_stack.h"
|
||||
|
||||
static UCHAR host_ready_for_basic_test;
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_cdc_ecm_alternate_setting_change_to_zero_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running CDC ECM Alternate Setting Change To Zero Test............... ");
|
||||
|
||||
stepinfo("\n");
|
||||
|
||||
ux_test_cdc_ecm_initialize(first_unused_memory);
|
||||
}
|
||||
|
||||
static void post_init_host()
|
||||
{
|
||||
|
||||
/* Change the data interface alternate setting to zero. */
|
||||
_ux_host_stack_interface_set(cdc_ecm_host->ux_host_class_cdc_ecm_interface_data);
|
||||
|
||||
/* Wait for the host to change settings, which means the device has too. */
|
||||
UX_TEST_CHECK_SUCCESS(ux_test_wait_for_value_ulong(&cdc_ecm_host->ux_host_class_cdc_ecm_link_state, 0));
|
||||
|
||||
/* Change the data interface alternate setting back to one. */
|
||||
_ux_host_stack_interface_set(cdc_ecm_host->ux_host_class_cdc_ecm_interface_data->ux_interface_next_interface);
|
||||
|
||||
/* Wait for the host to change settings, which means the device has too. */
|
||||
UX_TEST_CHECK_SUCCESS(ux_test_wait_for_value_ulong(&cdc_ecm_host->ux_host_class_cdc_ecm_link_state, 1));
|
||||
|
||||
/* Try a basic test. */
|
||||
host_ready_for_basic_test = 1;
|
||||
cdc_ecm_basic_test(BASIC_TEST_HOST, BASIC_TEST_TCP);
|
||||
|
||||
/* Huzzah! */
|
||||
|
||||
/* Change the data interface alternate setting to zero again - this time, with no deactivate callback. */
|
||||
cdc_ecm_device->ux_slave_class_cdc_ecm_parameter.ux_slave_class_cdc_ecm_instance_deactivate = UX_NULL;
|
||||
_ux_host_stack_interface_set(cdc_ecm_host->ux_host_class_cdc_ecm_interface_data);
|
||||
|
||||
/* Wait for the host to change settings, which means the device has too. */
|
||||
UX_TEST_CHECK_SUCCESS(ux_test_wait_for_value_ulong(&cdc_ecm_host->ux_host_class_cdc_ecm_link_state, 0));
|
||||
|
||||
/* Huzzah! Again! */
|
||||
}
|
||||
|
||||
static void post_init_device()
|
||||
{
|
||||
|
||||
/* Wait for basic test. */
|
||||
UX_TEST_CHECK_SUCCESS(ux_test_wait_for_value_uchar(&host_ready_for_basic_test, 1));
|
||||
cdc_ecm_basic_test(BASIC_TEST_DEVICE, BASIC_TEST_TCP);
|
||||
}
|
724
test/regression/usbx_cdc_ecm_basic_ipv6_test.c
Normal file
724
test/regression/usbx_cdc_ecm_basic_ipv6_test.c
Normal file
@ -0,0 +1,724 @@
|
||||
#ifndef USBX_UX_TEST_CDC_ECM_H
|
||||
#define USBX_UX_TEST_CDC_ECM_H
|
||||
|
||||
#include "ux_api.h"
|
||||
#include "ux_system.h"
|
||||
#include "ux_utility.h"
|
||||
#include "ux_network_driver.h"
|
||||
#include "ux_host_class_cdc_ecm.h"
|
||||
#include "ux_device_class_cdc_ecm.h"
|
||||
#include "ux_test_dcd_sim_slave.h"
|
||||
#include "ux_test_hcd_sim_host.h"
|
||||
#include "ux_test_utility_sim.h"
|
||||
#include "ux_test.h"
|
||||
#include "ux_test_actions.h"
|
||||
|
||||
//#define LOCAL_MACHINE
|
||||
|
||||
typedef struct DEVICE_INIT_DATA
|
||||
{
|
||||
UCHAR *framework;
|
||||
ULONG framework_length;
|
||||
UCHAR dont_register_hcd;
|
||||
UCHAR *string_framework;
|
||||
ULONG string_framework_length;
|
||||
} DEVICE_INIT_DATA;
|
||||
|
||||
#define DEMO_IP_THREAD_STACK_SIZE (8*1024)
|
||||
#define HOST_IP_ADDRESS IP_ADDRESS(192,168,1,176)
|
||||
#define HOST_SOCKET_PORT_UDP 45054
|
||||
#define HOST_SOCKET_PORT_TCP 45056
|
||||
#define DEVICE_IP_ADDRESS IP_ADDRESS(192,168,1,175)
|
||||
#define DEVICE_SOCKET_PORT_UDP 45055
|
||||
#define DEVICE_SOCKET_PORT_TCP 45057
|
||||
|
||||
#define PACKET_PAYLOAD 1400
|
||||
#define PACKET_POOL_SIZE (PACKET_PAYLOAD*10000)
|
||||
#define ARP_MEMORY_SIZE 1024
|
||||
|
||||
/* Define local constants. */
|
||||
|
||||
#define UX_DEMO_STACK_SIZE (4*1024)
|
||||
#define UX_USBX_MEMORY_SIZE (128*1024)
|
||||
|
||||
/* Define basic test constants. */
|
||||
|
||||
#define BASIC_TEST_NUM_ITERATIONS 10
|
||||
#define BASIC_TEST_NUM_PACKETS_PER_ITERATION 10
|
||||
#define BASIC_TEST_NUM_TOTAL_PACKETS (BASIC_TEST_NUM_ITERATIONS*BASIC_TEST_NUM_PACKETS_PER_ITERATION)
|
||||
#define BASIC_TEST_HOST 0
|
||||
#define BASIC_TEST_DEVICE 1
|
||||
#define BASIC_TEST_TCP 0
|
||||
#define BASIC_TEST_UDP 1
|
||||
|
||||
/* Host */
|
||||
|
||||
static UX_HOST_CLASS *class_driver_host;
|
||||
static UX_HOST_CLASS_CDC_ECM *cdc_ecm_host;
|
||||
static UX_HOST_CLASS_CDC_ECM *cdc_ecm_host_from_system_change_function;
|
||||
static TX_THREAD thread_host;
|
||||
static UCHAR thread_stack_host[UX_DEMO_STACK_SIZE];
|
||||
static NX_IP nx_ip_host;
|
||||
static NX_PACKET_POOL packet_pool_host;
|
||||
static NX_PACKET_POOL *packet_pool_host_ptr = &packet_pool_host;
|
||||
static NX_UDP_SOCKET udp_socket_host;
|
||||
static NX_TCP_SOCKET tcp_socket_host;
|
||||
static CHAR *packet_pool_memory_host;
|
||||
static CHAR ip_thread_stack_host[DEMO_IP_THREAD_STACK_SIZE];
|
||||
static CHAR arp_memory_host[ARP_MEMORY_SIZE];
|
||||
|
||||
/* Device */
|
||||
|
||||
static TX_THREAD thread_device;
|
||||
static UX_HOST_CLASS *class_driver_device;
|
||||
static UX_SLAVE_CLASS_CDC_ECM *cdc_ecm_device;
|
||||
static UX_SLAVE_CLASS_CDC_ECM_PARAMETER cdc_ecm_parameter;
|
||||
static UCHAR thread_stack_device[UX_DEMO_STACK_SIZE];
|
||||
static NX_IP nx_ip_device;
|
||||
static NX_PACKET_POOL packet_pool_device;
|
||||
static NX_UDP_SOCKET udp_socket_device;
|
||||
//static NX_TCP_SOCKET tcp_socket_device;
|
||||
static CHAR *packet_pool_memory_device;
|
||||
static CHAR ip_thread_stack_device[DEMO_IP_THREAD_STACK_SIZE];
|
||||
static CHAR arp_memory_device[ARP_MEMORY_SIZE];
|
||||
|
||||
static UCHAR global_is_device_initialized;
|
||||
static UCHAR global_host_ready_for_application;
|
||||
|
||||
static ULONG global_basic_test_num_writes_host;
|
||||
static ULONG global_basic_test_num_reads_host;
|
||||
static ULONG global_basic_test_num_writes_device;
|
||||
static ULONG global_basic_test_num_reads_device;
|
||||
static UCHAR device_is_finished;
|
||||
NXD_ADDRESS ipv6_addr_host;
|
||||
NXD_ADDRESS ipv6_addr_device;
|
||||
|
||||
/* Define local prototypes and definitions. */
|
||||
static void thread_entry_host(ULONG arg);
|
||||
static void thread_entry_device(ULONG arg);
|
||||
static void post_init_host();
|
||||
static void post_init_device();
|
||||
|
||||
#define DEFAULT_FRAMEWORK_LENGTH sizeof(default_device_framework)
|
||||
static unsigned char default_device_framework[] = {
|
||||
|
||||
/* Device Descriptor */
|
||||
0x12, /* bLength */
|
||||
0x01, /* bDescriptorType */
|
||||
0x10, 0x01, /* bcdUSB */
|
||||
0xef, /* bDeviceClass - Depends on bDeviceSubClass */
|
||||
0x02, /* bDeviceSubClass - Depends on bDeviceProtocol */
|
||||
0x01, /* bDeviceProtocol - There's an IAD */
|
||||
0x40, /* bMaxPacketSize0 */
|
||||
0x70, 0x07, /* idVendor */
|
||||
0x42, 0x10, /* idProduct */
|
||||
0x00, 0x01, /* bcdDevice */
|
||||
0x01, /* iManufacturer */
|
||||
0x02, /* iProduct */
|
||||
0x03, /* iSerialNumber */
|
||||
0x01, /* bNumConfigurations */
|
||||
|
||||
/* Configuration Descriptor */
|
||||
0x09, /* bLength */
|
||||
0x02, /* bDescriptorType */
|
||||
0x58, 0x00, /* wTotalLength */
|
||||
0x02, /* bNumInterfaces */
|
||||
0x01, /* bConfigurationValue */
|
||||
0x00, /* iConfiguration */
|
||||
0xc0, /* bmAttributes - Self-powered */
|
||||
0x00, /* bMaxPower */
|
||||
|
||||
/* Interface Association Descriptor */
|
||||
0x08, /* bLength */
|
||||
0x0b, /* bDescriptorType */
|
||||
0x00, /* bFirstInterface */
|
||||
0x02, /* bInterfaceCount */
|
||||
0x02, /* bFunctionClass - CDC - Communication */
|
||||
0x06, /* bFunctionSubClass - ECM */
|
||||
0x00, /* bFunctionProtocol - No class specific protocol required */
|
||||
0x00, /* iFunction */
|
||||
|
||||
/* Interface Descriptor */
|
||||
0x09, /* bLength */
|
||||
0x04, /* bDescriptorType */
|
||||
0x00, /* bInterfaceNumber */
|
||||
0x00, /* bAlternateSetting */
|
||||
0x01, /* bNumEndpoints */
|
||||
0x02, /* bInterfaceClass - CDC - Communication */
|
||||
0x06, /* bInterfaceSubClass - ECM */
|
||||
0x00, /* bInterfaceProtocol - No class specific protocol required */
|
||||
0x00, /* iInterface */
|
||||
|
||||
/* CDC Header Functional Descriptor */
|
||||
0x05, /* bLength */
|
||||
0x24, /* bDescriptorType */
|
||||
0x00, /* bDescriptorSubType */
|
||||
0x10, 0x01, /* bcdCDC */
|
||||
|
||||
/* CDC ECM Functional Descriptor */
|
||||
0x0d, /* bLength */
|
||||
0x24, /* bDescriptorType */
|
||||
0x0f, /* bDescriptorSubType */
|
||||
0x04, /* iMACAddress */
|
||||
0x00, 0x00, 0x00, 0x00, /* bmEthernetStatistics */
|
||||
0xea, 0x05, /* wMaxSegmentSize */
|
||||
0x00, 0x00, /* wNumberMCFilters */
|
||||
0x00, /* bNumberPowerFilters */
|
||||
|
||||
/* CDC Union Functional Descriptor */
|
||||
0x05, /* bLength */
|
||||
0x24, /* bDescriptorType */
|
||||
0x06, /* bDescriptorSubType */
|
||||
0x00, /* bmMasterInterface */
|
||||
0x01, /* bmSlaveInterface0 */
|
||||
|
||||
/* Endpoint Descriptor */
|
||||
0x07, /* bLength */
|
||||
0x05, /* bDescriptorType */
|
||||
0x83, /* bEndpointAddress */
|
||||
0x03, /* bmAttributes - Interrupt */
|
||||
0x08, 0x00, /* wMaxPacketSize */
|
||||
0x08, /* bInterval */
|
||||
|
||||
/* Interface Descriptor */
|
||||
0x09, /* bLength */
|
||||
0x04, /* bDescriptorType */
|
||||
0x01, /* bInterfaceNumber */
|
||||
0x00, /* bAlternateSetting */
|
||||
0x00, /* bNumEndpoints */
|
||||
0x0a, /* bInterfaceClass - CDC - Data */
|
||||
0x00, /* bInterfaceSubClass - Should be 0x00 */
|
||||
0x00, /* bInterfaceProtocol - No class specific protocol required */
|
||||
0x00, /* iInterface */
|
||||
|
||||
/* Interface Descriptor */
|
||||
0x09, /* bLength */
|
||||
0x04, /* bDescriptorType */
|
||||
0x01, /* bInterfaceNumber */
|
||||
0x01, /* bAlternateSetting */
|
||||
0x02, /* bNumEndpoints */
|
||||
0x0a, /* bInterfaceClass - CDC - Data */
|
||||
0x00, /* bInterfaceSubClass - Should be 0x00 */
|
||||
0x00, /* bInterfaceProtocol - No class specific protocol required */
|
||||
0x00, /* iInterface */
|
||||
|
||||
/* Endpoint Descriptor */
|
||||
0x07, /* bLength */
|
||||
0x05, /* bDescriptorType */
|
||||
0x02, /* bEndpointAddress */
|
||||
0x02, /* bmAttributes - Bulk */
|
||||
0x40, 0x00, /* wMaxPacketSize */
|
||||
0x00, /* bInterval */
|
||||
|
||||
/* Endpoint Descriptor */
|
||||
0x07, /* bLength */
|
||||
0x05, /* bDescriptorType */
|
||||
0x81, /* bEndpointAddress */
|
||||
0x02, /* bmAttributes - Bulk */
|
||||
0x40, 0x00, /* wMaxPacketSize */
|
||||
0x00, /* bInterval */
|
||||
|
||||
};
|
||||
|
||||
static unsigned char default_string_framework[] = {
|
||||
|
||||
/* Manufacturer string descriptor : Index 1 - "Express Logic" */
|
||||
0x09, 0x04, 0x01, 0x0c,
|
||||
0x45, 0x78, 0x70, 0x72, 0x65, 0x73, 0x20, 0x4c,
|
||||
0x6f, 0x67, 0x69, 0x63,
|
||||
|
||||
/* Product string descriptor : Index 2 - "EL CDCECM Device" */
|
||||
0x09, 0x04, 0x02, 0x10,
|
||||
0x45, 0x4c, 0x20, 0x43, 0x44, 0x43, 0x45, 0x43,
|
||||
0x4d, 0x20, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65,
|
||||
|
||||
/* Serial Number string descriptor : Index 3 - "0001" */
|
||||
0x09, 0x04, 0x03, 0x04,
|
||||
0x30, 0x30, 0x30, 0x31,
|
||||
|
||||
/* MAC Address string descriptor : Index 4 - "001E5841B879" */
|
||||
0x09, 0x04, 0x04, 0x0C,
|
||||
0x30, 0x30, 0x31, 0x45, 0x35, 0x38,
|
||||
0x34, 0x31, 0x42, 0x38, 0x37, 0x39,
|
||||
|
||||
};
|
||||
|
||||
/* Multiple languages are supported on the device, to add
|
||||
a language besides english, the unicode language code must
|
||||
be appended to the language_id_framework array and the length
|
||||
adjusted accordingly. */
|
||||
static unsigned char language_id_framework[] = {
|
||||
|
||||
/* English. */
|
||||
0x09, 0x04
|
||||
};
|
||||
|
||||
static DEVICE_INIT_DATA default_device_init_data = {
|
||||
.framework = default_device_framework,
|
||||
.framework_length = sizeof(default_device_framework),
|
||||
.dont_register_hcd = 0,
|
||||
.string_framework = default_string_framework,
|
||||
.string_framework_length = sizeof(default_string_framework)
|
||||
};
|
||||
|
||||
static void ux_test_cdc_ecm_initialize_use_framework(void *first_unused_memory, DEVICE_INIT_DATA *device_init_data)
|
||||
{
|
||||
|
||||
CHAR *memory_pointer = first_unused_memory;
|
||||
|
||||
/* Initialize possible uninitialized device init values. */
|
||||
|
||||
if (device_init_data->framework == NULL)
|
||||
{
|
||||
device_init_data->framework = default_device_framework;
|
||||
device_init_data->framework_length = sizeof(default_device_framework);
|
||||
}
|
||||
|
||||
if (device_init_data->string_framework == NULL)
|
||||
{
|
||||
device_init_data->string_framework = default_string_framework;
|
||||
device_init_data->string_framework_length = sizeof(default_string_framework);
|
||||
}
|
||||
|
||||
/* Initialize USBX Memory. */
|
||||
ux_system_initialize(memory_pointer, UX_USBX_MEMORY_SIZE, UX_NULL, 0);
|
||||
memory_pointer += UX_USBX_MEMORY_SIZE;
|
||||
|
||||
/* It looks weird if this doesn't have a comment! */
|
||||
ux_utility_error_callback_register(ux_test_error_callback);
|
||||
|
||||
/* Perform the initialization of the network driver. */
|
||||
UX_TEST_CHECK_SUCCESS(ux_network_driver_init());
|
||||
|
||||
/* Initialize the NetX system. */
|
||||
nx_system_initialize();
|
||||
|
||||
/* Now allocate memory for the packet pools. Note that using the memory passed
|
||||
to us by ThreadX is mucho bettero than putting it in global memory because
|
||||
we can reuse the memory for each test. So no more having to worry about
|
||||
running out of memory! */
|
||||
packet_pool_memory_host = memory_pointer;
|
||||
memory_pointer += PACKET_POOL_SIZE;
|
||||
packet_pool_memory_device = memory_pointer;
|
||||
memory_pointer += PACKET_POOL_SIZE;
|
||||
|
||||
/* Create the host thread. */
|
||||
UX_TEST_CHECK_SUCCESS(tx_thread_create(&thread_host, "host thread", thread_entry_host, (ULONG)(ALIGN_TYPE)device_init_data,
|
||||
thread_stack_host, UX_DEMO_STACK_SIZE,
|
||||
30, 30, 1, TX_DONT_START));
|
||||
UX_THREAD_EXTENSION_PTR_SET(&thread_host, device_init_data)
|
||||
tx_thread_resume(&thread_host);
|
||||
|
||||
/* Create the slave thread. */
|
||||
UX_TEST_CHECK_SUCCESS(tx_thread_create(&thread_device, "device thread", thread_entry_device, (ULONG)(ALIGN_TYPE)device_init_data,
|
||||
thread_stack_device, UX_DEMO_STACK_SIZE,
|
||||
30, 30, 1, TX_DONT_START));
|
||||
UX_THREAD_EXTENSION_PTR_SET(&thread_device, device_init_data)
|
||||
tx_thread_resume(&thread_device);
|
||||
}
|
||||
|
||||
static void ux_test_cdc_ecm_initialize(void *first_unused_memory)
|
||||
{
|
||||
|
||||
ux_test_cdc_ecm_initialize_use_framework(first_unused_memory, &default_device_init_data);
|
||||
}
|
||||
|
||||
static UINT system_change_function(ULONG event, UX_HOST_CLASS *class, VOID *instance)
|
||||
{
|
||||
if (event == UX_DEVICE_INSERTION)
|
||||
{
|
||||
cdc_ecm_host_from_system_change_function = instance;
|
||||
}
|
||||
else if (event == UX_DEVICE_REMOVAL)
|
||||
{
|
||||
cdc_ecm_host_from_system_change_function = UX_NULL;
|
||||
}
|
||||
return(UX_SUCCESS);
|
||||
}
|
||||
|
||||
static void class_cdc_ecm_get_host(void)
|
||||
{
|
||||
|
||||
UX_HOST_CLASS *class;
|
||||
|
||||
/* Find the main storage container */
|
||||
UX_TEST_CHECK_SUCCESS(ux_host_stack_class_get(_ux_system_host_class_cdc_ecm_name, &class));
|
||||
|
||||
/* We get the first instance of the storage device */
|
||||
UX_TEST_CHECK_SUCCESS(ux_test_host_stack_class_instance_get(class, 0, (void **) &cdc_ecm_host));
|
||||
|
||||
/* We still need to wait for the cdc-ecm status to be live */
|
||||
UX_TEST_CHECK_SUCCESS(ux_test_wait_for_value_uint(&cdc_ecm_host -> ux_host_class_cdc_ecm_state, UX_HOST_CLASS_INSTANCE_LIVE));
|
||||
|
||||
/* Now wait for the link to be up. */
|
||||
UX_TEST_CHECK_SUCCESS(ux_test_wait_for_value_ulong(&cdc_ecm_host->ux_host_class_cdc_ecm_link_state, UX_HOST_CLASS_CDC_ECM_LINK_STATE_UP));
|
||||
}
|
||||
|
||||
static VOID demo_cdc_ecm_instance_activate(VOID *cdc_ecm_instance)
|
||||
{
|
||||
|
||||
/* Save the CDC instance. */
|
||||
cdc_ecm_device = (UX_SLAVE_CLASS_CDC_ECM *) cdc_ecm_instance;
|
||||
}
|
||||
|
||||
static VOID demo_cdc_ecm_instance_deactivate(VOID *cdc_ecm_instance)
|
||||
{
|
||||
|
||||
/* Reset the CDC instance. */
|
||||
cdc_ecm_device = UX_NULL;
|
||||
}
|
||||
|
||||
/* Copied and pasted from ux_device_class_cdc_ecm_change.c. */
|
||||
static void ux_test_device_class_cdc_ecm_set_link_state(UX_SLAVE_CLASS_CDC_ECM *cdc_ecm, UCHAR new_link_state)
|
||||
{
|
||||
|
||||
/* Declare the link to be down. */
|
||||
cdc_ecm_device -> ux_slave_class_cdc_ecm_link_state = new_link_state;
|
||||
|
||||
/* We have a thread waiting for an event, we wake it up with a NETWORK NOTIFICATION CHANGE event.
|
||||
In turn they will release the NetX resources used and suspend. */
|
||||
UX_TEST_CHECK_SUCCESS(_ux_utility_event_flags_set(&cdc_ecm_device -> ux_slave_class_cdc_ecm_event_flags_group, UX_DEVICE_CLASS_CDC_ECM_NETWORK_NOTIFICATION_EVENT, TX_OR));
|
||||
}
|
||||
|
||||
static void read_packet_tcp(NX_TCP_SOCKET *tcp_socket, ULONG num_reads, CHAR *name)
|
||||
{
|
||||
|
||||
NX_PACKET *rcv_packet;
|
||||
ULONG num_writes_from_peer;
|
||||
|
||||
#ifndef LOCAL_MACHINE
|
||||
if (num_reads % 100 == 0)
|
||||
#endif
|
||||
stepinfo("%s reading tcp packet# %lu\n", name, num_reads);
|
||||
|
||||
UX_TEST_CHECK_SUCCESS(nx_tcp_socket_receive(tcp_socket, &rcv_packet, NX_WAIT_FOREVER));
|
||||
|
||||
num_writes_from_peer = *(ULONG *)rcv_packet->nx_packet_prepend_ptr;
|
||||
UX_TEST_ASSERT(num_writes_from_peer == num_reads);
|
||||
|
||||
UX_TEST_CHECK_SUCCESS(nx_packet_release(rcv_packet));
|
||||
}
|
||||
|
||||
static void write_packet_tcp(NX_TCP_SOCKET *tcp_socket, NX_PACKET_POOL *packet_pool, ULONG num_writes, CHAR *name)
|
||||
{
|
||||
|
||||
NX_PACKET *out_packet;
|
||||
|
||||
UX_TEST_CHECK_SUCCESS(nx_packet_allocate(packet_pool, &out_packet, NX_TCP_PACKET, NX_WAIT_FOREVER));
|
||||
|
||||
*(ULONG *)out_packet->nx_packet_prepend_ptr = num_writes;
|
||||
out_packet->nx_packet_length = sizeof(ULONG);
|
||||
out_packet->nx_packet_append_ptr = out_packet->nx_packet_prepend_ptr + out_packet->nx_packet_length;
|
||||
|
||||
#ifndef LOCAL_MACHINE
|
||||
if (num_writes % 100 == 0)
|
||||
#endif
|
||||
stepinfo("%s writing tcp packet# %lu\n", name, num_writes);
|
||||
|
||||
UX_TEST_CHECK_SUCCESS(nx_tcp_socket_send(tcp_socket, out_packet, NX_WAIT_FOREVER));
|
||||
}
|
||||
|
||||
static void read_packet_udp(NX_UDP_SOCKET *udp_socket, ULONG num_reads, CHAR *name)
|
||||
{
|
||||
|
||||
NX_PACKET *rcv_packet;
|
||||
ULONG num_writes_from_peer;
|
||||
|
||||
#ifndef LOCAL_MACHINE
|
||||
if (num_reads % 100 == 0)
|
||||
#endif
|
||||
stepinfo("%s reading udp packet# %lu\n", name, num_reads);
|
||||
|
||||
UX_TEST_CHECK_SUCCESS(nx_udp_socket_receive(udp_socket, &rcv_packet, NX_WAIT_FOREVER));
|
||||
|
||||
num_writes_from_peer = *(ULONG *)rcv_packet->nx_packet_prepend_ptr;
|
||||
UX_TEST_ASSERT(num_writes_from_peer == num_reads);
|
||||
|
||||
UX_TEST_CHECK_SUCCESS(nx_packet_release(rcv_packet));
|
||||
}
|
||||
|
||||
static void write_packet_udp(NX_UDP_SOCKET *udp_socket, NX_PACKET_POOL *packet_pool, ULONG ip_address, ULONG port, ULONG num_writes, CHAR *name)
|
||||
{
|
||||
|
||||
NX_PACKET *out_packet;
|
||||
|
||||
UX_TEST_CHECK_SUCCESS(nx_packet_allocate(packet_pool, &out_packet, NX_UDP_PACKET, NX_WAIT_FOREVER));
|
||||
|
||||
*(ULONG *)out_packet->nx_packet_prepend_ptr = num_writes;
|
||||
out_packet->nx_packet_length = sizeof(ULONG);
|
||||
out_packet->nx_packet_append_ptr = out_packet->nx_packet_prepend_ptr + out_packet->nx_packet_length;
|
||||
|
||||
#ifndef LOCAL_MACHINE
|
||||
if (num_writes % 100 == 0)
|
||||
#endif
|
||||
stepinfo("%s writing udp packet# %lu\n", name, num_writes);
|
||||
|
||||
UX_TEST_CHECK_SUCCESS(nx_udp_socket_send(udp_socket, out_packet, ip_address, port));
|
||||
}
|
||||
|
||||
static void thread_entry_host(ULONG device_init_data_ptr)
|
||||
{
|
||||
|
||||
DEVICE_INIT_DATA *device_init_data;
|
||||
|
||||
UX_THREAD_EXTENSION_PTR_GET(device_init_data, DEVICE_INIT_DATA, device_init_data_ptr);
|
||||
|
||||
/* Wait for device to initialize. */
|
||||
UX_TEST_CHECK_SUCCESS(ux_test_wait_for_value_uchar(&global_is_device_initialized, 1));
|
||||
|
||||
/* Create the IP instance. */
|
||||
|
||||
UX_TEST_CHECK_SUCCESS(nx_packet_pool_create(&packet_pool_host, "NetX Host Packet Pool", PACKET_PAYLOAD, packet_pool_memory_host, PACKET_POOL_SIZE));
|
||||
UX_TEST_CHECK_SUCCESS(nx_ip_create(&nx_ip_host, "NetX Host Thread", HOST_IP_ADDRESS, 0xFF000000UL,
|
||||
&packet_pool_host, _ux_network_driver_entry, ip_thread_stack_host, DEMO_IP_THREAD_STACK_SIZE, 1));
|
||||
|
||||
|
||||
/* Setup ARP. */
|
||||
|
||||
UX_TEST_CHECK_SUCCESS(nx_arp_enable(&nx_ip_host, (void *)arp_memory_host, ARP_MEMORY_SIZE));
|
||||
UX_TEST_CHECK_SUCCESS(nx_arp_static_entry_create(&nx_ip_host, DEVICE_IP_ADDRESS, 0x0000001E, 0x80032CD8));
|
||||
|
||||
/* Setup UDP. */
|
||||
|
||||
UX_TEST_CHECK_SUCCESS(nx_udp_enable(&nx_ip_host));
|
||||
UX_TEST_CHECK_SUCCESS(nx_udp_socket_create(&nx_ip_host, &udp_socket_host, "USB HOST UDP SOCKET", NX_IP_NORMAL, NX_DONT_FRAGMENT, 20, 20));
|
||||
UX_TEST_CHECK_SUCCESS(nx_udp_socket_bind(&udp_socket_host, HOST_SOCKET_PORT_UDP, NX_NO_WAIT));
|
||||
|
||||
// /* Setup TCP. */
|
||||
|
||||
// UX_TEST_CHECK_SUCCESS(nx_tcp_enable(&nx_ip_host));
|
||||
// UX_TEST_CHECK_SUCCESS(nx_tcp_socket_create(&nx_ip_host, &tcp_socket_host, "USB HOST TCP SOCKET", NX_IP_NORMAL, NX_DONT_FRAGMENT, NX_IP_TIME_TO_LIVE, 100, NX_NULL, NX_NULL));
|
||||
// UX_TEST_CHECK_SUCCESS(nx_tcp_server_socket_listen(&nx_ip_host, HOST_SOCKET_PORT_TCP, &tcp_socket_host, 5, NX_NULL));
|
||||
#if 1
|
||||
UX_TEST_CHECK_SUCCESS(nxd_ipv6_enable(&nx_ip_host));
|
||||
|
||||
UX_TEST_CHECK_SUCCESS(nxd_icmp_enable(&nx_ip_host));
|
||||
|
||||
UX_TEST_CHECK_SUCCESS(nx_ip_raw_packet_enable(&nx_ip_host));
|
||||
#endif
|
||||
|
||||
ipv6_addr_host.nxd_ip_version = NX_IP_VERSION_V6;
|
||||
ipv6_addr_host.nxd_ip_address.v6[0] = 0x20010000;
|
||||
ipv6_addr_host.nxd_ip_address.v6[1] = 0x00000000;
|
||||
ipv6_addr_host.nxd_ip_address.v6[2] = 0x00000000;
|
||||
ipv6_addr_host.nxd_ip_address.v6[3] = 0x00010001;
|
||||
|
||||
UX_TEST_CHECK_SUCCESS(nxd_ipv6_address_set(&nx_ip_host, 0, &ipv6_addr_host, 64, NX_NULL));
|
||||
|
||||
/* The code below is required for installing the host portion of USBX. */
|
||||
UX_TEST_CHECK_SUCCESS(ux_host_stack_initialize(system_change_function));
|
||||
|
||||
/* Register cdc_ecm class. */
|
||||
UX_TEST_CHECK_SUCCESS(ux_host_stack_class_register(_ux_system_host_class_cdc_ecm_name, ux_host_class_cdc_ecm_entry));
|
||||
|
||||
if (!device_init_data->dont_register_hcd)
|
||||
{
|
||||
|
||||
/* Register all the USB host controllers available in this system. */
|
||||
UX_TEST_CHECK_SUCCESS(ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize, 0, 0));
|
||||
|
||||
/* Find the storage class. */
|
||||
class_cdc_ecm_get_host();
|
||||
|
||||
// /* Connect to device TCP socket. */
|
||||
// UX_TEST_CHECK_SUCCESS(nx_tcp_server_socket_accept(&tcp_socket_host, NX_WAIT_FOREVER));
|
||||
}
|
||||
|
||||
global_host_ready_for_application = 1;
|
||||
|
||||
/* Call test code. */
|
||||
post_init_host();
|
||||
|
||||
/* We need to disconnect the host and device. This is because the NetX cleaning
|
||||
process (in usbxtestcontrol.c) includes disconnect the device, which tries
|
||||
to send a RST packet to the peer (or something). By disconnecting here,
|
||||
we ensure the deactivate routines notify the network driver so that the
|
||||
packet tranmissiong is stopped there. */
|
||||
ux_test_disconnect_slave();
|
||||
ux_test_disconnect_host_wait_for_enum_completion();
|
||||
|
||||
/* And finally the usbx system resources. */
|
||||
_ux_system_uninitialize();
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
|
||||
static void thread_entry_device(ULONG device_init_data_ptr)
|
||||
{
|
||||
|
||||
DEVICE_INIT_DATA *device_init_data;
|
||||
|
||||
UX_THREAD_EXTENSION_PTR_GET(device_init_data, DEVICE_INIT_DATA, device_init_data_ptr)
|
||||
|
||||
/* Create the IP instance. */
|
||||
|
||||
UX_TEST_CHECK_SUCCESS(nx_packet_pool_create(&packet_pool_device, "NetX Device Packet Pool", PACKET_PAYLOAD, packet_pool_memory_device, PACKET_POOL_SIZE));
|
||||
|
||||
UX_TEST_CHECK_SUCCESS(nx_ip_create(&nx_ip_device, "NetX Device Thread", DEVICE_IP_ADDRESS, 0xFF000000L, &packet_pool_device,
|
||||
_ux_network_driver_entry, ip_thread_stack_device, DEMO_IP_THREAD_STACK_SIZE, 1));
|
||||
|
||||
|
||||
/* Setup ARP. */
|
||||
|
||||
UX_TEST_CHECK_SUCCESS(nx_arp_enable(&nx_ip_device, (void *)arp_memory_device, ARP_MEMORY_SIZE));
|
||||
UX_TEST_CHECK_SUCCESS(nx_arp_static_entry_create(&nx_ip_device, HOST_IP_ADDRESS, 0x0000001E, 0x5841B878));
|
||||
|
||||
/* Setup UDP. */
|
||||
|
||||
UX_TEST_CHECK_SUCCESS(nx_udp_enable(&nx_ip_device));
|
||||
UX_TEST_CHECK_SUCCESS(nx_udp_socket_create(&nx_ip_device, &udp_socket_device, "USB DEVICE UDP SOCKET", NX_IP_NORMAL, NX_DONT_FRAGMENT, 20, 20));
|
||||
UX_TEST_CHECK_SUCCESS(nx_udp_socket_bind(&udp_socket_device, DEVICE_SOCKET_PORT_UDP, NX_NO_WAIT));
|
||||
|
||||
// /* Setup TCP. */
|
||||
|
||||
// UX_TEST_CHECK_SUCCESS(nx_tcp_enable(&nx_ip_device));
|
||||
// UX_TEST_CHECK_SUCCESS(nx_tcp_socket_create(&nx_ip_device, &tcp_socket_device, "USB DEVICE TCP SOCKET", NX_IP_NORMAL, NX_DONT_FRAGMENT, NX_IP_TIME_TO_LIVE, 100, NX_NULL, NX_NULL));
|
||||
// UX_TEST_CHECK_SUCCESS(nx_tcp_client_socket_bind(&tcp_socket_device, DEVICE_SOCKET_PORT_TCP, NX_WAIT_FOREVER));
|
||||
|
||||
#if 1
|
||||
UX_TEST_CHECK_SUCCESS(nxd_ipv6_enable(&nx_ip_device));
|
||||
|
||||
ipv6_addr_device.nxd_ip_version = NX_IP_VERSION_V6;
|
||||
ipv6_addr_device.nxd_ip_address.v6[0] = 0x20010000;
|
||||
ipv6_addr_device.nxd_ip_address.v6[1] = 0x00000000;
|
||||
ipv6_addr_device.nxd_ip_address.v6[2] = 0x00000000;
|
||||
ipv6_addr_device.nxd_ip_address.v6[3] = 0x00010002;
|
||||
|
||||
UX_TEST_CHECK_SUCCESS(nxd_ipv6_address_set(&nx_ip_device, 0, &ipv6_addr_device, 64, NX_NULL));
|
||||
|
||||
UX_TEST_CHECK_SUCCESS(nxd_icmp_enable(&nx_ip_device));
|
||||
|
||||
UX_TEST_CHECK_SUCCESS(nx_ip_raw_packet_enable(&nx_ip_device));
|
||||
|
||||
#endif
|
||||
|
||||
/* The code below is required for installing the device portion of USBX.
|
||||
In this demo, DFU is possible and we have a call back for state change. */
|
||||
UX_TEST_CHECK_SUCCESS(ux_device_stack_initialize(device_init_data->framework, device_init_data->framework_length,
|
||||
device_init_data->framework, device_init_data->framework_length,
|
||||
device_init_data->string_framework, device_init_data->string_framework_length,
|
||||
language_id_framework, sizeof(language_id_framework),
|
||||
UX_NULL));
|
||||
|
||||
/* Set the parameters for callback when insertion/extraction of a CDC device. Set to NULL.*/
|
||||
cdc_ecm_parameter.ux_slave_class_cdc_ecm_instance_activate = demo_cdc_ecm_instance_activate;
|
||||
cdc_ecm_parameter.ux_slave_class_cdc_ecm_instance_deactivate = demo_cdc_ecm_instance_deactivate;
|
||||
|
||||
/* Define a NODE ID. */
|
||||
cdc_ecm_parameter.ux_slave_class_cdc_ecm_parameter_local_node_id[0] = 0x00;
|
||||
cdc_ecm_parameter.ux_slave_class_cdc_ecm_parameter_local_node_id[1] = 0x1e;
|
||||
cdc_ecm_parameter.ux_slave_class_cdc_ecm_parameter_local_node_id[2] = 0x58;
|
||||
cdc_ecm_parameter.ux_slave_class_cdc_ecm_parameter_local_node_id[3] = 0x41;
|
||||
cdc_ecm_parameter.ux_slave_class_cdc_ecm_parameter_local_node_id[4] = 0xb8;
|
||||
cdc_ecm_parameter.ux_slave_class_cdc_ecm_parameter_local_node_id[5] = 0x78;
|
||||
|
||||
/* Define a remote NODE ID. */
|
||||
cdc_ecm_parameter.ux_slave_class_cdc_ecm_parameter_remote_node_id[0] = 0x00;
|
||||
cdc_ecm_parameter.ux_slave_class_cdc_ecm_parameter_remote_node_id[1] = 0x1e;
|
||||
cdc_ecm_parameter.ux_slave_class_cdc_ecm_parameter_remote_node_id[2] = 0x58;
|
||||
cdc_ecm_parameter.ux_slave_class_cdc_ecm_parameter_remote_node_id[3] = 0x41;
|
||||
cdc_ecm_parameter.ux_slave_class_cdc_ecm_parameter_remote_node_id[4] = 0xb8;
|
||||
cdc_ecm_parameter.ux_slave_class_cdc_ecm_parameter_remote_node_id[5] = 0x79;
|
||||
|
||||
/* Initialize the device cdc_ecm class. */
|
||||
UX_TEST_CHECK_SUCCESS(ux_device_stack_class_register(_ux_system_slave_class_cdc_ecm_name, ux_device_class_cdc_ecm_entry, 1, 0, &cdc_ecm_parameter));
|
||||
|
||||
/* Initialize the simulated device controller. */
|
||||
UX_TEST_CHECK_SUCCESS(_ux_test_dcd_sim_slave_initialize());
|
||||
|
||||
global_is_device_initialized = UX_TRUE;
|
||||
|
||||
if (!device_init_data->dont_register_hcd)
|
||||
{
|
||||
|
||||
UX_TEST_CHECK_SUCCESS(ux_test_wait_for_non_null((VOID **)&cdc_ecm_device));
|
||||
UX_TEST_CHECK_SUCCESS(ux_test_wait_for_value_ulong(&cdc_ecm_device->ux_slave_class_cdc_ecm_link_state, UX_DEVICE_CLASS_CDC_ECM_LINK_STATE_UP));
|
||||
|
||||
// /* Connect to host TCP socket. */
|
||||
// UX_TEST_CHECK_SUCCESS(nx_tcp_client_socket_connect(&tcp_socket_device, HOST_IP_ADDRESS, HOST_SOCKET_PORT_TCP, NX_WAIT_FOREVER));
|
||||
}
|
||||
|
||||
/* Wait for host - believe this is so that we know host is always first... gives us some 'determinism'. */
|
||||
UX_TEST_CHECK_SUCCESS(ux_test_wait_for_value_uchar(&global_host_ready_for_application, 1));
|
||||
|
||||
/* Call test code. */
|
||||
post_init_device();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_cdc_ecm_basic_ipv6_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running CDC ECM Basic Functionality Test............................ ");
|
||||
|
||||
stepinfo("\n");
|
||||
|
||||
ux_test_cdc_ecm_initialize(first_unused_memory);
|
||||
}
|
||||
|
||||
static void post_init_host()
|
||||
{
|
||||
UINT status;
|
||||
NX_PACKET *my_packet;
|
||||
ULONG value;
|
||||
|
||||
/* Print out test information banner. */
|
||||
printf("\nNetX Test: IPv6 Raw Packet Test......................................");
|
||||
|
||||
tx_thread_sleep(5 * NX_IP_PERIODIC_RATE);
|
||||
/* Now, pickup the three raw packets that should be queued on the other IP instance. */
|
||||
UX_TEST_CHECK_SUCCESS(nx_ip_raw_packet_receive(&nx_ip_host, &my_packet, 2 * NX_IP_PERIODIC_RATE));
|
||||
|
||||
if(memcmp(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28)) {
|
||||
printf("ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
UX_TEST_CHECK_SUCCESS(nx_packet_release(my_packet));
|
||||
|
||||
/* Wait for device to finish. */
|
||||
UX_TEST_CHECK_SUCCESS(ux_test_wait_for_value_uchar(&device_is_finished, UX_TRUE));
|
||||
|
||||
/* Disconnect. */
|
||||
ux_test_disconnect_slave_and_host_wait_for_enum_completion();
|
||||
|
||||
/* Connect with null system change function. */
|
||||
_ux_system_host->ux_system_host_change_function = UX_NULL;
|
||||
|
||||
/* Connect. */
|
||||
ux_test_connect_slave_and_host_wait_for_enum_completion();
|
||||
|
||||
/* We're done. */
|
||||
}
|
||||
|
||||
static void post_init_device()
|
||||
{
|
||||
UINT status;
|
||||
NX_PACKET *my_packet;
|
||||
NXD_ADDRESS dest_addr;
|
||||
ULONG value;
|
||||
|
||||
tx_thread_sleep(1 * NX_IP_PERIODIC_RATE);
|
||||
|
||||
/* Allocate a packet. */
|
||||
UX_TEST_CHECK_SUCCESS(nx_packet_allocate(&packet_pool_device, &my_packet, NX_UDP_PACKET, 2 * NX_IP_PERIODIC_RATE));
|
||||
|
||||
/* Write ABCs into the packet payload! */
|
||||
UX_TEST_CHECK_SUCCESS(nx_packet_data_append(my_packet, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &packet_pool_device, 2 * NX_IP_PERIODIC_RATE));
|
||||
|
||||
/* Send the raw IP packet. */
|
||||
UX_TEST_CHECK_SUCCESS(nxd_ip_raw_packet_send(&nx_ip_device, my_packet, &ipv6_addr_host, NX_IP_RAW >> 16, 0x80, NX_IP_NORMAL));
|
||||
|
||||
device_is_finished = UX_TRUE;
|
||||
}
|
||||
|
||||
#endif //USBX_UX_TEST_CDC_ECM_H
|
354
test/regression/usbx_cdc_ecm_basic_memory_test.c
Normal file
354
test/regression/usbx_cdc_ecm_basic_memory_test.c
Normal file
@ -0,0 +1,354 @@
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "usbx_ux_test_cdc_ecm.h"
|
||||
|
||||
/* Resource usage */
|
||||
|
||||
static ULONG set_cfg_counter;
|
||||
|
||||
static ULONG rsc_mem_alloc_cnt_on_set_cfg;
|
||||
static ULONG rsc_sem_on_set_cfg;
|
||||
static ULONG rsc_sem_get_on_set_cfg;
|
||||
static ULONG rsc_mutex_on_set_cfg;
|
||||
|
||||
static ULONG rsc_enum_sem_usage;
|
||||
static ULONG rsc_enum_sem_get_count;
|
||||
static ULONG rsc_enum_mutex_usage;
|
||||
static ULONG rsc_enum_mem_alloc_count;
|
||||
|
||||
static ULONG rsc_cdc_sem_usage;
|
||||
static ULONG rsc_cdc_sem_get_count;
|
||||
static ULONG rsc_cdc_mutex_usage;
|
||||
static ULONG rsc_cdc_mem_alloc_count;
|
||||
static ULONG rsc_cdc_mem_tx_rx_count;
|
||||
|
||||
static ULONG error_callback_counter;
|
||||
|
||||
/* Log resources usage on SetConfigure */
|
||||
|
||||
static UX_TEST_SETUP _SetConfigure = UX_TEST_SETUP_SetConfigure;
|
||||
|
||||
static VOID ux_test_hcd_entry_set_cfg(UX_TEST_ACTION *action, VOID *_params)
|
||||
{
|
||||
|
||||
set_cfg_counter ++;
|
||||
|
||||
rsc_mem_alloc_cnt_on_set_cfg = ux_test_utility_sim_mem_alloc_count();
|
||||
|
||||
rsc_sem_on_set_cfg = ux_test_utility_sim_sem_create_count();
|
||||
rsc_sem_get_on_set_cfg = ux_test_utility_sim_sem_get_count();
|
||||
rsc_mutex_on_set_cfg = ux_test_utility_sim_mutex_create_count();
|
||||
}
|
||||
|
||||
static UX_TEST_HCD_SIM_ACTION log_on_SetCfg[] = {
|
||||
{ .function = UX_HCD_TRANSFER_REQUEST,
|
||||
.req_setup = &_SetConfigure,
|
||||
.req_action = UX_TEST_SETUP_MATCH_REQ,
|
||||
.action_func = ux_test_hcd_entry_set_cfg,
|
||||
.no_return = UX_TRUE
|
||||
}, /* Invoke callback & continue */
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static void count_error_callback(struct UX_TEST_ACTION_STRUCT *action, VOID *params)
|
||||
{
|
||||
UX_TEST_ERROR_CALLBACK_PARAMS *error = (UX_TEST_ERROR_CALLBACK_PARAMS *)params;
|
||||
|
||||
// printf("error trap: 0x%x, 0x%x, 0x%x\n", error->system_level, error->system_context, error->error_code);
|
||||
error_callback_counter ++;
|
||||
}
|
||||
|
||||
static UX_TEST_HCD_SIM_ACTION count_on_error_trap[] = {
|
||||
{ .usbx_function = UX_TEST_OVERRIDE_ERROR_CALLBACK,
|
||||
.action_func = count_error_callback,
|
||||
},
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static UINT sleep_break_on_error(VOID)
|
||||
{
|
||||
|
||||
if (error_callback_counter >= 3)
|
||||
return error_callback_counter;
|
||||
|
||||
return UX_SUCCESS;
|
||||
}
|
||||
|
||||
static UINT sleep_break_on_host_tx_or_rx_buffer_allocated(VOID)
|
||||
{
|
||||
UINT buffer_count = 0;
|
||||
if (cdc_ecm_host == UX_NULL)
|
||||
return(UX_SUCCESS);
|
||||
if (cdc_ecm_host -> ux_host_class_cdc_ecm_xmit_buffer)
|
||||
buffer_count ++;
|
||||
if (cdc_ecm_host -> ux_host_class_cdc_ecm_receive_buffer)
|
||||
buffer_count ++;
|
||||
return (buffer_count);
|
||||
}
|
||||
|
||||
static UINT sleep_break_on_host_tx_and_rx_buffer_allocated(VOID)
|
||||
{
|
||||
UINT buffer_count = 0;
|
||||
if (cdc_ecm_host == UX_NULL)
|
||||
return(UX_SUCCESS);
|
||||
if (cdc_ecm_host -> ux_host_class_cdc_ecm_xmit_buffer)
|
||||
buffer_count ++;
|
||||
if (cdc_ecm_host -> ux_host_class_cdc_ecm_receive_buffer)
|
||||
buffer_count ++;
|
||||
return ((buffer_count >=2) ? buffer_count : UX_SUCCESS);
|
||||
}
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_cdc_ecm_basic_memory_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running CDC ECM Basic Memory Test................................... ");
|
||||
|
||||
stepinfo("\n");
|
||||
|
||||
/* Override error trap. */
|
||||
ux_test_link_hooks_from_array(count_on_error_trap);
|
||||
|
||||
/* Reset testing counts. */
|
||||
ux_test_utility_sim_mem_alloc_log_enable(UX_TRUE);
|
||||
ux_test_utility_sim_mem_alloc_count_reset();
|
||||
ux_test_utility_sim_mutex_create_count_reset();
|
||||
ux_test_utility_sim_sem_create_count_reset();
|
||||
ux_test_utility_sim_sem_get_count_reset();
|
||||
/* Reset error generations */
|
||||
ux_test_utility_sim_sem_error_generation_stop();
|
||||
ux_test_utility_sim_mutex_error_generation_stop();
|
||||
ux_test_utility_sim_sem_get_error_generation_stop();
|
||||
|
||||
ux_test_cdc_ecm_initialize(first_unused_memory);
|
||||
}
|
||||
|
||||
static void post_init_host()
|
||||
{
|
||||
|
||||
UINT status;
|
||||
ULONG mem_free;
|
||||
ULONG test_n;
|
||||
|
||||
|
||||
/* Test disconnect. */
|
||||
stepinfo(">>>>>>>>>>>>>>>>>>> Test disconnect\n");
|
||||
ux_test_disconnect_slave();
|
||||
ux_test_disconnect_host_wait_for_enum_completion();
|
||||
|
||||
/* Reset testing counts. */
|
||||
ux_test_utility_sim_mem_alloc_count_reset();
|
||||
ux_test_utility_sim_mutex_create_count_reset();
|
||||
ux_test_utility_sim_sem_create_count_reset();
|
||||
ux_test_utility_sim_sem_get_count_reset();
|
||||
ux_test_hcd_sim_host_set_actions(log_on_SetCfg);
|
||||
|
||||
/* Save free memory usage. */
|
||||
mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
|
||||
|
||||
stepinfo(">>>>>>>>>>>>>>>>>>> Test connect\n");
|
||||
/* Connect. */
|
||||
ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
|
||||
ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
|
||||
class_cdc_ecm_get_host();
|
||||
|
||||
/* Log create counts for further tests. */
|
||||
rsc_enum_mutex_usage = rsc_mutex_on_set_cfg;
|
||||
rsc_enum_sem_usage = rsc_sem_on_set_cfg;
|
||||
rsc_enum_mem_alloc_count = rsc_mem_alloc_cnt_on_set_cfg;
|
||||
/* Log create counts when instances active for further tests. */
|
||||
rsc_cdc_mutex_usage = ux_test_utility_sim_mutex_create_count() - rsc_enum_mutex_usage;
|
||||
rsc_cdc_sem_usage = ux_test_utility_sim_sem_create_count() - rsc_enum_sem_usage;
|
||||
rsc_cdc_mem_alloc_count = ux_test_utility_sim_mem_alloc_count() - rsc_enum_mem_alloc_count;
|
||||
/* Some allocation does not affect enum. */
|
||||
rsc_cdc_mem_tx_rx_count = 0;
|
||||
if (cdc_ecm_host->ux_host_class_cdc_ecm_receive_buffer)
|
||||
rsc_cdc_mem_tx_rx_count ++;
|
||||
if (cdc_ecm_host->ux_host_class_cdc_ecm_xmit_buffer)
|
||||
rsc_cdc_mem_tx_rx_count ++;
|
||||
/* Lock log base for tests. */
|
||||
ux_test_utility_sim_mem_alloc_log_lock();
|
||||
|
||||
stepinfo("enum mem: %ld\n", rsc_enum_mem_alloc_count);
|
||||
stepinfo("cdc mem : %ld\n", rsc_cdc_mem_alloc_count);
|
||||
stepinfo("mem free: %ld, %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available, _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_CACHE_SAFE] -> ux_byte_pool_available);
|
||||
|
||||
/* Simulate detach and attach for FS enumeration,
|
||||
and check if there is memory error in normal enumeration.
|
||||
*/
|
||||
stepinfo(">>>>>>>>>>>>>>>>>>> Enumeration test\n");
|
||||
mem_free = (~0);
|
||||
for (test_n = 0; test_n < 3; test_n++)
|
||||
{
|
||||
stepinfo("%4ld / 2\n", test_n);
|
||||
|
||||
/* Disconnect. */
|
||||
ux_test_dcd_sim_slave_disconnect();
|
||||
ux_test_hcd_sim_host_disconnect();
|
||||
|
||||
/* Update memory free level (disconnect) */
|
||||
if (mem_free == (~0))
|
||||
mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
|
||||
else if (mem_free != _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available)
|
||||
{
|
||||
|
||||
printf("ERROR #%d.%ld: Memory level different after re-enumerations %ld <> %ld\n", __LINE__, test_n, mem_free, _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Connect. */
|
||||
error_callback_counter = 0;
|
||||
ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
|
||||
ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
|
||||
|
||||
/* Wait and break on error. */
|
||||
ux_test_breakable_sleep(200, sleep_break_on_error);
|
||||
|
||||
/* Check */
|
||||
if (cdc_ecm_host_from_system_change_function == UX_NULL)
|
||||
{
|
||||
|
||||
printf("ERROR #%d.%ld: Enumeration fail\n", __LINE__, test_n);
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Simulate detach and attach for FS enumeration,
|
||||
and test possible memory allocation error handlings.
|
||||
*/
|
||||
if (rsc_cdc_mem_alloc_count) stepinfo(">>>>>>>>>>>>>>>>>>> Memory errors enumeration test\n");
|
||||
mem_free = (~0);
|
||||
for (test_n = 0; test_n < rsc_cdc_mem_alloc_count; test_n ++)
|
||||
{
|
||||
|
||||
stepinfo("%4ld / %4ld\n", test_n, rsc_cdc_mem_alloc_count - 1);
|
||||
|
||||
/* Disconnect. */
|
||||
ux_test_dcd_sim_slave_disconnect();
|
||||
ux_test_hcd_sim_host_disconnect();
|
||||
|
||||
/* Update memory free level (disconnect) */
|
||||
if (mem_free == (~0))
|
||||
mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
|
||||
else if (mem_free != _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available)
|
||||
{
|
||||
|
||||
printf("ERROR #%d.%ld: Memory level different after re-enumerations %ld <> %ld\n", __LINE__, test_n, mem_free, _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Set memory error generation */
|
||||
ux_test_utility_sim_mem_alloc_error_generation_start(test_n + rsc_enum_mem_alloc_count);
|
||||
|
||||
/* Connect. */
|
||||
error_callback_counter = 0;
|
||||
ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
|
||||
ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
|
||||
|
||||
if (test_n >= rsc_cdc_mem_alloc_count - rsc_cdc_mem_tx_rx_count)
|
||||
{
|
||||
|
||||
/* Wait and break on errors. */
|
||||
ux_test_breakable_sleep(200, sleep_break_on_error);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Wait and break on errors. */
|
||||
ux_test_breakable_sleep(200, sleep_break_on_error);
|
||||
|
||||
/* Check error */
|
||||
if (cdc_ecm_host_from_system_change_function != UX_NULL)
|
||||
{
|
||||
|
||||
printf("ERROR #%d.%ld: device detected when there is memory error\n", __LINE__, test_n);
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
stepinfo("mem free: %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
|
||||
}
|
||||
ux_test_utility_sim_mem_alloc_error_generation_stop();
|
||||
if (rsc_cdc_mem_alloc_count) stepinfo("\n");
|
||||
|
||||
/* Test device deinit. */
|
||||
stepinfo(">>>>>>>>>>>>>>>>>>> Test class deinit\n");
|
||||
ux_test_disconnect_slave();
|
||||
ux_test_disconnect_host_wait_for_enum_completion();
|
||||
ux_device_stack_class_unregister(_ux_system_slave_class_cdc_ecm_name, ux_device_class_cdc_ecm_entry);
|
||||
|
||||
/* Reset testing counts. */
|
||||
ux_test_utility_sim_mem_alloc_count_reset();
|
||||
ux_test_utility_sim_mutex_create_count_reset();
|
||||
ux_test_utility_sim_sem_create_count_reset();
|
||||
ux_test_utility_sim_sem_get_count_reset();
|
||||
|
||||
stepinfo(">>>>>>>>>>>>>>>>>>> Test class init\n");
|
||||
UX_TEST_CHECK_SUCCESS(ux_device_stack_class_register(_ux_system_slave_class_cdc_ecm_name, ux_device_class_cdc_ecm_entry, 1, 0, &cdc_ecm_parameter));
|
||||
|
||||
/* Log create counts for further tests. */
|
||||
rsc_cdc_mutex_usage = ux_test_utility_sim_mutex_create_count();
|
||||
rsc_cdc_sem_usage = ux_test_utility_sim_sem_create_count();
|
||||
rsc_cdc_mem_alloc_count = ux_test_utility_sim_mem_alloc_count();
|
||||
|
||||
/* Lock log base for tests. */
|
||||
ux_test_utility_sim_mem_alloc_log_lock();
|
||||
|
||||
if (rsc_cdc_mem_alloc_count) stepinfo(">>>>>>>>>>>>>>>>>>> Memory errors class init test\n");
|
||||
mem_free = (~0);
|
||||
for (test_n = 0; test_n < rsc_cdc_mem_alloc_count; test_n ++)
|
||||
{
|
||||
|
||||
stepinfo("%4ld / %4ld\n", test_n, rsc_cdc_mem_alloc_count - 1);
|
||||
|
||||
/* Deinit. */
|
||||
ux_device_stack_class_unregister(_ux_system_slave_class_cdc_ecm_name, ux_device_class_cdc_ecm_entry);
|
||||
|
||||
/* Update memory free level (disconnect) */
|
||||
if (mem_free == (~0))
|
||||
mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
|
||||
else if (mem_free != _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available)
|
||||
{
|
||||
|
||||
printf("ERROR #%d.%ld: Memory level different after re-init %ld <> %ld\n", __LINE__, test_n, mem_free, _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Set memory error generation */
|
||||
ux_test_utility_sim_mem_alloc_error_generation_start(test_n);
|
||||
|
||||
/* Init. */
|
||||
|
||||
status = ux_device_stack_class_register(_ux_system_slave_class_cdc_ecm_name, ux_device_class_cdc_ecm_entry, 1, 0, &cdc_ecm_parameter);
|
||||
|
||||
/* Check error */
|
||||
if (status != UX_MEMORY_INSUFFICIENT)
|
||||
{
|
||||
|
||||
printf("ERROR #%d.%ld: code 0x%x\n", __LINE__, test_n, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
stepinfo("mem free: %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
|
||||
}
|
||||
ux_test_utility_sim_mem_alloc_error_generation_stop();
|
||||
if (rsc_cdc_mem_alloc_count) stepinfo("\n");
|
||||
|
||||
stepinfo(">>>>>>>>>>>>>>>>>>> Test connect to avoid post post operation\n");
|
||||
/* Connect. */
|
||||
UX_TEST_CHECK_SUCCESS(ux_device_stack_class_register(_ux_system_slave_class_cdc_ecm_name, ux_device_class_cdc_ecm_entry, 1, 0, &cdc_ecm_parameter));
|
||||
ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
|
||||
ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
|
||||
class_cdc_ecm_get_host();
|
||||
|
||||
stepinfo(">>>>>>>>>>>>>>>>>>> post_init_host done\n");
|
||||
}
|
||||
|
||||
static void post_init_device()
|
||||
{
|
||||
stepinfo(">>>>>>>>>>>>>>>>>>> post_init_device empty\n");
|
||||
}
|
56
test/regression/usbx_cdc_ecm_basic_test.c
Normal file
56
test/regression/usbx_cdc_ecm_basic_test.c
Normal file
@ -0,0 +1,56 @@
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "usbx_ux_test_cdc_ecm.h"
|
||||
|
||||
static UCHAR device_is_finished;
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_cdc_ecm_basic_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running CDC ECM Basic Functionality Test............................ ");
|
||||
|
||||
stepinfo("\n");
|
||||
|
||||
ux_test_cdc_ecm_initialize(first_unused_memory);
|
||||
}
|
||||
|
||||
static void post_init_host()
|
||||
{
|
||||
|
||||
/* Running TCP test. */
|
||||
stepinfo("running TCP test.\n");
|
||||
cdc_ecm_basic_test(BASIC_TEST_HOST, BASIC_TEST_TCP);
|
||||
|
||||
/* Running UDP test. */
|
||||
stepinfo("running UDP test.\n");
|
||||
cdc_ecm_basic_test(BASIC_TEST_HOST, BASIC_TEST_UDP);
|
||||
|
||||
/* Wait for device to finish. */
|
||||
UX_TEST_CHECK_SUCCESS(ux_test_wait_for_value_uchar(&device_is_finished, UX_TRUE));
|
||||
|
||||
/* Disconnect. */
|
||||
ux_test_disconnect_slave_and_host_wait_for_enum_completion();
|
||||
|
||||
/* Connect with null system change function. */
|
||||
_ux_system_host->ux_system_host_change_function = UX_NULL;
|
||||
|
||||
/* Connect. */
|
||||
ux_test_connect_slave_and_host_wait_for_enum_completion();
|
||||
|
||||
/* We're done. */
|
||||
}
|
||||
|
||||
static void post_init_device()
|
||||
{
|
||||
|
||||
cdc_ecm_basic_test(BASIC_TEST_DEVICE, BASIC_TEST_TCP);
|
||||
cdc_ecm_basic_test(BASIC_TEST_DEVICE, BASIC_TEST_UDP);
|
||||
|
||||
device_is_finished = UX_TRUE;
|
||||
}
|
@ -0,0 +1,170 @@
|
||||
/* This tests the case where there is no interrupt endpoint in the CDC-ECM control
|
||||
interface. Host should not report an error since this endpoint is optional. */
|
||||
|
||||
#include "usbx_ux_test_cdc_ecm.h"
|
||||
|
||||
static unsigned char no_interrupt_endpoint_configuration_descriptor[] = {
|
||||
|
||||
/* Device Descriptor */
|
||||
0x12, /* bLength */
|
||||
0x01, /* bDescriptorType */
|
||||
0x10, 0x01, /* bcdUSB */
|
||||
0xef, /* bDeviceClass - Depends on bDeviceSubClass */
|
||||
0x02, /* bDeviceSubClass - Depends on bDeviceProtocol */
|
||||
0x01, /* bDeviceProtocol - There's an IAD */
|
||||
0x40, /* bMaxPacketSize0 */
|
||||
0x70, 0x07, /* idVendor */
|
||||
0x42, 0x10, /* idProduct */
|
||||
0x00, 0x01, /* bcdDevice */
|
||||
0x01, /* iManufacturer */
|
||||
0x02, /* iProduct */
|
||||
0x03, /* iSerialNumber */
|
||||
0x01, /* bNumConfigurations */
|
||||
|
||||
/* Configuration Descriptor */
|
||||
0x09, /* bLength */
|
||||
0x02, /* bDescriptorType */
|
||||
0x5f, 0x00, /* wTotalLength */
|
||||
0x02, /* bNumInterfaces */
|
||||
0x01, /* bConfigurationValue */
|
||||
0x00, /* iConfiguration */
|
||||
0xc0, /* bmAttributes - Self-powered */
|
||||
0x00, /* bMaxPower */
|
||||
|
||||
/* Interface Association Descriptor */
|
||||
0x08, /* bLength */
|
||||
0x0b, /* bDescriptorType */
|
||||
0x00, /* bFirstInterface */
|
||||
0x02, /* bInterfaceCount */
|
||||
0x02, /* bFunctionClass - CDC - Communication */
|
||||
0x06, /* bFunctionSubClass - ECM */
|
||||
0x00, /* bFunctionProtocol - No class specific protocol required */
|
||||
0x00, /* iFunction */
|
||||
|
||||
/* Interface Descriptor */
|
||||
0x09, /* bLength */
|
||||
0x04, /* bDescriptorType */
|
||||
0x00, /* bInterfaceNumber */
|
||||
0x00, /* bAlternateSetting */
|
||||
0x02, /* bNumEndpoints */
|
||||
0x02, /* bInterfaceClass - CDC - Communication */
|
||||
0x06, /* bInterfaceSubClass - ECM */
|
||||
0x00, /* bInterfaceProtocol - No class specific protocol required */
|
||||
0x00, /* iInterface */
|
||||
|
||||
/* CDC Header Functional Descriptor */
|
||||
0x05, /* bLength */
|
||||
0x24, /* bDescriptorType */
|
||||
0x00, /* bDescriptorSubType */
|
||||
0x10, 0x01, /* bcdCDC */
|
||||
|
||||
/* CDC ECM Functional Descriptor */
|
||||
0x0d, /* bLength */
|
||||
0x24, /* bDescriptorType */
|
||||
0x0f, /* bDescriptorSubType */
|
||||
0x04, /* iMACAddress */
|
||||
0x00, 0x00, 0x00, 0x00, /* bmEthernetStatistics */
|
||||
0xea, 0x05, /* wMaxSegmentSize */
|
||||
0x00, 0x00, /* wNumberMCFilters */
|
||||
0x00, /* bNumberPowerFilters */
|
||||
|
||||
/* CDC Union Functional Descriptor */
|
||||
0x05, /* bLength */
|
||||
0x24, /* bDescriptorType */
|
||||
0x06, /* bDescriptorSubType */
|
||||
0x00, /* bmMasterInterface */
|
||||
0x01, /* bmSlaveInterface0 */
|
||||
|
||||
/* ??? out (to hit non-in case) */
|
||||
/* Endpoint Descriptor */
|
||||
0x07, /* bLength */
|
||||
0x05, /* bDescriptorType */
|
||||
0x01, /* bEndpointAddress */
|
||||
0x02, /* bmAttributes - Bulk */
|
||||
0x40, 0x00, /* wMaxPacketSize */
|
||||
0x00, /* bInterval */
|
||||
|
||||
/* ??? in (to hit non-interrupt case) */
|
||||
/* Endpoint Descriptor */
|
||||
0x07, /* bLength */
|
||||
0x05, /* bDescriptorType */
|
||||
0x82, /* bEndpointAddress */
|
||||
0x02, /* bmAttributes - Bulk */
|
||||
0x40, 0x00, /* wMaxPacketSize */
|
||||
0x00, /* bInterval */
|
||||
|
||||
/* Interface Descriptor */
|
||||
0x09, /* bLength */
|
||||
0x04, /* bDescriptorType */
|
||||
0x01, /* bInterfaceNumber */
|
||||
0x00, /* bAlternateSetting */
|
||||
0x00, /* bNumEndpoints */
|
||||
0x0a, /* bInterfaceClass - CDC - Data */
|
||||
0x00, /* bInterfaceSubClass - Should be 0x00 */
|
||||
0x00, /* bInterfaceProtocol - No class specific protocol required */
|
||||
0x00, /* iInterface */
|
||||
|
||||
/* Interface Descriptor */
|
||||
0x09, /* bLength */
|
||||
0x04, /* bDescriptorType */
|
||||
0x01, /* bInterfaceNumber */
|
||||
0x01, /* bAlternateSetting */
|
||||
0x02, /* bNumEndpoints */
|
||||
0x0a, /* bInterfaceClass - CDC - Data */
|
||||
0x00, /* bInterfaceSubClass - Should be 0x00 */
|
||||
0x00, /* bInterfaceProtocol - No class specific protocol required */
|
||||
0x00, /* iInterface */
|
||||
|
||||
/* Endpoint Descriptor */
|
||||
0x07, /* bLength */
|
||||
0x05, /* bDescriptorType */
|
||||
0x03, /* bEndpointAddress */
|
||||
0x02, /* bmAttributes - Bulk */
|
||||
0x40, 0x00, /* wMaxPacketSize */
|
||||
0x00, /* bInterval */
|
||||
|
||||
/* Endpoint Descriptor */
|
||||
0x07, /* bLength */
|
||||
0x05, /* bDescriptorType */
|
||||
0x84, /* bEndpointAddress */
|
||||
0x02, /* bmAttributes - Bulk */
|
||||
0x40, 0x00, /* wMaxPacketSize */
|
||||
0x00, /* bInterval */
|
||||
|
||||
};
|
||||
|
||||
static DEVICE_INIT_DATA device_init_data = {
|
||||
.framework = no_interrupt_endpoint_configuration_descriptor,
|
||||
.framework_length = sizeof(no_interrupt_endpoint_configuration_descriptor),
|
||||
.dont_register_hcd = 1,
|
||||
};
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_cdc_ecm_control_interface_no_interrupt_endpoint_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running CDC-ECM No Interrupt Endpoint Test.......................... ");
|
||||
|
||||
stepinfo("\n");
|
||||
|
||||
ux_test_cdc_ecm_initialize_use_framework(first_unused_memory, &device_init_data);
|
||||
}
|
||||
|
||||
static void post_init_host()
|
||||
{
|
||||
|
||||
/* Enumerate. */
|
||||
UX_TEST_CHECK_SUCCESS(ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize, 0, 0));
|
||||
|
||||
/* The HCD init function put()s the HCD semaphore, so we can do this here. */
|
||||
ux_test_wait_for_enum_thread_completion();
|
||||
}
|
||||
|
||||
static void post_init_device()
|
||||
{
|
||||
}
|
@ -0,0 +1,177 @@
|
||||
/* This tests the following cases:
|
||||
1. There is an out endpoint, but not bulk.
|
||||
2. There is an in endpoint, but in bulk. */
|
||||
|
||||
#include "usbx_ux_test_cdc_ecm.h"
|
||||
|
||||
static unsigned char non_bulk_out_endpoint[] = {
|
||||
|
||||
/* Device Descriptor */
|
||||
0x12, /* bLength */
|
||||
0x01, /* bDescriptorType */
|
||||
0x10, 0x01, /* bcdUSB */
|
||||
0xef, /* bDeviceClass - Depends on bDeviceSubClass */
|
||||
0x02, /* bDeviceSubClass - Depends on bDeviceProtocol */
|
||||
0x01, /* bDeviceProtocol - There's an IAD */
|
||||
0x40, /* bMaxPacketSize0 */
|
||||
0x70, 0x07, /* idVendor */
|
||||
0x42, 0x10, /* idProduct */
|
||||
0x00, 0x01, /* bcdDevice */
|
||||
0x01, /* iManufacturer */
|
||||
0x02, /* iProduct */
|
||||
0x03, /* iSerialNumber */
|
||||
0x01, /* bNumConfigurations */
|
||||
|
||||
/* Configuration Descriptor */
|
||||
0x09, /* bLength */
|
||||
0x02, /* bDescriptorType */
|
||||
0x66, 0x00, /* wTotalLength */
|
||||
0x02, /* bNumInterfaces */
|
||||
0x01, /* bConfigurationValue */
|
||||
0x00, /* iConfiguration */
|
||||
0xc0, /* bmAttributes - Self-powered */
|
||||
0x00, /* bMaxPower */
|
||||
|
||||
/* Interface Association Descriptor */
|
||||
0x08, /* bLength */
|
||||
0x0b, /* bDescriptorType */
|
||||
0x00, /* bFirstInterface */
|
||||
0x02, /* bInterfaceCount */
|
||||
0x02, /* bFunctionClass - CDC - Communication */
|
||||
0x06, /* bFunctionSubClass - ECM */
|
||||
0x00, /* bFunctionProtocol - No class specific protocol required */
|
||||
0x00, /* iFunction */
|
||||
|
||||
/* Interface Descriptor */
|
||||
0x09, /* bLength */
|
||||
0x04, /* bDescriptorType */
|
||||
0x00, /* bInterfaceNumber */
|
||||
0x00, /* bAlternateSetting */
|
||||
0x01, /* bNumEndpoints */
|
||||
0x02, /* bInterfaceClass - CDC - Communication */
|
||||
0x06, /* bInterfaceSubClass - ECM */
|
||||
0x00, /* bInterfaceProtocol - No class specific protocol required */
|
||||
0x00, /* iInterface */
|
||||
|
||||
/* CDC Header Functional Descriptor */
|
||||
0x05, /* bLength */
|
||||
0x24, /* bDescriptorType */
|
||||
0x00, /* bDescriptorSubType */
|
||||
0x10, 0x01, /* bcdCDC */
|
||||
|
||||
/* CDC ECM Functional Descriptor */
|
||||
0x0d, /* bLength */
|
||||
0x24, /* bDescriptorType */
|
||||
0x0f, /* bDescriptorSubType */
|
||||
0x04, /* iMACAddress */
|
||||
0x00, 0x00, 0x00, 0x00, /* bmEthernetStatistics */
|
||||
0xea, 0x05, /* wMaxSegmentSize */
|
||||
0x00, 0x00, /* wNumberMCFilters */
|
||||
0x00, /* bNumberPowerFilters */
|
||||
|
||||
/* CDC Union Functional Descriptor */
|
||||
0x05, /* bLength */
|
||||
0x24, /* bDescriptorType */
|
||||
0x06, /* bDescriptorSubType */
|
||||
0x00, /* bmMasterInterface */
|
||||
0x01, /* bmSlaveInterface0 */
|
||||
|
||||
/* Endpoint Descriptor */
|
||||
0x07, /* bLength */
|
||||
0x05, /* bDescriptorType */
|
||||
0x81, /* bEndpointAddress */
|
||||
0x03, /* bmAttributes - Interrupt */
|
||||
0x08, 0x00, /* wMaxPacketSize */
|
||||
0x08, /* bInterval */
|
||||
|
||||
/* Interface Descriptor */
|
||||
0x09, /* bLength */
|
||||
0x04, /* bDescriptorType */
|
||||
0x01, /* bInterfaceNumber */
|
||||
0x00, /* bAlternateSetting */
|
||||
0x00, /* bNumEndpoints */
|
||||
0x0a, /* bInterfaceClass - CDC - Data */
|
||||
0x00, /* bInterfaceSubClass - Should be 0x00 */
|
||||
0x00, /* bInterfaceProtocol - No class specific protocol required */
|
||||
0x00, /* iInterface */
|
||||
|
||||
/* Interface Descriptor */
|
||||
0x09, /* bLength */
|
||||
0x04, /* bDescriptorType */
|
||||
0x01, /* bInterfaceNumber */
|
||||
0x01, /* bAlternateSetting */
|
||||
0x04, /* bNumEndpoints */
|
||||
0x0a, /* bInterfaceClass - CDC - Data */
|
||||
0x00, /* bInterfaceSubClass - Should be 0x00 */
|
||||
0x00, /* bInterfaceProtocol - No class specific protocol required */
|
||||
0x00, /* iInterface */
|
||||
|
||||
/* Endpoint Descriptor */
|
||||
0x07, /* bLength */
|
||||
0x05, /* bDescriptorType */
|
||||
0x02, /* bEndpointAddress */
|
||||
0x03, /* bmAttributes - Interrupt */
|
||||
0x40, 0x00, /* wMaxPacketSize */
|
||||
0x01, /* bInterval */
|
||||
|
||||
/* Endpoint Descriptor */
|
||||
0x07, /* bLength */
|
||||
0x05, /* bDescriptorType */
|
||||
0x83, /* bEndpointAddress */
|
||||
0x03, /* bmAttributes - Interrupt */
|
||||
0x40, 0x00, /* wMaxPacketSize */
|
||||
0x01, /* bInterval */
|
||||
|
||||
/* Endpoint Descriptor */
|
||||
0x07, /* bLength */
|
||||
0x05, /* bDescriptorType */
|
||||
0x04, /* bEndpointAddress */
|
||||
0x02, /* bmAttributes - Bulk */
|
||||
0x40, 0x00, /* wMaxPacketSize */
|
||||
0x00, /* bInterval */
|
||||
|
||||
/* Endpoint Descriptor */
|
||||
0x07, /* bLength */
|
||||
0x05, /* bDescriptorType */
|
||||
0x85, /* bEndpointAddress */
|
||||
0x02, /* bmAttributes - Bulk */
|
||||
0x40, 0x00, /* wMaxPacketSize */
|
||||
0x00, /* bInterval */
|
||||
|
||||
};
|
||||
|
||||
static DEVICE_INIT_DATA device_init_data = {
|
||||
.framework = non_bulk_out_endpoint,
|
||||
.framework_length = sizeof(non_bulk_out_endpoint),
|
||||
.dont_register_hcd = 1,
|
||||
};
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_cdc_ecm_data_interface_non_bulk_out_and_non_bulk_in_endpoint_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running CDC-ECM Non Bulk Out and Non Bulk In Endpoint Test.......... ");
|
||||
|
||||
stepinfo("\n");
|
||||
|
||||
ux_test_cdc_ecm_initialize_use_framework(first_unused_memory, &device_init_data);
|
||||
}
|
||||
|
||||
static void post_init_host()
|
||||
{
|
||||
|
||||
/* Enumerate. */
|
||||
UX_TEST_CHECK_SUCCESS(ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize, 0, 0));
|
||||
|
||||
/* The HCD init function put()s the HCD semaphore, so we can do this here. */
|
||||
ux_test_wait_for_enum_thread_completion();
|
||||
}
|
||||
|
||||
static void post_init_device()
|
||||
{
|
||||
}
|
@ -0,0 +1,177 @@
|
||||
/* This tests the case where there is no bulk in endpoint in the CDC-ECM data
|
||||
interface. Host should report an error.
|
||||
|
||||
Unfortunately, the device fails during activation if we use the 'no bulk-in
|
||||
endpoint' descriptor, so we have the device use a correct descriptor, then
|
||||
force the host to receive the invalid descriptor when it sends the GetDescriptor
|
||||
request for the configuration descriptor. */
|
||||
|
||||
#include "usbx_ux_test_cdc_ecm.h"
|
||||
|
||||
static unsigned char no_bulk_in_endpoint_framework[] = {
|
||||
|
||||
/* Configuration Descriptor */
|
||||
0x09, /* bLength */
|
||||
0x02, /* bDescriptorType */
|
||||
0x58, 0x00, /* wTotalLength */
|
||||
0x02, /* bNumInterfaces */
|
||||
0x01, /* bConfigurationValue */
|
||||
0x00, /* iConfiguration */
|
||||
0xc0, /* bmAttributes - Self-powered */
|
||||
0x00, /* bMaxPower */
|
||||
|
||||
/* Interface Association Descriptor */
|
||||
0x08, /* bLength */
|
||||
0x0b, /* bDescriptorType */
|
||||
0x00, /* bFirstInterface */
|
||||
0x02, /* bInterfaceCount */
|
||||
0x02, /* bFunctionClass - CDC - Communication */
|
||||
0x06, /* bFunctionSubClass - ECM */
|
||||
0x00, /* bFunctionProtocol - No class specific protocol required */
|
||||
0x00, /* iFunction */
|
||||
|
||||
/* Interface Descriptor */
|
||||
0x09, /* bLength */
|
||||
0x04, /* bDescriptorType */
|
||||
0x00, /* bInterfaceNumber */
|
||||
0x00, /* bAlternateSetting */
|
||||
0x01, /* bNumEndpoints */
|
||||
0x02, /* bInterfaceClass - CDC - Communication */
|
||||
0x06, /* bInterfaceSubClass - ECM */
|
||||
0x00, /* bInterfaceProtocol - No class specific protocol required */
|
||||
0x00, /* iInterface */
|
||||
|
||||
/* CDC Header Functional Descriptor */
|
||||
0x05, /* bLength */
|
||||
0x24, /* bDescriptorType */
|
||||
0x00, /* bDescriptorSubType */
|
||||
0x10, 0x01, /* bcdCDC */
|
||||
|
||||
/* CDC ECM Functional Descriptor */
|
||||
0x0d, /* bLength */
|
||||
0x24, /* bDescriptorType */
|
||||
0x0f, /* bDescriptorSubType */
|
||||
0x04, /* iMACAddress */
|
||||
0x00, 0x00, 0x00, 0x00, /* bmEthernetStatistics */
|
||||
0xea, 0x05, /* wMaxSegmentSize */
|
||||
0x00, 0x00, /* wNumberMCFilters */
|
||||
0x00, /* bNumberPowerFilters */
|
||||
|
||||
/* CDC Union Functional Descriptor */
|
||||
0x05, /* bLength */
|
||||
0x24, /* bDescriptorType */
|
||||
0x06, /* bDescriptorSubType */
|
||||
0x00, /* bmMasterInterface */
|
||||
0x01, /* bmSlaveInterface0 */
|
||||
|
||||
/* Endpoint Descriptor */
|
||||
0x07, /* bLength */
|
||||
0x05, /* bDescriptorType */
|
||||
0x83, /* bEndpointAddress */
|
||||
0x03, /* bmAttributes - Interrupt */
|
||||
0x08, 0x00, /* wMaxPacketSize */
|
||||
0x08, /* bInterval */
|
||||
|
||||
/* Interface Descriptor */
|
||||
0x09, /* bLength */
|
||||
0x04, /* bDescriptorType */
|
||||
0x01, /* bInterfaceNumber */
|
||||
0x00, /* bAlternateSetting */
|
||||
0x00, /* bNumEndpoints */
|
||||
0x0a, /* bInterfaceClass - CDC - Data */
|
||||
0x00, /* bInterfaceSubClass - Should be 0x00 */
|
||||
0x00, /* bInterfaceProtocol - No class specific protocol required */
|
||||
0x00, /* iInterface */
|
||||
|
||||
/* Interface Descriptor */
|
||||
0x09, /* bLength */
|
||||
0x04, /* bDescriptorType */
|
||||
0x01, /* bInterfaceNumber */
|
||||
0x01, /* bAlternateSetting */
|
||||
0x02, /* bNumEndpoints */
|
||||
0x0a, /* bInterfaceClass - CDC - Data */
|
||||
0x00, /* bInterfaceSubClass - Should be 0x00 */
|
||||
0x00, /* bInterfaceProtocol - No class specific protocol required */
|
||||
0x00, /* iInterface */
|
||||
|
||||
/* We use two bulk-out endpoints so that the lengths are the same (makes things easier). */
|
||||
|
||||
/* Endpoint Descriptor */
|
||||
0x07, /* bLength */
|
||||
0x05, /* bDescriptorType */
|
||||
0x02, /* bEndpointAddress */
|
||||
0x02, /* bmAttributes - Bulk */
|
||||
0x40, 0x00, /* wMaxPacketSize */
|
||||
0x00, /* bInterval */
|
||||
|
||||
/* Endpoint Descriptor */
|
||||
0x07, /* bLength */
|
||||
0x05, /* bDescriptorType */
|
||||
0x01, /* bEndpointAddress */
|
||||
0x02, /* bmAttributes - Bulk */
|
||||
0x40, 0x00, /* wMaxPacketSize */
|
||||
0x00, /* bInterval */
|
||||
|
||||
};
|
||||
|
||||
static DEVICE_INIT_DATA device_init_data = {
|
||||
.framework = default_device_framework,
|
||||
.framework_length = sizeof(default_device_framework),
|
||||
.dont_register_hcd = 1,
|
||||
};
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_cdc_ecm_data_interface_no_bulk_in_endpoint_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running CDC-ECM No Bulk In Endpiont Test............................ ");
|
||||
|
||||
stepinfo("\n");
|
||||
|
||||
ux_test_cdc_ecm_initialize_use_framework(first_unused_memory, &device_init_data);
|
||||
}
|
||||
|
||||
static void post_init_host()
|
||||
{
|
||||
|
||||
int i;
|
||||
|
||||
/* We need to intercept the configuration descriptor. */
|
||||
UX_TEST_ACTION change_config_desc_action = {0};
|
||||
change_config_desc_action.usbx_function = UX_TEST_OVERRIDE_UX_HCD_SIM_HOST_ENTRY;
|
||||
change_config_desc_action.function = UX_HCD_TRANSFER_REQUEST;
|
||||
change_config_desc_action.req_action = UX_TEST_MATCH_REQ_LEN | UX_TEST_SIM_REQ_ANSWER;
|
||||
change_config_desc_action.req_requested_len = 0x58; /* Length of config descriptor. */
|
||||
change_config_desc_action.req_data = no_bulk_in_endpoint_framework;
|
||||
change_config_desc_action.req_actual_len = sizeof(no_bulk_in_endpoint_framework);
|
||||
change_config_desc_action.req_status = UX_SUCCESS;
|
||||
change_config_desc_action.do_after = 0;
|
||||
change_config_desc_action.no_return = 0;
|
||||
|
||||
/* We expect this to fail multiple times since enumeration tries multiple times. */
|
||||
for (i = 0; i < UX_RH_ENUMERATION_RETRY; i++)
|
||||
{
|
||||
ux_test_add_action_to_main_list(change_config_desc_action);
|
||||
ux_test_add_action_to_main_list(create_error_match_action(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_ENDPOINT_HANDLE_UNKNOWN));
|
||||
}
|
||||
ux_test_add_action_to_main_list(create_error_match_action(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_ROOT_HUB, UX_DEVICE_ENUMERATION_FAILURE));
|
||||
|
||||
/* Enumerate. */
|
||||
UX_TEST_CHECK_SUCCESS(ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize, 0, 0));
|
||||
|
||||
/* The HCD init function put()s the HCD semaphore, so we can do this here. */
|
||||
ux_test_wait_for_enum_thread_completion();
|
||||
|
||||
/* Enumeration should've failed. */
|
||||
UX_TEST_ASSERT(ux_test_check_actions_empty());
|
||||
UX_TEST_ASSERT(cdc_ecm_host_from_system_change_function == UX_NULL);
|
||||
}
|
||||
|
||||
static void post_init_device()
|
||||
{
|
||||
}
|
@ -0,0 +1,177 @@
|
||||
/* This tests the case where there is no bulk out endpoint in the CDC-ECM data
|
||||
interface. Host should report an error.
|
||||
|
||||
Unfortunately, the device fails during activation if we use the 'no bulk-out
|
||||
endpoint' descriptor, so we have the device use a correct descriptor, then
|
||||
force the host to receive the invalid descriptor when it sends the GetDescriptor
|
||||
request for the configuration descriptor. */
|
||||
|
||||
#include "usbx_ux_test_cdc_ecm.h"
|
||||
|
||||
static unsigned char no_bulk_out_endpoint_framework[] = {
|
||||
|
||||
/* Configuration Descriptor */
|
||||
0x09, /* bLength */
|
||||
0x02, /* bDescriptorType */
|
||||
0x58, 0x00, /* wTotalLength */
|
||||
0x02, /* bNumInterfaces */
|
||||
0x01, /* bConfigurationValue */
|
||||
0x00, /* iConfiguration */
|
||||
0xc0, /* bmAttributes - Self-powered */
|
||||
0x00, /* bMaxPower */
|
||||
|
||||
/* Interface Association Descriptor */
|
||||
0x08, /* bLength */
|
||||
0x0b, /* bDescriptorType */
|
||||
0x00, /* bFirstInterface */
|
||||
0x02, /* bInterfaceCount */
|
||||
0x02, /* bFunctionClass - CDC - Communication */
|
||||
0x06, /* bFunctionSubClass - ECM */
|
||||
0x00, /* bFunctionProtocol - No class specific protocol required */
|
||||
0x00, /* iFunction */
|
||||
|
||||
/* Interface Descriptor */
|
||||
0x09, /* bLength */
|
||||
0x04, /* bDescriptorType */
|
||||
0x00, /* bInterfaceNumber */
|
||||
0x00, /* bAlternateSetting */
|
||||
0x01, /* bNumEndpoints */
|
||||
0x02, /* bInterfaceClass - CDC - Communication */
|
||||
0x06, /* bInterfaceSubClass - ECM */
|
||||
0x00, /* bInterfaceProtocol - No class specific protocol required */
|
||||
0x00, /* iInterface */
|
||||
|
||||
/* CDC Header Functional Descriptor */
|
||||
0x05, /* bLength */
|
||||
0x24, /* bDescriptorType */
|
||||
0x00, /* bDescriptorSubType */
|
||||
0x10, 0x01, /* bcdCDC */
|
||||
|
||||
/* CDC ECM Functional Descriptor */
|
||||
0x0d, /* bLength */
|
||||
0x24, /* bDescriptorType */
|
||||
0x0f, /* bDescriptorSubType */
|
||||
0x04, /* iMACAddress */
|
||||
0x00, 0x00, 0x00, 0x00, /* bmEthernetStatistics */
|
||||
0xea, 0x05, /* wMaxSegmentSize */
|
||||
0x00, 0x00, /* wNumberMCFilters */
|
||||
0x00, /* bNumberPowerFilters */
|
||||
|
||||
/* CDC Union Functional Descriptor */
|
||||
0x05, /* bLength */
|
||||
0x24, /* bDescriptorType */
|
||||
0x06, /* bDescriptorSubType */
|
||||
0x00, /* bmMasterInterface */
|
||||
0x01, /* bmSlaveInterface0 */
|
||||
|
||||
/* Endpoint Descriptor */
|
||||
0x07, /* bLength */
|
||||
0x05, /* bDescriptorType */
|
||||
0x83, /* bEndpointAddress */
|
||||
0x03, /* bmAttributes - Interrupt */
|
||||
0x08, 0x00, /* wMaxPacketSize */
|
||||
0x08, /* bInterval */
|
||||
|
||||
/* Interface Descriptor */
|
||||
0x09, /* bLength */
|
||||
0x04, /* bDescriptorType */
|
||||
0x01, /* bInterfaceNumber */
|
||||
0x00, /* bAlternateSetting */
|
||||
0x00, /* bNumEndpoints */
|
||||
0x0a, /* bInterfaceClass - CDC - Data */
|
||||
0x00, /* bInterfaceSubClass - Should be 0x00 */
|
||||
0x00, /* bInterfaceProtocol - No class specific protocol required */
|
||||
0x00, /* iInterface */
|
||||
|
||||
/* Interface Descriptor */
|
||||
0x09, /* bLength */
|
||||
0x04, /* bDescriptorType */
|
||||
0x01, /* bInterfaceNumber */
|
||||
0x01, /* bAlternateSetting */
|
||||
0x02, /* bNumEndpoints */
|
||||
0x0a, /* bInterfaceClass - CDC - Data */
|
||||
0x00, /* bInterfaceSubClass - Should be 0x00 */
|
||||
0x00, /* bInterfaceProtocol - No class specific protocol required */
|
||||
0x00, /* iInterface */
|
||||
|
||||
/* We use two bulk-in endpoints so that the lengths are the same (makes things easier). */
|
||||
|
||||
/* Endpoint Descriptor */
|
||||
0x07, /* bLength */
|
||||
0x05, /* bDescriptorType */
|
||||
0x82, /* bEndpointAddress */
|
||||
0x02, /* bmAttributes - Bulk */
|
||||
0x40, 0x00, /* wMaxPacketSize */
|
||||
0x00, /* bInterval */
|
||||
|
||||
/* Endpoint Descriptor */
|
||||
0x07, /* bLength */
|
||||
0x05, /* bDescriptorType */
|
||||
0x81, /* bEndpointAddress */
|
||||
0x02, /* bmAttributes - Bulk */
|
||||
0x40, 0x00, /* wMaxPacketSize */
|
||||
0x00, /* bInterval */
|
||||
|
||||
};
|
||||
|
||||
static DEVICE_INIT_DATA device_init_data = {
|
||||
.framework = default_device_framework,
|
||||
.framework_length = sizeof(default_device_framework),
|
||||
.dont_register_hcd = 1,
|
||||
};
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_cdc_ecm_data_interface_no_bulk_out_endpoint_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running CDC-ECM No Bulk Out Endpoint Test........................... ");
|
||||
|
||||
stepinfo("\n");
|
||||
|
||||
ux_test_cdc_ecm_initialize_use_framework(first_unused_memory, &device_init_data);
|
||||
}
|
||||
|
||||
static void post_init_host()
|
||||
{
|
||||
|
||||
int i;
|
||||
|
||||
/* We need to intercept the configuration descriptor. */
|
||||
UX_TEST_ACTION change_config_desc_action = {0};
|
||||
change_config_desc_action.usbx_function = UX_TEST_OVERRIDE_UX_HCD_SIM_HOST_ENTRY;
|
||||
change_config_desc_action.function = UX_HCD_TRANSFER_REQUEST;
|
||||
change_config_desc_action.req_action = UX_TEST_MATCH_REQ_LEN | UX_TEST_SIM_REQ_ANSWER;
|
||||
change_config_desc_action.req_requested_len = 0x58; /* Length of config descriptor. */
|
||||
change_config_desc_action.req_data = no_bulk_out_endpoint_framework;
|
||||
change_config_desc_action.req_actual_len = sizeof(no_bulk_out_endpoint_framework);
|
||||
change_config_desc_action.req_status = UX_SUCCESS;
|
||||
change_config_desc_action.do_after = 0;
|
||||
change_config_desc_action.no_return = 0;
|
||||
|
||||
/* We expect this to fail multiple times since enumeration tries multiple times. */
|
||||
for (i = 0; i < UX_RH_ENUMERATION_RETRY; i++)
|
||||
{
|
||||
ux_test_add_action_to_main_list(change_config_desc_action);
|
||||
ux_test_add_action_to_main_list(create_error_match_action(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_ENDPOINT_HANDLE_UNKNOWN));
|
||||
}
|
||||
ux_test_add_action_to_main_list(create_error_match_action(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_ROOT_HUB, UX_DEVICE_ENUMERATION_FAILURE));
|
||||
|
||||
/* Enumerate. */
|
||||
UX_TEST_CHECK_SUCCESS(ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize, 0, 0));
|
||||
|
||||
/* The HCD init function put()s the HCD semaphore, so we can do this here. */
|
||||
ux_test_wait_for_enum_thread_completion();
|
||||
|
||||
/* Enumeration should've failed. */
|
||||
UX_TEST_ASSERT(ux_test_check_actions_empty());
|
||||
UX_TEST_ASSERT(cdc_ecm_host_from_system_change_function == UX_NULL);
|
||||
}
|
||||
|
||||
static void post_init_device()
|
||||
{
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
/* This tests the case where the setting the data interface with endpoints fails. */
|
||||
|
||||
#include "usbx_ux_test_cdc_ecm.h"
|
||||
|
||||
static DEVICE_INIT_DATA device_init_data = {
|
||||
.framework = default_device_framework,
|
||||
.framework_length = sizeof(default_device_framework),
|
||||
.dont_register_hcd = 1,
|
||||
};
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_cdc_ecm_data_interface_setting_select_fails_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Data Interface Setting Select Fails Test.................... ");
|
||||
|
||||
stepinfo("\n");
|
||||
|
||||
ux_test_cdc_ecm_initialize_use_framework(first_unused_memory, &device_init_data);
|
||||
}
|
||||
|
||||
static void post_init_host()
|
||||
{
|
||||
|
||||
int i;
|
||||
|
||||
#if 0
|
||||
/* Create a transfer_request for the SET_INTERFACE request. No data for this request */
|
||||
transfer_request -> ux_transfer_request_requested_length = 0;
|
||||
transfer_request -> ux_transfer_request_function = UX_SET_INTERFACE;
|
||||
transfer_request -> ux_transfer_request_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_INTERFACE;
|
||||
transfer_request -> ux_transfer_request_index = (USHORT) interface -> ux_interface_descriptor.bInterfaceNumber;
|
||||
transfer_request -> ux_transfer_request_value = (USHORT) interface -> ux_interface_descriptor.bAlternateSetting;
|
||||
#endif
|
||||
|
||||
UX_TEST_SETUP alternate_setting_set_setup;
|
||||
alternate_setting_set_setup.ux_test_setup_type = UX_REQUEST_OUT | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_INTERFACE;
|
||||
alternate_setting_set_setup.ux_test_setup_request = UX_SET_INTERFACE;
|
||||
alternate_setting_set_setup.ux_test_setup_value = 1; /* Alternate Setting */
|
||||
alternate_setting_set_setup.ux_test_setup_index = 1; /* Interface (data is 1) */
|
||||
|
||||
/* We need to intercept the configuration descriptor. */
|
||||
UX_TEST_ACTION alternate_setting_fail_action = {0};
|
||||
alternate_setting_fail_action.usbx_function = UX_TEST_OVERRIDE_UX_HCD_SIM_HOST_ENTRY;
|
||||
alternate_setting_fail_action.function = UX_HCD_TRANSFER_REQUEST;
|
||||
alternate_setting_fail_action.req_action = UX_TEST_SETUP_MATCH_REQUEST;
|
||||
alternate_setting_fail_action.req_setup = &alternate_setting_set_setup;
|
||||
alternate_setting_fail_action.status = UX_ERROR;
|
||||
alternate_setting_fail_action.no_return = 0;
|
||||
|
||||
/* We expect this to fail multiple times since enumeration tries multiple times. */
|
||||
for (i = 0; i < UX_RH_ENUMERATION_RETRY; i++)
|
||||
{
|
||||
ux_test_add_action_to_main_list(alternate_setting_fail_action);
|
||||
}
|
||||
ux_test_add_action_to_main_list(create_error_match_action(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_ROOT_HUB, UX_DEVICE_ENUMERATION_FAILURE));
|
||||
|
||||
/* Enumerate. */
|
||||
UX_TEST_CHECK_SUCCESS(ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize, 0, 0));
|
||||
|
||||
/* The HCD init function put()s the HCD semaphore, so we can do this here. */
|
||||
ux_test_wait_for_enum_thread_completion();
|
||||
|
||||
/* Enumeration should've failed. */
|
||||
UX_TEST_ASSERT(ux_test_check_actions_empty());
|
||||
UX_TEST_ASSERT(cdc_ecm_host_from_system_change_function == UX_NULL);
|
||||
}
|
||||
|
||||
static void post_init_device()
|
||||
{
|
||||
}
|
@ -0,0 +1,149 @@
|
||||
/* This tests the case where the default data interface has endpoints - note that
|
||||
this is a violation of the specification since according to it, the default
|
||||
data interface should have 0 endpoints, however, our host supports it since
|
||||
so many devices violate the spec! */
|
||||
|
||||
#include "usbx_ux_test_cdc_ecm.h"
|
||||
|
||||
static unsigned char device_framework_high_speed_default_data_interface_with_endpoints[] = {
|
||||
|
||||
/* Device Descriptor */
|
||||
0x12, /* bLength */
|
||||
0x01, /* bDescriptorType */
|
||||
0x10, 0x01, /* bcdUSB */
|
||||
0xef, /* bDeviceClass - Depends on bDeviceSubClass */
|
||||
0x02, /* bDeviceSubClass - Depends on bDeviceProtocol */
|
||||
0x01, /* bDeviceProtocol - There's an IAD */
|
||||
0x40, /* bMaxPacketSize0 */
|
||||
0x70, 0x07, /* idVendor */
|
||||
0x42, 0x10, /* idProduct */
|
||||
0x00, 0x01, /* bcdDevice */
|
||||
0x01, /* iManufacturer */
|
||||
0x02, /* iProduct */
|
||||
0x03, /* iSerialNumber */
|
||||
0x01, /* bNumConfigurations */
|
||||
|
||||
/* Configuration Descriptor */
|
||||
0x09, /* bLength */
|
||||
0x02, /* bDescriptorType */
|
||||
0x4f, 0x00, /* wTotalLength */
|
||||
0x02, /* bNumInterfaces */
|
||||
0x01, /* bConfigurationValue */
|
||||
0x00, /* iConfiguration */
|
||||
0xc0, /* bmAttributes - Self-powered */
|
||||
0x00, /* bMaxPower */
|
||||
|
||||
/* Interface Association Descriptor */
|
||||
0x08, /* bLength */
|
||||
0x0b, /* bDescriptorType */
|
||||
0x00, /* bFirstInterface */
|
||||
0x02, /* bInterfaceCount */
|
||||
0x02, /* bFunctionClass - CDC - Communication */
|
||||
0x06, /* bFunctionSubClass - ECM */
|
||||
0x00, /* bFunctionProtocol - No class specific protocol required */
|
||||
0x00, /* iFunction */
|
||||
|
||||
/* Interface Descriptor */
|
||||
0x09, /* bLength */
|
||||
0x04, /* bDescriptorType */
|
||||
0x00, /* bInterfaceNumber */
|
||||
0x00, /* bAlternateSetting */
|
||||
0x01, /* bNumEndpoints */
|
||||
0x02, /* bInterfaceClass - CDC - Communication */
|
||||
0x06, /* bInterfaceSubClass - ECM */
|
||||
0x00, /* bInterfaceProtocol - No class specific protocol required */
|
||||
0x00, /* iInterface */
|
||||
|
||||
/* CDC Header Functional Descriptor */
|
||||
0x05, /* bLength */
|
||||
0x24, /* bDescriptorType */
|
||||
0x00, /* bDescriptorSubType */
|
||||
0x10, 0x01, /* bcdCDC */
|
||||
|
||||
/* CDC ECM Functional Descriptor */
|
||||
0x0d, /* bLength */
|
||||
0x24, /* bDescriptorType */
|
||||
0x0f, /* bDescriptorSubType */
|
||||
0x04, /* iMACAddress */
|
||||
0x00, 0x00, 0x00, 0x00, /* bmEthernetStatistics */
|
||||
0xea, 0x05, /* wMaxSegmentSize */
|
||||
0x00, 0x00, /* wNumberMCFilters */
|
||||
0x00, /* bNumberPowerFilters */
|
||||
|
||||
/* CDC Union Functional Descriptor */
|
||||
0x05, /* bLength */
|
||||
0x24, /* bDescriptorType */
|
||||
0x06, /* bDescriptorSubType */
|
||||
0x00, /* bmMasterInterface */
|
||||
0x01, /* bmSlaveInterface0 */
|
||||
|
||||
/* Endpoint Descriptor */
|
||||
0x07, /* bLength */
|
||||
0x05, /* bDescriptorType */
|
||||
0x83, /* bEndpointAddress */
|
||||
0x03, /* bmAttributes - Interrupt */
|
||||
0x08, 0x00, /* wMaxPacketSize */
|
||||
0x08, /* bInterval */
|
||||
|
||||
/* Interface Descriptor */
|
||||
0x09, /* bLength */
|
||||
0x04, /* bDescriptorType */
|
||||
0x01, /* bInterfaceNumber */
|
||||
0x00, /* bAlternateSetting */
|
||||
0x02, /* bNumEndpoints */
|
||||
0x0a, /* bInterfaceClass - CDC - Data */
|
||||
0x00, /* bInterfaceSubClass - Should be 0x00 */
|
||||
0x00, /* bInterfaceProtocol - No class specific protocol required */
|
||||
0x00, /* iInterface */
|
||||
|
||||
/* Endpoint Descriptor */
|
||||
0x07, /* bLength */
|
||||
0x05, /* bDescriptorType */
|
||||
0x02, /* bEndpointAddress */
|
||||
0x02, /* bmAttributes - Bulk */
|
||||
0x40, 0x00, /* wMaxPacketSize */
|
||||
0x00, /* bInterval */
|
||||
|
||||
/* Endpoint Descriptor */
|
||||
0x07, /* bLength */
|
||||
0x05, /* bDescriptorType */
|
||||
0x81, /* bEndpointAddress */
|
||||
0x02, /* bmAttributes - Bulk */
|
||||
0x40, 0x00, /* wMaxPacketSize */
|
||||
0x00, /* bInterval */
|
||||
|
||||
};
|
||||
|
||||
static DEVICE_INIT_DATA device_init_data = {
|
||||
.framework = device_framework_high_speed_default_data_interface_with_endpoints,
|
||||
.framework_length = sizeof(device_framework_high_speed_default_data_interface_with_endpoints),
|
||||
.dont_register_hcd = 0,
|
||||
};
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_cdc_ecm_default_data_interface_with_endpoints_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running CDC-ECM default data interface with endpoints Test.......... ");
|
||||
|
||||
stepinfo("\n");
|
||||
|
||||
ux_test_cdc_ecm_initialize_use_framework(first_unused_memory, &device_init_data);
|
||||
}
|
||||
|
||||
static void post_init_host()
|
||||
{
|
||||
|
||||
cdc_ecm_basic_test(BASIC_TEST_HOST, BASIC_TEST_TCP);
|
||||
}
|
||||
|
||||
static void post_init_device()
|
||||
{
|
||||
|
||||
cdc_ecm_basic_test(BASIC_TEST_DEVICE, BASIC_TEST_TCP);
|
||||
}
|
53
test/regression/usbx_cdc_ecm_disconnect_and_reconnect_test.c
Normal file
53
test/regression/usbx_cdc_ecm_disconnect_and_reconnect_test.c
Normal file
@ -0,0 +1,53 @@
|
||||
/* This test ensures everything works after a disconnection and reconnection. */
|
||||
|
||||
#include "usbx_ux_test_cdc_ecm.h"
|
||||
|
||||
static UCHAR host_ready_for_test_after_reconnection;
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_cdc_ecm_disconnect_and_reconnect_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running CDC-ECM Disconnect And Reconnect Test....................... ");
|
||||
|
||||
stepinfo("\n");
|
||||
|
||||
ux_test_cdc_ecm_initialize(first_unused_memory);
|
||||
}
|
||||
|
||||
static void post_init_host()
|
||||
{
|
||||
|
||||
cdc_ecm_basic_test(BASIC_TEST_HOST, BASIC_TEST_TCP);
|
||||
|
||||
/* Now disconnect. */
|
||||
ux_test_disconnect_host_wait_for_enum_completion();
|
||||
|
||||
/* Now reconnect. */
|
||||
ux_test_connect_host_wait_for_enum_completion();
|
||||
|
||||
/* Get class instance. */
|
||||
class_cdc_ecm_get_host();
|
||||
|
||||
/* Tell device we're ready. */
|
||||
host_ready_for_test_after_reconnection = 1;
|
||||
|
||||
/* Now run the basic test again. */
|
||||
cdc_ecm_basic_test(BASIC_TEST_HOST, BASIC_TEST_TCP);
|
||||
}
|
||||
|
||||
static void post_init_device()
|
||||
{
|
||||
|
||||
cdc_ecm_basic_test(BASIC_TEST_DEVICE, BASIC_TEST_TCP);
|
||||
|
||||
/* Now wait for the host to tell us to run the test again. */
|
||||
UX_TEST_CHECK_SUCCESS(ux_test_wait_for_value_uchar(&host_ready_for_test_after_reconnection, 1));
|
||||
|
||||
cdc_ecm_basic_test(BASIC_TEST_DEVICE, BASIC_TEST_TCP);
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
/* This tests the case where the bulk in semaphore at the class level creation
|
||||
fails. */
|
||||
|
||||
#include "usbx_ux_test_cdc_ecm.h"
|
||||
|
||||
static DEVICE_INIT_DATA device_init_data = {
|
||||
.framework = default_device_framework,
|
||||
.framework_length = sizeof(default_device_framework),
|
||||
.dont_register_hcd = 1,
|
||||
};
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_cdc_ecm_host_bulk_in_semaphore_create_fail_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running CDC-ECM Host Bulk In Semaphore Create Fail Test............. ");
|
||||
|
||||
stepinfo("\n");
|
||||
|
||||
ux_test_cdc_ecm_initialize_use_framework(first_unused_memory, &device_init_data);
|
||||
}
|
||||
|
||||
static void post_init_host()
|
||||
{
|
||||
|
||||
int i;
|
||||
|
||||
UX_TEST_ACTION semaphore_create_fail_action = {0};
|
||||
semaphore_create_fail_action.usbx_function = UX_TEST_OVERRIDE_TX_SEMAPHORE_CREATE;
|
||||
semaphore_create_fail_action.semaphore_name = "host CDC-ECM bulk in wait semaphore";
|
||||
semaphore_create_fail_action.no_return = 0;
|
||||
semaphore_create_fail_action.status = UX_ERROR;
|
||||
|
||||
for (i = 0; i < UX_RH_ENUMERATION_RETRY; i++)
|
||||
{
|
||||
ux_test_add_action_to_main_list(semaphore_create_fail_action);
|
||||
ux_test_add_action_to_main_list(create_error_match_action(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_UTILITY, UX_ERROR));
|
||||
}
|
||||
ux_test_add_action_to_main_list(create_error_match_action(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_ROOT_HUB, UX_DEVICE_ENUMERATION_FAILURE));
|
||||
|
||||
/* Enumerate. */
|
||||
UX_TEST_CHECK_SUCCESS(ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize, 0, 0));
|
||||
|
||||
/* The HCD init function put()s the HCD semaphore, so we can do this here. */
|
||||
ux_test_wait_for_enum_thread_completion();
|
||||
|
||||
UX_TEST_ASSERT(ux_test_check_actions_empty());
|
||||
UX_TEST_ASSERT(cdc_ecm_host_from_system_change_function == UX_NULL);
|
||||
}
|
||||
|
||||
static void post_init_device()
|
||||
{
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
/* This tests the case where there is an ongoing transfer on the bulk in endpoint
|
||||
during deactivation. The deactivate routine should wait for it to finish.
|
||||
|
||||
We do this by having the CDC-ECM thread suspend during the transfer arm,
|
||||
and then begin deactivation. We resume the CDC-ECM thread later! */
|
||||
|
||||
#include "usbx_ux_test_cdc_ecm.h"
|
||||
|
||||
static UCHAR cdc_ecm_thread_suspended;
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_cdc_ecm_host_bulk_in_transfer_arming_during_deactivate_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running CDC-ECM Host Bulk In Transfer Arming During... Test......... ");
|
||||
|
||||
stepinfo("\n");
|
||||
|
||||
ux_test_cdc_ecm_initialize(first_unused_memory);
|
||||
}
|
||||
|
||||
static VOID suspend_cdc_ecm_thread_action_func(UX_TEST_ACTION *action, VOID *params)
|
||||
{
|
||||
|
||||
/* The CDC-ECM thread is calling us. */
|
||||
|
||||
/* Notify test thread. */
|
||||
cdc_ecm_thread_suspended = 1;
|
||||
|
||||
/* Suspend. Test thread should wake us back up. */
|
||||
tx_thread_suspend(tx_thread_identify());
|
||||
}
|
||||
|
||||
static void post_init_host()
|
||||
{
|
||||
|
||||
/* Right now, host CDC-ECM thread is waiting for a bulk in transfer. We
|
||||
need for it to re-do a transfer so that we can get it to suspend via our
|
||||
action. First, we need to create and add our actions. */
|
||||
UX_TEST_ACTION bulk_in_transfer_suspend_action = {0};
|
||||
bulk_in_transfer_suspend_action.usbx_function = UX_TEST_OVERRIDE_UX_HCD_SIM_HOST_ENTRY;
|
||||
bulk_in_transfer_suspend_action.function = UX_HCD_TRANSFER_REQUEST;
|
||||
bulk_in_transfer_suspend_action.req_action = UX_TEST_MATCH_EP;
|
||||
bulk_in_transfer_suspend_action.req_ep_address = 0x81;
|
||||
bulk_in_transfer_suspend_action.action_func = suspend_cdc_ecm_thread_action_func;
|
||||
bulk_in_transfer_suspend_action.no_return = 1;
|
||||
ux_test_add_action_to_main_list(bulk_in_transfer_suspend_action);
|
||||
|
||||
/* Now have the CDC-ECM thread re-do the transfer. */
|
||||
write_packet_tcp(&tcp_socket_device, &packet_pool_device, 1, "device");
|
||||
|
||||
/* Wait for CDC-ECM thread to stall. */
|
||||
UX_TEST_CHECK_SUCCESS(ux_test_wait_for_value_uchar(&cdc_ecm_thread_suspended, 1));
|
||||
|
||||
/* Just for the hell of it, null out the system change function so we can hit that case too. */
|
||||
_ux_system_host->ux_system_host_change_function = UX_NULL;
|
||||
|
||||
/* Now disconnect the host. */
|
||||
ux_test_disconnect_host_no_wait();
|
||||
|
||||
/* Now wait for deactivation to suspend, waiting for bulk in to finish. */
|
||||
UX_TEST_CHECK_SUCCESS(ux_test_wait_for_value_uchar(&cdc_ecm_host -> ux_host_class_cdc_ecm_bulk_in_transfer_waiting_for_check_and_arm_to_finish, UX_TRUE));
|
||||
|
||||
/* Now resume the CDC-ECM thread. */
|
||||
tx_thread_resume(&cdc_ecm_host->ux_host_class_cdc_ecm_thread);
|
||||
|
||||
/* And now wait for deactivation to complete. */
|
||||
ux_test_wait_for_enum_thread_completion();
|
||||
|
||||
/* And now wait for... wait a second, we're done! Smiley face! That was easier than I thought! I'M SO FRICKEN HAPPY RIGHT NOWWWWWW! */
|
||||
}
|
||||
|
||||
static void post_init_device()
|
||||
{
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
/* This tests the case where there is an ongoing transfer on the bulk in endpoint
|
||||
during link down. The interrupt notification function should wait for it to finish.
|
||||
|
||||
We do this by having the CDC-ECM thread suspend during the transfer arm,
|
||||
and then begin link down event. We resume the HCD thread later! */
|
||||
|
||||
#include "usbx_ux_test_cdc_ecm.h"
|
||||
|
||||
static UCHAR cdc_ecm_thread_suspended;
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_cdc_ecm_host_bulk_in_transfer_arming_during_link_down_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running CDC-ECM Host Bulk In Transfer Arming During... Test......... ");
|
||||
|
||||
stepinfo("\n");
|
||||
|
||||
ux_test_cdc_ecm_initialize(first_unused_memory);
|
||||
}
|
||||
|
||||
static VOID suspend_cdc_ecm_thread_action_func(UX_TEST_ACTION *action, VOID *params)
|
||||
{
|
||||
|
||||
/* The CDC-ECM thread is calling us. */
|
||||
|
||||
/* Notify test thread. */
|
||||
cdc_ecm_thread_suspended = 1;
|
||||
|
||||
/* Suspend. Test thread should wake us back up. */
|
||||
tx_thread_suspend(tx_thread_identify());
|
||||
}
|
||||
|
||||
static void post_init_host()
|
||||
{
|
||||
|
||||
/* Right now, host CDC-ECM thread is waiting for a bulk in transfer. We
|
||||
need for it to re-do a transfer so that we can get it to suspend via our
|
||||
action. First, we need to create and add our actions. */
|
||||
UX_TEST_ACTION bulk_in_transfer_suspend_action = {0};
|
||||
bulk_in_transfer_suspend_action.usbx_function = UX_TEST_OVERRIDE_UX_HCD_SIM_HOST_ENTRY;
|
||||
bulk_in_transfer_suspend_action.function = UX_HCD_TRANSFER_REQUEST;
|
||||
bulk_in_transfer_suspend_action.req_action = UX_TEST_MATCH_EP;
|
||||
bulk_in_transfer_suspend_action.req_ep_address = 0x81;
|
||||
bulk_in_transfer_suspend_action.action_func = suspend_cdc_ecm_thread_action_func;
|
||||
bulk_in_transfer_suspend_action.no_return = 1;
|
||||
ux_test_add_action_to_main_list(bulk_in_transfer_suspend_action);
|
||||
|
||||
/* Now have the CDC-ECM thread re-do the transfer. */
|
||||
write_packet_tcp(&tcp_socket_device, &packet_pool_device, 1, "device");
|
||||
|
||||
/* Wait for CDC-ECM thread to stall. */
|
||||
UX_TEST_CHECK_SUCCESS(ux_test_wait_for_value_uchar(&cdc_ecm_thread_suspended, 1));
|
||||
|
||||
/* Just for the hell of it, null out the system change function so we can hit that case too. */
|
||||
_ux_system_host->ux_system_host_change_function = UX_NULL;
|
||||
|
||||
/* Now change the link to down. */
|
||||
ux_test_device_class_cdc_ecm_set_link_state(cdc_ecm_device, 0);
|
||||
|
||||
/* Now wait for interrupt notification function (AKA hcd thread) to suspend, waiting for bulk in to finish. */
|
||||
UX_TEST_CHECK_SUCCESS(ux_test_wait_for_value_uchar(&cdc_ecm_host -> ux_host_class_cdc_ecm_bulk_in_transfer_waiting_for_check_and_arm_to_finish, UX_TRUE));
|
||||
|
||||
/* Now resume the CDC-ECM thread. */
|
||||
tx_thread_resume(&cdc_ecm_host->ux_host_class_cdc_ecm_thread);
|
||||
|
||||
/* And now wait for CDC-ECM instance to go down. */
|
||||
ux_test_wait_for_value_ulong(&cdc_ecm_host->ux_host_class_cdc_ecm_link_state, 0);
|
||||
|
||||
/* And now wait for... wait a second, we're done! Smiley face! That was easier than I thought! I'M SO FRICKEN HAPPY RIGHT NOWWWWWW! */
|
||||
}
|
||||
|
||||
static void post_init_device()
|
||||
{
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
/* This tests the case where the bulk in transfer fails (in the cdc-ecm thread). */
|
||||
|
||||
#include "usbx_ux_test_cdc_ecm.h"
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_cdc_ecm_host_bulk_in_transfer_fail_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running CDC-ECM Host Bulk In Transfer Fail Test..................... ");
|
||||
|
||||
stepinfo("\n");
|
||||
|
||||
ux_test_cdc_ecm_initialize(first_unused_memory);
|
||||
}
|
||||
|
||||
static UCHAR is_cdc_ecm_thread_suspended;
|
||||
|
||||
static VOID suspend_cdc_ecm_thread_action_func(UX_TEST_ACTION *action, VOID *params)
|
||||
{
|
||||
|
||||
is_cdc_ecm_thread_suspended = 1;
|
||||
|
||||
/* We're being called by nx_packet_allocate in cdc-ecm thread. Wait for test
|
||||
thread to resume us. */
|
||||
tx_thread_suspend(tx_thread_identify());
|
||||
}
|
||||
|
||||
static void post_init_host()
|
||||
{
|
||||
|
||||
/* Currently, the cdc-ecm thread should be waiting for a transfer to complete.
|
||||
We need to create an action for having the bulk in transfer fail, add
|
||||
the action, then send data to host so the cdc-ecm thread will re-arm the
|
||||
transfer (which should fail). */
|
||||
|
||||
/* Create the action for having bulk in transfer fail. */
|
||||
UX_TEST_ACTION bulk_transfer_fail_action = {0};
|
||||
bulk_transfer_fail_action.usbx_function = UX_TEST_OVERRIDE_UX_HCD_SIM_HOST_ENTRY;
|
||||
bulk_transfer_fail_action.function = UX_HCD_TRANSFER_REQUEST;
|
||||
bulk_transfer_fail_action.req_action = UX_TEST_MATCH_EP;
|
||||
bulk_transfer_fail_action.req_ep_address = 0x81;
|
||||
bulk_transfer_fail_action.no_return = 0;
|
||||
bulk_transfer_fail_action.status = UX_ERROR;
|
||||
ux_test_add_action_to_main_list(bulk_transfer_fail_action);
|
||||
|
||||
/* Write to the host so the cdc-ecm thread will redo the bulk in transfer. */
|
||||
write_packet_udp(&udp_socket_device, &packet_pool_device, HOST_IP_ADDRESS, HOST_SOCKET_PORT_UDP, 0, "device");
|
||||
|
||||
/* Wait for the arm and fail. */
|
||||
UX_TEST_CHECK_SUCCESS(ux_test_wait_for_empty_actions());
|
||||
|
||||
/* Wait for the host to re-arm and wait for the transfer. */
|
||||
UX_TEST_CHECK_SUCCESS(ux_test_wait_for_value_uint(&cdc_ecm_host->ux_host_class_cdc_ecm_bulk_in_endpoint->ux_endpoint_transfer_request.ux_transfer_request_semaphore.tx_semaphore_suspended_count, 1));
|
||||
|
||||
/* Now we're done. */
|
||||
}
|
||||
|
||||
static void post_init_device()
|
||||
{
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
/* This tests the case where the bulk out semaphore at the class level creation
|
||||
fails. */
|
||||
|
||||
#include "usbx_ux_test_cdc_ecm.h"
|
||||
|
||||
static DEVICE_INIT_DATA device_init_data = {
|
||||
.framework = default_device_framework,
|
||||
.framework_length = sizeof(default_device_framework),
|
||||
.dont_register_hcd = 1,
|
||||
};
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_cdc_ecm_host_bulk_out_semaphore_create_fail_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running CDC-ECM Host Bulk Out Semaphore Create Fail Test............ ");
|
||||
|
||||
stepinfo("\n");
|
||||
|
||||
ux_test_cdc_ecm_initialize_use_framework(first_unused_memory, &device_init_data);
|
||||
}
|
||||
|
||||
static void post_init_host()
|
||||
{
|
||||
|
||||
int i;
|
||||
|
||||
UX_TEST_ACTION semaphore_create_fail_action = {0};
|
||||
semaphore_create_fail_action.usbx_function = UX_TEST_OVERRIDE_TX_SEMAPHORE_CREATE;
|
||||
semaphore_create_fail_action.semaphore_name = "host CDC-ECM bulk out wait semaphore";
|
||||
semaphore_create_fail_action.no_return = 0;
|
||||
semaphore_create_fail_action.status = UX_ERROR;
|
||||
|
||||
for (i = 0; i < UX_RH_ENUMERATION_RETRY; i++)
|
||||
{
|
||||
ux_test_add_action_to_main_list(semaphore_create_fail_action);
|
||||
ux_test_add_action_to_main_list(create_error_match_action(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_UTILITY, UX_ERROR));
|
||||
}
|
||||
ux_test_add_action_to_main_list(create_error_match_action(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_ROOT_HUB, UX_DEVICE_ENUMERATION_FAILURE));
|
||||
|
||||
/* Enumerate. */
|
||||
UX_TEST_CHECK_SUCCESS(ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize, 0, 0));
|
||||
|
||||
/* The HCD init function put()s the HCD semaphore, so we can do this here. */
|
||||
ux_test_wait_for_enum_thread_completion();
|
||||
|
||||
UX_TEST_ASSERT(ux_test_check_actions_empty());
|
||||
UX_TEST_ASSERT(cdc_ecm_host_from_system_change_function == UX_NULL);
|
||||
}
|
||||
|
||||
static void post_init_device()
|
||||
{
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
/* This tests the case where the bulk out transfer fails (in the cdc_ecm_write). */
|
||||
|
||||
#include "usbx_ux_test_cdc_ecm.h"
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_cdc_ecm_host_bulk_out_transfer_fail_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running CDC-ECM Host Bulk Out Transfer Fail Test.................... ");
|
||||
|
||||
stepinfo("\n");
|
||||
|
||||
ux_test_cdc_ecm_initialize(first_unused_memory);
|
||||
}
|
||||
|
||||
static void post_init_host()
|
||||
{
|
||||
|
||||
/* Create the action for having bulk in transfer fail. */
|
||||
UX_TEST_ACTION bulk_transfer_fail_action = {0};
|
||||
bulk_transfer_fail_action.usbx_function = UX_TEST_OVERRIDE_UX_HCD_SIM_HOST_ENTRY;
|
||||
bulk_transfer_fail_action.function = UX_HCD_TRANSFER_REQUEST;
|
||||
bulk_transfer_fail_action.req_action = UX_TEST_MATCH_EP;
|
||||
bulk_transfer_fail_action.req_ep_address = 0x02;
|
||||
bulk_transfer_fail_action.no_return = 0;
|
||||
bulk_transfer_fail_action.status = UX_ERROR;
|
||||
ux_test_add_action_to_main_list(bulk_transfer_fail_action);
|
||||
|
||||
/* Now send a packet so write function will run. */
|
||||
write_packet_tcp(&tcp_socket_host, &packet_pool_host, 0, "host");
|
||||
|
||||
/* Ensure write failed. */
|
||||
UX_TEST_CHECK_SUCCESS(ux_test_wait_for_empty_actions());
|
||||
|
||||
/* Now we're done. */
|
||||
}
|
||||
|
||||
static void post_init_device()
|
||||
{
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
/* This tests the case where the link is down and a thread is waiting for the
|
||||
bulk in transfer check-and-arm to finish. */
|
||||
|
||||
#include "usbx_ux_test_cdc_ecm.h"
|
||||
|
||||
static UCHAR cdc_ecm_thread_suspended;
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_cdc_ecm_host_bulk_in_transfer_arming_fails_due_to_link_down_and_thread_waiting_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running CDC-ECM Host Bulk In Transfer Arming During... Test......... ");
|
||||
|
||||
stepinfo("\n");
|
||||
|
||||
ux_test_cdc_ecm_initialize(first_unused_memory);
|
||||
}
|
||||
|
||||
static VOID suspend_cdc_ecm_thread_action_func(UX_TEST_ACTION *action, VOID *params)
|
||||
{
|
||||
|
||||
/* The CDC-ECM thread is calling us. */
|
||||
|
||||
/* Notify test thread. */
|
||||
cdc_ecm_thread_suspended = 1;
|
||||
|
||||
/* Suspend. Test thread should wake us back up. */
|
||||
tx_thread_suspend(tx_thread_identify());
|
||||
}
|
||||
|
||||
VOID cdc_ecm_thread_suspend_action_func(UX_TEST_ACTION *action, VOID *params)
|
||||
{
|
||||
cdc_ecm_thread_suspended = 1;
|
||||
tx_thread_suspend(tx_thread_identify());
|
||||
}
|
||||
|
||||
static void post_init_host()
|
||||
{
|
||||
|
||||
/* Right now, host CDC-ECM thread is waiting for a bulk in transfer. We
|
||||
need for it to re-do a transfer so that we can get it to suspend via our
|
||||
action. First, we need to create and add our actions. */
|
||||
UX_TEST_ACTION bulk_in_transfer_suspend_action = {0};
|
||||
bulk_in_transfer_suspend_action.usbx_function = UX_TEST_OVERRIDE_NX_PACKET_ALLOCATE;
|
||||
bulk_in_transfer_suspend_action.name_ptr = ip_pool_host_name;
|
||||
bulk_in_transfer_suspend_action.action_func = cdc_ecm_thread_suspend_action_func;
|
||||
ux_test_add_action_to_main_list(bulk_in_transfer_suspend_action);
|
||||
|
||||
/* Send data so thread does packet allocate. */
|
||||
write_packet_udp(&udp_socket_device, &packet_pool_device, HOST_IP_ADDRESS, HOST_SOCKET_PORT_UDP, 0, "device");
|
||||
|
||||
/* Wait for the thread to be suspended. */
|
||||
UX_TEST_CHECK_SUCCESS(ux_test_wait_for_value_uchar(&cdc_ecm_thread_suspended, 1));
|
||||
|
||||
/* Set link state to down. */
|
||||
ux_test_device_class_cdc_ecm_set_link_state(cdc_ecm_device, 0);
|
||||
|
||||
/* Now wait for the link to be set to pending down (it won't be down since thread is suspended). */
|
||||
UX_TEST_CHECK_SUCCESS(ux_test_wait_for_value_ulong(&cdc_ecm_host->ux_host_class_cdc_ecm_link_state, UX_HOST_CLASS_CDC_ECM_LINK_STATE_PENDING_DOWN));
|
||||
|
||||
/* Make CDC-ECM thread think a thread is indeed waiting. */
|
||||
cdc_ecm_host->ux_host_class_cdc_ecm_bulk_in_transfer_waiting_for_check_and_arm_to_finish = UX_TRUE;
|
||||
|
||||
/* Now resume CDC-ECM thread. */
|
||||
tx_thread_resume(&cdc_ecm_host->ux_host_class_cdc_ecm_thread);
|
||||
|
||||
/* Now wait for the semaphore to be put. */
|
||||
UX_TEST_CHECK_SUCCESS(ux_test_wait_for_value_ulong(&cdc_ecm_host->ux_host_class_cdc_ecm_bulk_in_transfer_waiting_for_check_and_arm_to_finish_semaphore.tx_semaphore_count, 1));
|
||||
|
||||
/* Now get the semaphore so the count is okay. */
|
||||
tx_semaphore_get(&cdc_ecm_host->ux_host_class_cdc_ecm_bulk_in_transfer_waiting_for_check_and_arm_to_finish_semaphore, TX_WAIT_FOREVER);
|
||||
|
||||
/* And now we're done. */
|
||||
}
|
||||
|
||||
static void post_init_device()
|
||||
{
|
||||
}
|
@ -0,0 +1,89 @@
|
||||
/* This tests the case where there is an ongoing transfer on the bulk out endpoint
|
||||
during link down. The interrupt notification function should wait for it to finish.
|
||||
|
||||
We do this by having the CDC-ECM thread suspend during the transfer arm,
|
||||
and then begin link down event. We resume the HCD thread later! */
|
||||
|
||||
#include "usbx_ux_test_cdc_ecm.h"
|
||||
|
||||
static UCHAR write_thread_suspended;
|
||||
static TX_THREAD write_thread;
|
||||
static UCHAR write_thread_stack[2048];
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_cdc_ecm_host_bulk_out_transfer_arming_during_link_down_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running CDC-ECM Host Bulk Out Transfer Arming During... Test........ ");
|
||||
|
||||
stepinfo("\n");
|
||||
|
||||
ux_test_cdc_ecm_initialize(first_unused_memory);
|
||||
}
|
||||
|
||||
static VOID suspend_write_thread_action_func(UX_TEST_ACTION *action, VOID *params)
|
||||
{
|
||||
|
||||
/* The write thread is calling us. */
|
||||
|
||||
/* Notify test thread. */
|
||||
write_thread_suspended = 1;
|
||||
|
||||
/* Suspend. Test thread should wake us back up. */
|
||||
tx_thread_suspend(tx_thread_identify());
|
||||
}
|
||||
|
||||
static void write_thread_entry(ULONG input)
|
||||
{
|
||||
|
||||
/* Do the write. */
|
||||
write_packet_tcp(&tcp_socket_host, &packet_pool_host, 0, "host");
|
||||
}
|
||||
|
||||
static void post_init_host()
|
||||
{
|
||||
|
||||
/* Create the thread that will do the write. */
|
||||
UX_TEST_CHECK_SUCCESS(tx_thread_create(&write_thread, "write thread", write_thread_entry, 0, write_thread_stack, sizeof(write_thread_stack), 20, 20, 0, TX_DONT_START));
|
||||
|
||||
/* Right now, host CDC-ECM thread is waiting for a bulk out transfer. We
|
||||
need for it to re-do a transfer so that we can get it to suspend via our
|
||||
action. First, we need to create and add our actions. */
|
||||
UX_TEST_ACTION bulk_out_transfer_suspend_action = {0};
|
||||
bulk_out_transfer_suspend_action.usbx_function = UX_TEST_OVERRIDE_UX_HCD_SIM_HOST_ENTRY;
|
||||
bulk_out_transfer_suspend_action.function = UX_HCD_TRANSFER_REQUEST;
|
||||
bulk_out_transfer_suspend_action.req_action = UX_TEST_MATCH_EP;
|
||||
bulk_out_transfer_suspend_action.req_ep_address = 0x02;
|
||||
bulk_out_transfer_suspend_action.action_func = suspend_write_thread_action_func;
|
||||
bulk_out_transfer_suspend_action.no_return = 1;
|
||||
ux_test_add_action_to_main_list(bulk_out_transfer_suspend_action);
|
||||
|
||||
/* Now start the write thread. */
|
||||
tx_thread_resume(&write_thread);
|
||||
|
||||
/* Now wait for it to be suspended. */
|
||||
ux_test_wait_for_value_uchar(&write_thread_suspended, 1);
|
||||
|
||||
/* Now change the link to down. */
|
||||
ux_test_device_class_cdc_ecm_set_link_state(cdc_ecm_device, 0);
|
||||
|
||||
/* Now wait for CDC-ECM thread to suspend, waiting for bulk out to finish. */
|
||||
UX_TEST_CHECK_SUCCESS(ux_test_wait_for_value_uchar(&cdc_ecm_host -> ux_host_class_cdc_ecm_bulk_out_transfer_waiting_for_check_and_arm_to_finish, UX_TRUE));
|
||||
|
||||
/* Now resume the write thread. */
|
||||
tx_thread_resume(&write_thread);
|
||||
|
||||
/* And now wait for write instance to go down. */
|
||||
ux_test_wait_for_value_ulong(&cdc_ecm_host->ux_host_class_cdc_ecm_link_state, 0);
|
||||
|
||||
/* And now wait for... wait a second, we're done! Smiley face! That was easier than I thought! I'M SO FRICKEN HAPPY RIGHT NOWWWWWW! */
|
||||
}
|
||||
|
||||
static void post_init_device()
|
||||
{
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
/* This tests the case where the CDC-ECM thread creation fails. */
|
||||
|
||||
#include "usbx_ux_test_cdc_ecm.h"
|
||||
|
||||
static DEVICE_INIT_DATA device_init_data = {
|
||||
.framework = default_device_framework,
|
||||
.framework_length = sizeof(default_device_framework),
|
||||
.dont_register_hcd = 1,
|
||||
};
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_cdc_ecm_host_first_interrupt_transfer_fail_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running CDC-ECM Host First Interrupt Transfer Fail Test............. ");
|
||||
|
||||
stepinfo("\n");
|
||||
|
||||
ux_test_cdc_ecm_initialize_use_framework(first_unused_memory, &device_init_data);
|
||||
}
|
||||
|
||||
static void post_init_host()
|
||||
{
|
||||
|
||||
int i;
|
||||
|
||||
UX_TEST_ACTION force_interrupt_transfer_fail_action = {0};
|
||||
force_interrupt_transfer_fail_action.usbx_function = UX_TEST_OVERRIDE_UX_HCD_SIM_HOST_ENTRY;
|
||||
force_interrupt_transfer_fail_action.function = UX_HCD_TRANSFER_REQUEST;
|
||||
force_interrupt_transfer_fail_action.req_action = UX_TEST_MATCH_EP;
|
||||
force_interrupt_transfer_fail_action.req_ep_address = 0x83;
|
||||
force_interrupt_transfer_fail_action.no_return = 0;
|
||||
force_interrupt_transfer_fail_action.status = UX_ERROR;
|
||||
|
||||
for (i = 0; i < UX_RH_ENUMERATION_RETRY; i++)
|
||||
{
|
||||
ux_test_add_action_to_main_list(force_interrupt_transfer_fail_action);
|
||||
}
|
||||
ux_test_add_action_to_main_list(create_error_match_action(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_ROOT_HUB, UX_DEVICE_ENUMERATION_FAILURE));
|
||||
|
||||
/* Enumerate. */
|
||||
UX_TEST_CHECK_SUCCESS(ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize, 0, 0));
|
||||
|
||||
/* The HCD init function put()s the HCD semaphore, so we can do this here. */
|
||||
ux_test_wait_for_enum_thread_completion();
|
||||
|
||||
UX_TEST_ASSERT(ux_test_check_actions_empty());
|
||||
UX_TEST_ASSERT(cdc_ecm_host_from_system_change_function == UX_NULL);
|
||||
}
|
||||
|
||||
static void post_init_device()
|
||||
{
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
/* This tests the case where the interrupt notification semaphore creation fails. */
|
||||
|
||||
#include "usbx_ux_test_cdc_ecm.h"
|
||||
|
||||
static DEVICE_INIT_DATA device_init_data = {
|
||||
.framework = default_device_framework,
|
||||
.framework_length = sizeof(default_device_framework),
|
||||
.dont_register_hcd = 1,
|
||||
};
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_cdc_ecm_host_interrupt_notification_semaphore_create_fail_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running CDC-ECM Host Interrupt Notification Semaphore Fail Test..... ");
|
||||
|
||||
stepinfo("\n");
|
||||
|
||||
ux_test_cdc_ecm_initialize_use_framework(first_unused_memory, &device_init_data);
|
||||
}
|
||||
|
||||
static void post_init_host()
|
||||
{
|
||||
|
||||
int i;
|
||||
|
||||
UX_TEST_ACTION semaphore_create_fail_action = {0};
|
||||
semaphore_create_fail_action.usbx_function = UX_TEST_OVERRIDE_TX_SEMAPHORE_CREATE;
|
||||
semaphore_create_fail_action.semaphore_name = "host CDC-ECM interrupt notification semaphore";
|
||||
semaphore_create_fail_action.no_return = 0;
|
||||
semaphore_create_fail_action.status = UX_ERROR;
|
||||
|
||||
for (i = 0; i < UX_RH_ENUMERATION_RETRY; i++)
|
||||
{
|
||||
ux_test_add_action_to_main_list(semaphore_create_fail_action);
|
||||
ux_test_add_action_to_main_list(create_error_match_action(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_UTILITY, UX_ERROR));
|
||||
}
|
||||
ux_test_add_action_to_main_list(create_error_match_action(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_ROOT_HUB, UX_DEVICE_ENUMERATION_FAILURE));
|
||||
|
||||
/* Enumerate. */
|
||||
UX_TEST_CHECK_SUCCESS(ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize, 0, 0));
|
||||
|
||||
/* The HCD init function put()s the HCD semaphore, so we can do this here. */
|
||||
ux_test_wait_for_enum_thread_completion();
|
||||
|
||||
UX_TEST_ASSERT(ux_test_check_actions_empty());
|
||||
UX_TEST_ASSERT(cdc_ecm_host_from_system_change_function == UX_NULL);
|
||||
}
|
||||
|
||||
static void post_init_device()
|
||||
{
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
/* This tests the case where the host receives a non-IP packet. */
|
||||
|
||||
#include "usbx_ux_test_cdc_ecm.h"
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_cdc_ecm_host_non_ip_packet_received_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running CDC-ECM Host Non IP Packet Received Test.................... ");
|
||||
|
||||
stepinfo("\n");
|
||||
|
||||
ux_test_cdc_ecm_initialize(first_unused_memory);
|
||||
}
|
||||
|
||||
static void post_init_host()
|
||||
{
|
||||
|
||||
NX_PACKET *out_packet;
|
||||
|
||||
/* Note that the packets we send to the host will just get released by NetX
|
||||
for being invalid. */
|
||||
|
||||
/** Test '*(packet -> nx_packet_prepend_ptr + 12) != 0x08' **/
|
||||
|
||||
UX_TEST_CHECK_SUCCESS(nx_packet_allocate(&packet_pool_device, &out_packet, NX_UDP_PACKET, NX_WAIT_FOREVER));
|
||||
|
||||
out_packet->nx_packet_length = (ULONG)(out_packet->nx_packet_data_end - out_packet->nx_packet_prepend_ptr);
|
||||
memset(out_packet->nx_packet_prepend_ptr, 'a', out_packet->nx_packet_length);
|
||||
out_packet->nx_packet_prepend_ptr[12] = 0x00;
|
||||
|
||||
/* Now send the packet. */
|
||||
_ux_device_class_cdc_ecm_write(cdc_ecm_device, out_packet);
|
||||
|
||||
/* Wait for host to receive it. */
|
||||
tx_thread_sleep(500);
|
||||
|
||||
/** Test '*(packet -> nx_packet_prepend_ptr + 13) != 0' **/
|
||||
|
||||
UX_TEST_CHECK_SUCCESS(nx_packet_allocate(&packet_pool_device, &out_packet, NX_UDP_PACKET, NX_WAIT_FOREVER));
|
||||
|
||||
out_packet->nx_packet_length = (ULONG)(out_packet->nx_packet_data_end - out_packet->nx_packet_prepend_ptr);
|
||||
memset(out_packet->nx_packet_prepend_ptr, 'a', out_packet->nx_packet_length);
|
||||
out_packet->nx_packet_prepend_ptr[12] = 0x08;
|
||||
out_packet->nx_packet_prepend_ptr[13] = 0x01;
|
||||
|
||||
/* Now send the packet. */
|
||||
_ux_device_class_cdc_ecm_write(cdc_ecm_device, out_packet);
|
||||
|
||||
/* Wait for host to receive it. */
|
||||
tx_thread_sleep(500);
|
||||
|
||||
/* We're done!? */
|
||||
}
|
||||
|
||||
static void post_init_device()
|
||||
{
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
/* This tests the case where the CDC-ECM thread creation fails. */
|
||||
|
||||
#include "usbx_ux_test_cdc_ecm.h"
|
||||
|
||||
static DEVICE_INIT_DATA device_init_data = {
|
||||
.framework = default_device_framework,
|
||||
.framework_length = sizeof(default_device_framework),
|
||||
.dont_register_hcd = 1,
|
||||
};
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_cdc_ecm_host_packet_pool_create_fail_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running CDC-ECM Host Packet Pool Create Test........................ ");
|
||||
printf("Deprecated\n");
|
||||
test_control_return(0);
|
||||
return;
|
||||
|
||||
stepinfo("\n");
|
||||
|
||||
ux_test_cdc_ecm_initialize_use_framework(first_unused_memory, &device_init_data);
|
||||
}
|
||||
|
||||
static void post_init_host()
|
||||
{
|
||||
|
||||
int i;
|
||||
|
||||
/* Enumerate first so we can initialize memory test. */
|
||||
UX_TEST_CHECK_SUCCESS(ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize, 0, 0));
|
||||
|
||||
/* The HCD init function put()s the HCD semaphore, so we can do this here. */
|
||||
ux_test_wait_for_enum_thread_completion();
|
||||
|
||||
/* We want at least one memory test. */
|
||||
ux_test_memory_test_initialize();
|
||||
|
||||
/* Disconnect so we can setup test. */
|
||||
ux_test_disconnect_host_wait_for_enum_completion();
|
||||
|
||||
UX_TEST_ACTION packet_pool_create_fail_action = {0};
|
||||
packet_pool_create_fail_action.usbx_function = UX_TEST_OVERRIDE_NX_PACKET_POOL_CREATE;
|
||||
packet_pool_create_fail_action.name_ptr = "host CDC-ECM packet pool";
|
||||
packet_pool_create_fail_action.no_return = 0;
|
||||
packet_pool_create_fail_action.status = UX_ERROR;
|
||||
|
||||
for (i = 0; i < UX_RH_ENUMERATION_RETRY; i++)
|
||||
{
|
||||
ux_test_add_action_to_main_list(packet_pool_create_fail_action);
|
||||
ux_test_add_action_to_main_list(create_error_match_action(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_ENUMERATOR, UX_ERROR));
|
||||
}
|
||||
ux_test_add_action_to_main_list(create_error_match_action(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_ROOT_HUB, UX_DEVICE_ENUMERATION_FAILURE));
|
||||
|
||||
/* Start enumeration. */
|
||||
ux_test_connect_slave_and_host_wait_for_enum_completion();
|
||||
|
||||
/* Disconnect. Note that this also does the memory check. */
|
||||
ux_test_disconnect_slave_and_host_wait_for_enum_completion();
|
||||
|
||||
UX_TEST_ASSERT(ux_test_check_actions_empty());
|
||||
UX_TEST_ASSERT(cdc_ecm_host_from_system_change_function == UX_NULL);
|
||||
}
|
||||
|
||||
static void post_init_device()
|
||||
{
|
||||
}
|
57
test/regression/usbx_cdc_ecm_host_thread_create_fail_test.c
Normal file
57
test/regression/usbx_cdc_ecm_host_thread_create_fail_test.c
Normal file
@ -0,0 +1,57 @@
|
||||
/* This tests the case where the CDC-ECM thread creation fails. */
|
||||
|
||||
#include "usbx_ux_test_cdc_ecm.h"
|
||||
|
||||
static DEVICE_INIT_DATA device_init_data = {
|
||||
.framework = default_device_framework,
|
||||
.framework_length = sizeof(default_device_framework),
|
||||
.dont_register_hcd = 1,
|
||||
};
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_cdc_ecm_host_thread_create_fail_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running CDC-ECM Host Thread Fail Test............................... ");
|
||||
|
||||
stepinfo("\n");
|
||||
|
||||
ux_test_cdc_ecm_initialize_use_framework(first_unused_memory, &device_init_data);
|
||||
}
|
||||
|
||||
static void post_init_host()
|
||||
{
|
||||
|
||||
int i;
|
||||
|
||||
UX_TEST_ACTION thread_create_fail_action = {0};
|
||||
thread_create_fail_action.usbx_function = UX_TEST_OVERRIDE_TX_THREAD_CREATE;
|
||||
thread_create_fail_action.name_ptr = "ux_host_cdc_ecm_thread";
|
||||
thread_create_fail_action.no_return = 0;
|
||||
thread_create_fail_action.status = UX_ERROR;
|
||||
|
||||
for (i = 0; i < UX_RH_ENUMERATION_RETRY; i++)
|
||||
{
|
||||
ux_test_add_action_to_main_list(thread_create_fail_action);
|
||||
ux_test_add_action_to_main_list(create_error_match_action(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_UTILITY, UX_ERROR));
|
||||
}
|
||||
ux_test_add_action_to_main_list(create_error_match_action(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_ROOT_HUB, UX_DEVICE_ENUMERATION_FAILURE));
|
||||
|
||||
/* Enumerate. */
|
||||
UX_TEST_CHECK_SUCCESS(ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize, 0, 0));
|
||||
|
||||
/* The HCD init function put()s the HCD semaphore, so we can do this here. */
|
||||
ux_test_wait_for_enum_thread_completion();
|
||||
|
||||
UX_TEST_ASSERT(ux_test_check_actions_empty());
|
||||
UX_TEST_ASSERT(cdc_ecm_host_from_system_change_function == UX_NULL);
|
||||
}
|
||||
|
||||
static void post_init_device()
|
||||
{
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
/* This tests the case where right before the transfer is armed, the link state
|
||||
is down in the cdc-ecm thread. */
|
||||
|
||||
#include "usbx_ux_test_cdc_ecm.h"
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_cdc_ecm_host_thread_link_down_before_transfer_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running CDC-ECM Host Thread Link Down Before Transfer Test.......... ");
|
||||
|
||||
stepinfo("\n");
|
||||
|
||||
ux_test_cdc_ecm_initialize(first_unused_memory);
|
||||
}
|
||||
|
||||
static UCHAR is_cdc_ecm_thread_suspended;
|
||||
|
||||
static VOID suspend_cdc_ecm_thread_action_func(UX_TEST_ACTION *action, VOID *params)
|
||||
{
|
||||
|
||||
is_cdc_ecm_thread_suspended = 1;
|
||||
|
||||
/* We're being called by nx_packet_allocate in cdc-ecm thread. Wait for test
|
||||
thread to resume us. */
|
||||
tx_thread_suspend(tx_thread_identify());
|
||||
}
|
||||
|
||||
static void post_init_host()
|
||||
{
|
||||
|
||||
/* Currently, the cdc-ecm thread should be waiting for a transfer to complete.
|
||||
We need to create an action for having the cdc-ecm thread suspend during
|
||||
the packet allocate, then do a write from the device so the cdc-ecm thread
|
||||
call the packet allocate, then set the link to down, then resume the thread. */
|
||||
|
||||
/* Create the action for having cdc-ecm thread suspend on packet allocate. */
|
||||
UX_TEST_ACTION packet_allocate_suspend_action = {0};
|
||||
packet_allocate_suspend_action.usbx_function = UX_TEST_OVERRIDE_NX_PACKET_ALLOCATE;
|
||||
packet_allocate_suspend_action.name_ptr = ip_pool_host_name;
|
||||
packet_allocate_suspend_action.action_func = suspend_cdc_ecm_thread_action_func;
|
||||
ux_test_add_action_to_main_list(packet_allocate_suspend_action);
|
||||
|
||||
/* Write to the host so the cdc-ecm thread will redo the nx_packet_allocate. */
|
||||
write_packet_udp(&udp_socket_device, &packet_pool_device, HOST_IP_ADDRESS, HOST_SOCKET_PORT_UDP, 0, "device");
|
||||
|
||||
/* Now wait for the cdc-ecm thread to suspend. */
|
||||
UX_TEST_CHECK_SUCCESS(ux_test_wait_for_value_uchar(&is_cdc_ecm_thread_suspended, 1));
|
||||
|
||||
/* Now set the link state to down. */
|
||||
ux_test_device_class_cdc_ecm_set_link_state(cdc_ecm_device, 0);
|
||||
|
||||
/* Now wait for the link to be set to pending down (it won't be down since thread is suspended). */
|
||||
UX_TEST_CHECK_SUCCESS(ux_test_wait_for_value_ulong(&cdc_ecm_host->ux_host_class_cdc_ecm_link_state, UX_HOST_CLASS_CDC_ECM_LINK_STATE_PENDING_DOWN));
|
||||
|
||||
/* Now resume the cdc-ecm thread. */
|
||||
tx_thread_resume(&cdc_ecm_host->ux_host_class_cdc_ecm_thread);
|
||||
|
||||
/* Now wait for link to be down. */
|
||||
UX_TEST_CHECK_SUCCESS(ux_test_wait_for_value_ulong(&cdc_ecm_host->ux_host_class_cdc_ecm_link_state, UX_HOST_CLASS_CDC_ECM_LINK_STATE_DOWN));
|
||||
|
||||
/* Now we're done. */
|
||||
}
|
||||
|
||||
static void post_init_device()
|
||||
{
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
/* This tests the case the nx_packet_allocate fails in the cdc-ecm thread. */
|
||||
|
||||
#include "usbx_ux_test_cdc_ecm.h"
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_cdc_ecm_host_thread_packet_allocate_fail_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running CDC-ECM Host Thread Packet Allocate Fail Test............... ");
|
||||
|
||||
stepinfo("\n");
|
||||
|
||||
ux_test_cdc_ecm_initialize(first_unused_memory);
|
||||
}
|
||||
|
||||
static void post_init_host()
|
||||
{
|
||||
|
||||
int i;
|
||||
int device_num_writes = 0;
|
||||
int host_num_reads = 0;
|
||||
|
||||
/* Have the device send the max number of packets to the host. */
|
||||
for (i = 0; i < UX_HOST_CLASS_CDC_ECM_NX_PKPOOL_ENTRIES; i++)
|
||||
{
|
||||
|
||||
write_packet_udp(&udp_socket_device, &packet_pool_device, HOST_IP_ADDRESS, HOST_SOCKET_PORT_UDP, device_num_writes++, "device");
|
||||
}
|
||||
|
||||
/* Time to setup our action since we expect an error. */
|
||||
ux_test_add_action_to_main_list(create_error_match_action(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_MEMORY_INSUFFICIENT));
|
||||
|
||||
/* Now send the one that should make the call overflow. */
|
||||
write_packet_udp(&udp_socket_device, &packet_pool_device, HOST_IP_ADDRESS, HOST_SOCKET_PORT_UDP, device_num_writes++, "device");
|
||||
|
||||
/* Now wait for error to occur. */
|
||||
UX_TEST_CHECK_SUCCESS(ux_test_wait_for_empty_actions());
|
||||
|
||||
/* Let's be good sports and make sure everything else works. */
|
||||
for (i = 0; i < UX_HOST_CLASS_CDC_ECM_NX_PKPOOL_ENTRIES + 1; i++)
|
||||
{
|
||||
|
||||
read_packet_udp(&udp_socket_host, host_num_reads++, "host");
|
||||
}
|
||||
|
||||
/* Send one more. */
|
||||
write_packet_udp(&udp_socket_device, &packet_pool_device, HOST_IP_ADDRESS, HOST_SOCKET_PORT_UDP, device_num_writes++, "device");
|
||||
/* Read one more. */
|
||||
read_packet_udp(&udp_socket_host, host_num_reads++, "host");
|
||||
}
|
||||
|
||||
static void post_init_device()
|
||||
{
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
/* This tests the case the nx_packet_allocate fails in the cdc-ecm thread. */
|
||||
|
||||
#define TEST_NX_PACKET_CHAIN
|
||||
#include "usbx_ux_test_cdc_ecm.h"
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_cdc_ecm_host_thread_packet_allocate_fail_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running CDC-ECM Host Thread Packet Append Fail Test................. ");
|
||||
stepinfo("\n");
|
||||
#if (UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1) && defined(UX_DEVICE_CLASS_CDC_ECM_ZERO_COPY)
|
||||
printf("Skipped\n");
|
||||
return;
|
||||
#endif
|
||||
|
||||
ux_test_cdc_ecm_initialize(first_unused_memory);
|
||||
}
|
||||
|
||||
static void post_init_host()
|
||||
{
|
||||
|
||||
ULONG n_available;
|
||||
int i;
|
||||
int device_num_writes = 0;
|
||||
int host_num_reads = 0;
|
||||
|
||||
/* Have the device send the max number of packets to the host. */
|
||||
ux_utility_delay_ms(1000);
|
||||
n_available = cdc_ecm_host->ux_host_class_cdc_ecm_packet_pool->nx_packet_pool_available;
|
||||
for (i = 0; i < n_available; i++)
|
||||
write_udp(&udp_socket_device, &packet_pool_device, HOST_IP_ADDRESS, HOST_SOCKET_PORT_UDP, device_num_writes++, "device", 4);
|
||||
ux_utility_delay_ms(1000);
|
||||
|
||||
/* Time to setup our action since we expect an error. */
|
||||
ux_test_add_action_to_main_list(create_error_match_action(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_CLASS_ETH_PACKET_ERROR));
|
||||
|
||||
/* Now send the one that should make the append error (discarded). */
|
||||
write_packet_udp(&udp_socket_device, &packet_pool_device, HOST_IP_ADDRESS, HOST_SOCKET_PORT_UDP, device_num_writes, "device");
|
||||
|
||||
/* Now wait for error to occur. */
|
||||
UX_TEST_CHECK_SUCCESS(ux_test_wait_for_empty_actions());
|
||||
|
||||
/* Let's be good sports and make sure everything else works. */
|
||||
for (i = 0; i < n_available; i++)
|
||||
read_packet_udp(&udp_socket_host, host_num_reads++, "host");
|
||||
|
||||
/* Send one more. */
|
||||
write_packet_udp(&udp_socket_device, &packet_pool_device, HOST_IP_ADDRESS, HOST_SOCKET_PORT_UDP, device_num_writes++, "device");
|
||||
/* Read one more. */
|
||||
read_packet_udp(&udp_socket_host, host_num_reads++, "host");
|
||||
}
|
||||
|
||||
static void post_init_device()
|
||||
{
|
||||
}
|
@ -0,0 +1,189 @@
|
||||
/* This test tests the case where there is an interface before the control interface. In this case, it's a storage class interface.
|
||||
We do this because during activation, we need to link the the control interface into the class instance, so we need to find it. */
|
||||
|
||||
#include "usbx_ux_test_cdc_ecm.h"
|
||||
|
||||
static unsigned char interface_before_control_interface_framework[] = {
|
||||
|
||||
/* Device Descriptor */
|
||||
0x12, /* bLength */
|
||||
0x01, /* bDescriptorType */
|
||||
0x10, 0x01, /* bcdUSB */
|
||||
0xef, /* bDeviceClass - Depends on bDeviceSubClass */
|
||||
0x02, /* bDeviceSubClass - Depends on bDeviceProtocol */
|
||||
0x01, /* bDeviceProtocol - There's an IAD */
|
||||
0x40, /* bMaxPacketSize0 */
|
||||
0x70, 0x07, /* idVendor */
|
||||
0x42, 0x10, /* idProduct */
|
||||
0x00, 0x01, /* bcdDevice */
|
||||
0x01, /* iManufacturer */
|
||||
0x02, /* iProduct */
|
||||
0x03, /* iSerialNumber */
|
||||
0x01, /* bNumConfigurations */
|
||||
|
||||
/* Configuration Descriptor */
|
||||
0x09, /* bLength */
|
||||
0x02, /* bDescriptorType */
|
||||
0x76, 0x00, /* wTotalLength */
|
||||
0x02, /* bNumInterfaces */
|
||||
0x01, /* bConfigurationValue */
|
||||
0x00, /* iConfiguration */
|
||||
0xc0, /* bmAttributes - Self-powered */
|
||||
0x00, /* bMaxPower */
|
||||
|
||||
/* Interface Descriptor */
|
||||
0x09, /* bLength */
|
||||
0x04, /* bDescriptorType */
|
||||
0x00, /* bInterfaceNumber */
|
||||
0x00, /* bAlternateSetting */
|
||||
0x03, /* bNumEndpoints */
|
||||
0x08, /* bInterfaceClass - Mass Storage */
|
||||
0x06, /* bInterfaceSubClass */
|
||||
0x50, /* bInterfaceProtocol */
|
||||
0x00, /* iInterface */
|
||||
|
||||
/* Endpoint Descriptor */
|
||||
0x07, /* bLength */
|
||||
0x05, /* bDescriptorType */
|
||||
0x81, /* bEndpointAddress */
|
||||
0x02, /* bmAttributes - Bulk */
|
||||
0x40, 0x00, /* wMaxPacketSize */
|
||||
0x00, /* bInterval */
|
||||
|
||||
/* Endpoint Descriptor */
|
||||
0x07, /* bLength */
|
||||
0x05, /* bDescriptorType */
|
||||
0x02, /* bEndpointAddress */
|
||||
0x02, /* bmAttributes - Bulk */
|
||||
0x40, 0x00, /* wMaxPacketSize */
|
||||
0x00, /* bInterval */
|
||||
|
||||
/* Endpoint Descriptor */
|
||||
0x07, /* bLength */
|
||||
0x05, /* bDescriptorType */
|
||||
0x83, /* bEndpointAddress */
|
||||
0x03, /* bmAttributes - Interrupt */
|
||||
0x40, 0x00, /* wMaxPacketSize */
|
||||
0x01, /* bInterval */
|
||||
|
||||
/* Interface Association Descriptor */
|
||||
0x08, /* bLength */
|
||||
0x0b, /* bDescriptorType */
|
||||
0x00, /* bFirstInterface */
|
||||
0x02, /* bInterfaceCount */
|
||||
0x02, /* bFunctionClass - CDC - Communication */
|
||||
0x06, /* bFunctionSubClass - ECM */
|
||||
0x00, /* bFunctionProtocol - No class specific protocol required */
|
||||
0x00, /* iFunction */
|
||||
|
||||
/* Interface Descriptor */
|
||||
0x09, /* bLength */
|
||||
0x04, /* bDescriptorType */
|
||||
0x00, /* bInterfaceNumber */
|
||||
0x00, /* bAlternateSetting */
|
||||
0x01, /* bNumEndpoints */
|
||||
0x02, /* bInterfaceClass - CDC - Communication */
|
||||
0x06, /* bInterfaceSubClass - ECM */
|
||||
0x00, /* bInterfaceProtocol - No class specific protocol required */
|
||||
0x00, /* iInterface */
|
||||
|
||||
/* CDC Header Functional Descriptor */
|
||||
0x05, /* bLength */
|
||||
0x24, /* bDescriptorType */
|
||||
0x00, /* bDescriptorSubType */
|
||||
0x10, 0x01, /* bcdCDC */
|
||||
|
||||
/* CDC ECM Functional Descriptor */
|
||||
0x0d, /* bLength */
|
||||
0x24, /* bDescriptorType */
|
||||
0x0f, /* bDescriptorSubType */
|
||||
0x04, /* iMACAddress */
|
||||
0x00, 0x00, 0x00, 0x00, /* bmEthernetStatistics */
|
||||
0xea, 0x05, /* wMaxSegmentSize */
|
||||
0x00, 0x00, /* wNumberMCFilters */
|
||||
0x00, /* bNumberPowerFilters */
|
||||
|
||||
/* CDC Union Functional Descriptor */
|
||||
0x05, /* bLength */
|
||||
0x24, /* bDescriptorType */
|
||||
0x06, /* bDescriptorSubType */
|
||||
0x00, /* bmMasterInterface */
|
||||
0x01, /* bmSlaveInterface0 */
|
||||
|
||||
/* Endpoint Descriptor */
|
||||
0x07, /* bLength */
|
||||
0x05, /* bDescriptorType */
|
||||
0x84, /* bEndpointAddress */
|
||||
0x03, /* bmAttributes - Interrupt */
|
||||
0x08, 0x00, /* wMaxPacketSize */
|
||||
0x08, /* bInterval */
|
||||
|
||||
/* Interface Descriptor */
|
||||
0x09, /* bLength */
|
||||
0x04, /* bDescriptorType */
|
||||
0x01, /* bInterfaceNumber */
|
||||
0x00, /* bAlternateSetting */
|
||||
0x00, /* bNumEndpoints */
|
||||
0x0a, /* bInterfaceClass - CDC - Data */
|
||||
0x00, /* bInterfaceSubClass - Should be 0x00 */
|
||||
0x00, /* bInterfaceProtocol - No class specific protocol required */
|
||||
0x00, /* iInterface */
|
||||
|
||||
/* Interface Descriptor */
|
||||
0x09, /* bLength */
|
||||
0x04, /* bDescriptorType */
|
||||
0x01, /* bInterfaceNumber */
|
||||
0x01, /* bAlternateSetting */
|
||||
0x02, /* bNumEndpoints */
|
||||
0x0a, /* bInterfaceClass - CDC - Data */
|
||||
0x00, /* bInterfaceSubClass - Should be 0x00 */
|
||||
0x00, /* bInterfaceProtocol - No class specific protocol required */
|
||||
0x00, /* iInterface */
|
||||
|
||||
/* Endpoint Descriptor */
|
||||
0x07, /* bLength */
|
||||
0x05, /* bDescriptorType */
|
||||
0x05, /* bEndpointAddress */
|
||||
0x02, /* bmAttributes - Bulk */
|
||||
0x40, 0x00, /* wMaxPacketSize */
|
||||
0x00, /* bInterval */
|
||||
|
||||
/* Endpoint Descriptor */
|
||||
0x07, /* bLength */
|
||||
0x05, /* bDescriptorType */
|
||||
0x86, /* bEndpointAddress */
|
||||
0x02, /* bmAttributes - Bulk */
|
||||
0x40, 0x00, /* wMaxPacketSize */
|
||||
0x00, /* bInterval */
|
||||
|
||||
};
|
||||
|
||||
static DEVICE_INIT_DATA device_init_data = { interface_before_control_interface_framework, sizeof(interface_before_control_interface_framework) };
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_cdc_ecm_interface_before_control_interface_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running cdc_ecm interface before control interface Test............. ");
|
||||
|
||||
stepinfo("\n");
|
||||
|
||||
ux_test_cdc_ecm_initialize_use_framework(first_unused_memory, &device_init_data);
|
||||
}
|
||||
|
||||
static void post_init_host()
|
||||
{
|
||||
|
||||
cdc_ecm_basic_test(BASIC_TEST_HOST, BASIC_TEST_TCP);
|
||||
}
|
||||
|
||||
static void post_init_device()
|
||||
{
|
||||
|
||||
cdc_ecm_basic_test(BASIC_TEST_DEVICE, BASIC_TEST_TCP);
|
||||
}
|
@ -0,0 +1,170 @@
|
||||
/* This tests the case where the default data interface has zero endpoints, and
|
||||
the interface right after is also a data interface but contains an invalid
|
||||
alternate setting value. Host should report error. */
|
||||
|
||||
#include "usbx_ux_test_cdc_ecm.h"
|
||||
|
||||
static unsigned char non_data_interface_after_zero_endpoint_data_interface_framework[] = {
|
||||
|
||||
/* Device Descriptor */
|
||||
0x12, /* bLength */
|
||||
0x01, /* bDescriptorType */
|
||||
0x10, 0x01, /* bcdUSB */
|
||||
0xef, /* bDeviceClass - Depends on bDeviceSubClass */
|
||||
0x02, /* bDeviceSubClass - Depends on bDeviceProtocol */
|
||||
0x01, /* bDeviceProtocol - There's an IAD */
|
||||
0x40, /* bMaxPacketSize0 */
|
||||
0x70, 0x07, /* idVendor */
|
||||
0x42, 0x10, /* idProduct */
|
||||
0x00, 0x01, /* bcdDevice */
|
||||
0x01, /* iManufacturer */
|
||||
0x02, /* iProduct */
|
||||
0x03, /* iSerialNumber */
|
||||
0x01, /* bNumConfigurations */
|
||||
|
||||
/* Configuration Descriptor */
|
||||
0x09, /* bLength */
|
||||
0x02, /* bDescriptorType */
|
||||
0x58, 0x00, /* wTotalLength */
|
||||
0x02, /* bNumInterfaces */
|
||||
0x01, /* bConfigurationValue */
|
||||
0x00, /* iConfiguration */
|
||||
0xc0, /* bmAttributes - Self-powered */
|
||||
0x00, /* bMaxPower */
|
||||
|
||||
/* Interface Association Descriptor */
|
||||
0x08, /* bLength */
|
||||
0x0b, /* bDescriptorType */
|
||||
0x00, /* bFirstInterface */
|
||||
0x02, /* bInterfaceCount */
|
||||
0x02, /* bFunctionClass - CDC - Communication */
|
||||
0x06, /* bFunctionSubClass - ECM */
|
||||
0x00, /* bFunctionProtocol - No class specific protocol required */
|
||||
0x00, /* iFunction */
|
||||
|
||||
/* Interface Descriptor */
|
||||
0x09, /* bLength */
|
||||
0x04, /* bDescriptorType */
|
||||
0x00, /* bInterfaceNumber */
|
||||
0x00, /* bAlternateSetting */
|
||||
0x01, /* bNumEndpoints */
|
||||
0x02, /* bInterfaceClass - CDC - Communication */
|
||||
0x06, /* bInterfaceSubClass - ECM */
|
||||
0x00, /* bInterfaceProtocol - No class specific protocol required */
|
||||
0x00, /* iInterface */
|
||||
|
||||
/* CDC Header Functional Descriptor */
|
||||
0x05, /* bLength */
|
||||
0x24, /* bDescriptorType */
|
||||
0x00, /* bDescriptorSubType */
|
||||
0x10, 0x01, /* bcdCDC */
|
||||
|
||||
/* CDC ECM Functional Descriptor */
|
||||
0x0d, /* bLength */
|
||||
0x24, /* bDescriptorType */
|
||||
0x0f, /* bDescriptorSubType */
|
||||
0x04, /* iMACAddress */
|
||||
0x00, 0x00, 0x00, 0x00, /* bmEthernetStatistics */
|
||||
0xea, 0x05, /* wMaxSegmentSize */
|
||||
0x00, 0x00, /* wNumberMCFilters */
|
||||
0x00, /* bNumberPowerFilters */
|
||||
|
||||
/* CDC Union Functional Descriptor */
|
||||
0x05, /* bLength */
|
||||
0x24, /* bDescriptorType */
|
||||
0x06, /* bDescriptorSubType */
|
||||
0x00, /* bmMasterInterface */
|
||||
0x01, /* bmSlaveInterface0 */
|
||||
|
||||
/* Endpoint Descriptor */
|
||||
0x07, /* bLength */
|
||||
0x05, /* bDescriptorType */
|
||||
0x83, /* bEndpointAddress */
|
||||
0x03, /* bmAttributes - Interrupt */
|
||||
0x08, 0x00, /* wMaxPacketSize */
|
||||
0x08, /* bInterval */
|
||||
|
||||
/* Interface Descriptor */
|
||||
0x09, /* bLength */
|
||||
0x04, /* bDescriptorType */
|
||||
0x01, /* bInterfaceNumber */
|
||||
0x00, /* bAlternateSetting */
|
||||
0x00, /* bNumEndpoints */
|
||||
0x0a, /* bInterfaceClass - CDC - Data */
|
||||
0x00, /* bInterfaceSubClass - Should be 0x00 */
|
||||
0x00, /* bInterfaceProtocol - No class specific protocol required */
|
||||
0x00, /* iInterface */
|
||||
|
||||
/* Interface Descriptor */
|
||||
0x09, /* bLength */
|
||||
0x04, /* bDescriptorType */
|
||||
0x01, /* bInterfaceNumber */
|
||||
/* Invalid alternate setting. */
|
||||
0xff, /* bAlternateSetting */
|
||||
0x02, /* bNumEndpoints */
|
||||
0x0a, /* bInterfaceClass - CDC - Data */
|
||||
0x00, /* bInterfaceSubClass - Should be 0x00 */
|
||||
0x00, /* bInterfaceProtocol - No class specific protocol required */
|
||||
0x00, /* iInterface */
|
||||
|
||||
/* Endpoint Descriptor */
|
||||
0x07, /* bLength */
|
||||
0x05, /* bDescriptorType */
|
||||
0x02, /* bEndpointAddress */
|
||||
0x02, /* bmAttributes - Bulk */
|
||||
0x40, 0x00, /* wMaxPacketSize */
|
||||
0x00, /* bInterval */
|
||||
|
||||
/* Endpoint Descriptor */
|
||||
0x07, /* bLength */
|
||||
0x05, /* bDescriptorType */
|
||||
0x81, /* bEndpointAddress */
|
||||
0x02, /* bmAttributes - Bulk */
|
||||
0x40, 0x00, /* wMaxPacketSize */
|
||||
0x00, /* bInterval */
|
||||
|
||||
};
|
||||
|
||||
static DEVICE_INIT_DATA device_init_data = {
|
||||
.framework = non_data_interface_after_zero_endpoint_data_interface_framework,
|
||||
.framework_length = sizeof(non_data_interface_after_zero_endpoint_data_interface_framework),
|
||||
.dont_register_hcd = 1,
|
||||
};
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_cdc_ecm_invalid_alternate_setting_after_zero_endpoint_data_interface_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running CDC-ECM Invalid Alternate Setting After... Test............. ");
|
||||
|
||||
stepinfo("\n");
|
||||
|
||||
ux_test_cdc_ecm_initialize_use_framework(first_unused_memory, &device_init_data);
|
||||
}
|
||||
|
||||
static void post_init_host()
|
||||
{
|
||||
|
||||
/* We expect this to fail multiple times since enumeration tries multiple times. */
|
||||
ux_test_add_action_to_main_list_multiple(create_error_match_action(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_DESCRIPTOR_CORRUPTED), 3);
|
||||
ux_test_add_action_to_main_list(create_error_match_action(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_ROOT_HUB, UX_DEVICE_ENUMERATION_FAILURE));
|
||||
|
||||
/* Enumerate. */
|
||||
UX_TEST_CHECK_SUCCESS(ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize, 0, 0));
|
||||
|
||||
/* The HCD init function put()s the HCD semaphore, so we can do this here. */
|
||||
ux_test_wait_for_enum_thread_completion();
|
||||
|
||||
/* Enumeration should've failed. */
|
||||
UX_TEST_ASSERT(ux_test_check_actions_empty());
|
||||
UX_TEST_ASSERT(cdc_ecm_host_from_system_change_function == UX_NULL);
|
||||
}
|
||||
|
||||
static void post_init_device()
|
||||
{
|
||||
}
|
@ -0,0 +1,199 @@
|
||||
/* This test the case where a LINK DOWN event is received while transfers are
|
||||
ongoing. */
|
||||
|
||||
#include "usbx_ux_test_cdc_ecm.h"
|
||||
#include "ux_device_stack.h"
|
||||
|
||||
static ULONG global_basic_test_num_writes_host;
|
||||
static ULONG global_basic_test_num_reads_host;
|
||||
|
||||
static ULONG global_basic_test_num_writes_device;
|
||||
static ULONG global_basic_test_num_reads_device;
|
||||
|
||||
static UCHAR host_waiting_for_link_down;
|
||||
static UCHAR host_waiting_for_link_up;
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_cdc_ecm_link_down_while_ongoing_transfers_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running CDC-ECM Host Link Down While Ongoing Transfers Test......... ");
|
||||
|
||||
stepinfo("\n");
|
||||
|
||||
ux_test_cdc_ecm_initialize(first_unused_memory);
|
||||
}
|
||||
|
||||
static void basic_test_host()
|
||||
{
|
||||
|
||||
UINT num_iters;
|
||||
UINT i;
|
||||
|
||||
/*** Basic test - no transfers going on. ***/
|
||||
stepinfo("Basic test - no transfers going on.\n");
|
||||
|
||||
/* Now wait for the link to be down. */
|
||||
host_waiting_for_link_down = 1;
|
||||
UX_TEST_CHECK_SUCCESS(ux_test_wait_for_value_ulong(&cdc_ecm_host->ux_host_class_cdc_ecm_link_state, UX_HOST_CLASS_CDC_ECM_LINK_STATE_DOWN));
|
||||
|
||||
/* Wait for everything to get cleaned up. */
|
||||
tx_thread_sleep(MS_TO_TICK(1000));
|
||||
|
||||
/* Now wait for the link to be up. */
|
||||
host_waiting_for_link_up = 1;
|
||||
UX_TEST_CHECK_SUCCESS(ux_test_wait_for_value_ulong(&cdc_ecm_host->ux_host_class_cdc_ecm_link_state, UX_HOST_CLASS_CDC_ECM_LINK_STATE_UP));
|
||||
|
||||
/* Run that basic test again. */
|
||||
for (num_iters = 0; num_iters < 10; num_iters++)
|
||||
{
|
||||
|
||||
for (i = 0; i < 10; i++)
|
||||
write_packet_udp(&udp_socket_host, &packet_pool_host, DEVICE_IP_ADDRESS, DEVICE_SOCKET_PORT_UDP, global_basic_test_num_writes_host++, "host");
|
||||
|
||||
for (i = 0; i < 10; i++)
|
||||
read_packet_udp(&udp_socket_host, global_basic_test_num_reads_host++, "host");
|
||||
}
|
||||
|
||||
/* Wait for all transfers to complete. */
|
||||
UX_TEST_CHECK_SUCCESS(ux_test_wait_for_value_ulong(&global_basic_test_num_reads_host, 100));
|
||||
UX_TEST_CHECK_SUCCESS(ux_test_wait_for_value_ulong(&global_basic_test_num_reads_device, 100));
|
||||
}
|
||||
|
||||
static void basic_test_device()
|
||||
{
|
||||
|
||||
UINT num_iters;
|
||||
UINT i;
|
||||
|
||||
/*** Basic test. ***/
|
||||
|
||||
/* Wait for host to wait for link down. */
|
||||
UX_TEST_CHECK_SUCCESS(ux_test_wait_for_value_uchar(&host_waiting_for_link_down, 1));
|
||||
host_waiting_for_link_down = 0;
|
||||
|
||||
/* Now set the link to down. */
|
||||
ux_test_device_class_cdc_ecm_set_link_state(cdc_ecm_device, UX_DEVICE_CLASS_CDC_ECM_LINK_STATE_DOWN);
|
||||
|
||||
/* Wait for host to wait for link up. */
|
||||
UX_TEST_CHECK_SUCCESS(ux_test_wait_for_value_uchar(&host_waiting_for_link_up, 1));
|
||||
host_waiting_for_link_up = 0;
|
||||
|
||||
/* Now set the link to up. */
|
||||
ux_test_device_class_cdc_ecm_set_link_state(cdc_ecm_device, UX_DEVICE_CLASS_CDC_ECM_LINK_STATE_UP);
|
||||
|
||||
/* Now do basic test. */
|
||||
for (num_iters = 0; num_iters < 10; num_iters++)
|
||||
{
|
||||
|
||||
for (i = 0; i < 10; i++)
|
||||
write_packet_udp(&udp_socket_device, &packet_pool_device, HOST_IP_ADDRESS, HOST_SOCKET_PORT_UDP, global_basic_test_num_writes_device++, "device");
|
||||
|
||||
for (i = 0; i < 10; i++)
|
||||
read_packet_udp(&udp_socket_device, global_basic_test_num_reads_device++, "device");
|
||||
}
|
||||
|
||||
/* Wait for all transfers to complete. */
|
||||
UX_TEST_CHECK_SUCCESS(ux_test_wait_for_value_ulong(&global_basic_test_num_reads_host, 100));
|
||||
UX_TEST_CHECK_SUCCESS(ux_test_wait_for_value_ulong(&global_basic_test_num_reads_device, 100));
|
||||
}
|
||||
|
||||
#define NUM_WRITES 500
|
||||
#define NUM_WRITES_BEFORE_LINK_DOWN 10
|
||||
#define MAX_WRITE_WHILE_LINK_DOWN (NUM_WRITES - NUM_WRITES_BEFORE_LINK_DOWN)
|
||||
|
||||
static void ongoing_writes_test_host()
|
||||
{
|
||||
|
||||
UINT i;
|
||||
UINT pre_write_fail_num_packet_pool_packets_available;
|
||||
UINT num_writes = 0;
|
||||
|
||||
/*** Link down when there are queued writes, and we try to add writes. ***/
|
||||
stepinfo("Ongoing writes test.\n");
|
||||
|
||||
pre_write_fail_num_packet_pool_packets_available = packet_pool_host.nx_packet_pool_available;
|
||||
|
||||
/* We expect some errors. */
|
||||
UX_TEST_ACTION error_match_action = create_error_match_action(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_CLASS_CDC_ECM_LINK_STATE_DOWN_ERROR);
|
||||
ux_test_add_action_to_main_list_multiple(error_match_action, MAX_WRITE_WHILE_LINK_DOWN);
|
||||
|
||||
/* Queue up some writes - device isn't going to read them, so they stay queued. */
|
||||
for (i = 0; i < NUM_WRITES; i++)
|
||||
{
|
||||
|
||||
/* Write packet. */
|
||||
write_packet_udp(&udp_socket_host, &packet_pool_host, DEVICE_IP_ADDRESS, DEVICE_SOCKET_PORT_UDP, num_writes++, "host");
|
||||
|
||||
/* Have we queued 10 packets? */
|
||||
if (i == NUM_WRITES_BEFORE_LINK_DOWN)
|
||||
{
|
||||
|
||||
/* Set the link to down. The _hope_ here is to have the CDC-ECM thread
|
||||
process the link down while we're still writing packets. This
|
||||
should be improved in the future. I don't want to be the poor
|
||||
SOB that has to do it!
|
||||
|
||||
We cheat here by calling a device API from the host. */
|
||||
ux_test_device_class_cdc_ecm_set_link_state(cdc_ecm_device, UX_DEVICE_CLASS_CDC_ECM_LINK_STATE_DOWN);
|
||||
|
||||
while (cdc_ecm_host->ux_host_class_cdc_ecm_link_state != UX_HOST_CLASS_CDC_ECM_LINK_STATE_DOWN)
|
||||
tx_thread_sleep(10);
|
||||
}
|
||||
}
|
||||
|
||||
/* Make sure everything is ok. */
|
||||
UX_TEST_ASSERT(cdc_ecm_host->ux_host_class_cdc_ecm_link_state == UX_HOST_CLASS_CDC_ECM_LINK_STATE_DOWN);
|
||||
NX_PACKET_POOL *packet_pool_host_local = &packet_pool_host;
|
||||
UX_HOST_CLASS_CDC_ECM *cdc_ecm_host_local = cdc_ecm_host;
|
||||
UX_TEST_ASSERT(packet_pool_host.nx_packet_pool_available == pre_write_fail_num_packet_pool_packets_available);
|
||||
|
||||
/* Make sure at least one error was reported. */
|
||||
UX_TEST_ASSERT(ux_test_get_num_actions_left() != 90);
|
||||
|
||||
/* Now clear the error match actions out. */
|
||||
ux_test_clear_main_list_actions();
|
||||
|
||||
/* Run that basic test again. */
|
||||
|
||||
/* Now wait for the link to be up. */
|
||||
host_waiting_for_link_up = 1;
|
||||
UX_TEST_CHECK_SUCCESS(ux_test_wait_for_value_ulong(&cdc_ecm_host->ux_host_class_cdc_ecm_link_state, UX_HOST_CLASS_CDC_ECM_LINK_STATE_UP));
|
||||
|
||||
cdc_ecm_basic_test(BASIC_TEST_HOST, BASIC_TEST_TCP);
|
||||
}
|
||||
|
||||
static void ongoing_writes_test_device()
|
||||
{
|
||||
|
||||
/*** Ongoing writes test. ***/
|
||||
|
||||
/* The host is gonna do all the work. At some point, he'll want the link back
|
||||
up to run the basic test again. */
|
||||
UX_TEST_CHECK_SUCCESS(ux_test_wait_for_value_uchar(&host_waiting_for_link_up, 1));
|
||||
|
||||
/* Set link to up. */
|
||||
ux_test_device_class_cdc_ecm_set_link_state(cdc_ecm_device, UX_DEVICE_CLASS_CDC_ECM_LINK_STATE_UP);
|
||||
|
||||
/* Now do basic test. */
|
||||
cdc_ecm_basic_test(BASIC_TEST_DEVICE, BASIC_TEST_TCP);
|
||||
}
|
||||
|
||||
static void post_init_host()
|
||||
{
|
||||
|
||||
//basic_test_host();
|
||||
ongoing_writes_test_host();
|
||||
}
|
||||
|
||||
static void post_init_device(ULONG input)
|
||||
{
|
||||
|
||||
//basic_test_device();
|
||||
ongoing_writes_test_device();
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
/* This tests the case where the mac address string is too long. This is an
|
||||
error. */
|
||||
|
||||
#include "usbx_ux_test_cdc_ecm.h"
|
||||
|
||||
static unsigned char invalid_mac_address_string_length[] = {
|
||||
|
||||
/* Manufacturer string descriptor : Index 1 - "Express Logic" */
|
||||
0x09, 0x04, 0x01, 0x0c,
|
||||
0x45, 0x78, 0x70, 0x72, 0x65, 0x73, 0x20, 0x4c,
|
||||
0x6f, 0x67, 0x69, 0x63,
|
||||
|
||||
/* Product string descriptor : Index 2 - "EL CDCECM Device" */
|
||||
0x09, 0x04, 0x02, 0x10,
|
||||
0x45, 0x4c, 0x20, 0x43, 0x44, 0x43, 0x45, 0x43,
|
||||
0x4d, 0x20, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65,
|
||||
|
||||
/* Serial Number string descriptor : Index 3 - "0001" */
|
||||
0x09, 0x04, 0x03, 0x04,
|
||||
0x30, 0x30, 0x30, 0x31,
|
||||
|
||||
/* MAC Address string descriptor : Index 4 - "001E5841B878" */
|
||||
0x09, 0x04, 0x04,
|
||||
0x1b, /* This byte is the length of the string. It just needs to be greater than 26 (look in mac_address_get.c). */
|
||||
0x30, 0x30, 0x31, 0x45, 0x35, 0x38,
|
||||
0x34, 0x31, 0x42, 0x38, 0x37, 0x38,
|
||||
0x30, 0x30, 0x31, 0x45, 0x35, 0x38,
|
||||
0x34, 0x31, 0x42, 0x38, 0x37, 0x38,
|
||||
0x37, 0x38, 0x37,
|
||||
|
||||
};
|
||||
|
||||
static DEVICE_INIT_DATA device_init_data = {
|
||||
.string_framework = invalid_mac_address_string_length,
|
||||
.string_framework_length = sizeof(invalid_mac_address_string_length),
|
||||
.dont_register_hcd = 1,
|
||||
};
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_cdc_ecm_mac_address_invalid_length_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running CDC-ECM Mac Address Invalid Length Test..................... ");
|
||||
|
||||
stepinfo("\n");
|
||||
|
||||
ux_test_cdc_ecm_initialize_use_framework(first_unused_memory, &device_init_data);
|
||||
}
|
||||
|
||||
static void post_init_host()
|
||||
{
|
||||
|
||||
int i;
|
||||
|
||||
/* We expect this to fail multiple times since enumeration tries multiple times. */
|
||||
for (i = 0; i < UX_RH_ENUMERATION_RETRY; i++)
|
||||
{
|
||||
|
||||
ux_test_add_action_to_main_list(create_error_match_action(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_DESCRIPTOR_CORRUPTED));
|
||||
}
|
||||
ux_test_add_action_to_main_list(create_error_match_action(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_ROOT_HUB, UX_DEVICE_ENUMERATION_FAILURE));
|
||||
|
||||
/* Enumerate. */
|
||||
UX_TEST_CHECK_SUCCESS(ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize, 0, 0));
|
||||
|
||||
/* The HCD init function put()s the HCD semaphore, so we can do this here. */
|
||||
ux_test_wait_for_enum_thread_completion();
|
||||
|
||||
/* Enumeration should've failed. */
|
||||
UX_TEST_ASSERT(ux_test_check_actions_empty());
|
||||
UX_TEST_ASSERT(cdc_ecm_host_from_system_change_function == UX_NULL);
|
||||
}
|
||||
|
||||
static void post_init_device()
|
||||
{
|
||||
}
|
78
test/regression/usbx_cdc_ecm_mac_address_test.c
Normal file
78
test/regression/usbx_cdc_ecm_mac_address_test.c
Normal file
@ -0,0 +1,78 @@
|
||||
/* This tests general cases in the mac address string like hexadecimal values. */
|
||||
|
||||
#include "usbx_ux_test_cdc_ecm.h"
|
||||
|
||||
static unsigned char mac_address_test_string_framework[] = {
|
||||
|
||||
/* Manufacturer string descriptor : Index 1 - "Express Logic" */
|
||||
0x09, 0x04, 0x01, 0x0c,
|
||||
0x45, 0x78, 0x70, 0x72, 0x65, 0x73, 0x20, 0x4c,
|
||||
0x6f, 0x67, 0x69, 0x63,
|
||||
|
||||
/* Product string descriptor : Index 2 - "EL CDCECM Device" */
|
||||
0x09, 0x04, 0x02, 0x10,
|
||||
0x45, 0x4c, 0x20, 0x43, 0x44, 0x43, 0x45, 0x43,
|
||||
0x4d, 0x20, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65,
|
||||
|
||||
/* Serial Number string descriptor : Index 3 - "0001" */
|
||||
0x09, 0x04, 0x03, 0x04,
|
||||
0x30, 0x30, 0x30, 0x31,
|
||||
|
||||
/* MAC Address string descriptor : Index 4 - "001E5841B878" */
|
||||
0x09, 0x04, 0x04, 0x0C,
|
||||
'A', 'A', /* Test capital upper and lower element. */
|
||||
'0', '1',
|
||||
'2', '3',
|
||||
'4', 'b',
|
||||
'c', 'D',
|
||||
'e', 'f',
|
||||
|
||||
};
|
||||
|
||||
static DEVICE_INIT_DATA device_init_data = {
|
||||
.string_framework = mac_address_test_string_framework,
|
||||
.string_framework_length = sizeof(mac_address_test_string_framework),
|
||||
};
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_cdc_ecm_mac_address_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running CDC-ECM Mac Address Test.................................... ");
|
||||
|
||||
stepinfo("\n");
|
||||
|
||||
ux_test_cdc_ecm_initialize_use_framework(first_unused_memory, &device_init_data);
|
||||
}
|
||||
|
||||
static void post_init_host()
|
||||
{
|
||||
/* Ensure the mac address is correct. */
|
||||
UX_TEST_ASSERT(cdc_ecm_host->ux_host_class_cdc_ecm_node_id[0] == 0xaa);
|
||||
UX_TEST_ASSERT(cdc_ecm_host->ux_host_class_cdc_ecm_node_id[1] == 0x01);
|
||||
UX_TEST_ASSERT(cdc_ecm_host->ux_host_class_cdc_ecm_node_id[2] == 0x23);
|
||||
UX_TEST_ASSERT(cdc_ecm_host->ux_host_class_cdc_ecm_node_id[3] == 0x4b);
|
||||
UX_TEST_ASSERT(cdc_ecm_host->ux_host_class_cdc_ecm_node_id[4] == 0xcd);
|
||||
UX_TEST_ASSERT(cdc_ecm_host->ux_host_class_cdc_ecm_node_id[5] == 0xef);
|
||||
|
||||
/* Configuration descriptor invalid while parsing MAC address */
|
||||
/* descriptor_length < 3 */
|
||||
default_device_framework[18] = 0;
|
||||
UX_TEST_ASSERT(UX_DESCRIPTOR_CORRUPTED == _ux_host_class_cdc_ecm_mac_address_get(cdc_ecm_host));
|
||||
/* descriptor_length > total_configuration_length */
|
||||
default_device_framework[18] = 0xFF;
|
||||
UX_TEST_ASSERT(UX_DESCRIPTOR_CORRUPTED == _ux_host_class_cdc_ecm_mac_address_get(cdc_ecm_host));
|
||||
/* Restore. */
|
||||
default_device_framework[18] = 9;
|
||||
UX_TEST_ASSERT(UX_SUCCESS == _ux_host_class_cdc_ecm_mac_address_get(cdc_ecm_host));
|
||||
|
||||
}
|
||||
|
||||
static void post_init_device()
|
||||
{
|
||||
}
|
111
test/regression/usbx_cdc_ecm_no_control_interface_test.c
Normal file
111
test/regression/usbx_cdc_ecm_no_control_interface_test.c
Normal file
@ -0,0 +1,111 @@
|
||||
/* This test tests the case where there is no control interface. */
|
||||
|
||||
#include "usbx_ux_test_cdc_ecm.h"
|
||||
|
||||
static unsigned char no_control_interface_framework[] = {
|
||||
|
||||
/* Device Descriptor */
|
||||
0x12, /* bLength */
|
||||
0x01, /* bDescriptorType */
|
||||
0x10, 0x01, /* bcdUSB */
|
||||
0xef, /* bDeviceClass - Depends on bDeviceSubClass */
|
||||
0x02, /* bDeviceSubClass - Depends on bDeviceProtocol */
|
||||
0x01, /* bDeviceProtocol - There's an IAD */
|
||||
0x40, /* bMaxPacketSize0 */
|
||||
0x70, 0x07, /* idVendor */
|
||||
0x42, 0x10, /* idProduct */
|
||||
0x00, 0x01, /* bcdDevice */
|
||||
0x01, /* iManufacturer */
|
||||
0x02, /* iProduct */
|
||||
0x03, /* iSerialNumber */
|
||||
0x01, /* bNumConfigurations */
|
||||
|
||||
/* Configuration Descriptor */
|
||||
0x09, /* bLength */
|
||||
0x02, /* bDescriptorType */
|
||||
0x29, 0x00, /* wTotalLength */
|
||||
0x02, /* bNumInterfaces */
|
||||
0x01, /* bConfigurationValue */
|
||||
0x00, /* iConfiguration */
|
||||
0xc0, /* bmAttributes - Self-powered */
|
||||
0x00, /* bMaxPower */
|
||||
|
||||
/* Interface Descriptor */
|
||||
0x09, /* bLength */
|
||||
0x04, /* bDescriptorType */
|
||||
0x01, /* bInterfaceNumber */
|
||||
0x00, /* bAlternateSetting */
|
||||
0x00, /* bNumEndpoints */
|
||||
0x0a, /* bInterfaceClass - CDC - Data */
|
||||
0x00, /* bInterfaceSubClass - Should be 0x00 */
|
||||
0x00, /* bInterfaceProtocol - No class specific protocol required */
|
||||
0x00, /* iInterface */
|
||||
|
||||
/* Interface Descriptor */
|
||||
0x09, /* bLength */
|
||||
0x04, /* bDescriptorType */
|
||||
0x01, /* bInterfaceNumber */
|
||||
0x01, /* bAlternateSetting */
|
||||
0x02, /* bNumEndpoints */
|
||||
0x0a, /* bInterfaceClass - CDC - Data */
|
||||
0x00, /* bInterfaceSubClass - Should be 0x00 */
|
||||
0x00, /* bInterfaceProtocol - No class specific protocol required */
|
||||
0x00, /* iInterface */
|
||||
|
||||
/* Endpoint Descriptor */
|
||||
0x07, /* bLength */
|
||||
0x05, /* bDescriptorType */
|
||||
0x05, /* bEndpointAddress */
|
||||
0x02, /* bmAttributes - Bulk */
|
||||
0x40, 0x00, /* wMaxPacketSize */
|
||||
0x00, /* bInterval */
|
||||
|
||||
/* Endpoint Descriptor */
|
||||
0x07, /* bLength */
|
||||
0x05, /* bDescriptorType */
|
||||
0x86, /* bEndpointAddress */
|
||||
0x02, /* bmAttributes - Bulk */
|
||||
0x40, 0x00, /* wMaxPacketSize */
|
||||
0x00, /* bInterval */
|
||||
|
||||
};
|
||||
|
||||
static DEVICE_INIT_DATA device_init_data = { no_control_interface_framework, sizeof(no_control_interface_framework), .dont_register_hcd = 1 };
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_cdc_ecm_no_control_interface_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running CDC-ECM No Control Interface Test........................... ");
|
||||
|
||||
stepinfo("\n");
|
||||
|
||||
ux_test_cdc_ecm_initialize_use_framework(first_unused_memory, &device_init_data);
|
||||
}
|
||||
|
||||
static void post_init_host()
|
||||
{
|
||||
|
||||
/* We expect this to fail multiple times since enumeration tries multiple times. */
|
||||
ux_test_add_action_to_main_list_multiple(create_error_match_action(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_DESCRIPTOR_CORRUPTED), 3);
|
||||
ux_test_add_action_to_main_list(create_error_match_action(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_ROOT_HUB, UX_DEVICE_ENUMERATION_FAILURE));
|
||||
|
||||
/* Begin enumeration. */
|
||||
UX_TEST_CHECK_SUCCESS(ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize, 0, 0));
|
||||
|
||||
/* The HCD init function put()s the HCD semaphore, so we can do this here. */
|
||||
ux_test_wait_for_enum_thread_completion();
|
||||
|
||||
/* Enumeration should've failed. */
|
||||
UX_TEST_ASSERT(ux_test_check_actions_empty());
|
||||
UX_TEST_ASSERT(cdc_ecm_host_from_system_change_function == UX_NULL);
|
||||
}
|
||||
|
||||
static void post_init_device()
|
||||
{
|
||||
}
|
164
test/regression/usbx_cdc_ecm_no_functional_descriptor_test.c
Normal file
164
test/regression/usbx_cdc_ecm_no_functional_descriptor_test.c
Normal file
@ -0,0 +1,164 @@
|
||||
/* This tests the case where there no functional descriptor. There should be a
|
||||
functional descriptor, so this is an error. */
|
||||
|
||||
#include "usbx_ux_test_cdc_ecm.h"
|
||||
|
||||
static unsigned char no_function_descriptor_framework[] = {
|
||||
|
||||
/* Device Descriptor */
|
||||
0x12, /* bLength */
|
||||
0x01, /* bDescriptorType */
|
||||
0x10, 0x01, /* bcdUSB */
|
||||
0xef, /* bDeviceClass - Depends on bDeviceSubClass */
|
||||
0x02, /* bDeviceSubClass - Depends on bDeviceProtocol */
|
||||
0x01, /* bDeviceProtocol - There's an IAD */
|
||||
0x40, /* bMaxPacketSize0 */
|
||||
0x70, 0x07, /* idVendor */
|
||||
0x42, 0x10, /* idProduct */
|
||||
0x00, 0x01, /* bcdDevice */
|
||||
0x01, /* iManufacturer */
|
||||
0x02, /* iProduct */
|
||||
0x03, /* iSerialNumber */
|
||||
0x01, /* bNumConfigurations */
|
||||
|
||||
/* Configuration Descriptor */
|
||||
0x09, /* bLength */
|
||||
0x02, /* bDescriptorType */
|
||||
0x4b, 0x00, /* wTotalLength */
|
||||
0x02, /* bNumInterfaces */
|
||||
0x01, /* bConfigurationValue */
|
||||
0x00, /* iConfiguration */
|
||||
0xc0, /* bmAttributes - Self-powered */
|
||||
0x00, /* bMaxPower */
|
||||
|
||||
/* Interface Association Descriptor */
|
||||
0x08, /* bLength */
|
||||
0x0b, /* bDescriptorType */
|
||||
0x00, /* bFirstInterface */
|
||||
0x02, /* bInterfaceCount */
|
||||
0x02, /* bFunctionClass - CDC - Communication */
|
||||
0x06, /* bFunctionSubClass - ECM */
|
||||
0x00, /* bFunctionProtocol - No class specific protocol required */
|
||||
0x00, /* iFunction */
|
||||
|
||||
/* Interface Descriptor */
|
||||
0x09, /* bLength */
|
||||
0x04, /* bDescriptorType */
|
||||
0x00, /* bInterfaceNumber */
|
||||
0x00, /* bAlternateSetting */
|
||||
0x01, /* bNumEndpoints */
|
||||
0x02, /* bInterfaceClass - CDC - Communication */
|
||||
0x06, /* bInterfaceSubClass - ECM */
|
||||
0x00, /* bInterfaceProtocol - No class specific protocol required */
|
||||
0x00, /* iInterface */
|
||||
|
||||
/* CDC Header Functional Descriptor */
|
||||
0x05, /* bLength */
|
||||
0x24, /* bDescriptorType */
|
||||
0x00, /* bDescriptorSubType */
|
||||
0x10, 0x01, /* bcdCDC */
|
||||
|
||||
/* CDC Union Functional Descriptor */
|
||||
0x05, /* bLength */
|
||||
0x24, /* bDescriptorType */
|
||||
0x06, /* bDescriptorSubType */
|
||||
0x00, /* bmMasterInterface */
|
||||
0x01, /* bmSlaveInterface0 */
|
||||
|
||||
/* Endpoint Descriptor */
|
||||
0x07, /* bLength */
|
||||
0x05, /* bDescriptorType */
|
||||
0x83, /* bEndpointAddress */
|
||||
0x03, /* bmAttributes - Interrupt */
|
||||
0x08, 0x00, /* wMaxPacketSize */
|
||||
0x08, /* bInterval */
|
||||
|
||||
/* Interface Descriptor */
|
||||
0x09, /* bLength */
|
||||
0x04, /* bDescriptorType */
|
||||
0x01, /* bInterfaceNumber */
|
||||
0x00, /* bAlternateSetting */
|
||||
0x00, /* bNumEndpoints */
|
||||
0x0a, /* bInterfaceClass - CDC - Data */
|
||||
0x00, /* bInterfaceSubClass - Should be 0x00 */
|
||||
0x00, /* bInterfaceProtocol - No class specific protocol required */
|
||||
0x00, /* iInterface */
|
||||
|
||||
/* Interface Descriptor */
|
||||
0x09, /* bLength */
|
||||
0x04, /* bDescriptorType */
|
||||
0x01, /* bInterfaceNumber */
|
||||
0x01, /* bAlternateSetting */
|
||||
0x02, /* bNumEndpoints */
|
||||
0x0a, /* bInterfaceClass - CDC - Data */
|
||||
0x00, /* bInterfaceSubClass - Should be 0x00 */
|
||||
0x00, /* bInterfaceProtocol - No class specific protocol required */
|
||||
0x00, /* iInterface */
|
||||
|
||||
/* Endpoint Descriptor */
|
||||
0x07, /* bLength */
|
||||
0x05, /* bDescriptorType */
|
||||
0x02, /* bEndpointAddress */
|
||||
0x02, /* bmAttributes - Bulk */
|
||||
0x40, 0x00, /* wMaxPacketSize */
|
||||
0x00, /* bInterval */
|
||||
|
||||
/* Endpoint Descriptor */
|
||||
0x07, /* bLength */
|
||||
0x05, /* bDescriptorType */
|
||||
0x81, /* bEndpointAddress */
|
||||
0x02, /* bmAttributes - Bulk */
|
||||
0x40, 0x00, /* wMaxPacketSize */
|
||||
0x00, /* bInterval */
|
||||
|
||||
};
|
||||
|
||||
static DEVICE_INIT_DATA device_init_data = {
|
||||
.framework = no_function_descriptor_framework,
|
||||
.framework_length = sizeof(no_function_descriptor_framework),
|
||||
.dont_register_hcd = 1,
|
||||
};
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_cdc_ecm_no_functional_descriptor_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running CDC-ECM No Functional Descriptor Test....................... ");
|
||||
|
||||
stepinfo("\n");
|
||||
|
||||
ux_test_cdc_ecm_initialize_use_framework(first_unused_memory, &device_init_data);
|
||||
}
|
||||
|
||||
static void post_init_host()
|
||||
{
|
||||
|
||||
int i;
|
||||
|
||||
/* We expect this to fail multiple times since enumeration tries multiple times. */
|
||||
for (i = 0; i < UX_RH_ENUMERATION_RETRY; i++)
|
||||
{
|
||||
|
||||
ux_test_add_action_to_main_list(create_error_match_action(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_DESCRIPTOR_CORRUPTED));
|
||||
}
|
||||
ux_test_add_action_to_main_list(create_error_match_action(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_ROOT_HUB, UX_DEVICE_ENUMERATION_FAILURE));
|
||||
|
||||
/* Enumerate. */
|
||||
UX_TEST_CHECK_SUCCESS(ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize, 0, 0));
|
||||
|
||||
/* The HCD init function put()s the HCD semaphore, so we can do this here. */
|
||||
ux_test_wait_for_enum_thread_completion();
|
||||
|
||||
/* Enumeration should've failed. */
|
||||
UX_TEST_ASSERT(ux_test_check_actions_empty());
|
||||
UX_TEST_ASSERT(cdc_ecm_host_from_system_change_function == UX_NULL);
|
||||
}
|
||||
|
||||
static void post_init_device()
|
||||
{
|
||||
}
|
@ -0,0 +1,176 @@
|
||||
/* This tests the case where the default data interface has zero endpoints, and
|
||||
the interface right after it is a non-data interface. Host should report error. */
|
||||
|
||||
#include "usbx_ux_test_cdc_ecm.h"
|
||||
|
||||
static unsigned char non_data_interface_after_zero_endpoint_data_interface_framework[] = {
|
||||
|
||||
/* Device Descriptor */
|
||||
0x12, /* bLength */
|
||||
0x01, /* bDescriptorType */
|
||||
0x10, 0x01, /* bcdUSB */
|
||||
0xef, /* bDeviceClass - Depends on bDeviceSubClass */
|
||||
0x02, /* bDeviceSubClass - Depends on bDeviceProtocol */
|
||||
0x01, /* bDeviceProtocol - There's an IAD */
|
||||
0x40, /* bMaxPacketSize0 */
|
||||
0x70, 0x07, /* idVendor */
|
||||
0x42, 0x10, /* idProduct */
|
||||
0x00, 0x01, /* bcdDevice */
|
||||
0x01, /* iManufacturer */
|
||||
0x02, /* iProduct */
|
||||
0x03, /* iSerialNumber */
|
||||
0x01, /* bNumConfigurations */
|
||||
|
||||
/* Configuration Descriptor */
|
||||
0x09, /* bLength */
|
||||
0x02, /* bDescriptorType */
|
||||
0x5f, 0x00, /* wTotalLength */
|
||||
0x02, /* bNumInterfaces */
|
||||
0x01, /* bConfigurationValue */
|
||||
0x00, /* iConfiguration */
|
||||
0xc0, /* bmAttributes - Self-powered */
|
||||
0x00, /* bMaxPower */
|
||||
|
||||
/* Interface Association Descriptor */
|
||||
0x08, /* bLength */
|
||||
0x0b, /* bDescriptorType */
|
||||
0x00, /* bFirstInterface */
|
||||
0x02, /* bInterfaceCount */
|
||||
0x02, /* bFunctionClass - CDC - Communication */
|
||||
0x06, /* bFunctionSubClass - ECM */
|
||||
0x00, /* bFunctionProtocol - No class specific protocol required */
|
||||
0x00, /* iFunction */
|
||||
|
||||
/* Interface Descriptor */
|
||||
0x09, /* bLength */
|
||||
0x04, /* bDescriptorType */
|
||||
0x00, /* bInterfaceNumber */
|
||||
0x00, /* bAlternateSetting */
|
||||
0x01, /* bNumEndpoints */
|
||||
0x02, /* bInterfaceClass - CDC - Communication */
|
||||
0x06, /* bInterfaceSubClass - ECM */
|
||||
0x00, /* bInterfaceProtocol - No class specific protocol required */
|
||||
0x00, /* iInterface */
|
||||
|
||||
/* CDC Header Functional Descriptor */
|
||||
0x05, /* bLength */
|
||||
0x24, /* bDescriptorType */
|
||||
0x00, /* bDescriptorSubType */
|
||||
0x10, 0x01, /* bcdCDC */
|
||||
|
||||
/* CDC ECM Functional Descriptor */
|
||||
0x0d, /* bLength */
|
||||
0x24, /* bDescriptorType */
|
||||
0x0f, /* bDescriptorSubType */
|
||||
0x04, /* iMACAddress */
|
||||
0x00, 0x00, 0x00, 0x00, /* bmEthernetStatistics */
|
||||
0xea, 0x05, /* wMaxSegmentSize */
|
||||
0x00, 0x00, /* wNumberMCFilters */
|
||||
0x00, /* bNumberPowerFilters */
|
||||
|
||||
/* CDC Union Functional Descriptor */
|
||||
0x05, /* bLength */
|
||||
0x24, /* bDescriptorType */
|
||||
0x06, /* bDescriptorSubType */
|
||||
0x00, /* bmMasterInterface */
|
||||
0x01, /* bmSlaveInterface0 */
|
||||
|
||||
/* Endpoint Descriptor */
|
||||
0x07, /* bLength */
|
||||
0x05, /* bDescriptorType */
|
||||
0x83, /* bEndpointAddress */
|
||||
0x03, /* bmAttributes - Interrupt */
|
||||
0x08, 0x00, /* wMaxPacketSize */
|
||||
0x08, /* bInterval */
|
||||
|
||||
/* Interface Descriptor */
|
||||
0x09, /* bLength */
|
||||
0x04, /* bDescriptorType */
|
||||
0x01, /* bInterfaceNumber */
|
||||
0x00, /* bAlternateSetting */
|
||||
0x00, /* bNumEndpoints */
|
||||
0x0a, /* bInterfaceClass - CDC - Data */
|
||||
0x00, /* bInterfaceSubClass - Should be 0x00 */
|
||||
0x00, /* bInterfaceProtocol - No class specific protocol required */
|
||||
0x00, /* iInterface */
|
||||
|
||||
/* Interface Descriptor */
|
||||
0x09, /* bLength */
|
||||
0x04, /* bDescriptorType */
|
||||
0x00, /* bInterfaceNumber */
|
||||
0x00, /* bAlternateSetting */
|
||||
0x03, /* bNumEndpoints */
|
||||
0x08, /* bInterfaceClass - Mass Storage */
|
||||
0x06, /* bInterfaceSubClass */
|
||||
0x50, /* bInterfaceProtocol */
|
||||
0x00, /* iInterface */
|
||||
|
||||
/* Endpoint Descriptor */
|
||||
0x07, /* bLength */
|
||||
0x05, /* bDescriptorType */
|
||||
0x81, /* bEndpointAddress */
|
||||
0x02, /* bmAttributes - Bulk */
|
||||
0x40, 0x00, /* wMaxPacketSize */
|
||||
0x00, /* bInterval */
|
||||
|
||||
/* Endpoint Descriptor */
|
||||
0x07, /* bLength */
|
||||
0x05, /* bDescriptorType */
|
||||
0x02, /* bEndpointAddress */
|
||||
0x02, /* bmAttributes - Bulk */
|
||||
0x40, 0x00, /* wMaxPacketSize */
|
||||
0x00, /* bInterval */
|
||||
|
||||
/* Endpoint Descriptor */
|
||||
0x07, /* bLength */
|
||||
0x05, /* bDescriptorType */
|
||||
0x84, /* bEndpointAddress */
|
||||
0x03, /* bmAttributes - Interrupt */
|
||||
0x40, 0x00, /* wMaxPacketSize */
|
||||
0x01, /* bInterval */
|
||||
|
||||
};
|
||||
|
||||
static DEVICE_INIT_DATA device_init_data = {
|
||||
.framework = non_data_interface_after_zero_endpoint_data_interface_framework,
|
||||
.framework_length = sizeof(non_data_interface_after_zero_endpoint_data_interface_framework),
|
||||
.dont_register_hcd = 1,
|
||||
};
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_cdc_ecm_non_data_interface_after_zero_endpoint_data_interface_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running CDC-ECM Non-Data Interface After Zero... Test............... ");
|
||||
|
||||
stepinfo("\n");
|
||||
|
||||
ux_test_cdc_ecm_initialize_use_framework(first_unused_memory, &device_init_data);
|
||||
}
|
||||
|
||||
static void post_init_host()
|
||||
{
|
||||
|
||||
/* We expect this to fail multiple times since enumeration tries multiple times. */
|
||||
ux_test_add_action_to_main_list_multiple(create_error_match_action(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_DESCRIPTOR_CORRUPTED), 3);
|
||||
ux_test_add_action_to_main_list(create_error_match_action(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_ROOT_HUB, UX_DEVICE_ENUMERATION_FAILURE));
|
||||
|
||||
/* Enumerate. */
|
||||
UX_TEST_CHECK_SUCCESS(ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize, 0, 0));
|
||||
|
||||
/* The HCD init function put()s the HCD semaphore, so we can do this here. */
|
||||
ux_test_wait_for_enum_thread_completion();
|
||||
|
||||
/* Enumeration should've failed. */
|
||||
UX_TEST_ASSERT(ux_test_check_actions_empty());
|
||||
UX_TEST_ASSERT(cdc_ecm_host_from_system_change_function == UX_NULL);
|
||||
}
|
||||
|
||||
static void post_init_device()
|
||||
{
|
||||
}
|
77
test/regression/usbx_cdc_ecm_nx_packet_chain_test.c
Normal file
77
test/regression/usbx_cdc_ecm_nx_packet_chain_test.c
Normal file
@ -0,0 +1,77 @@
|
||||
/* Include necessary system files. */
|
||||
|
||||
#define TEST_NX_PACKET_CHAIN
|
||||
#define BASIC_TEST_NUM_ITERATIONS 5
|
||||
#define BASIC_TEST_NUM_PACKETS_PER_ITERATION 5
|
||||
#include "usbx_ux_test_cdc_ecm.h"
|
||||
|
||||
static UCHAR device_is_finished;
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_cdc_ecm_nx_packet_chain_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running CDC ECM NX Packet Chain Test................................ ");
|
||||
|
||||
stepinfo("\n");
|
||||
|
||||
#if (UX_DEVICE_ENDPOINT_BUFFER_OWNER == 1) && defined(UX_DEVICE_CLASS_CDC_ECM_ZERO_COPY)
|
||||
printf("Skipped for Zero Copy mode\n");
|
||||
#else
|
||||
ux_test_cdc_ecm_initialize(first_unused_memory);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void post_init_host()
|
||||
{
|
||||
UCHAR *temp_buf = UX_NULL;
|
||||
ULONG n_available;
|
||||
int i;
|
||||
int device_num_writes = 0;
|
||||
|
||||
/*======== RX buffer allocation fail test. */
|
||||
|
||||
if (cdc_ecm_host->ux_host_class_cdc_ecm_receive_buffer)
|
||||
temp_buf = cdc_ecm_host->ux_host_class_cdc_ecm_receive_buffer;
|
||||
tx_thread_suspend(&cdc_ecm_host -> ux_host_class_cdc_ecm_thread);
|
||||
ux_test_add_action_to_main_list(create_error_match_action(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_MEMORY_INSUFFICIENT));
|
||||
ux_test_utility_sim_mem_allocate_until_flagged(UX_HOST_CLASS_CDC_ECM_NX_PAYLOAD_SIZE, UX_CACHE_SAFE_MEMORY);
|
||||
cdc_ecm_host -> ux_host_class_cdc_ecm_receive_buffer = UX_NULL;
|
||||
tx_thread_resume(&cdc_ecm_host -> ux_host_class_cdc_ecm_thread);
|
||||
UX_TEST_CHECK_SUCCESS(ux_test_wait_for_empty_actions());
|
||||
if (temp_buf)
|
||||
cdc_ecm_host -> ux_host_class_cdc_ecm_receive_buffer = temp_buf;
|
||||
ux_test_utility_sim_mem_free_all_flagged(UX_CACHE_SAFE_MEMORY);
|
||||
|
||||
|
||||
/* Running UDP test. */
|
||||
stepinfo("running UDP test.\n");
|
||||
cdc_ecm_basic_test(BASIC_TEST_HOST, BASIC_TEST_UDP);
|
||||
|
||||
/* Wait for device to finish. */
|
||||
UX_TEST_CHECK_SUCCESS(ux_test_wait_for_value_uchar(&device_is_finished, UX_TRUE));
|
||||
|
||||
/* Disconnect. */
|
||||
ux_test_disconnect_slave_and_host_wait_for_enum_completion();
|
||||
|
||||
/* Connect with null system change function. */
|
||||
_ux_system_host->ux_system_host_change_function = UX_NULL;
|
||||
|
||||
/* Connect. */
|
||||
ux_test_connect_slave_and_host_wait_for_enum_completion();
|
||||
|
||||
/* We're done. */
|
||||
}
|
||||
|
||||
static void post_init_device()
|
||||
{
|
||||
|
||||
/* Running UDP test. */
|
||||
cdc_ecm_basic_test(BASIC_TEST_DEVICE, BASIC_TEST_UDP);
|
||||
device_is_finished = UX_TRUE;
|
||||
}
|
@ -0,0 +1,141 @@
|
||||
/* This tests the case where there is only one default data interface and it
|
||||
has no endpoints. Host should report an error. */
|
||||
|
||||
#include "usbx_ux_test_cdc_ecm.h"
|
||||
|
||||
static unsigned char one_data_interface_with_no_endpoints_framework[] = {
|
||||
|
||||
/* Device Descriptor */
|
||||
0x12, /* bLength */
|
||||
0x01, /* bDescriptorType */
|
||||
0x10, 0x01, /* bcdUSB */
|
||||
0xef, /* bDeviceClass - Depends on bDeviceSubClass */
|
||||
0x02, /* bDeviceSubClass - Depends on bDeviceProtocol */
|
||||
0x01, /* bDeviceProtocol - There's an IAD */
|
||||
0x40, /* bMaxPacketSize0 */
|
||||
0x70, 0x07, /* idVendor */
|
||||
0x42, 0x10, /* idProduct */
|
||||
0x00, 0x01, /* bcdDevice */
|
||||
0x01, /* iManufacturer */
|
||||
0x02, /* iProduct */
|
||||
0x03, /* iSerialNumber */
|
||||
0x01, /* bNumConfigurations */
|
||||
|
||||
/* Configuration Descriptor */
|
||||
0x09, /* bLength */
|
||||
0x02, /* bDescriptorType */
|
||||
0x41, 0x00, /* wTotalLength */
|
||||
0x02, /* bNumInterfaces */
|
||||
0x01, /* bConfigurationValue */
|
||||
0x00, /* iConfiguration */
|
||||
0xc0, /* bmAttributes - Self-powered */
|
||||
0x00, /* bMaxPower */
|
||||
|
||||
/* Interface Association Descriptor */
|
||||
0x08, /* bLength */
|
||||
0x0b, /* bDescriptorType */
|
||||
0x00, /* bFirstInterface */
|
||||
0x02, /* bInterfaceCount */
|
||||
0x02, /* bFunctionClass - CDC - Communication */
|
||||
0x06, /* bFunctionSubClass - ECM */
|
||||
0x00, /* bFunctionProtocol - No class specific protocol required */
|
||||
0x00, /* iFunction */
|
||||
|
||||
/* Interface Descriptor */
|
||||
0x09, /* bLength */
|
||||
0x04, /* bDescriptorType */
|
||||
0x00, /* bInterfaceNumber */
|
||||
0x00, /* bAlternateSetting */
|
||||
0x01, /* bNumEndpoints */
|
||||
0x02, /* bInterfaceClass - CDC - Communication */
|
||||
0x06, /* bInterfaceSubClass - ECM */
|
||||
0x00, /* bInterfaceProtocol - No class specific protocol required */
|
||||
0x00, /* iInterface */
|
||||
|
||||
/* CDC Header Functional Descriptor */
|
||||
0x05, /* bLength */
|
||||
0x24, /* bDescriptorType */
|
||||
0x00, /* bDescriptorSubType */
|
||||
0x10, 0x01, /* bcdCDC */
|
||||
|
||||
/* CDC ECM Functional Descriptor */
|
||||
0x0d, /* bLength */
|
||||
0x24, /* bDescriptorType */
|
||||
0x0f, /* bDescriptorSubType */
|
||||
0x04, /* iMACAddress */
|
||||
0x00, 0x00, 0x00, 0x00, /* bmEthernetStatistics */
|
||||
0xea, 0x05, /* wMaxSegmentSize */
|
||||
0x00, 0x00, /* wNumberMCFilters */
|
||||
0x00, /* bNumberPowerFilters */
|
||||
|
||||
/* CDC Union Functional Descriptor */
|
||||
0x05, /* bLength */
|
||||
0x24, /* bDescriptorType */
|
||||
0x06, /* bDescriptorSubType */
|
||||
0x00, /* bmMasterInterface */
|
||||
0x01, /* bmSlaveInterface0 */
|
||||
|
||||
/* Endpoint Descriptor */
|
||||
0x07, /* bLength */
|
||||
0x05, /* bDescriptorType */
|
||||
0x83, /* bEndpointAddress */
|
||||
0x03, /* bmAttributes - Interrupt */
|
||||
0x08, 0x00, /* wMaxPacketSize */
|
||||
0x08, /* bInterval */
|
||||
|
||||
/* Interface Descriptor */
|
||||
0x09, /* bLength */
|
||||
0x04, /* bDescriptorType */
|
||||
0x01, /* bInterfaceNumber */
|
||||
0x00, /* bAlternateSetting */
|
||||
0x00, /* bNumEndpoints */
|
||||
0x0a, /* bInterfaceClass - CDC - Data */
|
||||
0x00, /* bInterfaceSubClass - Should be 0x00 */
|
||||
0x00, /* bInterfaceProtocol - No class specific protocol required */
|
||||
0x00, /* iInterface */
|
||||
|
||||
};
|
||||
|
||||
static DEVICE_INIT_DATA device_init_data = {
|
||||
.framework = one_data_interface_with_no_endpoints_framework,
|
||||
.framework_length = sizeof(one_data_interface_with_no_endpoints_framework),
|
||||
.dont_register_hcd = 1,
|
||||
};
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_cdc_ecm_one_data_interface_with_no_endpoints_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running CDC-ECM One Data Interface With No Endpoints Test........... ");
|
||||
|
||||
stepinfo("\n");
|
||||
|
||||
ux_test_cdc_ecm_initialize_use_framework(first_unused_memory, &device_init_data);
|
||||
}
|
||||
|
||||
static void post_init_host()
|
||||
{
|
||||
|
||||
/* We expect this to fail multiple times since enumeration tries multiple times. */
|
||||
ux_test_add_action_to_main_list_multiple(create_error_match_action(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_DESCRIPTOR_CORRUPTED), 3);
|
||||
ux_test_add_action_to_main_list(create_error_match_action(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_ROOT_HUB, UX_DEVICE_ENUMERATION_FAILURE));
|
||||
|
||||
/* Enumerate. */
|
||||
UX_TEST_CHECK_SUCCESS(ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize, 0, 0));
|
||||
|
||||
/* The HCD init function put()s the HCD semaphore, so we can do this here. */
|
||||
ux_test_wait_for_enum_thread_completion();
|
||||
|
||||
/* Enumeration should've failed. */
|
||||
UX_TEST_ASSERT(ux_test_check_actions_empty());
|
||||
UX_TEST_ASSERT(cdc_ecm_host_from_system_change_function == UX_NULL);
|
||||
}
|
||||
|
||||
static void post_init_device()
|
||||
{
|
||||
}
|
400
test/regression/usbx_class_device_enumeration_test.c
Normal file
400
test/regression/usbx_class_device_enumeration_test.c
Normal file
@ -0,0 +1,400 @@
|
||||
/* This test is designed to test the simple dpump host/device class operation. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
#include "ux_api.h"
|
||||
#include "ux_system.h"
|
||||
#include "ux_utility.h"
|
||||
#include "ux_host_class_dummy.h"
|
||||
#include "ux_device_class_dummy.h"
|
||||
#include "ux_test.h"
|
||||
|
||||
|
||||
/* Define USBX demo constants. */
|
||||
|
||||
#define UX_DEMO_STACK_SIZE 4096
|
||||
#define UX_DEMO_BUFFER_SIZE 2048
|
||||
#define UX_DEMO_RUN 1
|
||||
#define UX_DEMO_MEMORY_SIZE (64*1024)
|
||||
|
||||
|
||||
/* Define the counters used in the demo application... */
|
||||
|
||||
static ULONG thread_0_counter;
|
||||
static ULONG thread_1_counter;
|
||||
static ULONG error_counter;
|
||||
|
||||
|
||||
/* Define USBX demo global variables. */
|
||||
|
||||
static UX_HOST_CLASS *class_driver;
|
||||
static UX_HOST_CLASS_DUMMY *dummy;
|
||||
static UX_DEVICE_CLASS_DUMMY *dummy_slave;
|
||||
|
||||
static UINT expected_error;
|
||||
|
||||
#define _W0(w) ( (w) & 0xFF)
|
||||
#define _W1(w) (((w) >> 8) & 0xFF)
|
||||
|
||||
#define _DEVICE_DESCRIPTOR(cls, sub, protocol, pktsize, vid, pid, n_cfg) \
|
||||
0x12, 0x01, 0x10, 0x01, \
|
||||
(cls), (sub), (protocol), (pktsize), \
|
||||
_W0(vid), _W1(vid), _W0(pid), _W1(pid), \
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, (n_cfg),
|
||||
|
||||
#define _QUALIFIER_DESCRIPTOR(cls, sub, protocol, n_cfg) \
|
||||
0x0a, 0x06, 0x00, 0x02, \
|
||||
(cls), (sub), (protocol), 0x40, (n_cfg), 0x00,
|
||||
|
||||
#define _CONFIGURATION_DESCRIPTOR(total_len, n_ifc, cfg_val) \
|
||||
0x09, 0x02, _W0(total_len), _W1(total_len), (n_ifc), (cfg_val), \
|
||||
0x00, 0xc0, 0x32,
|
||||
|
||||
#define _INTERFACE_DESCRIPTOR(ifc_n, alt, n_ep, cls, sub, protocol) \
|
||||
0x09, 0x04, (ifc_n), (alt), (n_ep), (cls), (sub), (protocol), 0x00,
|
||||
|
||||
#define _ENDPOINT_DESCRIPTOR(addr, attr, pktsize, interval) \
|
||||
0x07, 0x05, (addr), (attr), _W0(pktsize), _W1(pktsize), (interval),
|
||||
|
||||
#define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED sizeof(device_framework_full_speed)
|
||||
static UCHAR device_framework_full_speed[] = {
|
||||
_DEVICE_DESCRIPTOR(0x99, 0x99, 0x99, 8, 0x08EC, 0x0001, 1)
|
||||
_CONFIGURATION_DESCRIPTOR(32, 1, 1)
|
||||
_INTERFACE_DESCRIPTOR(0, 0, 2, 0x99, 0x99, 0x99)
|
||||
_ENDPOINT_DESCRIPTOR(0x01, 0x02, 64, 0x00)
|
||||
_ENDPOINT_DESCRIPTOR(0x82, 0x02, 64, 0x00)
|
||||
};
|
||||
|
||||
|
||||
#define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED sizeof(device_framework_high_speed)
|
||||
static UCHAR device_framework_high_speed[] = {
|
||||
_DEVICE_DESCRIPTOR(0x99, 0x99, 0x99, 64, 0x08EC, 0x0001, 1)
|
||||
_QUALIFIER_DESCRIPTOR(0, 0, 0, 1)
|
||||
_CONFIGURATION_DESCRIPTOR(32, 1, 1)
|
||||
_INTERFACE_DESCRIPTOR(0, 0, 2, 0x99, 0x99, 0x99)
|
||||
_ENDPOINT_DESCRIPTOR(0x01, 0x02, 512, 0x00)
|
||||
_ENDPOINT_DESCRIPTOR(0x82, 0x02, 512, 0x00)
|
||||
};
|
||||
|
||||
/* String Device Framework :
|
||||
Byte 0 and 1 : Word containing the language ID : 0x0904 for US
|
||||
Byte 2 : Byte containing the index of the descriptor
|
||||
Byte 3 : Byte containing the length of the descriptor string
|
||||
*/
|
||||
#define STRING_FRAMEWORK_LENGTH sizeof(string_framework)
|
||||
static UCHAR string_framework[] = {
|
||||
|
||||
/* Manufacturer string descriptor : Index 1 */
|
||||
0x09, 0x04, 0x01, 0x0c,
|
||||
0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
|
||||
0x6f, 0x67, 0x69, 0x63,
|
||||
|
||||
/* Product string descriptor : Index 2 */
|
||||
0x09, 0x04, 0x02, 0x0c,
|
||||
0x44, 0x61, 0x74, 0x61, 0x50, 0x75, 0x6d, 0x70,
|
||||
0x44, 0x65, 0x6d, 0x6f,
|
||||
|
||||
/* Serial Number string descriptor : Index 3 */
|
||||
0x09, 0x04, 0x03, 0x04,
|
||||
0x30, 0x30, 0x30, 0x31
|
||||
};
|
||||
|
||||
|
||||
/* Multiple languages are supported on the device, to add
|
||||
a language besides English, the unicode language code must
|
||||
be appended to the language_id_framework array and the length
|
||||
adjusted accordingly. */
|
||||
#define LANGUAGE_ID_FRAMEWORK_LENGTH sizeof(language_id_framework)
|
||||
static UCHAR language_id_framework[] = {
|
||||
|
||||
/* English. */
|
||||
0x09, 0x04
|
||||
};
|
||||
|
||||
|
||||
/* Define prototypes for external Host Controller's (HCDs), classes and clients. */
|
||||
|
||||
static VOID tx_demo_instance_activate(VOID *dummy_instance);
|
||||
static VOID tx_demo_instance_deactivate(VOID *dummy_instance);
|
||||
|
||||
#if defined(UX_HOST_STANDALONE)
|
||||
static UINT tx_demo_host_change_function(ULONG e, UX_HOST_CLASS *c, VOID *p);
|
||||
#else
|
||||
#define tx_demo_host_change_function UX_NULL
|
||||
#endif
|
||||
|
||||
UINT ux_hcd_sim_initialize(UX_HCD *hcd);
|
||||
|
||||
static TX_THREAD tx_demo_thread_host_simulation;
|
||||
static TX_THREAD tx_demo_thread_slave_simulation;
|
||||
static void tx_demo_thread_host_simulation_entry(ULONG);
|
||||
static void tx_demo_thread_slave_simulation_entry(ULONG);
|
||||
|
||||
|
||||
/* Define the ISR dispatch. */
|
||||
|
||||
extern VOID (*test_isr_dispatch)(void);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
/* Define the ISR dispatch routine. */
|
||||
|
||||
static void test_isr(void)
|
||||
{
|
||||
|
||||
/* For further expansion of interrupt-level testing. */
|
||||
}
|
||||
|
||||
|
||||
static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
|
||||
{
|
||||
if (expected_error == 0 || error_code != expected_error)
|
||||
{
|
||||
/* Failed test. */
|
||||
printf("Error on line %d, system_level: %d, system_context: %d, error code: %x\n", __LINE__, system_level, system_context, error_code);
|
||||
// test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_class_device_enumeration_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *stack_pointer;
|
||||
CHAR *memory_pointer;
|
||||
UX_DEVICE_CLASS_DUMMY_PARAMETER parameter;
|
||||
|
||||
|
||||
printf("Running Basic Device Class Enumeration Test......................... ");
|
||||
|
||||
/* Initialize the free memory pointer. */
|
||||
stack_pointer = (CHAR *) first_unused_memory;
|
||||
memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
|
||||
|
||||
/* Initialize USBX Memory. */
|
||||
status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL, 0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the error callback. */
|
||||
_ux_utility_error_callback_register(error_callback);
|
||||
|
||||
/* The code below is required for installing the host portion of USBX. */
|
||||
status = ux_host_stack_initialize(tx_demo_host_change_function);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register all the host class drivers for this USBX implementation. */
|
||||
status = ux_host_stack_class_register(_ux_host_class_dummy_name, _ux_host_class_dummy_device_entry);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* The code below is required for installing the device portion of USBX */
|
||||
status = ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
|
||||
device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
|
||||
string_framework, STRING_FRAMEWORK_LENGTH,
|
||||
language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH, UX_NULL);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Set the parameters for callback when insertion/extraction of a Data Pump device. */
|
||||
_ux_utility_memory_set((void *)¶meter, 0x00, sizeof(parameter));
|
||||
parameter.ux_device_class_dummy_parameter_callbacks.ux_device_class_dummy_instance_activate = tx_demo_instance_activate;
|
||||
parameter.ux_device_class_dummy_parameter_callbacks.ux_device_class_dummy_instance_deactivate = tx_demo_instance_deactivate;
|
||||
|
||||
/* Initialize the device dpump class. The class is connected with interface 0 */
|
||||
status = ux_device_stack_class_register(_ux_device_class_dummy_name, _ux_device_class_dummy_entry,
|
||||
1, 0, ¶meter);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Initialize the simulated device controller. */
|
||||
status = _ux_dcd_sim_slave_initialize();
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register all the USB host controllers available in this system */
|
||||
status = ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, ux_hcd_sim_host_initialize,0,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the main host simulation thread. */
|
||||
status = tx_thread_create(&tx_demo_thread_host_simulation, "tx demo host simulation", tx_demo_thread_host_simulation_entry, 0,
|
||||
stack_pointer, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the main demo thread. */
|
||||
status = tx_thread_create(&tx_demo_thread_slave_simulation, "tx demo slave simulation", tx_demo_thread_slave_simulation_entry, 0,
|
||||
stack_pointer + UX_DEMO_STACK_SIZE, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void tx_demo_thread_host_simulation_entry(ULONG arg)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
ULONG actual_length;
|
||||
UCHAR current_char;
|
||||
UX_HOST_CLASS *cls;
|
||||
UINT i;
|
||||
|
||||
stepinfo(">>>>> Dummy Class Get\n");
|
||||
status = ux_host_stack_class_get(_ux_host_class_dummy_name, &cls);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
printf("ERROR #%d: 0x%x\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
stepinfo(">>>>> Dummy Class Instance Wait\n");
|
||||
do
|
||||
{
|
||||
status = ux_host_stack_class_instance_get(cls, 0, (VOID **) &dummy);
|
||||
#if defined(UX_HOST_STANDALONE)
|
||||
ux_system_tasks_run();
|
||||
#endif
|
||||
tx_thread_relinquish();
|
||||
} while (status != UX_SUCCESS);
|
||||
|
||||
stepinfo(">>>>> Dummy Class State Wait\n");
|
||||
while(dummy -> ux_host_class_dummy_state != UX_HOST_CLASS_INSTANCE_LIVE)
|
||||
{
|
||||
#if defined(UX_HOST_STANDALONE)
|
||||
ux_system_tasks_run();
|
||||
#endif
|
||||
tx_thread_relinquish();
|
||||
}
|
||||
|
||||
expected_error = 0;
|
||||
|
||||
/* Sleep for a tick to make sure everything is complete. */
|
||||
tx_thread_sleep(1);
|
||||
|
||||
/* Check for errors from other threads. */
|
||||
if (error_counter)
|
||||
{
|
||||
|
||||
/* DPUMP error. */
|
||||
printf("ERROR #%d: total %ld errors\n", __LINE__, error_counter);
|
||||
test_control_return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void tx_demo_thread_slave_simulation_entry(ULONG arg)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
ULONG actual_length;
|
||||
|
||||
|
||||
while(1)
|
||||
{
|
||||
#if defined(UX_DEVICE_STANDALONE)
|
||||
|
||||
/* Run device tasks. */
|
||||
ux_system_tasks_run();
|
||||
#endif
|
||||
/* Increment thread counter. */
|
||||
thread_1_counter++;
|
||||
|
||||
/* Relinquish to other thread. */
|
||||
tx_thread_relinquish();
|
||||
}
|
||||
}
|
||||
|
||||
static VOID tx_demo_instance_activate(VOID *inst)
|
||||
{
|
||||
dummy_slave = (UX_DEVICE_CLASS_DUMMY *)inst;
|
||||
}
|
||||
|
||||
static VOID tx_demo_instance_deactivate(VOID *inst)
|
||||
{
|
||||
dummy_slave = UX_NULL;
|
||||
}
|
||||
|
||||
#if defined(UX_HOST_STANDALONE)
|
||||
static UINT tx_demo_host_change_function(ULONG e, UX_HOST_CLASS *c, VOID *p)
|
||||
{
|
||||
if (e == UX_STANDALONE_WAIT_BACKGROUND_TASK)
|
||||
{
|
||||
tx_thread_relinquish();
|
||||
}
|
||||
}
|
||||
#endif
|
840
test/regression/usbx_class_hid_basic_memory_test.c
Normal file
840
test/regression/usbx_class_hid_basic_memory_test.c
Normal file
@ -0,0 +1,840 @@
|
||||
/* This file tests the ux_device_class_hid API. */
|
||||
|
||||
#include "usbx_test_common_hid.h"
|
||||
|
||||
#include "ux_test_dcd_sim_slave.h"
|
||||
#include "ux_test_hcd_sim_host.h"
|
||||
#include "ux_test_utility_sim.h"
|
||||
|
||||
#include "ux_host_class_hid_mouse.h"
|
||||
#include "ux_host_class_hid_keyboard.h"
|
||||
#include "ux_host_class_hid_remote_control.h"
|
||||
|
||||
|
||||
static UCHAR hid_keyboard_report[] = {
|
||||
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||
0x09, 0x06, // USAGE (Keyboard)
|
||||
0xa1, 0x01, // COLLECTION (Application)
|
||||
0x05, 0x07, // USAGE_PAGE (Keyboard)
|
||||
0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)
|
||||
0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x25, 0x01, // LOGICAL_MAXIMUM (1)
|
||||
0x75, 0x01, // REPORT_SIZE (1)
|
||||
0x95, 0x08, // REPORT_COUNT (8)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x81, 0x03, // INPUT (Cnst,Var,Abs)
|
||||
0x95, 0x05, // REPORT_COUNT (5)
|
||||
0x75, 0x01, // REPORT_SIZE (1)
|
||||
0x05, 0x08, // USAGE_PAGE (LEDs)
|
||||
0x19, 0x01, // USAGE_MINIMUM (Num Lock)
|
||||
0x29, 0x05, // USAGE_MAXIMUM (Kana)
|
||||
0x91, 0x02, // OUTPUT (Data,Var,Abs)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x75, 0x03, // REPORT_SIZE (3)
|
||||
0x91, 0x03, // OUTPUT (Cnst,Var,Abs)
|
||||
0x95, 0x06, // REPORT_COUNT (6)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x25, 0x65, // LOGICAL_MAXIMUM (101)
|
||||
0x05, 0x07, // USAGE_PAGE (Keyboard)
|
||||
0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
|
||||
0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)
|
||||
0x81, 0x00, // INPUT (Data,Ary,Abs)
|
||||
0xc0, // END_COLLECTION
|
||||
|
||||
0xa1, 0x01, // COLLECTION (Application)
|
||||
0x19, 0x01, // USAGE_MINIMUM (1)
|
||||
0x29, 0x04, // USAGE_MAXIMUM (4)
|
||||
0x75, 0x04, // REPORT_SIZE (4)
|
||||
0x95, 0x04, // REPORT_COUNT (4)
|
||||
0xb1, 0x02, // FEATURE (Data,Var,Abs)
|
||||
0x85, 0x02, // REPORT_ID (2)
|
||||
0x19, 0x05, // USAGE_MINIMUM (5)
|
||||
0x29, 0x07, // USAGE_MAXIMUM (7)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x95, 0x03, // REPORT_COUNT (3)
|
||||
0xb1, 0x02, // FEATURE (Data,Var,Abs)
|
||||
0x85, 0x04, // REPORT_ID (4)
|
||||
0x09, 0x08, // USAGE (8)
|
||||
0x75, 0x10, // REPORT_SIZE (16)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0xb1, 0x02, // FEATURE (Data,Var,Abs)
|
||||
0xc0, // END_COLLECTION
|
||||
};
|
||||
#define HID_KEYBOARD_REPORT_LENGTH sizeof(hid_keyboard_report)/sizeof(hid_keyboard_report[0])
|
||||
|
||||
|
||||
static UCHAR hid_mouse_report[] = {
|
||||
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||
0x09, 0x02, // USAGE (Mouse)
|
||||
0xa1, 0x01, // COLLECTION (Application)
|
||||
0x09, 0x01, // USAGE (Pointer)
|
||||
0xa1, 0x00, // COLLECTION (Physical)
|
||||
0x05, 0x09, // USAGE_PAGE (Button)
|
||||
0x19, 0x01, // USAGE_MINIMUM (Button 1)
|
||||
0x29, 0x03, // USAGE_MAXIMUM (Button 3)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x25, 0x01, // LOGICAL_MAXIMUM (1)
|
||||
0x95, 0x03, // REPORT_COUNT (3)
|
||||
0x75, 0x01, // REPORT_SIZE (1)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x75, 0x05, // REPORT_SIZE (5)
|
||||
0x81, 0x03, // INPUT (Cnst,Var,Abs)
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||
0x09, 0x30, // USAGE (X)
|
||||
0x09, 0x31, // USAGE (Y)
|
||||
0x15, 0x81, // LOGICAL_MINIMUM (-127)
|
||||
0x25, 0x7f, // LOGICAL_MAXIMUM (127)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x95, 0x02, // REPORT_COUNT (2)
|
||||
0x81, 0x06, // INPUT (Data,Var,Rel)
|
||||
0x09, 0x38, // USAGE (Mouse Wheel)
|
||||
0x15, 0x81, // LOGICAL_MINIMUM (-127)
|
||||
0x25, 0x7f, // LOGICAL_MAXIMUM (127)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x81, 0x06, // INPUT (Data,Var,Rel)
|
||||
0xc0, // END_COLLECTION
|
||||
0xc0, // END_COLLECTION
|
||||
};
|
||||
#define HID_MOUSE_REPORT_LENGTH (sizeof(hid_mouse_report)/sizeof(hid_mouse_report[0]))
|
||||
|
||||
static UCHAR hid_remote_control_report[] = {
|
||||
|
||||
0x05, 0x0c, // USAGE_PAGE (Consumer Devices)
|
||||
0x09, 0x01, // USAGE (Consumer Control)
|
||||
0xa1, 0x01, // COLLECTION (Application)
|
||||
0x09, 0x02, // USAGE (Numeric Key Pad)
|
||||
0xa1, 0x02, // COLLECTION (Logical)
|
||||
0x05, 0x09, // USAGE_PAGE (Button)
|
||||
0x19, 0x01, // USAGE_MINIMUM (Button 1)
|
||||
0x29, 0x0a, // USAGE_MAXIMUM (Button 10)
|
||||
0x15, 0x01, // LOGICAL_MINIMUM (1)
|
||||
0x25, 0x0a, // LOGICAL_MAXIMUM (10)
|
||||
0x75, 0x04, // REPORT_SIZE (4)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x81, 0x00, // INPUT (Data,Ary,Abs)
|
||||
0xc0, // END_COLLECTION
|
||||
0x05, 0x0c, // USAGE_PAGE (Consumer Devices)
|
||||
0x09, 0x86, // USAGE (Channel)
|
||||
0x09, 0xe0, // USAGE (Volume)
|
||||
0x15, 0xff, // LOGICAL_MINIMUM (-1)
|
||||
0x25, 0x01, // LOGICAL_MAXIMUM (1)
|
||||
0x75, 0x02, // REPORT_SIZE (2)
|
||||
0x95, 0x02, // REPORT_COUNT (2)
|
||||
0x81, 0x46, // INPUT (Data,Var,Rel,Null)
|
||||
0xc0 // END_COLLECTION
|
||||
};
|
||||
#define HID_REMOTE_CONTROL_REPORT_LENGTH (sizeof(hid_remote_control_report)/sizeof(hid_remote_control_report[0]))
|
||||
|
||||
/* Configuration descriptor 9 bytes */
|
||||
#define CFG_DESC(wTotalLength, bNumInterfaces, bConfigurationValue)\
|
||||
/* Configuration 1 descriptor 9 bytes */\
|
||||
0x09, 0x02, LSB(wTotalLength), MSB(wTotalLength),\
|
||||
(bNumInterfaces), (bConfigurationValue), 0x00,\
|
||||
0x40, 0x00,
|
||||
#define CFG_DESC_LEN (9)
|
||||
|
||||
|
||||
/* HID Mouse/Keyboard interface descriptors 9+9+7=25 bytes */
|
||||
#define HID_IFC_DESC_ALL(ifc, report_len, interrupt_epa) \
|
||||
/* Interface descriptor */\
|
||||
0x09, 0x04, (ifc), 0x00, 0x01, 0x03, 0x00, 0x00, 0x00,\
|
||||
/* HID descriptor */\
|
||||
0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(report_len),\
|
||||
MSB(report_len),\
|
||||
/* Endpoint descriptor (Interrupt) */\
|
||||
0x07, 0x05, (interrupt_epa), 0x03, 0x08, 0x00, 0x08,
|
||||
#define HID_IFC_DESC_ALL_LEN (9+9+7)
|
||||
|
||||
|
||||
static UCHAR device_framework_full_speed[] = {
|
||||
|
||||
/* Device descriptor */
|
||||
0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08,
|
||||
0x81, 0x0A, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x01,
|
||||
|
||||
CFG_DESC(CFG_DESC_LEN+3*HID_IFC_DESC_ALL_LEN, 2, 1)
|
||||
/* Keyboard */
|
||||
HID_IFC_DESC_ALL(0, HID_KEYBOARD_REPORT_LENGTH, 0x82)
|
||||
/* Mouse */
|
||||
HID_IFC_DESC_ALL(1, HID_MOUSE_REPORT_LENGTH, 0x81)
|
||||
/* Remote control */
|
||||
HID_IFC_DESC_ALL(2, HID_REMOTE_CONTROL_REPORT_LENGTH, 0x83)
|
||||
};
|
||||
#define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED sizeof(device_framework_full_speed)
|
||||
|
||||
|
||||
static UCHAR device_framework_high_speed[] = {
|
||||
|
||||
/* Device descriptor */
|
||||
0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
|
||||
0x0a, 0x07, 0x25, 0x40, 0x01, 0x00, 0x01, 0x02,
|
||||
0x03, 0x01,
|
||||
|
||||
/* Device qualifier descriptor */
|
||||
0x0a, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
|
||||
0x01, 0x00,
|
||||
|
||||
CFG_DESC(CFG_DESC_LEN+3*HID_IFC_DESC_ALL_LEN, 2, 1)
|
||||
/* Keyboard */
|
||||
HID_IFC_DESC_ALL(0, HID_KEYBOARD_REPORT_LENGTH, 0x82)
|
||||
/* Mouse */
|
||||
HID_IFC_DESC_ALL(1, HID_MOUSE_REPORT_LENGTH, 0x81)
|
||||
/* Remote control */
|
||||
HID_IFC_DESC_ALL(2, HID_REMOTE_CONTROL_REPORT_LENGTH, 0x83)
|
||||
};
|
||||
#define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED sizeof(device_framework_high_speed)
|
||||
|
||||
|
||||
/* String Device Framework :
|
||||
Byte 0 and 1 : Word containing the language ID : 0x0904 for US
|
||||
Byte 2 : Byte containing the index of the descriptor
|
||||
Byte 3 : Byte containing the length of the descriptor string
|
||||
*/
|
||||
static UCHAR string_framework[] = {
|
||||
|
||||
/* Manufacturer string descriptor : Index 1 */
|
||||
0x09, 0x04, 0x01, 0x0c,
|
||||
0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
|
||||
0x6f, 0x67, 0x69, 0x63,
|
||||
|
||||
/* Product string descriptor : Index 2 */
|
||||
0x09, 0x04, 0x02, 0x0c,
|
||||
0x55, 0x53, 0x42, 0x20, 0x4b, 0x65, 0x79, 0x62,
|
||||
0x6f, 0x61, 0x72, 0x64,
|
||||
|
||||
/* Serial Number string descriptor : Index 3 */
|
||||
0x09, 0x04, 0x03, 0x04,
|
||||
0x30, 0x30, 0x30, 0x31
|
||||
};
|
||||
#define STRING_FRAMEWORK_LENGTH sizeof(string_framework)
|
||||
|
||||
|
||||
/* Multiple languages are supported on the device, to add
|
||||
a language besides english, the unicode language code must
|
||||
be appended to the language_id_framework array and the length
|
||||
adjusted accordingly. */
|
||||
static UCHAR language_id_framework[] = {
|
||||
|
||||
/* English. */
|
||||
0x09, 0x04
|
||||
};
|
||||
#define LANGUAGE_ID_FRAMEWORK_LENGTH sizeof(language_id_framework)
|
||||
|
||||
static UX_HOST_CLASS_HID *hid = UX_NULL;
|
||||
static UX_HOST_CLASS_HID_MOUSE *hid_mouse = UX_NULL;
|
||||
static UX_HOST_CLASS_HID_KEYBOARD *hid_keyboard = UX_NULL;
|
||||
static UX_HOST_CLASS_HID_REMOTE_CONTROL *hid_remote_control = UX_NULL;
|
||||
|
||||
static UX_SLAVE_CLASS_HID *hid_mouse_slave = UX_NULL;
|
||||
static UX_SLAVE_CLASS_HID *hid_keyboard_slave = UX_NULL;
|
||||
static UX_SLAVE_CLASS_HID *hid_remote_control_slave = UX_NULL;
|
||||
|
||||
static UX_SLAVE_CLASS_HID_PARAMETER hid_mouse_parameter;
|
||||
static UX_SLAVE_CLASS_HID_PARAMETER hid_keyboard_parameter;
|
||||
static UX_SLAVE_CLASS_HID_PARAMETER hid_remote_control_parameter;
|
||||
|
||||
static ULONG rsc_mem_alloc_cnt_on_set_cfg;
|
||||
static ULONG rsc_enum_mem_alloc_count;
|
||||
static ULONG rsc_hid_mem_alloc_count;
|
||||
|
||||
static ULONG error_callback_counter;
|
||||
static UCHAR error_callback_ignore;
|
||||
|
||||
static ULONG error_counter = 0;
|
||||
|
||||
static UINT _is_mouse(UX_HOST_CLASS_HID_CLIENT *client)
|
||||
{
|
||||
return(UX_SUCCESS == _ux_utility_memory_compare(client->ux_host_class_hid_client_name,
|
||||
_ux_system_host_class_hid_client_mouse_name,
|
||||
_ux_utility_string_length_get(_ux_system_host_class_hid_client_mouse_name)));
|
||||
}
|
||||
static UINT _is_keyboard(UX_HOST_CLASS_HID_CLIENT *client)
|
||||
{
|
||||
return(UX_SUCCESS == _ux_utility_memory_compare(client->ux_host_class_hid_client_name,
|
||||
_ux_system_host_class_hid_client_keyboard_name,
|
||||
_ux_utility_string_length_get(_ux_system_host_class_hid_client_keyboard_name)));
|
||||
}
|
||||
static UINT ux_system_host_change_function(ULONG event, UX_HOST_CLASS *cls, VOID *inst)
|
||||
{
|
||||
|
||||
UX_HOST_CLASS_HID_CLIENT *client = (UX_HOST_CLASS_HID_CLIENT *)inst;
|
||||
|
||||
// if(event >= UX_HID_CLIENT_INSERTION) printf("hChg: ev %lx, cls %p, inst %p, %s\n", event, cls, inst, _is_mouse(client) ? "Mouse" : _is_keyboard(client) ? "Keyboard" : "Remote Control");
|
||||
switch(event)
|
||||
{
|
||||
|
||||
case UX_HID_CLIENT_INSERTION:
|
||||
if (_is_mouse(client))
|
||||
hid_mouse = (UX_HOST_CLASS_HID_MOUSE *)client->ux_host_class_hid_client_local_instance;
|
||||
else
|
||||
{
|
||||
if (_is_keyboard(client))
|
||||
hid_keyboard = (UX_HOST_CLASS_HID_KEYBOARD *)client->ux_host_class_hid_client_local_instance;
|
||||
else
|
||||
hid_remote_control = (UX_HOST_CLASS_HID_REMOTE_CONTROL *)client->ux_host_class_hid_client_local_instance;
|
||||
}
|
||||
break;
|
||||
|
||||
case UX_HID_CLIENT_REMOVAL:
|
||||
if (_is_mouse(client))
|
||||
hid_mouse = UX_NULL;
|
||||
else
|
||||
{
|
||||
if (_is_keyboard(client))
|
||||
hid_keyboard = UX_NULL;
|
||||
else
|
||||
hid_remote_control = UX_NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static VOID mouse_instance_activate_callback(VOID *parameter)
|
||||
{
|
||||
// printf("dMouse: %p\n", parameter);
|
||||
hid_mouse_slave = (UX_SLAVE_CLASS_HID *)parameter;
|
||||
}
|
||||
|
||||
static VOID keyboard_instance_activate_callback(VOID *parameter)
|
||||
{
|
||||
// printf("dKeyboard: %p\n", parameter);
|
||||
hid_keyboard_slave = (UX_SLAVE_CLASS_HID *)parameter;
|
||||
}
|
||||
|
||||
static VOID remote_control_instance_activate_callback(VOID *parameter)
|
||||
{
|
||||
// printf("dKeyboard: %p\n", parameter);
|
||||
hid_remote_control_slave = (UX_SLAVE_CLASS_HID *)parameter;
|
||||
}
|
||||
|
||||
static VOID instance_deactivate_callback(VOID *parameter)
|
||||
{
|
||||
// printf("dRm: %p\n", parameter);
|
||||
if ((VOID *)hid_mouse_slave == parameter)
|
||||
hid_mouse_slave = UX_NULL;
|
||||
|
||||
if ((VOID *)hid_keyboard_slave == parameter)
|
||||
hid_keyboard_slave = UX_NULL;
|
||||
|
||||
if ((VOID *)hid_remote_control_slave == parameter)
|
||||
hid_remote_control_slave = UX_NULL;
|
||||
}
|
||||
|
||||
static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
|
||||
{
|
||||
if (error_code == UX_MEMORY_INSUFFICIENT)
|
||||
error_callback_counter ++;
|
||||
// printf("ERROR #%d: 0x%x, 0x%x, 0x%x\n", __LINE__, system_level, system_context, error_code);
|
||||
}
|
||||
|
||||
static UINT break_on_all_activated(VOID)
|
||||
{
|
||||
|
||||
if (hid_mouse_slave == UX_NULL)
|
||||
return 0;
|
||||
if (hid_keyboard_slave == UX_NULL)
|
||||
return 0;
|
||||
if (hid_remote_control_slave == UX_NULL)
|
||||
return 0;
|
||||
if (hid_mouse == UX_NULL)
|
||||
return 0;
|
||||
if (hid_keyboard == UX_NULL)
|
||||
return 0;
|
||||
if (hid_remote_control == UX_NULL)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static UINT break_on_all_removed(VOID)
|
||||
{
|
||||
if (hid_mouse_slave || hid_keyboard_slave || hid_remote_control_slave)
|
||||
return 0;
|
||||
if (hid_mouse || hid_keyboard || hid_remote_control)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static UINT sleep_break_on_error(VOID)
|
||||
{
|
||||
|
||||
if (error_callback_counter >= 3)
|
||||
return error_callback_counter;
|
||||
|
||||
return UX_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static VOID ux_test_hcd_entry_set_cfg(UX_TEST_ACTION *action, VOID *_params)
|
||||
{
|
||||
rsc_mem_alloc_cnt_on_set_cfg = ux_test_utility_sim_mem_alloc_count();
|
||||
}
|
||||
|
||||
static UX_TEST_SETUP _SetConfigure = UX_TEST_SETUP_SetConfigure;
|
||||
|
||||
static UX_TEST_HCD_SIM_ACTION log_on_SetCfg[] = {
|
||||
/* function, request to match,
|
||||
port action, port status,
|
||||
request action, request EP, request data, request actual length, request status,
|
||||
status, additional callback,
|
||||
no_return */
|
||||
{ UX_HCD_TRANSFER_REQUEST, &_SetConfigure,
|
||||
UX_FALSE, UX_TEST_PORT_STATUS_DISC,
|
||||
UX_TEST_SETUP_MATCH_REQ, 0, UX_NULL, 0, 0,
|
||||
UX_SUCCESS, ux_test_hcd_entry_set_cfg,
|
||||
UX_TRUE}, /* Invoke callback & continue */
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_ux_device_class_hid_basic_memory_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *stack_pointer;
|
||||
CHAR *memory_pointer;
|
||||
ULONG mem_free;
|
||||
ULONG alloc_count;
|
||||
ULONG test_n;
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running UX Class HID Basic Memory test ............................. ");
|
||||
stepinfo("\n");
|
||||
|
||||
/* Initialize memory logger. */
|
||||
ux_test_utility_sim_mem_alloc_log_enable(UX_TRUE);
|
||||
ux_test_utility_sim_mem_alloc_count_reset();
|
||||
|
||||
/* Initialize the free memory pointer */
|
||||
stack_pointer = (CHAR *) usbx_memory;
|
||||
memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
|
||||
|
||||
/* Initialize USBX. Memory */
|
||||
status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d, code 0x%x\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the error callback. */
|
||||
_ux_utility_error_callback_register(error_callback);
|
||||
|
||||
/* The code below is required for installing the host portion of USBX */
|
||||
status = ux_host_stack_initialize(ux_system_host_change_function);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d, code 0x%x\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = ux_host_stack_class_register(_ux_system_host_class_hid_name, ux_host_class_hid_entry);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d, code 0x%x\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the HID client(s). */
|
||||
status |= ux_host_class_hid_client_register(_ux_system_host_class_hid_client_mouse_name, ux_host_class_hid_mouse_entry);
|
||||
status |= ux_host_class_hid_client_register(_ux_system_host_class_hid_client_keyboard_name, ux_host_class_hid_keyboard_entry);
|
||||
status |= ux_host_class_hid_client_register(_ux_system_host_class_hid_client_remote_control_name, ux_host_class_hid_remote_control_entry);
|
||||
#if UX_MAX_SLAVE_CLASS_DRIVER > 1
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d, code 0x%x\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* The code below is required for installing the device portion of USBX. No call back for
|
||||
device status change in this example. */
|
||||
status = ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
|
||||
device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
|
||||
string_framework, STRING_FRAMEWORK_LENGTH,
|
||||
language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d, code 0x%x\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Initialize the hid class parameters for mouse and keyboard. */
|
||||
hid_mouse_parameter.ux_device_class_hid_parameter_report_address = hid_mouse_report;
|
||||
hid_mouse_parameter.ux_device_class_hid_parameter_report_length = HID_MOUSE_REPORT_LENGTH;
|
||||
hid_mouse_parameter.ux_device_class_hid_parameter_callback = demo_thread_hid_callback;
|
||||
hid_mouse_parameter.ux_slave_class_hid_instance_activate = mouse_instance_activate_callback;
|
||||
hid_mouse_parameter.ux_slave_class_hid_instance_deactivate = instance_deactivate_callback;
|
||||
|
||||
hid_keyboard_parameter.ux_device_class_hid_parameter_report_address = hid_keyboard_report;
|
||||
hid_keyboard_parameter.ux_device_class_hid_parameter_report_length = HID_KEYBOARD_REPORT_LENGTH;
|
||||
hid_keyboard_parameter.ux_device_class_hid_parameter_callback = demo_thread_hid_callback;
|
||||
hid_keyboard_parameter.ux_slave_class_hid_instance_activate = keyboard_instance_activate_callback;
|
||||
hid_keyboard_parameter.ux_slave_class_hid_instance_deactivate = instance_deactivate_callback;
|
||||
|
||||
hid_remote_control_parameter.ux_device_class_hid_parameter_report_address = hid_remote_control_report;
|
||||
hid_remote_control_parameter.ux_device_class_hid_parameter_report_length = HID_REMOTE_CONTROL_REPORT_LENGTH;
|
||||
hid_remote_control_parameter.ux_device_class_hid_parameter_callback = demo_thread_hid_callback;
|
||||
hid_remote_control_parameter.ux_slave_class_hid_instance_activate = remote_control_instance_activate_callback;
|
||||
hid_remote_control_parameter.ux_slave_class_hid_instance_deactivate = instance_deactivate_callback;
|
||||
|
||||
stepinfo(">>>>>>>>>> Test HID Class Initialize/deinitialize memory\n");
|
||||
|
||||
stepinfo(">>>>>>>>>> - Reset counts\n");
|
||||
ux_test_utility_sim_mem_alloc_count_reset();
|
||||
mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
|
||||
|
||||
stepinfo(">>>>>>>>>> - _class_register\n");
|
||||
|
||||
/* Initilize the device hid class. */
|
||||
status = ux_device_stack_class_register(_ux_system_slave_class_hid_name, ux_device_class_hid_entry,
|
||||
1,1, (VOID *)&hid_mouse_parameter);
|
||||
status |= ux_device_stack_class_register(_ux_system_slave_class_hid_name, ux_device_class_hid_entry,
|
||||
1,0, (VOID *)&hid_keyboard_parameter);
|
||||
status |= ux_device_stack_class_register(_ux_system_slave_class_hid_name, ux_device_class_hid_entry,
|
||||
1,2, (VOID *)&hid_remote_control_parameter);
|
||||
#if UX_MAX_SLAVE_CLASS_DRIVER > 1
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d, code 0x%x\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
#endif
|
||||
#if 1
|
||||
/* Log create counts when instances active for further tests. */
|
||||
alloc_count = ux_test_utility_sim_mem_alloc_count();
|
||||
|
||||
/* Lock log base for tests. */
|
||||
ux_test_utility_sim_mem_alloc_log_lock();
|
||||
|
||||
stepinfo("init & uninit alloc : %ld\n", alloc_count);
|
||||
stepinfo("mem free : %ld, %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available, _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_CACHE_SAFE] -> ux_byte_pool_available);
|
||||
|
||||
if (alloc_count) stepinfo(">>>>>>>>>> - Init/deinit memory errors test\n");
|
||||
mem_free = (~0);
|
||||
for (test_n = 0; test_n < alloc_count; test_n ++)
|
||||
{
|
||||
|
||||
stepinfo("%4ld / %4ld\n", test_n, alloc_count - 1);
|
||||
|
||||
/* Unregister. */
|
||||
ux_device_stack_class_unregister(_ux_system_slave_class_hid_name, ux_device_class_hid_entry);
|
||||
ux_device_stack_class_unregister(_ux_system_slave_class_hid_name, ux_device_class_hid_entry);
|
||||
ux_device_stack_class_unregister(_ux_system_slave_class_hid_name, ux_device_class_hid_entry);
|
||||
|
||||
/* Update memory free level (disconnect) */
|
||||
if (mem_free == (~0))
|
||||
mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
|
||||
else if (mem_free != _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available)
|
||||
{
|
||||
|
||||
printf("ERROR #%d.%ld: Memory level different after re-enumerations %ld <> %ld\n", __LINE__, test_n, mem_free, _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
|
||||
error_counter ++;
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Set memory error generation */
|
||||
ux_test_utility_sim_mem_alloc_error_generation_start(test_n);
|
||||
|
||||
/* Register. */
|
||||
status = ux_device_stack_class_register(_ux_system_slave_class_hid_name, ux_device_class_hid_entry,
|
||||
1,1, (VOID *)&hid_mouse_parameter);
|
||||
status |= ux_device_stack_class_register(_ux_system_slave_class_hid_name, ux_device_class_hid_entry,
|
||||
1,0, (VOID *)&hid_keyboard_parameter);
|
||||
status |= ux_device_stack_class_register(_ux_system_slave_class_hid_name, ux_device_class_hid_entry,
|
||||
1,2, (VOID *)&hid_remote_control_parameter);
|
||||
#if UX_MAX_SLAVE_CLASS_DRIVER > 1
|
||||
/* Check error */
|
||||
if (status == UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d.%ld: registered when there is memory error\n", __LINE__, test_n);
|
||||
error_counter ++;
|
||||
}
|
||||
#endif
|
||||
|
||||
stepinfo("mem free: %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
|
||||
}
|
||||
ux_test_utility_sim_mem_alloc_error_generation_stop();
|
||||
if (alloc_count) stepinfo("\n");
|
||||
|
||||
/* Unregister. */
|
||||
ux_device_stack_class_unregister(_ux_system_slave_class_hid_name, ux_device_class_hid_entry);
|
||||
ux_device_stack_class_unregister(_ux_system_slave_class_hid_name, ux_device_class_hid_entry);
|
||||
ux_device_stack_class_unregister(_ux_system_slave_class_hid_name, ux_device_class_hid_entry);
|
||||
|
||||
/* Register. */
|
||||
status = ux_device_stack_class_register(_ux_system_slave_class_hid_name, ux_device_class_hid_entry,
|
||||
1,1, (VOID *)&hid_mouse_parameter);
|
||||
status |= ux_device_stack_class_register(_ux_system_slave_class_hid_name, ux_device_class_hid_entry,
|
||||
1,0, (VOID *)&hid_keyboard_parameter);
|
||||
status |= ux_device_stack_class_register(_ux_system_slave_class_hid_name, ux_device_class_hid_entry,
|
||||
1,2, (VOID *)&hid_remote_control_parameter);
|
||||
#if UX_MAX_SLAVE_CLASS_DRIVER > 1
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d, code 0x%x\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
/* Initialize the simulated device controller. */
|
||||
status = _ux_dcd_sim_slave_initialize();
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d, code 0x%x\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register all the USB host controllers available in this system */
|
||||
status = ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize,0,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d, code 0x%x\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the main host simulation thread. */
|
||||
status = tx_thread_create(&tx_demo_thread_host_simulation, "tx demo host simulation", tx_demo_thread_host_simulation_entry, 0,
|
||||
stack_pointer, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d, code 0x%x\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#if defined(UX_DEVICE_STANDALONE)
|
||||
|
||||
/* Create the main device simulation thread. */
|
||||
status = tx_thread_create(&tx_demo_thread_device_simulation, "tx demo device simulation", tx_demo_thread_device_simulation_entry, 0,
|
||||
stack_pointer + UX_DEMO_STACK_SIZE, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d, code 0x%x\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(UX_DEVICE_STANDALONE)
|
||||
static void tx_demo_thread_device_simulation_entry(ULONG arg)
|
||||
{
|
||||
while(1)
|
||||
{
|
||||
ux_system_tasks_run();
|
||||
tx_thread_relinquish();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void tx_demo_thread_host_simulation_entry(ULONG arg)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
UX_DEVICE *device;
|
||||
ULONG mem_free;
|
||||
ULONG alloc_count;
|
||||
ULONG test_n;
|
||||
UX_HCD *hcd;
|
||||
|
||||
|
||||
stepinfo(">>>>>>>>>> Thread start\n");
|
||||
|
||||
hcd = &_ux_system_host->ux_system_host_hcd_array[0];
|
||||
|
||||
ux_test_breakable_sleep(500, break_on_all_activated);
|
||||
|
||||
/* Get device instance. */
|
||||
status = ux_host_stack_device_get(0, &device);
|
||||
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
printf("ERROR #%d: get_device fail, 0x%x\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
stepinfo(">>>>>>>>>> Disconnect\n");
|
||||
|
||||
ux_test_dcd_sim_slave_disconnect();
|
||||
ux_test_hcd_sim_host_disconnect();
|
||||
|
||||
if (hid_keyboard || hid_mouse)
|
||||
{
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
stepinfo(">>>>>>>>>> Reset counts\n");
|
||||
|
||||
ux_test_utility_sim_mem_alloc_count_reset();
|
||||
mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
|
||||
|
||||
rsc_mem_alloc_cnt_on_set_cfg = 0;
|
||||
ux_test_hcd_sim_host_set_actions(log_on_SetCfg);
|
||||
|
||||
stepinfo(">>>>>>>>>> Connect\n");
|
||||
|
||||
ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
|
||||
ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
|
||||
ux_test_breakable_sleep(500, break_on_all_activated);
|
||||
|
||||
/* Log create counts for further tests. */
|
||||
rsc_enum_mem_alloc_count = rsc_mem_alloc_cnt_on_set_cfg;
|
||||
|
||||
/* Log create counts when instances active for further tests. */
|
||||
alloc_count = ux_test_utility_sim_mem_alloc_count();
|
||||
|
||||
/* Lock log base for tests. */
|
||||
ux_test_utility_sim_mem_alloc_log_lock();
|
||||
|
||||
rsc_hid_mem_alloc_count = alloc_count - rsc_enum_mem_alloc_count;
|
||||
|
||||
stepinfo("enum mem: %ld\n", rsc_enum_mem_alloc_count);
|
||||
stepinfo("hid mem : %ld\n", rsc_hid_mem_alloc_count);
|
||||
stepinfo("mem free: %ld, %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available, _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_CACHE_SAFE] -> ux_byte_pool_available);
|
||||
|
||||
if (hid_mouse == UX_NULL
|
||||
#if UX_MAX_SLAVE_CLASS_DRIVER > 1
|
||||
|| hid_keyboard == UX_NULL
|
||||
#endif
|
||||
)
|
||||
{
|
||||
printf("ERROR #%d: %p %p\n", __LINE__, hid_keyboard, hid_mouse);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Simulate detach and attach for FS enumeration,
|
||||
and test possible memory allocation error handlings.
|
||||
*/
|
||||
if (rsc_hid_mem_alloc_count) stepinfo(">>>>>>>>>> Memory errors enumeration test\n");
|
||||
mem_free = (~0);
|
||||
for (test_n = 0; test_n < rsc_hid_mem_alloc_count; test_n ++)
|
||||
{
|
||||
|
||||
stepinfo("%4ld / %4ld\n", test_n, rsc_hid_mem_alloc_count - 1);
|
||||
|
||||
/* Disconnect. */
|
||||
ux_test_dcd_sim_slave_disconnect();
|
||||
ux_test_hcd_sim_host_disconnect();
|
||||
|
||||
/* Check number of devices. */
|
||||
if (hcd->ux_hcd_nb_devices != 0)
|
||||
{
|
||||
printf("ERROR #%d.%ld: number of devices (%d) must be 0\n", __LINE__, test_n, hcd->ux_hcd_nb_devices);
|
||||
error_counter ++;
|
||||
}
|
||||
|
||||
/* Update memory free level (disconnect) */
|
||||
if (mem_free == (~0))
|
||||
mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
|
||||
else if (mem_free != _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available)
|
||||
{
|
||||
|
||||
printf("ERROR #%d.%ld: Memory level different after re-enumerations %ld <> %ld\n", __LINE__, test_n, mem_free, _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
|
||||
error_counter ++;
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Set memory error generation */
|
||||
ux_test_utility_sim_mem_alloc_error_generation_start(test_n + rsc_enum_mem_alloc_count);
|
||||
|
||||
/* Connect. */
|
||||
error_callback_counter = 0;
|
||||
ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
|
||||
#if 1 /* @nick */
|
||||
ux_test_hcd_sim_host_connect_no_wait(UX_FULL_SPEED_DEVICE);
|
||||
|
||||
/* Wait for enum thread to complete. */
|
||||
ux_test_wait_for_enum_thread_completion();
|
||||
#else
|
||||
ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
|
||||
|
||||
/* Wait and break on errors. */
|
||||
ux_test_breakable_sleep(400, sleep_break_on_error);
|
||||
#endif
|
||||
|
||||
/* Check error */
|
||||
if (hid_mouse && hid_keyboard && hid_mouse_slave && hid_keyboard_slave && hid_remote_control && hid_remote_control_slave)
|
||||
{
|
||||
|
||||
printf("ERROR #%d.%ld: device detected when there is memory error\n", __LINE__, test_n);
|
||||
error_counter ++;
|
||||
}
|
||||
stepinfo("mem free: %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
|
||||
ux_test_utility_sim_mem_alloc_error_generation_stop();
|
||||
}
|
||||
if (alloc_count) stepinfo("\n");
|
||||
|
||||
stepinfo(">>>>>>>>>> Test done\n");
|
||||
|
||||
/* Now disconnect the device. */
|
||||
_ux_device_stack_disconnect();
|
||||
|
||||
/* And deinitialize the class. */
|
||||
status = ux_device_stack_class_unregister(_ux_system_slave_class_hid_name, ux_device_class_hid_entry);
|
||||
|
||||
/* Deinitialize the device side of usbx. */
|
||||
_ux_device_stack_uninitialize();
|
||||
|
||||
/* And finally the usbx system resources. */
|
||||
_ux_system_uninitialize();
|
||||
|
||||
if (error_counter)
|
||||
{
|
||||
printf("FAIL %ld errors!\n", error_counter);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
|
||||
static UINT demo_thread_hid_callback(UX_SLAVE_CLASS_HID *class, UX_SLAVE_CLASS_HID_EVENT *event)
|
||||
{
|
||||
return(UX_SUCCESS);
|
||||
}
|
610
test/regression/usbx_class_hid_basic_test.c
Normal file
610
test/regression/usbx_class_hid_basic_test.c
Normal file
@ -0,0 +1,610 @@
|
||||
/* This file tests basic HID functionalities. */
|
||||
|
||||
#include "usbx_test_common_hid.h"
|
||||
|
||||
#define DUMMY_USBX_MEMORY_SIZE (64*1024)
|
||||
static UCHAR dummy_usbx_memory[DUMMY_USBX_MEMORY_SIZE];
|
||||
|
||||
static UCHAR hid_keyboard_report[] = {
|
||||
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||
0x09, 0x06, // USAGE (Keyboard)
|
||||
0xa1, 0x01, // COLLECTION (Application)
|
||||
|
||||
0x05, 0x07, // USAGE_PAGE (Keyboard)
|
||||
0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)
|
||||
0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x25, 0x01, // LOGICAL_MAXIMUM (1)
|
||||
0x75, 0x01, // REPORT_SIZE (1)
|
||||
0x95, 0x08, // REPORT_COUNT (8)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x81, 0x03, // INPUT (Cnst,Var,Abs)
|
||||
|
||||
0x95, 0x05, // REPORT_COUNT (5)
|
||||
0x75, 0x01, // REPORT_SIZE (1)
|
||||
0x05, 0x08, // USAGE_PAGE (LEDs)
|
||||
0x19, 0x01, // USAGE_MINIMUM (Num Lock)
|
||||
0x29, 0x05, // USAGE_MAXIMUM (Kana)
|
||||
0x91, 0x02, // OUTPUT (Data,Var,Abs)
|
||||
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x75, 0x03, // REPORT_SIZE (3)
|
||||
0x91, 0x03, // OUTPUT (Cnst,Var,Abs)
|
||||
|
||||
0x95, 0x06, // REPORT_COUNT (6)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x25, 0x65, // LOGICAL_MAXIMUM (101)
|
||||
0x05, 0x07, // USAGE_PAGE (Keyboard)
|
||||
0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
|
||||
0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)
|
||||
0x81, 0x00, // INPUT (Data,Ary,Abs)
|
||||
|
||||
0xc0 // END_COLLECTION
|
||||
};
|
||||
#define HID_KEYBOARD_REPORT_LENGTH sizeof(hid_keyboard_report)/sizeof(hid_keyboard_report[0])
|
||||
|
||||
static UCHAR hid_mouse_report[] = {
|
||||
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||
0x09, 0x02, // USAGE (Mouse)
|
||||
0xa1, 0x01, // COLLECTION (Application)
|
||||
0x85, 0x01, // REPORT_ID (1)
|
||||
0x09, 0x01, // USAGE (Pointer)
|
||||
0xa1, 0x00, // COLLECTION (Physical)
|
||||
0x05, 0x09, // USAGE_PAGE (Button)
|
||||
0x19, 0x01, // USAGE_MINIMUM (Button 1)
|
||||
0x29, 0x03, // USAGE_MAXIMUM (Button 3)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x25, 0x01, // LOGICAL_MAXIMUM (1)
|
||||
0x95, 0x03, // REPORT_COUNT (3)
|
||||
0x75, 0x01, // REPORT_SIZE (1)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x75, 0x05, // REPORT_SIZE (5)
|
||||
0x81, 0x03, // INPUT (Cnst,Var,Abs)
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||
0x09, 0x30, // USAGE (X)
|
||||
0x09, 0x31, // USAGE (Y)
|
||||
0x15, 0x81, // LOGICAL_MINIMUM (-127)
|
||||
0x25, 0x7f, // LOGICAL_MAXIMUM (127)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x95, 0x02, // REPORT_COUNT (2)
|
||||
0x81, 0x06, // INPUT (Data,Var,Rel)
|
||||
0x09, 0x38, // USAGE (Mouse Wheel)
|
||||
0x15, 0x81, // LOGICAL_MINIMUM (-127)
|
||||
0x25, 0x7f, // LOGICAL_MAXIMUM (127)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x81, 0x06, // INPUT (Data,Var,Rel)
|
||||
0xc0, // END_COLLECTION
|
||||
0xc0 // END_COLLECTION
|
||||
};
|
||||
#define HID_MOUSE_REPORT_LENGTH (sizeof(hid_mouse_report)/sizeof(hid_mouse_report[0]))
|
||||
|
||||
static UCHAR hid_report_descriptor[] = {
|
||||
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||
0x09, 0x06, // USAGE (Keyboard)
|
||||
0xa1, 0x01, // COLLECTION (Application)
|
||||
|
||||
0x19, 0x01, // USAGE_MINIMUM (1)
|
||||
0x29, 0x04, // USAGE_MAXIMUM (4)
|
||||
0x75, 0x04, // REPORT_SIZE (4)
|
||||
0x95, 0x04, // REPORT_COUNT (4)
|
||||
0xb1, 0x02, // FEATURE (Data,Var,Abs)
|
||||
|
||||
0x85, 0x02, // REPORT_ID (2)
|
||||
0x19, 0x05, // USAGE_MINIMUM (5)
|
||||
0x29, 0x07, // USAGE_MAXIMUM (7)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x95, 0x03, // REPORT_COUNT (3)
|
||||
0xb1, 0x02, // FEATURE (Data,Var,Abs)
|
||||
|
||||
0x85, 0x04, // REPORT_ID (4)
|
||||
0x09, 0x08, // USAGE (8)
|
||||
0x75, 0x10, // REPORT_SIZE (16)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0xb1, 0x02, // FEATURE (Data,Var,Abs)
|
||||
|
||||
/* USBX requires at least one input report. */
|
||||
0x09, 0x01, // USAGE (1)
|
||||
0x75, 0x10, // REPORT_SIZE (16)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
|
||||
/* USBX expects keyboards to have at least one output report, otherwise it's an error. */
|
||||
0x95, 0x05, // REPORT_COUNT (5)
|
||||
0x75, 0x01, // REPORT_SIZE (1)
|
||||
0x05, 0x08, // USAGE_PAGE (LEDs)
|
||||
0x19, 0x01, // USAGE_MINIMUM (Num Lock)
|
||||
0x29, 0x05, // USAGE_MAXIMUM (Kana)
|
||||
0x91, 0x02, // OUTPUT (Data,Var,Abs)
|
||||
|
||||
0xc0, // END_COLLECTION
|
||||
};
|
||||
#define HID_REPORT_LENGTH sizeof(hid_report_descriptor)/sizeof(hid_report_descriptor[0])
|
||||
|
||||
|
||||
/* Configuration descriptor 9 bytes */
|
||||
#define CFG_DESC(wTotalLength, bNumInterfaces, bConfigurationValue)\
|
||||
/* Configuration 1 descriptor 9 bytes */\
|
||||
0x09, 0x02, LSB(wTotalLength), MSB(wTotalLength),\
|
||||
(bNumInterfaces), (bConfigurationValue), 0x00,\
|
||||
0x40, 0x00,
|
||||
#define CFG_DESC_LEN (9)
|
||||
|
||||
|
||||
/* HID Mouse/Keyboard interface descriptors 9+9+7=25 bytes */
|
||||
#define HID_IFC_DESC_ALL(ifc, report_len, interrupt_epa) \
|
||||
/* Interface descriptor */\
|
||||
0x09, 0x04, (ifc), 0x00, 0x01, 0x03, 0x00, 0x00, 0x00,\
|
||||
/* HID descriptor */\
|
||||
0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(report_len),\
|
||||
MSB(report_len),\
|
||||
/* Endpoint descriptor (Interrupt) */\
|
||||
0x07, 0x05, (interrupt_epa), 0x03, 0x08, 0x00, 0x08,
|
||||
#define HID_IFC_DESC_ALL_LEN (9+9+7)
|
||||
|
||||
static UCHAR device_framework_full_speed[] = {
|
||||
|
||||
/* Device descriptor */
|
||||
0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08,
|
||||
0x81, 0x0A, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x01,
|
||||
|
||||
CFG_DESC(CFG_DESC_LEN+1*HID_IFC_DESC_ALL_LEN, 1, 1)
|
||||
/* Keyboard */
|
||||
HID_IFC_DESC_ALL(0, HID_REPORT_LENGTH, 0x81)
|
||||
};
|
||||
#define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED sizeof(device_framework_full_speed)
|
||||
|
||||
static UCHAR device_framework_high_speed[] = {
|
||||
|
||||
/* Device descriptor */
|
||||
0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
|
||||
0x0a, 0x07, 0x25, 0x40, 0x01, 0x00, 0x01, 0x02,
|
||||
0x03, 0x01,
|
||||
|
||||
/* Device qualifier descriptor */
|
||||
0x0a, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
|
||||
0x01, 0x00,
|
||||
|
||||
CFG_DESC(CFG_DESC_LEN+1*HID_IFC_DESC_ALL_LEN, 1, 1)
|
||||
/* Keyboard */
|
||||
HID_IFC_DESC_ALL(0, HID_REPORT_LENGTH, 0x81)
|
||||
};
|
||||
#define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED sizeof(device_framework_high_speed)
|
||||
|
||||
|
||||
/* String Device Framework :
|
||||
Byte 0 and 1 : Word containing the language ID : 0x0904 for US
|
||||
Byte 2 : Byte containing the index of the descriptor
|
||||
Byte 3 : Byte containing the length of the descriptor string
|
||||
*/
|
||||
static UCHAR string_framework[] = {
|
||||
|
||||
/* Manufacturer string descriptor : Index 1 */
|
||||
0x09, 0x04, 0x01, 0x0c,
|
||||
0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
|
||||
0x6f, 0x67, 0x69, 0x63,
|
||||
|
||||
/* Product string descriptor : Index 2 */
|
||||
0x09, 0x04, 0x02, 0x0c,
|
||||
0x55, 0x53, 0x42, 0x20, 0x4b, 0x65, 0x79, 0x62,
|
||||
0x6f, 0x61, 0x72, 0x64,
|
||||
|
||||
/* Serial Number string descriptor : Index 3 */
|
||||
0x09, 0x04, 0x03, 0x04,
|
||||
0x30, 0x30, 0x30, 0x31
|
||||
};
|
||||
#define STRING_FRAMEWORK_LENGTH sizeof(string_framework)
|
||||
|
||||
|
||||
/* Multiple languages are supported on the device, to add
|
||||
a language besides english, the unicode language code must
|
||||
be appended to the language_id_framework array and the length
|
||||
adjusted accordingly. */
|
||||
static UCHAR language_id_framework[] = {
|
||||
|
||||
/* English. */
|
||||
0x09, 0x04
|
||||
};
|
||||
#define LANGUAGE_ID_FRAMEWORK_LENGTH sizeof(language_id_framework)
|
||||
|
||||
|
||||
UINT _ux_hcd_sim_host_entry(UX_HCD *hcd, UINT function, VOID *parameter);
|
||||
|
||||
|
||||
static UINT ux_system_host_change_function(ULONG event, UX_HOST_CLASS *cls, VOID *inst)
|
||||
{
|
||||
switch(event)
|
||||
{
|
||||
case UX_HID_CLIENT_INSERTION:
|
||||
break;
|
||||
case UX_HID_CLIENT_REMOVAL:
|
||||
break;
|
||||
#if defined(UX_HOST_STANDALONE)
|
||||
case UX_STANDALONE_WAIT_BACKGROUND_TASK:
|
||||
/* Let other threads to run. */
|
||||
tx_thread_relinquish();
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
|
||||
{
|
||||
}
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_class_hid_basic_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR * stack_pointer;
|
||||
CHAR * memory_pointer;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running HID Class Basic Test........................................ ");
|
||||
|
||||
/* Initialize the free memory pointer */
|
||||
stack_pointer = (CHAR *) usbx_memory;
|
||||
memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
|
||||
|
||||
/* Initialize USBX. Memory */
|
||||
status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the error callback. */
|
||||
_ux_utility_error_callback_register(error_callback);
|
||||
|
||||
/* The code below is required for installing the host portion of USBX */
|
||||
status = ux_host_stack_initialize(ux_system_host_change_function);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = ux_host_stack_class_register(_ux_system_host_class_hid_name, ux_host_class_hid_entry);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* No client registered, just HID. */
|
||||
|
||||
/* The code below is required for installing the device portion of USBX. No call back for
|
||||
device status change in this example. */
|
||||
status = ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
|
||||
device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
|
||||
string_framework, STRING_FRAMEWORK_LENGTH,
|
||||
language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Initialize the hid class parameters. */
|
||||
hid_parameter.ux_device_class_hid_parameter_report_address = hid_report_descriptor;
|
||||
hid_parameter.ux_device_class_hid_parameter_report_length = HID_REPORT_LENGTH;
|
||||
hid_parameter.ux_device_class_hid_parameter_callback = demo_thread_hid_set_callback;
|
||||
hid_parameter.ux_device_class_hid_parameter_get_callback = demo_thread_hid_get_callback;
|
||||
|
||||
hid_parameter.ux_slave_class_hid_instance_activate = demo_device_hid_instance_activate;
|
||||
hid_parameter.ux_slave_class_hid_instance_deactivate = demo_device_hid_instance_deactivate;
|
||||
|
||||
/* Initilize the device hid class. The class is connected with interface 2 */
|
||||
status = ux_device_stack_class_register(_ux_system_slave_class_hid_name, ux_device_class_hid_entry,
|
||||
1, 0, (VOID *)&hid_parameter);
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Initialize the simulated device controller. */
|
||||
status = _ux_dcd_sim_slave_initialize();
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register all the USB host controllers available in this system */
|
||||
status = ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, ux_hcd_sim_host_initialize,0,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the main device simulation thread. */
|
||||
status = tx_thread_create(&tx_demo_thread_device_simulation, "tx demo device simulation", tx_demo_thread_device_simulation_entry, 0,
|
||||
stack_pointer, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
stack_pointer += UX_DEMO_STACK_SIZE;
|
||||
|
||||
/* Create the main host simulation thread. */
|
||||
status = tx_thread_create(&tx_demo_thread_host_simulation, "tx demo host simulation", tx_demo_thread_host_simulation_entry, 0,
|
||||
stack_pointer, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
static void tx_demo_thread_device_simulation_entry(ULONG arg)
|
||||
{
|
||||
while(1)
|
||||
{
|
||||
#if defined(UX_DEVICE_STANDALONE)
|
||||
ux_system_tasks_run();
|
||||
#else
|
||||
tx_thread_suspend(&tx_demo_thread_device_simulation);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static UINT demo_wait(ULONG tick, UINT (*check)())
|
||||
{
|
||||
ULONG t0, t1;
|
||||
UINT status;
|
||||
|
||||
t0 = tx_time_get();
|
||||
while(1)
|
||||
{
|
||||
#if defined(UX_HOST_STANDALONE)
|
||||
ux_system_tasks_run();
|
||||
#endif
|
||||
if (check)
|
||||
{
|
||||
status = check();
|
||||
if (status == UX_SUCCESS)
|
||||
break;
|
||||
}
|
||||
t1 = tx_time_get();
|
||||
if (_ux_utility_time_elapsed(t0, t1) >= tick)
|
||||
{
|
||||
return(UX_TIMEOUT);
|
||||
}
|
||||
}
|
||||
return(UX_SUCCESS);
|
||||
}
|
||||
|
||||
static UINT demo_class_hid_wait(ULONG tick)
|
||||
{
|
||||
return(demo_wait(tick, demo_class_hid_get));
|
||||
}
|
||||
|
||||
static void test_hid_idle_requests(VOID)
|
||||
{
|
||||
USHORT idle_time;
|
||||
UINT status;
|
||||
INT i;
|
||||
#define N_TEST_IDLES 4
|
||||
USHORT test_idles[N_TEST_IDLES] = {1, 8, 20, 0};
|
||||
ULONG mem_level = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
|
||||
|
||||
|
||||
/* Get input report. */
|
||||
hid_report_id.ux_host_class_hid_report_get_report = UX_NULL;
|
||||
hid_report_id.ux_host_class_hid_report_get_type = UX_HOST_CLASS_HID_REPORT_TYPE_INPUT;
|
||||
status = _ux_host_class_hid_report_id_get(hid, &hid_report_id);
|
||||
UX_TEST_ASSERT(status == UX_SUCCESS);
|
||||
|
||||
status = _ux_host_class_hid_idle_get(hid, &idle_time, hid_report_id.ux_host_class_hid_report_get_id);
|
||||
UX_TEST_ASSERT(status == UX_SUCCESS);
|
||||
test_idles[N_TEST_IDLES - 1] = idle_time;
|
||||
|
||||
for (i = 0; i < N_TEST_IDLES; i ++)
|
||||
{
|
||||
status = _ux_host_class_hid_idle_set(hid, test_idles[i], hid_report_id.ux_host_class_hid_report_get_id);
|
||||
UX_TEST_ASSERT(status == UX_SUCCESS);
|
||||
status = _ux_host_class_hid_idle_get(hid, &idle_time, hid_report_id.ux_host_class_hid_report_get_id);
|
||||
UX_TEST_ASSERT(status == UX_SUCCESS);
|
||||
UX_TEST_ASSERT(idle_time == test_idles[i]);
|
||||
}
|
||||
|
||||
UX_TEST_ASSERT(mem_level == _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
|
||||
}
|
||||
|
||||
static void test_hid_report_requests(VOID)
|
||||
{
|
||||
ULONG tmp_bytes[2];
|
||||
UINT status;
|
||||
INT i;
|
||||
#define N_TEST_REPORT_REQS 5
|
||||
ULONG mem_level = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
|
||||
|
||||
/* Get output report. */
|
||||
hid_report_id.ux_host_class_hid_report_get_report = UX_NULL;
|
||||
hid_report_id.ux_host_class_hid_report_get_type = UX_HOST_CLASS_HID_REPORT_TYPE_FEATURE;
|
||||
status = _ux_host_class_hid_report_id_get(hid, &hid_report_id);
|
||||
UX_TEST_ASSERT(status == UX_SUCCESS);
|
||||
|
||||
/* Memorize the report pointer. */
|
||||
client_report.ux_host_class_hid_client_report = hid_report_id.ux_host_class_hid_report_get_report;
|
||||
|
||||
/* The report set is raw since the LEDs mask is already in the right format. */
|
||||
client_report.ux_host_class_hid_client_report_flags = UX_HOST_CLASS_HID_REPORT_RAW;
|
||||
|
||||
/* The length of this report is 2 byte (16 bits). */
|
||||
client_report.ux_host_class_hid_client_report_length = 2;
|
||||
|
||||
/* The output report buffer is the LED mask field. */
|
||||
client_report.ux_host_class_hid_client_report_buffer = tmp_bytes;
|
||||
|
||||
for (i = 0; i < N_TEST_REPORT_REQS; i ++)
|
||||
{
|
||||
_ux_utility_memory_set(tmp_bytes, i, sizeof(tmp_bytes));
|
||||
status = _ux_host_class_hid_report_set(hid, &client_report);
|
||||
UX_TEST_ASSERT(status == UX_SUCCESS);
|
||||
|
||||
_ux_utility_memory_set(tmp_bytes, 0xFF, sizeof(tmp_bytes));
|
||||
status = _ux_host_class_hid_report_get(hid, &client_report);
|
||||
UX_TEST_ASSERT_MESSAGE(status == UX_SUCCESS, "0x%x\n", status);
|
||||
UX_TEST_ASSERT(*(UCHAR *)tmp_bytes == i);
|
||||
}
|
||||
|
||||
UX_TEST_ASSERT(mem_level == _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
|
||||
}
|
||||
|
||||
static ULONG test_hid_report_callback_count = 0;
|
||||
static ULONG test_hid_report_callback_wait = 0;
|
||||
static VOID test_hid_report_callback(UX_HOST_CLASS_HID_REPORT_CALLBACK *callback)
|
||||
{
|
||||
test_hid_report_callback_count ++;
|
||||
}
|
||||
static UINT test_hid_report_callback_count_check(VOID)
|
||||
{
|
||||
return(test_hid_report_callback_count >= test_hid_report_callback_wait ?
|
||||
UX_SUCCESS : UX_ERROR);
|
||||
}
|
||||
static void test_hid_periodic_reports(VOID)
|
||||
{
|
||||
UINT status;
|
||||
ULONG mem_level;
|
||||
|
||||
/* Get input report. */
|
||||
hid_report_id.ux_host_class_hid_report_get_report = UX_NULL;
|
||||
hid_report_id.ux_host_class_hid_report_get_type = UX_HOST_CLASS_HID_REPORT_TYPE_INPUT;
|
||||
status = _ux_host_class_hid_report_id_get(hid, &hid_report_id);
|
||||
UX_TEST_ASSERT(status == UX_SUCCESS);
|
||||
|
||||
/* Initialize the report callback. */
|
||||
hid_report_callback.ux_host_class_hid_report_callback_id = hid_report_id.ux_host_class_hid_report_get_id;
|
||||
hid_report_callback.ux_host_class_hid_report_callback_function = test_hid_report_callback;
|
||||
hid_report_callback.ux_host_class_hid_report_callback_buffer = UX_NULL;
|
||||
hid_report_callback.ux_host_class_hid_report_callback_flags = UX_HOST_CLASS_HID_REPORT_RAW;
|
||||
hid_report_callback.ux_host_class_hid_report_callback_length = hid_report_id.ux_host_class_hid_report_get_report->ux_host_class_hid_report_byte_length;
|
||||
|
||||
/* Register the report call back when data comes it on this report. */
|
||||
status = _ux_host_class_hid_report_callback_register(hid, &hid_report_callback);
|
||||
UX_TEST_ASSERT(status == UX_SUCCESS);
|
||||
|
||||
/* Start background report reading. */
|
||||
_ux_host_class_hid_periodic_report_start(hid);
|
||||
|
||||
mem_level = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
|
||||
|
||||
device_hid_event.ux_device_class_hid_event_length = 4;
|
||||
device_hid_event.ux_device_class_hid_event_buffer[0] = 0;
|
||||
device_hid_event.ux_device_class_hid_event_buffer[1] = 0;
|
||||
device_hid_event.ux_device_class_hid_event_buffer[2] = '0';
|
||||
device_hid_event.ux_device_class_hid_event_buffer[3] = '1';
|
||||
|
||||
test_hid_report_callback_count = 0;
|
||||
test_hid_report_callback_wait = 1;
|
||||
_ux_device_class_hid_event_set(device_hid, &device_hid_event);
|
||||
demo_wait(10, test_hid_report_callback_count_check);
|
||||
UX_TEST_ASSERT(test_hid_report_callback_count == 1);
|
||||
|
||||
test_hid_report_callback_count = 0;
|
||||
test_hid_report_callback_wait = 2;
|
||||
_ux_device_class_hid_event_set(device_hid, &device_hid_event);
|
||||
_ux_device_class_hid_event_set(device_hid, &device_hid_event);
|
||||
demo_wait(10, test_hid_report_callback_count_check);
|
||||
UX_TEST_ASSERT(test_hid_report_callback_count == 2);
|
||||
|
||||
UX_TEST_ASSERT(mem_level == _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
|
||||
}
|
||||
|
||||
static void tx_demo_thread_host_simulation_entry(ULONG arg)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
/* Find the HID class */
|
||||
status = demo_class_hid_wait(100);
|
||||
UX_TEST_ASSERT(status == UX_SUCCESS);
|
||||
|
||||
|
||||
test_hid_idle_requests();
|
||||
test_hid_report_requests();
|
||||
test_hid_periodic_reports();
|
||||
|
||||
/* Now disconnect the device. */
|
||||
_ux_device_stack_disconnect();
|
||||
|
||||
/* And deinitialize the class. */
|
||||
status = ux_device_stack_class_unregister(_ux_system_slave_class_hid_name, ux_device_class_hid_entry);
|
||||
|
||||
/* Deinitialize the device side of usbx. */
|
||||
_ux_device_stack_uninitialize();
|
||||
|
||||
/* And finally the usbx system resources. */
|
||||
_ux_system_uninitialize();
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
|
||||
static UINT demo_thread_hid_set_callback(UX_SLAVE_CLASS_HID *class, UX_SLAVE_CLASS_HID_EVENT *event)
|
||||
{
|
||||
_ux_utility_memory_copy(&device_hid_event, event, sizeof(UX_SLAVE_CLASS_HID_EVENT));
|
||||
return(UX_SUCCESS);
|
||||
}
|
||||
static UINT demo_thread_hid_get_callback(UX_SLAVE_CLASS_HID *class, UX_SLAVE_CLASS_HID_EVENT *event)
|
||||
{
|
||||
_ux_utility_memory_copy(event, &device_hid_event, sizeof(UX_SLAVE_CLASS_HID_EVENT));
|
||||
return(UX_SUCCESS);
|
||||
}
|
||||
|
||||
static void demo_device_hid_instance_activate(VOID *inst)
|
||||
{
|
||||
if (device_hid == UX_NULL)
|
||||
device_hid = (UX_SLAVE_CLASS_HID *)inst;
|
||||
}
|
||||
static void demo_device_hid_instance_deactivate(VOID *inst)
|
||||
{
|
||||
if (inst == (VOID *)device_hid)
|
||||
device_hid = UX_NULL;
|
||||
}
|
493
test/regression/usbx_class_hid_keyboard_basic_test.c
Normal file
493
test/regression/usbx_class_hid_keyboard_basic_test.c
Normal file
@ -0,0 +1,493 @@
|
||||
/* This file tests basic HID functionalities. */
|
||||
|
||||
#include "usbx_test_common_hid.h"
|
||||
#include "ux_host_class_hid_keyboard.h"
|
||||
|
||||
#define DUMMY_USBX_MEMORY_SIZE (64*1024)
|
||||
static UCHAR dummy_usbx_memory[DUMMY_USBX_MEMORY_SIZE];
|
||||
|
||||
static UCHAR hid_keyboard_report[] = {
|
||||
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||
0x09, 0x06, // USAGE (Keyboard)
|
||||
0xa1, 0x01, // COLLECTION (Application)
|
||||
|
||||
0x05, 0x07, // USAGE_PAGE (Keyboard)
|
||||
0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)
|
||||
0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x25, 0x01, // LOGICAL_MAXIMUM (1)
|
||||
0x75, 0x01, // REPORT_SIZE (1)
|
||||
0x95, 0x08, // REPORT_COUNT (8)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x81, 0x03, // INPUT (Cnst,Var,Abs)
|
||||
|
||||
0x95, 0x05, // REPORT_COUNT (5)
|
||||
0x75, 0x01, // REPORT_SIZE (1)
|
||||
0x05, 0x08, // USAGE_PAGE (LEDs)
|
||||
0x19, 0x01, // USAGE_MINIMUM (Num Lock)
|
||||
0x29, 0x05, // USAGE_MAXIMUM (Kana)
|
||||
0x91, 0x02, // OUTPUT (Data,Var,Abs)
|
||||
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x75, 0x03, // REPORT_SIZE (3)
|
||||
0x91, 0x03, // OUTPUT (Cnst,Var,Abs)
|
||||
|
||||
0x95, 0x06, // REPORT_COUNT (6)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x25, 0x65, // LOGICAL_MAXIMUM (101)
|
||||
0x05, 0x07, // USAGE_PAGE (Keyboard)
|
||||
0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
|
||||
0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)
|
||||
0x81, 0x00, // INPUT (Data,Ary,Abs)
|
||||
|
||||
0xc0 // END_COLLECTION
|
||||
};
|
||||
#define HID_KEYBOARD_REPORT_LENGTH sizeof(hid_keyboard_report)/sizeof(hid_keyboard_report[0])
|
||||
|
||||
static UCHAR hid_mouse_report[] = {
|
||||
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||
0x09, 0x02, // USAGE (Mouse)
|
||||
0xa1, 0x01, // COLLECTION (Application)
|
||||
0x85, 0x01, // REPORT_ID (1)
|
||||
0x09, 0x01, // USAGE (Pointer)
|
||||
0xa1, 0x00, // COLLECTION (Physical)
|
||||
0x05, 0x09, // USAGE_PAGE (Button)
|
||||
0x19, 0x01, // USAGE_MINIMUM (Button 1)
|
||||
0x29, 0x03, // USAGE_MAXIMUM (Button 3)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x25, 0x01, // LOGICAL_MAXIMUM (1)
|
||||
0x95, 0x03, // REPORT_COUNT (3)
|
||||
0x75, 0x01, // REPORT_SIZE (1)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x75, 0x05, // REPORT_SIZE (5)
|
||||
0x81, 0x03, // INPUT (Cnst,Var,Abs)
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||
0x09, 0x30, // USAGE (X)
|
||||
0x09, 0x31, // USAGE (Y)
|
||||
0x15, 0x81, // LOGICAL_MINIMUM (-127)
|
||||
0x25, 0x7f, // LOGICAL_MAXIMUM (127)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x95, 0x02, // REPORT_COUNT (2)
|
||||
0x81, 0x06, // INPUT (Data,Var,Rel)
|
||||
0x09, 0x38, // USAGE (Mouse Wheel)
|
||||
0x15, 0x81, // LOGICAL_MINIMUM (-127)
|
||||
0x25, 0x7f, // LOGICAL_MAXIMUM (127)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x81, 0x06, // INPUT (Data,Var,Rel)
|
||||
0xc0, // END_COLLECTION
|
||||
0xc0 // END_COLLECTION
|
||||
};
|
||||
#define HID_MOUSE_REPORT_LENGTH (sizeof(hid_mouse_report)/sizeof(hid_mouse_report[0]))
|
||||
|
||||
#define hid_report_descriptor hid_keyboard_report
|
||||
#define HID_REPORT_LENGTH HID_KEYBOARD_REPORT_LENGTH
|
||||
|
||||
/* Configuration descriptor 9 bytes */
|
||||
#define CFG_DESC(wTotalLength, bNumInterfaces, bConfigurationValue)\
|
||||
/* Configuration 1 descriptor 9 bytes */\
|
||||
0x09, 0x02, LSB(wTotalLength), MSB(wTotalLength),\
|
||||
(bNumInterfaces), (bConfigurationValue), 0x00,\
|
||||
0x40, 0x00,
|
||||
#define CFG_DESC_LEN (9)
|
||||
|
||||
|
||||
/* HID Mouse/Keyboard interface descriptors 9+9+7=25 bytes */
|
||||
#define HID_IFC_DESC_ALL(ifc, report_len, interrupt_epa) \
|
||||
/* Interface descriptor */\
|
||||
0x09, 0x04, (ifc), 0x00, 0x01, 0x03, 0x00, 0x00, 0x00,\
|
||||
/* HID descriptor */\
|
||||
0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(report_len),\
|
||||
MSB(report_len),\
|
||||
/* Endpoint descriptor (Interrupt) */\
|
||||
0x07, 0x05, (interrupt_epa), 0x03, 0x08, 0x00, 0x08,
|
||||
#define HID_IFC_DESC_ALL_LEN (9+9+7)
|
||||
|
||||
static UCHAR device_framework_full_speed[] = {
|
||||
|
||||
/* Device descriptor */
|
||||
0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08,
|
||||
0x81, 0x0A, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x01,
|
||||
|
||||
CFG_DESC(CFG_DESC_LEN+1*HID_IFC_DESC_ALL_LEN, 1, 1)
|
||||
/* Keyboard */
|
||||
HID_IFC_DESC_ALL(0, HID_REPORT_LENGTH, 0x81)
|
||||
};
|
||||
#define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED sizeof(device_framework_full_speed)
|
||||
|
||||
static UCHAR device_framework_high_speed[] = {
|
||||
|
||||
/* Device descriptor */
|
||||
0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
|
||||
0x0a, 0x07, 0x25, 0x40, 0x01, 0x00, 0x01, 0x02,
|
||||
0x03, 0x01,
|
||||
|
||||
/* Device qualifier descriptor */
|
||||
0x0a, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
|
||||
0x01, 0x00,
|
||||
|
||||
CFG_DESC(CFG_DESC_LEN+1*HID_IFC_DESC_ALL_LEN, 1, 1)
|
||||
/* Keyboard */
|
||||
HID_IFC_DESC_ALL(0, HID_REPORT_LENGTH, 0x81)
|
||||
};
|
||||
#define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED sizeof(device_framework_high_speed)
|
||||
|
||||
|
||||
/* String Device Framework :
|
||||
Byte 0 and 1 : Word containing the language ID : 0x0904 for US
|
||||
Byte 2 : Byte containing the index of the descriptor
|
||||
Byte 3 : Byte containing the length of the descriptor string
|
||||
*/
|
||||
static UCHAR string_framework[] = {
|
||||
|
||||
/* Manufacturer string descriptor : Index 1 */
|
||||
0x09, 0x04, 0x01, 0x0c,
|
||||
0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
|
||||
0x6f, 0x67, 0x69, 0x63,
|
||||
|
||||
/* Product string descriptor : Index 2 */
|
||||
0x09, 0x04, 0x02, 0x0c,
|
||||
0x55, 0x53, 0x42, 0x20, 0x4b, 0x65, 0x79, 0x62,
|
||||
0x6f, 0x61, 0x72, 0x64,
|
||||
|
||||
/* Serial Number string descriptor : Index 3 */
|
||||
0x09, 0x04, 0x03, 0x04,
|
||||
0x30, 0x30, 0x30, 0x31
|
||||
};
|
||||
#define STRING_FRAMEWORK_LENGTH sizeof(string_framework)
|
||||
|
||||
|
||||
/* Multiple languages are supported on the device, to add
|
||||
a language besides english, the unicode language code must
|
||||
be appended to the language_id_framework array and the length
|
||||
adjusted accordingly. */
|
||||
static UCHAR language_id_framework[] = {
|
||||
|
||||
/* English. */
|
||||
0x09, 0x04
|
||||
};
|
||||
#define LANGUAGE_ID_FRAMEWORK_LENGTH sizeof(language_id_framework)
|
||||
|
||||
|
||||
UINT _ux_hcd_sim_host_entry(UX_HCD *hcd, UINT function, VOID *parameter);
|
||||
|
||||
|
||||
static UINT ux_system_host_change_function(ULONG event, UX_HOST_CLASS *cls, VOID *inst)
|
||||
{
|
||||
switch(event)
|
||||
{
|
||||
case UX_HID_CLIENT_INSERTION:
|
||||
break;
|
||||
case UX_HID_CLIENT_REMOVAL:
|
||||
break;
|
||||
#if defined(UX_HOST_STANDALONE)
|
||||
case UX_STANDALONE_WAIT_BACKGROUND_TASK:
|
||||
/* Let other threads to run. */
|
||||
tx_thread_relinquish();
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
|
||||
{
|
||||
}
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_class_hid_keyboard_basic_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR * stack_pointer;
|
||||
CHAR * memory_pointer;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running HID Class Keyboard Basic Test............................... ");
|
||||
|
||||
/* Initialize the free memory pointer */
|
||||
stack_pointer = (CHAR *) usbx_memory;
|
||||
memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
|
||||
|
||||
/* Initialize USBX. Memory */
|
||||
status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the error callback. */
|
||||
_ux_utility_error_callback_register(error_callback);
|
||||
|
||||
/* The code below is required for installing the host portion of USBX */
|
||||
status = ux_host_stack_initialize(ux_system_host_change_function);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = ux_host_stack_class_register(_ux_system_host_class_hid_name, ux_host_class_hid_entry);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the HID client(s). */
|
||||
status = ux_host_class_hid_client_register(_ux_system_host_class_hid_client_keyboard_name, ux_host_class_hid_keyboard_entry);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* The code below is required for installing the device portion of USBX. No call back for
|
||||
device status change in this example. */
|
||||
status = ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
|
||||
device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
|
||||
string_framework, STRING_FRAMEWORK_LENGTH,
|
||||
language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Initialize the hid class parameters. */
|
||||
hid_parameter.ux_device_class_hid_parameter_report_address = hid_report_descriptor;
|
||||
hid_parameter.ux_device_class_hid_parameter_report_length = HID_REPORT_LENGTH;
|
||||
hid_parameter.ux_device_class_hid_parameter_callback = demo_thread_hid_set_callback;
|
||||
hid_parameter.ux_device_class_hid_parameter_get_callback = demo_thread_hid_get_callback;
|
||||
|
||||
hid_parameter.ux_slave_class_hid_instance_activate = demo_device_hid_instance_activate;
|
||||
hid_parameter.ux_slave_class_hid_instance_deactivate = demo_device_hid_instance_deactivate;
|
||||
|
||||
/* Initilize the device hid class. The class is connected with interface 2 */
|
||||
status = ux_device_stack_class_register(_ux_system_slave_class_hid_name, ux_device_class_hid_entry,
|
||||
1, 0, (VOID *)&hid_parameter);
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Initialize the simulated device controller. */
|
||||
status = _ux_dcd_sim_slave_initialize();
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register all the USB host controllers available in this system */
|
||||
status = ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, ux_hcd_sim_host_initialize,0,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the main device simulation thread. */
|
||||
status = tx_thread_create(&tx_demo_thread_device_simulation, "tx demo device simulation", tx_demo_thread_device_simulation_entry, 0,
|
||||
stack_pointer, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
stack_pointer += UX_DEMO_STACK_SIZE;
|
||||
|
||||
/* Create the main host simulation thread. */
|
||||
status = tx_thread_create(&tx_demo_thread_host_simulation, "tx demo host simulation", tx_demo_thread_host_simulation_entry, 0,
|
||||
stack_pointer, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
static void tx_demo_thread_device_simulation_entry(ULONG arg)
|
||||
{
|
||||
while(1)
|
||||
{
|
||||
#if defined(UX_DEVICE_STANDALONE)
|
||||
ux_system_tasks_run();
|
||||
#else
|
||||
tx_thread_suspend(&tx_demo_thread_device_simulation);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static UINT demo_class_hid_wait(ULONG tick)
|
||||
{
|
||||
return(ux_test_sleep_break_on_success(tick, demo_class_hid_keyboard_get));
|
||||
}
|
||||
|
||||
static UINT _wait_key(UX_HOST_CLASS_HID_KEYBOARD *keyboard, ULONG *keyboard_key, ULONG *keyboard_state)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
UINT i;
|
||||
|
||||
|
||||
for(i = 0; i < 200; i ++)
|
||||
{
|
||||
#if defined(UX_HOST_STANDALONE)
|
||||
ux_system_tasks_run();
|
||||
#endif
|
||||
status = ux_host_class_hid_keyboard_key_get(keyboard, keyboard_key, keyboard_state);
|
||||
if (status == UX_SUCCESS)
|
||||
{
|
||||
// printf("Key: %lx,%lx\n", *keyboard_key, *keyboard_state);
|
||||
|
||||
#if defined(UX_HOST_CLASS_HID_KEYBOARD_EVENTS_KEY_CHANGES_MODE_REPORT_LOCK_KEYS) || defined(UX_HOST_CLASS_HID_KEYBOARD_EVENTS_KEY_CHANGES_MODE_REPORT_MODIFIER_KEYS)
|
||||
if (*keyboard_state & UX_HID_KEYBOARD_STATE_FUNCTION)
|
||||
continue;
|
||||
#endif
|
||||
|
||||
#if !defined(UX_HOST_CLASS_HID_KEYBOARD_EVENTS_KEY_CHANGES_MODE_REPORT_KEY_DOWN_ONLY)
|
||||
if (*keyboard_state & UX_HID_KEYBOARD_STATE_KEY_UP)
|
||||
continue;
|
||||
#endif
|
||||
return UX_SUCCESS;
|
||||
}
|
||||
_ux_utility_delay_ms(1);
|
||||
}
|
||||
return UX_ERROR;
|
||||
}
|
||||
|
||||
|
||||
static void test_hid_keyboard_keys(VOID)
|
||||
{
|
||||
UINT status;
|
||||
ULONG keyboard_key;
|
||||
ULONG keyboard_state;
|
||||
|
||||
/* Initialize key event. */
|
||||
device_hid_event.ux_device_class_hid_event_length = 4;
|
||||
device_hid_event.ux_device_class_hid_event_buffer[0] = 0; /* Modifier. */
|
||||
device_hid_event.ux_device_class_hid_event_buffer[1] = 0; /* Reserved. */
|
||||
device_hid_event.ux_device_class_hid_event_buffer[2] = 0; /* Key ...... */
|
||||
device_hid_event.ux_device_class_hid_event_buffer[3] = 0; /* Key ...... */
|
||||
|
||||
/* Set modifier + key. */
|
||||
device_hid_event.ux_device_class_hid_event_buffer[0] = 1; /* Left CTRL */
|
||||
device_hid_event.ux_device_class_hid_event_buffer[2] = 4; /* a */
|
||||
_ux_device_class_hid_event_set(device_hid, &device_hid_event);
|
||||
status = _wait_key(hid_keyboard, &keyboard_key, &keyboard_state);
|
||||
UX_TEST_ASSERT(status == UX_SUCCESS);
|
||||
UX_TEST_ASSERT(keyboard_state & UX_HID_KEYBOARD_STATE_LEFT_CTRL);
|
||||
UX_TEST_ASSERT(keyboard_key == 'a');
|
||||
|
||||
/* Set modifier + key. */
|
||||
device_hid_event.ux_device_class_hid_event_buffer[0] = (1 << 5); /* Right SHIFT */
|
||||
device_hid_event.ux_device_class_hid_event_buffer[2] = 5; /* b -> B */
|
||||
_ux_device_class_hid_event_set(device_hid, &device_hid_event);
|
||||
status = _wait_key(hid_keyboard, &keyboard_key, &keyboard_state);
|
||||
UX_TEST_ASSERT(status == UX_SUCCESS);
|
||||
UX_TEST_ASSERT(keyboard_state & UX_HID_KEYBOARD_STATE_RIGHT_SHIFT);
|
||||
UX_TEST_ASSERT(keyboard_key == 'B');
|
||||
|
||||
/* Send CAPS_Lock. */
|
||||
device_hid_event.ux_device_class_hid_event_buffer[0] = 0;
|
||||
device_hid_event.ux_device_class_hid_event_buffer[2] = UX_HID_LED_KEY_CAPS_LOCK;
|
||||
_ux_device_class_hid_event_set(device_hid, &device_hid_event);
|
||||
device_hid_event.ux_device_class_hid_event_buffer[0] = 0;
|
||||
device_hid_event.ux_device_class_hid_event_buffer[2] = 6; /* c -> C */
|
||||
_ux_device_class_hid_event_set(device_hid, &device_hid_event);
|
||||
status = _wait_key(hid_keyboard, &keyboard_key, &keyboard_state);
|
||||
UX_TEST_ASSERT(status == UX_SUCCESS);
|
||||
UX_TEST_ASSERT(keyboard_state & UX_HID_KEYBOARD_STATE_CAPS_LOCK);
|
||||
UX_TEST_ASSERT(keyboard_key == 'C');
|
||||
}
|
||||
|
||||
static void tx_demo_thread_host_simulation_entry(ULONG arg)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
/* Find the HID class */
|
||||
status = demo_class_hid_wait(100);
|
||||
UX_TEST_ASSERT(status == UX_SUCCESS);
|
||||
|
||||
test_hid_keyboard_keys();
|
||||
|
||||
/* Now disconnect the device. */
|
||||
_ux_device_stack_disconnect();
|
||||
|
||||
/* And deinitialize the class. */
|
||||
status = ux_device_stack_class_unregister(_ux_system_slave_class_hid_name, ux_device_class_hid_entry);
|
||||
|
||||
/* Deinitialize the device side of usbx. */
|
||||
_ux_device_stack_uninitialize();
|
||||
|
||||
/* And finally the usbx system resources. */
|
||||
_ux_system_uninitialize();
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
|
||||
static UINT demo_thread_hid_set_callback(UX_SLAVE_CLASS_HID *class, UX_SLAVE_CLASS_HID_EVENT *event)
|
||||
{
|
||||
_ux_utility_memory_copy(&device_hid_event, event, sizeof(UX_SLAVE_CLASS_HID_EVENT));
|
||||
return(UX_SUCCESS);
|
||||
}
|
||||
static UINT demo_thread_hid_get_callback(UX_SLAVE_CLASS_HID *class, UX_SLAVE_CLASS_HID_EVENT *event)
|
||||
{
|
||||
_ux_utility_memory_copy(event, &device_hid_event, sizeof(UX_SLAVE_CLASS_HID_EVENT));
|
||||
return(UX_SUCCESS);
|
||||
}
|
||||
|
||||
static void demo_device_hid_instance_activate(VOID *inst)
|
||||
{
|
||||
if (device_hid == UX_NULL)
|
||||
device_hid = (UX_SLAVE_CLASS_HID *)inst;
|
||||
}
|
||||
static void demo_device_hid_instance_deactivate(VOID *inst)
|
||||
{
|
||||
if (inst == (VOID *)device_hid)
|
||||
device_hid = UX_NULL;
|
||||
}
|
530
test/regression/usbx_class_hid_mouse_basic_test.c
Normal file
530
test/regression/usbx_class_hid_mouse_basic_test.c
Normal file
@ -0,0 +1,530 @@
|
||||
/* This file tests basic HID functionalities. */
|
||||
|
||||
#include "usbx_test_common_hid.h"
|
||||
#include "ux_host_class_hid_keyboard.h"
|
||||
|
||||
#define DUMMY_USBX_MEMORY_SIZE (64*1024)
|
||||
static UCHAR dummy_usbx_memory[DUMMY_USBX_MEMORY_SIZE];
|
||||
|
||||
static UCHAR hid_keyboard_report[] = {
|
||||
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||
0x09, 0x06, // USAGE (Keyboard)
|
||||
0xa1, 0x01, // COLLECTION (Application)
|
||||
|
||||
0x05, 0x07, // USAGE_PAGE (Keyboard)
|
||||
0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)
|
||||
0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x25, 0x01, // LOGICAL_MAXIMUM (1)
|
||||
0x75, 0x01, // REPORT_SIZE (1)
|
||||
0x95, 0x08, // REPORT_COUNT (8)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x81, 0x03, // INPUT (Cnst,Var,Abs)
|
||||
|
||||
0x95, 0x05, // REPORT_COUNT (5)
|
||||
0x75, 0x01, // REPORT_SIZE (1)
|
||||
0x05, 0x08, // USAGE_PAGE (LEDs)
|
||||
0x19, 0x01, // USAGE_MINIMUM (Num Lock)
|
||||
0x29, 0x05, // USAGE_MAXIMUM (Kana)
|
||||
0x91, 0x02, // OUTPUT (Data,Var,Abs)
|
||||
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x75, 0x03, // REPORT_SIZE (3)
|
||||
0x91, 0x03, // OUTPUT (Cnst,Var,Abs)
|
||||
|
||||
0x95, 0x06, // REPORT_COUNT (6)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x25, 0x65, // LOGICAL_MAXIMUM (101)
|
||||
0x05, 0x07, // USAGE_PAGE (Keyboard)
|
||||
0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
|
||||
0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)
|
||||
0x81, 0x00, // INPUT (Data,Ary,Abs)
|
||||
|
||||
0xc0 // END_COLLECTION
|
||||
};
|
||||
#define HID_KEYBOARD_REPORT_LENGTH sizeof(hid_keyboard_report)/sizeof(hid_keyboard_report[0])
|
||||
|
||||
static UCHAR hid_mouse_report[] = {
|
||||
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||
0x09, 0x02, // USAGE (Mouse)
|
||||
0xa1, 0x01, // COLLECTION (Application)
|
||||
0x09, 0x01, // USAGE (Pointer)
|
||||
0xa1, 0x00, // COLLECTION (Physical)
|
||||
0x05, 0x09, // USAGE_PAGE (Button)
|
||||
0x19, 0x01, // USAGE_MINIMUM (Button 1)
|
||||
0x29, 0x03, // USAGE_MAXIMUM (Button 3)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x25, 0x01, // LOGICAL_MAXIMUM (1)
|
||||
0x95, 0x03, // REPORT_COUNT (3)
|
||||
0x75, 0x01, // REPORT_SIZE (1)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x75, 0x05, // REPORT_SIZE (5)
|
||||
0x81, 0x03, // INPUT (Cnst,Var,Abs)
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||
0x09, 0x30, // USAGE (X)
|
||||
0x09, 0x31, // USAGE (Y)
|
||||
0x15, 0x81, // LOGICAL_MINIMUM (-127)
|
||||
0x25, 0x7f, // LOGICAL_MAXIMUM (127)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x95, 0x02, // REPORT_COUNT (2)
|
||||
0x81, 0x06, // INPUT (Data,Var,Rel)
|
||||
0x09, 0x38, // USAGE (Mouse Wheel)
|
||||
0x15, 0x81, // LOGICAL_MINIMUM (-127)
|
||||
0x25, 0x7f, // LOGICAL_MAXIMUM (127)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x81, 0x06, // INPUT (Data,Var,Rel)
|
||||
0xc0, // END_COLLECTION
|
||||
0xc0 // END_COLLECTION
|
||||
};
|
||||
#define HID_MOUSE_REPORT_LENGTH (sizeof(hid_mouse_report)/sizeof(hid_mouse_report[0]))
|
||||
|
||||
#define hid_report_descriptor hid_mouse_report
|
||||
#define HID_REPORT_LENGTH HID_MOUSE_REPORT_LENGTH
|
||||
|
||||
/* Configuration descriptor 9 bytes */
|
||||
#define CFG_DESC(wTotalLength, bNumInterfaces, bConfigurationValue)\
|
||||
/* Configuration 1 descriptor 9 bytes */\
|
||||
0x09, 0x02, LSB(wTotalLength), MSB(wTotalLength),\
|
||||
(bNumInterfaces), (bConfigurationValue), 0x00,\
|
||||
0x40, 0x00,
|
||||
#define CFG_DESC_LEN (9)
|
||||
|
||||
|
||||
/* HID Mouse/Keyboard interface descriptors 9+9+7=25 bytes */
|
||||
#define HID_IFC_DESC_ALL(ifc, report_len, interrupt_epa) \
|
||||
/* Interface descriptor */\
|
||||
0x09, 0x04, (ifc), 0x00, 0x01, 0x03, 0x00, 0x00, 0x00,\
|
||||
/* HID descriptor */\
|
||||
0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(report_len),\
|
||||
MSB(report_len),\
|
||||
/* Endpoint descriptor (Interrupt) */\
|
||||
0x07, 0x05, (interrupt_epa), 0x03, 0x08, 0x00, 0x08,
|
||||
#define HID_IFC_DESC_ALL_LEN (9+9+7)
|
||||
|
||||
static UCHAR device_framework_full_speed[] = {
|
||||
|
||||
/* Device descriptor */
|
||||
0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08,
|
||||
0x81, 0x0A, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x01,
|
||||
|
||||
CFG_DESC(CFG_DESC_LEN+1*HID_IFC_DESC_ALL_LEN, 1, 1)
|
||||
/* Keyboard */
|
||||
HID_IFC_DESC_ALL(0, HID_REPORT_LENGTH, 0x81)
|
||||
};
|
||||
#define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED sizeof(device_framework_full_speed)
|
||||
|
||||
static UCHAR device_framework_high_speed[] = {
|
||||
|
||||
/* Device descriptor */
|
||||
0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
|
||||
0x0a, 0x07, 0x25, 0x40, 0x01, 0x00, 0x01, 0x02,
|
||||
0x03, 0x01,
|
||||
|
||||
/* Device qualifier descriptor */
|
||||
0x0a, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
|
||||
0x01, 0x00,
|
||||
|
||||
CFG_DESC(CFG_DESC_LEN+1*HID_IFC_DESC_ALL_LEN, 1, 1)
|
||||
/* Keyboard */
|
||||
HID_IFC_DESC_ALL(0, HID_REPORT_LENGTH, 0x81)
|
||||
};
|
||||
#define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED sizeof(device_framework_high_speed)
|
||||
|
||||
|
||||
/* String Device Framework :
|
||||
Byte 0 and 1 : Word containing the language ID : 0x0904 for US
|
||||
Byte 2 : Byte containing the index of the descriptor
|
||||
Byte 3 : Byte containing the length of the descriptor string
|
||||
*/
|
||||
static UCHAR string_framework[] = {
|
||||
|
||||
/* Manufacturer string descriptor : Index 1 */
|
||||
0x09, 0x04, 0x01, 0x0c,
|
||||
0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
|
||||
0x6f, 0x67, 0x69, 0x63,
|
||||
|
||||
/* Product string descriptor : Index 2 */
|
||||
0x09, 0x04, 0x02, 0x0c,
|
||||
0x55, 0x53, 0x42, 0x20, 0x4b, 0x65, 0x79, 0x62,
|
||||
0x6f, 0x61, 0x72, 0x64,
|
||||
|
||||
/* Serial Number string descriptor : Index 3 */
|
||||
0x09, 0x04, 0x03, 0x04,
|
||||
0x30, 0x30, 0x30, 0x31
|
||||
};
|
||||
#define STRING_FRAMEWORK_LENGTH sizeof(string_framework)
|
||||
|
||||
|
||||
/* Multiple languages are supported on the device, to add
|
||||
a language besides english, the unicode language code must
|
||||
be appended to the language_id_framework array and the length
|
||||
adjusted accordingly. */
|
||||
static UCHAR language_id_framework[] = {
|
||||
|
||||
/* English. */
|
||||
0x09, 0x04
|
||||
};
|
||||
#define LANGUAGE_ID_FRAMEWORK_LENGTH sizeof(language_id_framework)
|
||||
|
||||
|
||||
UINT _ux_hcd_sim_host_entry(UX_HCD *hcd, UINT function, VOID *parameter);
|
||||
|
||||
|
||||
static UINT ux_system_host_change_function(ULONG event, UX_HOST_CLASS *cls, VOID *inst)
|
||||
{
|
||||
switch(event)
|
||||
{
|
||||
case UX_HID_CLIENT_INSERTION:
|
||||
break;
|
||||
case UX_HID_CLIENT_REMOVAL:
|
||||
break;
|
||||
#if defined(UX_HOST_STANDALONE)
|
||||
case UX_STANDALONE_WAIT_BACKGROUND_TASK:
|
||||
/* Let other threads to run. */
|
||||
tx_thread_relinquish();
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
|
||||
{
|
||||
}
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_class_hid_mouse_basic_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR * stack_pointer;
|
||||
CHAR * memory_pointer;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running HID Class Mouse Basic Test............................... ");
|
||||
|
||||
/* Initialize the free memory pointer */
|
||||
stack_pointer = (CHAR *) usbx_memory;
|
||||
memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
|
||||
|
||||
/* Initialize USBX. Memory */
|
||||
status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the error callback. */
|
||||
_ux_utility_error_callback_register(error_callback);
|
||||
|
||||
/* The code below is required for installing the host portion of USBX */
|
||||
status = ux_host_stack_initialize(ux_system_host_change_function);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = ux_host_stack_class_register(_ux_system_host_class_hid_name, ux_host_class_hid_entry);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the HID client(s). */
|
||||
status = ux_host_class_hid_client_register(_ux_system_host_class_hid_client_mouse_name, ux_host_class_hid_mouse_entry);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* The code below is required for installing the device portion of USBX. No call back for
|
||||
device status change in this example. */
|
||||
status = ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
|
||||
device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
|
||||
string_framework, STRING_FRAMEWORK_LENGTH,
|
||||
language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Initialize the hid class parameters. */
|
||||
ux_utility_memory_set(&hid_parameter, 0, sizeof(hid_parameter));
|
||||
hid_parameter.ux_device_class_hid_parameter_report_address = hid_report_descriptor;
|
||||
hid_parameter.ux_device_class_hid_parameter_report_length = HID_REPORT_LENGTH;
|
||||
hid_parameter.ux_device_class_hid_parameter_callback = demo_thread_hid_set_callback;
|
||||
hid_parameter.ux_device_class_hid_parameter_get_callback = demo_thread_hid_get_callback;
|
||||
|
||||
hid_parameter.ux_slave_class_hid_instance_activate = demo_device_hid_instance_activate;
|
||||
hid_parameter.ux_slave_class_hid_instance_deactivate = demo_device_hid_instance_deactivate;
|
||||
|
||||
/* Initialize the device hid class. The class is connected with interface 2 */
|
||||
status = ux_device_stack_class_register(_ux_system_slave_class_hid_name, ux_device_class_hid_entry,
|
||||
1, 0, (VOID *)&hid_parameter);
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Initialize the simulated device controller. */
|
||||
status = _ux_dcd_sim_slave_initialize();
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register all the USB host controllers available in this system */
|
||||
status = ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, ux_hcd_sim_host_initialize,0,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the main device simulation thread. */
|
||||
status = tx_thread_create(&tx_demo_thread_device_simulation, "tx demo device simulation", tx_demo_thread_device_simulation_entry, 0,
|
||||
stack_pointer, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
stack_pointer += UX_DEMO_STACK_SIZE;
|
||||
|
||||
/* Create the main host simulation thread. */
|
||||
status = tx_thread_create(&tx_demo_thread_host_simulation, "tx demo host simulation", tx_demo_thread_host_simulation_entry, 0,
|
||||
stack_pointer, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
static void tx_demo_thread_device_simulation_entry(ULONG arg)
|
||||
{
|
||||
while(1)
|
||||
{
|
||||
#if defined(UX_DEVICE_STANDALONE)
|
||||
ux_system_tasks_run();
|
||||
#else
|
||||
tx_thread_suspend(&tx_demo_thread_device_simulation);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static UINT demo_class_hid_wait(ULONG tick)
|
||||
{
|
||||
return(ux_test_sleep_break_on_success(tick, demo_class_hid_mouse_get));
|
||||
}
|
||||
|
||||
static UINT _wait_mouse_change(UX_HOST_CLASS_HID_MOUSE *mouse,
|
||||
ULONG *buttons, SLONG *x, SLONG *y, SLONG *w)
|
||||
{
|
||||
UINT status;
|
||||
UINT i;
|
||||
ULONG buttons_bak = *buttons;
|
||||
SLONG x_bak = *x, y_bak = *y;
|
||||
SLONG w_bak = *w;
|
||||
|
||||
for (i = 0; i < 200; i ++)
|
||||
{
|
||||
#if defined(UX_HOST_STANDALONE)
|
||||
ux_system_tasks_run();
|
||||
#endif
|
||||
ux_host_class_hid_mouse_buttons_get(hid_mouse, buttons);
|
||||
ux_host_class_hid_mouse_position_get(hid_mouse, x, y);
|
||||
ux_host_class_hid_mouse_wheel_get(hid_mouse, w);
|
||||
if (buttons_bak != *buttons ||
|
||||
x_bak != *x ||
|
||||
y_bak != *y ||
|
||||
w_bak != *w)
|
||||
{
|
||||
return(UX_SUCCESS);
|
||||
}
|
||||
tx_thread_sleep(1);
|
||||
}
|
||||
return(UX_ERROR);
|
||||
}
|
||||
|
||||
static void test_hid_mouse_events(VOID)
|
||||
{
|
||||
UINT status;
|
||||
ULONG buttons = 0;
|
||||
SLONG x = 0xFF, y = 0xFF;
|
||||
SLONG wheel = 0;
|
||||
|
||||
/* Initialize mouse event. */
|
||||
device_hid_event.ux_device_class_hid_event_length = 4;
|
||||
device_hid_event.ux_device_class_hid_event_buffer[0] = 0; /* ...M|R|L */
|
||||
device_hid_event.ux_device_class_hid_event_buffer[1] = 0; /* X */
|
||||
device_hid_event.ux_device_class_hid_event_buffer[2] = 0; /* Y */
|
||||
device_hid_event.ux_device_class_hid_event_buffer[3] = 0; /* Wheel */
|
||||
|
||||
status = ux_host_class_hid_mouse_buttons_get(hid_mouse, &buttons);
|
||||
status |= ux_host_class_hid_mouse_position_get(hid_mouse, &x, &y);
|
||||
status |= ux_host_class_hid_mouse_wheel_get(hid_mouse, &wheel);
|
||||
UX_ASSERT(status == UX_SUCCESS);
|
||||
UX_ASSERT(buttons == 0);
|
||||
UX_ASSERT(x == 0);
|
||||
UX_ASSERT(y == 0);
|
||||
UX_ASSERT(wheel == 0);
|
||||
|
||||
/* Set L click. */
|
||||
device_hid_event.ux_device_class_hid_event_buffer[0] = 1; /* ...M|R|L */
|
||||
_ux_device_class_hid_event_set(device_hid, &device_hid_event);
|
||||
status = _wait_mouse_change(hid_mouse, &buttons, &x, &y, &wheel);
|
||||
UX_ASSERT(status == UX_SUCCESS);
|
||||
UX_ASSERT(buttons == 1);
|
||||
UX_ASSERT(x == 0);
|
||||
UX_ASSERT(y == 0);
|
||||
UX_ASSERT(wheel == 0);
|
||||
|
||||
/* Set R click. */
|
||||
device_hid_event.ux_device_class_hid_event_buffer[0] = 3; /* ...M|R|L */
|
||||
_ux_device_class_hid_event_set(device_hid, &device_hid_event);
|
||||
status = _wait_mouse_change(hid_mouse, &buttons, &x, &y, &wheel);
|
||||
UX_ASSERT(status == UX_SUCCESS);
|
||||
UX_ASSERT(buttons == 3);
|
||||
UX_ASSERT(x == 0);
|
||||
UX_ASSERT(y == 0);
|
||||
UX_ASSERT(wheel == 0);
|
||||
|
||||
/* Move X. */
|
||||
device_hid_event.ux_device_class_hid_event_buffer[1] = -1; /* X */
|
||||
_ux_device_class_hid_event_set(device_hid, &device_hid_event);
|
||||
status = _wait_mouse_change(hid_mouse, &buttons, &x, &y, &wheel);
|
||||
UX_ASSERT(status == UX_SUCCESS);
|
||||
UX_ASSERT(buttons == 3);
|
||||
UX_ASSERT(x == -1);
|
||||
UX_ASSERT(y == 0);
|
||||
UX_ASSERT(wheel == 0);
|
||||
|
||||
/* Move X. */
|
||||
device_hid_event.ux_device_class_hid_event_buffer[1] = +8; /* X */
|
||||
_ux_device_class_hid_event_set(device_hid, &device_hid_event);
|
||||
status = _wait_mouse_change(hid_mouse, &buttons, &x, &y, &wheel);
|
||||
UX_ASSERT(status == UX_SUCCESS);
|
||||
UX_ASSERT(buttons == 3);
|
||||
UX_ASSERT(x == +7);
|
||||
UX_ASSERT(y == 0);
|
||||
UX_ASSERT(wheel == 0);
|
||||
|
||||
/* Move Y. */
|
||||
device_hid_event.ux_device_class_hid_event_buffer[2] = +8; /* Y */
|
||||
_ux_device_class_hid_event_set(device_hid, &device_hid_event);
|
||||
status = _wait_mouse_change(hid_mouse, &buttons, &x, &y, &wheel);
|
||||
UX_ASSERT(status == UX_SUCCESS);
|
||||
UX_ASSERT(buttons == 3);
|
||||
UX_ASSERT(x == 15);
|
||||
UX_ASSERT(y == 8);
|
||||
UX_ASSERT(wheel == 0);
|
||||
|
||||
/* Move Wheel. */
|
||||
device_hid_event.ux_device_class_hid_event_buffer[1] = -2; /* X */
|
||||
device_hid_event.ux_device_class_hid_event_buffer[2] = -5; /* Y */
|
||||
device_hid_event.ux_device_class_hid_event_buffer[3] = +10; /* Wheel */
|
||||
_ux_device_class_hid_event_set(device_hid, &device_hid_event);
|
||||
status = _wait_mouse_change(hid_mouse, &buttons, &x, &y, &wheel);
|
||||
UX_ASSERT(status == UX_SUCCESS);
|
||||
UX_ASSERT(buttons == 3);
|
||||
UX_ASSERT(x == 13);
|
||||
UX_ASSERT(y == 3);
|
||||
UX_ASSERT(wheel == 10);
|
||||
}
|
||||
|
||||
static void tx_demo_thread_host_simulation_entry(ULONG arg)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
/* Find the HID class */
|
||||
status = demo_class_hid_wait(100);
|
||||
UX_TEST_ASSERT(status == UX_SUCCESS);
|
||||
|
||||
test_hid_mouse_events();
|
||||
|
||||
/* Now disconnect the device. */
|
||||
_ux_device_stack_disconnect();
|
||||
|
||||
/* And deinitialize the class. */
|
||||
status = ux_device_stack_class_unregister(_ux_system_slave_class_hid_name, ux_device_class_hid_entry);
|
||||
|
||||
/* Deinitialize the device side of usbx. */
|
||||
_ux_device_stack_uninitialize();
|
||||
|
||||
/* And finally the usbx system resources. */
|
||||
_ux_system_uninitialize();
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
|
||||
static UINT demo_thread_hid_set_callback(UX_SLAVE_CLASS_HID *class, UX_SLAVE_CLASS_HID_EVENT *event)
|
||||
{
|
||||
_ux_utility_memory_copy(&device_hid_event, event, sizeof(UX_SLAVE_CLASS_HID_EVENT));
|
||||
return(UX_SUCCESS);
|
||||
}
|
||||
static UINT demo_thread_hid_get_callback(UX_SLAVE_CLASS_HID *class, UX_SLAVE_CLASS_HID_EVENT *event)
|
||||
{
|
||||
_ux_utility_memory_copy(event, &device_hid_event, sizeof(UX_SLAVE_CLASS_HID_EVENT));
|
||||
return(UX_SUCCESS);
|
||||
}
|
||||
|
||||
static void demo_device_hid_instance_activate(VOID *inst)
|
||||
{
|
||||
if (device_hid == UX_NULL)
|
||||
device_hid = (UX_SLAVE_CLASS_HID *)inst;
|
||||
}
|
||||
static void demo_device_hid_instance_deactivate(VOID *inst)
|
||||
{
|
||||
if (inst == (VOID *)device_hid)
|
||||
device_hid = UX_NULL;
|
||||
}
|
503
test/regression/usbx_class_hid_remote_control_basic_test.c
Normal file
503
test/regression/usbx_class_hid_remote_control_basic_test.c
Normal file
@ -0,0 +1,503 @@
|
||||
/* This file tests basic HID functionalities. */
|
||||
|
||||
#include "usbx_test_common_hid.h"
|
||||
#include "ux_host_class_hid_keyboard.h"
|
||||
|
||||
#define DUMMY_USBX_MEMORY_SIZE (64*1024)
|
||||
static UCHAR dummy_usbx_memory[DUMMY_USBX_MEMORY_SIZE];
|
||||
|
||||
static UCHAR hid_keyboard_report[] = {
|
||||
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||
0x09, 0x06, // USAGE (Keyboard)
|
||||
0xa1, 0x01, // COLLECTION (Application)
|
||||
|
||||
0x05, 0x07, // USAGE_PAGE (Keyboard)
|
||||
0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)
|
||||
0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x25, 0x01, // LOGICAL_MAXIMUM (1)
|
||||
0x75, 0x01, // REPORT_SIZE (1)
|
||||
0x95, 0x08, // REPORT_COUNT (8)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x81, 0x03, // INPUT (Cnst,Var,Abs)
|
||||
|
||||
0x95, 0x05, // REPORT_COUNT (5)
|
||||
0x75, 0x01, // REPORT_SIZE (1)
|
||||
0x05, 0x08, // USAGE_PAGE (LEDs)
|
||||
0x19, 0x01, // USAGE_MINIMUM (Num Lock)
|
||||
0x29, 0x05, // USAGE_MAXIMUM (Kana)
|
||||
0x91, 0x02, // OUTPUT (Data,Var,Abs)
|
||||
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x75, 0x03, // REPORT_SIZE (3)
|
||||
0x91, 0x03, // OUTPUT (Cnst,Var,Abs)
|
||||
|
||||
0x95, 0x06, // REPORT_COUNT (6)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x25, 0x65, // LOGICAL_MAXIMUM (101)
|
||||
0x05, 0x07, // USAGE_PAGE (Keyboard)
|
||||
0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
|
||||
0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)
|
||||
0x81, 0x00, // INPUT (Data,Ary,Abs)
|
||||
|
||||
0xc0 // END_COLLECTION
|
||||
};
|
||||
#define HID_KEYBOARD_REPORT_LENGTH sizeof(hid_keyboard_report)/sizeof(hid_keyboard_report[0])
|
||||
|
||||
static UCHAR hid_mouse_report[] = {
|
||||
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||
0x09, 0x02, // USAGE (Mouse)
|
||||
0xa1, 0x01, // COLLECTION (Application)
|
||||
0x09, 0x01, // USAGE (Pointer)
|
||||
0xa1, 0x00, // COLLECTION (Physical)
|
||||
0x05, 0x09, // USAGE_PAGE (Button)
|
||||
0x19, 0x01, // USAGE_MINIMUM (Button 1)
|
||||
0x29, 0x03, // USAGE_MAXIMUM (Button 3)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x25, 0x01, // LOGICAL_MAXIMUM (1)
|
||||
0x95, 0x03, // REPORT_COUNT (3)
|
||||
0x75, 0x01, // REPORT_SIZE (1)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x75, 0x05, // REPORT_SIZE (5)
|
||||
0x81, 0x03, // INPUT (Cnst,Var,Abs)
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||
0x09, 0x30, // USAGE (X)
|
||||
0x09, 0x31, // USAGE (Y)
|
||||
0x15, 0x81, // LOGICAL_MINIMUM (-127)
|
||||
0x25, 0x7f, // LOGICAL_MAXIMUM (127)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x95, 0x02, // REPORT_COUNT (2)
|
||||
0x81, 0x06, // INPUT (Data,Var,Rel)
|
||||
0x09, 0x38, // USAGE (Mouse Wheel)
|
||||
0x15, 0x81, // LOGICAL_MINIMUM (-127)
|
||||
0x25, 0x7f, // LOGICAL_MAXIMUM (127)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x81, 0x06, // INPUT (Data,Var,Rel)
|
||||
0xc0, // END_COLLECTION
|
||||
0xc0 // END_COLLECTION
|
||||
};
|
||||
#define HID_MOUSE_REPORT_LENGTH (sizeof(hid_mouse_report)/sizeof(hid_mouse_report[0]))
|
||||
|
||||
static UCHAR hid_remote_control_report[] = {
|
||||
|
||||
0x05, 0x0c, // USAGE_PAGE (Consumer Devices)
|
||||
0x09, 0x01, // USAGE (Consumer Control)
|
||||
0xa1, 0x01, // COLLECTION (Application)
|
||||
0x09, 0x02, // USAGE (Numeric Key Pad)
|
||||
0xa1, 0x02, // COLLECTION (Logical)
|
||||
0x05, 0x09, // USAGE_PAGE (Button)
|
||||
0x19, 0x01, // USAGE_MINIMUM (Button 1)
|
||||
0x29, 0x0a, // USAGE_MAXIMUM (Button 10)
|
||||
0x15, 0x01, // LOGICAL_MINIMUM (1)
|
||||
0x25, 0x0a, // LOGICAL_MAXIMUM (10)
|
||||
0x75, 0x04, // REPORT_SIZE (4)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x81, 0x00, // INPUT (Data,Ary,Abs)
|
||||
0xc0, // END_COLLECTION
|
||||
0x05, 0x0c, // USAGE_PAGE (Consumer Devices)
|
||||
0x09, 0x86, // USAGE (Channel)
|
||||
0x09, 0xe0, // USAGE (Volume)
|
||||
0x15, 0xff, // LOGICAL_MINIMUM (-1)
|
||||
0x25, 0x01, // LOGICAL_MAXIMUM (1)
|
||||
0x75, 0x02, // REPORT_SIZE (2)
|
||||
0x95, 0x02, // REPORT_COUNT (2)
|
||||
0x81, 0x46, // INPUT (Data,Var,Rel,Null)
|
||||
0xc0 // END_COLLECTION
|
||||
};
|
||||
#define HID_REMOTE_CONTROL_REPORT_LENGTH (sizeof(hid_remote_control_report)/sizeof(hid_remote_control_report[0]))
|
||||
|
||||
|
||||
#define hid_report_descriptor hid_remote_control_report
|
||||
#define HID_REPORT_LENGTH HID_REMOTE_CONTROL_REPORT_LENGTH
|
||||
|
||||
/* Configuration descriptor 9 bytes */
|
||||
#define CFG_DESC(wTotalLength, bNumInterfaces, bConfigurationValue)\
|
||||
/* Configuration 1 descriptor 9 bytes */\
|
||||
0x09, 0x02, LSB(wTotalLength), MSB(wTotalLength),\
|
||||
(bNumInterfaces), (bConfigurationValue), 0x00,\
|
||||
0x40, 0x00,
|
||||
#define CFG_DESC_LEN (9)
|
||||
|
||||
|
||||
/* HID Mouse/Keyboard interface descriptors 9+9+7=25 bytes */
|
||||
#define HID_IFC_DESC_ALL(ifc, report_len, interrupt_epa) \
|
||||
/* Interface descriptor */\
|
||||
0x09, 0x04, (ifc), 0x00, 0x01, 0x03, 0x00, 0x00, 0x00,\
|
||||
/* HID descriptor */\
|
||||
0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(report_len),\
|
||||
MSB(report_len),\
|
||||
/* Endpoint descriptor (Interrupt) */\
|
||||
0x07, 0x05, (interrupt_epa), 0x03, 0x08, 0x00, 0x08,
|
||||
#define HID_IFC_DESC_ALL_LEN (9+9+7)
|
||||
|
||||
static UCHAR device_framework_full_speed[] = {
|
||||
|
||||
/* Device descriptor */
|
||||
0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08,
|
||||
0x81, 0x0A, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x01,
|
||||
|
||||
CFG_DESC(CFG_DESC_LEN+1*HID_IFC_DESC_ALL_LEN, 1, 1)
|
||||
/* Keyboard */
|
||||
HID_IFC_DESC_ALL(0, HID_REPORT_LENGTH, 0x81)
|
||||
};
|
||||
#define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED sizeof(device_framework_full_speed)
|
||||
|
||||
static UCHAR device_framework_high_speed[] = {
|
||||
|
||||
/* Device descriptor */
|
||||
0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
|
||||
0x0a, 0x07, 0x25, 0x40, 0x01, 0x00, 0x01, 0x02,
|
||||
0x03, 0x01,
|
||||
|
||||
/* Device qualifier descriptor */
|
||||
0x0a, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
|
||||
0x01, 0x00,
|
||||
|
||||
CFG_DESC(CFG_DESC_LEN+1*HID_IFC_DESC_ALL_LEN, 1, 1)
|
||||
/* Keyboard */
|
||||
HID_IFC_DESC_ALL(0, HID_REPORT_LENGTH, 0x81)
|
||||
};
|
||||
#define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED sizeof(device_framework_high_speed)
|
||||
|
||||
|
||||
/* String Device Framework :
|
||||
Byte 0 and 1 : Word containing the language ID : 0x0904 for US
|
||||
Byte 2 : Byte containing the index of the descriptor
|
||||
Byte 3 : Byte containing the length of the descriptor string
|
||||
*/
|
||||
static UCHAR string_framework[] = {
|
||||
|
||||
/* Manufacturer string descriptor : Index 1 */
|
||||
0x09, 0x04, 0x01, 0x0c,
|
||||
0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
|
||||
0x6f, 0x67, 0x69, 0x63,
|
||||
|
||||
/* Product string descriptor : Index 2 */
|
||||
0x09, 0x04, 0x02, 0x0c,
|
||||
0x55, 0x53, 0x42, 0x20, 0x4b, 0x65, 0x79, 0x62,
|
||||
0x6f, 0x61, 0x72, 0x64,
|
||||
|
||||
/* Serial Number string descriptor : Index 3 */
|
||||
0x09, 0x04, 0x03, 0x04,
|
||||
0x30, 0x30, 0x30, 0x31
|
||||
};
|
||||
#define STRING_FRAMEWORK_LENGTH sizeof(string_framework)
|
||||
|
||||
|
||||
/* Multiple languages are supported on the device, to add
|
||||
a language besides english, the unicode language code must
|
||||
be appended to the language_id_framework array and the length
|
||||
adjusted accordingly. */
|
||||
static UCHAR language_id_framework[] = {
|
||||
|
||||
/* English. */
|
||||
0x09, 0x04
|
||||
};
|
||||
#define LANGUAGE_ID_FRAMEWORK_LENGTH sizeof(language_id_framework)
|
||||
|
||||
|
||||
UINT _ux_hcd_sim_host_entry(UX_HCD *hcd, UINT function, VOID *parameter);
|
||||
|
||||
|
||||
static UINT ux_system_host_change_function(ULONG event, UX_HOST_CLASS *cls, VOID *inst)
|
||||
{
|
||||
switch(event)
|
||||
{
|
||||
case UX_HID_CLIENT_INSERTION:
|
||||
break;
|
||||
case UX_HID_CLIENT_REMOVAL:
|
||||
break;
|
||||
#if defined(UX_HOST_STANDALONE)
|
||||
case UX_STANDALONE_WAIT_BACKGROUND_TASK:
|
||||
/* Let other threads to run. */
|
||||
tx_thread_relinquish();
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
|
||||
{
|
||||
}
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_class_hid_remote_control_basic_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR * stack_pointer;
|
||||
CHAR * memory_pointer;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running HID Class Remote Control Basic Test......................... ");
|
||||
|
||||
/* Initialize the free memory pointer */
|
||||
stack_pointer = (CHAR *) usbx_memory;
|
||||
memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
|
||||
|
||||
/* Initialize USBX. Memory */
|
||||
status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the error callback. */
|
||||
_ux_utility_error_callback_register(error_callback);
|
||||
|
||||
/* The code below is required for installing the host portion of USBX */
|
||||
status = ux_host_stack_initialize(ux_system_host_change_function);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = ux_host_stack_class_register(_ux_system_host_class_hid_name, ux_host_class_hid_entry);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the HID client(s). */
|
||||
status = ux_host_class_hid_client_register(_ux_system_host_class_hid_client_remote_control_name, ux_host_class_hid_remote_control_entry);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: 0x%x\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* The code below is required for installing the device portion of USBX. No call back for
|
||||
device status change in this example. */
|
||||
status = ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
|
||||
device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
|
||||
string_framework, STRING_FRAMEWORK_LENGTH,
|
||||
language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Initialize the hid class parameters. */
|
||||
hid_parameter.ux_device_class_hid_parameter_report_address = hid_report_descriptor;
|
||||
hid_parameter.ux_device_class_hid_parameter_report_length = HID_REPORT_LENGTH;
|
||||
hid_parameter.ux_device_class_hid_parameter_callback = demo_thread_hid_set_callback;
|
||||
hid_parameter.ux_device_class_hid_parameter_get_callback = demo_thread_hid_get_callback;
|
||||
|
||||
hid_parameter.ux_slave_class_hid_instance_activate = demo_device_hid_instance_activate;
|
||||
hid_parameter.ux_slave_class_hid_instance_deactivate = demo_device_hid_instance_deactivate;
|
||||
|
||||
/* Initilize the device hid class. The class is connected with interface 2 */
|
||||
status = ux_device_stack_class_register(_ux_system_slave_class_hid_name, ux_device_class_hid_entry,
|
||||
1, 0, (VOID *)&hid_parameter);
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Initialize the simulated device controller. */
|
||||
status = _ux_dcd_sim_slave_initialize();
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register all the USB host controllers available in this system */
|
||||
status = ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, ux_hcd_sim_host_initialize,0,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the main device simulation thread. */
|
||||
status = tx_thread_create(&tx_demo_thread_device_simulation, "tx demo device simulation", tx_demo_thread_device_simulation_entry, 0,
|
||||
stack_pointer, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
stack_pointer += UX_DEMO_STACK_SIZE;
|
||||
|
||||
/* Create the main host simulation thread. */
|
||||
status = tx_thread_create(&tx_demo_thread_host_simulation, "tx demo host simulation", tx_demo_thread_host_simulation_entry, 0,
|
||||
stack_pointer, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
static void tx_demo_thread_device_simulation_entry(ULONG arg)
|
||||
{
|
||||
while(1)
|
||||
{
|
||||
#if defined(UX_DEVICE_STANDALONE)
|
||||
ux_system_tasks_run();
|
||||
#else
|
||||
tx_thread_suspend(&tx_demo_thread_device_simulation);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static UINT demo_class_hid_wait(ULONG tick)
|
||||
{
|
||||
return(ux_test_sleep_break_on_success(tick, demo_class_hid_remote_control_get));
|
||||
}
|
||||
|
||||
static UINT _wait_remote_control_usage(UX_HOST_CLASS_HID_REMOTE_CONTROL *remote_control,
|
||||
ULONG *usage, ULONG *value)
|
||||
{
|
||||
UINT status;
|
||||
UINT i;
|
||||
|
||||
for (i = 0; i < 200; i ++)
|
||||
{
|
||||
#if defined(UX_HOST_STANDALONE)
|
||||
ux_system_tasks_run();
|
||||
#endif
|
||||
status = ux_host_class_hid_remote_control_usage_get(remote_control, usage, value);
|
||||
if (status == UX_SUCCESS)
|
||||
return(UX_SUCCESS);
|
||||
tx_thread_sleep(1);
|
||||
}
|
||||
return(UX_ERROR);
|
||||
}
|
||||
|
||||
static void test_hid_remote_control_events(VOID)
|
||||
{
|
||||
UINT status;
|
||||
ULONG usage;
|
||||
ULONG value;
|
||||
|
||||
/* Initialize mouse event. */
|
||||
device_hid_event.ux_device_class_hid_event_length = 1;
|
||||
device_hid_event.ux_device_class_hid_event_buffer[0] = 0; /* CH(2)|CH(2)|Bn(4) */
|
||||
|
||||
device_hid_event.ux_device_class_hid_event_buffer[0] = (3 << 6) | (1 << 4) | (10); /* CH(2)|CH(2)|Bn(4) */
|
||||
_ux_device_class_hid_event_set(device_hid, &device_hid_event);
|
||||
status = _wait_remote_control_usage(hid_remote_control, &usage, &value);
|
||||
UX_ASSERT(status == UX_SUCCESS);
|
||||
UX_ASSERT(usage == (0x90000+10));
|
||||
UX_ASSERT(value == 10);
|
||||
status = ux_host_class_hid_remote_control_usage_get(hid_remote_control, &usage, &value);
|
||||
UX_ASSERT(status == UX_SUCCESS);
|
||||
UX_ASSERT(usage == 0xc0086);
|
||||
UX_ASSERT(value == 1);
|
||||
status = ux_host_class_hid_remote_control_usage_get(hid_remote_control, &usage, &value);
|
||||
UX_ASSERT(status == UX_SUCCESS);
|
||||
UX_ASSERT(usage == 0xc00e0);
|
||||
UX_ASSERT(value == 3);
|
||||
|
||||
device_hid_event.ux_device_class_hid_event_buffer[0] = (1 << 6) | (0 << 4) | (5); /* CH(2)|CH(2)|Bn(4) */
|
||||
_ux_device_class_hid_event_set(device_hid, &device_hid_event);
|
||||
status = _wait_remote_control_usage(hid_remote_control, &usage, &value);
|
||||
UX_ASSERT(status == UX_SUCCESS);
|
||||
UX_ASSERT(usage == (0x90000+5));
|
||||
UX_ASSERT(value == 5);
|
||||
status = ux_host_class_hid_remote_control_usage_get(hid_remote_control, &usage, &value);
|
||||
UX_ASSERT(status == UX_SUCCESS);
|
||||
UX_ASSERT(usage == 0xc0086);
|
||||
UX_ASSERT(value == 0);
|
||||
status = ux_host_class_hid_remote_control_usage_get(hid_remote_control, &usage, &value);
|
||||
UX_ASSERT(status == UX_SUCCESS);
|
||||
UX_ASSERT(usage == 0xc00e0);
|
||||
UX_ASSERT(value == 1);
|
||||
}
|
||||
|
||||
static void tx_demo_thread_host_simulation_entry(ULONG arg)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
/* Find the HID class */
|
||||
status = demo_class_hid_wait(100);
|
||||
UX_TEST_ASSERT(status == UX_SUCCESS);
|
||||
|
||||
test_hid_remote_control_events();
|
||||
|
||||
/* Now disconnect the device. */
|
||||
_ux_device_stack_disconnect();
|
||||
|
||||
/* And deinitialize the class. */
|
||||
status = ux_device_stack_class_unregister(_ux_system_slave_class_hid_name, ux_device_class_hid_entry);
|
||||
|
||||
/* Deinitialize the device side of usbx. */
|
||||
_ux_device_stack_uninitialize();
|
||||
|
||||
/* And finally the usbx system resources. */
|
||||
_ux_system_uninitialize();
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
|
||||
static UINT demo_thread_hid_set_callback(UX_SLAVE_CLASS_HID *class, UX_SLAVE_CLASS_HID_EVENT *event)
|
||||
{
|
||||
_ux_utility_memory_copy(&device_hid_event, event, sizeof(UX_SLAVE_CLASS_HID_EVENT));
|
||||
return(UX_SUCCESS);
|
||||
}
|
||||
static UINT demo_thread_hid_get_callback(UX_SLAVE_CLASS_HID *class, UX_SLAVE_CLASS_HID_EVENT *event)
|
||||
{
|
||||
_ux_utility_memory_copy(event, &device_hid_event, sizeof(UX_SLAVE_CLASS_HID_EVENT));
|
||||
return(UX_SUCCESS);
|
||||
}
|
||||
|
||||
static void demo_device_hid_instance_activate(VOID *inst)
|
||||
{
|
||||
if (device_hid == UX_NULL)
|
||||
device_hid = (UX_SLAVE_CLASS_HID *)inst;
|
||||
}
|
||||
static void demo_device_hid_instance_deactivate(VOID *inst)
|
||||
{
|
||||
if (inst == (VOID *)device_hid)
|
||||
device_hid = UX_NULL;
|
||||
}
|
516
test/regression/usbx_class_interface_enumeration_test.c
Normal file
516
test/regression/usbx_class_interface_enumeration_test.c
Normal file
@ -0,0 +1,516 @@
|
||||
/* This test is designed to test the simple dpump host/device class operation. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
#include "ux_api.h"
|
||||
#include "ux_system.h"
|
||||
#include "ux_utility.h"
|
||||
#include "ux_host_class_dummy.h"
|
||||
#include "ux_device_class_dummy.h"
|
||||
#include "ux_test.h"
|
||||
|
||||
|
||||
/* Define USBX demo constants. */
|
||||
|
||||
#define UX_DEMO_STACK_SIZE 4096
|
||||
#define UX_DEMO_BUFFER_SIZE 2048
|
||||
#define UX_DEMO_RUN 1
|
||||
#define UX_DEMO_MEMORY_SIZE (64*1024)
|
||||
|
||||
|
||||
/* Define the counters used in the demo application... */
|
||||
|
||||
static ULONG thread_0_counter;
|
||||
static ULONG thread_1_counter;
|
||||
static ULONG error_counter;
|
||||
|
||||
|
||||
/* Define USBX demo global variables. */
|
||||
|
||||
static UX_HOST_CLASS *class_driver;
|
||||
static UX_HOST_CLASS_DUMMY *dummy;
|
||||
static UX_DEVICE_CLASS_DUMMY *dummy_slave;
|
||||
|
||||
static UINT expected_error;
|
||||
|
||||
#define _W0(w) ( (w) & 0xFF)
|
||||
#define _W1(w) (((w) >> 8) & 0xFF)
|
||||
|
||||
#define _DEVICE_DESCRIPTOR(cls, sub, protocol, pktsize, vid, pid, n_cfg) \
|
||||
0x12, 0x01, 0x10, 0x01, \
|
||||
(cls), (sub), (protocol), (pktsize), \
|
||||
_W0(vid), _W1(vid), _W0(pid), _W1(pid), \
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, (n_cfg),
|
||||
|
||||
#define _QUALIFIER_DESCRIPTOR(cls, sub, protocol, n_cfg) \
|
||||
0x0a, 0x06, 0x00, 0x02, \
|
||||
(cls), (sub), (protocol), 0x40, (n_cfg), 0x00,
|
||||
|
||||
#define _CONFIGURATION_DESCRIPTOR(total_len, n_ifc, cfg_val) \
|
||||
0x09, 0x02, _W0(total_len), _W1(total_len), (n_ifc), (cfg_val), \
|
||||
0x00, 0xc0, 0x32,
|
||||
|
||||
#define _INTERFACE_DESCRIPTOR(ifc_n, alt, n_ep, cls, sub, protocol) \
|
||||
0x09, 0x04, (ifc_n), (alt), (n_ep), (cls), (sub), (protocol), 0x00,
|
||||
|
||||
#define _ENDPOINT_DESCRIPTOR(addr, attr, pktsize, interval) \
|
||||
0x07, 0x05, (addr), (attr), _W0(pktsize), _W1(pktsize), (interval),
|
||||
|
||||
#define _CONFIGURATION_TOTAL_LENGTH (9+9+9+2*7)
|
||||
#define _CONFIGURATION_DESCRIPTORS(hs) \
|
||||
_CONFIGURATION_DESCRIPTOR(_CONFIGURATION_TOTAL_LENGTH, 1, 1) \
|
||||
_INTERFACE_DESCRIPTOR(0, 0, 0, 0x99, 0x99, 0x99) \
|
||||
_INTERFACE_DESCRIPTOR(0, 1, 2, 0x99, 0x99, 0x99) \
|
||||
_ENDPOINT_DESCRIPTOR(0x01, 0x02, (hs) ? 512 : 64, 0x00) \
|
||||
_ENDPOINT_DESCRIPTOR(0x82, 0x02, (hs) ? 512 : 64, 0x00)
|
||||
|
||||
#define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED sizeof(device_framework_full_speed)
|
||||
static UCHAR device_framework_full_speed[] = {
|
||||
_DEVICE_DESCRIPTOR(0x00, 0x00, 0x00, 8, 0x08EC, 0x0001, 1)
|
||||
_CONFIGURATION_DESCRIPTORS(0)
|
||||
};
|
||||
|
||||
|
||||
#define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED sizeof(device_framework_high_speed)
|
||||
static UCHAR device_framework_high_speed[] = {
|
||||
_DEVICE_DESCRIPTOR(0x00, 0x00, 0x00, 64, 0x08EC, 0x0001, 1)
|
||||
_QUALIFIER_DESCRIPTOR(0, 0, 0, 1)
|
||||
_CONFIGURATION_DESCRIPTORS(1)
|
||||
};
|
||||
|
||||
/* String Device Framework :
|
||||
Byte 0 and 1 : Word containing the language ID : 0x0904 for US
|
||||
Byte 2 : Byte containing the index of the descriptor
|
||||
Byte 3 : Byte containing the length of the descriptor string
|
||||
*/
|
||||
#define STRING_FRAMEWORK_LENGTH sizeof(string_framework)
|
||||
static UCHAR string_framework[] = {
|
||||
|
||||
/* Manufacturer string descriptor : Index 1 */
|
||||
0x09, 0x04, 0x01, 0x0c,
|
||||
0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
|
||||
0x6f, 0x67, 0x69, 0x63,
|
||||
|
||||
/* Product string descriptor : Index 2 */
|
||||
0x09, 0x04, 0x02, 0x0c,
|
||||
0x44, 0x61, 0x74, 0x61, 0x50, 0x75, 0x6d, 0x70,
|
||||
0x44, 0x65, 0x6d, 0x6f,
|
||||
|
||||
/* Serial Number string descriptor : Index 3 */
|
||||
0x09, 0x04, 0x03, 0x04,
|
||||
0x30, 0x30, 0x30, 0x31
|
||||
};
|
||||
|
||||
|
||||
/* Multiple languages are supported on the device, to add
|
||||
a language besides English, the unicode language code must
|
||||
be appended to the language_id_framework array and the length
|
||||
adjusted accordingly. */
|
||||
#define LANGUAGE_ID_FRAMEWORK_LENGTH sizeof(language_id_framework)
|
||||
static UCHAR language_id_framework[] = {
|
||||
|
||||
/* English. */
|
||||
0x09, 0x04
|
||||
};
|
||||
|
||||
|
||||
/* Define prototypes for external Host Controller's (HCDs), classes and clients. */
|
||||
|
||||
static VOID tx_demo_instance_activate(VOID *dummy_instance);
|
||||
static VOID tx_demo_instance_deactivate(VOID *dummy_instance);
|
||||
static VOID tx_demo_instance_change(UX_DEVICE_CLASS_DUMMY *dummy_instance);
|
||||
|
||||
#if defined(UX_HOST_STANDALONE)
|
||||
static UINT tx_demo_host_change_function(ULONG e, UX_HOST_CLASS *c, VOID *p);
|
||||
#else
|
||||
#define tx_demo_host_change_function UX_NULL
|
||||
#endif
|
||||
|
||||
UINT ux_hcd_sim_initialize(UX_HCD *hcd);
|
||||
|
||||
static TX_THREAD tx_demo_thread_host_simulation;
|
||||
static TX_THREAD tx_demo_thread_slave_simulation;
|
||||
static void tx_demo_thread_host_simulation_entry(ULONG);
|
||||
static void tx_demo_thread_slave_simulation_entry(ULONG);
|
||||
|
||||
|
||||
/* Define the ISR dispatch. */
|
||||
|
||||
extern VOID (*test_isr_dispatch)(void);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
/* Define the ISR dispatch routine. */
|
||||
|
||||
static void test_isr(void)
|
||||
{
|
||||
|
||||
/* For further expansion of interrupt-level testing. */
|
||||
}
|
||||
|
||||
|
||||
static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
|
||||
{
|
||||
if (expected_error == 0 || error_code != expected_error)
|
||||
{
|
||||
/* Failed test. */
|
||||
printf("Error on line %d, system_level: %d, system_context: %d, error code: %x\n", __LINE__, system_level, system_context, error_code);
|
||||
// test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_class_interface_enumeration_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *stack_pointer;
|
||||
CHAR *memory_pointer;
|
||||
UX_DEVICE_CLASS_DUMMY_PARAMETER parameter;
|
||||
|
||||
|
||||
printf("Running Basic Interface Class Enumeration Test...................... ");
|
||||
|
||||
/* Initialize the free memory pointer. */
|
||||
stack_pointer = (CHAR *) first_unused_memory;
|
||||
memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
|
||||
|
||||
/* Initialize USBX Memory. */
|
||||
status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL, 0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the error callback. */
|
||||
_ux_utility_error_callback_register(error_callback);
|
||||
|
||||
/* The code below is required for installing the host portion of USBX. */
|
||||
status = ux_host_stack_initialize(tx_demo_host_change_function);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register all the host class drivers for this USBX implementation. */
|
||||
status = ux_host_stack_class_register(_ux_host_class_dummy_name, _ux_host_class_dummy_entry);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* The code below is required for installing the device portion of USBX */
|
||||
status = ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
|
||||
device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
|
||||
string_framework, STRING_FRAMEWORK_LENGTH,
|
||||
language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH, UX_NULL);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Set the parameters for callback when insertion/extraction of a Data Pump device. */
|
||||
_ux_utility_memory_set((void *)¶meter, 0x00, sizeof(parameter));
|
||||
parameter.ux_device_class_dummy_parameter_callbacks.ux_device_class_dummy_instance_activate = tx_demo_instance_activate;
|
||||
parameter.ux_device_class_dummy_parameter_callbacks.ux_device_class_dummy_instance_deactivate = tx_demo_instance_deactivate;
|
||||
parameter.ux_device_class_dummy_parameter_callbacks.ux_device_class_dummy_change = tx_demo_instance_change;
|
||||
|
||||
/* Initialize the device dpump class. The class is connected with interface 0 */
|
||||
status = ux_device_stack_class_register(_ux_device_class_dummy_name, _ux_device_class_dummy_entry,
|
||||
1, 0, ¶meter);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Initialize the simulated device controller. */
|
||||
status = _ux_dcd_sim_slave_initialize();
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register all the USB host controllers available in this system */
|
||||
status = ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, ux_hcd_sim_host_initialize,0,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the main host simulation thread. */
|
||||
status = tx_thread_create(&tx_demo_thread_host_simulation, "tx demo host simulation", tx_demo_thread_host_simulation_entry, 0,
|
||||
stack_pointer, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the main demo thread. */
|
||||
status = tx_thread_create(&tx_demo_thread_slave_simulation, "tx demo slave simulation", tx_demo_thread_slave_simulation_entry, 0,
|
||||
stack_pointer + UX_DEMO_STACK_SIZE, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
static UINT ux_demo_dummy_instance_check(VOID)
|
||||
{
|
||||
UINT status;
|
||||
UX_HOST_CLASS *cls;
|
||||
status = ux_host_stack_class_get(_ux_host_class_dummy_name, &cls);
|
||||
if (status != UX_SUCCESS)
|
||||
return(status);
|
||||
status = ux_host_stack_class_instance_get(cls, 0, (VOID **) &dummy);
|
||||
if (status != UX_SUCCESS)
|
||||
return(status);
|
||||
if (dummy -> ux_host_class_dummy_state != UX_HOST_CLASS_INSTANCE_LIVE)
|
||||
return(UX_NO_CLASS_MATCH);
|
||||
return(UX_SUCCESS);
|
||||
}
|
||||
|
||||
static UINT ux_demo_dummy_instance_connect_wait(ULONG wait_ticks)
|
||||
{
|
||||
ULONG t0 = tx_time_get(), t1;
|
||||
while(1)
|
||||
{
|
||||
#if defined(UX_HOST_STANDALONE)
|
||||
ux_system_tasks_run();
|
||||
#endif
|
||||
if (UX_SUCCESS == ux_demo_dummy_instance_check())
|
||||
return(UX_SUCCESS);
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* Wait forever. */
|
||||
if (wait_ticks == 0xFFFFFFFFul)
|
||||
continue;
|
||||
|
||||
/* No wait. */
|
||||
if (wait_ticks == 0)
|
||||
break;
|
||||
|
||||
/* Check timeout. */
|
||||
t1 = tx_time_get();
|
||||
if (t1 >= t0)
|
||||
t1 = t1 - t0;
|
||||
else
|
||||
t1 = 0xFFFFFFFFul - t0 + t1;
|
||||
if (t1 > wait_ticks)
|
||||
break;
|
||||
}
|
||||
return(UX_ERROR);
|
||||
}
|
||||
|
||||
static UINT ux_demo_dummy_instance_remove_wait(ULONG wait_ticks)
|
||||
{
|
||||
ULONG t0 = tx_time_get(), t1;
|
||||
while(1)
|
||||
{
|
||||
#if defined(UX_HOST_STANDALONE)
|
||||
ux_system_tasks_run();
|
||||
#endif
|
||||
if (UX_SUCCESS != ux_demo_dummy_instance_check())
|
||||
{
|
||||
dummy = UX_NULL;
|
||||
return(UX_SUCCESS);
|
||||
}
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* Wait forever. */
|
||||
if (wait_ticks == 0xFFFFFFFFul)
|
||||
continue;
|
||||
|
||||
/* No wait. */
|
||||
if (wait_ticks == 0)
|
||||
break;
|
||||
|
||||
/* Check timeout. */
|
||||
t1 = tx_time_get();
|
||||
if (t1 >= t0)
|
||||
t1 = t1 - t0;
|
||||
else
|
||||
t1 = 0xFFFFFFFFul - t0 + t1;
|
||||
if (t1 > wait_ticks)
|
||||
break;
|
||||
}
|
||||
return(UX_ERROR);
|
||||
}
|
||||
|
||||
static void tx_demo_thread_host_simulation_entry(ULONG arg)
|
||||
{
|
||||
UINT status;
|
||||
UX_DEVICE *device;
|
||||
UX_CONFIGURATION *configuration;
|
||||
UX_INTERFACE *interface;
|
||||
|
||||
stepinfo(">>>> Dummy Class Connection Wait\n");
|
||||
status = ux_demo_dummy_instance_connect_wait(1000);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
stepinfo(">>>> Dummy Class Configuration Deactivate\n");
|
||||
interface = dummy -> ux_host_class_dummy_interface;
|
||||
configuration = interface -> ux_interface_configuration;
|
||||
device = configuration -> ux_configuration_device;
|
||||
status = ux_host_stack_device_configuration_deactivate(device);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
status = ux_demo_dummy_instance_remove_wait(10);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
stepinfo(">>>> Dummy Class Configuration Activate\n");
|
||||
status = ux_host_stack_device_configuration_activate(configuration);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
status = ux_demo_dummy_instance_connect_wait(1000);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#if UX_TEST_MULTI_ALT_ON
|
||||
stepinfo(">>>> Dummy Class Interface Change\n");
|
||||
status = _ux_host_class_dummy_select_interface(dummy, 0, 1);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
printf("ERROR #%d, 0x%x\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
status = _ux_host_class_dummy_select_interface(dummy, 0, 0);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
printf("ERROR #%d, 0x%x\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
expected_error = 0;
|
||||
|
||||
/* Sleep for a tick to make sure everything is complete. */
|
||||
tx_thread_sleep(1);
|
||||
|
||||
/* Check for errors from other threads. */
|
||||
if (error_counter)
|
||||
{
|
||||
|
||||
/* DPUMP error. */
|
||||
printf("ERROR #%d: total %ld errors\n", __LINE__, error_counter);
|
||||
test_control_return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void tx_demo_thread_slave_simulation_entry(ULONG arg)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
ULONG actual_length;
|
||||
|
||||
|
||||
while(1)
|
||||
{
|
||||
#if defined(UX_DEVICE_STANDALONE)
|
||||
|
||||
/* Run device tasks. */
|
||||
ux_system_tasks_run();
|
||||
#endif
|
||||
/* Increment thread counter. */
|
||||
thread_1_counter++;
|
||||
|
||||
/* Relinquish to other thread. */
|
||||
tx_thread_relinquish();
|
||||
}
|
||||
}
|
||||
|
||||
static VOID tx_demo_instance_activate(VOID *inst)
|
||||
{
|
||||
dummy_slave = (UX_DEVICE_CLASS_DUMMY *)inst;
|
||||
}
|
||||
|
||||
static VOID tx_demo_instance_deactivate(VOID *inst)
|
||||
{
|
||||
dummy_slave = UX_NULL;
|
||||
}
|
||||
|
||||
static VOID tx_demo_instance_change(UX_DEVICE_CLASS_DUMMY *dummy)
|
||||
{
|
||||
UX_PARAMETER_NOT_USED(dummy);
|
||||
}
|
||||
|
||||
#if defined(UX_HOST_STANDALONE)
|
||||
static UINT tx_demo_host_change_function(ULONG e, UX_HOST_CLASS *c, VOID *p)
|
||||
{
|
||||
if (e == UX_STANDALONE_WAIT_BACKGROUND_TASK)
|
||||
{
|
||||
tx_thread_relinquish();
|
||||
}
|
||||
}
|
||||
#endif
|
561
test/regression/usbx_class_multi_interface_enumeration_test.c
Normal file
561
test/regression/usbx_class_multi_interface_enumeration_test.c
Normal file
@ -0,0 +1,561 @@
|
||||
/* This test is designed to test the simple dpump host/device class operation. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
#include "ux_api.h"
|
||||
#include "ux_system.h"
|
||||
#include "ux_utility.h"
|
||||
#include "ux_host_class_dummy.h"
|
||||
#include "ux_device_class_dummy.h"
|
||||
#include "ux_test.h"
|
||||
|
||||
|
||||
/* Define USBX demo constants. */
|
||||
|
||||
#define UX_DEMO_STACK_SIZE 4096
|
||||
#define UX_DEMO_BUFFER_SIZE 2048
|
||||
#define UX_DEMO_RUN 1
|
||||
#define UX_DEMO_MEMORY_SIZE (64*1024)
|
||||
|
||||
|
||||
/* Define the counters used in the demo application... */
|
||||
|
||||
static ULONG thread_0_counter;
|
||||
static ULONG thread_1_counter;
|
||||
static ULONG error_counter;
|
||||
|
||||
|
||||
/* Define USBX demo global variables. */
|
||||
|
||||
static UX_HOST_CLASS *class_driver;
|
||||
static UX_HOST_CLASS_DUMMY *dummy;
|
||||
static UX_DEVICE_CLASS_DUMMY *dummy_slave;
|
||||
|
||||
static UINT expected_error;
|
||||
|
||||
#define _W0(w) ( (w) & 0xFF)
|
||||
#define _W1(w) (((w) >> 8) & 0xFF)
|
||||
|
||||
#define _DEVICE_DESCRIPTOR(cls, sub, protocol, pktsize, vid, pid, n_cfg) \
|
||||
0x12, 0x01, 0x10, 0x01, \
|
||||
(cls), (sub), (protocol), (pktsize), \
|
||||
_W0(vid), _W1(vid), _W0(pid), _W1(pid), \
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, (n_cfg),
|
||||
|
||||
#define _QUALIFIER_DESCRIPTOR(cls, sub, protocol, n_cfg) \
|
||||
0x0a, 0x06, 0x00, 0x02, \
|
||||
(cls), (sub), (protocol), 0x40, (n_cfg), 0x00,
|
||||
|
||||
#define _CONFIGURATION_DESCRIPTOR(total_len, n_ifc, cfg_val) \
|
||||
0x09, 0x02, _W0(total_len), _W1(total_len), (n_ifc), (cfg_val), \
|
||||
0x00, 0xc0, 0x32,
|
||||
|
||||
#define _INTERFACE_DESCRIPTOR(ifc_n, alt, n_ep, cls, sub, protocol) \
|
||||
0x09, 0x04, (ifc_n), (alt), (n_ep), (cls), (sub), (protocol), 0x00,
|
||||
|
||||
#define _ENDPOINT_DESCRIPTOR(addr, attr, pktsize, interval) \
|
||||
0x07, 0x05, (addr), (attr), _W0(pktsize), _W1(pktsize), (interval),
|
||||
|
||||
#define _CONFIGURATION_TOTAL_LENGTH (9+9*3+7*4)
|
||||
#define _CONFIGURATION_DESCRIPTORS(hs) \
|
||||
_CONFIGURATION_DESCRIPTOR(_CONFIGURATION_TOTAL_LENGTH, 3, 1) \
|
||||
_INTERFACE_DESCRIPTOR(0, 0, 1, 0x0E, 0x00, 0x00) \
|
||||
_ENDPOINT_DESCRIPTOR(0x03, 0x02, 8, 0x04) \
|
||||
_INTERFACE_DESCRIPTOR(1, 0, 2, 0x99, 0x99, 0x99) \
|
||||
_ENDPOINT_DESCRIPTOR(0x01, 0x02, (hs) ? 512 : 64, 0x00) \
|
||||
_ENDPOINT_DESCRIPTOR(0x82, 0x02, (hs) ? 512 : 64, 0x00) \
|
||||
_INTERFACE_DESCRIPTOR(2, 0, 1, 0x0E, 0x00, 0x00) \
|
||||
_ENDPOINT_DESCRIPTOR(0x84, 0x02,32, 0x04)
|
||||
|
||||
#define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED sizeof(device_framework_full_speed)
|
||||
static UCHAR device_framework_full_speed[] = {
|
||||
_DEVICE_DESCRIPTOR(0x00, 0x00, 0x00, 8, 0x08EC, 0x0001, 1)
|
||||
_CONFIGURATION_DESCRIPTORS(0)
|
||||
};
|
||||
|
||||
|
||||
#define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED sizeof(device_framework_high_speed)
|
||||
static UCHAR device_framework_high_speed[] = {
|
||||
_DEVICE_DESCRIPTOR(0x00, 0x00, 0x00, 64, 0x08EC, 0x0001, 1)
|
||||
_QUALIFIER_DESCRIPTOR(0, 0, 0, 1)
|
||||
_CONFIGURATION_DESCRIPTORS(1)
|
||||
};
|
||||
|
||||
/* String Device Framework :
|
||||
Byte 0 and 1 : Word containing the language ID : 0x0904 for US
|
||||
Byte 2 : Byte containing the index of the descriptor
|
||||
Byte 3 : Byte containing the length of the descriptor string
|
||||
*/
|
||||
#define STRING_FRAMEWORK_LENGTH sizeof(string_framework)
|
||||
static UCHAR string_framework[] = {
|
||||
|
||||
/* Manufacturer string descriptor : Index 1 */
|
||||
0x09, 0x04, 0x01, 0x0c,
|
||||
0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
|
||||
0x6f, 0x67, 0x69, 0x63,
|
||||
|
||||
/* Product string descriptor : Index 2 */
|
||||
0x09, 0x04, 0x02, 0x0c,
|
||||
0x44, 0x61, 0x74, 0x61, 0x50, 0x75, 0x6d, 0x70,
|
||||
0x44, 0x65, 0x6d, 0x6f,
|
||||
|
||||
/* Serial Number string descriptor : Index 3 */
|
||||
0x09, 0x04, 0x03, 0x04,
|
||||
0x30, 0x30, 0x30, 0x31
|
||||
};
|
||||
|
||||
|
||||
/* Multiple languages are supported on the device, to add
|
||||
a language besides English, the unicode language code must
|
||||
be appended to the language_id_framework array and the length
|
||||
adjusted accordingly. */
|
||||
#define LANGUAGE_ID_FRAMEWORK_LENGTH sizeof(language_id_framework)
|
||||
static UCHAR language_id_framework[] = {
|
||||
|
||||
/* English. */
|
||||
0x09, 0x04
|
||||
};
|
||||
|
||||
|
||||
static UX_HOST_CLASS_DUMMY_QUERY _accept_0x99_0x99_0x99[] =
|
||||
{
|
||||
{.ux_host_class_query_on = UX_TRUE,
|
||||
.ux_host_class_query_usage = UX_HOST_CLASS_COMMAND_USAGE_CSP,
|
||||
.ux_host_class_query_class = 0x99,
|
||||
.ux_host_class_query_subclass = 0x99,
|
||||
.ux_host_class_query_protocol = 0x99},
|
||||
{0}
|
||||
};
|
||||
|
||||
/* Define prototypes for external Host Controller's (HCDs), classes and clients. */
|
||||
|
||||
static VOID tx_demo_instance_activate(VOID *dummy_instance);
|
||||
static VOID tx_demo_instance_deactivate(VOID *dummy_instance);
|
||||
static VOID tx_demo_instance_change(UX_DEVICE_CLASS_DUMMY *dummy_instance);
|
||||
|
||||
#if defined(UX_HOST_STANDALONE)
|
||||
static UINT tx_demo_host_change_function(ULONG e, UX_HOST_CLASS *c, VOID *p);
|
||||
#else
|
||||
#define tx_demo_host_change_function UX_NULL
|
||||
#endif
|
||||
|
||||
UINT ux_hcd_sim_initialize(UX_HCD *hcd);
|
||||
|
||||
static TX_THREAD tx_demo_thread_host_simulation;
|
||||
static TX_THREAD tx_demo_thread_slave_simulation;
|
||||
static void tx_demo_thread_host_simulation_entry(ULONG);
|
||||
static void tx_demo_thread_slave_simulation_entry(ULONG);
|
||||
|
||||
|
||||
/* Define the ISR dispatch. */
|
||||
|
||||
extern VOID (*test_isr_dispatch)(void);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
/* Define the ISR dispatch routine. */
|
||||
|
||||
static void test_isr(void)
|
||||
{
|
||||
|
||||
/* For further expansion of interrupt-level testing. */
|
||||
}
|
||||
|
||||
|
||||
static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
|
||||
{
|
||||
if (expected_error == 0 || error_code != expected_error)
|
||||
{
|
||||
/* Failed test. */
|
||||
printf("Error on line %d, system_level: %d, system_context: %d, error code: %x\n", __LINE__, system_level, system_context, error_code);
|
||||
// test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_class_multi_interface_enumeration_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *stack_pointer;
|
||||
CHAR *memory_pointer;
|
||||
UX_DEVICE_CLASS_DUMMY_PARAMETER parameter;
|
||||
|
||||
|
||||
printf("Running Multiple Interface Class Enumeration Test................... ");
|
||||
|
||||
/* Initialize the free memory pointer. */
|
||||
stack_pointer = (CHAR *) first_unused_memory;
|
||||
memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
|
||||
|
||||
/* Initialize USBX Memory. */
|
||||
status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL, 0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the error callback. */
|
||||
_ux_utility_error_callback_register(error_callback);
|
||||
|
||||
/* The code below is required for installing the host portion of USBX. */
|
||||
status = ux_host_stack_initialize(tx_demo_host_change_function);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register all the host class drivers for this USBX implementation. */
|
||||
status = ux_host_stack_class_register(_ux_host_class_dummy_name, _ux_host_class_dummy_entry);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* The code below is required for installing the device portion of USBX */
|
||||
status = ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
|
||||
device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
|
||||
string_framework, STRING_FRAMEWORK_LENGTH,
|
||||
language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH, UX_NULL);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Set the parameters for callback when insertion/extraction of a Data Pump device. */
|
||||
_ux_utility_memory_set((void *)¶meter, 0x00, sizeof(parameter));
|
||||
parameter.ux_device_class_dummy_parameter_callbacks.ux_device_class_dummy_instance_activate = tx_demo_instance_activate;
|
||||
parameter.ux_device_class_dummy_parameter_callbacks.ux_device_class_dummy_instance_deactivate = tx_demo_instance_deactivate;
|
||||
parameter.ux_device_class_dummy_parameter_callbacks.ux_device_class_dummy_change = tx_demo_instance_change;
|
||||
|
||||
/* Initialize the device dpump class. The class is connected with interface 0 */
|
||||
_ux_host_class_dummy_query_reject_unknown_set(UX_TRUE);
|
||||
_ux_host_class_dummy_query_list_set(_accept_0x99_0x99_0x99);
|
||||
status = ux_device_stack_class_register(_ux_device_class_dummy_name, _ux_device_class_dummy_entry,
|
||||
1, 0, ¶meter);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Initialize the simulated device controller. */
|
||||
status = _ux_dcd_sim_slave_initialize();
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register all the USB host controllers available in this system */
|
||||
status = ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, ux_hcd_sim_host_initialize,0,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the main host simulation thread. */
|
||||
status = tx_thread_create(&tx_demo_thread_host_simulation, "tx demo host simulation", tx_demo_thread_host_simulation_entry, 0,
|
||||
stack_pointer, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the main demo thread. */
|
||||
status = tx_thread_create(&tx_demo_thread_slave_simulation, "tx demo slave simulation", tx_demo_thread_slave_simulation_entry, 0,
|
||||
stack_pointer + UX_DEMO_STACK_SIZE, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
static UINT ux_demo_dummy_instance_check(VOID)
|
||||
{
|
||||
UINT status;
|
||||
UX_HOST_CLASS *cls;
|
||||
status = ux_host_stack_class_get(_ux_host_class_dummy_name, &cls);
|
||||
if (status != UX_SUCCESS)
|
||||
return(status);
|
||||
status = ux_host_stack_class_instance_get(cls, 0, (VOID **) &dummy);
|
||||
if (status != UX_SUCCESS)
|
||||
return(status);
|
||||
if (dummy -> ux_host_class_dummy_state != UX_HOST_CLASS_INSTANCE_LIVE)
|
||||
return(UX_NO_CLASS_MATCH);
|
||||
return(UX_SUCCESS);
|
||||
}
|
||||
|
||||
static UINT ux_demo_dummy_instance_connect_wait(ULONG wait_ticks)
|
||||
{
|
||||
ULONG t0 = tx_time_get(), t1;
|
||||
while(1)
|
||||
{
|
||||
#if defined(UX_HOST_STANDALONE)
|
||||
ux_system_tasks_run();
|
||||
#endif
|
||||
if (UX_SUCCESS == ux_demo_dummy_instance_check())
|
||||
return(UX_SUCCESS);
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* Wait forever. */
|
||||
if (wait_ticks == 0xFFFFFFFFul)
|
||||
continue;
|
||||
|
||||
/* No wait. */
|
||||
if (wait_ticks == 0)
|
||||
break;
|
||||
|
||||
/* Check timeout. */
|
||||
t1 = tx_time_get();
|
||||
if (t1 >= t0)
|
||||
t1 = t1 - t0;
|
||||
else
|
||||
t1 = 0xFFFFFFFFul - t0 + t1;
|
||||
if (t1 > wait_ticks)
|
||||
break;
|
||||
}
|
||||
return(UX_ERROR);
|
||||
}
|
||||
|
||||
static UINT ux_demo_dummy_instance_remove_wait(ULONG wait_ticks)
|
||||
{
|
||||
ULONG t0 = tx_time_get(), t1;
|
||||
while(1)
|
||||
{
|
||||
#if defined(UX_HOST_STANDALONE)
|
||||
ux_system_tasks_run();
|
||||
#endif
|
||||
if (UX_SUCCESS != ux_demo_dummy_instance_check())
|
||||
{
|
||||
dummy = UX_NULL;
|
||||
return(UX_SUCCESS);
|
||||
}
|
||||
tx_thread_relinquish();
|
||||
|
||||
/* Wait forever. */
|
||||
if (wait_ticks == 0xFFFFFFFFul)
|
||||
continue;
|
||||
|
||||
/* No wait. */
|
||||
if (wait_ticks == 0)
|
||||
break;
|
||||
|
||||
/* Check timeout. */
|
||||
t1 = tx_time_get();
|
||||
if (t1 >= t0)
|
||||
t1 = t1 - t0;
|
||||
else
|
||||
t1 = 0xFFFFFFFFul - t0 + t1;
|
||||
if (t1 > wait_ticks)
|
||||
break;
|
||||
}
|
||||
return(UX_ERROR);
|
||||
}
|
||||
|
||||
static void tx_demo_thread_host_simulation_entry(ULONG arg)
|
||||
{
|
||||
UINT status;
|
||||
UX_DEVICE *device;
|
||||
UX_CONFIGURATION *configuration;
|
||||
UX_INTERFACE *interface_ptr;
|
||||
UX_ENDPOINT *endpoint;
|
||||
|
||||
stepinfo(">>>> Dummy Class Connection Wait\n");
|
||||
status = ux_demo_dummy_instance_connect_wait(100);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
stepinfo(">>>> Dummy Class Configuration Deactivate\n");
|
||||
interface_ptr = dummy -> ux_host_class_dummy_interface;
|
||||
configuration = interface_ptr -> ux_interface_configuration;
|
||||
device = configuration -> ux_configuration_device;
|
||||
status = ux_host_stack_device_configuration_deactivate(device);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
status = ux_demo_dummy_instance_remove_wait(10);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
stepinfo(">>>> Dummy Class Configuration Activate\n");
|
||||
status = ux_host_stack_device_configuration_activate(configuration);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
status = ux_demo_dummy_instance_connect_wait(100);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#if UX_HOST_STACK_CONFIGURATION_INSTANCE_CREATE_CONTROL == UX_HOST_STACK_CONFIGURATION_INSTANCE_CREATE_ALL
|
||||
stepinfo(">>>> Check physical endpoints (create all)\n");
|
||||
status = ux_host_stack_configuration_interface_get(configuration, 0, 0, &interface_ptr);
|
||||
UX_TEST_CHECK_SUCCESS(status);
|
||||
status = ux_host_stack_interface_endpoint_get(interface_ptr, 0, &endpoint);
|
||||
UX_TEST_CHECK_SUCCESS(status);
|
||||
UX_TEST_ASSERT(endpoint -> ux_endpoint_ed != UX_NULL);
|
||||
|
||||
status = ux_host_stack_configuration_interface_get(configuration, 1, 0, &interface_ptr);
|
||||
UX_TEST_CHECK_SUCCESS(status);
|
||||
status = ux_host_stack_interface_endpoint_get(interface_ptr, 0, &endpoint);
|
||||
UX_TEST_CHECK_SUCCESS(status);
|
||||
UX_TEST_ASSERT(endpoint -> ux_endpoint_ed != UX_NULL);
|
||||
status = ux_host_stack_interface_endpoint_get(interface_ptr, 1, &endpoint);
|
||||
UX_TEST_CHECK_SUCCESS(status);
|
||||
UX_TEST_ASSERT(endpoint -> ux_endpoint_ed != UX_NULL);
|
||||
|
||||
status = ux_host_stack_configuration_interface_get(configuration, 2, 0, &interface_ptr);
|
||||
UX_TEST_CHECK_SUCCESS(status);
|
||||
UX_TEST_CHECK_SUCCESS(status);
|
||||
status = ux_host_stack_interface_endpoint_get(interface_ptr, 0, &endpoint);
|
||||
UX_TEST_CHECK_SUCCESS(status);
|
||||
UX_TEST_ASSERT(endpoint -> ux_endpoint_ed != UX_NULL);
|
||||
|
||||
#elif UX_HOST_STACK_CONFIGURATION_INSTANCE_CREATE_CONTROL == UX_HOST_STACK_CONFIGURATION_INSTANCE_CREATE_OWNED
|
||||
stepinfo(">>>> Check physical endpoints (create owned)\n");
|
||||
status = ux_host_stack_configuration_interface_get(configuration, 0, 0, &interface_ptr);
|
||||
UX_TEST_CHECK_SUCCESS(status);
|
||||
status = ux_host_stack_interface_endpoint_get(interface_ptr, 0, &endpoint);
|
||||
UX_TEST_ASSERT(endpoint -> ux_endpoint_ed == UX_NULL);
|
||||
|
||||
status = ux_host_stack_configuration_interface_get(configuration, 1, 0, &interface_ptr);
|
||||
UX_TEST_CHECK_SUCCESS(status);
|
||||
status = ux_host_stack_interface_endpoint_get(interface_ptr, 0, &endpoint);
|
||||
UX_TEST_ASSERT(endpoint -> ux_endpoint_ed != UX_NULL);
|
||||
status = ux_host_stack_interface_endpoint_get(interface_ptr, 1, &endpoint);
|
||||
UX_TEST_ASSERT(endpoint -> ux_endpoint_ed != UX_NULL);
|
||||
|
||||
status = ux_host_stack_configuration_interface_get(configuration, 2, 0, &interface_ptr);
|
||||
UX_TEST_CHECK_SUCCESS(status);
|
||||
status = ux_host_stack_interface_endpoint_get(interface_ptr, 0, &endpoint);
|
||||
UX_TEST_ASSERT(endpoint -> ux_endpoint_ed == UX_NULL);
|
||||
|
||||
#endif
|
||||
|
||||
expected_error = 0;
|
||||
|
||||
/* Sleep for a tick to make sure everything is complete. */
|
||||
tx_thread_sleep(1);
|
||||
|
||||
/* Check for errors from other threads. */
|
||||
if (error_counter)
|
||||
{
|
||||
|
||||
/* DPUMP error. */
|
||||
printf("ERROR #%d: total %ld errors\n", __LINE__, error_counter);
|
||||
test_control_return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void tx_demo_thread_slave_simulation_entry(ULONG arg)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
ULONG actual_length;
|
||||
|
||||
|
||||
while(1)
|
||||
{
|
||||
#if defined(UX_DEVICE_STANDALONE)
|
||||
|
||||
/* Run device tasks. */
|
||||
ux_system_tasks_run();
|
||||
#endif
|
||||
/* Increment thread counter. */
|
||||
thread_1_counter++;
|
||||
|
||||
/* Relinquish to other thread. */
|
||||
tx_thread_relinquish();
|
||||
}
|
||||
}
|
||||
|
||||
static VOID tx_demo_instance_activate(VOID *inst)
|
||||
{
|
||||
dummy_slave = (UX_DEVICE_CLASS_DUMMY *)inst;
|
||||
}
|
||||
|
||||
static VOID tx_demo_instance_deactivate(VOID *inst)
|
||||
{
|
||||
dummy_slave = UX_NULL;
|
||||
}
|
||||
|
||||
static VOID tx_demo_instance_change(UX_DEVICE_CLASS_DUMMY *dummy)
|
||||
{
|
||||
UX_PARAMETER_NOT_USED(dummy);
|
||||
}
|
||||
|
||||
#if defined(UX_HOST_STANDALONE)
|
||||
static UINT tx_demo_host_change_function(ULONG e, UX_HOST_CLASS *c, VOID *p)
|
||||
{
|
||||
if (e == UX_STANDALONE_WAIT_BACKGROUND_TASK)
|
||||
{
|
||||
tx_thread_relinquish();
|
||||
}
|
||||
}
|
||||
#endif
|
852
test/regression/usbx_class_printer_basic_tests.c
Normal file
852
test/regression/usbx_class_printer_basic_tests.c
Normal file
@ -0,0 +1,852 @@
|
||||
/* This test is designed to test the simple dpump host/device class operation. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
#include "ux_api.h"
|
||||
#include "ux_system.h"
|
||||
#include "ux_utility.h"
|
||||
|
||||
#include "fx_api.h"
|
||||
|
||||
#include "ux_device_class_printer.h"
|
||||
#include "ux_device_stack.h"
|
||||
#include "ux_host_class_printer.h"
|
||||
|
||||
#include "ux_test_dcd_sim_slave.h"
|
||||
#include "ux_test_hcd_sim_host.h"
|
||||
#include "ux_test_utility_sim.h"
|
||||
|
||||
/* Define constants. */
|
||||
#define UX_DEMO_DEBUG_SIZE (4096*8)
|
||||
#define UX_DEMO_STACK_SIZE 1024
|
||||
#define UX_DEMO_BUFFER_SIZE (UX_SLAVE_REQUEST_DATA_MAX_LENGTH + 1)
|
||||
#define UX_DEMO_XMIT_BUFFER_SIZE 512
|
||||
#define UX_DEMO_RECEPTION_BUFFER_SIZE 512
|
||||
#define UX_DEMO_FILE_BUFFER_SIZE 512
|
||||
#define UX_DEMO_RECEPTION_BLOCK_SIZE 64
|
||||
#define UX_DEMO_MEMORY_SIZE (64*1024)
|
||||
#define UX_DEMO_FILE_SIZE (128 * 1024)
|
||||
#define UX_RAM_DISK_MEMORY (256 * 1024)
|
||||
|
||||
/* Define local/extern function prototypes. */
|
||||
static VOID test_thread_entry(ULONG);
|
||||
static TX_THREAD tx_test_thread_host_simulation;
|
||||
static TX_THREAD tx_test_thread_slave_simulation;
|
||||
static VOID tx_test_thread_host_simulation_entry(ULONG);
|
||||
static VOID tx_test_thread_slave_simulation_entry(ULONG);
|
||||
|
||||
static TX_THREAD tx_test_thread_printer_read;
|
||||
static TX_THREAD tx_test_thread_printer_write;
|
||||
static TX_SEMAPHORE tx_test_semaphore_printer_trigger;
|
||||
static VOID tx_test_printer_read_entry(ULONG);
|
||||
static VOID tx_test_printer_write_entry(ULONG);
|
||||
|
||||
static VOID ux_test_hcd_entry_should_not_be_called(UX_TEST_ACTION *action, VOID *params);
|
||||
static VOID ux_test_hcd_entry_disconnect(UX_TEST_ACTION *action, VOID *params);
|
||||
static VOID ux_test_hcd_entry_set_cfg(UX_TEST_ACTION *action, VOID *params);
|
||||
|
||||
/* Define global data structures. */
|
||||
static UCHAR usbx_memory[UX_DEMO_MEMORY_SIZE + (UX_DEMO_STACK_SIZE * 2)];
|
||||
|
||||
static UX_DEVICE *device = UX_NULL;
|
||||
static UX_HOST_CLASS_PRINTER *host_printer = UX_NULL;
|
||||
static UCHAR host_buffer[UX_DEMO_BUFFER_SIZE * 8];
|
||||
|
||||
static ULONG enum_counter;
|
||||
|
||||
static ULONG error_counter;
|
||||
static ULONG error_callback_counter;
|
||||
|
||||
static ULONG set_cfg_counter;
|
||||
|
||||
static ULONG rsc_mem_alloc_cnt_on_set_cfg;
|
||||
static ULONG rsc_mem_free_on_set_cfg;
|
||||
static ULONG rsc_sem_on_set_cfg;
|
||||
static ULONG rsc_sem_get_on_set_cfg;
|
||||
static ULONG rsc_mutex_on_set_cfg;
|
||||
|
||||
static ULONG rsc_enum_sem_usage;
|
||||
static ULONG rsc_enum_sem_get_count;
|
||||
static ULONG rsc_enum_mutex_usage;
|
||||
static ULONG rsc_enum_mem_usage;
|
||||
static ULONG rsc_enum_mem_alloc_count;
|
||||
|
||||
static ULONG rsc_test_sem_usage;
|
||||
static ULONG rsc_test_sem_get_count;
|
||||
static ULONG rsc_test_mutex_usage;
|
||||
static ULONG rsc_test_mem_alloc_count;
|
||||
|
||||
static UX_DEVICE_CLASS_PRINTER *device_printer = UX_NULL;
|
||||
static UX_DEVICE_CLASS_PRINTER_PARAMETER device_printer_parameter;
|
||||
static UCHAR device_buffer[UX_DEMO_BUFFER_SIZE * 8];
|
||||
static ULONG device_buffer_length = 0;
|
||||
static UCHAR device_printer_soft_reset_count = 0;
|
||||
|
||||
/* Device printer device ID. */
|
||||
static UCHAR printer_device_id[] =
|
||||
{
|
||||
" " // Will be replaced by length (big endian)
|
||||
"MFG:Generic;" // manufacturer (case sensitive)
|
||||
"MDL:Generic_/_Text_Only;" // model (case sensitive)
|
||||
"CMD:1284.4;" // PDL command set
|
||||
"CLS:PRINTER;" // class
|
||||
"DES:Generic text only printer;" // description
|
||||
};
|
||||
|
||||
/* Define device framework. */
|
||||
|
||||
#define _W0(w) ( (w) & 0xFF)
|
||||
#define _W1(w) (((w) >> 8) & 0xFF)
|
||||
|
||||
#define _CONFIGURATION_DESCRIPTOR(total_len, n_ifc, cfg_val) \
|
||||
0x09, 0x02, _W0(total_len), _W1(total_len), (n_ifc), (cfg_val), \
|
||||
0x00, 0xc0, 0x32,
|
||||
|
||||
#define _INTERFACE_DESCRIPTOR(ifc_n, alt, n_ep, cls, sub, protocol) \
|
||||
0x09, 0x04, (ifc_n), (alt), (n_ep), (cls), (sub), (protocol), 0x00,
|
||||
|
||||
#define _ENDPOINT_DESCRIPTOR(addr, attr, pktsize, interval) \
|
||||
0x07, 0x05, (addr), (attr), _W0(pktsize), _W1(pktsize), (interval),
|
||||
|
||||
#define _CFG_TOTAL_LEN (9+9+7+7)
|
||||
|
||||
#define STRING_FRAMEWORK_LENGTH 47
|
||||
#define LANGUAGE_ID_FRAMEWORK_LENGTH 2
|
||||
|
||||
static unsigned char device_framework_full_speed[] = {
|
||||
|
||||
/* Device descriptor 18 bytes
|
||||
0xEF bDeviceClass: Composite class code
|
||||
0x02 bDeviceSubclass: class sub code
|
||||
0x00 bDeviceProtocol: Device protocol
|
||||
idVendor & idProduct - http://www.linux-usb.org/usb.ids
|
||||
*/
|
||||
0x12, 0x01, 0x10, 0x01,
|
||||
0x00, 0x00, 0x00,
|
||||
0x08,
|
||||
0x84, 0x84, 0x00, 0x00,
|
||||
0x00, 0x01,
|
||||
0x01, 0x02, 0x03,
|
||||
0x01,
|
||||
|
||||
_CONFIGURATION_DESCRIPTOR(_CFG_TOTAL_LEN, 1, 1)
|
||||
_INTERFACE_DESCRIPTOR(0, 0, 2, 0x07, 0x01, 0x02)
|
||||
_ENDPOINT_DESCRIPTOR(0x01, 0x02, 64, 0x00)
|
||||
_ENDPOINT_DESCRIPTOR(0x82, 0x02, 64, 0x00)
|
||||
};
|
||||
|
||||
#define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED sizeof(device_framework_full_speed)
|
||||
#define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED sizeof(device_framework_full_speed)
|
||||
#define device_framework_high_speed device_framework_full_speed
|
||||
|
||||
static unsigned char string_framework[] = {
|
||||
|
||||
/* Manufacturer string descriptor : Index 1 - "AzureRTOS" */
|
||||
0x09, 0x04, 0x01, 9,
|
||||
'A','z','u','r','e','R','T','O','S',
|
||||
|
||||
/* Product string descriptor : Index 2 - "Printer device" */
|
||||
0x09, 0x04, 0x02, 14,
|
||||
'P','r','i','n','t','e','r',' ','d','e','v','i','c','e',
|
||||
|
||||
/* Serial Number string descriptor : Index 3 - "0001" */
|
||||
0x09, 0x04, 0x03, 0x04,
|
||||
0x30, 0x30, 0x30, 0x31
|
||||
};
|
||||
|
||||
|
||||
/* Multiple languages are supported on the device, to add
|
||||
a language besides english, the unicode language code must
|
||||
be appended to the language_id_framework array and the length
|
||||
adjusted accordingly. */
|
||||
static unsigned char language_id_framework[] = {
|
||||
|
||||
/* English. */
|
||||
0x09, 0x04
|
||||
};
|
||||
|
||||
static UX_TEST_SETUP _SetConfigure = UX_TEST_SETUP_SetConfigure;
|
||||
|
||||
/* Test interactions */
|
||||
|
||||
static UX_TEST_HCD_SIM_ACTION log_on_SetCfg[] = {
|
||||
/* function, request to match,
|
||||
port action, port status,
|
||||
request action, request EP, request data, request actual length, request status,
|
||||
status, additional callback,
|
||||
no_return */
|
||||
{ UX_HCD_TRANSFER_REQUEST, &_SetConfigure,
|
||||
UX_FALSE, UX_TEST_PORT_STATUS_DISC,
|
||||
UX_TEST_SETUP_MATCH_REQ, 0, UX_NULL, 0, 0,
|
||||
UX_SUCCESS, ux_test_hcd_entry_set_cfg,
|
||||
UX_TRUE}, /* Invoke callback & continue */
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
/* Define the ISR dispatch. */
|
||||
|
||||
extern VOID (*test_isr_dispatch)(void);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
/* Define the ISR dispatch routine. */
|
||||
|
||||
static void test_isr(void)
|
||||
{
|
||||
|
||||
/* For further expansion of interrupt-level testing. */
|
||||
}
|
||||
|
||||
static UINT test_slave_change_function(ULONG change)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static UINT test_host_change_function(ULONG event, UX_HOST_CLASS *cls, VOID *inst)
|
||||
{
|
||||
|
||||
UX_HOST_CLASS_PRINTER *printer_inst = (UX_HOST_CLASS_PRINTER *) inst;
|
||||
|
||||
switch(event)
|
||||
{
|
||||
|
||||
case UX_DEVICE_INSERTION:
|
||||
host_printer = printer_inst;
|
||||
break;
|
||||
|
||||
case UX_DEVICE_REMOVAL:
|
||||
if (host_printer == printer_inst)
|
||||
host_printer = UX_NULL;
|
||||
break;
|
||||
|
||||
case UX_DEVICE_CONNECTION:
|
||||
device = (UX_DEVICE *)inst;
|
||||
break;
|
||||
|
||||
case UX_DEVICE_DISCONNECTION:
|
||||
if ((VOID *)device == inst)
|
||||
device = UX_NULL;
|
||||
break;
|
||||
|
||||
#if defined(UX_HOST_STANDALONE)
|
||||
case UX_STANDALONE_WAIT_BACKGROUND_TASK:
|
||||
tx_thread_relinquish();
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static VOID test_printer_instance_activate(VOID *dummy_instance)
|
||||
{
|
||||
if (device_printer == UX_NULL)
|
||||
device_printer = (UX_DEVICE_CLASS_PRINTER *)dummy_instance;
|
||||
}
|
||||
static VOID test_printer_instance_deactivate(VOID *dummy_instance)
|
||||
{
|
||||
if ((VOID*)device_printer == dummy_instance)
|
||||
device_printer = UX_NULL;
|
||||
}
|
||||
static VOID test_printer_soft_reset(VOID *dummy_instance)
|
||||
{
|
||||
device_printer_soft_reset_count ++;
|
||||
}
|
||||
|
||||
static VOID test_ux_error_callback(UINT system_level, UINT system_context, UINT error_code)
|
||||
{
|
||||
error_callback_counter ++;
|
||||
}
|
||||
|
||||
static VOID ux_test_hcd_entry_set_cfg(UX_TEST_ACTION *action, VOID *params)
|
||||
{
|
||||
|
||||
set_cfg_counter ++;
|
||||
|
||||
rsc_mem_free_on_set_cfg = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
|
||||
|
||||
rsc_mem_alloc_cnt_on_set_cfg = ux_test_utility_sim_mem_alloc_count();
|
||||
|
||||
rsc_sem_on_set_cfg = ux_test_utility_sim_sem_create_count();
|
||||
rsc_enum_sem_get_count = ux_test_utility_sim_sem_get_count();
|
||||
rsc_mutex_on_set_cfg = ux_test_utility_sim_mutex_create_count();
|
||||
}
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_host_class_printer_basic_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR * stack_pointer;
|
||||
CHAR * memory_pointer;
|
||||
|
||||
|
||||
printf("Running Printer Basic Functionality Test............................ ");
|
||||
|
||||
/* Reset testing counts. */
|
||||
ux_test_utility_sim_mem_alloc_log_enable(UX_TRUE);
|
||||
ux_test_utility_sim_mem_alloc_count_reset();
|
||||
ux_test_utility_sim_mutex_create_count_reset();
|
||||
ux_test_utility_sim_sem_create_count_reset();
|
||||
ux_test_utility_sim_sem_get_count_reset();
|
||||
/* Reset error generations */
|
||||
ux_test_utility_sim_sem_error_generation_stop();
|
||||
ux_test_utility_sim_mutex_error_generation_stop();
|
||||
ux_test_utility_sim_sem_get_error_generation_stop();
|
||||
|
||||
/* Initialize the free memory pointer */
|
||||
stack_pointer = (CHAR *) usbx_memory;
|
||||
memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 4);
|
||||
|
||||
/* Initialize USBX Memory */
|
||||
status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf(" ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the error callback. */
|
||||
_ux_utility_error_callback_register(test_ux_error_callback);
|
||||
|
||||
/* The code below is required for installing the host portion of USBX */
|
||||
status = ux_host_stack_initialize(test_host_change_function);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf(" ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register CDC-ACM class. */
|
||||
status = ux_host_stack_class_register(_ux_system_host_class_printer_name, _ux_host_class_printer_entry);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf(" ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* The code below is required for installing the device portion of USBX. No call back for
|
||||
device status change in this example. */
|
||||
status = ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
|
||||
device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
|
||||
string_framework, STRING_FRAMEWORK_LENGTH,
|
||||
language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,
|
||||
test_slave_change_function);
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf(" ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Set the parameters for callback when insertion/extraction of a printer device. */
|
||||
_ux_utility_memory_set(&device_printer_parameter, 0, sizeof(device_printer_parameter));
|
||||
_ux_utility_short_put_big_endian(printer_device_id, sizeof(printer_device_id));
|
||||
device_printer_parameter.ux_device_class_printer_device_id = printer_device_id;
|
||||
device_printer_parameter.ux_device_class_printer_instance_activate = test_printer_instance_activate;
|
||||
device_printer_parameter.ux_device_class_printer_instance_deactivate = test_printer_instance_deactivate;
|
||||
device_printer_parameter.ux_device_class_printer_soft_reset = test_printer_soft_reset;
|
||||
/* Initialize the device cdc class. This class owns both interfaces starting with 0. */
|
||||
status = ux_device_stack_class_register(_ux_system_device_class_printer_name,
|
||||
ux_device_class_printer_entry,
|
||||
1, 0, &device_printer_parameter);
|
||||
/* Initialize the simulated device controller. */
|
||||
status = _ux_test_dcd_sim_slave_initialize();
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf(" ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register all the USB host controllers available in this system */
|
||||
status = ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize,0,0);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf(" ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the main host simulation thread. */
|
||||
status = tx_thread_create(&tx_test_thread_host_simulation, "tx test host simulation", tx_test_thread_host_simulation_entry, 0,
|
||||
stack_pointer, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf(" ERROR #9\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the main slave simulation thread. */
|
||||
stack_pointer += UX_DEMO_STACK_SIZE;
|
||||
status = tx_thread_create(&tx_test_thread_slave_simulation, "tx test slave simulation", tx_test_thread_slave_simulation_entry, 0,
|
||||
stack_pointer, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf(" ERROR #10\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the device printer read thread. */
|
||||
stack_pointer += UX_DEMO_STACK_SIZE;
|
||||
status = tx_thread_create(&tx_test_thread_printer_read, "tx test printer read",
|
||||
tx_test_printer_read_entry, UX_TRUE,
|
||||
stack_pointer, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf(" ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the device printer write thread. */
|
||||
stack_pointer += UX_DEMO_STACK_SIZE;
|
||||
status = tx_thread_create(&tx_test_thread_printer_write, "tx test printer write",
|
||||
tx_test_printer_write_entry, UX_FALSE,
|
||||
stack_pointer, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf(" ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the device printer write trigger. */
|
||||
status = tx_semaphore_create(&tx_test_semaphore_printer_trigger,
|
||||
"tx test printer trigger",
|
||||
0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf(" ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
static UINT _test_check_host_connection_error(VOID)
|
||||
{
|
||||
if (device_printer && host_printer)
|
||||
return(UX_SUCCESS);
|
||||
if (error_callback_counter >= 3)
|
||||
return(UX_SUCCESS);
|
||||
return(UX_ERROR);
|
||||
}
|
||||
|
||||
static UINT _test_check_host_connection_success(VOID)
|
||||
{
|
||||
if (device_printer && host_printer)
|
||||
return(UX_SUCCESS);
|
||||
return(UX_ERROR);
|
||||
}
|
||||
|
||||
static UINT _test_check_host_disconnection_success(VOID)
|
||||
{
|
||||
if (device_printer == UX_NULL && host_printer == UX_NULL)
|
||||
return(UX_SUCCESS);
|
||||
return(UX_ERROR);
|
||||
}
|
||||
|
||||
static VOID _printer_enumeration_test(VOID)
|
||||
{
|
||||
UINT status;
|
||||
ULONG mem_free;
|
||||
ULONG test_n;
|
||||
|
||||
stepinfo(">>>>>>>>>>>> Enumeration information collection\n");
|
||||
{
|
||||
|
||||
/* Test disconnect. */
|
||||
ux_test_dcd_sim_slave_disconnect();
|
||||
ux_test_hcd_sim_host_disconnect();
|
||||
|
||||
/* Check connection. */
|
||||
status = ux_test_sleep_break_on_success(100, _test_check_host_disconnection_success);
|
||||
UX_TEST_ASSERT(status == UX_SUCCESS);
|
||||
|
||||
/* Reset testing counts. */
|
||||
ux_test_utility_sim_mem_alloc_count_reset();
|
||||
ux_test_utility_sim_mutex_create_count_reset();
|
||||
ux_test_utility_sim_sem_create_count_reset();
|
||||
ux_test_utility_sim_sem_get_count_reset();
|
||||
ux_test_hcd_sim_host_set_actions(log_on_SetCfg);
|
||||
|
||||
/* Save free memory usage. */
|
||||
mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
|
||||
ux_test_dcd_sim_slave_connect(UX_HIGH_SPEED_DEVICE);
|
||||
ux_test_hcd_sim_host_connect(UX_HIGH_SPEED_DEVICE);
|
||||
|
||||
/* Check connection. */
|
||||
status = ux_test_sleep_break_on_success(100, _test_check_host_connection_success);
|
||||
UX_TEST_ASSERT(status == UX_SUCCESS);
|
||||
|
||||
/* Log create counts for further tests. */
|
||||
rsc_enum_mutex_usage = rsc_mutex_on_set_cfg;
|
||||
rsc_enum_sem_usage = rsc_sem_on_set_cfg;
|
||||
rsc_enum_mem_alloc_count = rsc_mem_alloc_cnt_on_set_cfg;
|
||||
/* Log create counts when instances active for further tests. */
|
||||
rsc_test_mutex_usage = ux_test_utility_sim_mutex_create_count() - rsc_enum_mutex_usage;
|
||||
rsc_test_sem_usage = ux_test_utility_sim_sem_create_count() - rsc_enum_sem_usage;
|
||||
rsc_test_mem_alloc_count = ux_test_utility_sim_mem_alloc_count() - rsc_enum_mem_alloc_count;
|
||||
|
||||
/* Lock log base for tests. */
|
||||
ux_test_utility_sim_mem_alloc_log_lock();
|
||||
|
||||
stepinfo("enum mem: %ld\n", rsc_enum_mem_alloc_count);
|
||||
stepinfo("test mem : %ld\n", rsc_test_mem_alloc_count);
|
||||
stepinfo("mem free: %ld, %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available, _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_CACHE_SAFE] -> ux_byte_pool_available);
|
||||
}
|
||||
|
||||
stepinfo(">>>>>>>>>>>> Enumeration test\n");
|
||||
mem_free = (~0);
|
||||
for (test_n = 0; test_n < 3; test_n++)
|
||||
{
|
||||
stepinfo("%4ld / 2\n", test_n);
|
||||
|
||||
/* Disconnect. */
|
||||
ux_test_dcd_sim_slave_disconnect();
|
||||
ux_test_hcd_sim_host_disconnect();
|
||||
|
||||
/* Check */
|
||||
status = ux_test_sleep_break_on_success(100, _test_check_host_disconnection_success);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d.%ld: Disconnect fail\n", __LINE__, test_n);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Update memory free level (disconnect) */
|
||||
if (mem_free == (~0))
|
||||
mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
|
||||
else if (mem_free != _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available)
|
||||
{
|
||||
|
||||
printf("ERROR #%d.%ld: Memory level different after re-enumerations %ld <> %ld\n", __LINE__, test_n, mem_free, _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Connect. */
|
||||
error_callback_counter = 0;
|
||||
ux_test_dcd_sim_slave_connect(UX_HIGH_SPEED_DEVICE);
|
||||
ux_test_hcd_sim_host_connect(UX_HIGH_SPEED_DEVICE);
|
||||
|
||||
/* Wait and break on error. */
|
||||
error_callback_counter = 0;
|
||||
status = ux_test_sleep_break_on_success(100, _test_check_host_connection_error);
|
||||
|
||||
/* Check */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d.%ld: Enumeration fail\n", __LINE__, test_n);
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
stepinfo("\n");
|
||||
|
||||
if (rsc_test_mem_alloc_count) stepinfo(">>>>>>>>>>>> Memory errors enumeration test\n");
|
||||
mem_free = (~0);
|
||||
for (test_n = 0; test_n < rsc_test_mem_alloc_count; test_n ++)
|
||||
{
|
||||
|
||||
stepinfo("%4ld / %4ld\n", test_n, rsc_test_mem_alloc_count - 1);
|
||||
|
||||
/* Disconnect. */
|
||||
ux_test_dcd_sim_slave_disconnect();
|
||||
ux_test_hcd_sim_host_disconnect();
|
||||
|
||||
/* Check */
|
||||
status = ux_test_sleep_break_on_success(100, _test_check_host_disconnection_success);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
stepinfo("ERROR #%d.%ld: Disconnect fail\n", __LINE__, test_n);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Update memory free level (disconnect) */
|
||||
if (mem_free == (~0))
|
||||
mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
|
||||
else if (mem_free != _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available)
|
||||
{
|
||||
|
||||
stepinfo("ERROR #%d.%ld: Memory level different after re-enumerations %ld <> %ld\n", __LINE__, test_n, mem_free, _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Set memory error generation */
|
||||
ux_test_utility_sim_mem_alloc_error_generation_start(test_n + rsc_enum_mem_alloc_count);
|
||||
|
||||
/* Connect. */
|
||||
error_callback_counter = 0;
|
||||
ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
|
||||
ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
|
||||
|
||||
/* Wait and break on errors. */
|
||||
status = ux_test_sleep_break_on_success(100, _test_check_host_connection_error);
|
||||
|
||||
/* Check error */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Check error trap. */
|
||||
if (error_callback_counter == 0)
|
||||
{
|
||||
stepinfo("ERROR #%d.%ld: device detected when there is memory error\n", __LINE__, test_n);
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
stepinfo("mem free: %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
|
||||
}
|
||||
ux_test_utility_sim_mem_alloc_error_generation_stop();
|
||||
if (rsc_test_mem_alloc_count) stepinfo("\n");
|
||||
|
||||
/* If device disconnected, re-connect. */
|
||||
if (_test_check_host_connection_success() != UX_SUCCESS)
|
||||
{
|
||||
ux_test_dcd_sim_slave_disconnect();
|
||||
ux_test_hcd_sim_host_disconnect();
|
||||
ux_test_dcd_sim_slave_connect(UX_HIGH_SPEED_DEVICE);
|
||||
ux_test_hcd_sim_host_connect(UX_HIGH_SPEED_DEVICE);
|
||||
|
||||
/* Check */
|
||||
status = ux_test_sleep_break_on_success(100, _test_check_host_connection_success);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d: Enumeration fail\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
static VOID _printer_requests_test(VOID)
|
||||
{
|
||||
UINT status;
|
||||
ULONG printer_port_status;
|
||||
|
||||
stepinfo(">>>>>>>>>>>>>>>> Test GET_DEVICE_ID\n");
|
||||
status = ux_host_class_printer_device_id_get(host_printer, host_buffer, sizeof(host_buffer));
|
||||
UX_TEST_ASSERT(status == UX_SUCCESS);
|
||||
|
||||
stepinfo(">>>>>>>>>>>>>>>> Test GET_PORT_STATUS\n");
|
||||
ux_device_class_printer_ioctl(device_printer, UX_DEVICE_CLASS_PRINTER_IOCTL_PORT_STATUS_SET, (VOID *)0x73);
|
||||
status = ux_host_class_printer_status_get(host_printer, &printer_port_status);
|
||||
UX_TEST_ASSERT(status == UX_SUCCESS);
|
||||
UX_TEST_ASSERT(printer_port_status == 0x73);
|
||||
|
||||
stepinfo(">>>>>>>>>>>>>>>> Test SOFT_RESET\n");
|
||||
device_printer_soft_reset_count = 0;
|
||||
status = ux_host_class_printer_soft_reset(host_printer);
|
||||
UX_TEST_ASSERT(status == UX_SUCCESS);
|
||||
UX_TEST_ASSERT(device_printer_soft_reset_count == 1);
|
||||
}
|
||||
|
||||
void tx_test_printer_read_entry(ULONG arg)
|
||||
{
|
||||
UINT status;
|
||||
ULONG actual_length;
|
||||
while(1)
|
||||
{
|
||||
if (device_printer == UX_NULL)
|
||||
{
|
||||
tx_thread_sleep(10);
|
||||
continue;
|
||||
}
|
||||
status = ux_device_class_printer_read(device_printer, device_buffer, sizeof(device_buffer), &actual_length);
|
||||
/* Endpoint not ready. */
|
||||
if (status == UX_TRANSFER_BUS_RESET ||
|
||||
status == UX_TRANSFER_NO_ANSWER)
|
||||
{
|
||||
tx_thread_sleep(10);
|
||||
continue;
|
||||
}
|
||||
device_buffer_length = actual_length;
|
||||
UX_TEST_ASSERT_MESSAGE(status == UX_SUCCESS, "#%d status 0x%x\n", __LINE__, status);
|
||||
}
|
||||
}
|
||||
|
||||
void tx_test_printer_write_entry(ULONG arg)
|
||||
{
|
||||
UINT status;
|
||||
ULONG send_total;
|
||||
while(1)
|
||||
{
|
||||
/* Wait a trigger. */
|
||||
status = tx_semaphore_get(&tx_test_semaphore_printer_trigger, TX_WAIT_FOREVER);
|
||||
if (status != TX_SUCCESS || device_printer == UX_NULL)
|
||||
{
|
||||
tx_thread_sleep(10);
|
||||
continue;
|
||||
}
|
||||
/* Send device_buffer_length. */
|
||||
status = ux_device_class_printer_write(device_printer, device_buffer, device_buffer_length, &send_total);
|
||||
UX_TEST_ASSERT(status == UX_SUCCESS);
|
||||
UX_TEST_ASSERT(device_buffer_length == send_total);
|
||||
}
|
||||
}
|
||||
|
||||
static VOID _printer_read_write_test(VOID)
|
||||
{
|
||||
struct _TEST_DEF {
|
||||
ULONG fill;
|
||||
ULONG length;
|
||||
ULONG zlp;
|
||||
} tests[] = {
|
||||
{0x5A, 1, 0},
|
||||
{0x7E, 512, 1},
|
||||
{0xC2, 513, 0},
|
||||
{0x4C, UX_SLAVE_REQUEST_DATA_MAX_LENGTH, 1},
|
||||
{0xA5, UX_SLAVE_REQUEST_DATA_MAX_LENGTH + 1, 0},
|
||||
{0x3C, sizeof(device_buffer), 0},
|
||||
{0xC4, sizeof(device_buffer) - 1, 0},
|
||||
};
|
||||
#define _TEST_N (sizeof(tests)/sizeof(struct _TEST_DEF))
|
||||
INT i;
|
||||
ULONG actual_length;
|
||||
UINT status;
|
||||
for(i = 0; i < _TEST_N; i ++)
|
||||
{
|
||||
stepinfo(">>>>>>>>>>>>>>>> Test Write %ld\n", tests[i].length);
|
||||
device_buffer_length = 0;
|
||||
ux_utility_memory_set(device_buffer, ~tests[i].fill, tests[i].length);
|
||||
ux_utility_memory_set(host_buffer, tests[i].fill, tests[i].length);
|
||||
status = ux_host_class_printer_write(host_printer, host_buffer, tests[i].length, &actual_length);
|
||||
UX_TEST_ASSERT(status == UX_SUCCESS);
|
||||
UX_TEST_ASSERT(tests[i].length == actual_length);
|
||||
if (tests[i].zlp)
|
||||
{
|
||||
status = ux_host_class_printer_write(host_printer, host_buffer, 0, &actual_length);
|
||||
UX_TEST_ASSERT(status == UX_SUCCESS);
|
||||
UX_TEST_ASSERT(0 == actual_length);
|
||||
}
|
||||
UX_TEST_ASSERT(device_buffer_length == tests[i].length);
|
||||
status = ux_utility_memory_compare(device_buffer, host_buffer, tests[i].length);
|
||||
UX_TEST_ASSERT(status == UX_SUCCESS);
|
||||
|
||||
stepinfo(">>>>>>>>>>>>>>>> Test Read %ld\n", tests[i].length);
|
||||
status = tx_semaphore_put(&tx_test_semaphore_printer_trigger);
|
||||
UX_TEST_ASSERT(status == TX_SUCCESS);
|
||||
ux_utility_memory_set(host_buffer, ~tests[i].fill, tests[i].length);
|
||||
status = ux_host_class_printer_read(host_printer, host_buffer, tests[i].length, &actual_length);
|
||||
UX_TEST_ASSERT(status == UX_SUCCESS);
|
||||
UX_TEST_ASSERT(tests[i].length == actual_length);
|
||||
UX_TEST_ASSERT(host_buffer[0] == tests[i].fill);
|
||||
UX_TEST_ASSERT(host_buffer[tests[i].length - 1] == tests[i].fill);
|
||||
|
||||
#if defined(UX_DEVICE_CLASS_PRINTER_WRITE_AUTO_ZLP)
|
||||
stepinfo(">>>>>>>>>>>>>>>> Test Read (Device Write) with auto ZLP %ld\n", tests[i].length);
|
||||
status = tx_semaphore_put(&tx_test_semaphore_printer_trigger);
|
||||
UX_TEST_CHECK_SUCCESS(status);
|
||||
ux_utility_memory_set(host_buffer, ~tests[i].fill, tests[i].length);
|
||||
status = ux_host_class_printer_read(host_printer, host_buffer, sizeof(host_buffer), &actual_length);
|
||||
if (actual_length == 0) /* There could be ZLP. */
|
||||
status = ux_host_class_printer_read(host_printer, host_buffer, sizeof(host_buffer), &actual_length);
|
||||
UX_TEST_CHECK_SUCCESS(status);
|
||||
UX_TEST_ASSERT(tests[i].length == actual_length);
|
||||
UX_TEST_ASSERT(host_buffer[0] == tests[i].fill);
|
||||
UX_TEST_ASSERT(host_buffer[tests[i].length - 1] == tests[i].fill);
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void tx_test_thread_host_simulation_entry(ULONG arg)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
ULONG test_n;
|
||||
ULONG mem_free;
|
||||
ULONG loop;
|
||||
ULONG parameter_u32[64/4];
|
||||
USHORT *parameter_u16 = (USHORT*)parameter_u32;
|
||||
UCHAR *parameter_u8 = (UCHAR*)parameter_u32;
|
||||
|
||||
|
||||
stepinfo("\n");
|
||||
stepinfo(">>>>>>>>>>>>>>>> Test connect\n");
|
||||
ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
|
||||
ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
|
||||
status = ux_test_sleep_break_on_success(100, _test_check_host_connection_success);
|
||||
UX_TEST_ASSERT(status == UX_SUCCESS);
|
||||
|
||||
_printer_enumeration_test();
|
||||
_printer_requests_test();
|
||||
_printer_read_write_test();
|
||||
|
||||
/* Test disconnect. */
|
||||
stepinfo(">>>>>>>>>>>>>>>> Test disconnect\n");
|
||||
ux_test_dcd_sim_slave_disconnect();
|
||||
ux_test_hcd_sim_host_disconnect();
|
||||
if (host_printer != UX_NULL)
|
||||
{
|
||||
|
||||
printf("ERROR #13: instance not removed when disconnect");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Finally disconnect the device. */
|
||||
ux_device_stack_disconnect();
|
||||
|
||||
/* And deinitialize the class. */
|
||||
status = ux_device_stack_class_unregister(_ux_system_device_class_printer_name, _ux_device_class_printer_entry);
|
||||
|
||||
/* Deinitialize the device side of usbx. */
|
||||
_ux_device_stack_uninitialize();
|
||||
|
||||
/* And finally the usbx system resources. */
|
||||
_ux_system_uninitialize();
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
|
||||
}
|
||||
|
||||
void tx_test_thread_slave_simulation_entry(ULONG arg)
|
||||
{
|
||||
|
||||
while(1)
|
||||
{
|
||||
#if defined(UX_DEVICE_STANDALONE)
|
||||
ux_system_tasks_run();
|
||||
tx_thread_relinquish();
|
||||
#else
|
||||
/* Sleep so ThreadX on Win32 will delete this thread. */
|
||||
tx_thread_sleep(10);
|
||||
#endif
|
||||
}
|
||||
}
|
@ -0,0 +1,837 @@
|
||||
/* This test is designed to test the simple dpump host/device class operation. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
#include "ux_api.h"
|
||||
#include "ux_system.h"
|
||||
#include "ux_utility.h"
|
||||
|
||||
#include "fx_api.h"
|
||||
|
||||
#include "ux_device_class_printer.h"
|
||||
#include "ux_device_stack.h"
|
||||
#include "ux_host_class_printer.h"
|
||||
|
||||
#include "ux_test_dcd_sim_slave.h"
|
||||
#include "ux_test_hcd_sim_host.h"
|
||||
#include "ux_test_utility_sim.h"
|
||||
|
||||
/* Define constants. */
|
||||
#define UX_DEMO_DEBUG_SIZE (4096*8)
|
||||
#define UX_DEMO_STACK_SIZE 1024
|
||||
#define UX_DEMO_BUFFER_SIZE (UX_SLAVE_REQUEST_DATA_MAX_LENGTH + 1)
|
||||
#define UX_DEMO_XMIT_BUFFER_SIZE 512
|
||||
#define UX_DEMO_RECEPTION_BUFFER_SIZE 512
|
||||
#define UX_DEMO_FILE_BUFFER_SIZE 512
|
||||
#define UX_DEMO_RECEPTION_BLOCK_SIZE 64
|
||||
#define UX_DEMO_MEMORY_SIZE (64*1024)
|
||||
#define UX_DEMO_FILE_SIZE (128 * 1024)
|
||||
#define UX_RAM_DISK_MEMORY (256 * 1024)
|
||||
|
||||
/* Define local/extern function prototypes. */
|
||||
static VOID test_thread_entry(ULONG);
|
||||
static TX_THREAD tx_test_thread_host_simulation;
|
||||
static TX_THREAD tx_test_thread_slave_simulation;
|
||||
static VOID tx_test_thread_host_simulation_entry(ULONG);
|
||||
static VOID tx_test_thread_slave_simulation_entry(ULONG);
|
||||
|
||||
static VOID ux_test_hcd_entry_should_not_be_called(UX_TEST_ACTION *action, VOID *params);
|
||||
static VOID ux_test_hcd_entry_disconnect(UX_TEST_ACTION *action, VOID *params);
|
||||
static VOID ux_test_hcd_entry_set_cfg(UX_TEST_ACTION *action, VOID *params);
|
||||
|
||||
/* Define global data structures. */
|
||||
static UCHAR usbx_memory[UX_DEMO_MEMORY_SIZE + (UX_DEMO_STACK_SIZE * 2)];
|
||||
|
||||
static UX_DEVICE *device = UX_NULL;
|
||||
static UX_HOST_CLASS_PRINTER *host_printer = UX_NULL;
|
||||
static UCHAR host_buffer[UX_DEMO_BUFFER_SIZE * 8];
|
||||
|
||||
static ULONG enum_counter;
|
||||
|
||||
static ULONG error_counter;
|
||||
static ULONG error_callback_counter;
|
||||
|
||||
static ULONG set_cfg_counter;
|
||||
|
||||
static ULONG rsc_mem_alloc_cnt_on_set_cfg;
|
||||
static ULONG rsc_mem_free_on_set_cfg;
|
||||
static ULONG rsc_sem_on_set_cfg;
|
||||
static ULONG rsc_sem_get_on_set_cfg;
|
||||
static ULONG rsc_mutex_on_set_cfg;
|
||||
|
||||
static ULONG rsc_enum_sem_usage;
|
||||
static ULONG rsc_enum_sem_get_count;
|
||||
static ULONG rsc_enum_mutex_usage;
|
||||
static ULONG rsc_enum_mem_usage;
|
||||
static ULONG rsc_enum_mem_alloc_count;
|
||||
|
||||
static ULONG rsc_test_sem_usage;
|
||||
static ULONG rsc_test_sem_get_count;
|
||||
static ULONG rsc_test_mutex_usage;
|
||||
static ULONG rsc_test_mem_alloc_count;
|
||||
|
||||
static UX_DEVICE_CLASS_PRINTER *device_printer = UX_NULL;
|
||||
static UX_DEVICE_CLASS_PRINTER_PARAMETER device_printer_parameter;
|
||||
static UCHAR device_buffer[UX_DEMO_BUFFER_SIZE * 8];
|
||||
static ULONG device_buffer_length = 0;
|
||||
static UCHAR device_printer_soft_reset_count = 0;
|
||||
static ULONG device_read_length = UX_SLAVE_REQUEST_DATA_MAX_LENGTH;
|
||||
UCHAR _ux_device_class_printer_name[] = "_ux_device_class_printer";
|
||||
|
||||
/* Device printer device ID. */
|
||||
static UCHAR printer_device_id[] =
|
||||
{
|
||||
" " // Will be replaced by length (big endian)
|
||||
"MFG:Generic;" // manufacturer (case sensitive)
|
||||
"MDL:Generic_/_Text_Only;" // model (case sensitive)
|
||||
"CMD:1284.4;" // PDL command set
|
||||
"CLS:PRINTER;" // class
|
||||
"DES:Generic text only printer;" // description
|
||||
};
|
||||
|
||||
/* Define device framework. */
|
||||
|
||||
#define _W0(w) ( (w) & 0xFF)
|
||||
#define _W1(w) (((w) >> 8) & 0xFF)
|
||||
|
||||
#define _CONFIGURATION_DESCRIPTOR(total_len, n_ifc, cfg_val) \
|
||||
0x09, 0x02, _W0(total_len), _W1(total_len), (n_ifc), (cfg_val), \
|
||||
0x00, 0xc0, 0x32,
|
||||
|
||||
#define _INTERFACE_DESCRIPTOR(ifc_n, alt, n_ep, cls, sub, protocol) \
|
||||
0x09, 0x04, (ifc_n), (alt), (n_ep), (cls), (sub), (protocol), 0x00,
|
||||
|
||||
#define _ENDPOINT_DESCRIPTOR(addr, attr, pktsize, interval) \
|
||||
0x07, 0x05, (addr), (attr), _W0(pktsize), _W1(pktsize), (interval),
|
||||
|
||||
#define _CFG_TOTAL_LEN (9+9+7+7)
|
||||
|
||||
#define STRING_FRAMEWORK_LENGTH 47
|
||||
#define LANGUAGE_ID_FRAMEWORK_LENGTH 2
|
||||
|
||||
static unsigned char device_framework_full_speed[] = {
|
||||
|
||||
/* Device descriptor 18 bytes
|
||||
0xEF bDeviceClass: Composite class code
|
||||
0x02 bDeviceSubclass: class sub code
|
||||
0x00 bDeviceProtocol: Device protocol
|
||||
idVendor & idProduct - http://www.linux-usb.org/usb.ids
|
||||
*/
|
||||
0x12, 0x01, 0x10, 0x01,
|
||||
0x00, 0x00, 0x00,
|
||||
0x08,
|
||||
0x84, 0x84, 0x00, 0x00,
|
||||
0x00, 0x01,
|
||||
0x01, 0x02, 0x03,
|
||||
0x01,
|
||||
|
||||
_CONFIGURATION_DESCRIPTOR(_CFG_TOTAL_LEN, 1, 1)
|
||||
_INTERFACE_DESCRIPTOR(0, 0, 2, 0x07, 0x01, 0x02)
|
||||
_ENDPOINT_DESCRIPTOR(0x01, 0x02, 64, 0x00)
|
||||
_ENDPOINT_DESCRIPTOR(0x82, 0x02, 64, 0x00)
|
||||
};
|
||||
|
||||
#define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED sizeof(device_framework_full_speed)
|
||||
#define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED sizeof(device_framework_full_speed)
|
||||
#define device_framework_high_speed device_framework_full_speed
|
||||
|
||||
static unsigned char string_framework[] = {
|
||||
|
||||
/* Manufacturer string descriptor : Index 1 - "AzureRTOS" */
|
||||
0x09, 0x04, 0x01, 9,
|
||||
'A','z','u','r','e','R','T','O','S',
|
||||
|
||||
/* Product string descriptor : Index 2 - "Printer device" */
|
||||
0x09, 0x04, 0x02, 14,
|
||||
'P','r','i','n','t','e','r',' ','d','e','v','i','c','e',
|
||||
|
||||
/* Serial Number string descriptor : Index 3 - "0001" */
|
||||
0x09, 0x04, 0x03, 0x04,
|
||||
0x30, 0x30, 0x30, 0x31
|
||||
};
|
||||
|
||||
|
||||
/* Multiple languages are supported on the device, to add
|
||||
a language besides english, the unicode language code must
|
||||
be appended to the language_id_framework array and the length
|
||||
adjusted accordingly. */
|
||||
static unsigned char language_id_framework[] = {
|
||||
|
||||
/* English. */
|
||||
0x09, 0x04
|
||||
};
|
||||
|
||||
static UX_TEST_SETUP _SetConfigure = UX_TEST_SETUP_SetConfigure;
|
||||
|
||||
/* Test interactions */
|
||||
|
||||
static UX_TEST_HCD_SIM_ACTION log_on_SetCfg[] = {
|
||||
/* function, request to match,
|
||||
port action, port status,
|
||||
request action, request EP, request data, request actual length, request status,
|
||||
status, additional callback,
|
||||
no_return */
|
||||
{ UX_HCD_TRANSFER_REQUEST, &_SetConfigure,
|
||||
UX_FALSE, UX_TEST_PORT_STATUS_DISC,
|
||||
UX_TEST_SETUP_MATCH_REQ, 0, UX_NULL, 0, 0,
|
||||
UX_SUCCESS, ux_test_hcd_entry_set_cfg,
|
||||
UX_TRUE}, /* Invoke callback & continue */
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
/* Define the ISR dispatch. */
|
||||
|
||||
extern VOID (*test_isr_dispatch)(void);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
/* Define the ISR dispatch routine. */
|
||||
|
||||
static void test_isr(void)
|
||||
{
|
||||
|
||||
/* For further expansion of interrupt-level testing. */
|
||||
}
|
||||
|
||||
static UINT test_slave_change_function(ULONG change)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static UINT test_host_change_function(ULONG event, UX_HOST_CLASS *cls, VOID *inst)
|
||||
{
|
||||
|
||||
UX_HOST_CLASS_PRINTER *printer_inst = (UX_HOST_CLASS_PRINTER *) inst;
|
||||
|
||||
switch(event)
|
||||
{
|
||||
|
||||
case UX_DEVICE_INSERTION:
|
||||
host_printer = printer_inst;
|
||||
break;
|
||||
|
||||
case UX_DEVICE_REMOVAL:
|
||||
if (host_printer == printer_inst)
|
||||
host_printer = UX_NULL;
|
||||
break;
|
||||
|
||||
case UX_DEVICE_CONNECTION:
|
||||
device = (UX_DEVICE *)inst;
|
||||
break;
|
||||
|
||||
case UX_DEVICE_DISCONNECTION:
|
||||
if ((VOID *)device == inst)
|
||||
device = UX_NULL;
|
||||
break;
|
||||
|
||||
#if defined(UX_HOST_STANDALONE)
|
||||
case UX_STANDALONE_WAIT_BACKGROUND_TASK:
|
||||
tx_thread_relinquish();
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static VOID test_printer_instance_activate(VOID *dummy_instance)
|
||||
{
|
||||
if (device_printer == UX_NULL)
|
||||
device_printer = (UX_DEVICE_CLASS_PRINTER *)dummy_instance;
|
||||
}
|
||||
static VOID test_printer_instance_deactivate(VOID *dummy_instance)
|
||||
{
|
||||
if ((VOID*)device_printer == dummy_instance)
|
||||
device_printer = UX_NULL;
|
||||
}
|
||||
static VOID test_printer_soft_reset(VOID *dummy_instance)
|
||||
{
|
||||
device_printer_soft_reset_count ++;
|
||||
}
|
||||
static VOID test_ux_error_callback(UINT system_level, UINT system_context, UINT error_code)
|
||||
{
|
||||
error_callback_counter ++;
|
||||
}
|
||||
|
||||
static VOID ux_test_hcd_entry_set_cfg(UX_TEST_ACTION *action, VOID *params)
|
||||
{
|
||||
|
||||
set_cfg_counter ++;
|
||||
|
||||
rsc_mem_free_on_set_cfg = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
|
||||
|
||||
rsc_mem_alloc_cnt_on_set_cfg = ux_test_utility_sim_mem_alloc_count();
|
||||
|
||||
rsc_sem_on_set_cfg = ux_test_utility_sim_sem_create_count();
|
||||
rsc_enum_sem_get_count = ux_test_utility_sim_sem_get_count();
|
||||
rsc_mutex_on_set_cfg = ux_test_utility_sim_mutex_create_count();
|
||||
}
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_class_printer_device_standalone_basic_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR * stack_pointer;
|
||||
CHAR * memory_pointer;
|
||||
|
||||
|
||||
printf("Running Host Class Printer Basic Functionality Test................. \n");
|
||||
|
||||
/* Reset testing counts. */
|
||||
ux_test_utility_sim_mem_alloc_log_enable(UX_TRUE);
|
||||
ux_test_utility_sim_mem_alloc_count_reset();
|
||||
ux_test_utility_sim_mutex_create_count_reset();
|
||||
ux_test_utility_sim_sem_create_count_reset();
|
||||
ux_test_utility_sim_sem_get_count_reset();
|
||||
/* Reset error generations */
|
||||
ux_test_utility_sim_sem_error_generation_stop();
|
||||
ux_test_utility_sim_mutex_error_generation_stop();
|
||||
ux_test_utility_sim_sem_get_error_generation_stop();
|
||||
|
||||
/* Initialize the free memory pointer */
|
||||
stack_pointer = (CHAR *) usbx_memory;
|
||||
memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 4);
|
||||
|
||||
/* Initialize USBX Memory */
|
||||
status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf(" ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the error callback. */
|
||||
_ux_utility_error_callback_register(test_ux_error_callback);
|
||||
|
||||
/* The code below is required for installing the host portion of USBX */
|
||||
status = ux_host_stack_initialize(test_host_change_function);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf(" ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register CDC-ACM class. */
|
||||
status = ux_host_stack_class_register(_ux_system_host_class_printer_name, ux_host_class_printer_entry);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf(" ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* The code below is required for installing the device portion of USBX. No call back for
|
||||
device status change in this example. */
|
||||
status = ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
|
||||
device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
|
||||
string_framework, STRING_FRAMEWORK_LENGTH,
|
||||
language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,
|
||||
test_slave_change_function);
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf(" ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Set the parameters for callback when insertion/extraction of a printer device. */
|
||||
_ux_utility_memory_set(&device_printer_parameter, 0, sizeof(device_printer_parameter));
|
||||
_ux_utility_short_put_big_endian(printer_device_id, sizeof(printer_device_id));
|
||||
device_printer_parameter.ux_device_class_printer_device_id = printer_device_id;
|
||||
device_printer_parameter.ux_device_class_printer_instance_activate = test_printer_instance_activate;
|
||||
device_printer_parameter.ux_device_class_printer_instance_deactivate = test_printer_instance_deactivate;
|
||||
device_printer_parameter.ux_device_class_printer_soft_reset = test_printer_soft_reset;
|
||||
/* Initialize the device cdc class. This class owns both interfaces starting with 0. */
|
||||
status = ux_device_stack_class_register(_ux_device_class_printer_name,
|
||||
_ux_device_class_printer_entry,
|
||||
1, 0, &device_printer_parameter);
|
||||
/* Initialize the simulated device controller. */
|
||||
status = _ux_test_dcd_sim_slave_initialize();
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf(" ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register all the USB host controllers available in this system */
|
||||
status = ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_test_hcd_sim_host_initialize,0,0);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf(" ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the main host simulation thread. */
|
||||
status = tx_thread_create(&tx_test_thread_host_simulation, "tx test host simulation", tx_test_thread_host_simulation_entry, 0,
|
||||
stack_pointer, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf(" ERROR #9\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the main slave simulation thread. */
|
||||
stack_pointer += UX_DEMO_STACK_SIZE;
|
||||
status = tx_thread_create(&tx_test_thread_slave_simulation, "tx test slave simulation", tx_test_thread_slave_simulation_entry, 0,
|
||||
stack_pointer, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf(" ERROR #10\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
static UINT _test_check_host_connection_error(VOID)
|
||||
{
|
||||
if (device_printer && host_printer)
|
||||
return(UX_SUCCESS);
|
||||
if (error_callback_counter >= 3)
|
||||
return(UX_SUCCESS);
|
||||
return(UX_ERROR);
|
||||
}
|
||||
|
||||
static UINT _test_check_host_connection_success(VOID)
|
||||
{
|
||||
if (device_printer && host_printer)
|
||||
return(UX_SUCCESS);
|
||||
return(UX_ERROR);
|
||||
}
|
||||
|
||||
static UINT _test_check_host_disconnection_success(VOID)
|
||||
{
|
||||
if (device_printer == UX_NULL && host_printer == UX_NULL)
|
||||
return(UX_SUCCESS);
|
||||
return(UX_ERROR);
|
||||
}
|
||||
|
||||
static VOID _printer_enumeration_test(VOID)
|
||||
{
|
||||
UINT status;
|
||||
ULONG mem_free;
|
||||
ULONG test_n;
|
||||
|
||||
stepinfo(">>>>>>>>>>>> Enumeration information collection\n");
|
||||
{
|
||||
|
||||
/* Test disconnect. */
|
||||
ux_test_dcd_sim_slave_disconnect();
|
||||
ux_test_hcd_sim_host_disconnect();
|
||||
|
||||
/* Check connection. */
|
||||
status = ux_test_sleep_break_on_success(100, _test_check_host_disconnection_success);
|
||||
UX_TEST_ASSERT(status == UX_SUCCESS);
|
||||
|
||||
/* Reset testing counts. */
|
||||
ux_test_utility_sim_mem_alloc_count_reset();
|
||||
ux_test_utility_sim_mutex_create_count_reset();
|
||||
ux_test_utility_sim_sem_create_count_reset();
|
||||
ux_test_utility_sim_sem_get_count_reset();
|
||||
ux_test_hcd_sim_host_set_actions(log_on_SetCfg);
|
||||
|
||||
/* Save free memory usage. */
|
||||
mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
|
||||
ux_test_dcd_sim_slave_connect(UX_HIGH_SPEED_DEVICE);
|
||||
ux_test_hcd_sim_host_connect(UX_HIGH_SPEED_DEVICE);
|
||||
|
||||
/* Check connection. */
|
||||
status = ux_test_sleep_break_on_success(100, _test_check_host_connection_success);
|
||||
UX_TEST_ASSERT(status == UX_SUCCESS);
|
||||
|
||||
/* Log create counts for further tests. */
|
||||
rsc_enum_mutex_usage = rsc_mutex_on_set_cfg;
|
||||
rsc_enum_sem_usage = rsc_sem_on_set_cfg;
|
||||
rsc_enum_mem_alloc_count = rsc_mem_alloc_cnt_on_set_cfg;
|
||||
/* Log create counts when instances active for further tests. */
|
||||
rsc_test_mutex_usage = ux_test_utility_sim_mutex_create_count() - rsc_enum_mutex_usage;
|
||||
rsc_test_sem_usage = ux_test_utility_sim_sem_create_count() - rsc_enum_sem_usage;
|
||||
rsc_test_mem_alloc_count = ux_test_utility_sim_mem_alloc_count() - rsc_enum_mem_alloc_count;
|
||||
|
||||
/* Lock log base for tests. */
|
||||
ux_test_utility_sim_mem_alloc_log_lock();
|
||||
|
||||
stepinfo("enum mem: %ld\n", rsc_enum_mem_alloc_count);
|
||||
stepinfo("test mem : %ld\n", rsc_test_mem_alloc_count);
|
||||
stepinfo("mem free: %ld, %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available, _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_CACHE_SAFE] -> ux_byte_pool_available);
|
||||
}
|
||||
|
||||
stepinfo(">>>>>>>>>>>> Enumeration test\n");
|
||||
mem_free = (~0);
|
||||
for (test_n = 0; test_n < 3; test_n++)
|
||||
{
|
||||
stepinfo("%4ld / 2\n", test_n);
|
||||
|
||||
/* Disconnect. */
|
||||
ux_test_dcd_sim_slave_disconnect();
|
||||
ux_test_hcd_sim_host_disconnect();
|
||||
|
||||
/* Check */
|
||||
status = ux_test_sleep_break_on_success(100, _test_check_host_disconnection_success);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d.%ld: Disconnect fail\n", __LINE__, test_n);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Update memory free level (disconnect) */
|
||||
if (mem_free == (~0))
|
||||
mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
|
||||
else if (mem_free != _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available)
|
||||
{
|
||||
|
||||
printf("ERROR #%d.%ld: Memory level different after re-enumerations %ld <> %ld\n", __LINE__, test_n, mem_free, _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Connect. */
|
||||
error_callback_counter = 0;
|
||||
ux_test_dcd_sim_slave_connect(UX_HIGH_SPEED_DEVICE);
|
||||
ux_test_hcd_sim_host_connect(UX_HIGH_SPEED_DEVICE);
|
||||
|
||||
/* Wait and break on error. */
|
||||
error_callback_counter = 0;
|
||||
status = ux_test_sleep_break_on_success(100, _test_check_host_connection_error);
|
||||
|
||||
/* Check */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d.%ld: Enumeration fail\n", __LINE__, test_n);
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
stepinfo("\n");
|
||||
|
||||
if (rsc_test_mem_alloc_count) stepinfo(">>>>>>>>>>>> Memory errors enumeration test\n");
|
||||
mem_free = (~0);
|
||||
for (test_n = 0; test_n < rsc_test_mem_alloc_count; test_n ++)
|
||||
{
|
||||
|
||||
stepinfo("%4ld / %4ld\n", test_n, rsc_test_mem_alloc_count - 1);
|
||||
|
||||
/* Disconnect. */
|
||||
ux_test_dcd_sim_slave_disconnect();
|
||||
ux_test_hcd_sim_host_disconnect();
|
||||
|
||||
/* Check */
|
||||
status = ux_test_sleep_break_on_success(100, _test_check_host_disconnection_success);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
stepinfo("ERROR #%d.%ld: Disconnect fail\n", __LINE__, test_n);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Update memory free level (disconnect) */
|
||||
if (mem_free == (~0))
|
||||
mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
|
||||
else if (mem_free != _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available)
|
||||
{
|
||||
|
||||
stepinfo("ERROR #%d.%ld: Memory level different after re-enumerations %ld <> %ld\n", __LINE__, test_n, mem_free, _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Set memory error generation */
|
||||
ux_test_utility_sim_mem_alloc_error_generation_start(test_n + rsc_enum_mem_alloc_count);
|
||||
|
||||
/* Connect. */
|
||||
error_callback_counter = 0;
|
||||
ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
|
||||
ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
|
||||
|
||||
/* Wait and break on errors. */
|
||||
status = ux_test_sleep_break_on_success(100, _test_check_host_connection_error);
|
||||
|
||||
/* Check error */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Check error trap. */
|
||||
if (error_callback_counter == 0)
|
||||
{
|
||||
stepinfo("ERROR #%d.%ld: device detected when there is memory error\n", __LINE__, test_n);
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
stepinfo("mem free: %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
|
||||
}
|
||||
ux_test_utility_sim_mem_alloc_error_generation_stop();
|
||||
if (rsc_test_mem_alloc_count) stepinfo("\n");
|
||||
|
||||
/* If device disconnected, re-connect. */
|
||||
if (_test_check_host_connection_success() != UX_SUCCESS)
|
||||
{
|
||||
ux_test_dcd_sim_slave_disconnect();
|
||||
ux_test_hcd_sim_host_disconnect();
|
||||
ux_test_dcd_sim_slave_connect(UX_HIGH_SPEED_DEVICE);
|
||||
ux_test_hcd_sim_host_connect(UX_HIGH_SPEED_DEVICE);
|
||||
|
||||
/* Check */
|
||||
status = ux_test_sleep_break_on_success(100, _test_check_host_connection_success);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d: Enumeration fail\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
static VOID _printer_requests_test(VOID)
|
||||
{
|
||||
UINT status;
|
||||
ULONG printer_port_status;
|
||||
|
||||
stepinfo(">>>>>>>>>>>>>>>> Test GET_DEVICE_ID\n");
|
||||
status = ux_host_class_printer_device_id_get(host_printer, host_buffer, sizeof(host_buffer));
|
||||
UX_TEST_ASSERT(status == UX_SUCCESS);
|
||||
|
||||
stepinfo(">>>>>>>>>>>>>>>> Test GET_PORT_STATUS\n");
|
||||
ux_device_class_printer_ioctl(device_printer, UX_DEVICE_CLASS_PRINTER_IOCTL_PORT_STATUS_SET, (VOID *)0x73);
|
||||
status = ux_host_class_printer_status_get(host_printer, &printer_port_status);
|
||||
UX_TEST_ASSERT(status == UX_SUCCESS);
|
||||
UX_TEST_ASSERT(printer_port_status == 0x73);
|
||||
|
||||
stepinfo(">>>>>>>>>>>>>>>> Test SOFT_RESET\n");
|
||||
device_printer_soft_reset_count = 0;
|
||||
status = ux_host_class_printer_soft_reset(host_printer);
|
||||
UX_TEST_ASSERT(status == UX_SUCCESS);
|
||||
UX_TEST_ASSERT(device_printer_soft_reset_count == 1);
|
||||
}
|
||||
|
||||
static VOID _printer_read_write_test(VOID)
|
||||
{
|
||||
struct _TEST_DEF {
|
||||
ULONG fill;
|
||||
ULONG length;
|
||||
ULONG zlp;
|
||||
} tests[] = {
|
||||
{0x5A, 1, 0},
|
||||
{0x7E, 512, 1},
|
||||
{0xC2, 513, 0},
|
||||
{0x4C, UX_SLAVE_REQUEST_DATA_MAX_LENGTH, 1},
|
||||
{0xA5, UX_SLAVE_REQUEST_DATA_MAX_LENGTH + 1, 0},
|
||||
{0x3C, sizeof(device_buffer), 0},
|
||||
{0xC4, sizeof(device_buffer) - 1, 0},
|
||||
};
|
||||
#define _TEST_N (sizeof(tests)/sizeof(struct _TEST_DEF))
|
||||
INT i;
|
||||
ULONG actual_length;
|
||||
UINT status;
|
||||
for(i = 0; i < _TEST_N; i ++)
|
||||
{
|
||||
|
||||
stepinfo(">>>>>>>>>>>>>>>> Test Write %ld\n", tests[i].length);
|
||||
device_buffer_length = 0;
|
||||
device_read_length = tests[i].length;
|
||||
ux_utility_memory_set(device_buffer, ~tests[i].fill, tests[i].length);
|
||||
ux_utility_memory_set(host_buffer, tests[i].fill, tests[i].length);
|
||||
status = ux_host_class_printer_write(host_printer, host_buffer, tests[i].length, &actual_length);
|
||||
UX_TEST_ASSERT(status == UX_SUCCESS);
|
||||
UX_TEST_ASSERT(tests[i].length == actual_length);
|
||||
if (tests[i].zlp)
|
||||
{
|
||||
status = ux_host_class_printer_write(host_printer, host_buffer, 0, &actual_length);
|
||||
UX_TEST_ASSERT(status == UX_SUCCESS);
|
||||
UX_TEST_ASSERT(0 == actual_length);
|
||||
}
|
||||
|
||||
/* Wait a while for background reception. */
|
||||
tx_thread_sleep(tests[i].length/64 + 1);
|
||||
|
||||
UX_TEST_ASSERT(device_buffer_length == tests[i].length);
|
||||
status = ux_utility_memory_compare(device_buffer, host_buffer, tests[i].length);
|
||||
UX_TEST_ASSERT(status == UX_SUCCESS);
|
||||
|
||||
stepinfo(">>>>>>>>>>>>>>>> Test Read %ld\n", tests[i].length);
|
||||
UX_TEST_ASSERT(status == TX_SUCCESS);
|
||||
ux_utility_memory_set(host_buffer, ~tests[i].fill, tests[i].length);
|
||||
status = ux_host_class_printer_read(host_printer, host_buffer, tests[i].length, &actual_length);
|
||||
UX_TEST_ASSERT(status == UX_SUCCESS);
|
||||
UX_TEST_ASSERT(tests[i].length == actual_length);
|
||||
UX_TEST_ASSERT(host_buffer[0] == tests[i].fill);
|
||||
UX_TEST_ASSERT(host_buffer[tests[i].length - 1] == tests[i].fill);
|
||||
}
|
||||
}
|
||||
|
||||
void tx_test_thread_host_simulation_entry(ULONG arg)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
ULONG test_n;
|
||||
ULONG mem_free;
|
||||
ULONG loop;
|
||||
ULONG parameter_u32[64/4];
|
||||
USHORT *parameter_u16 = (USHORT*)parameter_u32;
|
||||
UCHAR *parameter_u8 = (UCHAR*)parameter_u32;
|
||||
|
||||
|
||||
stepinfo("\n");
|
||||
stepinfo(">>>>>>>>>>>>>>>> Test connect\n");
|
||||
ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
|
||||
ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
|
||||
status = ux_test_sleep_break_on_success(100, _test_check_host_connection_success);
|
||||
UX_TEST_ASSERT(status == UX_SUCCESS);
|
||||
|
||||
// _printer_enumeration_test();
|
||||
_printer_requests_test();
|
||||
|
||||
|
||||
_printer_read_write_test();
|
||||
|
||||
/* Test disconnect. */
|
||||
stepinfo(">>>>>>>>>>>>>>>> Test disconnect\n");
|
||||
ux_test_dcd_sim_slave_disconnect();
|
||||
ux_test_hcd_sim_host_disconnect();
|
||||
if (host_printer != UX_NULL)
|
||||
{
|
||||
|
||||
printf("ERROR #13: instance not removed when disconnect");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
|
||||
/* Finally disconnect the device. */
|
||||
ux_device_stack_disconnect();
|
||||
|
||||
/* And deinitialize the class. */
|
||||
status = ux_device_stack_class_unregister(_ux_device_class_printer_name, _ux_device_class_printer_entry);
|
||||
|
||||
/* Deinitialize the device side of usbx. */
|
||||
_ux_device_stack_uninitialize();
|
||||
|
||||
/* And finally the usbx system resources. */
|
||||
_ux_system_uninitialize();
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
|
||||
}
|
||||
|
||||
void tx_test_thread_slave_simulation_entry(ULONG arg)
|
||||
{
|
||||
UINT status;
|
||||
ULONG actual_length;
|
||||
ULONG read_length = device_read_length;
|
||||
ULONG write_length, write_zlp = UX_FALSE;
|
||||
#define PRINTER_DEVICE_STATE_READ UX_STATE_STEP
|
||||
#define PRINTER_DEVICE_STATE_WRITE UX_STATE_STEP + 1
|
||||
#define PRINTER_DEVICE_STATE_ZLP UX_STATE_STEP + 2
|
||||
UINT printer_device_state = UX_STATE_RESET;
|
||||
|
||||
while(1)
|
||||
{
|
||||
ux_system_tasks_run();
|
||||
|
||||
/* Reset state if read length changed. */
|
||||
// if (read_length != device_read_length)
|
||||
// {
|
||||
// printer_device_state = UX_STATE_RESET;
|
||||
// read_length = device_read_length;
|
||||
// }
|
||||
|
||||
switch(printer_device_state)
|
||||
{
|
||||
case UX_STATE_RESET:
|
||||
if (device_printer != UX_NULL)
|
||||
{
|
||||
printer_device_state = PRINTER_DEVICE_STATE_READ;
|
||||
}
|
||||
break;
|
||||
|
||||
case PRINTER_DEVICE_STATE_READ:
|
||||
if (device_printer == UX_NULL)
|
||||
{
|
||||
printer_device_state = UX_STATE_RESET;
|
||||
break;
|
||||
}
|
||||
status = ux_device_class_printer_read_run(device_printer, device_buffer, sizeof(device_buffer), &actual_length);
|
||||
if (status < UX_STATE_NEXT)
|
||||
{
|
||||
printf("ERROR #%d: read status 0x%x\n", __LINE__, status);
|
||||
return;
|
||||
}
|
||||
if (status == UX_STATE_NEXT)
|
||||
{
|
||||
if (actual_length == 0)
|
||||
{
|
||||
printer_device_state = UX_STATE_RESET;
|
||||
break;
|
||||
}
|
||||
write_length = actual_length;
|
||||
printer_device_state = PRINTER_DEVICE_STATE_WRITE;
|
||||
device_buffer_length = actual_length;
|
||||
}
|
||||
break;
|
||||
|
||||
case PRINTER_DEVICE_STATE_WRITE:
|
||||
if (device_printer == UX_NULL)
|
||||
{
|
||||
printer_device_state = UX_STATE_RESET;
|
||||
break;
|
||||
}
|
||||
status = ux_device_class_printer_write_run(device_printer, device_buffer, write_length, &actual_length);
|
||||
if (status < UX_STATE_NEXT)
|
||||
{
|
||||
printf("ERROR #%d: write status 0x%x\n", __LINE__, status);
|
||||
return;
|
||||
}
|
||||
if (status == UX_STATE_NEXT)
|
||||
{
|
||||
printer_device_state = PRINTER_DEVICE_STATE_READ;
|
||||
break;
|
||||
}
|
||||
|
||||
case PRINTER_DEVICE_STATE_ZLP:
|
||||
if (device_printer == UX_NULL)
|
||||
{
|
||||
printer_device_state = UX_STATE_RESET;
|
||||
break;
|
||||
}
|
||||
status = ux_device_class_printer_write_run(device_printer, device_buffer, 0, &actual_length);
|
||||
if (status < UX_STATE_NEXT)
|
||||
{
|
||||
printf("ERROR #%d: ZLP status 0x%x\n", __LINE__, status);
|
||||
return;
|
||||
}
|
||||
if (status == UX_STATE_NEXT)
|
||||
printer_device_state = PRINTER_DEVICE_STATE_READ;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
printer_device_state = UX_STATE_RESET;
|
||||
}
|
||||
|
||||
/* Let other threads run. */
|
||||
tx_thread_relinquish();
|
||||
}
|
||||
}
|
377
test/regression/usbx_control_transfer_stall_test.c
Normal file
377
test/regression/usbx_control_transfer_stall_test.c
Normal file
@ -0,0 +1,377 @@
|
||||
/* This tests ensures that when the device stalls the default endpoint upon an invalid request, it is unstalled after sending a valid request. */
|
||||
|
||||
#include "usbx_test_common_hid.h"
|
||||
#include "ux_host_class_hid_keyboard.h"
|
||||
|
||||
|
||||
#define DUMMY_USBX_MEMORY_SIZE (64*1024)
|
||||
static UCHAR dummy_usbx_memory[DUMMY_USBX_MEMORY_SIZE];
|
||||
|
||||
static UCHAR hid_report_descriptor[] = {
|
||||
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||
0x09, 0x06, // USAGE (Keyboard)
|
||||
0xa1, 0x01, // COLLECTION (Application)
|
||||
0x05, 0x07, // USAGE_PAGE (Keyboard)
|
||||
0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)
|
||||
0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x25, 0x01, // LOGICAL_MAXIMUM (1)
|
||||
0x75, 0x01, // REPORT_SIZE (1)
|
||||
0x95, 0x08, // REPORT_COUNT (8)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x81, 0x03, // INPUT (Cnst,Var,Abs)
|
||||
0x95, 0x05, // REPORT_COUNT (5)
|
||||
0x75, 0x01, // REPORT_SIZE (1)
|
||||
0x05, 0x08, // USAGE_PAGE (LEDs)
|
||||
0x19, 0x01, // USAGE_MINIMUM (Num Lock)
|
||||
0x29, 0x05, // USAGE_MAXIMUM (Kana)
|
||||
0x91, 0x02, // OUTPUT (Data,Var,Abs)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x75, 0x03, // REPORT_SIZE (3)
|
||||
0x91, 0x03, // OUTPUT (Cnst,Var,Abs)
|
||||
0x95, 0x06, // REPORT_COUNT (6)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x25, 0x65, // LOGICAL_MAXIMUM (101)
|
||||
0x05, 0x07, // USAGE_PAGE (Keyboard)
|
||||
0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
|
||||
0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)
|
||||
0x81, 0x00, // INPUT (Data,Ary,Abs)
|
||||
0xc0 // END_COLLECTION
|
||||
};
|
||||
#define HID_REPORT_LENGTH sizeof(hid_report_descriptor)/sizeof(hid_report_descriptor[0])
|
||||
|
||||
|
||||
#define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED 52
|
||||
static UCHAR device_framework_full_speed[DEVICE_FRAMEWORK_LENGTH_FULL_SPEED] = {
|
||||
|
||||
/* Device descriptor */
|
||||
0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08,
|
||||
0x81, 0x0A, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x01,
|
||||
|
||||
/* Configuration descriptor */
|
||||
0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x00, 0xc0,
|
||||
0x32,
|
||||
|
||||
/* Interface descriptor */
|
||||
0x09, 0x04, 0x02, 0x00, 0x01, 0x03, 0x00, 0x00,
|
||||
0x00,
|
||||
|
||||
/* HID descriptor */
|
||||
0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(HID_REPORT_LENGTH),
|
||||
MSB(HID_REPORT_LENGTH),
|
||||
|
||||
/* Endpoint descriptor (Interrupt) */
|
||||
0x07, 0x05, 0x82, 0x03, 0x08, 0x00, 0x08
|
||||
|
||||
};
|
||||
|
||||
|
||||
#define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED 62
|
||||
static UCHAR device_framework_high_speed[DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED] = {
|
||||
|
||||
/* Device descriptor */
|
||||
0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
|
||||
0x0a, 0x07, 0x25, 0x40, 0x01, 0x00, 0x01, 0x02,
|
||||
0x03, 0x01,
|
||||
|
||||
/* Device qualifier descriptor */
|
||||
0x0a, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
|
||||
0x01, 0x00,
|
||||
|
||||
/* Configuration descriptor */
|
||||
0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x00, 0xc0,
|
||||
0x32,
|
||||
|
||||
/* Interface descriptor */
|
||||
0x09, 0x04, 0x02, 0x00, 0x01, 0x03, 0x00, 0x00,
|
||||
0x00,
|
||||
|
||||
/* HID descriptor */
|
||||
0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(HID_REPORT_LENGTH),
|
||||
MSB(HID_REPORT_LENGTH),
|
||||
|
||||
/* Endpoint descriptor (Interrupt) */
|
||||
0x07, 0x05, 0x82, 0x03, 0x08, 0x00, 0x08
|
||||
|
||||
};
|
||||
|
||||
|
||||
/* String Device Framework :
|
||||
Byte 0 and 1 : Word containing the language ID : 0x0904 for US
|
||||
Byte 2 : Byte containing the index of the descriptor
|
||||
Byte 3 : Byte containing the length of the descriptor string
|
||||
*/
|
||||
|
||||
#define STRING_FRAMEWORK_LENGTH 40
|
||||
static UCHAR string_framework[] = {
|
||||
|
||||
/* Manufacturer string descriptor : Index 1 */
|
||||
0x09, 0x04, 0x01, 0x0c,
|
||||
0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
|
||||
0x6f, 0x67, 0x69, 0x63,
|
||||
|
||||
/* Product string descriptor : Index 2 */
|
||||
0x09, 0x04, 0x02, 0x0c,
|
||||
0x55, 0x53, 0x42, 0x20, 0x4b, 0x65, 0x79, 0x62,
|
||||
0x6f, 0x61, 0x72, 0x64,
|
||||
|
||||
/* Serial Number string descriptor : Index 3 */
|
||||
0x09, 0x04, 0x03, 0x04,
|
||||
0x30, 0x30, 0x30, 0x31
|
||||
};
|
||||
|
||||
|
||||
/* Multiple languages are supported on the device, to add
|
||||
a language besides english, the unicode language code must
|
||||
be appended to the language_id_framework array and the length
|
||||
adjusted accordingly. */
|
||||
#define LANGUAGE_ID_FRAMEWORK_LENGTH 2
|
||||
static UCHAR language_id_framework[] = {
|
||||
|
||||
/* English. */
|
||||
0x09, 0x04
|
||||
};
|
||||
|
||||
|
||||
UINT _ux_hcd_sim_host_entry(UX_HCD *hcd, UINT function, VOID *parameter);
|
||||
|
||||
|
||||
static UINT ux_system_host_change_function(ULONG a, UX_HOST_CLASS *b, VOID *c)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
|
||||
{
|
||||
|
||||
if (error_code != UX_TRANSFER_STALLED)
|
||||
{
|
||||
|
||||
/* Failed test. */
|
||||
printf("Error on line %d, system_level: %d, system_context: %d, error code: %d\n", __LINE__, system_level, system_context, error_code);
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_control_transfer_stall_test(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR * stack_pointer;
|
||||
CHAR * memory_pointer;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Control Transfer Stall test....................... ");
|
||||
|
||||
/* Initialize the free memory pointer */
|
||||
stack_pointer = (CHAR *) usbx_memory;
|
||||
memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
|
||||
|
||||
/* Initialize USBX. Memory */
|
||||
status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the error callback. */
|
||||
_ux_utility_error_callback_register(error_callback);
|
||||
|
||||
/* The code below is required for installing the host portion of USBX */
|
||||
status = ux_host_stack_initialize(ux_system_host_change_function);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = ux_host_stack_class_register(_ux_system_host_class_hid_name, ux_host_class_hid_entry);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the HID client(s). */
|
||||
status = ux_host_class_hid_client_register(_ux_system_host_class_hid_client_keyboard_name, ux_host_class_hid_keyboard_entry);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* The code below is required for installing the device portion of USBX. No call back for
|
||||
device status change in this example. */
|
||||
status = ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
|
||||
device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
|
||||
string_framework, STRING_FRAMEWORK_LENGTH,
|
||||
language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Initialize the hid class parameters. */
|
||||
hid_parameter.ux_device_class_hid_parameter_report_address = hid_report_descriptor;
|
||||
hid_parameter.ux_device_class_hid_parameter_report_length = HID_REPORT_LENGTH;
|
||||
hid_parameter.ux_device_class_hid_parameter_callback = demo_thread_hid_callback;
|
||||
|
||||
/* Initilize the device hid class. The class is connected with interface 2 */
|
||||
status = ux_device_stack_class_register(_ux_system_slave_class_hid_name, ux_device_class_hid_entry,
|
||||
1,2, (VOID *)&hid_parameter);
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Initialize the simulated device controller. */
|
||||
status = _ux_dcd_sim_slave_initialize();
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register all the USB host controllers available in this system */
|
||||
status = ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, ux_hcd_sim_host_initialize,0,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the main host simulation thread. */
|
||||
status = tx_thread_create(&tx_demo_thread_host_simulation, "tx demo host simulation", tx_demo_thread_host_simulation_entry, 0,
|
||||
stack_pointer, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
static void tx_demo_thread_host_simulation_entry(ULONG arg)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
UX_HOST_CLASS_HID_KEYBOARD *keyboard;
|
||||
UX_ENDPOINT *endpoint;
|
||||
UX_TRANSFER *transfer_request;
|
||||
UCHAR descriptor[1024];
|
||||
|
||||
/* Find the HID class */
|
||||
status = demo_class_hid_get();
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the HID client */
|
||||
hid_client = hid -> ux_host_class_hid_client;
|
||||
|
||||
/* Check if the instance of the keyboard is live */
|
||||
while (hid_client -> ux_host_class_hid_client_local_instance == UX_NULL)
|
||||
tx_thread_sleep(10);
|
||||
|
||||
/* Get the keyboard instance */
|
||||
keyboard = (UX_HOST_CLASS_HID_KEYBOARD *)hid_client -> ux_host_class_hid_client_local_instance;
|
||||
|
||||
/* Get default endpoint. */
|
||||
endpoint = &hid->ux_host_class_hid_device->ux_device_control_endpoint;
|
||||
|
||||
/* Get the transfer request. */
|
||||
transfer_request = &endpoint->ux_endpoint_transfer_request;
|
||||
|
||||
/* Stall the default endpoint by sending it an invalid request. */
|
||||
|
||||
/* Create a transfer request for an invalid request. */
|
||||
transfer_request -> ux_transfer_request_data_pointer = descriptor;
|
||||
transfer_request -> ux_transfer_request_requested_length = 0x09;
|
||||
transfer_request -> ux_transfer_request_function = UX_GET_DESCRIPTOR;
|
||||
transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_DEVICE;
|
||||
transfer_request -> ux_transfer_request_value = 0xffff << 8;
|
||||
transfer_request -> ux_transfer_request_index = 0x02;
|
||||
|
||||
/* Send request to HCD layer. */
|
||||
status = ux_host_stack_transfer_request(transfer_request);
|
||||
if (status != UX_TRANSFER_STALLED)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now send it a valid request. */
|
||||
|
||||
/* Create a transfer request for a valid request. */
|
||||
transfer_request -> ux_transfer_request_data_pointer = descriptor;
|
||||
transfer_request -> ux_transfer_request_requested_length = UX_CONFIGURATION_DESCRIPTOR_LENGTH;
|
||||
transfer_request -> ux_transfer_request_function = UX_GET_DESCRIPTOR;
|
||||
transfer_request -> ux_transfer_request_type = UX_REQUEST_IN | UX_REQUEST_TYPE_STANDARD | UX_REQUEST_TARGET_DEVICE;
|
||||
transfer_request -> ux_transfer_request_value = UX_CONFIGURATION_DESCRIPTOR_ITEM << 8;
|
||||
transfer_request -> ux_transfer_request_index = 0x02;
|
||||
|
||||
/* Send request to HCD layer. */
|
||||
status = ux_host_stack_transfer_request(transfer_request);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now disconnect the device. */
|
||||
_ux_device_stack_disconnect();
|
||||
|
||||
/* And deinitialize the class. */
|
||||
status = ux_device_stack_class_unregister(_ux_system_slave_class_hid_name, ux_device_class_hid_entry);
|
||||
|
||||
/* Deinitialize the device side of usbx. */
|
||||
_ux_device_stack_uninitialize();
|
||||
|
||||
/* And finally the usbx system resources. */
|
||||
_ux_system_uninitialize();
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
|
||||
static UINT demo_thread_hid_callback(UX_SLAVE_CLASS_HID *class, UX_SLAVE_CLASS_HID_EVENT *event)
|
||||
{
|
||||
return(UX_SUCCESS);
|
||||
}
|
1640
test/regression/usbx_device_class_ccid_basic_tests.c
Normal file
1640
test/regression/usbx_device_class_ccid_basic_tests.c
Normal file
File diff suppressed because it is too large
Load Diff
1492
test/regression/usbx_device_class_ccid_busy_abort_tests.c
Normal file
1492
test/regression/usbx_device_class_ccid_busy_abort_tests.c
Normal file
File diff suppressed because it is too large
Load Diff
900
test/regression/usbx_device_dfu_basic_test.c
Normal file
900
test/regression/usbx_device_dfu_basic_test.c
Normal file
@ -0,0 +1,900 @@
|
||||
/* This test is designed to test the simple dpump host/device class operation. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
#include "ux_api.h"
|
||||
#include "ux_system.h"
|
||||
#include "ux_utility.h"
|
||||
#include "ux_hcd_sim_host.h"
|
||||
|
||||
#include "fx_api.h"
|
||||
|
||||
#include "ux_device_class_dfu.h"
|
||||
#include "ux_device_stack.h"
|
||||
#include "ux_host_stack.h"
|
||||
|
||||
#include "ux_test_dcd_sim_slave.h"
|
||||
#include "ux_test_hcd_sim_host.h"
|
||||
#include "ux_test_utility_sim.h"
|
||||
|
||||
|
||||
#define UX_DEMO_REQUEST_MAX_LENGTH \
|
||||
((UX_HCD_SIM_HOST_MAX_PAYLOAD) > (UX_SLAVE_REQUEST_DATA_MAX_LENGTH) ? \
|
||||
(UX_HCD_SIM_HOST_MAX_PAYLOAD) : (UX_SLAVE_REQUEST_DATA_MAX_LENGTH))
|
||||
|
||||
|
||||
/* Define constants. */
|
||||
|
||||
#define UX_DEMO_MEMORY_SIZE (128*1024)
|
||||
#define UX_DEMO_STACK_SIZE (1024)
|
||||
|
||||
|
||||
/* Define local/extern function prototypes. */
|
||||
|
||||
static void test_thread_entry(ULONG);
|
||||
static TX_THREAD tx_test_thread_host_simulation;
|
||||
static TX_THREAD tx_test_thread_slave_simulation;
|
||||
static void tx_test_thread_host_simulation_entry(ULONG);
|
||||
static void tx_test_thread_slave_simulation_entry(ULONG);
|
||||
|
||||
static VOID demo_thread_dfu_activate(VOID *dfu);
|
||||
static VOID demo_thread_dfu_deactivate(VOID *dfu);
|
||||
static UINT demo_thread_dfu_read(VOID *dfu, ULONG block_number, UCHAR * data_pointer, ULONG length, ULONG *actual_length);
|
||||
static UINT demo_thread_dfu_write(VOID *dfu, ULONG block_number, UCHAR * data_pointer, ULONG length, ULONG *media_status);
|
||||
static UINT demo_thread_dfu_get_status(VOID *dfu, ULONG *media_status);
|
||||
static UINT demo_thread_dfu_notify(VOID *dfu, ULONG notification);
|
||||
static UINT demo_thread_dfu_custom_request(VOID *dfu, UX_SLAVE_TRANSFER *transfer);
|
||||
|
||||
/* Define global data structures. */
|
||||
|
||||
static UCHAR usbx_memory[UX_DEMO_MEMORY_SIZE + (UX_DEMO_STACK_SIZE * 2)];
|
||||
|
||||
static ULONG error_counter;
|
||||
|
||||
static ULONG set_cfg_counter;
|
||||
|
||||
static ULONG rsc_mem_free_on_set_cfg;
|
||||
static ULONG rsc_sem_on_set_cfg;
|
||||
static ULONG rsc_sem_get_on_set_cfg;
|
||||
static ULONG rsc_mutex_on_set_cfg;
|
||||
|
||||
static ULONG rsc_enum_sem_usage;
|
||||
static ULONG rsc_enum_sem_get_count;
|
||||
static ULONG rsc_enum_mutex_usage;
|
||||
static ULONG rsc_enum_mem_usage;
|
||||
|
||||
static ULONG interaction_count;
|
||||
|
||||
static UCHAR error_callback_ignore = UX_TRUE;
|
||||
static ULONG error_callback_counter;
|
||||
|
||||
static UX_SLAVE_CLASS_DFU_PARAMETER dfu_parameter;
|
||||
|
||||
static UX_DEVICE *device;
|
||||
static ULONG dfu_block;
|
||||
static ULONG dfu_transfer_length;
|
||||
static ULONG dfu_actual_length;
|
||||
static UCHAR dfu_host_buffer[UX_DEMO_REQUEST_MAX_LENGTH];
|
||||
static UCHAR dfu_device_buffer[UX_DEMO_REQUEST_MAX_LENGTH];
|
||||
|
||||
|
||||
/* Define device framework. */
|
||||
|
||||
/* DFU descriptor must be same for all frameworks!!! */
|
||||
#define DFU_FUNCTION_DESCRIPTOR \
|
||||
/* Functional descriptor for DFU. */ \
|
||||
0x09, 0x21, \
|
||||
0x0f, /* bmAttributes: B3 bitWillDetach */ \
|
||||
/* B2 bitManifestationTolerant */ \
|
||||
/* B1 bitCanUpload, B0 bitCanDnload */ \
|
||||
0xE8, 0x03, /* wDetachTimeOut: 0x03E8 (1000) */ \
|
||||
UX_W0(UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH), \
|
||||
UX_W1(UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH), /* wTransferSize: */ \
|
||||
0x00, 0x01, /* bcdDFUVersion: 0x0100 */
|
||||
|
||||
/* Interface descriptor for APP/DFU mode. */
|
||||
#define DFU_INTERFACE_DESCRIPTOR(bInterfaceNumber, bInterfaceProtocol) \
|
||||
/* Interface descriptor for DFU. */ \
|
||||
0x09, 0x04, \
|
||||
(bInterfaceNumber), 0x00, 0x00, \
|
||||
0xFE, 0x01, (bInterfaceProtocol), \
|
||||
0x00, \
|
||||
|
||||
#define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED sizeof(device_framework_full_speed)
|
||||
static UCHAR device_framework_full_speed[] = {
|
||||
|
||||
/* Device descriptor */
|
||||
0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x40,
|
||||
0x99, 0x99, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02,
|
||||
0x03, 0x01,
|
||||
|
||||
/* Configuration descriptor */
|
||||
0x09, 0x02, 0x1b, 0x00, 0x01, 0x01, 0x00, 0xc0,
|
||||
0x32,
|
||||
|
||||
/* Interface descriptor for DFU (bInterfaceProtocol = 1). */
|
||||
DFU_INTERFACE_DESCRIPTOR(0x00, 0x01)
|
||||
DFU_FUNCTION_DESCRIPTOR
|
||||
};
|
||||
|
||||
#define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED sizeof(device_framework_high_speed)
|
||||
static UCHAR device_framework_high_speed[] = {
|
||||
|
||||
/* Device descriptor */
|
||||
0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
|
||||
0x99, 0x99, 0x00, 0x00, 0x01, 0x00, 0x01, 0x02,
|
||||
0x03, 0x01,
|
||||
|
||||
/* Device qualifier descriptor */
|
||||
0x0a, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
|
||||
0x01, 0x00,
|
||||
|
||||
/* Configuration descriptor */
|
||||
0x09, 0x02, 0x1b, 0x00, 0x01, 0x01, 0x00, 0xc0,
|
||||
0x32,
|
||||
|
||||
/* Interface descriptor for DFU (bInterfaceProtocol = 1). */
|
||||
DFU_INTERFACE_DESCRIPTOR(0x00, 0x01)
|
||||
DFU_FUNCTION_DESCRIPTOR
|
||||
};
|
||||
|
||||
/* String Device Framework :
|
||||
Byte 0 and 1 : Word containing the language ID : 0x0904 for US
|
||||
Byte 2 : Byte containing the index of the descriptor
|
||||
Byte 3 : Byte containing the length of the descriptor string
|
||||
*/
|
||||
#define STRING_FRAMEWORK_LENGTH sizeof(string_framework)
|
||||
static UCHAR string_framework[] = {
|
||||
|
||||
/* Manufacturer string descriptor : Index 1 - "Microsoft AzureRTOS" */
|
||||
0x09, 0x04, 0x01, 19,
|
||||
'M', 'i', 'c', 'r', 'o', 's', 'o', 'f',
|
||||
't', ' ', 'A', 'z', 'u', 'r', 'e', 'R',
|
||||
'T', 'O', 'S',
|
||||
|
||||
/* Product string descriptor : Index 2 - "DFU Demo Device" */
|
||||
0x09, 0x04, 0x02, 15,
|
||||
'D', 'F', 'U', ' ', 'D', 'e', 'm', 'o',
|
||||
' ', 'D', 'e', 'v', 'i', 'c', 'e',
|
||||
|
||||
/* Serial Number string descriptor : Index 3 - "0000" */
|
||||
0x09, 0x04, 0x03, 0x04,
|
||||
'0', '0', '0', '0'
|
||||
};
|
||||
|
||||
/* Multiple languages are supported on the device, to add
|
||||
a language besides english, the unicode language code must
|
||||
be appended to the language_id_framework array and the length
|
||||
adjusted accordingly. */
|
||||
#define LANGUAGE_ID_FRAMEWORK_LENGTH sizeof(language_id_framework)
|
||||
static UCHAR language_id_framework[] = {
|
||||
|
||||
/* English. */
|
||||
0x09, 0x04
|
||||
};
|
||||
|
||||
|
||||
#define DEVICE_FRAMEWORK_LENGTH_DFU sizeof(device_framework_dfu)
|
||||
static UCHAR device_framework_dfu[] = {
|
||||
|
||||
/* Device descriptor */
|
||||
0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x40,
|
||||
0x99, 0x99, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02,
|
||||
0x03, 0x01,
|
||||
|
||||
/* Configuration descriptor */
|
||||
0x09, 0x02, 0x1B, 0x00, 0x01, 0x01, 0x00, 0xc0,
|
||||
0x32,
|
||||
|
||||
/* Interface descriptor for DFU (bInterfaceProtocol = 2). */
|
||||
DFU_INTERFACE_DESCRIPTOR(0x00, 0x02)
|
||||
DFU_FUNCTION_DESCRIPTOR
|
||||
};
|
||||
|
||||
|
||||
/* Define the ISR dispatch. */
|
||||
|
||||
extern VOID (*test_isr_dispatch)(void);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
|
||||
void test_control_return(UINT status);
|
||||
|
||||
static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
|
||||
{
|
||||
|
||||
error_callback_counter ++;
|
||||
|
||||
if (!error_callback_ignore)
|
||||
{
|
||||
{
|
||||
/* Failed test. */
|
||||
printf("Error #%d, system_level: %d, system_context: %d, error_code: 0x%x\n", __LINE__, system_level, system_context, error_code);
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Define the ISR dispatch routine. */
|
||||
|
||||
static void test_isr(void)
|
||||
{
|
||||
|
||||
/* For further expansion of interrupt-level testing. */
|
||||
}
|
||||
|
||||
|
||||
static UINT demo_system_host_change_function(ULONG event, UX_HOST_CLASS *cls, VOID *inst)
|
||||
{
|
||||
if (event == UX_DEVICE_CONNECTION)
|
||||
{
|
||||
device = (UX_DEVICE *)inst;
|
||||
}
|
||||
if (event == UX_DEVICE_DISCONNECTION)
|
||||
{
|
||||
if ((VOID *)device == inst)
|
||||
device = UX_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_device_dfu_basic_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR * stack_pointer;
|
||||
CHAR * memory_pointer;
|
||||
ULONG test_n;
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running Device DFU Basic Functionality Test......................... ");
|
||||
|
||||
/* Reset testing counts. */
|
||||
ux_test_utility_sim_mutex_create_count_reset();
|
||||
ux_test_utility_sim_sem_create_count_reset();
|
||||
ux_test_utility_sim_sem_get_count_reset();
|
||||
/* Reset error generations */
|
||||
ux_test_utility_sim_sem_error_generation_stop();
|
||||
ux_test_utility_sim_mutex_error_generation_stop();
|
||||
ux_test_utility_sim_sem_get_error_generation_stop();
|
||||
|
||||
/* Initialize the free memory pointer */
|
||||
stack_pointer = (CHAR *) usbx_memory;
|
||||
memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
|
||||
|
||||
/* Initialize USBX Memory */
|
||||
status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the error callback. */
|
||||
_ux_utility_error_callback_register(error_callback);
|
||||
|
||||
/* The code below is required for installing the host portion of USBX */
|
||||
status = ux_host_stack_initialize(demo_system_host_change_function);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* There is no host class for DFU now. */
|
||||
|
||||
/* The code below is required for installing the device portion of USBX. No call back for
|
||||
device status change in this example. */
|
||||
status = ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
|
||||
device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
|
||||
string_framework, STRING_FRAMEWORK_LENGTH,
|
||||
language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Store the DFU parameters. */
|
||||
dfu_parameter.ux_slave_class_dfu_parameter_instance_activate = demo_thread_dfu_activate;
|
||||
dfu_parameter.ux_slave_class_dfu_parameter_instance_deactivate = demo_thread_dfu_deactivate;
|
||||
dfu_parameter.ux_slave_class_dfu_parameter_read = demo_thread_dfu_read;
|
||||
dfu_parameter.ux_slave_class_dfu_parameter_write = demo_thread_dfu_write;
|
||||
dfu_parameter.ux_slave_class_dfu_parameter_get_status = demo_thread_dfu_get_status;
|
||||
dfu_parameter.ux_slave_class_dfu_parameter_notify = demo_thread_dfu_notify;
|
||||
#ifdef UX_DEVICE_CLASS_DFU_CUSTOM_REQUEST_ENABLE
|
||||
dfu_parameter.ux_device_class_dfu_parameter_custom_request = demo_thread_dfu_custom_request;
|
||||
#endif
|
||||
dfu_parameter.ux_slave_class_dfu_parameter_framework = device_framework_dfu;
|
||||
dfu_parameter.ux_slave_class_dfu_parameter_framework_length = DEVICE_FRAMEWORK_LENGTH_DFU;
|
||||
|
||||
/* Initilize the device dfu class. The class is connected with interface 1 on configuration 1. */
|
||||
status = ux_device_stack_class_register(_ux_system_slave_class_dfu_name, ux_device_class_dfu_entry,
|
||||
1, 0, (VOID *)&dfu_parameter);
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Initialize the simulated device controller. */
|
||||
status = _ux_dcd_sim_slave_initialize();
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register all the USB host controllers available in this system */
|
||||
status = ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, _ux_hcd_sim_host_initialize,0,0);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the main host simulation thread. */
|
||||
status = tx_thread_create(&tx_test_thread_host_simulation, "tx demo host simulation", tx_test_thread_host_simulation_entry, 0,
|
||||
stack_pointer, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the main slave simulation thread. */
|
||||
status = tx_thread_create(&tx_test_thread_slave_simulation, "tx demo slave simulation", tx_test_thread_slave_simulation_entry, 0,
|
||||
stack_pointer + UX_DEMO_STACK_SIZE, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #%d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
static UINT _req_DFU_LOCK(UX_TRANSFER *control_transfer)
|
||||
{
|
||||
UINT status;
|
||||
#if defined(UX_HOST_STANDALONE)
|
||||
while(1)
|
||||
{
|
||||
ux_system_tasks_run();
|
||||
tx_thread_relinquish();
|
||||
|
||||
UX_ENDPOINT *endpoint = control_transfer -> ux_transfer_request_endpoint;
|
||||
if (endpoint == UX_NULL || endpoint -> ux_endpoint_state != UX_ENDPOINT_RUNNING)
|
||||
{
|
||||
status = UX_ENDPOINT_HANDLE_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
UX_DEVICE *device = endpoint -> ux_endpoint_device;
|
||||
if (device == UX_NULL || device -> ux_device_handle != (ULONG)(ALIGN_TYPE)(device))
|
||||
{
|
||||
status = UX_DEVICE_HANDLE_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
if ((device -> ux_device_flags & UX_DEVICE_FLAG_LOCK) == 0)
|
||||
{
|
||||
device -> ux_device_flags |= UX_DEVICE_FLAG_LOCK;
|
||||
control_transfer -> ux_transfer_request_flags |= UX_TRANSFER_FLAG_AUTO_DEVICE_UNLOCK;
|
||||
control_transfer -> ux_transfer_request_timeout_value = UX_WAIT_FOREVER;
|
||||
status = UX_SUCCESS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
status = _ux_utility_semaphore_get(&control_transfer->ux_transfer_request_endpoint->ux_endpoint_device->ux_device_protection_semaphore, UX_WAIT_FOREVER);
|
||||
#endif
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
printf("ERROR #%d: %x\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
static UINT _req_DFU_GETSTATE(UX_TRANSFER *control_transfer)
|
||||
{
|
||||
_req_DFU_LOCK(control_transfer);
|
||||
control_transfer->ux_transfer_request_type = 0xA1;
|
||||
control_transfer->ux_transfer_request_function = UX_SLAVE_CLASS_DFU_COMMAND_GET_STATE;
|
||||
control_transfer->ux_transfer_request_index = 0;
|
||||
control_transfer->ux_transfer_request_requested_length = 1;
|
||||
control_transfer->ux_transfer_request_data_pointer = dfu_host_buffer;
|
||||
control_transfer->ux_transfer_request_value = 0;
|
||||
return ux_host_stack_transfer_request(control_transfer);
|
||||
}
|
||||
static UINT _req_DFU_GETSTATUS(UX_TRANSFER *control_transfer)
|
||||
{
|
||||
_req_DFU_LOCK(control_transfer);
|
||||
control_transfer->ux_transfer_request_type = 0xA1;
|
||||
control_transfer->ux_transfer_request_function = UX_SLAVE_CLASS_DFU_COMMAND_GET_STATUS;
|
||||
control_transfer->ux_transfer_request_index = 0;
|
||||
control_transfer->ux_transfer_request_requested_length = 6;
|
||||
control_transfer->ux_transfer_request_data_pointer = dfu_host_buffer;
|
||||
control_transfer->ux_transfer_request_value = 0;
|
||||
return ux_host_stack_transfer_request(control_transfer);
|
||||
}
|
||||
static UINT _req_DFU_DETACH(UX_TRANSFER *control_transfer)
|
||||
{
|
||||
_req_DFU_LOCK(control_transfer);
|
||||
control_transfer->ux_transfer_request_type = 0x21;
|
||||
control_transfer->ux_transfer_request_function = UX_SLAVE_CLASS_DFU_COMMAND_DETACH;
|
||||
control_transfer->ux_transfer_request_index = 0;
|
||||
control_transfer->ux_transfer_request_value = 1000;
|
||||
control_transfer->ux_transfer_request_requested_length = 0;
|
||||
return ux_host_stack_transfer_request(control_transfer);
|
||||
}
|
||||
static UINT _req_DFU_DNLOAD_IN(UX_TRANSFER *control_transfer, ULONG block, ULONG len)
|
||||
{
|
||||
_req_DFU_LOCK(control_transfer);
|
||||
control_transfer->ux_transfer_request_type = 0xA1;
|
||||
control_transfer->ux_transfer_request_function = UX_SLAVE_CLASS_DFU_COMMAND_DOWNLOAD;
|
||||
control_transfer->ux_transfer_request_index = 0;
|
||||
control_transfer->ux_transfer_request_data_pointer = dfu_host_buffer;
|
||||
control_transfer->ux_transfer_request_requested_length = len;
|
||||
control_transfer->ux_transfer_request_value = block;
|
||||
return ux_host_stack_transfer_request(control_transfer);
|
||||
}
|
||||
static UINT _req_DFU_DNLOAD(UX_TRANSFER *control_transfer, ULONG block, ULONG len)
|
||||
{
|
||||
_req_DFU_LOCK(control_transfer);
|
||||
control_transfer->ux_transfer_request_type = 0x21;
|
||||
control_transfer->ux_transfer_request_function = UX_SLAVE_CLASS_DFU_COMMAND_DOWNLOAD;
|
||||
control_transfer->ux_transfer_request_index = 0;
|
||||
control_transfer->ux_transfer_request_data_pointer = dfu_host_buffer;
|
||||
control_transfer->ux_transfer_request_requested_length = len;
|
||||
control_transfer->ux_transfer_request_value = block;
|
||||
return ux_host_stack_transfer_request(control_transfer);
|
||||
}
|
||||
static UINT _req_DFU_UPLOAD(UX_TRANSFER *control_transfer, ULONG block, ULONG len)
|
||||
{
|
||||
_req_DFU_LOCK(control_transfer);
|
||||
control_transfer->ux_transfer_request_type = 0xA1;
|
||||
control_transfer->ux_transfer_request_function = UX_SLAVE_CLASS_DFU_COMMAND_UPLOAD;
|
||||
control_transfer->ux_transfer_request_index = 0;
|
||||
control_transfer->ux_transfer_request_data_pointer = dfu_host_buffer;
|
||||
control_transfer->ux_transfer_request_requested_length = len;
|
||||
control_transfer->ux_transfer_request_value = block;
|
||||
return ux_host_stack_transfer_request(control_transfer);
|
||||
}
|
||||
static UINT _req_DFU_CLRSTATUS(UX_TRANSFER *control_transfer)
|
||||
{
|
||||
_req_DFU_LOCK(control_transfer);
|
||||
control_transfer->ux_transfer_request_type = 0x21;
|
||||
control_transfer->ux_transfer_request_function = UX_SLAVE_CLASS_DFU_COMMAND_CLEAR_STATUS;
|
||||
control_transfer->ux_transfer_request_index = 0;
|
||||
control_transfer->ux_transfer_request_data_pointer = UX_NULL;
|
||||
control_transfer->ux_transfer_request_requested_length = 0;
|
||||
control_transfer->ux_transfer_request_value = 0;
|
||||
return ux_host_stack_transfer_request(control_transfer);
|
||||
}
|
||||
|
||||
|
||||
static void tx_test_thread_host_simulation_entry(ULONG arg)
|
||||
{
|
||||
UX_ENDPOINT *control_endpoint;
|
||||
UX_TRANSFER *control_transfer;
|
||||
ULONG len, trans_len, block;
|
||||
INT i;
|
||||
UINT status;
|
||||
|
||||
stepinfo("\n");
|
||||
|
||||
stepinfo(">>>>>>>>>>>> Test DFU connect\n");
|
||||
status = ux_test_wait_for_non_null((VOID **)&device);
|
||||
UX_TEST_ASSERT(status == UX_SUCCESS);
|
||||
if (device -> ux_device_state == UX_DEVICE_CONFIGURED)
|
||||
{
|
||||
printf("ERROR #%d, device state 0x%lx\n", __LINE__, device->ux_device_state);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
stepinfo(">>>>>>>>>>>> Test DFU set configure\n");
|
||||
status = ux_host_stack_device_configuration_select(device->ux_device_first_configuration);
|
||||
UX_TEST_ASSERT(status == UX_SUCCESS);
|
||||
|
||||
/* Get endpoint and transfer request. */
|
||||
control_endpoint = &device->ux_device_control_endpoint;
|
||||
control_transfer = &control_endpoint->ux_endpoint_transfer_request;
|
||||
|
||||
stepinfo(">>>>>>>>>>>> Test DFU_GETSTATE\n");
|
||||
status = _req_DFU_GETSTATE(control_transfer);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
printf("ERROR #%d: transfer status 0x%x\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
UX_TEST_ASSERT(dfu_host_buffer[0] == UX_SYSTEM_DFU_STATE_APP_IDLE);
|
||||
|
||||
stepinfo(">>>>>>>>>>>> Test DFU DETACH\n");
|
||||
|
||||
/* Uses DFU framework after USB reset (re-connect). */
|
||||
ux_test_dcd_sim_slave_connect_framework(device_framework_dfu, DEVICE_FRAMEWORK_LENGTH_DFU);
|
||||
status = _req_DFU_DETACH(control_transfer);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
printf("ERROR #%d: transfer status 0x%x\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
status = ux_test_wait_for_null((VOID **)&device);
|
||||
UX_TEST_ASSERT(status == UX_SUCCESS);
|
||||
status = ux_test_wait_for_non_null((VOID **)&device);
|
||||
UX_TEST_ASSERT(status == UX_SUCCESS);
|
||||
status = ux_host_stack_device_configuration_select(device->ux_device_first_configuration);
|
||||
UX_TEST_ASSERT(status == UX_SUCCESS);
|
||||
|
||||
status = _req_DFU_GETSTATE(control_transfer);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
printf("ERROR #%d: transfer status 0x%x\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
UX_TEST_ASSERT(dfu_host_buffer[0] == UX_SYSTEM_DFU_STATE_DFU_IDLE);
|
||||
|
||||
#if defined(UX_DEVICE_CLASS_DFU_CUSTOM_REQUEST_ENABLE)
|
||||
status = _req_DFU_DNLOAD(control_transfer, 0, 0);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
printf("ERROR #%d: transfer status 0x%x\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
UX_TEST_ASSERT(dfu_host_buffer[0] == UX_SYSTEM_DFU_STATE_DFU_IDLE);
|
||||
#else
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(UX_DEVICE_CLASS_DFU_UPLOAD_DISABLE)
|
||||
|
||||
stepinfo(">>>>>>>>>>>> Test DFU UPLOAD FAIL\n");
|
||||
status = _req_DFU_UPLOAD(control_transfer, 0, UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH + 1);
|
||||
if (status != UX_TRANSFER_STALLED)
|
||||
{
|
||||
printf("ERROR #%d: UPLOAD should STALL\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
status = _req_DFU_CLRSTATUS(control_transfer);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
printf("ERROR #%d: CLRSTATUS error 0x%x\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
stepinfo(">>>>>>>>>>>> Test DFU UPLOAD\n");
|
||||
trans_len = UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH;
|
||||
for (block = 0; block < 99; block ++)
|
||||
{
|
||||
for (i = 0; i < trans_len; i ++)
|
||||
{
|
||||
dfu_device_buffer[i] = (UCHAR)(block + i);
|
||||
dfu_host_buffer[i] = 0xFF;
|
||||
}
|
||||
dfu_actual_length = trans_len;
|
||||
status = _req_DFU_UPLOAD(control_transfer, block, trans_len);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
printf("ERROR #%d(%ld, %ld): UPLOAD status 0x%x\n", __LINE__, block, trans_len, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
UX_TEST_ASSERT(dfu_transfer_length == trans_len);
|
||||
UX_TEST_ASSERT(dfu_block == block);
|
||||
if (ux_utility_memory_compare(dfu_host_buffer, dfu_device_buffer, trans_len) != UX_SUCCESS)
|
||||
{
|
||||
printf("ERROR #%d(%ld, %ld): data error\n", __LINE__, block, trans_len);
|
||||
printf(" device buffer %p: %2x %2x ...\n", dfu_device_buffer, dfu_device_buffer[0], dfu_device_buffer[1]);
|
||||
printf(" host buffer %p: %2x %2x ...\n", dfu_host_buffer, dfu_host_buffer[0], dfu_host_buffer[1]);
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
/* Finish upload. */
|
||||
dfu_actual_length = trans_len >> 1;
|
||||
status = _req_DFU_UPLOAD(control_transfer, block, trans_len);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
printf("ERROR #%d: UPLOAD(0) 0x%x\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
/* Check state. */
|
||||
status = _req_DFU_GETSTATE(control_transfer);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
printf("ERROR #%d: transfer status 0x%x\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
UX_TEST_ASSERT(dfu_host_buffer[0] == UX_SYSTEM_DFU_STATE_DFU_IDLE);
|
||||
#endif
|
||||
|
||||
stepinfo(">>>>>>>>>>>> Test DFU DNLOAD error\n");
|
||||
status = _req_DFU_DNLOAD_IN(control_transfer, 0, 16);
|
||||
UX_TEST_CHECK_CODE(UX_TRANSFER_STALLED, status);
|
||||
#if defined(UX_DEVICE_CLASS_DFU_ERROR_GET_ENABLE)
|
||||
status = _req_DFU_GETSTATUS(control_transfer);
|
||||
UX_TEST_CHECK_SUCCESS(status);
|
||||
#endif
|
||||
status = _req_DFU_CLRSTATUS(control_transfer);
|
||||
UX_TEST_CHECK_SUCCESS(status);
|
||||
|
||||
stepinfo(">>>>>>>>>>>> Test DFU DNLOAD\n");
|
||||
for (len = 1, block = 0; len < UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH * 2; len <<= 1)
|
||||
{
|
||||
for (i = 0; i < len; i ++)
|
||||
{
|
||||
dfu_host_buffer[i] = (UCHAR)(block + i);
|
||||
dfu_device_buffer[i] = 0xFF;
|
||||
}
|
||||
trans_len = UX_MIN(len, UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH);
|
||||
|
||||
status = _req_DFU_DNLOAD(control_transfer, block, trans_len);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
printf("ERROR #%d(%ld, %ld): DNLOAD status 0x%x\n", __LINE__, block, trans_len, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
UX_TEST_ASSERT(dfu_transfer_length == trans_len);
|
||||
UX_TEST_ASSERT(dfu_block == block);
|
||||
if (ux_utility_memory_compare(dfu_host_buffer, dfu_device_buffer, trans_len) != UX_SUCCESS)
|
||||
{
|
||||
printf("ERROR #%d(%ld, %ld): data error\n", __LINE__, block, trans_len);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = _req_DFU_GETSTATUS(control_transfer);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
printf("ERROR #%d(%ld, %ld): GETSTATUS status 0x%x\n", __LINE__, block, trans_len, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
block ++;
|
||||
}
|
||||
/* Finish download. */
|
||||
status = _req_DFU_DNLOAD(control_transfer, block, 0);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
printf("ERROR #%d: DNLOAD(0) 0x%x\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
/* Manifestation. */
|
||||
status = _req_DFU_GETSTATE(control_transfer);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
printf("ERROR #%d: GETSTATE status 0x%x\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
UX_TEST_ASSERT(dfu_host_buffer[0] == UX_SLAVE_CLASS_DFU_STATUS_STATE_DFU_MANIFEST_SYNC);
|
||||
|
||||
/* Uses DFU framework after USB reset (re-connect). */
|
||||
ux_test_dcd_sim_slave_connect_framework(UX_NULL, 0);
|
||||
status = _req_DFU_GETSTATUS(control_transfer);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
printf("ERROR #%d: GETSTATUS status 0x%x\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
UX_TEST_ASSERT(dfu_host_buffer[4] == UX_SLAVE_CLASS_DFU_STATUS_STATE_DFU_MANIFEST_WAIT_RESET);
|
||||
|
||||
/* Reset */
|
||||
status = ux_test_wait_for_null((VOID **)&device);
|
||||
UX_TEST_ASSERT(status == UX_SUCCESS);
|
||||
status = ux_test_wait_for_non_null((VOID **)&device);
|
||||
UX_TEST_ASSERT(status == UX_SUCCESS);
|
||||
status = ux_host_stack_device_configuration_select(device->ux_device_first_configuration);
|
||||
UX_TEST_ASSERT(status == UX_SUCCESS);
|
||||
|
||||
status = _req_DFU_GETSTATE(control_transfer);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
printf("ERROR #%d: transfer status 0x%x\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
UX_TEST_ASSERT(dfu_host_buffer[0] == UX_SYSTEM_DFU_STATE_APP_IDLE);
|
||||
|
||||
stepinfo(">>>>>>>>>>>> All Done\n");
|
||||
|
||||
/* Finally disconnect the device. */
|
||||
ux_device_stack_disconnect();
|
||||
|
||||
/* Deinitialize the device side of usbx. */
|
||||
_ux_device_stack_uninitialize();
|
||||
|
||||
/* And finally the usbx system resources. */
|
||||
_ux_system_uninitialize();
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
|
||||
static void tx_test_thread_slave_simulation_entry(ULONG arg)
|
||||
{
|
||||
while(1)
|
||||
{
|
||||
|
||||
#if defined(UX_DEVICE_STANDALONE)
|
||||
ux_system_tasks_run();
|
||||
tx_thread_relinquish();
|
||||
#else
|
||||
|
||||
/* Sleep so ThreadX on Win32 will delete this thread. */
|
||||
tx_thread_sleep(10);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static UINT demo_device_state_change(ULONG event)
|
||||
{
|
||||
return(UX_SUCCESS);
|
||||
}
|
||||
|
||||
static VOID demo_thread_dfu_activate(VOID *dfu)
|
||||
{
|
||||
}
|
||||
|
||||
static VOID demo_thread_dfu_deactivate(VOID *dfu)
|
||||
{
|
||||
}
|
||||
|
||||
static UINT demo_thread_dfu_read(VOID *dfu, ULONG block_number, UCHAR * data_pointer, ULONG length, ULONG *actual_length)
|
||||
{
|
||||
ULONG return_length;
|
||||
|
||||
stepinfo("dfuRead %ld,%ld: %2x %2x %2x %2x ... -> %p\n", block_number, length,
|
||||
dfu_device_buffer[0], dfu_device_buffer[1], dfu_device_buffer[2], dfu_device_buffer[3],
|
||||
data_pointer);
|
||||
dfu_block = block_number;
|
||||
dfu_transfer_length = length;
|
||||
|
||||
return_length = UX_MIN(length, sizeof(dfu_device_buffer));
|
||||
return_length = UX_MIN(return_length, dfu_actual_length);
|
||||
|
||||
ux_utility_memory_copy(data_pointer, dfu_device_buffer, return_length);
|
||||
|
||||
/* Here is where the data block is read from the firmware. */
|
||||
/* Some code needs to be inserted specifically for a target platform. */
|
||||
*actual_length = return_length;
|
||||
return(UX_SUCCESS);
|
||||
}
|
||||
|
||||
static UINT demo_thread_dfu_write(VOID *dfu, ULONG block_number, UCHAR * data_pointer, ULONG length, ULONG *media_status)
|
||||
{
|
||||
stepinfo("dfuWrite %ld,%ld\n", block_number, length);
|
||||
dfu_block = block_number;
|
||||
dfu_transfer_length = length;
|
||||
ux_utility_memory_copy(dfu_device_buffer, data_pointer, UX_MIN(length, sizeof(dfu_device_buffer)));
|
||||
|
||||
/* Here is where the data block is coming to be written to the firmware. */
|
||||
/* Some code needs to be inserted specifically for a target platform. */
|
||||
/* Return media status ok. */
|
||||
*media_status = UX_SLAVE_CLASS_DFU_MEDIA_STATUS_OK ;
|
||||
return(UX_SUCCESS);
|
||||
}
|
||||
|
||||
static UINT demo_thread_dfu_get_status(VOID *dfu, ULONG *media_status)
|
||||
{
|
||||
|
||||
/* Return media status ok. */
|
||||
*media_status = UX_SLAVE_CLASS_DFU_MEDIA_STATUS_OK ;
|
||||
|
||||
return(UX_SUCCESS);
|
||||
}
|
||||
|
||||
static UINT demo_thread_dfu_notify(VOID *dfu, ULONG notification)
|
||||
{
|
||||
stepinfo("dfuNotify 0x%lx\n", notification);
|
||||
switch (notification)
|
||||
{
|
||||
|
||||
|
||||
case UX_SLAVE_CLASS_DFU_NOTIFICATION_BEGIN_DOWNLOAD :
|
||||
|
||||
/* Begin of Download. */
|
||||
break;
|
||||
|
||||
case UX_SLAVE_CLASS_DFU_NOTIFICATION_END_DOWNLOAD :
|
||||
|
||||
/* Completion of Download. */
|
||||
break;
|
||||
|
||||
case UX_SLAVE_CLASS_DFU_NOTIFICATION_ABORT_DOWNLOAD :
|
||||
|
||||
/* Download was aborted. */
|
||||
break;
|
||||
|
||||
case UX_SLAVE_CLASS_DFU_NOTIFICATION_BEGIN_UPLOAD :
|
||||
|
||||
/* Begin of UPLOAD. */
|
||||
break;
|
||||
|
||||
case UX_SLAVE_CLASS_DFU_NOTIFICATION_END_UPLOAD :
|
||||
|
||||
/* Completion of UPLOAD. */
|
||||
break;
|
||||
|
||||
case UX_SLAVE_CLASS_DFU_NOTIFICATION_ABORT_UPLOAD :
|
||||
|
||||
/* Download was aborted. */
|
||||
break;
|
||||
|
||||
default :
|
||||
|
||||
/* Bad notification signal. Should never get here. */
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return(UX_SUCCESS);
|
||||
}
|
||||
|
||||
static UINT demo_thread_dfu_custom_request(VOID *dfu, UX_SLAVE_TRANSFER *transfer)
|
||||
{
|
||||
UCHAR *setup;
|
||||
UCHAR *buffer;
|
||||
|
||||
/* Check state and request to insert custom operation, before the standard
|
||||
handling process.
|
||||
If no standard handling process is needed, return UX_SUCCESS.
|
||||
*/
|
||||
|
||||
/* E.g., accept DNLOAD command with wLength 0 in dfuIDLE. */
|
||||
if (ux_device_class_dfu_state_get((UX_SLAVE_CLASS_DFU *)dfu) == UX_SLAVE_CLASS_DFU_STATUS_STATE_DFU_IDLE)
|
||||
{
|
||||
setup = transfer -> ux_slave_transfer_request_setup;
|
||||
buffer = transfer -> ux_slave_transfer_request_data_pointer;
|
||||
|
||||
if (setup[UX_SETUP_REQUEST] == UX_SLAVE_CLASS_DFU_COMMAND_DOWNLOAD &&
|
||||
setup[UX_SETUP_LENGTH] == 0 &&
|
||||
setup[UX_SETUP_LENGTH + 1] == 0)
|
||||
{
|
||||
|
||||
/* Accept the case (by default it's stalled). */
|
||||
stepinfo("dfuIDLE - accept dfuDNLOAD & wLength 0\n");
|
||||
|
||||
/* Fill the status data payload. First with status. */
|
||||
*buffer = UX_SLAVE_CLASS_DFU_STATUS_OK;
|
||||
|
||||
/* Poll time out value is set to 500ms. */
|
||||
*(buffer + UX_SLAVE_CLASS_DFU_GET_STATUS_POLL_TIMEOUT) = UX_DW0(500);
|
||||
*(buffer + UX_SLAVE_CLASS_DFU_GET_STATUS_POLL_TIMEOUT + 1) = UX_DW1(500);
|
||||
*(buffer + UX_SLAVE_CLASS_DFU_GET_STATUS_POLL_TIMEOUT + 2) = UX_DW2(500);
|
||||
|
||||
/* Next state: still dfuIDLE. */
|
||||
*(buffer + UX_SLAVE_CLASS_DFU_GET_STATUS_STATE) = (UCHAR) UX_SYSTEM_DFU_STATE_DFU_IDLE;
|
||||
|
||||
/* String index set to 0. */
|
||||
*(buffer + UX_SLAVE_CLASS_DFU_GET_STATUS_STRING) = 0;
|
||||
|
||||
/* We have a request to obtain the status of the DFU instance. */
|
||||
_ux_device_stack_transfer_request(transfer, UX_SLAVE_CLASS_DFU_GET_STATUS_LENGTH, UX_SLAVE_CLASS_DFU_GET_STATUS_LENGTH);
|
||||
|
||||
/* Inform stack it's taken. */
|
||||
return(UX_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
/* No custom request. */
|
||||
return(UX_ERROR);
|
||||
}
|
651
test/regression/usbx_dpump_basic_test.c
Normal file
651
test/regression/usbx_dpump_basic_test.c
Normal file
@ -0,0 +1,651 @@
|
||||
/* This test is designed to test the simple dpump host/device class operation. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
#include "ux_api.h"
|
||||
#include "ux_system.h"
|
||||
#include "ux_utility.h"
|
||||
#include "ux_host_class_dpump.h"
|
||||
#include "ux_device_class_dpump.h"
|
||||
|
||||
|
||||
/* Define USBX demo constants. */
|
||||
|
||||
#define UX_DEMO_STACK_SIZE 4096
|
||||
#define UX_DEMO_BUFFER_SIZE 2048
|
||||
#define UX_DEMO_RUN 1
|
||||
#define UX_DEMO_MEMORY_SIZE (64*1024)
|
||||
|
||||
|
||||
/* Define the counters used in the demo application... */
|
||||
|
||||
static ULONG thread_0_counter;
|
||||
static ULONG thread_1_counter;
|
||||
static ULONG error_counter;
|
||||
|
||||
|
||||
/* Define USBX demo global variables. */
|
||||
|
||||
static unsigned char host_out_buffer[UX_HOST_CLASS_DPUMP_PACKET_SIZE];
|
||||
static unsigned char host_in_buffer[UX_HOST_CLASS_DPUMP_PACKET_SIZE];
|
||||
static unsigned char slave_buffer[UX_HOST_CLASS_DPUMP_PACKET_SIZE];
|
||||
|
||||
static UX_HOST_CLASS *class_driver;
|
||||
static UX_HOST_CLASS_DPUMP *dpump;
|
||||
static UX_SLAVE_CLASS_DPUMP *dpump_slave;
|
||||
|
||||
static UINT expected_error;
|
||||
|
||||
#define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED 50
|
||||
static UCHAR device_framework_full_speed[] = {
|
||||
|
||||
/* Device descriptor */
|
||||
0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08,
|
||||
0xec, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x01,
|
||||
|
||||
/* Configuration descriptor */
|
||||
0x09, 0x02, 0x20, 0x00, 0x01, 0x01, 0x00, 0xc0,
|
||||
0x32,
|
||||
|
||||
/* Interface descriptor */
|
||||
0x09, 0x04, 0x00, 0x00, 0x02, 0x99, 0x99, 0x99,
|
||||
0x00,
|
||||
|
||||
/* Endpoint descriptor (Bulk Out) */
|
||||
0x07, 0x05, 0x01, 0x02, 0x40, 0x00, 0x00,
|
||||
|
||||
#ifdef UX_DEVICE_BIDIRECTIONAL_ENDPOINT_SUPPORT
|
||||
/* Endpoint descriptor (Bulk In) */
|
||||
0x07, 0x05, 0x81, 0x02, 0x40, 0x00, 0x00
|
||||
#else
|
||||
/* Endpoint descriptor (Bulk In) */
|
||||
0x07, 0x05, 0x82, 0x02, 0x40, 0x00, 0x00
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
#define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED 60
|
||||
static UCHAR device_framework_high_speed[] = {
|
||||
|
||||
/* Device descriptor */
|
||||
0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
|
||||
0x0a, 0x07, 0x25, 0x40, 0x01, 0x00, 0x01, 0x02,
|
||||
0x03, 0x01,
|
||||
|
||||
/* Device qualifier descriptor */
|
||||
0x0a, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
|
||||
0x01, 0x00,
|
||||
|
||||
/* Configuration descriptor */
|
||||
0x09, 0x02, 0x20, 0x00, 0x01, 0x01, 0x00, 0xc0,
|
||||
0x32,
|
||||
|
||||
/* Interface descriptor */
|
||||
0x09, 0x04, 0x00, 0x00, 0x02, 0x99, 0x99, 0x99,
|
||||
0x00,
|
||||
|
||||
/* Endpoint descriptor (Bulk Out) */
|
||||
0x07, 0x05, 0x01, 0x02, 0x00, 0x02, 0x00,
|
||||
|
||||
#ifdef UX_DEVICE_BIDIRECTIONAL_ENDPOINT_SUPPORT
|
||||
/* Endpoint descriptor (Bulk In) */
|
||||
0x07, 0x05, 0x81, 0x02, 0x40, 0x00, 0x00
|
||||
#else
|
||||
/* Endpoint descriptor (Bulk In) */
|
||||
0x07, 0x05, 0x82, 0x02, 0x00, 0x02, 0x00
|
||||
#endif
|
||||
};
|
||||
|
||||
/* String Device Framework :
|
||||
Byte 0 and 1 : Word containing the language ID : 0x0904 for US
|
||||
Byte 2 : Byte containing the index of the descriptor
|
||||
Byte 3 : Byte containing the length of the descriptor string
|
||||
*/
|
||||
|
||||
#define STRING_FRAMEWORK_LENGTH 38
|
||||
static UCHAR string_framework[] = {
|
||||
|
||||
/* Manufacturer string descriptor : Index 1 */
|
||||
0x09, 0x04, 0x01, 0x0c,
|
||||
0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
|
||||
0x6f, 0x67, 0x69, 0x63,
|
||||
|
||||
/* Product string descriptor : Index 2 */
|
||||
0x09, 0x04, 0x02, 0x0c,
|
||||
0x44, 0x61, 0x74, 0x61, 0x50, 0x75, 0x6d, 0x70,
|
||||
0x44, 0x65, 0x6d, 0x6f,
|
||||
|
||||
/* Serial Number string descriptor : Index 3 */
|
||||
0x09, 0x04, 0x03, 0x04,
|
||||
0x30, 0x30, 0x30, 0x31
|
||||
};
|
||||
|
||||
|
||||
/* Multiple languages are supported on the device, to add
|
||||
a language besides English, the unicode language code must
|
||||
be appended to the language_id_framework array and the length
|
||||
adjusted accordingly. */
|
||||
#define LANGUAGE_ID_FRAMEWORK_LENGTH 2
|
||||
static UCHAR language_id_framework[] = {
|
||||
|
||||
/* English. */
|
||||
0x09, 0x04
|
||||
};
|
||||
|
||||
|
||||
/* Define prototypes for external Host Controller's (HCDs), classes and clients. */
|
||||
|
||||
static VOID tx_demo_instance_activate(VOID *dpump_instance);
|
||||
static VOID tx_demo_instance_deactivate(VOID *dpump_instance);
|
||||
|
||||
#if defined(UX_HOST_STANDALONE)
|
||||
static UINT tx_demo_host_change_function(ULONG e, UX_HOST_CLASS *c, VOID *p);
|
||||
#else
|
||||
#define tx_demo_host_change_function UX_NULL
|
||||
#endif
|
||||
|
||||
UINT _ux_host_class_dpump_entry(UX_HOST_CLASS_COMMAND *command);
|
||||
UINT ux_hcd_sim_initialize(UX_HCD *hcd);
|
||||
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_read (UX_HOST_CLASS_DPUMP *dpump, UCHAR *data_pointer,
|
||||
ULONG requested_length, ULONG *actual_length);
|
||||
|
||||
static TX_THREAD tx_demo_thread_host_simulation;
|
||||
static TX_THREAD tx_demo_thread_slave_simulation;
|
||||
static void tx_demo_thread_host_simulation_entry(ULONG);
|
||||
static void tx_demo_thread_slave_simulation_entry(ULONG);
|
||||
|
||||
|
||||
/* Define the ISR dispatch. */
|
||||
|
||||
extern VOID (*test_isr_dispatch)(void);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
/* Define the ISR dispatch routine. */
|
||||
|
||||
static void test_isr(void)
|
||||
{
|
||||
|
||||
/* For further expansion of interrupt-level testing. */
|
||||
}
|
||||
|
||||
|
||||
static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
|
||||
{
|
||||
if (expected_error == 0 || error_code != expected_error)
|
||||
{
|
||||
/* Failed test. */
|
||||
printf("Error on line %d, system_level: %d, system_context: %d, error code: %x\n", __LINE__, system_level, system_context, error_code);
|
||||
// test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_dpump_basic_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *stack_pointer;
|
||||
CHAR *memory_pointer;
|
||||
UX_SLAVE_CLASS_DPUMP_PARAMETER parameter;
|
||||
|
||||
|
||||
/* Initialize the free memory pointer. */
|
||||
stack_pointer = (CHAR *) first_unused_memory;
|
||||
memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
|
||||
|
||||
/* Initialize USBX Memory. */
|
||||
status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL, 0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running DPUMP Basic Functionality Test.............................. ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the error callback. */
|
||||
_ux_utility_error_callback_register(error_callback);
|
||||
|
||||
/* The code below is required for installing the host portion of USBX. */
|
||||
status = ux_host_stack_initialize(tx_demo_host_change_function);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running DPUMP Basic Functionality Test.............................. ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register all the host class drivers for this USBX implementation. */
|
||||
status = ux_host_stack_class_register(_ux_system_host_class_dpump_name, ux_host_class_dpump_entry);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running DPUMP Basic Functionality Test.............................. ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* The code below is required for installing the device portion of USBX */
|
||||
status = ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
|
||||
device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
|
||||
string_framework, STRING_FRAMEWORK_LENGTH,
|
||||
language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH, UX_NULL);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running DPUMP Basic Functionality Test.............................. ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Set the parameters for callback when insertion/extraction of a Data Pump device. */
|
||||
parameter.ux_slave_class_dpump_instance_activate = tx_demo_instance_activate;
|
||||
parameter.ux_slave_class_dpump_instance_deactivate = tx_demo_instance_deactivate;
|
||||
|
||||
/* Initialize the device dpump class. The class is connected with interface 0 */
|
||||
status = ux_device_stack_class_register(_ux_system_slave_class_dpump_name, _ux_device_class_dpump_entry,
|
||||
1, 0, ¶meter);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running DPUMP Basic Functionality Test.............................. ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Initialize the simulated device controller. */
|
||||
status = _ux_dcd_sim_slave_initialize();
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running DPUMP Basic Functionality Test.............................. ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register all the USB host controllers available in this system */
|
||||
status = ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, ux_hcd_sim_host_initialize,0,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running DPUMP Basic Functionality Test.............................. ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the main host simulation thread. */
|
||||
status = tx_thread_create(&tx_demo_thread_host_simulation, "tx demo host simulation", tx_demo_thread_host_simulation_entry, 0,
|
||||
stack_pointer, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running DPUMP Basic Functionality Test.............................. ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the main demo thread. */
|
||||
status = tx_thread_create(&tx_demo_thread_slave_simulation, "tx demo slave simulation", tx_demo_thread_slave_simulation_entry, 0,
|
||||
stack_pointer + UX_DEMO_STACK_SIZE, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running DPUMP Basic Functionality Test.............................. ERROR #9\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void tx_demo_thread_host_simulation_entry(ULONG arg)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
ULONG actual_length;
|
||||
UCHAR current_char;
|
||||
UX_HOST_CLASS *class;
|
||||
UINT i;
|
||||
#if 0
|
||||
UX_ENDPOINT *endpoint;
|
||||
#endif
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running DPUMP Basic Functionality Test.............................. ");
|
||||
|
||||
/* Find the class container with unregistered name. */
|
||||
status = ux_host_stack_class_get(_ux_system_host_class_hid_name, &class);
|
||||
|
||||
/* Should return error. */
|
||||
if (status != UX_HOST_CLASS_UNKNOWN)
|
||||
{
|
||||
|
||||
/* DPUMP basic test error. */
|
||||
printf("ERROR #10\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Find the main data pump container. */
|
||||
status = ux_host_stack_class_get(_ux_system_host_class_dpump_name, &class);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
/* DPUMP basic test error. */
|
||||
printf("ERROR #10\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* We get the first instance of the data pump device. */
|
||||
do
|
||||
{
|
||||
|
||||
status = ux_host_stack_class_instance_get(class, 0, (VOID **) &dpump);
|
||||
|
||||
#if defined(UX_HOST_STANDALONE)
|
||||
ux_system_tasks_run();
|
||||
#endif
|
||||
tx_thread_relinquish();
|
||||
|
||||
} while (status != UX_SUCCESS);
|
||||
|
||||
/* We still need to wait for the data pump status to be live. */
|
||||
while (dpump -> ux_host_class_dpump_state != UX_HOST_CLASS_INSTANCE_LIVE)
|
||||
{
|
||||
|
||||
#if defined(UX_HOST_STANDALONE)
|
||||
ux_system_tasks_run();
|
||||
#endif
|
||||
tx_thread_relinquish();
|
||||
|
||||
}
|
||||
|
||||
/* At this point, the data pump class has been found. Now use the
|
||||
data pump to send and receive data between the host and device. */
|
||||
|
||||
/* We start with a 'A' in buffer. */
|
||||
current_char = 'A';
|
||||
|
||||
/* Perform this test sequence 100 times. */
|
||||
for (i = 0; i < 100; i++)
|
||||
{
|
||||
|
||||
/* Increment thread counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
/* Initialize the write buffer. */
|
||||
_ux_utility_memory_set(host_out_buffer, current_char, UX_HOST_CLASS_DPUMP_PACKET_SIZE);
|
||||
|
||||
/* Increment the character in buffer. */
|
||||
current_char++;
|
||||
|
||||
/* Check for upper alphabet limit. */
|
||||
if (current_char > 'Z')
|
||||
current_char = 'A';
|
||||
|
||||
/* Write to the host Data Pump Bulk out endpoint. */
|
||||
status = _ux_host_class_dpump_write (dpump, host_out_buffer, UX_HOST_CLASS_DPUMP_PACKET_SIZE, &actual_length);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
/* DPUMP basic test error. */
|
||||
printf("ERROR #%d: 0x%x\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Verify that the status and the amount of data is correct. */
|
||||
if ((status != UX_SUCCESS) || actual_length != UX_HOST_CLASS_DPUMP_PACKET_SIZE)
|
||||
{
|
||||
|
||||
/* DPUMP basic test error. */
|
||||
printf("ERROR #12\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#if defined(UX_HOST_STANDALONE)
|
||||
/* Relinquish to other thread. */
|
||||
tx_thread_relinquish();
|
||||
#endif
|
||||
|
||||
/* Read to the Data Pump Bulk out endpoint. */
|
||||
status = _ux_host_class_dpump_read (dpump, host_in_buffer, UX_HOST_CLASS_DPUMP_PACKET_SIZE, &actual_length);
|
||||
|
||||
/* Verify that the status and the amount of data is correct. */
|
||||
if ((status != UX_SUCCESS) || actual_length != UX_HOST_CLASS_DPUMP_PACKET_SIZE)
|
||||
{
|
||||
|
||||
/* DPUMP basic test error. */
|
||||
printf("ERROR #13\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Relinquish to other thread. */
|
||||
tx_thread_relinquish();
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Test ux_host_stack_endpoint_reset with invalid endpoint number. */
|
||||
endpoint = dpump -> ux_host_class_dpump_interface -> ux_interface_first_endpoint;
|
||||
endpoint -> ux_endpoint_descriptor.bEndpointAddress = 0xf;
|
||||
expected_error = UX_TRANSFER_STALLED;
|
||||
status = _ux_host_stack_endpoint_reset(endpoint);
|
||||
|
||||
/* Check for error. */
|
||||
if (status == UX_SUCCESS)
|
||||
{
|
||||
|
||||
/* DPUMP basic test error. */
|
||||
printf("ERROR #14\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
expected_error = 0;
|
||||
|
||||
/* Sleep for a tick to make sure everything is complete. */
|
||||
tx_thread_sleep(1);
|
||||
|
||||
/* Check for errors from other threads. */
|
||||
if (error_counter)
|
||||
{
|
||||
|
||||
/* DPUMP error. */
|
||||
printf("ERROR #%d: total %ld errors\n", __LINE__, error_counter);
|
||||
test_control_return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void tx_demo_thread_slave_simulation_entry(ULONG arg)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
ULONG actual_length;
|
||||
#if defined(UX_DEVICE_STANDALONE)
|
||||
#define DPUMP_DEVICE_STATE_READ UX_STATE_STEP
|
||||
#define DPUMP_DEVICE_STATE_WRITE UX_STATE_STEP + 1
|
||||
UINT dpump_device_state = UX_STATE_RESET;
|
||||
#endif
|
||||
|
||||
|
||||
while(1)
|
||||
{
|
||||
#if defined(UX_DEVICE_STANDALONE)
|
||||
|
||||
/* Run device tasks. */
|
||||
ux_system_tasks_run();
|
||||
|
||||
/* DPUMP echo state machine. */
|
||||
switch(dpump_device_state)
|
||||
{
|
||||
case UX_STATE_RESET:
|
||||
if (dpump_slave != UX_NULL)
|
||||
|
||||
/* Start reading. */
|
||||
dpump_device_state = DPUMP_DEVICE_STATE_READ;
|
||||
break;
|
||||
|
||||
case DPUMP_DEVICE_STATE_READ:
|
||||
|
||||
/* Read from the device data pump. */
|
||||
if (dpump_slave == UX_NULL)
|
||||
{
|
||||
dpump_device_state = UX_STATE_RESET;
|
||||
break;
|
||||
}
|
||||
status = ux_device_class_dpump_read_run(dpump_slave, slave_buffer, UX_HOST_CLASS_DPUMP_PACKET_SIZE, &actual_length);
|
||||
|
||||
if (status < UX_STATE_NEXT)
|
||||
{
|
||||
printf("ERROR #%d: read status 0x%x\n", __LINE__, status);
|
||||
error_counter ++;
|
||||
return;
|
||||
}
|
||||
|
||||
if (status == UX_STATE_NEXT)
|
||||
{
|
||||
if (actual_length != UX_HOST_CLASS_DPUMP_PACKET_SIZE)
|
||||
{
|
||||
printf("ERROR #%d: read length %ld\n", __LINE__, actual_length);
|
||||
error_counter ++;
|
||||
return;
|
||||
}
|
||||
|
||||
dpump_device_state = DPUMP_DEVICE_STATE_WRITE;
|
||||
}
|
||||
break;
|
||||
|
||||
case DPUMP_DEVICE_STATE_WRITE:
|
||||
|
||||
/* Now write to the device data pump. */
|
||||
if (dpump_slave == UX_NULL)
|
||||
{
|
||||
dpump_device_state = UX_STATE_RESET;
|
||||
break;
|
||||
}
|
||||
status = ux_device_class_dpump_write_run(dpump_slave, slave_buffer, UX_HOST_CLASS_DPUMP_PACKET_SIZE, &actual_length);
|
||||
|
||||
if (status < UX_STATE_NEXT)
|
||||
{
|
||||
printf("ERROR #%d: write status 0x%x\n", __LINE__, status);
|
||||
error_counter ++;
|
||||
return;
|
||||
}
|
||||
|
||||
if (status == UX_STATE_NEXT)
|
||||
dpump_device_state = DPUMP_DEVICE_STATE_READ;
|
||||
break;
|
||||
|
||||
default:
|
||||
dpump_device_state = UX_STATE_RESET;
|
||||
}
|
||||
|
||||
/* Increment thread counter. */
|
||||
thread_1_counter++;
|
||||
|
||||
/* Relinquish to other thread. */
|
||||
tx_thread_relinquish();
|
||||
|
||||
#else
|
||||
/* Ensure the dpump class on the device is still alive. */
|
||||
while (dpump_slave != UX_NULL)
|
||||
{
|
||||
|
||||
/* Increment thread counter. */
|
||||
thread_1_counter++;
|
||||
|
||||
/* Read from the device data pump. */
|
||||
status = _ux_device_class_dpump_read(dpump_slave, slave_buffer, UX_HOST_CLASS_DPUMP_PACKET_SIZE, &actual_length);
|
||||
|
||||
/* Verify that the status and the amount of data is correct. */
|
||||
if ((status != UX_SUCCESS) || actual_length != UX_HOST_CLASS_DPUMP_PACKET_SIZE)
|
||||
{
|
||||
printf("ERROR #%d.%ld: read status 0x%x, length %ld\n", __LINE__, thread_1_counter, status, actual_length);
|
||||
|
||||
/* Increment error counter. */
|
||||
error_counter++;
|
||||
|
||||
/* Return from thread. */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Now write to the device data pump. */
|
||||
status = _ux_device_class_dpump_write(dpump_slave, slave_buffer, UX_HOST_CLASS_DPUMP_PACKET_SIZE, &actual_length);
|
||||
|
||||
/* Verify that the status and the amount of data is correct. */
|
||||
if ((status != UX_SUCCESS) || actual_length != UX_HOST_CLASS_DPUMP_PACKET_SIZE)
|
||||
{
|
||||
printf("ERROR #%d.%ld: write status 0x%x, length %ld\n", __LINE__, thread_1_counter, status, actual_length);
|
||||
|
||||
/* Increment error counter. */
|
||||
error_counter++;
|
||||
|
||||
/* Return from thread. */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Relinquish to other thread. */
|
||||
tx_thread_relinquish();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static VOID tx_demo_instance_activate(VOID *dpump_instance)
|
||||
{
|
||||
|
||||
/* Save the DPUMP instance. */
|
||||
dpump_slave = (UX_SLAVE_CLASS_DPUMP *) dpump_instance;
|
||||
}
|
||||
|
||||
static VOID tx_demo_instance_deactivate(VOID *dpump_instance)
|
||||
{
|
||||
|
||||
/* Reset the DPUMP instance. */
|
||||
dpump_slave = UX_NULL;
|
||||
}
|
||||
|
||||
#if defined(UX_HOST_STANDALONE)
|
||||
static UINT tx_demo_host_change_function(ULONG e, UX_HOST_CLASS *c, VOID *p)
|
||||
{
|
||||
if (e == UX_STANDALONE_WAIT_BACKGROUND_TASK)
|
||||
{
|
||||
tx_thread_relinquish();
|
||||
}
|
||||
}
|
||||
#endif
|
417
test/regression/usbx_hid_interrupt_endpoint_get_report_test.c
Normal file
417
test/regression/usbx_hid_interrupt_endpoint_get_report_test.c
Normal file
@ -0,0 +1,417 @@
|
||||
/* This file tests retrieving an input report via the interrupt endpoint. */
|
||||
|
||||
#include "usbx_test_common_hid.h"
|
||||
#include "ux_host_class_hid_keyboard.h"
|
||||
|
||||
|
||||
#define DUMMY_USBX_MEMORY_SIZE (64*1024)
|
||||
static UCHAR dummy_usbx_memory[DUMMY_USBX_MEMORY_SIZE];
|
||||
|
||||
static UCHAR buffer[1024];
|
||||
|
||||
static UCHAR hid_report_descriptor[] = {
|
||||
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||
0x09, 0x06, // USAGE (Keyboard)
|
||||
0xa1, 0x01, // COLLECTION (Application)
|
||||
0x05, 0x07, // USAGE_PAGE (Keyboard)
|
||||
0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)
|
||||
0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x25, 0x01, // LOGICAL_MAXIMUM (1)
|
||||
0x75, 0x01, // REPORT_SIZE (1)
|
||||
0x95, 0x08, // REPORT_COUNT (8)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x81, 0x03, // INPUT (Cnst,Var,Abs)
|
||||
0x95, 0x05, // REPORT_COUNT (5)
|
||||
0x75, 0x01, // REPORT_SIZE (1)
|
||||
0x05, 0x08, // USAGE_PAGE (LEDs)
|
||||
0x19, 0x01, // USAGE_MINIMUM (Num Lock)
|
||||
0x29, 0x05, // USAGE_MAXIMUM (Kana)
|
||||
0x91, 0x02, // OUTPUT (Data,Var,Abs)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x75, 0x03, // REPORT_SIZE (3)
|
||||
0x91, 0x03, // OUTPUT (Cnst,Var,Abs)
|
||||
0x95, 0x06, // REPORT_COUNT (6)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x25, 0x65, // LOGICAL_MAXIMUM (101)
|
||||
0x05, 0x07, // USAGE_PAGE (Keyboard)
|
||||
0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
|
||||
0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)
|
||||
0x81, 0x00, // INPUT (Data,Ary,Abs)
|
||||
0xc0 // END_COLLECTION
|
||||
};
|
||||
#define HID_REPORT_LENGTH sizeof(hid_report_descriptor)/sizeof(hid_report_descriptor[0])
|
||||
|
||||
|
||||
#define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED 52
|
||||
static UCHAR device_framework_full_speed[DEVICE_FRAMEWORK_LENGTH_FULL_SPEED] = {
|
||||
|
||||
/* Device descriptor */
|
||||
0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08,
|
||||
0x81, 0x0A, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x01,
|
||||
|
||||
/* Configuration descriptor */
|
||||
0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x00, 0xc0,
|
||||
0x32,
|
||||
|
||||
/* Interface descriptor */
|
||||
0x09, 0x04, 0x02, 0x00, 0x01, 0x03, 0x00, 0x00,
|
||||
0x00,
|
||||
|
||||
/* HID descriptor */
|
||||
0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(HID_REPORT_LENGTH),
|
||||
MSB(HID_REPORT_LENGTH),
|
||||
|
||||
/* Endpoint descriptor (Interrupt) */
|
||||
0x07, 0x05, 0x82, 0x03, 0x08, 0x00, 0x08
|
||||
|
||||
};
|
||||
|
||||
|
||||
#define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED 62
|
||||
static UCHAR device_framework_high_speed[DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED] = {
|
||||
|
||||
/* Device descriptor */
|
||||
0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
|
||||
0x0a, 0x07, 0x25, 0x40, 0x01, 0x00, 0x01, 0x02,
|
||||
0x03, 0x01,
|
||||
|
||||
/* Device qualifier descriptor */
|
||||
0x0a, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
|
||||
0x01, 0x00,
|
||||
|
||||
/* Configuration descriptor */
|
||||
0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x00, 0xc0,
|
||||
0x32,
|
||||
|
||||
/* Interface descriptor */
|
||||
0x09, 0x04, 0x02, 0x00, 0x01, 0x03, 0x00, 0x00,
|
||||
0x00,
|
||||
|
||||
/* HID descriptor */
|
||||
0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(HID_REPORT_LENGTH),
|
||||
MSB(HID_REPORT_LENGTH),
|
||||
|
||||
/* Endpoint descriptor (Interrupt) */
|
||||
0x07, 0x05, 0x82, 0x03, 0x08, 0x00, 0x08
|
||||
|
||||
};
|
||||
|
||||
|
||||
/* String Device Framework :
|
||||
Byte 0 and 1 : Word containing the language ID : 0x0904 for US
|
||||
Byte 2 : Byte containing the index of the descriptor
|
||||
Byte 3 : Byte containing the length of the descriptor string
|
||||
*/
|
||||
|
||||
#define STRING_FRAMEWORK_LENGTH 40
|
||||
static UCHAR string_framework[] = {
|
||||
|
||||
/* Manufacturer string descriptor : Index 1 */
|
||||
0x09, 0x04, 0x01, 0x0c,
|
||||
0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
|
||||
0x6f, 0x67, 0x69, 0x63,
|
||||
|
||||
/* Product string descriptor : Index 2 */
|
||||
0x09, 0x04, 0x02, 0x0c,
|
||||
0x55, 0x53, 0x42, 0x20, 0x4b, 0x65, 0x79, 0x62,
|
||||
0x6f, 0x61, 0x72, 0x64,
|
||||
|
||||
/* Serial Number string descriptor : Index 3 */
|
||||
0x09, 0x04, 0x03, 0x04,
|
||||
0x30, 0x30, 0x30, 0x31
|
||||
};
|
||||
|
||||
|
||||
/* Multiple languages are supported on the device, to add
|
||||
a language besides english, the unicode language code must
|
||||
be appended to the language_id_framework array and the length
|
||||
adjusted accordingly. */
|
||||
#define LANGUAGE_ID_FRAMEWORK_LENGTH 2
|
||||
static UCHAR language_id_framework[] = {
|
||||
|
||||
/* English. */
|
||||
0x09, 0x04
|
||||
};
|
||||
|
||||
|
||||
UINT _ux_hcd_sim_host_entry(UX_HCD *hcd, UINT function, VOID *parameter);
|
||||
|
||||
|
||||
static UINT ux_system_host_change_function(ULONG a, UX_HOST_CLASS *b, VOID *c)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
|
||||
{
|
||||
|
||||
/* @BUG_FIX_PENDING: ux_dcd_sim_slave_function.c doesn't support transfer aborts, which happen during device unregistration of a class. */
|
||||
if (error_code != UX_FUNCTION_NOT_SUPPORTED)
|
||||
{
|
||||
|
||||
/* Failed test. */
|
||||
printf("Error on line %d, system_level: %d, system_context: %d, error code: %d\n", __LINE__, system_level, system_context, error_code);
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_hid_interrupt_endpoint_get_report_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR * stack_pointer;
|
||||
CHAR * memory_pointer;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running HID Interrupt Endpoint Get Report Test...................... ");
|
||||
|
||||
/* Initialize the free memory pointer */
|
||||
stack_pointer = (CHAR *) usbx_memory;
|
||||
memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
|
||||
|
||||
/* Initialize USBX. Memory */
|
||||
status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the error callback. */
|
||||
_ux_utility_error_callback_register(error_callback);
|
||||
|
||||
/* The code below is required for installing the host portion of USBX */
|
||||
status = ux_host_stack_initialize(ux_system_host_change_function);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = ux_host_stack_class_register(_ux_system_host_class_hid_name, ux_host_class_hid_entry);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the HID client(s). */
|
||||
status = ux_host_class_hid_client_register(_ux_system_host_class_hid_client_keyboard_name, ux_host_class_hid_keyboard_entry);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* The code below is required for installing the device portion of USBX. No call back for
|
||||
device status change in this example. */
|
||||
status = ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
|
||||
device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
|
||||
string_framework, STRING_FRAMEWORK_LENGTH,
|
||||
language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Initialize the hid class parameters. */
|
||||
hid_parameter.ux_device_class_hid_parameter_report_address = hid_report_descriptor;
|
||||
hid_parameter.ux_device_class_hid_parameter_report_length = HID_REPORT_LENGTH;
|
||||
hid_parameter.ux_device_class_hid_parameter_callback = demo_thread_hid_callback;
|
||||
|
||||
/* Initilize the device hid class. The class is connected with interface 2 */
|
||||
status = ux_device_stack_class_register(_ux_system_slave_class_hid_name, ux_device_class_hid_entry,
|
||||
1,2, (VOID *)&hid_parameter);
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Initialize the simulated device controller. */
|
||||
status = _ux_dcd_sim_slave_initialize();
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register all the USB host controllers available in this system */
|
||||
status = ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, ux_hcd_sim_host_initialize,0,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the main host simulation thread. */
|
||||
status = tx_thread_create(&tx_demo_thread_host_simulation, "tx demo host simulation", tx_demo_thread_host_simulation_entry, 0,
|
||||
stack_pointer, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
static void tx_demo_thread_host_simulation_entry(ULONG arg)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
UX_ENDPOINT *interrupt_endpoint;
|
||||
UX_TRANSFER *interrupt_endpoint_transfer_request;
|
||||
ULONG report_id;
|
||||
UX_SLAVE_CLASS_HID_EVENT hid_event;
|
||||
UX_SLAVE_CLASS_HID *slave_hid;
|
||||
UINT max_get_report_attempts = 5;
|
||||
|
||||
|
||||
/* Find the HID class */
|
||||
status = demo_class_hid_get();
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Set report id. */
|
||||
report_id = 0;
|
||||
|
||||
/* Get the slave hid. */
|
||||
slave_hid = _ux_system_slave -> ux_system_slave_device.ux_slave_device_first_interface -> ux_slave_interface_class_instance;
|
||||
|
||||
/* Get the endpoint and transfer request. */
|
||||
interrupt_endpoint = hid -> ux_host_class_hid_interrupt_endpoint;
|
||||
interrupt_endpoint_transfer_request = &interrupt_endpoint -> ux_endpoint_transfer_request;
|
||||
|
||||
/* Kill the periodic thread so it doesn't get the report before us. */
|
||||
status = _ux_host_class_hid_periodic_report_stop(hid);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Add an event for the host to get. */
|
||||
|
||||
/* Set the length. */
|
||||
hid_event.ux_device_class_hid_event_length = 8;
|
||||
|
||||
/* First byte is a modifier byte. */
|
||||
hid_event.ux_device_class_hid_event_buffer[0] = 0x01;
|
||||
|
||||
/* Second byte is reserved. */
|
||||
hid_event.ux_device_class_hid_event_buffer[1] = 0x02;
|
||||
|
||||
/* The 6 next bytes are keys. */
|
||||
hid_event.ux_device_class_hid_event_buffer[2] = 0x03;
|
||||
hid_event.ux_device_class_hid_event_buffer[3] = 0x04;
|
||||
hid_event.ux_device_class_hid_event_buffer[4] = 0x05;
|
||||
hid_event.ux_device_class_hid_event_buffer[5] = 0x06;
|
||||
hid_event.ux_device_class_hid_event_buffer[6] = 0x07;
|
||||
hid_event.ux_device_class_hid_event_buffer[7] = 0x08;
|
||||
|
||||
/* Add the event. */
|
||||
status = ux_device_class_hid_event_set(slave_hid, &hid_event);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create a transfer request for the GET_REPORT request. We don't need to fill in all the members
|
||||
because this is not a control transfer request. */
|
||||
interrupt_endpoint_transfer_request -> ux_transfer_request_data_pointer = buffer;
|
||||
interrupt_endpoint_transfer_request -> ux_transfer_request_requested_length = hid_event.ux_device_class_hid_event_length;
|
||||
|
||||
/* Wait for the device's interrupt thread to pick up the event and send it to us. */
|
||||
while (1)
|
||||
{
|
||||
|
||||
/* Send request to HCD layer. */
|
||||
status = ux_host_stack_transfer_request(interrupt_endpoint_transfer_request);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Did we receive it? */
|
||||
if (buffer[0] == 0x01 &&
|
||||
buffer[1] == 0x02 &&
|
||||
buffer[2] == 0x03 &&
|
||||
buffer[3] == 0x04 &&
|
||||
buffer[4] == 0x05 &&
|
||||
buffer[5] == 0x06 &&
|
||||
buffer[6] == 0x07 &&
|
||||
buffer[7] == 0x08)
|
||||
break;
|
||||
|
||||
max_get_report_attempts--;
|
||||
if (max_get_report_attempts == 0)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
ux_utility_thread_sleep(10);
|
||||
}
|
||||
|
||||
/* Now disconnect the device. */
|
||||
_ux_device_stack_disconnect();
|
||||
|
||||
/* And deinitialize the class. */
|
||||
status = ux_device_stack_class_unregister(_ux_system_slave_class_hid_name, ux_device_class_hid_entry);
|
||||
|
||||
/* Deinitialize the device side of usbx. */
|
||||
_ux_device_stack_uninitialize();
|
||||
|
||||
/* And finally the usbx system resources. */
|
||||
_ux_system_uninitialize();
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
|
||||
static UINT demo_thread_hid_callback(UX_SLAVE_CLASS_HID *class, UX_SLAVE_CLASS_HID_EVENT *event)
|
||||
{
|
||||
return(UX_SUCCESS);
|
||||
}
|
582
test/regression/usbx_hid_keyboard_basic_test.c
Normal file
582
test/regression/usbx_hid_keyboard_basic_test.c
Normal file
@ -0,0 +1,582 @@
|
||||
/* This test is designed to test the simple dpump host/device class operation. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
#include "ux_api.h"
|
||||
#include "ux_system.h"
|
||||
#include "ux_utility.h"
|
||||
#include "ux_host_class_hid.h"
|
||||
#include "ux_host_class_hid_keyboard.h"
|
||||
#include "ux_device_class_hid.h"
|
||||
#include "ux_device_stack.h"
|
||||
#include "ux_test_utility_sim.h"
|
||||
#include "ux_test_hcd_sim_host.h"
|
||||
|
||||
/* Define constants. */
|
||||
#define UX_DEMO_DEBUG_SIZE (4096*8)
|
||||
#define UX_DEMO_STACK_SIZE 1024
|
||||
#define UX_DEMO_BUFFER_SIZE 2048
|
||||
#define UX_DEMO_RECEPTION_BUFFER_SIZE 512
|
||||
#define UX_DEMO_XMIT_BUFFER_SIZE 512
|
||||
#define UX_DEMO_RECEPTION_BLOCK_SIZE 64
|
||||
#define UX_DEMO_MEMORY_SIZE (64*1024)
|
||||
|
||||
/* Define local/extern function prototypes. */
|
||||
static void demo_thread_entry(ULONG);
|
||||
static UINT demo_thread_hid_callback(UX_SLAVE_CLASS_HID *, UX_SLAVE_CLASS_HID_EVENT *);
|
||||
static TX_THREAD tx_demo_thread_host_simulation;
|
||||
static TX_THREAD tx_demo_thread_slave_simulation;
|
||||
static void tx_demo_thread_host_simulation_entry(ULONG);
|
||||
static void tx_demo_thread_slave_simulation_entry(ULONG);
|
||||
|
||||
|
||||
/* Define global data structures. */
|
||||
static UCHAR usbx_memory[UX_DEMO_MEMORY_SIZE + (UX_DEMO_STACK_SIZE * 2)];
|
||||
static ULONG error_counter;
|
||||
static TX_THREAD demo_thread;
|
||||
static UX_HOST_CLASS *class_driver;
|
||||
static ULONG class_driver_index;
|
||||
static UX_HOST_CLASS_HID *hid;
|
||||
static UX_HOST_CLASS_HID_CLIENT *hid_client;
|
||||
static UX_HOST_CLASS_HID_KEYBOARD *keyboard;
|
||||
static UINT status;
|
||||
static UINT transfer_completed;
|
||||
static ULONG requested_length;
|
||||
static TX_SEMAPHORE demo_semaphore;
|
||||
|
||||
static ULONG keyboard_char;
|
||||
static ULONG keyboard_state;
|
||||
static UCHAR keyboard_queue[1024];
|
||||
static ULONG keyboard_queue_index;
|
||||
|
||||
static UX_SLAVE_CLASS_HID_PARAMETER hid_parameter;
|
||||
|
||||
static UCHAR hid_keyboard_report[] = {
|
||||
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||
0x09, 0x06, // USAGE (Keyboard)
|
||||
0xa1, 0x01, // COLLECTION (Application)
|
||||
/* Modifier keys. */
|
||||
0x05, 0x07, // USAGE_PAGE (Keyboard)
|
||||
0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)
|
||||
0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x25, 0x01, // LOGICAL_MAXIMUM (1)
|
||||
0x75, 0x01, // REPORT_SIZE (1)
|
||||
0x95, 0x08, // REPORT_COUNT (8)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
/* Padding. */
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x81, 0x03, // INPUT (Cnst,Var,Abs)
|
||||
/* LEDs. */
|
||||
0x95, 0x05, // REPORT_COUNT (5)
|
||||
0x75, 0x01, // REPORT_SIZE (1)
|
||||
0x05, 0x08, // USAGE_PAGE (LEDs)
|
||||
0x19, 0x01, // USAGE_MINIMUM (Num Lock)
|
||||
0x29, 0x05, // USAGE_MAXIMUM (Kana)
|
||||
0x91, 0x02, // OUTPUT (Data,Var,Abs)
|
||||
/* Padding. */
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x75, 0x03, // REPORT_SIZE (3)
|
||||
0x91, 0x03, // OUTPUT (Cnst,Var,Abs)
|
||||
/* Keys. */
|
||||
0x95, 0x06, // REPORT_COUNT (6)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x25, 0x65, // LOGICAL_MAXIMUM (101)
|
||||
0x05, 0x07, // USAGE_PAGE (Keyboard)
|
||||
0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
|
||||
0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)
|
||||
0x81, 0x00, // INPUT (Data,Ary,Abs)
|
||||
0xc0, // END_COLLECTION
|
||||
|
||||
0xa1, 0x01, // COLLECTION (Application)
|
||||
0x19, 0x01, // USAGE_MINIMUM (1)
|
||||
0x29, 0x04, // USAGE_MAXIMUM (4)
|
||||
0x75, 0x04, // REPORT_SIZE (4)
|
||||
0x95, 0x04, // REPORT_COUNT (4)
|
||||
0xb1, 0x02, // FEATURE (Data,Var,Abs)
|
||||
0x85, 0x02, // REPORT_ID (2)
|
||||
0x19, 0x05, // USAGE_MINIMUM (5)
|
||||
0x29, 0x07, // USAGE_MAXIMUM (7)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x95, 0x03, // REPORT_COUNT (3)
|
||||
0xb1, 0x02, // FEATURE (Data,Var,Abs)
|
||||
0x85, 0x04, // REPORT_ID (4)
|
||||
0x09, 0x08, // USAGE (8)
|
||||
0x75, 0x10, // REPORT_SIZE (16)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0xb1, 0x02, // FEATURE (Data,Var,Abs)
|
||||
0xc0, // END_COLLECTION
|
||||
|
||||
};
|
||||
#define HID_KEYBOARD_REPORT_LENGTH (sizeof(hid_keyboard_report)/sizeof(hid_keyboard_report[0]))
|
||||
|
||||
|
||||
#define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED 52
|
||||
static UCHAR device_framework_full_speed[] = {
|
||||
|
||||
/* Device descriptor */
|
||||
0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08,
|
||||
0x81, 0x0A, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x01,
|
||||
|
||||
/* Configuration descriptor */
|
||||
0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x00, 0xc0,
|
||||
0x32,
|
||||
|
||||
/* Interface descriptor */
|
||||
0x09, 0x04, 0x02, 0x00, 0x01, 0x03, 0x00, 0x00,
|
||||
0x00,
|
||||
|
||||
/* HID descriptor */
|
||||
0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, HID_KEYBOARD_REPORT_LENGTH,
|
||||
0x00,
|
||||
|
||||
/* Endpoint descriptor (Interrupt) */
|
||||
0x07, 0x05, 0x82, 0x03, 0x08, 0x00, 0x08
|
||||
|
||||
};
|
||||
|
||||
|
||||
#define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED 62
|
||||
static UCHAR device_framework_high_speed[] = {
|
||||
|
||||
/* Device descriptor */
|
||||
0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
|
||||
0x0a, 0x07, 0x25, 0x40, 0x01, 0x00, 0x01, 0x02,
|
||||
0x03, 0x01,
|
||||
|
||||
/* Device qualifier descriptor */
|
||||
0x0a, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
|
||||
0x01, 0x00,
|
||||
|
||||
/* Configuration descriptor */
|
||||
0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x00, 0xc0,
|
||||
0x32,
|
||||
|
||||
/* Interface descriptor */
|
||||
0x09, 0x04, 0x02, 0x00, 0x01, 0x03, 0x00, 0x00,
|
||||
0x00,
|
||||
|
||||
/* HID descriptor */
|
||||
0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, HID_KEYBOARD_REPORT_LENGTH,
|
||||
0x00,
|
||||
|
||||
/* Endpoint descriptor (Interrupt) */
|
||||
0x07, 0x05, 0x82, 0x03, 0x08, 0x00, 0x08
|
||||
|
||||
};
|
||||
|
||||
|
||||
/* String Device Framework :
|
||||
Byte 0 and 1 : Word containing the language ID : 0x0904 for US
|
||||
Byte 2 : Byte containing the index of the descriptor
|
||||
Byte 3 : Byte containing the length of the descriptor string
|
||||
*/
|
||||
|
||||
#define STRING_FRAMEWORK_LENGTH 40
|
||||
static UCHAR string_framework[] = {
|
||||
|
||||
/* Manufacturer string descriptor : Index 1 */
|
||||
0x09, 0x04, 0x01, 0x0c,
|
||||
0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
|
||||
0x6f, 0x67, 0x69, 0x63,
|
||||
|
||||
/* Product string descriptor : Index 2 */
|
||||
0x09, 0x04, 0x02, 0x0c,
|
||||
0x55, 0x53, 0x42, 0x20, 0x4b, 0x65, 0x79, 0x62,
|
||||
0x6f, 0x61, 0x72, 0x64,
|
||||
|
||||
/* Serial Number string descriptor : Index 3 */
|
||||
0x09, 0x04, 0x03, 0x04,
|
||||
0x30, 0x30, 0x30, 0x31
|
||||
};
|
||||
|
||||
|
||||
/* Multiple languages are supported on the device, to add
|
||||
a language besides english, the unicode language code must
|
||||
be appended to the language_id_framework array and the length
|
||||
adjusted accordingly. */
|
||||
#define LANGUAGE_ID_FRAMEWORK_LENGTH 2
|
||||
static UCHAR language_id_framework[] = {
|
||||
|
||||
/* English. */
|
||||
0x09, 0x04
|
||||
};
|
||||
|
||||
/* Define the ISR dispatch. */
|
||||
|
||||
extern VOID (*test_isr_dispatch)(void);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
/* Define the ISR dispatch routine. */
|
||||
|
||||
static void test_isr(void)
|
||||
{
|
||||
|
||||
/* For further expansion of interrupt-level testing. */
|
||||
}
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_hid_keyboard_basic_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR * stack_pointer;
|
||||
CHAR * memory_pointer;
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running HID Keyboard Basic Functionality Test....................... ");
|
||||
|
||||
/* Initialize the free memory pointer */
|
||||
stack_pointer = (CHAR *) usbx_memory;
|
||||
memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
|
||||
|
||||
/* Initialize USBX. Memory */
|
||||
status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #1\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the error callback. */
|
||||
ux_utility_error_callback_register(ux_test_error_callback);
|
||||
|
||||
/* The code below is required for installing the host portion of USBX */
|
||||
status = ux_host_stack_initialize(UX_NULL);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #2\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = ux_host_stack_class_register(_ux_system_host_class_hid_name, ux_host_class_hid_entry);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #3\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the HID client(s). */
|
||||
status = ux_host_class_hid_client_register(_ux_system_host_class_hid_client_keyboard_name, ux_host_class_hid_keyboard_entry);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #4\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* The code below is required for installing the device portion of USBX. No call back for
|
||||
device status change in this example. */
|
||||
status = ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
|
||||
device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
|
||||
string_framework, STRING_FRAMEWORK_LENGTH,
|
||||
language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #6\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Initialize the hid class parameters for a keyboard. */
|
||||
hid_parameter.ux_device_class_hid_parameter_report_address = hid_keyboard_report;
|
||||
hid_parameter.ux_device_class_hid_parameter_report_length = HID_KEYBOARD_REPORT_LENGTH;
|
||||
hid_parameter.ux_device_class_hid_parameter_callback = demo_thread_hid_callback;
|
||||
|
||||
/* Initilize the device hid class. The class is connected with interface 2 */
|
||||
status = ux_device_stack_class_register(_ux_system_slave_class_hid_name, ux_device_class_hid_entry,
|
||||
1,2, (VOID *)&hid_parameter);
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #7\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
|
||||
/* Initialize the simulated device controller. */
|
||||
status = _ux_dcd_sim_slave_initialize();
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #8\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register all the USB host controllers available in this system */
|
||||
status = ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, ux_hcd_sim_host_initialize,0,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #5\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the main host simulation thread. */
|
||||
status = tx_thread_create(&tx_demo_thread_host_simulation, "tx demo host simulation", tx_demo_thread_host_simulation_entry, 0,
|
||||
stack_pointer, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #9\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the main demo thread. */
|
||||
status = tx_thread_create(&tx_demo_thread_slave_simulation, "tx demo slave simulation", tx_demo_thread_slave_simulation_entry, 0,
|
||||
stack_pointer + UX_DEMO_STACK_SIZE, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("ERROR #10\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static UINT demo_class_hid_connect_wait(ULONG nb_loop)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
UX_HOST_CLASS *class;
|
||||
|
||||
/* Find the main HID container */
|
||||
status = ux_host_stack_class_get(_ux_system_host_class_hid_name, &class);
|
||||
if (status != UX_SUCCESS)
|
||||
return(status);
|
||||
|
||||
/* We get the first instance of the hid device */
|
||||
do
|
||||
{
|
||||
|
||||
status = ux_host_stack_class_instance_get(class, 0, (void **) &hid);
|
||||
if (status == UX_SUCCESS && hid -> ux_host_class_hid_state == UX_HOST_CLASS_INSTANCE_LIVE)
|
||||
return(UX_SUCCESS);
|
||||
_ux_utility_delay_ms(10);
|
||||
} while (nb_loop --);
|
||||
|
||||
return(UX_ERROR);
|
||||
}
|
||||
|
||||
static UINT demo_class_hid_disconnect_wait(ULONG nb_loop)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
UX_HOST_CLASS *class;
|
||||
|
||||
/* Find the main HID container */
|
||||
status = ux_host_stack_class_get(_ux_system_host_class_hid_name, &class);
|
||||
if (status != UX_SUCCESS)
|
||||
return(status);
|
||||
|
||||
/* We get the first instance of the hid device */
|
||||
do {
|
||||
|
||||
status = ux_host_stack_class_instance_get(class, 0, (void **) &hid);
|
||||
if (status != UX_SUCCESS)
|
||||
return(UX_SUCCESS);
|
||||
_ux_utility_delay_ms(10);
|
||||
} while(nb_loop --);
|
||||
|
||||
return(UX_ERROR);
|
||||
}
|
||||
|
||||
static void tx_demo_thread_host_simulation_entry(ULONG arg)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
UINT max_hid_loop;
|
||||
|
||||
|
||||
/* Initilize max loop value. */
|
||||
max_hid_loop = 16;
|
||||
|
||||
/* Find the HID class */
|
||||
status = demo_class_hid_connect_wait(50);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
/* HID Keyboard basic test error. */
|
||||
printf("ERROR #11\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the HID client */
|
||||
hid_client = hid -> ux_host_class_hid_client;
|
||||
|
||||
/* Get the keyboard instance */
|
||||
keyboard = (UX_HOST_CLASS_HID_KEYBOARD *)hid_client -> ux_host_class_hid_client_local_instance;
|
||||
|
||||
/* Init the keyboard queue index. */
|
||||
keyboard_queue_index = 0;
|
||||
|
||||
while (max_hid_loop--)
|
||||
{
|
||||
/* Get a key/state from the keyboard. */
|
||||
status = ux_host_class_hid_keyboard_key_get(keyboard, &keyboard_char, &keyboard_state);
|
||||
|
||||
/* Check if there is something. */
|
||||
if (status == UX_SUCCESS)
|
||||
{
|
||||
/* We have a character in the queue. */
|
||||
keyboard_queue[keyboard_queue_index] = (UCHAR) keyboard_char;
|
||||
|
||||
/* Can we accept more ? */
|
||||
if(keyboard_queue_index < 1024)
|
||||
keyboard_queue_index++;
|
||||
|
||||
}
|
||||
|
||||
tx_thread_sleep(10);
|
||||
}
|
||||
|
||||
/* Simulate disconnect. */
|
||||
ux_test_hcd_sim_host_disconnect();
|
||||
demo_class_hid_disconnect_wait(5);
|
||||
|
||||
/* Now disconnect the device. */
|
||||
_ux_device_stack_disconnect();
|
||||
|
||||
/* And deinitialize the class. */
|
||||
status = ux_device_stack_class_unregister(_ux_system_slave_class_hid_name, ux_device_class_hid_entry);
|
||||
|
||||
/* Deinitialize the device side of usbx. */
|
||||
_ux_device_stack_uninitialize();
|
||||
|
||||
/* And finally the usbx system resources. */
|
||||
_ux_system_uninitialize();
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
|
||||
static UINT demo_thread_hid_callback(UX_SLAVE_CLASS_HID *class, UX_SLAVE_CLASS_HID_EVENT *event)
|
||||
{
|
||||
return(UX_SUCCESS);
|
||||
}
|
||||
|
||||
static void tx_demo_thread_slave_simulation_entry(ULONG arg)
|
||||
{
|
||||
|
||||
UX_SLAVE_DEVICE *device;
|
||||
UX_SLAVE_INTERFACE *interface;
|
||||
UX_SLAVE_CLASS_HID *hid;
|
||||
UX_SLAVE_CLASS_HID_EVENT hid_event;
|
||||
UCHAR key;
|
||||
|
||||
/* Get the pointer to the device. */
|
||||
device = &_ux_system_slave -> ux_system_slave_device;
|
||||
|
||||
/* Set the first key to 'a' which is 04. */
|
||||
key = 0x04;
|
||||
|
||||
/* reset the HID event structure. */
|
||||
ux_utility_memory_set(&hid_event, 0, sizeof(UX_SLAVE_CLASS_HID_EVENT));
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Is the device configured ? */
|
||||
while (device -> ux_slave_device_state != UX_DEVICE_CONFIGURED)
|
||||
{
|
||||
#if defined(UX_DEVICE_STANDALONE)
|
||||
ux_system_tasks_run();
|
||||
tx_thread_relinquish();
|
||||
#else
|
||||
/* Then wait. */
|
||||
tx_thread_sleep(10);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Until the device stays configured. */
|
||||
while (device -> ux_slave_device_state == UX_DEVICE_CONFIGURED)
|
||||
{
|
||||
|
||||
/* Get the interface. We use the first interface, this is a simple device. */
|
||||
interface = device -> ux_slave_device_first_interface;
|
||||
|
||||
/* Form that interface, derive the HID owner. */
|
||||
hid = interface -> ux_slave_interface_class_instance;
|
||||
|
||||
#if defined(UX_DEVICE_STANDALONE)
|
||||
ULONG tick_to_wait = UX_MS_TO_TICK(2000);
|
||||
ULONG tick_start = _ux_utility_time_get();
|
||||
while(_ux_utility_time_elapsed(tick_start, _ux_utility_time_get()) < tick_to_wait)
|
||||
{
|
||||
ux_system_tasks_run();
|
||||
tx_thread_relinquish();
|
||||
}
|
||||
#else
|
||||
/* Wait for 2 seconds. */
|
||||
ux_utility_thread_sleep(UX_MS_TO_TICK(2000));
|
||||
#endif
|
||||
|
||||
/* Then insert a key into the keyboard event. Length is fixed to 8. */
|
||||
hid_event.ux_device_class_hid_event_length = 8;
|
||||
|
||||
/* First byte is a modifier byte. */
|
||||
hid_event.ux_device_class_hid_event_buffer[0] = 0;
|
||||
|
||||
/* Second byte is reserved. */
|
||||
hid_event.ux_device_class_hid_event_buffer[1] = 0;
|
||||
|
||||
/* The 6 next bytes are keys. We only have one key here. */
|
||||
hid_event.ux_device_class_hid_event_buffer[2] = key;
|
||||
|
||||
/* Set the keyboard event. */
|
||||
ux_device_class_hid_event_set(hid, &hid_event);
|
||||
|
||||
/* Next event has the key depressed. */
|
||||
hid_event.ux_device_class_hid_event_buffer[2] = 0;
|
||||
|
||||
/* Length is fixed to 8. */
|
||||
hid_event.ux_device_class_hid_event_length = 8;
|
||||
|
||||
/* Set the keyboard event. */
|
||||
ux_device_class_hid_event_set(hid, &hid_event);
|
||||
|
||||
/* Are we at the end of alphabet ? */
|
||||
if (key != (0x04 + 26))
|
||||
|
||||
/* Next key. */
|
||||
key++;
|
||||
|
||||
else
|
||||
|
||||
/* Start over again. */
|
||||
key = 0x04;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
378
test/regression/usbx_hid_keyboard_extraction_test.c
Normal file
378
test/regression/usbx_hid_keyboard_extraction_test.c
Normal file
@ -0,0 +1,378 @@
|
||||
/* This test concentrates on keyboard device removal. */
|
||||
|
||||
#include "usbx_test_common_hid.h"
|
||||
#include "ux_host_class_hid_keyboard.h"
|
||||
|
||||
|
||||
static UCHAR hid_report_descriptor[] = {
|
||||
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||
0x09, 0x06, // USAGE (Keyboard)
|
||||
0xa1, 0x01, // COLLECTION (Application)
|
||||
0x05, 0x07, // USAGE_PAGE (Keyboard)
|
||||
0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)
|
||||
0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x25, 0x01, // LOGICAL_MAXIMUM (1)
|
||||
0x75, 0x01, // REPORT_SIZE (1)
|
||||
0x95, 0x08, // REPORT_COUNT (8)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x81, 0x03, // INPUT (Cnst,Var,Abs)
|
||||
0x95, 0x05, // REPORT_COUNT (5)
|
||||
0x75, 0x01, // REPORT_SIZE (1)
|
||||
0x05, 0x08, // USAGE_PAGE (LEDs)
|
||||
0x19, 0x01, // USAGE_MINIMUM (Num Lock)
|
||||
0x29, 0x05, // USAGE_MAXIMUM (Kana)
|
||||
0x91, 0x02, // OUTPUT (Data,Var,Abs)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x75, 0x03, // REPORT_SIZE (3)
|
||||
0x91, 0x03, // OUTPUT (Cnst,Var,Abs)
|
||||
0x95, 0x06, // REPORT_COUNT (6)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x25, 0x65, // LOGICAL_MAXIMUM (101)
|
||||
0x05, 0x07, // USAGE_PAGE (Keyboard)
|
||||
0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
|
||||
0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)
|
||||
0x81, 0x00, // INPUT (Data,Ary,Abs)
|
||||
/* Add a feature report to hit some code in _ux_host_class_hid_instance_clean(). */
|
||||
0x95, 0x06, // REPORT_COUNT (6)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x25, 0x65, // LOGICAL_MAXIMUM (101)
|
||||
0x05, 0x07, // USAGE_PAGE (Keyboard)
|
||||
0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
|
||||
0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)
|
||||
0xb1, 0x00, // FEATURE (Data,Ary,Abs)
|
||||
0xc0 // END_COLLECTION
|
||||
};
|
||||
#define HID_REPORT_LENGTH sizeof(hid_report_descriptor)/sizeof(hid_report_descriptor[0])
|
||||
|
||||
|
||||
#define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED 52
|
||||
static UCHAR device_framework_full_speed[DEVICE_FRAMEWORK_LENGTH_FULL_SPEED] = {
|
||||
|
||||
/* Device descriptor */
|
||||
0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08,
|
||||
0x81, 0x0A, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x01,
|
||||
|
||||
/* Configuration descriptor */
|
||||
0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x00, 0xc0,
|
||||
0x32,
|
||||
|
||||
/* Interface descriptor */
|
||||
0x09, 0x04, 0x02, 0x00, 0x01, 0x03, 0x00, 0x00,
|
||||
0x00,
|
||||
|
||||
/* HID descriptor */
|
||||
0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(HID_REPORT_LENGTH),
|
||||
MSB(HID_REPORT_LENGTH),
|
||||
|
||||
/* Endpoint descriptor (Interrupt) */
|
||||
0x07, 0x05, 0x82, 0x03, 0x08, 0x00, 0x08
|
||||
|
||||
};
|
||||
|
||||
|
||||
#define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED 62
|
||||
static UCHAR device_framework_high_speed[DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED] = {
|
||||
|
||||
/* Device descriptor */
|
||||
0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
|
||||
0x0a, 0x07, 0x25, 0x40, 0x01, 0x00, 0x01, 0x02,
|
||||
0x03, 0x01,
|
||||
|
||||
/* Device qualifier descriptor */
|
||||
0x0a, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
|
||||
0x01, 0x00,
|
||||
|
||||
/* Configuration descriptor */
|
||||
0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x00, 0xc0,
|
||||
0x32,
|
||||
|
||||
/* Interface descriptor */
|
||||
0x09, 0x04, 0x02, 0x00, 0x01, 0x03, 0x00, 0x00,
|
||||
0x00,
|
||||
|
||||
/* HID descriptor */
|
||||
0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(HID_REPORT_LENGTH),
|
||||
MSB(HID_REPORT_LENGTH),
|
||||
|
||||
/* Endpoint descriptor (Interrupt) */
|
||||
0x07, 0x05, 0x82, 0x03, 0x08, 0x00, 0x08
|
||||
|
||||
};
|
||||
|
||||
|
||||
/* String Device Framework :
|
||||
Byte 0 and 1 : Word containing the language ID : 0x0904 for US
|
||||
Byte 2 : Byte containing the index of the descriptor
|
||||
Byte 3 : Byte containing the length of the descriptor string
|
||||
*/
|
||||
|
||||
#define STRING_FRAMEWORK_LENGTH 40
|
||||
static UCHAR string_framework[] = {
|
||||
|
||||
/* Manufacturer string descriptor : Index 1 */
|
||||
0x09, 0x04, 0x01, 0x0c,
|
||||
0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
|
||||
0x6f, 0x67, 0x69, 0x63,
|
||||
|
||||
/* Product string descriptor : Index 2 */
|
||||
0x09, 0x04, 0x02, 0x0c,
|
||||
0x55, 0x53, 0x42, 0x20, 0x4b, 0x65, 0x79, 0x62,
|
||||
0x6f, 0x61, 0x72, 0x64,
|
||||
|
||||
/* Serial Number string descriptor : Index 3 */
|
||||
0x09, 0x04, 0x03, 0x04,
|
||||
0x30, 0x30, 0x30, 0x31
|
||||
};
|
||||
|
||||
|
||||
/* Multiple languages are supported on the device, to add
|
||||
a language besides english, the unicode language code must
|
||||
be appended to the language_id_framework array and the length
|
||||
adjusted accordingly. */
|
||||
#define LANGUAGE_ID_FRAMEWORK_LENGTH 2
|
||||
static UCHAR language_id_framework[] = {
|
||||
|
||||
/* English. */
|
||||
0x09, 0x04
|
||||
};
|
||||
|
||||
|
||||
UINT _ux_hcd_sim_host_entry(UX_HCD *hcd, UINT function, VOID *parameter);
|
||||
|
||||
|
||||
static UINT ux_system_host_change_function(ULONG a, UX_HOST_CLASS *b, VOID *c)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
|
||||
{
|
||||
|
||||
/* Failed test. */
|
||||
printf("Error on line %d, system_level: %d, system_context: %d, error code: %d\n", __LINE__, system_level, system_context, error_code);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_hid_keyboard_extraction_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR * stack_pointer;
|
||||
CHAR * memory_pointer;
|
||||
UINT descriptor_size = HID_REPORT_LENGTH;
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running HID Device Removal Keyboard Test............................ ");
|
||||
|
||||
/* Initialize the free memory pointer */
|
||||
stack_pointer = (CHAR *) usbx_memory;
|
||||
memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
|
||||
|
||||
/* Initialize USBX. Memory */
|
||||
status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the error callback. */
|
||||
_ux_utility_error_callback_register(error_callback);
|
||||
|
||||
/* The code below is required for installing the host portion of USBX */
|
||||
status = ux_host_stack_initialize(ux_system_host_change_function);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = ux_host_stack_class_register(_ux_system_host_class_hid_name, ux_host_class_hid_entry);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the HID client(s). */
|
||||
status = ux_host_class_hid_client_register(_ux_system_host_class_hid_client_keyboard_name, ux_host_class_hid_keyboard_entry);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* The code below is required for installing the device portion of USBX. No call back for
|
||||
device status change in this example. */
|
||||
status = ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
|
||||
device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
|
||||
string_framework, STRING_FRAMEWORK_LENGTH,
|
||||
language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Initialize the hid class parameters. */
|
||||
hid_parameter.ux_device_class_hid_parameter_report_address = hid_report_descriptor;
|
||||
hid_parameter.ux_device_class_hid_parameter_report_length = HID_REPORT_LENGTH;
|
||||
hid_parameter.ux_device_class_hid_parameter_callback = demo_thread_hid_callback;
|
||||
|
||||
/* Initilize the device hid class. The class is connected with interface 2 */
|
||||
status = ux_device_stack_class_register(_ux_system_slave_class_hid_name, ux_device_class_hid_entry,
|
||||
1,2, (VOID *)&hid_parameter);
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
|
||||
/* Initialize the simulated device controller. */
|
||||
status = _ux_dcd_sim_slave_initialize();
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register all the USB host controllers available in this system */
|
||||
status = ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, ux_hcd_sim_host_initialize,0,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the main host simulation thread. */
|
||||
status = tx_thread_create(&tx_demo_thread_host_simulation, "tx demo host simulation", tx_demo_thread_host_simulation_entry, 0,
|
||||
stack_pointer, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
static UINT ux_hcd_sim_host_entry_filter_device_extraction_test(UX_HCD *hcd, UINT function, VOID *parameter)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
switch(function)
|
||||
{
|
||||
case UX_HCD_GET_PORT_STATUS:
|
||||
|
||||
/* No device on this port. */
|
||||
status = 0;
|
||||
|
||||
/* This is a Full speed device. */
|
||||
status |= UX_PS_DS_FS;
|
||||
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
|
||||
status = _ux_hcd_sim_host_entry(hcd, function, parameter);
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void tx_demo_thread_host_simulation_entry(ULONG arg)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
UX_HOST_CLASS_HID_KEYBOARD *keyboard;
|
||||
UX_HCD *hcd;
|
||||
|
||||
|
||||
/* Find the HID class */
|
||||
status = demo_class_hid_get();
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the HID client */
|
||||
hid_client = hid -> ux_host_class_hid_client;
|
||||
|
||||
/* Check if the instance of the keyboard is live */
|
||||
while (hid_client -> ux_host_class_hid_client_local_instance == UX_NULL)
|
||||
tx_thread_sleep(10);
|
||||
|
||||
/* Get the keyboard instance */
|
||||
keyboard = (UX_HOST_CLASS_HID_KEYBOARD *)hid_client -> ux_host_class_hid_client_local_instance;
|
||||
|
||||
hcd = UX_DEVICE_HCD_GET(hid -> ux_host_class_hid_device);
|
||||
|
||||
/* Change the HCD entry function to our filter function. */
|
||||
hcd -> ux_hcd_entry_function = ux_hcd_sim_host_entry_filter_device_extraction_test;
|
||||
|
||||
/* Signal port activity to the enum thread. */
|
||||
hcd -> ux_hcd_root_hub_signal[0] = 1;
|
||||
|
||||
/* Signal enum thread. */
|
||||
_ux_utility_semaphore_put(&_ux_system_host -> ux_system_host_enum_semaphore);
|
||||
|
||||
/* Wait for hid class to shut down. */
|
||||
while(hid -> ux_host_class_hid_state == UX_HOST_CLASS_INSTANCE_LIVE)
|
||||
tx_thread_sleep(10);
|
||||
|
||||
/* Now disconnect the device. */
|
||||
_ux_device_stack_disconnect();
|
||||
|
||||
/* And deinitialize the class. */
|
||||
status = ux_device_stack_class_unregister(_ux_system_slave_class_hid_name, ux_device_class_hid_entry);
|
||||
|
||||
/* Deinitialize the device side of usbx. */
|
||||
_ux_device_stack_uninitialize();
|
||||
|
||||
/* And finally the usbx system resources. */
|
||||
_ux_system_uninitialize();
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
|
||||
static UINT demo_thread_hid_callback(UX_SLAVE_CLASS_HID *class, UX_SLAVE_CLASS_HID_EVENT *event)
|
||||
{
|
||||
return(UX_SUCCESS);
|
||||
}
|
371
test/regression/usbx_hid_keyboard_extraction_test2.c
Normal file
371
test/regression/usbx_hid_keyboard_extraction_test2.c
Normal file
@ -0,0 +1,371 @@
|
||||
/* This test concentrates on keyboard device removal.
|
||||
This is similar to the first extraction test, except there is no ux_system_host_change_function.
|
||||
This allows us to hit the following false condition in _ux_host_class_hid_keyboard_deactivate:
|
||||
if (_ux_system_host -> ux_system_host_change_function != UX_NULL) */
|
||||
|
||||
#include "usbx_test_common_hid.h"
|
||||
#include "ux_host_class_hid_keyboard.h"
|
||||
|
||||
|
||||
static UCHAR hid_report_descriptor[] = {
|
||||
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||
0x09, 0x06, // USAGE (Keyboard)
|
||||
0xa1, 0x01, // COLLECTION (Application)
|
||||
0x05, 0x07, // USAGE_PAGE (Keyboard)
|
||||
0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)
|
||||
0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x25, 0x01, // LOGICAL_MAXIMUM (1)
|
||||
0x75, 0x01, // REPORT_SIZE (1)
|
||||
0x95, 0x08, // REPORT_COUNT (8)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x81, 0x03, // INPUT (Cnst,Var,Abs)
|
||||
0x95, 0x05, // REPORT_COUNT (5)
|
||||
0x75, 0x01, // REPORT_SIZE (1)
|
||||
0x05, 0x08, // USAGE_PAGE (LEDs)
|
||||
0x19, 0x01, // USAGE_MINIMUM (Num Lock)
|
||||
0x29, 0x05, // USAGE_MAXIMUM (Kana)
|
||||
0x91, 0x02, // OUTPUT (Data,Var,Abs)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x75, 0x03, // REPORT_SIZE (3)
|
||||
0x91, 0x03, // OUTPUT (Cnst,Var,Abs)
|
||||
0x95, 0x06, // REPORT_COUNT (6)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x25, 0x65, // LOGICAL_MAXIMUM (101)
|
||||
0x05, 0x07, // USAGE_PAGE (Keyboard)
|
||||
0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
|
||||
0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)
|
||||
0x81, 0x00, // INPUT (Data,Ary,Abs)
|
||||
/* Add a feature report to hit some code in _ux_host_class_hid_instance_clean(). */
|
||||
0x95, 0x06, // REPORT_COUNT (6)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x25, 0x65, // LOGICAL_MAXIMUM (101)
|
||||
0x05, 0x07, // USAGE_PAGE (Keyboard)
|
||||
0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
|
||||
0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)
|
||||
0xb1, 0x00, // FEATURE (Data,Ary,Abs)
|
||||
0xc0 // END_COLLECTION
|
||||
};
|
||||
#define HID_REPORT_LENGTH sizeof(hid_report_descriptor)/sizeof(hid_report_descriptor[0])
|
||||
|
||||
|
||||
#define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED 52
|
||||
static UCHAR device_framework_full_speed[DEVICE_FRAMEWORK_LENGTH_FULL_SPEED] = {
|
||||
|
||||
/* Device descriptor */
|
||||
0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08,
|
||||
0x81, 0x0A, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x01,
|
||||
|
||||
/* Configuration descriptor */
|
||||
0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x00, 0xc0,
|
||||
0x32,
|
||||
|
||||
/* Interface descriptor */
|
||||
0x09, 0x04, 0x02, 0x00, 0x01, 0x03, 0x00, 0x00,
|
||||
0x00,
|
||||
|
||||
/* HID descriptor */
|
||||
0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(HID_REPORT_LENGTH),
|
||||
MSB(HID_REPORT_LENGTH),
|
||||
|
||||
/* Endpoint descriptor (Interrupt) */
|
||||
0x07, 0x05, 0x82, 0x03, 0x08, 0x00, 0x08
|
||||
|
||||
};
|
||||
|
||||
|
||||
#define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED 62
|
||||
static UCHAR device_framework_high_speed[DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED] = {
|
||||
|
||||
/* Device descriptor */
|
||||
0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
|
||||
0x0a, 0x07, 0x25, 0x40, 0x01, 0x00, 0x01, 0x02,
|
||||
0x03, 0x01,
|
||||
|
||||
/* Device qualifier descriptor */
|
||||
0x0a, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
|
||||
0x01, 0x00,
|
||||
|
||||
/* Configuration descriptor */
|
||||
0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x00, 0xc0,
|
||||
0x32,
|
||||
|
||||
/* Interface descriptor */
|
||||
0x09, 0x04, 0x02, 0x00, 0x01, 0x03, 0x00, 0x00,
|
||||
0x00,
|
||||
|
||||
/* HID descriptor */
|
||||
0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(HID_REPORT_LENGTH),
|
||||
MSB(HID_REPORT_LENGTH),
|
||||
|
||||
/* Endpoint descriptor (Interrupt) */
|
||||
0x07, 0x05, 0x82, 0x03, 0x08, 0x00, 0x08
|
||||
|
||||
};
|
||||
|
||||
|
||||
/* String Device Framework :
|
||||
Byte 0 and 1 : Word containing the language ID : 0x0904 for US
|
||||
Byte 2 : Byte containing the index of the descriptor
|
||||
Byte 3 : Byte containing the length of the descriptor string
|
||||
*/
|
||||
|
||||
#define STRING_FRAMEWORK_LENGTH 40
|
||||
static UCHAR string_framework[] = {
|
||||
|
||||
/* Manufacturer string descriptor : Index 1 */
|
||||
0x09, 0x04, 0x01, 0x0c,
|
||||
0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
|
||||
0x6f, 0x67, 0x69, 0x63,
|
||||
|
||||
/* Product string descriptor : Index 2 */
|
||||
0x09, 0x04, 0x02, 0x0c,
|
||||
0x55, 0x53, 0x42, 0x20, 0x4b, 0x65, 0x79, 0x62,
|
||||
0x6f, 0x61, 0x72, 0x64,
|
||||
|
||||
/* Serial Number string descriptor : Index 3 */
|
||||
0x09, 0x04, 0x03, 0x04,
|
||||
0x30, 0x30, 0x30, 0x31
|
||||
};
|
||||
|
||||
|
||||
/* Multiple languages are supported on the device, to add
|
||||
a language besides english, the unicode language code must
|
||||
be appended to the language_id_framework array and the length
|
||||
adjusted accordingly. */
|
||||
#define LANGUAGE_ID_FRAMEWORK_LENGTH 2
|
||||
static UCHAR language_id_framework[] = {
|
||||
|
||||
/* English. */
|
||||
0x09, 0x04
|
||||
};
|
||||
|
||||
|
||||
UINT _ux_hcd_sim_host_entry(UX_HCD *hcd, UINT function, VOID *parameter);
|
||||
|
||||
|
||||
static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
|
||||
{
|
||||
|
||||
/* Failed test. */
|
||||
printf("Error on line %d, system_level: %d, system_context: %d, error code: %d\n", __LINE__, system_level, system_context, error_code);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_hid_keyboard_extraction_test2_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR * stack_pointer;
|
||||
CHAR * memory_pointer;
|
||||
UINT descriptor_size = HID_REPORT_LENGTH;
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running HID Device Removal Keyboard Test2........................... ");
|
||||
|
||||
/* Initialize the free memory pointer */
|
||||
stack_pointer = (CHAR *) usbx_memory;
|
||||
memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
|
||||
|
||||
/* Initialize USBX. Memory */
|
||||
status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the error callback. */
|
||||
_ux_utility_error_callback_register(error_callback);
|
||||
|
||||
/* The code below is required for installing the host portion of USBX */
|
||||
status = ux_host_stack_initialize(NULL);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = ux_host_stack_class_register(_ux_system_host_class_hid_name, ux_host_class_hid_entry);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the HID client(s). */
|
||||
status = ux_host_class_hid_client_register(_ux_system_host_class_hid_client_keyboard_name, ux_host_class_hid_keyboard_entry);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* The code below is required for installing the device portion of USBX. No call back for
|
||||
device status change in this example. */
|
||||
status = ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
|
||||
device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
|
||||
string_framework, STRING_FRAMEWORK_LENGTH,
|
||||
language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Initialize the hid class parameters. */
|
||||
hid_parameter.ux_device_class_hid_parameter_report_address = hid_report_descriptor;
|
||||
hid_parameter.ux_device_class_hid_parameter_report_length = HID_REPORT_LENGTH;
|
||||
hid_parameter.ux_device_class_hid_parameter_callback = demo_thread_hid_callback;
|
||||
|
||||
/* Initilize the device hid class. The class is connected with interface 2 */
|
||||
status = ux_device_stack_class_register(_ux_system_slave_class_hid_name, ux_device_class_hid_entry,
|
||||
1,2, (VOID *)&hid_parameter);
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
|
||||
/* Initialize the simulated device controller. */
|
||||
status = _ux_dcd_sim_slave_initialize();
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register all the USB host controllers available in this system */
|
||||
status = ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, ux_hcd_sim_host_initialize,0,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the main host simulation thread. */
|
||||
status = tx_thread_create(&tx_demo_thread_host_simulation, "tx demo host simulation", tx_demo_thread_host_simulation_entry, 0,
|
||||
stack_pointer, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
static UINT ux_hcd_sim_host_entry_filter_device_extraction_test(UX_HCD *hcd, UINT function, VOID *parameter)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
switch(function)
|
||||
{
|
||||
case UX_HCD_GET_PORT_STATUS:
|
||||
|
||||
/* No device on this port. */
|
||||
status = 0;
|
||||
|
||||
/* This is a Full speed device. */
|
||||
status |= UX_PS_DS_FS;
|
||||
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
|
||||
status = _ux_hcd_sim_host_entry(hcd, function, parameter);
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void tx_demo_thread_host_simulation_entry(ULONG arg)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
UX_HCD *hcd;
|
||||
|
||||
/* Find the HID class */
|
||||
status = demo_class_hid_get();
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the HID client */
|
||||
hid_client = hid -> ux_host_class_hid_client;
|
||||
|
||||
/* Check if the instance of the keyboard is live */
|
||||
while (hid_client -> ux_host_class_hid_client_local_instance == UX_NULL)
|
||||
tx_thread_sleep(10);
|
||||
|
||||
hcd = UX_DEVICE_HCD_GET(hid -> ux_host_class_hid_device);
|
||||
|
||||
/* Change the HCD entry function to our filter function. */
|
||||
hcd -> ux_hcd_entry_function = ux_hcd_sim_host_entry_filter_device_extraction_test;
|
||||
|
||||
/* Signal port activity to the enum thread. */
|
||||
hcd -> ux_hcd_root_hub_signal[0] = 1;
|
||||
|
||||
/* Signal enum thread. */
|
||||
_ux_utility_semaphore_put(&_ux_system_host -> ux_system_host_enum_semaphore);
|
||||
|
||||
/* Wait for hid class to shut down. */
|
||||
while(hid -> ux_host_class_hid_state == UX_HOST_CLASS_INSTANCE_LIVE)
|
||||
tx_thread_sleep(10);
|
||||
|
||||
/* Now disconnect the device. */
|
||||
_ux_device_stack_disconnect();
|
||||
|
||||
/* And deinitialize the class. */
|
||||
status = ux_device_stack_class_unregister(_ux_system_slave_class_hid_name, ux_device_class_hid_entry);
|
||||
|
||||
/* Deinitialize the device side of usbx. */
|
||||
_ux_device_stack_uninitialize();
|
||||
|
||||
/* And finally the usbx system resources. */
|
||||
_ux_system_uninitialize();
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
|
||||
static UINT demo_thread_hid_callback(UX_SLAVE_CLASS_HID *class, UX_SLAVE_CLASS_HID_EVENT *event)
|
||||
{
|
||||
return(UX_SUCCESS);
|
||||
}
|
558
test/regression/usbx_hid_keyboard_key_get_test.c
Normal file
558
test/regression/usbx_hid_keyboard_key_get_test.c
Normal file
@ -0,0 +1,558 @@
|
||||
/* This test concentrates on the ux_host_class_hid_keyboard_key_get API. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tx_api.h"
|
||||
#include "ux_api.h"
|
||||
#include "ux_system.h"
|
||||
#include "ux_utility.h"
|
||||
#include "ux_host_class_hid.h"
|
||||
#include "ux_host_class_hid_keyboard.h"
|
||||
#include "ux_device_class_hid.h"
|
||||
#include "ux_device_stack.h"
|
||||
|
||||
/* Define constants. */
|
||||
#define UX_DEMO_DEBUG_SIZE (4096*8)
|
||||
#define UX_DEMO_STACK_SIZE 1024
|
||||
#define UX_DEMO_BUFFER_SIZE 2048
|
||||
#define UX_DEMO_RECEPTION_BUFFER_SIZE 512
|
||||
#define UX_DEMO_XMIT_BUFFER_SIZE 512
|
||||
#define UX_DEMO_RECEPTION_BLOCK_SIZE 64
|
||||
#define UX_DEMO_MEMORY_SIZE (64*1024)
|
||||
|
||||
/* Define local/extern function prototypes. */
|
||||
static void demo_thread_entry(ULONG);
|
||||
static UINT demo_thread_hid_callback(UX_SLAVE_CLASS_HID *, UX_SLAVE_CLASS_HID_EVENT *);
|
||||
static TX_THREAD tx_demo_thread_host_simulation;
|
||||
static TX_THREAD tx_demo_thread_slave_simulation;
|
||||
static void tx_demo_thread_host_simulation_entry(ULONG);
|
||||
static void tx_demo_thread_slave_simulation_entry(ULONG);
|
||||
|
||||
|
||||
/* Define global data structures. */
|
||||
static UCHAR usbx_memory[UX_DEMO_MEMORY_SIZE + (UX_DEMO_STACK_SIZE * 2)];
|
||||
static ULONG error_counter;
|
||||
static TX_THREAD demo_thread;
|
||||
static UX_HOST_CLASS *class_driver;
|
||||
static ULONG class_driver_index;
|
||||
static UX_HOST_CLASS_HID *hid;
|
||||
static UX_HOST_CLASS_HID_CLIENT *hid_client;
|
||||
static UX_HOST_CLASS_HID_KEYBOARD *keyboard;
|
||||
static UINT status;
|
||||
static UINT transfer_completed;
|
||||
static ULONG requested_length;
|
||||
static TX_SEMAPHORE demo_semaphore;
|
||||
|
||||
static ULONG keyboard_char;
|
||||
static ULONG keyboard_state;
|
||||
static UCHAR keyboard_queue[1024];
|
||||
static ULONG keyboard_queue_index;
|
||||
|
||||
static UX_SLAVE_CLASS_HID_PARAMETER hid_parameter;
|
||||
|
||||
|
||||
#define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED 52
|
||||
static UCHAR device_framework_full_speed[] = {
|
||||
|
||||
/* Device descriptor */
|
||||
0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08,
|
||||
0x81, 0x0A, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x01,
|
||||
|
||||
/* Configuration descriptor */
|
||||
0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x00, 0xc0,
|
||||
0x32,
|
||||
|
||||
/* Interface descriptor */
|
||||
0x09, 0x04, 0x02, 0x00, 0x01, 0x03, 0x00, 0x00,
|
||||
0x00,
|
||||
|
||||
/* HID descriptor */
|
||||
0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, 0x3f,
|
||||
0x00,
|
||||
|
||||
/* Endpoint descriptor (Interrupt) */
|
||||
0x07, 0x05, 0x82, 0x03, 0x08, 0x00, 0x08
|
||||
|
||||
};
|
||||
|
||||
|
||||
#define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED 62
|
||||
static UCHAR device_framework_high_speed[] = {
|
||||
|
||||
/* Device descriptor */
|
||||
0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
|
||||
0x0a, 0x07, 0x25, 0x40, 0x01, 0x00, 0x01, 0x02,
|
||||
0x03, 0x01,
|
||||
|
||||
/* Device qualifier descriptor */
|
||||
0x0a, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
|
||||
0x01, 0x00,
|
||||
|
||||
/* Configuration descriptor */
|
||||
0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x00, 0xc0,
|
||||
0x32,
|
||||
|
||||
/* Interface descriptor */
|
||||
0x09, 0x04, 0x02, 0x00, 0x01, 0x03, 0x00, 0x00,
|
||||
0x00,
|
||||
|
||||
/* HID descriptor */
|
||||
0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, 0x3f,
|
||||
0x00,
|
||||
|
||||
/* Endpoint descriptor (Interrupt) */
|
||||
0x07, 0x05, 0x82, 0x03, 0x08, 0x00, 0x08
|
||||
|
||||
};
|
||||
|
||||
|
||||
/* String Device Framework :
|
||||
Byte 0 and 1 : Word containing the language ID : 0x0904 for US
|
||||
Byte 2 : Byte containing the index of the descriptor
|
||||
Byte 3 : Byte containing the length of the descriptor string
|
||||
*/
|
||||
|
||||
#define STRING_FRAMEWORK_LENGTH 40
|
||||
static UCHAR string_framework[] = {
|
||||
|
||||
/* Manufacturer string descriptor : Index 1 */
|
||||
0x09, 0x04, 0x01, 0x0c,
|
||||
0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
|
||||
0x6f, 0x67, 0x69, 0x63,
|
||||
|
||||
/* Product string descriptor : Index 2 */
|
||||
0x09, 0x04, 0x02, 0x0c,
|
||||
0x55, 0x53, 0x42, 0x20, 0x4b, 0x65, 0x79, 0x62,
|
||||
0x6f, 0x61, 0x72, 0x64,
|
||||
|
||||
/* Serial Number string descriptor : Index 3 */
|
||||
0x09, 0x04, 0x03, 0x04,
|
||||
0x30, 0x30, 0x30, 0x31
|
||||
};
|
||||
|
||||
|
||||
/* Multiple languages are supported on the device, to add
|
||||
a language besides english, the unicode language code must
|
||||
be appended to the language_id_framework array and the length
|
||||
adjusted accordingly. */
|
||||
#define LANGUAGE_ID_FRAMEWORK_LENGTH 2
|
||||
static UCHAR language_id_framework[] = {
|
||||
|
||||
/* English. */
|
||||
0x09, 0x04
|
||||
};
|
||||
|
||||
#define HID_KEYBOARD_REPORT_LENGTH 63
|
||||
static UCHAR hid_keyboard_report[HID_KEYBOARD_REPORT_LENGTH] = {
|
||||
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||
0x09, 0x06, // USAGE (Keyboard)
|
||||
0xa1, 0x01, // COLLECTION (Application)
|
||||
0x05, 0x07, // USAGE_PAGE (Keyboard)
|
||||
0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)
|
||||
0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x25, 0x01, // LOGICAL_MAXIMUM (1)
|
||||
0x75, 0x01, // REPORT_SIZE (1)
|
||||
0x95, 0x08, // REPORT_COUNT (8)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x81, 0x03, // INPUT (Cnst,Var,Abs)
|
||||
0x95, 0x05, // REPORT_COUNT (5)
|
||||
0x75, 0x01, // REPORT_SIZE (1)
|
||||
0x05, 0x08, // USAGE_PAGE (LEDs)
|
||||
0x19, 0x01, // USAGE_MINIMUM (Num Lock)
|
||||
0x29, 0x05, // USAGE_MAXIMUM (Kana)
|
||||
0x91, 0x02, // OUTPUT (Data,Var,Abs)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x75, 0x03, // REPORT_SIZE (3)
|
||||
0x91, 0x03, // OUTPUT (Cnst,Var,Abs)
|
||||
0x95, 0x06, // REPORT_COUNT (6)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x25, 0x65, // LOGICAL_MAXIMUM (101)
|
||||
0x05, 0x07, // USAGE_PAGE (Keyboard)
|
||||
0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
|
||||
0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)
|
||||
0x81, 0x00, // INPUT (Data,Ary,Abs)
|
||||
0xc0 // END_COLLECTION
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* Define the ISR dispatch. */
|
||||
|
||||
extern VOID (*test_isr_dispatch)(void);
|
||||
|
||||
|
||||
/* Prototype for test control return. */
|
||||
|
||||
void test_control_return(UINT status);
|
||||
|
||||
|
||||
/* Define the ISR dispatch routine. */
|
||||
|
||||
static void test_isr(void)
|
||||
{
|
||||
|
||||
/* For further expansion of interrupt-level testing. */
|
||||
}
|
||||
|
||||
|
||||
static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
|
||||
{
|
||||
|
||||
/* @BUG_FIX_PENDING: ux_dcd_sim_slave_function.c doesn't support transfer aborts, which happen during device unregistration of a class. */
|
||||
if (error_code != UX_FUNCTION_NOT_SUPPORTED)
|
||||
{
|
||||
|
||||
/* Failed test. */
|
||||
printf("Error on line %d, system_level: %d, system_context: %d, error code: %d\n", __LINE__, system_level, system_context, error_code);
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_hid_keyboard_key_get_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR * stack_pointer;
|
||||
CHAR * memory_pointer;
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running HID Keyboard Key Get Test................................... ");
|
||||
|
||||
/* Initialize the free memory pointer */
|
||||
stack_pointer = (CHAR *) usbx_memory;
|
||||
memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
|
||||
|
||||
/* Initialize USBX. Memory */
|
||||
status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the error callback. */
|
||||
_ux_utility_error_callback_register(error_callback);
|
||||
|
||||
/* The code below is required for installing the host portion of USBX */
|
||||
status = ux_host_stack_initialize(UX_NULL);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = ux_host_stack_class_register(_ux_system_host_class_hid_name, ux_host_class_hid_entry);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the HID client(s). */
|
||||
status = ux_host_class_hid_client_register(_ux_system_host_class_hid_client_keyboard_name, ux_host_class_hid_keyboard_entry);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* The code below is required for installing the device portion of USBX. No call back for
|
||||
device status change in this example. */
|
||||
status = ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
|
||||
device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
|
||||
string_framework, STRING_FRAMEWORK_LENGTH,
|
||||
language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Initialize the hid class parameters for a keyboard. */
|
||||
hid_parameter.ux_device_class_hid_parameter_report_address = hid_keyboard_report;
|
||||
hid_parameter.ux_device_class_hid_parameter_report_length = HID_KEYBOARD_REPORT_LENGTH;
|
||||
hid_parameter.ux_device_class_hid_parameter_callback = demo_thread_hid_callback;
|
||||
|
||||
/* Initilize the device hid class. The class is connected with interface 2 */
|
||||
status = ux_device_stack_class_register(_ux_system_slave_class_hid_name, ux_device_class_hid_entry,
|
||||
1,2, (VOID *)&hid_parameter);
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
|
||||
/* Initialize the simulated device controller. */
|
||||
status = _ux_dcd_sim_slave_initialize();
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register all the USB host controllers available in this system */
|
||||
status = ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, ux_hcd_sim_host_initialize,0,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the main host simulation thread. */
|
||||
status = tx_thread_create(&tx_demo_thread_host_simulation, "tx demo host simulation", tx_demo_thread_host_simulation_entry, 0,
|
||||
stack_pointer, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the main demo thread. */
|
||||
status = tx_thread_create(&tx_demo_thread_slave_simulation, "tx demo slave simulation", tx_demo_thread_slave_simulation_entry, 0,
|
||||
stack_pointer + UX_DEMO_STACK_SIZE, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static UINT demo_class_hid_get(void)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
UX_HOST_CLASS *class;
|
||||
|
||||
/* Find the main HID container */
|
||||
status = ux_host_stack_class_get(_ux_system_host_class_hid_name, &class);
|
||||
if (status != UX_SUCCESS)
|
||||
return(status);
|
||||
|
||||
/* We get the first instance of the hid device */
|
||||
do
|
||||
{
|
||||
|
||||
status = ux_host_stack_class_instance_get(class, 0, (void **) &hid);
|
||||
tx_thread_sleep(10);
|
||||
} while (status != UX_SUCCESS);
|
||||
|
||||
/* We still need to wait for the hid status to be live */
|
||||
while (hid -> ux_host_class_hid_state != UX_HOST_CLASS_INSTANCE_LIVE)
|
||||
tx_thread_sleep(10);
|
||||
|
||||
return(UX_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
static void tx_demo_thread_host_simulation_entry(ULONG arg)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
UINT max_hid_loop;
|
||||
ALIGN_TYPE tmp;
|
||||
ULONG key, state;
|
||||
|
||||
/* Initilize max loop value. Make sure we wrap. */
|
||||
max_hid_loop = 2*UX_HOST_CLASS_HID_KEYBOARD_USAGE_ARRAY_LENGTH;
|
||||
|
||||
/* Find the HID class */
|
||||
status = demo_class_hid_get();
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
/* HID Keyboard basic test error. */
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the HID client */
|
||||
hid_client = hid -> ux_host_class_hid_client;
|
||||
|
||||
/* Check if the instance of the keyboard is live */
|
||||
while (hid_client -> ux_host_class_hid_client_local_instance == UX_NULL)
|
||||
tx_thread_sleep(10);
|
||||
|
||||
/* Get the keyboard instance */
|
||||
keyboard = (UX_HOST_CLASS_HID_KEYBOARD *)hid_client -> ux_host_class_hid_client_local_instance;
|
||||
|
||||
/**************************************************/
|
||||
/** Test case: _ux_host_stack_class_instance_verify() fails. **/
|
||||
/**************************************************/
|
||||
|
||||
/* Set the keyboard's class container to NULL. */
|
||||
tmp = (ALIGN_TYPE)keyboard -> ux_host_class_hid_keyboard_hid;
|
||||
keyboard -> ux_host_class_hid_keyboard_hid = UX_NULL;
|
||||
|
||||
if(ux_host_class_hid_keyboard_key_get(keyboard, &key, &state) != UX_HOST_CLASS_INSTANCE_UNKNOWN)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Restore state for next test. */
|
||||
keyboard -> ux_host_class_hid_keyboard_hid = (UX_HOST_CLASS_HID *)tmp;
|
||||
|
||||
/**************************************************/
|
||||
/** Test case: if ((array_tail+2) >= array_end) (wraps) **/
|
||||
/**************************************************/
|
||||
|
||||
/* Init the keyboard queue index. */
|
||||
keyboard_queue_index = 0;
|
||||
|
||||
while (max_hid_loop--)
|
||||
{
|
||||
/* Get a key/state from the keyboard. */
|
||||
status = ux_host_class_hid_keyboard_key_get(keyboard, &keyboard_char, &keyboard_state);
|
||||
|
||||
/* Check if there is something. */
|
||||
if (status == UX_SUCCESS)
|
||||
{
|
||||
/* We have a character in the queue. */
|
||||
keyboard_queue[keyboard_queue_index] = (UCHAR) keyboard_char;
|
||||
|
||||
/* Can we accept more ? */
|
||||
if(keyboard_queue_index < 1024)
|
||||
keyboard_queue_index++;
|
||||
|
||||
}
|
||||
|
||||
tx_thread_sleep(1);
|
||||
}
|
||||
|
||||
/* Now disconnect the device. */
|
||||
_ux_device_stack_disconnect();
|
||||
|
||||
/* And deinitialize the class. */
|
||||
status = ux_device_stack_class_unregister(_ux_system_slave_class_hid_name, ux_device_class_hid_entry);
|
||||
|
||||
/* Deinitialize the device side of usbx. */
|
||||
_ux_device_stack_uninitialize();
|
||||
|
||||
/* And finally the usbx system resources. */
|
||||
_ux_system_uninitialize();
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
|
||||
static UINT demo_thread_hid_callback(UX_SLAVE_CLASS_HID *class, UX_SLAVE_CLASS_HID_EVENT *event)
|
||||
{
|
||||
return(UX_SUCCESS);
|
||||
}
|
||||
|
||||
static void tx_demo_thread_slave_simulation_entry(ULONG arg)
|
||||
{
|
||||
|
||||
UX_SLAVE_DEVICE *device;
|
||||
UX_SLAVE_INTERFACE *interface;
|
||||
UX_SLAVE_CLASS_HID *hid;
|
||||
UX_SLAVE_CLASS_HID_EVENT hid_event;
|
||||
UCHAR key;
|
||||
|
||||
/* Get the pointer to the device. */
|
||||
device = &_ux_system_slave -> ux_system_slave_device;
|
||||
|
||||
/* Set the first key to 'a' which is 04. */
|
||||
key = 0x04;
|
||||
|
||||
/* reset the HID event structure. */
|
||||
ux_utility_memory_set(&hid_event, 0, sizeof(UX_SLAVE_CLASS_HID_EVENT));
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Is the device configured ? */
|
||||
while (device -> ux_slave_device_state != UX_DEVICE_CONFIGURED)
|
||||
|
||||
/* Then wait. */
|
||||
tx_thread_sleep(10);
|
||||
|
||||
/* Until the device stays configured. */
|
||||
while (device -> ux_slave_device_state == UX_DEVICE_CONFIGURED)
|
||||
{
|
||||
|
||||
/* Get the interface. We use the first interface, this is a simple device. */
|
||||
interface = device -> ux_slave_device_first_interface;
|
||||
|
||||
/* Form that interface, derive the HID owner. */
|
||||
hid = interface -> ux_slave_interface_class_instance;
|
||||
|
||||
/* Wait for 2 seconds. */
|
||||
ux_utility_thread_sleep(2);
|
||||
|
||||
/* Then insert a key into the keyboard event. Length is fixed to 8. */
|
||||
hid_event.ux_device_class_hid_event_length = 8;
|
||||
|
||||
/* First byte is a modifier byte. */
|
||||
hid_event.ux_device_class_hid_event_buffer[0] = 0;
|
||||
|
||||
/* Second byte is reserved. */
|
||||
hid_event.ux_device_class_hid_event_buffer[1] = 0;
|
||||
|
||||
/* The 6 next bytes are keys. We only have one key here. */
|
||||
hid_event.ux_device_class_hid_event_buffer[2] = key;
|
||||
|
||||
/* Set the keyboard event. */
|
||||
ux_device_class_hid_event_set(hid, &hid_event);
|
||||
|
||||
/* Next event has the key depressed. */
|
||||
hid_event.ux_device_class_hid_event_buffer[2] = 0;
|
||||
|
||||
/* Length is fixed to 8. */
|
||||
hid_event.ux_device_class_hid_event_length = 8;
|
||||
|
||||
/* Set the keyboard event. */
|
||||
ux_device_class_hid_event_set(hid, &hid_event);
|
||||
|
||||
/* Are we at the end of alphabet ? */
|
||||
if (key != (0x04 + 26))
|
||||
|
||||
/* Next key. */
|
||||
key++;
|
||||
|
||||
else
|
||||
|
||||
/* Start over again. */
|
||||
key = 0x04;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
1194
test/regression/usbx_hid_keyboard_key_test.c
Normal file
1194
test/regression/usbx_hid_keyboard_key_test.c
Normal file
File diff suppressed because it is too large
Load Diff
722
test/regression/usbx_hid_keyboard_key_with_report_id_test.c
Normal file
722
test/regression/usbx_hid_keyboard_key_with_report_id_test.c
Normal file
@ -0,0 +1,722 @@
|
||||
/* This file tests that the host correctly receives the keys the device sends to it when
|
||||
the report descriptor defines a non-zero report id. */
|
||||
|
||||
#include "usbx_test_common_hid.h"
|
||||
|
||||
#include "ux_host_class_hid_keyboard.h"
|
||||
|
||||
static UCHAR ux_host_class_hid_keyboard_regular_array[] =
|
||||
{
|
||||
0,0,0,0,
|
||||
'a','b','c','d','e','f','g','h','i','j', 'k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
|
||||
'1','2','3','4','5','6','7','8','9','0',
|
||||
0x0d,0x1b,0x08,0x07,0x20,'-','=','[',']',
|
||||
'\\','#',';',0x27,'`',',','.','/',0xf0,
|
||||
0xbb,0xbc,0xbd,0xbe,0xbf,0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,
|
||||
0x00,0xf1,0x00,0xd2,0xc7,0xc9,0xd3,0xcf,0xd1,0xcd,0xcd,0xd0,0xc8,0xf2,
|
||||
'/','*','-','+',
|
||||
0x0d,'1','2','3','4','5','6','7','8','9','0','.','\\',0x00,0x00,'=',
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
};
|
||||
|
||||
static UCHAR ux_host_class_hid_keyboard_shift_array[] =
|
||||
{
|
||||
0,0,0,0,
|
||||
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
|
||||
'!','@','#','$','%','^','&','*','(',')',
|
||||
0x0d,0x1b,0x08,0x07,0x20,'_','+','{','}',
|
||||
'|','~',':','"','~','<','>','?',0xf0,
|
||||
0xbb,0xbc,0xbd,0xbe,0xbf,0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,
|
||||
0x00,0xf1,0x00,0xd2,0xc7,0xc9,0xd3,0xcf,0xd1,0xcd,0xcd,0xd0,0xc8,0xf2,
|
||||
'/','*','-','+',
|
||||
0x0d,'1','2','3','4','5','6','7','8','9','0','.','\\',0x00,0x00,'=',
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
};
|
||||
|
||||
static UCHAR ux_host_class_hid_keyboard_numlock_on_array[] =
|
||||
{
|
||||
'/','*','-','+',
|
||||
0x0d,'1','2','3','4','5','6','7','8','9','0','.','\\',0x00,0x00,'=',
|
||||
};
|
||||
|
||||
static UCHAR ux_host_class_hid_keyboard_numlock_off_array[] =
|
||||
{
|
||||
'/','*','-','+',
|
||||
0x0d,0xcf,0xd0,0xd1,0xcb,'5',0xcd,0xc7,0xc8,0xc9,0xd2,0xd3,'\\',0x00,0x00,'=',
|
||||
};
|
||||
|
||||
|
||||
#define DUMMY_USBX_MEMORY_SIZE (64*1024)
|
||||
static UCHAR dummy_usbx_memory[DUMMY_USBX_MEMORY_SIZE];
|
||||
|
||||
static UCHAR hid_report_descriptor[] = {
|
||||
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||
0x09, 0x06, // USAGE (Keyboard)
|
||||
0xa1, 0x01, // COLLECTION (Application)
|
||||
0x85, 0x01, // REPORT_ID (1)
|
||||
0x05, 0x07, // USAGE_PAGE (Keyboard)
|
||||
0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)
|
||||
0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x25, 0x01, // LOGICAL_MAXIMUM (1)
|
||||
0x75, 0x01, // REPORT_SIZE (1)
|
||||
0x95, 0x08, // REPORT_COUNT (8)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x81, 0x03, // INPUT (Cnst,Var,Abs)
|
||||
0x95, 0x05, // REPORT_COUNT (5)
|
||||
0x75, 0x01, // REPORT_SIZE (1)
|
||||
0x05, 0x08, // USAGE_PAGE (LEDs)
|
||||
0x19, 0x01, // USAGE_MINIMUM (Num Lock)
|
||||
0x29, 0x05, // USAGE_MAXIMUM (Kana)
|
||||
0x91, 0x02, // OUTPUT (Data,Var,Abs)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x75, 0x03, // REPORT_SIZE (3)
|
||||
0x91, 0x03, // OUTPUT (Cnst,Var,Abs)
|
||||
0x95, 0x06, // REPORT_COUNT (6)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x25, ARRAY_COUNT(ux_host_class_hid_keyboard_regular_array), // LOGICAL_MAXIMUM ()
|
||||
0x05, 0x07, // USAGE_PAGE (Keyboard)
|
||||
0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
|
||||
0x29, ARRAY_COUNT(ux_host_class_hid_keyboard_regular_array), // USAGE_MAXIMUM ()
|
||||
0x81, 0x00, // INPUT (Data,Ary,Abs)
|
||||
0xc0 // END_COLLECTION
|
||||
};
|
||||
#define HID_REPORT_LENGTH sizeof(hid_report_descriptor)/sizeof(hid_report_descriptor[0])
|
||||
|
||||
|
||||
#define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED 52
|
||||
static UCHAR device_framework_full_speed[DEVICE_FRAMEWORK_LENGTH_FULL_SPEED] = {
|
||||
|
||||
/* Device descriptor */
|
||||
0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08,
|
||||
0x81, 0x0A, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x01,
|
||||
|
||||
/* Configuration descriptor */
|
||||
0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x00, 0xc0,
|
||||
0x32,
|
||||
|
||||
/* Interface descriptor */
|
||||
0x09, 0x04, 0x02, 0x00, 0x01, 0x03, 0x00, 0x00,
|
||||
0x00,
|
||||
|
||||
/* HID descriptor */
|
||||
0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(HID_REPORT_LENGTH),
|
||||
MSB(HID_REPORT_LENGTH),
|
||||
|
||||
/* Endpoint descriptor (Interrupt) */
|
||||
0x07, 0x05, 0x82, 0x03, 0x08, 0x00, 0x08
|
||||
|
||||
};
|
||||
|
||||
|
||||
#define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED 62
|
||||
static UCHAR device_framework_high_speed[DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED] = {
|
||||
|
||||
/* Device descriptor */
|
||||
0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
|
||||
0x0a, 0x07, 0x25, 0x40, 0x01, 0x00, 0x01, 0x02,
|
||||
0x03, 0x01,
|
||||
|
||||
/* Device qualifier descriptor */
|
||||
0x0a, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
|
||||
0x01, 0x00,
|
||||
|
||||
/* Configuration descriptor */
|
||||
0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x00, 0xc0,
|
||||
0x32,
|
||||
|
||||
/* Interface descriptor */
|
||||
0x09, 0x04, 0x02, 0x00, 0x01, 0x03, 0x00, 0x00,
|
||||
0x00,
|
||||
|
||||
/* HID descriptor */
|
||||
0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(HID_REPORT_LENGTH),
|
||||
MSB(HID_REPORT_LENGTH),
|
||||
|
||||
/* Endpoint descriptor (Interrupt) */
|
||||
0x07, 0x05, 0x82, 0x03, 0x08, 0x00, 0x08
|
||||
|
||||
};
|
||||
|
||||
|
||||
/* String Device Framework :
|
||||
Byte 0 and 1 : Word containing the language ID : 0x0904 for US
|
||||
Byte 2 : Byte containing the index of the descriptor
|
||||
Byte 3 : Byte containing the length of the descriptor string
|
||||
*/
|
||||
|
||||
#define STRING_FRAMEWORK_LENGTH 40
|
||||
static UCHAR string_framework[] = {
|
||||
|
||||
/* Manufacturer string descriptor : Index 1 */
|
||||
0x09, 0x04, 0x01, 0x0c,
|
||||
0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
|
||||
0x6f, 0x67, 0x69, 0x63,
|
||||
|
||||
/* Product string descriptor : Index 2 */
|
||||
0x09, 0x04, 0x02, 0x0c,
|
||||
0x55, 0x53, 0x42, 0x20, 0x4b, 0x65, 0x79, 0x62,
|
||||
0x6f, 0x61, 0x72, 0x64,
|
||||
|
||||
/* Serial Number string descriptor : Index 3 */
|
||||
0x09, 0x04, 0x03, 0x04,
|
||||
0x30, 0x30, 0x30, 0x31
|
||||
};
|
||||
|
||||
|
||||
/* Multiple languages are supported on the device, to add
|
||||
a language besides english, the unicode language code must
|
||||
be appended to the language_id_framework array and the length
|
||||
adjusted accordingly. */
|
||||
#define LANGUAGE_ID_FRAMEWORK_LENGTH 2
|
||||
static UCHAR language_id_framework[] = {
|
||||
|
||||
/* English. */
|
||||
0x09, 0x04
|
||||
};
|
||||
|
||||
|
||||
UINT _ux_hcd_sim_host_entry(UX_HCD *hcd, UINT function, VOID *parameter);
|
||||
|
||||
|
||||
static UINT ux_system_host_change_function(ULONG a, UX_HOST_CLASS *b, VOID *c)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
|
||||
{
|
||||
|
||||
/* Failed test. */
|
||||
printf("Error on line %d, system_level: %d, system_context: %d, error code: %d\n", __LINE__, system_level, system_context, error_code);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_hid_keyboard_key_with_report_id_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR * stack_pointer;
|
||||
CHAR * memory_pointer;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running HID Keyboard Key With Report ID Test....................... ");
|
||||
|
||||
/* Initialize the free memory pointer */
|
||||
stack_pointer = (CHAR *) usbx_memory;
|
||||
memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
|
||||
|
||||
/* Initialize USBX. Memory */
|
||||
status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the error callback. */
|
||||
_ux_utility_error_callback_register(error_callback);
|
||||
|
||||
/* The code below is required for installing the host portion of USBX */
|
||||
status = ux_host_stack_initialize(ux_system_host_change_function);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = ux_host_stack_class_register(_ux_system_host_class_hid_name, ux_host_class_hid_entry);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the HID client(s). */
|
||||
status = ux_host_class_hid_client_register(_ux_system_host_class_hid_client_keyboard_name, ux_host_class_hid_keyboard_entry);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* The code below is required for installing the device portion of USBX. No call back for
|
||||
device status change in this example. */
|
||||
status = ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
|
||||
device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
|
||||
string_framework, STRING_FRAMEWORK_LENGTH,
|
||||
language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Initialize the hid class parameters. */
|
||||
hid_parameter.ux_device_class_hid_parameter_report_address = hid_report_descriptor;
|
||||
hid_parameter.ux_device_class_hid_parameter_report_length = HID_REPORT_LENGTH;
|
||||
hid_parameter.ux_device_class_hid_parameter_callback = demo_thread_hid_callback;
|
||||
hid_parameter.ux_device_class_hid_parameter_report_id = 1;
|
||||
|
||||
/* Initilize the device hid class. The class is connected with interface 2 */
|
||||
status = ux_device_stack_class_register(_ux_system_slave_class_hid_name, ux_device_class_hid_entry,
|
||||
1,2, (VOID *)&hid_parameter);
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Initialize the simulated device controller. */
|
||||
status = _ux_dcd_sim_slave_initialize();
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register all the USB host controllers available in this system */
|
||||
status = ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, ux_hcd_sim_host_initialize,0,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the main host simulation thread. */
|
||||
status = tx_thread_create(&tx_demo_thread_host_simulation, "tx demo host simulation", tx_demo_thread_host_simulation_entry, 0,
|
||||
stack_pointer, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the main demo thread. */
|
||||
status = tx_thread_create(&tx_demo_thread_slave_simulation, "tx demo slave simulation", tx_demo_thread_slave_simulation_entry, 0,
|
||||
stack_pointer + UX_DEMO_STACK_SIZE, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Running HID Keyboard Basic Functionality Test....................... ERROR #10\n");
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void tx_demo_thread_host_simulation_entry(ULONG arg)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
UX_HOST_CLASS_HID_KEYBOARD *keyboard;
|
||||
ULONG keyboard_key;
|
||||
ULONG keyboard_state;
|
||||
ULONG expected_key;
|
||||
ULONG num_keypad_keys;
|
||||
ULONG i;
|
||||
|
||||
|
||||
/* Find the HID class */
|
||||
status = demo_class_hid_get();
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the HID client */
|
||||
hid_client = hid -> ux_host_class_hid_client;
|
||||
|
||||
/* Check if the instance of the keyboard is live */
|
||||
while (hid_client -> ux_host_class_hid_client_local_instance == UX_NULL)
|
||||
tx_thread_sleep(10);
|
||||
|
||||
/* Get the keyboard instance */
|
||||
keyboard = (UX_HOST_CLASS_HID_KEYBOARD *)hid_client -> ux_host_class_hid_client_local_instance;
|
||||
|
||||
/** Test receiving maximum keys at once. **/
|
||||
|
||||
for (i = 4; i < 10; i++)
|
||||
{
|
||||
|
||||
while (ux_host_class_hid_keyboard_key_get(keyboard, &keyboard_key, &keyboard_state) != UX_SUCCESS)
|
||||
ux_utility_thread_sleep(1);
|
||||
|
||||
expected_key = ux_host_class_hid_keyboard_regular_array[i];
|
||||
|
||||
if (keyboard_key != expected_key)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
/** Test regular keys. **/
|
||||
|
||||
for (i = 1; i < ARRAY_COUNT(ux_host_class_hid_keyboard_regular_array); i++)
|
||||
{
|
||||
|
||||
/* These keys change the keyboard state and are not retrievable. */
|
||||
if (i == UX_HID_LED_KEY_CAPS_LOCK ||
|
||||
i == UX_HID_LED_KEY_NUM_LOCK ||
|
||||
i == UX_HID_LED_KEY_SCROLL_LOCK)
|
||||
continue;
|
||||
|
||||
while (ux_host_class_hid_keyboard_key_get(keyboard, &keyboard_key, &keyboard_state) != UX_SUCCESS)
|
||||
ux_utility_thread_sleep(1);
|
||||
|
||||
expected_key = ux_host_class_hid_keyboard_regular_array[i];
|
||||
|
||||
if (keyboard_key != expected_key)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
/** Test shift keys. **/
|
||||
|
||||
for (i = 1; i < ARRAY_COUNT(ux_host_class_hid_keyboard_regular_array); i++)
|
||||
{
|
||||
|
||||
/* These keys change the keyboard state and are not retrievable. */
|
||||
if (i == UX_HID_LED_KEY_CAPS_LOCK ||
|
||||
i == UX_HID_LED_KEY_NUM_LOCK ||
|
||||
i == UX_HID_LED_KEY_SCROLL_LOCK)
|
||||
continue;
|
||||
|
||||
while (ux_host_class_hid_keyboard_key_get(keyboard, &keyboard_key, &keyboard_state) != UX_SUCCESS)
|
||||
ux_utility_thread_sleep(1);
|
||||
|
||||
expected_key = ux_host_class_hid_keyboard_shift_array[i];
|
||||
|
||||
if (keyboard_key != expected_key)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
/** Test numlock on keys. **/
|
||||
|
||||
num_keypad_keys = (UX_HID_KEYBOARD_KEYS_KEYPAD_UPPER_RANGE - UX_HID_KEYBOARD_KEYS_KEYPAD_LOWER_RANGE) + 1;
|
||||
|
||||
for (i = 0; i < ARRAY_COUNT(ux_host_class_hid_keyboard_numlock_on_array); i++)
|
||||
{
|
||||
|
||||
while (ux_host_class_hid_keyboard_key_get(keyboard, &keyboard_key, &keyboard_state) != UX_SUCCESS)
|
||||
ux_utility_thread_sleep(2);
|
||||
|
||||
expected_key = ux_host_class_hid_keyboard_numlock_on_array[i];
|
||||
|
||||
if (keyboard_key != ux_host_class_hid_keyboard_numlock_on_array[i])
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
/** Test numlock off keys. **/
|
||||
|
||||
for (i = 0; i < ARRAY_COUNT(ux_host_class_hid_keyboard_numlock_off_array); i++)
|
||||
{
|
||||
|
||||
while (ux_host_class_hid_keyboard_key_get(keyboard, &keyboard_key, &keyboard_state) != UX_SUCCESS)
|
||||
ux_utility_thread_sleep(2);
|
||||
|
||||
expected_key = ux_host_class_hid_keyboard_numlock_off_array[i];
|
||||
|
||||
if (keyboard_key != ux_host_class_hid_keyboard_numlock_off_array[i])
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
/** Test keyboard on states. **/
|
||||
|
||||
while (ux_host_class_hid_keyboard_key_get(keyboard, &keyboard_key, &keyboard_state) != UX_SUCCESS)
|
||||
ux_utility_thread_sleep(2);
|
||||
|
||||
/* Ensure every bit is enabled (represented by 0xff07 (search for "Define HID Keyboard States." in ux_host_class_hid_keyboard.h)). */
|
||||
if (keyboard_state != 0xff07)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/** Test keyboard off states. **/
|
||||
|
||||
while (ux_host_class_hid_keyboard_key_get(keyboard, &keyboard_key, &keyboard_state) != UX_SUCCESS)
|
||||
ux_utility_thread_sleep(2);
|
||||
|
||||
/* Ensure every bit is disabled. */
|
||||
if (keyboard_state != 0x0000)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now disconnect the device. */
|
||||
_ux_device_stack_disconnect();
|
||||
|
||||
/* And deinitialize the class. */
|
||||
status = ux_device_stack_class_unregister(_ux_system_slave_class_hid_name, ux_device_class_hid_entry);
|
||||
|
||||
/* Deinitialize the device side of usbx. */
|
||||
_ux_device_stack_uninitialize();
|
||||
|
||||
/* And finally the usbx system resources. */
|
||||
_ux_system_uninitialize();
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
|
||||
static UINT demo_thread_hid_callback(UX_SLAVE_CLASS_HID *class, UX_SLAVE_CLASS_HID_EVENT *event)
|
||||
{
|
||||
return(UX_SUCCESS);
|
||||
}
|
||||
|
||||
static void tx_demo_thread_slave_simulation_entry(ULONG arg)
|
||||
{
|
||||
|
||||
UX_SLAVE_DEVICE *device;
|
||||
UX_SLAVE_INTERFACE *interface;
|
||||
UX_SLAVE_CLASS_HID *hid;
|
||||
UX_SLAVE_CLASS_HID_EVENT hid_event;
|
||||
UINT i;
|
||||
|
||||
/* Get the pointer to the device. */
|
||||
device = &_ux_system_slave -> ux_system_slave_device;
|
||||
|
||||
/* reset the HID event structure. */
|
||||
ux_utility_memory_set(&hid_event, 0, sizeof(UX_SLAVE_CLASS_HID_EVENT));
|
||||
|
||||
/* Is the device configured ? */
|
||||
while (device->ux_slave_device_state != UX_DEVICE_CONFIGURED)
|
||||
|
||||
/* Then wait. */
|
||||
tx_thread_sleep(10);
|
||||
|
||||
/* Get the interface. We use the first interface, this is a simple device. */
|
||||
interface = device->ux_slave_device_first_interface;
|
||||
|
||||
/* Form that interface, derive the HID owner. */
|
||||
hid = interface->ux_slave_interface_class_instance;
|
||||
|
||||
hid_event.ux_device_class_hid_event_report_id = 1;
|
||||
|
||||
/** Test receiving maximum keys at once. **/
|
||||
|
||||
hid_event.ux_device_class_hid_event_length = 8;
|
||||
|
||||
/* Modification byte. */
|
||||
hid_event.ux_device_class_hid_event_buffer[0] = 0;
|
||||
|
||||
/* Reserved byte. */
|
||||
hid_event.ux_device_class_hid_event_buffer[1] = 0;
|
||||
|
||||
/* Set keys. */
|
||||
for (i = 0; i < 6; i++)
|
||||
hid_event.ux_device_class_hid_event_buffer[2 + i] = 4 + i;
|
||||
|
||||
ux_device_class_hid_event_set(hid, &hid_event);
|
||||
|
||||
ux_utility_thread_sleep(2);
|
||||
|
||||
/** Test regular keys. Only go up to maximum value specified by report descriptor. **/
|
||||
|
||||
for (i = 1; i < ARRAY_COUNT(ux_host_class_hid_keyboard_regular_array); i++)
|
||||
{
|
||||
|
||||
/* These keys change the keyboard state and are not retrievable. */
|
||||
if (i == UX_HID_LED_KEY_CAPS_LOCK ||
|
||||
i == UX_HID_LED_KEY_NUM_LOCK ||
|
||||
i == UX_HID_LED_KEY_SCROLL_LOCK)
|
||||
continue;
|
||||
|
||||
hid_event.ux_device_class_hid_event_length = 8;
|
||||
|
||||
/* Modification byte. */
|
||||
hid_event.ux_device_class_hid_event_buffer[0] = 0;
|
||||
|
||||
/* Reserved byte. */
|
||||
hid_event.ux_device_class_hid_event_buffer[1] = 0;
|
||||
|
||||
/* Key byte. */
|
||||
hid_event.ux_device_class_hid_event_buffer[2] = i;
|
||||
|
||||
ux_device_class_hid_event_set(hid, &hid_event);
|
||||
|
||||
ux_utility_thread_sleep(2);
|
||||
}
|
||||
|
||||
/** Test shift keys. Only go up to maximum value specified by report descriptor. **/
|
||||
|
||||
/* Turn CAPS LOCK on. */
|
||||
hid_event.ux_device_class_hid_event_length = 8;
|
||||
hid_event.ux_device_class_hid_event_buffer[0] = 0;
|
||||
hid_event.ux_device_class_hid_event_buffer[1] = 0;
|
||||
hid_event.ux_device_class_hid_event_buffer[2] = UX_HID_LED_KEY_CAPS_LOCK;
|
||||
ux_device_class_hid_event_set(hid, &hid_event);
|
||||
|
||||
for (i = 1; i < ARRAY_COUNT(ux_host_class_hid_keyboard_regular_array); i++)
|
||||
{
|
||||
|
||||
/* These keys change the keyboard state and are not retrievable. */
|
||||
if (i == UX_HID_LED_KEY_CAPS_LOCK ||
|
||||
i == UX_HID_LED_KEY_NUM_LOCK ||
|
||||
i == UX_HID_LED_KEY_SCROLL_LOCK)
|
||||
continue;
|
||||
|
||||
hid_event.ux_device_class_hid_event_length = 8;
|
||||
|
||||
/* Modification byte. */
|
||||
hid_event.ux_device_class_hid_event_buffer[0] = 0;
|
||||
|
||||
/* Reserved byte. */
|
||||
hid_event.ux_device_class_hid_event_buffer[1] = 0;
|
||||
|
||||
/* Key byte. */
|
||||
hid_event.ux_device_class_hid_event_buffer[2] = i;
|
||||
|
||||
ux_device_class_hid_event_set(hid, &hid_event);
|
||||
|
||||
ux_utility_thread_sleep(2);
|
||||
}
|
||||
|
||||
/* Turn CAPS LOCK off. */
|
||||
hid_event.ux_device_class_hid_event_length = 8;
|
||||
hid_event.ux_device_class_hid_event_buffer[0] = 0;
|
||||
hid_event.ux_device_class_hid_event_buffer[1] = 0;
|
||||
hid_event.ux_device_class_hid_event_buffer[2] = UX_HID_LED_KEY_CAPS_LOCK;
|
||||
ux_device_class_hid_event_set(hid, &hid_event);
|
||||
|
||||
/** Test NUM LOCK on keys. NUM LOCK is on by default. **/
|
||||
|
||||
for (i = UX_HID_KEYBOARD_KEYS_KEYPAD_LOWER_RANGE; i <= UX_HID_KEYBOARD_KEYS_KEYPAD_UPPER_RANGE; i++)
|
||||
{
|
||||
|
||||
hid_event.ux_device_class_hid_event_length = 8;
|
||||
|
||||
/* Modification byte. */
|
||||
hid_event.ux_device_class_hid_event_buffer[0] = 0;
|
||||
|
||||
/* Reserved byte. */
|
||||
hid_event.ux_device_class_hid_event_buffer[1] = 0;
|
||||
|
||||
/* Key byte. */
|
||||
hid_event.ux_device_class_hid_event_buffer[2] = i;
|
||||
|
||||
ux_device_class_hid_event_set(hid, &hid_event);
|
||||
|
||||
ux_utility_thread_sleep(2);
|
||||
}
|
||||
|
||||
/** Test NUM LOCK off keys. **/
|
||||
|
||||
/* Turn NUM LOCK off. */
|
||||
hid_event.ux_device_class_hid_event_length = 8;
|
||||
hid_event.ux_device_class_hid_event_buffer[0] = 0;
|
||||
hid_event.ux_device_class_hid_event_buffer[1] = 0;
|
||||
hid_event.ux_device_class_hid_event_buffer[2] = UX_HID_LED_KEY_NUM_LOCK;
|
||||
ux_device_class_hid_event_set(hid, &hid_event);
|
||||
|
||||
for (i = UX_HID_KEYBOARD_KEYS_KEYPAD_LOWER_RANGE; i <= UX_HID_KEYBOARD_KEYS_KEYPAD_UPPER_RANGE; i++)
|
||||
{
|
||||
|
||||
hid_event.ux_device_class_hid_event_length = 8;
|
||||
|
||||
/* Modification byte. */
|
||||
hid_event.ux_device_class_hid_event_buffer[0] = 0;
|
||||
|
||||
/* Reserved byte. */
|
||||
hid_event.ux_device_class_hid_event_buffer[1] = 0;
|
||||
|
||||
/* Key byte. */
|
||||
hid_event.ux_device_class_hid_event_buffer[2] = i;
|
||||
|
||||
ux_device_class_hid_event_set(hid, &hid_event);
|
||||
|
||||
ux_utility_thread_sleep(2);
|
||||
}
|
||||
|
||||
/* Turn NUM LOCK on. */
|
||||
hid_event.ux_device_class_hid_event_length = 8;
|
||||
hid_event.ux_device_class_hid_event_buffer[0] = 0;
|
||||
hid_event.ux_device_class_hid_event_buffer[1] = 0;
|
||||
hid_event.ux_device_class_hid_event_buffer[2] = UX_HID_LED_KEY_NUM_LOCK;
|
||||
ux_device_class_hid_event_set(hid, &hid_event);
|
||||
|
||||
/** Test key states. **/
|
||||
|
||||
/* Enable every bit in key state. */
|
||||
hid_event.ux_device_class_hid_event_length = 8;
|
||||
hid_event.ux_device_class_hid_event_buffer[0] = 0xff;
|
||||
hid_event.ux_device_class_hid_event_buffer[1] = 0;
|
||||
hid_event.ux_device_class_hid_event_buffer[2] = UX_HID_LED_KEY_CAPS_LOCK;
|
||||
hid_event.ux_device_class_hid_event_buffer[3] = UX_HID_LED_KEY_SCROLL_LOCK;
|
||||
|
||||
/* Add a key so the host can receive it, allowing checking of key state. */
|
||||
hid_event.ux_device_class_hid_event_buffer[4] = 0x04;
|
||||
|
||||
ux_device_class_hid_event_set(hid, &hid_event);
|
||||
|
||||
/** Test key states. **/
|
||||
|
||||
/* Disable every bit in key state. */
|
||||
hid_event.ux_device_class_hid_event_length = 8;
|
||||
hid_event.ux_device_class_hid_event_buffer[0] = 0x00;
|
||||
hid_event.ux_device_class_hid_event_buffer[1] = 0;
|
||||
hid_event.ux_device_class_hid_event_buffer[2] = UX_HID_LED_KEY_CAPS_LOCK;
|
||||
hid_event.ux_device_class_hid_event_buffer[3] = UX_HID_LED_KEY_SCROLL_LOCK;
|
||||
hid_event.ux_device_class_hid_event_buffer[4] = UX_HID_LED_KEY_NUM_LOCK;
|
||||
|
||||
/* Add a key so the host can receive it, allowing checking of key state. */
|
||||
hid_event.ux_device_class_hid_event_buffer[5] = 0x04;
|
||||
|
||||
ux_device_class_hid_event_set(hid, &hid_event);
|
||||
}
|
510
test/regression/usbx_hid_mouse_basic_test.c
Normal file
510
test/regression/usbx_hid_mouse_basic_test.c
Normal file
@ -0,0 +1,510 @@
|
||||
/* This test is designed to test simple usage of the mouse class. */
|
||||
|
||||
#include "usbx_test_common_hid.h"
|
||||
|
||||
#include "ux_host_class_hid_keyboard.h"
|
||||
#include "ux_host_class_hid_mouse.h"
|
||||
|
||||
#include "ux_test_utility_sim.h"
|
||||
#include "ux_test_hcd_sim_host.h"
|
||||
|
||||
static UX_HOST_CLASS_HID_MOUSE *mouse;
|
||||
static UCHAR has_host_received;
|
||||
|
||||
|
||||
static UCHAR hid_mouse_report[] = {
|
||||
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||
0x09, 0x02, // USAGE (Mouse)
|
||||
0xa1, 0x01, // COLLECTION (Application)
|
||||
0x09, 0x01, // USAGE (Pointer)
|
||||
0xa1, 0x00, // COLLECTION (Physical)
|
||||
0x05, 0x09, // USAGE_PAGE (Button)
|
||||
0x19, 0x01, // USAGE_MINIMUM (Button 1)
|
||||
0x29, 0x03, // USAGE_MAXIMUM (Button 3)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x25, 0x01, // LOGICAL_MAXIMUM (1)
|
||||
0x95, 0x03, // REPORT_COUNT (3)
|
||||
0x75, 0x01, // REPORT_SIZE (1)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x75, 0x05, // REPORT_SIZE (5)
|
||||
0x81, 0x03, // INPUT (Cnst,Var,Abs)
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||
0x09, 0x30, // USAGE (X)
|
||||
0x09, 0x31, // USAGE (Y)
|
||||
0x15, 0x81, // LOGICAL_MINIMUM (-127)
|
||||
0x25, 0x7f, // LOGICAL_MAXIMUM (127)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x95, 0x02, // REPORT_COUNT (2)
|
||||
0x81, 0x06, // INPUT (Data,Var,Rel)
|
||||
0x09, 0x38, // USAGE (Mouse Wheel)
|
||||
0x15, 0x81, // LOGICAL_MINIMUM (-127)
|
||||
0x25, 0x7f, // LOGICAL_MAXIMUM (127)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x81, 0x06, // INPUT (Data,Var,Rel)
|
||||
0xc0, // END_COLLECTION
|
||||
0xc0 // END_COLLECTION
|
||||
};
|
||||
#define HID_MOUSE_REPORT_LENGTH (sizeof(hid_mouse_report)/sizeof(hid_mouse_report[0]))
|
||||
|
||||
|
||||
#define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED 52
|
||||
static UCHAR device_framework_full_speed[] = {
|
||||
|
||||
/* Device descriptor */
|
||||
0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08,
|
||||
0x81, 0x0A, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x01,
|
||||
|
||||
/* Configuration descriptor */
|
||||
0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x00, 0xc0,
|
||||
0x32,
|
||||
|
||||
/* Interface descriptor */
|
||||
0x09, 0x04, 0x02, 0x00, 0x01, 0x03, 0x00, 0x00,
|
||||
0x00,
|
||||
|
||||
/* HID descriptor */
|
||||
0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(HID_MOUSE_REPORT_LENGTH),
|
||||
MSB(HID_MOUSE_REPORT_LENGTH),
|
||||
|
||||
/* Endpoint descriptor (Interrupt) */
|
||||
0x07, 0x05, 0x82, 0x03, 0x08, 0x00, 0x08
|
||||
|
||||
};
|
||||
|
||||
|
||||
#define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED 62
|
||||
static UCHAR device_framework_high_speed[] = {
|
||||
|
||||
/* Device descriptor */
|
||||
0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
|
||||
0x0a, 0x07, 0x25, 0x40, 0x01, 0x00, 0x01, 0x02,
|
||||
0x03, 0x01,
|
||||
|
||||
/* Device qualifier descriptor */
|
||||
0x0a, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
|
||||
0x01, 0x00,
|
||||
|
||||
/* Configuration descriptor */
|
||||
0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x00, 0xc0,
|
||||
0x32,
|
||||
|
||||
/* Interface descriptor */
|
||||
0x09, 0x04, 0x02, 0x00, 0x01, 0x03, 0x00, 0x00,
|
||||
0x00,
|
||||
|
||||
/* HID descriptor */
|
||||
0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(HID_MOUSE_REPORT_LENGTH),
|
||||
MSB(HID_MOUSE_REPORT_LENGTH),
|
||||
|
||||
/* Endpoint descriptor (Interrupt) */
|
||||
0x07, 0x05, 0x82, 0x03, 0x08, 0x00, 0x08
|
||||
|
||||
};
|
||||
|
||||
|
||||
/* String Device Framework :
|
||||
Byte 0 and 1 : Word containing the language ID : 0x0904 for US
|
||||
Byte 2 : Byte containing the index of the descriptor
|
||||
Byte 3 : Byte containing the length of the descriptor string
|
||||
*/
|
||||
|
||||
#define STRING_FRAMEWORK_LENGTH 40
|
||||
static UCHAR string_framework[] = {
|
||||
|
||||
/* Manufacturer string descriptor : Index 1 */
|
||||
0x09, 0x04, 0x01, 0x0c,
|
||||
0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
|
||||
0x6f, 0x67, 0x69, 0x63,
|
||||
|
||||
/* Product string descriptor : Index 2 */
|
||||
0x09, 0x04, 0x02, 0x0c,
|
||||
0x55, 0x53, 0x42, 0x20, 0x4b, 0x65, 0x79, 0x62,
|
||||
0x6f, 0x61, 0x72, 0x64,
|
||||
|
||||
/* Serial Number string descriptor : Index 3 */
|
||||
0x09, 0x04, 0x03, 0x04,
|
||||
0x30, 0x30, 0x30, 0x31
|
||||
};
|
||||
|
||||
|
||||
/* Multiple languages are supported on the device, to add
|
||||
a language besides english, the unicode language code must
|
||||
be appended to the language_id_framework array and the length
|
||||
adjusted accordingly. */
|
||||
#define LANGUAGE_ID_FRAMEWORK_LENGTH 2
|
||||
static UCHAR language_id_framework[] = {
|
||||
|
||||
/* English. */
|
||||
0x09, 0x04
|
||||
};
|
||||
|
||||
|
||||
static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
|
||||
{
|
||||
|
||||
/* Failed test. */
|
||||
printf("Error on line %d, system_level: %d, system_context: %d, error code: %d\n", __LINE__, system_level, system_context, error_code);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_hid_mouse_basic_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *stack_pointer;
|
||||
CHAR *memory_pointer;
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running HID Mouse Basic Functionality Test.......................... ");
|
||||
|
||||
/* Initialize the free memory pointer */
|
||||
stack_pointer = (CHAR *) usbx_memory;
|
||||
memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
|
||||
|
||||
/* Initialize USBX. Memory */
|
||||
status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the error callback. */
|
||||
_ux_utility_error_callback_register(error_callback);
|
||||
|
||||
/* The code below is required for installing the host portion of USBX */
|
||||
status = ux_host_stack_initialize(UX_NULL);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = ux_host_stack_class_register(_ux_system_host_class_hid_name, ux_host_class_hid_entry);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the HID client(s). */
|
||||
status = ux_host_class_hid_client_register(_ux_system_host_class_hid_client_mouse_name, ux_host_class_hid_mouse_entry);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* The code below is required for installing the device portion of USBX. No call back for
|
||||
device status change in this example. */
|
||||
status = ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
|
||||
device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
|
||||
string_framework, STRING_FRAMEWORK_LENGTH,
|
||||
language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Initialize the hid class parameters for a mouse. */
|
||||
hid_parameter.ux_device_class_hid_parameter_report_address = hid_mouse_report;
|
||||
hid_parameter.ux_device_class_hid_parameter_report_length = HID_MOUSE_REPORT_LENGTH;
|
||||
hid_parameter.ux_device_class_hid_parameter_callback = demo_thread_hid_callback;
|
||||
|
||||
/* Initilize the device hid class. The class is connected with interface 2 */
|
||||
status = ux_device_stack_class_register(_ux_system_slave_class_hid_name, ux_device_class_hid_entry,
|
||||
1,2, (VOID *)&hid_parameter);
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
|
||||
/* Initialize the simulated device controller. */
|
||||
status = _ux_dcd_sim_slave_initialize();
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register all the USB host controllers available in this system */
|
||||
status = ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, ux_hcd_sim_host_initialize,0,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the main host simulation thread. */
|
||||
status = tx_thread_create(&tx_demo_thread_host_simulation, "tx demo host simulation", tx_demo_thread_host_simulation_entry, 0,
|
||||
stack_pointer, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the main demo thread. */
|
||||
status = tx_thread_create(&tx_demo_thread_slave_simulation, "tx demo slave simulation", tx_demo_thread_slave_simulation_entry, 0,
|
||||
stack_pointer + UX_DEMO_STACK_SIZE, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
static UINT sleep_break_on_removed(VOID)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
UX_HOST_CLASS *class;
|
||||
|
||||
/* Find the main HID container. */
|
||||
status = ux_host_stack_class_get(_ux_system_host_class_hid_name, &class);
|
||||
if (status == UX_SUCCESS)
|
||||
{
|
||||
|
||||
/* Find the instance. */
|
||||
status = ux_host_stack_class_instance_get(class, 0, (void **) &hid);
|
||||
if (status != UX_SUCCESS)
|
||||
return UX_TRUE;
|
||||
}
|
||||
|
||||
return UX_FALSE;
|
||||
}
|
||||
|
||||
|
||||
static void tx_demo_thread_host_simulation_entry(ULONG arg)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
UINT max_num_loops;
|
||||
UINT num_loops;
|
||||
ULONG num_attempts;
|
||||
ULONG max_attempts;
|
||||
SLONG cur_mouse_wheel_movement;
|
||||
SLONG next_mouse_wheel_movement;
|
||||
SLONG cur_mouse_x_position;
|
||||
SLONG cur_mouse_y_position;
|
||||
SLONG next_mouse_x_position;
|
||||
SLONG next_mouse_y_position;
|
||||
ULONG cur_mouse_buttons;
|
||||
UCHAR next_mouse_buttons;
|
||||
|
||||
/* Initilize max loop value. */
|
||||
max_num_loops = 16;
|
||||
|
||||
/* Find the HID class */
|
||||
status = demo_class_hid_get();
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the HID client */
|
||||
hid_client = hid -> ux_host_class_hid_client;
|
||||
|
||||
/* Check if the instance of the keyboard is live */
|
||||
while (hid_client -> ux_host_class_hid_client_local_instance == UX_NULL)
|
||||
tx_thread_sleep(10);
|
||||
|
||||
/* Get the mouse instance */
|
||||
mouse = (UX_HOST_CLASS_HID_MOUSE *)hid_client -> ux_host_class_hid_client_local_instance;
|
||||
|
||||
/* Set number of successful loops to execute. */
|
||||
num_loops = 0;
|
||||
max_num_loops = 16;
|
||||
|
||||
/* Set number of fails. */
|
||||
num_attempts = 0;
|
||||
max_attempts = 3*max_num_loops;
|
||||
|
||||
/* Set initial mouse button values. */
|
||||
next_mouse_buttons = 0x01;
|
||||
|
||||
/* Set initial mouse position values. */
|
||||
next_mouse_x_position = -8;
|
||||
next_mouse_y_position = -8;
|
||||
|
||||
/* Set initial mouse wheel value. */
|
||||
next_mouse_wheel_movement = -8;
|
||||
|
||||
while (num_loops++ != max_num_loops)
|
||||
{
|
||||
|
||||
/* Once one works, the others should work as well. */
|
||||
while (1)
|
||||
{
|
||||
ux_host_class_hid_mouse_buttons_get(mouse, &cur_mouse_buttons);
|
||||
if (cur_mouse_buttons == next_mouse_buttons)
|
||||
break;
|
||||
tx_thread_sleep(10);
|
||||
}
|
||||
ux_host_class_hid_mouse_position_get(mouse, &cur_mouse_x_position, &cur_mouse_y_position);
|
||||
ux_host_class_hid_mouse_wheel_get(mouse, &cur_mouse_wheel_movement);
|
||||
|
||||
/* Are these the expected values? */
|
||||
UX_TEST_ASSERT(cur_mouse_buttons == next_mouse_buttons &&
|
||||
cur_mouse_x_position == next_mouse_x_position &&
|
||||
cur_mouse_y_position == next_mouse_y_position &&
|
||||
cur_mouse_wheel_movement == next_mouse_wheel_movement);
|
||||
|
||||
/* Signal to device to continue. */
|
||||
has_host_received = 1;
|
||||
|
||||
/* Increment values. */
|
||||
next_mouse_buttons = 0x07 & (next_mouse_buttons + 1);
|
||||
next_mouse_x_position++;
|
||||
next_mouse_y_position++;
|
||||
next_mouse_wheel_movement++;
|
||||
}
|
||||
|
||||
/* Simulate detach. */
|
||||
ux_test_hcd_sim_host_disconnect();
|
||||
ux_test_breakable_sleep(50, sleep_break_on_removed);
|
||||
|
||||
/* Now disconnect the device. */
|
||||
_ux_device_stack_disconnect();
|
||||
|
||||
/* And deinitialize the class. */
|
||||
status = ux_device_stack_class_unregister(_ux_system_slave_class_hid_name, ux_device_class_hid_entry);
|
||||
|
||||
/* Deinitialize the device side of usbx. */
|
||||
_ux_device_stack_uninitialize();
|
||||
|
||||
/* And finally the usbx system resources. */
|
||||
_ux_system_uninitialize();
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
|
||||
static UINT demo_thread_hid_callback(UX_SLAVE_CLASS_HID *class, UX_SLAVE_CLASS_HID_EVENT *event)
|
||||
{
|
||||
return(UX_SUCCESS);
|
||||
}
|
||||
|
||||
static void tx_demo_thread_slave_simulation_entry(ULONG arg)
|
||||
{
|
||||
|
||||
UX_SLAVE_DEVICE *device;
|
||||
UX_SLAVE_INTERFACE *interface;
|
||||
UX_SLAVE_CLASS_HID *hid;
|
||||
UX_SLAVE_CLASS_HID_EVENT hid_event;
|
||||
|
||||
/* Get the pointer to the device. */
|
||||
device = &_ux_system_slave -> ux_system_slave_device;
|
||||
|
||||
/* reset the HID event structure. */
|
||||
ux_utility_memory_set(&hid_event, 0, sizeof(UX_SLAVE_CLASS_HID_EVENT));
|
||||
|
||||
/* Set length of event. */
|
||||
hid_event.ux_device_class_hid_event_length = 4;
|
||||
|
||||
/* Set initial value for buttons. The first three bits are for buttons, the rest are padding. */
|
||||
hid_event.ux_device_class_hid_event_buffer[0] = 1;
|
||||
|
||||
/* Set initial value for x and y positions. */
|
||||
hid_event.ux_device_class_hid_event_buffer[1] = -8;
|
||||
hid_event.ux_device_class_hid_event_buffer[2] = -8;
|
||||
|
||||
/* Set initial value for mouse wheel. */
|
||||
hid_event.ux_device_class_hid_event_buffer[3] = -8;
|
||||
|
||||
while (1)
|
||||
{
|
||||
|
||||
/* Is the device configured ? */
|
||||
while (device -> ux_slave_device_state != UX_DEVICE_CONFIGURED)
|
||||
{
|
||||
#if defined(UX_DEVICE_STANDALONE)
|
||||
ux_system_tasks_run();
|
||||
tx_thread_relinquish();
|
||||
#else
|
||||
/* Then wait. */
|
||||
tx_thread_sleep(10);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* Until the device stays configured. */
|
||||
while (device -> ux_slave_device_state == UX_DEVICE_CONFIGURED)
|
||||
{
|
||||
#if defined(UX_DEVICE_STANDALONE)
|
||||
ux_system_tasks_run();
|
||||
tx_thread_relinquish();
|
||||
#endif
|
||||
|
||||
/* Get the interface. We use the first interface, this is a simple device. */
|
||||
interface = device -> ux_slave_device_first_interface;
|
||||
|
||||
/* From that interface, derive the HID owner. */
|
||||
hid = interface -> ux_slave_interface_class_instance;
|
||||
|
||||
/* Set the mouse event. */
|
||||
ux_device_class_hid_event_set(hid, &hid_event);
|
||||
|
||||
/* Wait for host to receive. */
|
||||
while (!has_host_received)
|
||||
{
|
||||
#if defined(UX_DEVICE_STANDALONE)
|
||||
ux_system_tasks_run();
|
||||
tx_thread_relinquish();
|
||||
#else
|
||||
tx_thread_sleep(10);
|
||||
#endif
|
||||
}
|
||||
has_host_received = 0;
|
||||
|
||||
/* Change the buttons. */
|
||||
hid_event.ux_device_class_hid_event_buffer[0] = (0x7 & hid_event.ux_device_class_hid_event_buffer[0] + 1);
|
||||
|
||||
/* Change the x, y, and wheel positions. These are relative values. */
|
||||
hid_event.ux_device_class_hid_event_buffer[1] = 1;
|
||||
hid_event.ux_device_class_hid_event_buffer[2] = 1;
|
||||
hid_event.ux_device_class_hid_event_buffer[3] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
370
test/regression/usbx_hid_mouse_extraction_test.c
Normal file
370
test/regression/usbx_hid_mouse_extraction_test.c
Normal file
@ -0,0 +1,370 @@
|
||||
/* This test is designed to test the extraction of a mouse device. */
|
||||
|
||||
#include "usbx_test_common_hid.h"
|
||||
#include "ux_host_class_hid_mouse.h"
|
||||
|
||||
|
||||
static UX_HOST_CLASS_HID_MOUSE *mouse;
|
||||
|
||||
|
||||
static UCHAR hid_mouse_report[] = {
|
||||
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||
0x09, 0x02, // USAGE (Mouse)
|
||||
0xa1, 0x01, // COLLECTION (Application)
|
||||
0x09, 0x01, // USAGE (Pointer)
|
||||
0xa1, 0x00, // COLLECTION (Physical)
|
||||
0x05, 0x09, // USAGE_PAGE (Button)
|
||||
0x19, 0x01, // USAGE_MINIMUM (Button 1)
|
||||
0x29, 0x03, // USAGE_MAXIMUM (Button 3)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x25, 0x01, // LOGICAL_MAXIMUM (1)
|
||||
0x95, 0x03, // REPORT_COUNT (3)
|
||||
0x75, 0x01, // REPORT_SIZE (1)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x75, 0x05, // REPORT_SIZE (5)
|
||||
0x81, 0x03, // INPUT (Cnst,Var,Abs)
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||
0x09, 0x30, // USAGE (X)
|
||||
0x09, 0x31, // USAGE (Y)
|
||||
0x15, 0x81, // LOGICAL_MINIMUM (-127)
|
||||
0x25, 0x7f, // LOGICAL_MAXIMUM (127)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x95, 0x02, // REPORT_COUNT (2)
|
||||
0x81, 0x06, // INPUT (Data,Var,Rel)
|
||||
0x09, 0x38, // USAGE (Mouse Wheel)
|
||||
0x15, 0x81, // LOGICAL_MINIMUM (-127)
|
||||
0x25, 0x7f, // LOGICAL_MAXIMUM (127)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x81, 0x06, // INPUT (Data,Var,Rel)
|
||||
0xc0, // END_COLLECTION
|
||||
0xc0 // END_COLLECTION
|
||||
};
|
||||
#define HID_MOUSE_REPORT_LENGTH (sizeof(hid_mouse_report)/sizeof(hid_mouse_report[0]))
|
||||
|
||||
|
||||
#define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED 52
|
||||
static UCHAR device_framework_full_speed[] = {
|
||||
|
||||
/* Device descriptor */
|
||||
0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08,
|
||||
0x81, 0x0A, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x01,
|
||||
|
||||
/* Configuration descriptor */
|
||||
0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x00, 0xc0,
|
||||
0x32,
|
||||
|
||||
/* Interface descriptor */
|
||||
0x09, 0x04, 0x02, 0x00, 0x01, 0x03, 0x00, 0x00,
|
||||
0x00,
|
||||
|
||||
/* HID descriptor */
|
||||
0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(HID_MOUSE_REPORT_LENGTH),
|
||||
MSB(HID_MOUSE_REPORT_LENGTH),
|
||||
|
||||
/* Endpoint descriptor (Interrupt) */
|
||||
0x07, 0x05, 0x82, 0x03, 0x08, 0x00, 0x08
|
||||
|
||||
};
|
||||
|
||||
|
||||
#define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED 62
|
||||
static UCHAR device_framework_high_speed[] = {
|
||||
|
||||
/* Device descriptor */
|
||||
0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
|
||||
0x0a, 0x07, 0x25, 0x40, 0x01, 0x00, 0x01, 0x02,
|
||||
0x03, 0x01,
|
||||
|
||||
/* Device qualifier descriptor */
|
||||
0x0a, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
|
||||
0x01, 0x00,
|
||||
|
||||
/* Configuration descriptor */
|
||||
0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x00, 0xc0,
|
||||
0x32,
|
||||
|
||||
/* Interface descriptor */
|
||||
0x09, 0x04, 0x02, 0x00, 0x01, 0x03, 0x00, 0x00,
|
||||
0x00,
|
||||
|
||||
/* HID descriptor */
|
||||
0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(HID_MOUSE_REPORT_LENGTH),
|
||||
MSB(HID_MOUSE_REPORT_LENGTH),
|
||||
|
||||
/* Endpoint descriptor (Interrupt) */
|
||||
0x07, 0x05, 0x82, 0x03, 0x08, 0x00, 0x08
|
||||
|
||||
};
|
||||
|
||||
|
||||
/* String Device Framework :
|
||||
Byte 0 and 1 : Word containing the language ID : 0x0904 for US
|
||||
Byte 2 : Byte containing the index of the descriptor
|
||||
Byte 3 : Byte containing the length of the descriptor string
|
||||
*/
|
||||
|
||||
#define STRING_FRAMEWORK_LENGTH 40
|
||||
static UCHAR string_framework[] = {
|
||||
|
||||
/* Manufacturer string descriptor : Index 1 */
|
||||
0x09, 0x04, 0x01, 0x0c,
|
||||
0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
|
||||
0x6f, 0x67, 0x69, 0x63,
|
||||
|
||||
/* Product string descriptor : Index 2 */
|
||||
0x09, 0x04, 0x02, 0x0c,
|
||||
0x55, 0x53, 0x42, 0x20, 0x4b, 0x65, 0x79, 0x62,
|
||||
0x6f, 0x61, 0x72, 0x64,
|
||||
|
||||
/* Serial Number string descriptor : Index 3 */
|
||||
0x09, 0x04, 0x03, 0x04,
|
||||
0x30, 0x30, 0x30, 0x31
|
||||
};
|
||||
|
||||
|
||||
/* Multiple languages are supported on the device, to add
|
||||
a language besides english, the unicode language code must
|
||||
be appended to the language_id_framework array and the length
|
||||
adjusted accordingly. */
|
||||
#define LANGUAGE_ID_FRAMEWORK_LENGTH 2
|
||||
static UCHAR language_id_framework[] = {
|
||||
|
||||
/* English. */
|
||||
0x09, 0x04
|
||||
};
|
||||
|
||||
|
||||
UINT _ux_hcd_sim_host_entry(UX_HCD *hcd, UINT function, VOID *parameter);
|
||||
|
||||
static UINT ux_system_host_change_function(ULONG a, UX_HOST_CLASS *b, VOID *c)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
|
||||
{
|
||||
|
||||
/* Failed test. */
|
||||
printf("Error on line %d, system_level: %d, system_context: %d, error code: %d\n", __LINE__, system_level, system_context, error_code);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_hid_mouse_extraction_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR * stack_pointer;
|
||||
CHAR * memory_pointer;
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running HID Mouse Extraction Test................................... ");
|
||||
|
||||
/* Initialize the free memory pointer */
|
||||
stack_pointer = (CHAR *) usbx_memory;
|
||||
memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
|
||||
|
||||
/* Initialize USBX. Memory */
|
||||
status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the error callback. */
|
||||
_ux_utility_error_callback_register(error_callback);
|
||||
|
||||
/* The code below is required for installing the host portion of USBX */
|
||||
status = ux_host_stack_initialize(ux_system_host_change_function);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = ux_host_stack_class_register(_ux_system_host_class_hid_name, ux_host_class_hid_entry);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the HID client(s). */
|
||||
status = ux_host_class_hid_client_register(_ux_system_host_class_hid_client_mouse_name, ux_host_class_hid_mouse_entry);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* The code below is required for installing the device portion of USBX. No call back for
|
||||
device status change in this example. */
|
||||
status = ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
|
||||
device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
|
||||
string_framework, STRING_FRAMEWORK_LENGTH,
|
||||
language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Initialize the hid class parameters for a mouse. */
|
||||
hid_parameter.ux_device_class_hid_parameter_report_address = hid_mouse_report;
|
||||
hid_parameter.ux_device_class_hid_parameter_report_length = HID_MOUSE_REPORT_LENGTH;
|
||||
hid_parameter.ux_device_class_hid_parameter_callback = demo_thread_hid_callback;
|
||||
|
||||
/* Initilize the device hid class. The class is connected with interface 2 */
|
||||
status = ux_device_stack_class_register(_ux_system_slave_class_hid_name, ux_device_class_hid_entry,
|
||||
1,2, (VOID *)&hid_parameter);
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
|
||||
/* Initialize the simulated device controller. */
|
||||
status = _ux_dcd_sim_slave_initialize();
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register all the USB host controllers available in this system */
|
||||
status = ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, ux_hcd_sim_host_initialize,0,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the main host simulation thread. */
|
||||
status = tx_thread_create(&tx_demo_thread_host_simulation, "tx demo host simulation", tx_demo_thread_host_simulation_entry, 0,
|
||||
stack_pointer, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static UINT ux_hcd_sim_host_entry_filter_device_extraction_test(UX_HCD *hcd, UINT function, VOID *parameter)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
switch(function)
|
||||
{
|
||||
case UX_HCD_GET_PORT_STATUS:
|
||||
|
||||
/* No device on this port. */
|
||||
status = 0;
|
||||
|
||||
/* This is a Full speed device. */
|
||||
status |= UX_PS_DS_FS;
|
||||
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
|
||||
status = _ux_hcd_sim_host_entry(hcd, function, parameter);
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void tx_demo_thread_host_simulation_entry(ULONG arg)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
UX_HCD *hcd;
|
||||
|
||||
/* Find the HID class */
|
||||
status = demo_class_hid_get();
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the HID client */
|
||||
hid_client = hid -> ux_host_class_hid_client;
|
||||
|
||||
/* Check if the instance of the keyboard is live */
|
||||
while (hid_client -> ux_host_class_hid_client_local_instance == UX_NULL)
|
||||
tx_thread_sleep(10);
|
||||
|
||||
/* Get the mouse instance */
|
||||
mouse = (UX_HOST_CLASS_HID_MOUSE *)hid_client -> ux_host_class_hid_client_local_instance;
|
||||
|
||||
hcd = UX_DEVICE_HCD_GET(hid -> ux_host_class_hid_device);
|
||||
|
||||
/* Change the HCD entry function to our filter function. */
|
||||
hcd -> ux_hcd_entry_function = ux_hcd_sim_host_entry_filter_device_extraction_test;
|
||||
|
||||
/* Signal port activity to the enum thread. */
|
||||
hcd -> ux_hcd_root_hub_signal[0] = 1;
|
||||
|
||||
/* Signal enum thread. */
|
||||
_ux_utility_semaphore_put(&_ux_system_host -> ux_system_host_enum_semaphore);
|
||||
|
||||
/* Wait for hid class to shut down. */
|
||||
while(hid -> ux_host_class_hid_state == UX_HOST_CLASS_INSTANCE_LIVE)
|
||||
tx_thread_sleep(10);
|
||||
|
||||
/* Now disconnect the device. */
|
||||
_ux_device_stack_disconnect();
|
||||
|
||||
/* And deinitialize the class. */
|
||||
status = ux_device_stack_class_unregister(_ux_system_slave_class_hid_name, ux_device_class_hid_entry);
|
||||
|
||||
/* Deinitialize the device side of usbx. */
|
||||
_ux_device_stack_uninitialize();
|
||||
|
||||
/* And finally the usbx system resources. */
|
||||
_ux_system_uninitialize();
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
|
||||
static UINT demo_thread_hid_callback(UX_SLAVE_CLASS_HID *class, UX_SLAVE_CLASS_HID_EVENT *event)
|
||||
{
|
||||
return(UX_SUCCESS);
|
||||
}
|
369
test/regression/usbx_hid_mouse_extraction_test2.c
Normal file
369
test/regression/usbx_hid_mouse_extraction_test2.c
Normal file
@ -0,0 +1,369 @@
|
||||
/* This test is designed to test the extraction of a mouse device.
|
||||
This is similar to the first extraction test, except there is no ux_system_host_change_function.
|
||||
This allows us to hit the following false condition in _ux_host_class_hid_mouse_deactivate:
|
||||
if (_ux_system_host -> ux_system_host_change_function != UX_NULL)
|
||||
*/
|
||||
|
||||
#include "usbx_test_common_hid.h"
|
||||
#include "ux_host_class_hid_mouse.h"
|
||||
|
||||
|
||||
static UX_HOST_CLASS_HID_MOUSE *mouse;
|
||||
|
||||
|
||||
static UCHAR hid_mouse_report[] = {
|
||||
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||
0x09, 0x02, // USAGE (Mouse)
|
||||
0xa1, 0x01, // COLLECTION (Application)
|
||||
0x09, 0x01, // USAGE (Pointer)
|
||||
0xa1, 0x00, // COLLECTION (Physical)
|
||||
0x05, 0x09, // USAGE_PAGE (Button)
|
||||
0x19, 0x01, // USAGE_MINIMUM (Button 1)
|
||||
0x29, 0x03, // USAGE_MAXIMUM (Button 3)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x25, 0x01, // LOGICAL_MAXIMUM (1)
|
||||
0x95, 0x03, // REPORT_COUNT (3)
|
||||
0x75, 0x01, // REPORT_SIZE (1)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x75, 0x05, // REPORT_SIZE (5)
|
||||
0x81, 0x03, // INPUT (Cnst,Var,Abs)
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||
0x09, 0x30, // USAGE (X)
|
||||
0x09, 0x31, // USAGE (Y)
|
||||
0x15, 0x81, // LOGICAL_MINIMUM (-127)
|
||||
0x25, 0x7f, // LOGICAL_MAXIMUM (127)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x95, 0x02, // REPORT_COUNT (2)
|
||||
0x81, 0x06, // INPUT (Data,Var,Rel)
|
||||
0x09, 0x38, // USAGE (Mouse Wheel)
|
||||
0x15, 0x81, // LOGICAL_MINIMUM (-127)
|
||||
0x25, 0x7f, // LOGICAL_MAXIMUM (127)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x81, 0x06, // INPUT (Data,Var,Rel)
|
||||
0xc0, // END_COLLECTION
|
||||
0xc0 // END_COLLECTION
|
||||
};
|
||||
#define HID_MOUSE_REPORT_LENGTH (sizeof(hid_mouse_report)/sizeof(hid_mouse_report[0]))
|
||||
|
||||
|
||||
#define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED 52
|
||||
static UCHAR device_framework_full_speed[] = {
|
||||
|
||||
/* Device descriptor */
|
||||
0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08,
|
||||
0x81, 0x0A, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x01,
|
||||
|
||||
/* Configuration descriptor */
|
||||
0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x00, 0xc0,
|
||||
0x32,
|
||||
|
||||
/* Interface descriptor */
|
||||
0x09, 0x04, 0x02, 0x00, 0x01, 0x03, 0x00, 0x00,
|
||||
0x00,
|
||||
|
||||
/* HID descriptor */
|
||||
0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(HID_MOUSE_REPORT_LENGTH),
|
||||
MSB(HID_MOUSE_REPORT_LENGTH),
|
||||
|
||||
/* Endpoint descriptor (Interrupt) */
|
||||
0x07, 0x05, 0x82, 0x03, 0x08, 0x00, 0x08
|
||||
|
||||
};
|
||||
|
||||
|
||||
#define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED 62
|
||||
static UCHAR device_framework_high_speed[] = {
|
||||
|
||||
/* Device descriptor */
|
||||
0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
|
||||
0x0a, 0x07, 0x25, 0x40, 0x01, 0x00, 0x01, 0x02,
|
||||
0x03, 0x01,
|
||||
|
||||
/* Device qualifier descriptor */
|
||||
0x0a, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
|
||||
0x01, 0x00,
|
||||
|
||||
/* Configuration descriptor */
|
||||
0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x00, 0xc0,
|
||||
0x32,
|
||||
|
||||
/* Interface descriptor */
|
||||
0x09, 0x04, 0x02, 0x00, 0x01, 0x03, 0x00, 0x00,
|
||||
0x00,
|
||||
|
||||
/* HID descriptor */
|
||||
0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(HID_MOUSE_REPORT_LENGTH),
|
||||
MSB(HID_MOUSE_REPORT_LENGTH),
|
||||
|
||||
/* Endpoint descriptor (Interrupt) */
|
||||
0x07, 0x05, 0x82, 0x03, 0x08, 0x00, 0x08
|
||||
|
||||
};
|
||||
|
||||
|
||||
/* String Device Framework :
|
||||
Byte 0 and 1 : Word containing the language ID : 0x0904 for US
|
||||
Byte 2 : Byte containing the index of the descriptor
|
||||
Byte 3 : Byte containing the length of the descriptor string
|
||||
*/
|
||||
|
||||
#define STRING_FRAMEWORK_LENGTH 40
|
||||
static UCHAR string_framework[] = {
|
||||
|
||||
/* Manufacturer string descriptor : Index 1 */
|
||||
0x09, 0x04, 0x01, 0x0c,
|
||||
0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
|
||||
0x6f, 0x67, 0x69, 0x63,
|
||||
|
||||
/* Product string descriptor : Index 2 */
|
||||
0x09, 0x04, 0x02, 0x0c,
|
||||
0x55, 0x53, 0x42, 0x20, 0x4b, 0x65, 0x79, 0x62,
|
||||
0x6f, 0x61, 0x72, 0x64,
|
||||
|
||||
/* Serial Number string descriptor : Index 3 */
|
||||
0x09, 0x04, 0x03, 0x04,
|
||||
0x30, 0x30, 0x30, 0x31
|
||||
};
|
||||
|
||||
|
||||
/* Multiple languages are supported on the device, to add
|
||||
a language besides english, the unicode language code must
|
||||
be appended to the language_id_framework array and the length
|
||||
adjusted accordingly. */
|
||||
#define LANGUAGE_ID_FRAMEWORK_LENGTH 2
|
||||
static UCHAR language_id_framework[] = {
|
||||
|
||||
/* English. */
|
||||
0x09, 0x04
|
||||
};
|
||||
|
||||
|
||||
UINT _ux_hcd_sim_host_entry(UX_HCD *hcd, UINT function, VOID *parameter);
|
||||
|
||||
|
||||
static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
|
||||
{
|
||||
|
||||
/* Failed test. */
|
||||
printf("Error on line %d, system_level: %d, system_context: %d, error code: %d\n", __LINE__, system_level, system_context, error_code);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_hid_mouse_extraction_test2_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR * stack_pointer;
|
||||
CHAR * memory_pointer;
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running HID Mouse Extraction Test 2................................. ");
|
||||
|
||||
/* Initialize the free memory pointer */
|
||||
stack_pointer = (CHAR *) usbx_memory;
|
||||
memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
|
||||
|
||||
/* Initialize USBX. Memory */
|
||||
status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the error callback. */
|
||||
_ux_utility_error_callback_register(error_callback);
|
||||
|
||||
/* The code below is required for installing the host portion of USBX */
|
||||
status = ux_host_stack_initialize(NULL);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = ux_host_stack_class_register(_ux_system_host_class_hid_name, ux_host_class_hid_entry);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the HID client(s). */
|
||||
status = ux_host_class_hid_client_register(_ux_system_host_class_hid_client_mouse_name, ux_host_class_hid_mouse_entry);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* The code below is required for installing the device portion of USBX. No call back for
|
||||
device status change in this example. */
|
||||
status = ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
|
||||
device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
|
||||
string_framework, STRING_FRAMEWORK_LENGTH,
|
||||
language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Initialize the hid class parameters for a mouse. */
|
||||
hid_parameter.ux_device_class_hid_parameter_report_address = hid_mouse_report;
|
||||
hid_parameter.ux_device_class_hid_parameter_report_length = HID_MOUSE_REPORT_LENGTH;
|
||||
hid_parameter.ux_device_class_hid_parameter_callback = demo_thread_hid_callback;
|
||||
|
||||
/* Initilize the device hid class. The class is connected with interface 2 */
|
||||
status = ux_device_stack_class_register(_ux_system_slave_class_hid_name, ux_device_class_hid_entry,
|
||||
1,2, (VOID *)&hid_parameter);
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
|
||||
/* Initialize the simulated device controller. */
|
||||
status = _ux_dcd_sim_slave_initialize();
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register all the USB host controllers available in this system */
|
||||
status = ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, ux_hcd_sim_host_initialize,0,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the main host simulation thread. */
|
||||
status = tx_thread_create(&tx_demo_thread_host_simulation, "tx demo host simulation", tx_demo_thread_host_simulation_entry, 0,
|
||||
stack_pointer, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static UINT ux_hcd_sim_host_entry_filter_device_extraction_test(UX_HCD *hcd, UINT function, VOID *parameter)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
switch(function)
|
||||
{
|
||||
case UX_HCD_GET_PORT_STATUS:
|
||||
|
||||
/* No device on this port. */
|
||||
status = 0;
|
||||
|
||||
/* This is a Full speed device. */
|
||||
status |= UX_PS_DS_FS;
|
||||
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
|
||||
status = _ux_hcd_sim_host_entry(hcd, function, parameter);
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void tx_demo_thread_host_simulation_entry(ULONG arg)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
UX_HCD *hcd;
|
||||
|
||||
/* Find the HID class */
|
||||
status = demo_class_hid_get();
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the HID client */
|
||||
hid_client = hid -> ux_host_class_hid_client;
|
||||
|
||||
/* Check if the instance of the keyboard is live */
|
||||
while (hid_client -> ux_host_class_hid_client_local_instance == UX_NULL)
|
||||
tx_thread_sleep(10);
|
||||
|
||||
/* Get the mouse instance */
|
||||
mouse = (UX_HOST_CLASS_HID_MOUSE *)hid_client -> ux_host_class_hid_client_local_instance;
|
||||
|
||||
hcd = UX_DEVICE_HCD_GET(hid -> ux_host_class_hid_device);
|
||||
|
||||
/* Change the HCD entry function to our filter function. */
|
||||
hcd -> ux_hcd_entry_function = ux_hcd_sim_host_entry_filter_device_extraction_test;
|
||||
|
||||
/* Signal port activity to the enum thread. */
|
||||
hcd -> ux_hcd_root_hub_signal[0] = 1;
|
||||
|
||||
/* Signal enum thread. */
|
||||
_ux_utility_semaphore_put(&_ux_system_host -> ux_system_host_enum_semaphore);
|
||||
|
||||
/* Wait for hid class to shut down. */
|
||||
while(hid -> ux_host_class_hid_state == UX_HOST_CLASS_INSTANCE_LIVE)
|
||||
tx_thread_sleep(10);
|
||||
|
||||
/* Now disconnect the device. */
|
||||
_ux_device_stack_disconnect();
|
||||
|
||||
/* And deinitialize the class. */
|
||||
status = ux_device_stack_class_unregister(_ux_system_slave_class_hid_name, ux_device_class_hid_entry);
|
||||
|
||||
/* Deinitialize the device side of usbx. */
|
||||
_ux_device_stack_uninitialize();
|
||||
|
||||
/* And finally the usbx system resources. */
|
||||
_ux_system_uninitialize();
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
|
||||
static UINT demo_thread_hid_callback(UX_SLAVE_CLASS_HID *class, UX_SLAVE_CLASS_HID_EVENT *event)
|
||||
{
|
||||
return(UX_SUCCESS);
|
||||
}
|
361
test/regression/usbx_hid_remote_control_extraction_test.c
Normal file
361
test/regression/usbx_hid_remote_control_extraction_test.c
Normal file
@ -0,0 +1,361 @@
|
||||
/* This test is concentrates on extraction of a remote control device. */
|
||||
|
||||
#include "usbx_test_common_hid.h"
|
||||
#include "ux_host_class_hid_remote_control.h"
|
||||
|
||||
|
||||
static UX_HOST_CLASS_HID_REMOTE_CONTROL *remote_control;
|
||||
|
||||
|
||||
static UCHAR hid_remote_control_report[] = {
|
||||
|
||||
0x05, 0x0c, // USAGE_PAGE (Consumer Devices)
|
||||
0x09, 0x01, // USAGE (Consumer Control)
|
||||
0xa1, 0x01, // COLLECTION (Application)
|
||||
0x09, 0x02, // USAGE (Numeric Key Pad)
|
||||
0xa1, 0x02, // COLLECTION (Logical)
|
||||
0x05, 0x09, // USAGE_PAGE (Button)
|
||||
0x19, 0x01, // USAGE_MINIMUM (Button 1)
|
||||
0x29, 0x0a, // USAGE_MAXIMUM (Button 10)
|
||||
0x15, 0x01, // LOGICAL_MINIMUM (1)
|
||||
0x25, 0x0a, // LOGICAL_MAXIMUM (10)
|
||||
0x75, 0x04, // REPORT_SIZE (4)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x81, 0x00, // INPUT (Data,Ary,Abs)
|
||||
0xc0, // END_COLLECTION
|
||||
0x05, 0x0c, // USAGE_PAGE (Consumer Devices)
|
||||
0x09, 0x86, // USAGE (Channel)
|
||||
0x09, 0xe0, // USAGE (Volume)
|
||||
0x15, 0xff, // LOGICAL_MINIMUM (-1)
|
||||
0x25, 0x01, // LOGICAL_MAXIMUM (1)
|
||||
0x75, 0x02, // REPORT_SIZE (2)
|
||||
0x95, 0x02, // REPORT_COUNT (2)
|
||||
0x81, 0x46, // INPUT (Data,Var,Rel,Null)
|
||||
0xc0 // END_COLLECTION
|
||||
};
|
||||
#define HID_REMOTE_CONTROL_REPORT_LENGTH (sizeof(hid_remote_control_report)/sizeof(hid_remote_control_report[0]))
|
||||
|
||||
|
||||
#define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED 52
|
||||
static UCHAR device_framework_full_speed[] = {
|
||||
|
||||
/* Device descriptor */
|
||||
0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08,
|
||||
0x81, 0x0A, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x01,
|
||||
|
||||
/* Configuration descriptor */
|
||||
0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x00, 0xc0,
|
||||
0x32,
|
||||
|
||||
/* Interface descriptor */
|
||||
0x09, 0x04, 0x02, 0x00, 0x01, 0x03, 0x00, 0x00,
|
||||
0x00,
|
||||
|
||||
/* HID descriptor */
|
||||
0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(HID_REMOTE_CONTROL_REPORT_LENGTH),
|
||||
MSB(HID_REMOTE_CONTROL_REPORT_LENGTH),
|
||||
|
||||
/* Endpoint descriptor (Interrupt) */
|
||||
0x07, 0x05, 0x82, 0x03, 0x08, 0x00, 0x08
|
||||
|
||||
};
|
||||
|
||||
|
||||
#define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED 62
|
||||
static UCHAR device_framework_high_speed[] = {
|
||||
|
||||
/* Device descriptor */
|
||||
0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
|
||||
0x0a, 0x07, 0x25, 0x40, 0x01, 0x00, 0x01, 0x02,
|
||||
0x03, 0x01,
|
||||
|
||||
/* Device qualifier descriptor */
|
||||
0x0a, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
|
||||
0x01, 0x00,
|
||||
|
||||
/* Configuration descriptor */
|
||||
0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x00, 0xc0,
|
||||
0x32,
|
||||
|
||||
/* Interface descriptor */
|
||||
0x09, 0x04, 0x02, 0x00, 0x01, 0x03, 0x00, 0x00,
|
||||
0x00,
|
||||
|
||||
/* HID descriptor */
|
||||
0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(HID_REMOTE_CONTROL_REPORT_LENGTH),
|
||||
MSB(HID_REMOTE_CONTROL_REPORT_LENGTH),
|
||||
|
||||
/* Endpoint descriptor (Interrupt) */
|
||||
0x07, 0x05, 0x82, 0x03, 0x08, 0x00, 0x08
|
||||
|
||||
};
|
||||
|
||||
|
||||
/* String Device Framework :
|
||||
Byte 0 and 1 : Word containing the language ID : 0x0904 for US
|
||||
Byte 2 : Byte containing the index of the descriptor
|
||||
Byte 3 : Byte containing the length of the descriptor string
|
||||
*/
|
||||
|
||||
#define STRING_FRAMEWORK_LENGTH 40
|
||||
static UCHAR string_framework[] = {
|
||||
|
||||
/* Manufacturer string descriptor : Index 1 */
|
||||
0x09, 0x04, 0x01, 0x0c,
|
||||
0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
|
||||
0x6f, 0x67, 0x69, 0x63,
|
||||
|
||||
/* Product string descriptor : Index 2 */
|
||||
0x09, 0x04, 0x02, 0x0c,
|
||||
0x55, 0x53, 0x42, 0x20, 0x4b, 0x65, 0x79, 0x62,
|
||||
0x6f, 0x61, 0x72, 0x64,
|
||||
|
||||
/* Serial Number string descriptor : Index 3 */
|
||||
0x09, 0x04, 0x03, 0x04,
|
||||
0x30, 0x30, 0x30, 0x31
|
||||
};
|
||||
|
||||
|
||||
/* Multiple languages are supported on the device, to add
|
||||
a language besides english, the unicode language code must
|
||||
be appended to the language_id_framework array and the length
|
||||
adjusted accordingly. */
|
||||
#define LANGUAGE_ID_FRAMEWORK_LENGTH 2
|
||||
static UCHAR language_id_framework[] = {
|
||||
|
||||
/* English. */
|
||||
0x09, 0x04
|
||||
};
|
||||
|
||||
|
||||
UINT _ux_hcd_sim_host_entry(UX_HCD *hcd, UINT function, VOID *parameter);
|
||||
|
||||
static UINT ux_system_host_change_function(ULONG a, UX_HOST_CLASS *b, VOID *c)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
|
||||
{
|
||||
|
||||
/* Failed test. */
|
||||
printf("Error on line %d, system_level: %d, system_context: %d, error code: %d\n", __LINE__, system_level, system_context, error_code);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_hid_remote_control_extraction_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR * stack_pointer;
|
||||
CHAR * memory_pointer;
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running HID Remote Control Extraction Test.......................... ");
|
||||
|
||||
/* Initialize the free memory pointer */
|
||||
stack_pointer = (CHAR *) usbx_memory;
|
||||
memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
|
||||
|
||||
/* Initialize USBX. Memory */
|
||||
status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the error callback. */
|
||||
_ux_utility_error_callback_register(error_callback);
|
||||
|
||||
/* The code below is required for installing the host portion of USBX */
|
||||
status = ux_host_stack_initialize(ux_system_host_change_function);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = ux_host_stack_class_register(_ux_system_host_class_hid_name, ux_host_class_hid_entry);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the HID client(s). */
|
||||
status = ux_host_class_hid_client_register(_ux_system_host_class_hid_client_remote_control_name, ux_host_class_hid_remote_control_entry);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* The code below is required for installing the device portion of USBX. No call back for
|
||||
device status change in this example. */
|
||||
status = ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
|
||||
device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
|
||||
string_framework, STRING_FRAMEWORK_LENGTH,
|
||||
language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Initialize the hid class parameters for a mouse. */
|
||||
hid_parameter.ux_device_class_hid_parameter_report_address = hid_remote_control_report;
|
||||
hid_parameter.ux_device_class_hid_parameter_report_length = HID_REMOTE_CONTROL_REPORT_LENGTH;
|
||||
hid_parameter.ux_device_class_hid_parameter_callback = demo_thread_hid_callback;
|
||||
|
||||
/* Initilize the device hid class. The class is connected with interface 2 */
|
||||
status = ux_device_stack_class_register(_ux_system_slave_class_hid_name, ux_device_class_hid_entry,
|
||||
1,2, (VOID *)&hid_parameter);
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
|
||||
/* Initialize the simulated device controller. */
|
||||
status = _ux_dcd_sim_slave_initialize();
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register all the USB host controllers available in this system */
|
||||
status = ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, ux_hcd_sim_host_initialize,0,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the main host simulation thread. */
|
||||
status = tx_thread_create(&tx_demo_thread_host_simulation, "tx demo host simulation", tx_demo_thread_host_simulation_entry, 0,
|
||||
stack_pointer, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static UINT ux_hcd_sim_host_entry_filter_device_extraction_test(UX_HCD *hcd, UINT function, VOID *parameter)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
switch(function)
|
||||
{
|
||||
case UX_HCD_GET_PORT_STATUS:
|
||||
|
||||
/* No device on this port. */
|
||||
status = 0;
|
||||
|
||||
/* This is a Full speed device. */
|
||||
status |= UX_PS_DS_FS;
|
||||
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
|
||||
status = _ux_hcd_sim_host_entry(hcd, function, parameter);
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void tx_demo_thread_host_simulation_entry(ULONG arg)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
UX_HCD *hcd;
|
||||
|
||||
/* Find the HID class */
|
||||
status = demo_class_hid_get();
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the HID client */
|
||||
hid_client = hid -> ux_host_class_hid_client;
|
||||
|
||||
/* Check if the instance of the keyboard is live */
|
||||
while (hid_client -> ux_host_class_hid_client_local_instance == UX_NULL)
|
||||
tx_thread_sleep(10);
|
||||
|
||||
/* Get the mouse instance */
|
||||
remote_control = (UX_HOST_CLASS_HID_REMOTE_CONTROL *)hid_client -> ux_host_class_hid_client_local_instance;
|
||||
|
||||
hcd = UX_DEVICE_HCD_GET(hid -> ux_host_class_hid_device);
|
||||
|
||||
/* Change the HCD entry function to our filter function. */
|
||||
hcd -> ux_hcd_entry_function = ux_hcd_sim_host_entry_filter_device_extraction_test;
|
||||
|
||||
/* Signal port activity to the enum thread. */
|
||||
hcd -> ux_hcd_root_hub_signal[0] = 1;
|
||||
|
||||
/* Signal enum thread. */
|
||||
_ux_utility_semaphore_put(&_ux_system_host -> ux_system_host_enum_semaphore);
|
||||
|
||||
/* Wait for hid class to shut down. */
|
||||
while(hid -> ux_host_class_hid_state == UX_HOST_CLASS_INSTANCE_LIVE)
|
||||
tx_thread_sleep(10);
|
||||
|
||||
/* Now disconnect the device. */
|
||||
_ux_device_stack_disconnect();
|
||||
|
||||
/* And deinitialize the class. */
|
||||
status = ux_device_stack_class_unregister(_ux_system_slave_class_hid_name, ux_device_class_hid_entry);
|
||||
|
||||
/* Deinitialize the device side of usbx. */
|
||||
_ux_device_stack_uninitialize();
|
||||
|
||||
/* And finally the usbx system resources. */
|
||||
_ux_system_uninitialize();
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
|
||||
static UINT demo_thread_hid_callback(UX_SLAVE_CLASS_HID *class, UX_SLAVE_CLASS_HID_EVENT *event)
|
||||
{
|
||||
return(UX_SUCCESS);
|
||||
}
|
358
test/regression/usbx_hid_remote_control_extraction_test2.c
Normal file
358
test/regression/usbx_hid_remote_control_extraction_test2.c
Normal file
@ -0,0 +1,358 @@
|
||||
/* This test is concentrates on extraction of a remote control device.
|
||||
This is similar to the first extraction test, except there is no ux_system_host_change_function.
|
||||
This allows us to hit the following false condition in _ux_host_class_hid_remote_control_deactivate:
|
||||
if (_ux_system_host -> ux_system_host_change_function != UX_NULL) */
|
||||
|
||||
#include "usbx_test_common_hid.h"
|
||||
#include "ux_host_class_hid_remote_control.h"
|
||||
|
||||
|
||||
static UX_HOST_CLASS_HID_REMOTE_CONTROL *remote_control;
|
||||
|
||||
|
||||
static UCHAR hid_remote_control_report[] = {
|
||||
|
||||
0x05, 0x0c, // USAGE_PAGE (Consumer Devices)
|
||||
0x09, 0x01, // USAGE (Consumer Control)
|
||||
0xa1, 0x01, // COLLECTION (Application)
|
||||
0x09, 0x02, // USAGE (Numeric Key Pad)
|
||||
0xa1, 0x02, // COLLECTION (Logical)
|
||||
0x05, 0x09, // USAGE_PAGE (Button)
|
||||
0x19, 0x01, // USAGE_MINIMUM (Button 1)
|
||||
0x29, 0x0a, // USAGE_MAXIMUM (Button 10)
|
||||
0x15, 0x01, // LOGICAL_MINIMUM (1)
|
||||
0x25, 0x0a, // LOGICAL_MAXIMUM (10)
|
||||
0x75, 0x04, // REPORT_SIZE (4)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x81, 0x00, // INPUT (Data,Ary,Abs)
|
||||
0xc0, // END_COLLECTION
|
||||
0x05, 0x0c, // USAGE_PAGE (Consumer Devices)
|
||||
0x09, 0x86, // USAGE (Channel)
|
||||
0x09, 0xe0, // USAGE (Volume)
|
||||
0x15, 0xff, // LOGICAL_MINIMUM (-1)
|
||||
0x25, 0x01, // LOGICAL_MAXIMUM (1)
|
||||
0x75, 0x02, // REPORT_SIZE (2)
|
||||
0x95, 0x02, // REPORT_COUNT (2)
|
||||
0x81, 0x46, // INPUT (Data,Var,Rel,Null)
|
||||
0xc0 // END_COLLECTION
|
||||
};
|
||||
#define HID_REMOTE_CONTROL_REPORT_LENGTH (sizeof(hid_remote_control_report)/sizeof(hid_remote_control_report[0]))
|
||||
|
||||
|
||||
#define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED 52
|
||||
static UCHAR device_framework_full_speed[] = {
|
||||
|
||||
/* Device descriptor */
|
||||
0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08,
|
||||
0x81, 0x0A, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x01,
|
||||
|
||||
/* Configuration descriptor */
|
||||
0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x00, 0xc0,
|
||||
0x32,
|
||||
|
||||
/* Interface descriptor */
|
||||
0x09, 0x04, 0x02, 0x00, 0x01, 0x03, 0x00, 0x00,
|
||||
0x00,
|
||||
|
||||
/* HID descriptor */
|
||||
0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(HID_REMOTE_CONTROL_REPORT_LENGTH),
|
||||
MSB(HID_REMOTE_CONTROL_REPORT_LENGTH),
|
||||
|
||||
/* Endpoint descriptor (Interrupt) */
|
||||
0x07, 0x05, 0x82, 0x03, 0x08, 0x00, 0x08
|
||||
|
||||
};
|
||||
|
||||
|
||||
#define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED 62
|
||||
static UCHAR device_framework_high_speed[] = {
|
||||
|
||||
/* Device descriptor */
|
||||
0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
|
||||
0x0a, 0x07, 0x25, 0x40, 0x01, 0x00, 0x01, 0x02,
|
||||
0x03, 0x01,
|
||||
|
||||
/* Device qualifier descriptor */
|
||||
0x0a, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
|
||||
0x01, 0x00,
|
||||
|
||||
/* Configuration descriptor */
|
||||
0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x00, 0xc0,
|
||||
0x32,
|
||||
|
||||
/* Interface descriptor */
|
||||
0x09, 0x04, 0x02, 0x00, 0x01, 0x03, 0x00, 0x00,
|
||||
0x00,
|
||||
|
||||
/* HID descriptor */
|
||||
0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(HID_REMOTE_CONTROL_REPORT_LENGTH),
|
||||
MSB(HID_REMOTE_CONTROL_REPORT_LENGTH),
|
||||
|
||||
/* Endpoint descriptor (Interrupt) */
|
||||
0x07, 0x05, 0x82, 0x03, 0x08, 0x00, 0x08
|
||||
|
||||
};
|
||||
|
||||
|
||||
/* String Device Framework :
|
||||
Byte 0 and 1 : Word containing the language ID : 0x0904 for US
|
||||
Byte 2 : Byte containing the index of the descriptor
|
||||
Byte 3 : Byte containing the length of the descriptor string
|
||||
*/
|
||||
|
||||
#define STRING_FRAMEWORK_LENGTH 40
|
||||
static UCHAR string_framework[] = {
|
||||
|
||||
/* Manufacturer string descriptor : Index 1 */
|
||||
0x09, 0x04, 0x01, 0x0c,
|
||||
0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
|
||||
0x6f, 0x67, 0x69, 0x63,
|
||||
|
||||
/* Product string descriptor : Index 2 */
|
||||
0x09, 0x04, 0x02, 0x0c,
|
||||
0x55, 0x53, 0x42, 0x20, 0x4b, 0x65, 0x79, 0x62,
|
||||
0x6f, 0x61, 0x72, 0x64,
|
||||
|
||||
/* Serial Number string descriptor : Index 3 */
|
||||
0x09, 0x04, 0x03, 0x04,
|
||||
0x30, 0x30, 0x30, 0x31
|
||||
};
|
||||
|
||||
|
||||
/* Multiple languages are supported on the device, to add
|
||||
a language besides english, the unicode language code must
|
||||
be appended to the language_id_framework array and the length
|
||||
adjusted accordingly. */
|
||||
#define LANGUAGE_ID_FRAMEWORK_LENGTH 2
|
||||
static UCHAR language_id_framework[] = {
|
||||
|
||||
/* English. */
|
||||
0x09, 0x04
|
||||
};
|
||||
|
||||
|
||||
UINT _ux_hcd_sim_host_entry(UX_HCD *hcd, UINT function, VOID *parameter);
|
||||
|
||||
static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
|
||||
{
|
||||
|
||||
/* Failed test. */
|
||||
printf("Error on line %d, system_level: %d, system_context: %d, error code: %d\n", __LINE__, system_level, system_context, error_code);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_hid_remote_control_extraction_test2_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR * stack_pointer;
|
||||
CHAR * memory_pointer;
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running HID Remote Control Extraction Test 2........................ ");
|
||||
|
||||
/* Initialize the free memory pointer */
|
||||
stack_pointer = (CHAR *) usbx_memory;
|
||||
memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
|
||||
|
||||
/* Initialize USBX. Memory */
|
||||
status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the error callback. */
|
||||
_ux_utility_error_callback_register(error_callback);
|
||||
|
||||
/* The code below is required for installing the host portion of USBX */
|
||||
status = ux_host_stack_initialize(NULL);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = ux_host_stack_class_register(_ux_system_host_class_hid_name, ux_host_class_hid_entry);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the HID client(s). */
|
||||
status = ux_host_class_hid_client_register(_ux_system_host_class_hid_client_remote_control_name, ux_host_class_hid_remote_control_entry);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* The code below is required for installing the device portion of USBX. No call back for
|
||||
device status change in this example. */
|
||||
status = ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
|
||||
device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
|
||||
string_framework, STRING_FRAMEWORK_LENGTH,
|
||||
language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Initialize the hid class parameters for a mouse. */
|
||||
hid_parameter.ux_device_class_hid_parameter_report_address = hid_remote_control_report;
|
||||
hid_parameter.ux_device_class_hid_parameter_report_length = HID_REMOTE_CONTROL_REPORT_LENGTH;
|
||||
hid_parameter.ux_device_class_hid_parameter_callback = demo_thread_hid_callback;
|
||||
|
||||
/* Initilize the device hid class. The class is connected with interface 2 */
|
||||
status = ux_device_stack_class_register(_ux_system_slave_class_hid_name, ux_device_class_hid_entry,
|
||||
1,2, (VOID *)&hid_parameter);
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
|
||||
/* Initialize the simulated device controller. */
|
||||
status = _ux_dcd_sim_slave_initialize();
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register all the USB host controllers available in this system */
|
||||
status = ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, ux_hcd_sim_host_initialize,0,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the main host simulation thread. */
|
||||
status = tx_thread_create(&tx_demo_thread_host_simulation, "tx demo host simulation", tx_demo_thread_host_simulation_entry, 0,
|
||||
stack_pointer, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static UINT ux_hcd_sim_host_entry_filter_device_extraction_test(UX_HCD *hcd, UINT function, VOID *parameter)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
switch(function)
|
||||
{
|
||||
case UX_HCD_GET_PORT_STATUS:
|
||||
|
||||
/* No device on this port. */
|
||||
status = 0;
|
||||
|
||||
/* This is a Full speed device. */
|
||||
status |= UX_PS_DS_FS;
|
||||
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
|
||||
status = _ux_hcd_sim_host_entry(hcd, function, parameter);
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void tx_demo_thread_host_simulation_entry(ULONG arg)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
UX_HCD *hcd;
|
||||
|
||||
/* Find the HID class */
|
||||
status = demo_class_hid_get();
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the HID client */
|
||||
hid_client = hid -> ux_host_class_hid_client;
|
||||
|
||||
/* Check if the instance of the keyboard is live */
|
||||
while (hid_client -> ux_host_class_hid_client_local_instance == UX_NULL)
|
||||
tx_thread_sleep(10);
|
||||
|
||||
/* Get the mouse instance */
|
||||
remote_control = (UX_HOST_CLASS_HID_REMOTE_CONTROL *)hid_client -> ux_host_class_hid_client_local_instance;
|
||||
|
||||
hcd = UX_DEVICE_HCD_GET(hid -> ux_host_class_hid_device);
|
||||
|
||||
/* Change the HCD entry function to our filter function. */
|
||||
hcd -> ux_hcd_entry_function = ux_hcd_sim_host_entry_filter_device_extraction_test;
|
||||
|
||||
/* Signal port activity to the enum thread. */
|
||||
hcd -> ux_hcd_root_hub_signal[0] = 1;
|
||||
|
||||
/* Signal enum thread. */
|
||||
_ux_utility_semaphore_put(&_ux_system_host -> ux_system_host_enum_semaphore);
|
||||
|
||||
/* Wait for hid class to shut down. */
|
||||
while(hid -> ux_host_class_hid_state == UX_HOST_CLASS_INSTANCE_LIVE)
|
||||
tx_thread_sleep(10);
|
||||
|
||||
/* Now disconnect the device. */
|
||||
_ux_device_stack_disconnect();
|
||||
|
||||
/* And deinitialize the class. */
|
||||
status = ux_device_stack_class_unregister(_ux_system_slave_class_hid_name, ux_device_class_hid_entry);
|
||||
|
||||
/* Deinitialize the device side of usbx. */
|
||||
_ux_device_stack_uninitialize();
|
||||
|
||||
/* And finally the usbx system resources. */
|
||||
_ux_system_uninitialize();
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
|
||||
static UINT demo_thread_hid_callback(UX_SLAVE_CLASS_HID *class, UX_SLAVE_CLASS_HID_EVENT *event)
|
||||
{
|
||||
return(UX_SUCCESS);
|
||||
}
|
692
test/regression/usbx_hid_remote_control_tests.c
Normal file
692
test/regression/usbx_hid_remote_control_tests.c
Normal file
@ -0,0 +1,692 @@
|
||||
/* TODO: some common stuff from storage we might want to pull out:
|
||||
-memory check - pretty good
|
||||
-connect and disconnect
|
||||
-getting class/instance
|
||||
*/
|
||||
|
||||
#include "ux_api.h"
|
||||
#include "ux_utility.h"
|
||||
#include "ux_host_class_hid.h"
|
||||
#include "ux_device_class_hid.h"
|
||||
#include "ux_host_class_hid_remote_control.h"
|
||||
|
||||
#include "ux_test.h"
|
||||
#include "ux_test_actions.h"
|
||||
#include "ux_test_dcd_sim_slave.h"
|
||||
#include "ux_test_hcd_sim_host.h"
|
||||
|
||||
|
||||
#define LSB(x) (x & 0xff)
|
||||
#define MSB(x) ((x & 0xff00) >> 8)
|
||||
|
||||
/* Define constants. */
|
||||
#define UX_DEMO_STACK_SIZE 1024
|
||||
#define UX_DEMO_MEMORY_SIZE (64*1024)
|
||||
|
||||
/* Define local/extern function prototypes. */
|
||||
static void test_main_thread_entry(ULONG);
|
||||
|
||||
/* Define global data structures. */
|
||||
static UCHAR usbx_memory[UX_DEMO_MEMORY_SIZE + (UX_DEMO_STACK_SIZE * 2)];
|
||||
static TX_THREAD test_main_thread;
|
||||
static TX_THREAD test_slave_thread;
|
||||
static UCHAR test_slave_thread_stack[4096];
|
||||
static UX_HOST_CLASS *global_host_hid_class;
|
||||
static UX_HOST_CLASS_HID *global_host_hid;
|
||||
static UX_SLAVE_CLASS_HID *global_slave_hid;
|
||||
static UX_SLAVE_CLASS_HID *global_slave_hid_persistent;
|
||||
static UX_HOST_CLASS_HID_CLIENT *global_host_hid_client;
|
||||
static UX_HOST_CLASS_HID_REMOTE_CONTROL *global_host_remote_control;
|
||||
static UX_SLAVE_CLASS_HID_PARAMETER global_slave_hid_parameter;
|
||||
static UX_HCD *global_hcd;
|
||||
|
||||
|
||||
static UCHAR hid_report_descriptor[] = {
|
||||
|
||||
0x05, 0x0c, // USAGE_PAGE (Consumer Devices)
|
||||
0x09, 0x01, // USAGE (Consumer Control)
|
||||
0xa1, 0x01, // COLLECTION (Application)
|
||||
0x09, 0x02, // USAGE (Numeric Key Pad)
|
||||
0xa1, 0x02, // COLLECTION (Logical)
|
||||
0x05, 0x09, // USAGE_PAGE (Button)
|
||||
0x19, 0x01, // USAGE_MINIMUM (Button 1)
|
||||
0x29, 0x0a, // USAGE_MAXIMUM (Button 10)
|
||||
0x15, 0x01, // LOGICAL_MINIMUM (1)
|
||||
0x25, 0x0a, // LOGICAL_MAXIMUM (10)
|
||||
0x75, 0x04, // REPORT_SIZE (4)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x81, 0x00, // INPUT (Data,Ary,Abs)
|
||||
0xc0, // END_COLLECTION
|
||||
0x05, 0x0c, // USAGE_PAGE (Consumer Devices)
|
||||
0x09, 0x86, // USAGE (Channel)
|
||||
0x09, 0xe0, // USAGE (Volume)
|
||||
0x15, 0xff, // LOGICAL_MINIMUM (-1)
|
||||
0x25, 0x01, // LOGICAL_MAXIMUM (1)
|
||||
0x75, 0x02, // REPORT_SIZE (2)
|
||||
0x95, 0x02, // REPORT_COUNT (2)
|
||||
0x81, 0x46, // INPUT (Data,Var,Rel,Null)
|
||||
0xc0 // END_COLLECTION
|
||||
};
|
||||
|
||||
static UCHAR device_framework_full_speed[] = {
|
||||
|
||||
/* Device descriptor */
|
||||
0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08,
|
||||
0x81, 0x0A, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x01,
|
||||
|
||||
/* Configuration descriptor */
|
||||
0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x00, 0xc0,
|
||||
0x32,
|
||||
|
||||
/* Interface descriptor */
|
||||
0x09, 0x04, 0x02, 0x00, 0x01, 0x03, 0x00, 0x00,
|
||||
0x00,
|
||||
|
||||
/* HID descriptor */
|
||||
0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(sizeof(hid_report_descriptor)),
|
||||
MSB(sizeof(hid_report_descriptor)),
|
||||
|
||||
/* Endpoint descriptor (Interrupt) */
|
||||
0x07, 0x05, 0x82, 0x03, 0x08, 0x00, 0x08
|
||||
|
||||
};
|
||||
|
||||
#define FULL_SPEED_REPORT_DESCRIPTOR_LENGTH_LSB_POS (0x12 + 0x09 + 0x09 + 0x7)
|
||||
#define FULL_SPEED_REPORT_DESCRIPTOR_LENGTH_MSB_POS (FULL_SPEED_REPORT_DESCRIPTOR_LENGTH_LSB_POS + 1)
|
||||
|
||||
|
||||
static UCHAR device_framework_high_speed[] = {
|
||||
|
||||
/* Device descriptor */
|
||||
0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
|
||||
0x0a, 0x07, 0x25, 0x40, 0x01, 0x00, 0x01, 0x02,
|
||||
0x03, 0x01,
|
||||
|
||||
/* Device qualifier descriptor */
|
||||
0x0a, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
|
||||
0x01, 0x00,
|
||||
|
||||
/* Configuration descriptor */
|
||||
0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x00, 0xc0,
|
||||
0x32,
|
||||
|
||||
/* Interface descriptor */
|
||||
0x09, 0x04, 0x02, 0x00, 0x01, 0x03, 0x00, 0x00,
|
||||
0x00,
|
||||
|
||||
/* HID descriptor */
|
||||
0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(sizeof(hid_report_descriptor)),
|
||||
MSB(sizeof(hid_report_descriptor)),
|
||||
|
||||
/* Endpoint descriptor (Interrupt) */
|
||||
0x07, 0x05, 0x82, 0x03, 0x08, 0x00, 0x08
|
||||
|
||||
};
|
||||
|
||||
#define HIGH_SPEED_REPORT_DESCRIPTOR_LENGTH_LSB_POS (0x12 + 0x0a + 0x09 + 0x09 + 0x7)
|
||||
#define HIGH_SPEED_REPORT_DESCRIPTOR_LENGTH_MSB_POS (HIGH_SPEED_REPORT_DESCRIPTOR_LENGTH_LSB_POS + 1)
|
||||
|
||||
|
||||
/* String Device Framework :
|
||||
Byte 0 and 1 : Word containing the language ID : 0x0904 for US
|
||||
Byte 2 : Byte containing the index of the descriptor
|
||||
Byte 3 : Byte containing the length of the descriptor string
|
||||
*/
|
||||
|
||||
#define STRING_FRAMEWORK_LENGTH 40
|
||||
static UCHAR string_framework[] = {
|
||||
|
||||
/* Manufacturer string descriptor : Index 1 */
|
||||
0x09, 0x04, 0x01, 0x0c,
|
||||
0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
|
||||
0x6f, 0x67, 0x69, 0x63,
|
||||
|
||||
/* Product string descriptor : Index 2 */
|
||||
0x09, 0x04, 0x02, 0x0c,
|
||||
0x55, 0x53, 0x42, 0x20, 0x4b, 0x65, 0x79, 0x62,
|
||||
0x6f, 0x61, 0x72, 0x64,
|
||||
|
||||
/* Serial Number string descriptor : Index 3 */
|
||||
0x09, 0x04, 0x03, 0x04,
|
||||
0x30, 0x30, 0x30, 0x31
|
||||
};
|
||||
|
||||
|
||||
/* Multiple languages are supported on the device, to add
|
||||
a language besides english, the unicode language code must
|
||||
be appended to the language_id_framework array and the length
|
||||
adjusted accordingly. */
|
||||
#define LANGUAGE_ID_FRAMEWORK_LENGTH 2
|
||||
static UCHAR language_id_framework[] = {
|
||||
|
||||
/* English. */
|
||||
0x09, 0x04
|
||||
};
|
||||
|
||||
/* Functions from storage basic test. */
|
||||
|
||||
static VOID get_global_hid_values()
|
||||
{
|
||||
|
||||
UX_TEST_CHECK_SUCCESS(ux_host_stack_class_get(_ux_system_host_class_hid_name, &global_host_hid_class));
|
||||
UX_TEST_CHECK_SUCCESS(ux_host_stack_class_instance_get(global_host_hid_class, 0, (void **) &global_host_hid));
|
||||
UX_TEST_ASSERT(global_host_hid -> ux_host_class_hid_state == UX_HOST_CLASS_INSTANCE_LIVE);
|
||||
global_host_hid_client = global_host_hid -> ux_host_class_hid_client;
|
||||
UX_TEST_ASSERT(global_host_hid_client -> ux_host_class_hid_client_local_instance != UX_NULL);
|
||||
global_host_remote_control = (UX_HOST_CLASS_HID_REMOTE_CONTROL *)global_host_hid_client -> ux_host_class_hid_client_local_instance;
|
||||
}
|
||||
|
||||
static VOID wait_for_enum_completion_and_get_global_hid_values()
|
||||
{
|
||||
|
||||
ux_test_wait_for_enum_thread_completion();
|
||||
get_global_hid_values();
|
||||
}
|
||||
|
||||
/* Returns whether or not the enumeration succeeded. */
|
||||
static VOID connect_host_and_slave()
|
||||
{
|
||||
|
||||
ux_test_connect_slave_and_host_wait_for_enum_completion();
|
||||
get_global_hid_values();
|
||||
}
|
||||
|
||||
/* General HID utilities. */
|
||||
|
||||
void set_report_descriptor(UCHAR *report_descriptor, ULONG report_descriptor_length)
|
||||
{
|
||||
|
||||
/* Should only be called if the host and slave is disconnected. */
|
||||
UX_TEST_ASSERT(global_hcd->ux_hcd_nb_devices == 0);
|
||||
UX_TEST_ASSERT(_ux_system_slave->ux_system_slave_device.ux_slave_device_state == UX_DEVICE_RESET);
|
||||
|
||||
global_slave_hid_persistent->ux_device_class_hid_report_address = report_descriptor;
|
||||
global_slave_hid_persistent->ux_device_class_hid_report_length = report_descriptor_length;
|
||||
|
||||
device_framework_full_speed[FULL_SPEED_REPORT_DESCRIPTOR_LENGTH_LSB_POS] = LSB(report_descriptor_length);
|
||||
device_framework_full_speed[FULL_SPEED_REPORT_DESCRIPTOR_LENGTH_MSB_POS] = MSB(report_descriptor_length);
|
||||
|
||||
device_framework_high_speed[HIGH_SPEED_REPORT_DESCRIPTOR_LENGTH_LSB_POS] = LSB(report_descriptor_length);
|
||||
device_framework_high_speed[HIGH_SPEED_REPORT_DESCRIPTOR_LENGTH_MSB_POS] = MSB(report_descriptor_length);
|
||||
}
|
||||
|
||||
UINT slave_hid_callback(UX_SLAVE_CLASS_HID *hid, UX_SLAVE_CLASS_HID_EVENT *event)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
VOID slave_class_hid_instance_activate(VOID *instance)
|
||||
{
|
||||
|
||||
if (global_slave_hid_persistent)
|
||||
UX_TEST_ASSERT(global_slave_hid_persistent == instance);
|
||||
global_slave_hid_persistent = instance;
|
||||
|
||||
global_slave_hid = instance;
|
||||
}
|
||||
|
||||
VOID slave_class_hid_instance_deactivate(VOID *instance)
|
||||
{
|
||||
|
||||
global_slave_hid = UX_NULL;
|
||||
}
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_hid_remote_control_tests_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR *stack_pointer;
|
||||
CHAR *memory_pointer;
|
||||
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running HID Remote Control Tests.................................... ");
|
||||
|
||||
stepinfo("\n");
|
||||
|
||||
/* Initialize the free memory pointer */
|
||||
stack_pointer = (CHAR *) usbx_memory;
|
||||
memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
|
||||
|
||||
/* Initialize USBX. Memory */
|
||||
status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the error callback. */
|
||||
_ux_utility_error_callback_register(ux_test_error_callback);
|
||||
|
||||
/* The code below is required for installing the host portion of USBX */
|
||||
status = ux_host_stack_initialize(UX_NULL);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = ux_host_stack_class_register(_ux_system_host_class_hid_name, ux_host_class_hid_entry);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the HID client(s). */
|
||||
status = ux_host_class_hid_client_register(_ux_system_host_class_hid_client_remote_control_name, ux_host_class_hid_remote_control_entry);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* The code below is required for installing the device portion of USBX. No call back for
|
||||
device status change in this example. */
|
||||
status = ux_device_stack_initialize(device_framework_high_speed, sizeof(device_framework_high_speed),
|
||||
device_framework_full_speed, sizeof(device_framework_full_speed),
|
||||
string_framework, STRING_FRAMEWORK_LENGTH,
|
||||
language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH, UX_NULL);
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Initialize the hid class parameters for a mouse. */
|
||||
global_slave_hid_parameter.ux_slave_class_hid_instance_activate = slave_class_hid_instance_activate;
|
||||
global_slave_hid_parameter.ux_slave_class_hid_instance_deactivate = slave_class_hid_instance_deactivate;
|
||||
global_slave_hid_parameter.ux_device_class_hid_parameter_report_address = hid_report_descriptor;
|
||||
global_slave_hid_parameter.ux_device_class_hid_parameter_report_length = sizeof(hid_report_descriptor);
|
||||
global_slave_hid_parameter.ux_device_class_hid_parameter_callback = slave_hid_callback;
|
||||
|
||||
/* Initilize the device hid class. The class is connected with interface 2. */
|
||||
status = ux_device_stack_class_register(_ux_system_slave_class_hid_name, ux_device_class_hid_entry,
|
||||
1, 2, (VOID *)&global_slave_hid_parameter);
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
|
||||
/* Initialize the simulated device controller. */
|
||||
status = _ux_dcd_sim_slave_initialize();
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register all the USB host controllers available in this system */
|
||||
status = ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, ux_hcd_sim_host_initialize,0,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
global_hcd = &_ux_system_host->ux_system_host_hcd_array[0];
|
||||
|
||||
/* Create the main host simulation thread. */
|
||||
status = tx_thread_create(&test_main_thread, "test_main_thread", test_main_thread_entry, 0,
|
||||
stack_pointer, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* basic_test resources */
|
||||
|
||||
static UINT basic_test_get_next_channel_volume_value(ULONG value)
|
||||
{
|
||||
|
||||
if (value == 0x03)
|
||||
return 0x00;
|
||||
else if (value == 0x00)
|
||||
return 0x01;
|
||||
else if (value == 0x01)
|
||||
return 0x03;
|
||||
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
static void basic_test_slave_thread_entry(ULONG arg)
|
||||
{
|
||||
|
||||
UX_SLAVE_CLASS_HID_EVENT hid_event;
|
||||
ULONG value;
|
||||
UINT max_num_loops;
|
||||
|
||||
|
||||
/* reset the HID event structure. */
|
||||
ux_utility_memory_set(&hid_event, 0, sizeof(UX_SLAVE_CLASS_HID_EVENT));
|
||||
|
||||
/* Set length of event. */
|
||||
hid_event.ux_device_class_hid_event_length = 1;
|
||||
|
||||
/* Set initial keypad value. */
|
||||
hid_event.ux_device_class_hid_event_buffer[0] = 0x01;
|
||||
|
||||
/* Set initial channel value. */
|
||||
hid_event.ux_device_class_hid_event_buffer[0] |= (0x03 << 4);
|
||||
|
||||
/* Set initial volume value. */
|
||||
hid_event.ux_device_class_hid_event_buffer[0] |= (0x01 << 6);
|
||||
|
||||
max_num_loops = 2*UX_HOST_CLASS_HID_REMOTE_CONTROL_USAGE_ARRAY_LENGTH;
|
||||
while (max_num_loops--)
|
||||
{
|
||||
|
||||
stepinfo(" slave - max_num_loops: %d\n", max_num_loops);
|
||||
|
||||
/* Wait for host to receive. */
|
||||
ux_utility_thread_sleep(2);
|
||||
|
||||
/* Set the mouse event. */
|
||||
UX_TEST_CHECK_SUCCESS(ux_device_class_hid_event_set(global_slave_hid, &hid_event));
|
||||
|
||||
/* Change keypad value. */
|
||||
value = hid_event.ux_device_class_hid_event_buffer[0] & 0x0f;
|
||||
if (value >= 0x0a)
|
||||
value = 0x01;
|
||||
else
|
||||
value++;
|
||||
|
||||
hid_event.ux_device_class_hid_event_buffer[0] &= 0xf0;
|
||||
hid_event.ux_device_class_hid_event_buffer[0] |= value;
|
||||
|
||||
/* Change channel value. */
|
||||
value = ((hid_event.ux_device_class_hid_event_buffer[0] & 0x30) >> 4);
|
||||
hid_event.ux_device_class_hid_event_buffer[0] &= ~0x30;
|
||||
hid_event.ux_device_class_hid_event_buffer[0] |= (basic_test_get_next_channel_volume_value(value) << 4);
|
||||
|
||||
/* Change volume value. */
|
||||
value = ((hid_event.ux_device_class_hid_event_buffer[0] & 0xc0) >> 6);
|
||||
hid_event.ux_device_class_hid_event_buffer[0] &= ~0xc0;
|
||||
hid_event.ux_device_class_hid_event_buffer[0] |= (basic_test_get_next_channel_volume_value(value) << 6);
|
||||
}
|
||||
}
|
||||
|
||||
static void basic_test()
|
||||
{
|
||||
|
||||
UINT max_num_loops;
|
||||
ULONG usage;
|
||||
ULONG value;
|
||||
ULONG expected_keypad_value;
|
||||
ULONG expected_channel_value;
|
||||
ULONG expected_volume_value;
|
||||
|
||||
|
||||
stepinfo("basic_test\n");
|
||||
|
||||
UX_TEST_CHECK_SUCCESS(tx_thread_create(&test_slave_thread, "test_slave_thread", basic_test_slave_thread_entry, 0,
|
||||
test_slave_thread_stack, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START));
|
||||
|
||||
/* Initialize expected values. */
|
||||
expected_keypad_value = 0x01;
|
||||
expected_channel_value = 0x03;
|
||||
expected_volume_value = 0x01;
|
||||
|
||||
/* Set number of successful loops to execute. */
|
||||
max_num_loops = 2*UX_HOST_CLASS_HID_REMOTE_CONTROL_USAGE_ARRAY_LENGTH;
|
||||
while (max_num_loops--)
|
||||
{
|
||||
|
||||
stepinfo(" host - max_num_loops: %d\n", max_num_loops);
|
||||
|
||||
/* Wait for an event from the device. Each event should have 3 usages. The first is the keypad. */
|
||||
while (ux_host_class_hid_remote_control_usage_get(global_host_remote_control, &usage, &value) != UX_SUCCESS)
|
||||
tx_thread_sleep(1);
|
||||
|
||||
if (usage != (0x00090000 | expected_keypad_value) || value != expected_keypad_value)
|
||||
{
|
||||
|
||||
printf("Error on line %d. usage: 0x%lx, expected usage: 0x%lx, value: 0x%lx, expected_keypad_value: 0x%lx\n",
|
||||
__LINE__, usage, 0x00090000 | expected_keypad_value, value, expected_keypad_value);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
if (++expected_keypad_value > 0x0a)
|
||||
expected_keypad_value = 1;
|
||||
|
||||
/* Get the channel value. */
|
||||
ux_host_class_hid_remote_control_usage_get(global_host_remote_control, &usage, &value);
|
||||
if (usage != 0x000c0086 || value != expected_channel_value)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
expected_channel_value = basic_test_get_next_channel_volume_value(value);
|
||||
|
||||
/* Get the volume value. */
|
||||
ux_host_class_hid_remote_control_usage_get(global_host_remote_control, &usage, &value);
|
||||
if (usage != 0x000c00e0 || value != expected_volume_value)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
expected_volume_value = basic_test_get_next_channel_volume_value(value);
|
||||
}
|
||||
|
||||
UX_TEST_CHECK_SUCCESS(tx_thread_terminate(&test_slave_thread));
|
||||
UX_TEST_CHECK_SUCCESS(tx_thread_delete(&test_slave_thread));
|
||||
}
|
||||
|
||||
/* event_overflow_test resources */
|
||||
|
||||
#define EBT_MAX_EVENTS ((UX_HOST_CLASS_HID_REMOTE_CONTROL_USAGE_ARRAY_LENGTH/2) - 1)
|
||||
#define EBT_NUM_OVERFLOW_EVENTS 100
|
||||
|
||||
static TX_SEMAPHORE ebt_slave_wakes_host_semaphore;
|
||||
static TX_SEMAPHORE ebt_host_wakes_slave_semaphore;
|
||||
|
||||
static UCHAR host_event_buffer_test_hid_report_descriptor[] = {
|
||||
|
||||
0x05, 0x0c, // USAGE_PAGE (Consumer Devices)
|
||||
0x09, 0x01, // USAGE (Consumer Control)
|
||||
0xa1, 0x01, // COLLECTION (Application)
|
||||
0x05, 0x0c, // USAGE_PAGE (Consumer Devices)
|
||||
0x09, 0xe0, // USAGE (Volume)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x25, 0xff, // LOGICAL_MAXIMUM (255)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x81, 0x46, // INPUT (Data,Var,Rel,Null)
|
||||
0xc0 // END_COLLECTION
|
||||
};
|
||||
|
||||
static void event_buffer_test_slave_thread_entry(ULONG arg)
|
||||
{
|
||||
|
||||
UX_SLAVE_CLASS_HID_EVENT hid_event = { 0 };
|
||||
UINT i;
|
||||
|
||||
|
||||
/* Add the exact amount. Remember, the host's usage array consists of pairs,
|
||||
hence the divide by two. */
|
||||
for (i = 0; i < EBT_MAX_EVENTS; i++)
|
||||
{
|
||||
|
||||
/* Setup and send event. */
|
||||
hid_event.ux_device_class_hid_event_length = 1;
|
||||
hid_event.ux_device_class_hid_event_buffer[0] = i;
|
||||
UX_TEST_CHECK_SUCCESS(ux_device_class_hid_event_set(global_slave_hid, &hid_event));
|
||||
|
||||
/* Wait for host to receive it. */
|
||||
tx_thread_sleep(2);
|
||||
}
|
||||
|
||||
/* Wake up host test thread. */
|
||||
tx_semaphore_put(&ebt_slave_wakes_host_semaphore);
|
||||
|
||||
/* Wait for second part of test. */
|
||||
tx_semaphore_get(&ebt_host_wakes_slave_semaphore, TX_WAIT_FOREVER);
|
||||
|
||||
/* We expect to receive some errors. */
|
||||
ux_test_add_action_to_main_list_multiple(create_error_match_action(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_BUFFER_OVERFLOW), EBT_NUM_OVERFLOW_EVENTS);
|
||||
|
||||
for (i = 0; i < EBT_MAX_EVENTS + EBT_NUM_OVERFLOW_EVENTS; i++)
|
||||
{
|
||||
|
||||
/* Setup and send event. */
|
||||
hid_event.ux_device_class_hid_event_length = 1;
|
||||
hid_event.ux_device_class_hid_event_buffer[0] = i;
|
||||
UX_TEST_CHECK_SUCCESS(ux_device_class_hid_event_set(global_slave_hid, &hid_event));
|
||||
|
||||
/* Wait for host to receive it. */
|
||||
tx_thread_sleep(2);
|
||||
}
|
||||
|
||||
/* Ensure all of our actions are gone. */
|
||||
UX_TEST_ASSERT_MESSAGE(ux_test_check_actions_empty(), "Number of actions remaining: %d\n", ux_test_get_num_actions_left());
|
||||
|
||||
/* Wake up host test thread. */
|
||||
tx_semaphore_put(&ebt_slave_wakes_host_semaphore);
|
||||
}
|
||||
|
||||
static void host_event_buffer_test()
|
||||
{
|
||||
|
||||
ULONG usage;
|
||||
ULONG value;
|
||||
UINT i;
|
||||
|
||||
|
||||
stepinfo("event_buffer_overflow_test\n");
|
||||
|
||||
ux_test_disconnect_slave_and_host_wait_for_enum_completion(global_hcd);
|
||||
set_report_descriptor(host_event_buffer_test_hid_report_descriptor, sizeof(host_event_buffer_test_hid_report_descriptor));
|
||||
connect_host_and_slave();
|
||||
|
||||
UX_TEST_CHECK_SUCCESS(tx_semaphore_create(&ebt_slave_wakes_host_semaphore, "ebt_slave_wakes_host_semaphore", 0));
|
||||
UX_TEST_CHECK_SUCCESS(tx_semaphore_create(&ebt_host_wakes_slave_semaphore, "ebt_host_wakes_slave_semaphore", 0));
|
||||
|
||||
UX_TEST_CHECK_SUCCESS(tx_thread_create(&test_slave_thread, "test_slave_thread", event_buffer_test_slave_thread_entry, 0,
|
||||
test_slave_thread_stack, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START));
|
||||
|
||||
stepinfo(" exact amount\n");
|
||||
|
||||
/* Wait for slave to send exact amount. */
|
||||
tx_semaphore_get(&ebt_slave_wakes_host_semaphore, TX_WAIT_FOREVER);
|
||||
|
||||
/* Ensure exact amount was sent. */
|
||||
for (i = 0; i < EBT_MAX_EVENTS; i++)
|
||||
{
|
||||
|
||||
UX_TEST_CHECK_SUCCESS(ux_host_class_hid_remote_control_usage_get(global_host_remote_control, &usage, &value));
|
||||
UX_TEST_ASSERT(usage == 0x000c00e0);
|
||||
UX_TEST_ASSERT(value == i);
|
||||
}
|
||||
|
||||
/* Should be no more. */
|
||||
UX_TEST_CHECK_NOT_SUCCESS(ux_host_class_hid_remote_control_usage_get(global_host_remote_control, &usage, &value));
|
||||
|
||||
stepinfo(" overflow\n");
|
||||
|
||||
/* Wake up slave. */
|
||||
tx_semaphore_put(&ebt_host_wakes_slave_semaphore);
|
||||
|
||||
/* Wait for slave to overflow. */
|
||||
tx_semaphore_get(&ebt_slave_wakes_host_semaphore, TX_WAIT_FOREVER);
|
||||
|
||||
/* Ensure exact amount was sent. */
|
||||
for (i = 0; i < EBT_MAX_EVENTS; i++)
|
||||
{
|
||||
|
||||
UX_TEST_CHECK_SUCCESS(ux_host_class_hid_remote_control_usage_get(global_host_remote_control, &usage, &value));
|
||||
UX_TEST_ASSERT(usage == 0x000c00e0);
|
||||
UX_TEST_ASSERT(value == i);
|
||||
}
|
||||
|
||||
/* Should be no more. */
|
||||
UX_TEST_CHECK_NOT_SUCCESS(ux_host_class_hid_remote_control_usage_get(global_host_remote_control, &usage, &value));
|
||||
|
||||
UX_TEST_CHECK_SUCCESS(tx_thread_terminate(&test_slave_thread));
|
||||
UX_TEST_CHECK_SUCCESS(tx_thread_delete(&test_slave_thread));
|
||||
}
|
||||
|
||||
static void test_main_thread_entry(ULONG arg)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
UINT i;
|
||||
void (*tests[])() =
|
||||
{
|
||||
basic_test,
|
||||
host_event_buffer_test,
|
||||
};
|
||||
|
||||
|
||||
ux_test_wait_for_enum_thread_completion();
|
||||
get_global_hid_values();
|
||||
ux_test_memory_test_initialize();
|
||||
get_global_hid_values();
|
||||
/* Run tests. */
|
||||
for (i = 0; i < ARRAY_COUNT(tests); i++)
|
||||
{
|
||||
tests[i]();
|
||||
|
||||
ux_test_disconnect_slave_and_host_wait_for_enum_completion(global_hcd);
|
||||
set_report_descriptor(hid_report_descriptor, sizeof(hid_report_descriptor));
|
||||
connect_host_and_slave();
|
||||
|
||||
UX_TEST_ASSERT(ux_test_check_actions_empty());
|
||||
}
|
||||
|
||||
/* Now disconnect the device. */
|
||||
_ux_device_stack_disconnect();
|
||||
|
||||
/* And deinitialize the class. */
|
||||
status = ux_device_stack_class_unregister(_ux_system_slave_class_hid_name, ux_device_class_hid_entry);
|
||||
|
||||
/* Deinitialize the device side of usbx. */
|
||||
_ux_device_stack_uninitialize();
|
||||
|
||||
/* And finally the usbx system resources. */
|
||||
_ux_system_uninitialize();
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
|
||||
static UINT demo_thread_hid_callback(UX_SLAVE_CLASS_HID *class, UX_SLAVE_CLASS_HID_EVENT *event)
|
||||
{
|
||||
return(UX_SUCCESS);
|
||||
}
|
@ -0,0 +1,313 @@
|
||||
/* This test ensures that the parser fails when too many collections are used. */
|
||||
|
||||
#include "usbx_test_common_hid.h"
|
||||
#include "ux_host_class_hid_keyboard.h"
|
||||
|
||||
|
||||
static UINT callback_error_code;
|
||||
|
||||
static UCHAR hid_report_descriptor[] = {
|
||||
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||
0x09, 0x06, // USAGE (Keyboard)
|
||||
0xa1, 0x01, // COLLECTION (Application)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x75, 0x02, // REPORT_SIZE (2)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
0xa1, 0x00, // COLLECTION (Physical)
|
||||
0x95, 0x03, // REPORT_COUNT (3)
|
||||
0x75, 0x04, // REPORT_SIZE (4)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
0xa1, 0x00, // COLLECTION (Physical)
|
||||
0x95, 0x05, // REPORT_COUNT (5)
|
||||
0x75, 0x06, // REPORT_SIZE (6)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
0xa1, 0x00, // COLLECTION (Physical)
|
||||
0x95, 0x07, // REPORT_COUNT (7)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
/* Add 5th collection (should break). */
|
||||
0xa1, 0x00, // COLLECTION (Physical)
|
||||
0x95, 0x07, // REPORT_COUNT (7)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
0xc0, // END_COLLECTION
|
||||
0xc0, // END_COLLECTION
|
||||
0xc0, // END_COLLECTION
|
||||
0xc0, // END_COLLECTION
|
||||
0xc0, // END_COLLECTION
|
||||
};
|
||||
#define HID_REPORT_LENGTH sizeof(hid_report_descriptor)/sizeof(hid_report_descriptor[0])
|
||||
|
||||
|
||||
#define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED 52
|
||||
static UCHAR device_framework_full_speed[DEVICE_FRAMEWORK_LENGTH_FULL_SPEED] = {
|
||||
|
||||
/* Device descriptor */
|
||||
0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08,
|
||||
0x81, 0x0A, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x01,
|
||||
|
||||
/* Configuration descriptor */
|
||||
0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x00, 0xc0,
|
||||
0x32,
|
||||
|
||||
/* Interface descriptor */
|
||||
0x09, 0x04, 0x02, 0x00, 0x01, 0x03, 0x00, 0x00,
|
||||
0x00,
|
||||
|
||||
/* HID descriptor */
|
||||
0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(HID_REPORT_LENGTH),
|
||||
MSB(HID_REPORT_LENGTH),
|
||||
|
||||
/* Endpoint descriptor (Interrupt) */
|
||||
0x07, 0x05, 0x82, 0x03, 0x08, 0x00, 0x08
|
||||
|
||||
};
|
||||
|
||||
|
||||
#define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED 62
|
||||
static UCHAR device_framework_high_speed[DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED] = {
|
||||
|
||||
/* Device descriptor */
|
||||
0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
|
||||
0x0a, 0x07, 0x25, 0x40, 0x01, 0x00, 0x01, 0x02,
|
||||
0x03, 0x01,
|
||||
|
||||
/* Device qualifier descriptor */
|
||||
0x0a, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
|
||||
0x01, 0x00,
|
||||
|
||||
/* Configuration descriptor */
|
||||
0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x00, 0xc0,
|
||||
0x32,
|
||||
|
||||
/* Interface descriptor */
|
||||
0x09, 0x04, 0x02, 0x00, 0x01, 0x03, 0x00, 0x00,
|
||||
0x00,
|
||||
|
||||
/* HID descriptor */
|
||||
0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(HID_REPORT_LENGTH),
|
||||
MSB(HID_REPORT_LENGTH),
|
||||
|
||||
/* Endpoint descriptor (Interrupt) */
|
||||
0x07, 0x05, 0x82, 0x03, 0x08, 0x00, 0x08
|
||||
|
||||
};
|
||||
|
||||
|
||||
/* String Device Framework :
|
||||
Byte 0 and 1 : Word containing the language ID : 0x0904 for US
|
||||
Byte 2 : Byte containing the index of the descriptor
|
||||
Byte 3 : Byte containing the length of the descriptor string
|
||||
*/
|
||||
|
||||
#define STRING_FRAMEWORK_LENGTH 40
|
||||
static UCHAR string_framework[] = {
|
||||
|
||||
/* Manufacturer string descriptor : Index 1 */
|
||||
0x09, 0x04, 0x01, 0x0c,
|
||||
0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
|
||||
0x6f, 0x67, 0x69, 0x63,
|
||||
|
||||
/* Product string descriptor : Index 2 */
|
||||
0x09, 0x04, 0x02, 0x0c,
|
||||
0x55, 0x53, 0x42, 0x20, 0x4b, 0x65, 0x79, 0x62,
|
||||
0x6f, 0x61, 0x72, 0x64,
|
||||
|
||||
/* Serial Number string descriptor : Index 3 */
|
||||
0x09, 0x04, 0x03, 0x04,
|
||||
0x30, 0x30, 0x30, 0x31
|
||||
};
|
||||
|
||||
|
||||
/* Multiple languages are supported on the device, to add
|
||||
a language besides english, the unicode language code must
|
||||
be appended to the language_id_framework array and the length
|
||||
adjusted accordingly. */
|
||||
#define LANGUAGE_ID_FRAMEWORK_LENGTH 2
|
||||
static UCHAR language_id_framework[] = {
|
||||
|
||||
/* English. */
|
||||
0x09, 0x04
|
||||
};
|
||||
|
||||
|
||||
|
||||
static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
|
||||
{
|
||||
|
||||
if (error_code != UX_HOST_CLASS_HID_COLLECTION_OVERFLOW &&
|
||||
error_code != UX_DESCRIPTOR_CORRUPTED &&
|
||||
error_code != UX_DEVICE_ENUMERATION_FAILURE)
|
||||
{
|
||||
|
||||
/* Something went wrong. */
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_hid_report_descriptor_collection_overflow_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR * stack_pointer;
|
||||
CHAR * memory_pointer;
|
||||
UINT descriptor_size = HID_REPORT_LENGTH;
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running HID Report Descriptor Collection Oveflow Test............... ");
|
||||
|
||||
/* Initialize the free memory pointer */
|
||||
stack_pointer = (CHAR *) usbx_memory;
|
||||
memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
|
||||
|
||||
/* Initialize USBX. Memory */
|
||||
status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the error callback. */
|
||||
_ux_utility_error_callback_register(error_callback);
|
||||
|
||||
/* The code below is required for installing the host portion of USBX */
|
||||
status = ux_host_stack_initialize(UX_NULL);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = ux_host_stack_class_register(_ux_system_host_class_hid_name, ux_host_class_hid_entry);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the HID client(s). */
|
||||
status = ux_host_class_hid_client_register(_ux_system_host_class_hid_client_keyboard_name, ux_host_class_hid_keyboard_entry);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* The code below is required for installing the device portion of USBX. No call back for
|
||||
device status change in this example. */
|
||||
status = ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
|
||||
device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
|
||||
string_framework, STRING_FRAMEWORK_LENGTH,
|
||||
language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Initialize the hid class parameters. */
|
||||
hid_parameter.ux_device_class_hid_parameter_report_address = hid_report_descriptor;
|
||||
hid_parameter.ux_device_class_hid_parameter_report_length = HID_REPORT_LENGTH;
|
||||
hid_parameter.ux_device_class_hid_parameter_callback = demo_thread_hid_callback;
|
||||
|
||||
/* Initilize the device hid class. The class is connected with interface 2 */
|
||||
status = ux_device_stack_class_register(_ux_system_slave_class_hid_name, ux_device_class_hid_entry,
|
||||
1,2, (VOID *)&hid_parameter);
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
|
||||
/* Initialize the simulated device controller. */
|
||||
status = _ux_dcd_sim_slave_initialize();
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register all the USB host controllers available in this system */
|
||||
status = ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, ux_hcd_sim_host_initialize,0,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the main host simulation thread. */
|
||||
status = tx_thread_create(&tx_demo_thread_host_simulation, "tx demo host simulation", tx_demo_thread_host_simulation_entry, 0,
|
||||
stack_pointer, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
static void tx_demo_thread_host_simulation_entry(ULONG arg)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* Find the HID class */
|
||||
status = demo_class_hid_get();
|
||||
if (status == UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now disconnect the device. */
|
||||
_ux_device_stack_disconnect();
|
||||
|
||||
/* And deinitialize the class. */
|
||||
status = ux_device_stack_class_unregister(_ux_system_slave_class_hid_name, ux_device_class_hid_entry);
|
||||
|
||||
/* Deinitialize the device side of usbx. */
|
||||
_ux_device_stack_uninitialize();
|
||||
|
||||
/* And finally the usbx system resources. */
|
||||
_ux_system_uninitialize();
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
|
||||
|
||||
static UINT demo_thread_hid_callback(UX_SLAVE_CLASS_HID *class, UX_SLAVE_CLASS_HID_EVENT *event)
|
||||
{
|
||||
return(UX_SUCCESS);
|
||||
}
|
@ -0,0 +1,502 @@
|
||||
#include "usbx_test_common_hid.h"
|
||||
#include "ux_host_class_hid_keyboard.h"
|
||||
|
||||
|
||||
static SLONG input_report_buffer_decompressed_original[1024];
|
||||
static UCHAR input_report_buffer_compressed[1024];
|
||||
static SLONG input_report_buffer_decompressed[1024];
|
||||
|
||||
static UCHAR hid_report_descriptor[] = {
|
||||
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||
0x09, 0x06, // USAGE (Keyboard)
|
||||
0xa1, 0x01, // COLLECTION (Application)
|
||||
|
||||
/* First field */
|
||||
0x09, 0x01, // USAGE (1)
|
||||
0x75, 0x01, // REPORT_SIZE (1)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
|
||||
/* Second field */
|
||||
0x19, 0x02, // USAGE_MINIMUM (2)
|
||||
0x29, 0x04, // USAGE_MAXIMUM (4)
|
||||
0x75, 0x01, // REPORT_SIZE (1)
|
||||
0x95, 0x03, // REPORT_COUNT (3)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
|
||||
/* Third field */
|
||||
0x0a, 0xcd, 0xab, // USAGE (0xabcd)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
|
||||
/* Fourth field */
|
||||
0x19, 0x06, // USAGE_MINIMUM (6)
|
||||
0x29, 0x08, // USAGE_MAXIMUM (8)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x95, 0x03, // REPORT_COUNT (3)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
|
||||
/* Fifth field */
|
||||
0x09, 0x01, // USAGE (1)
|
||||
0x75, 0x09, // REPORT_SIZE (9)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
|
||||
/* Sixth field */
|
||||
0x19, 0x0a, // USAGE_MINIMUM (10)
|
||||
0x29, 0x0c, // USAGE_MAXIMUM (12)
|
||||
0x75, 0x09, // REPORT_SIZE (9)
|
||||
0x95, 0x03, // REPORT_COUNT (3)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
|
||||
/* Seventh field */
|
||||
0x09, 0x0d, // USAGE (13)
|
||||
0x75, 0x1f, // REPORT_SIZE (31)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
|
||||
/* Eigth field */
|
||||
0x09, 0x0e, // USAGE (14)
|
||||
0x75, 0x20, // REPORT_SIZE (32)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
|
||||
/* USBX expects keyboards to have at least one output report, otherwise it's an error. */
|
||||
0x95, 0x05, // REPORT_COUNT (5)
|
||||
0x75, 0x01, // REPORT_SIZE (1)
|
||||
0x05, 0x08, // USAGE_PAGE (LEDs)
|
||||
0x19, 0x01, // USAGE_MINIMUM (Num Lock)
|
||||
0x29, 0x05, // USAGE_MAXIMUM (Kana)
|
||||
0x91, 0x02, // OUTPUT (Data,Var,Abs)
|
||||
|
||||
0xc0, // END_COLLECTION
|
||||
};
|
||||
#define HID_REPORT_LENGTH sizeof(hid_report_descriptor)/sizeof(hid_report_descriptor[0])
|
||||
|
||||
|
||||
#define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED 52
|
||||
static UCHAR device_framework_full_speed[DEVICE_FRAMEWORK_LENGTH_FULL_SPEED] = {
|
||||
|
||||
/* Device descriptor */
|
||||
0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08,
|
||||
0x81, 0x0A, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x01,
|
||||
|
||||
/* Configuration descriptor */
|
||||
0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x00, 0xc0,
|
||||
0x32,
|
||||
|
||||
/* Interface descriptor */
|
||||
0x09, 0x04, 0x02, 0x00, 0x01, 0x03, 0x00, 0x00,
|
||||
0x00,
|
||||
|
||||
/* HID descriptor */
|
||||
0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(HID_REPORT_LENGTH),
|
||||
MSB(HID_REPORT_LENGTH),
|
||||
|
||||
/* Endpoint descriptor (Interrupt) */
|
||||
0x07, 0x05, 0x82, 0x03, 0x08, 0x00, 0x08
|
||||
|
||||
};
|
||||
|
||||
|
||||
#define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED 62
|
||||
static UCHAR device_framework_high_speed[DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED] = {
|
||||
|
||||
/* Device descriptor */
|
||||
0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
|
||||
0x0a, 0x07, 0x25, 0x40, 0x01, 0x00, 0x01, 0x02,
|
||||
0x03, 0x01,
|
||||
|
||||
/* Device qualifier descriptor */
|
||||
0x0a, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
|
||||
0x01, 0x00,
|
||||
|
||||
/* Configuration descriptor */
|
||||
0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x00, 0xc0,
|
||||
0x32,
|
||||
|
||||
/* Interface descriptor */
|
||||
0x09, 0x04, 0x02, 0x00, 0x01, 0x03, 0x00, 0x00,
|
||||
0x00,
|
||||
|
||||
/* HID descriptor */
|
||||
0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(HID_REPORT_LENGTH),
|
||||
MSB(HID_REPORT_LENGTH),
|
||||
|
||||
/* Endpoint descriptor (Interrupt) */
|
||||
0x07, 0x05, 0x82, 0x03, 0x08, 0x00, 0x08
|
||||
|
||||
};
|
||||
|
||||
|
||||
/* String Device Framework :
|
||||
Byte 0 and 1 : Word containing the language ID : 0x0904 for US
|
||||
Byte 2 : Byte containing the index of the descriptor
|
||||
Byte 3 : Byte containing the length of the descriptor string
|
||||
*/
|
||||
|
||||
#define STRING_FRAMEWORK_LENGTH 40
|
||||
static UCHAR string_framework[] = {
|
||||
|
||||
/* Manufacturer string descriptor : Index 1 */
|
||||
0x09, 0x04, 0x01, 0x0c,
|
||||
0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
|
||||
0x6f, 0x67, 0x69, 0x63,
|
||||
|
||||
/* Product string descriptor : Index 2 */
|
||||
0x09, 0x04, 0x02, 0x0c,
|
||||
0x55, 0x53, 0x42, 0x20, 0x4b, 0x65, 0x79, 0x62,
|
||||
0x6f, 0x61, 0x72, 0x64,
|
||||
|
||||
/* Serial Number string descriptor : Index 3 */
|
||||
0x09, 0x04, 0x03, 0x04,
|
||||
0x30, 0x30, 0x30, 0x31
|
||||
};
|
||||
|
||||
|
||||
/* Multiple languages are supported on the device, to add
|
||||
a language besides english, the unicode language code must
|
||||
be appended to the language_id_framework array and the length
|
||||
adjusted accordingly. */
|
||||
#define LANGUAGE_ID_FRAMEWORK_LENGTH 2
|
||||
static UCHAR language_id_framework[] = {
|
||||
|
||||
/* English. */
|
||||
0x09, 0x04
|
||||
};
|
||||
|
||||
|
||||
static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
|
||||
{
|
||||
|
||||
/* Failed test. */
|
||||
printf("Error on line %d, system_level: %d, system_context: %d, error code: %d\n", __LINE__, system_level, system_context, error_code);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_hid_report_descriptor_compress_and_decompress_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR * stack_pointer;
|
||||
CHAR * memory_pointer;
|
||||
UINT descriptor_size = HID_REPORT_LENGTH;
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running ux_host_class_hid_report_ compress/decompress Test.......... ");
|
||||
|
||||
/* Initialize the free memory pointer */
|
||||
stack_pointer = (CHAR *) usbx_memory;
|
||||
memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
|
||||
|
||||
/* Initialize USBX. Memory */
|
||||
status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the error callback. */
|
||||
_ux_utility_error_callback_register(error_callback);
|
||||
|
||||
/* The code below is required for installing the host portion of USBX */
|
||||
status = ux_host_stack_initialize(UX_NULL);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = ux_host_stack_class_register(_ux_system_host_class_hid_name, ux_host_class_hid_entry);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the HID client(s). */
|
||||
status = ux_host_class_hid_client_register(_ux_system_host_class_hid_client_keyboard_name, ux_host_class_hid_keyboard_entry);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* The code below is required for installing the device portion of USBX. No call back for
|
||||
device status change in this example. */
|
||||
status = ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
|
||||
device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
|
||||
string_framework, STRING_FRAMEWORK_LENGTH,
|
||||
language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Initialize the hid class parameters. */
|
||||
hid_parameter.ux_device_class_hid_parameter_report_address = hid_report_descriptor;
|
||||
hid_parameter.ux_device_class_hid_parameter_report_length = HID_REPORT_LENGTH;
|
||||
hid_parameter.ux_device_class_hid_parameter_callback = demo_thread_hid_callback;
|
||||
|
||||
/* Initilize the device hid class. The class is connected with interface 2 */
|
||||
status = ux_device_stack_class_register(_ux_system_slave_class_hid_name, ux_device_class_hid_entry,
|
||||
1,2, (VOID *)&hid_parameter);
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
|
||||
/* Initialize the simulated device controller. */
|
||||
status = _ux_dcd_sim_slave_initialize();
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register all the USB host controllers available in this system */
|
||||
status = ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, ux_hcd_sim_host_initialize,0,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the main host simulation thread. */
|
||||
status = tx_thread_create(&tx_demo_thread_host_simulation, "tx demo host simulation", tx_demo_thread_host_simulation_entry, 0,
|
||||
stack_pointer, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void tx_demo_thread_host_simulation_entry(ULONG arg)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
UX_HOST_CLASS_HID_REPORT_GET_ID report_id;
|
||||
UX_HOST_CLASS_HID_CLIENT_REPORT client_report;
|
||||
UX_HOST_CLASS_HID_REPORT *input_report_descriptor;
|
||||
|
||||
|
||||
/* Find the HID class */
|
||||
status = demo_class_hid_get();
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the first input report descriptor. */
|
||||
report_id.ux_host_class_hid_report_get_report = UX_NULL;
|
||||
report_id.ux_host_class_hid_report_get_type = UX_HOST_CLASS_HID_REPORT_TYPE_INPUT;
|
||||
status = ux_host_class_hid_report_id_get(hid, &report_id);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
input_report_descriptor = report_id.ux_host_class_hid_report_get_report;
|
||||
if (input_report_descriptor -> ux_host_class_hid_report_id != 0)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* First field */
|
||||
|
||||
input_report_buffer_decompressed_original[0] = 0x00010001;
|
||||
input_report_buffer_decompressed_original[1] = 0x01;
|
||||
|
||||
/* Second field */
|
||||
|
||||
input_report_buffer_decompressed_original[2] = 0x00010002;
|
||||
input_report_buffer_decompressed_original[3] = 0x01;
|
||||
|
||||
input_report_buffer_decompressed_original[4] = 0x00010003;
|
||||
input_report_buffer_decompressed_original[5] = 0x00;
|
||||
|
||||
input_report_buffer_decompressed_original[6] = 0x00010004;
|
||||
input_report_buffer_decompressed_original[7] = 0x01;
|
||||
|
||||
/* Third field */
|
||||
|
||||
input_report_buffer_decompressed_original[8] = 0x0001abcd;
|
||||
input_report_buffer_decompressed_original[9] = 0x30;
|
||||
|
||||
/* Fourth field */
|
||||
|
||||
input_report_buffer_decompressed_original[10] = 0x00010006;
|
||||
input_report_buffer_decompressed_original[11] = 0x52;
|
||||
|
||||
input_report_buffer_decompressed_original[12] = 0x00010007;
|
||||
input_report_buffer_decompressed_original[13] = 0x74;
|
||||
|
||||
input_report_buffer_decompressed_original[14] = 0x00010008;
|
||||
input_report_buffer_decompressed_original[15] = 0x96;
|
||||
|
||||
/* Fifth field */
|
||||
|
||||
input_report_buffer_decompressed_original[16] = 0x00010001;
|
||||
input_report_buffer_decompressed_original[17] = 0x0b8;
|
||||
|
||||
/* Sixth field */
|
||||
|
||||
input_report_buffer_decompressed_original[18] = 0x0001000a;
|
||||
input_report_buffer_decompressed_original[19] = 0x06d;
|
||||
|
||||
input_report_buffer_decompressed_original[20] = 0x0001000b;
|
||||
input_report_buffer_decompressed_original[21] = 0x1bf;
|
||||
|
||||
input_report_buffer_decompressed_original[22] = 0x0001000c;
|
||||
input_report_buffer_decompressed_original[23] = 0x003;
|
||||
|
||||
/* Seventh field */
|
||||
|
||||
input_report_buffer_decompressed_original[24] = 0x0001000d;
|
||||
input_report_buffer_decompressed_original[25] = 0x09674523;
|
||||
|
||||
/* Eigth field */
|
||||
|
||||
input_report_buffer_decompressed_original[26] = 0x0001000e;
|
||||
input_report_buffer_decompressed_original[27] = 0x03df9b57;
|
||||
|
||||
/* Fill out the request for the decompress api. */
|
||||
client_report.ux_host_class_hid_client_report = input_report_descriptor;
|
||||
client_report.ux_host_class_hid_client_report_buffer = input_report_buffer_decompressed_original;
|
||||
client_report.ux_host_class_hid_client_report_actual_length = 0;
|
||||
|
||||
/* Request compression. */
|
||||
status = _ux_host_class_hid_report_compress(hid, &client_report, input_report_buffer_compressed, 17);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Check output of report compression. */
|
||||
if (
|
||||
input_report_buffer_compressed[0] != 0x0b ||
|
||||
input_report_buffer_compressed[1] != 0x23 ||
|
||||
input_report_buffer_compressed[2] != 0x45 ||
|
||||
input_report_buffer_compressed[3] != 0x67 ||
|
||||
input_report_buffer_compressed[4] != 0x89 ||
|
||||
input_report_buffer_compressed[5] != 0xab ||
|
||||
input_report_buffer_compressed[6] != 0xcd ||
|
||||
input_report_buffer_compressed[7] != 0xef ||
|
||||
input_report_buffer_compressed[8] != 0x01 ||
|
||||
input_report_buffer_compressed[9] != 0x23 ||
|
||||
input_report_buffer_compressed[10] != 0x45 ||
|
||||
input_report_buffer_compressed[11] != 0x67 ||
|
||||
input_report_buffer_compressed[12] != 0x89 ||
|
||||
input_report_buffer_compressed[13] != 0xab ||
|
||||
input_report_buffer_compressed[14] != 0xcd ||
|
||||
input_report_buffer_compressed[15] != 0xef ||
|
||||
input_report_buffer_compressed[16] != 0x01
|
||||
)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* You're gonna love this. Decompress it and make sure it matches the original! */
|
||||
|
||||
client_report.ux_host_class_hid_client_report_buffer = input_report_buffer_decompressed;
|
||||
status = _ux_host_class_hid_report_decompress(hid, &client_report, input_report_buffer_compressed, 28);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
if (memcmp(input_report_buffer_decompressed, input_report_buffer_decompressed_original, 28))
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Decompress it with report id. */
|
||||
input_report_buffer_compressed[32] = 0x01;
|
||||
memcpy(&input_report_buffer_compressed[33], &input_report_buffer_compressed[0], 17);
|
||||
client_report.ux_host_class_hid_client_report_buffer = input_report_buffer_decompressed;
|
||||
client_report.ux_host_class_hid_client_report->ux_host_class_hid_report_id = 0x1;
|
||||
status = _ux_host_class_hid_report_decompress(hid, &client_report, &input_report_buffer_compressed[32], 29);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
if (memcmp(input_report_buffer_decompressed, input_report_buffer_decompressed_original, 28))
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Told ya! */
|
||||
|
||||
/* Now disconnect the device. */
|
||||
_ux_device_stack_disconnect();
|
||||
|
||||
/* And deinitialize the class. */
|
||||
status = ux_device_stack_class_unregister(_ux_system_slave_class_hid_name, ux_device_class_hid_entry);
|
||||
|
||||
/* Deinitialize the device side of usbx. */
|
||||
_ux_device_stack_uninitialize();
|
||||
|
||||
/* And finally the usbx system resources. */
|
||||
_ux_system_uninitialize();
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
|
||||
static UINT demo_thread_hid_callback(UX_SLAVE_CLASS_HID *class, UX_SLAVE_CLASS_HID_EVENT *event)
|
||||
{
|
||||
return(UX_SUCCESS);
|
||||
}
|
423
test/regression/usbx_hid_report_descriptor_compress_array_test.c
Normal file
423
test/regression/usbx_hid_report_descriptor_compress_array_test.c
Normal file
@ -0,0 +1,423 @@
|
||||
/* This test concentrates on the report compress api. */
|
||||
|
||||
#include "usbx_test_common_hid.h"
|
||||
#include "ux_host_class_hid_keyboard.h"
|
||||
#include "ux_test.h"
|
||||
|
||||
|
||||
static UCHAR input_report_buffer_compressed[1024];
|
||||
static SLONG input_report_buffer_decompressed_original[1024];
|
||||
|
||||
static UCHAR hid_report_descriptor[] = {
|
||||
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||
0x09, 0x06, // USAGE (Keyboard)
|
||||
0xa1, 0x01, // COLLECTION (Application)
|
||||
/* Keys. */
|
||||
0x95, 0x06, // REPORT_COUNT (6)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x15, 0x01, // LOGICAL_MINIMUM (0)
|
||||
0x25, 0x65, // LOGICAL_MAXIMUM (101)
|
||||
0x05, 0x07, // USAGE_PAGE (Keyboard)
|
||||
0x19, 0x01, // USAGE_MINIMUM (Reserved (no event indicated))
|
||||
0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)
|
||||
0x81, 0x00, // INPUT (Data,Ary,Abs)
|
||||
0xc0, // END_COLLECTION
|
||||
};
|
||||
#define HID_REPORT_LENGTH sizeof(hid_report_descriptor)/sizeof(hid_report_descriptor[0])
|
||||
|
||||
|
||||
#define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED 52
|
||||
static UCHAR device_framework_full_speed[DEVICE_FRAMEWORK_LENGTH_FULL_SPEED] = {
|
||||
|
||||
/* Device descriptor */
|
||||
0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08,
|
||||
0x81, 0x0A, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x01,
|
||||
|
||||
/* Configuration descriptor */
|
||||
0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x00, 0xc0,
|
||||
0x32,
|
||||
|
||||
/* Interface descriptor */
|
||||
0x09, 0x04, 0x02, 0x00, 0x01, 0x03, 0x00, 0x00,
|
||||
0x00,
|
||||
|
||||
/* HID descriptor */
|
||||
0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(HID_REPORT_LENGTH),
|
||||
MSB(HID_REPORT_LENGTH),
|
||||
|
||||
/* Endpoint descriptor (Interrupt) */
|
||||
0x07, 0x05, 0x82, 0x03, 0x08, 0x00, 0x08
|
||||
|
||||
};
|
||||
|
||||
|
||||
#define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED 62
|
||||
static UCHAR device_framework_high_speed[DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED] = {
|
||||
|
||||
/* Device descriptor */
|
||||
0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
|
||||
0x0a, 0x07, 0x25, 0x40, 0x01, 0x00, 0x01, 0x02,
|
||||
0x03, 0x01,
|
||||
|
||||
/* Device qualifier descriptor */
|
||||
0x0a, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
|
||||
0x01, 0x00,
|
||||
|
||||
/* Configuration descriptor */
|
||||
0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x00, 0xc0,
|
||||
0x32,
|
||||
|
||||
/* Interface descriptor */
|
||||
0x09, 0x04, 0x02, 0x00, 0x01, 0x03, 0x00, 0x00,
|
||||
0x00,
|
||||
|
||||
/* HID descriptor */
|
||||
0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(HID_REPORT_LENGTH),
|
||||
MSB(HID_REPORT_LENGTH),
|
||||
|
||||
/* Endpoint descriptor (Interrupt) */
|
||||
0x07, 0x05, 0x82, 0x03, 0x08, 0x00, 0x08
|
||||
|
||||
};
|
||||
|
||||
|
||||
/* String Device Framework :
|
||||
Byte 0 and 1 : Word containing the language ID : 0x0904 for US
|
||||
Byte 2 : Byte containing the index of the descriptor
|
||||
Byte 3 : Byte containing the length of the descriptor string
|
||||
*/
|
||||
|
||||
#define STRING_FRAMEWORK_LENGTH 40
|
||||
static UCHAR string_framework[] = {
|
||||
|
||||
/* Manufacturer string descriptor : Index 1 */
|
||||
0x09, 0x04, 0x01, 0x0c,
|
||||
0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
|
||||
0x6f, 0x67, 0x69, 0x63,
|
||||
|
||||
/* Product string descriptor : Index 2 */
|
||||
0x09, 0x04, 0x02, 0x0c,
|
||||
0x55, 0x53, 0x42, 0x20, 0x4b, 0x65, 0x79, 0x62,
|
||||
0x6f, 0x61, 0x72, 0x64,
|
||||
|
||||
/* Serial Number string descriptor : Index 3 */
|
||||
0x09, 0x04, 0x03, 0x04,
|
||||
0x30, 0x30, 0x30, 0x31
|
||||
};
|
||||
|
||||
|
||||
/* Multiple languages are supported on the device, to add
|
||||
a language besides english, the unicode language code must
|
||||
be appended to the language_id_framework array and the length
|
||||
adjusted accordingly. */
|
||||
#define LANGUAGE_ID_FRAMEWORK_LENGTH 2
|
||||
static UCHAR language_id_framework[] = {
|
||||
|
||||
/* English. */
|
||||
0x09, 0x04
|
||||
};
|
||||
|
||||
|
||||
static UCHAR ignore_errors;
|
||||
static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
|
||||
{
|
||||
|
||||
if (!ignore_errors)
|
||||
{
|
||||
|
||||
/* Failed test. */
|
||||
printf("Error on line %d, system_level: %d, system_context: %d, error code: %d\n", __LINE__, system_level, system_context, error_code);
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_hid_report_descriptor_compress_array_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR * stack_pointer;
|
||||
CHAR * memory_pointer;
|
||||
UINT descriptor_size = HID_REPORT_LENGTH;
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running HID Report Descriptor Decompress Test....................... ");
|
||||
|
||||
/* Initialize the free memory pointer */
|
||||
stack_pointer = (CHAR *) usbx_memory;
|
||||
memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
|
||||
|
||||
/* Initialize USBX. Memory */
|
||||
status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the error callback. */
|
||||
_ux_utility_error_callback_register(error_callback);
|
||||
|
||||
/* The code below is required for installing the host portion of USBX */
|
||||
status = ux_host_stack_initialize(UX_NULL);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = ux_host_stack_class_register(_ux_system_host_class_hid_name, ux_host_class_hid_entry);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the HID client(s). */
|
||||
status = ux_host_class_hid_client_register(_ux_system_host_class_hid_client_keyboard_name, ux_host_class_hid_keyboard_entry);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* The code below is required for installing the device portion of USBX. No call back for
|
||||
device status change in this example. */
|
||||
status = ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
|
||||
device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
|
||||
string_framework, STRING_FRAMEWORK_LENGTH,
|
||||
language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Initialize the hid class parameters. */
|
||||
hid_parameter.ux_device_class_hid_parameter_report_address = hid_report_descriptor;
|
||||
hid_parameter.ux_device_class_hid_parameter_report_length = HID_REPORT_LENGTH;
|
||||
hid_parameter.ux_device_class_hid_parameter_callback = demo_thread_hid_callback;
|
||||
|
||||
/* Initilize the device hid class. The class is connected with interface 2 */
|
||||
status = ux_device_stack_class_register(_ux_system_slave_class_hid_name, ux_device_class_hid_entry,
|
||||
1,2, (VOID *)&hid_parameter);
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
|
||||
/* Initialize the simulated device controller. */
|
||||
status = _ux_dcd_sim_slave_initialize();
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register all the USB host controllers available in this system */
|
||||
status = ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, ux_hcd_sim_host_initialize,0,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the main host simulation thread. */
|
||||
status = tx_thread_create(&tx_demo_thread_host_simulation, "tx demo host simulation", tx_demo_thread_host_simulation_entry, 0,
|
||||
stack_pointer, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void tx_demo_thread_host_simulation_entry(ULONG arg)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
UX_HOST_CLASS_HID_REPORT_GET_ID report_id;
|
||||
UX_HOST_CLASS_HID_CLIENT_REPORT client_report;
|
||||
UX_HOST_CLASS_HID_REPORT *input_report_descriptor;
|
||||
SLONG report_buffer_decompressed[1024];
|
||||
UCHAR report_buffer_compressed[1024] = {0};
|
||||
|
||||
|
||||
/* Find the HID class */
|
||||
status = demo_class_hid_get();
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/** Do basic test. **/
|
||||
|
||||
/* Get the first input report descriptor. */
|
||||
report_id.ux_host_class_hid_report_get_report = UX_NULL;
|
||||
report_id.ux_host_class_hid_report_get_type = UX_HOST_CLASS_HID_REPORT_TYPE_INPUT;
|
||||
UX_TEST_CHECK_SUCCESS(ux_host_class_hid_report_id_get(hid, &report_id));
|
||||
input_report_descriptor = report_id.ux_host_class_hid_report_get_report;
|
||||
|
||||
/* 1 */
|
||||
report_buffer_decompressed[0] = 0x00070001;
|
||||
report_buffer_decompressed[1] = 0x1;
|
||||
|
||||
/* 2 */
|
||||
report_buffer_decompressed[2] = 0x00070002;
|
||||
report_buffer_decompressed[3] = 0x2;
|
||||
|
||||
/* 3 */
|
||||
report_buffer_decompressed[4] = 0x00070003;
|
||||
report_buffer_decompressed[5] = 0x3;
|
||||
|
||||
/* 4 */
|
||||
report_buffer_decompressed[6] = 0x00070004;
|
||||
report_buffer_decompressed[7] = 0x4;
|
||||
|
||||
/* 5 */
|
||||
report_buffer_decompressed[8] = 0x00070005;
|
||||
report_buffer_decompressed[9] = 0x5;
|
||||
|
||||
/* 6 */
|
||||
report_buffer_decompressed[10] = 0x00070006;
|
||||
report_buffer_decompressed[11] = 0x6;
|
||||
|
||||
/* Fill out the request for the compress api. */
|
||||
client_report.ux_host_class_hid_client_report = input_report_descriptor;
|
||||
client_report.ux_host_class_hid_client_report_buffer = report_buffer_decompressed;
|
||||
client_report.ux_host_class_hid_client_report_actual_length = 0;
|
||||
|
||||
/* Request compression. */
|
||||
UX_TEST_CHECK_SUCCESS(_ux_host_class_hid_report_compress(hid, &client_report, report_buffer_compressed, sizeof(report_buffer_compressed)));
|
||||
|
||||
/* Check it. */
|
||||
UX_TEST_ASSERT(report_buffer_compressed[0] == 0x1);
|
||||
UX_TEST_ASSERT(report_buffer_compressed[1] == 0x2);
|
||||
UX_TEST_ASSERT(report_buffer_compressed[2] == 0x3);
|
||||
UX_TEST_ASSERT(report_buffer_compressed[3] == 0x4);
|
||||
UX_TEST_ASSERT(report_buffer_compressed[4] == 0x5);
|
||||
UX_TEST_ASSERT(report_buffer_compressed[5] == 0x6);
|
||||
|
||||
/** Test invalid usage page. **/
|
||||
|
||||
/* Get the first input report descriptor. */
|
||||
report_id.ux_host_class_hid_report_get_report = UX_NULL;
|
||||
report_id.ux_host_class_hid_report_get_type = UX_HOST_CLASS_HID_REPORT_TYPE_INPUT;
|
||||
UX_TEST_CHECK_SUCCESS(ux_host_class_hid_report_id_get(hid, &report_id));
|
||||
input_report_descriptor = report_id.ux_host_class_hid_report_get_report;
|
||||
|
||||
/* Add invalid usage page. */
|
||||
report_buffer_decompressed[0] = 0x00000000;
|
||||
report_buffer_decompressed[1] = 0x00;
|
||||
|
||||
/* Fill out the request for the compress api. */
|
||||
client_report.ux_host_class_hid_client_report = input_report_descriptor;
|
||||
client_report.ux_host_class_hid_client_report_buffer = report_buffer_decompressed;
|
||||
client_report.ux_host_class_hid_client_report_actual_length = 0;
|
||||
|
||||
ignore_errors = 1;
|
||||
|
||||
/* Request compression. This should fail. */
|
||||
UX_TEST_CHECK_NOT_SUCCESS(_ux_host_class_hid_report_compress(hid, &client_report, report_buffer_compressed, sizeof(report_buffer_compressed)));
|
||||
|
||||
ignore_errors = 0;
|
||||
|
||||
/** Test usage too large. **/
|
||||
|
||||
/* Get the first input report descriptor. */
|
||||
report_id.ux_host_class_hid_report_get_report = UX_NULL;
|
||||
report_id.ux_host_class_hid_report_get_type = UX_HOST_CLASS_HID_REPORT_TYPE_INPUT;
|
||||
UX_TEST_CHECK_SUCCESS(ux_host_class_hid_report_id_get(hid, &report_id));
|
||||
input_report_descriptor = report_id.ux_host_class_hid_report_get_report;
|
||||
|
||||
/* Add unknown usage. */
|
||||
report_buffer_decompressed[0] = 0x00070066;
|
||||
report_buffer_decompressed[1] = 0x66;
|
||||
|
||||
/* Fill out the request for the compress api. */
|
||||
client_report.ux_host_class_hid_client_report = input_report_descriptor;
|
||||
client_report.ux_host_class_hid_client_report_buffer = report_buffer_decompressed;
|
||||
client_report.ux_host_class_hid_client_report_actual_length = 0;
|
||||
|
||||
ignore_errors = 1;
|
||||
|
||||
/* Request compression. This should fail. */
|
||||
UX_TEST_CHECK_NOT_SUCCESS(_ux_host_class_hid_report_compress(hid, &client_report, report_buffer_compressed, sizeof(report_buffer_compressed)));
|
||||
|
||||
ignore_errors = 0;
|
||||
|
||||
/** Test usage too small. **/
|
||||
|
||||
/* Get the first input report descriptor. */
|
||||
report_id.ux_host_class_hid_report_get_report = UX_NULL;
|
||||
report_id.ux_host_class_hid_report_get_type = UX_HOST_CLASS_HID_REPORT_TYPE_INPUT;
|
||||
UX_TEST_CHECK_SUCCESS(ux_host_class_hid_report_id_get(hid, &report_id));
|
||||
input_report_descriptor = report_id.ux_host_class_hid_report_get_report;
|
||||
|
||||
/* Add unknown usage. */
|
||||
report_buffer_decompressed[0] = 0x00070000;
|
||||
report_buffer_decompressed[1] = 0x0;
|
||||
|
||||
/* Fill out the request for the compress api. */
|
||||
client_report.ux_host_class_hid_client_report = input_report_descriptor;
|
||||
client_report.ux_host_class_hid_client_report_buffer = report_buffer_decompressed;
|
||||
client_report.ux_host_class_hid_client_report_actual_length = 0;
|
||||
|
||||
ignore_errors = 1;
|
||||
|
||||
/* Request compression. This should fail. */
|
||||
UX_TEST_CHECK_NOT_SUCCESS(_ux_host_class_hid_report_compress(hid, &client_report, report_buffer_compressed, sizeof(report_buffer_compressed)));
|
||||
|
||||
ignore_errors = 0;
|
||||
|
||||
/* Now disconnect the device. */
|
||||
_ux_device_stack_disconnect();
|
||||
|
||||
/* And deinitialize the class. */
|
||||
status = ux_device_stack_class_unregister(_ux_system_slave_class_hid_name, ux_device_class_hid_entry);
|
||||
|
||||
/* Deinitialize the device side of usbx. */
|
||||
_ux_device_stack_uninitialize();
|
||||
|
||||
/* And finally the usbx system resources. */
|
||||
_ux_system_uninitialize();
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
|
||||
static UINT demo_thread_hid_callback(UX_SLAVE_CLASS_HID *class, UX_SLAVE_CLASS_HID_EVENT *event)
|
||||
{
|
||||
return(UX_SUCCESS);
|
||||
}
|
463
test/regression/usbx_hid_report_descriptor_compress_test.c
Normal file
463
test/regression/usbx_hid_report_descriptor_compress_test.c
Normal file
@ -0,0 +1,463 @@
|
||||
/* This test concentrates on the report compress api. */
|
||||
|
||||
#include "usbx_test_common_hid.h"
|
||||
#include "ux_host_class_hid_keyboard.h"
|
||||
|
||||
|
||||
static UCHAR input_report_buffer_compressed[1024];
|
||||
static SLONG input_report_buffer_decompressed_original[1024];
|
||||
|
||||
static UCHAR hid_report_descriptor[] = {
|
||||
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||
0x09, 0x06, // USAGE (Keyboard)
|
||||
0xa1, 0x01, // COLLECTION (Application)
|
||||
|
||||
/* First field */
|
||||
0x09, 0x01, // USAGE (1)
|
||||
0x75, 0x01, // REPORT_SIZE (1)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
|
||||
/* Second field */
|
||||
0x19, 0x02, // USAGE_MINIMUM (2)
|
||||
0x29, 0x04, // USAGE_MAXIMUM (4)
|
||||
0x75, 0x01, // REPORT_SIZE (1)
|
||||
0x95, 0x03, // REPORT_COUNT (3)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
|
||||
/* Third field */
|
||||
0x0a, 0xcd, 0xab, // USAGE (0xabcd)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
|
||||
/* Fourth field */
|
||||
0x19, 0x06, // USAGE_MINIMUM (6)
|
||||
0x29, 0x08, // USAGE_MAXIMUM (8)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x95, 0x03, // REPORT_COUNT (3)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
|
||||
/* Fifth field */
|
||||
0x09, 0x01, // USAGE (1)
|
||||
0x75, 0x09, // REPORT_SIZE (9)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
|
||||
/* Sixth field */
|
||||
0x19, 0x0a, // USAGE_MINIMUM (10)
|
||||
0x29, 0x0c, // USAGE_MAXIMUM (12)
|
||||
0x75, 0x09, // REPORT_SIZE (9)
|
||||
0x95, 0x03, // REPORT_COUNT (3)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
|
||||
/* Seventh field */
|
||||
0x09, 0x0d, // USAGE (13)
|
||||
0x75, 0x1f, // REPORT_SIZE (31)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
|
||||
/* Eigth field */
|
||||
0x09, 0x0e, // USAGE (14)
|
||||
0x75, 0x20, // REPORT_SIZE (32)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
|
||||
/* USBX expects keyboards to have at least one output report, otherwise it's an error. */
|
||||
0x95, 0x05, // REPORT_COUNT (5)
|
||||
0x75, 0x01, // REPORT_SIZE (1)
|
||||
0x05, 0x08, // USAGE_PAGE (LEDs)
|
||||
0x19, 0x01, // USAGE_MINIMUM (Num Lock)
|
||||
0x29, 0x05, // USAGE_MAXIMUM (Kana)
|
||||
0x91, 0x02, // OUTPUT (Data,Var,Abs)
|
||||
|
||||
0xc0, // END_COLLECTION
|
||||
};
|
||||
#define HID_REPORT_LENGTH sizeof(hid_report_descriptor)/sizeof(hid_report_descriptor[0])
|
||||
|
||||
|
||||
#define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED 52
|
||||
static UCHAR device_framework_full_speed[DEVICE_FRAMEWORK_LENGTH_FULL_SPEED] = {
|
||||
|
||||
/* Device descriptor */
|
||||
0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08,
|
||||
0x81, 0x0A, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x01,
|
||||
|
||||
/* Configuration descriptor */
|
||||
0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x00, 0xc0,
|
||||
0x32,
|
||||
|
||||
/* Interface descriptor */
|
||||
0x09, 0x04, 0x02, 0x00, 0x01, 0x03, 0x00, 0x00,
|
||||
0x00,
|
||||
|
||||
/* HID descriptor */
|
||||
0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(HID_REPORT_LENGTH),
|
||||
MSB(HID_REPORT_LENGTH),
|
||||
|
||||
/* Endpoint descriptor (Interrupt) */
|
||||
0x07, 0x05, 0x82, 0x03, 0x08, 0x00, 0x08
|
||||
|
||||
};
|
||||
|
||||
|
||||
#define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED 62
|
||||
static UCHAR device_framework_high_speed[DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED] = {
|
||||
|
||||
/* Device descriptor */
|
||||
0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
|
||||
0x0a, 0x07, 0x25, 0x40, 0x01, 0x00, 0x01, 0x02,
|
||||
0x03, 0x01,
|
||||
|
||||
/* Device qualifier descriptor */
|
||||
0x0a, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
|
||||
0x01, 0x00,
|
||||
|
||||
/* Configuration descriptor */
|
||||
0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x00, 0xc0,
|
||||
0x32,
|
||||
|
||||
/* Interface descriptor */
|
||||
0x09, 0x04, 0x02, 0x00, 0x01, 0x03, 0x00, 0x00,
|
||||
0x00,
|
||||
|
||||
/* HID descriptor */
|
||||
0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(HID_REPORT_LENGTH),
|
||||
MSB(HID_REPORT_LENGTH),
|
||||
|
||||
/* Endpoint descriptor (Interrupt) */
|
||||
0x07, 0x05, 0x82, 0x03, 0x08, 0x00, 0x08
|
||||
|
||||
};
|
||||
|
||||
|
||||
/* String Device Framework :
|
||||
Byte 0 and 1 : Word containing the language ID : 0x0904 for US
|
||||
Byte 2 : Byte containing the index of the descriptor
|
||||
Byte 3 : Byte containing the length of the descriptor string
|
||||
*/
|
||||
|
||||
#define STRING_FRAMEWORK_LENGTH 40
|
||||
static UCHAR string_framework[] = {
|
||||
|
||||
/* Manufacturer string descriptor : Index 1 */
|
||||
0x09, 0x04, 0x01, 0x0c,
|
||||
0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
|
||||
0x6f, 0x67, 0x69, 0x63,
|
||||
|
||||
/* Product string descriptor : Index 2 */
|
||||
0x09, 0x04, 0x02, 0x0c,
|
||||
0x55, 0x53, 0x42, 0x20, 0x4b, 0x65, 0x79, 0x62,
|
||||
0x6f, 0x61, 0x72, 0x64,
|
||||
|
||||
/* Serial Number string descriptor : Index 3 */
|
||||
0x09, 0x04, 0x03, 0x04,
|
||||
0x30, 0x30, 0x30, 0x31
|
||||
};
|
||||
|
||||
|
||||
/* Multiple languages are supported on the device, to add
|
||||
a language besides english, the unicode language code must
|
||||
be appended to the language_id_framework array and the length
|
||||
adjusted accordingly. */
|
||||
#define LANGUAGE_ID_FRAMEWORK_LENGTH 2
|
||||
static UCHAR language_id_framework[] = {
|
||||
|
||||
/* English. */
|
||||
0x09, 0x04
|
||||
};
|
||||
|
||||
|
||||
static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
|
||||
{
|
||||
|
||||
/* Failed test. */
|
||||
printf("Error on line %d, system_level: %d, system_context: %d, error code: %d\n", __LINE__, system_level, system_context, error_code);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_hid_report_descriptor_compress_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR * stack_pointer;
|
||||
CHAR * memory_pointer;
|
||||
UINT descriptor_size = HID_REPORT_LENGTH;
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running HID Report Descriptor Decompress Test....................... ");
|
||||
|
||||
/* Initialize the free memory pointer */
|
||||
stack_pointer = (CHAR *) usbx_memory;
|
||||
memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
|
||||
|
||||
/* Initialize USBX. Memory */
|
||||
status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the error callback. */
|
||||
_ux_utility_error_callback_register(error_callback);
|
||||
|
||||
/* The code below is required for installing the host portion of USBX */
|
||||
status = ux_host_stack_initialize(UX_NULL);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = ux_host_stack_class_register(_ux_system_host_class_hid_name, ux_host_class_hid_entry);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the HID client(s). */
|
||||
status = ux_host_class_hid_client_register(_ux_system_host_class_hid_client_keyboard_name, ux_host_class_hid_keyboard_entry);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* The code below is required for installing the device portion of USBX. No call back for
|
||||
device status change in this example. */
|
||||
status = ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
|
||||
device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
|
||||
string_framework, STRING_FRAMEWORK_LENGTH,
|
||||
language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Initialize the hid class parameters. */
|
||||
hid_parameter.ux_device_class_hid_parameter_report_address = hid_report_descriptor;
|
||||
hid_parameter.ux_device_class_hid_parameter_report_length = HID_REPORT_LENGTH;
|
||||
hid_parameter.ux_device_class_hid_parameter_callback = demo_thread_hid_callback;
|
||||
|
||||
/* Initilize the device hid class. The class is connected with interface 2 */
|
||||
status = ux_device_stack_class_register(_ux_system_slave_class_hid_name, ux_device_class_hid_entry,
|
||||
1,2, (VOID *)&hid_parameter);
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
|
||||
/* Initialize the simulated device controller. */
|
||||
status = _ux_dcd_sim_slave_initialize();
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register all the USB host controllers available in this system */
|
||||
status = ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, ux_hcd_sim_host_initialize,0,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the main host simulation thread. */
|
||||
status = tx_thread_create(&tx_demo_thread_host_simulation, "tx demo host simulation", tx_demo_thread_host_simulation_entry, 0,
|
||||
stack_pointer, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void tx_demo_thread_host_simulation_entry(ULONG arg)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
UX_HOST_CLASS_HID_REPORT_GET_ID report_id;
|
||||
UX_HOST_CLASS_HID_CLIENT_REPORT client_report;
|
||||
UX_HOST_CLASS_HID_REPORT *input_report_descriptor;
|
||||
|
||||
|
||||
/* Find the HID class */
|
||||
status = demo_class_hid_get();
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the first input report descriptor. */
|
||||
report_id.ux_host_class_hid_report_get_report = UX_NULL;
|
||||
report_id.ux_host_class_hid_report_get_type = UX_HOST_CLASS_HID_REPORT_TYPE_INPUT;
|
||||
status = ux_host_class_hid_report_id_get(hid, &report_id);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
input_report_descriptor = report_id.ux_host_class_hid_report_get_report;
|
||||
if (input_report_descriptor -> ux_host_class_hid_report_id != 0)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* First field */
|
||||
|
||||
input_report_buffer_decompressed_original[0] = 0x00010001;
|
||||
input_report_buffer_decompressed_original[1] = 0x01;
|
||||
|
||||
/* Second field */
|
||||
|
||||
input_report_buffer_decompressed_original[2] = 0x00010002;
|
||||
input_report_buffer_decompressed_original[3] = 0x01;
|
||||
|
||||
input_report_buffer_decompressed_original[4] = 0x00010003;
|
||||
input_report_buffer_decompressed_original[5] = 0x00;
|
||||
|
||||
input_report_buffer_decompressed_original[6] = 0x00010004;
|
||||
input_report_buffer_decompressed_original[7] = 0x01;
|
||||
|
||||
/* Third field */
|
||||
|
||||
input_report_buffer_decompressed_original[8] = 0x0001abcd;
|
||||
input_report_buffer_decompressed_original[9] = 0x30;
|
||||
|
||||
/* Fourth field */
|
||||
|
||||
input_report_buffer_decompressed_original[10] = 0x00010006;
|
||||
input_report_buffer_decompressed_original[11] = 0x52;
|
||||
|
||||
input_report_buffer_decompressed_original[12] = 0x00010007;
|
||||
input_report_buffer_decompressed_original[13] = 0x74;
|
||||
|
||||
input_report_buffer_decompressed_original[14] = 0x00010008;
|
||||
input_report_buffer_decompressed_original[15] = 0x96;
|
||||
|
||||
/* Fifth field */
|
||||
|
||||
input_report_buffer_decompressed_original[16] = 0x00010001;
|
||||
input_report_buffer_decompressed_original[17] = 0x0b8;
|
||||
|
||||
/* Sixth field */
|
||||
|
||||
input_report_buffer_decompressed_original[18] = 0x0001000a;
|
||||
input_report_buffer_decompressed_original[19] = 0x06d;
|
||||
|
||||
input_report_buffer_decompressed_original[20] = 0x0001000b;
|
||||
input_report_buffer_decompressed_original[21] = 0x1bf;
|
||||
|
||||
input_report_buffer_decompressed_original[22] = 0x0001000c;
|
||||
input_report_buffer_decompressed_original[23] = 0x003;
|
||||
|
||||
/* Seventh field */
|
||||
|
||||
input_report_buffer_decompressed_original[24] = 0x0001000d;
|
||||
input_report_buffer_decompressed_original[25] = 0x09674523;
|
||||
|
||||
/* Eigth field */
|
||||
|
||||
input_report_buffer_decompressed_original[26] = 0x0001000e;
|
||||
input_report_buffer_decompressed_original[27] = 0x03df9b57;
|
||||
|
||||
/* Fill out the request for the decompress api. */
|
||||
client_report.ux_host_class_hid_client_report = input_report_descriptor;
|
||||
client_report.ux_host_class_hid_client_report_buffer = input_report_buffer_decompressed_original;
|
||||
client_report.ux_host_class_hid_client_report_actual_length = 0;
|
||||
|
||||
/* Request compression. */
|
||||
status = _ux_host_class_hid_report_compress(hid, &client_report, input_report_buffer_compressed, 17);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Check output of report compression. */
|
||||
if (
|
||||
input_report_buffer_compressed[0] != 0x0b ||
|
||||
input_report_buffer_compressed[1] != 0x23 ||
|
||||
input_report_buffer_compressed[2] != 0x45 ||
|
||||
input_report_buffer_compressed[3] != 0x67 ||
|
||||
input_report_buffer_compressed[4] != 0x89 ||
|
||||
input_report_buffer_compressed[5] != 0xab ||
|
||||
input_report_buffer_compressed[6] != 0xcd ||
|
||||
input_report_buffer_compressed[7] != 0xef ||
|
||||
input_report_buffer_compressed[8] != 0x01 ||
|
||||
input_report_buffer_compressed[9] != 0x23 ||
|
||||
input_report_buffer_compressed[10] != 0x45 ||
|
||||
input_report_buffer_compressed[11] != 0x67 ||
|
||||
input_report_buffer_compressed[12] != 0x89 ||
|
||||
input_report_buffer_compressed[13] != 0xab ||
|
||||
input_report_buffer_compressed[14] != 0xcd ||
|
||||
input_report_buffer_compressed[15] != 0xef ||
|
||||
input_report_buffer_compressed[16] != 0x01
|
||||
)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now disconnect the device. */
|
||||
_ux_device_stack_disconnect();
|
||||
|
||||
/* And deinitialize the class. */
|
||||
status = ux_device_stack_class_unregister(_ux_system_slave_class_hid_name, ux_device_class_hid_entry);
|
||||
|
||||
/* Deinitialize the device side of usbx. */
|
||||
_ux_device_stack_uninitialize();
|
||||
|
||||
/* And finally the usbx system resources. */
|
||||
_ux_system_uninitialize();
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
|
||||
static UINT demo_thread_hid_callback(UX_SLAVE_CLASS_HID *class, UX_SLAVE_CLASS_HID_EVENT *event)
|
||||
{
|
||||
return(UX_SUCCESS);
|
||||
}
|
@ -0,0 +1,367 @@
|
||||
/* This test concentrates on the report decompression api when the report contains an array item. */
|
||||
|
||||
#include "usbx_test_common_hid.h"
|
||||
#include "ux_host_class_hid_keyboard.h"
|
||||
|
||||
|
||||
static UCHAR report_buffer_compressed[1024];
|
||||
static SLONG report_buffer_decompressed[1024];
|
||||
|
||||
static UCHAR hid_report_descriptor[] = {
|
||||
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||
0x09, 0x06, // USAGE (Keyboard)
|
||||
0xa1, 0x01, // COLLECTION (Application)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x25, 0x65, // LOGICAL_MAXIMUM (101)
|
||||
0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
|
||||
0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x95, 0x06, // REPORT_COUNT (6)
|
||||
0x81, 0x00, // INPUT (Data,Ary,Abs)
|
||||
|
||||
/* USBX expects keyboards to have at least one output report, otherwise it's an error. */
|
||||
0x95, 0x05, // REPORT_COUNT (5)
|
||||
0x75, 0x01, // REPORT_SIZE (1)
|
||||
0x05, 0x08, // USAGE_PAGE (LEDs)
|
||||
0x19, 0x01, // USAGE_MINIMUM (Num Lock)
|
||||
0x29, 0x05, // USAGE_MAXIMUM (Kana)
|
||||
0x91, 0x02, // OUTPUT (Data,Var,Abs)
|
||||
|
||||
0xc0, // END_COLLECTION
|
||||
};
|
||||
#define HID_REPORT_LENGTH sizeof(hid_report_descriptor)/sizeof(hid_report_descriptor[0])
|
||||
|
||||
|
||||
#define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED 52
|
||||
static UCHAR device_framework_full_speed[DEVICE_FRAMEWORK_LENGTH_FULL_SPEED] = {
|
||||
|
||||
/* Device descriptor */
|
||||
0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08,
|
||||
0x81, 0x0A, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x01,
|
||||
|
||||
/* Configuration descriptor */
|
||||
0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x00, 0xc0,
|
||||
0x32,
|
||||
|
||||
/* Interface descriptor */
|
||||
0x09, 0x04, 0x02, 0x00, 0x01, 0x03, 0x00, 0x00,
|
||||
0x00,
|
||||
|
||||
/* HID descriptor */
|
||||
0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(HID_REPORT_LENGTH),
|
||||
MSB(HID_REPORT_LENGTH),
|
||||
|
||||
/* Endpoint descriptor (Interrupt) */
|
||||
0x07, 0x05, 0x82, 0x03, 0x08, 0x00, 0x08
|
||||
|
||||
};
|
||||
|
||||
|
||||
#define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED 62
|
||||
static UCHAR device_framework_high_speed[DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED] = {
|
||||
|
||||
/* Device descriptor */
|
||||
0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
|
||||
0x0a, 0x07, 0x25, 0x40, 0x01, 0x00, 0x01, 0x02,
|
||||
0x03, 0x01,
|
||||
|
||||
/* Device qualifier descriptor */
|
||||
0x0a, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
|
||||
0x01, 0x00,
|
||||
|
||||
/* Configuration descriptor */
|
||||
0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x00, 0xc0,
|
||||
0x32,
|
||||
|
||||
/* Interface descriptor */
|
||||
0x09, 0x04, 0x02, 0x00, 0x01, 0x03, 0x00, 0x00,
|
||||
0x00,
|
||||
|
||||
/* HID descriptor */
|
||||
0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(HID_REPORT_LENGTH),
|
||||
MSB(HID_REPORT_LENGTH),
|
||||
|
||||
/* Endpoint descriptor (Interrupt) */
|
||||
0x07, 0x05, 0x82, 0x03, 0x08, 0x00, 0x08
|
||||
|
||||
};
|
||||
|
||||
|
||||
/* String Device Framework :
|
||||
Byte 0 and 1 : Word containing the language ID : 0x0904 for US
|
||||
Byte 2 : Byte containing the index of the descriptor
|
||||
Byte 3 : Byte containing the length of the descriptor string
|
||||
*/
|
||||
|
||||
#define STRING_FRAMEWORK_LENGTH 40
|
||||
static UCHAR string_framework[] = {
|
||||
|
||||
/* Manufacturer string descriptor : Index 1 */
|
||||
0x09, 0x04, 0x01, 0x0c,
|
||||
0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
|
||||
0x6f, 0x67, 0x69, 0x63,
|
||||
|
||||
/* Product string descriptor : Index 2 */
|
||||
0x09, 0x04, 0x02, 0x0c,
|
||||
0x55, 0x53, 0x42, 0x20, 0x4b, 0x65, 0x79, 0x62,
|
||||
0x6f, 0x61, 0x72, 0x64,
|
||||
|
||||
/* Serial Number string descriptor : Index 3 */
|
||||
0x09, 0x04, 0x03, 0x04,
|
||||
0x30, 0x30, 0x30, 0x31
|
||||
};
|
||||
|
||||
|
||||
/* Multiple languages are supported on the device, to add
|
||||
a language besides english, the unicode language code must
|
||||
be appended to the language_id_framework array and the length
|
||||
adjusted accordingly. */
|
||||
#define LANGUAGE_ID_FRAMEWORK_LENGTH 2
|
||||
static UCHAR language_id_framework[] = {
|
||||
|
||||
/* English. */
|
||||
0x09, 0x04
|
||||
};
|
||||
|
||||
|
||||
|
||||
static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
|
||||
{
|
||||
|
||||
/* Failed test. */
|
||||
printf("Error on line %d, system_level: %d, system_context: %d, error code: %d\n", __LINE__, system_level, system_context, error_code);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_hid_report_descriptor_decompress_array_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR * stack_pointer;
|
||||
CHAR * memory_pointer;
|
||||
UINT descriptor_size = HID_REPORT_LENGTH;
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running HID Report Descriptor Decompress Array Test................. ");
|
||||
|
||||
/* Initialize the free memory pointer */
|
||||
stack_pointer = (CHAR *) usbx_memory;
|
||||
memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
|
||||
|
||||
/* Initialize USBX. Memory */
|
||||
status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the error callback. */
|
||||
_ux_utility_error_callback_register(error_callback);
|
||||
|
||||
/* The code below is required for installing the host portion of USBX */
|
||||
status = ux_host_stack_initialize(UX_NULL);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = ux_host_stack_class_register(_ux_system_host_class_hid_name, ux_host_class_hid_entry);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the HID client(s). */
|
||||
status = ux_host_class_hid_client_register(_ux_system_host_class_hid_client_keyboard_name, ux_host_class_hid_keyboard_entry);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* The code below is required for installing the device portion of USBX. No call back for
|
||||
device status change in this example. */
|
||||
status = ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
|
||||
device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
|
||||
string_framework, STRING_FRAMEWORK_LENGTH,
|
||||
language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Initialize the hid class parameters. */
|
||||
hid_parameter.ux_device_class_hid_parameter_report_address = hid_report_descriptor;
|
||||
hid_parameter.ux_device_class_hid_parameter_report_length = HID_REPORT_LENGTH;
|
||||
hid_parameter.ux_device_class_hid_parameter_callback = demo_thread_hid_callback;
|
||||
|
||||
/* Initilize the device hid class. The class is connected with interface 2 */
|
||||
status = ux_device_stack_class_register(_ux_system_slave_class_hid_name, ux_device_class_hid_entry,
|
||||
1,2, (VOID *)&hid_parameter);
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
|
||||
/* Initialize the simulated device controller. */
|
||||
status = _ux_dcd_sim_slave_initialize();
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register all the USB host controllers available in this system */
|
||||
status = ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, ux_hcd_sim_host_initialize,0,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the main host simulation thread. */
|
||||
status = tx_thread_create(&tx_demo_thread_host_simulation, "tx demo host simulation", tx_demo_thread_host_simulation_entry, 0,
|
||||
stack_pointer, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
static void tx_demo_thread_host_simulation_entry(ULONG arg)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
UX_HOST_CLASS_HID_REPORT_GET_ID report_id;
|
||||
UX_HOST_CLASS_HID_CLIENT_REPORT input_report_request;
|
||||
UX_HOST_CLASS_HID_REPORT *input_report_descriptor;
|
||||
|
||||
|
||||
/* Find the HID class */
|
||||
status = demo_class_hid_get();
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the first input report descriptor. */
|
||||
report_id.ux_host_class_hid_report_get_report = UX_NULL;
|
||||
report_id.ux_host_class_hid_report_get_type = UX_HOST_CLASS_HID_REPORT_TYPE_INPUT;
|
||||
status = ux_host_class_hid_report_id_get(hid, &report_id);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
input_report_descriptor = report_id.ux_host_class_hid_report_get_report;
|
||||
if (input_report_descriptor -> ux_host_class_hid_report_id != 0)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Fill out the request for the decompress api. */
|
||||
input_report_request.ux_host_class_hid_client_report = input_report_descriptor;
|
||||
input_report_request.ux_host_class_hid_client_report_buffer = report_buffer_decompressed;
|
||||
input_report_request.ux_host_class_hid_client_report_length = input_report_descriptor -> ux_host_class_hid_report_byte_length;
|
||||
input_report_request.ux_host_class_hid_client_report_actual_length = 0;
|
||||
input_report_request.ux_host_class_hid_client_report_flags = UX_HOST_CLASS_HID_REPORT_DECOMPRESSED;
|
||||
|
||||
/* Fill out report. */
|
||||
report_buffer_compressed[0] = 0x00;
|
||||
report_buffer_compressed[1] = 0x10;
|
||||
report_buffer_compressed[2] = 0x23;
|
||||
report_buffer_compressed[3] = 0x37;
|
||||
report_buffer_compressed[4] = 0x43;
|
||||
report_buffer_compressed[5] = 0x65;
|
||||
|
||||
/* Request decompression. */
|
||||
status = _ux_host_class_hid_report_decompress(hid, &input_report_request, report_buffer_compressed, 6);
|
||||
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Check output of decompression of report. */
|
||||
if (
|
||||
report_buffer_decompressed[0] != 0x00010000 ||
|
||||
report_buffer_decompressed[1] != 0x00 ||
|
||||
report_buffer_decompressed[2] != 0x00010010 ||
|
||||
report_buffer_decompressed[3] != 0x10 ||
|
||||
report_buffer_decompressed[4] != 0x00010023 ||
|
||||
report_buffer_decompressed[5] != 0x23 ||
|
||||
report_buffer_decompressed[6] != 0x00010037 ||
|
||||
report_buffer_decompressed[7] != 0x37 ||
|
||||
report_buffer_decompressed[8] != 0x00010043 ||
|
||||
report_buffer_decompressed[9] != 0x43 ||
|
||||
report_buffer_decompressed[10] != 0x00010065 ||
|
||||
report_buffer_decompressed[11] != 0x65
|
||||
)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now disconnect the device. */
|
||||
_ux_device_stack_disconnect();
|
||||
|
||||
/* And deinitialize the class. */
|
||||
status = ux_device_stack_class_unregister(_ux_system_slave_class_hid_name, ux_device_class_hid_entry);
|
||||
|
||||
/* Deinitialize the device side of usbx. */
|
||||
_ux_device_stack_uninitialize();
|
||||
|
||||
/* And finally the usbx system resources. */
|
||||
_ux_system_uninitialize();
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
|
||||
static UINT demo_thread_hid_callback(UX_SLAVE_CLASS_HID *class, UX_SLAVE_CLASS_HID_EVENT *event)
|
||||
{
|
||||
return(UX_SUCCESS);
|
||||
}
|
500
test/regression/usbx_hid_report_descriptor_decompress_test.c
Normal file
500
test/regression/usbx_hid_report_descriptor_decompress_test.c
Normal file
@ -0,0 +1,500 @@
|
||||
/* This test concentrates on the report decompress api. */
|
||||
|
||||
#include "usbx_test_common_hid.h"
|
||||
#include "ux_host_class_hid_keyboard.h"
|
||||
|
||||
|
||||
static UCHAR report_buffer_compressed_original[1024];
|
||||
static UCHAR report_buffer_compressed[1024];
|
||||
static SLONG report_buffer_decompressed[1024];
|
||||
|
||||
static UCHAR hid_report_descriptor[] = {
|
||||
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||
0x09, 0x06, // USAGE (Keyboard)
|
||||
0xa1, 0x01, // COLLECTION (Application)
|
||||
|
||||
/* First field */
|
||||
0x09, 0x01, // USAGE (1)
|
||||
0x75, 0x01, // REPORT_SIZE (1)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
|
||||
/* Second field */
|
||||
0x19, 0x02, // USAGE_MINIMUM (2)
|
||||
0x29, 0x04, // USAGE_MAXIMUM (4)
|
||||
0x75, 0x01, // REPORT_SIZE (1)
|
||||
0x95, 0x03, // REPORT_COUNT (3)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
|
||||
/* Third field */
|
||||
0x0a, 0xcd, 0xab, // USAGE (0xabcd)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
|
||||
/* Fourth field */
|
||||
0x19, 0x06, // USAGE_MINIMUM (6)
|
||||
0x29, 0x08, // USAGE_MAXIMUM (8)
|
||||
0x75, 0x08, // REPORT_SIZE (8)
|
||||
0x95, 0x03, // REPORT_COUNT (3)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
|
||||
/* Fifth field */
|
||||
0x09, 0x01, // USAGE (1)
|
||||
0x75, 0x09, // REPORT_SIZE (9)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
|
||||
/* Sixth field */
|
||||
0x19, 0x0a, // USAGE_MINIMUM (10)
|
||||
0x29, 0x0c, // USAGE_MAXIMUM (12)
|
||||
0x75, 0x09, // REPORT_SIZE (9)
|
||||
0x95, 0x03, // REPORT_COUNT (3)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
|
||||
/* Seventh field */
|
||||
0x09, 0x0d, // USAGE (13)
|
||||
0x75, 0x1f, // REPORT_SIZE (31)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
|
||||
/* Eigth field */
|
||||
0x09, 0x0e, // USAGE (14)
|
||||
0x75, 0x20, // REPORT_SIZE (32)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
|
||||
/* bits: 1 + 3 + 8 + 24 + 9 + 27 + 31 + 32 = 135; 17 bytes overall */
|
||||
|
||||
/* USBX expects keyboards to have at least one output report, otherwise it's an error. */
|
||||
0x95, 0x05, // REPORT_COUNT (5)
|
||||
0x75, 0x01, // REPORT_SIZE (1)
|
||||
0x05, 0x08, // USAGE_PAGE (LEDs)
|
||||
0x19, 0x01, // USAGE_MINIMUM (Num Lock)
|
||||
0x29, 0x05, // USAGE_MAXIMUM (Kana)
|
||||
0x91, 0x02, // OUTPUT (Data,Var,Abs)
|
||||
|
||||
0xc0, // END_COLLECTION
|
||||
};
|
||||
#define HID_REPORT_LENGTH sizeof(hid_report_descriptor)/sizeof(hid_report_descriptor[0])
|
||||
|
||||
|
||||
#define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED 52
|
||||
static UCHAR device_framework_full_speed[DEVICE_FRAMEWORK_LENGTH_FULL_SPEED] = {
|
||||
|
||||
/* Device descriptor */
|
||||
0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08,
|
||||
0x81, 0x0A, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x01,
|
||||
|
||||
/* Configuration descriptor */
|
||||
0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x00, 0xc0,
|
||||
0x32,
|
||||
|
||||
/* Interface descriptor */
|
||||
0x09, 0x04, 0x02, 0x00, 0x01, 0x03, 0x00, 0x00,
|
||||
0x00,
|
||||
|
||||
/* HID descriptor */
|
||||
0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(HID_REPORT_LENGTH),
|
||||
MSB(HID_REPORT_LENGTH),
|
||||
|
||||
/* Endpoint descriptor (Interrupt) */
|
||||
0x07, 0x05, 0x82, 0x03, 0x08, 0x00, 0x08
|
||||
|
||||
};
|
||||
|
||||
|
||||
#define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED 62
|
||||
static UCHAR device_framework_high_speed[DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED] = {
|
||||
|
||||
/* Device descriptor */
|
||||
0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
|
||||
0x0a, 0x07, 0x25, 0x40, 0x01, 0x00, 0x01, 0x02,
|
||||
0x03, 0x01,
|
||||
|
||||
/* Device qualifier descriptor */
|
||||
0x0a, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
|
||||
0x01, 0x00,
|
||||
|
||||
/* Configuration descriptor */
|
||||
0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x00, 0xc0,
|
||||
0x32,
|
||||
|
||||
/* Interface descriptor */
|
||||
0x09, 0x04, 0x02, 0x00, 0x01, 0x03, 0x00, 0x00,
|
||||
0x00,
|
||||
|
||||
/* HID descriptor */
|
||||
0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(HID_REPORT_LENGTH),
|
||||
MSB(HID_REPORT_LENGTH),
|
||||
|
||||
/* Endpoint descriptor (Interrupt) */
|
||||
0x07, 0x05, 0x82, 0x03, 0x08, 0x00, 0x08
|
||||
|
||||
};
|
||||
|
||||
|
||||
/* String Device Framework :
|
||||
Byte 0 and 1 : Word containing the language ID : 0x0904 for US
|
||||
Byte 2 : Byte containing the index of the descriptor
|
||||
Byte 3 : Byte containing the length of the descriptor string
|
||||
*/
|
||||
|
||||
#define STRING_FRAMEWORK_LENGTH 40
|
||||
static UCHAR string_framework[] = {
|
||||
|
||||
/* Manufacturer string descriptor : Index 1 */
|
||||
0x09, 0x04, 0x01, 0x0c,
|
||||
0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
|
||||
0x6f, 0x67, 0x69, 0x63,
|
||||
|
||||
/* Product string descriptor : Index 2 */
|
||||
0x09, 0x04, 0x02, 0x0c,
|
||||
0x55, 0x53, 0x42, 0x20, 0x4b, 0x65, 0x79, 0x62,
|
||||
0x6f, 0x61, 0x72, 0x64,
|
||||
|
||||
/* Serial Number string descriptor : Index 3 */
|
||||
0x09, 0x04, 0x03, 0x04,
|
||||
0x30, 0x30, 0x30, 0x31
|
||||
};
|
||||
|
||||
|
||||
/* Multiple languages are supported on the device, to add
|
||||
a language besides english, the unicode language code must
|
||||
be appended to the language_id_framework array and the length
|
||||
adjusted accordingly. */
|
||||
#define LANGUAGE_ID_FRAMEWORK_LENGTH 2
|
||||
static UCHAR language_id_framework[] = {
|
||||
|
||||
/* English. */
|
||||
0x09, 0x04
|
||||
};
|
||||
|
||||
|
||||
static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
|
||||
{
|
||||
|
||||
/* Failed test. */
|
||||
printf("Error on line %d, system_level: %d, system_context: %d, error code: %d\n", __LINE__, system_level, system_context, error_code);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_hid_report_descriptor_decompress_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR * stack_pointer;
|
||||
CHAR * memory_pointer;
|
||||
UINT descriptor_size = HID_REPORT_LENGTH;
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running HID Report Descriptor Decompress Test....................... ");
|
||||
|
||||
/* Initialize the free memory pointer */
|
||||
stack_pointer = (CHAR *) usbx_memory;
|
||||
memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
|
||||
|
||||
/* Initialize USBX. Memory */
|
||||
status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the error callback. */
|
||||
_ux_utility_error_callback_register(error_callback);
|
||||
|
||||
/* The code below is required for installing the host portion of USBX */
|
||||
status = ux_host_stack_initialize(UX_NULL);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = ux_host_stack_class_register(_ux_system_host_class_hid_name, ux_host_class_hid_entry);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the HID client(s). */
|
||||
status = ux_host_class_hid_client_register(_ux_system_host_class_hid_client_keyboard_name, ux_host_class_hid_keyboard_entry);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* The code below is required for installing the device portion of USBX. No call back for
|
||||
device status change in this example. */
|
||||
status = ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
|
||||
device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
|
||||
string_framework, STRING_FRAMEWORK_LENGTH,
|
||||
language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Initialize the hid class parameters. */
|
||||
hid_parameter.ux_device_class_hid_parameter_report_address = hid_report_descriptor;
|
||||
hid_parameter.ux_device_class_hid_parameter_report_length = HID_REPORT_LENGTH;
|
||||
hid_parameter.ux_device_class_hid_parameter_callback = demo_thread_hid_callback;
|
||||
|
||||
/* Initilize the device hid class. The class is connected with interface 2 */
|
||||
status = ux_device_stack_class_register(_ux_system_slave_class_hid_name, ux_device_class_hid_entry,
|
||||
1,2, (VOID *)&hid_parameter);
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
|
||||
/* Initialize the simulated device controller. */
|
||||
status = _ux_dcd_sim_slave_initialize();
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register all the USB host controllers available in this system */
|
||||
status = ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, ux_hcd_sim_host_initialize,0,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the main host simulation thread. */
|
||||
status = tx_thread_create(&tx_demo_thread_host_simulation, "tx demo host simulation", tx_demo_thread_host_simulation_entry, 0,
|
||||
stack_pointer, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void tx_demo_thread_host_simulation_entry(ULONG arg)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
UX_HOST_CLASS_HID_REPORT_GET_ID report_get_id;
|
||||
UX_HOST_CLASS_HID_CLIENT_REPORT client_report;
|
||||
UX_HOST_CLASS_HID_REPORT *hid_report;
|
||||
|
||||
/* Find the HID class */
|
||||
status = demo_class_hid_get();
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Get the first input report descriptor. */
|
||||
report_get_id.ux_host_class_hid_report_get_report = UX_NULL;
|
||||
report_get_id.ux_host_class_hid_report_get_type = UX_HOST_CLASS_HID_REPORT_TYPE_INPUT;
|
||||
status = ux_host_class_hid_report_id_get(hid, &report_get_id);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
hid_report = report_get_id.ux_host_class_hid_report_get_report;
|
||||
if (hid_report -> ux_host_class_hid_report_id != 0)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Fill out the request for the decompress api. */
|
||||
client_report.ux_host_class_hid_client_report = hid_report;
|
||||
client_report.ux_host_class_hid_client_report_buffer = report_buffer_decompressed;
|
||||
client_report.ux_host_class_hid_client_report_length = hid_report -> ux_host_class_hid_report_byte_length;
|
||||
client_report.ux_host_class_hid_client_report_actual_length = 0;
|
||||
|
||||
/* Fill out report. */
|
||||
report_buffer_compressed_original[0] = 0x0b; // [0] bits 1-8: 0000 1011
|
||||
report_buffer_compressed_original[1] = 0x23; // [1] bits 9-16: 0010 0011
|
||||
report_buffer_compressed_original[2] = 0x45; // [2] bits 17-24: 0100 0101
|
||||
report_buffer_compressed_original[3] = 0x67; // [3] bits 25-32: 0110 0111
|
||||
report_buffer_compressed_original[4] = 0x89; // [4] bits 33-40: 1000 1001
|
||||
report_buffer_compressed_original[5] = 0xab; // [5] bits 41-48: 1010 1011
|
||||
report_buffer_compressed_original[6] = 0xcd; // [6] bits 49-56: 1100 1101
|
||||
report_buffer_compressed_original[7] = 0xef; // [7] bits 57-64: 1110 1111
|
||||
report_buffer_compressed_original[8] = 0x01; // [8] bits 65-72: 0000 0001
|
||||
report_buffer_compressed_original[9] = 0x23; // [9] bits 73-80: 0010 0011
|
||||
report_buffer_compressed_original[10] = 0x45; // [10] bits 81-88: 0100 0101
|
||||
report_buffer_compressed_original[11] = 0x67; // [11] bits 89-96: 0110 0111
|
||||
report_buffer_compressed_original[12] = 0x89; // [12] bits 97-104: 1000 1001
|
||||
report_buffer_compressed_original[13] = 0xab; // [13] bits 105-112: 1010 1011
|
||||
report_buffer_compressed_original[14] = 0xcd; // [14] bits 113-120: 1100 1101
|
||||
report_buffer_compressed_original[15] = 0xef; // [15] bits 121-128: 1110 1111
|
||||
report_buffer_compressed_original[16] = 0x01; // [16] bits 129-136: 0000 0001
|
||||
|
||||
/* Request decompression. */
|
||||
status = _ux_host_class_hid_report_decompress(hid, &client_report, report_buffer_compressed_original, 17);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Check output of decompression of report. */
|
||||
if (
|
||||
/* First field */
|
||||
|
||||
/* bit 1 */
|
||||
report_buffer_decompressed[0] != 0x00010001 ||
|
||||
report_buffer_decompressed[1] != 0x01 ||
|
||||
|
||||
/* Second field */
|
||||
|
||||
/* bit 2 */
|
||||
report_buffer_decompressed[2] != 0x00010002 ||
|
||||
report_buffer_decompressed[3] != 0x01 ||
|
||||
|
||||
/* bit 3 */
|
||||
report_buffer_decompressed[4] != 0x00010003 ||
|
||||
report_buffer_decompressed[5] != 0x00 ||
|
||||
|
||||
/* bit 4 */
|
||||
report_buffer_decompressed[6] != 0x00010004 ||
|
||||
report_buffer_decompressed[7] != 0x01 ||
|
||||
|
||||
/* Third field */
|
||||
|
||||
/* bits 5-12 */
|
||||
report_buffer_decompressed[8] != 0x0001abcd ||
|
||||
report_buffer_decompressed[9] != 0x30 ||
|
||||
|
||||
/* Fourth field */
|
||||
|
||||
/* bits 13-20 */
|
||||
report_buffer_decompressed[10] != 0x00010006 ||
|
||||
report_buffer_decompressed[11] != 0x52 ||
|
||||
|
||||
/* bits 21-28 */
|
||||
report_buffer_decompressed[12] != 0x00010007 ||
|
||||
report_buffer_decompressed[13] != 0x74 ||
|
||||
|
||||
/* bits 29-36 */
|
||||
report_buffer_decompressed[14] != 0x00010008 ||
|
||||
report_buffer_decompressed[15] != 0x96 ||
|
||||
|
||||
/* Fifth field */
|
||||
|
||||
/* bits 37-45 */
|
||||
report_buffer_decompressed[16] != 0x00010001 ||
|
||||
report_buffer_decompressed[17] != 0x0b8 ||
|
||||
|
||||
/* Sixth field */
|
||||
|
||||
/* bits 46-54 - 0 0110 1101 */
|
||||
report_buffer_decompressed[18] != 0x0001000a ||
|
||||
report_buffer_decompressed[19] != 0x06d ||
|
||||
|
||||
/* bits 55-63 - 1 1011 1111 */
|
||||
report_buffer_decompressed[20] != 0x0001000b ||
|
||||
report_buffer_decompressed[21] != 0x1bf ||
|
||||
|
||||
/* bits 64-72 - 0 0000 0011 */
|
||||
report_buffer_decompressed[22] != 0x0001000c ||
|
||||
report_buffer_decompressed[23] != 0x003 ||
|
||||
|
||||
/* Seventh field */
|
||||
|
||||
/* bits 73-103 - 000 1001 0110 0111 0100 0101 0010 0011 */
|
||||
report_buffer_decompressed[24] != 0x0001000d ||
|
||||
report_buffer_decompressed[25] != 0x09674523 ||
|
||||
|
||||
/* Eigth field */
|
||||
|
||||
/* bits 104-135 - 0000 0011 1101 1111 1001 1011 0101 0111 */
|
||||
report_buffer_decompressed[26] != 0x0001000e ||
|
||||
report_buffer_decompressed[27] != 0x03df9b57
|
||||
)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Now perform the inverse: compression. */
|
||||
status = _ux_host_class_hid_report_compress(hid, &client_report, report_buffer_compressed, 28);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* These should be the same (god help us). */
|
||||
if(ux_utility_memory_compare(report_buffer_compressed, report_buffer_compressed_original, 17) != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Now disconnect the device. */
|
||||
_ux_device_stack_disconnect();
|
||||
|
||||
/* And deinitialize the class. */
|
||||
status = ux_device_stack_class_unregister(_ux_system_slave_class_hid_name, ux_device_class_hid_entry);
|
||||
|
||||
/* Deinitialize the device side of usbx. */
|
||||
_ux_device_stack_uninitialize();
|
||||
|
||||
/* And finally the usbx system resources. */
|
||||
_ux_system_uninitialize();
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
|
||||
static UINT demo_thread_hid_callback(UX_SLAVE_CLASS_HID *class, UX_SLAVE_CLASS_HID_EVENT *event)
|
||||
{
|
||||
return(UX_SUCCESS);
|
||||
}
|
@ -0,0 +1,304 @@
|
||||
/* This test ensures that the parser generates an error upon encountering an invalid close delimiter tag. */
|
||||
|
||||
#include "usbx_test_common_hid.h"
|
||||
#include "ux_host_class_hid_keyboard.h"
|
||||
|
||||
|
||||
static UINT callback_error_code;
|
||||
|
||||
static UCHAR hid_report_descriptor[] = {
|
||||
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||
0x09, 0x06, // USAGE (Keyboard)
|
||||
0xa1, 0x01, // COLLECTION (Application)
|
||||
0xa9, 0x01, // DELIMITER (Open)
|
||||
0x0b, 0x20, 0x00, 0x05, 0x00, // USAGE (Gaming Controls:Point of View)
|
||||
0x0b, 0x39, 0x00, 0x01, 0x00, // USAGE (Generic Desktop:Hat switch)
|
||||
0x0b, 0x20, 0x00, 0x05, 0x00, // USAGE (Gaming Controls:Point of View)
|
||||
0xa9, 0x00, // DELIMITER (Close)
|
||||
/* Add an extra invalid delimiter close tag. */
|
||||
0xa9, 0x00, // DELIMITER (Close)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x25, 0x03, // LOGICAL_MAXIMUM (3)
|
||||
0x35, 0x00, // PHYSICAL_MINIMUM (0)
|
||||
0x46, 0x0e, 0x01, // PHYSICAL_MAXIMUM (270)
|
||||
0x65, 0x14, // UNIT (Eng Rot:Angular Pos)
|
||||
0x55, 0x00, // UNIT_EXPONENT (0)
|
||||
0x75, 0x04, // REPORT_SIZE (4)
|
||||
0x95, 0x01, // REPORT_COUNT (1)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
0xc0 // END_COLLECTION
|
||||
};
|
||||
#define HID_REPORT_LENGTH sizeof(hid_report_descriptor)/sizeof(hid_report_descriptor[0])
|
||||
|
||||
|
||||
#define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED 52
|
||||
static UCHAR device_framework_full_speed[DEVICE_FRAMEWORK_LENGTH_FULL_SPEED] = {
|
||||
|
||||
/* Device descriptor */
|
||||
0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08,
|
||||
0x81, 0x0A, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x01,
|
||||
|
||||
/* Configuration descriptor */
|
||||
0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x00, 0xc0,
|
||||
0x32,
|
||||
|
||||
/* Interface descriptor */
|
||||
0x09, 0x04, 0x02, 0x00, 0x01, 0x03, 0x00, 0x00,
|
||||
0x00,
|
||||
|
||||
/* HID descriptor */
|
||||
0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(HID_REPORT_LENGTH),
|
||||
MSB(HID_REPORT_LENGTH),
|
||||
|
||||
/* Endpoint descriptor (Interrupt) */
|
||||
0x07, 0x05, 0x82, 0x03, 0x08, 0x00, 0x08
|
||||
|
||||
};
|
||||
|
||||
|
||||
#define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED 62
|
||||
static UCHAR device_framework_high_speed[DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED] = {
|
||||
|
||||
/* Device descriptor */
|
||||
0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
|
||||
0x0a, 0x07, 0x25, 0x40, 0x01, 0x00, 0x01, 0x02,
|
||||
0x03, 0x01,
|
||||
|
||||
/* Device qualifier descriptor */
|
||||
0x0a, 0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40,
|
||||
0x01, 0x00,
|
||||
|
||||
/* Configuration descriptor */
|
||||
0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x00, 0xc0,
|
||||
0x32,
|
||||
|
||||
/* Interface descriptor */
|
||||
0x09, 0x04, 0x02, 0x00, 0x01, 0x03, 0x00, 0x00,
|
||||
0x00,
|
||||
|
||||
/* HID descriptor */
|
||||
0x09, 0x21, 0x10, 0x01, 0x21, 0x01, 0x22, LSB(HID_REPORT_LENGTH),
|
||||
MSB(HID_REPORT_LENGTH),
|
||||
|
||||
/* Endpoint descriptor (Interrupt) */
|
||||
0x07, 0x05, 0x82, 0x03, 0x08, 0x00, 0x08
|
||||
|
||||
};
|
||||
|
||||
|
||||
/* String Device Framework :
|
||||
Byte 0 and 1 : Word containing the language ID : 0x0904 for US
|
||||
Byte 2 : Byte containing the index of the descriptor
|
||||
Byte 3 : Byte containing the length of the descriptor string
|
||||
*/
|
||||
|
||||
#define STRING_FRAMEWORK_LENGTH 40
|
||||
static UCHAR string_framework[] = {
|
||||
|
||||
/* Manufacturer string descriptor : Index 1 */
|
||||
0x09, 0x04, 0x01, 0x0c,
|
||||
0x45, 0x78, 0x70, 0x72,0x65, 0x73, 0x20, 0x4c,
|
||||
0x6f, 0x67, 0x69, 0x63,
|
||||
|
||||
/* Product string descriptor : Index 2 */
|
||||
0x09, 0x04, 0x02, 0x0c,
|
||||
0x55, 0x53, 0x42, 0x20, 0x4b, 0x65, 0x79, 0x62,
|
||||
0x6f, 0x61, 0x72, 0x64,
|
||||
|
||||
/* Serial Number string descriptor : Index 3 */
|
||||
0x09, 0x04, 0x03, 0x04,
|
||||
0x30, 0x30, 0x30, 0x31
|
||||
};
|
||||
|
||||
|
||||
/* Multiple languages are supported on the device, to add
|
||||
a language besides english, the unicode language code must
|
||||
be appended to the language_id_framework array and the length
|
||||
adjusted accordingly. */
|
||||
#define LANGUAGE_ID_FRAMEWORK_LENGTH 2
|
||||
static UCHAR language_id_framework[] = {
|
||||
|
||||
/* English. */
|
||||
0x09, 0x04
|
||||
};
|
||||
|
||||
|
||||
|
||||
static VOID error_callback(UINT system_level, UINT system_context, UINT error_code)
|
||||
{
|
||||
|
||||
if (error_code != UX_HOST_CLASS_HID_DELIMITER_ERROR &&
|
||||
error_code != UX_DESCRIPTOR_CORRUPTED &&
|
||||
error_code != UX_DEVICE_ENUMERATION_FAILURE)
|
||||
{
|
||||
|
||||
/* Something went wrong. */
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
#ifdef CTEST
|
||||
void test_application_define(void *first_unused_memory)
|
||||
#else
|
||||
void usbx_hid_report_descriptor_delimiter_nested_close_test_application_define(void *first_unused_memory)
|
||||
#endif
|
||||
{
|
||||
|
||||
UINT status;
|
||||
CHAR * stack_pointer;
|
||||
CHAR * memory_pointer;
|
||||
UINT descriptor_size = HID_REPORT_LENGTH;
|
||||
|
||||
/* Inform user. */
|
||||
printf("Running HID Report Descriptor Delimiter Nested Close Test........... ");
|
||||
|
||||
/* Initialize the free memory pointer */
|
||||
stack_pointer = (CHAR *) usbx_memory;
|
||||
memory_pointer = stack_pointer + (UX_DEMO_STACK_SIZE * 2);
|
||||
|
||||
/* Initialize USBX. Memory */
|
||||
status = ux_system_initialize(memory_pointer, UX_DEMO_MEMORY_SIZE, UX_NULL,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the error callback. */
|
||||
_ux_utility_error_callback_register(error_callback);
|
||||
|
||||
/* The code below is required for installing the host portion of USBX */
|
||||
status = ux_host_stack_initialize(UX_NULL);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
status = ux_host_stack_class_register(_ux_system_host_class_hid_name, ux_host_class_hid_entry);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register the HID client(s). */
|
||||
status = ux_host_class_hid_client_register(_ux_system_host_class_hid_client_keyboard_name, ux_host_class_hid_keyboard_entry);
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* The code below is required for installing the device portion of USBX. No call back for
|
||||
device status change in this example. */
|
||||
status = ux_device_stack_initialize(device_framework_high_speed, DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED,
|
||||
device_framework_full_speed, DEVICE_FRAMEWORK_LENGTH_FULL_SPEED,
|
||||
string_framework, STRING_FRAMEWORK_LENGTH,
|
||||
language_id_framework, LANGUAGE_ID_FRAMEWORK_LENGTH,UX_NULL);
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Initialize the hid class parameters. */
|
||||
hid_parameter.ux_device_class_hid_parameter_report_address = hid_report_descriptor;
|
||||
hid_parameter.ux_device_class_hid_parameter_report_length = HID_REPORT_LENGTH;
|
||||
hid_parameter.ux_device_class_hid_parameter_callback = demo_thread_hid_callback;
|
||||
|
||||
/* Initilize the device hid class. The class is connected with interface 2 */
|
||||
status = ux_device_stack_class_register(_ux_system_slave_class_hid_name, ux_device_class_hid_entry,
|
||||
1,2, (VOID *)&hid_parameter);
|
||||
if(status!=UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
|
||||
/* Initialize the simulated device controller. */
|
||||
status = _ux_dcd_sim_slave_initialize();
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Register all the USB host controllers available in this system */
|
||||
status = ux_host_stack_hcd_register(_ux_system_host_hcd_simulator_name, ux_hcd_sim_host_initialize,0,0);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Create the main host simulation thread. */
|
||||
status = tx_thread_create(&tx_demo_thread_host_simulation, "tx demo host simulation", tx_demo_thread_host_simulation_entry, 0,
|
||||
stack_pointer, UX_DEMO_STACK_SIZE,
|
||||
20, 20, 1, TX_AUTO_START);
|
||||
|
||||
/* Check for error. */
|
||||
if (status != TX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d\n", __LINE__);
|
||||
test_control_return(1);
|
||||
}
|
||||
}
|
||||
|
||||
static void tx_demo_thread_host_simulation_entry(ULONG arg)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
/* Find the HID class */
|
||||
status = demo_class_hid_get();
|
||||
if (status == UX_SUCCESS)
|
||||
{
|
||||
|
||||
printf("Error on line %d, error code: %d\n", __LINE__, status);
|
||||
test_control_return(1);
|
||||
}
|
||||
|
||||
/* Now disconnect the device. */
|
||||
_ux_device_stack_disconnect();
|
||||
|
||||
/* And deinitialize the class. */
|
||||
status = ux_device_stack_class_unregister(_ux_system_slave_class_hid_name, ux_device_class_hid_entry);
|
||||
|
||||
/* Deinitialize the device side of usbx. */
|
||||
_ux_device_stack_uninitialize();
|
||||
|
||||
/* And finally the usbx system resources. */
|
||||
_ux_system_uninitialize();
|
||||
|
||||
/* Successful test. */
|
||||
printf("SUCCESS!\n");
|
||||
test_control_return(0);
|
||||
}
|
||||
|
||||
|
||||
static UINT demo_thread_hid_callback(UX_SLAVE_CLASS_HID *class, UX_SLAVE_CLASS_HID_EVENT *event)
|
||||
{
|
||||
return(UX_SUCCESS);
|
||||
}
|
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