mirror of
https://github.com/azure-rtos/usbx.git
synced 2025-01-28 07:03:07 +08:00
6ed7092b77
Add regression tests (auto triggered on PR, manually triggered in forked branch).
266 lines
9.0 KiB
C
266 lines
9.0 KiB
C
/* This test simulator is designed to redirect simulate ux_hcd_sim_slave_ APIs for test. */
|
|
|
|
#include "tx_api.h"
|
|
#include "tx_thread.h"
|
|
|
|
#include "ux_api.h"
|
|
#include "ux_dcd_sim_slave.h"
|
|
|
|
#include "ux_test_dcd_sim_slave.h"
|
|
#include "ux_test_utility_sim.h"
|
|
|
|
static ULONG _ux_dcd_sim_slave_speed = UX_FULL_SPEED_DEVICE;
|
|
static UCHAR *_ux_dcd_sim_framework = UX_NULL;
|
|
static ULONG _ux_dcd_sim_framework_length = 0;
|
|
|
|
static UX_TEST_DCD_SIM_ACTION *ux_test_actions = UX_NULL;
|
|
static UX_TEST_DCD_SIM_ACTION *ux_test_main_action_list;
|
|
|
|
VOID ux_test_dcd_sim_slave_cleanup(VOID)
|
|
{
|
|
_ux_dcd_sim_slave_speed = UX_FULL_SPEED_DEVICE;
|
|
|
|
_ux_dcd_sim_framework = UX_NULL;
|
|
_ux_dcd_sim_framework_length = 0;
|
|
|
|
ux_test_actions = UX_NULL;
|
|
ux_test_main_action_list = UX_NULL;
|
|
}
|
|
|
|
VOID ux_test_dcd_sim_slave_disconnect(VOID)
|
|
{
|
|
|
|
#if 1
|
|
UINT old_threshold;
|
|
#else
|
|
TX_INTERRUPT_SAVE_AREA
|
|
#endif
|
|
|
|
#if 1
|
|
/* Disconnection is usually handled in an ISR, which cannot be preempted. Copy behavior.
|
|
Note that the regular TX_DISABLE doesn't work on Windows. Might not work for Linux
|
|
either. */
|
|
tx_thread_preemption_change(tx_thread_identify(), 0, &old_threshold);
|
|
#else
|
|
TX_DISABLE
|
|
#endif
|
|
|
|
ux_device_stack_disconnect();
|
|
|
|
#if 1
|
|
tx_thread_preemption_change(tx_thread_identify(), old_threshold, &old_threshold);
|
|
#else
|
|
TX_RESTORE
|
|
#endif
|
|
}
|
|
|
|
VOID ux_test_dcd_sim_slave_connect(ULONG speed)
|
|
{
|
|
_ux_dcd_sim_slave_speed = speed;
|
|
//_ux_dcd_sim_slave_initialize_complete();
|
|
}
|
|
|
|
VOID ux_test_dcd_sim_slave_connect_framework(UCHAR * framework, ULONG framework_length)
|
|
{
|
|
_ux_dcd_sim_framework = framework;
|
|
_ux_dcd_sim_framework_length = framework_length;
|
|
//_ux_dcd_sim_slave_initialize_complete();
|
|
}
|
|
|
|
/* Fork and modified to replace _ux_dcd_sim_slave_initialize_complete in lib for testing control. */
|
|
UINT _ux_dcd_sim_slave_initialize_complete(VOID)
|
|
{
|
|
|
|
UX_SLAVE_DCD *dcd;
|
|
UX_SLAVE_DEVICE *device;
|
|
UCHAR * device_framework;
|
|
UX_SLAVE_TRANSFER *transfer_request;
|
|
|
|
/* Get the pointer to the DCD. */
|
|
dcd = &_ux_system_slave -> ux_system_slave_dcd;
|
|
|
|
/* Get the pointer to the device. */
|
|
device = &_ux_system_slave -> ux_system_slave_device;
|
|
|
|
if (_ux_dcd_sim_framework != UX_NULL && _ux_dcd_sim_framework_length != 0)
|
|
{
|
|
|
|
/* Initialize customized framework. */
|
|
_ux_system_slave -> ux_system_slave_device_framework = _ux_dcd_sim_framework;
|
|
_ux_system_slave -> ux_system_slave_device_framework_length = _ux_dcd_sim_framework_length;
|
|
}
|
|
else
|
|
{
|
|
/* Slave simulator is a Full/high speed controller. */
|
|
if (_ux_dcd_sim_slave_speed == UX_HIGH_SPEED_DEVICE)
|
|
{
|
|
|
|
_ux_system_slave -> ux_system_slave_device_framework = _ux_system_slave -> ux_system_slave_device_framework_high_speed;
|
|
_ux_system_slave -> ux_system_slave_device_framework_length = _ux_system_slave -> ux_system_slave_device_framework_length_high_speed;
|
|
}
|
|
else
|
|
{
|
|
|
|
_ux_system_slave -> ux_system_slave_device_framework = _ux_system_slave -> ux_system_slave_device_framework_full_speed;
|
|
_ux_system_slave -> ux_system_slave_device_framework_length = _ux_system_slave -> ux_system_slave_device_framework_length_full_speed;
|
|
}
|
|
/* Save device speed. */
|
|
_ux_system_slave->ux_system_slave_speed = _ux_dcd_sim_slave_speed;
|
|
}
|
|
|
|
/* Get the device framework pointer. */
|
|
device_framework = _ux_system_slave -> ux_system_slave_device_framework;
|
|
|
|
/* And create the decompressed device descriptor structure. */
|
|
_ux_utility_descriptor_parse(device_framework,
|
|
_ux_system_device_descriptor_structure,
|
|
UX_DEVICE_DESCRIPTOR_ENTRIES,
|
|
(UCHAR *) &device -> ux_slave_device_descriptor);
|
|
|
|
/* Now we create a transfer request to accept the first SETUP packet
|
|
and get the ball running. First get the address of the endpoint
|
|
transfer request container. */
|
|
transfer_request = &device -> ux_slave_device_control_endpoint.ux_slave_endpoint_transfer_request;
|
|
|
|
/* Set the timeout to be for Control Endpoint. */
|
|
transfer_request -> ux_slave_transfer_request_timeout = MS_TO_TICK(UX_CONTROL_TRANSFER_TIMEOUT);
|
|
|
|
/* Adjust the current data pointer as well. */
|
|
transfer_request -> ux_slave_transfer_request_current_data_pointer =
|
|
transfer_request -> ux_slave_transfer_request_data_pointer;
|
|
|
|
/* Update the transfer request endpoint pointer with the default endpoint. */
|
|
transfer_request -> ux_slave_transfer_request_endpoint = &device -> ux_slave_device_control_endpoint;
|
|
|
|
/* The control endpoint max packet size needs to be filled manually in its descriptor. */
|
|
transfer_request -> ux_slave_transfer_request_endpoint -> ux_slave_endpoint_descriptor.wMaxPacketSize =
|
|
device -> ux_slave_device_descriptor.bMaxPacketSize0;
|
|
|
|
/* On the control endpoint, always expect the maximum. */
|
|
transfer_request -> ux_slave_transfer_request_requested_length =
|
|
device -> ux_slave_device_descriptor.bMaxPacketSize0;
|
|
|
|
/* Attach the control endpoint to the transfer request. */
|
|
transfer_request -> ux_slave_transfer_request_endpoint = &device -> ux_slave_device_control_endpoint;
|
|
|
|
/* Create the default control endpoint attached to the device.
|
|
Once this endpoint is enabled, the host can then send a setup packet
|
|
The device controller will receive it and will call the setup function
|
|
module. */
|
|
dcd -> ux_slave_dcd_function(dcd, UX_DCD_CREATE_ENDPOINT,
|
|
(VOID *) &device -> ux_slave_device_control_endpoint);
|
|
|
|
/* Ensure the control endpoint is properly reset. */
|
|
device -> ux_slave_device_control_endpoint.ux_slave_endpoint_state = UX_ENDPOINT_RESET;
|
|
|
|
/* A SETUP packet is a DATA IN operation. */
|
|
transfer_request -> ux_slave_transfer_request_phase = UX_TRANSFER_PHASE_DATA_IN;
|
|
|
|
/* We are now ready for the USB device to accept the first packet when connected. */
|
|
return(UX_SUCCESS);
|
|
}
|
|
|
|
static UINT last_function = 0;
|
|
static char *_func_name[] = {
|
|
"",
|
|
"DISABLE_CONTROLLER",
|
|
"GET_PORT_STATUS",
|
|
"ENABLE_PORT",
|
|
"DISABLE_PORT",
|
|
"POWER_ON_PORT",
|
|
"POWER_DOWN_PORT",
|
|
"SUSPEND_PORT",
|
|
"RESUME_PORT",
|
|
"RESET_PORT",
|
|
"GET_FRAME_NUMBER",
|
|
"SET_FRAME_NUMBER",
|
|
"TRANSFER_REQUEST",
|
|
"TRANSFER_ABORT",
|
|
"CREATE_ENDPOINT",
|
|
"DESTROY_ENDPOINT",
|
|
"RESET_ENDPOINT",
|
|
"SET_DEVICE_ADDRESS",
|
|
"ISR_PENDING",
|
|
"CHANGE_STATE",
|
|
"STALL_ENDPOINT",
|
|
"ENDPOINT_STATUS"
|
|
};
|
|
|
|
|
|
|
|
UINT _ux_test_dcd_sim_slave_function(UX_SLAVE_DCD *dcd, UINT function, VOID *parameter)
|
|
{
|
|
|
|
UINT status;
|
|
UX_TEST_OVERRIDE_UX_DCD_SIM_SLAVE_FUNCTION_PARAMS params = { dcd, function, parameter };
|
|
UX_TEST_ACTION action;
|
|
|
|
|
|
/* Perform hooked callbacks. */
|
|
ux_test_do_hooks_before(UX_TEST_OVERRIDE_UX_DCD_SIM_SLAVE_FUNCTION, ¶ms);
|
|
|
|
action = ux_test_action_handler(UX_TEST_OVERRIDE_UX_DCD_SIM_SLAVE_FUNCTION, ¶ms);
|
|
ux_test_do_action_before(&action, ¶ms);
|
|
|
|
/* NOTE: This shouldn't be used anymore. */
|
|
if (ux_test_is_expedient_on())
|
|
{
|
|
if (action.matched && !action.do_after)
|
|
{
|
|
if (!action.no_return)
|
|
{
|
|
return action.status;
|
|
}
|
|
}
|
|
}
|
|
|
|
status = _ux_dcd_sim_slave_function(dcd, function, parameter);
|
|
|
|
ux_test_do_action_after(&action, ¶ms);
|
|
|
|
/* NOTE: This shouldn't be used anymore. */
|
|
if (ux_test_is_expedient_on())
|
|
{
|
|
if (action.matched && action.do_after)
|
|
{
|
|
if (!action.no_return)
|
|
{
|
|
return action.status;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Perform hooked callbacks. */
|
|
ux_test_do_hooks_after(UX_TEST_OVERRIDE_UX_DCD_SIM_SLAVE_FUNCTION, ¶ms);
|
|
|
|
/* Return completion status. */
|
|
return(status);
|
|
}
|
|
|
|
UINT _ux_test_dcd_sim_slave_initialize(VOID)
|
|
{
|
|
UINT status;
|
|
UX_SLAVE_DEVICE *device;
|
|
UX_SLAVE_DCD *dcd;
|
|
|
|
status = _ux_dcd_sim_slave_initialize();
|
|
|
|
/* Redirect the entry function */
|
|
device = &_ux_system_slave -> ux_system_slave_device;
|
|
dcd = &_ux_system_slave -> ux_system_slave_dcd;
|
|
dcd -> ux_slave_dcd_function = _ux_test_dcd_sim_slave_function;
|
|
|
|
return status;
|
|
}
|
|
|
|
VOID ux_test_dcd_sim_slave_transfer_done(UX_SLAVE_TRANSFER *transfer, UINT code)
|
|
{
|
|
UX_SLAVE_ENDPOINT *endpoint = transfer -> ux_slave_transfer_request_endpoint;
|
|
UX_DCD_SIM_SLAVE_ED *slave_ed = (UX_DCD_SIM_SLAVE_ED *)endpoint -> ux_slave_endpoint_ed;
|
|
transfer -> ux_slave_transfer_request_completion_code = code;
|
|
transfer -> ux_slave_transfer_request_status = UX_TRANSFER_STATUS_COMPLETED;
|
|
slave_ed -> ux_sim_slave_ed_status |= UX_DCD_SIM_SLAVE_ED_STATUS_TRANSFER;
|
|
slave_ed -> ux_sim_slave_ed_status |= UX_DCD_SIM_SLAVE_ED_STATUS_DONE;
|
|
_ux_device_semaphore_put(&transfer -> ux_slave_transfer_request_semaphore);
|
|
}
|