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