GD32F10x USB-Device: E:/USB Libraries/GD32_USB_Device_Library/Class/cdc/src/usbd_cdc_core.c Source File

GD32F103 Firmware

usbd_cdc_core.c
Go to the documentation of this file.
1 
11 /* Includes ------------------------------------------------------------------*/
12 #include "usbd_cdc_core.h"
13 #include "usbd_enum.h"
14 
30 static uint8_t USBD_CDC_Init (void *pudev, uint8_t ConfigIndex);
31 static uint8_t USBD_CDC_DeInit (void *pudev, uint8_t ConfigIndex);
32 static uint8_t USBD_CDC_GetClassDescriptor (void *pudev, USB_DEVICE_REQ *req);
33 static uint8_t USBD_CDC_ClassReqHandle (void *pudev, USB_DEVICE_REQ *req);
34 static uint8_t USBD_CDC_GetInterface (void *pudev, USB_DEVICE_REQ *req);
35 static uint8_t USBD_CDC_SetInterface (void *pudev, USB_DEVICE_REQ *req);
36 static uint8_t USBD_CDC_EP0_RxReady (void *pudev);
37 static uint8_t USBD_CDC_DataIn (void *pudev, uint8_t EpID);
38 static uint8_t USBD_CDC_DataOut (void *pudev, uint8_t EpID);
39 static uint8_t USBD_CDC_SOF (void *pudev);
40 static uint8_t* USBD_CDC_GetCfgDesc (uint8_t USBSpeed, uint16_t *len);
41 
42 static void USBD_CDC_AsynchXferHandle (void *pudev);
43 
47 extern CDC_IF_Fop_TypeDef APP_FOPS;
48 
49 uint8_t USB_Tx_State = 0;
50 
51 static __IO uint32_t USBD_CDC_AltSet = 0;
52 
53 uint8_t USB_DATA_Buffer[USB_CDC_DATA_PACKET_SIZE];
54 uint8_t USB_CMD_Buffer[USB_CDC_CMD_PACKET_SIZE];
55 uint8_t APP_DATA_Buffer[APP_RX_DATA_SIZE];
56 
57 __IO uint32_t end_packet = 0;
58 
59 uint32_t AppBufInPtr = 0;
60 uint32_t AppBufOutPtr = 0;
61 uint32_t AppRxLength = 0;
62 
63 static uint32_t CDCCmd = 0xFF;
64 static uint32_t CDCLen = 0;
65 
66 /* USB CDC device class callbacks structure */
67 USBD_Class_cb_TypeDef USBD_CDC_cb =
68 {
69  USBD_CDC_Init,
70  USBD_CDC_DeInit,
71  USBD_CDC_GetClassDescriptor,
72  USBD_CDC_ClassReqHandle,
73  USBD_CDC_GetInterface,
74  USBD_CDC_SetInterface,
75  NULL,/* EP0_TxSent */
76  USBD_CDC_EP0_RxReady,
77  USBD_CDC_DataIn,
78  USBD_CDC_DataOut,
79  USBD_CDC_SOF,
80  USBD_CDC_GetCfgDesc,
81 };
82 
83 /* USB CDC device configuration descriptor set */
84 const uint8_t USBD_CDC_CfgDesc[USB_CDC_CONFIG_DESC_SIZE] =
85 {
86  /*Configuration Descriptor*/
87  0x09, /* bLength: configuration descriptor size */
88  USB_DESCTYPE_CONFIGURATION, /* bDescriptorType: configuration descriptor type */
89  USB_CDC_CONFIG_DESC_SIZE, /* wTotalLength: configuration descriptor set total length */
90  0x00,
91  0x02, /* bNumInterfaces: 2 interface */
92  0x01, /* bConfigurationValue: Configuration value */
93  0x00, /* iConfiguration: index of string descriptor describing the configuration */
94  0x80, /* bmAttributes: device attributes (bus powered and not support remote wakeup) */
95  0x32, /* bMaxPower 100 mA: this current is used for detectiong Vbus */
96 
97  /*Interface descriptor */
98  0x09, /* bLength: interface descriptor size */
99  USB_DESCTYPE_INTERFACE, /* bDescriptorType: interface descriptor type */
100  0x00, /* bInterfaceNumber: number of interface */
101  0x00, /* bAlternateSetting: alternate setting */
102  0x01, /* bNumEndpoints: 1 endpoint used for command IN */
103  0x02, /* bInterfaceClass: CDC class */
104  0x02, /* bInterfaceSubClass: abstract control model */
105  0x01, /* nInterfaceProtocol: common AT commands */
106  0x00, /* iInterface: index of interface string descriptor */
107 
108  /* Header functional descriptor */
109  0x05, /* bFunctionLength: the descriptor size */
110  0x24, /* bDescriptorType: CS_INTERFACE */
111  0x00, /* bDescriptorSubtype: header function descriptor */
112  0x10, /* bcdCDC: spec release number (CDC1.10) */
113  0x01,
114 
115  /* Call management functional descriptor */
116  0x05, /* bFunctionLength: the descriptor size */
117  0x24, /* bDescriptorType: CS_INTERFACE */
118  0x01, /* bDescriptorSubtype: Call Management Func Desc */
119  0x00, /* bmCapabilities: D0 is reset, D1 is ignored */
120  0x01, /* bDataInterface: 1 interface used for call management */
121 
122  /* ACM functional descriptor */
123  0x04, /* bFunctionLength: the dsecriptor length */
124  0x24, /* bDescriptorType: CS_INTERFACE */
125  0x02, /* bDescriptorSubtype: Abstract Control Management desc */
126  0x02, /* bmCapabilities: D1 */
127 
128  /* Union functional descriptor */
129  0x05, /* bFunctionLength: the descriptor length */
130  0x24, /* bDescriptorType: CS_INTERFACE */
131  0x06, /* bDescriptorSubtype: Union func desc */
132  0x00, /* bMasterInterface: Communication class interface */
133  0x01, /* bSlaveInterface0: Data Class Interface */
134 
135  /* Command endpoint descriptor */
136  0x07, /* bLength: endpoint descriptor size */
137  USB_DESCTYPE_ENDPOINT, /* bDescriptorType: endpoint descriptor type */
138  CDC_CMD_EP, /* bEndpointAddress: endpoint address(EP2_IN) */
139  0x03, /* bmAttributes: interrupt endpoint */
140  LOWBYTE(USB_CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: 8 bytes max */
141  HIGHBYTE(USB_CDC_CMD_PACKET_SIZE),
142  0x0A, /* bInterval: polling interval(10ms) */
143 
144  /* Data class interface descriptor */
145  0x09, /* bLength: interface descriptor size */
146  USB_DESCTYPE_INTERFACE, /* bDescriptorType: interface descriptor type */
147  0x01, /* bInterfaceNumber: number of interface */
148  0x00, /* bAlternateSetting: alternate setting */
149  0x02, /* bNumEndpoints: 2 endpoints used */
150  0x0A, /* bInterfaceClass: CDC class */
151  0x00, /* bInterfaceSubClass: no set */
152  0x00, /* bInterfaceProtocol: no set */
153  0x00, /* iInterface: no set */
154 
155  /* Data OUT endpoint descriptor */
156  0x07, /* bLength: endpoint descriptor size */
157  USB_DESCTYPE_ENDPOINT, /* bDescriptorType: endpoint descriptor type */
158  CDC_DATA_OUT_EP, /* bEndpointAddress: endpoint address(EP3_OUT) */
159  0x02, /* bmAttributes: bulk endpoint */
160  LOWBYTE(CDC_DATA_OUT_PACKET_SIZE), /* wMaxPacketSize: 64 bytes max */
161  HIGHBYTE(CDC_DATA_OUT_PACKET_SIZE),
162  0x00, /* bInterval: ignore for Bulk transfer */
163 
164  /* Data IN endpoint descriptor */
165  0x07, /* bLength: endpoint descriptor size */
166  USB_DESCTYPE_ENDPOINT, /* bDescriptorType: endpoint descriptor type */
167  CDC_DATA_IN_EP, /* bEndpointAddress: endpoint address(EP1_IN) */
168  0x02, /* bmAttributes: bulk endpoint */
169  LOWBYTE(CDC_DATA_IN_PACKET_SIZE), /* wMaxPacketSize: 64 bytes max */
170  HIGHBYTE(CDC_DATA_IN_PACKET_SIZE),
171  0x00 /* bInterval: ignore for bulk transfer */
172 };
173 
188 static uint8_t USBD_CDC_Init (void *pudev, uint8_t ConfigIndex)
189 {
190  USB_EP_BufConfig(pudev, CDC_DATA_IN_EP, USB_SNG_BUFTYPE, BULK_TX_ADDRESS);
191  USB_EP_BufConfig(pudev, CDC_CMD_EP, USB_SNG_BUFTYPE, INT_TX_ADDRESS);
192  USB_EP_BufConfig(pudev, CDC_DATA_OUT_EP, USB_SNG_BUFTYPE, BULK_RX_ADDRESS);
193 
194  /* Initialize the data Tx/Rx endpoint */
195  USB_EP_Init(pudev, CDC_DATA_IN_EP, USB_EPTYPE_BULK, CDC_DATA_IN_PACKET_SIZE);
196  USB_EP_Init(pudev, CDC_DATA_OUT_EP, USB_EPTYPE_BULK, CDC_DATA_OUT_PACKET_SIZE);
197 
198  /* Initialize the command Tx endpoint */
199  USB_EP_Init(pudev, CDC_CMD_EP, USB_EPTYPE_INT, USB_CDC_CMD_PACKET_SIZE);
200 
201  /* Initialize the interface physical components */
202  APP_FOPS.pIf_Init(DEFAULT_CONFIG);
203 
204  /* Enable OUT endpoint prepare to receive next packet */
205  USB_EP_Rx(pudev, CDC_DATA_OUT_EP, (uint8_t*)(USB_DATA_Buffer), CDC_DATA_OUT_PACKET_SIZE);
206 
207  return USBD_OK;
208 }
209 
216 static uint8_t USBD_CDC_DeInit (void *pudev, uint8_t ConfigIndex)
217 {
218  /* Deinitialize the data Tx/Rx endpoint */
219  USB_EP_DeInit(pudev, CDC_DATA_IN_EP);
220  USB_EP_DeInit(pudev, CDC_DATA_OUT_EP);
221 
222  /* Deinitialize the command Tx endpoint */
223  USB_EP_DeInit(pudev, CDC_CMD_EP);
224 
225  /* Restore default state of the interface physical components */
226  APP_FOPS.pIf_DeInit();
227 
228  return USBD_OK;
229 }
230 
237 static uint8_t USBD_CDC_GetClassDescriptor (void *pudev, USB_DEVICE_REQ *req)
238 {
239  uint16_t len = USB_CDC_DESC_SIZE;
240  uint8_t *pbuf= (uint8_t*)USBD_CDC_CfgDesc + 9;
241 
242  if((req->wValue >> 8) == CDC_DESC_TYPE)
243  {
244  len = MIN(USB_CDC_DESC_SIZE, req->wLength);
245  pbuf = (uint8_t*)USBD_CDC_CfgDesc + 9 + (9 * USBD_ITF_MAX_NUM);
246  }
247 
248  USB_CtlTx (pudev, pbuf, len);
249 
250  return USBD_OK;
251 }
252 
259 static uint8_t USBD_CDC_ClassReqHandle (void *pudev, USB_DEVICE_REQ *req)
260 {
261  if (req->wLength)
262  {
263  if (req->bmRequestType & 0x80)
264  {
265  /* Request is from device to host */
266 
267  /* Get the request data from media access layer */
268  APP_FOPS.pIf_Ctrl(req->bRequest, USB_CMD_Buffer, req->wLength);
269 
270  /* Send the request data to the host */
271  USB_CtlTx (pudev, USB_CMD_Buffer, req->wLength);
272  }
273  else
274  {
275  /* Request is from host to device */
276 
277  /* Set the value of the current command to be processed */
278  CDCCmd = req->bRequest;
279  CDCLen = req->wLength;
280 
281  /* Enable EP0 prepare to receive command data packet */
282  USB_CtlRx (pudev, USB_CMD_Buffer, req->wLength);
283  }
284  }
285  else
286  {
287  /* The command to be handled in the media access layer */
288  APP_FOPS.pIf_Ctrl(req->bRequest, NULL, 0);
289  }
290 
291  return USBD_OK;
292 }
293 
300 static uint8_t USBD_CDC_GetInterface (void *pudev, USB_DEVICE_REQ *req)
301 {
302  USB_CtlTx (pudev, (uint8_t *)&USBD_CDC_AltSet, 1);
303 
304  return USBD_OK;
305 }
306 
313 static uint8_t USBD_CDC_SetInterface (void *pudev, USB_DEVICE_REQ *req)
314 {
315  if ((uint8_t)(req->wValue) < USBD_ITF_MAX_NUM)
316  {
317  USBD_CDC_AltSet = (uint8_t)(req->wValue);
318  }
319  else
320  {
321  /* Call the error management function (command will be nacked */
322  USBD_EnumError (pudev, req);
323  }
324 
325  return USBD_OK;
326 }
327 
333 static uint8_t USBD_CDC_EP0_RxReady (void *pudev)
334 {
335  if (CDCCmd != NO_CMD)
336  {
337  /* Process the command data */
338  APP_FOPS.pIf_Ctrl(CDCCmd, USB_CMD_Buffer, CDCLen);
339 
340  CDCCmd = NO_CMD;
341  CDCLen = 0;
342  }
343 
344  return USBD_OK;
345 }
346 
353 static uint8_t USBD_CDC_DataIn (void *pudev, uint8_t EpID)
354 {
355  uint16_t USB_Tx_length;
356 
357  if (USB_Tx_State == 1)
358  {
359  if (AppRxLength == 0)
360  {
361  if (end_packet == 1)
362  {
363  end_packet = 0;
364 
365  /*Send zero-length packet*/
366  USB_EP_Tx (pudev, CDC_DATA_IN_EP, 0, 0);
367  }
368  else
369  {
370  USB_Tx_State = 0;
371  }
372  }
373  else
374  {
375  if (AppRxLength > CDC_DATA_IN_PACKET_SIZE)
376  {
377  USB_Tx_length = CDC_DATA_IN_PACKET_SIZE;
378  }
379  else
380  {
381  USB_Tx_length = AppRxLength;
382  if (AppRxLength == CDC_DATA_IN_PACKET_SIZE) end_packet = 1;
383  }
384 
385  /* Prepare the available data buffer to be sent on IN endpoint */
386  USB_EP_Tx (pudev,
387  CDC_DATA_IN_EP,
388  &APP_DATA_Buffer[AppBufOutPtr],
389  USB_Tx_length);
390 
391  AppBufOutPtr += USB_Tx_length;
392  AppRxLength -= USB_Tx_length;
393  }
394  }
395 
396  return USBD_OK;
397 }
398 
405 static uint8_t USBD_CDC_DataOut (void *pudev, uint8_t EpID)
406 {
407  uint16_t USB_Rx_Cnt;
408 
409  /* Update the received data counter */
410  USB_Rx_Cnt = ((USB_DEVICE_HANDLE*)pudev)->dev.out_ep[EpID].xfer_count;
411 
412  /* USB received data will be immediately processed in media access layer */
413  APP_FOPS.pIf_DataRx(COM2, USB_DATA_Buffer, USB_Rx_Cnt);
414 
415  /* Enable Out endpoint prepare to receive next data packet */
416  USB_EP_Rx(pudev,
417  CDC_DATA_OUT_EP,
418  USB_DATA_Buffer,
419  CDC_DATA_OUT_PACKET_SIZE);
420 
421  return USBD_OK;
422 }
423 
429 static uint8_t USBD_CDC_SOF (void *pudev)
430 {
431  static uint8_t FrameCount = 0;
432 
433  if (FrameCount++ == CDC_IN_FRAME_INTERVAL)
434  {
435  /* Frame counter is reset */
436  FrameCount = 0;
437 
438  /* Handle asynchronous transmission between USB endpoint and Usart */
439  USBD_CDC_AsynchXferHandle(pudev);
440  }
441 
442  return USBD_OK;
443 }
444 
450 static void USBD_CDC_AsynchXferHandle (void *pudev)
451 {
452  uint16_t USB_Tx_length;
453 
454  if(USB_Tx_State != 1)
455  {
456  if(AppBufOutPtr == AppBufInPtr)
457  {
458  /* No data received by real usart */
459  return;
460  }
461 
462  if(AppBufOutPtr > AppBufInPtr) /* Need rollback */
463  {
464  AppRxLength = APP_RX_DATA_SIZE - AppBufOutPtr;
465  }
466  else
467  {
468  AppRxLength = AppBufInPtr - AppBufOutPtr;
469  }
470 
471  if (AppRxLength > CDC_DATA_IN_PACKET_SIZE)
472  {
473  USB_Tx_length = CDC_DATA_IN_PACKET_SIZE;
474  }
475  else
476  {
477  USB_Tx_length = AppRxLength;
478  if (USB_Tx_length == CDC_DATA_IN_PACKET_SIZE) end_packet = 1; /* Last packet will be sent */
479  }
480 
481  USB_EP_Tx (pudev,
482  CDC_DATA_IN_EP,
483  &APP_DATA_Buffer[AppBufOutPtr],
484  USB_Tx_length);
485 
486  /* Update Tx parameters */
487  AppBufOutPtr += USB_Tx_length;
488  AppRxLength -= USB_Tx_length;
489 
490  USB_Tx_State = 1;
491 
492  if (AppBufOutPtr == APP_RX_DATA_SIZE)
493  {
494  AppBufOutPtr = 0;
495  }
496  }
497 }
498 
505 static uint8_t *USBD_CDC_GetCfgDesc (uint8_t USBSpeed, uint16_t *len)
506 {
507  *len = sizeof (USBD_CDC_CfgDesc);
508 
509  return (uint8_t*)USBD_CDC_CfgDesc;
510 }
511 
532 /************************ (C) COPYRIGHT 2014 GIGADEVICE *****END OF FILE****/
#define CDC_CMD_EP
USB device class callback type define.
Definition: usb_core.h:148
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:346
#define CDC_IN_FRAME_INTERVAL
Header file for the usbd_cdc_core.c file.
void USB_EP_DeInit(USB_CORE_HANDLE *pudev, uint8_t EpAddr)
Configure the endpoint when it is disabled.
Definition: usb_core.c:251
void USB_EP_Init(USB_CORE_HANDLE *pudev, uint8_t EpAddr, uint8_t EpType, uint16_t EpMps)
Endpoint initialization.
Definition: usb_core.c:152
uint8_t USB_CtlRx(USB_CORE_HANDLE *pudev, uint8_t *pbuf, uint16_t Len)
Receive data on the control pipe.
Definition: usb_core.c:538
uint8_t USB_CtlTx(USB_CORE_HANDLE *pudev, uint8_t *pbuf, uint16_t Len)
Transmit data on the control pipe.
Definition: usb_core.c:504
USB enumeration function prototypes.
#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:98
void USBD_EnumError(USB_DEVICE_HANDLE *pudev, USB_DEVICE_REQ *req)
Handle usb enumeration error event.
Definition: usbd_enum.c:749
USB standard device request struct.
Definition: usb_core.h:120
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:309
#define APP_RX_DATA_SIZE
Generated on Fri Feb 6 2015 14:56:35 for GD32F10x USB-Device by   doxygen 1.8.8