GD32F1x0: USB/GD32_USB_Device_Library/Class/cdc/src/usbd_cdc_loopback_core.c Source File

GD32F1x0

usbd_cdc_loopback_core.c
1 
11 /* Includes ------------------------------------------------------------------*/
12 #include "usbd_cdc_loopback_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_GetCfgDesc (uint8_t USBSpeed, uint16_t *len);
40 
44 static __IO uint32_t USBD_CDC_AltSet = 0;
45 
46 uint8_t USB_DATA_Buffer[USB_CDC_DATA_PACKET_SIZE];
47 uint8_t USB_CMD_Buffer[USB_CDC_CMD_PACKET_SIZE];
48 
49 extern uint8_t PacketSent;
50 extern uint8_t PacketReceive;
51 
52 static uint32_t CDCCmd = 0xFF;
53 
54 uint32_t ReceiveLength = 0;
55 
56 LINE_CODING linecoding =
57 {
58  115200, /* Baud rate */
59  0x00, /* Stop bits - 1 */
60  0x00, /* Parity - none */
61  0x08 /* Num of bits 8 */
62 };
63 
64 
65 /* USB CDC device class callbacks structure */
66 USBD_Class_cb_TypeDef USBD_CDC_cb =
67 {
68  USBD_CDC_Init,
69  USBD_CDC_DeInit,
70  USBD_CDC_GetClassDescriptor,
71  USBD_CDC_ClassReqHandle,
72  USBD_CDC_GetInterface,
73  USBD_CDC_SetInterface,
74  NULL,/* EP0_TxSent */
75  USBD_CDC_EP0_RxReady,
76  USBD_CDC_DataIn,
77  USBD_CDC_DataOut,
78  NULL,
79  USBD_CDC_GetCfgDesc,
80 };
81 
82 /* USB CDC device configuration descriptor set */
83 const uint8_t USBD_CDC_CfgDesc[USB_CDC_CONFIG_DESC_SIZE] =
84 {
85  /*Configuration Descriptor*/
86  0x09, /* bLength: configuration descriptor size */
87  USB_DESCTYPE_CONFIGURATION, /* bDescriptorType: configuration descriptor type */
88  USB_CDC_CONFIG_DESC_SIZE, /* wTotalLength: configuration descriptor set total length */
89  0x00,
90  0x02, /* bNumInterfaces: 2 interface */
91  0x01, /* bConfigurationValue: Configuration value */
92  0x00, /* iConfiguration: index of string descriptor describing the configuration */
93  0x80, /* bmAttributes: device attributes (bus powered and not support remote wakeup) */
94  0x32, /* bMaxPower 100 mA: this current is used for detectiong Vbus */
95 
96  /*Interface descriptor */
97  0x09, /* bLength: interface descriptor size */
98  USB_DESCTYPE_INTERFACE, /* bDescriptorType: interface descriptor type */
99  0x00, /* bInterfaceNumber: number of interface */
100  0x00, /* bAlternateSetting: alternate setting */
101  0x01, /* bNumEndpoints: 1 endpoint used for command IN */
102  0x02, /* bInterfaceClass: CDC class */
103  0x02, /* bInterfaceSubClass: abstract control model */
104  0x01, /* nInterfaceProtocol: common AT commands */
105  0x00, /* iInterface: index of interface string descriptor */
106 
107  /* Header functional descriptor */
108  0x05, /* bFunctionLength: the descriptor size */
109  0x24, /* bDescriptorType: CS_INTERFACE */
110  0x00, /* bDescriptorSubtype: header function descriptor */
111  0x10, /* bcdCDC: spec release number (CDC1.10) */
112  0x01,
113 
114  /* Call management functional descriptor */
115  0x05, /* bFunctionLength: the descriptor size */
116  0x24, /* bDescriptorType: CS_INTERFACE */
117  0x01, /* bDescriptorSubtype: Call Management Func Desc */
118  0x00, /* bmCapabilities: D0 is reset, D1 is ignored */
119  0x01, /* bDataInterface: 1 interface used for call management */
120 
121  /* ACM functional descriptor */
122  0x04, /* bFunctionLength: the dsecriptor length */
123  0x24, /* bDescriptorType: CS_INTERFACE */
124  0x02, /* bDescriptorSubtype: Abstract Control Management desc */
125  0x02, /* bmCapabilities: D1 */
126 
127  /* Union functional descriptor */
128  0x05, /* bFunctionLength: the descriptor length */
129  0x24, /* bDescriptorType: CS_INTERFACE */
130  0x06, /* bDescriptorSubtype: Union func desc */
131  0x00, /* bMasterInterface: Communication class interface */
132  0x01, /* bSlaveInterface0: Data Class Interface */
133 
134  /* Command endpoint descriptor */
135  0x07, /* bLength: endpoint descriptor size */
136  USB_DESCTYPE_ENDPOINT, /* bDescriptorType: endpoint descriptor type */
137  CDC_CMD_EP, /* bEndpointAddress: endpoint address(EP2_IN) */
138  0x03, /* bmAttributes: interrupt endpoint */
139  LOWBYTE(USB_CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: 8 bytes max */
140  HIGHBYTE(USB_CDC_CMD_PACKET_SIZE),
141  0x0A, /* bInterval: polling interval(10ms) */
142 
143  /* Data class interface descriptor */
144  0x09, /* bLength: interface descriptor size */
145  USB_DESCTYPE_INTERFACE, /* bDescriptorType: interface descriptor type */
146  0x01, /* bInterfaceNumber: number of interface */
147  0x00, /* bAlternateSetting: alternate setting */
148  0x02, /* bNumEndpoints: 2 endpoints used */
149  0x0A, /* bInterfaceClass: CDC class */
150  0x00, /* bInterfaceSubClass: no set */
151  0x00, /* bInterfaceProtocol: no set */
152  0x00, /* iInterface: no set */
153 
154  /* Data OUT endpoint descriptor */
155  0x07, /* bLength: endpoint descriptor size */
156  USB_DESCTYPE_ENDPOINT, /* bDescriptorType: endpoint descriptor type */
157  CDC_DATA_OUT_EP, /* bEndpointAddress: endpoint address(EP3_OUT) */
158  0x02, /* bmAttributes: bulk endpoint */
159  LOWBYTE(CDC_DATA_OUT_PACKET_SIZE), /* wMaxPacketSize: 64 bytes max */
160  HIGHBYTE(CDC_DATA_OUT_PACKET_SIZE),
161  0x00, /* bInterval: ignore for Bulk transfer */
162 
163  /* Data IN endpoint descriptor */
164  0x07, /* bLength: endpoint descriptor size */
165  USB_DESCTYPE_ENDPOINT, /* bDescriptorType: endpoint descriptor type */
166  CDC_DATA_IN_EP, /* bEndpointAddress: endpoint address(EP1_IN) */
167  0x02, /* bmAttributes: bulk endpoint */
168  LOWBYTE(CDC_DATA_IN_PACKET_SIZE), /* wMaxPacketSize: 64 bytes max */
169  HIGHBYTE(CDC_DATA_IN_PACKET_SIZE),
170  0x00 /* bInterval: ignore for bulk transfer */
171 };
172 
187 static uint8_t USBD_CDC_Init (void *pudev, uint8_t ConfigIndex)
188 {
189  USB_EP_BufConfig(pudev, CDC_DATA_IN_EP, USB_SNG_BUFTYPE, BULK_TX_ADDRESS);
190  USB_EP_BufConfig(pudev, CDC_CMD_EP, USB_SNG_BUFTYPE, INT_TX_ADDRESS);
191  USB_EP_BufConfig(pudev, CDC_DATA_OUT_EP, USB_SNG_BUFTYPE, BULK_RX_ADDRESS);
192 
193  /* Initialize the data Tx/Rx endpoint */
194  USB_EP_Init(pudev, CDC_DATA_IN_EP, USB_EPTYPE_BULK, CDC_DATA_IN_PACKET_SIZE);
195  USB_EP_Init(pudev, CDC_DATA_OUT_EP, USB_EPTYPE_BULK, CDC_DATA_OUT_PACKET_SIZE);
196 
197  /* Initialize the command Tx endpoint */
198  USB_EP_Init(pudev, CDC_CMD_EP, USB_EPTYPE_INT, USB_CDC_CMD_PACKET_SIZE);
199 
200  return USBD_OK;
201 }
202 
209 static uint8_t USBD_CDC_DeInit (void *pudev, uint8_t ConfigIndex)
210 {
211  /* Deinitialize the data Tx/Rx endpoint */
212  USB_EP_DeInit(pudev, CDC_DATA_IN_EP);
213  USB_EP_DeInit(pudev, CDC_DATA_OUT_EP);
214 
215  /* Deinitialize the command Tx endpoint */
216  USB_EP_DeInit(pudev, CDC_CMD_EP);
217 
218  return USBD_OK;
219 }
220 
227 static uint8_t USBD_CDC_GetClassDescriptor (void *pudev, USB_DEVICE_REQ *req)
228 {
229  uint16_t len = USB_CDC_DESC_SIZE;
230  uint8_t *pbuf= (uint8_t*)USBD_CDC_CfgDesc + 9;
231 
232  if((req->wValue >> 8) == CDC_DESC_TYPE)
233  {
234  len = MIN(USB_CDC_DESC_SIZE, req->wLength);
235  pbuf = (uint8_t*)USBD_CDC_CfgDesc + 9 + (9 * USBD_ITF_MAX_NUM);
236  }
237 
238  USB_CtlTx (pudev, pbuf, len);
239 
240  return USBD_OK;
241 }
242 
249 static uint8_t USBD_CDC_ClassReqHandle (void *pudev, USB_DEVICE_REQ *req)
250 {
251  switch (req->bRequest)
252  {
253  case SEND_ENCAPSULATED_COMMAND:
254  /* No operation for this driver */
255  break;
256 
257  case GET_ENCAPSULATED_RESPONSE:
258  /* No operation for this driver */
259  break;
260 
261  case SET_COMM_FEATURE:
262  /* No operation for this driver */
263  break;
264 
265  case GET_COMM_FEATURE:
266  /* No operation for this driver */
267  break;
268 
269  case CLEAR_COMM_FEATURE:
270  /* No operation for this driver */
271  break;
272 
273  case SET_LINE_CODING:
274  /* Set the value of the current command to be processed */
275  CDCCmd = req->bRequest;
276 
277  /* Enable EP0 prepare to receive command data packet */
278  USB_CtlRx (pudev, USB_CMD_Buffer, req->wLength);
279  break;
280 
281  case GET_LINE_CODING:
282  USB_CMD_Buffer[0] = (uint8_t)(linecoding.dwDTERate);
283  USB_CMD_Buffer[1] = (uint8_t)(linecoding.dwDTERate >> 8);
284  USB_CMD_Buffer[2] = (uint8_t)(linecoding.dwDTERate >> 16);
285  USB_CMD_Buffer[3] = (uint8_t)(linecoding.dwDTERate >> 24);
286  USB_CMD_Buffer[4] = linecoding.bCharFormat;
287  USB_CMD_Buffer[5] = linecoding.bParityType;
288  USB_CMD_Buffer[6] = linecoding.bDataBits;
289 
290  /* Send the request data to the host */
291  USB_CtlTx (pudev, USB_CMD_Buffer, req->wLength);
292  break;
293 
294  case SET_CONTROL_LINE_STATE:
295  /* No operation for this driver */
296  break;
297 
298  case SEND_BREAK:
299  /* No operation for this driver */
300  break;
301 
302  default:
303  break;
304  }
305 
306  return USBD_OK;
307 }
308 
315 static uint8_t USBD_CDC_GetInterface (void *pudev, USB_DEVICE_REQ *req)
316 {
317  USB_CtlTx (pudev, (uint8_t *)&USBD_CDC_AltSet, 1);
318 
319  return USBD_OK;
320 }
321 
328 static uint8_t USBD_CDC_SetInterface (void *pudev, USB_DEVICE_REQ *req)
329 {
330  if ((uint8_t)(req->wValue) < USBD_ITF_MAX_NUM)
331  {
332  USBD_CDC_AltSet = (uint8_t)(req->wValue);
333  }
334  else
335  {
336  /* Call the error management function (command will be nacked */
337  USBD_EnumError (pudev, req);
338  }
339 
340  return USBD_OK;
341 }
342 
348 static uint8_t USBD_CDC_EP0_RxReady (void *pudev)
349 {
350  if (CDCCmd != NO_CMD)
351  {
352  /* Process the command data */
353  linecoding.dwDTERate = (uint32_t)(USB_CMD_Buffer[0] |
354  (USB_CMD_Buffer[1] << 8) |
355  (USB_CMD_Buffer[2] << 16) |
356  (USB_CMD_Buffer[3] << 24));
357 
358  linecoding.bCharFormat = USB_CMD_Buffer[4];
359  linecoding.bParityType = USB_CMD_Buffer[5];
360  linecoding.bDataBits = USB_CMD_Buffer[6];
361 
362  CDCCmd = NO_CMD;
363  }
364 
365  return USBD_OK;
366 }
367 
374 static uint8_t USBD_CDC_DataIn (void *pudev, uint8_t EpID)
375 {
376  PacketSent = 1;
377 
378  return USBD_OK;
379 }
380 
387 static uint8_t USBD_CDC_DataOut (void *pudev, uint8_t EpID)
388 {
389  PacketReceive = 1;
390 
391  ReceiveLength = _GetEPRxCount(EpID);
392 
393  return USBD_OK;
394 }
395 
402 static uint8_t *USBD_CDC_GetCfgDesc (uint8_t USBSpeed, uint16_t *len)
403 {
404  *len = sizeof (USBD_CDC_CfgDesc);
405 
406  return (uint8_t*)USBD_CDC_CfgDesc;
407 }
408 
414 void USBD_CDC_SendData (void *pudev, uint32_t DataLen)
415 {
416  /* Limit the transfer data length */
417  if(DataLen <= USB_CDC_DATA_PACKET_SIZE)
418  {
419  PacketSent = 0;
420 
421  USB_EP_Tx(pudev, CDC_DATA_IN_EP, (uint8_t*)(USB_DATA_Buffer), DataLen);
422  }
423 }
424 
430 void USBD_CDC_ReceiveData(void *pudev)
431 {
432  PacketReceive = 0;
433 
434  USB_EP_Rx(pudev, CDC_DATA_OUT_EP, (uint8_t*)(USB_DATA_Buffer), CDC_DATA_OUT_PACKET_SIZE);
435 }
436 
457 /************************ (C) COPYRIGHT 2014 GIGADEVICE *****END OF FILE****/
#define CDC_CMD_EP
USB device class callback type define.
Definition: usb_core.h:153
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
void USBD_CDC_SendData(void *pudev, uint32_t DataLen)
Send the data received from the GD32 to the PC through USB.
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
Header file for the usbd_cdc_core.c file.
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 USB_CtlTx(USB_CORE_HANDLE *pudev, uint8_t *pbuf, uint16_t Len)
Transmit data on the control pipe.
Definition: usb_core.c:543
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:107
void USBD_EnumError(USB_DEVICE_HANDLE *pudev, USB_DEVICE_REQ *req)
Handle usb enumeration error event.
Definition: usbd_enum.c:755
void USBD_CDC_ReceiveData(void *pudev)
Receive the data from the PC to GD32 and send it through USB.
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