STM32F769IDiscovery  1.00
uDANTE Audio Networking with STM32F7 DISCO board
usbd_dfu.c
Go to the documentation of this file.
1 
58 /* Includes ------------------------------------------------------------------*/
59 #include "usbd_dfu.h"
60 #include "usbd_desc.h"
61 #include "usbd_ctlreq.h"
62 
63 
94 #define DFU_SAMPLE_FREQ(frq) (uint8_t)(frq), (uint8_t)((frq >> 8)), (uint8_t)((frq >> 16))
95 
96 #define DFU_PACKET_SZE(frq) (uint8_t)(((frq * 2 * 2)/1000) & 0xFF), \
97  (uint8_t)((((frq * 2 * 2)/1000) >> 8) & 0xFF)
98 
111 static uint8_t USBD_DFU_Init (USBD_HandleTypeDef *pdev,
112  uint8_t cfgidx);
113 
114 static uint8_t USBD_DFU_DeInit (USBD_HandleTypeDef *pdev,
115  uint8_t cfgidx);
116 
117 static uint8_t USBD_DFU_Setup (USBD_HandleTypeDef *pdev,
118  USBD_SetupReqTypedef *req);
119 
120 static uint8_t *USBD_DFU_GetCfgDesc (uint16_t *length);
121 
122 static uint8_t *USBD_DFU_GetDeviceQualifierDesc (uint16_t *length);
123 
124 static uint8_t USBD_DFU_DataIn (USBD_HandleTypeDef *pdev, uint8_t epnum);
125 
126 static uint8_t USBD_DFU_DataOut (USBD_HandleTypeDef *pdev, uint8_t epnum);
127 
128 static uint8_t USBD_DFU_EP0_RxReady (USBD_HandleTypeDef *pdev);
129 
130 static uint8_t USBD_DFU_EP0_TxReady (USBD_HandleTypeDef *pdev);
131 
132 static uint8_t USBD_DFU_SOF (USBD_HandleTypeDef *pdev);
133 
134 static uint8_t USBD_DFU_IsoINIncomplete (USBD_HandleTypeDef *pdev, uint8_t epnum);
135 
136 static uint8_t USBD_DFU_IsoOutIncomplete (USBD_HandleTypeDef *pdev, uint8_t epnum);
137 
138 #if (USBD_SUPPORT_USER_STRING == 1)
139 static uint8_t* USBD_DFU_GetUsrStringDesc ( USBD_HandleTypeDef *pdev, uint8_t index , uint16_t *length);
140 #endif
141 
142 static void DFU_Detach (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
143 
144 static void DFU_Download (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
145 
146 static void DFU_Upload (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
147 
148 static void DFU_GetStatus (USBD_HandleTypeDef *pdev);
149 
150 static void DFU_ClearStatus (USBD_HandleTypeDef *pdev);
151 
152 static void DFU_GetState (USBD_HandleTypeDef *pdev);
153 
154 static void DFU_Abort (USBD_HandleTypeDef *pdev);
155 
156 static void DFU_Leave (USBD_HandleTypeDef *pdev);
157 
158 
168 {
169  USBD_DFU_Init,
170  USBD_DFU_DeInit,
171  USBD_DFU_Setup,
172  USBD_DFU_EP0_TxReady,
173  USBD_DFU_EP0_RxReady,
174  USBD_DFU_DataIn,
175  USBD_DFU_DataOut,
176  USBD_DFU_SOF,
177  USBD_DFU_IsoINIncomplete,
178  USBD_DFU_IsoOutIncomplete,
179  USBD_DFU_GetCfgDesc,
180  USBD_DFU_GetCfgDesc,
181  USBD_DFU_GetCfgDesc,
182  USBD_DFU_GetDeviceQualifierDesc,
183 #if (USBD_SUPPORT_USER_STRING == 1)
184  USBD_DFU_GetUsrStringDesc
185 #endif
186 };
187 
188 /* USB DFU device Configuration Descriptor */
189 __ALIGN_BEGIN static uint8_t USBD_DFU_CfgDesc[USB_DFU_CONFIG_DESC_SIZ] __ALIGN_END =
190 {
191  0x09, /* bLength: Configuation Descriptor size */
192  USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
194  /* wTotalLength: Bytes returned */
195  0x00,
196  0x01, /*bNumInterfaces: 1 interface*/
197  0x01, /*bConfigurationValue: Configuration value*/
198  0x02, /*iConfiguration: Index of string descriptor describing the configuration*/
199  0xC0, /*bmAttributes: bus powered and Supprts Remote Wakeup */
200  0x32, /*MaxPower 100 mA: this current is used for detecting Vbus*/
201  /* 09 */
202 
203  /********** Descriptor of DFU interface 0 Alternate setting 0 **************/
204  USBD_DFU_IF_DESC(0), /* This interface is mandatory for all devices */
205 
206 #if (USBD_DFU_MAX_ITF_NUM > 1)
207  /********** Descriptor of DFU interface 0 Alternate setting 1 **************/
208  USBD_DFU_IF_DESC(1),
209 #endif /* (USBD_DFU_MAX_ITF_NUM > 1) */
210 
211 #if (USBD_DFU_MAX_ITF_NUM > 2)
212  /********** Descriptor of DFU interface 0 Alternate setting 2 **************/
213  USBD_DFU_IF_DESC(2),
214 #endif /* (USBD_DFU_MAX_ITF_NUM > 2) */
215 
216 #if (USBD_DFU_MAX_ITF_NUM > 3)
217  /********** Descriptor of DFU interface 0 Alternate setting 3 **************/
218  USBD_DFU_IF_DESC(3),
219 #endif /* (USBD_DFU_MAX_ITF_NUM > 3) */
220 
221 #if (USBD_DFU_MAX_ITF_NUM > 4)
222  /********** Descriptor of DFU interface 0 Alternate setting 4 **************/
223  USBD_DFU_IF_DESC(4),
224 #endif /* (USBD_DFU_MAX_ITF_NUM > 4) */
225 
226 #if (USBD_DFU_MAX_ITF_NUM > 5)
227  /********** Descriptor of DFU interface 0 Alternate setting 5 **************/
228  USBD_DFU_IF_DESC(5),
229 #endif /* (USBD_DFU_MAX_ITF_NUM > 5) */
230 
231 #if (USBD_DFU_MAX_ITF_NUM > 6)
232 #error "ERROR: usbd_dfu_core.c: Modify the file to support more descriptors!"
233 #endif /* (USBD_DFU_MAX_ITF_NUM > 6) */
234 
235  /******************** DFU Functional Descriptor********************/
236  0x09, /*blength = 9 Bytes*/
237  DFU_DESCRIPTOR_TYPE, /* DFU Functional Descriptor*/
238  0x0B, /*bmAttribute
239  bitCanDnload = 1 (bit 0)
240  bitCanUpload = 1 (bit 1)
241  bitManifestationTolerant = 0 (bit 2)
242  bitWillDetach = 1 (bit 3)
243  Reserved (bit4-6)
244  bitAcceleratedST = 0 (bit 7)*/
245  0xFF, /*DetachTimeOut= 255 ms*/
246  0x00,
247  /*WARNING: In DMA mode the multiple MPS packets feature is still not supported
248  ==> In this case, when using DMA USBD_DFU_XFER_SIZE should be set to 64 in usbd_conf.h */
249  TRANSFER_SIZE_BYTES(USBD_DFU_XFER_SIZE), /* TransferSize = 1024 Byte*/
250  0x1A, /* bcdDFUVersion*/
251  0x01
252  /***********************************************************/
253  /* 9*/
254 };
255 
256 /* USB Standard Device Descriptor */
257 __ALIGN_BEGIN static uint8_t USBD_DFU_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END =
258 {
261  0x00,
262  0x02,
263  0x00,
264  0x00,
265  0x00,
266  0x40,
267  0x01,
268  0x00,
269 };
270 
286 static uint8_t USBD_DFU_Init (USBD_HandleTypeDef *pdev,
287  uint8_t cfgidx)
288 {
290 
291  /* Allocate Audio structure */
293 
294  if(pdev->pClassData == NULL)
295  {
296  return USBD_FAIL;
297  }
298  else
299  {
300  hdfu = (USBD_DFU_HandleTypeDef*) pdev->pClassData;
301 
302  hdfu->alt_setting = 0;
303  hdfu->data_ptr = USBD_DFU_APP_DEFAULT_ADD;
304  hdfu->wblock_num = 0;
305  hdfu->wlength = 0;
306 
308  hdfu->dev_state = DFU_STATE_IDLE;
309 
310  hdfu->dev_status[0] = DFU_ERROR_NONE;
311  hdfu->dev_status[1] = 0;
312  hdfu->dev_status[2] = 0;
313  hdfu->dev_status[3] = 0;
314  hdfu->dev_status[4] = DFU_STATE_IDLE;
315  hdfu->dev_status[5] = 0;
316 
317  /* Initialize Hardware layer */
318  if (((USBD_DFU_MediaTypeDef *)pdev->pUserData)->Init() != USBD_OK)
319  {
320  return USBD_FAIL;
321  }
322  }
323  return USBD_OK;
324 }
325 
333 static uint8_t USBD_DFU_DeInit (USBD_HandleTypeDef *pdev,
334  uint8_t cfgidx)
335 {
337  hdfu = (USBD_DFU_HandleTypeDef*) pdev->pClassData;
338 
339  hdfu->wblock_num = 0;
340  hdfu->wlength = 0;
341 
342  hdfu->dev_state = DFU_STATE_IDLE;
343  hdfu->dev_status[0] = DFU_ERROR_NONE;
344  hdfu->dev_status[4] = DFU_STATE_IDLE;
345 
346  /* DeInit physical Interface components */
347  if(pdev->pClassData != NULL)
348  {
349  /* De-Initialize Hardware layer */
350  ((USBD_DFU_MediaTypeDef *)pdev->pUserData)->DeInit();
351  USBD_free(pdev->pClassData);
352  pdev->pClassData = NULL;
353  }
354 
355  return USBD_OK;
356 }
357 
365 static uint8_t USBD_DFU_Setup (USBD_HandleTypeDef *pdev,
367 {
368  uint8_t *pbuf = 0;
369  uint16_t len = 0;
370  uint8_t ret = USBD_OK;
372 
373  hdfu = (USBD_DFU_HandleTypeDef*) pdev->pClassData;
374 
375  switch (req->bmRequest & USB_REQ_TYPE_MASK)
376  {
377  case USB_REQ_TYPE_CLASS :
378  switch (req->bRequest)
379  {
380  case DFU_DNLOAD:
381  DFU_Download(pdev, req);
382  break;
383 
384  case DFU_UPLOAD:
385  DFU_Upload(pdev, req);
386  break;
387 
388  case DFU_GETSTATUS:
389  DFU_GetStatus(pdev);
390  break;
391 
392  case DFU_CLRSTATUS:
393  DFU_ClearStatus(pdev);
394  break;
395 
396  case DFU_GETSTATE:
397  DFU_GetState(pdev);
398  break;
399 
400  case DFU_ABORT:
401  DFU_Abort(pdev);
402  break;
403 
404  case DFU_DETACH:
405  DFU_Detach(pdev, req);
406  break;
407 
408 
409  default:
410  USBD_CtlError (pdev, req);
411  ret = USBD_FAIL;
412  }
413  break;
414 
416  switch (req->bRequest)
417  {
419  if( (req->wValue >> 8) == DFU_DESCRIPTOR_TYPE)
420  {
421  pbuf = USBD_DFU_CfgDesc + (9 * (USBD_DFU_MAX_ITF_NUM + 1));
422  len = MIN(USB_DFU_DESC_SIZ , req->wLength);
423  }
424 
425  USBD_CtlSendData (pdev,
426  pbuf,
427  len);
428  break;
429 
430  case USB_REQ_GET_INTERFACE :
431  USBD_CtlSendData (pdev,
432  (uint8_t *)&hdfu->alt_setting,
433  1);
434  break;
435 
436  case USB_REQ_SET_INTERFACE :
437  if ((uint8_t)(req->wValue) < USBD_DFU_MAX_ITF_NUM)
438  {
439  hdfu->alt_setting = (uint8_t)(req->wValue);
440  }
441  else
442  {
443  /* Call the error management function (command will be nacked */
444  USBD_CtlError (pdev, req);
445  ret = USBD_FAIL;
446  }
447  break;
448 
449  default:
450  USBD_CtlError (pdev, req);
451  ret = USBD_FAIL;
452  }
453  }
454  return ret;
455 }
456 
457 
465 static uint8_t *USBD_DFU_GetCfgDesc (uint16_t *length)
466 {
467  *length = sizeof (USBD_DFU_CfgDesc);
468  return USBD_DFU_CfgDesc;
469 }
470 
478 static uint8_t USBD_DFU_DataIn (USBD_HandleTypeDef *pdev,
479  uint8_t epnum)
480 {
481 
482  return USBD_OK;
483 }
484 
491 static uint8_t USBD_DFU_EP0_RxReady (USBD_HandleTypeDef *pdev)
492 {
493 
494  return USBD_OK;
495 }
502 static uint8_t USBD_DFU_EP0_TxReady (USBD_HandleTypeDef *pdev)
503 {
504  uint32_t addr;
507 
508  hdfu = (USBD_DFU_HandleTypeDef*) pdev->pClassData;
509 
511  {
512  /* Decode the Special Command*/
513  if (hdfu->wblock_num == 0)
514  {
515  if ((hdfu->buffer.d8[0] == DFU_CMD_GETCOMMANDS) && (hdfu->wlength == 1))
516  {
517 
518  }
519  else if (( hdfu->buffer.d8[0] == DFU_CMD_SETADDRESSPOINTER ) && (hdfu->wlength == 5))
520  {
521  hdfu->data_ptr = hdfu->buffer.d8[1];
522  hdfu->data_ptr += hdfu->buffer.d8[2] << 8;
523  hdfu->data_ptr += hdfu->buffer.d8[3] << 16;
524  hdfu->data_ptr += hdfu->buffer.d8[4] << 24;
525  }
526  else if (( hdfu->buffer.d8[0] == DFU_CMD_ERASE ) && (hdfu->wlength == 5))
527  {
528  hdfu->data_ptr = hdfu->buffer.d8[1];
529  hdfu->data_ptr += hdfu->buffer.d8[2] << 8;
530  hdfu->data_ptr += hdfu->buffer.d8[3] << 16;
531  hdfu->data_ptr += hdfu->buffer.d8[4] << 24;
532 
533  if (((USBD_DFU_MediaTypeDef *)pdev->pUserData)->Erase(hdfu->data_ptr) != USBD_OK)
534  {
535  return USBD_FAIL;
536  }
537  }
538  else
539  {
540  /* Reset the global length and block number */
541  hdfu->wlength = 0;
542  hdfu->wblock_num = 0;
543  /* Call the error management function (command will be nacked) */
544  req.bmRequest = 0;
545  req.wLength = 1;
546  USBD_CtlError (pdev, &req);
547  }
548  }
549  /* Regular Download Command */
550  else if (hdfu->wblock_num > 1)
551  {
552  /* Decode the required address */
553  addr = ((hdfu->wblock_num - 2) * USBD_DFU_XFER_SIZE) + hdfu->data_ptr;
554 
555  /* Preform the write operation */
556  if (((USBD_DFU_MediaTypeDef *)pdev->pUserData)->Write(hdfu->buffer.d8, (uint8_t *)addr, hdfu->wlength) != USBD_OK)
557  {
558  return USBD_FAIL;
559  }
560  }
561  /* Reset the global length and block number */
562  hdfu->wlength = 0;
563  hdfu->wblock_num = 0;
564 
565  /* Update the state machine */
567 
568  hdfu->dev_status[1] = 0;
569  hdfu->dev_status[2] = 0;
570  hdfu->dev_status[3] = 0;
571  hdfu->dev_status[4] = hdfu->dev_state;
572  return USBD_OK;
573  }
574  else if (hdfu->dev_state == DFU_STATE_MANIFEST)/* Manifestation in progress*/
575  {
576  /* Start leaving DFU mode */
577  DFU_Leave(pdev);
578  }
579 
580  return USBD_OK;
581 }
588 static uint8_t USBD_DFU_SOF (USBD_HandleTypeDef *pdev)
589 {
590 
591  return USBD_OK;
592 }
600 static uint8_t USBD_DFU_IsoINIncomplete (USBD_HandleTypeDef *pdev, uint8_t epnum)
601 {
602 
603  return USBD_OK;
604 }
612 static uint8_t USBD_DFU_IsoOutIncomplete (USBD_HandleTypeDef *pdev, uint8_t epnum)
613 {
614 
615  return USBD_OK;
616 }
624 static uint8_t USBD_DFU_DataOut (USBD_HandleTypeDef *pdev,
625  uint8_t epnum)
626 {
627 
628  return USBD_OK;
629 }
630 
637 static uint8_t *USBD_DFU_GetDeviceQualifierDesc (uint16_t *length)
638 {
639  *length = sizeof (USBD_DFU_DeviceQualifierDesc);
640  return USBD_DFU_DeviceQualifierDesc;
641 }
642 
651 #if (USBD_SUPPORT_USER_STRING == 1)
652 static uint8_t* USBD_DFU_GetUsrStringDesc (USBD_HandleTypeDef *pdev, uint8_t index , uint16_t *length)
653 {
654  static uint8_t USBD_StrDesc[255];
655  /* Check if the requested string interface is supported */
657  {
658  USBD_GetString ((uint8_t *)((USBD_DFU_MediaTypeDef *)pdev->pUserData)->pStrDesc, USBD_StrDesc, length);
659  return USBD_StrDesc;
660  }
661  /* Not supported Interface Descriptor index */
662  else
663  {
664  return NULL;
665  }
666 }
667 #endif
668 
675  USBD_DFU_MediaTypeDef *fops)
676 {
677  if(fops != NULL)
678  {
679  pdev->pUserData= fops;
680  }
681  return 0;
682 }
683 
684 /******************************************************************************
685  DFU Class requests management
686 ******************************************************************************/
694 static void DFU_Detach(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
695 {
697 
698  hdfu = (USBD_DFU_HandleTypeDef*) pdev->pClassData;
699 
702  || hdfu->dev_state == DFU_STATE_UPLOAD_IDLE )
703  {
704  /* Update the state machine */
705  hdfu->dev_state = DFU_STATE_IDLE;
706  hdfu->dev_status[0] = DFU_ERROR_NONE;
707  hdfu->dev_status[1] = 0;
708  hdfu->dev_status[2] = 0;
709  hdfu->dev_status[3] = 0; /*bwPollTimeout=0ms*/
710  hdfu->dev_status[4] = hdfu->dev_state;
711  hdfu->dev_status[5] = 0; /*iString*/
712  hdfu->wblock_num = 0;
713  hdfu->wlength = 0;
714  }
715 
716  /* Check the detach capability in the DFU functional descriptor */
717  if ((USBD_DFU_CfgDesc[12 + (9 * USBD_DFU_MAX_ITF_NUM)]) & DFU_DETACH_MASK)
718  {
719  /* Perform an Attach-Detach operation on USB bus */
720  USBD_Stop (pdev);
721  USBD_Start (pdev);
722  }
723  else
724  {
725  /* Wait for the period of time specified in Detach request */
726  USBD_Delay (req->wValue);
727  }
728 }
729 
737 static void DFU_Download(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
738 {
740 
741  hdfu = (USBD_DFU_HandleTypeDef*) pdev->pClassData;
742 
743  /* Data setup request */
744  if (req->wLength > 0)
745  {
746  if ((hdfu->dev_state == DFU_STATE_IDLE) || (hdfu->dev_state == DFU_STATE_DNLOAD_IDLE))
747  {
748  /* Update the global length and block number */
749  hdfu->wblock_num = req->wValue;
750  hdfu->wlength = req->wLength;
751 
752  /* Update the state machine */
754  hdfu->dev_status[4] = hdfu->dev_state;
755 
756  /* Prepare the reception of the buffer over EP0 */
757  USBD_CtlPrepareRx (pdev,
758  (uint8_t*)hdfu->buffer.d8,
759  hdfu->wlength);
760  }
761  /* Unsupported state */
762  else
763  {
764  /* Call the error management function (command will be nacked */
765  USBD_CtlError (pdev, req);
766  }
767  }
768  /* 0 Data DNLOAD request */
769  else
770  {
771  /* End of DNLOAD operation*/
772  if (hdfu->dev_state == DFU_STATE_DNLOAD_IDLE || hdfu->dev_state == DFU_STATE_IDLE )
773  {
776  hdfu->dev_status[1] = 0;
777  hdfu->dev_status[2] = 0;
778  hdfu->dev_status[3] = 0;
779  hdfu->dev_status[4] = hdfu->dev_state;
780  }
781  else
782  {
783  /* Call the error management function (command will be nacked */
784  USBD_CtlError (pdev, req);
785  }
786  }
787 }
788 
796 static void DFU_Upload(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
797 {
799 
800  hdfu = (USBD_DFU_HandleTypeDef*) pdev->pClassData;
801 
802  uint8_t *phaddr = NULL;
803  uint32_t addr = 0;
804 
805  /* Data setup request */
806  if (req->wLength > 0)
807  {
808  if ((hdfu->dev_state == DFU_STATE_IDLE) || (hdfu->dev_state == DFU_STATE_UPLOAD_IDLE))
809  {
810  /* Update the global length and block number */
811  hdfu->wblock_num = req->wValue;
812  hdfu->wlength = req->wLength;
813 
814  /* DFU Get Command */
815  if (hdfu->wblock_num == 0)
816  {
817  /* Update the state machine */
819 
820  hdfu->dev_status[1] = 0;
821  hdfu->dev_status[2] = 0;
822  hdfu->dev_status[3] = 0;
823  hdfu->dev_status[4] = hdfu->dev_state;
824 
825  /* Store the values of all supported commands */
826  hdfu->buffer.d8[0] = DFU_CMD_GETCOMMANDS;
828  hdfu->buffer.d8[2] = DFU_CMD_ERASE;
829 
830  /* Send the status data over EP0 */
831  USBD_CtlSendData (pdev,
832  (uint8_t *)(&(hdfu->buffer.d8[0])),
833  3);
834  }
835  else if (hdfu->wblock_num > 1)
836  {
838 
839  hdfu->dev_status[1] = 0;
840  hdfu->dev_status[2] = 0;
841  hdfu->dev_status[3] = 0;
842  hdfu->dev_status[4] = hdfu->dev_state;
843 
844  addr = ((hdfu->wblock_num - 2) * USBD_DFU_XFER_SIZE) + hdfu->data_ptr; /* Change is Accelerated*/
845 
846  /* Return the physical address where data are stored */
847  phaddr = ((USBD_DFU_MediaTypeDef *)pdev->pUserData)->Read((uint8_t *)addr, hdfu->buffer.d8, hdfu->wlength);
848 
849  /* Send the status data over EP0 */
850  USBD_CtlSendData (pdev,
851  phaddr,
852  hdfu->wlength);
853  }
854  else /* unsupported hdfu->wblock_num */
855  {
857 
858  hdfu->dev_status[1] = 0;
859  hdfu->dev_status[2] = 0;
860  hdfu->dev_status[3] = 0;
861  hdfu->dev_status[4] = hdfu->dev_state;
862 
863  /* Call the error management function (command will be nacked */
864  USBD_CtlError (pdev, req);
865  }
866  }
867  /* Unsupported state */
868  else
869  {
870  hdfu->wlength = 0;
871  hdfu->wblock_num = 0;
872  /* Call the error management function (command will be nacked */
873  USBD_CtlError (pdev, req);
874  }
875  }
876  /* No Data setup request */
877  else
878  {
879  hdfu->dev_state = DFU_STATE_IDLE;
880 
881  hdfu->dev_status[1] = 0;
882  hdfu->dev_status[2] = 0;
883  hdfu->dev_status[3] = 0;
884  hdfu->dev_status[4] = hdfu->dev_state;
885  }
886 }
887 
894 static void DFU_GetStatus(USBD_HandleTypeDef *pdev)
895 {
897 
898  hdfu = (USBD_DFU_HandleTypeDef*) pdev->pClassData;
899 
900  switch (hdfu->dev_state)
901  {
903  if (hdfu->wlength != 0)
904  {
906 
907  hdfu->dev_status[1] = 0;
908  hdfu->dev_status[2] = 0;
909  hdfu->dev_status[3] = 0;
910  hdfu->dev_status[4] = hdfu->dev_state;
911 
912  if ((hdfu->wblock_num == 0) && (hdfu->buffer.d8[0] == DFU_CMD_ERASE))
913  {
914  ((USBD_DFU_MediaTypeDef *)pdev->pUserData)->GetStatus(hdfu->data_ptr, DFU_MEDIA_ERASE, hdfu->dev_status);
915  }
916  else
917  {
918  ((USBD_DFU_MediaTypeDef *)pdev->pUserData)->GetStatus(hdfu->data_ptr, DFU_MEDIA_PROGRAM, hdfu->dev_status);
919  }
920  }
921  else /* (hdfu->wlength==0)*/
922  {
924 
925  hdfu->dev_status[1] = 0;
926  hdfu->dev_status[2] = 0;
927  hdfu->dev_status[3] = 0;
928  hdfu->dev_status[4] = hdfu->dev_state;
929  }
930  break;
931 
934  {
936 
937  hdfu->dev_status[1] = 1; /*bwPollTimeout = 1ms*/
938  hdfu->dev_status[2] = 0;
939  hdfu->dev_status[3] = 0;
940  hdfu->dev_status[4] = hdfu->dev_state;
941  }
942  else if ((hdfu->manif_state == DFU_MANIFEST_COMPLETE) && \
943  ((USBD_DFU_CfgDesc[(11 + (9 * USBD_DFU_MAX_ITF_NUM))]) & 0x04))
944  {
945  hdfu->dev_state = DFU_STATE_IDLE;
946 
947  hdfu->dev_status[1] = 0;
948  hdfu->dev_status[2] = 0;
949  hdfu->dev_status[3] = 0;
950  hdfu->dev_status[4] = hdfu->dev_state;
951  }
952  break;
953 
954  default :
955  break;
956  }
957 
958  /* Send the status data over EP0 */
959  USBD_CtlSendData (pdev,
960  (uint8_t *)(&(hdfu->dev_status[0])),
961  6);
962 }
963 
970 static void DFU_ClearStatus(USBD_HandleTypeDef *pdev)
971 {
973 
974  hdfu = (USBD_DFU_HandleTypeDef*) pdev->pClassData;
975 
976  if (hdfu->dev_state == DFU_STATE_ERROR)
977  {
978  hdfu->dev_state = DFU_STATE_IDLE;
979  hdfu->dev_status[0] = DFU_ERROR_NONE;/*bStatus*/
980  hdfu->dev_status[1] = 0;
981  hdfu->dev_status[2] = 0;
982  hdfu->dev_status[3] = 0; /*bwPollTimeout=0ms*/
983  hdfu->dev_status[4] = hdfu->dev_state;/*bState*/
984  hdfu->dev_status[5] = 0;/*iString*/
985  }
986  else
987  { /*State Error*/
988  hdfu->dev_state = DFU_STATE_ERROR;
989  hdfu->dev_status[0] = DFU_ERROR_UNKNOWN;/*bStatus*/
990  hdfu->dev_status[1] = 0;
991  hdfu->dev_status[2] = 0;
992  hdfu->dev_status[3] = 0; /*bwPollTimeout=0ms*/
993  hdfu->dev_status[4] = hdfu->dev_state;/*bState*/
994  hdfu->dev_status[5] = 0;/*iString*/
995  }
996 }
997 
1004 static void DFU_GetState(USBD_HandleTypeDef *pdev)
1005 {
1006  USBD_DFU_HandleTypeDef *hdfu;
1007 
1008  hdfu = (USBD_DFU_HandleTypeDef*) pdev->pClassData;
1009 
1010  /* Return the current state of the DFU interface */
1011  USBD_CtlSendData (pdev,
1012  &hdfu->dev_state,
1013  1);
1014 }
1015 
1022 static void DFU_Abort(USBD_HandleTypeDef *pdev)
1023 {
1024  USBD_DFU_HandleTypeDef *hdfu;
1025 
1026  hdfu = (USBD_DFU_HandleTypeDef*) pdev->pClassData;
1027 
1030  || hdfu->dev_state == DFU_STATE_UPLOAD_IDLE )
1031  {
1032  hdfu->dev_state = DFU_STATE_IDLE;
1033  hdfu->dev_status[0] = DFU_ERROR_NONE;
1034  hdfu->dev_status[1] = 0;
1035  hdfu->dev_status[2] = 0;
1036  hdfu->dev_status[3] = 0; /*bwPollTimeout=0ms*/
1037  hdfu->dev_status[4] = hdfu->dev_state;
1038  hdfu->dev_status[5] = 0; /*iString*/
1039  hdfu->wblock_num = 0;
1040  hdfu->wlength = 0;
1041  }
1042 }
1043 
1051 void DFU_Leave(USBD_HandleTypeDef *pdev)
1052 {
1053  USBD_DFU_HandleTypeDef *hdfu;
1054 
1055  hdfu = (USBD_DFU_HandleTypeDef*) pdev->pClassData;
1056 
1058 
1059  if ((USBD_DFU_CfgDesc[(11 + (9 * USBD_DFU_MAX_ITF_NUM))]) & 0x04)
1060  {
1062 
1063  hdfu->dev_status[1] = 0;
1064  hdfu->dev_status[2] = 0;
1065  hdfu->dev_status[3] = 0;
1066  hdfu->dev_status[4] = hdfu->dev_state;
1067  return;
1068  }
1069  else
1070  {
1071 
1073 
1074  hdfu->dev_status[1] = 0;
1075  hdfu->dev_status[2] = 0;
1076  hdfu->dev_status[3] = 0;
1077  hdfu->dev_status[4] = hdfu->dev_state;
1078 
1079  /* Disconnect the USB device */
1080  USBD_Stop (pdev);
1081 
1082  /* DeInitilialize the MAL(Media Access Layer) */
1083  ((USBD_DFU_MediaTypeDef *)pdev->pUserData)->DeInit();
1084 
1085  /* Generate system reset to allow jumping to the user code */
1086  NVIC_SystemReset();
1087 
1088  /* This instruction will not be reached (system reset) */
1089  for(;;);
1090  }
1091 }
1092 
1107 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Header file for the usbd_dfu.c file.
#define DFU_ERROR_UNKNOWN
Definition: usbd_dfu.h:91
#define DFU_STATE_DNLOAD_IDLE
Definition: usbd_dfu.h:67
uint8_t bmRequest
Definition: usbd_def.h:151
uint16_t wValue
Definition: usbd_def.h:153
#define DFU_CMD_SETADDRESSPOINTER
Definition: usbd_dfu.h:105
USBD_StatusTypeDef USBD_Stop(USBD_HandleTypeDef *pdev)
USBD_Stop Stop the USB Device Core.
Definition: usbd_core.c:196
uint8_t bRequest
Definition: usbd_def.h:152
#define USB_LEN_DEV_QUALIFIER_DESC
Definition: usbd_def.h:57
#define DFU_STATE_UPLOAD_IDLE
Definition: usbd_dfu.h:71
#define TRANSFER_SIZE_BYTES(size)
Definition: usbd_dfu.h:143
uint8_t d8[USBD_DFU_XFER_SIZE]
Definition: usbd_dfu.h:162
#define DFU_STATE_DNLOAD_SYNC
Definition: usbd_dfu.h:65
__IO uint32_t alt_setting
Definition: usbd_dfu.h:172
if(LCD_Lock==DISABLE)
Definition: lcd_log.c:249
#define DFU_STATE_MANIFEST_SYNC
Definition: usbd_dfu.h:68
#define USB_REQ_GET_DESCRIPTOR
Definition: usbd_def.h:87
#define USB_REQ_GET_INTERFACE
Definition: usbd_def.h:91
#define USBD_free
Definition: usbd_conf.h:74
#define DFU_STATE_DNLOAD_BUSY
Definition: usbd_dfu.h:66
#define DFU_MEDIA_PROGRAM
Definition: usbd_dfu.h:109
#define USB_DFU_CONFIG_DESC_SIZ
Definition: usbd_dfu.h:53
#define USBD_IDX_INTERFACE_STR
Definition: usbd_def.h:71
USBD_ClassTypeDef USBD_DFU
Definition: usbd_dfu.c:167
#define USB_DFU_DESC_SIZ
Definition: usbd_dfu.h:54
#define NULL
Definition: usbd_def.h:53
#define USBD_DFU_MAX_ITF_NUM
#define __ALIGN_END
#define USBD_malloc
Definition: usbd_conf.h:73
union USBD_DFU_HandleTypeDef::@34 buffer
#define USB_REQ_SET_INTERFACE
Definition: usbd_def.h:92
uint16_t wLength
Definition: usbd_def.h:155
void USBD_CtlError(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
USBD_CtlError Handle USB low level Error.
Definition: usbd_ctlreq.c:716
Definition: pbuf.h:108
#define DFU_DESCRIPTOR_TYPE
Definition: usbd_dfu.h:56
#define USB_REQ_TYPE_CLASS
Definition: usbd_def.h:74
#define DFU_CMD_ERASE
Definition: usbd_dfu.h:106
void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len)
USBD_GetString Convert Ascii string into unicode one.
Definition: usbd_ctlreq.c:732
#define DFU_STATE_MANIFEST
Definition: usbd_dfu.h:69
#define DFU_ERROR_STALLEDPKT
Definition: usbd_dfu.h:92
#define USB_DESC_TYPE_CONFIGURATION
Definition: usbd_def.h:96
#define USB_REQ_TYPE_STANDARD
Definition: usbd_def.h:73
uint8_t dev_status[DFU_STATUS_DEPTH]
Definition: usbd_dfu.h:166
__STATIC_INLINE void NVIC_SystemReset(void)
System Reset.
Definition: core_cm0.h:730
#define USBD_DFU_IF_DESC(n)
Definition: usbd_dfu.h:133
#define DFU_CMD_GETCOMMANDS
Definition: usbd_dfu.h:104
USBD_StatusTypeDef USBD_CtlPrepareRx(USBD_HandleTypeDef *pdev, uint8_t *pbuf, uint16_t len)
USBD_CtlPrepareRx receive data on the ctl pipe.
Definition: usbd_ioreq.c:135
uint8_t USBD_DFU_RegisterMedia(USBD_HandleTypeDef *pdev, USBD_DFU_MediaTypeDef *fops)
USBD_DFU_GetUsrStringDesc Manages the transfer of memory interfaces string descriptors.
Definition: usbd_dfu.c:674
#define DFU_STATE_ERROR
Definition: usbd_dfu.h:72
#define DFU_MANIFEST_IN_PROGRESS
Definition: usbd_dfu.h:98
USBD_StatusTypeDef USBD_Start(USBD_HandleTypeDef *pdev)
USBD_Start Start the USB Device Core.
Definition: usbd_core.c:181
USBD_StatusTypeDef USBD_CtlSendData(USBD_HandleTypeDef *pdev, uint8_t *buf, uint16_t len)
USBD_CtlSendData send data on the ctl pipe.
Definition: usbd_ioreq.c:95
#define DFU_STATE_MANIFEST_WAIT_RESET
Definition: usbd_dfu.h:70
#define USB_DESC_TYPE_DEVICE_QUALIFIER
Definition: usbd_def.h:100
#define DFU_STATE_IDLE
Definition: usbd_dfu.h:64
#define DFU_DETACH_MASK
Definition: usbd_dfu.h:115
#define USB_REQ_TYPE_MASK
Definition: usbd_def.h:76
#define DFU_MANIFEST_COMPLETE
Definition: usbd_dfu.h:97
#define MIN(a, b)
Definition: usbd_def.h:265
#define DFU_ERROR_NONE
Definition: usbd_dfu.h:77
#define DFU_MEDIA_ERASE
Definition: usbd_dfu.h:108