1 /***************************************************************************
2 * Copyright (c) 2024 Microsoft Corporation
3 *
4 * This program and the accompanying materials are made available under the
5 * terms of the MIT License which is available at
6 * https://opensource.org/licenses/MIT.
7 *
8 * SPDX-License-Identifier: MIT
9 **************************************************************************/
10
11
12 /**************************************************************************/
13 /**************************************************************************/
14 /** */
15 /** USBX Component */
16 /** */
17 /** ACM CDC Class */
18 /** */
19 /**************************************************************************/
20 /**************************************************************************/
21
22
23 /* Include necessary system files. */
24
25 #define UX_SOURCE_CODE
26
27 #include "ux_api.h"
28 #include "ux_host_class_cdc_acm.h"
29 #include "ux_host_stack.h"
30
31
32 /**************************************************************************/
33 /* */
34 /* FUNCTION RELEASE */
35 /* */
36 /* _ux_host_class_cdc_acm_reception_callback PORTABLE C */
37 /* 6.1 */
38 /* AUTHOR */
39 /* */
40 /* Chaoqiong Xiao, Microsoft Corporation */
41 /* */
42 /* DESCRIPTION */
43 /* */
44 /* This function is the callback from the USBX transfer functions, */
45 /* it is called when a full or partial transfer has been done for a */
46 /* bulk in transfer. It calls back the application. */
47 /* */
48 /* INPUT */
49 /* */
50 /* transfer_request Pointer to transfer request */
51 /* */
52 /* OUTPUT */
53 /* */
54 /* None */
55 /* */
56 /* CALLS */
57 /* */
58 /* _ux_host_stack_transfer_request Process transfer request */
59 /* */
60 /* CALLED BY */
61 /* */
62 /* Application */
63 /* */
64 /* RELEASE HISTORY */
65 /* */
66 /* DATE NAME DESCRIPTION */
67 /* */
68 /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
69 /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */
70 /* resulting in version 6.1 */
71 /* */
72 /**************************************************************************/
_ux_host_class_cdc_acm_reception_callback(UX_TRANSFER * transfer_request)73 VOID _ux_host_class_cdc_acm_reception_callback (UX_TRANSFER *transfer_request)
74 {
75
76 UX_HOST_CLASS_CDC_ACM *cdc_acm;
77 UX_HOST_CLASS_CDC_ACM_RECEPTION *cdc_acm_reception;
78
79 /* Get the class instance for this transfer request. */
80 cdc_acm = (UX_HOST_CLASS_CDC_ACM *) transfer_request -> ux_transfer_request_class_instance;
81
82 /* Get the pointer to the acm reception structure. */
83 cdc_acm_reception = cdc_acm -> ux_host_class_cdc_acm_reception;
84
85 /* Check the state of the transfer. If there is an error, we do not proceed with this report. */
86 if (transfer_request -> ux_transfer_request_completion_code != UX_SUCCESS)
87 {
88
89 /* The reception is stopped. */
90 cdc_acm_reception -> ux_host_class_cdc_acm_reception_state = UX_HOST_CLASS_CDC_ACM_RECEPTION_STATE_STOPPED;
91
92 /* We do not proceed. */
93 return;
94
95 }
96
97 /* Move to the next reception buffer. Check if we are at the end of the application buffer. */
98 if (cdc_acm_reception -> ux_host_class_cdc_acm_reception_data_head + cdc_acm_reception -> ux_host_class_cdc_acm_reception_block_size >=
99 cdc_acm_reception -> ux_host_class_cdc_acm_reception_data_buffer + cdc_acm_reception -> ux_host_class_cdc_acm_reception_data_buffer_size)
100
101 /* Program the head to be at the beginning of the application buffer. */
102 cdc_acm_reception -> ux_host_class_cdc_acm_reception_data_head = cdc_acm_reception -> ux_host_class_cdc_acm_reception_data_buffer;
103
104 else
105
106 /* Program the head to be after the current buffer. */
107 cdc_acm_reception -> ux_host_class_cdc_acm_reception_data_head += cdc_acm_reception -> ux_host_class_cdc_acm_reception_block_size;
108
109 /* OVERFLOW check: if the head reaches the tail buffer that contains reception data */
110 if (cdc_acm_reception -> ux_host_class_cdc_acm_reception_data_tail == cdc_acm_reception -> ux_host_class_cdc_acm_reception_data_head)
111 {
112
113 /* Error trap. */
114 _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_BUFFER_OVERFLOW);
115
116 /* If trace is enabled, insert this event into the trace buffer. */
117 UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_BUFFER_OVERFLOW, transfer_request, 0, 0, UX_TRACE_ERRORS, 0, 0)
118
119 /* We have an overflow. We cannot continue. Report to the application. */
120 cdc_acm_reception -> ux_host_class_cdc_acm_reception_callback(cdc_acm, UX_BUFFER_OVERFLOW, UX_NULL, 0);
121
122 /* And stop the transfer in progress flag. */
123 cdc_acm_reception -> ux_host_class_cdc_acm_reception_state = UX_HOST_CLASS_CDC_ACM_RECEPTION_STATE_STOPPED;
124
125 return;
126 }
127
128 /* We need to report this transfer to the application. */
129 cdc_acm_reception -> ux_host_class_cdc_acm_reception_callback(cdc_acm,
130 transfer_request -> ux_transfer_request_completion_code,
131 transfer_request -> ux_transfer_request_data_pointer,
132 transfer_request -> ux_transfer_request_actual_length);
133
134 /* Set data pointer to the next reception buffer. */
135 transfer_request -> ux_transfer_request_data_pointer = cdc_acm_reception -> ux_host_class_cdc_acm_reception_data_head;
136
137 /* Arm another transfer. */
138 _ux_host_stack_transfer_request(transfer_request);
139
140 /* There is no status to be reported back to the stack. */
141 return;
142 }
143
144