GD32F1x0: USB/GD32_USB_Device_Library/Class/IAP/src/usbd_iap_core.c Source File

GD32F1x0

usbd_iap_core.c
Go to the documentation of this file.
1 
11 /* Includes ------------------------------------------------------------------*/
12 #include "usbd_iap_core.h"
13 #include "usbd_iap_mal.h"
14 
30 static uint8_t USBD_CUSTOMHID_Init (void *pudev, uint8_t ConfigIndex);
31 static uint8_t USBD_CUSTOMHID_DeInit (void *pudev, uint8_t ConfigIndex);
32 static uint8_t USBD_CUSTOMHID_GetClassDescriptor (void *pudev, USB_DEVICE_REQ *req);
33 static uint8_t USBD_CUSTOMHID_ClassReqHandle (void *pudev, USB_DEVICE_REQ *req);
34 static uint8_t USBD_CUSTOMHID_GetInterface (void *pudev, USB_DEVICE_REQ *req);
35 static uint8_t USBD_CUSTOMHID_SetInterface (void *pudev, USB_DEVICE_REQ *req);
36 static uint8_t USBD_CUSTOMHID_DataIn (void *pudev, uint8_t EpID);
37 static uint8_t USBD_CUSTOMHID_DataOut (void *pudev, uint8_t EpID);
38 static uint8_t* USBD_CUSTOMHID_GetCfgDesc (uint8_t Speed, uint16_t *len);
39 
40 /* DFU Requests management functions */
41 static void IAP_Req_ERASE (void *pudev);
42 static void IAP_Req_DNLOAD (void *pudev);
43 static void IAP_Req_OptionByte(void *pudev);
44 static void IAP_Req_Leave (void *pudev);
45 static void IAP_SendAddress (void *pudev);
46 
50 uint8_t Report_buf[65];
51 uint8_t OptionByte[17] = {0};
52 
53 /* State machine variables */
54 uint8_t DeviceStatus[17];
55 uint8_t BinAddress[17];
56 
57 uint8_t USBD_CUSTOMHID_Report_ID = 0;
58 uint8_t flag = 0;
59 
60 static uint32_t USBD_CUSTOMHID_AltSet = 0;
61 static uint32_t USBD_CUSTOMHID_Protocol = 0;
62 static uint32_t USBD_CUSTOMHID_IdleState = 0;
63 
64 static uint16_t TransferTimes = 0;
65 static uint16_t PageCount = 0;
66 static uint32_t FileLength = 0;
67 static uint32_t BaseAddress = APP_LOADED_ADDR;
68 
69 extern uint8_t MAL_Buffer[TRANSFER_SIZE];
70 
71 USBD_Class_cb_TypeDef USBD_CUSTOMHID_cb =
72 {
73  USBD_CUSTOMHID_Init,
74  USBD_CUSTOMHID_DeInit,
75  USBD_CUSTOMHID_GetClassDescriptor,
76  USBD_CUSTOMHID_ClassReqHandle,
77  USBD_CUSTOMHID_GetInterface,
78  USBD_CUSTOMHID_SetInterface,
79  NULL, /* EP0_TxSent */
80  NULL, /* EP0_RxReady */
81  USBD_CUSTOMHID_DataIn,
82  USBD_CUSTOMHID_DataOut,
83  NULL, /* SOF */
84  USBD_CUSTOMHID_GetCfgDesc,
85 };
86 
87 /* USB HID device Configuration Descriptor */
88 const uint8_t USBD_HID_CfgDesc[CUSTOMHID_CONFIG_DESC_SIZE] =
89 {
90  0x09, /* bLength: Configuration Descriptor size */
91  USB_DESCTYPE_CONFIGURATION, /* bDescriptorType: Configuration */
92  CUSTOMHID_CONFIG_DESC_SIZE, /* wTotalLength: configuration descriptor set total length */
93  0x00,
94  0x01, /* bNumInterfaces: 1 interface */
95  0x01, /* bConfigurationValue: configuration value */
96  0x00, /* iConfiguration: index of string descriptor describing the configuration */
97  0x80, /* bmAttributes: device attributes (bus powered and not support remote wakeup) */
98  0x32, /* bMaxPower 100 mA: this current is used for detecting Vbus */
99 
100  /************** Custom HID interface descriptor ****************/
101  0x09, /* bLength: interface descriptor size */
102  USB_DESCTYPE_INTERFACE,/* bDescriptorType: interface descriptor type */
103  0x00, /* bInterfaceNumber: number of interface */
104  0x00, /* bAlternateSetting: alternate setting */
105  0x02, /* bNumEndpoints: 2 endpoints */
106  0x03, /* bInterfaceClass: HID */
107  0x00, /* bInterfaceSubClass: 1 = BIOS boot, 0 = no boot */
108  0x00, /* nInterfaceProtocol: 0 = none, 1 = keyboard, 2 = mouse */
109  0x00, /* iInterface: index of string descriptor */
110 
111  /******************** HID descriptor ********************/
112  0x09, /* bLength: HID descriptor size */
113  CUSTOMHID_DESC_TYPE, /* bDescriptorType: HID */
114  0x11, /* bcdHID: HID class protocol(HID1.11) */
115  0x01,
116  0x00, /* bCountryCode: device country code */
117  0x01, /* bNumDescriptors: number of HID class descriptors to follow */
118  0x22, /* bDescriptorType: followed class descriptor type(report descriptor) */
119  CUSTOMHID_REPORT_DESC_SIZE, /* wDescriptorLength: total length of report descriptor */
120  0x00,
121 
122  /******************** Custom HID endpoints descriptor ***********/
123  0x07, /* bLength: Endpoint Descriptor size */
124  USB_DESCTYPE_ENDPOINT, /* bDescriptorType: endpoint descriptor type */
125  CUSTOMHID_IN_EP, /* bEndpointAddress: endpoint address (IN) */
126  0x03, /* bmAttributes: endpoint attribute(interrupt endpoint) */
127  CUSTOMHID_IN_PACKET, /* wMaxPacketSize: 2 bytes max */
128  0x00,
129  0x20, /* bInterval: Polling Interval (32 ms) */
130 
131  0x07, /* bLength: endpoint descriptor size */
132  USB_DESCTYPE_ENDPOINT, /* bDescriptorType: endpoint descriptor type */
133  CUSTOMHID_OUT_EP, /* bEndpointAddress: endpoint address (OUT) */
134  0x03, /* bmAttributes: endpoint attribute(interrupt endpoint) */
135  CUSTOMHID_OUT_PACKET, /* wMaxPacketSize: 2 Bytes max */
136  0x00,
137  0x20, /* bInterval: Polling Interval (32 ms) */
138 };
139 
140 /* USB custom HID device report descriptor */
141 const uint8_t CustomHID_ReportDescriptor[CUSTOMHID_REPORT_DESC_SIZE] =
142 {
143  0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */
144  0x09, 0x00, /* USAGE (Custom Device) */
145  0xa1, 0x01, /* COLLECTION (Application) */
146 
147  /* IAP command and data */
148  0x85, 0x01, /* REPORT_ID (0x01) */
149  0x09, 0x01, /* USAGE (IAP command) */
150  0x15, 0x00, /* LOGICAL_MINIMUM (0) */
151  0x25, 0xff, /* LOGICAL_MAXIMUM (255) */
152  0x75, 0x08, /* REPORT_SIZE (8) */
153  0x95, 0x3f, /* REPORT_COUNT (63) */
154  0x91, 0x82, /* OUTPUT (Data,Var,Abs,Vol) */
155 
156  /* Device Status and Device Option Byte */
157  0x85, 0x02, /* REPORT_ID (0x02) */
158  0x09, 0x02, /* USAGE (Status and option byte) */
159  0x15, 0x00, /* LOGICAL_MINIMUM (0) */
160  0x25, 0xff, /* LOGICAL_MAXIMUM (255) */
161  0x75, 0x08, /* REPORT_SIZE (8) */
162  0x95, 0x10, /* REPORT_COUNT (16) */
163  0x81, 0x82, /* INPUT (Data,Var,Abs,Vol) */
164 
165  0xc0 /* END_COLLECTION */
166 };
167 
182 uint8_t USBD_CUSTOMHID_Init (void *pudev, uint8_t ConfigIndex)
183 {
184  USB_EP_BufConfig(pudev, CUSTOMHID_IN_EP, USB_SNG_BUFTYPE, HID_TX_ADDRESS);
185  USB_EP_BufConfig(pudev, CUSTOMHID_OUT_EP, USB_SNG_BUFTYPE, HID_RX_ADDRESS);
186 
187  /* Initialize Tx endpoint */
188  USB_EP_Init(pudev,
189  CUSTOMHID_IN_EP,
190  USB_EPTYPE_INT,
191  CUSTOMHID_IN_PACKET);
192 
193  /* Initialize Rx endpoint */
194  USB_EP_Init(pudev,
195  CUSTOMHID_OUT_EP,
196  USB_EPTYPE_INT,
197  CUSTOMHID_OUT_PACKET);
198 
199  /* Initialize the MAL(Media Access Layer) */
200  IAP_MAL_Init();
201 
202  /* Prepare receive Data */
203  USB_EP_Rx(pudev, CUSTOMHID_OUT_EP, Report_buf, 64);
204 
205  return USBD_OK;
206 }
207 
214 uint8_t USBD_CUSTOMHID_DeInit (void *pudev, uint8_t ConfigIndex)
215 {
216  /* Deinitialize the custom HID endpoints */
217  USB_EP_DeInit (pudev, CUSTOMHID_IN_EP);
218  USB_EP_DeInit (pudev, CUSTOMHID_OUT_EP);
219 
220  /* Deinitilialize the MAL(Media Access Layer) */
221  IAP_MAL_DeInit();
222 
223  return USBD_OK;
224 }
225 
232 uint8_t USBD_CUSTOMHID_ClassReqHandle (void *pudev, USB_DEVICE_REQ *req)
233 {
234  uint8_t USBD_CUSTOMHID_Report_LENGTH = 0;
235 
236  switch (req->bRequest)
237  {
238  case GET_REPORT:
239  /* No use for this driver */
240  break;
241 
242  case GET_IDLE:
243  USB_CtlTx (pudev, (uint8_t *)&USBD_CUSTOMHID_IdleState, 1);
244  break;
245 
246  case GET_PROTOCOL:
247  USB_CtlTx (pudev, (uint8_t *)&USBD_CUSTOMHID_Protocol, 1);
248  break;
249 
250  case SET_REPORT:
251  flag = 1;
252  USBD_CUSTOMHID_Report_ID = (uint8_t)(req->wValue);
253  USBD_CUSTOMHID_Report_LENGTH = (uint8_t)(req->wLength);
254  USB_CtlRx (pudev, Report_buf, USBD_CUSTOMHID_Report_LENGTH);
255  break;
256 
257  case SET_IDLE:
258  USBD_CUSTOMHID_IdleState = (uint8_t)(req->wValue >> 8);
259  break;
260 
261  case SET_PROTOCOL:
262  USBD_CUSTOMHID_Protocol = (uint8_t)(req->wValue);
263  break;
264 
265  default:
266  USBD_EnumError (pudev, req);
267  return USBD_FAIL;
268  }
269 
270  return USBD_OK;
271 }
272 
279 uint8_t USBD_CUSTOMHID_GetClassDescriptor (void *pudev, USB_DEVICE_REQ *req)
280 {
281  uint16_t len = 0;
282  uint8_t *pbuf = NULL;
283 
284  switch(req->wValue >> 8)
285  {
286  case CUSTOMHID_REPORT_DESCTYPE:
287  len = MIN(CUSTOMHID_REPORT_DESC_SIZE, req->wLength);
288  pbuf = (uint8_t *)CustomHID_ReportDescriptor;
289  break;
290 
291  case CUSTOMHID_DESC_TYPE:
292  len = MIN(USB_CUSTOMHID_DESC_SIZE, req->wLength);
293  pbuf = (uint8_t *)USBD_HID_CfgDesc + 0x12;
294  break;
295 
296  default:
297  break;
298  }
299 
300  USB_CtlTx (pudev, pbuf, len);
301 
302  return USBD_OK;
303 }
304 
311 uint8_t USBD_CUSTOMHID_GetInterface (void *pudev, USB_DEVICE_REQ *req)
312 {
313  USB_CtlTx (pudev, (uint8_t *)&USBD_CUSTOMHID_AltSet, 1);
314 
315  return USBD_OK;
316 }
317 
324 uint8_t USBD_CUSTOMHID_SetInterface (void *pudev, USB_DEVICE_REQ *req)
325 {
326  USBD_CUSTOMHID_AltSet = (uint8_t)(req->wValue);
327 
328  return USBD_OK;
329 }
330 
339  uint8_t *report,
340  uint16_t Len)
341 {
342  if (pudev->dev.device_cur_status == USB_STATUS_CONFIGURED)
343  {
344  USB_EP_Tx (pudev, CUSTOMHID_IN_EP, report, Len);
345  }
346 
347  return USBD_OK;
348 }
349 
356 uint8_t *USBD_CUSTOMHID_GetCfgDesc (uint8_t Speed, uint16_t *len)
357 {
358  *len = sizeof (USBD_HID_CfgDesc);
359 
360  return (uint8_t*)USBD_HID_CfgDesc;
361 }
362 
369 uint8_t USBD_CUSTOMHID_DataIn (void *pudev, uint8_t EpID)
370 {
371  return USBD_OK;
372 }
373 
380 uint8_t USBD_CUSTOMHID_DataOut (void *pudev, uint8_t EpID)
381 {
382  if (EpID == 1)
383  {
384  switch (Report_buf[0])
385  {
386  case 0x01:
387  switch(Report_buf[1])
388  {
389  case IAP_DNLOAD:
390  IAP_Req_DNLOAD(pudev);
391  break;
392 
393  case IAP_ERASE:
394  IAP_Req_ERASE(pudev);
395  break;
396 
397  case IAP_OPTION_BYTE:
398  IAP_Req_OptionByte(pudev);
399  break;
400 
401  case IAP_LEAVE:
402  IAP_Req_Leave(pudev);
403  break;
404 
405  case IAP_GETBIN_ADDRESS:
406  IAP_SendAddress(pudev);
407  break;
408 
409  default:
410  USBD_EnumError(pudev, NULL);
411  return USBD_FAIL;
412  }
413  break;
414 
415  default:
416  break;
417  }
418  }
419 
420  USB_EP_Rx(pudev, CUSTOMHID_OUT_EP, Report_buf, 64);
421 
422  return USBD_OK;
423 }
424 
430 static void IAP_Req_DNLOAD(void *pudev)
431 {
432  if(TransferTimes != 0)
433  {
434  if(TransferTimes == 1)
435  {
436  IAP_MAL_Write(&Report_buf[2], BaseAddress, FileLength % TRANSFER_SIZE);
437 
438  DeviceStatus[0] = 0x02;
439  DeviceStatus[1] = 0x02;
440  USBD_CUSTOMHID_SendReport (pudev, DeviceStatus, 17);
441  }
442  else
443  {
444  IAP_MAL_Write(&Report_buf[2], BaseAddress, TRANSFER_SIZE);
445 
446  BaseAddress += TRANSFER_SIZE;
447  }
448 
449  TransferTimes --;
450  }
451 }
452 
458 static void IAP_Req_ERASE(void *pudev)
459 {
460  BaseAddress = Report_buf[2];
461  BaseAddress |= Report_buf[3] << 8;
462  BaseAddress |= Report_buf[4] << 16;
463  BaseAddress |= Report_buf[5] << 24;
464 
465  PageCount = Report_buf[6];
466 
467  FileLength = Report_buf[7];
468  FileLength |= Report_buf[8] << 8;
469  FileLength |= Report_buf[9] << 16;
470  FileLength |= Report_buf[10] << 24;
471 
472  if((FileLength % TRANSFER_SIZE) == 0)
473  {
474  TransferTimes = FileLength / TRANSFER_SIZE;
475  }
476  else
477  {
478  TransferTimes = FileLength / TRANSFER_SIZE + 1;
479  }
480 
481  IAP_MAL_Erase(BaseAddress, PageCount);
482 
483  DeviceStatus[0] = 0x02;
484  DeviceStatus[1] = 0x01;
485 
486  USB_EP_Tx(pudev, CUSTOMHID_IN_EP, DeviceStatus, 17);
487 }
488 
494 static void IAP_Req_OptionByte(void *pudev)
495 {
496  uint8_t i = 0;
497  uint32_t Address = 0x1FFFF800;
498 
499  OptionByte[0]= 0x02;
500 
501  for(i = 1; i < 17; i++)
502  {
503  OptionByte[i] = *(uint8_t *)Address;
504  Address++;
505  }
506 
507  USBD_CUSTOMHID_SendReport (&USB_Device_dev, OptionByte, 17);
508 }
509 
515 static void IAP_Req_Leave(void *pudev)
516 {
517  IAP_MAL_DeInit();
518 
519  /* Generate system reset to allow jumping to the user code */
520  NVIC_SystemReset();
521 }
522 
528 static void IAP_SendAddress(void *pudev)
529 {
530  BinAddress[0] = 0x02;
531 
532  BinAddress[1] = (uint8_t)(APP_LOADED_ADDR);
533  BinAddress[2] = (uint8_t)(APP_LOADED_ADDR >> 8);
534  BinAddress[3] = (uint8_t)(APP_LOADED_ADDR >> 16);
535  BinAddress[4] = (uint8_t)(APP_LOADED_ADDR >> 24);
536 
537  USBD_CUSTOMHID_SendReport (&USB_Device_dev, BinAddress, 17);
538 }
539 
560 /************************ (C) COPYRIGHT 2014 GIGADEVICE *****END OF FILE****/
USB device class callback type define.
Definition: usb_core.h:153
uint8_t USBD_CUSTOMHID_SendReport(USB_DEVICE_HANDLE *pudev, uint8_t *report, uint16_t Len)
Send custom HID Report.
void USB_EP_Tx(USB_CORE_HANDLE *pudev, uint8_t EpAddr, uint8_t *pbuf, uint16_t BufLen)
Endpoint prepare to transmit data.
Definition: usb_core.c:376
Custom HID device class core defines for usb iap.
uint8_t IAP_MAL_Erase(uint32_t Addr, uint32_t PageCount)
Erase a memory sector.
Definition: usbd_iap_mal.c:114
uint8_t IAP_MAL_Init(void)
Initialize the memory media on the GD32.
Definition: usbd_iap_mal.c:70
USB DFU device media access layer header file.
void USB_EP_DeInit(USB_CORE_HANDLE *pudev, uint8_t EpAddr)
Configure the endpoint when it is disabled.
Definition: usb_core.c:275
void USB_EP_Init(USB_CORE_HANDLE *pudev, uint8_t EpAddr, uint8_t EpType, uint16_t EpMps)
Endpoint initialization.
Definition: usb_core.c:169
uint8_t USB_CtlRx(USB_CORE_HANDLE *pudev, uint8_t *pbuf, uint16_t Len)
Receive data on the control pipe.
Definition: usb_core.c:577
uint8_t IAP_MAL_Write(uint8_t Data[], uint32_t Addr, uint32_t Len)
Write data to sectors of memory.
Definition: usbd_iap_mal.c:148
uint8_t USB_CtlTx(USB_CORE_HANDLE *pudev, uint8_t *pbuf, uint16_t Len)
Transmit data on the control pipe.
Definition: usb_core.c:543
uint8_t IAP_MAL_DeInit(void)
Deinitialize the memory media on the GD32.
Definition: usbd_iap_mal.c:92
#define USB_SNG_BUFTYPE
USB endpoint kind.
Definition: usb_core.h:52
void USB_EP_BufConfig(USB_CORE_HANDLE *pudev, uint8_t EpAddr, uint8_t EpKind, uint32_t BufAddr)
Configure buffer for endpoint.
Definition: usb_core.c:107
void USBD_EnumError(USB_DEVICE_HANDLE *pudev, USB_DEVICE_REQ *req)
Handle usb enumeration error event.
Definition: usbd_enum.c:755
USB standard device request struct.
Definition: usb_core.h:122
void USB_EP_Rx(USB_CORE_HANDLE *pudev, uint8_t EpAddr, uint8_t *pbuf, uint16_t BufLen)
Endpoint prepare to receive data.
Definition: usb_core.c:336
Generated by   doxygen 1.8.10