GD32F1x0: USB/GD32_USB_Device_Driver/src/usb_core.c Source File

GD32F1x0

usb_core.c
Go to the documentation of this file.
1 
11 /* Includes ------------------------------------------------------------------*/
12 #include "usb_core.h"
13 
29 uint32_t InterruptMask = 0;
30 
44 void DR_Init (void)
45 {
46  /* Just reset the CLOSE bit */
47  _SetCTLR(CTLR_SETRST);
48 
49  /* May be need wait some time(tSTARTUP) ... */
50 
51  /* Clear SETRST bit in CTLR register */
52  _SetCTLR(0);
53 
54  /* Clear all pending interrupts */
55  _SetIFR(0);
56 
57  /* Set allocation buffer address */
58  _SetBAR(BUFFER_ADDRESS);
59 
60  InterruptMask = IER_MASK;
61 
62 #ifdef LPM_ENABLED
63  /* enable L1REQ interrupt */
64  _SetLPM_CNTR(LPM_STIE);
65 #endif
66 
67  /* Enable all interrupts mask bits */
68  _SetCTLR(InterruptMask);
69 }
70 
76 void DR_StopDevice (void)
77 {
78  /* Disable all interrupts and set USB reset */
79  _SetCTLR(CTLR_SETRST);
80 
81  /* Clear all interrupt flags */
82  _SetIFR(0);
83 
84  /* Close device */
85  _SetCTLR(CTLR_SETRST | CTLR_CLOSE);
86 }
87 
108  uint8_t EpAddr,
109  uint8_t EpKind,
110  uint32_t BufAddr)
111 
112 {
113  USB_EP *ep;
114  uint8_t EpID = EpAddr & 0x7F;
115 
116  if (EpAddr >> 7)
117  {
118  /* Get an IN endpoint */
119  ep = &pudev->dev.in_ep[EpID];
120  }
121  else
122  {
123  /* Get a OUT endpoint */
124  ep = &pudev->dev.out_ep[EpID];
125  }
126 
127  if (EpKind == USB_SNG_BUFTYPE)
128  {
129  /* Endpoint is single buffer kind */
130  ep->is_dblbuf = 0;
131 
132  /* Configure the buffer address */
133  ep->bufaddress = (uint16_t)BufAddr;
134  }
135  else if(EpKind == USB_DBL_BUFTYPE)
136  {
137  /* Endpoint is double buffer kind */
138  ep->is_dblbuf = 1;
139 
140  /* Get the buffer0 and buffer1 address */
141  ep->buf0addr = BufAddr & 0xFFFF;
142  ep->buf1addr = (BufAddr & 0xFFFF0000) >> 16;
143 
144  /* Set the endpoint kind as double buffer */
145  _SetEPDoubleBuff(EpID);
146 
147  /* Set buffer address for double buffered endpoint */
148  _SetEPDblBufAddr(EpID, ep->buf0addr, ep->buf1addr);
149  }
150 }
151 
152 
170  uint8_t EpAddr,
171  uint8_t EpType,
172  uint16_t EpMps)
173 {
174  USB_EP *ep;
175  uint8_t EpID = EpAddr & 0x7F;
176 
177  /* Set the endpoint type */
178  switch (EpType)
179  {
180  case USB_EPTYPE_CONTROL:
181  _SetEPType(EpID, EP_CONTROL);
182  break;
183 
184  case USB_EPTYPE_BULK:
185  _SetEPType(EpID, EP_BULK);
186  break;
187 
188  case USB_EPTYPE_INT:
189  _SetEPType(EpID, EP_INTERRUPT);
190  break;
191 
192  case USB_EPTYPE_ISOC:
193  _SetEPType(EpID, EP_ISO);
194  break;
195  }
196 
197  if (EpAddr >> 7)
198  {
199  ep = &pudev->dev.in_ep[EpID];
200 
201  /* Initialize the transmit endpoint data toggle bit */
202  _ClearDTG_TX(EpID);
203 
204  if(ep->is_dblbuf == 0)
205  {
206  /* Set the endpoint transmit buffer address */
207  _SetEPTxAddr(EpID, ep->bufaddress);
208 
209  /* Configure the endpoint status as NAK status */
210  _SetEPTxStatus(EpID, EPTX_NAK);
211 
212  /* Control endpoint need toggle data toggle bit */
213  if(EpID == 0) _ToggleDTG_TX(EpID);
214  }
215  else
216  {
217  /* Clear another direction data toggle bit when use double buffer */
218  _ClearDTG_RX(EpID);
219 
220  /* Set the Double buffer counter */
221  _SetEPDblBuffCount(EpID, DBUF_EP_IN, 0);
222 
223  /* Configure the double buffer endpoint status */
225  _SetEPTxStatus(EpID, EPTX_VALID);
226  }
227  }
228  else
229  {
230  ep = &pudev->dev.out_ep[EpID];
231 
232  _ClearDTG_RX(EpID);
233 
234  if(ep->is_dblbuf == 0)
235  {
236  /*Set the endpoint receive buffer address */
237  _SetEPRxAddr(EpID, ep->bufaddress);
238 
239  /* Configure the endpoint status as NAK */
240  _SetEPRxStatus(EpID, EPRX_NAK);
241  }
242  else
243  {
244  _ClearDTG_TX(EpID);
245 
246  /* Toggle the SW_BUF bit(TX data toggle bit) */
247  _ToggleDTG_TX(EpID);
248 
249  /* Configure the endpoint status as DISABLED in two direction */
252  }
253  }
254 
255  /* Initialize the basic parameters */
256  ep->maxpacket = EpMps;
257  ep->is_stall = 0;
258 
259  /* Initialize the transaction level parameters */
260  ep->xfer_buf = 0;
261  ep->xfer_len = 0;
262  ep->xfer_count = 0;
263  ep->ctrl_count = 0;
264 }
265 
275 void USB_EP_DeInit (USB_CORE_HANDLE *pudev, uint8_t EpAddr)
276 {
277  USB_EP *ep;
278  uint8_t EpID = EpAddr & 0x7F;
279 
280  if (EpAddr >> 7)
281  {
282  ep = &pudev->dev.in_ep[EpID];
283 
284  _ClearDTG_TX(EpID);
285 
286  if(ep->is_dblbuf != 0)
287  {
288  /* Clear the data toggle bits of the endpoint */
289  _ClearDTG_RX(EpID);
290 
291  /* Reset value of the data toggle bits for the endpoint IN */
292  _ToggleDTG_TX(EpID);
293 
294  /* Configure the endpoint status as DISABLED */
296  }
297 
298  /* Configure the endpoint status as DISABLED */
300  }
301  else
302  {
303  ep = &pudev->dev.out_ep[EpID];
304 
305  _ClearDTG_RX(EpID);
306 
307  if(ep->is_dblbuf != 0)
308  {
309  /* Clear the data toggle bits of the endpoint */
310  _ClearDTG_TX(EpID);
311 
312  /* Reset value of the data toggle bits for the endpoint OUT */
313  _ToggleDTG_RX(EpID);
314 
315  /* Configure the endpoint status as DISABLED */
317  }
318 
319  /* Configure the endpoint status as DISABLED */
321  }
322 }
323 
324 
337  uint8_t EpAddr,
338  uint8_t *pbuf,
339  uint16_t BufLen)
340 {
341  USB_EP *ep;
342  uint8_t EpID = EpAddr & 0x7F;
343 
344  ep = &pudev->dev.out_ep[EpID];
345 
346  /* Configure the transaction level parameters */
347  ep->xfer_buf = pbuf;
348  ep->xfer_len = BufLen;
349 
350  if (ep->is_dblbuf == 0)
351  {
352  /* Set receive buffer byte count */
353  _SetEPRxCount(EpID, ep->maxpacket);
354  }
355  else
356  {
357  /* Set the double buffer receive byte count */
358  _SetEPDblBuffCount(EpID, DBUF_EP_OUT, ep->maxpacket);
359  }
360 
361  /* Enable endpoint to receive */
362  _SetEPRxStatus(EpID, EPRX_VALID);
363 }
364 
377  uint8_t EpAddr,
378  uint8_t *pbuf,
379  uint16_t BufLen)
380 {
381  USB_EP *ep;
382  __IO uint32_t len = 0;
383  uint8_t EpID = EpAddr & 0x7F;
384 
385  ep = &pudev->dev.in_ep[EpID];
386 
387  /* Configure the transaction level parameters */
388  ep->xfer_buf = pbuf;
389  ep->xfer_len = BufLen;
390  ep->xfer_count = 0;
391 
392  /* Transmit length is more than one packet */
393  if (ep->xfer_len > ep->maxpacket)
394  {
395  len = ep->maxpacket;
396  }
397  else
398  {
399  len = ep->xfer_len;
400  }
401 
402  if (ep->is_dblbuf == 0)
403  {
404  UserCopyToBuffer(ep->xfer_buf, ep->bufaddress, len);
405  _SetEPTxCount(EpID, len);
406  }
407  else
408  {
409  /* Set the Double buffer counter */
410  _SetEPDblBuffCount(EpID, DBUF_EP_IN, len);
411 
412  /* Copy the data to the double buffered endpoint buffer */
413  if (_GetEPxCSR(EpID) & EPTX_DTG)
414  {
415  UserCopyToBuffer(ep->xfer_buf, ep->buf1addr, len);
416  }
417  else
418  {
419  UserCopyToBuffer(ep->xfer_buf, ep->buf0addr, len);
420  }
421 
422  FreeUserBuffer(EpID, DBUF_EP_IN);
423  }
424 
425  /* Enable endpoint to transmit */
426  _SetEPTxStatus(EpID, EPTX_VALID);
427 }
428 
438 void USB_EP_Stall (USB_CORE_HANDLE *pudev, uint8_t EpAddr)
439 {
440  USB_EP *ep;
441  uint8_t EpID = EpAddr & 0x7F;
442 
443  if (EpAddr >> 7)
444  {
445  ep = &pudev->dev.in_ep[EpID];
446  _SetEPTxStatus(EpID, EPTX_STALL);
447  }
448  else
449  {
450  ep = &pudev->dev.out_ep[EpID];
451  _SetEPRxStatus(EpID, EPRX_STALL);
452  }
453 
454  if (EpID == 0)
455  {
456  /* Control endpoint need to be stalled in two directions */
458  }
459 
460  /* Endpoint now is stalled */
461  ep->is_stall = 1;
462 }
463 
473 void USB_EP_ClrStall (USB_CORE_HANDLE *pudev, uint8_t EpAddr)
474 {
475  USB_EP *ep;
476  uint8_t EpID = EpAddr & 0x7F;
477 
478  if (EpAddr >> 7)
479  {
480  ep = &pudev->dev.in_ep[EpID];
481  _ClearDTG_TX(EpID);
482  _SetEPTxStatus(EpID, EPTX_VALID);
483  }
484  else
485  {
486  ep = &pudev->dev.out_ep[EpID];
487  _ClearDTG_RX(EpID);
488  _SetEPRxStatus(EpID, EPRX_VALID);
489  }
490 
491  /* Endpoint now is not stalled */
492  ep->is_stall = 0;
493 }
494 
501 void USB_EP_SetAddress (USB_CORE_HANDLE *pudev, uint8_t Addr)
502 {
503  uint8_t i;
504 
505  /* Set endpoints address */
506  for (i = 0; i < EP_COUNT; i++)
507  {
508  _SetEPAddress(i, i);
509  }
510 
511  /* Set device address and enable USB module */
512  _SetAR(Addr | AR_USBEN);
513 }
514 
524 uint8_t USB_EP_GetStatus (USB_CORE_HANDLE *pudev, uint8_t EpAddr)
525 {
526  if (EpAddr >> 7)
527  {
528  return _GetEPTxStatus((EpAddr & 0x7F));
529  }
530  else
531  {
532  return _GetEPRxStatus(EpAddr);
533  }
534 }
535 
543 uint8_t USB_CtlTx (USB_CORE_HANDLE *pudev,
544  uint8_t *pbuf,
545  uint16_t Len)
546 {
547  pudev->dev.device_cur_state = USB_CTRL_DATA_IN;
548 
549  USB_EP_Tx(pudev, EP0_IN, pbuf, Len);
550 
551  return USB_OK;
552 }
553 
562  uint8_t *pbuf,
563  uint16_t Len)
564 {
565  USB_EP_Tx (pudev, EP0_IN, pbuf, Len);
566 
567  return USB_OK;
568 }
569 
577 uint8_t USB_CtlRx (USB_CORE_HANDLE *pudev,
578  uint8_t *pbuf,
579  uint16_t Len)
580 {
581  pudev->dev.device_cur_state = USB_CTRL_DATA_OUT;
582 
583  USB_EP_Rx(pudev, EP0_OUT, pbuf, Len);
584 
585  return USB_OK;
586 }
587 
596  uint8_t *pbuf,
597  uint16_t Len)
598 {
599  USB_EP_Rx(pudev, EP0_OUT, pbuf, Len);
600 
601  return USB_OK;
602 }
603 
610 {
611  pudev->dev.device_cur_state = USB_CTRL_STATUS_IN;
612 
613  USB_EP_Tx(pudev, EP0_IN, NULL, 0);
614 
615  return USB_OK;
616 }
617 
624 {
625  _Set_Status_Out(EP0);
626 
627  pudev->dev.device_cur_state = USB_CTRL_STATUS_OUT;
628 
629  USB_EP_Rx(pudev, EP0_OUT, NULL, 0);
630 
631  return USB_OK;
632 }
633 
640 uint16_t USB_GetRxCount (USB_CORE_HANDLE *pudev, uint8_t EpID)
641 {
642  return pudev->dev.out_ep[EpID].xfer_count;
643 }
644 
661 /************************ (C) COPYRIGHT 2014 GIGADEVICE *****END OF FILE****/
#define USB_EPTYPE_CONTROL
USB endpoint type.
Definition: usb_core.h:44
void DR_Init(void)
Device register initialization.
Definition: usb_core.c:44
#define _ToggleDTG_RX(EpID)
Toggle and Clear EPRX_DTG bit in the endpoint control and status register.
Definition: usb_regs.h:498
uint8_t USB_CtlTransmitStatus(USB_CORE_HANDLE *pudev)
Transmit status stage on the control pipe.
Definition: usb_core.c:609
#define EP_ISO
Definition: usb_regs.h:258
#define EP_BULK
EP_CTL[1:0] endpoint type control.
Definition: usb_regs.h:256
uint8_t USB_CtlContinueTx(USB_CORE_HANDLE *pudev, uint8_t *pbuf, uint16_t Len)
Continue transmitting data on the control pipe.
Definition: usb_core.c:561
void USB_EP_ClrStall(USB_CORE_HANDLE *pudev, uint8_t EpAddr)
Clear endpoint stalled status.
Definition: usb_core.c:473
#define _SetEPAddress(EpID, Addr)
Set and Get endpoint address.
Definition: usb_regs.h:526
#define IER_MASK
Interrupt flag mask which decide what event should be handled by application.
Definition: usb_core.h:38
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
#define EPTX_STALL
Definition: usb_regs.h:271
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 endpoint struct.
Definition: usb_core.h:101
#define EPRX_DISABLED
RX_STA[1:0] status for Rx transfer.
Definition: usb_regs.h:279
#define _Set_Status_Out(EpID)
Set and Clear directly STATUS_OUT state of endpoint.
Definition: usb_regs.h:471
void USB_EP_Init(USB_CORE_HANDLE *pudev, uint8_t EpAddr, uint8_t EpType, uint16_t EpMps)
Endpoint initialization.
Definition: usb_core.c:169
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
#define EP0_OUT
First bit is direction(0 for Rx and 1 for Tx)
Definition: usb_regs.h:108
#define EPTX_NAK
Definition: usb_regs.h:272
#define EPRX_STALL
Definition: usb_regs.h:280
uint8_t USB_CtlReceiveStatus(USB_CORE_HANDLE *pudev)
Receive status stage on the control pipe.
Definition: usb_core.c:623
#define EPRX_NAK
Definition: usb_regs.h:281
uint8_t USB_EP_GetStatus(USB_CORE_HANDLE *pudev, uint8_t EpAddr)
Get the endpoint status.
Definition: usb_core.c:524
uint16_t USB_GetRxCount(USB_CORE_HANDLE *pudev, uint8_t EpID)
Get the received data length.
Definition: usb_core.c:640
void FreeUserBuffer(uint8_t EpID, uint8_t Dir)
Free buffer used from application by toggling the SW_BUF byte.
Definition: usb_buf.c:36
#define EPTX_VALID
Definition: usb_regs.h:273
#define _SetEPRxTxStatus(EpID, StateRx, StateTx)
Rx and Tx transfer status setting (bits EPRX_STA[1:0] & EPTX_STA[1:0])
Definition: usb_regs.h:451
#define CTLR_SETRST
Definition: usb_regs.h:164
Device Driver Header file.
#define _SetEPRxStatus(EpID, State)
Rx transfer status setting and getting (bits EPRX_STA[1:0])
Definition: usb_regs.h:426
void USB_EP_Stall(USB_CORE_HANDLE *pudev, uint8_t EpAddr)
Set an endpoint to STALL status.
Definition: usb_core.c:438
void USB_EP_SetAddress(USB_CORE_HANDLE *pudev, uint8_t Addr)
Set USB device and endpoints address.
Definition: usb_core.c:501
void USB_EP_DeInit(USB_CORE_HANDLE *pudev, uint8_t EpAddr)
Configure the endpoint when it is disabled.
Definition: usb_core.c:275
#define _ToggleDTG_TX(EpID)
Toggle and Clear EPTX_DTG bit in the endpoint control and status register.
Definition: usb_regs.h:507
#define EP_CONTROL
Definition: usb_regs.h:257
#define _SetEPDoubleBuff(EpID)
Set and Clear directly double buffered feature of endpoint.
Definition: usb_regs.h:480
#define EPRX_VALID
Definition: usb_regs.h:282
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
#define CTLR_CLOSE
Definition: usb_regs.h:163
#define AR_USBEN
AR device address register bit definitions.
Definition: usb_regs.h:201
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
#define EPTX_DTG
Definition: usb_regs.h:244
#define _SetEPTxAddr(EpID, Addr)
Set Tx/Rx buffer address.
Definition: usb_regs.h:564
void UserCopyToBuffer(uint8_t *UsrBuf, uint16_t BufAddr, uint16_t Bytes)
Copy a buffer from user memory area to the allocation buffer area.
Definition: usb_buf.c:55
#define USB_SNG_BUFTYPE
USB endpoint kind.
Definition: usb_core.h:52
#define _SetEPDblBufAddr(EpID, Buf0Addr, Buf1Addr)
Sets a double buffer endpoint addresses.
Definition: usb_regs.h:651
uint8_t USB_CtlContinueRx(USB_CORE_HANDLE *pudev, uint8_t *pbuf, uint16_t Len)
Continue receive data on the contrl pipe.
Definition: usb_core.c:595
#define _SetEPTxCount(EpID, Count)
Set Tx/Rx buffer byte count.
Definition: usb_regs.h:619
#define LPM_STIE
LPM control register bit definitions.
Definition: usb_regs.h:226
#define EP_INTERRUPT
Definition: usb_regs.h:259
void DR_StopDevice(void)
Device register configure when stop device.
Definition: usb_core.c:76
#define _SetEPTxStatus(EpID, State)
Tx transfer status setting and getting (bits EPTX_STA[1:0])
Definition: usb_regs.h:407
#define EPTX_DISABLED
TX_STA[1:0] status for Tx transfer.
Definition: usb_regs.h:270
#define _SetEPType(EpID, Type)
Endpoint type setting and getting(bits EP_CTL[1:0] in endpoint control and status register) ...
Definition: usb_regs.h:391
Generated by   doxygen 1.8.10