summaryrefslogtreecommitdiff
path: root/common/usbx_device_classes
diff options
context:
space:
mode:
authorTiejun Zhou <[email protected]>2022-10-26 23:43:22 +0000
committerTiejun Zhou <[email protected]>2022-10-26 23:43:22 +0000
commit232e89f35b3714d735e3d44c33c0cf419de74504 (patch)
tree567402c81a7208f55fea445c3599e3110c8aa361 /common/usbx_device_classes
parentcd55ec74569aa3fbfbd8f02d025a47c5a51a285a (diff)
Release 6.2.0v6.2.0_rel
Diffstat (limited to 'common/usbx_device_classes')
-rw-r--r--common/usbx_device_classes/CMakeLists.txt10
-rw-r--r--common/usbx_device_classes/inc/ux_device_class_audio.h49
-rw-r--r--common/usbx_device_classes/inc/ux_device_class_cdc_ecm.h14
-rw-r--r--common/usbx_device_classes/inc/ux_device_class_printer.h42
-rw-r--r--common/usbx_device_classes/inc/ux_device_class_rndis.h18
-rw-r--r--common/usbx_device_classes/inc/ux_device_class_video.h26
-rw-r--r--common/usbx_device_classes/src/ux_device_class_audio_activate.c11
-rw-r--r--common/usbx_device_classes/src/ux_device_class_audio_change.c21
-rw-r--r--common/usbx_device_classes/src/ux_device_class_audio_feedback_task_function.c164
-rw-r--r--common/usbx_device_classes/src/ux_device_class_audio_feedback_thread_entry.c11
-rw-r--r--common/usbx_device_classes/src/ux_device_class_audio_initialize.c58
-rw-r--r--common/usbx_device_classes/src/ux_device_class_audio_interrupt_send.c11
-rw-r--r--common/usbx_device_classes/src/ux_device_class_audio_interrupt_task_function.c198
-rw-r--r--common/usbx_device_classes/src/ux_device_class_audio_read_task_function.c188
-rw-r--r--common/usbx_device_classes/src/ux_device_class_audio_read_thread_entry.c7
-rw-r--r--common/usbx_device_classes/src/ux_device_class_audio_reception_start.c13
-rw-r--r--common/usbx_device_classes/src/ux_device_class_audio_tasks_run.c153
-rw-r--r--common/usbx_device_classes/src/ux_device_class_audio_transmission_start.c13
-rw-r--r--common/usbx_device_classes/src/ux_device_class_audio_write_task_function.c210
-rw-r--r--common/usbx_device_classes/src/ux_device_class_audio_write_thread_entry.c11
-rw-r--r--common/usbx_device_classes/src/ux_device_class_cdc_acm_read_run.c7
-rw-r--r--common/usbx_device_classes/src/ux_device_class_cdc_acm_tasks_run.c15
-rw-r--r--common/usbx_device_classes/src/ux_device_class_cdc_acm_write_run.c9
-rw-r--r--common/usbx_device_classes/src/ux_device_class_cdc_ecm_bulkin_thread.c31
-rw-r--r--common/usbx_device_classes/src/ux_device_class_cdc_ecm_bulkout_thread.c76
-rw-r--r--common/usbx_device_classes/src/ux_device_class_cdc_ecm_initialize.c34
-rw-r--r--common/usbx_device_classes/src/ux_device_class_cdc_ecm_uninitialize.c11
-rw-r--r--[-rwxr-xr-x]common/usbx_device_classes/src/ux_device_class_hid_control_request.c0
-rw-r--r--common/usbx_device_classes/src/ux_device_class_hid_initialize.c10
-rw-r--r--common/usbx_device_classes/src/ux_device_class_printer_initialize.c17
-rw-r--r--common/usbx_device_classes/src/ux_device_class_printer_read_run.c238
-rw-r--r--common/usbx_device_classes/src/ux_device_class_printer_soft_reset.c11
-rw-r--r--common/usbx_device_classes/src/ux_device_class_printer_uninitialize.c9
-rw-r--r--common/usbx_device_classes/src/ux_device_class_printer_write_run.c258
-rw-r--r--common/usbx_device_classes/src/ux_device_class_rndis_bulkin_thread.c44
-rw-r--r--common/usbx_device_classes/src/ux_device_class_rndis_bulkout_thread.c119
-rw-r--r--common/usbx_device_classes/src/ux_device_class_rndis_initialize.c38
-rw-r--r--common/usbx_device_classes/src/ux_device_class_storage_tasks_run.c24
-rw-r--r--common/usbx_device_classes/src/ux_device_class_video_activate.c13
-rw-r--r--common/usbx_device_classes/src/ux_device_class_video_change.c14
-rw-r--r--common/usbx_device_classes/src/ux_device_class_video_initialize.c28
-rw-r--r--common/usbx_device_classes/src/ux_device_class_video_read_task_function.c188
-rw-r--r--common/usbx_device_classes/src/ux_device_class_video_read_thread_entry.c6
-rw-r--r--common/usbx_device_classes/src/ux_device_class_video_reception_start.c19
-rw-r--r--common/usbx_device_classes/src/ux_device_class_video_tasks_run.c113
-rw-r--r--common/usbx_device_classes/src/ux_device_class_video_transmission_start.c22
-rw-r--r--common/usbx_device_classes/src/ux_device_class_video_write_task_function.c209
-rw-r--r--common/usbx_device_classes/src/ux_device_class_video_write_thread_entry.c11
48 files changed, 2546 insertions, 256 deletions
diff --git a/common/usbx_device_classes/CMakeLists.txt b/common/usbx_device_classes/CMakeLists.txt
index f3c3867..5291d4b 100644
--- a/common/usbx_device_classes/CMakeLists.txt
+++ b/common/usbx_device_classes/CMakeLists.txt
@@ -10,14 +10,17 @@ target_sources(${PROJECT_NAME} PRIVATE
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_audio_feedback_get.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_audio_feedback_set.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_audio_feedback_thread_entry.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_audio_feedback_task_function.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_audio_frame_write.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_audio_initialize.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_audio_interrupt_send.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_audio_interrupt_thread_entry.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_audio_interrupt_task_function.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_audio_ioctl.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_audio_read_frame_free.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_audio_read_frame_get.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_audio_read_thread_entry.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_audio_read_task_function.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_audio_reception_start.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_audio_sample_read16.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_audio_sample_read24.c
@@ -30,6 +33,8 @@ target_sources(${PROJECT_NAME} PRIVATE
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_audio_write_frame_commit.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_audio_write_frame_get.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_audio_write_thread_entry.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_audio_write_task_function.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_audio_tasks_run.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_ccid_activate.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_ccid_auto_seq_done.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_ccid_auto_seq_start.c
@@ -144,9 +149,11 @@ target_sources(${PROJECT_NAME} PRIVATE
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_printer_initialize.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_printer_ioctl.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_printer_read.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_printer_read_run.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_printer_soft_reset.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_printer_uninitialize.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_printer_write.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_printer_write_run.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_rndis_activate.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_rndis_bulkin_thread.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_rndis_bulkout_thread.c
@@ -201,13 +208,16 @@ target_sources(${PROJECT_NAME} PRIVATE
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_video_max_payload_get.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_video_read_payload_free.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_video_read_payload_get.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_video_read_task_function.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_video_read_thread_entry.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_video_reception_start.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_video_stream_get.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_video_tasks_run.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_video_transmission_start.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_video_uninitialize.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_video_write_payload_commit.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_video_write_payload_get.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_video_write_task_function.c
${CMAKE_CURRENT_LIST_DIR}/src/ux_device_class_video_write_thread_entry.c
# {{END_TARGET_SOURCES}}
diff --git a/common/usbx_device_classes/inc/ux_device_class_audio.h b/common/usbx_device_classes/inc/ux_device_class_audio.h
index 8ce47fa..4cc5be3 100644
--- a/common/usbx_device_classes/inc/ux_device_class_audio.h
+++ b/common/usbx_device_classes/inc/ux_device_class_audio.h
@@ -26,7 +26,7 @@
/* COMPONENT DEFINITION RELEASE */
/* */
/* ux_device_class_audio.h PORTABLE C */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -59,6 +59,9 @@
/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */
/* added interrupt support, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Yajun Xia Modified comment(s), */
+/* added standalone support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
@@ -310,6 +313,17 @@ extern "C" {
#define UX_DEVICE_CLASS_AUDIO_IOCTL_GET_ARG 1
+/* Define Audio Class Task states. */
+#define UX_DEVICE_CLASS_AUDIO_INTERRUPT_STOP (UX_STATE_RESET)
+#define UX_DEVICE_CLASS_AUDIO_INTERRUPT_START (UX_STATE_STEP + 1)
+#define UX_DEVICE_CLASS_AUDIO_INTERRUPT_WAIT (UX_STATE_STEP + 2)
+
+#define UX_DEVICE_CLASS_AUDIO_STREAM_RW_STOP (UX_STATE_RESET)
+#define UX_DEVICE_CLASS_AUDIO_STREAM_RW_START (UX_STATE_STEP + 1)
+#define UX_DEVICE_CLASS_AUDIO_STREAM_RW_WAIT (UX_STATE_STEP + 2)
+
+#define UX_DEVICE_CLASS_AUDIO_STREAM_FEEDBACK_RW_STOP (UX_STATE_RESET)
+#define UX_DEVICE_CLASS_AUDIO_STREAM_FEEDBACK_RW_WAIT (UX_STATE_STEP + 1)
/* Define Audio Class callback structure. */
@@ -336,11 +350,20 @@ typedef struct UX_DEVICE_CLASS_AUDIO_STREAM_CALLBACKS_STRUCT
typedef struct UX_DEVICE_CLASS_AUDIO_STREAM_PARAMETER_STRUCT
{
+#if !defined(UX_DEVICE_STANDALONE)
ULONG ux_device_class_audio_stream_parameter_thread_stack_size;
VOID (*ux_device_class_audio_stream_parameter_thread_entry)(ULONG id);
+#else
+ UINT (*ux_device_class_audio_stream_parameter_task_function)(struct UX_DEVICE_CLASS_AUDIO_STREAM_STRUCT*);
+#endif
+
#if defined(UX_DEVICE_CLASS_AUDIO_FEEDBACK_SUPPORT)
+#if !defined(UX_DEVICE_STANDALONE)
ULONG ux_device_class_audio_stream_parameter_feedback_thread_stack_size;
VOID (*ux_device_class_audio_stream_parameter_feedback_thread_entry)(ULONG id);
+#else
+ UINT (*ux_device_class_audio_stream_parameter_feedback_task_function)(struct UX_DEVICE_CLASS_AUDIO_STREAM_STRUCT*);
+#endif
#endif
UX_DEVICE_CLASS_AUDIO_STREAM_CALLBACKS ux_device_class_audio_stream_parameter_callbacks;
@@ -386,6 +409,10 @@ typedef struct UX_DEVICE_CLASS_AUDIO_STREAM_STRUCT
#if !defined(UX_DEVICE_STANDALONE)
UCHAR *ux_device_class_audio_stream_feedback_thread_stack;
UX_THREAD ux_device_class_audio_stream_feedback_thread;
+#else
+ UINT (*ux_device_class_audio_stream_feedback_task_function)(struct UX_DEVICE_CLASS_AUDIO_STREAM_STRUCT*);
+ UINT ux_device_class_audio_stream_feedback_task_state;
+ UINT ux_device_class_audio_stream_feedback_task_status;
#endif
#endif
@@ -394,11 +421,16 @@ typedef struct UX_DEVICE_CLASS_AUDIO_STREAM_STRUCT
#if !defined(UX_DEVICE_STANDALONE)
UCHAR *ux_device_class_audio_stream_thread_stack;
UX_THREAD ux_device_class_audio_stream_thread;
+#else
+ UINT (*ux_device_class_audio_stream_task_function)(struct UX_DEVICE_CLASS_AUDIO_STREAM_STRUCT*);
+ UINT ux_device_class_audio_stream_task_state;
+ UINT ux_device_class_audio_stream_task_status;
#endif
UCHAR *ux_device_class_audio_stream_buffer;
ULONG ux_device_class_audio_stream_buffer_size;
ULONG ux_device_class_audio_stream_frame_buffer_size;
+ ULONG ux_device_class_audio_stream_buffer_error_count;
UX_DEVICE_CLASS_AUDIO_FRAME *ux_device_class_audio_stream_transfer_pos;
UX_DEVICE_CLASS_AUDIO_FRAME *ux_device_class_audio_stream_access_pos;
@@ -429,6 +461,9 @@ typedef struct UX_DEVICE_CLASS_AUDIO_STRUCT
#if !defined(UX_DEVICE_STANDALONE)
UX_SEMAPHORE ux_device_class_audio_status_semaphore;
UX_MUTEX ux_device_class_audio_status_mutex;
+#else
+ UINT ux_device_class_audio_interrupt_task_state;
+ UINT ux_device_class_audio_interrupt_task_status;
#endif
#endif
} UX_DEVICE_CLASS_AUDIO;
@@ -452,7 +487,8 @@ UINT _ux_device_class_audio_stream_get(UX_DEVICE_CLASS_AUDIO *audio, ULONG st
VOID _ux_device_class_audio_write_thread_entry(ULONG audio_stream);
VOID _ux_device_class_audio_read_thread_entry(ULONG audio_stream);
-
+UINT _ux_device_class_audio_write_task_function(UX_DEVICE_CLASS_AUDIO_STREAM *stream);
+UINT _ux_device_class_audio_read_task_function(UX_DEVICE_CLASS_AUDIO_STREAM *stream);
UINT _ux_device_class_audio_reception_start(UX_DEVICE_CLASS_AUDIO_STREAM *audio);
UINT _ux_device_class_audio_sample_read8(UX_DEVICE_CLASS_AUDIO_STREAM *audio, UCHAR *sample);
UINT _ux_device_class_audio_sample_read16(UX_DEVICE_CLASS_AUDIO_STREAM *audio, USHORT *sample);
@@ -469,13 +505,18 @@ UINT _ux_device_class_audio_write_frame_get(UX_DEVICE_CLASS_AUDIO_STREAM *aud
UINT _ux_device_class_audio_write_frame_commit(UX_DEVICE_CLASS_AUDIO_STREAM *audio, ULONG length);
VOID _ux_device_class_audio_feedback_thread_entry(ULONG audio_stream);
+UINT _ux_device_class_audio_feedback_task_function(UX_DEVICE_CLASS_AUDIO_STREAM *stream);
UINT _ux_device_class_audio_feedback_set(UX_DEVICE_CLASS_AUDIO_STREAM *audio, UCHAR *encoded_feedback);
UINT _ux_device_class_audio_feedback_get(UX_DEVICE_CLASS_AUDIO_STREAM *audio, UCHAR *encoded_feedback);
ULONG _ux_device_class_audio_speed_get(UX_DEVICE_CLASS_AUDIO_STREAM *audio);
VOID _ux_device_class_audio_interrupt_thread_entry(ULONG audio_inst);
+UINT _ux_device_class_audio_interrupt_task_function(UX_DEVICE_CLASS_AUDIO *audio);
UINT _ux_device_class_audio_interrupt_send(UX_DEVICE_CLASS_AUDIO *audio, UCHAR *int_data);
+#if defined(UX_DEVICE_STANDALONE)
+UINT _ux_device_class_audio_tasks_run(VOID *instance);
+#endif
/* Define Device Class Audio API prototypes. */
@@ -484,6 +525,9 @@ UINT _ux_device_class_audio_interrupt_send(UX_DEVICE_CLASS_AUDIO *audio, UCHA
#define ux_device_class_audio_read_thread_entry _ux_device_class_audio_read_thread_entry
#define ux_device_class_audio_write_thread_entry _ux_device_class_audio_write_thread_entry
+#define ux_device_class_audio_read_task_function _ux_device_class_audio_read_task_function
+#define ux_device_class_audio_write_task_function _ux_device_class_audio_write_task_function
+
#define ux_device_class_audio_stream_get _ux_device_class_audio_stream_get
#define ux_device_class_audio_reception_start _ux_device_class_audio_reception_start
@@ -505,6 +549,7 @@ UINT _ux_device_class_audio_interrupt_send(UX_DEVICE_CLASS_AUDIO *audio, UCHA
#define ux_device_class_audio_speed_get _ux_device_class_audio_speed_get
#define ux_device_class_audio_feedback_thread_entry _ux_device_class_audio_feedback_thread_entry
+#define ux_device_class_audio_feedback_task_function _ux_device_class_audio_feedback_task_function
#define ux_device_class_audio_feedback_get _ux_device_class_audio_feedback_get
#define ux_device_class_audio_feedback_set _ux_device_class_audio_feedback_set
diff --git a/common/usbx_device_classes/inc/ux_device_class_cdc_ecm.h b/common/usbx_device_classes/inc/ux_device_class_cdc_ecm.h
index 3f662d8..54f3ac7 100644
--- a/common/usbx_device_classes/inc/ux_device_class_cdc_ecm.h
+++ b/common/usbx_device_classes/inc/ux_device_class_cdc_ecm.h
@@ -24,7 +24,7 @@
/* COMPONENT DEFINITION RELEASE */
/* */
/* ux_device_class_cdc_ecm.h PORTABLE C */
-/* 6.1.11 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -52,6 +52,9 @@
/* 04-25-2022 Chaoqiong Xiao Modified comment(s), */
/* fixed standalone compile, */
/* resulting in version 6.1.11 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* added wait definitions, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
@@ -274,6 +277,12 @@ VOID _ux_network_driver_link_down(VOID *ux_network_handle);
#define UX_DEVICE_CLASS_CDC_ECM_PACKET_POOL_WAIT 1000
#endif
+#ifndef UX_DEVICE_CLASS_CDC_ECM_PACKET_POOL_INST_WAIT
+#define UX_DEVICE_CLASS_CDC_ECM_PACKET_POOL_INST_WAIT 1000
+#endif
+
+#define UX_DEVICE_CLASS_CDC_ECM_LINK_CHECK_WAIT 10
+
/* Define Slave CDC_ECM Class Calling Parameter structure */
typedef struct UX_SLAVE_CLASS_CDC_ECM_PARAMETER_STRUCT
@@ -316,7 +325,6 @@ typedef struct UX_SLAVE_CLASS_CDC_ECM_STRUCT
UCHAR ux_slave_class_cdc_ecm_remote_node_id[UX_DEVICE_CLASS_CDC_ECM_NODE_ID_LENGTH];
ULONG ux_slave_class_cdc_ecm_nx_ip_address;
ULONG ux_slave_class_cdc_ecm_nx_ip_network_mask;
- UCHAR *ux_slave_class_cdc_ecm_pool_memory;
#if !defined(UX_DEVICE_STANDALONE)
NX_IP *ux_slave_class_cdc_ecm_nx_ip;
@@ -324,7 +332,7 @@ typedef struct UX_SLAVE_CLASS_CDC_ECM_STRUCT
NX_PACKET *ux_slave_class_cdc_ecm_xmit_queue;
NX_PACKET *ux_slave_class_cdc_ecm_xmit_queue_tail;
NX_PACKET *ux_slave_class_cdc_ecm_receive_queue;
- NX_PACKET_POOL ux_slave_class_cdc_ecm_packet_pool;
+ NX_PACKET_POOL *ux_slave_class_cdc_ecm_packet_pool;
#endif
#if !defined(UX_DEVICE_STANDALONE)
diff --git a/common/usbx_device_classes/inc/ux_device_class_printer.h b/common/usbx_device_classes/inc/ux_device_class_printer.h
index a77aff5..52ae8ce 100644
--- a/common/usbx_device_classes/inc/ux_device_class_printer.h
+++ b/common/usbx_device_classes/inc/ux_device_class_printer.h
@@ -24,7 +24,7 @@
/* COMPONENT DEFINITION RELEASE */
/* */
/* ux_device_class_printer.h PORTABLE C */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -44,6 +44,9 @@
/* resulting in version 6.1.11 */
/* 07-29-2022 Chaoqiong Xiao Modified comment(s), */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Yajun xia Modified comment(s), */
+/* added standalone support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
@@ -92,6 +95,16 @@ extern "C" {
#define UX_DEVICE_CLASS_PRINTER_IOCTL_READ_TIMEOUT_SET 2
#define UX_DEVICE_CLASS_PRINTER_IOCTL_WRITE_TIMEOUT_SET 3
+#if defined(UX_DEVICE_STANDALONE)
+
+/* Printer read state machine states. */
+#define UX_DEVICE_CLASS_PRINTER_READ_START (UX_STATE_STEP + 1)
+#define UX_DEVICE_CLASS_PRINTER_READ_WAIT (UX_STATE_STEP + 2)
+
+/* Printer write state machine states. */
+#define UX_DEVICE_CLASS_PRINTER_WRITE_START (UX_STATE_STEP + 1)
+#define UX_DEVICE_CLASS_PRINTER_WRITE_WAIT (UX_STATE_STEP + 2)
+#endif
/* Define Device Printer Class Calling Parameter structure */
@@ -117,6 +130,21 @@ typedef struct UX_DEVICE_CLASS_PRINTER_STRUCT
#if !defined(UX_DEVICE_STANDALONE)
UX_MUTEX ux_device_class_printer_endpoint_out_mutex;
UX_MUTEX ux_device_class_printer_endpoint_in_mutex;
+#else
+ UCHAR *ux_device_class_printer_read_buffer;
+ ULONG ux_device_class_printer_read_requested_length;
+ ULONG ux_device_class_printer_read_transfer_length;
+ ULONG ux_device_class_printer_read_actual_length;
+ UINT ux_device_class_printer_read_status;
+ UINT ux_device_class_printer_read_state;
+
+ UCHAR *ux_device_class_printer_write_buffer;
+ ULONG ux_device_class_printer_write_transfer_length;
+ ULONG ux_device_class_printer_write_host_length;
+ ULONG ux_device_class_printer_write_requested_length;
+ ULONG ux_device_class_printer_write_actual_length;
+ UINT ux_device_class_printer_write_status;
+ UINT ux_device_class_printer_write_state;
#endif
} UX_DEVICE_CLASS_PRINTER;
@@ -139,7 +167,12 @@ UINT _ux_device_class_printer_read(UX_DEVICE_CLASS_PRINTER *printer, UCHAR *buf
UINT _ux_device_class_printer_ioctl(UX_DEVICE_CLASS_PRINTER *printer, ULONG ioctl_function,
VOID *parameter);
-
+#if defined(UX_DEVICE_STANDALONE)
+UINT _ux_device_class_printer_write_run(UX_DEVICE_CLASS_PRINTER *printer, UCHAR *buffer,
+ ULONG requested_length, ULONG *actual_length);
+UINT _ux_device_class_printer_read_run(UX_DEVICE_CLASS_PRINTER *printer, UCHAR *buffer,
+ ULONG requested_length, ULONG *actual_length);
+#endif
/* Define Device Printer Class API prototypes. */
@@ -148,6 +181,11 @@ UINT _ux_device_class_printer_ioctl(UX_DEVICE_CLASS_PRINTER *printer, ULONG ioc
#define ux_device_class_printer_write _ux_device_class_printer_write
#define ux_device_class_printer_ioctl _ux_device_class_printer_ioctl
+#if defined(UX_DEVICE_STANDALONE)
+#define ux_device_class_printer_read_run _ux_device_class_printer_read_run
+#define ux_device_class_printer_write_run _ux_device_class_printer_write_run
+#endif
+
/* Determine if a C++ compiler is being used. If so, complete the standard
C conditional started above. */
#ifdef __cplusplus
diff --git a/common/usbx_device_classes/inc/ux_device_class_rndis.h b/common/usbx_device_classes/inc/ux_device_class_rndis.h
index 7ac55d8..abcd833 100644
--- a/common/usbx_device_classes/inc/ux_device_class_rndis.h
+++ b/common/usbx_device_classes/inc/ux_device_class_rndis.h
@@ -24,7 +24,7 @@
/* COMPONENT DEFINITION RELEASE */
/* */
/* ux_device_class_rndis.h PORTABLE C */
-/* 6.1.11 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -52,6 +52,9 @@
/* 04-25-2022 Chaoqiong Xiao Modified comment(s), */
/* fixed standalone compile, */
/* resulting in version 6.1.11 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* added wait and length DEFs, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
@@ -478,6 +481,16 @@ VOID _ux_network_driver_link_down(VOID *ux_network_handle);
#define UX_DEVICE_CLASS_RNDIS_PACKET_POOL_WAIT 10
#endif
+#ifndef UX_DEVICE_CLASS_RNDIS_PACKET_POOL_INST_WAIT
+#define UX_DEVICE_CLASS_RNDIS_PACKET_POOL_INST_WAIT 100
+#endif
+
+/* Calculate message buffer length (not overflow). */
+#define UX_DEVICE_CLASS_RNDIS_MAX_MSG_LENGTH (UX_DEVICE_CLASS_RNDIS_MAX_PACKET_LENGTH + UX_DEVICE_CLASS_RNDIS_PACKET_HEADER_LENGTH)
+#if UX_DEVICE_CLASS_RNDIS_MAX_MSG_LENGTH > UX_SLAVE_REQUEST_DATA_MAX_LENGTH
+#error "Error: the maximum-sized RNDIS response cannot fit inside the control endpoint's data buffer. Increase UX_SLAVE_REQUEST_DATA_MAX_LENGTH."
+#endif
+
/* Calculate response buffer length. */
#define UX_DEVICE_CLASS_RNDIS_OID_SUPPORTED_RESPONSE_LENGTH (UX_DEVICE_CLASS_RNDIS_CMPLT_QUERY_INFO_BUFFER + UX_DEVICE_CLASS_RNDIS_OID_SUPPORTED_LIST_LENGTH * 4)
#define UX_DEVICE_CLASS_RNDIS_VENDOR_DESCRIPTION_MAX_RESPONSE_LENGTH (UX_DEVICE_CLASS_RNDIS_CMPLT_QUERY_INFO_BUFFER + UX_DEVICE_CLASS_RNDIS_VENDOR_DESCRIPTION_MAX_LENGTH)
@@ -544,7 +557,6 @@ typedef struct UX_SLAVE_CLASS_RNDIS_STRUCT
ULONG ux_slave_class_rndis_statistics_xmit_more_collisions;
UCHAR ux_slave_class_rndis_local_node_id[UX_DEVICE_CLASS_RNDIS_NODE_ID_LENGTH];
UCHAR ux_slave_class_rndis_remote_node_id[UX_DEVICE_CLASS_RNDIS_NODE_ID_LENGTH];
- UCHAR *ux_slave_class_rndis_pool_memory;
ULONG ux_slave_class_rndis_nx_ip_address;
ULONG ux_slave_class_rndis_nx_ip_network_mask;
@@ -553,7 +565,7 @@ typedef struct UX_SLAVE_CLASS_RNDIS_STRUCT
NX_INTERFACE *ux_slave_class_rndis_nx_interface;
NX_PACKET *ux_slave_class_rndis_xmit_queue;
NX_PACKET *ux_slave_class_rndis_receive_queue;
- NX_PACKET_POOL ux_slave_class_rndis_packet_pool;
+ NX_PACKET_POOL *ux_slave_class_rndis_packet_pool;
#endif
#if !defined(UX_DEVICE_STANDALONE)
diff --git a/common/usbx_device_classes/inc/ux_device_class_video.h b/common/usbx_device_classes/inc/ux_device_class_video.h
index 4c6d3e8..9851532 100644
--- a/common/usbx_device_classes/inc/ux_device_class_video.h
+++ b/common/usbx_device_classes/inc/ux_device_class_video.h
@@ -26,7 +26,7 @@
/* COMPONENT DEFINITION RELEASE */
/* */
/* ux_device_class_video.h PORTABLE C */
-/* 6.1.11 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -41,6 +41,9 @@
/* DATE NAME DESCRIPTION */
/* */
/* 04-25-2022 Chaoqiong Xiao Initial Version 6.1.11 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* added standalone support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
@@ -508,6 +511,12 @@ typedef struct UX_DEVICE_CLASS_VIDEO_PAYLOAD_HEADER_STRUCT
#define UX_DEVICE_CLASS_VIDEO_STREAM_ERROR_CODE_STILL_IMAGE_CAPTURE_ERROR 7
+/* Define Video Class Task states. */
+#define UX_DEVICE_CLASS_VIDEO_STREAM_RW_STOP (UX_STATE_RESET)
+#define UX_DEVICE_CLASS_VIDEO_STREAM_RW_START (UX_STATE_STEP + 1)
+#define UX_DEVICE_CLASS_VIDEO_STREAM_RW_WAIT (UX_STATE_STEP + 2)
+
+
/* Define Video Class callback structure. */
struct UX_DEVICE_CLASS_VIDEO_STREAM_STRUCT;
@@ -541,8 +550,12 @@ typedef struct UX_DEVICE_CLASS_VIDEO_PAYLOAD_STRUCT
typedef struct UX_DEVICE_CLASS_VIDEO_STREAM_PARAMETER_STRUCT
{
+#if defined(UX_DEVICE_STANDALONE)
+ UINT (*ux_device_class_video_stream_parameter_task_function)(struct UX_DEVICE_CLASS_VIDEO_STREAM_STRUCT*);
+#else
ULONG ux_device_class_video_stream_parameter_thread_stack_size;
VOID (*ux_device_class_video_stream_parameter_thread_entry)(ULONG id);
+#endif
UX_DEVICE_CLASS_VIDEO_STREAM_CALLBACKS ux_device_class_video_stream_parameter_callbacks;
ULONG ux_device_class_video_stream_parameter_max_payload_buffer_size;
@@ -572,8 +585,13 @@ typedef struct UX_DEVICE_CLASS_VIDEO_STREAM_STRUCT
#if !defined(UX_DEVICE_STANDALONE)
UCHAR *ux_device_class_video_stream_thread_stack;
UX_THREAD ux_device_class_video_stream_thread;
+#else
+ UINT (*ux_device_class_video_stream_task_function)(struct UX_DEVICE_CLASS_VIDEO_STREAM_STRUCT*);
+ UINT ux_device_class_video_stream_task_state;
+ UINT ux_device_class_video_stream_task_status;
#endif
+ ULONG ux_device_class_video_stream_buffer_error_count;
UCHAR *ux_device_class_video_stream_buffer;
ULONG ux_device_class_video_stream_buffer_size;
ULONG ux_device_class_video_stream_payload_buffer_size;
@@ -636,6 +654,9 @@ UINT _ux_device_class_video_transmission_start(UX_DEVICE_CLASS_VIDEO_STREAM *
UINT _ux_device_class_video_write_payload_get(UX_DEVICE_CLASS_VIDEO_STREAM *video, UCHAR **buffer, ULONG *max_length);
UINT _ux_device_class_video_write_payload_commit(UX_DEVICE_CLASS_VIDEO_STREAM *video, ULONG length);
+UINT _ux_device_class_video_tasks_run(VOID *instance);
+UINT _ux_device_class_video_read_task_function(UX_DEVICE_CLASS_VIDEO_STREAM *stream);
+UINT _ux_device_class_video_write_task_function(UX_DEVICE_CLASS_VIDEO_STREAM *stream);
/* Define Video Class API prototypes. */
@@ -663,6 +684,9 @@ UINT _ux_device_class_video_write_payload_commit(UX_DEVICE_CLASS_VIDEO_STREAM
#define ux_device_class_video_ioctl _ux_device_class_video_ioctl
+#define ux_device_class_video_read_task_function _ux_device_class_video_read_task_function
+#define ux_device_class_video_write_task_function _ux_device_class_video_write_task_function
+
/* Determine if a C++ compiler is being used. If so, complete the standard
C conditional started above. */
diff --git a/common/usbx_device_classes/src/ux_device_class_audio_activate.c b/common/usbx_device_classes/src/ux_device_class_audio_activate.c
index 53163cf..2f9b89d 100644
--- a/common/usbx_device_classes/src/ux_device_class_audio_activate.c
+++ b/common/usbx_device_classes/src/ux_device_class_audio_activate.c
@@ -33,7 +33,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_audio_activate PORTABLE C */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -70,6 +70,9 @@
/* names conflict C++ keyword, */
/* added interrupt support, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Yajun Xia Modified comment(s), */
+/* added standalone support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_device_class_audio_activate(UX_SLAVE_CLASS_COMMAND *command)
@@ -166,6 +169,12 @@ ULONG stream_index;
/* Store the class instance into the interface. */
stream_interface -> ux_slave_interface_class_instance = (VOID *)audio;
+#if defined(UX_DEVICE_STANDALONE)
+
+ /* Reset stream task state. */
+ stream -> ux_device_class_audio_stream_task_state = UX_STATE_RESET;
+ stream -> ux_device_class_audio_stream_task_state = UX_SUCCESS;
+#endif
}
/* If there is a activate function call it. */
diff --git a/common/usbx_device_classes/src/ux_device_class_audio_change.c b/common/usbx_device_classes/src/ux_device_class_audio_change.c
index 35d4a3a..9ac4e67 100644
--- a/common/usbx_device_classes/src/ux_device_class_audio_change.c
+++ b/common/usbx_device_classes/src/ux_device_class_audio_change.c
@@ -33,7 +33,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_audio_change PORTABLE C */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -81,6 +81,9 @@
/* rx full packet for */
/* feedback, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Yajun Xia Modified comment(s), */
+/* added standalone support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_device_class_audio_change(UX_SLAVE_CLASS_COMMAND *command)
@@ -137,8 +140,9 @@ ULONG endpoint_dir;
/* Parse all endpoints. */
#if defined(UX_DEVICE_STANDALONE)
- /* Standalone mode not supported. */
- endpoint_dir = 0;
+ endpoint_dir = (stream -> ux_device_class_audio_stream_task_function ==
+ _ux_device_class_audio_read_task_function) ?
+ UX_ENDPOINT_OUT: UX_ENDPOINT_IN;
#else
endpoint_dir = (stream -> ux_device_class_audio_stream_thread.tx_thread_entry ==
@@ -229,6 +233,15 @@ ULONG endpoint_dir;
return(UX_DESCRIPTOR_CORRUPTED);
}
+#if defined(UX_DEVICE_STANDALONE)
+
+ /* Reset background transfer state. */
+ stream -> ux_device_class_audio_stream_task_state = UX_STATE_RESET;
+#endif
+
+ /* Now reset payload buffer error count. */
+ stream -> ux_device_class_audio_stream_buffer_error_count = 0;
+
/* Now reset frame buffers. */
frame_buffer = stream -> ux_device_class_audio_stream_buffer;
while(frame_buffer < stream -> ux_device_class_audio_stream_buffer + stream -> ux_device_class_audio_stream_buffer_size)
@@ -243,7 +256,7 @@ ULONG endpoint_dir;
}
stream -> ux_device_class_audio_stream_transfer_pos = stream -> ux_device_class_audio_stream_access_pos;
-#if defined(UX_DEVICE_CLASS_AUDIO_FEEDBACK_SUPPORT)
+#if defined(UX_DEVICE_CLASS_AUDIO_FEEDBACK_SUPPORT) && !defined(UX_DEVICE_STANDALONE)
/* If feedback supported, resume the thread. */
if (stream -> ux_device_class_audio_stream_feedback_thread_stack)
diff --git a/common/usbx_device_classes/src/ux_device_class_audio_feedback_task_function.c b/common/usbx_device_classes/src/ux_device_class_audio_feedback_task_function.c
new file mode 100644
index 0000000..8bcf857
--- /dev/null
+++ b/common/usbx_device_classes/src/ux_device_class_audio_feedback_task_function.c
@@ -0,0 +1,164 @@
+/**************************************************************************/
+/* */
+/* 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 Audio Class */
+/** */
+/**************************************************************************/
+/**************************************************************************/
+
+#define UX_SOURCE_CODE
+
+
+/* Include necessary system files. */
+
+#include "ux_api.h"
+#include "ux_device_class_audio.h"
+#include "ux_device_stack.h"
+
+
+#if defined(UX_DEVICE_CLASS_AUDIO_FEEDBACK_SUPPORT) && defined(UX_DEVICE_STANDALONE)
+/**************************************************************************/
+/* */
+/* FUNCTION RELEASE */
+/* */
+/* _ux_device_class_audio_feedback_task_function PORTABLE C */
+/* 6.2.0 */
+/* AUTHOR */
+/* */
+/* Yajun Xia, Microsoft Corporation */
+/* */
+/* DESCRIPTION */
+/* */
+/* This function is background task of ISO OUT/IN (feedback of IN/OUT) */
+/* for the Audio class. */
+/* */
+/* It's for standalone mode. */
+/* */
+/* INPUT */
+/* */
+/* stream Pointer to audio stream */
+/* */
+/* OUTPUT */
+/* */
+/* State machine status */
+/* UX_STATE_EXIT Device not configured */
+/* UX_STATE_IDLE No feedback transfer running */
+/* UX_STATE_WAIT Feedback transfer running */
+/* */
+/* CALLS */
+/* */
+/* _ux_system_error_handler System error trap */
+/* _ux_device_stack_transfer_run Run transfer state machine */
+/* */
+/* CALLED BY */
+/* */
+/* Audio Class (task) */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 10-31-2022 Yajun Xia Initial Version 6.2.0 */
+/* */
+/**************************************************************************/
+UINT _ux_device_class_audio_feedback_task_function(UX_DEVICE_CLASS_AUDIO_STREAM *stream)
+{
+
+UINT status;
+UX_SLAVE_DEVICE *device;
+UX_SLAVE_ENDPOINT *endpoint;
+UX_SLAVE_TRANSFER *transfer;
+ULONG transfer_length;
+
+
+ /* Get stack device instance. */
+ device = stream -> ux_device_class_audio_stream_audio -> ux_device_class_audio_device;
+
+ /* Check if the device is configured. */
+ if (device -> ux_slave_device_state != UX_DEVICE_CONFIGURED)
+ {
+
+ /* Error trap. */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_CONFIGURATION_HANDLE_UNKNOWN);
+
+ stream -> ux_device_class_audio_stream_feedback_task_state = UX_STATE_EXIT;
+ return(UX_STATE_EXIT);
+ }
+
+ /* Get endpoint instance. */
+ endpoint = stream -> ux_device_class_audio_stream_feedback;
+
+ /* Endpoint not available, maybe it's alternate setting 0. */
+ if (endpoint == UX_NULL)
+ {
+
+ /* Error trap. */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_ENDPOINT_HANDLE_UNKNOWN);
+
+ stream -> ux_device_class_audio_stream_feedback_task_state = UX_STATE_RESET;
+ return(UX_STATE_IDLE);
+ }
+
+ /* Get transfer instance. */
+ transfer = &endpoint -> ux_slave_endpoint_transfer_request;
+
+ /* Length is pre-set on interface alternate setting activate. */
+ transfer_length = transfer -> ux_slave_transfer_request_requested_length;
+
+ switch (stream -> ux_device_class_audio_stream_feedback_task_state)
+ {
+ case UX_STATE_RESET:
+ stream -> ux_device_class_audio_stream_feedback_task_state = UX_DEVICE_CLASS_AUDIO_STREAM_FEEDBACK_RW_WAIT;
+ stream -> ux_device_class_audio_stream_feedback_task_status = UX_TRANSFER_NO_ANSWER;
+
+ /* Fall through. */
+ case UX_DEVICE_CLASS_AUDIO_STREAM_FEEDBACK_RW_WAIT:
+
+ /* Issue transfer request. */
+ status = _ux_device_stack_transfer_run(transfer, transfer_length, transfer_length);
+
+ /* Any error or success case. */
+ if (status < UX_STATE_NEXT)
+ {
+
+ /* Error notification! */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_TRANSFER_ERROR);
+
+ stream -> ux_device_class_audio_stream_feedback_task_state = UX_STATE_RESET;
+ stream -> ux_device_class_audio_stream_feedback_task_status = transfer -> ux_slave_transfer_request_completion_code;
+ return(UX_STATE_EXIT);
+ }
+
+ /* Success case. */
+ if (status == UX_STATE_NEXT)
+ {
+ stream -> ux_device_class_audio_stream_feedback_task_state = UX_DEVICE_CLASS_AUDIO_STREAM_FEEDBACK_RW_WAIT;
+ stream -> ux_device_class_audio_stream_feedback_task_status = transfer -> ux_slave_transfer_request_completion_code;
+ }
+
+ /* Keep waiting. */
+ return(UX_STATE_WAIT);
+
+ default:
+ stream -> ux_device_class_audio_stream_feedback_task_state = UX_STATE_RESET;
+ stream -> ux_device_class_audio_stream_feedback_task_status = UX_INVALID_STATE;
+ break;
+ }
+
+ /* Error case. */
+ return(UX_STATE_EXIT);
+}
+#endif
diff --git a/common/usbx_device_classes/src/ux_device_class_audio_feedback_thread_entry.c b/common/usbx_device_classes/src/ux_device_class_audio_feedback_thread_entry.c
index 88525f1..f71c0bd 100644
--- a/common/usbx_device_classes/src/ux_device_class_audio_feedback_thread_entry.c
+++ b/common/usbx_device_classes/src/ux_device_class_audio_feedback_thread_entry.c
@@ -35,7 +35,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_audio_feedback_thread_entry PORTABLE C */
-/* 6.1.10 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -70,11 +70,17 @@
/* DATE NAME DESCRIPTION */
/* */
/* 01-31-2022 Chaoqiong Xiao Initial Version 6.1.10 */
+/* 10-31-2022 Yajun Xia Modified comment(s), */
+/* added standalone support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
VOID _ux_device_class_audio_feedback_thread_entry(ULONG audio_stream)
{
-
+#if defined(UX_DEVICE_STANDALONE)
+ UX_PARAMETER_NOT_USED(audio_stream);
+ return;
+#else
UINT status;
UX_DEVICE_CLASS_AUDIO_STREAM *stream;
UX_SLAVE_DEVICE *device;
@@ -128,5 +134,6 @@ ULONG transfer_length;
/* We need to suspend ourselves. We will be resumed by the device enumeration module or when a change of alternate setting happens. */
_ux_utility_thread_suspend(&stream -> ux_device_class_audio_stream_feedback_thread);
}
+#endif
}
#endif
diff --git a/common/usbx_device_classes/src/ux_device_class_audio_initialize.c b/common/usbx_device_classes/src/ux_device_class_audio_initialize.c
index 4887494..4ba297a 100644
--- a/common/usbx_device_classes/src/ux_device_class_audio_initialize.c
+++ b/common/usbx_device_classes/src/ux_device_class_audio_initialize.c
@@ -33,7 +33,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_audio_initialize PORTABLE C */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -84,14 +84,13 @@
/* added interrupt support, */
/* refined internal logic, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Yajun Xia Modified comment(s), */
+/* added standalone support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_device_class_audio_initialize(UX_SLAVE_CLASS_COMMAND *command)
{
-#if defined(UX_DEVICE_STANDALONE)
- UX_PARAMETER_NOT_USED(command);
- return(UX_FUNCTION_NOT_SUPPORTED);
-#else
UINT status = UX_SUCCESS;
UX_DEVICE_CLASS_AUDIO *audio;
@@ -153,8 +152,7 @@ ULONG i;
audio_parameter -> ux_device_class_audio_parameter_status_size;
audio -> ux_device_class_audio_status_queue_bytes = memory_size;
-#if defined(UX_DEVICE_STANDALONE)
-#else
+#if !defined(UX_DEVICE_STANDALONE)
if (UX_OVERFLOW_CHECK_ADD_ULONG(memory_size, UX_DEVICE_CLASS_AUDIO_INTERRUPT_THREAD_STACK_SIZE))
{
_ux_utility_memory_free(audio);
@@ -217,6 +215,15 @@ ULONG i;
audio -> ux_device_class_audio_status_queue =
(UCHAR *)audio_class -> ux_slave_class_thread_stack +
UX_DEVICE_CLASS_AUDIO_INTERRUPT_THREAD_STACK_SIZE;
+#else
+ audio -> ux_device_class_audio_status_queue = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_REGULAR_MEMORY, memory_size);
+
+ /* Check for successful allocation. */
+ if (audio -> ux_device_class_audio_status_queue == UX_NULL)
+ {
+ _ux_utility_memory_free(audio);
+ return(UX_MEMORY_INSUFFICIENT);
+ }
#endif
#endif
@@ -268,6 +275,8 @@ ULONG i;
stream -> ux_device_class_audio_stream_transfer_pos = (UX_DEVICE_CLASS_AUDIO_FRAME *)stream -> ux_device_class_audio_stream_buffer;
stream -> ux_device_class_audio_stream_access_pos = stream -> ux_device_class_audio_stream_transfer_pos;
+#if !defined(UX_DEVICE_STANDALONE)
+
/* Create memory block for streaming thread stack in addition. */
if (stream_parameter -> ux_device_class_audio_stream_parameter_thread_stack_size == 0)
memory_size = UX_DEVICE_CLASS_AUDIO_FEEDBACK_THREAD_STACK_SIZE;
@@ -298,13 +307,19 @@ ULONG i;
}
UX_THREAD_EXTENSION_PTR_SET(&(stream -> ux_device_class_audio_stream_thread), stream)
+#else
+
+ /* Save task function for streaming. */
+ stream -> ux_device_class_audio_stream_task_function = stream_parameter -> ux_device_class_audio_stream_parameter_task_function;
+#endif
#if defined(UX_DEVICE_CLASS_AUDIO_FEEDBACK_SUPPORT)
+#if !defined(UX_DEVICE_STANDALONE)
+
/* Check entry to confirm feedback is supported. */
if (stream_parameter -> ux_device_class_audio_stream_parameter_feedback_thread_entry)
{
-
/* Create memory block for streaming thread stack in addition. */
if (stream_parameter -> ux_device_class_audio_stream_parameter_feedback_thread_stack_size == 0)
memory_size = UX_THREAD_STACK_SIZE;
@@ -336,6 +351,14 @@ ULONG i;
UX_THREAD_EXTENSION_PTR_SET(&(stream -> ux_device_class_audio_stream_feedback_thread), stream)
}
+#else
+ if (stream_parameter -> ux_device_class_audio_stream_parameter_feedback_task_function)
+ {
+
+ /* Save task function for streaming. */
+ stream -> ux_device_class_audio_stream_feedback_task_function = stream_parameter -> ux_device_class_audio_stream_parameter_feedback_task_function;
+ }
+#endif
#endif
/* Save callbacks. */
@@ -365,6 +388,12 @@ ULONG i;
&audio_parameter -> ux_device_class_audio_parameter_callbacks,
sizeof(UX_DEVICE_CLASS_AUDIO_CALLBACKS)); /* Use case of memcpy is verified. */
+#if defined(UX_DEVICE_STANDALONE)
+
+ /* Link task function. */
+ audio_class -> ux_slave_class_task_function = _ux_device_class_audio_tasks_run;
+#endif
+
/* Return completion status. */
return(UX_SUCCESS);
}
@@ -377,24 +406,27 @@ ULONG i;
for (i = 0; i < audio -> ux_device_class_audio_streams_nb; i ++)
{
#if defined(UX_DEVICE_CLASS_AUDIO_FEEDBACK_SUPPORT)
+#if !defined(UX_DEVICE_STANDALONE)
if (stream -> ux_device_class_audio_stream_feedback_thread_stack)
{
_ux_device_thread_delete(&stream -> ux_device_class_audio_stream_feedback_thread);
_ux_utility_memory_free(stream -> ux_device_class_audio_stream_feedback_thread_stack);
}
#endif
+#endif
+#if !defined(UX_DEVICE_STANDALONE)
if (stream -> ux_device_class_audio_stream_thread_stack)
{
_ux_device_thread_delete(&stream -> ux_device_class_audio_stream_thread);
_ux_utility_memory_free(stream -> ux_device_class_audio_stream_thread_stack);
}
+#endif
if (stream -> ux_device_class_audio_stream_buffer)
_ux_utility_memory_free(stream -> ux_device_class_audio_stream_buffer);
stream ++;
}
#if defined(UX_DEVICE_CLASS_AUDIO_INTERRUPT_SUPPORT)
-#if defined(UX_DEVICE_STANDALONE)
-#else
+#if !defined(UX_DEVICE_STANDALONE)
if (audio_class -> ux_slave_class_thread_stack)
{
_ux_device_thread_delete(&audio_class -> ux_slave_class_thread);
@@ -403,10 +435,14 @@ ULONG i;
_ux_device_semaphore_delete(&audio -> ux_device_class_audio_status_semaphore);
_ux_device_mutex_delete(&audio -> ux_device_class_audio_status_mutex);
}
+#else
+ if (audio -> ux_device_class_audio_status_queue)
+ {
+ _ux_utility_memory_free(audio -> ux_device_class_audio_status_queue);
+ }
#endif
#endif
_ux_utility_memory_free(audio);
return(status);
-#endif
}
diff --git a/common/usbx_device_classes/src/ux_device_class_audio_interrupt_send.c b/common/usbx_device_classes/src/ux_device_class_audio_interrupt_send.c
index 72c51fb..eb5d438 100644
--- a/common/usbx_device_classes/src/ux_device_class_audio_interrupt_send.c
+++ b/common/usbx_device_classes/src/ux_device_class_audio_interrupt_send.c
@@ -34,7 +34,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_audio_interrupt_send PORTABLE C */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -68,6 +68,9 @@
/* DATE NAME DESCRIPTION */
/* */
/* 07-29-2022 Chaoqiong Xiao Initial Version 6.1.12 */
+/* 10-31-2022 Yajun Xia Modified comment(s), */
+/* added standalone support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_device_class_audio_interrupt_send(UX_DEVICE_CLASS_AUDIO *audio, UCHAR *int_data)
@@ -77,11 +80,6 @@ UINT _ux_device_class_audio_interrupt_send(UX_DEVICE_CLASS_AUDIO *audio, UCHA
UX_PARAMETER_NOT_USED(int_data);
return(UX_FUNCTION_NOT_SUPPORTED);
#else
-#if defined(UX_DEVICE_STANDALONE)
- UX_PARAMETER_NOT_USED(audio);
- UX_PARAMETER_NOT_USED(int_data);
- return(UX_FUNCTION_NOT_SUPPORTED);
-#else
UX_SLAVE_DEVICE *device;
UX_SLAVE_ENDPOINT *endpoint;
@@ -169,5 +167,4 @@ ULONG i;
/* Return success. */
return(UX_SUCCESS);
#endif
-#endif
}
diff --git a/common/usbx_device_classes/src/ux_device_class_audio_interrupt_task_function.c b/common/usbx_device_classes/src/ux_device_class_audio_interrupt_task_function.c
new file mode 100644
index 0000000..eeac5c2
--- /dev/null
+++ b/common/usbx_device_classes/src/ux_device_class_audio_interrupt_task_function.c
@@ -0,0 +1,198 @@
+/**************************************************************************/
+/* */
+/* 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 Audio Class */
+/** */
+/**************************************************************************/
+/**************************************************************************/
+
+#define UX_SOURCE_CODE
+
+
+/* Include necessary system files. */
+
+#include "ux_api.h"
+#include "ux_device_class_audio.h"
+#include "ux_device_stack.h"
+
+#if defined(UX_DEVICE_STANDALONE) && defined(UX_DEVICE_CLASS_AUDIO_INTERRUPT_SUPPORT)
+/**************************************************************************/
+/* */
+/* FUNCTION RELEASE */
+/* */
+/* _ux_device_class_audio_interrupt_task_function PORTABLE C */
+/* 6.2.0 */
+/* AUTHOR */
+/* */
+/* Yajun Xia, Microsoft Corporation */
+/* */
+/* DESCRIPTION */
+/* */
+/* This function is task of INTERRUPT IN from the Audio class. */
+/* */
+/* It's for standalone mode. */
+/* */
+/* INPUT */
+/* */
+/* audio Address of audio instance */
+/* */
+/* OUTPUT */
+/* */
+/* State machine Status to check */
+/* UX_STATE_EXIT Abnormal, to reset state */
+/* UX_STATE_IDLE No interrupt transfer running */
+/* UX_STATE_WAIT Keep running, waiting */
+/* */
+/* CALLS */
+/* */
+/* _ux_system_error_handler System error trap */
+/* _ux_utility_memory_copy Copy memory */
+/* _ux_device_stack_transfer_run Run Transfer state machine */
+/* */
+/* CALLED BY */
+/* */
+/* Audio Class (task) */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 10-31-2022 Yajun Xia Initial Version 6.2.0 */
+/* */
+/**************************************************************************/
+UINT _ux_device_class_audio_interrupt_task_function(UX_DEVICE_CLASS_AUDIO *audio)
+{
+
+UINT status;
+UX_SLAVE_DEVICE *device;
+UX_SLAVE_ENDPOINT *endpoint;
+UX_SLAVE_TRANSFER *transfer;
+UCHAR *buff;
+
+
+ /* Get stack device instance. */
+ device = audio -> ux_device_class_audio_device;
+
+ /* Check if the device is configured. */
+ if (device -> ux_slave_device_state != UX_DEVICE_CONFIGURED)
+ {
+
+ /* Error trap. */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_CONFIGURATION_HANDLE_UNKNOWN);
+
+ audio -> ux_device_class_audio_interrupt_task_state = UX_STATE_EXIT;
+ return(UX_STATE_EXIT);
+ }
+
+ /* Get endpoint instance. */
+ endpoint = audio -> ux_device_class_audio_interrupt;
+
+ /* Endpoint not available, maybe it's alternate setting 0. */
+ if (endpoint == UX_NULL)
+ {
+
+ /* Error trap. */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_ENDPOINT_HANDLE_UNKNOWN);
+
+ audio -> ux_device_class_audio_interrupt_task_state = UX_STATE_RESET;
+ return(UX_STATE_IDLE);
+ }
+
+ /* No packet in queue */
+ if (audio -> ux_device_class_audio_status_queued == 0)
+ {
+ audio -> ux_device_class_audio_interrupt_task_state = UX_STATE_RESET;
+ audio -> ux_device_class_audio_interrupt_task_status = UX_TRANSFER_NOT_READY;
+ return(UX_STATE_EXIT);
+ }
+
+ /* Get transfer instance. */
+ transfer = &endpoint -> ux_slave_endpoint_transfer_request;
+
+ /* Handle state cases. */
+ switch(audio -> ux_device_class_audio_interrupt_task_state)
+ {
+ case UX_STATE_RESET:
+ audio -> ux_device_class_audio_interrupt_task_state = UX_DEVICE_CLASS_AUDIO_INTERRUPT_START;
+ audio -> ux_device_class_audio_interrupt_task_status = UX_TRANSFER_NO_ANSWER;
+
+ /* Fall through. */
+ case UX_DEVICE_CLASS_AUDIO_INTERRUPT_START:
+ if (audio -> ux_device_class_audio_status_size > transfer -> ux_slave_transfer_request_transfer_length)
+ {
+
+ /* Error trap. */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_TRANSFER_ERROR);
+
+ audio -> ux_device_class_audio_interrupt_task_state = UX_STATE_RESET;
+ audio -> ux_device_class_audio_interrupt_task_status = UX_ERROR;
+ return(UX_STATE_EXIT);
+ }
+
+ _ux_utility_memory_copy(transfer -> ux_slave_transfer_request_data_pointer,
+ audio -> ux_device_class_audio_status_tail, audio -> ux_device_class_audio_status_size); /* Use case of memcpy is verified. */
+
+ audio -> ux_device_class_audio_interrupt_task_state = UX_DEVICE_CLASS_AUDIO_INTERRUPT_WAIT;
+
+ /* Fall through. */
+ case UX_DEVICE_CLASS_AUDIO_INTERRUPT_WAIT:
+
+ /* Start frame transfer anyway. */
+ status = _ux_device_stack_transfer_run(transfer, audio -> ux_device_class_audio_status_size,
+ audio -> ux_device_class_audio_status_size);
+
+ /* Any error or success case. */
+ if (status < UX_STATE_NEXT)
+ {
+
+ /* Error notification! */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_TRANSFER_ERROR);
+
+ audio -> ux_device_class_audio_interrupt_task_state = UX_STATE_RESET;
+ audio -> ux_device_class_audio_interrupt_task_status =
+ transfer -> ux_slave_transfer_request_completion_code;
+ return(UX_STATE_EXIT);
+ }
+
+ /* Success case. */
+ if (status == UX_STATE_NEXT)
+ {
+ buff = audio -> ux_device_class_audio_status_tail;
+ buff += audio -> ux_device_class_audio_status_size;
+
+ if (buff >= (audio -> ux_device_class_audio_status_queue + audio -> ux_device_class_audio_status_queue_bytes))
+ buff = audio -> ux_device_class_audio_status_queue;
+
+ audio -> ux_device_class_audio_status_tail = buff;
+ audio -> ux_device_class_audio_status_queued -= audio -> ux_device_class_audio_status_size;
+ audio -> ux_device_class_audio_interrupt_task_state = UX_DEVICE_CLASS_AUDIO_INTERRUPT_START;
+ audio -> ux_device_class_audio_interrupt_task_status =
+ transfer -> ux_slave_transfer_request_completion_code;
+ }
+
+ /* Keep waiting. */
+ return(UX_STATE_WAIT);
+
+ default: /* Error. */
+ audio -> ux_device_class_audio_interrupt_task_state = UX_STATE_RESET;
+ audio -> ux_device_class_audio_interrupt_task_status = UX_INVALID_STATE;
+ break;
+ }
+
+ /* Error case. */
+ return(UX_STATE_EXIT);
+}
+#endif
diff --git a/common/usbx_device_classes/src/ux_device_class_audio_read_task_function.c b/common/usbx_device_classes/src/ux_device_class_audio_read_task_function.c
new file mode 100644
index 0000000..03d43d8
--- /dev/null
+++ b/common/usbx_device_classes/src/ux_device_class_audio_read_task_function.c
@@ -0,0 +1,188 @@
+/**************************************************************************/
+/* */
+/* 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 Audio Class */
+/** */
+/**************************************************************************/
+/**************************************************************************/
+
+#define UX_SOURCE_CODE
+
+
+/* Include necessary system files. */
+
+#include "ux_api.h"
+#include "ux_device_class_audio.h"
+#include "ux_device_stack.h"
+
+
+#if defined(UX_DEVICE_STANDALONE)
+/**************************************************************************/
+/* */
+/* FUNCTION RELEASE */
+/* */
+/* _ux_device_class_audio_read_task_function PORTABLE C */
+/* 6.2.0 */
+/* AUTHOR */
+/* */
+/* Yajun Xia, Microsoft Corporation */
+/* */
+/* DESCRIPTION */
+/* */
+/* This function is the background task of the audio stream read. */
+/* */
+/* It's for standalone mode. */
+/* */
+/* INPUT */
+/* */
+/* stream Pointer to audio stream */
+/* */
+/* OUTPUT */
+/* */
+/* State machine status */
+/* UX_STATE_EXIT Device not configured */
+/* UX_STATE_IDLE No streaming transfer running */
+/* UX_STATE_WAIT Streaming transfer running */
+/* */
+/* CALLS */
+/* */
+/* _ux_device_stack_transfer_run Run transfer state machine */
+/* _ux_utility_memory_copy Copy memory */
+/* */
+/* CALLED BY */
+/* */
+/* USBX Device Stack */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 10-31-2022 Yajun Xia Initial Version 6.2.0 */
+/* */
+/**************************************************************************/
+UINT _ux_device_class_audio_read_task_function(UX_DEVICE_CLASS_AUDIO_STREAM *stream)
+{
+UX_SLAVE_DEVICE *device;
+UX_SLAVE_ENDPOINT *endpoint;
+UX_SLAVE_TRANSFER *transfer;
+UCHAR *next_pos;
+UX_DEVICE_CLASS_AUDIO_FRAME *next_frame;
+ULONG max_packet_size;
+ULONG actual_length;
+UINT status;
+
+
+ /* Get the pointer to the device. */
+ device = stream -> ux_device_class_audio_stream_audio -> ux_device_class_audio_device;
+
+ /* Check if the device is configured. */
+ if (device -> ux_slave_device_state != UX_DEVICE_CONFIGURED)
+ {
+ stream -> ux_device_class_audio_stream_task_state = UX_STATE_EXIT;
+ return(UX_STATE_EXIT);
+ }
+
+ /* Get the endpoint. */
+ endpoint = stream -> ux_device_class_audio_stream_endpoint;
+
+ /* No endpoint ready, maybe it's alternate setting 0. */
+ if (endpoint == UX_NULL)
+ return(UX_STATE_IDLE);
+
+ /* Check if background transfer task is started. */
+ if (stream -> ux_device_class_audio_stream_task_state == UX_DEVICE_CLASS_AUDIO_STREAM_RW_STOP)
+ return(UX_STATE_IDLE);
+
+ /* Get transfer instance. */
+ transfer = &endpoint -> ux_slave_endpoint_transfer_request;
+
+ /* If not started yet, reset transfer and start polling. */
+ if (stream -> ux_device_class_audio_stream_task_state == UX_DEVICE_CLASS_AUDIO_STREAM_RW_START)
+ {
+
+ /* Next state: transfer wait. */
+ stream -> ux_device_class_audio_stream_task_state = UX_DEVICE_CLASS_AUDIO_STREAM_RW_WAIT;
+
+ /* Reset transfer state. */
+ UX_SLAVE_TRANSFER_STATE_RESET(transfer);
+ }
+
+ /* Run transfer state machine. */
+ max_packet_size = endpoint -> ux_slave_endpoint_transfer_request.ux_slave_transfer_request_transfer_length;
+ status = _ux_device_stack_transfer_run(transfer, max_packet_size, max_packet_size);
+
+ /* Error case. */
+ if (status < UX_STATE_NEXT)
+ {
+
+ /* Error on background transfer task start. */
+ stream -> ux_device_class_audio_stream_task_state = UX_STATE_RESET;
+ stream -> ux_device_class_audio_stream_task_status =
+ transfer -> ux_slave_transfer_request_completion_code;
+
+ /* Error notification! */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_TRANSFER_ERROR);
+ return(UX_STATE_EXIT);
+ }
+
+ /* Success case. */
+ if (status == UX_STATE_NEXT)
+ {
+
+ /* Next state: start. */
+ stream -> ux_device_class_audio_stream_task_state = UX_DEVICE_CLASS_AUDIO_STREAM_RW_START;
+ stream -> ux_device_class_audio_stream_task_status =
+ transfer -> ux_slave_transfer_request_completion_code;
+
+ /* Get actual transfer length. */
+ actual_length = transfer -> ux_slave_transfer_request_actual_length;
+
+ /* Frame received, log it. */
+ stream -> ux_device_class_audio_stream_transfer_pos -> ux_device_class_audio_frame_length = actual_length;
+ stream -> ux_device_class_audio_stream_transfer_pos -> ux_device_class_audio_frame_pos = 0;
+ _ux_utility_memory_copy(stream -> ux_device_class_audio_stream_transfer_pos -> ux_device_class_audio_frame_data,
+ transfer -> ux_slave_transfer_request_data_pointer,
+ actual_length); /* Use case of memcpy is verified. */
+
+ /* For simple, do not advance the transfer position if there is overflow. */
+ next_pos = (UCHAR *)stream -> ux_device_class_audio_stream_transfer_pos;
+ next_pos += stream -> ux_device_class_audio_stream_frame_buffer_size;
+ if (next_pos >= stream -> ux_device_class_audio_stream_buffer + stream -> ux_device_class_audio_stream_buffer_size)
+ next_pos = stream -> ux_device_class_audio_stream_buffer;
+ next_frame = (UX_DEVICE_CLASS_AUDIO_FRAME *)next_pos;
+
+ /* Check overflow! */
+ if (next_frame -> ux_device_class_audio_frame_length > 0)
+ {
+
+ /* Error notification! */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_BUFFER_OVERFLOW);
+ stream -> ux_device_class_audio_stream_buffer_error_count ++;
+ }
+ else
+
+ /* Update transfer position. */
+ stream -> ux_device_class_audio_stream_transfer_pos = next_frame;
+
+ /* Invoke notification callback. */
+ if (stream -> ux_device_class_audio_stream_callbacks.ux_device_class_audio_stream_frame_done != UX_NULL)
+ stream -> ux_device_class_audio_stream_callbacks.ux_device_class_audio_stream_frame_done(stream, actual_length);
+ }
+
+ /* Keep waiting. */
+ return(UX_STATE_WAIT);
+}
+#endif
diff --git a/common/usbx_device_classes/src/ux_device_class_audio_read_thread_entry.c b/common/usbx_device_classes/src/ux_device_class_audio_read_thread_entry.c
index 6046051..8af97f0 100644
--- a/common/usbx_device_classes/src/ux_device_class_audio_read_thread_entry.c
+++ b/common/usbx_device_classes/src/ux_device_class_audio_read_thread_entry.c
@@ -34,7 +34,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_audio_read_thread_entry PORTABLE C */
-/* 6.1.10 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -81,6 +81,9 @@
/* 01-31-2022 Chaoqiong Xiao Modified comment(s), */
/* refined macros names, */
/* resulting in version 6.1.10 */
+/* 10-31-2022 Yajun Xia Modified comment(s), */
+/* added standalone support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
VOID _ux_device_class_audio_read_thread_entry(ULONG audio_stream)
@@ -133,6 +136,7 @@ ULONG actual_length;
/* Error notification! */
_ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_TRANSFER_ERROR);
+ stream -> ux_device_class_audio_stream_buffer_error_count ++;
break;
}
@@ -159,6 +163,7 @@ ULONG actual_length;
/* Error notification! */
_ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_BUFFER_OVERFLOW);
+ stream -> ux_device_class_audio_stream_buffer_error_count ++;
}
else
diff --git a/common/usbx_device_classes/src/ux_device_class_audio_reception_start.c b/common/usbx_device_classes/src/ux_device_class_audio_reception_start.c
index 120eb1e..078ce81 100644
--- a/common/usbx_device_classes/src/ux_device_class_audio_reception_start.c
+++ b/common/usbx_device_classes/src/ux_device_class_audio_reception_start.c
@@ -34,7 +34,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_audio_reception_start PORTABLE C */
-/* 6.1.10 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -70,6 +70,9 @@
/* 01-31-2022 Chaoqiong Xiao Modified comment(s), */
/* refined macros names, */
/* resulting in version 6.1.10 */
+/* 10-31-2022 Yajun Xia Modified comment(s), */
+/* added standalone support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_device_class_audio_reception_start(UX_DEVICE_CLASS_AUDIO_STREAM *stream)
@@ -103,7 +106,15 @@ UX_SLAVE_DEVICE *device;
if (stream -> ux_device_class_audio_stream_transfer_pos -> ux_device_class_audio_frame_length > 0)
return(UX_BUFFER_OVERFLOW);
+#if defined(UX_DEVICE_STANDALONE)
+
+ /* Start read task. */
+ if (stream -> ux_device_class_audio_stream_task_state == UX_DEVICE_CLASS_AUDIO_STREAM_RW_STOP)
+ stream -> ux_device_class_audio_stream_task_state = UX_DEVICE_CLASS_AUDIO_STREAM_RW_START;
+#else
+
/* Start read thread. */
_ux_device_thread_resume(&stream -> ux_device_class_audio_stream_thread);
+#endif
return(UX_SUCCESS);
}
diff --git a/common/usbx_device_classes/src/ux_device_class_audio_tasks_run.c b/common/usbx_device_classes/src/ux_device_class_audio_tasks_run.c
new file mode 100644
index 0000000..2518ef2
--- /dev/null
+++ b/common/usbx_device_classes/src/ux_device_class_audio_tasks_run.c
@@ -0,0 +1,153 @@
+/**************************************************************************/
+/* */
+/* 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 Audio Class */
+/** */
+/**************************************************************************/
+/**************************************************************************/
+
+#define UX_SOURCE_CODE
+
+
+/* Include necessary system files. */
+
+#include "ux_api.h"
+#include "ux_device_class_audio.h"
+#include "ux_device_stack.h"
+
+
+#if defined(UX_DEVICE_STANDALONE)
+/**************************************************************************/
+/* */
+/* FUNCTION RELEASE */
+/* */
+/* _ux_device_class_audio_tasks_run PORTABLE C */
+/* 6.2.0 */
+/* AUTHOR */
+/* */
+/* Yajun Xia, Microsoft Corporation */
+/* */
+/* DESCRIPTION */
+/* */
+/* This function is the background task of the audio. */
+/* */
+/* It's for standalone mode. */
+/* */
+/* INPUT */
+/* */
+/* instance Pointer to audio class */
+/* */
+/* OUTPUT */
+/* */
+/* State machine status */
+/* UX_STATE_EXIT Device not configured */
+/* UX_STATE_IDLE No streaming transfer running */
+/* UX_STATE_WAIT Streaming transfer running */
+/* */
+/* CALLS */
+/* */
+/* (ux_device_class_audio_stream_task_function) */
+/* Run stream task */
+/* (ux_device_class_audio_stream_feedback_task_function) */
+/* Run stream feedback task */
+/* */
+/* CALLED BY */
+/* */
+/* USBX Device Stack */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 10-31-2022 Yajun Xia Initial Version 6.2.0 */
+/* */
+/**************************************************************************/
+UINT _ux_device_class_audio_tasks_run(VOID *instance)
+{
+UX_SLAVE_DEVICE *device;
+UX_DEVICE_CLASS_AUDIO *audio;
+UX_DEVICE_CLASS_AUDIO_STREAM *stream;
+ULONG stream_index;
+UINT status;
+#if defined(UX_DEVICE_CLASS_AUDIO_INTERRUPT_SUPPORT)
+ULONG interrupt_running_count = 0;
+#endif
+ULONG stream_running_count = 0;
+#if defined(UX_DEVICE_CLASS_AUDIO_FEEDBACK_SUPPORT)
+ULONG feedback_running_count = 0;
+#endif
+
+ /* Get audio instance. */
+ audio = (UX_DEVICE_CLASS_AUDIO *) instance;
+
+ /* Get the pointer to the device. */
+ device = &_ux_system_slave -> ux_system_slave_device;
+
+ /* Check if the device is configured. */
+ if (device -> ux_slave_device_state != UX_DEVICE_CONFIGURED)
+ return(UX_STATE_EXIT);
+
+#if defined(UX_DEVICE_CLASS_AUDIO_INTERRUPT_SUPPORT)
+
+ /* Run audio status tasks. */
+ status = _ux_device_class_audio_interrupt_task_function(audio);
+ if (status == UX_STATE_EXIT)
+ return(status);
+ if (status == UX_STATE_WAIT)
+ interrupt_running_count++;
+#endif
+
+ for (stream_index = 0;
+ stream_index < audio -> ux_device_class_audio_streams_nb;
+ stream_index ++)
+ {
+ stream = &audio -> ux_device_class_audio_streams[stream_index];
+ status = stream -> ux_device_class_audio_stream_task_function(stream);
+ if (status == UX_STATE_EXIT)
+ return(status);
+ if (status == UX_STATE_WAIT)
+ stream_running_count ++;
+
+#if defined(UX_DEVICE_CLASS_AUDIO_FEEDBACK_SUPPORT)
+ if (stream -> ux_device_class_audio_stream_feedback_task_function != UX_NULL)
+ {
+ status = stream -> ux_device_class_audio_stream_feedback_task_function(stream);
+ if (status == UX_STATE_EXIT)
+ return(status);
+ if (status == UX_STATE_WAIT)
+ feedback_running_count ++;
+ }
+#endif
+ }
+
+ if ((stream_running_count > 0)
+#if defined(UX_DEVICE_CLASS_AUDIO_INTERRUPT_SUPPORT)
+ || (interrupt_running_count > 0)
+#endif
+#if defined(UX_DEVICE_CLASS_AUDIO_FEEDBACK_SUPPORT)
+ || (feedback_running_count > 0)
+#endif
+ )
+ {
+ return UX_STATE_WAIT;
+ }
+ else
+ {
+ return UX_STATE_IDLE;
+ }
+}
+
+#endif \ No newline at end of file
diff --git a/common/usbx_device_classes/src/ux_device_class_audio_transmission_start.c b/common/usbx_device_classes/src/ux_device_class_audio_transmission_start.c
index 050390c..69b58c5 100644
--- a/common/usbx_device_classes/src/ux_device_class_audio_transmission_start.c
+++ b/common/usbx_device_classes/src/ux_device_class_audio_transmission_start.c
@@ -34,7 +34,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_audio_transmission_start PORTABLE C */
-/* 6.1.10 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -70,6 +70,9 @@
/* 01-31-2022 Chaoqiong Xiao Modified comment(s), */
/* refined macros names, */
/* resulting in version 6.1.10 */
+/* 10-31-2022 Yajun Xia Modified comment(s), */
+/* added standalone support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_device_class_audio_transmission_start(UX_DEVICE_CLASS_AUDIO_STREAM *stream)
@@ -103,7 +106,15 @@ UX_SLAVE_DEVICE *device;
if (stream -> ux_device_class_audio_stream_transfer_pos -> ux_device_class_audio_frame_length == 0)
return(UX_BUFFER_OVERFLOW);
+#if defined(UX_DEVICE_STANDALONE)
+
+ /* Start write task. */
+ if (stream -> ux_device_class_audio_stream_task_state == UX_DEVICE_CLASS_AUDIO_STREAM_RW_STOP)
+ stream -> ux_device_class_audio_stream_task_state = UX_DEVICE_CLASS_AUDIO_STREAM_RW_START;
+#else
+
/* Start write thread. */
_ux_device_thread_resume(&stream -> ux_device_class_audio_stream_thread);
+#endif
return(UX_SUCCESS);
}
diff --git a/common/usbx_device_classes/src/ux_device_class_audio_write_task_function.c b/common/usbx_device_classes/src/ux_device_class_audio_write_task_function.c
new file mode 100644
index 0000000..2c30a3c
--- /dev/null
+++ b/common/usbx_device_classes/src/ux_device_class_audio_write_task_function.c
@@ -0,0 +1,210 @@
+/**************************************************************************/
+/* */
+/* 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 Audio Class */
+/** */
+/**************************************************************************/
+/**************************************************************************/
+
+#define UX_SOURCE_CODE
+
+
+/* Include necessary system files. */
+
+#include "ux_api.h"
+#include "ux_device_class_audio.h"
+#include "ux_device_stack.h"
+
+
+#if defined(UX_DEVICE_STANDALONE)
+/**************************************************************************/
+/* */
+/* FUNCTION RELEASE */
+/* */
+/* _ux_device_class_audio_write_task_function PORTABLE C */
+/* 6.2.0 */
+/* AUTHOR */
+/* */
+/* Yajun Xia, Microsoft Corporation */
+/* */
+/* DESCRIPTION */
+/* */
+/* This function is the background task of the audio stream write. */
+/* */
+/* It's for standalone mode. */
+/* */
+/* INPUT */
+/* */
+/* audio_class Address of audio class */
+/* container */
+/* */
+/* OUTPUT */
+/* */
+/* State machine status */
+/* UX_STATE_EXIT Device not configured */
+/* UX_STATE_IDLE No streaming transfer running */
+/* UX_STATE_WAIT Streaming transfer running */
+/* */
+/* CALLS */
+/* */
+/* _ux_device_stack_transfer_run Run transfer state machine */
+/* _ux_utility_memory_copy Copy memory */
+/* */
+/* CALLED BY */
+/* */
+/* USBX Device Stack */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 10-31-2022 Yajun Xia Initial Version 6.2.0 */
+/* */
+/**************************************************************************/
+UINT _ux_device_class_audio_write_task_function(UX_DEVICE_CLASS_AUDIO_STREAM *stream)
+{
+UX_SLAVE_DEVICE *device;
+UX_SLAVE_ENDPOINT *endpoint;
+UX_SLAVE_TRANSFER *transfer;
+UCHAR *next_pos;
+UX_DEVICE_CLASS_AUDIO_FRAME *next_frame;
+ULONG transfer_length;
+ULONG actual_length;
+UINT status;
+
+
+ /* Get the pointer to the device. */
+ device = stream -> ux_device_class_audio_stream_audio -> ux_device_class_audio_device;
+
+ /* Check if the device is configured. */
+ if (device -> ux_slave_device_state != UX_DEVICE_CONFIGURED)
+ {
+ stream -> ux_device_class_audio_stream_task_state = UX_STATE_EXIT;
+ return(UX_STATE_EXIT);
+ }
+
+ /* Get the endpoint. */
+ endpoint = stream -> ux_device_class_audio_stream_endpoint;
+
+ /* No endpoint ready, maybe it's alternate setting 0. */
+ if (endpoint == UX_NULL)
+ return(UX_STATE_IDLE);
+
+ /* Check if background transfer task is started. */
+ if (stream -> ux_device_class_audio_stream_task_state == UX_DEVICE_CLASS_AUDIO_STREAM_RW_STOP)
+ return(UX_STATE_IDLE);
+
+ /* Get transfer instance. */
+ transfer = &endpoint -> ux_slave_endpoint_transfer_request;
+
+ /* If not started yet, prepare data, reset transfer and start polling. */
+ if (stream -> ux_device_class_audio_stream_task_state == UX_DEVICE_CLASS_AUDIO_STREAM_RW_START)
+ {
+
+ /* Next state: transfer wait. */
+ stream -> ux_device_class_audio_stream_task_state = UX_DEVICE_CLASS_AUDIO_STREAM_RW_WAIT;
+
+ /* Start frame transfer anyway (even ZLP). */
+ transfer_length = stream -> ux_device_class_audio_stream_transfer_pos -> ux_device_class_audio_frame_length;
+ if (transfer_length)
+ _ux_utility_memory_copy(transfer -> ux_slave_transfer_request_data_pointer,
+ stream -> ux_device_class_audio_stream_transfer_pos -> ux_device_class_audio_frame_data, transfer_length); /* Use case of memcpy is verified. */
+
+ /* Reset transfer state. */
+ UX_SLAVE_TRANSFER_STATE_RESET(transfer);
+ }
+
+ /* Get current transfer length. */
+ transfer_length = stream -> ux_device_class_audio_stream_transfer_pos -> ux_device_class_audio_frame_length;
+
+ /* Run transfer states. */
+ status = _ux_device_stack_transfer_run(transfer, transfer_length, transfer_length);
+
+ /* Error case. */
+ if (status < UX_STATE_NEXT)
+ {
+
+ /* Error on background transfer task start. */
+ stream -> ux_device_class_audio_stream_task_state = UX_STATE_RESET;
+ stream -> ux_device_class_audio_stream_task_status =
+ transfer -> ux_slave_transfer_request_completion_code;
+
+ /* Error notification! */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_TRANSFER_ERROR);
+ return(UX_STATE_EXIT);
+ }
+
+ /* Success case. */
+ if (status == UX_STATE_NEXT)
+ {
+
+ /* Next state: start. */
+ stream -> ux_device_class_audio_stream_task_state = UX_DEVICE_CLASS_AUDIO_STREAM_RW_START;
+ stream -> ux_device_class_audio_stream_task_status =
+ transfer -> ux_slave_transfer_request_completion_code;
+
+ /* Frame sent, free it. */
+ stream -> ux_device_class_audio_stream_transfer_pos -> ux_device_class_audio_frame_length = 0;
+
+ /* Get actual transfer length. */
+ actual_length = transfer -> ux_slave_transfer_request_actual_length;
+
+ /* Calculate next position. */
+ next_pos = (UCHAR *)stream -> ux_device_class_audio_stream_transfer_pos;
+ next_pos += stream -> ux_device_class_audio_stream_frame_buffer_size;
+ if (next_pos >= stream -> ux_device_class_audio_stream_buffer + stream -> ux_device_class_audio_stream_buffer_size)
+ next_pos = stream -> ux_device_class_audio_stream_buffer;
+ next_frame = (UX_DEVICE_CLASS_AUDIO_FRAME *)next_pos;
+
+ /* Underflow check! */
+ if (transfer_length)
+ {
+
+ /* Advance position. */
+ stream -> ux_device_class_audio_stream_transfer_pos = next_frame;
+
+ /* Error trap! */
+ if (next_frame -> ux_device_class_audio_frame_length == 0)
+ {
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_BUFFER_OVERFLOW);
+ stream -> ux_device_class_audio_stream_buffer_error_count ++;
+ }
+ }
+ else
+ {
+
+ /* Advance position if next payload available. */
+ if (next_frame -> ux_device_class_audio_frame_length)
+ stream -> ux_device_class_audio_stream_transfer_pos = next_frame;
+ else
+ {
+
+ /* Error trap! */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_BUFFER_OVERFLOW);
+ stream -> ux_device_class_audio_stream_buffer_error_count ++;
+ }
+ }
+
+ /* Invoke notification callback. */
+ if (stream -> ux_device_class_audio_stream_callbacks.ux_device_class_audio_stream_frame_done != UX_NULL)
+ stream -> ux_device_class_audio_stream_callbacks.ux_device_class_audio_stream_frame_done(stream, actual_length);
+ }
+
+ /* Keep waiting. */
+ return(UX_STATE_WAIT);
+}
+#endif
+
diff --git a/common/usbx_device_classes/src/ux_device_class_audio_write_thread_entry.c b/common/usbx_device_classes/src/ux_device_class_audio_write_thread_entry.c
index f6c1cf0..ce6bd7b 100644
--- a/common/usbx_device_classes/src/ux_device_class_audio_write_thread_entry.c
+++ b/common/usbx_device_classes/src/ux_device_class_audio_write_thread_entry.c
@@ -34,7 +34,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_audio_write_thread_entry PORTABLE C */
-/* 6.1.10 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -75,6 +75,9 @@
/* 01-31-2022 Chaoqiong Xiao Modified comment(s), */
/* refined macros names, */
/* resulting in version 6.1.10 */
+/* 10-31-2022 Yajun Xia Modified comment(s), */
+/* added standalone support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
VOID _ux_device_class_audio_write_thread_entry(ULONG audio_stream)
@@ -153,7 +156,10 @@ ULONG actual_length;
/* Error trap! */
if (next_frame -> ux_device_class_audio_frame_length == 0)
+ {
+ stream -> ux_device_class_audio_stream_buffer_error_count ++;
_ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_BUFFER_OVERFLOW);
+ }
}
else
{
@@ -162,9 +168,12 @@ ULONG actual_length;
if (next_frame -> ux_device_class_audio_frame_length)
stream -> ux_device_class_audio_stream_transfer_pos = next_frame;
else
+ {
/* Error trap! */
_ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_BUFFER_OVERFLOW);
+ stream -> ux_device_class_audio_stream_buffer_error_count ++;
+ }
}
/* Invoke notification callback. */
diff --git a/common/usbx_device_classes/src/ux_device_class_cdc_acm_read_run.c b/common/usbx_device_classes/src/ux_device_class_cdc_acm_read_run.c
index 4086b03..e89212a 100644
--- a/common/usbx_device_classes/src/ux_device_class_cdc_acm_read_run.c
+++ b/common/usbx_device_classes/src/ux_device_class_cdc_acm_read_run.c
@@ -37,7 +37,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_cdc_acm_read_run PORTABLE C */
-/* 6.1.10 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -79,6 +79,9 @@
/* DATE NAME DESCRIPTION */
/* */
/* 01-31-2022 Chaoqiong Xiao Initial Version 6.1.10 */
+/* 10-31-2022 Yajun Xia Modified comment(s), */
+/* fixed return code, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_device_class_cdc_acm_read_run(UX_SLAVE_CLASS_CDC_ACM *cdc_acm,
@@ -200,7 +203,7 @@ UINT status = UX_SUCCESS;
cdc_acm -> ux_device_class_cdc_acm_read_state = UX_STATE_RESET;
cdc_acm -> ux_device_class_cdc_acm_read_status =
transfer_request -> ux_slave_transfer_request_completion_code;
- return(UX_STATE_EXIT);
+ return(UX_STATE_ERROR);
}
/* Success case. */
diff --git a/common/usbx_device_classes/src/ux_device_class_cdc_acm_tasks_run.c b/common/usbx_device_classes/src/ux_device_class_cdc_acm_tasks_run.c
index 63c4e8f..55f5ddd 100644
--- a/common/usbx_device_classes/src/ux_device_class_cdc_acm_tasks_run.c
+++ b/common/usbx_device_classes/src/ux_device_class_cdc_acm_tasks_run.c
@@ -31,8 +31,11 @@
#if defined(UX_DEVICE_STANDALONE)
+
+#ifndef UX_DEVICE_CLASS_CDC_ACM_TRANSMISSION_DISABLE
static inline VOID _ux_device_class_cdc_acm_transmission_read_run(UX_SLAVE_CLASS_CDC_ACM *cdc_acm);
static inline VOID _ux_device_class_cdc_acm_transmission_write_run(UX_SLAVE_CLASS_CDC_ACM *cdc_acm);
+#endif
/**************************************************************************/
@@ -40,7 +43,7 @@ static inline VOID _ux_device_class_cdc_acm_transmission_write_run(UX_SLAVE_CLAS
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_cdc_acm_tasks_run PORTABLE C */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -80,21 +83,23 @@ static inline VOID _ux_device_class_cdc_acm_transmission_write_run(UX_SLAVE_CLAS
/* names conflict C++ keyword, */
/* supported write auto ZLP, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* fixed compile warnings, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_device_class_cdc_acm_tasks_run(VOID *instance)
{
-UX_SLAVE_DEVICE *device;
-UX_SLAVE_CLASS_CDC_ACM *cdc_acm;
UINT status = UX_STATE_IDLE;
+#ifndef UX_DEVICE_CLASS_CDC_ACM_TRANSMISSION_DISABLE
+UX_SLAVE_DEVICE *device;
+UX_SLAVE_CLASS_CDC_ACM *cdc_acm;
/* Get CDC ACM instance. */
cdc_acm = (UX_SLAVE_CLASS_CDC_ACM*) instance;
-#ifndef UX_DEVICE_CLASS_CDC_ACM_TRANSMISSION_DISABLE
-
/* Check if transmission is started. */
if (!cdc_acm -> ux_slave_class_cdc_acm_transmission_status)
return(status);
diff --git a/common/usbx_device_classes/src/ux_device_class_cdc_acm_write_run.c b/common/usbx_device_classes/src/ux_device_class_cdc_acm_write_run.c
index 630bea7..35ea2ad 100644
--- a/common/usbx_device_classes/src/ux_device_class_cdc_acm_write_run.c
+++ b/common/usbx_device_classes/src/ux_device_class_cdc_acm_write_run.c
@@ -37,7 +37,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_cdc_acm_write_run PORTABLE C */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -83,6 +83,9 @@
/* names conflict C++ keyword, */
/* added auto ZLP support, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Yajun Xia Modified comment(s), */
+/* fixed return code, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_device_class_cdc_acm_write_run(UX_SLAVE_CLASS_CDC_ACM *cdc_acm,
@@ -125,7 +128,7 @@ UINT status = 0;
cdc_acm -> ux_device_class_cdc_acm_write_state = UX_STATE_RESET;
cdc_acm -> ux_device_class_cdc_acm_write_status = UX_CONFIGURATION_HANDLE_UNKNOWN;
- return(UX_CONFIGURATION_HANDLE_UNKNOWN);
+ return(UX_STATE_EXIT);
}
/* We need the interface to the class. */
@@ -224,7 +227,7 @@ UINT status = 0;
cdc_acm -> ux_device_class_cdc_acm_write_state = UX_STATE_RESET;
cdc_acm -> ux_device_class_cdc_acm_write_status =
transfer_request -> ux_slave_transfer_request_completion_code;
- return(UX_STATE_EXIT);
+ return(UX_STATE_ERROR);
}
/* Success case. */
diff --git a/common/usbx_device_classes/src/ux_device_class_cdc_ecm_bulkin_thread.c b/common/usbx_device_classes/src/ux_device_class_cdc_ecm_bulkin_thread.c
index a30a9bd..57968f6 100644
--- a/common/usbx_device_classes/src/ux_device_class_cdc_ecm_bulkin_thread.c
+++ b/common/usbx_device_classes/src/ux_device_class_cdc_ecm_bulkin_thread.c
@@ -35,7 +35,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_cdc_ecm_bulkin_thread PORTABLE C */
-/* 6.1.11 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -83,6 +83,9 @@
/* 04-25-2022 Chaoqiong Xiao Modified comment(s), */
/* fixed standalone compile, */
/* resulting in version 6.1.11 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* used NX API to copy data, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
VOID _ux_device_class_cdc_ecm_bulkin_thread(ULONG cdc_ecm_class)
@@ -95,8 +98,8 @@ UX_SLAVE_TRANSFER *transfer_request;
UINT status;
ULONG actual_flags;
NX_PACKET *current_packet;
-UCHAR *packet_header;
ULONG transfer_length;
+ULONG copied;
/* Cast properly the cdc_ecm instance. */
UX_THREAD_EXTENSION_PTR_GET(class_ptr, UX_SLAVE_CLASS, cdc_ecm_class)
@@ -148,24 +151,26 @@ ULONG transfer_length;
if (cdc_ecm -> ux_slave_class_cdc_ecm_link_state == UX_DEVICE_CLASS_CDC_ECM_LINK_STATE_UP)
{
- /* Load the address of the current packet header at the physical header. */
- packet_header = current_packet -> nx_packet_prepend_ptr;
-
/* Can the packet fit in the transfer requests data buffer? */
if (current_packet -> nx_packet_length <= UX_SLAVE_REQUEST_DATA_MAX_LENGTH)
{
/* Copy the packet in the transfer descriptor buffer. */
- _ux_utility_memory_copy(transfer_request -> ux_slave_transfer_request_data_pointer, packet_header, current_packet -> nx_packet_length); /* Use case of memcpy is verified. */
+ status = nx_packet_data_extract_offset(current_packet, 0,
+ transfer_request -> ux_slave_transfer_request_data_pointer,
+ current_packet -> nx_packet_length, &copied);
+ if (status == UX_SUCCESS)
+ {
- /* Calculate the transfer length. */
- transfer_length = current_packet -> nx_packet_length;
-
- /* If trace is enabled, insert this event into the trace buffer. */
- UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_CLASS_CDC_ECM_PACKET_TRANSMIT, cdc_ecm, 0, 0, 0, UX_TRACE_DEVICE_CLASS_EVENTS, 0, 0)
+ /* Calculate the transfer length. */
+ transfer_length = current_packet -> nx_packet_length;
+
+ /* If trace is enabled, insert this event into the trace buffer. */
+ UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_CLASS_CDC_ECM_PACKET_TRANSMIT, cdc_ecm, 0, 0, 0, UX_TRACE_DEVICE_CLASS_EVENTS, 0, 0)
- /* Send the request to the device controller. */
- status = _ux_device_stack_transfer_request(transfer_request, transfer_length, UX_DEVICE_CLASS_CDC_ECM_ETHERNET_PACKET_SIZE);
+ /* Send the request to the device controller. */
+ status = _ux_device_stack_transfer_request(transfer_request, transfer_length, UX_DEVICE_CLASS_CDC_ECM_ETHERNET_PACKET_SIZE + 1);
+ }
/* Check error code. */
if (status != UX_SUCCESS)
diff --git a/common/usbx_device_classes/src/ux_device_class_cdc_ecm_bulkout_thread.c b/common/usbx_device_classes/src/ux_device_class_cdc_ecm_bulkout_thread.c
index 6b0ba9f..8b1cc26 100644
--- a/common/usbx_device_classes/src/ux_device_class_cdc_ecm_bulkout_thread.c
+++ b/common/usbx_device_classes/src/ux_device_class_cdc_ecm_bulkout_thread.c
@@ -35,7 +35,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_cdc_ecm_bulkout_thread PORTABLE C */
-/* 6.1.11 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -83,6 +83,11 @@
/* 04-25-2022 Chaoqiong Xiao Modified comment(s), */
/* fixed standalone compile, */
/* resulting in version 6.1.11 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* fixed EP not ready issue, */
+/* used pool from NX IP inst, */
+/* used NX API to copy data, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
VOID _ux_device_class_cdc_ecm_bulkout_thread(ULONG cdc_ecm_class)
@@ -94,7 +99,7 @@ UX_SLAVE_DEVICE *device;
UX_SLAVE_TRANSFER *transfer_request;
UINT status;
NX_PACKET *packet;
-ULONG ip_given_length;
+USB_NETWORK_DEVICE_TYPE *ux_nx_device;
/* Cast properly the cdc_ecm instance. */
UX_THREAD_EXTENSION_PTR_GET(class_ptr, UX_SLAVE_CLASS, cdc_ecm_class)
@@ -113,8 +118,38 @@ ULONG ip_given_length;
while (device -> ux_slave_device_state == UX_DEVICE_CONFIGURED)
{
+ /* Check if packet pool is ready. */
+ if (cdc_ecm -> ux_slave_class_cdc_ecm_packet_pool == UX_NULL)
+ {
+
+ /* Get the network device handle. */
+ ux_nx_device = (USB_NETWORK_DEVICE_TYPE *)(cdc_ecm -> ux_slave_class_cdc_ecm_network_handle);
+
+ /* Get packet pool from IP instance (if available). */
+ if (ux_nx_device -> ux_network_device_ip_instance != UX_NULL)
+ {
+ cdc_ecm -> ux_slave_class_cdc_ecm_packet_pool = ux_nx_device -> ux_network_device_ip_instance -> nx_ip_default_packet_pool;
+ }
+ else
+ {
+
+ /* Error trap. */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_CLASS_ETH_PACKET_POOL_ERROR);
+
+ _ux_utility_delay_ms(UX_DEVICE_CLASS_CDC_ECM_PACKET_POOL_INST_WAIT);
+ continue;
+ }
+ }
+
+ /* Check if Bulk OUT endpoint is ready. */
+ if (cdc_ecm -> ux_slave_class_cdc_ecm_bulkout_endpoint == UX_NULL)
+ {
+ _ux_utility_delay_ms(UX_DEVICE_CLASS_CDC_ECM_LINK_CHECK_WAIT);
+ continue;
+ }
+
/* We can accept new reception. Get a NX Packet */
- status = nx_packet_allocate(&cdc_ecm -> ux_slave_class_cdc_ecm_packet_pool, &packet,
+ status = nx_packet_allocate(cdc_ecm -> ux_slave_class_cdc_ecm_packet_pool, &packet,
NX_RECEIVE_PACKET, UX_MS_TO_TICK(UX_DEVICE_CLASS_CDC_ECM_PACKET_POOL_WAIT));
if (status == NX_SUCCESS)
@@ -136,7 +171,7 @@ ULONG ip_given_length;
/* Send the request to the device controller. */
status = _ux_device_stack_transfer_request(transfer_request, UX_DEVICE_CLASS_CDC_ECM_MAX_PACKET_LENGTH,
UX_DEVICE_CLASS_CDC_ECM_MAX_PACKET_LENGTH);
-
+
/* Check the completion code. */
if (status == UX_SUCCESS)
{
@@ -147,26 +182,27 @@ ULONG ip_given_length;
/* Adjust the prepend pointer to take into account the non 3 bit alignment of the ethernet header. */
packet -> nx_packet_prepend_ptr += sizeof(USHORT);
-
- /* Set the prepend, length, and append fields. */
- packet -> nx_packet_length = transfer_request -> ux_slave_transfer_request_actual_length;
- packet -> nx_packet_append_ptr = packet -> nx_packet_prepend_ptr + transfer_request -> ux_slave_transfer_request_actual_length;
-
+ packet -> nx_packet_append_ptr += sizeof(USHORT);
+
/* Copy the received packet in the IP packet data area. */
- _ux_utility_memory_copy(packet -> nx_packet_prepend_ptr, transfer_request -> ux_slave_transfer_request_data_pointer, packet -> nx_packet_length); /* Use case of memcpy is verified. */
-
- /* Calculate the accurate packet length from ip header. */
- if((*(packet -> nx_packet_prepend_ptr + 12) == 0x08) &&
- (*(packet -> nx_packet_prepend_ptr + 13) == 0))
+ status = nx_packet_data_append(packet,
+ transfer_request -> ux_slave_transfer_request_data_pointer,
+ transfer_request -> ux_slave_transfer_request_actual_length,
+ cdc_ecm -> ux_slave_class_cdc_ecm_packet_pool,
+ UX_MS_TO_TICK(UX_DEVICE_CLASS_CDC_ECM_PACKET_POOL_WAIT));
+ if (status == NX_SUCCESS)
+ {
+
+ /* Send that packet to the NetX USB broker. */
+ _ux_network_driver_packet_received(cdc_ecm -> ux_slave_class_cdc_ecm_network_handle, packet);
+ }
+ else
{
- ip_given_length = _ux_utility_short_get_big_endian(packet -> nx_packet_prepend_ptr + 16) + UX_DEVICE_CLASS_CDC_ECM_ETHERNET_SIZE;
- packet -> nx_packet_length = ip_given_length ;
- packet -> nx_packet_append_ptr = packet -> nx_packet_prepend_ptr + ip_given_length;
+ /* We received a malformed packet. Report to application. */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_CLASS_MALFORMED_PACKET_RECEIVED_ERROR);
+ nx_packet_release(packet);
}
-
- /* Send that packet to the NetX USB broker. */
- _ux_network_driver_packet_received(cdc_ecm -> ux_slave_class_cdc_ecm_network_handle, packet);
}
else
diff --git a/common/usbx_device_classes/src/ux_device_class_cdc_ecm_initialize.c b/common/usbx_device_classes/src/ux_device_class_cdc_ecm_initialize.c
index f1723be..84ae21b 100644
--- a/common/usbx_device_classes/src/ux_device_class_cdc_ecm_initialize.c
+++ b/common/usbx_device_classes/src/ux_device_class_cdc_ecm_initialize.c
@@ -27,14 +27,13 @@
#include "ux_device_class_cdc_ecm.h"
#include "ux_device_stack.h"
-UX_DEVICE_CLASS_CDC_ECM_NX_ETHERNET_POOL_ALLOCSIZE_ASSERT
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_cdc_ecm_initialize PORTABLE C */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -61,8 +60,6 @@ UX_DEVICE_CLASS_CDC_ECM_NX_ETHERNET_POOL_ALLOCSIZE_ASSERT
/* _ux_utility_event_flags_delete Delete Flag group */
/* _ux_device_thread_create Create Thread */
/* _ux_device_thread_delete Delete Thread */
-/* nx_packet_pool_create Create NetX packet pool */
-/* nx_packet_pool_delete Delete NetX packet pool */
/* */
/* CALLED BY */
/* */
@@ -89,6 +86,9 @@ UX_DEVICE_CLASS_CDC_ECM_NX_ETHERNET_POOL_ALLOCSIZE_ASSERT
/* fixed parameter/variable */
/* names conflict C++ keyword, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* removed internal NX pool, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_device_class_cdc_ecm_initialize(UX_SLAVE_CLASS_COMMAND *command)
@@ -153,28 +153,6 @@ UINT status;
status = (UX_MEMORY_INSUFFICIENT);
}
- /* Allocate some packet pool for reception. */
- if (status == UX_SUCCESS)
- {
-
- /* UX_DEVICE_CLASS_CDC_ECM_NX_ETHERNET_POOL_ALLOCSIZE overflow has been checked by
- * UX_DEVICE_CLASS_CDC_ECM_NX_ETHERNET_POOL_ALLOCSIZE_ASSERT outside of function.
- */
- cdc_ecm -> ux_slave_class_cdc_ecm_pool_memory =
- _ux_utility_memory_allocate(UX_NO_ALIGN, UX_CACHE_SAFE_MEMORY, UX_DEVICE_CLASS_CDC_ECM_NX_ETHERNET_POOL_ALLOCSIZE);
-
- /* Check for successful allocation. */
- if (cdc_ecm -> ux_slave_class_cdc_ecm_pool_memory == UX_NULL)
- status = (UX_MEMORY_INSUFFICIENT);
- else
- {
- /* Create a packet pool. */
- status = nx_packet_pool_create(&cdc_ecm -> ux_slave_class_cdc_ecm_packet_pool, "CDC ECM Device Packet Pool",
- UX_DEVICE_CLASS_CDC_ECM_NX_PAYLOAD_SIZE, cdc_ecm -> ux_slave_class_cdc_ecm_pool_memory,
- UX_DEVICE_CLASS_CDC_ECM_NX_ETHERNET_POOL_ALLOCSIZE);
- }
- }
-
/* Interrupt endpoint treatment needs to be running in a different thread. So start
a new thread. We pass a pointer to the cdc_ecm instance to the new thread. This thread
does not start until we have a instance of the class. */
@@ -267,10 +245,6 @@ UINT status;
/* Free allocated resources. */
- if (cdc_ecm -> ux_slave_class_cdc_ecm_packet_pool.nx_packet_pool_id)
- nx_packet_pool_delete(&cdc_ecm -> ux_slave_class_cdc_ecm_packet_pool);
- if (cdc_ecm -> ux_slave_class_cdc_ecm_pool_memory)
- _ux_utility_memory_free(cdc_ecm -> ux_slave_class_cdc_ecm_pool_memory);
if (cdc_ecm -> ux_slave_class_cdc_ecm_bulkin_thread_stack)
_ux_utility_memory_free(cdc_ecm -> ux_slave_class_cdc_ecm_bulkin_thread_stack);
if (cdc_ecm -> ux_slave_class_cdc_ecm_interrupt_thread_stack)
diff --git a/common/usbx_device_classes/src/ux_device_class_cdc_ecm_uninitialize.c b/common/usbx_device_classes/src/ux_device_class_cdc_ecm_uninitialize.c
index c429632..43ae217 100644
--- a/common/usbx_device_classes/src/ux_device_class_cdc_ecm_uninitialize.c
+++ b/common/usbx_device_classes/src/ux_device_class_cdc_ecm_uninitialize.c
@@ -35,7 +35,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_cdc_ecm_uninitialize PORTABLE C */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -82,6 +82,9 @@
/* fixed parameter/variable */
/* names conflict C++ keyword, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* removed internal NX pool, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_device_class_cdc_ecm_uninitialize(UX_SLAVE_CLASS_COMMAND *command)
@@ -131,14 +134,8 @@ UX_SLAVE_CLASS *class_ptr;
/* Delete the interrupt thread sync event flags group. */
_ux_device_event_flags_delete(&cdc_ecm -> ux_slave_class_cdc_ecm_event_flags_group);
- /* Delete the reception packet pool. */
- nx_packet_pool_delete(&cdc_ecm -> ux_slave_class_cdc_ecm_packet_pool);
-
#endif
- /* Free the packet pool memory. */
- _ux_utility_memory_free(cdc_ecm -> ux_slave_class_cdc_ecm_pool_memory);
-
/* Free the resources. */
_ux_utility_memory_free(cdc_ecm);
}
diff --git a/common/usbx_device_classes/src/ux_device_class_hid_control_request.c b/common/usbx_device_classes/src/ux_device_class_hid_control_request.c
index 4d04c38..4d04c38 100755..100644
--- a/common/usbx_device_classes/src/ux_device_class_hid_control_request.c
+++ b/common/usbx_device_classes/src/ux_device_class_hid_control_request.c
diff --git a/common/usbx_device_classes/src/ux_device_class_hid_initialize.c b/common/usbx_device_classes/src/ux_device_class_hid_initialize.c
index 22f8e46..74fc89b 100644
--- a/common/usbx_device_classes/src/ux_device_class_hid_initialize.c
+++ b/common/usbx_device_classes/src/ux_device_class_hid_initialize.c
@@ -33,7 +33,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_hid_initialize PORTABLE C */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -85,6 +85,9 @@
/* fixed parameter/variable */
/* names conflict C++ keyword, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* fixed compile warnings, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_device_class_hid_initialize(UX_SLAVE_CLASS_COMMAND *command)
@@ -228,8 +231,13 @@ UINT status = UX_SUCCESS;
}
+#if !defined(UX_DEVICE_STANDALONE) || defined(UX_DEVICE_CLASS_HID_INTERRUPT_OUT_SUPPORT)
+
+ /* There is still initialization activities after array creation,
+ * and some error occurs in this stage. */
/* Free allocated event array memory. */
_ux_utility_memory_free(hid -> ux_device_class_hid_event_array);
+#endif
}
else
diff --git a/common/usbx_device_classes/src/ux_device_class_printer_initialize.c b/common/usbx_device_classes/src/ux_device_class_printer_initialize.c
index 1007d29..f07e446 100644
--- a/common/usbx_device_classes/src/ux_device_class_printer_initialize.c
+++ b/common/usbx_device_classes/src/ux_device_class_printer_initialize.c
@@ -33,7 +33,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_printer_initialize PORTABLE C */
-/* 6.1.11 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -69,19 +69,20 @@
/* 04-25-2022 Chaoqiong Xiao Modified comment(s), */
/* fixed standalone compile, */
/* resulting in version 6.1.11 */
+/* 10-31-2022 Yajun Xia Modified comment(s), */
+/* added standalone support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_device_class_printer_initialize(UX_SLAVE_CLASS_COMMAND *command)
{
-#if defined(UX_DEVICE_STANDALONE)
- UX_PARAMETER_NOT_USED(command);
- return(UX_FUNCTION_NOT_SUPPORTED);
-#else
UX_DEVICE_CLASS_PRINTER *printer;
UX_DEVICE_CLASS_PRINTER_PARAMETER *printer_parameter;
UX_SLAVE_CLASS *printer_class;
+#if !defined(UX_DEVICE_STANDALONE)
UINT status;
+#endif
/* Get the class container. */
printer_class = command -> ux_slave_class_command_class_ptr;
@@ -105,6 +106,7 @@ UINT status;
printer -> ux_device_class_printer_parameter.ux_device_class_printer_instance_deactivate = printer_parameter -> ux_device_class_printer_instance_deactivate;
printer -> ux_device_class_printer_parameter.ux_device_class_printer_soft_reset = printer_parameter -> ux_device_class_printer_soft_reset;
+#if !defined(UX_DEVICE_STANDALONE)
/* Create the Mutex for each endpoint as multiple threads cannot access each pipe at the same time. */
status = _ux_utility_mutex_create(&printer -> ux_device_class_printer_endpoint_in_mutex, "ux_device_class_printer_in_mutex");
@@ -135,11 +137,14 @@ UINT status;
/* Return fatal error. */
return(UX_MUTEX_ERROR);
}
+#else
+ printer -> ux_device_class_printer_write_state = UX_STATE_RESET;
+ printer -> ux_device_class_printer_read_state = UX_STATE_RESET;
+#endif
/* Reset port status. */
printer -> ux_device_class_printer_port_status = 0;
/* Return completion status. */
return(UX_SUCCESS);
-#endif
}
diff --git a/common/usbx_device_classes/src/ux_device_class_printer_read_run.c b/common/usbx_device_classes/src/ux_device_class_printer_read_run.c
new file mode 100644
index 0000000..acfb390
--- /dev/null
+++ b/common/usbx_device_classes/src/ux_device_class_printer_read_run.c
@@ -0,0 +1,238 @@
+/**************************************************************************/
+/* */
+/* 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 Printer Class */
+/** */
+/**************************************************************************/
+/**************************************************************************/
+
+#define UX_SOURCE_CODE
+
+
+/* Include necessary system files. */
+
+#include "ux_api.h"
+#include "ux_device_class_printer.h"
+#include "ux_device_stack.h"
+
+
+#if defined(UX_DEVICE_STANDALONE)
+
+
+/**************************************************************************/
+/* */
+/* FUNCTION RELEASE */
+/* */
+/* _ux_device_class_printer_read_run PORTABLE C */
+/* 6.2.0 */
+/* AUTHOR */
+/* */
+/* Yajun Xia, Microsoft Corporation */
+/* */
+/* DESCRIPTION */
+/* */
+/* This function reads from the Printer class. */
+/* */
+/* It's for standalone mode. */
+/* */
+/* INPUT */
+/* */
+/* printer Address of printer class */
+/* instance */
+/* buffer Pointer to buffer to save */
+/* received data */
+/* requested_length Length of bytes to read */
+/* actual_length Pointer to save number of */
+/* bytes read */
+/* */
+/* OUTPUT */
+/* */
+/* State machine Status to check */
+/* UX_STATE_NEXT Transfer done, to next state */
+/* UX_STATE_EXIT Abnormal, to reset state */
+/* (others) Keep running, waiting */
+/* */
+/* CALLS */
+/* */
+/* _ux_device_stack_transfer_run Transfer request */
+/* _ux_utility_memory_copy Copy memory */
+/* */
+/* CALLED BY */
+/* */
+/* Application */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 10-31-2022 Yajun xia Initial Version 6.2.0 */
+/* */
+/**************************************************************************/
+UINT _ux_device_class_printer_read_run(UX_DEVICE_CLASS_PRINTER *printer, UCHAR *buffer,
+ ULONG requested_length, ULONG *actual_length)
+{
+
+UX_SLAVE_ENDPOINT *endpoint;
+UX_SLAVE_DEVICE *device;
+UX_SLAVE_TRANSFER *transfer_request;
+ULONG max_transfer_length;
+UINT status = UX_SUCCESS;
+
+ /* If trace is enabled, insert this event into the trace buffer. */
+ UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_CLASS_PRINTER_READ, printer, buffer, requested_length, 0, UX_TRACE_DEVICE_CLASS_EVENTS, 0, 0)
+
+ /* Get the pointer to the device. */
+ device = &_ux_system_slave -> ux_system_slave_device;
+
+ /* As long as the device is in the CONFIGURED state. */
+ if (device -> ux_slave_device_state != UX_DEVICE_CONFIGURED)
+ {
+
+ /* Error trap. */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_CONFIGURATION_HANDLE_UNKNOWN);
+
+ /* If trace is enabled, insert this event into the trace buffer. */
+ UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_CONFIGURATION_HANDLE_UNKNOWN, device, 0, 0, UX_TRACE_ERRORS, 0, 0)
+
+ /* Cannot proceed with command, the interface is down. */
+ printer -> ux_device_class_printer_read_state = UX_STATE_RESET;
+ printer -> ux_device_class_printer_read_status = UX_CONFIGURATION_HANDLE_UNKNOWN;
+
+ return(UX_STATE_EXIT);
+ }
+
+ /* Locate the endpoint. */
+ endpoint = printer -> ux_device_class_printer_endpoint_out;
+
+ /* All Printer reading are on the endpoint OUT, from the host. */
+ transfer_request = &endpoint -> ux_slave_endpoint_transfer_request;
+
+ /* Handle state cases. */
+ switch(printer -> ux_device_class_printer_read_state)
+ {
+ case UX_STATE_RESET:
+
+ /* If trace is enabled, insert this event into the trace buffer. */
+ UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_CLASS_PRINTER_READ, printer, buffer, requested_length, 0, UX_TRACE_DEVICE_CLASS_EVENTS, 0, 0)
+
+ printer -> ux_device_class_printer_read_state = UX_DEVICE_CLASS_PRINTER_READ_START;
+ printer -> ux_device_class_printer_read_status = UX_TRANSFER_NO_ANSWER;
+ printer -> ux_device_class_printer_read_buffer = buffer;
+ printer -> ux_device_class_printer_read_requested_length = requested_length;
+ printer -> ux_device_class_printer_read_actual_length = 0;
+
+ /* Fall through. */
+ case UX_DEVICE_CLASS_PRINTER_READ_START:
+
+ /* Get remaining transfer length. */
+ requested_length = printer -> ux_device_class_printer_read_requested_length -
+ printer -> ux_device_class_printer_read_actual_length;
+
+ /* There is nothing remaining, it's done. */
+ if (requested_length == 0)
+ {
+ *actual_length = printer -> ux_device_class_printer_read_actual_length;
+ printer -> ux_device_class_printer_read_state = UX_STATE_RESET;
+ printer -> ux_device_class_printer_read_status = UX_SUCCESS;
+ return(UX_STATE_NEXT);
+ }
+
+ printer -> ux_device_class_printer_read_transfer_length = requested_length;
+
+ /* Next state. */
+ printer -> ux_device_class_printer_read_state = UX_DEVICE_CLASS_PRINTER_READ_WAIT;
+ UX_SLAVE_TRANSFER_STATE_RESET(transfer_request);
+
+ /* Fall through. */
+ case UX_DEVICE_CLASS_PRINTER_READ_WAIT:
+
+ /* Get a full packet each time */
+ max_transfer_length = endpoint -> ux_slave_endpoint_descriptor.wMaxPacketSize;
+
+ /* Run the transfer state machine. */
+ status = _ux_device_stack_transfer_run(transfer_request,
+ max_transfer_length,
+ max_transfer_length);
+
+ /* Error case. */
+ if (status < UX_STATE_NEXT)
+ {
+ printer -> ux_device_class_printer_read_state = UX_STATE_RESET;
+ printer -> ux_device_class_printer_read_status =
+ transfer_request -> ux_slave_transfer_request_completion_code;
+ return(UX_STATE_ERROR);
+ }
+
+ /* Success case. */
+ if (status == UX_STATE_NEXT)
+ {
+ /* Check overflow */
+ if (printer -> ux_device_class_printer_read_transfer_length <
+ transfer_request -> ux_slave_transfer_request_actual_length)
+ {
+ printer -> ux_device_class_printer_read_state = UX_STATE_ERROR;
+ printer -> ux_device_class_printer_read_status = UX_TRANSFER_BUFFER_OVERFLOW;
+ return(UX_STATE_ERROR);
+ }
+
+ /* We need to copy the buffer locally. */
+ _ux_utility_memory_copy(printer -> ux_device_class_printer_read_buffer,
+ transfer_request -> ux_slave_transfer_request_data_pointer,
+ transfer_request -> ux_slave_transfer_request_actual_length); /* Use case of memcpy is verified. */
+
+ /* Next buffer address. */
+ printer -> ux_device_class_printer_read_buffer +=
+ transfer_request -> ux_slave_transfer_request_actual_length;
+
+ /* Set the length actually received. */
+ printer -> ux_device_class_printer_read_actual_length +=
+ transfer_request -> ux_slave_transfer_request_actual_length;
+
+ /* Last transfer status. */
+ printer -> ux_device_class_printer_read_status =
+ transfer_request -> ux_slave_transfer_request_completion_code;
+
+ /* Update actual length. */
+ *actual_length = printer -> ux_device_class_printer_read_actual_length;
+
+ /* Check short packet. */
+ if (transfer_request -> ux_slave_transfer_request_actual_length <
+ transfer_request -> ux_slave_transfer_request_requested_length)
+ {
+
+ /* It's done. */
+ printer -> ux_device_class_printer_read_state = UX_STATE_RESET;
+ return(UX_STATE_NEXT);
+ }
+
+ /* Next state. */
+ printer -> ux_device_class_printer_read_state = UX_DEVICE_CLASS_PRINTER_READ_START;
+ }
+
+ /* Keep waiting. */
+ return(UX_STATE_WAIT);
+
+ default: /* Error. */
+ printer -> ux_device_class_printer_read_state = UX_STATE_RESET;
+ printer -> ux_device_class_printer_read_status = UX_INVALID_STATE;
+ break;
+ }
+
+ /* Error cases. */
+ return(UX_STATE_EXIT);
+}
+
+#endif
diff --git a/common/usbx_device_classes/src/ux_device_class_printer_soft_reset.c b/common/usbx_device_classes/src/ux_device_class_printer_soft_reset.c
index fa96f3b..9d41d96 100644
--- a/common/usbx_device_classes/src/ux_device_class_printer_soft_reset.c
+++ b/common/usbx_device_classes/src/ux_device_class_printer_soft_reset.c
@@ -34,7 +34,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_printer_soft_reset PORTABLE C */
-/* 6.1.10 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -66,6 +66,9 @@
/* DATE NAME DESCRIPTION */
/* */
/* 01-31-2022 Chaoqiong Xiao Initial Version 6.1.10 */
+/* 10-31-2022 Yajun Xia Modified comment(s), */
+/* added standalone support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
VOID _ux_device_class_printer_soft_reset(UX_DEVICE_CLASS_PRINTER *printer)
@@ -76,11 +79,17 @@ UX_SLAVE_ENDPOINT *endpoint;
/* Stop OUT. */
endpoint = printer -> ux_device_class_printer_endpoint_out;
_ux_device_stack_transfer_all_request_abort(endpoint, UX_ENDPOINT_RESET);
+#if defined(UX_DEVICE_STANDALONE)
+ printer -> ux_device_class_printer_write_state = UX_STATE_RESET;
+#endif
/* Stop IN (optional). */
endpoint = printer -> ux_device_class_printer_endpoint_in;
if (endpoint != UX_NULL)
{
_ux_device_stack_transfer_all_request_abort(endpoint, UX_ENDPOINT_RESET);
+#if defined(UX_DEVICE_STANDALONE)
+ printer -> ux_device_class_printer_read_state = UX_STATE_RESET;
+#endif
}
}
diff --git a/common/usbx_device_classes/src/ux_device_class_printer_uninitialize.c b/common/usbx_device_classes/src/ux_device_class_printer_uninitialize.c
index 1ff77aa..6a4e956 100644
--- a/common/usbx_device_classes/src/ux_device_class_printer_uninitialize.c
+++ b/common/usbx_device_classes/src/ux_device_class_printer_uninitialize.c
@@ -34,7 +34,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_printer_uninitialize PORTABLE C */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -72,6 +72,9 @@
/* fixed parameter/variable */
/* names conflict C++ keyword, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Yajun Xia Modified comment(s), */
+/* added standalone support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_device_class_printer_uninitialize(UX_SLAVE_CLASS_COMMAND *command)
@@ -89,13 +92,13 @@ UX_SLAVE_CLASS *class_ptr;
/* Sanity check. */
if (printer != UX_NULL)
{
-
+#if !defined(UX_DEVICE_STANDALONE)
/* Delete the IN endpoint mutex. */
_ux_device_mutex_delete(&printer -> ux_device_class_printer_endpoint_in_mutex);
/* Out Mutex. */
_ux_device_mutex_delete(&printer -> ux_device_class_printer_endpoint_out_mutex);
-
+#endif
/* Free the resources. */
_ux_utility_memory_free(printer);
}
diff --git a/common/usbx_device_classes/src/ux_device_class_printer_write_run.c b/common/usbx_device_classes/src/ux_device_class_printer_write_run.c
new file mode 100644
index 0000000..d078cd4
--- /dev/null
+++ b/common/usbx_device_classes/src/ux_device_class_printer_write_run.c
@@ -0,0 +1,258 @@
+/**************************************************************************/
+/* */
+/* 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 Printer Class */
+/** */
+/**************************************************************************/
+/**************************************************************************/
+
+#define UX_SOURCE_CODE
+
+
+/* Include necessary system files. */
+
+#include "ux_api.h"
+#include "ux_device_class_printer.h"
+#include "ux_device_stack.h"
+
+
+#if defined(UX_DEVICE_STANDALONE)
+
+/**************************************************************************/
+/* */
+/* FUNCTION RELEASE */
+/* */
+/* _ux_device_class_printer_write_run PORTABLE C */
+/* 6.2.0 */
+/* AUTHOR */
+/* */
+/* Yajun Xia, Microsoft Corporation */
+/* */
+/* DESCRIPTION */
+/* */
+/* This function writes to the Printer class. */
+/* */
+/* It's for standalone mode. */
+/* */
+/* INPUT */
+/* */
+/* printer Address of printer class */
+/* instance */
+/* buffer Pointer to data to write */
+/* requested_length Length of bytes to write, */
+/* set to 0 to issue ZLP */
+/* actual_length Pointer to save number of */
+/* bytes written */
+/* */
+/* OUTPUT */
+/* */
+/* State machine Status to check */
+/* UX_STATE_NEXT Transfer done, to next state */
+/* UX_STATE_EXIT Abnormal, to reset state */
+/* (others) Keep running, waiting */
+/* */
+/* CALLS */
+/* */
+/* _ux_device_stack_transfer_run Run Transfer state machine */
+/* _ux_utility_memory_copy Copy memory */
+/* */
+/* CALLED BY */
+/* */
+/* Application */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 10-31-2022 Yajun Xia Initial Version 6.2.0 */
+/* */
+/**************************************************************************/
+UINT _ux_device_class_printer_write_run(UX_DEVICE_CLASS_PRINTER *printer, UCHAR *buffer,
+ ULONG requested_length, ULONG *actual_length)
+{
+
+UX_SLAVE_ENDPOINT *endpoint;
+UX_SLAVE_DEVICE *device;
+UX_SLAVE_TRANSFER *transfer_request;
+UINT zlp = UX_FALSE;
+UINT status = 0;
+
+ /* If trace is enabled, insert this event into the trace buffer. */
+ UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_CLASS_PRINTER_WRITE, printer, buffer, requested_length, 0, UX_TRACE_DEVICE_CLASS_EVENTS, 0, 0)
+
+ /* Get the pointer to the device. */
+ device = &_ux_system_slave -> ux_system_slave_device;
+
+ /* As long as the device is in the CONFIGURED state. */
+ if (device -> ux_slave_device_state != UX_DEVICE_CONFIGURED)
+ {
+
+ /* Error trap. */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_CONFIGURATION_HANDLE_UNKNOWN);
+
+ /* If trace is enabled, insert this event into the trace buffer. */
+ UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_CONFIGURATION_HANDLE_UNKNOWN, device, 0, 0, UX_TRACE_ERRORS, 0, 0)
+
+ /* Cannot proceed with command, the interface is down. */
+ printer -> ux_device_class_printer_write_state = UX_STATE_RESET;
+ printer -> ux_device_class_printer_write_status = UX_CONFIGURATION_HANDLE_UNKNOWN;
+
+ return(UX_STATE_EXIT);
+ }
+
+ /* Locate the endpoints. */
+ endpoint = printer -> ux_device_class_printer_endpoint_in;
+
+ /* Check if it's available. */
+ if (endpoint == UX_NULL)
+ {
+ /* Error trap. */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_ENDPOINT_HANDLE_UNKNOWN);
+
+ printer -> ux_device_class_printer_write_state = UX_STATE_RESET;
+ printer -> ux_device_class_printer_write_status = UX_ENDPOINT_HANDLE_UNKNOWN;
+
+ return(UX_STATE_EXIT);
+ }
+
+ /* We are writing to the IN endpoint. */
+ transfer_request = &endpoint -> ux_slave_endpoint_transfer_request;
+
+ /* Handle state cases. */
+ switch(printer -> ux_device_class_printer_write_state)
+ {
+ case UX_STATE_RESET:
+ printer -> ux_device_class_printer_write_state = UX_DEVICE_CLASS_PRINTER_WRITE_START;
+ printer -> ux_device_class_printer_write_status = UX_TRANSFER_NO_ANSWER;
+ printer -> ux_device_class_printer_write_buffer = buffer;
+ printer -> ux_device_class_printer_write_requested_length = requested_length;
+ printer -> ux_device_class_printer_write_actual_length = 0;
+ printer -> ux_device_class_printer_write_host_length = UX_SLAVE_REQUEST_DATA_MAX_LENGTH;
+ if (requested_length == 0)
+ zlp = UX_TRUE;
+
+ /* Fall through. */
+ case UX_DEVICE_CLASS_PRINTER_WRITE_START:
+
+ /* Get remaining requested length. */
+ requested_length = printer -> ux_device_class_printer_write_requested_length -
+ printer -> ux_device_class_printer_write_actual_length;
+
+ /* There is no remaining, we are done. */
+ if (requested_length == 0 && !zlp)
+ {
+ *actual_length = printer -> ux_device_class_printer_write_actual_length;
+ printer -> ux_device_class_printer_write_state = UX_STATE_RESET;
+ printer -> ux_device_class_printer_write_status = UX_SUCCESS;
+ return(UX_STATE_NEXT);
+ }
+
+ /* Check if we have enough in the local buffer. */
+ if (requested_length > UX_SLAVE_REQUEST_DATA_MAX_LENGTH)
+
+ /* We have too much to transfer. */
+ printer -> ux_device_class_printer_write_transfer_length =
+ UX_SLAVE_REQUEST_DATA_MAX_LENGTH;
+
+ else
+ {
+
+ /* We can proceed with the demanded length. */
+ printer -> ux_device_class_printer_write_transfer_length = requested_length;
+
+#if !defined(UX_DEVICE_CLASS_PRINTER_WRITE_AUTO_ZLP)
+
+ /* Assume expected length and transfer length match. */
+ printer -> ux_device_class_printer_write_host_length = requested_length;
+#else
+
+ /* Assume expected more than transfer to let stack append ZLP if needed. */
+ printer -> ux_device_class_printer_write_host_length = UX_SLAVE_REQUEST_DATA_MAX_LENGTH + 1;
+#endif
+ }
+
+
+ /* On a out, we copy the buffer to the caller. Not very efficient but it makes the API
+ easier. */
+ _ux_utility_memory_copy(transfer_request -> ux_slave_transfer_request_data_pointer,
+ printer -> ux_device_class_printer_write_buffer,
+ printer -> ux_device_class_printer_write_transfer_length); /* Use case of memcpy is verified. */
+
+ /* Next state. */
+ printer -> ux_device_class_printer_write_state = UX_DEVICE_CLASS_PRINTER_WRITE_WAIT;
+ UX_SLAVE_TRANSFER_STATE_RESET(transfer_request);
+
+ /* Fall through. */
+ case UX_DEVICE_CLASS_PRINTER_WRITE_WAIT:
+
+ /* Send the request to the device controller. */
+ status = _ux_device_stack_transfer_run(transfer_request,
+ printer -> ux_device_class_printer_write_transfer_length,
+ printer -> ux_device_class_printer_write_host_length);
+
+ /* Error case. */
+ if (status < UX_STATE_NEXT)
+ {
+
+ printer -> ux_device_class_printer_write_state = UX_STATE_RESET;
+ printer -> ux_device_class_printer_write_status =
+ transfer_request -> ux_slave_transfer_request_completion_code;
+ return(UX_STATE_ERROR);
+ }
+
+ /* Success case. */
+ if (status == UX_STATE_NEXT)
+ {
+
+ /* Next buffer address. */
+ printer -> ux_device_class_printer_write_buffer +=
+ transfer_request -> ux_slave_transfer_request_actual_length;
+
+ /* Set the length actually received. */
+ printer -> ux_device_class_printer_write_actual_length +=
+ transfer_request -> ux_slave_transfer_request_actual_length;
+
+ /* Last transfer status. */
+ printer -> ux_device_class_printer_write_status =
+ transfer_request -> ux_slave_transfer_request_completion_code;
+
+ /* Update actual done length. */
+ *actual_length = printer -> ux_device_class_printer_write_actual_length;
+
+ /* Check ZLP case. */
+ if (printer -> ux_device_class_printer_write_requested_length == 0)
+ {
+ printer -> ux_device_class_printer_write_state = UX_STATE_RESET;
+ return(UX_STATE_NEXT);
+ }
+
+ /* Next state. */
+ printer -> ux_device_class_printer_write_state = UX_DEVICE_CLASS_PRINTER_WRITE_START;
+ }
+
+ /* Keep waiting. */
+ return(UX_STATE_WAIT);
+
+ default: /* Error. */
+ printer -> ux_device_class_printer_write_state = UX_STATE_RESET;
+ break;
+ }
+
+ /* Error case. */
+ return(UX_STATE_EXIT);
+}
+
+#endif
diff --git a/common/usbx_device_classes/src/ux_device_class_rndis_bulkin_thread.c b/common/usbx_device_classes/src/ux_device_class_rndis_bulkin_thread.c
index be900a9..92c1115 100644
--- a/common/usbx_device_classes/src/ux_device_class_rndis_bulkin_thread.c
+++ b/common/usbx_device_classes/src/ux_device_class_rndis_bulkin_thread.c
@@ -35,7 +35,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_rndis_bulkin_thread PORTABLE C */
-/* 6.1.11 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -85,6 +85,9 @@
/* 04-25-2022 Chaoqiong Xiao Modified comment(s), */
/* fixed standalone compile, */
/* resulting in version 6.1.11 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* used NX API to copy data, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
VOID _ux_device_class_rndis_bulkin_thread(ULONG rndis_class)
@@ -97,8 +100,8 @@ UX_SLAVE_TRANSFER *transfer_request;
UINT status;
ULONG actual_flags;
NX_PACKET *current_packet;
-UCHAR *packet_header;
ULONG transfer_length;
+ULONG copied;
/* Cast properly the rndis instance. */
UX_THREAD_EXTENSION_PTR_GET(class_ptr, UX_SLAVE_CLASS, rndis_class)
@@ -150,9 +153,6 @@ ULONG transfer_length;
if (rndis -> ux_slave_class_rndis_link_state == UX_DEVICE_CLASS_RNDIS_LINK_STATE_UP)
{
- /* Load the address of the current packet header at the physical header. */
- packet_header = current_packet -> nx_packet_prepend_ptr;
-
/* Calculate the transfer length. */
transfer_length = current_packet -> nx_packet_length + UX_DEVICE_CLASS_RNDIS_PACKET_HEADER_LENGTH;
@@ -161,21 +161,27 @@ ULONG transfer_length;
{
/* Copy the packet in the transfer descriptor buffer. */
- _ux_utility_memory_copy (transfer_request -> ux_slave_transfer_request_data_pointer + UX_DEVICE_CLASS_RNDIS_PACKET_HEADER_LENGTH, packet_header, current_packet -> nx_packet_length); /* Use case of memcpy is verified. */
-
- /* Add the RNDIS header to this packet. */
- _ux_utility_long_put(transfer_request -> ux_slave_transfer_request_data_pointer + UX_DEVICE_CLASS_RNDIS_PACKET_MESSAGE_TYPE, UX_DEVICE_CLASS_RNDIS_PACKET_HEADER_MSG);
- _ux_utility_long_put(transfer_request -> ux_slave_transfer_request_data_pointer + UX_DEVICE_CLASS_RNDIS_PACKET_MESSAGE_LENGTH, transfer_length);
- _ux_utility_long_put(transfer_request -> ux_slave_transfer_request_data_pointer + UX_DEVICE_CLASS_RNDIS_PACKET_DATA_OFFSET,
- UX_DEVICE_CLASS_RNDIS_PACKET_HEADER_LENGTH - UX_DEVICE_CLASS_RNDIS_PACKET_DATA_OFFSET);
- _ux_utility_long_put(transfer_request -> ux_slave_transfer_request_data_pointer + UX_DEVICE_CLASS_RNDIS_PACKET_DATA_LENGTH, current_packet -> nx_packet_length);
-
- /* If trace is enabled, insert this event into the trace buffer. */
- UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_CLASS_RNDIS_PACKET_TRANSMIT, rndis, 0, 0, 0, UX_TRACE_DEVICE_CLASS_EVENTS, 0, 0)
+ status = nx_packet_data_extract_offset(current_packet, 0,
+ transfer_request -> ux_slave_transfer_request_data_pointer +
+ UX_DEVICE_CLASS_RNDIS_PACKET_HEADER_LENGTH,
+ current_packet -> nx_packet_length, &copied);
+ if (status == NX_SUCCESS)
+ {
+
+ /* Add the RNDIS header to this packet. */
+ _ux_utility_long_put(transfer_request -> ux_slave_transfer_request_data_pointer + UX_DEVICE_CLASS_RNDIS_PACKET_MESSAGE_TYPE, UX_DEVICE_CLASS_RNDIS_PACKET_HEADER_MSG);
+ _ux_utility_long_put(transfer_request -> ux_slave_transfer_request_data_pointer + UX_DEVICE_CLASS_RNDIS_PACKET_MESSAGE_LENGTH, transfer_length);
+ _ux_utility_long_put(transfer_request -> ux_slave_transfer_request_data_pointer + UX_DEVICE_CLASS_RNDIS_PACKET_DATA_OFFSET,
+ UX_DEVICE_CLASS_RNDIS_PACKET_HEADER_LENGTH - UX_DEVICE_CLASS_RNDIS_PACKET_DATA_OFFSET);
+ _ux_utility_long_put(transfer_request -> ux_slave_transfer_request_data_pointer + UX_DEVICE_CLASS_RNDIS_PACKET_DATA_LENGTH, current_packet -> nx_packet_length);
+
+ /* If trace is enabled, insert this event into the trace buffer. */
+ UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_CLASS_RNDIS_PACKET_TRANSMIT, rndis, 0, 0, 0, UX_TRACE_DEVICE_CLASS_EVENTS, 0, 0)
+
+ /* Send the request to the device controller. */
+ status = _ux_device_stack_transfer_request(transfer_request, transfer_length, UX_DEVICE_CLASS_RNDIS_ETHERNET_PACKET_SIZE + 1);
+ }
- /* Send the request to the device controller. */
- status = _ux_device_stack_transfer_request(transfer_request, transfer_length, UX_DEVICE_CLASS_RNDIS_ETHERNET_PACKET_SIZE);
-
/* Check for error. */
if (status != UX_SUCCESS)
diff --git a/common/usbx_device_classes/src/ux_device_class_rndis_bulkout_thread.c b/common/usbx_device_classes/src/ux_device_class_rndis_bulkout_thread.c
index a569e5f..1fcc35a 100644
--- a/common/usbx_device_classes/src/ux_device_class_rndis_bulkout_thread.c
+++ b/common/usbx_device_classes/src/ux_device_class_rndis_bulkout_thread.c
@@ -35,7 +35,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_rndis_bulkout_thread PORTABLE C */
-/* 6.1.11 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -84,6 +84,10 @@
/* 04-25-2022 Chaoqiong Xiao Modified comment(s), */
/* fixed standalone compile, */
/* resulting in version 6.1.11 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* used NX API to copy data, */
+/* used linked NX IP pool, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
VOID _ux_device_class_rndis_bulkout_thread(ULONG rndis_class)
@@ -95,8 +99,8 @@ UX_SLAVE_DEVICE *device;
UX_SLAVE_TRANSFER *transfer_request;
UINT status;
NX_PACKET *packet;
-ULONG ip_given_length;
ULONG packet_payload;
+USB_NETWORK_DEVICE_TYPE *ux_nx_device;
/* Cast properly the rndis instance. */
UX_THREAD_EXTENSION_PTR_GET(class_ptr, UX_SLAVE_CLASS, rndis_class)
@@ -117,16 +121,39 @@ ULONG packet_payload;
/* As long as the device is in the CONFIGURED state. */
while (device -> ux_slave_device_state == UX_DEVICE_CONFIGURED)
{
-
+
+ /* Check if packet pool is ready. */
+ if (rndis -> ux_slave_class_rndis_packet_pool == UX_NULL)
+ {
+
+ /* Get the network device handle. */
+ ux_nx_device = (USB_NETWORK_DEVICE_TYPE *)(rndis -> ux_slave_class_rndis_network_handle);
+
+ /* Get packet pool from IP instance (if available). */
+ if (ux_nx_device -> ux_network_device_ip_instance != UX_NULL)
+ {
+ rndis -> ux_slave_class_rndis_packet_pool = ux_nx_device -> ux_network_device_ip_instance -> nx_ip_default_packet_pool;
+ }
+ else
+ {
+
+ /* Error trap. */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_CLASS_ETH_PACKET_POOL_ERROR);
+
+ _ux_utility_delay_ms(UX_DEVICE_CLASS_RNDIS_PACKET_POOL_INST_WAIT);
+ continue;
+ }
+ }
+
/* We can accept new reception. Get a NX Packet. */
- status = nx_packet_allocate(&rndis -> ux_slave_class_rndis_packet_pool, &packet,
+ status = nx_packet_allocate(rndis -> ux_slave_class_rndis_packet_pool, &packet,
NX_RECEIVE_PACKET, UX_MS_TO_TICK(UX_DEVICE_CLASS_RNDIS_PACKET_POOL_WAIT));
if (status == NX_SUCCESS)
{
/* And length. */
- transfer_request -> ux_slave_transfer_request_requested_length = UX_DEVICE_CLASS_RNDIS_MAX_PACKET_LENGTH;
+ transfer_request -> ux_slave_transfer_request_requested_length = UX_DEVICE_CLASS_RNDIS_MAX_MSG_LENGTH;
transfer_request -> ux_slave_transfer_request_actual_length = 0;
/* Memorize this packet at the beginning of the queue. */
@@ -136,8 +163,8 @@ ULONG packet_payload;
packet -> nx_packet_queue_next = UX_NULL;
/* Send the request to the device controller. */
- status = _ux_device_stack_transfer_request(transfer_request, UX_DEVICE_CLASS_RNDIS_MAX_PACKET_LENGTH + UX_DEVICE_CLASS_RNDIS_PACKET_HEADER_LENGTH,
- UX_DEVICE_CLASS_RNDIS_MAX_PACKET_LENGTH + UX_DEVICE_CLASS_RNDIS_PACKET_HEADER_LENGTH);
+ status = _ux_device_stack_transfer_request(transfer_request, UX_DEVICE_CLASS_RNDIS_MAX_MSG_LENGTH,
+ UX_DEVICE_CLASS_RNDIS_MAX_MSG_LENGTH);
/* Check the completion code. */
if (status == UX_SUCCESS)
@@ -147,63 +174,71 @@ ULONG packet_payload;
/* If trace is enabled, insert this event into the trace buffer. */
UX_TRACE_IN_LINE_INSERT(UX_TRACE_DEVICE_CLASS_RNDIS_PACKET_RECEIVE, rndis, 0, 0, 0, UX_TRACE_DEVICE_CLASS_EVENTS, 0, 0)
- /* Check the state of the transfer. If there is an error, we do not proceed with this report. Also ensure the header has a valid ID of 1. */
- if (_ux_utility_long_get(transfer_request -> ux_slave_transfer_request_data_pointer + UX_DEVICE_CLASS_RNDIS_PACKET_MESSAGE_TYPE) == UX_DEVICE_CLASS_RNDIS_PACKET_HEADER_MSG)
+ /* Check the state of the transfer. If there is an error, we do not proceed with this report.
+ Ensure this packet is at least larger than the header.
+ Also ensure the header has a valid ID of 1. */
+ if (transfer_request -> ux_slave_transfer_request_actual_length > UX_DEVICE_CLASS_RNDIS_PACKET_HEADER_LENGTH &&
+ _ux_utility_long_get(transfer_request -> ux_slave_transfer_request_data_pointer + UX_DEVICE_CLASS_RNDIS_PACKET_MESSAGE_TYPE) == UX_DEVICE_CLASS_RNDIS_PACKET_HEADER_MSG)
{
- /* Ensure this packet is at least larger than the header. */
- if (transfer_request -> ux_slave_transfer_request_actual_length > UX_DEVICE_CLASS_RNDIS_PACKET_HEADER_LENGTH)
- {
-
- /* Get the size of the payload. */
- packet_payload = _ux_utility_long_get(transfer_request -> ux_slave_transfer_request_data_pointer + UX_DEVICE_CLASS_RNDIS_PACKET_DATA_LENGTH);
-
- /* Ensure the length reported in the RNDIS header is not larger than it actually is.
- The reason we can't check to see if the length reported in the header and the
- actual length are exactly equal is because there might other data after the payload
- (padding, or even a message). */
- if (packet_payload <= transfer_request -> ux_slave_transfer_request_actual_length - UX_DEVICE_CLASS_RNDIS_PACKET_HEADER_LENGTH)
- {
+ /* Get the size of the payload. */
+ packet_payload = _ux_utility_long_get(transfer_request -> ux_slave_transfer_request_data_pointer + UX_DEVICE_CLASS_RNDIS_PACKET_DATA_LENGTH);
- /* Adjust the prepend pointer to take into account the non 3 bit alignment of the ethernet header. */
- packet -> nx_packet_prepend_ptr += sizeof(USHORT);
-
- /* Adjust the prepend, length, and append fields. */
- packet -> nx_packet_length = packet_payload;
- packet -> nx_packet_append_ptr = packet -> nx_packet_prepend_ptr + packet_payload;
-
+ /* Ensure the length reported in the RNDIS header is not larger than it actually is.
+ The reason we can't check to see if the length reported in the header and the
+ actual length are exactly equal is because there might other data after the payload
+ (padding, or even a message). */
+ if (packet_payload <= transfer_request -> ux_slave_transfer_request_actual_length - UX_DEVICE_CLASS_RNDIS_PACKET_HEADER_LENGTH)
+ {
- /* Copy the received packet in the IP packet data area. */
- _ux_utility_memory_copy(packet -> nx_packet_prepend_ptr, transfer_request -> ux_slave_transfer_request_data_pointer + UX_DEVICE_CLASS_RNDIS_PACKET_BUFFER, packet_payload); /* Use case of memcpy is verified. */
-
- /* Calculate the accurate packet length from ip header */
- if((*(packet -> nx_packet_prepend_ptr + 12) == 0x08) &&
- (*(packet -> nx_packet_prepend_ptr + 13) == 0))
- {
+ /* Adjust the prepend pointer to take into account the non 3 bit alignment of the ethernet header. */
+ packet -> nx_packet_prepend_ptr += sizeof(USHORT);
+ packet -> nx_packet_append_ptr += sizeof(USHORT);
- ip_given_length = _ux_utility_short_get_big_endian(packet -> nx_packet_prepend_ptr + 16) + UX_DEVICE_CLASS_RNDIS_ETHERNET_SIZE;
- packet -> nx_packet_length = ip_given_length ;
- packet -> nx_packet_append_ptr = packet -> nx_packet_prepend_ptr + ip_given_length;
- }
+ /* Copy the received packet in the IP packet data area. */
+ status = nx_packet_data_append(packet,
+ transfer_request -> ux_slave_transfer_request_data_pointer +
+ UX_DEVICE_CLASS_RNDIS_PACKET_BUFFER,
+ packet_payload,
+ rndis -> ux_slave_class_rndis_packet_pool,
+ UX_MS_TO_TICK(UX_DEVICE_CLASS_RNDIS_PACKET_POOL_WAIT));
+ if (status == UX_SUCCESS)
+ {
/* Send that packet to the NetX USB broker. */
_ux_network_driver_packet_received(rndis -> ux_slave_class_rndis_network_handle, packet);
}
else
+ {
- /* We received a malformed packet. Report to application. */
- _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_CLASS_MALFORMED_PACKET_RECEIVED_ERROR);
+ /* Error. */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_CLASS_ETH_PACKET_ERROR);
+ nx_packet_release(packet);
+ }
}
else
+ {
/* We received a malformed packet. Report to application. */
_ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_CLASS_MALFORMED_PACKET_RECEIVED_ERROR);
+ nx_packet_release(packet);
+ }
+ }
+ else
+ {
+
+ /* We received a malformed packet. Report to application. */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_CLASS_MALFORMED_PACKET_RECEIVED_ERROR);
+ nx_packet_release(packet);
}
}
else
+ {
/* Free the packet that was not successfully received. */
nx_packet_release(packet);
+ }
+
}
else
{
diff --git a/common/usbx_device_classes/src/ux_device_class_rndis_initialize.c b/common/usbx_device_classes/src/ux_device_class_rndis_initialize.c
index 8af7732..18604e8 100644
--- a/common/usbx_device_classes/src/ux_device_class_rndis_initialize.c
+++ b/common/usbx_device_classes/src/ux_device_class_rndis_initialize.c
@@ -78,7 +78,7 @@ ULONG ux_device_class_rndis_oid_supported_list[UX_DEVICE_CLASS_RNDIS_OID_SUPPORT
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_rndis_initialize PORTABLE C */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -136,6 +136,9 @@ ULONG ux_device_class_rndis_oid_supported_list[UX_DEVICE_CLASS_RNDIS_OID_SUPPORT
/* fixed parameter/variable */
/* names conflict C++ keyword, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* removed internal NX pool, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_device_class_rndis_initialize(UX_SLAVE_CLASS_COMMAND *command)
@@ -294,31 +297,6 @@ UINT status;
status = UX_EVENT_ERROR;
}
- /* Allocate some packet pool for reception. */
- if (status == UX_SUCCESS)
- {
-
- /* UX_DEVICE_CLASS_RNDIS_NX_ETHERNET_POOL_ALLOCSIZE overflow has been checked by
- * UX_DEVICE_CLASS_RNDIS_NX_ETHERNET_POOL_ALLOCSIZE_ASSERT outside of function.
- */
- rndis -> ux_slave_class_rndis_pool_memory = _ux_utility_memory_allocate(UX_NO_ALIGN, UX_CACHE_SAFE_MEMORY, UX_DEVICE_CLASS_RNDIS_NX_ETHERNET_POOL_ALLOCSIZE);
-
- /* Check the completion status. */
- if (rndis -> ux_slave_class_rndis_pool_memory == UX_NULL)
- status = UX_MEMORY_INSUFFICIENT;
- }
-
- /* Create a packet pool. */
- if (status == UX_SUCCESS)
- {
- status = nx_packet_pool_create(&rndis -> ux_slave_class_rndis_packet_pool, "Rndis Device Packet Pool",
- UX_DEVICE_CLASS_RNDIS_NX_PAYLOAD_SIZE, rndis -> ux_slave_class_rndis_pool_memory, UX_DEVICE_CLASS_RNDIS_NX_ETHERNET_POOL_ALLOCSIZE);
-
- /* Check for pool creation error. */
- if (status != UX_SUCCESS)
- status = UX_MEMORY_INSUFFICIENT;
- }
-
/* Create a semaphore for protecting the driver entry. */
if (status == UX_SUCCESS)
{
@@ -338,14 +316,6 @@ UINT status;
if (rndis -> ux_slave_class_rndis_semaphore.tx_semaphore_id != 0)
_ux_device_semaphore_delete(&rndis -> ux_slave_class_rndis_semaphore);
- /* Delete the packet pool. */
- if (rndis -> ux_slave_class_rndis_packet_pool.nx_packet_pool_id != 0)
- nx_packet_pool_delete(&rndis -> ux_slave_class_rndis_packet_pool);
-
- /* Free rndis -> ux_slave_class_rndis_pool_memory. */
- if (rndis -> ux_slave_class_rndis_pool_memory)
- _ux_utility_memory_free(rndis -> ux_slave_class_rndis_pool_memory);
-
/* Delete rndis -> ux_slave_class_rndis_event_flags_group. */
if (rndis -> ux_slave_class_rndis_event_flags_group.tx_event_flags_group_id != 0)
_ux_utility_event_flags_delete(&rndis -> ux_slave_class_rndis_event_flags_group);
diff --git a/common/usbx_device_classes/src/ux_device_class_storage_tasks_run.c b/common/usbx_device_classes/src/ux_device_class_storage_tasks_run.c
index 2acafd4..a3652f6 100644
--- a/common/usbx_device_classes/src/ux_device_class_storage_tasks_run.c
+++ b/common/usbx_device_classes/src/ux_device_class_storage_tasks_run.c
@@ -65,7 +65,7 @@ static inline VOID _ux_device_class_storage_disk_error(UX_SLAVE_CLASS_STORAGE *s
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_storage_tasks_run PORTABLE C */
-/* 6.1.10 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -125,6 +125,9 @@ static inline VOID _ux_device_class_storage_disk_error(UX_SLAVE_CLASS_STORAGE *s
/* DATE NAME DESCRIPTION */
/* */
/* 01-31-2022 Chaoqiong Xiao Initial Version 6.1.10 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* improved internal logic, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_device_class_storage_tasks_run(VOID *instance)
@@ -148,13 +151,14 @@ static inline UINT _ux_device_class_storage_task_usb(UX_SLAVE_CLASS_STORAGE *sto
UX_SLAVE_DEVICE *device;
UCHAR state;
UINT status;
+INT immediate_state = UX_TRUE;
/* Get pointer to the device. */
device = &_ux_system_slave -> ux_system_slave_device;
/* Run states once. */
- while(1)
+ while(immediate_state)
{
/* General check for MSC ready. */
@@ -301,9 +305,12 @@ UINT status;
break;
}
- /* Unhandled, just do again by app call. */
- return(UX_STATE_EXIT);
+ /* Unhandled, just break the loop and do again by app call. */
+ immediate_state = UX_FALSE;
}
+
+ /* Unhandled state. */
+ return(UX_STATE_EXIT);
}
static inline VOID _ux_device_class_storage_cbw_receive(UX_SLAVE_CLASS_STORAGE *storage)
@@ -979,9 +986,10 @@ static inline VOID _ux_device_class_storage_task_disk(UX_SLAVE_CLASS_STORAGE *st
{
UCHAR state = storage -> ux_device_class_storage_disk_state;
UINT status;
+INT immediate_state = UX_TRUE;
/* Run states once. */
- while(1)
+ while(immediate_state)
{
/* Update state. */
@@ -1035,8 +1043,8 @@ UINT status;
break;
}
- /* Task run once. */
- return;
+ /* Task run once, break the loop. */
+ immediate_state = UX_FALSE;
}
}
static inline VOID _ux_device_class_storage_disk_start(UX_SLAVE_CLASS_STORAGE *storage)
@@ -1058,6 +1066,8 @@ ULONG max_n_blocks;
/* Max blocks for one buffer. */
block_size = storage -> ux_slave_class_storage_lun[storage -> ux_slave_class_storage_cbw_lun].
ux_slave_class_storage_media_block_length;
+ if (block_size == 0)
+ UX_ASSERT(UX_FALSE);
max_n_blocks = UX_SLAVE_CLASS_STORAGE_BUFFER_SIZE / block_size;
/* Prepare next disk read. */
diff --git a/common/usbx_device_classes/src/ux_device_class_video_activate.c b/common/usbx_device_classes/src/ux_device_class_video_activate.c
index 80e71f6..7d78048 100644
--- a/common/usbx_device_classes/src/ux_device_class_video_activate.c
+++ b/common/usbx_device_classes/src/ux_device_class_video_activate.c
@@ -33,7 +33,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_video_activate PORTABLE C */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -67,6 +67,9 @@
/* fixed parameter/variable */
/* names conflict C++ keyword, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* added standalone support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_device_class_video_activate(UX_SLAVE_CLASS_COMMAND *command)
@@ -154,6 +157,14 @@ ULONG stream_index;
/* Store the class instance into the interface. */
stream_interface -> ux_slave_interface_class_instance = (VOID *)video;
+
+#if defined(UX_DEVICE_STANDALONE)
+
+ /* Reset stream task state. */
+ stream -> ux_device_class_video_stream_task_state = UX_STATE_RESET;
+ stream -> ux_device_class_video_stream_task_status = UX_SUCCESS;
+#endif
+
}
/* If there is a activate function call it. */
diff --git a/common/usbx_device_classes/src/ux_device_class_video_change.c b/common/usbx_device_classes/src/ux_device_class_video_change.c
index 199fcc6..9bf5e01 100644
--- a/common/usbx_device_classes/src/ux_device_class_video_change.c
+++ b/common/usbx_device_classes/src/ux_device_class_video_change.c
@@ -33,7 +33,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_video_change PORTABLE C */
-/* 6.1.12 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -67,6 +67,9 @@
/* fixed parameter/variable */
/* names conflict C++ keyword, */
/* resulting in version 6.1.12 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* added standalone support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_device_class_video_change(UX_SLAVE_CLASS_COMMAND *command)
@@ -160,6 +163,15 @@ ULONG stream_index;
return(UX_DESCRIPTOR_CORRUPTED);
}
+#if defined(UX_DEVICE_STANDALONE)
+
+ /* Reset background transfer state. */
+ stream -> ux_device_class_video_stream_task_state = UX_STATE_RESET;
+#endif
+
+ /* Now reset payload buffer error count. */
+ stream -> ux_device_class_video_stream_buffer_error_count = 0;
+
/* Now reset payload buffers. */
payload_buffer = stream -> ux_device_class_video_stream_buffer;
while(payload_buffer < stream -> ux_device_class_video_stream_buffer + stream -> ux_device_class_video_stream_buffer_size)
diff --git a/common/usbx_device_classes/src/ux_device_class_video_initialize.c b/common/usbx_device_classes/src/ux_device_class_video_initialize.c
index 8ffb9fe..625bc4f 100644
--- a/common/usbx_device_classes/src/ux_device_class_video_initialize.c
+++ b/common/usbx_device_classes/src/ux_device_class_video_initialize.c
@@ -33,7 +33,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_video_initialize PORTABLE C */
-/* 6.1.11 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -67,14 +67,13 @@
/* DATE NAME DESCRIPTION */
/* */
/* 04-25-2022 Chaoqiong Xiao Initial Version 6.1.11 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* added standalone support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_device_class_video_initialize(UX_SLAVE_CLASS_COMMAND *command)
{
-#if defined(UX_DEVICE_STANDALONE)
- UX_PARAMETER_NOT_USED(command);
- return(UX_FUNCTION_NOT_SUPPORTED);
-#else
UINT status = UX_SUCCESS;
UX_DEVICE_CLASS_VIDEO *video;
@@ -163,6 +162,9 @@ ULONG i;
stream -> ux_device_class_video_stream_transfer_pos = (UX_DEVICE_CLASS_VIDEO_PAYLOAD *)stream -> ux_device_class_video_stream_buffer;
stream -> ux_device_class_video_stream_access_pos = stream -> ux_device_class_video_stream_transfer_pos;
+
+#if !defined(UX_DEVICE_STANDALONE)
+
/* Create memory block for streaming thread stack in addition. */
if (stream_parameter -> ux_device_class_video_stream_parameter_thread_stack_size == 0)
memory_size = UX_DEVICE_CLASS_VIDEO_THREAD_STACK_SIZE;
@@ -189,6 +191,11 @@ ULONG i;
break;
UX_THREAD_EXTENSION_PTR_SET(&(stream -> ux_device_class_video_stream_thread), stream)
+#else
+
+ /* Save task function for streaming. */
+ stream -> ux_device_class_video_stream_task_function = stream_parameter -> ux_device_class_video_stream_parameter_task_function;
+#endif
/* Save callbacks. */
_ux_utility_memory_copy(&stream -> ux_device_class_video_stream_callbacks,
@@ -217,6 +224,12 @@ ULONG i;
&video_parameter -> ux_device_class_video_parameter_callbacks,
sizeof(UX_DEVICE_CLASS_VIDEO_CALLBACKS)); /* Use case of memcpy is verified. */
+#if defined(UX_DEVICE_STANDALONE)
+
+ /* Link task function. */
+ class_inst -> ux_slave_class_task_function = _ux_device_class_video_tasks_run;
+#endif
+
/* Return completion status. */
return(UX_SUCCESS);
}
@@ -228,10 +241,14 @@ ULONG i;
stream = video -> ux_device_class_video_streams;
for (i = 0; i < video -> ux_device_class_video_streams_nb; i ++)
{
+
+#if !defined(UX_DEVICE_STANDALONE)
if (stream -> ux_device_class_video_stream_thread.tx_thread_id)
_ux_utility_thread_delete(&stream -> ux_device_class_video_stream_thread);
if (stream -> ux_device_class_video_stream_thread_stack)
_ux_utility_memory_free(stream -> ux_device_class_video_stream_thread_stack);
+#endif
+
if (stream -> ux_device_class_video_stream_buffer)
_ux_utility_memory_free(stream -> ux_device_class_video_stream_buffer);
stream ++;
@@ -239,5 +256,4 @@ ULONG i;
_ux_utility_memory_free(video);
return(status);
-#endif
}
diff --git a/common/usbx_device_classes/src/ux_device_class_video_read_task_function.c b/common/usbx_device_classes/src/ux_device_class_video_read_task_function.c
new file mode 100644
index 0000000..a7422cc
--- /dev/null
+++ b/common/usbx_device_classes/src/ux_device_class_video_read_task_function.c
@@ -0,0 +1,188 @@
+/**************************************************************************/
+/* */
+/* 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 Video Class */
+/** */
+/**************************************************************************/
+/**************************************************************************/
+
+#define UX_SOURCE_CODE
+
+
+/* Include necessary system files. */
+
+#include "ux_api.h"
+#include "ux_device_class_video.h"
+#include "ux_device_stack.h"
+
+
+#if defined(UX_DEVICE_STANDALONE)
+/**************************************************************************/
+/* */
+/* FUNCTION RELEASE */
+/* */
+/* _ux_device_class_video_read_task_function PORTABLE C */
+/* 6.2.0 */
+/* AUTHOR */
+/* */
+/* Chaoqiong Xiao, Microsoft Corporation */
+/* */
+/* DESCRIPTION */
+/* */
+/* This function is the background task of the video stream read. */
+/* */
+/* It's for standalone mode. */
+/* */
+/* INPUT */
+/* */
+/* stream Pointer to video stream */
+/* */
+/* OUTPUT */
+/* */
+/* State machine status */
+/* UX_STATE_EXIT Device not configured */
+/* UX_STATE_IDLE No streaming transfer running */
+/* UX_STATE_WAIT Streaming transfer running */
+/* */
+/* CALLS */
+/* */
+/* _ux_device_stack_transfer_run Run transfer state machine */
+/* _ux_utility_memory_copy Copy memory */
+/* */
+/* CALLED BY */
+/* */
+/* USBX Device Stack */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 10-31-2022 Chaoqiong Xiao Initial Version 6.2.0 */
+/* */
+/**************************************************************************/
+UINT _ux_device_class_video_read_task_function(UX_DEVICE_CLASS_VIDEO_STREAM *stream)
+{
+UX_SLAVE_DEVICE *device;
+UX_SLAVE_ENDPOINT *endpoint;
+UX_SLAVE_TRANSFER *transfer;
+UCHAR *next_pos;
+UX_DEVICE_CLASS_VIDEO_PAYLOAD *next_payload;
+ULONG max_packet_size;
+ULONG actual_length;
+UINT status;
+
+
+ /* Get the pointer to the device. */
+ device = stream -> ux_device_class_video_stream_video -> ux_device_class_video_device;
+
+ /* Check if the device is configured. */
+ if (device -> ux_slave_device_state != UX_DEVICE_CONFIGURED)
+ {
+ stream -> ux_device_class_video_stream_task_state = UX_STATE_EXIT;
+ return(UX_STATE_EXIT);
+ }
+
+ /* Get the endpoint. */
+ endpoint = stream -> ux_device_class_video_stream_endpoint;
+
+ /* No endpoint ready, maybe it's alternate setting 0. */
+ if (endpoint == UX_NULL)
+ return(UX_STATE_IDLE);
+
+ /* Check if background transfer task is started. */
+ if (stream -> ux_device_class_video_stream_task_state == UX_DEVICE_CLASS_VIDEO_STREAM_RW_STOP)
+ return(UX_STATE_IDLE);
+
+ /* Get transfer instance. */
+ transfer = &endpoint -> ux_slave_endpoint_transfer_request;
+
+ /* If not started yet, reset transfer and start polling. */
+ if (stream -> ux_device_class_video_stream_task_state == UX_DEVICE_CLASS_VIDEO_STREAM_RW_START)
+ {
+
+ /* Next state: transfer wait. */
+ stream -> ux_device_class_video_stream_task_state = UX_DEVICE_CLASS_VIDEO_STREAM_RW_WAIT;
+
+ /* Reset transfer state. */
+ UX_SLAVE_TRANSFER_STATE_RESET(transfer);
+ }
+
+ /* Run transfer state machine. */
+ max_packet_size = endpoint -> ux_slave_endpoint_transfer_request.
+ ux_slave_transfer_request_transfer_length;
+ status = _ux_device_stack_transfer_run(transfer, max_packet_size, max_packet_size);
+
+ /* Error case. */
+ if (status < UX_STATE_NEXT)
+ {
+
+ /* Error on background transfer task start. */
+ stream -> ux_device_class_video_stream_task_state = UX_STATE_RESET;
+ stream -> ux_device_class_video_stream_task_status =
+ transfer -> ux_slave_transfer_request_completion_code;
+
+ /* Error notification! */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_TRANSFER_ERROR);
+ return(UX_STATE_EXIT);
+ }
+
+ /* Success case. */
+ if (status == UX_STATE_NEXT)
+ {
+
+ /* Next state: start. */
+ stream -> ux_device_class_video_stream_task_state = UX_DEVICE_CLASS_VIDEO_STREAM_RW_START;
+ stream -> ux_device_class_video_stream_task_status =
+ transfer -> ux_slave_transfer_request_completion_code;
+
+ /* Get actual transfer length. */
+ actual_length = transfer -> ux_slave_transfer_request_actual_length;
+
+ /* Frame received, log it. */
+ stream -> ux_device_class_video_stream_transfer_pos -> ux_device_class_video_payload_length = actual_length;
+ _ux_utility_memory_copy(stream -> ux_device_class_video_stream_transfer_pos -> ux_device_class_video_payload_data,
+ transfer -> ux_slave_transfer_request_data_pointer,
+ actual_length); /* Use case of memcpy is verified. */
+
+ /* For simple, do not advance the transfer position if there is overflow. */
+ next_pos = (UCHAR *)stream -> ux_device_class_video_stream_transfer_pos;
+ next_pos += stream -> ux_device_class_video_stream_payload_buffer_size;
+ if (next_pos >= stream -> ux_device_class_video_stream_buffer + stream -> ux_device_class_video_stream_buffer_size)
+ next_pos = stream -> ux_device_class_video_stream_buffer;
+ next_payload = (UX_DEVICE_CLASS_VIDEO_PAYLOAD *)next_pos;
+
+ /* Check overflow! */
+ if (next_payload -> ux_device_class_video_payload_length > 0)
+ {
+
+ /* Error notification! */
+ stream -> ux_device_class_video_stream_buffer_error_count ++;
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_BUFFER_OVERFLOW);
+ }
+ else
+
+ /* Update transfer position. */
+ stream -> ux_device_class_video_stream_transfer_pos = next_payload;
+
+ /* Invoke notification callback. */
+ if (stream -> ux_device_class_video_stream_callbacks.ux_device_class_video_stream_payload_done != UX_NULL)
+ stream -> ux_device_class_video_stream_callbacks.ux_device_class_video_stream_payload_done(stream, actual_length);
+ }
+
+ /* Keep waiting. */
+ return(UX_STATE_WAIT);
+}
+#endif
diff --git a/common/usbx_device_classes/src/ux_device_class_video_read_thread_entry.c b/common/usbx_device_classes/src/ux_device_class_video_read_thread_entry.c
index e9cd669..060723d 100644
--- a/common/usbx_device_classes/src/ux_device_class_video_read_thread_entry.c
+++ b/common/usbx_device_classes/src/ux_device_class_video_read_thread_entry.c
@@ -35,7 +35,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_video_read_thread_entry PORTABLE C */
-/* 6.1.11 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -69,6 +69,9 @@
/* DATE NAME DESCRIPTION */
/* */
/* 04-25-2022 Chaoqiong Xiao Initial Version 6.1.11 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* added error statistics, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
VOID _ux_device_class_video_read_thread_entry(ULONG video_stream)
@@ -145,6 +148,7 @@ ULONG actual_length;
{
/* Error notification! */
+ stream -> ux_device_class_video_stream_buffer_error_count ++;
_ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_BUFFER_OVERFLOW);
}
else
diff --git a/common/usbx_device_classes/src/ux_device_class_video_reception_start.c b/common/usbx_device_classes/src/ux_device_class_video_reception_start.c
index 84be153..342b00e 100644
--- a/common/usbx_device_classes/src/ux_device_class_video_reception_start.c
+++ b/common/usbx_device_classes/src/ux_device_class_video_reception_start.c
@@ -34,7 +34,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_video_reception_start PORTABLE C */
-/* 6.1.11 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -65,14 +65,13 @@
/* DATE NAME DESCRIPTION */
/* */
/* 04-25-2022 Chaoqiong Xiao Initial Version 6.1.11 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* added standalone support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_device_class_video_reception_start(UX_DEVICE_CLASS_VIDEO_STREAM *stream)
{
-#if defined(UX_DEVICE_STANDALONE)
- UX_PARAMETER_NOT_USED(stream);
- return(UX_FUNCTION_NOT_SUPPORTED);
-#else
UX_SLAVE_ENDPOINT *endpoint;
UX_SLAVE_DEVICE *device;
@@ -102,8 +101,16 @@ UX_SLAVE_DEVICE *device;
if (stream -> ux_device_class_video_stream_transfer_pos -> ux_device_class_video_payload_length > 0)
return(UX_BUFFER_OVERFLOW);
+#if defined(UX_DEVICE_STANDALONE)
+
+ /* Start read task. */
+ if (stream -> ux_device_class_video_stream_task_state == UX_DEVICE_CLASS_VIDEO_STREAM_RW_STOP)
+ stream -> ux_device_class_video_stream_task_state = UX_DEVICE_CLASS_VIDEO_STREAM_RW_START;
+
+#else
/* Start read thread. */
_ux_utility_thread_resume(&stream -> ux_device_class_video_stream_thread);
- return(UX_SUCCESS);
#endif
+
+ return(UX_SUCCESS);
}
diff --git a/common/usbx_device_classes/src/ux_device_class_video_tasks_run.c b/common/usbx_device_classes/src/ux_device_class_video_tasks_run.c
new file mode 100644
index 0000000..24ca2ed
--- /dev/null
+++ b/common/usbx_device_classes/src/ux_device_class_video_tasks_run.c
@@ -0,0 +1,113 @@
+/**************************************************************************/
+/* */
+/* 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 Video Class */
+/** */
+/**************************************************************************/
+/**************************************************************************/
+
+#define UX_SOURCE_CODE
+
+
+/* Include necessary system files. */
+
+#include "ux_api.h"
+#include "ux_device_class_video.h"
+#include "ux_device_stack.h"
+
+
+#if defined(UX_DEVICE_STANDALONE)
+/**************************************************************************/
+/* */
+/* FUNCTION RELEASE */
+/* */
+/* _ux_device_class_video_tasks_run PORTABLE C */
+/* 6.2.0 */
+/* AUTHOR */
+/* */
+/* Chaoqiong Xiao, Microsoft Corporation */
+/* */
+/* DESCRIPTION */
+/* */
+/* This function is the background task of the video. */
+/* */
+/* It's for standalone mode. */
+/* */
+/* INPUT */
+/* */
+/* instance Pointer to video class */
+/* */
+/* OUTPUT */
+/* */
+/* State machine status */
+/* UX_STATE_EXIT Device not configured */
+/* UX_STATE_IDLE No streaming transfer running */
+/* UX_STATE_WAIT Streaming transfer running */
+/* */
+/* CALLS */
+/* */
+/* (ux_device_class_video_stream_task_function) */
+/* Run stream task */
+/* */
+/* CALLED BY */
+/* */
+/* USBX Device Stack */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 10-31-2022 Chaoqiong Xiao Initial Version 6.2.0 */
+/* */
+/**************************************************************************/
+UINT _ux_device_class_video_tasks_run(VOID *instance)
+{
+UX_SLAVE_DEVICE *device;
+UX_DEVICE_CLASS_VIDEO *video;
+UX_DEVICE_CLASS_VIDEO_STREAM *stream;
+ULONG stream_index;
+UINT status;
+ULONG running_count;
+
+
+ /* Get Video instance. */
+ video = (UX_DEVICE_CLASS_VIDEO *) instance;
+
+ /* Get the pointer to the device. */
+ device = &_ux_system_slave -> ux_system_slave_device;
+
+ /* Check if the device is configured. */
+ if (device -> ux_slave_device_state != UX_DEVICE_CONFIGURED)
+ return(UX_STATE_EXIT);
+
+ /* Run video streaming tasks. */
+ running_count = 0;
+ for (stream_index = 0;
+ stream_index < video -> ux_device_class_video_streams_nb;
+ stream_index ++)
+ {
+ stream = &video -> ux_device_class_video_streams[stream_index];
+ status = stream -> ux_device_class_video_stream_task_function(stream);
+ if (status == UX_STATE_EXIT)
+ return(status);
+ if (status == UX_STATE_WAIT)
+ running_count ++;
+ }
+
+ /* Return state running. */
+ return (running_count > 0) ? (UX_STATE_WAIT) : (UX_STATE_IDLE);
+}
+#endif
diff --git a/common/usbx_device_classes/src/ux_device_class_video_transmission_start.c b/common/usbx_device_classes/src/ux_device_class_video_transmission_start.c
index 63a6c30..c01f117 100644
--- a/common/usbx_device_classes/src/ux_device_class_video_transmission_start.c
+++ b/common/usbx_device_classes/src/ux_device_class_video_transmission_start.c
@@ -34,7 +34,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_video_transmission_start PORTABLE C */
-/* 6.1.11 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -65,14 +65,13 @@
/* DATE NAME DESCRIPTION */
/* */
/* 04-25-2022 Chaoqiong Xiao Initial Version 6.1.11 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* added standalone support, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
UINT _ux_device_class_video_transmission_start(UX_DEVICE_CLASS_VIDEO_STREAM *stream)
{
-#if defined(UX_DEVICE_STANDALONE)
- UX_PARAMETER_NOT_USED(stream);
- return(UX_FUNCTION_NOT_SUPPORTED);
-#else
UX_SLAVE_ENDPOINT *endpoint;
UX_SLAVE_DEVICE *device;
@@ -102,8 +101,17 @@ UX_SLAVE_DEVICE *device;
if (stream -> ux_device_class_video_stream_transfer_pos -> ux_device_class_video_payload_length == 0)
return(UX_BUFFER_OVERFLOW);
+#if defined(UX_DEVICE_STANDALONE)
+
+ /* Start write task. */
+ if (stream -> ux_device_class_video_stream_task_state == UX_DEVICE_CLASS_VIDEO_STREAM_RW_STOP)
+ stream -> ux_device_class_video_stream_task_state = UX_DEVICE_CLASS_VIDEO_STREAM_RW_START;
+
+#else
+
/* Start write thread. */
- _ux_utility_thread_resume(&stream -> ux_device_class_video_stream_thread);
- return(UX_SUCCESS);
+ _ux_device_thread_resume(&stream -> ux_device_class_video_stream_thread);
#endif
+
+ return(UX_SUCCESS);
}
diff --git a/common/usbx_device_classes/src/ux_device_class_video_write_task_function.c b/common/usbx_device_classes/src/ux_device_class_video_write_task_function.c
new file mode 100644
index 0000000..55dba42
--- /dev/null
+++ b/common/usbx_device_classes/src/ux_device_class_video_write_task_function.c
@@ -0,0 +1,209 @@
+/**************************************************************************/
+/* */
+/* 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 Video Class */
+/** */
+/**************************************************************************/
+/**************************************************************************/
+
+#define UX_SOURCE_CODE
+
+
+/* Include necessary system files. */
+
+#include "ux_api.h"
+#include "ux_device_class_video.h"
+#include "ux_device_stack.h"
+
+
+#if defined(UX_DEVICE_STANDALONE)
+/**************************************************************************/
+/* */
+/* FUNCTION RELEASE */
+/* */
+/* _ux_device_class_video_write_task_function PORTABLE C */
+/* 6.2.0 */
+/* AUTHOR */
+/* */
+/* Chaoqiong Xiao, Microsoft Corporation */
+/* */
+/* DESCRIPTION */
+/* */
+/* This function is the background task of the video stream write. */
+/* */
+/* It's for standalone mode. */
+/* */
+/* INPUT */
+/* */
+/* video_class Address of video class */
+/* container */
+/* */
+/* OUTPUT */
+/* */
+/* State machine status */
+/* UX_STATE_EXIT Device not configured */
+/* UX_STATE_IDLE No streaming transfer running */
+/* UX_STATE_WAIT Streaming transfer running */
+/* */
+/* CALLS */
+/* */
+/* _ux_device_stack_transfer_run Run transfer state machine */
+/* _ux_utility_memory_copy Copy memory */
+/* */
+/* CALLED BY */
+/* */
+/* USBX Device Stack */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 10-31-2022 Chaoqiong Xiao Initial Version 6.2.0 */
+/* */
+/**************************************************************************/
+UINT _ux_device_class_video_write_task_function(UX_DEVICE_CLASS_VIDEO_STREAM *stream)
+{
+UX_SLAVE_DEVICE *device;
+UX_SLAVE_ENDPOINT *endpoint;
+UX_SLAVE_TRANSFER *transfer;
+UCHAR *next_pos;
+UX_DEVICE_CLASS_VIDEO_PAYLOAD *next_payload;
+ULONG transfer_length;
+ULONG actual_length;
+UINT status;
+
+
+ /* Get the pointer to the device. */
+ device = stream -> ux_device_class_video_stream_video -> ux_device_class_video_device;
+
+ /* Check if the device is configured. */
+ if (device -> ux_slave_device_state != UX_DEVICE_CONFIGURED)
+ {
+ stream -> ux_device_class_video_stream_task_state = UX_STATE_EXIT;
+ return(UX_STATE_EXIT);
+ }
+
+ /* Get the endpoint. */
+ endpoint = stream -> ux_device_class_video_stream_endpoint;
+
+ /* No endpoint ready, maybe it's alternate setting 0. */
+ if (endpoint == UX_NULL)
+ return(UX_STATE_IDLE);
+
+ /* Check if background transfer task is started. */
+ if (stream -> ux_device_class_video_stream_task_state == UX_DEVICE_CLASS_VIDEO_STREAM_RW_STOP)
+ return(UX_STATE_IDLE);
+
+ /* Get transfer instance. */
+ transfer = &endpoint -> ux_slave_endpoint_transfer_request;
+
+ /* If not started yet, prepare data, reset transfer and start polling. */
+ if (stream -> ux_device_class_video_stream_task_state == UX_DEVICE_CLASS_VIDEO_STREAM_RW_START)
+ {
+
+ /* Next state: transfer wait. */
+ stream -> ux_device_class_video_stream_task_state = UX_DEVICE_CLASS_VIDEO_STREAM_RW_WAIT;
+
+ /* Start payload transfer anyway (even ZLP). */
+ transfer_length = stream -> ux_device_class_video_stream_transfer_pos -> ux_device_class_video_payload_length;
+ if (transfer_length)
+ _ux_utility_memory_copy(transfer -> ux_slave_transfer_request_data_pointer,
+ stream -> ux_device_class_video_stream_transfer_pos -> ux_device_class_video_payload_data, transfer_length); /* Use case of memcpy is verified. */
+
+ /* Reset transfer state. */
+ UX_SLAVE_TRANSFER_STATE_RESET(transfer);
+ }
+
+ /* Get current transfer length. */
+ transfer_length = stream -> ux_device_class_video_stream_transfer_pos -> ux_device_class_video_payload_length;
+
+ /* Run transfer states. */
+ status = _ux_device_stack_transfer_run(transfer, transfer_length, transfer_length);
+
+ /* Error case. */
+ if (status < UX_STATE_NEXT)
+ {
+
+ /* Error on background transfer task start. */
+ stream -> ux_device_class_video_stream_task_state = UX_STATE_RESET;
+ stream -> ux_device_class_video_stream_task_status =
+ transfer -> ux_slave_transfer_request_completion_code;
+
+ /* Error notification! */
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_TRANSFER_ERROR);
+ return(UX_STATE_EXIT);
+ }
+
+ /* Success case. */
+ if (status == UX_STATE_NEXT)
+ {
+
+ /* Next state: start. */
+ stream -> ux_device_class_video_stream_task_state = UX_DEVICE_CLASS_VIDEO_STREAM_RW_START;
+ stream -> ux_device_class_video_stream_task_status =
+ transfer -> ux_slave_transfer_request_completion_code;
+
+ /* Frame sent, free it. */
+ stream -> ux_device_class_video_stream_transfer_pos -> ux_device_class_video_payload_length = 0;
+
+ /* Get actual transfer length. */
+ actual_length = transfer -> ux_slave_transfer_request_actual_length;
+
+ /* Calculate next position. */
+ next_pos = (UCHAR *)stream -> ux_device_class_video_stream_transfer_pos;
+ next_pos += stream -> ux_device_class_video_stream_payload_buffer_size;
+ if (next_pos >= stream -> ux_device_class_video_stream_buffer + stream -> ux_device_class_video_stream_buffer_size)
+ next_pos = stream -> ux_device_class_video_stream_buffer;
+ next_payload = (UX_DEVICE_CLASS_VIDEO_PAYLOAD *)next_pos;
+
+ /* Underflow check! */
+ if (transfer_length)
+ {
+
+ /* Advance position. */
+ stream -> ux_device_class_video_stream_transfer_pos = next_payload;
+
+ /* Error trap! */
+ if (next_payload -> ux_device_class_video_payload_length == 0)
+ {
+ stream -> ux_device_class_video_stream_buffer_error_count ++;
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_BUFFER_OVERFLOW);
+ }
+ }
+ else
+ {
+
+ /* Advance position if next payload available. */
+ if (next_payload -> ux_device_class_video_payload_length)
+ stream -> ux_device_class_video_stream_transfer_pos = next_payload;
+ else
+ {
+
+ /* Error trap! */
+ stream -> ux_device_class_video_stream_buffer_error_count ++;
+ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_BUFFER_OVERFLOW);
+ }
+ }
+
+ /* Invoke notification callback. */
+ if (stream -> ux_device_class_video_stream_callbacks.ux_device_class_video_stream_payload_done != UX_NULL)
+ stream -> ux_device_class_video_stream_callbacks.ux_device_class_video_stream_payload_done(stream, actual_length);
+ }
+
+ /* Keep waiting. */
+ return(UX_STATE_WAIT);
+}
+#endif
diff --git a/common/usbx_device_classes/src/ux_device_class_video_write_thread_entry.c b/common/usbx_device_classes/src/ux_device_class_video_write_thread_entry.c
index 43006d6..3dce636 100644
--- a/common/usbx_device_classes/src/ux_device_class_video_write_thread_entry.c
+++ b/common/usbx_device_classes/src/ux_device_class_video_write_thread_entry.c
@@ -35,7 +35,7 @@
/* FUNCTION RELEASE */
/* */
/* _ux_device_class_video_write_thread_entry PORTABLE C */
-/* 6.1.11 */
+/* 6.2.0 */
/* AUTHOR */
/* */
/* Chaoqiong Xiao, Microsoft Corporation */
@@ -69,6 +69,9 @@
/* DATE NAME DESCRIPTION */
/* */
/* 04-25-2022 Chaoqiong Xiao Initial Version 6.1.11 */
+/* 10-31-2022 Chaoqiong Xiao Modified comment(s), */
+/* added error statistics, */
+/* resulting in version 6.2.0 */
/* */
/**************************************************************************/
VOID _ux_device_class_video_write_thread_entry(ULONG video_stream)
@@ -147,7 +150,10 @@ ULONG actual_length;
/* Error trap! */
if (next_payload -> ux_device_class_video_payload_length == 0)
+ {
+ stream -> ux_device_class_video_stream_buffer_error_count ++;
_ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_BUFFER_OVERFLOW);
+ }
}
else
{
@@ -156,9 +162,12 @@ ULONG actual_length;
if (next_payload -> ux_device_class_video_payload_length)
stream -> ux_device_class_video_stream_transfer_pos = next_payload;
else
+ {
/* Error trap! */
+ stream -> ux_device_class_video_stream_buffer_error_count ++;
_ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_BUFFER_OVERFLOW);
+ }
}
/* Invoke notification callback. */