From dfb4460f72adebdb045a2d92e39a31df9a503898 Mon Sep 17 00:00:00 2001 From: Yuxin Zhou Date: Sat, 3 Apr 2021 01:05:33 +0000 Subject: [PATCH] Release 6.1.6 --- common/core/inc/ux_api.h | 16 +- common/core/inc/ux_dcd_sim_slave.h | 11 +- common/core/inc/ux_hcd_sim_host.h | 6 +- common/core/inc/ux_user_sample.h | 50 +- .../src/ux_dcd_sim_slave_endpoint_create.c | 15 +- .../src/ux_dcd_sim_slave_endpoint_status.c | 17 +- common/core/src/ux_dcd_sim_slave_initialize.c | 21 +- .../ux_dcd_sim_slave_initialize_complete.c | 24 +- .../core/src/ux_dcd_sim_slave_state_change.c | 26 +- common/core/src/ux_device_stack_get_status.c | 13 +- .../core/src/ux_device_stack_uninitialize.c | 9 +- common/core/src/ux_hcd_sim_host_initialize.c | 21 +- .../src/ux_hcd_sim_host_port_status_get.c | 13 +- .../ux_hcd_sim_host_transaction_schedule.c | 30 +- common/usbx_device_classes/CMakeLists.txt | 2 + .../inc/ux_device_class_audio10.h | 6 +- .../inc/ux_device_class_audio20.h | 6 +- .../inc/ux_device_class_cdc_acm.h | 9 +- .../inc/ux_device_class_dfu.h | 55 +- .../ux_device_class_audio10_control_process.c | 7 +- .../ux_device_class_audio20_control_process.c | 7 +- .../ux_device_class_cdc_acm_bulkin_thread.c | 10 +- .../ux_device_class_cdc_acm_bulkout_thread.c | 10 +- .../src/ux_device_class_cdc_acm_initialize.c | 120 +++- .../src/ux_device_class_cdc_acm_ioctl.c | 135 +--- .../src/ux_device_class_cdc_acm_unitialize.c | 17 +- ...device_class_cdc_acm_write_with_callback.c | 15 +- .../src/ux_device_class_dfu_activate.c | 10 +- .../src/ux_device_class_dfu_control_request.c | 627 +++++++++++++----- .../src/ux_device_class_dfu_deactivate.c | 36 +- .../src/ux_device_class_dfu_initialize.c | 28 +- .../src/ux_device_class_dfu_state_get.c | 73 ++ .../src/ux_device_class_dfu_state_sync.c | 97 +++ .../src/ux_device_class_storage_thread.c | 8 +- .../src/ux_host_class_storage_deactivate.c | 9 +- .../ux_hcd_ehci_interrupt_endpoint_create.c | 13 +- .../ux_hcd_ehci_interrupt_endpoint_destroy.c | 8 +- .../ux_hcd_ehci_isochronous_endpoint_create.c | 15 +- ...ux_hcd_ehci_isochronous_endpoint_destroy.c | 20 +- .../src/ux_hcd_ehci_least_traffic_list_get.c | 8 +- .../ux_hcd_ohci_interrupt_endpoint_create.c | 12 +- .../ux_hcd_ohci_isochronous_endpoint_create.c | 13 +- 42 files changed, 1229 insertions(+), 419 deletions(-) create mode 100644 common/usbx_device_classes/src/ux_device_class_dfu_state_get.c create mode 100644 common/usbx_device_classes/src/ux_device_class_dfu_state_sync.c diff --git a/common/core/inc/ux_api.h b/common/core/inc/ux_api.h index 11969cc7..1aafec18 100755 --- a/common/core/inc/ux_api.h +++ b/common/core/inc/ux_api.h @@ -26,7 +26,7 @@ /* APPLICATION INTERFACE DEFINITION RELEASE */ /* */ /* ux_api.h PORTABLE C */ -/* 6.1.5 */ +/* 6.1.6 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -83,6 +83,10 @@ /* resulting in version 6.1.4 */ /* 03-02-2021 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1.5 */ +/* 04-02-2021 Chaoqiong Xiao Modified comment(s), */ +/* added macros for Word/DWord */ +/* to bytes extraction, */ +/* resulting in version 6.1.6 */ /* */ /**************************************************************************/ @@ -217,7 +221,7 @@ typedef signed char SCHAR; #define AZURE_RTOS_USBX #define USBX_MAJOR_VERSION 6 #define USBX_MINOR_VERSION 1 -#define USBX_PATCH_VERSION 5 +#define USBX_PATCH_VERSION 6 /* Macros for concatenating tokens, where UX_CONCATn concatenates n tokens. */ @@ -233,6 +237,14 @@ typedef signed char SCHAR; #define UX_MIN(a, b) ((a) < (b) ? (a) : (b)) #define UX_MAX(a, b) ((a) > (b) ? (a) : (b)) +#define UX_W0(word) ( (word) & 0xFF) +#define UX_W1(word) (((word) >> 8) & 0xFF) + +#define UX_DW0(dword) ( (dword) & 0xFF) +#define UX_DW1(dword) (((dword) >> 8) & 0xFF) +#define UX_DW2(dword) (((dword) >> 16) & 0xFF) +#define UX_DW3(dword) (((dword) >> 24) & 0xFF) + /* Safe arithmetic check macros. */ #ifndef UX_DISABLE_ARITHMETIC_CHECK diff --git a/common/core/inc/ux_dcd_sim_slave.h b/common/core/inc/ux_dcd_sim_slave.h index f9ebcffe..ae7e4527 100644 --- a/common/core/inc/ux_dcd_sim_slave.h +++ b/common/core/inc/ux_dcd_sim_slave.h @@ -26,7 +26,7 @@ /* COMPONENT DEFINITION RELEASE */ /* */ /* ux_dcd_sim_slave.h PORTABLE C */ -/* 6.1 */ +/* 6.1.6 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -44,6 +44,10 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 04-02-2021 Chaoqiong Xiao Modified comment(s), */ +/* added HCD connected to, */ +/* supported bi-dir-endpoints, */ +/* resulting in version 6.1.6 */ /* */ /**************************************************************************/ @@ -112,7 +116,12 @@ typedef struct UX_DCD_SIM_SLAVE_STRUCT *ux_dcd_sim_slave_dcd_owner; struct UX_DCD_SIM_SLAVE_ED_STRUCT ux_dcd_sim_slave_ed[UX_DCD_SIM_SLAVE_MAX_ED]; +#ifdef UX_DEVICE_BIDIRECTIONAL_ENDPOINT_SUPPORT + struct UX_DCD_SIM_SLAVE_ED_STRUCT + ux_dcd_sim_slave_ed_in[UX_DCD_SIM_SLAVE_MAX_ED]; +#endif UINT (*ux_dcd_sim_slave_dcd_control_request_process_hub)(UX_SLAVE_TRANSFER *transfer_request); + VOID *ux_dcd_sim_slave_hcd; } UX_DCD_SIM_SLAVE; diff --git a/common/core/inc/ux_hcd_sim_host.h b/common/core/inc/ux_hcd_sim_host.h index 8bf78b93..825552c2 100644 --- a/common/core/inc/ux_hcd_sim_host.h +++ b/common/core/inc/ux_hcd_sim_host.h @@ -26,7 +26,7 @@ /* COMPONENT DEFINITION RELEASE */ /* */ /* ux_hcd_sim_host.h PORTABLE C */ -/* 6.1.2 */ +/* 6.1.6 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -51,6 +51,9 @@ /* 11-09-2020 Chaoqiong Xiao Modified comment(s), */ /* added HCD uninitialize, */ /* resulting in version 6.1.2 */ +/* 04-02-2021 Chaoqiong Xiao Modified comment(s), */ +/* added port status variable, */ +/* resulting in version 6.1.6 */ /* */ /**************************************************************************/ @@ -96,6 +99,7 @@ typedef struct UX_HCD_SIM_HOST_STRUCT *ux_hcd_sim_host_hcd_owner; ULONG ux_hcd_sim_host_hcor; UINT ux_hcd_sim_host_nb_root_hubs; + ULONG ux_hcd_sim_host_port_status[1]; struct UX_HCD_SIM_HOST_ED_STRUCT *ux_hcd_sim_host_ed_list; struct UX_HCD_SIM_HOST_TD_STRUCT diff --git a/common/core/inc/ux_user_sample.h b/common/core/inc/ux_user_sample.h index ea139cf8..81421478 100644 --- a/common/core/inc/ux_user_sample.h +++ b/common/core/inc/ux_user_sample.h @@ -26,7 +26,7 @@ /* PORT SPECIFIC C INFORMATION RELEASE */ /* */ /* ux_user.h PORTABLE C */ -/* 6.1.4 */ +/* 6.1.6 */ /* */ /* AUTHOR */ /* */ @@ -51,6 +51,13 @@ /* compile option for using */ /* packet pool from NetX, */ /* resulting in version 6.1.4 */ +/* 04-02-2021 Chaoqiong Xiao Modified comment(s), */ +/* added DFU_UPLOAD option, */ +/* added macro to enable */ +/* device bi-dir-endpoints, */ +/* added macro to disable CDC- */ +/* ACM transmission support, */ +/* resulting in version 6.1.6 */ /* */ /**************************************************************************/ @@ -292,6 +299,47 @@ /* #define UX_DEVICE_CLASS_HID_MAX_EVENTS_QUEUE 8 */ + +/* Defined, this macro will disable DFU_UPLOAD support. */ + +/* #define UX_DEVICE_CLASS_DFU_UPLOAD_DISABLE */ + +/* Defined, this macro will enable DFU_GETSTATUS and DFU_GETSTATE in dfuERROR. */ + +/* #define UX_DEVICE_CLASS_DFU_ERROR_GET_ENABLE */ + +/* Defined, this macro will change status mode. + 0 - simple mode, + status is queried from application in dfuDNLOAD-SYNC and dfuMANIFEST-SYNC state, + no bwPollTimeout. + 1 - status is queried from application once requested, + b0-3 : media status + b4-7 : bStatus + b8-31: bwPollTimeout + bwPollTimeout supported. +*/ + +/* #define UX_DEVICE_CLASS_DFU_STATUS_MODE (1) */ + +/* Defined, this value represents the default DFU status bwPollTimeout. + The value is 3 bytes long (max 0xFFFFFFu). + By default the bwPollTimeout is 1 (means 1ms). + */ + +/* #define UX_DEVICE_CLASS_DFU_STATUS_POLLTIMEOUT (1) */ + +/* Defined, this macro will enable custom request process callback. */ + +/* #define UX_DEVICE_CLASS_DFU_CUSTOM_REQUEST_ENABLE */ + +/* Defined, this macro disables CDC ACM non-blocking transmission support. */ + +/* #define UX_DEVICE_CLASS_CDC_ACM_TRANSMISSION_DISABLE */ + +/* Defined, this macro enables device bi-directional-endpoint support. */ + +/* #define UX_DEVICE_BIDIRECTIONAL_ENDPOINT_SUPPORT */ + /* Defined, this value will only enable the host side of usbx. */ /* #define UX_HOST_SIDE_ONLY */ diff --git a/common/core/src/ux_dcd_sim_slave_endpoint_create.c b/common/core/src/ux_dcd_sim_slave_endpoint_create.c index 912d5bfc..e73c10f9 100644 --- a/common/core/src/ux_dcd_sim_slave_endpoint_create.c +++ b/common/core/src/ux_dcd_sim_slave_endpoint_create.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_dcd_sim_slave_endpoint_create PORTABLE C */ -/* 6.1 */ +/* 6.1.6 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -67,6 +67,9 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 04-02-2021 Chaoqiong Xiao Modified comment(s), */ +/* supported bi-dir-endpoints, */ +/* resulting in version 6.1.6 */ /* */ /**************************************************************************/ UINT _ux_dcd_sim_slave_endpoint_create(UX_DCD_SIM_SLAVE *dcd_sim_slave, UX_SLAVE_ENDPOINT *endpoint) @@ -79,9 +82,17 @@ ULONG sim_slave_endpoint_index; /* The simulator slave controller has 16 endpoints maximum. Endpoint 0 is always control. The other endpoints are generic. We can use the endpoint number as an index. */ sim_slave_endpoint_index = endpoint ->ux_slave_endpoint_descriptor.bEndpointAddress & ~(ULONG)UX_ENDPOINT_DIRECTION; - + /* Fetch the address of the physical endpoint. */ +#ifdef UX_DEVICE_BIDIRECTIONAL_ENDPOINT_SUPPORT + ed = ((endpoint -> ux_slave_endpoint_descriptor.bEndpointAddress == 0) ? + &dcd_sim_slave -> ux_dcd_sim_slave_ed[0] : + ((endpoint -> ux_slave_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION) ? + &dcd_sim_slave -> ux_dcd_sim_slave_ed_in[sim_slave_endpoint_index] : + &dcd_sim_slave -> ux_dcd_sim_slave_ed[sim_slave_endpoint_index])); +#else ed = &dcd_sim_slave -> ux_dcd_sim_slave_ed[sim_slave_endpoint_index]; +#endif /* Check the endpoint status, if it is free, reserve it. If not reject this endpoint. */ if ((ed -> ux_sim_slave_ed_status & UX_DCD_SIM_SLAVE_ED_STATUS_USED) == 0) diff --git a/common/core/src/ux_dcd_sim_slave_endpoint_status.c b/common/core/src/ux_dcd_sim_slave_endpoint_status.c index a8b5c69c..eec691af 100644 --- a/common/core/src/ux_dcd_sim_slave_endpoint_status.c +++ b/common/core/src/ux_dcd_sim_slave_endpoint_status.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_dcd_sim_slave_endpoint_status PORTABLE C */ -/* 6.1 */ +/* 6.1.6 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -67,6 +67,9 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 04-02-2021 Chaoqiong Xiao Modified comment(s), */ +/* supported bi-dir-endpoints, */ +/* resulting in version 6.1.6 */ /* */ /**************************************************************************/ UINT _ux_dcd_sim_slave_endpoint_status(UX_DCD_SIM_SLAVE *dcd_sim_slave, ULONG endpoint_index) @@ -75,8 +78,20 @@ UINT _ux_dcd_sim_slave_endpoint_status(UX_DCD_SIM_SLAVE *dcd_sim_slave, ULONG e UX_DCD_SIM_SLAVE_ED *ed; +#ifdef UX_DEVICE_BIDIRECTIONAL_ENDPOINT_SUPPORT +ULONG ed_addr = endpoint_index; /* Passed value as endpoint address. */ +ULONG ed_dir = ed_addr & UX_ENDPOINT_DIRECTION; +ULONG ed_index = ed_addr & ~UX_ENDPOINT_DIRECTION; + + /* Fetch the address of the physical endpoint. */ + ed = ((ed_addr == 0) ? &dcd_sim_slave -> ux_dcd_sim_slave_ed[0] : + ((ed_dir) ? &dcd_sim_slave -> ux_dcd_sim_slave_ed_in[ed_index] : + &dcd_sim_slave -> ux_dcd_sim_slave_ed[ed_index])); +#else + /* Fetch the address of the physical endpoint. */ ed = &dcd_sim_slave -> ux_dcd_sim_slave_ed[endpoint_index]; +#endif /* Check the endpoint status, if it is free, we have a illegal endpoint. */ if ((ed -> ux_sim_slave_ed_status & UX_DCD_SIM_SLAVE_ED_STATUS_USED) == 0) diff --git a/common/core/src/ux_dcd_sim_slave_initialize.c b/common/core/src/ux_dcd_sim_slave_initialize.c index febc3bfd..7af4aa30 100644 --- a/common/core/src/ux_dcd_sim_slave_initialize.c +++ b/common/core/src/ux_dcd_sim_slave_initialize.c @@ -27,6 +27,7 @@ #include "ux_api.h" #include "ux_dcd_sim_slave.h" +#include "ux_hcd_sim_host.h" /**************************************************************************/ @@ -34,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_dcd_sim_slave_initialize PORTABLE C */ -/* 6.1 */ +/* 6.1.6 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -66,6 +67,10 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 04-02-2021 Chaoqiong Xiao Modified comment(s), */ +/* added link with HCD, */ +/* set device to full speed, */ +/* resulting in version 6.1.6 */ /* */ /**************************************************************************/ UINT _ux_dcd_sim_slave_initialize(VOID) @@ -73,6 +78,7 @@ UINT _ux_dcd_sim_slave_initialize(VOID) UX_SLAVE_DCD *dcd; UX_DCD_SIM_SLAVE *dcd_sim_slave; +UX_HCD *hcd; /* Get the pointer to the DCD. */ @@ -97,6 +103,19 @@ UX_DCD_SIM_SLAVE *dcd_sim_slave; /* Initialize the function collector for this DCD. */ dcd -> ux_slave_dcd_function = _ux_dcd_sim_slave_function; + /* Link the HCD (always first registered one) to DCD driver. */ + if (_ux_system_host) + { + hcd = _ux_system_host -> ux_system_host_hcd_array; + if (hcd) + { + dcd_sim_slave -> ux_dcd_sim_slave_hcd = (VOID *)hcd; + } + } + + /* Set system to full speed by default. */ + _ux_system_slave -> ux_system_slave_speed = UX_FULL_SPEED_DEVICE; + /* Set the state of the controller to OPERATIONAL now. */ dcd -> ux_slave_dcd_status = UX_DCD_STATUS_OPERATIONAL; diff --git a/common/core/src/ux_dcd_sim_slave_initialize_complete.c b/common/core/src/ux_dcd_sim_slave_initialize_complete.c index 820dad51..f2d0dca4 100644 --- a/common/core/src/ux_dcd_sim_slave_initialize_complete.c +++ b/common/core/src/ux_dcd_sim_slave_initialize_complete.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_dcd_sim_slave_initialize_complete PORTABLE C */ -/* 6.1 */ +/* 6.1.6 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -69,6 +69,9 @@ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* prefixed UX to MS_TO_TICK, */ /* resulting in version 6.1 */ +/* 04-02-2021 Chaoqiong Xiao Modified comment(s), */ +/* added framework init cases, */ +/* resulting in version 6.1.6 */ /* */ /**************************************************************************/ UINT _ux_dcd_sim_slave_initialize_complete(VOID) @@ -86,9 +89,22 @@ UX_SLAVE_TRANSFER *transfer_request; /* Get the pointer to the device. */ device = &_ux_system_slave -> ux_system_slave_device; - /* Slave simulator is a Full speed controller. */ - _ux_system_slave -> ux_system_slave_device_framework = _ux_system_slave -> ux_system_slave_device_framework_full_speed; - _ux_system_slave -> ux_system_slave_device_framework_length = _ux_system_slave -> ux_system_slave_device_framework_length_full_speed; + /* Prepare according to speed. */ + if (_ux_system_slave -> ux_system_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; + + } /* Get the device framework pointer. */ device_framework = _ux_system_slave -> ux_system_slave_device_framework; diff --git a/common/core/src/ux_dcd_sim_slave_state_change.c b/common/core/src/ux_dcd_sim_slave_state_change.c index 4ed8e3cb..0b0bf152 100644 --- a/common/core/src/ux_dcd_sim_slave_state_change.c +++ b/common/core/src/ux_dcd_sim_slave_state_change.c @@ -27,6 +27,7 @@ #include "ux_api.h" #include "ux_dcd_sim_slave.h" +#include "ux_hcd_sim_host.h" /**************************************************************************/ @@ -34,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_dcd_sim_slave_state_change PORTABLE C */ -/* 6.1 */ +/* 6.1.6 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -68,14 +69,35 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 04-02-2021 Chaoqiong Xiao Modified comment(s), */ +/* simulate force disconnect, */ +/* resulting in version 6.1.6 */ /* */ /**************************************************************************/ UINT _ux_dcd_sim_slave_state_change(UX_DCD_SIM_SLAVE *dcd_sim_slave, ULONG state) { - UX_PARAMETER_NOT_USED(dcd_sim_slave); +UX_HCD *hcd; + + UX_PARAMETER_NOT_USED(state); + if (state == UX_DEVICE_FORCE_DISCONNECT) + { + + /* Simulate port detach & attach on host side. */ + + /* Get HCD. */ + hcd = (UX_HCD *)dcd_sim_slave -> ux_dcd_sim_slave_hcd; + + /* Something happened on this port. Signal it to the root hub thread. */ + if (hcd) + { + hcd -> ux_hcd_root_hub_signal[0] = 2; + _ux_utility_semaphore_put(&_ux_system_host -> ux_system_host_enum_semaphore); + } + } + /* Nothing to do in simulation mode. */ return(UX_SUCCESS); } diff --git a/common/core/src/ux_device_stack_get_status.c b/common/core/src/ux_device_stack_get_status.c index 8eb364df..73293f12 100644 --- a/common/core/src/ux_device_stack_get_status.c +++ b/common/core/src/ux_device_stack_get_status.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_stack_get_status PORTABLE C */ -/* 6.1 */ +/* 6.1.6 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -70,6 +70,9 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 04-02-2021 Chaoqiong Xiao Modified comment(s), */ +/* supported bi-dir-endpoints, */ +/* resulting in version 6.1.6 */ /* */ /**************************************************************************/ UINT _ux_device_stack_get_status(ULONG request_type, ULONG request_index, ULONG request_length) @@ -143,9 +146,17 @@ ULONG data_length; case UX_REQUEST_TARGET_ENDPOINT: +#ifndef UX_DEVICE_BIDIRECTIONAL_ENDPOINT_SUPPORT + /* This feature returns the halt state of a specific endpoint. The endpoint index is used to retrieve the endpoint container. */ status = dcd -> ux_slave_dcd_function(dcd, UX_DCD_ENDPOINT_STATUS, (VOID *)(ALIGN_TYPE)(request_index & (UINT)~UX_ENDPOINT_DIRECTION)); +#else + + /* This feature returns the halt state of a specific endpoint. The endpoint address + is used to retrieve the endpoint container. */ + status = dcd -> ux_slave_dcd_function(dcd, UX_DCD_ENDPOINT_STATUS, (VOID *)(ALIGN_TYPE)(request_index)); +#endif /* Check the status. We may have a unknown endpoint. */ if (status != UX_ERROR) diff --git a/common/core/src/ux_device_stack_uninitialize.c b/common/core/src/ux_device_stack_uninitialize.c index 71258eec..6d163e26 100644 --- a/common/core/src/ux_device_stack_uninitialize.c +++ b/common/core/src/ux_device_stack_uninitialize.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_stack_uninitialize PORTABLE C */ -/* 6.1 */ +/* 6.1.6 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -65,6 +65,10 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 04-02-2021 Chaoqiong Xiao Modified comment(s), */ +/* fixed uninitialize in case */ +/* there is no EP except EP0, */ +/* resulting in version 6.1.6 */ /* */ /**************************************************************************/ UINT _ux_device_stack_uninitialize(VOID) @@ -110,7 +114,8 @@ ULONG endpoints_found; } /* Free the endpoint pool address in the device container. */ - _ux_utility_memory_free(device -> ux_slave_device_endpoints_pool); + if (device -> ux_slave_device_endpoints_pool) + _ux_utility_memory_free(device -> ux_slave_device_endpoints_pool); /* Free memory for interface pool. */ _ux_utility_memory_free(device -> ux_slave_device_interfaces_pool); diff --git a/common/core/src/ux_hcd_sim_host_initialize.c b/common/core/src/ux_hcd_sim_host_initialize.c index c385e751..ed1cf88f 100644 --- a/common/core/src/ux_hcd_sim_host_initialize.c +++ b/common/core/src/ux_hcd_sim_host_initialize.c @@ -27,6 +27,7 @@ #include "ux_api.h" #include "ux_hcd_sim_host.h" +#include "ux_dcd_sim_slave.h" /**************************************************************************/ @@ -34,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_hcd_sim_host_initialize PORTABLE C */ -/* 6.1 */ +/* 6.1.6 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -74,11 +75,16 @@ /* instead of using them */ /* directly, */ /* resulting in version 6.1 */ +/* 04-02-2021 Chaoqiong Xiao Modified comment(s), */ +/* added link with DCD, */ +/* resulting in version 6.1.6 */ /* */ /**************************************************************************/ UINT _ux_hcd_sim_host_initialize(UX_HCD *hcd) { +UX_SLAVE_DCD *dcd; +UX_DCD_SIM_SLAVE *dcd_sim_slave; UX_HCD_SIM_HOST *hcd_sim_host; UINT status; @@ -176,11 +182,24 @@ UINT status; return(status); } + /* Link the HCD to DCD driver. */ + if (_ux_system_slave) + { + dcd = &_ux_system_slave -> ux_system_slave_dcd; + if (dcd) + { + dcd_sim_slave = (UX_DCD_SIM_SLAVE *) dcd -> ux_slave_dcd_controller_hardware; + if (dcd_sim_slave) + dcd_sim_slave -> ux_dcd_sim_slave_hcd = (VOID *)hcd; + } + } + /* Get the number of ports on the controller. The number of ports needs to be reflected both for the generic HCD container and the local sim_host container. In the simulator, the number of ports is hardwired to 1 only. */ hcd -> ux_hcd_nb_root_hubs = 1; hcd_sim_host -> ux_hcd_sim_host_nb_root_hubs = 1; + hcd_sim_host -> ux_hcd_sim_host_port_status[0] = UX_PS_CCS | UX_PS_DS_FS; /* Something happened on this port. Signal it to the root hub thread. */ hcd -> ux_hcd_root_hub_signal[0] = 1; diff --git a/common/core/src/ux_hcd_sim_host_port_status_get.c b/common/core/src/ux_hcd_sim_host_port_status_get.c index 8c32526b..8711e5f2 100644 --- a/common/core/src/ux_hcd_sim_host_port_status_get.c +++ b/common/core/src/ux_hcd_sim_host_port_status_get.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_hcd_sim_host_port_status_get PORTABLE C */ -/* 6.1 */ +/* 6.1.6 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -93,6 +93,9 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 04-02-2021 Chaoqiong Xiao Modified comment(s), */ +/* used changeable status, */ +/* resulting in version 6.1.6 */ /* */ /**************************************************************************/ ULONG _ux_hcd_sim_host_port_status_get(UX_HCD_SIM_HOST *hcd_sim_host, ULONG port_index) @@ -114,12 +117,8 @@ ULONG port_status; return(UX_PORT_INDEX_UNKNOWN); } - /* The port is valid, build the status mask for this port. This function - returns always returned a device connected. */ - port_status = UX_PS_CCS; - - /* And this is a Full speed device. */ - port_status |= UX_PS_DS_FS; + /* Returns current port status. */ + port_status = hcd_sim_host -> ux_hcd_sim_host_port_status[port_index]; /* Return port status. */ return(port_status); diff --git a/common/core/src/ux_hcd_sim_host_transaction_schedule.c b/common/core/src/ux_hcd_sim_host_transaction_schedule.c index 58e61271..023de418 100644 --- a/common/core/src/ux_hcd_sim_host_transaction_schedule.c +++ b/common/core/src/ux_hcd_sim_host_transaction_schedule.c @@ -36,7 +36,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_hcd_sim_host_transaction_schedule PORTABLE C */ -/* 6.1 */ +/* 6.1.6 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -77,6 +77,10 @@ /* verified memset and memcpy */ /* cases, */ /* resulting in version 6.1 */ +/* 04-02-2021 Chaoqiong Xiao Modified comment(s), */ +/* fixed control OUT transfer, */ +/* supported bi-dir-endpoints, */ +/* resulting in version 6.1.6 */ /* */ /**************************************************************************/ UINT _ux_hcd_sim_host_transaction_schedule(UX_HCD_SIM_HOST *hcd_sim_host, UX_HCD_SIM_HOST_ED *ed) @@ -94,6 +98,7 @@ ULONG slave_transfer_remaining; UCHAR wake_host; UCHAR wake_slave; ULONG transaction_length; +ULONG td_length; UX_SLAVE_TRANSFER *slave_transfer_request; UX_TRANSFER *transfer_request; ULONG endpoint_index; @@ -124,7 +129,15 @@ UX_SLAVE_DCD *dcd; dcd_sim_slave = (UX_DCD_SIM_SLAVE *) dcd -> ux_slave_dcd_controller_hardware; /* Get the endpoint as seen from the device side. */ +#ifdef UX_DEVICE_BIDIRECTIONAL_ENDPOINT_SUPPORT + slave_ed = ((endpoint -> ux_endpoint_descriptor.bEndpointAddress == 0) ? + &dcd_sim_slave -> ux_dcd_sim_slave_ed[0] : + ((endpoint -> ux_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION) ? + &dcd_sim_slave -> ux_dcd_sim_slave_ed_in[endpoint_index] : + &dcd_sim_slave -> ux_dcd_sim_slave_ed[endpoint_index])); +#else slave_ed = &dcd_sim_slave -> ux_dcd_sim_slave_ed[endpoint_index]; +#endif /* Is this ED used? */ if ((slave_ed -> ux_sim_slave_ed_status & UX_DCD_SIM_SLAVE_ED_STATUS_USED) == 0) @@ -155,7 +168,8 @@ UX_SLAVE_DCD *dcd; slave_transfer_request -> ux_slave_transfer_request_actual_length = td -> ux_sim_host_td_length; /* Move the buffer from the host TD to the device TD. */ - _ux_utility_memory_copy(slave_transfer_request -> ux_slave_transfer_request_setup, td -> ux_sim_host_td_buffer, + _ux_utility_memory_copy(slave_transfer_request -> ux_slave_transfer_request_setup, + td -> ux_sim_host_td_buffer, td -> ux_sim_host_td_length); /* Use case of memcpy is verified. */ /* The setup phase never fails. We acknowledge the transfer code here by taking the TD out of the endpoint. */ @@ -202,20 +216,22 @@ UX_SLAVE_DCD *dcd; { /* Copy the amount of data in the td into the slave transaction buffer. */ - _ux_utility_memory_copy(slave_transfer_request -> ux_slave_transfer_request_current_data_pointer, data_td -> ux_sim_host_td_buffer, - data_td -> ux_sim_host_td_length); /* Use case of memcpy is verified. */ + td_length = UX_MIN(data_td -> ux_sim_host_td_length, transaction_length); + _ux_utility_memory_copy(slave_transfer_request -> ux_slave_transfer_request_current_data_pointer, + data_td -> ux_sim_host_td_buffer, + td_length); /* Use case of memcpy is verified. */ /* Add to the actual payload length. */ - slave_transfer_request -> ux_slave_transfer_request_actual_length += data_td -> ux_sim_host_td_length; + slave_transfer_request -> ux_slave_transfer_request_actual_length += td_length; /* Update the host transfer's actual length. */ transfer_request -> ux_transfer_request_actual_length += transaction_length; /* Decrement the total length. */ - transaction_length -= data_td -> ux_sim_host_td_length; + transaction_length -= td_length; /* Update buffer pointer. */ - slave_transfer_request -> ux_slave_transfer_request_current_data_pointer += data_td -> ux_sim_host_td_length; + slave_transfer_request -> ux_slave_transfer_request_current_data_pointer += td_length; /* Update the td in the head. */ ed -> ux_sim_host_ed_head_td = data_td; diff --git a/common/usbx_device_classes/CMakeLists.txt b/common/usbx_device_classes/CMakeLists.txt index 10f99967..0cf623a6 100644 --- a/common/usbx_device_classes/CMakeLists.txt +++ b/common/usbx_device_classes/CMakeLists.txt @@ -52,6 +52,8 @@ target_sources(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_dfu_deactivate.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_dfu_entry.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_dfu_initialize.c + ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_dfu_state_get.c + ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_dfu_state_sync.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_dfu_thread.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_hid_activate.c ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_hid_control_request.c diff --git a/common/usbx_device_classes/inc/ux_device_class_audio10.h b/common/usbx_device_classes/inc/ux_device_class_audio10.h index add1f9e8..e03003f3 100644 --- a/common/usbx_device_classes/inc/ux_device_class_audio10.h +++ b/common/usbx_device_classes/inc/ux_device_class_audio10.h @@ -26,7 +26,7 @@ /* COMPONENT DEFINITION RELEASE */ /* */ /* ux_device_class_audio10.h PORTABLE C */ -/* 6.1 */ +/* 6.1.6 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -43,6 +43,9 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 04-02-2021 Chaoqiong Xiao Modified comment(s), */ +/* added volume RES support, */ +/* resulting in version 6.1.6 */ /* */ /**************************************************************************/ @@ -341,6 +344,7 @@ typedef struct UX_DEVICE_CLASS_AUDIO10_CONTROL_STRUCT USHORT ux_device_class_audio10_control_mute[1]; SHORT ux_device_class_audio10_control_volume_min[1]; SHORT ux_device_class_audio10_control_volume_max[1]; + USHORT ux_device_class_audio10_control_volume_res[1]; SHORT ux_device_class_audio10_control_volume[1]; } UX_DEVICE_CLASS_AUDIO10_CONTROL; diff --git a/common/usbx_device_classes/inc/ux_device_class_audio20.h b/common/usbx_device_classes/inc/ux_device_class_audio20.h index f55df762..058657d1 100644 --- a/common/usbx_device_classes/inc/ux_device_class_audio20.h +++ b/common/usbx_device_classes/inc/ux_device_class_audio20.h @@ -26,7 +26,7 @@ /* COMPONENT DEFINITION RELEASE */ /* */ /* ux_device_class_audio20.h PORTABLE C */ -/* 6.1 */ +/* 6.1.6 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -43,6 +43,9 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 04-02-2021 Chaoqiong Xiao Modified comment(s), */ +/* added volume RES support, */ +/* resulting in version 6.1.6 */ /* */ /**************************************************************************/ @@ -398,6 +401,7 @@ typedef struct UX_DEVICE_CLASS_AUDIO20_CONTROL_STRUCT USHORT ux_device_class_audio20_control_mute[1]; SHORT ux_device_class_audio20_control_volume_min[1]; SHORT ux_device_class_audio20_control_volume_max[1]; + USHORT ux_device_class_audio20_control_volume_res[1]; SHORT ux_device_class_audio20_control_volume[1]; } UX_DEVICE_CLASS_AUDIO20_CONTROL; diff --git a/common/usbx_device_classes/inc/ux_device_class_cdc_acm.h b/common/usbx_device_classes/inc/ux_device_class_cdc_acm.h index 3934fc94..eb8840c8 100644 --- a/common/usbx_device_classes/inc/ux_device_class_cdc_acm.h +++ b/common/usbx_device_classes/inc/ux_device_class_cdc_acm.h @@ -24,7 +24,7 @@ /* COMPONENT DEFINITION RELEASE */ /* */ /* ux_device_class_cdc_acm.h PORTABLE C */ -/* 6.1 */ +/* 6.1.6 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -44,6 +44,10 @@ /* TX symbols instead of using */ /* them directly, */ /* resulting in version 6.1 */ +/* 04-02-2021 Chaoqiong Xiao Modified comment(s), */ +/* added macro to disable */ +/* transmission support, */ +/* resulting in version 6.1.6 */ /* */ /**************************************************************************/ @@ -150,6 +154,7 @@ typedef struct UX_SLAVE_CLASS_CDC_ACM_STRUCT UCHAR ux_slave_class_cdc_acm_data_bit; UCHAR ux_slave_class_cdc_acm_data_dtr_state; UCHAR ux_slave_class_cdc_acm_data_rts_state; +#ifndef UX_DEVICE_CLASS_CDC_ACM_TRANSMISSION_DISABLE UX_THREAD ux_slave_class_cdc_acm_bulkin_thread; UX_THREAD ux_slave_class_cdc_acm_bulkout_thread; UCHAR *ux_slave_class_cdc_acm_bulkin_thread_stack; @@ -162,7 +167,7 @@ typedef struct UX_SLAVE_CLASS_CDC_ACM_STRUCT ULONG ux_slave_class_cdc_acm_callback_total_length; UCHAR *ux_slave_class_cdc_acm_callback_data_pointer; UCHAR *ux_slave_class_cdc_acm_callback_current_data_pointer; - +#endif } UX_SLAVE_CLASS_CDC_ACM; /* Define some CDC Class structures */ diff --git a/common/usbx_device_classes/inc/ux_device_class_dfu.h b/common/usbx_device_classes/inc/ux_device_class_dfu.h index 10e3985a..16ffde8a 100644 --- a/common/usbx_device_classes/inc/ux_device_class_dfu.h +++ b/common/usbx_device_classes/inc/ux_device_class_dfu.h @@ -24,7 +24,7 @@ /* COMPONENT DEFINITION RELEASE */ /* */ /* ux_device_class_dfu.h PORTABLE C */ -/* 6.1 */ +/* 6.1.6 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -44,6 +44,12 @@ /* TX symbols instead of using */ /* them directly, */ /* resulting in version 6.1 */ +/* 04-02-2021 Chaoqiong Xiao Modified comment(s), */ +/* added DFU_UPLOAD support, */ +/* refined dfu_read prototype, */ +/* removed block count (it's */ +/* from host request wValue), */ +/* resulting in version 6.1.6 */ /* */ /**************************************************************************/ @@ -115,14 +121,37 @@ #define UX_SLAVE_CLASS_DFU_GET_STATUS_STRING 5 #define UX_SLAVE_CLASS_DFU_GET_STATUS_LENGTH 6 +/* Status mode for DFU_GETSTATUS + 0 - simple mode, + status is queried from application in dfuDNLOAD-SYNC and dfuMANIFEST-SYNC state, + no bwPollTimeout. + 1 - status is queried from application once requested, + b0-3 : media status + b4-7 : bStatus + b8-31: bwPollTimeout + bwPollTimeout supported. +*/ +#ifndef UX_DEVICE_CLASS_DFU_STATUS_MODE +#define UX_DEVICE_CLASS_DFU_STATUS_MODE (0) +#endif + +/* Status mode 0 bwPollTimeout (width: 3 bytes, ~0xFFFFFF). */ +#ifndef UX_DEVICE_CLASS_DFU_STATUS_POLLTIMEOUT +#define UX_DEVICE_CLASS_DFU_STATUS_POLLTIMEOUT (1) +#endif + + /* Define DFU class GET_STATE command response. */ #define UX_SLAVE_CLASS_DFU_GET_STATE_STATE 0 #define UX_SLAVE_CLASS_DFU_GET_STATE_LENGTH 1 /* Define DFU application notification signals. */ -#define UX_SLAVE_CLASS_DFU_NOTIFICATION_BEGIN_DOWNLOAD 1 -#define UX_SLAVE_CLASS_DFU_NOTIFICATION_END_DOWNLOAD 2 -#define UX_SLAVE_CLASS_DFU_NOTIFICATION_ABORT_DOWNLOAD 3 +#define UX_SLAVE_CLASS_DFU_NOTIFICATION_BEGIN_DOWNLOAD 0x1u +#define UX_SLAVE_CLASS_DFU_NOTIFICATION_END_DOWNLOAD 0x2u +#define UX_SLAVE_CLASS_DFU_NOTIFICATION_ABORT_DOWNLOAD 0x3u +#define UX_SLAVE_CLASS_DFU_NOTIFICATION_BEGIN_UPLOAD 0x5u +#define UX_SLAVE_CLASS_DFU_NOTIFICATION_END_UPLOAD 0x6u +#define UX_SLAVE_CLASS_DFU_NOTIFICATION_ABORT_UPLOAD 0x7u /* Define DFU application notification signals. */ #define UX_SLAVE_CLASS_DFU_MEDIA_STATUS_OK 0 @@ -142,10 +171,13 @@ typedef struct UX_SLAVE_CLASS_DFU_PARAMETER_STRUCT ULONG ux_slave_class_dfu_parameter_capabilities; VOID (*ux_slave_class_dfu_parameter_instance_activate)(VOID *); VOID (*ux_slave_class_dfu_parameter_instance_deactivate)(VOID *); - UINT (*ux_slave_class_dfu_parameter_read)(VOID *dfu, ULONG block_number, UCHAR * data_pointer, ULONG length, ULONG *media_status); + UINT (*ux_slave_class_dfu_parameter_read)(VOID *dfu, ULONG block_number, UCHAR * data_pointer, ULONG length, ULONG *actual_length); UINT (*ux_slave_class_dfu_parameter_write)(VOID *dfu, ULONG block_number, UCHAR * data_pointer, ULONG length, ULONG *media_status); UINT (*ux_slave_class_dfu_parameter_get_status)(VOID *dfu, ULONG *media_status); UINT (*ux_slave_class_dfu_parameter_notify)(VOID *dfu, ULONG notification); +#ifdef UX_DEVICE_CLASS_DFU_CUSTOM_REQUEST_ENABLE + UINT (*ux_device_class_dfu_parameter_custom_request)(VOID *dfu, UX_SLAVE_TRANSFER *transfer); +#endif UCHAR *ux_slave_class_dfu_parameter_framework; ULONG ux_slave_class_dfu_parameter_framework_length; @@ -157,15 +189,15 @@ typedef struct UX_SLAVE_CLASS_DFU_STRUCT { UX_SLAVE_INTERFACE *ux_slave_class_dfu_interface; ULONG ux_slave_class_dfu_status; - ULONG ux_slave_class_dfu_state; VOID (*ux_slave_class_dfu_instance_activate)(VOID *); VOID (*ux_slave_class_dfu_instance_deactivate)(VOID *); - UINT (*ux_slave_class_dfu_read)(VOID *dfu, ULONG block_number, UCHAR * data_pointer, ULONG length, ULONG *media_status); + UINT (*ux_slave_class_dfu_read)(VOID *dfu, ULONG block_number, UCHAR * data_pointer, ULONG length, ULONG *actual_length); UINT (*ux_slave_class_dfu_write)(VOID *dfu, ULONG block_number, UCHAR * data_pointer, ULONG length, ULONG *media_status); UINT (*ux_slave_class_dfu_get_status)(VOID *dfu, ULONG *media_status); UINT (*ux_slave_class_dfu_notify)(VOID *dfu, ULONG notification); - ULONG ux_slave_class_dfu_download_block_count; - ULONG ux_slave_class_dfu_upload_block_count; +#ifdef UX_DEVICE_CLASS_DFU_CUSTOM_REQUEST_ENABLE + UINT (*ux_device_class_dfu_custom_request)(VOID *dfu, UX_SLAVE_TRANSFER *transfer); +#endif UX_THREAD ux_slave_class_dfu_thread; UCHAR *ux_slave_class_dfu_thread_stack; UX_EVENT_FLAGS_GROUP ux_slave_class_dfu_event_flags_group; @@ -181,8 +213,13 @@ UINT _ux_device_class_dfu_entry(UX_SLAVE_CLASS_COMMAND *command); UINT _ux_device_class_dfu_initialize(UX_SLAVE_CLASS_COMMAND *command); VOID _ux_device_class_dfu_thread(ULONG dfu_class); +UCHAR _ux_device_class_dfu_state_get(UX_SLAVE_CLASS_DFU *dfu); +VOID _ux_device_class_dfu_state_sync(UX_SLAVE_CLASS_DFU *dfu); + /* Define Device DFU Class API prototypes. */ #define ux_device_class_dfu_entry _ux_device_class_dfu_entry +#define ux_device_class_dfu_state_get _ux_device_class_dfu_state_get +#define ux_device_class_dfu_state_sync _ux_device_class_dfu_state_sync #endif /* UX_DEVICE_CLASS_DFU_H */ diff --git a/common/usbx_device_classes/src/ux_device_class_audio10_control_process.c b/common/usbx_device_classes/src/ux_device_class_audio10_control_process.c index 0e32334d..f8091bae 100644 --- a/common/usbx_device_classes/src/ux_device_class_audio10_control_process.c +++ b/common/usbx_device_classes/src/ux_device_class_audio10_control_process.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_audio10_control_process PORTABLE C */ -/* 6.1 */ +/* 6.1.6 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -75,6 +75,9 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 04-02-2021 Chaoqiong Xiao Modified comment(s), */ +/* added volume RES support, */ +/* resulting in version 6.1.6 */ /* */ /**************************************************************************/ UINT _ux_device_class_audio10_control_process(UX_DEVICE_CLASS_AUDIO *audio, @@ -208,7 +211,7 @@ ULONG i; _ux_utility_short_put(transfer -> ux_slave_transfer_request_data_pointer, (USHORT) (request == UX_DEVICE_CLASS_AUDIO10_GET_MIN ? control -> ux_device_class_audio10_control_volume_min[0] : (request == UX_DEVICE_CLASS_AUDIO10_GET_MAX ? control -> ux_device_class_audio10_control_volume_max[0] : - (request == UX_DEVICE_CLASS_AUDIO10_GET_RES ? 0x0001 : + (request == UX_DEVICE_CLASS_AUDIO10_GET_RES ? UX_MAX(1, control -> ux_device_class_audio10_control_volume_res[0]) : control -> ux_device_class_audio10_control_volume[0])))); _ux_device_stack_transfer_request(transfer, 2, request_length); diff --git a/common/usbx_device_classes/src/ux_device_class_audio20_control_process.c b/common/usbx_device_classes/src/ux_device_class_audio20_control_process.c index a5b92f47..20fb743c 100644 --- a/common/usbx_device_classes/src/ux_device_class_audio20_control_process.c +++ b/common/usbx_device_classes/src/ux_device_class_audio20_control_process.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_audio20_control_process PORTABLE C */ -/* 6.1 */ +/* 6.1.6 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -76,6 +76,9 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 04-02-2021 Chaoqiong Xiao Modified comment(s), */ +/* added volume RES support, */ +/* resulting in version 6.1.6 */ /* */ /**************************************************************************/ UINT _ux_device_class_audio20_control_process(UX_DEVICE_CLASS_AUDIO *audio, @@ -271,7 +274,7 @@ ULONG i; _ux_utility_short_put(transfer -> ux_slave_transfer_request_data_pointer + 0, 1); _ux_utility_short_put(transfer -> ux_slave_transfer_request_data_pointer + 2, (USHORT)control -> ux_device_class_audio20_control_volume_min[0]); _ux_utility_short_put(transfer -> ux_slave_transfer_request_data_pointer + 4, (USHORT)control -> ux_device_class_audio20_control_volume_max[0]); - _ux_utility_short_put(transfer -> ux_slave_transfer_request_data_pointer + 6, 1); + _ux_utility_short_put(transfer -> ux_slave_transfer_request_data_pointer + 6, (USHORT)UX_MAX(1, control -> ux_device_class_audio20_control_volume_res[0])); _ux_device_stack_transfer_request(transfer, 8, request_length); /* Done success. */ diff --git a/common/usbx_device_classes/src/ux_device_class_cdc_acm_bulkin_thread.c b/common/usbx_device_classes/src/ux_device_class_cdc_acm_bulkin_thread.c index b72f9be3..4583a205 100644 --- a/common/usbx_device_classes/src/ux_device_class_cdc_acm_bulkin_thread.c +++ b/common/usbx_device_classes/src/ux_device_class_cdc_acm_bulkin_thread.c @@ -28,12 +28,14 @@ #include "ux_device_class_cdc_acm.h" #include "ux_device_stack.h" + +#ifndef UX_DEVICE_CLASS_CDC_ACM_TRANSMISSION_DISABLE /**************************************************************************/ /* */ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_cdc_acm_bulkin_thread PORTABLE C */ -/* 6.1 */ +/* 6.1.6 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -72,6 +74,10 @@ /* refer to TX symbols instead */ /* of using them directly, */ /* resulting in version 6.1 */ +/* 04-02-2021 Chaoqiong Xiao Modified comment(s), */ +/* added macro to disable */ +/* transmission support, */ +/* resulting in version 6.1.6 */ /* */ /**************************************************************************/ VOID _ux_device_class_cdc_acm_bulkin_thread(ULONG cdc_acm_class) @@ -213,4 +219,4 @@ ULONG sent_length; _ux_utility_thread_suspend(&cdc_acm -> ux_slave_class_cdc_acm_bulkin_thread); } } - +#endif diff --git a/common/usbx_device_classes/src/ux_device_class_cdc_acm_bulkout_thread.c b/common/usbx_device_classes/src/ux_device_class_cdc_acm_bulkout_thread.c index 4003f542..301f368a 100644 --- a/common/usbx_device_classes/src/ux_device_class_cdc_acm_bulkout_thread.c +++ b/common/usbx_device_classes/src/ux_device_class_cdc_acm_bulkout_thread.c @@ -28,12 +28,14 @@ #include "ux_device_class_cdc_acm.h" #include "ux_device_stack.h" + +#ifndef UX_DEVICE_CLASS_CDC_ACM_TRANSMISSION_DISABLE /**************************************************************************/ /* */ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_cdc_acm_bulkout_thread PORTABLE C */ -/* 6.1 */ +/* 6.1.6 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -68,6 +70,10 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 04-02-2021 Chaoqiong Xiao Modified comment(s), */ +/* added macro to disable */ +/* transmission support, */ +/* resulting in version 6.1.6 */ /* */ /**************************************************************************/ VOID _ux_device_class_cdc_acm_bulkout_thread(ULONG cdc_acm_class) @@ -148,4 +154,4 @@ UINT status; _ux_utility_thread_suspend(&cdc_acm -> ux_slave_class_cdc_acm_bulkout_thread); } } - +#endif diff --git a/common/usbx_device_classes/src/ux_device_class_cdc_acm_initialize.c b/common/usbx_device_classes/src/ux_device_class_cdc_acm_initialize.c index ba7c9dae..1612759b 100644 --- a/common/usbx_device_classes/src/ux_device_class_cdc_acm_initialize.c +++ b/common/usbx_device_classes/src/ux_device_class_cdc_acm_initialize.c @@ -28,12 +28,16 @@ #include "ux_device_stack.h" +#if UX_OVERFLOW_CHECK_MULC_ULONG(UX_THREAD_STACK_SIZE, 2) +#error UX_THREAD_STACK_SIZE too large +#endif + /**************************************************************************/ /* */ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_cdc_acm_initialize PORTABLE C */ -/* 6.1 */ +/* 6.1.6 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -68,6 +72,12 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 04-02-2021 Chaoqiong Xiao Modified comment(s), */ +/* added macro to disable */ +/* transmission support, */ +/* moved transmission resource */ +/* allocate to here (init), */ +/* resulting in version 6.1.6 */ /* */ /**************************************************************************/ UINT _ux_device_class_cdc_acm_initialize(UX_SLAVE_CLASS_COMMAND *command) @@ -136,6 +146,114 @@ UINT status; cdc_acm -> ux_slave_class_cdc_acm_parity = UX_SLAVE_CLASS_CDC_ACM_LINE_CODING_PARITY; cdc_acm -> ux_slave_class_cdc_acm_data_bit = UX_SLAVE_CLASS_CDC_ACM_LINE_CODING_DATA_BIT; +#ifndef UX_DEVICE_CLASS_CDC_ACM_TRANSMISSION_DISABLE + + /* We need to prepare the 2 threads for sending and receiving. */ + /* Allocate some memory for the bulk out and in thread stack. */ + cdc_acm -> ux_slave_class_cdc_acm_bulkout_thread_stack = + _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, UX_THREAD_STACK_SIZE * 2); + + /* Check for successful allocation. */ + if (cdc_acm -> ux_slave_class_cdc_acm_bulkout_thread_stack == UX_NULL) + + /* Return the status to the caller. */ + status = (UX_MEMORY_INSUFFICIENT); + + /* If success, go on to create event flags. */ + if (status == UX_SUCCESS) + { + + /* Allocate some memory for the bulk in thread stack. */ + cdc_acm -> ux_slave_class_cdc_acm_bulkin_thread_stack = + cdc_acm -> ux_slave_class_cdc_acm_bulkout_thread_stack + UX_THREAD_STACK_SIZE; + + /* Create a event flag group for the cdc_acm class to synchronize with the application writing event . */ + status = _ux_utility_event_flags_create( + &cdc_acm -> ux_slave_class_cdc_acm_event_flags_group, + "ux_device_class_cdc_acm_event_flag"); + + /* Check status. */ + if (status != UX_SUCCESS) + { + status = (UX_EVENT_ERROR); + } + } + + /* If success, go on to create bulkin thread. */ + if (status == UX_SUCCESS) + { + + /* Bulk endpoint treatment needs to be running in a different thread. So start + a new thread. We pass a pointer to the cdc_acm instance to the new thread. This thread + does not start until we have a instance of the class. */ + status = _ux_utility_thread_create( + &cdc_acm -> ux_slave_class_cdc_acm_bulkin_thread, + "ux_slave_class_cdc_acm_bulkin_thread", + _ux_device_class_cdc_acm_bulkin_thread, + (ULONG) (ALIGN_TYPE) cdc_acm, + (VOID *) cdc_acm -> ux_slave_class_cdc_acm_bulkin_thread_stack, + UX_THREAD_STACK_SIZE, UX_THREAD_PRIORITY_CLASS, + UX_THREAD_PRIORITY_CLASS, UX_NO_TIME_SLICE, UX_DONT_START); + + /* Check the creation of this thread. */ + if (status != UX_SUCCESS) + { + status = (UX_THREAD_ERROR); + } + else + { + UX_THREAD_EXTENSION_PTR_SET( + &(cdc_acm -> ux_slave_class_cdc_acm_bulkin_thread), cdc_acm) + } + } + + /* If success, go on to create bulkout thread. */ + if (status == UX_SUCCESS) + { + + /* Bulk endpoint treatment needs to be running in a different thread. So start + a new thread. We pass a pointer to the cdc_acm instance to the new thread. This thread + does not start until we have a instance of the class. */ + status = _ux_utility_thread_create( + &cdc_acm -> ux_slave_class_cdc_acm_bulkout_thread, + "ux_slave_class_cdc_acm_bulkout_thread", + _ux_device_class_cdc_acm_bulkout_thread, + (ULONG) (ALIGN_TYPE) cdc_acm, + (VOID *) cdc_acm -> ux_slave_class_cdc_acm_bulkout_thread_stack, + UX_THREAD_STACK_SIZE, UX_THREAD_PRIORITY_CLASS, + UX_THREAD_PRIORITY_CLASS, UX_NO_TIME_SLICE, UX_DONT_START); + + /* Check the creation of this thread. */ + if (status != UX_SUCCESS) + { + status = (UX_THREAD_ERROR); + } + else + { + UX_THREAD_EXTENSION_PTR_SET( + &(cdc_acm -> ux_slave_class_cdc_acm_bulkout_thread), cdc_acm) + } + } + + /* Check error. */ + if (status != UX_SUCCESS) + { + + /* Free resources and return error. */ + if (cdc_acm -> ux_slave_class_cdc_acm_bulkin_thread.tx_thread_id) + _ux_utility_thread_delete(&cdc_acm -> ux_slave_class_cdc_acm_bulkin_thread); + if (cdc_acm -> ux_slave_class_cdc_acm_event_flags_group.tx_event_flags_group_id) + _ux_utility_event_flags_delete(&cdc_acm -> ux_slave_class_cdc_acm_event_flags_group); + if (cdc_acm -> ux_slave_class_cdc_acm_bulkout_thread_stack) + _ux_utility_memory_free(cdc_acm -> ux_slave_class_cdc_acm_bulkout_thread_stack); + _ux_utility_mutex_delete(&cdc_acm -> ux_slave_class_cdc_acm_endpoint_in_mutex); + _ux_utility_mutex_delete(&cdc_acm -> ux_slave_class_cdc_acm_endpoint_out_mutex); + _ux_utility_memory_free(cdc_acm); + return(status); + } + +#endif + /* Return completion status. */ return(UX_SUCCESS); } diff --git a/common/usbx_device_classes/src/ux_device_class_cdc_acm_ioctl.c b/common/usbx_device_classes/src/ux_device_class_cdc_acm_ioctl.c index 8c42688f..2d8dd0a6 100644 --- a/common/usbx_device_classes/src/ux_device_class_cdc_acm_ioctl.c +++ b/common/usbx_device_classes/src/ux_device_class_cdc_acm_ioctl.c @@ -79,6 +79,12 @@ /* 03-02-2021 Xiuwen Cai Modified comment(s), removed */ /* unreachable statement, */ /* resulting in version 6.1.5 */ +/* 04-02-2021 Chaoqiong Xiao Modified comment(s), */ +/* added macro to disable */ +/* transmission support, */ +/* moved transmission resource */ +/* management to init/uninit, */ +/* resulting in version 6.1.6 */ /* */ /**************************************************************************/ UINT _ux_device_class_cdc_acm_ioctl(UX_SLAVE_CLASS_CDC_ACM *cdc_acm, ULONG ioctl_function, @@ -230,8 +236,9 @@ UX_SLAVE_TRANSFER *transfer_request; break; - case UX_SLAVE_CLASS_CDC_ACM_IOCTL_TRANSMISSION_START: +#ifndef UX_DEVICE_CLASS_CDC_ACM_TRANSMISSION_DISABLE + case UX_SLAVE_CLASS_CDC_ACM_IOCTL_TRANSMISSION_START: /* Check if we are in callback transmission already. */ if (cdc_acm -> ux_slave_class_cdc_acm_transmission_status == UX_TRUE) @@ -244,108 +251,16 @@ UX_SLAVE_TRANSFER *transfer_request; /* Properly cast the parameter pointer. */ callback = (UX_SLAVE_CLASS_CDC_ACM_CALLBACK_PARAMETER *) parameter; - /* We need to start the 2 threads for sending and receiving. */ - /* Allocate some memory for the bulk out thread stack. */ - cdc_acm -> ux_slave_class_cdc_acm_bulkout_thread_stack = - _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, UX_THREAD_STACK_SIZE); - - /* Check for successful allocation. */ - if (cdc_acm -> ux_slave_class_cdc_acm_bulkout_thread_stack == UX_NULL) - { - - /* Return the status to the caller. */ - return(UX_MEMORY_INSUFFICIENT); - } - - /* Allocate some memory for the bulk in thread stack. */ - cdc_acm -> ux_slave_class_cdc_acm_bulkin_thread_stack = - _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, UX_THREAD_STACK_SIZE); - - /* Check for successful allocation. */ - if (cdc_acm -> ux_slave_class_cdc_acm_bulkin_thread_stack == UX_NULL) - { - - /* Free resources. */ - _ux_utility_memory_free(cdc_acm -> ux_slave_class_cdc_acm_bulkout_thread_stack ); - - /* Return the status to the caller. */ - return(UX_MEMORY_INSUFFICIENT); - } - - /* Create a event flag group for the cdc_acm class to synchronize with the application writing event . */ - status = _ux_utility_event_flags_create(&cdc_acm -> ux_slave_class_cdc_acm_event_flags_group, "ux_device_class_cdc_acm_event_flag"); - - /* Check status. */ - if (status != UX_SUCCESS) - { - - /* Free resources. */ - _ux_utility_memory_free(cdc_acm -> ux_slave_class_cdc_acm_bulkout_thread_stack ); - _ux_utility_memory_free(cdc_acm -> ux_slave_class_cdc_acm_bulkin_thread_stack ); - - /* Do not proceed. */ - return(UX_EVENT_ERROR); - } - - /* Bulk endpoint treatment needs to be running in a different thread. So start - a new thread. We pass a pointer to the cdc_acm instance to the new thread. This thread - does not start until we have a instance of the class. */ - status = _ux_utility_thread_create(&cdc_acm -> ux_slave_class_cdc_acm_bulkin_thread , "ux_slave_class_cdc_acm_bulkin_thread", - _ux_device_class_cdc_acm_bulkin_thread, - (ULONG) (ALIGN_TYPE) cdc_acm, (VOID *) cdc_acm -> ux_slave_class_cdc_acm_bulkin_thread_stack , - UX_THREAD_STACK_SIZE, UX_THREAD_PRIORITY_CLASS, - UX_THREAD_PRIORITY_CLASS, UX_NO_TIME_SLICE, UX_AUTO_START); - - /* Check the creation of this thread. */ - if (status != UX_SUCCESS) - { - - /* Delete the event flag group for the acm class. */ - _ux_utility_event_flags_delete(&cdc_acm -> ux_slave_class_cdc_acm_event_flags_group); - - /* Free some of the resource used. */ - _ux_utility_memory_free(cdc_acm -> ux_slave_class_cdc_acm_bulkout_thread_stack ); - _ux_utility_memory_free(cdc_acm -> ux_slave_class_cdc_acm_bulkin_thread_stack ); - - return(UX_THREAD_ERROR); - } - - UX_THREAD_EXTENSION_PTR_SET(&(cdc_acm -> ux_slave_class_cdc_acm_bulkin_thread), cdc_acm) - - /* Bulk endpoint treatment needs to be running in a different thread. So start - a new thread. We pass a pointer to the cdc_acm instance to the new thread. This thread - does not start until we have a instance of the class. */ - status = _ux_utility_thread_create(&cdc_acm -> ux_slave_class_cdc_acm_bulkout_thread , "ux_slave_class_cdc_acm_bulkout_thread", - _ux_device_class_cdc_acm_bulkout_thread, - (ULONG) (ALIGN_TYPE) cdc_acm, (VOID *) cdc_acm -> ux_slave_class_cdc_acm_bulkout_thread_stack , - UX_THREAD_STACK_SIZE, UX_THREAD_PRIORITY_CLASS, - UX_THREAD_PRIORITY_CLASS, UX_NO_TIME_SLICE, UX_AUTO_START); - - /* Check the creation of this thread. */ - if (status != UX_SUCCESS) - { - - /* Delete the event flag group for the acm class. */ - _ux_utility_event_flags_delete(&cdc_acm -> ux_slave_class_cdc_acm_event_flags_group); - - /* Delete bulk in thread. */ - _ux_utility_thread_delete(&cdc_acm -> ux_slave_class_cdc_acm_bulkin_thread); - - /* Free some of the resource used. */ - _ux_utility_memory_free(cdc_acm -> ux_slave_class_cdc_acm_bulkout_thread_stack ); - _ux_utility_memory_free(cdc_acm -> ux_slave_class_cdc_acm_bulkin_thread_stack ); - - return(UX_THREAD_ERROR); - } - - UX_THREAD_EXTENSION_PTR_SET(&(cdc_acm -> ux_slave_class_cdc_acm_bulkout_thread), cdc_acm) - /* Save the callback function for write. */ cdc_acm -> ux_device_class_cdc_acm_write_callback = callback -> ux_device_class_cdc_acm_parameter_write_callback; /* Save the callback function for read. */ cdc_acm -> ux_device_class_cdc_acm_read_callback = callback -> ux_device_class_cdc_acm_parameter_read_callback; + /* Start transmission threads. */ + _ux_utility_thread_resume(&cdc_acm -> ux_slave_class_cdc_acm_bulkin_thread); + _ux_utility_thread_resume(&cdc_acm -> ux_slave_class_cdc_acm_bulkout_thread); + /* Declare the transmission with callback on. */ cdc_acm -> ux_slave_class_cdc_acm_transmission_status = UX_TRUE; @@ -367,40 +282,21 @@ UX_SLAVE_TRANSFER *transfer_request; /* Get the transfer request associated with the endpoint. */ transfer_request = &endpoint -> ux_slave_endpoint_transfer_request; - /* Check the status of the transfer. */ - if (transfer_request -> ux_slave_transfer_request_status == UX_TRANSFER_STATUS_PENDING) - { - /* Abort the transfer. */ _ux_device_stack_transfer_abort(transfer_request, UX_TRANSFER_STATUS_ABORT); - } - /* Next endpoint. */ endpoint = endpoint -> ux_slave_endpoint_next_endpoint; /* Get the transfer request associated with the endpoint. */ transfer_request = &endpoint -> ux_slave_endpoint_transfer_request; - /* Check the status of the transfer. */ - if (transfer_request -> ux_slave_transfer_request_status == UX_TRANSFER_STATUS_PENDING) - { - /* Abort the transfer. */ _ux_device_stack_transfer_abort(transfer_request, UX_TRANSFER_STATUS_ABORT); - } - - /* Terminate threads. */ - _ux_utility_thread_delete(&cdc_acm -> ux_slave_class_cdc_acm_bulkin_thread); - _ux_utility_thread_delete(&cdc_acm -> ux_slave_class_cdc_acm_bulkout_thread); - - /* Free resources. */ - _ux_utility_memory_free(cdc_acm -> ux_slave_class_cdc_acm_bulkout_thread_stack ); - _ux_utility_memory_free(cdc_acm -> ux_slave_class_cdc_acm_bulkin_thread_stack ); - - /* Delete the event flag group for the acm class. */ - _ux_utility_event_flags_delete(&cdc_acm -> ux_slave_class_cdc_acm_event_flags_group); + /* Suspend threads. */ + _ux_utility_thread_suspend(&cdc_acm -> ux_slave_class_cdc_acm_bulkin_thread); + _ux_utility_thread_suspend(&cdc_acm -> ux_slave_class_cdc_acm_bulkout_thread); /* Clear scheduled write flag. */ cdc_acm -> ux_slave_class_cdc_acm_scheduled_write = UX_FALSE; @@ -414,6 +310,7 @@ UX_SLAVE_TRANSFER *transfer_request; return(UX_ERROR); break; +#endif default: diff --git a/common/usbx_device_classes/src/ux_device_class_cdc_acm_unitialize.c b/common/usbx_device_classes/src/ux_device_class_cdc_acm_unitialize.c index fc7742cc..3df8ba98 100644 --- a/common/usbx_device_classes/src/ux_device_class_cdc_acm_unitialize.c +++ b/common/usbx_device_classes/src/ux_device_class_cdc_acm_unitialize.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_cdc_acm_uninitialize PORTABLE C */ -/* 6.1 */ +/* 6.1.6 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -67,6 +67,12 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 04-02-2021 Chaoqiong Xiao Modified comment(s), */ +/* added macro to disable */ +/* transmission support, */ +/* moved transmission resource */ +/* free to here (uninit), */ +/* resulting in version 6.1.6 */ /* */ /**************************************************************************/ UINT _ux_device_class_cdc_acm_uninitialize(UX_SLAVE_CLASS_COMMAND *command) @@ -91,6 +97,15 @@ UX_SLAVE_CLASS *class; /* Out Mutex. */ _ux_utility_mutex_delete(&cdc_acm -> ux_slave_class_cdc_acm_endpoint_out_mutex); +#ifndef UX_DEVICE_CLASS_CDC_ACM_TRANSMISSION_DISABLE + + /* Free resources and return error. */ + _ux_utility_thread_delete(&cdc_acm -> ux_slave_class_cdc_acm_bulkin_thread); + _ux_utility_thread_delete(&cdc_acm -> ux_slave_class_cdc_acm_bulkout_thread); + _ux_utility_event_flags_delete(&cdc_acm -> ux_slave_class_cdc_acm_event_flags_group); + _ux_utility_memory_free(cdc_acm -> ux_slave_class_cdc_acm_bulkout_thread_stack); +#endif + /* Free the resources. */ _ux_utility_memory_free(cdc_acm); diff --git a/common/usbx_device_classes/src/ux_device_class_cdc_acm_write_with_callback.c b/common/usbx_device_classes/src/ux_device_class_cdc_acm_write_with_callback.c index 3aba3d26..1915a6ac 100644 --- a/common/usbx_device_classes/src/ux_device_class_cdc_acm_write_with_callback.c +++ b/common/usbx_device_classes/src/ux_device_class_cdc_acm_write_with_callback.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_cdc_acm_write_with_callback PORTABLE C */ -/* 6.1 */ +/* 6.1.6 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -72,12 +72,21 @@ /* TX symbols instead of using */ /* them directly, */ /* resulting in version 6.1 */ +/* 04-02-2021 Chaoqiong Xiao Modified comment(s), */ +/* added macro to disable */ +/* transmission support, */ +/* resulting in version 6.1.6 */ /* */ /**************************************************************************/ UINT _ux_device_class_cdc_acm_write_with_callback(UX_SLAVE_CLASS_CDC_ACM *cdc_acm, UCHAR *buffer, ULONG requested_length) { - +#ifdef UX_DEVICE_CLASS_CDC_ACM_TRANSMISSION_DISABLE + UX_PARAMETER_NOT_USED(cdc_acm); + UX_PARAMETER_NOT_USED(buffer); + UX_PARAMETER_NOT_USED(requested_length); + return(UX_FUNCTION_NOT_SUPPORTED); +#else UX_SLAVE_DEVICE *device; UINT status; @@ -132,6 +141,6 @@ UINT status; /* Simply return the last function result. When we leave this function, the deferred writing has been scheduled. */ return(status); - +#endif } diff --git a/common/usbx_device_classes/src/ux_device_class_dfu_activate.c b/common/usbx_device_classes/src/ux_device_class_dfu_activate.c index 259a6a4c..db088755 100644 --- a/common/usbx_device_classes/src/ux_device_class_dfu_activate.c +++ b/common/usbx_device_classes/src/ux_device_class_dfu_activate.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_dfu_activate PORTABLE C */ -/* 6.1 */ +/* 6.1.6 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -71,6 +71,10 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 04-02-2021 Chaoqiong Xiao Modified comment(s), */ +/* removed block count (it's */ +/* from host request wValue), */ +/* resulting in version 6.1.6 */ /* */ /**************************************************************************/ UINT _ux_device_class_dfu_activate(UX_SLAVE_CLASS_COMMAND *command) @@ -116,10 +120,6 @@ UX_SLAVE_CLASS *class; /* In the system, state the DFU state machine to DFU idle. */ _ux_system_slave -> ux_system_slave_device_dfu_state_machine = UX_SYSTEM_DFU_STATE_DFU_IDLE; - /* Reset the download/upload parameters. */ - dfu -> ux_slave_class_dfu_download_block_count = 0; - dfu -> ux_slave_class_dfu_upload_block_count = 0; - /* Set the mode to DFU mode. */ _ux_system_slave -> ux_system_slave_device_dfu_mode = UX_DEVICE_CLASS_DFU_MODE_DFU ; diff --git a/common/usbx_device_classes/src/ux_device_class_dfu_control_request.c b/common/usbx_device_classes/src/ux_device_class_dfu_control_request.c index ebf023b1..89927d7e 100644 --- a/common/usbx_device_classes/src/ux_device_class_dfu_control_request.c +++ b/common/usbx_device_classes/src/ux_device_class_dfu_control_request.c @@ -11,8 +11,8 @@ /**************************************************************************/ /**************************************************************************/ -/** */ -/** USBX Component */ +/** */ +/** USBX Component */ /** */ /** Device DFU Class */ /** */ @@ -29,48 +29,59 @@ #include "ux_device_stack.h" -/**************************************************************************/ -/* */ -/* FUNCTION RELEASE */ -/* */ -/* _ux_device_class_dfu_control_request PORTABLE C */ -/* 6.1 */ +#if UX_DEVICE_CLASS_DFU_STATUS_MODE == 1 +static inline VOID _ux_device_class_dfu_status_get(UX_SLAVE_CLASS_DFU *, + UX_SLAVE_TRANSFER *, UCHAR, UCHAR, UCHAR, UCHAR); +#endif + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _ux_device_class_dfu_control_request PORTABLE C */ +/* 6.1.6 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ /* */ /* DESCRIPTION */ -/* */ -/* This function manages the based sent by the host on the control */ -/* endpoints with a CLASS or VENDOR SPECIFIC type. */ -/* */ -/* INPUT */ -/* */ -/* dfu Pointer to dfu class */ -/* */ -/* OUTPUT */ -/* */ -/* None */ -/* */ -/* CALLS */ -/* */ -/* _ux_device_stack_endpoint_stall Endpoint stall */ -/* _ux_device_stack_transfer_request Transfer request */ -/* */ -/* CALLED BY */ -/* */ +/* */ +/* This function manages the based sent by the host on the control */ +/* endpoints with a CLASS or VENDOR SPECIFIC type. */ +/* */ +/* INPUT */ +/* */ +/* dfu Pointer to dfu class */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* _ux_device_stack_endpoint_stall Endpoint stall */ +/* _ux_device_stack_transfer_request Transfer request */ +/* */ +/* CALLED BY */ +/* */ /* DFU Class */ -/* */ -/* RELEASE HISTORY */ -/* */ -/* DATE NAME DESCRIPTION */ -/* */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* used UX prefix to refer to */ /* TX symbols instead of using */ /* them directly, */ /* resulting in version 6.1 */ +/* 04-02-2021 Chaoqiong Xiao Modified comment(s), */ +/* added DFU_UPLOAD support, */ +/* removed block count (it's */ +/* from host request wValue), */ +/* resulting in version 6.1.6 */ /* */ /**************************************************************************/ UINT _ux_device_class_dfu_control_request(UX_SLAVE_CLASS_COMMAND *command) @@ -82,6 +93,7 @@ UX_SLAVE_CLASS *class; UX_SLAVE_CLASS_DFU *dfu; ULONG request; +ULONG request_value; ULONG request_length; ULONG actual_length; ULONG media_status; @@ -92,80 +104,104 @@ ULONG media_status; /* Get the class container. */ class = command -> ux_slave_class_command_class_ptr; - + /* Get the storage instance from this class container. */ dfu = (UX_SLAVE_CLASS_DFU *) class -> ux_slave_class_instance; /* Get the pointer to the transfer request associated with the control endpoint. */ transfer_request = &device -> ux_slave_device_control_endpoint.ux_slave_endpoint_transfer_request; +#ifdef UX_DEVICE_CLASS_DFU_CUSTOM_REQUEST_ENABLE + if (dfu -> ux_device_class_dfu_custom_request) + { + + /* The status simply tells us if the registered callback handled the + request - if there was an issue processing the request, it would've + stalled the control endpoint, notifying the host (and not us). */ + media_status = dfu -> ux_device_class_dfu_custom_request(dfu, transfer_request); + + /* Custom request handled. */ + if (media_status == UX_SUCCESS) + return(media_status); + + /* Try to handle with standard handler. */ + } +#endif + /* Extract all necessary fields of the request. */ request = *(transfer_request -> ux_slave_transfer_request_setup + UX_SETUP_REQUEST); - /* Pickup the request length. */ + /* Pickup the request wValue. */ + request_value = _ux_utility_short_get(transfer_request -> ux_slave_transfer_request_setup + UX_SETUP_VALUE); + + /* Pickup the request wLength. */ request_length = _ux_utility_short_get(transfer_request -> ux_slave_transfer_request_setup + UX_SETUP_LENGTH); /* What state are we in ? */ - switch (_ux_system_slave -> ux_system_slave_device_dfu_state_machine) + switch (_ux_system_slave -> ux_system_slave_device_dfu_state_machine) { - + case UX_SYSTEM_DFU_STATE_APP_IDLE : /* Here we process only the request we can accept in the APP IDLE state. */ switch (request) { - + case UX_SLAVE_CLASS_DFU_COMMAND_DETACH : - + /* The host is asking for a Detach and switch to the DFU mode. Either we force the reset here or - we wait for a specified timer. If there is no reset while this timer is running we abandon + we wait for a specified timer. If there is no reset while this timer is running we abandon the DFU Detach.*/ if (_ux_system_slave -> ux_system_slave_device_dfu_capabilities & UX_SLAVE_CLASS_DFU_CAPABILITY_WILL_DETACH) { - + /* Wake up the DFU thread and send a detach request.. */ - _ux_utility_event_flags_set(&dfu -> ux_slave_class_dfu_event_flags_group, UX_DEVICE_CLASS_DFU_THREAD_EVENT_DISCONNECT, UX_OR); + _ux_utility_event_flags_set(&dfu -> ux_slave_class_dfu_event_flags_group, UX_DEVICE_CLASS_DFU_THREAD_EVENT_DISCONNECT, UX_OR); } else { /* We expect the host to issue a reset. Arm a timer in the DFU thread. */ - _ux_utility_event_flags_set(&dfu -> ux_slave_class_dfu_event_flags_group, UX_DEVICE_CLASS_DFU_THREAD_EVENT_WAIT_RESET, UX_OR); + _ux_utility_event_flags_set(&dfu -> ux_slave_class_dfu_event_flags_group, UX_DEVICE_CLASS_DFU_THREAD_EVENT_WAIT_RESET, UX_OR); } /* We can switch dfu state machine. */ _ux_system_slave -> ux_system_slave_device_dfu_state_machine = UX_SYSTEM_DFU_STATE_APP_DETACH; - + break; case UX_SLAVE_CLASS_DFU_COMMAND_GET_STATUS : - + +#if UX_DEVICE_CLASS_DFU_STATUS_MODE == 1 + _ux_device_class_dfu_status_get(dfu, transfer_request, UX_FALSE, 0, 0, 0); +#else /* Fill the status data payload. First with status. */ - *transfer_request -> ux_slave_transfer_request_data_pointer = (UCHAR) dfu -> ux_slave_class_dfu_status; + *transfer_request -> ux_slave_transfer_request_data_pointer = (UCHAR) dfu -> ux_slave_class_dfu_status; /* Poll time out value is set to 1ms. */ - *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_POLL_TIMEOUT) = 1; - *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_POLL_TIMEOUT + 1) = 0; - *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_POLL_TIMEOUT + 2) = 0; + *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_POLL_TIMEOUT) = UX_DW0(UX_DEVICE_CLASS_DFU_STATUS_POLLTIMEOUT); + *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_POLL_TIMEOUT + 1) = UX_DW1(UX_DEVICE_CLASS_DFU_STATUS_POLLTIMEOUT); + *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_POLL_TIMEOUT + 2) = UX_DW2(UX_DEVICE_CLASS_DFU_STATUS_POLLTIMEOUT); /* Next state. */ *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_STATE) = (UCHAR) _ux_system_slave -> ux_system_slave_device_dfu_state_machine; /* String index set to 0. */ *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_STRING) = 0; - +#endif + /* We have a request to obtain the status of the DFU instance. */ _ux_device_stack_transfer_request(transfer_request, UX_SLAVE_CLASS_DFU_GET_STATUS_LENGTH, UX_SLAVE_CLASS_DFU_GET_STATUS_LENGTH); - + break; case UX_SLAVE_CLASS_DFU_COMMAND_GET_STATE : - + /* Fill the status data payload. First with state. */ - *transfer_request -> ux_slave_transfer_request_data_pointer = (UCHAR) _ux_system_slave -> ux_system_slave_device_dfu_state_machine; + *transfer_request -> ux_slave_transfer_request_data_pointer = (UCHAR) _ux_system_slave -> ux_system_slave_device_dfu_state_machine; /* We have a request to obtain the status of the DFU instance. */ _ux_device_stack_transfer_request(transfer_request, UX_SLAVE_CLASS_DFU_GET_STATE_LENGTH, UX_SLAVE_CLASS_DFU_GET_STATE_LENGTH); @@ -173,66 +209,71 @@ ULONG media_status; break; default: - + /* Unknown function. Stall the endpoint. */ _ux_device_stack_endpoint_stall(&device -> ux_slave_device_control_endpoint); break; } break; - + case UX_SYSTEM_DFU_STATE_APP_DETACH : /* Here we process only the request we can accept in the APP DETACH state. */ switch (request) { - + case UX_SLAVE_CLASS_DFU_COMMAND_GET_STATUS : - + +#if UX_DEVICE_CLASS_DFU_STATUS_MODE == 1 + _ux_device_class_dfu_status_get(dfu, transfer_request, UX_FALSE, 0, 0, 0); +#else + /* Fill the status data payload. First with status. */ - *transfer_request -> ux_slave_transfer_request_data_pointer = (UCHAR) dfu -> ux_slave_class_dfu_status; + *transfer_request -> ux_slave_transfer_request_data_pointer = (UCHAR) dfu -> ux_slave_class_dfu_status; /* Poll time out value is set to 1ms. */ - *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_POLL_TIMEOUT) = 1; - *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_POLL_TIMEOUT + 1) = 0; - *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_POLL_TIMEOUT + 2) = 0; + *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_POLL_TIMEOUT) = UX_DW0(UX_DEVICE_CLASS_DFU_STATUS_POLLTIMEOUT); + *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_POLL_TIMEOUT + 1) = UX_DW1(UX_DEVICE_CLASS_DFU_STATUS_POLLTIMEOUT); + *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_POLL_TIMEOUT + 2) = UX_DW2(UX_DEVICE_CLASS_DFU_STATUS_POLLTIMEOUT); /* Next state. */ *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_STATE) = (UCHAR) _ux_system_slave -> ux_system_slave_device_dfu_state_machine; /* String index set to 0. */ *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_STRING) = 0; - +#endif + /* We have a request to obtain the status of the DFU instance. */ _ux_device_stack_transfer_request(transfer_request, UX_SLAVE_CLASS_DFU_GET_STATUS_LENGTH, UX_SLAVE_CLASS_DFU_GET_STATUS_LENGTH); - + break; case UX_SLAVE_CLASS_DFU_COMMAND_GET_STATE : - + /* Fill the status data payload. First with state. */ - *transfer_request -> ux_slave_transfer_request_data_pointer = (UCHAR) _ux_system_slave -> ux_system_slave_device_dfu_state_machine; + *transfer_request -> ux_slave_transfer_request_data_pointer = (UCHAR) _ux_system_slave -> ux_system_slave_device_dfu_state_machine; /* We have a request to obtain the status of the DFU instance. */ _ux_device_stack_transfer_request(transfer_request, UX_SLAVE_CLASS_DFU_GET_STATE_LENGTH, UX_SLAVE_CLASS_DFU_GET_STATE_LENGTH); - + break; default: - + /* Unknown function. Stall the endpoint. */ _ux_device_stack_endpoint_stall(&device -> ux_slave_device_control_endpoint); break; } break; - + case UX_SYSTEM_DFU_STATE_DFU_IDLE : /* Here we process only the request we can accept in the DFU mode IDLE state. */ switch (request) { - + case UX_SLAVE_CLASS_DFU_COMMAND_DOWNLOAD : /* We received a DOWNLOAD command. Check the length field of the request. It cannot be 0. */ @@ -252,84 +293,117 @@ ULONG media_status; /* Have we declared a DOWNLOAD possible in our device framework ? */ if (_ux_system_slave -> ux_system_slave_device_dfu_capabilities & UX_SLAVE_CLASS_DFU_CAPABILITY_CAN_DOWNLOAD) { - + /* Send a notification to the application. Begin of transfer. */ dfu -> ux_slave_class_dfu_notify(dfu, UX_SLAVE_CLASS_DFU_NOTIFICATION_BEGIN_DOWNLOAD); - + /* Write the first block to the firmware. */ - dfu -> ux_slave_class_dfu_write(dfu, dfu -> ux_slave_class_dfu_download_block_count, + dfu -> ux_slave_class_dfu_write(dfu, request_value, transfer_request -> ux_slave_transfer_request_data_pointer, - request_length, + request_length, &actual_length); - + /* In the system, state the DFU state machine to dfu DOWNLOAD SYNC. */ _ux_system_slave -> ux_system_slave_device_dfu_state_machine = UX_SYSTEM_DFU_STATE_DFU_DNLOAD_SYNC; - - /* Increase the block count. */ - dfu -> ux_slave_class_dfu_download_block_count++; - + } else { - + /* Download is not accepted. Stall the endpoint. */ _ux_device_stack_endpoint_stall(&device -> ux_slave_device_control_endpoint); - + /* In the system, state the DFU state machine to dfu ERROR. */ _ux_system_slave -> ux_system_slave_device_dfu_state_machine = UX_SYSTEM_DFU_STATE_DFU_ERROR; - + } } break; - + case UX_SLAVE_CLASS_DFU_COMMAND_ABORT : /* Send a notification to the application. */ dfu -> ux_slave_class_dfu_notify(dfu, UX_SLAVE_CLASS_DFU_NOTIFICATION_ABORT_DOWNLOAD); - + /* In the system, state the DFU state machine to dfu IDLE. */ _ux_system_slave -> ux_system_slave_device_dfu_state_machine = UX_SYSTEM_DFU_STATE_DFU_IDLE; - - /* Reset the download/upload parameters. */ - dfu -> ux_slave_class_dfu_download_block_count = 0; - dfu -> ux_slave_class_dfu_upload_block_count = 0; - + break; case UX_SLAVE_CLASS_DFU_COMMAND_GET_STATUS : - + +#if UX_DEVICE_CLASS_DFU_STATUS_MODE == 1 + _ux_device_class_dfu_status_get(dfu, transfer_request, UX_FALSE, 0, 0, 0); +#else + /* Fill the status data payload. First with status. */ - *transfer_request -> ux_slave_transfer_request_data_pointer = (UCHAR) dfu -> ux_slave_class_dfu_status; + *transfer_request -> ux_slave_transfer_request_data_pointer = (UCHAR) dfu -> ux_slave_class_dfu_status; /* Poll time out value is set to 1ms. */ - *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_POLL_TIMEOUT) = 1; - *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_POLL_TIMEOUT + 1) = 0; - *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_POLL_TIMEOUT + 2) = 0; + *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_POLL_TIMEOUT) = UX_DW0(UX_DEVICE_CLASS_DFU_STATUS_POLLTIMEOUT); + *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_POLL_TIMEOUT + 1) = UX_DW1(UX_DEVICE_CLASS_DFU_STATUS_POLLTIMEOUT); + *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_POLL_TIMEOUT + 2) = UX_DW2(UX_DEVICE_CLASS_DFU_STATUS_POLLTIMEOUT); /* Next state. */ *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_STATE) = (UCHAR) UX_SYSTEM_DFU_STATE_DFU_IDLE; /* String index set to 0. */ *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_STRING) = 0; - +#endif + /* We have a request to obtain the status of the DFU instance. */ _ux_device_stack_transfer_request(transfer_request, UX_SLAVE_CLASS_DFU_GET_STATUS_LENGTH, UX_SLAVE_CLASS_DFU_GET_STATUS_LENGTH); - + break; - + case UX_SLAVE_CLASS_DFU_COMMAND_GET_STATE : - + /* Fill the status data payload. First with state. */ - *transfer_request -> ux_slave_transfer_request_data_pointer = (UCHAR) _ux_system_slave -> ux_system_slave_device_dfu_state_machine; + *transfer_request -> ux_slave_transfer_request_data_pointer = (UCHAR) _ux_system_slave -> ux_system_slave_device_dfu_state_machine; /* We have a request to obtain the status of the DFU instance. */ _ux_device_stack_transfer_request(transfer_request, UX_SLAVE_CLASS_DFU_GET_STATE_LENGTH, UX_SLAVE_CLASS_DFU_GET_STATE_LENGTH); - + + break; + +#ifndef UX_DEVICE_CLASS_DFU_UPLOAD_DISABLE + case UX_SLAVE_CLASS_DFU_COMMAND_UPLOAD: + + /* bitCanUpload != 1, or length = 0. */ + if (!(_ux_system_slave -> ux_system_slave_device_dfu_capabilities & UX_SLAVE_CLASS_DFU_CAPABILITY_CAN_UPLOAD) || + request_length == 0) + { + _ux_device_stack_endpoint_stall(&device -> ux_slave_device_control_endpoint); + + /* In the system, state the DFU state machine to dfu ERROR. */ + _ux_system_slave -> ux_system_slave_device_dfu_state_machine = UX_SYSTEM_DFU_STATE_DFU_ERROR; + + break; + } + + /* bitCanUpload = 1. */ + + /* Send a notification to the application. Begin of transfer. */ + dfu -> ux_slave_class_dfu_notify(dfu, UX_SLAVE_CLASS_DFU_NOTIFICATION_BEGIN_UPLOAD); + + /* Read the first block to the firmware. */ + dfu -> ux_slave_class_dfu_read(dfu, request_value, + transfer_request -> ux_slave_transfer_request_data_pointer, + request_length, + &actual_length); + + /* In the system, state the DFU state machine to dfu UPLOAD IDLE. */ + _ux_system_slave -> ux_system_slave_device_dfu_state_machine = UX_SYSTEM_DFU_STATE_DFU_UPLOAD_IDLE; + + /* We have a request to upload DFU firmware block. */ + _ux_device_stack_transfer_request(transfer_request, actual_length, request_length); + break; - +#endif + default: - + /* Unknown function. Stall the endpoint. */ _ux_device_stack_endpoint_stall(&device -> ux_slave_device_control_endpoint); @@ -340,19 +414,26 @@ ULONG media_status; } break; - + case UX_SYSTEM_DFU_STATE_DFU_DNLOAD_SYNC : /* Here we process only the request we can accept in the DFU mode DOWNLOAD state. */ switch (request) { - + case UX_SLAVE_CLASS_DFU_COMMAND_GET_STATUS : +#if UX_DEVICE_CLASS_DFU_STATUS_MODE == 1 + _ux_device_class_dfu_status_get(dfu, transfer_request, UX_TRUE, + UX_SLAVE_CLASS_DFU_STATUS_STATE_DFU_DNLOAD_IDLE, + UX_SLAVE_CLASS_DFU_STATUS_STATE_DFU_DNBUSY, + UX_SLAVE_CLASS_DFU_STATUS_STATE_DFU_ERROR); +#else + /* Check if the device is still buys performing the write. Write could be delayed. */ dfu -> ux_slave_class_dfu_get_status(dfu, &media_status); - + /* Check status of device. */ switch (media_status) { @@ -363,14 +444,14 @@ ULONG media_status; dfu -> ux_slave_class_dfu_status = UX_SLAVE_CLASS_DFU_STATUS_OK ; _ux_system_slave -> ux_system_slave_device_dfu_state_machine = UX_SLAVE_CLASS_DFU_STATUS_STATE_DFU_DNLOAD_IDLE; break; - + case UX_SLAVE_CLASS_DFU_MEDIA_STATUS_BUSY : - + /* Set the next state for busy but no error status. */ dfu -> ux_slave_class_dfu_status = UX_SLAVE_CLASS_DFU_STATUS_OK ; _ux_system_slave -> ux_system_slave_device_dfu_state_machine = UX_SLAVE_CLASS_DFU_STATUS_STATE_DFU_DNBUSY; break; - + case UX_SLAVE_CLASS_DFU_MEDIA_STATUS_ERROR : /* Set the next state for busy and error status. */ @@ -381,36 +462,37 @@ ULONG media_status; } /* Fill the status data payload. First with status. */ - *transfer_request -> ux_slave_transfer_request_data_pointer = (UCHAR) dfu -> ux_slave_class_dfu_status; + *transfer_request -> ux_slave_transfer_request_data_pointer = (UCHAR) dfu -> ux_slave_class_dfu_status; /* Poll time out value is set to 1ms. */ - *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_POLL_TIMEOUT) = 1; - *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_POLL_TIMEOUT + 1) = 0; - *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_POLL_TIMEOUT + 2) = 0; + *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_POLL_TIMEOUT) = UX_DW0(UX_DEVICE_CLASS_DFU_STATUS_POLLTIMEOUT); + *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_POLL_TIMEOUT + 1) = UX_DW1(UX_DEVICE_CLASS_DFU_STATUS_POLLTIMEOUT); + *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_POLL_TIMEOUT + 2) = UX_DW2(UX_DEVICE_CLASS_DFU_STATUS_POLLTIMEOUT); /* Next state. */ *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_STATE) = (UCHAR) _ux_system_slave -> ux_system_slave_device_dfu_state_machine; /* String index set to 0. */ *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_STRING) = 0; - +#endif + /* We have a request to obtain the status of the DFU instance. */ _ux_device_stack_transfer_request(transfer_request, UX_SLAVE_CLASS_DFU_GET_STATUS_LENGTH, UX_SLAVE_CLASS_DFU_GET_STATUS_LENGTH); - + break; - + case UX_SLAVE_CLASS_DFU_COMMAND_GET_STATE : - + /* Fill the status data payload. First with state. */ - *transfer_request -> ux_slave_transfer_request_data_pointer = (UCHAR) _ux_system_slave -> ux_system_slave_device_dfu_state_machine; + *transfer_request -> ux_slave_transfer_request_data_pointer = (UCHAR) _ux_system_slave -> ux_system_slave_device_dfu_state_machine; /* We have a request to obtain the status of the DFU instance. */ _ux_device_stack_transfer_request(transfer_request, UX_SLAVE_CLASS_DFU_GET_STATE_LENGTH, UX_SLAVE_CLASS_DFU_GET_STATE_LENGTH); - + break; - + default: - + /* Unknown function. Stall the endpoint. */ _ux_device_stack_endpoint_stall(&device -> ux_slave_device_control_endpoint); @@ -427,7 +509,7 @@ ULONG media_status; /* Here we process only the request we can accept in the DFU mode DNLOAD state. */ switch (request) { - + case UX_SLAVE_CLASS_DFU_COMMAND_DOWNLOAD : /* We received a DOWNLOAD command. Check the length field of the request. If it is 0, @@ -437,7 +519,7 @@ ULONG media_status; /* Send the notification of end of download to application. */ dfu -> ux_slave_class_dfu_notify(dfu, UX_SLAVE_CLASS_DFU_NOTIFICATION_END_DOWNLOAD); - + /* In the system, state the DFU state machine to DFU MANIFEST SYNCH. */ _ux_system_slave -> ux_system_slave_device_dfu_state_machine = UX_SLAVE_CLASS_DFU_STATUS_STATE_DFU_MANIFEST_SYNC; @@ -445,70 +527,67 @@ ULONG media_status; else { - + /* Write the next block to the firmware. */ - dfu -> ux_slave_class_dfu_write(dfu, dfu -> ux_slave_class_dfu_download_block_count, + dfu -> ux_slave_class_dfu_write(dfu, request_value, transfer_request -> ux_slave_transfer_request_data_pointer, - request_length, + request_length, &actual_length); /* In the system, state the DFU state machine to dfu DOWNLOAD SYNC. */ _ux_system_slave -> ux_system_slave_device_dfu_state_machine = UX_SYSTEM_DFU_STATE_DFU_DNLOAD_SYNC; - - /* Increase the block count. */ - dfu -> ux_slave_class_dfu_download_block_count++; - } break; - + case UX_SLAVE_CLASS_DFU_COMMAND_ABORT : - /* Send a notification to the application. */ - dfu -> ux_slave_class_dfu_notify(dfu, UX_SLAVE_CLASS_DFU_NOTIFICATION_ABORT_DOWNLOAD); - - /* In the system, state the DFU state machine to dfu IDLE. */ - _ux_system_slave -> ux_system_slave_device_dfu_state_machine = UX_SYSTEM_DFU_STATE_DFU_IDLE; + /* Send a notification to the application. */ + dfu -> ux_slave_class_dfu_notify(dfu, UX_SLAVE_CLASS_DFU_NOTIFICATION_ABORT_DOWNLOAD); + + /* In the system, state the DFU state machine to dfu IDLE. */ + _ux_system_slave -> ux_system_slave_device_dfu_state_machine = UX_SYSTEM_DFU_STATE_DFU_IDLE; - /* Reset the download/upload parameters. */ - dfu -> ux_slave_class_dfu_download_block_count = 0; - dfu -> ux_slave_class_dfu_upload_block_count = 0; - break; case UX_SLAVE_CLASS_DFU_COMMAND_GET_STATUS : - + +#if UX_DEVICE_CLASS_DFU_STATUS_MODE == 1 + _ux_device_class_dfu_status_get(dfu, transfer_request, UX_FALSE, 0, 0, 0); +#else + /* Fill the status data payload. First with status. */ - *transfer_request -> ux_slave_transfer_request_data_pointer = (UCHAR) dfu -> ux_slave_class_dfu_status; + *transfer_request -> ux_slave_transfer_request_data_pointer = (UCHAR) dfu -> ux_slave_class_dfu_status; /* Poll time out value is set to 1ms. */ - *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_POLL_TIMEOUT) = 1; - *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_POLL_TIMEOUT + 1) = 0; - *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_POLL_TIMEOUT + 2) = 0; + *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_POLL_TIMEOUT) = UX_DW0(UX_DEVICE_CLASS_DFU_STATUS_POLLTIMEOUT); + *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_POLL_TIMEOUT + 1) = UX_DW1(UX_DEVICE_CLASS_DFU_STATUS_POLLTIMEOUT); + *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_POLL_TIMEOUT + 2) = UX_DW2(UX_DEVICE_CLASS_DFU_STATUS_POLLTIMEOUT); /* Next state. */ *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_STATE) = (UCHAR) _ux_system_slave -> ux_system_slave_device_dfu_state_machine; /* String index set to 0. */ *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_STRING) = 0; - +#endif + /* We have a request to obtain the status of the DFU instance. */ _ux_device_stack_transfer_request(transfer_request, UX_SLAVE_CLASS_DFU_GET_STATUS_LENGTH, UX_SLAVE_CLASS_DFU_GET_STATUS_LENGTH); - + break; - + case UX_SLAVE_CLASS_DFU_COMMAND_GET_STATE : - + /* Fill the status data payload. First with state. */ - *transfer_request -> ux_slave_transfer_request_data_pointer = (UCHAR) _ux_system_slave -> ux_system_slave_device_dfu_state_machine; + *transfer_request -> ux_slave_transfer_request_data_pointer = (UCHAR) _ux_system_slave -> ux_system_slave_device_dfu_state_machine; /* We have a request to obtain the status of the DFU instance. */ _ux_device_stack_transfer_request(transfer_request, UX_SLAVE_CLASS_DFU_GET_STATE_LENGTH, UX_SLAVE_CLASS_DFU_GET_STATE_LENGTH); - + break; - + default: - + /* Unknown function. Stall the endpoint. */ _ux_device_stack_endpoint_stall(&device -> ux_slave_device_control_endpoint); @@ -525,12 +604,30 @@ ULONG media_status; /* Here we process only the request we can accept in the MANIFEST SYNCH state. */ switch (request) { - + case UX_SLAVE_CLASS_DFU_COMMAND_GET_STATUS : - + +#if UX_DEVICE_CLASS_DFU_STATUS_MODE == 1 + _ux_device_class_dfu_status_get(dfu, transfer_request, UX_TRUE, + UX_SLAVE_CLASS_DFU_STATUS_STATE_DFU_MANIFEST_WAIT_RESET, + UX_SLAVE_CLASS_DFU_STATUS_STATE_DFU_MANIFEST, + UX_SLAVE_CLASS_DFU_STATUS_STATE_DFU_ERROR); + if ((_ux_system_slave -> ux_system_slave_device_dfu_state_machine == + UX_SLAVE_CLASS_DFU_STATUS_STATE_DFU_MANIFEST_WAIT_RESET) && + (_ux_system_slave -> ux_system_slave_device_dfu_capabilities & + UX_SLAVE_CLASS_DFU_CAPABILITY_WILL_DETACH)) + { + + /* Wake up the DFU thread and send a detach request.. */ + _ux_utility_event_flags_set( + &dfu -> ux_slave_class_dfu_event_flags_group, + UX_DEVICE_CLASS_DFU_THREAD_EVENT_DISCONNECT, UX_OR); + } +#else + /* Check if the device is still buys performing the write. Write could be delayed. */ dfu -> ux_slave_class_dfu_get_status(dfu, &media_status); - + /* Check status of device. */ switch (media_status) { @@ -544,21 +641,21 @@ ULONG media_status; /* Check who is responsible for the RESET. */ if (_ux_system_slave -> ux_system_slave_device_dfu_capabilities & UX_SLAVE_CLASS_DFU_CAPABILITY_WILL_DETACH) { - + /* Wake up the DFU thread and send a detach request.. */ - _ux_utility_event_flags_set(&dfu -> ux_slave_class_dfu_event_flags_group, UX_DEVICE_CLASS_DFU_THREAD_EVENT_DISCONNECT, UX_OR); + _ux_utility_event_flags_set(&dfu -> ux_slave_class_dfu_event_flags_group, UX_DEVICE_CLASS_DFU_THREAD_EVENT_DISCONNECT, UX_OR); } break; - + case UX_SLAVE_CLASS_DFU_MEDIA_STATUS_BUSY : - + /* Set the next state for busy but no error status. */ dfu -> ux_slave_class_dfu_status = UX_SLAVE_CLASS_DFU_STATUS_OK ; _ux_system_slave -> ux_system_slave_device_dfu_state_machine = UX_SLAVE_CLASS_DFU_STATUS_STATE_DFU_MANIFEST; break; - + case UX_SLAVE_CLASS_DFU_MEDIA_STATUS_ERROR : /* Set the next state for busy and error status. */ @@ -568,58 +665,93 @@ ULONG media_status; } /* Fill the status data payload. First with status. */ - *transfer_request -> ux_slave_transfer_request_data_pointer = (UCHAR) dfu -> ux_slave_class_dfu_status; + *transfer_request -> ux_slave_transfer_request_data_pointer = (UCHAR) dfu -> ux_slave_class_dfu_status; /* Poll time out value is set to 1ms. */ - *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_POLL_TIMEOUT) = 1; - *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_POLL_TIMEOUT + 1) = 0; - *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_POLL_TIMEOUT + 2) = 0; + *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_POLL_TIMEOUT) = UX_DW0(UX_DEVICE_CLASS_DFU_STATUS_POLLTIMEOUT); + *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_POLL_TIMEOUT + 1) = UX_DW1(UX_DEVICE_CLASS_DFU_STATUS_POLLTIMEOUT); + *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_POLL_TIMEOUT + 2) = UX_DW2(UX_DEVICE_CLASS_DFU_STATUS_POLLTIMEOUT); /* Next state. */ *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_STATE) = (UCHAR) _ux_system_slave -> ux_system_slave_device_dfu_state_machine; /* String index set to 0. */ *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_STRING) = 0; - +#endif + /* We have a request to obtain the status of the DFU instance. */ _ux_device_stack_transfer_request(transfer_request, UX_SLAVE_CLASS_DFU_GET_STATUS_LENGTH, UX_SLAVE_CLASS_DFU_GET_STATUS_LENGTH); - + break; case UX_SLAVE_CLASS_DFU_COMMAND_GET_STATE : - + /* Fill the status data payload. First with state. */ - *transfer_request -> ux_slave_transfer_request_data_pointer = (UCHAR) _ux_system_slave -> ux_system_slave_device_dfu_state_machine; + *transfer_request -> ux_slave_transfer_request_data_pointer = (UCHAR) _ux_system_slave -> ux_system_slave_device_dfu_state_machine; /* We have a request to obtain the status of the DFU instance. */ _ux_device_stack_transfer_request(transfer_request, UX_SLAVE_CLASS_DFU_GET_STATE_LENGTH, UX_SLAVE_CLASS_DFU_GET_STATE_LENGTH); - + break; default: - + /* Unknown function. Stall the endpoint. */ _ux_device_stack_endpoint_stall(&device -> ux_slave_device_control_endpoint); break; } break; - + case UX_SLAVE_CLASS_DFU_STATUS_STATE_DFU_ERROR : /* Here we process only the request we can accept in the ERROR state. */ switch (request) { - + +#ifdef UX_DEVICE_CLASS_DFU_ERROR_GET_ENABLE + case UX_SLAVE_CLASS_DFU_COMMAND_GET_STATUS : + + /* Fill the status data payload. First with status. */ + *transfer_request -> ux_slave_transfer_request_data_pointer = (UCHAR) dfu -> ux_slave_class_dfu_status; + + /* Poll time out value is set to 1ms. */ + *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_POLL_TIMEOUT) = 1; + *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_POLL_TIMEOUT + 1) = 0; + *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_POLL_TIMEOUT + 2) = 0; + + /* Next state. */ + *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_STATE) = (UCHAR) _ux_system_slave -> ux_system_slave_device_dfu_state_machine; + + /* String index set to 0. */ + *(transfer_request -> ux_slave_transfer_request_data_pointer + 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_request, UX_SLAVE_CLASS_DFU_GET_STATUS_LENGTH, UX_SLAVE_CLASS_DFU_GET_STATUS_LENGTH); + + break; + + case UX_SLAVE_CLASS_DFU_COMMAND_GET_STATE : + + /* Fill the status data payload. First with state. */ + *transfer_request -> ux_slave_transfer_request_data_pointer = (UCHAR) _ux_system_slave -> ux_system_slave_device_dfu_state_machine; + + /* We have a request to obtain the status of the DFU instance. */ + _ux_device_stack_transfer_request(transfer_request, UX_SLAVE_CLASS_DFU_GET_STATE_LENGTH, UX_SLAVE_CLASS_DFU_GET_STATE_LENGTH); + + break; +#endif + case UX_SLAVE_CLASS_DFU_COMMAND_CLEAR_STATUS : /* In the system, state the DFU state machine to dfu IDLE. */ + dfu -> ux_slave_class_dfu_status = UX_SLAVE_CLASS_DFU_MEDIA_STATUS_OK; _ux_system_slave -> ux_system_slave_device_dfu_state_machine = UX_SYSTEM_DFU_STATE_DFU_IDLE; - + break; default: - + /* Unknown function. Stall the endpoint. */ _ux_device_stack_endpoint_stall(&device -> ux_slave_device_control_endpoint); break; @@ -628,6 +760,102 @@ ULONG media_status; break; +#ifndef UX_DEVICE_CLASS_DFU_UPLOAD_DISABLE + case UX_SLAVE_CLASS_DFU_STATUS_STATE_DFU_UPLOAD_IDLE: + + /* Here we process only the request we can accept in the DFU mode UPLOAD IDLE state. */ + switch (request) + { + + case UX_SLAVE_CLASS_DFU_COMMAND_UPLOAD: + + /* Length 0 case undefined, just keep state. */ + if (request_length == 0) + break; + + /* We received a UPLOAD command with length > 0. */ + + /* Read the next block from the firmware. */ + dfu -> ux_slave_class_dfu_read(dfu, request_value, + transfer_request -> ux_slave_transfer_request_data_pointer, + request_length, + &actual_length); + + /* If it's short frame, switch to dfu IDLE. */ + if (actual_length < request_length) + { + + /* Send a notification to the application. */ + dfu -> ux_slave_class_dfu_notify(dfu, UX_SLAVE_CLASS_DFU_NOTIFICATION_END_UPLOAD); + + /* In the system, state the DFU state machine to dfu IDLE. */ + _ux_system_slave -> ux_system_slave_device_dfu_state_machine = UX_SYSTEM_DFU_STATE_DFU_IDLE; + } + + /* We have a request to upload DFU firmware block. */ + _ux_device_stack_transfer_request(transfer_request, actual_length, request_length); + + break; + + case UX_SLAVE_CLASS_DFU_COMMAND_ABORT : + + /* Send a notification to the application. */ + dfu -> ux_slave_class_dfu_notify(dfu, UX_SLAVE_CLASS_DFU_NOTIFICATION_ABORT_UPLOAD); + + /* In the system, state the DFU state machine to dfu IDLE. */ + _ux_system_slave -> ux_system_slave_device_dfu_state_machine = UX_SYSTEM_DFU_STATE_DFU_IDLE; + + break; + + case UX_SLAVE_CLASS_DFU_COMMAND_GET_STATUS : + +#if UX_DEVICE_CLASS_DFU_STATUS_MODE == 1 + _ux_device_class_dfu_status_get(dfu, transfer_request, UX_FALSE, 0, 0, 0); +#else + + /* Fill the status data payload. First with status. */ + *transfer_request -> ux_slave_transfer_request_data_pointer = (UCHAR) dfu -> ux_slave_class_dfu_status; + + /* Poll time out value is set to 1ms. */ + *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_POLL_TIMEOUT) = UX_DW0(UX_DEVICE_CLASS_DFU_STATUS_POLLTIMEOUT); + *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_POLL_TIMEOUT + 1) = UX_DW1(UX_DEVICE_CLASS_DFU_STATUS_POLLTIMEOUT); + *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_POLL_TIMEOUT + 2) = UX_DW2(UX_DEVICE_CLASS_DFU_STATUS_POLLTIMEOUT); + + /* Next state. */ + *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_STATE) = (UCHAR) _ux_system_slave -> ux_system_slave_device_dfu_state_machine; + + /* String index set to 0. */ + *(transfer_request -> ux_slave_transfer_request_data_pointer + UX_SLAVE_CLASS_DFU_GET_STATUS_STRING) = 0; +#endif + + /* We have a request to obtain the status of the DFU instance. */ + _ux_device_stack_transfer_request(transfer_request, UX_SLAVE_CLASS_DFU_GET_STATUS_LENGTH, UX_SLAVE_CLASS_DFU_GET_STATUS_LENGTH); + + break; + + case UX_SLAVE_CLASS_DFU_COMMAND_GET_STATE : + + /* Fill the status data payload. First with state. */ + *transfer_request -> ux_slave_transfer_request_data_pointer = (UCHAR) _ux_system_slave -> ux_system_slave_device_dfu_state_machine; + + /* We have a request to obtain the status of the DFU instance. */ + _ux_device_stack_transfer_request(transfer_request, UX_SLAVE_CLASS_DFU_GET_STATE_LENGTH, UX_SLAVE_CLASS_DFU_GET_STATE_LENGTH); + + break; + + default: + + /* Unknown function. Stall the endpoint. */ + _ux_device_stack_endpoint_stall(&device -> ux_slave_device_control_endpoint); + + /* In the system, state the DFU state machine to dfu ERROR. */ + _ux_system_slave -> ux_system_slave_device_dfu_state_machine = UX_SYSTEM_DFU_STATE_DFU_ERROR; + + break; + } + + break; +#endif default: @@ -638,3 +866,58 @@ ULONG media_status; return(UX_SUCCESS); } +#if UX_DEVICE_CLASS_DFU_STATUS_MODE == 1 +static inline VOID _ux_device_class_dfu_status_get(UX_SLAVE_CLASS_DFU *dfu, + UX_SLAVE_TRANSFER *transfer, + UCHAR move_state, + UCHAR state_ok, UCHAR state_busy, UCHAR state_error) +{ +ULONG media_status = ((UX_SLAVE_CLASS_DFU_MEDIA_STATUS_OK) | + (UX_SLAVE_CLASS_DFU_STATUS_OK << 4) | + (UX_DEVICE_CLASS_DFU_STATUS_POLLTIMEOUT << 8)); +UCHAR *buffer = transfer -> ux_slave_transfer_request_data_pointer; +ULONG dfu_status, dfu_polltimeout; + + /* Get status from application. */ + dfu -> ux_slave_class_dfu_get_status(dfu, &media_status); + + /* Extract bStatus and bwPollTimeout. */ + dfu_status = (media_status >> 4) & 0xFu; + dfu_polltimeout = (media_status >> 8) & 0xFFFFFFu; + dfu -> ux_slave_class_dfu_status = dfu_status; + + /* Move state based on returned status. */ + if (move_state) + { + + /* OK/BUSY/ERROR ? */ + switch((media_status & 0xF)) + { + case UX_SLAVE_CLASS_DFU_MEDIA_STATUS_OK: + _ux_system_slave -> ux_system_slave_device_dfu_state_machine = state_ok; + break; + case UX_SLAVE_CLASS_DFU_MEDIA_STATUS_BUSY: + _ux_system_slave -> ux_system_slave_device_dfu_state_machine = state_busy; + break; + case UX_SLAVE_CLASS_DFU_MEDIA_STATUS_ERROR: + default: + _ux_system_slave -> ux_system_slave_device_dfu_state_machine = state_error; + break; + } + } + + /* Fill the status data payload. First with status. */ + *buffer = (UCHAR) dfu_status; + + /* Poll time out value is set to 1ms. */ + *(buffer + UX_SLAVE_CLASS_DFU_GET_STATUS_POLL_TIMEOUT) = UX_DW0(dfu_polltimeout); + *(buffer + UX_SLAVE_CLASS_DFU_GET_STATUS_POLL_TIMEOUT + 1) = UX_DW1(dfu_polltimeout); + *(buffer + UX_SLAVE_CLASS_DFU_GET_STATUS_POLL_TIMEOUT + 2) = UX_DW2(dfu_polltimeout); + + /* Next state. */ + *(buffer + UX_SLAVE_CLASS_DFU_GET_STATUS_STATE) = (UCHAR) _ux_system_slave -> ux_system_slave_device_dfu_state_machine; + + /* String index set to 0. */ + *(buffer + UX_SLAVE_CLASS_DFU_GET_STATUS_STRING) = 0; +} +#endif diff --git a/common/usbx_device_classes/src/ux_device_class_dfu_deactivate.c b/common/usbx_device_classes/src/ux_device_class_dfu_deactivate.c index 96132e2b..dfc42d5e 100644 --- a/common/usbx_device_classes/src/ux_device_class_dfu_deactivate.c +++ b/common/usbx_device_classes/src/ux_device_class_dfu_deactivate.c @@ -34,7 +34,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_dfu_deactivate PORTABLE C */ -/* 6.1 */ +/* 6.1.6 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -66,50 +66,24 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 04-02-2021 Chaoqiong Xiao Modified comment(s), */ +/* removed endpoints aborting, */ +/* resulting in version 6.1.6 */ /* */ /**************************************************************************/ UINT _ux_device_class_dfu_deactivate(UX_SLAVE_CLASS_COMMAND *command) { -UX_SLAVE_INTERFACE *interface; UX_SLAVE_CLASS_DFU *dfu; -UX_SLAVE_ENDPOINT *endpoint_in; -UX_SLAVE_ENDPOINT *endpoint_out; UX_SLAVE_CLASS *class; + /* Get the class container. */ class = command -> ux_slave_class_command_class_ptr; /* Get the class instance in the container. */ dfu = (UX_SLAVE_CLASS_DFU *) class -> ux_slave_class_instance; - /* We need the interface to the class. */ - interface = dfu -> ux_slave_class_dfu_interface; - - /* Locate the endpoints. */ - endpoint_in = interface -> ux_slave_interface_first_endpoint; - - /* Check the endpoint direction, if IN we have the correct endpoint. */ - if ((endpoint_in -> ux_slave_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION) != UX_ENDPOINT_IN) - { - - /* Wrong direction, we found the OUT endpoint first. */ - endpoint_out = endpoint_in; - - /* So the next endpoint has to be the IN endpoint. */ - endpoint_in = endpoint_out -> ux_slave_endpoint_next_endpoint; - } - else - { - - /* We found the endpoint IN first, so next endpoint is OUT. */ - endpoint_out = endpoint_in -> ux_slave_endpoint_next_endpoint; - } - - /* Terminate the transactions pending on the endpoints. */ - _ux_device_stack_transfer_all_request_abort(endpoint_in, UX_TRANSFER_BUS_RESET); - _ux_device_stack_transfer_all_request_abort(endpoint_out, UX_TRANSFER_BUS_RESET); - /* If there is a deactivate function call it. */ if (dfu -> ux_slave_class_dfu_instance_deactivate != UX_NULL) { diff --git a/common/usbx_device_classes/src/ux_device_class_dfu_initialize.c b/common/usbx_device_classes/src/ux_device_class_dfu_initialize.c index 165fdf4d..a7571e0b 100644 --- a/common/usbx_device_classes/src/ux_device_class_dfu_initialize.c +++ b/common/usbx_device_classes/src/ux_device_class_dfu_initialize.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_dfu_initialize PORTABLE C */ -/* 6.1 */ +/* 6.1.6 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -73,6 +73,10 @@ /* TX symbols instead of using */ /* them directly, */ /* resulting in version 6.1 */ +/* 04-02-2021 Chaoqiong Xiao Modified comment(s), */ +/* fixed max transfer size, */ +/* added max size limit check, */ +/* resulting in version 6.1.6 */ /* */ /**************************************************************************/ UINT _ux_device_class_dfu_initialize(UX_SLAVE_CLASS_COMMAND *command) @@ -111,7 +115,10 @@ ULONG descriptor_length; dfu -> ux_slave_class_dfu_write = dfu_parameter -> ux_slave_class_dfu_parameter_write; dfu -> ux_slave_class_dfu_get_status = dfu_parameter -> ux_slave_class_dfu_parameter_get_status; dfu -> ux_slave_class_dfu_notify = dfu_parameter -> ux_slave_class_dfu_parameter_notify; - +#ifdef UX_DEVICE_CLASS_DFU_CUSTOM_REQUEST_ENABLE + dfu -> ux_device_class_dfu_custom_request = dfu_parameter -> ux_device_class_dfu_parameter_custom_request; +#endif + /* Store the device dfu in the project structure. */ _ux_system_slave -> ux_system_slave_dfu_framework = dfu_parameter -> ux_slave_class_dfu_parameter_framework; _ux_system_slave -> ux_system_slave_dfu_framework_length = dfu_parameter -> ux_slave_class_dfu_parameter_framework_length; @@ -122,12 +129,18 @@ ULONG descriptor_length; dfu_framework_length = _ux_system_slave -> ux_system_slave_dfu_framework_length; /* Parse the device framework and locate interfaces and endpoint descriptor(s). */ + status = UX_DESCRIPTOR_CORRUPTED; while (dfu_framework_length != 0) { /* Get the length of this descriptor. */ descriptor_length = (ULONG) *dfu_framework; + /* Length validation. */ + if (descriptor_length < 2 || + descriptor_length > dfu_framework_length) + break; + /* And its type. */ descriptor_type = *(dfu_framework + 1); @@ -141,6 +154,10 @@ ULONG descriptor_length; UX_DFU_FUNCTIONAL_DESCRIPTOR_ENTRIES, (UCHAR *) &dfu_functional_descriptor); + /* Control transfer limit validation. */ + if (dfu_functional_descriptor.wTransferSize > UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH) + break; + /* Retrieve the DFU capabilities and store them in the system. */ _ux_system_slave -> ux_system_slave_device_dfu_capabilities = dfu_functional_descriptor.bmAttributes; @@ -148,11 +165,14 @@ ULONG descriptor_length; _ux_system_slave -> ux_system_slave_device_dfu_detach_timeout = dfu_functional_descriptor.wDetachTimeOut; /* Retrieve the DFU transfer size value. */ - _ux_system_slave -> ux_system_slave_device_dfu_transfer_size = dfu_functional_descriptor.wDetachTimeOut; - + _ux_system_slave -> ux_system_slave_device_dfu_transfer_size = dfu_functional_descriptor.wTransferSize; + /* In the system, state the DFU state machine. */ _ux_system_slave -> ux_system_slave_device_dfu_state_machine = UX_SYSTEM_DFU_STATE_APP_IDLE; + /* DFU descriptor parsed, done. */ + status = UX_SUCCESS; + break; } /* Adjust what is left of the device framework. */ diff --git a/common/usbx_device_classes/src/ux_device_class_dfu_state_get.c b/common/usbx_device_classes/src/ux_device_class_dfu_state_get.c new file mode 100644 index 00000000..67730ad4 --- /dev/null +++ b/common/usbx_device_classes/src/ux_device_class_dfu_state_get.c @@ -0,0 +1,73 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) Microsoft Corporation. All rights reserved. */ +/* */ +/* This software is licensed under the Microsoft Software License */ +/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +/* and in the root directory of this software. */ +/* */ +/**************************************************************************/ + +/**************************************************************************/ +/** */ +/** USBX Component */ +/** */ +/** Device DFU Class */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +#define UX_SOURCE_CODE + + +/* Include necessary system files. */ + +#include "ux_api.h" +#include "ux_device_class_dfu.h" +#include "ux_device_stack.h" + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _ux_device_class_dfu_state_get PORTABLE C */ +/* 6.1.6 */ +/* AUTHOR */ +/* */ +/* Chaoqiong Xiao, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function gets the USB DFU device state. */ +/* */ +/* INPUT */ +/* */ +/* dfu Pointer to DFU instance */ +/* */ +/* OUTPUT */ +/* */ +/* DFU state */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* USBX Source Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 04-02-2021 Chaoqiong Xiao Initial Version 6.1.6 */ +/* */ +/**************************************************************************/ +UCHAR _ux_device_class_dfu_state_get(UX_SLAVE_CLASS_DFU *dfu) +{ + UX_PARAMETER_NOT_USED(dfu); + return (UCHAR)_ux_system_slave -> ux_system_slave_device_dfu_state_machine; +} diff --git a/common/usbx_device_classes/src/ux_device_class_dfu_state_sync.c b/common/usbx_device_classes/src/ux_device_class_dfu_state_sync.c new file mode 100644 index 00000000..c2e6e0de --- /dev/null +++ b/common/usbx_device_classes/src/ux_device_class_dfu_state_sync.c @@ -0,0 +1,97 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) Microsoft Corporation. All rights reserved. */ +/* */ +/* This software is licensed under the Microsoft Software License */ +/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +/* and in the root directory of this software. */ +/* */ +/**************************************************************************/ + +/**************************************************************************/ +/** */ +/** USBX Component */ +/** */ +/** Device DFU Class */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +#define UX_SOURCE_CODE + + +/* Include necessary system files. */ + +#include "ux_api.h" +#include "ux_device_class_dfu.h" +#include "ux_device_stack.h" + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _ux_device_class_dfu_state_sync PORTABLE C */ +/* 6.1.6 */ +/* AUTHOR */ +/* */ +/* Chaoqiong Xiao, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function syncs the USB DFU device state. */ +/* This allows application to move DFU state out of follow: */ +/* - dfuDNBUSY -> dfuDNLOAD-SYNC */ +/* - dfuMANIFEST -> dfuMANIFEST-SYNC */ +/* Other states will be kept. */ +/* Note the dfuDNBUSY and dfuMANIFEST is involved by returning busy */ +/* status in application ux_slave_class_dfu_get_status callback, and */ +/* needs application to issue ux_device_class_dfu_state_sync to go */ +/* out of the state. */ +/* */ +/* INPUT */ +/* */ +/* dfu Pointer to DFU instance */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* USBX Source Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 04-02-2021 Chaoqiong Xiao Initial Version 6.1.6 */ +/* */ +/**************************************************************************/ +VOID _ux_device_class_dfu_state_sync(UX_SLAVE_CLASS_DFU *dfu) +{ +UX_INTERRUPT_SAVE_AREA + + UX_PARAMETER_NOT_USED(dfu); + UX_DISABLE + switch(_ux_system_slave -> ux_system_slave_device_dfu_state_machine) + { + case UX_SLAVE_CLASS_DFU_STATUS_STATE_DFU_DNBUSY: + _ux_system_slave -> ux_system_slave_device_dfu_state_machine = + UX_SLAVE_CLASS_DFU_STATUS_STATE_DFU_DNLOAD_SYNC; + break; + case UX_SLAVE_CLASS_DFU_STATUS_STATE_DFU_MANIFEST: + _ux_system_slave -> ux_system_slave_device_dfu_state_machine = + UX_SLAVE_CLASS_DFU_STATUS_STATE_DFU_MANIFEST_SYNC; + break; + default: + break; + } + UX_RESTORE +} diff --git a/common/usbx_device_classes/src/ux_device_class_storage_thread.c b/common/usbx_device_classes/src/ux_device_class_storage_thread.c index 5f6983ac..5f189f6a 100644 --- a/common/usbx_device_classes/src/ux_device_class_storage_thread.c +++ b/common/usbx_device_classes/src/ux_device_class_storage_thread.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_device_class_storage_thread PORTABLE C */ -/* 6.1.3 */ +/* 6.1.6 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -103,6 +103,10 @@ /* 12-31-2020 Chaoqiong Xiao Modified comment(s), */ /* fixed USB CV test issues, */ /* resulting in version 6.1.3 */ +/* 04-02-2021 Chaoqiong Xiao Modified comment(s), */ +/* fixed compile issues with */ +/* some macro options, */ +/* resulting in version 6.1.6 */ /* */ /**************************************************************************/ VOID _ux_device_class_storage_thread(ULONG storage_class) @@ -351,9 +355,9 @@ UCHAR *cbw_cb; /* Special treatment of TOC command. If error, default to Stall endpoint. */ if (status == UX_SUCCESS) break; - /* fall through */ #endif + /* fall through */ default: /* The command is unknown or unsupported, so we stall the endpoint. */ diff --git a/common/usbx_host_classes/src/ux_host_class_storage_deactivate.c b/common/usbx_host_classes/src/ux_host_class_storage_deactivate.c index 4d136242..d28c9504 100644 --- a/common/usbx_host_classes/src/ux_host_class_storage_deactivate.c +++ b/common/usbx_host_classes/src/ux_host_class_storage_deactivate.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_host_class_storage_deactivate PORTABLE C */ -/* 6.1 */ +/* 6.1.6 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -82,6 +82,10 @@ /* class specific structured */ /* data, */ /* resulting in version 6.1 */ +/* 04-02-2021 Chaoqiong Xiao Modified comment(s), */ +/* fixed compile issues with */ +/* some macro options, */ +/* resulting in version 6.1.6 */ /* */ /**************************************************************************/ UINT _ux_host_class_storage_deactivate(UX_HOST_CLASS_COMMAND *command) @@ -133,9 +137,6 @@ VOID *memory; if (storage -> ux_host_class_storage_interrupt_endpoint != UX_NULL) { - /* Then interrupt endpoint. */ - transfer_request = &storage -> ux_host_class_storage_interrupt_endpoint -> ux_endpoint_transfer_request; - /* Abort the data transfer on the interrupt endpoint. */ _ux_host_stack_endpoint_transfer_abort(storage -> ux_host_class_storage_interrupt_endpoint); diff --git a/common/usbx_host_controllers/src/ux_hcd_ehci_interrupt_endpoint_create.c b/common/usbx_host_controllers/src/ux_hcd_ehci_interrupt_endpoint_create.c index e57dd139..488c54fb 100755 --- a/common/usbx_host_controllers/src/ux_hcd_ehci_interrupt_endpoint_create.c +++ b/common/usbx_host_controllers/src/ux_hcd_ehci_interrupt_endpoint_create.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_hcd_ehci_interrupt_endpoint_create PORTABLE C */ -/* 6.1.2 */ +/* 6.1.6 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -96,6 +96,11 @@ /* 11-09-2020 Chaoqiong Xiao Modified comment(s), */ /* fixed compile warnings, */ /* resulting in version 6.1.2 */ +/* 04-02-2021 Chaoqiong Xiao Modified comment(s), */ +/* fixed compile issues with */ +/* some macro options, */ +/* filled max transfer length, */ +/* resulting in version 6.1.6 */ /* */ /**************************************************************************/ UINT _ux_hcd_ehci_interrupt_endpoint_create(UX_HCD_EHCI *hcd_ehci, UX_ENDPOINT *endpoint) @@ -131,6 +136,10 @@ UINT i; return(UX_FUNCTION_NOT_SUPPORTED); #endif + /* We need to take into account the nature of the HCD to define the max size + of any transfer in the transfer request. */ + endpoint -> ux_endpoint_transfer_request.ux_transfer_request_maximum_length = UX_EHCI_MAX_PAYLOAD; + /* Obtain a ED for this new endpoint. This ED will live as long as the endpoint is active and will be the container for the tds. */ ed = _ux_hcd_ehci_ed_obtain(hcd_ehci); @@ -331,7 +340,7 @@ UINT i; } /* Reserve count for SSplit (Max 16). */ - ed_anchor -> ux_ehci_ed_microframe_ssplit_count[i] ++; + ed_anchor ->REF_AS.ANCHOR.ux_ehci_ed_microframe_ssplit_count[i] ++; /* Reserve packet bytes for microframe load. */ if (endpoint -> ux_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION) diff --git a/common/usbx_host_controllers/src/ux_hcd_ehci_interrupt_endpoint_destroy.c b/common/usbx_host_controllers/src/ux_hcd_ehci_interrupt_endpoint_destroy.c index 9b996688..822c7bcb 100755 --- a/common/usbx_host_controllers/src/ux_hcd_ehci_interrupt_endpoint_destroy.c +++ b/common/usbx_host_controllers/src/ux_hcd_ehci_interrupt_endpoint_destroy.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_hcd_ehci_interrupt_endpoint_destroy PORTABLE C */ -/* 6.1.2 */ +/* 6.1.6 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -75,6 +75,10 @@ /* 11-09-2020 Chaoqiong Xiao Modified comment(s), */ /* fixed compile warnings, */ /* resulting in version 6.1.2 */ +/* 04-02-2021 Chaoqiong Xiao Modified comment(s), */ +/* fixed compile issues with */ +/* some macro options, */ +/* resulting in version 6.1.6 */ /* */ /**************************************************************************/ UINT _ux_hcd_ehci_interrupt_endpoint_destroy(UX_HCD_EHCI *hcd_ehci, UX_ENDPOINT *endpoint) @@ -157,7 +161,7 @@ ULONG max_packet_size; { /* Decrement the start split count. */ - ed -> REF_AS.INTR.ux_ehci_ed_anchor -> ux_ehci_ed_microframe_ssplit_count[frindex] --; + ed -> REF_AS.INTR.ux_ehci_ed_anchor -> REF_AS.ANCHOR.ux_ehci_ed_microframe_ssplit_count[frindex] --; /* Check next endpoint if it's IN (load in C-Mask). */ if (endpoint -> ux_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION) diff --git a/common/usbx_host_controllers/src/ux_hcd_ehci_isochronous_endpoint_create.c b/common/usbx_host_controllers/src/ux_hcd_ehci_isochronous_endpoint_create.c index 2c594c24..29dd2512 100755 --- a/common/usbx_host_controllers/src/ux_hcd_ehci_isochronous_endpoint_create.c +++ b/common/usbx_host_controllers/src/ux_hcd_ehci_isochronous_endpoint_create.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_hcd_ehci_isochronous_endpoint_create PORTABLE C */ -/* 6.1.2 */ +/* 6.1.6 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -79,6 +79,11 @@ /* 11-09-2020 Chaoqiong Xiao Modified comment(s), */ /* fixed compile warnings, */ /* resulting in version 6.1.2 */ +/* 04-02-2021 Chaoqiong Xiao Modified comment(s), */ +/* fixed compile issues with */ +/* some macro options, */ +/* filled max transfer length, */ +/* resulting in version 6.1.6 */ /* */ /**************************************************************************/ UINT _ux_hcd_ehci_isochronous_endpoint_create(UX_HCD_EHCI *hcd_ehci, UX_ENDPOINT *endpoint) @@ -158,6 +163,10 @@ UINT status; /* Get max transfer size. */ max_trans_size = max_packet_size * mult; + /* We need to take into account the nature of the HCD to define the max size + of any transfer in the transfer request. */ + endpoint -> ux_endpoint_transfer_request.ux_transfer_request_maximum_length = max_trans_size; + /* Get the Endpt, Device Address, I/O, Maximum Packet Size, Mult. */ endpt = (endpoint -> ux_endpoint_descriptor.bEndpointAddress << UX_EHCI_HSISO_ENDPT_SHIFT) & UX_EHCI_HSISO_ENDPT_MASK; device_address = device -> ux_device_address & UX_EHCI_HSISO_DEVICE_ADDRESS_MASK; @@ -430,7 +439,7 @@ UINT status; ed_anchor -> REF_AS.ANCHOR.ux_ehci_ed_microframe_load[i] = (USHORT)(ed_anchor -> REF_AS.ANCHOR.ux_ehci_ed_microframe_load[i] + 188u); /* Increment SSplit count. */ - ed_anchor -> ux_ehci_ed_microframe_ssplit_count[i] ++; + ed_anchor -> REF_AS.ANCHOR.ux_ehci_ed_microframe_ssplit_count[i] ++; } } else @@ -481,7 +490,7 @@ UINT status; } /* Increment SSplit count. */ - ed_anchor -> ux_ehci_ed_microframe_ssplit_count[i] ++; + ed_anchor -> REF_AS.ANCHOR.ux_ehci_ed_microframe_ssplit_count[i] ++; } } diff --git a/common/usbx_host_controllers/src/ux_hcd_ehci_isochronous_endpoint_destroy.c b/common/usbx_host_controllers/src/ux_hcd_ehci_isochronous_endpoint_destroy.c index bc5c15fe..92c3bf0a 100755 --- a/common/usbx_host_controllers/src/ux_hcd_ehci_isochronous_endpoint_destroy.c +++ b/common/usbx_host_controllers/src/ux_hcd_ehci_isochronous_endpoint_destroy.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_hcd_ehci_isochronous_endpoint_destroy PORTABLE C */ -/* 6.1.2 */ +/* 6.1.6 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -75,6 +75,10 @@ /* 11-09-2020 Chaoqiong Xiao Modified comment(s), */ /* fixed compile warnings, */ /* resulting in version 6.1.2 */ +/* 04-02-2021 Chaoqiong Xiao Modified comment(s), */ +/* fixed compile issues with */ +/* some macro options, */ +/* resulting in version 6.1.6 */ /* */ /**************************************************************************/ UINT _ux_hcd_ehci_isochronous_endpoint_destroy(UX_HCD_EHCI *hcd_ehci, UX_ENDPOINT *endpoint) @@ -221,7 +225,7 @@ ULONG last_size; { /* Update start split count. */ - ed_td.sitd_ptr -> ux_ehci_fsiso_td_anchor -> ux_ehci_ed_microframe_ssplit_count[frindex] --; + ed_td.sitd_ptr -> ux_ehci_fsiso_td_anchor -> REF_AS.ANCHOR.ux_ehci_ed_microframe_ssplit_count[frindex] --; /* Update load for OUT. */ if ((endpoint -> ux_endpoint_descriptor.bEndpointAddress & UX_ENDPOINT_DIRECTION) == 0) @@ -231,19 +235,19 @@ ULONG last_size; last_size = max_packet_size % 188; if (last_size == 0 && frindex == last_frindex) - ed_td.sitd_ptr -> ux_ehci_fsiso_td_anchor -> ux_ehci_ed_microframe_load[frindex] = (USHORT) - (ed_td.sitd_ptr -> ux_ehci_fsiso_td_anchor -> ux_ehci_ed_microframe_load[frindex] - last_size); + ed_td.sitd_ptr -> ux_ehci_fsiso_td_anchor -> REF_AS.ANCHOR.ux_ehci_ed_microframe_load[frindex] = (USHORT) + (ed_td.sitd_ptr -> ux_ehci_fsiso_td_anchor -> REF_AS.ANCHOR.ux_ehci_ed_microframe_load[frindex] - last_size); else - ed_td.sitd_ptr -> ux_ehci_fsiso_td_anchor -> ux_ehci_ed_microframe_load[frindex] = (USHORT) - (ed_td.sitd_ptr -> ux_ehci_fsiso_td_anchor -> ux_ehci_ed_microframe_load[frindex] - 188u); + ed_td.sitd_ptr -> ux_ehci_fsiso_td_anchor -> REF_AS.ANCHOR.ux_ehci_ed_microframe_load[frindex] = (USHORT) + (ed_td.sitd_ptr -> ux_ehci_fsiso_td_anchor -> REF_AS.ANCHOR.ux_ehci_ed_microframe_load[frindex] - 188u); } } /* Update complete split related (IN only). */ if (ed_td.sitd_ptr -> ux_ehci_fsiso_td_cap1 & (UX_EHCI_CMASK_0 << frindex)) - ed_td.sitd_ptr -> ux_ehci_fsiso_td_anchor -> ux_ehci_ed_microframe_load[frindex] = (USHORT) - (ed_td.sitd_ptr -> ux_ehci_fsiso_td_anchor -> ux_ehci_ed_microframe_load[frindex] - 188u); + ed_td.sitd_ptr -> ux_ehci_fsiso_td_anchor -> REF_AS.ANCHOR.ux_ehci_ed_microframe_load[frindex] = (USHORT) + (ed_td.sitd_ptr -> ux_ehci_fsiso_td_anchor -> REF_AS.ANCHOR.ux_ehci_ed_microframe_load[frindex] - 188u); } } else diff --git a/common/usbx_host_controllers/src/ux_hcd_ehci_least_traffic_list_get.c b/common/usbx_host_controllers/src/ux_hcd_ehci_least_traffic_list_get.c index 8611ef20..62977629 100755 --- a/common/usbx_host_controllers/src/ux_hcd_ehci_least_traffic_list_get.c +++ b/common/usbx_host_controllers/src/ux_hcd_ehci_least_traffic_list_get.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_hcd_ehci_least_traffic_list_get PORTABLE C */ -/* 6.1.2 */ +/* 6.1.6 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -75,6 +75,10 @@ /* 11-09-2020 Chaoqiong Xiao Modified comment(s), */ /* fixed compile warnings, */ /* resulting in version 6.1.2 */ +/* 04-02-2021 Chaoqiong Xiao Modified comment(s), */ +/* fixed compile issues with */ +/* some macro options, */ +/* resulting in version 6.1.6 */ /* */ /**************************************************************************/ UX_EHCI_ED *_ux_hcd_ehci_least_traffic_list_get(UX_HCD_EHCI *hcd_ehci, @@ -132,7 +136,7 @@ ULONG bandwidth_used; { microframe_load[frindex] += ed -> REF_AS.ANCHOR.ux_ehci_ed_microframe_load[frindex]; #if defined(UX_HCD_EHCI_SPLIT_TRANSFER_ENABLE) - microframe_ssplit_count[frindex] += ed -> ux_ehci_ed_microframe_ssplit_count[frindex]; + microframe_ssplit_count[frindex] += ed -> REF_AS.ANCHOR.ux_ehci_ed_microframe_ssplit_count[frindex]; #endif } diff --git a/common/usbx_host_controllers/src/ux_hcd_ohci_interrupt_endpoint_create.c b/common/usbx_host_controllers/src/ux_hcd_ohci_interrupt_endpoint_create.c index 0deb9f5d..28df4d85 100644 --- a/common/usbx_host_controllers/src/ux_hcd_ohci_interrupt_endpoint_create.c +++ b/common/usbx_host_controllers/src/ux_hcd_ohci_interrupt_endpoint_create.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_hcd_ohci_interrupt_endpoint_create PORTABLE C */ -/* 6.1 */ +/* 6.1.6 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -91,6 +91,9 @@ /* fixed physical and virtual */ /* address conversion, */ /* resulting in version 6.1 */ +/* 04-02-2021 Chaoqiong Xiao Modified comment(s), */ +/* filled max transfer length, */ +/* resulting in version 6.1.6 */ /* */ /**************************************************************************/ UINT _ux_hcd_ohci_interrupt_endpoint_create(UX_HCD_OHCI *hcd_ohci, UX_ENDPOINT *endpoint) @@ -123,9 +126,12 @@ UINT interval_ohci; /* Attach the ED to the endpoint container. */ endpoint -> ux_endpoint_ed = (VOID *) ed; - - /* Program the ED for subsequent transfers we need to set the following things: + /* We need to take into account the nature of the HCD to define the max size + of any transfer in the transfer request. */ + endpoint -> ux_endpoint_transfer_request.ux_transfer_request_maximum_length = UX_OHCI_MAX_PAYLOAD; + + /* Program the ED for subsequent transfers we need to set the following things: 1) Address of the device 2) endpoint number 3) speed diff --git a/common/usbx_host_controllers/src/ux_hcd_ohci_isochronous_endpoint_create.c b/common/usbx_host_controllers/src/ux_hcd_ohci_isochronous_endpoint_create.c index 2c342d2d..6abc362d 100644 --- a/common/usbx_host_controllers/src/ux_hcd_ohci_isochronous_endpoint_create.c +++ b/common/usbx_host_controllers/src/ux_hcd_ohci_isochronous_endpoint_create.c @@ -35,7 +35,7 @@ /* FUNCTION RELEASE */ /* */ /* _ux_hcd_ohci_isochronous_endpoint_create PORTABLE C */ -/* 6.1 */ +/* 6.1.6 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ @@ -71,6 +71,9 @@ /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */ /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */ /* resulting in version 6.1 */ +/* 04-02-2021 Chaoqiong Xiao Modified comment(s), */ +/* filled max transfer length, */ +/* resulting in version 6.1.6 */ /* */ /**************************************************************************/ UINT _ux_hcd_ohci_isochronous_endpoint_create(UX_HCD_OHCI *hcd_ohci, UX_ENDPOINT *endpoint) @@ -102,9 +105,13 @@ UX_OHCI_ISO_TD *td; /* Attach the ED to the endpoint container. */ endpoint -> ux_endpoint_ed = (VOID *) ed; - - /* Program the ED for subsequent transfers we need to set the following things: + /* We need to take into account the nature of the HCD to define the max size + of any transfer in the transfer request. */ + endpoint -> ux_endpoint_transfer_request.ux_transfer_request_maximum_length = + endpoint -> ux_endpoint_descriptor.wMaxPacketSize; + + /* Program the ED for subsequent transfers we need to set the following things: 1) Address of the device 2) endpoint number 3) speed (always full speed for iso)