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