1 /**************************************************************************/
2 /*                                                                        */
3 /*       Copyright (c) Microsoft Corporation. All rights reserved.        */
4 /*                                                                        */
5 /*       This software is licensed under the Microsoft Software License   */
6 /*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
7 /*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
8 /*       and in the root directory of this software.                      */
9 /*                                                                        */
10 /**************************************************************************/
11 
12 /**************************************************************************/
13 /**************************************************************************/
14 /**                                                                       */
15 /** USBX Component                                                        */
16 /**                                                                       */
17 /**   DFU Class                                                           */
18 /**                                                                       */
19 /**************************************************************************/
20 /**************************************************************************/
21 
22 /**************************************************************************/
23 /*                                                                        */
24 /*  COMPONENT DEFINITION                                   RELEASE        */
25 /*                                                                        */
26 /*    ux_device_class_dfu.h                               PORTABLE C      */
27 /*                                                           6.1.12       */
28 /*  AUTHOR                                                                */
29 /*                                                                        */
30 /*    Chaoqiong Xiao, Microsoft Corporation                               */
31 /*                                                                        */
32 /*  DESCRIPTION                                                           */
33 /*                                                                        */
34 /*    This file defines the equivalences for the USBX Device Class DFU    */
35 /*    ACM component.                                                      */
36 /*                                                                        */
37 /*  RELEASE HISTORY                                                       */
38 /*                                                                        */
39 /*    DATE              NAME                      DESCRIPTION             */
40 /*                                                                        */
41 /*  05-19-2020     Chaoqiong Xiao           Initial Version 6.0           */
42 /*  09-30-2020     Chaoqiong Xiao           Modified comment(s),          */
43 /*                                            used UX prefix to refer to  */
44 /*                                            TX symbols instead of using */
45 /*                                            them directly,              */
46 /*                                            resulting in version 6.1    */
47 /*  04-02-2021     Chaoqiong Xiao           Modified comment(s),          */
48 /*                                            added DFU_UPLOAD support,   */
49 /*                                            refined dfu_read prototype, */
50 /*                                            removed block count (it's   */
51 /*                                            from host request wValue),  */
52 /*                                            resulting in version 6.1.6  */
53 /*  08-02-2021     Chaoqiong Xiao           Modified comment(s),          */
54 /*                                            added extern "C" keyword    */
55 /*                                            for compatibility with C++, */
56 /*                                            resulting in version 6.1.8  */
57 /*  01-31-2022     Chaoqiong Xiao           Modified comment(s),          */
58 /*                                            added standalone support,   */
59 /*                                            resulting in version 6.1.10 */
60 /*  07-29-2022     Chaoqiong Xiao           Modified comment(s),          */
61 /*                                            added macros for req types, */
62 /*                                            resulting in version 6.1.12 */
63 /*                                                                        */
64 /**************************************************************************/
65 
66 #ifndef UX_DEVICE_CLASS_DFU_H
67 #define UX_DEVICE_CLASS_DFU_H
68 
69 /* Determine if a C++ compiler is being used.  If so, ensure that standard
70    C is used to process the API information.  */
71 
72 #ifdef   __cplusplus
73 
74 /* Yes, C++ compiler is present.  Use standard C.  */
75 extern   "C" {
76 
77 #endif
78 
79 /* Define DFU class descriptor capabilities.  */
80 #define UX_SLAVE_CLASS_DFU_CAPABILITY_WILL_DETACH                   0x08
81 #define UX_SLAVE_CLASS_DFU_CAPABILITY_MANIFESTATION_TOLERANT        0x04
82 #define UX_SLAVE_CLASS_DFU_CAPABILITY_CAN_UPLOAD                    0x02
83 #define UX_SLAVE_CLASS_DFU_CAPABILITY_CAN_DOWNLOAD                  0x01
84 
85 /* Define DFU Class USB Class constants.  */
86 #define UX_SLAVE_CLASS_DFU_CLASS                                    0xFE
87 #define UX_SLAVE_CLASS_DFU_SUBCLASS                                 0x01
88 #define UX_SLAVE_CLASS_DFU_PROTOCOL_RUNTIME                         0x01
89 #define UX_SLAVE_CLASS_DFU_PROTOCOL_DFU_MODE                        0x02
90 
91 /* Define DFU MODES signals.  */
92 #define UX_DEVICE_CLASS_DFU_MODE_RUNTIME                            1
93 #define UX_DEVICE_CLASS_DFU_MODE_DFU                                2
94 
95 
96 /* Device DFU bmRequestType.  */
97 #define UX_DEVICE_CLASS_DFU_REQTYPE_INTERFACE_SET                   (UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE) /* 00100001b, 0x21   */
98 #define UX_DEVICE_CLASS_DFU_REQTYPE_INTERFACE_GET                   (UX_REQUEST_IN | UX_REQUEST_TYPE_CLASS | UX_REQUEST_TARGET_INTERFACE) /* 10100001b, 0xA1  */
99 
100 
101 /* Device DFU Requests */
102 #define UX_SLAVE_CLASS_DFU_COMMAND_DETACH                           0
103 #define UX_SLAVE_CLASS_DFU_COMMAND_DOWNLOAD                         1
104 #define UX_SLAVE_CLASS_DFU_COMMAND_UPLOAD                           2
105 #define UX_SLAVE_CLASS_DFU_COMMAND_GET_STATUS                       3
106 #define UX_SLAVE_CLASS_DFU_COMMAND_CLEAR_STATUS                     4
107 #define UX_SLAVE_CLASS_DFU_COMMAND_GET_STATE                        5
108 #define UX_SLAVE_CLASS_DFU_COMMAND_ABORT                            6
109 
110 /* Device DFU Status values */
111 #define UX_SLAVE_CLASS_DFU_STATUS_OK                                0x00
112 #define UX_SLAVE_CLASS_DFU_STATUS_ERROR_TARGET                      0x01
113 #define UX_SLAVE_CLASS_DFU_STATUS_ERROR_FILE                        0x02
114 #define UX_SLAVE_CLASS_DFU_STATUS_ERROR_WRITE                       0x03
115 #define UX_SLAVE_CLASS_DFU_STATUS_ERROR_ERASE                       0x04
116 #define UX_SLAVE_CLASS_DFU_STATUS_ERROR_CHECK_ERASED                0x05
117 #define UX_SLAVE_CLASS_DFU_STATUS_ERROR_PROG                        0x06
118 #define UX_SLAVE_CLASS_DFU_STATUS_ERROR_VERIFY                      0x07
119 #define UX_SLAVE_CLASS_DFU_STATUS_ERROR_ADDRESS                     0x08
120 #define UX_SLAVE_CLASS_DFU_STATUS_ERROR_NOTDONE                     0x09
121 #define UX_SLAVE_CLASS_DFU_STATUS_ERROR_FIRMWARE                    0x0A
122 #define UX_SLAVE_CLASS_DFU_STATUS_ERROR_VENDOR                      0x0B
123 #define UX_SLAVE_CLASS_DFU_STATUS_ERROR_USBR                        0x0C
124 #define UX_SLAVE_CLASS_DFU_STATUS_ERROR_POR                         0x0D
125 #define UX_SLAVE_CLASS_DFU_STATUS_ERROR_UNKNOWN                     0x0E
126 #define UX_SLAVE_CLASS_DFU_STATUS_ERROR_STALLEDPKT                  0x0F
127 
128 #define UX_SLAVE_CLASS_DFU_STATUS_STATE_APP_IDLE                    0
129 #define UX_SLAVE_CLASS_DFU_STATUS_STATE_APP_DETACH                  1
130 #define UX_SLAVE_CLASS_DFU_STATUS_STATE_DFU_IDLE                    2
131 #define UX_SLAVE_CLASS_DFU_STATUS_STATE_DFU_DNLOAD_SYNC             3
132 #define UX_SLAVE_CLASS_DFU_STATUS_STATE_DFU_DNBUSY                  4
133 #define UX_SLAVE_CLASS_DFU_STATUS_STATE_DFU_DNLOAD_IDLE             5
134 #define UX_SLAVE_CLASS_DFU_STATUS_STATE_DFU_MANIFEST_SYNC           6
135 #define UX_SLAVE_CLASS_DFU_STATUS_STATE_DFU_MANIFEST                7
136 #define UX_SLAVE_CLASS_DFU_STATUS_STATE_DFU_MANIFEST_WAIT_RESET     8
137 #define UX_SLAVE_CLASS_DFU_STATUS_STATE_DFU_UPLOAD_IDLE             9
138 #define UX_SLAVE_CLASS_DFU_STATUS_STATE_DFU_ERROR                   10
139 
140 /* Define DFU class GET_STATUS command response.  */
141 #define UX_SLAVE_CLASS_DFU_GET_STATUS_STATUS                        0
142 #define UX_SLAVE_CLASS_DFU_GET_STATUS_POLL_TIMEOUT                  1
143 #define UX_SLAVE_CLASS_DFU_GET_STATUS_STATE                         4
144 #define UX_SLAVE_CLASS_DFU_GET_STATUS_STRING                        5
145 #define UX_SLAVE_CLASS_DFU_GET_STATUS_LENGTH                        6
146 
147 /* Status mode for DFU_GETSTATUS
148    0 - simple mode,
149        status is queried from application in dfuDNLOAD-SYNC and dfuMANIFEST-SYNC state,
150        no bwPollTimeout.
151    1 - status is queried from application once requested,
152        b0-3 : media status
153        b4-7 : bStatus
154        b8-31: bwPollTimeout
155        bwPollTimeout supported.
156 */
157 #ifndef UX_DEVICE_CLASS_DFU_STATUS_MODE
158 #define UX_DEVICE_CLASS_DFU_STATUS_MODE                             (0)
159 #endif
160 
161 /* Status mode 0 bwPollTimeout (width: 3 bytes, ~0xFFFFFF).  */
162 #ifndef UX_DEVICE_CLASS_DFU_STATUS_POLLTIMEOUT
163 #define UX_DEVICE_CLASS_DFU_STATUS_POLLTIMEOUT                      (1)
164 #endif
165 
166 
167 /* Define DFU class GET_STATE command response.  */
168 #define UX_SLAVE_CLASS_DFU_GET_STATE_STATE                          0
169 #define UX_SLAVE_CLASS_DFU_GET_STATE_LENGTH                         1
170 
171 /* Define DFU application notification signals.  */
172 #define UX_SLAVE_CLASS_DFU_NOTIFICATION_BEGIN_DOWNLOAD              0x1u
173 #define UX_SLAVE_CLASS_DFU_NOTIFICATION_END_DOWNLOAD                0x2u
174 #define UX_SLAVE_CLASS_DFU_NOTIFICATION_ABORT_DOWNLOAD              0x3u
175 #define UX_SLAVE_CLASS_DFU_NOTIFICATION_BEGIN_UPLOAD                0x5u
176 #define UX_SLAVE_CLASS_DFU_NOTIFICATION_END_UPLOAD                  0x6u
177 #define UX_SLAVE_CLASS_DFU_NOTIFICATION_ABORT_UPLOAD                0x7u
178 
179 /* Define DFU application notification signals.  */
180 #define UX_SLAVE_CLASS_DFU_MEDIA_STATUS_OK                          0
181 #define UX_SLAVE_CLASS_DFU_MEDIA_STATUS_BUSY                        1
182 #define UX_SLAVE_CLASS_DFU_MEDIA_STATUS_ERROR                       2
183 
184 /* Define DFU thread event signals.  */
185 #define UX_DEVICE_CLASS_DFU_THREAD_EVENT_DISCONNECT                 0x1u
186 #define UX_DEVICE_CLASS_DFU_THREAD_EVENT_WAIT_RESET                 0x2u
187 
188 /* Define Slave DFU Class Calling Parameter structure */
189 
190 typedef struct UX_SLAVE_CLASS_DFU_PARAMETER_STRUCT
191 {
192 
193     ULONG                   ux_slave_class_dfu_parameter_will_detach;
194     ULONG                   ux_slave_class_dfu_parameter_capabilities;
195     VOID                    (*ux_slave_class_dfu_parameter_instance_activate)(VOID *);
196     VOID                    (*ux_slave_class_dfu_parameter_instance_deactivate)(VOID *);
197     UINT                    (*ux_slave_class_dfu_parameter_read)(VOID *dfu, ULONG block_number, UCHAR * data_pointer, ULONG length, ULONG *actual_length);
198     UINT                    (*ux_slave_class_dfu_parameter_write)(VOID *dfu, ULONG block_number, UCHAR * data_pointer, ULONG length, ULONG *media_status);
199     UINT                    (*ux_slave_class_dfu_parameter_get_status)(VOID *dfu, ULONG *media_status);
200     UINT                    (*ux_slave_class_dfu_parameter_notify)(VOID *dfu, ULONG notification);
201 #ifdef UX_DEVICE_CLASS_DFU_CUSTOM_REQUEST_ENABLE
202     UINT                    (*ux_device_class_dfu_parameter_custom_request)(VOID *dfu, UX_SLAVE_TRANSFER *transfer);
203 #endif
204     UCHAR                   *ux_slave_class_dfu_parameter_framework;
205     ULONG                   ux_slave_class_dfu_parameter_framework_length;
206 
207 } UX_SLAVE_CLASS_DFU_PARAMETER;
208 
209 /* Define DFU Class structure.  */
210 
211 typedef struct UX_SLAVE_CLASS_DFU_STRUCT
212 {
213     UX_SLAVE_INTERFACE      *ux_slave_class_dfu_interface;
214     ULONG                   ux_slave_class_dfu_status;
215     VOID                    (*ux_slave_class_dfu_instance_activate)(VOID *);
216     VOID                    (*ux_slave_class_dfu_instance_deactivate)(VOID *);
217     UINT                    (*ux_slave_class_dfu_read)(VOID *dfu, ULONG block_number, UCHAR * data_pointer, ULONG length, ULONG *actual_length);
218     UINT                    (*ux_slave_class_dfu_write)(VOID *dfu, ULONG block_number, UCHAR * data_pointer, ULONG length, ULONG *media_status);
219     UINT                    (*ux_slave_class_dfu_get_status)(VOID *dfu, ULONG *media_status);
220     UINT                    (*ux_slave_class_dfu_notify)(VOID *dfu, ULONG notification);
221 #ifdef UX_DEVICE_CLASS_DFU_CUSTOM_REQUEST_ENABLE
222     UINT                    (*ux_device_class_dfu_custom_request)(VOID *dfu, UX_SLAVE_TRANSFER *transfer);
223 #endif
224 
225 #if !defined(UX_DEVICE_STANDALONE)
226     UX_THREAD               ux_slave_class_dfu_thread;
227     UCHAR                   *ux_slave_class_dfu_thread_stack;
228     UX_EVENT_FLAGS_GROUP    ux_slave_class_dfu_event_flags_group;
229 #else
230     ULONG                   ux_device_class_dfu_flags;
231 #endif
232 } UX_SLAVE_CLASS_DFU;
233 
234 #if !defined(UX_DEVICE_STANDALONE)
235 #define _ux_device_class_dfu_event_flags_set(dfu, flags)    do {                                    \
236         _ux_utility_event_flags_set(&(dfu) -> ux_slave_class_dfu_event_flags_group, flags, UX_OR);  \
237     } while(0)
238 #else
239 #define _ux_device_class_dfu_event_flags_set(dfu, flags)    do {                \
240         (dfu) -> ux_device_class_dfu_flags |= flags;                            \
241     } while(0)
242 #endif
243 
244 /* Define Device DFU Class prototypes.  */
245 
246 UINT  _ux_device_class_dfu_activate(UX_SLAVE_CLASS_COMMAND *command);
247 UINT  _ux_device_class_dfu_control_request(UX_SLAVE_CLASS_COMMAND *command);
248 UINT  _ux_device_class_dfu_deactivate(UX_SLAVE_CLASS_COMMAND *command);
249 UINT  _ux_device_class_dfu_entry(UX_SLAVE_CLASS_COMMAND *command);
250 UINT  _ux_device_class_dfu_initialize(UX_SLAVE_CLASS_COMMAND *command);
251 VOID  _ux_device_class_dfu_thread(ULONG dfu_class);
252 
253 UCHAR _ux_device_class_dfu_state_get(UX_SLAVE_CLASS_DFU *dfu);
254 VOID  _ux_device_class_dfu_state_sync(UX_SLAVE_CLASS_DFU *dfu);
255 
256 UINT  _ux_device_class_dfu_tasks_run(VOID *class_instance);
257 
258 /* Define Device DFU Class API prototypes.  */
259 
260 #define ux_device_class_dfu_entry        _ux_device_class_dfu_entry
261 #define ux_device_class_dfu_state_get    _ux_device_class_dfu_state_get
262 #define ux_device_class_dfu_state_sync   _ux_device_class_dfu_state_sync
263 
264 /* Determine if a C++ compiler is being used.  If so, complete the standard
265    C conditional started above.  */
266 #ifdef __cplusplus
267 }
268 #endif
269 
270 #endif /* UX_DEVICE_CLASS_DFU_H */
271