1 /**
2   **************************************************************************
3   * @file     usbd_core.c
4   * @brief    usb device driver
5   **************************************************************************
6   *                       Copyright notice & Disclaimer
7   *
8   * The software Board Support Package (BSP) that is made available to
9   * download from Artery official website is the copyrighted work of Artery.
10   * Artery authorizes customers to use, copy, and distribute the BSP
11   * software and its related documentation for the purpose of design and
12   * development in conjunction with Artery microcontrollers. Use of the
13   * software is governed by this copyright notice and the following disclaimer.
14   *
15   * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
16   * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
17   * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
18   * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
19   * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
20   * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
21   *
22   **************************************************************************
23   */
24 
25 #include "usb_core.h"
26 #include "usbd_core.h"
27 #include "usbd_sdr.h"
28 
29 /** @defgroup USBD_drivers_core
30   * @brief usb device drivers core
31   * @{
32   */
33 
34 /** @defgroup USBD_core_private_functions
35   * @{
36   */
37 
38 #ifdef USE_OTG_DEVICE_MODE
39 
40 /**
41   * @brief  usb core in transfer complete handler
42   * @param  udev: to the structure of usbd_core_type
43   * @param  ept_addr: endpoint number
44   * @retval none
45   */
usbd_core_in_handler(usbd_core_type * udev,uint8_t ept_addr)46 void usbd_core_in_handler(usbd_core_type *udev, uint8_t ept_addr)
47 {
48   /* get endpoint info*/
49   usb_ept_info *ept_info = &udev->ept_in[ept_addr & 0x7F];
50 
51   if(ept_addr == 0)
52   {
53     if(udev->ept0_sts == USB_EPT0_DATA_IN)
54     {
55       if(ept_info->rem0_len > ept_info->maxpacket)
56       {
57         ept_info->rem0_len -= ept_info->maxpacket;
58         usbd_ept_send(udev, 0, ept_info->trans_buf,
59                       MIN(ept_info->rem0_len, ept_info->maxpacket));
60       }
61       /* endpoint 0 */
62       else if(ept_info->last_len == ept_info->maxpacket
63         && ept_info->ept0_slen >= ept_info->maxpacket
64         && ept_info->ept0_slen < udev->ept0_wlength)
65       {
66         ept_info->last_len = 0;
67         usbd_ept_send(udev, 0, 0, 0);
68         usbd_ept_recv(udev, ept_addr, 0, 0);
69       }
70       else
71       {
72 
73         if(udev->class_handler->ept0_tx_handler != 0 &&
74             udev->conn_state == USB_CONN_STATE_CONFIGURED)
75         {
76           udev->class_handler->ept0_tx_handler(udev);
77         }
78         usbd_ctrl_recv_status(udev);
79 
80       }
81     }
82   }
83   else if(udev->class_handler->in_handler != 0 &&
84           udev->conn_state == USB_CONN_STATE_CONFIGURED)
85   {
86     /* other user define endpoint */
87     udev->class_handler->in_handler(udev, ept_addr);
88   }
89 }
90 
91 /**
92   * @brief  usb core out transfer complete handler
93   * @param  udev: to the structure of usbd_core_type
94   * @param  ept_addr: endpoint number
95   * @retval none
96   */
usbd_core_out_handler(usbd_core_type * udev,uint8_t ept_addr)97 void usbd_core_out_handler(usbd_core_type *udev, uint8_t ept_addr)
98 {
99    /* get endpoint info*/
100   usb_ept_info *ept_info = &udev->ept_out[ept_addr & 0x7F];
101 
102   if(ept_addr == 0)
103   {
104     /* endpoint 0 */
105     if(udev->ept0_sts == USB_EPT0_DATA_OUT)
106     {
107       if(ept_info->rem0_len > ept_info->maxpacket)
108       {
109         ept_info->rem0_len -= ept_info->maxpacket;
110         usbd_ept_recv(udev, ept_addr, ept_info->trans_buf,
111                       MIN(ept_info->rem0_len, ept_info->maxpacket));
112       }
113       else
114       {
115           if(udev->class_handler->ept0_rx_handler != 0)
116           {
117             udev->class_handler->ept0_rx_handler(udev);
118           }
119           usbd_ctrl_send_status(udev);
120       }
121     }
122   }
123   else if(udev->class_handler->out_handler != 0 &&
124           udev->conn_state == USB_CONN_STATE_CONFIGURED)
125   {
126     /* other user define endpoint */
127     udev->class_handler->out_handler(udev, ept_addr);
128   }
129 }
130 
131 /**
132   * @brief  usb core setup transfer complete handler
133   * @param  udev: to the structure of usbd_core_type
134   * @param  ept_addr: endpoint number
135   * @retval none
136   */
usbd_core_setup_handler(usbd_core_type * udev,uint8_t ept_num)137 void usbd_core_setup_handler(usbd_core_type *udev, uint8_t ept_num)
138 {
139   /* setup parse */
140   usbd_setup_request_parse(&udev->setup, (uint8_t *)udev->setup_buffer);
141 
142   /* set ept0 status */
143   udev->ept0_sts = USB_EPT0_SETUP;
144   udev->ept0_wlength = udev->setup.wLength;
145 
146   switch(udev->setup.bmRequestType & USB_REQ_RECIPIENT_MASK)
147   {
148     case USB_REQ_RECIPIENT_DEVICE:
149       /* recipient device request */
150       usbd_device_request(udev);
151       break;
152     case USB_REQ_RECIPIENT_INTERFACE:
153       /* recipient interface request */
154       usbd_interface_request(udev);
155       break;
156     case USB_REQ_RECIPIENT_ENDPOINT:
157       /* recipient endpoint request */
158       usbd_endpoint_request(udev);
159       break;
160     default:
161       break;
162   }
163 }
164 
165 /**
166   * @brief  usb control endpoint send data
167   * @param  udev: to the structure of usbd_core_type
168   * @param  ept_addr: endpoint number
169   * @param  buffer: send data buffer
170   * @param  len: send data length
171   * @retval none
172   */
usbd_ctrl_send(usbd_core_type * udev,uint8_t * buffer,uint16_t len)173 void usbd_ctrl_send(usbd_core_type *udev, uint8_t *buffer, uint16_t len)
174 {
175   usb_ept_info *ept_info = &udev->ept_in[0];
176 
177   ept_info->ept0_slen = len;
178   ept_info->rem0_len = len;
179   udev->ept0_sts = USB_EPT0_DATA_IN;
180 
181   usbd_ept_send(udev, 0, buffer, len);
182 }
183 
184 /**
185   * @brief  usb control endpoint recv data
186   * @param  udev: to the structure of usbd_core_type
187   * @param  ept_addr: endpoint number
188   * @param  buffer: recv data buffer
189   * @param  len: recv data length
190   * @retval none
191   */
usbd_ctrl_recv(usbd_core_type * udev,uint8_t * buffer,uint16_t len)192 void usbd_ctrl_recv(usbd_core_type *udev, uint8_t *buffer, uint16_t len)
193 {
194   usb_ept_info *ept_info = &udev->ept_out[0];
195 
196   ept_info->ept0_slen = len;
197   ept_info->rem0_len = len;
198   udev->ept0_sts = USB_EPT0_DATA_OUT;
199 
200   usbd_ept_recv(udev, 0, buffer, len);
201 }
202 
203 /**
204   * @brief  usb control endpoint send in status
205   * @param  udev: to the structure of usbd_core_type
206   * @retval none
207   */
usbd_ctrl_send_status(usbd_core_type * udev)208 void usbd_ctrl_send_status(usbd_core_type *udev)
209 {
210   udev->ept0_sts = USB_EPT0_STATUS_IN;
211 
212   usbd_ept_send(udev, 0, 0, 0);
213 }
214 
215 /**
216   * @brief  usb control endpoint send out status
217   * @param  udev: to the structure of usbd_core_type
218   * @retval none
219   */
usbd_ctrl_recv_status(usbd_core_type * udev)220 void usbd_ctrl_recv_status(usbd_core_type *udev)
221 {
222   udev->ept0_sts = USB_EPT0_STATUS_OUT;
223 
224   usbd_ept_recv(udev, 0, 0, 0);
225 }
226 
227 /**
228   * @brief  clear endpoint stall
229   * @param  udev: to the structure of usbd_core_type
230   * @param  ept_addr: endpoint number
231   * @retval none
232   */
usbd_clear_stall(usbd_core_type * udev,uint8_t ept_addr)233 void usbd_clear_stall(usbd_core_type *udev, uint8_t ept_addr)
234 {
235   usb_ept_info *ept_info;
236   usb_reg_type *usbx = udev->usb_reg;
237 
238   if(ept_addr & 0x80)
239   {
240     /* in endpoint */
241     ept_info = &udev->ept_in[ept_addr & 0x7F];
242   }
243   else
244   {
245     /* out endpoint */
246     ept_info = &udev->ept_out[ept_addr & 0x7F];
247   }
248   usb_ept_clear_stall(usbx, ept_info);
249   ept_info->stall = 0;
250 }
251 
252 /**
253   * @brief  usb set endpoint to stall status
254   * @param  udev: to the structure of usbd_core_type
255   * @param  ept_addr: endpoint number
256   * @retval none
257   */
usbd_set_stall(usbd_core_type * udev,uint8_t ept_addr)258 void usbd_set_stall(usbd_core_type *udev, uint8_t ept_addr)
259 {
260   usb_ept_info *ept_info;
261   usb_reg_type *usbx = udev->usb_reg;
262 
263   if(ept_addr & 0x80)
264   {
265     /* in endpoint */
266     ept_info = &udev->ept_in[ept_addr & 0x7F];
267   }
268   else
269   {
270     /* out endpoint */
271     ept_info = &udev->ept_out[ept_addr & 0x7F];
272   }
273   usb_ept_stall(usbx, ept_info);
274 
275   ept_info->stall = 1;
276 }
277 
278 /**
279   * @brief  un-support device request
280   * @param  udev: to the structure of usbd_core_type
281   * @retval none
282   */
usbd_ctrl_unsupport(usbd_core_type * udev)283 void usbd_ctrl_unsupport(usbd_core_type *udev)
284 {
285   /* return stall status */
286   usbd_set_stall(udev, 0x00);
287   usbd_set_stall(udev, 0x80);
288 }
289 
290 #ifdef OTG_USE_DMA
291 /**
292   * @brief  endpoint 0 out dma set
293   * @param  udev: to the structure of usbd_core_type
294   * @retval none
295   */
usbd_ept0_out_dma_set(usbd_core_type * udev)296 void usbd_ept0_out_dma_set(usbd_core_type *udev)
297 {
298   otg_eptout_type *usb_outept = USB_OUTEPT(udev->usb_reg, 0);
299 
300   if(usb_outept->doepctl_bit.eptena == TRUE)
301   {
302     return;
303   }
304   USB_OUTEPT(udev->usb_reg, 0)->doepdma = (uint32_t)udev->setup_buffer;
305   USB_OUTEPT(udev->usb_reg, 0)->doepctl_bit.usbacept = TRUE;
306   USB_OUTEPT(udev->usb_reg, 0)->doepctl_bit.eptena = TRUE;
307 }
308 #endif
309 /**
310   * @brief  get endpoint receive data length
311   * @param  udev: to the structure of usbd_core_type
312   * @param  ept_addr: endpoint number
313   * @retval data receive len
314   */
usbd_get_recv_len(usbd_core_type * udev,uint8_t ept_addr)315 uint32_t usbd_get_recv_len(usbd_core_type *udev, uint8_t ept_addr)
316 {
317   usb_ept_info *ept = &udev->ept_out[ept_addr & 0x7F];
318   return ept->trans_len;
319 }
320 
321 /**
322   * @brief  usb open endpoint
323   * @param  udev: to the structure of usbd_core_type
324   * @param  ept_addr: endpoint number
325   * @param  ept_type: endpoint type
326   * @param  maxpacket: endpoint support max buffer size
327   * @retval none
328   */
usbd_ept_open(usbd_core_type * udev,uint8_t ept_addr,uint8_t ept_type,uint16_t maxpacket)329 void usbd_ept_open(usbd_core_type *udev, uint8_t ept_addr, uint8_t ept_type, uint16_t maxpacket)
330 {
331   usb_reg_type *usbx = udev->usb_reg;
332   usb_ept_info *ept_info;
333 
334   if((ept_addr & 0x80) == 0)
335   {
336     /* out endpoint info */
337     ept_info = &udev->ept_out[ept_addr & 0x7F];
338     ept_info->inout = EPT_DIR_OUT;
339   }
340   else
341   {
342     /* in endpoint info */
343     ept_info = &udev->ept_in[ept_addr & 0x7F];
344     ept_info->inout = EPT_DIR_IN;
345   }
346 
347   /* set endpoint maxpacket and type */
348   ept_info->maxpacket = maxpacket;
349   ept_info->trans_type = ept_type;
350 
351   /* open endpoint */
352   usb_ept_open(usbx, ept_info);
353 #ifdef USB_SUPPORT_EPT1_INTERRUPT
354     if(((ept_addr & 0x7F) == 1) && (udev->speed == USB_HIGH_SPEED))
355     {
356       if(ept_info->inout == EPT_DIR_IN)
357       {
358         OTG_DEVICE(udev->usb_reg)->deachintmsk_bit.inep1intmsk = TRUE;
359         OTG_DEVICE(usbx)->daintmsk &= ~(1 << ept_info->eptn);
360       }
361       else
362       {
363         OTG_DEVICE(udev->usb_reg)->deachintmsk_bit.outep1intmsk = TRUE;
364         OTG_DEVICE(usbx)->daintmsk &= ~((1 << ept_info->eptn) << 16);
365       }
366     }
367  #endif
368 }
369 
370 /**
371   * @brief  usb close endpoint
372   * @param  udev: to the structure of usbd_core_type
373   * @param  ept_addr: endpoint number
374   * @retval none
375   */
usbd_ept_close(usbd_core_type * udev,uint8_t ept_addr)376 void usbd_ept_close(usbd_core_type *udev, uint8_t ept_addr)
377 {
378   usb_ept_info *ept_info;
379   if(ept_addr & 0x80)
380   {
381     /* in endpoint */
382     ept_info = &udev->ept_in[ept_addr & 0x7F];
383   }
384   else
385   {
386     /* out endpoint */
387     ept_info = &udev->ept_out[ept_addr & 0x7F];
388   }
389 
390   /* close endpoint */
391   usb_ept_close(udev->usb_reg, ept_info);
392 }
393 
394 /**
395   * @brief  usb device connect to host
396   * @param  udev: to the structure of usbd_core_type
397   * @retval none
398   */
usbd_connect(usbd_core_type * udev)399 void usbd_connect(usbd_core_type *udev)
400 {
401   usb_connect(udev->usb_reg);
402 }
403 
404 /**
405   * @brief  usb device disconnect to host
406   * @param  udev: to the structure of usbd_core_type
407   * @retval none
408   */
usbd_disconnect(usbd_core_type * udev)409 void usbd_disconnect(usbd_core_type *udev)
410 {
411   usb_disconnect(udev->usb_reg);
412 }
413 
414 /**
415   * @brief  usb device set device address.
416   * @param  udev: to the structure of usbd_core_type
417   * @param  address: host assignment address
418   * @retval none
419   */
usbd_set_device_addr(usbd_core_type * udev,uint8_t address)420 void usbd_set_device_addr(usbd_core_type *udev, uint8_t address)
421 {
422   usb_set_address(udev->usb_reg, address);
423 }
424 
425 /**
426   * @brief  usb endpoint structure initialization
427   * @param  udev: to the structure of usbd_core_type
428   * @retval none
429   */
usb_ept_default_init(usbd_core_type * udev)430 void usb_ept_default_init(usbd_core_type *udev)
431 {
432   uint8_t i_index = 0;
433   /* init in endpoint info structure */
434   for(i_index = 0; i_index < USB_EPT_MAX_NUM; i_index ++)
435   {
436     udev->ept_in[i_index].eptn        = i_index;
437     udev->ept_in[i_index].ept_address = i_index;
438     udev->ept_in[i_index].inout         = EPT_DIR_IN;
439     udev->ept_in[i_index].maxpacket   = 0;
440     udev->ept_in[i_index].trans_buf   = 0;
441     udev->ept_in[i_index].total_len   = 0;
442   }
443 
444   /* init out endpoint info structure */
445   for(i_index = 0; i_index < USB_EPT_MAX_NUM; i_index ++)
446   {
447     udev->ept_out[i_index].eptn        = i_index;
448     udev->ept_out[i_index].ept_address = i_index;
449     udev->ept_out[i_index].inout       = EPT_DIR_OUT;
450     udev->ept_out[i_index].maxpacket   = 0;
451     udev->ept_out[i_index].trans_buf   = 0;
452     udev->ept_out[i_index].total_len   = 0;
453   }
454 }
455 
456 /**
457   * @brief  endpoint send data
458   * @param  udev: to the structure of usbd_core_type
459   * @param  ept_addr: endpoint number
460   * @param  buffer: send data buffer
461   * @param  len: send data length
462   * @retval none
463   */
usbd_ept_send(usbd_core_type * udev,uint8_t ept_addr,uint8_t * buffer,uint16_t len)464 void usbd_ept_send(usbd_core_type *udev, uint8_t ept_addr, uint8_t *buffer, uint16_t len)
465 {
466   /* get endpoint info struct and register */
467   usb_reg_type *usbx = udev->usb_reg;
468   usb_ept_info *ept_info = &udev->ept_in[ept_addr & 0x7F];
469   otg_eptin_type *ept_in = USB_INEPT(usbx, ept_info->eptn);
470   otg_device_type *dev = OTG_DEVICE(usbx);
471   uint32_t pktcnt;
472 
473   /* set send data buffer and length */
474   ept_info->trans_buf = buffer;
475   ept_info->total_len = len;
476   ept_info->trans_len = 0;
477 
478   /* transfer data len is zero */
479   if(ept_info->total_len == 0)
480   {
481     ept_in->dieptsiz_bit.pktcnt = 1;
482     ept_in->dieptsiz_bit.xfersize = 0;
483   }
484   else
485   {
486     if((ept_addr & 0x7F) == 0) // endpoint 0
487     {
488       /* endpoint 0 */
489       if(ept_info->total_len > ept_info->maxpacket)
490       {
491         ept_info->total_len = ept_info->maxpacket;
492       }
493 
494       /* set transfer size  */
495       ept_in->dieptsiz_bit.xfersize = ept_info->total_len;
496 
497       /* set packet count */
498       ept_in->dieptsiz_bit.pktcnt = 1;
499 
500       ept_info->last_len = ept_info->total_len;
501     }
502     else
503     {
504       /* other endpoint */
505 
506       /* packet count */
507       pktcnt = (ept_info->total_len + ept_info->maxpacket - 1) / ept_info->maxpacket;
508 
509       /* set transfer size  */
510       ept_in->dieptsiz_bit.xfersize = ept_info->total_len;
511 
512       /* set packet count */
513       ept_in->dieptsiz_bit.pktcnt = pktcnt;
514 
515       if(ept_info->trans_type == EPT_ISO_TYPE)
516       {
517         ept_in->dieptsiz_bit.mc = 1;
518       }
519     }
520   }
521 #ifdef OTG_USE_DMA
522   if(udev->dma_en == TRUE)
523   {
524     if(ept_info->trans_buf != 0)
525     {
526       ept_in->diepdma = (uint32_t)ept_info->trans_buf;
527     }
528       /* clear endpoint nak */
529     ept_in->diepctl_bit.cnak = TRUE;
530 
531     /* endpoint enable */
532     ept_in->diepctl_bit.eptena = TRUE;
533   }
534 
535   else
536 #endif
537   {
538     if(ept_info->trans_type == EPT_ISO_TYPE)
539     {
540       if((dev->dsts_bit.soffn & 0x1) == 0)
541       {
542         ept_in->diepctl_bit.setd1pid = TRUE;
543       }
544       else
545       {
546         ept_in->diepctl_bit.setd0pid = TRUE;
547       }
548     }
549 
550     /* clear endpoint nak */
551     ept_in->diepctl_bit.cnak = TRUE;
552 
553     /* endpoint enable */
554     ept_in->diepctl_bit.eptena = TRUE;
555 
556     if(ept_info->trans_type == EPT_ISO_TYPE)
557     {
558       /* write data to fifo */
559       usb_write_packet(usbx, ept_info->trans_buf, ept_info->eptn, ept_info->total_len);
560     }
561     if(ept_info->trans_type != EPT_ISO_TYPE)
562     {
563       if(ept_info->total_len > 0)
564       {
565         /* set in endpoint tx fifo empty interrupt mask */
566         dev->diepempmsk |= 1 << ept_info->eptn;
567       }
568     }
569   }
570 }
571 
572 /**
573   * @brief  endpoint receive data
574   * @param  udev: to the structure of usbd_core_type
575   * @param  ept_addr: endpoint number
576   * @param  buffer: receive data buffer
577   * @param  len: receive data length
578   * @retval none
579   */
usbd_ept_recv(usbd_core_type * udev,uint8_t ept_addr,uint8_t * buffer,uint16_t len)580 void usbd_ept_recv(usbd_core_type *udev, uint8_t ept_addr, uint8_t *buffer, uint16_t len)
581 {
582   /* get endpoint info struct and register */
583   usb_reg_type *usbx = udev->usb_reg;
584   usb_ept_info *ept_info = &udev->ept_out[ept_addr & 0x7F];
585   otg_eptout_type *ept_out = USB_OUTEPT(usbx, ept_info->eptn);
586   otg_device_type *dev = OTG_DEVICE(usbx);
587   uint32_t pktcnt;
588 
589    /* set receive data buffer and length */
590   ept_info->trans_buf = buffer;
591   ept_info->total_len = len;
592   ept_info->trans_len = 0;
593 
594   if((ept_addr & 0x7F) == 0 && len > 0)
595   {
596     /* endpoint 0 */
597     ept_info->total_len = ept_info->maxpacket;
598   }
599 
600   if(ept_info->total_len == 0 || ((ept_addr & 0x7F) == 0))
601   {
602     /* set transfer size  */
603     ept_out->doeptsiz_bit.xfersize = ept_info->maxpacket;
604 
605     /* set packet count */
606     ept_out->doeptsiz_bit.pktcnt = 1;
607   }
608   else
609   {
610     pktcnt = (ept_info->total_len + ept_info->maxpacket - 1) / ept_info->maxpacket;
611 
612     /* set transfer size  */
613     ept_out->doeptsiz_bit.xfersize = ept_info->maxpacket * pktcnt;
614 
615     /* set packet count */
616     ept_out->doeptsiz_bit.pktcnt = pktcnt;
617   }
618 #ifdef OTG_USE_DMA
619   if(udev->dma_en == TRUE && buffer != 0)
620   {
621     ept_out->doepdma = (uint32_t)(ept_info->trans_buf);
622   }
623 #endif
624   if(ept_info->trans_type == EPT_ISO_TYPE)
625   {
626    if((dev->dsts_bit.soffn & 0x01) == 0)
627    {
628      ept_out->doepctl_bit.setd1pid = TRUE;
629    }
630    else
631    {
632      ept_out->doepctl_bit.setd0pid = TRUE;
633    }
634   }
635 
636   /* clear endpoint nak */
637   ept_out->doepctl_bit.cnak = TRUE;
638 
639   /* endpoint enable */
640   ept_out->doepctl_bit.eptena = TRUE;
641 }
642 
643 /**
644   * @brief  get usb connect state
645   * @param  udev: to the structure of usbd_core_type
646   * @retval usb connect state
647   */
usbd_connect_state_get(usbd_core_type * udev)648 usbd_conn_state usbd_connect_state_get(usbd_core_type *udev)
649 {
650   return udev->conn_state;
651 }
652 
653 /**
654   * @brief  usb device remote wakeup
655   * @param  udev: to the structure of usbd_core_type
656   * @retval none
657   */
usbd_remote_wakeup(usbd_core_type * udev)658 void usbd_remote_wakeup(usbd_core_type *udev)
659 {
660   /* check device is in suspend mode */
661   if(usb_suspend_status_get(udev->usb_reg) == 1)
662   {
663     /* set connect state */
664     udev->conn_state = udev->old_conn_state;
665 
666     /* open phy clock */
667     usb_open_phy_clk(udev->usb_reg);
668 
669     /* set remote wakeup */
670     usb_remote_wkup_set(udev->usb_reg);
671 
672     /* delay 10 ms */
673     rt_thread_mdelay(10);
674 
675     /* clear remote wakup */
676     usb_remote_wkup_clear(udev->usb_reg);
677   }
678 }
679 
680 /**
681   * @brief  usb device enter suspend mode
682   * @param  udev: to the structure of usbd_core_type
683   * @retval none
684   */
usbd_enter_suspend(usbd_core_type * udev)685 void usbd_enter_suspend(usbd_core_type *udev)
686 {
687   /* check device is in suspend mode */
688   if(usb_suspend_status_get(udev->usb_reg) == 1)
689   {
690     /* stop phy clk */
691     usb_stop_phy_clk(udev->usb_reg);
692   }
693 }
694 
695 /**
696   * @brief  usb device flush in endpoint fifo
697   * @param  udev: to the structure of usbd_core_type
698   * @param  ept_num: endpoint number
699   * @retval none
700   */
usbd_flush_tx_fifo(usbd_core_type * udev,uint8_t ept_num)701 void usbd_flush_tx_fifo(usbd_core_type *udev, uint8_t ept_num)
702 {
703   /* flush endpoint tx fifo */
704   usb_flush_tx_fifo(udev->usb_reg, ept_num & 0x1F);
705 }
706 
707 /**
708   * @brief  usb device endpoint fifo alloc
709   * @param  udev: to the structure of usbd_core_type
710   * @retval none
711   */
usbd_fifo_alloc(usbd_core_type * udev)712 void usbd_fifo_alloc(usbd_core_type *udev)
713 {
714   usb_reg_type *usbx = udev->usb_reg;
715 
716   if(usbx == OTG1_GLOBAL)
717   {
718     /* set receive fifo size */
719     usb_set_rx_fifo(usbx, USBD_RX_SIZE);
720 
721     /* set endpoint0 tx fifo size */
722     usb_set_tx_fifo(usbx, USB_EPT0, USBD_EP0_TX_SIZE);
723 
724     /* set endpoint1 tx fifo size */
725     usb_set_tx_fifo(usbx, USB_EPT1, USBD_EP1_TX_SIZE);
726 
727     /* set endpoint2 tx fifo size */
728     usb_set_tx_fifo(usbx, USB_EPT2, USBD_EP2_TX_SIZE);
729 
730     /* set endpoint3 tx fifo size */
731     usb_set_tx_fifo(usbx, USB_EPT3, USBD_EP3_TX_SIZE);
732 #if (USB_EPT_MAX_NUM == 8)
733     if(USB_EPT_MAX_NUM == 8)
734     {
735       /* set endpoint4 tx fifo size */
736       usb_set_tx_fifo(usbx, USB_EPT4, USBD_EP4_TX_SIZE);
737 
738       /* set endpoint5 tx fifo size */
739       usb_set_tx_fifo(usbx, USB_EPT5, USBD_EP5_TX_SIZE);
740 
741       /* set endpoint6 tx fifo size */
742       usb_set_tx_fifo(usbx, USB_EPT6, USBD_EP6_TX_SIZE);
743 
744       /* set endpoint7 tx fifo size */
745       usb_set_tx_fifo(usbx, USB_EPT7, USBD_EP7_TX_SIZE);
746     }
747 #endif
748   }
749 #ifdef OTG2_GLOBAL
750   if(usbx == OTG2_GLOBAL)
751   {
752     /* set receive fifo size */
753     usb_set_rx_fifo(usbx, USBD2_RX_SIZE);
754 
755     /* set endpoint0 tx fifo size */
756     usb_set_tx_fifo(usbx, USB_EPT0, USBD2_EP0_TX_SIZE);
757 
758     /* set endpoint1 tx fifo size */
759     usb_set_tx_fifo(usbx, USB_EPT1, USBD2_EP1_TX_SIZE);
760 
761     /* set endpoint2 tx fifo size */
762     usb_set_tx_fifo(usbx, USB_EPT2, USBD2_EP2_TX_SIZE);
763 
764     /* set endpoint3 tx fifo size */
765     usb_set_tx_fifo(usbx, USB_EPT3, USBD2_EP3_TX_SIZE);
766 
767     if(USB_EPT_MAX_NUM == 8)
768     {
769       /* set endpoint4 tx fifo size */
770       usb_set_tx_fifo(usbx, USB_EPT4, USBD2_EP4_TX_SIZE);
771 
772       /* set endpoint5 tx fifo size */
773       usb_set_tx_fifo(usbx, USB_EPT5, USBD2_EP5_TX_SIZE);
774 
775       /* set endpoint6 tx fifo size */
776       usb_set_tx_fifo(usbx, USB_EPT6, USBD2_EP6_TX_SIZE);
777 
778       /* set endpoint7 tx fifo size */
779       usb_set_tx_fifo(usbx, USB_EPT7, USBD2_EP7_TX_SIZE);
780     }
781   }
782 #endif
783 }
784 
785 /**
786   * @brief  usb device core initialization
787   * @param  udev: to the structure of usbd_core_type
788   * @param  usb_reg: usb otgfs peripheral global register
789   *         this parameter can be one of the following values:
790   *         OTG1_GLOBAL , OTG2_GLOBAL
791   * @param  class_handler: usb class handler
792   * @param  desc_handler: device config handler
793   * @param  core_id: usb core id number
794   * @retval usb_sts_type
795   */
usbd_core_init(usbd_core_type * udev,usb_reg_type * usb_reg,uint8_t core_id)796 usb_sts_type usbd_core_init(usbd_core_type *udev,
797                             usb_reg_type *usb_reg,
798                             uint8_t core_id)
799 {
800   usb_reg_type *usbx;
801   otg_device_type *dev;
802   otg_eptin_type *ept_in;
803   otg_eptout_type *ept_out;
804   uint32_t i_index;
805   uint32_t hs_phytype;
806 
807   udev->usb_reg = usb_reg;
808   usbx = usb_reg;
809   dev = OTG_DEVICE(usbx);
810 
811   hs_phytype = *(__IO uint32_t *)((uint32_t)usbx + 0x48) & 0xC0;
812   /* set connect state */
813   udev->conn_state = USB_CONN_STATE_DEFAULT;
814   if((core_id == USB_HIGH_SPEED_CORE_ID) && hs_phytype)
815   {
816     udev->speed = USB_HIGH_SPEED;
817   }
818   else
819   {
820     udev->speed = USB_FULL_SPEED;
821   }
822   /* device class config */
823   udev->device_addr = 0;
824   /* set device disconnect */
825   usbd_disconnect(udev);
826 
827   /* set endpoint to default status */
828   usb_ept_default_init(udev);
829 
830   /* disable usb global interrupt */
831   usb_interrupt_disable(usbx);
832 
833   /* init global register */
834   usb_global_init(usbx);
835   if(udev->dma_en == TRUE && hs_phytype)
836   {
837     usbx->gahbcfg |= 1 << 5 | 3 << 1;
838   }
839   else
840   {
841     udev->dma_en = FALSE;
842   }
843   /* set device mode */
844   usb_global_set_mode(usbx, OTG_DEVICE_MODE);
845 
846   rt_thread_mdelay(25);
847 
848   /* open phy clock */
849   usb_open_phy_clk(udev->usb_reg);
850 
851   /* set periodic frame interval */
852   dev->dcfg_bit.perfrint = DCFG_PERFRINT_80;
853 
854   /* set device speed to full-speed */
855   if((core_id == USB_HIGH_SPEED_CORE_ID) && hs_phytype)
856   {
857     dev->dcfg_bit.devspd = 0; /*high speed*/
858   }
859   else
860   {
861     if(hs_phytype == 0xC0 )
862     {
863       dev->dcfg_bit.devspd = 1; /*full speed in high*/
864     }
865     else
866     {
867       dev->dcfg_bit.devspd = USB_DCFG_FULL_SPEED;
868     }
869   }
870   /* flush all tx fifo */
871   usb_flush_tx_fifo(usbx, 16);
872 
873   /* flush share rx fifo */
874   usb_flush_rx_fifo(usbx);
875 
876   /* clear all endpoint interrupt flag and mask */
877   dev->daint = 0xFFFFFFFF;
878   dev->daintmsk = 0;
879   dev->diepmsk = 0;
880   dev->doepmsk = 0;
881 
882   for(i_index = 0; i_index < USB_EPT_MAX_NUM; i_index ++)
883   {
884     usbx->dieptxfn[i_index] = 0;
885   }
886 
887   /* endpoint fifo alloc */
888   usbd_fifo_alloc(udev);
889 
890   /* disable all in endpoint */
891   for(i_index = 0; i_index < USB_EPT_MAX_NUM; i_index ++)
892   {
893     ept_in = USB_INEPT(usbx, i_index);
894     if(ept_in->diepctl_bit.eptena)
895     {
896       ept_in->diepctl = 0;
897       ept_in->diepctl_bit.eptdis = TRUE;
898       ept_in->diepctl_bit.snak = TRUE;
899     }
900     else
901     {
902       ept_in->diepctl = 0;
903     }
904     ept_in->dieptsiz = 0;
905     ept_in->diepint = 0xFF;
906   }
907 
908   /* disable all out endpoint */
909   for(i_index = 0; i_index < USB_EPT_MAX_NUM; i_index ++)
910   {
911     ept_out = USB_OUTEPT(usbx, i_index);
912     if(ept_out->doepctl_bit.eptena)
913     {
914       ept_out->doepctl = 0;
915       ept_out->doepctl_bit.eptdis = TRUE;
916       ept_out->doepctl_bit.snak = TRUE;
917     }
918     else
919     {
920       ept_out->doepctl = 0;
921     }
922     ept_out->doeptsiz = 0;
923     ept_out->doepint = 0xFF;
924   }
925   dev->diepmsk_bit.txfifoudrmsk = TRUE;
926 
927   /* clear global interrupt and mask */
928   usbx->gintmsk = 0;
929   usbx->gintsts = 0xBFFFFFFF;
930 
931   /* enable global interrupt mask */
932   usbx->gintmsk = USB_OTG_SOF_INT |
933                   USB_OTG_USBSUSP_INT | USB_OTG_USBRST_INT |
934                   USB_OTG_ENUMDONE_INT | USB_OTG_IEPT_INT |
935                   USB_OTG_OEPT_INT | USB_OTG_INCOMISOIN_INT |
936                   USB_OTG_INCOMPIP_INCOMPISOOUT_INT | USB_OTG_WKUP_INT |
937                   USB_OTG_OTGINT_INT;
938   if(udev->dma_en == FALSE || hs_phytype == 0)
939   {
940     usbx->gintmsk |= USB_OTG_RXFLVL_INT;
941   }
942   /* usb connect */
943   usbd_connect(udev);
944 
945   /* enable global interrupt */
946   usb_interrupt_enable(usbx);
947 
948   return USB_OK;
949 
950 }
951 
952 #endif
953 
954 /**
955   * @}
956   */
957 
958 /**
959   * @}
960   */
961