GD32F1x0: USB/GD32_USB_Device_Library/Core/src/usbd_it.c Source File

GD32F1x0

usbd_it.c
1 
11 /* Includes ------------------------------------------------------------------*/
12 #include "usbd_it.h"
13 
29 static uint8_t USBINT_LPST (USB_DEVICE_HANDLE *pudev);
30 static uint8_t USBINT_HPST (USB_DEVICE_HANDLE *pudev);
31 static uint8_t USBINT_PMOU (USB_DEVICE_HANDLE *pudev);
32 static uint8_t USBINT_Error (USB_DEVICE_HANDLE *pudev);
33 static uint8_t USBINT_SOF (USB_DEVICE_HANDLE *pudev);
34 static uint8_t USBINT_ESOF (USB_DEVICE_HANDLE *pudev);
35 static uint8_t USBINT_Reset (USB_DEVICE_HANDLE *pudev);
36 static uint8_t USBINT_Suspend (USB_DEVICE_HANDLE *pudev);
37 static uint8_t USBINT_WakeUp (USB_DEVICE_HANDLE *pudev);
38 
46 extern __IO uint8_t SuspendEnabled;
47 
48 USB_INTHandler_TypeDef USB_INTHandler =
49 {
50  USBINT_HPST,
51  USBINT_LPST,
52  USBINT_PMOU,
53  USBINT_Error,
54  USBINT_Reset,
55  USBINT_SOF,
56  USBINT_ESOF,
57  USBINT_Suspend,
58  USBINT_WakeUp,
59 };
60 
61 USB_INTHandler_TypeDef *USB_INT_fops = &USB_INTHandler;
62 
76 static uint8_t USBINT_LPST (USB_DEVICE_HANDLE *pudev)
77 {
78  USB_EP *Ep = NULL;
79  uint8_t EpID = 0;
80  __IO uint16_t Ifr = 0;
81  __IO uint16_t EpValue = 0;
82 
83  /* Wait till interrupts are not pending */
84  while(((Ifr = _GetIFR()) & IFR_STIF) != 0)
85  {
86  /* Get endpoint number and the value of control and state register */
87  EpID = (uint8_t)(Ifr & IFR_EPNUM);
88  EpValue = _GetEPxCSR(EpID);
89 
90  if((Ifr & IFR_DIR) == 0)
91  {
92  /* Handle the In direction transaction */
93 
94  Ep = &(pudev->dev.in_ep[EpID]);
95 
96  if((EpValue & EPTX_ST) != 0)
97  {
98  /* Clear successful transmit interrupt flag */
99  _ClearEPTX_ST(EpID);
100 
101  /* Just handle single buffer situation */
102  Ep->xfer_count = _GetEPTxCount(EpID);
103 
104  /* Maybe mutiple packets */
105  Ep->xfer_buf += Ep->xfer_count;
106 
107  USBD_DataInStage(pudev, EpID);
108  }
109  }
110  else
111  {
112  /* Handle the OUT direction transaction */
113 
114  int count = 0;
115 
116  Ep = &(pudev->dev.out_ep[EpID]);
117 
118  if((EpValue & EPRX_ST) != 0)
119  {
120  /* Clear successful receive interrupt flag */
121  _ClearEPRX_ST(EpID);
122 
123  count = _GetEPRxCount(EpID);
124 
125  if(count != 0)
126  {
127  if((EpValue & EP_SETUP) != 0)
128  {
129  /* Handle setup packet */
130  BufferCopyToUser(&(pudev->dev.setup_packet[0]), Ep->bufaddress, count);
131 
132  USBD_SetupStage(pudev);
133 
134  return USBD_OK;
135  }
136  else
137  {
138  BufferCopyToUser(Ep->xfer_buf, Ep->bufaddress, count);
139  }
140  }
141 
142  /* Maybe mutiple packets */
143  Ep->xfer_count += count;
144  Ep->xfer_buf += count;
145  Ep->xfer_len -= count;
146 
147  if(Ep->xfer_len == 0 || count < Ep->maxpacket)
148  {
149  USBD_DataOutStage(pudev, EpID);
150  Ep->xfer_count = 0;
151  }
152  else
153  {
154  USB_EP_Rx(pudev, EpID, Ep->xfer_buf, Ep->xfer_len);
155  }
156  }
157  }/* if((temp_Ifr & IFR_DIR) == 0) else ... */
158  }/* while(...) */
159 
160  return USBD_OK;
161 }
162 
168 static uint8_t USBINT_HPST (USB_DEVICE_HANDLE *pudev)
169 {
170  USB_EP *Ep = NULL;
171  uint8_t EpID = 0;
172  __IO uint16_t Ifr = 0;
173  __IO uint16_t EpValue = 0;
174 
175  /* wait till interrupts are not pending */
176  while (((Ifr = _GetIFR()) & IFR_STIF) != 0)
177  {
178  /* Get endpoint number and the value of control and states register */
179  EpID = (uint8_t)(Ifr & IFR_EPNUM);
180  EpValue = _GetEPxCSR(EpID);
181 
182  if((Ifr & IFR_DIR) == 0)
183  {
184  /* handle the In direction transaction */
185 
186  Ep = &(pudev->dev.in_ep[EpID]);
187 
188  if((EpValue & EPTX_ST) != 0)
189  {
190  uint16_t len = 0;
191  uint16_t bufaddr = 0;
192 
193  _ClearEPTX_ST(EpID);
194 
195  if (EpValue & EPTX_DTG)
196  {
197  Ep->xfer_count = _GetEPDblBuf0Count(EpID);
198  bufaddr = Ep->buf1addr;
199  }
200  else
201  {
202  Ep->xfer_count = _GetEPDblBuf1Count(EpID);
203  bufaddr = Ep->buf0addr;
204  }
205 
206  Ep->xfer_buf += Ep->xfer_count;
207  Ep->xfer_len -= Ep->xfer_count;
208 
209  if(Ep->xfer_len > Ep->maxpacket)
210  {
211  len = Ep->maxpacket;
212  }
213  else if((0 < Ep->xfer_len) && (Ep->xfer_len <= Ep->maxpacket))
214  {
215  len = Ep->xfer_len;
216  }
217 
218  if(len > 0)
219  {
220  UserCopyToBuffer(Ep->xfer_buf, bufaddr, len);
221  FreeUserBuffer(EpID, DBUF_EP_IN);
222  }
223 
224  if(Ep->xfer_len == 0)
225  {
226  _SetEPTxStatus(EpID, EPTX_NAK);
227  pudev->dev.class_cb->DataIn(&USB_Device_dev, EpID);
228  }
229  }
230  }
231  else
232  {
233  /* Handle the Out direction transaction */
234 
235  Ep = &((&USB_Device_dev)->dev.out_ep[EpID]);
236 
237  if((EpValue & EPRX_ST) != 0)
238  {
239  int count = 0;
240 
241  _ClearEPRX_ST(EpID);
242 
243  if (EpValue & EPTX_DTG)
244  {
245  count = _GetEPDblBuf0Count(EpID);
246  if (count != 0)
247  {
248  BufferCopyToUser(Ep->xfer_buf, Ep->buf0addr, count);
249  }
250  }
251  else
252  {
253  count = _GetEPDblBuf1Count(EpID);
254  if (count != 0)
255  {
256  BufferCopyToUser(Ep->xfer_buf, Ep->buf1addr, count);
257  }
258  }
259 
260  FreeUserBuffer(EpID, DBUF_EP_OUT);
261 
262  /* Maybe multiple packets */
263  Ep->xfer_buf += count;
264  Ep->xfer_count += count;
265  Ep->xfer_len -= count;
266 
267  if((Ep->xfer_len == 0) || (count < Ep->maxpacket))
268  {
269  _SetEPRxStatus(EpID, EPRX_NAK);
270  pudev->dev.class_cb->DataOut(&USB_Device_dev, EpID);
271  Ep->xfer_count = 0;
272  }
273  }
274  }/* if((temp_Ifr & IFR_DIR) == 0) else ... */
275  }/* while(...) */
276 
277  return USBD_OK;
278 }
279 
285 static uint8_t USBINT_PMOU (USB_CORE_HANDLE *pudev)
286 {
287  return USBD_OK;
288 }
289 
295 static uint8_t USBINT_Error (USB_CORE_HANDLE *pudev)
296 {
297  return USBD_OK;
298 }
299 
305 static uint8_t USBINT_SOF (USB_CORE_HANDLE *pudev)
306 {
307  if(pudev->dev.class_cb->SOF)
308  {
309  pudev->dev.class_cb->SOF(pudev);
310  }
311  return USBD_OK;
312 }
313 
319 static uint8_t USBINT_ESOF (USB_CORE_HANDLE *pudev)
320 {
321  /* Control resume time by ESOFs */
322  USBD_Resume(RESUME_ESOF);
323 
324  return USBD_OK;
325 }
326 
332 static uint8_t USBINT_Reset (USB_CORE_HANDLE *pudev)
333 {
334 #ifdef LPM_ENABLED
335  uint16_t sLPM;
336 #endif
337 
338  USB_EP_BufConfig(pudev, 0x00, USB_SNG_BUFTYPE, EP0_RX_ADDRESS);
339  USB_EP_BufConfig(pudev, 0x80, USB_SNG_BUFTYPE, EP0_TX_ADDRESS);
340 
341  /* Initialize endpoint0 in OUT direction */
342  USB_EP_Init(pudev,
343  EP0_OUT,
346 
347  /* Initialize endpoint0 in IN direction */
348  USB_EP_Init(pudev,
349  EP0_IN,
352 
353  /* Set device address as default address 0 */
354  USB_EP_SetAddress(pudev, 0);
355 
356 #ifdef LPM_ENABLED
357  sLPM = SUBEP_VALID;
358  _SetLPM_CNTR(0x8000);
359  _SetSUBEP0R(sLPM);
360 #endif
361 
362  /* Endpoint 0 prepare to receive setup packet */
363  USB_EP_Rx(pudev, EP0_OUT, pudev->dev.setup_packet, 8);
364 
365  pudev->dev.device_cur_status = USB_STATUS_DEFAULT;
366 
367 #ifdef USE_LCD_LOG
368  /* Call back user reset function */
369  pudev->dev.user_cb->DeviceReset(pudev->dev.speed);
370 #endif
371 
372  return USBD_OK;
373 }
374 
380 static uint8_t USBINT_Suspend (USB_CORE_HANDLE *pudev)
381 {
382  /* Store the device current status */
383  pudev->dev.device_old_status = pudev->dev.device_cur_status;
384 
385  /* Set device in suspended state */
386  pudev->dev.device_cur_status = USB_STATUS_SUSPENDED;
387 
388 #ifdef USE_LCD_LOG
389  /* Call back user suspend function */
390  pudev->dev.user_cb->DeviceSuspended();
391 #endif
392 
393  /* Enter usb in suspend and mcu system in low power mode */
394  if (SuspendEnabled)
395  {
396  USBD_Suspend();
397  }
398  else
399  {
400  /* if not possible then resume after xx ms */
401  USBD_Resume(RESUME_LATER);
402  }
403 
404  return USBD_OK;
405 }
406 
412 static uint8_t USBINT_WakeUp (USB_CORE_HANDLE *pudev)
413 {
414 #ifdef USE_LCD_LOG
415  /* Call back user resume function */
416  pudev->dev.user_cb->DeviceResumed();
417 #endif
418 
419  /* Restore the old status */
420  pudev->dev.device_cur_status = pudev->dev.device_old_status;
421 
422  USBD_Resume(RESUME_EXTERNAL);
423 
424  return USBD_OK;
425 }
426 
443 /************************ (C) COPYRIGHT 2014 GIGADEVICE *****END OF FILE****/
#define EPTX_ST
Definition: usb_regs.h:243
#define USB_EPTYPE_CONTROL
USB endpoint type.
Definition: usb_core.h:44
USB device interrupt events handle function defines.
uint8_t USBD_SetupStage(USB_DEVICE_HANDLE *pudev)
Usb setup stage processing.
Definition: usbd_core.c:109
void USB_EP_SetAddress(USB_CORE_HANDLE *pudev, uint8_t Addr)
Set USB device and endpoints address.
Definition: usb_core.c:501
#define EPRX_ST
EPCSR endpoint control and status register bit definitions.
Definition: usb_regs.h:237
uint8_t USBD_DataInStage(USB_DEVICE_HANDLE *pudev, uint8_t EpID)
Data in stage processing.
Definition: usbd_core.c:197
USB endpoint struct.
Definition: usb_core.h:101
#define _ClearEPRX_ST(EpID)
Clear bit EPRX_ST / EPTX_ST in the endpoint control and status register.
Definition: usb_regs.h:489
void USBD_Resume(RESUME_STATE ResumeValue)
Resume state machine handling.
Definition: usbd_pwr.c:148
#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 IFR_EPNUM
Definition: usb_regs.h:178
void USBD_Suspend(void)
Set usb device to suspend mode.
Definition: usbd_pwr.c:110
#define IFR_DIR
Definition: usb_regs.h:177
void USB_EP_Init(USB_CORE_HANDLE *pudev, uint8_t EpAddr, uint8_t EpType, uint16_t EpMps)
Endpoint initialization.
Definition: usb_core.c:169
#define EPRX_NAK
Definition: usb_regs.h:281
#define EP_SETUP
Definition: usb_regs.h:240
#define IFR_STIF
IFR interrupt events bits definitions.
Definition: usb_regs.h:169
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 USB_EP0_MAX_SIZE
USB endpoint0 max packet size.
Definition: usb_core.h:68
uint8_t USBD_DataOutStage(USB_DEVICE_HANDLE *pudev, uint8_t EpID)
Data out stage processing.
Definition: usbd_core.c:145
#define _SetEPRxStatus(EpID, State)
Rx transfer status setting and getting (bits EPRX_STA[1:0])
Definition: usb_regs.h:426
#define SUBEP_VALID
Definition: usb_regs.h:221
#define _GetEPTxCount(EpID)
Get Tx/Rx buffer byte count.
Definition: usb_regs.h:631
#define EPTX_DTG
Definition: usb_regs.h:244
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
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 BufferCopyToUser(uint8_t *UsrBuf, uint16_t BufAddr, uint16_t Bytes)
Copy a buffer from the allocation buffer area to user memory area.
Definition: usb_buf.c:78
#define _SetEPTxStatus(EpID, State)
Tx transfer status setting and getting (bits EPTX_STA[1:0])
Definition: usb_regs.h:407
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 _GetEPDblBuf0Count(EpID)
Get buffer 0/1 byte count.
Definition: usb_regs.h:698
Generated by   doxygen 1.8.10