2 ******************************************************************************
3 * @file usbd_dfu_core.c
4 * @author MCD Application Team
7 * @brief This file provides the high layer firmware functions to manage the
8 * following functionalities of the USB DFU Class:
9 * - Initialization and Configuration of high and low layer
10 * - Enumeration as DFU Device (and enumeration for each implemented memory interface)
11 * - Transfers to/from memory interfaces
12 * - Easy-to-customize "plug-in-like" modules for adding/removing memory interfaces.
17 * ===================================================================
18 * DFU Class Driver Description
19 * ===================================================================
20 * This driver manages the DFU class V1.1 following the "Device Class Specification for
21 * Device Firmware Upgrade Version 1.1 Aug 5, 2004".
22 * This driver implements the following aspects of the specification:
23 * - Device descriptor management
24 * - Configuration descriptor management
25 * - Enumeration as DFU device (in DFU mode only)
26 * - Requests management (supporting ST DFU sub-protocol)
27 * - Memory operations management (Download/Upload/Erase/Detach/GetState/GetStatus)
28 * - DFU state machine implementation.
31 * ST DFU sub-protocol is compliant with DFU protocol and use sub-requests to manage
32 * memory addressing, commands processing, specific memories operations (ie. Erase) ...
33 * As required by the DFU specification, only endpoint 0 is used in this application.
34 * Other endpoints and functions may be added to the application (ie. DFU ...)
36 * These aspects may be enriched or modified for a specific user application.
38 * This driver doesn't implement the following aspects of the specification
39 * (but it is possible to manage these features with some modifications on this driver):
40 * - Manifestation Tolerant mode
44 ******************************************************************************
47 * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
48 * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
49 * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
50 * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
51 * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
52 * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
54 * <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
55 ******************************************************************************
58 /* Includes ------------------------------------------------------------------*/
59 #include "usbd_dfu_core.h"
60 #include "usbd_desc.h"
65 /** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
70 /** @defgroup usbd_dfu
71 * @brief usbd core module
75 /** @defgroup usbd_dfu_Private_TypesDefinitions
83 /** @defgroup usbd_dfu_Private_Defines
91 /** @defgroup usbd_dfu_Private_Macros
99 /** @defgroup usbd_dfu_Private_FunctionPrototypes
103 /*********************************************
104 DFU Device library callbacks
105 *********************************************/
106 static uint8_t usbd_dfu_Init (void *pdev,
109 static uint8_t usbd_dfu_DeInit (void *pdev,
112 static uint8_t usbd_dfu_Setup (void *pdev,
115 static uint8_t EP0_TxSent (void *pdev);
117 static uint8_t EP0_RxReady (void *pdev);
120 static uint8_t *USBD_DFU_GetCfgDesc (uint8_t speed,
124 #ifdef USB_OTG_HS_CORE
125 static uint8_t *USBD_DFU_GetOtherCfgDesc (uint8_t speed,
129 static uint8_t* USBD_DFU_GetUsrStringDesc (uint8_t speed,
133 /*********************************************
134 DFU Requests management functions
135 *********************************************/
136 static void DFU_Req_DETACH (void *pdev,
139 static void DFU_Req_DNLOAD (void *pdev,
142 static void DFU_Req_UPLOAD (void *pdev,
145 static void DFU_Req_GETSTATUS (void *pdev);
147 static void DFU_Req_CLRSTATUS (void *pdev);
149 static void DFU_Req_GETSTATE (void *pdev);
151 static void DFU_Req_ABORT (void *pdev);
153 static void DFU_LeaveDFUMode (void *pdev);
159 /** @defgroup usbd_dfu_Private_Variables
162 #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
163 #if defined ( __ICCARM__ ) /*!< IAR Compiler */
164 #pragma data_alignment=4
166 #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
167 __ALIGN_BEGIN uint8_t usbd_dfu_CfgDesc[USB_DFU_CONFIG_DESC_SIZ] __ALIGN_END ;
170 #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
171 #if defined ( __ICCARM__ ) /*!< IAR Compiler */
172 #pragma data_alignment=4
174 #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
175 __ALIGN_BEGIN uint8_t usbd_dfu_OtherCfgDesc[USB_DFU_CONFIG_DESC_SIZ] __ALIGN_END ;
177 /* The list of Interface String descriptor pointers is defined in usbd_dfu_mal.c
178 file. This list can be updated whenever a memory has to be added or removed */
179 extern const uint8_t* usbd_dfu_StringDesc[];
181 /* State Machine variables */
183 uint8_t DeviceStatus[6];
184 uint32_t Manifest_State = Manifest_complete;
185 /* Data Management variables */
186 static uint32_t wBlockNum = 0, wlength = 0;
187 static uint32_t Pointer = APP_DEFAULT_ADD; /* Base Address to Erase, Program or Read */
188 static __IO uint32_t usbd_dfu_AltSet = 0;
190 extern uint8_t MAL_Buffer[];
192 /* DFU interface class callbacks structure */
193 USBD_Class_cb_TypeDef DFU_cb =
206 #ifdef USB_OTG_HS_CORE
207 USBD_DFU_GetOtherCfgDesc, /* use same cobfig as per FS */
209 USBD_DFU_GetUsrStringDesc,
212 #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
213 #if defined ( __ICCARM__ ) /*!< IAR Compiler */
214 #pragma data_alignment=4
216 #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
217 /* USB DFU device Configuration Descriptor */
218 __ALIGN_BEGIN uint8_t usbd_dfu_CfgDesc[USB_DFU_CONFIG_DESC_SIZ] __ALIGN_END =
220 0x09, /* bLength: Configuation Descriptor size */
221 USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */
222 USB_DFU_CONFIG_DESC_SIZ,
223 /* wTotalLength: Bytes returned */
225 0x01, /*bNumInterfaces: 1 interface*/
226 0x01, /*bConfigurationValue: Configuration value*/
227 0x02, /*iConfiguration: Index of string descriptor describing the configuration*/
228 0xC0, /*bmAttributes: bus powered and Supprts Remote Wakeup */
229 0x32, /*MaxPower 100 mA: this current is used for detecting Vbus*/
232 /********** Descriptor of DFU interface 0 Alternate setting 0 **************/
233 USBD_DFU_IF_DESC(0), /* This interface is mandatory for all devices */
235 #if (USBD_ITF_MAX_NUM > 1)
236 /********** Descriptor of DFU interface 0 Alternate setting 1 **************/
238 #endif /* (USBD_ITF_MAX_NUM > 1) */
240 #if (USBD_ITF_MAX_NUM > 2)
241 /********** Descriptor of DFU interface 0 Alternate setting 2 **************/
243 #endif /* (USBD_ITF_MAX_NUM > 2) */
245 #if (USBD_ITF_MAX_NUM > 3)
246 /********** Descriptor of DFU interface 0 Alternate setting 3 **************/
248 #endif /* (USBD_ITF_MAX_NUM > 3) */
250 #if (USBD_ITF_MAX_NUM > 4)
251 /********** Descriptor of DFU interface 0 Alternate setting 4 **************/
253 #endif /* (USBD_ITF_MAX_NUM > 4) */
255 #if (USBD_ITF_MAX_NUM > 5)
256 /********** Descriptor of DFU interface 0 Alternate setting 5 **************/
258 #endif /* (USBD_ITF_MAX_NUM > 5) */
260 #if (USBD_ITF_MAX_NUM > 6)
261 #error "ERROR: usbd_dfu_core.c: Modify the file to support more descriptors!"
262 #endif /* (USBD_ITF_MAX_NUM > 6) */
264 /******************** DFU Functional Descriptor********************/
265 0x09, /*blength = 9 Bytes*/
266 DFU_DESCRIPTOR_TYPE, /* DFU Functional Descriptor*/
268 bitCanDnload = 1 (bit 0)
269 bitCanUpload = 1 (bit 1)
270 bitManifestationTolerant = 0 (bit 2)
271 bitWillDetach = 1 (bit 3)
273 bitAcceleratedST = 0 (bit 7)*/
274 0xFF, /*DetachTimeOut= 255 ms*/
276 /*WARNING: In DMA mode the multiple MPS packets feature is still not supported
277 ==> In this case, when using DMA XFERSIZE should be set to 64 in usbd_conf.h */
278 TRANSFER_SIZE_BYTES(XFERSIZE), /* TransferSize = 1024 Byte*/
279 0x1A, /* bcdDFUVersion*/
281 /***********************************************************/
285 #ifdef USE_USB_OTG_HS
286 #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
287 #if defined ( __ICCARM__ ) /*!< IAR Compiler */
288 #pragma data_alignment=4
290 #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
292 __ALIGN_BEGIN uint8_t usbd_dfu_OtherCfgDesc[USB_DFU_CONFIG_DESC_SIZ] __ALIGN_END =
294 0x09, /* bLength: Configuation Descriptor size */
295 USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION, /* bDescriptorType: Configuration */
296 USB_DFU_CONFIG_DESC_SIZ,
297 /* wTotalLength: Bytes returned */
299 0x01, /*bNumInterfaces: 1 interface*/
300 0x01, /*bConfigurationValue: Configuration value*/
301 0x02, /*iConfiguration: Index of string descriptor describing the configuration*/
302 0xC0, /*bmAttributes: bus powered and Supprts Remote Wakeup */
303 0x32, /*MaxPower 100 mA: this current is used for detecting Vbus*/
306 /********** Descriptor of DFU interface 0 Alternate setting 0 **************/
307 USBD_DFU_IF_DESC(0), /* This interface is mandatory for all devices */
309 #if (USBD_ITF_MAX_NUM > 1)
310 /********** Descriptor of DFU interface 0 Alternate setting 1 **************/
312 #endif /* (USBD_ITF_MAX_NUM > 1) */
314 #if (USBD_ITF_MAX_NUM > 2)
315 /********** Descriptor of DFU interface 0 Alternate setting 2 **************/
317 #endif /* (USBD_ITF_MAX_NUM > 2) */
319 #if (USBD_ITF_MAX_NUM > 3)
320 /********** Descriptor of DFU interface 0 Alternate setting 3 **************/
322 #endif /* (USBD_ITF_MAX_NUM > 3) */
324 #if (USBD_ITF_MAX_NUM > 4)
325 /********** Descriptor of DFU interface 0 Alternate setting 4 **************/
327 #endif /* (USBD_ITF_MAX_NUM > 4) */
329 #if (USBD_ITF_MAX_NUM > 5)
330 /********** Descriptor of DFU interface 0 Alternate setting 5 **************/
332 #endif /* (USBD_ITF_MAX_NUM > 5) */
334 #if (USBD_ITF_MAX_NUM > 6)
335 #error "ERROR: usbd_dfu_core.c: Modify the file to support more descriptors!"
336 #endif /* (USBD_ITF_MAX_NUM > 6) */
338 /******************** DFU Functional Descriptor********************/
339 0x09, /*blength = 9 Bytes*/
340 DFU_DESCRIPTOR_TYPE, /* DFU Functional Descriptor*/
342 bitCanDnload = 1 (bit 0)
343 bitCanUpload = 1 (bit 1)
344 bitManifestationTolerant = 0 (bit 2)
345 bitWillDetach = 1 (bit 3)
347 bitAcceleratedST = 0 (bit 7)*/
348 0xFF, /*DetachTimeOut= 255 ms*/
350 /*WARNING: In DMA mode the multiple MPS packets feature is still not supported
351 ==> In this case, when using DMA XFERSIZE should be set to 64 in usbd_conf.h */
352 TRANSFER_SIZE_BYTES(XFERSIZE), /* TransferSize = 1024 Byte*/
353 0x1A, /* bcdDFUVersion*/
355 /***********************************************************/
358 #endif /* USE_USB_OTG_HS */
360 #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
361 #if defined ( __ICCARM__ ) /*!< IAR Compiler */
362 #pragma data_alignment=4
365 __ALIGN_BEGIN static uint8_t usbd_dfu_Desc[USB_DFU_DESC_SIZ] __ALIGN_END =
367 0x09, /*blength = 9 Bytes*/
368 DFU_DESCRIPTOR_TYPE, /* DFU Functional Descriptor*/
370 bitCanDnload = 1 (bit 0)
371 bitCanUpload = 1 (bit 1)
372 bitManifestationTolerant = 0 (bit 2)
373 bitWillDetach = 1 (bit 3)
375 bitAcceleratedST = 0 (bit 7)*/
376 0xFF, /*DetachTimeOut= 255 ms*/
378 /*WARNING: In DMA mode the multiple MPS packets feature is still not supported
379 ==> In this case, when using DMA XFERSIZE should be set to 64 in usbd_conf.h */
380 TRANSFER_SIZE_BYTES(XFERSIZE), /* TransferSize = 1024 Byte*/
381 0x1A, /* bcdDFUVersion*/
384 #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
390 /** @defgroup usbd_dfu_Private_Functions
395 * @brief usbd_dfu_Init
396 * Initializes the DFU interface.
397 * @param pdev: device instance
398 * @param cfgidx: Configuration index
401 static uint8_t usbd_dfu_Init (void *pdev,
404 /* Initilialize the MAL(Media Access Layer) */
407 /* Initialize the state of the DFU interface */
408 DeviceState = STATE_dfuIDLE;
409 DeviceStatus[0] = STATUS_OK;
410 DeviceStatus[4] = DeviceState;
416 * @brief usbd_dfu_Init
417 * De-initializes the DFU layer.
418 * @param pdev: device instance
419 * @param cfgidx: Configuration index
422 static uint8_t usbd_dfu_DeInit (void *pdev,
425 /* Restore default state */
426 DeviceState = STATE_dfuIDLE;
427 DeviceStatus[0] = STATUS_OK;
428 DeviceStatus[4] = DeviceState;
432 /* DeInitilialize the MAL(Media Access Layer) */
439 * @brief usbd_dfu_Setup
440 * Handles the DFU request parsing.
441 * @param pdev: instance
442 * @param req: usb requests
445 static uint8_t usbd_dfu_Setup (void *pdev,
449 uint8_t *pbuf = NULL;
451 switch (req->bmRequest & USB_REQ_TYPE_MASK)
453 /* DFU Class Requests -------------------------------*/
454 case USB_REQ_TYPE_CLASS :
455 switch (req->bRequest)
458 DFU_Req_DNLOAD(pdev, req);
462 DFU_Req_UPLOAD(pdev, req);
466 DFU_Req_GETSTATUS(pdev);
470 DFU_Req_CLRSTATUS(pdev);
474 DFU_Req_GETSTATE(pdev);
482 DFU_Req_DETACH(pdev, req);
486 USBD_CtlError (pdev, req);
491 /* Standard Requests -------------------------------*/
492 case USB_REQ_TYPE_STANDARD:
493 switch (req->bRequest)
495 case USB_REQ_GET_DESCRIPTOR:
496 if( (req->wValue >> 8) == DFU_DESCRIPTOR_TYPE)
498 #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
499 pbuf = usbd_dfu_Desc;
501 pbuf = usbd_dfu_CfgDesc + 9 + (9 * USBD_ITF_MAX_NUM);
503 len = MIN(USB_DFU_DESC_SIZ , req->wLength);
506 USBD_CtlSendData (pdev,
511 case USB_REQ_GET_INTERFACE :
512 USBD_CtlSendData (pdev,
513 (uint8_t *)&usbd_dfu_AltSet,
517 case USB_REQ_SET_INTERFACE :
518 if ((uint8_t)(req->wValue) < USBD_ITF_MAX_NUM)
520 usbd_dfu_AltSet = (uint8_t)(req->wValue);
524 /* Call the error management function (command will be nacked */
525 USBD_CtlError (pdev, req);
535 * Handles the DFU control endpoint data IN stage.
536 * @param pdev: device instance
539 static uint8_t EP0_TxSent (void *pdev)
544 if (DeviceState == STATE_dfuDNBUSY)
546 /* Decode the Special Command*/
549 if ((MAL_Buffer[0] == CMD_GETCOMMANDS) && (wlength == 1))
551 else if (( MAL_Buffer[0] == CMD_SETADDRESSPOINTER ) && (wlength == 5))
553 Pointer = MAL_Buffer[1];
554 Pointer += MAL_Buffer[2] << 8;
555 Pointer += MAL_Buffer[3] << 16;
556 Pointer += MAL_Buffer[4] << 24;
558 else if (( MAL_Buffer[0] == CMD_ERASE ) && (wlength == 5))
560 Pointer = MAL_Buffer[1];
561 Pointer += MAL_Buffer[2] << 8;
562 Pointer += MAL_Buffer[3] << 16;
563 Pointer += MAL_Buffer[4] << 24;
568 /* Reset the global length and block number */
571 /* Call the error management function (command will be nacked) */
574 USBD_CtlError (pdev, &req);
577 /* Regular Download Command */
578 else if (wBlockNum > 1)
580 /* Decode the required address */
581 Addr = ((wBlockNum - 2) * XFERSIZE) + Pointer;
583 /* Preform the write operation */
584 MAL_Write(Addr, wlength);
586 /* Reset the global lenght and block number */
590 /* Update the state machine */
591 DeviceState = STATE_dfuDNLOAD_SYNC;
592 DeviceStatus[4] = DeviceState;
598 else if (DeviceState == STATE_dfuMANIFEST)/* Manifestation in progress*/
600 /* Start leaving DFU mode */
601 DFU_LeaveDFUMode(pdev);
609 * Handles the DFU control endpoint data OUT stage.
610 * @param pdev: device instance
613 static uint8_t EP0_RxReady (void *pdev)
619 /******************************************************************************
620 DFU Class requests management
621 ******************************************************************************/
623 * @brief DFU_Req_DETACH
624 * Handles the DFU DETACH request.
625 * @param pdev: device instance
626 * @param req: pointer to the request structure.
629 static void DFU_Req_DETACH(void *pdev, USB_SETUP_REQ *req)
631 if (DeviceState == STATE_dfuIDLE || DeviceState == STATE_dfuDNLOAD_SYNC
632 || DeviceState == STATE_dfuDNLOAD_IDLE || DeviceState == STATE_dfuMANIFEST_SYNC
633 || DeviceState == STATE_dfuUPLOAD_IDLE )
635 /* Update the state machine */
636 DeviceState = STATE_dfuIDLE;
637 DeviceStatus[0] = STATUS_OK;
640 DeviceStatus[3] = 0; /*bwPollTimeout=0ms*/
641 DeviceStatus[4] = DeviceState;
642 DeviceStatus[5] = 0; /*iString*/
647 /* Check the detach capability in the DFU functional descriptor */
648 if ((usbd_dfu_CfgDesc[12 + (9 * USBD_ITF_MAX_NUM)]) & DFU_DETACH_MASK)
650 /* Perform an Attach-Detach operation on USB bus */
651 DCD_DevDisconnect (pdev);
652 DCD_DevConnect (pdev);
656 /* Wait for the period of time specified in Detach request */
657 USB_OTG_BSP_mDelay (req->wValue);
662 * @brief DFU_Req_DNLOAD
663 * Handles the DFU DNLOAD request.
664 * @param pdev: device instance
665 * @param req: pointer to the request structure
668 static void DFU_Req_DNLOAD(void *pdev, USB_SETUP_REQ *req)
670 /* Data setup request */
671 if (req->wLength > 0)
673 if ((DeviceState == STATE_dfuIDLE) || (DeviceState == STATE_dfuDNLOAD_IDLE))
675 /* Update the global length and block number */
676 wBlockNum = req->wValue;
677 wlength = req->wLength;
679 /* Update the state machine */
680 DeviceState = STATE_dfuDNLOAD_SYNC;
681 DeviceStatus[4] = DeviceState;
683 /* Prepare the reception of the buffer over EP0 */
684 USBD_CtlPrepareRx (pdev,
685 (uint8_t*)MAL_Buffer,
688 /* Unsupported state */
691 /* Call the error management function (command will be nacked */
692 USBD_CtlError (pdev, req);
695 /* 0 Data DNLOAD request */
698 /* End of DNLOAD operation*/
699 if (DeviceState == STATE_dfuDNLOAD_IDLE || DeviceState == STATE_dfuIDLE )
701 Manifest_State = Manifest_In_Progress;
702 DeviceState = STATE_dfuMANIFEST_SYNC;
706 DeviceStatus[4] = DeviceState;
710 /* Call the error management function (command will be nacked */
711 USBD_CtlError (pdev, req);
717 * @brief DFU_Req_UPLOAD
718 * Handles the DFU UPLOAD request.
719 * @param pdev: instance
720 * @param req: pointer to the request structure
723 static void DFU_Req_UPLOAD(void *pdev, USB_SETUP_REQ *req)
725 uint8_t *Phy_Addr = NULL;
728 /* Data setup request */
729 if (req->wLength > 0)
731 if ((DeviceState == STATE_dfuIDLE) || (DeviceState == STATE_dfuUPLOAD_IDLE))
733 /* Update the global langth and block number */
734 wBlockNum = req->wValue;
735 wlength = req->wLength;
737 /* DFU Get Command */
740 /* Update the state machine */
741 DeviceState = (wlength > 3)? STATE_dfuIDLE:STATE_dfuUPLOAD_IDLE;
742 DeviceStatus[4] = DeviceState;
747 /* Store the values of all supported commands */
748 MAL_Buffer[0] = CMD_GETCOMMANDS;
749 MAL_Buffer[1] = CMD_SETADDRESSPOINTER;
750 MAL_Buffer[2] = CMD_ERASE;
752 /* Send the status data over EP0 */
753 USBD_CtlSendData (pdev,
754 (uint8_t *)(&(MAL_Buffer[0])),
757 else if (wBlockNum > 1)
759 DeviceState = STATE_dfuUPLOAD_IDLE ;
760 DeviceStatus[4] = DeviceState;
764 Addr = ((wBlockNum - 2) * XFERSIZE) + Pointer; /* Change is Accelerated*/
766 /* Return the physical address where data are stored */
767 Phy_Addr = MAL_Read(Addr, wlength);
769 /* Send the status data over EP0 */
770 USBD_CtlSendData (pdev,
774 else /* unsupported wBlockNum */
776 DeviceState = STATUS_ERRSTALLEDPKT;
777 DeviceStatus[4] = DeviceState;
782 /* Call the error management function (command will be nacked */
783 USBD_CtlError (pdev, req);
786 /* Unsupported state */
791 /* Call the error management function (command will be nacked */
792 USBD_CtlError (pdev, req);
795 /* No Data setup request */
798 DeviceState = STATE_dfuIDLE;
802 DeviceStatus[4] = DeviceState;
807 * @brief DFU_Req_GETSTATUS
808 * Handles the DFU GETSTATUS request.
809 * @param pdev: instance
812 static void DFU_Req_GETSTATUS(void *pdev)
816 case STATE_dfuDNLOAD_SYNC:
819 DeviceState = STATE_dfuDNBUSY;
820 DeviceStatus[4] = DeviceState;
821 if ((wBlockNum == 0) && (MAL_Buffer[0] == CMD_ERASE))
823 MAL_GetStatus(Pointer, 0, DeviceStatus);
827 MAL_GetStatus(Pointer, 1, DeviceStatus);
830 else /* (wlength==0)*/
832 DeviceState = STATE_dfuDNLOAD_IDLE;
833 DeviceStatus[4] = DeviceState;
840 case STATE_dfuMANIFEST_SYNC :
841 if (Manifest_State == Manifest_In_Progress)
843 DeviceState = STATE_dfuMANIFEST;
844 DeviceStatus[4] = DeviceState;
845 DeviceStatus[1] = 1; /*bwPollTimeout = 1ms*/
850 else if ((Manifest_State == Manifest_complete) && \
851 ((usbd_dfu_CfgDesc[(11 + (9 * USBD_ITF_MAX_NUM))]) & 0x04))
853 DeviceState = STATE_dfuIDLE;
854 DeviceStatus[4] = DeviceState;
866 /* Send the status data over EP0 */
867 USBD_CtlSendData (pdev,
868 (uint8_t *)(&(DeviceStatus[0])),
873 * @brief DFU_Req_CLRSTATUS
874 * Handles the DFU CLRSTATUS request.
875 * @param pdev: device instance
878 static void DFU_Req_CLRSTATUS(void *pdev)
880 if (DeviceState == STATE_dfuERROR)
882 DeviceState = STATE_dfuIDLE;
883 DeviceStatus[0] = STATUS_OK;/*bStatus*/
886 DeviceStatus[3] = 0; /*bwPollTimeout=0ms*/
887 DeviceStatus[4] = DeviceState;/*bState*/
888 DeviceStatus[5] = 0;/*iString*/
892 DeviceState = STATE_dfuERROR;
893 DeviceStatus[0] = STATUS_ERRUNKNOWN;/*bStatus*/
896 DeviceStatus[3] = 0; /*bwPollTimeout=0ms*/
897 DeviceStatus[4] = DeviceState;/*bState*/
898 DeviceStatus[5] = 0;/*iString*/
903 * @brief DFU_Req_GETSTATE
904 * Handles the DFU GETSTATE request.
905 * @param pdev: device instance
908 static void DFU_Req_GETSTATE(void *pdev)
910 /* Return the current state of the DFU interface */
911 USBD_CtlSendData (pdev,
917 * @brief DFU_Req_ABORT
918 * Handles the DFU ABORT request.
919 * @param pdev: device instance
922 static void DFU_Req_ABORT(void *pdev)
924 if (DeviceState == STATE_dfuIDLE || DeviceState == STATE_dfuDNLOAD_SYNC
925 || DeviceState == STATE_dfuDNLOAD_IDLE || DeviceState == STATE_dfuMANIFEST_SYNC
926 || DeviceState == STATE_dfuUPLOAD_IDLE )
928 DeviceState = STATE_dfuIDLE;
929 DeviceStatus[0] = STATUS_OK;
932 DeviceStatus[3] = 0; /*bwPollTimeout=0ms*/
933 DeviceStatus[4] = DeviceState;
934 DeviceStatus[5] = 0; /*iString*/
941 * @brief DFU_LeaveDFUMode
942 * Handles the sub-protocol DFU leave DFU mode request (leaves DFU mode
943 * and resets device to jump to user loaded code).
944 * @param pdev: device instance
947 void DFU_LeaveDFUMode(void *pdev)
949 Manifest_State = Manifest_complete;
951 if ((usbd_dfu_CfgDesc[(11 + (9 * USBD_ITF_MAX_NUM))]) & 0x04)
953 DeviceState = STATE_dfuMANIFEST_SYNC;
954 DeviceStatus[4] = DeviceState;
962 DeviceState = STATE_dfuMANIFEST_WAIT_RESET;
963 DeviceStatus[4] = DeviceState;
968 /* Disconnect the USB device */
969 DCD_DevDisconnect (pdev);
971 /* DeInitilialize the MAL(Media Access Layer) */
974 /* Generate system reset to allow jumping to the user code */
977 /* This instruction will not be reached (system reset) */
983 * @brief USBD_DFU_GetCfgDesc
984 * Returns configuration descriptor
985 * @param speed : current device speed
986 * @param length : pointer data length
987 * @retval pointer to descriptor buffer
989 static uint8_t *USBD_DFU_GetCfgDesc (uint8_t speed, uint16_t *length)
991 *length = sizeof (usbd_dfu_CfgDesc);
992 return usbd_dfu_CfgDesc;
995 #ifdef USB_OTG_HS_CORE
997 * @brief USBD_DFU_GetOtherCfgDesc
998 * Returns other speed configuration descriptor.
999 * @param speed : current device speed
1000 * @param length : pointer data length
1001 * @retval pointer to descriptor buffer
1003 static uint8_t *USBD_DFU_GetOtherCfgDesc (uint8_t speed, uint16_t *length)
1005 *length = sizeof (usbd_dfu_OtherCfgDesc);
1006 return usbd_dfu_OtherCfgDesc;
1011 * @brief USBD_DFU_GetUsrStringDesc
1012 * Manages the transfer of memory interfaces string descriptors.
1013 * @param speed : current device speed
1014 * @param index: desciptor index
1015 * @param length : pointer data length
1016 * @retval pointer to the descriptor table or NULL if the descriptor is not supported.
1018 static uint8_t* USBD_DFU_GetUsrStringDesc (uint8_t speed, uint8_t index , uint16_t *length)
1020 /* Check if the requested string interface is supported */
1021 if (index <= (USBD_IDX_INTERFACE_STR + USBD_ITF_MAX_NUM))
1025 USBD_GetString ((uint8_t *)usbd_dfu_StringDesc[index - USBD_IDX_INTERFACE_STR - 1], USBD_StrDesc, length);
1026 return USBD_StrDesc;
1028 /* Not supported Interface Descriptor index */
1046 /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/