1 /*
2 * Copyright (c) 2021-2022, STMicroelectronics - All Rights Reserved
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #include <assert.h>
8 #include <stdint.h>
9
10 #include <common/debug.h>
11 #include <drivers/usb_device.h>
12
13 /* Define for EP address */
14 #define EP_DIR_MASK BIT(7)
15 #define EP_DIR_IN BIT(7)
16 #define EP_NUM_MASK GENMASK(3, 0)
17
18 #define EP0_IN (0U | EP_DIR_IN)
19 #define EP0_OUT 0U
20
21 /* USB address between 1 through 127 = 0x7F mask */
22 #define ADDRESS_MASK GENMASK(6, 0)
23
24 /*
25 * Set a STALL condition over an endpoint
26 * pdev: USB handle
27 * ep_addr: endpoint address
28 * return : status
29 */
usb_core_set_stall(struct usb_handle * pdev,uint8_t ep_addr)30 static enum usb_status usb_core_set_stall(struct usb_handle *pdev, uint8_t ep_addr)
31 {
32 struct usbd_ep *ep;
33 struct pcd_handle *hpcd = (struct pcd_handle *)pdev->data;
34 uint8_t num;
35
36 num = ep_addr & EP_NUM_MASK;
37 if (num >= USBD_EP_NB) {
38 return USBD_FAIL;
39 }
40 if ((EP_DIR_MASK & ep_addr) == EP_DIR_IN) {
41 ep = &hpcd->in_ep[num];
42 ep->is_in = true;
43 } else {
44 ep = &hpcd->out_ep[num];
45 ep->is_in = false;
46 }
47 ep->num = num;
48
49 pdev->driver->ep_set_stall(hpcd->instance, ep);
50 if (num == 0U) {
51 pdev->driver->ep0_out_start(hpcd->instance);
52 }
53
54 return USBD_OK;
55 }
56
57 /*
58 * usb_core_get_desc
59 * Handle Get Descriptor requests
60 * pdev : device instance
61 * req : usb request
62 */
usb_core_get_desc(struct usb_handle * pdev,struct usb_setup_req * req)63 static void usb_core_get_desc(struct usb_handle *pdev, struct usb_setup_req *req)
64 {
65 uint16_t len;
66 uint8_t *pbuf;
67 uint8_t desc_type = HIBYTE(req->value);
68 uint8_t desc_idx = LOBYTE(req->value);
69
70 switch (desc_type) {
71 case USB_DESC_TYPE_DEVICE:
72 pbuf = pdev->desc->get_device_desc(&len);
73 break;
74
75 case USB_DESC_TYPE_CONFIGURATION:
76 pbuf = pdev->desc->get_config_desc(&len);
77 break;
78
79 case USB_DESC_TYPE_STRING:
80 switch (desc_idx) {
81 case USBD_IDX_LANGID_STR:
82 pbuf = pdev->desc->get_lang_id_desc(&len);
83 break;
84
85 case USBD_IDX_MFC_STR:
86 pbuf = pdev->desc->get_manufacturer_desc(&len);
87 break;
88
89 case USBD_IDX_PRODUCT_STR:
90 pbuf = pdev->desc->get_product_desc(&len);
91 break;
92
93 case USBD_IDX_SERIAL_STR:
94 pbuf = pdev->desc->get_serial_desc(&len);
95 break;
96
97 case USBD_IDX_CONFIG_STR:
98 pbuf = pdev->desc->get_configuration_desc(&len);
99 break;
100
101 case USBD_IDX_INTERFACE_STR:
102 pbuf = pdev->desc->get_interface_desc(&len);
103 break;
104
105 /* For all USER string */
106 case USBD_IDX_USER0_STR:
107 default:
108 pbuf = pdev->desc->get_usr_desc(desc_idx - USBD_IDX_USER0_STR, &len);
109 break;
110 }
111 break;
112
113 case USB_DESC_TYPE_DEVICE_QUALIFIER:
114 pbuf = pdev->desc->get_device_qualifier_desc(&len);
115 break;
116
117 case USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION:
118 if (pdev->desc->get_other_speed_config_desc == NULL) {
119 usb_core_ctl_error(pdev);
120 return;
121 }
122 pbuf = pdev->desc->get_other_speed_config_desc(&len);
123 break;
124
125 default:
126 ERROR("Unknown request %i\n", desc_type);
127 usb_core_ctl_error(pdev);
128 return;
129 }
130
131 if ((len != 0U) && (req->length != 0U)) {
132 len = MIN(len, req->length);
133
134 /* Start the transfer */
135 usb_core_transmit_ep0(pdev, pbuf, len);
136 }
137 }
138
139 /*
140 * usb_core_set_config
141 * Handle Set device configuration request
142 * pdev : device instance
143 * req : usb request
144 */
usb_core_set_config(struct usb_handle * pdev,struct usb_setup_req * req)145 static void usb_core_set_config(struct usb_handle *pdev, struct usb_setup_req *req)
146 {
147 static uint8_t cfgidx;
148
149 cfgidx = LOBYTE(req->value);
150
151 if (cfgidx > USBD_MAX_NUM_CONFIGURATION) {
152 usb_core_ctl_error(pdev);
153 return;
154 }
155
156 switch (pdev->dev_state) {
157 case USBD_STATE_ADDRESSED:
158 if (cfgidx != 0U) {
159 pdev->dev_config = cfgidx;
160 pdev->dev_state = USBD_STATE_CONFIGURED;
161 if (!pdev->class) {
162 usb_core_ctl_error(pdev);
163 return;
164 }
165 /* Set configuration and Start the Class */
166 if (pdev->class->init(pdev, cfgidx) != 0U) {
167 usb_core_ctl_error(pdev);
168 return;
169 }
170 }
171 break;
172
173 case USBD_STATE_CONFIGURED:
174 if (cfgidx == 0U) {
175 pdev->dev_state = USBD_STATE_ADDRESSED;
176 pdev->dev_config = cfgidx;
177 pdev->class->de_init(pdev, cfgidx);
178 } else if (cfgidx != pdev->dev_config) {
179 if (pdev->class == NULL) {
180 usb_core_ctl_error(pdev);
181 return;
182 }
183 /* Clear old configuration */
184 pdev->class->de_init(pdev, pdev->dev_config);
185 /* Set new configuration */
186 pdev->dev_config = cfgidx;
187 /* Set configuration and start the USB class */
188 if (pdev->class->init(pdev, cfgidx) != 0U) {
189 usb_core_ctl_error(pdev);
190 return;
191 }
192 }
193 break;
194
195 default:
196 usb_core_ctl_error(pdev);
197 return;
198 }
199
200 /* Send status */
201 usb_core_transmit_ep0(pdev, NULL, 0U);
202 }
203
204 /*
205 * usb_core_get_status
206 * Handle Get Status request
207 * pdev : device instance
208 * req : usb request
209 */
usb_core_get_status(struct usb_handle * pdev,struct usb_setup_req * req)210 static void usb_core_get_status(struct usb_handle *pdev,
211 struct usb_setup_req *req)
212 {
213 if ((pdev->dev_state != USBD_STATE_ADDRESSED) &&
214 (pdev->dev_state != USBD_STATE_CONFIGURED)) {
215 usb_core_ctl_error(pdev);
216 return;
217 }
218
219 pdev->dev_config_status = USB_CONFIG_SELF_POWERED;
220
221 if (pdev->dev_remote_wakeup != 0U) {
222 pdev->dev_config_status |= USB_CONFIG_REMOTE_WAKEUP;
223 }
224
225 /* Start the transfer */
226 usb_core_transmit_ep0(pdev, (uint8_t *)&pdev->dev_config_status, 2U);
227 }
228
229 /*
230 * usb_core_set_address
231 * Set device address
232 * pdev : device instance
233 * req : usb request
234 */
usb_core_set_address(struct usb_handle * pdev,struct usb_setup_req * req)235 static void usb_core_set_address(struct usb_handle *pdev,
236 struct usb_setup_req *req)
237 {
238 uint8_t dev_addr;
239
240 if ((req->index != 0U) || (req->length != 0U)) {
241 usb_core_ctl_error(pdev);
242 return;
243 }
244
245 dev_addr = req->value & ADDRESS_MASK;
246 if (pdev->dev_state != USBD_STATE_DEFAULT) {
247 usb_core_ctl_error(pdev);
248 return;
249 }
250
251 pdev->dev_address = dev_addr;
252 pdev->driver->set_address(((struct pcd_handle *)(pdev->data))->instance, dev_addr);
253
254 /* Send status */
255 usb_core_transmit_ep0(pdev, NULL, 0U);
256
257 if (dev_addr != 0U) {
258 pdev->dev_state = USBD_STATE_ADDRESSED;
259 } else {
260 pdev->dev_state = USBD_STATE_DEFAULT;
261 }
262 }
263
264 /*
265 * usb_core_dev_req
266 * Handle standard usb device requests
267 * pdev : device instance
268 * req : usb request
269 * return : status
270 */
usb_core_dev_req(struct usb_handle * pdev,struct usb_setup_req * req)271 static enum usb_status usb_core_dev_req(struct usb_handle *pdev,
272 struct usb_setup_req *req)
273 {
274 VERBOSE("receive request %i\n", req->b_request);
275 switch (req->b_request) {
276 case USB_REQ_GET_DESCRIPTOR:
277 usb_core_get_desc(pdev, req);
278 break;
279
280 case USB_REQ_SET_CONFIGURATION:
281 usb_core_set_config(pdev, req);
282 break;
283
284 case USB_REQ_GET_STATUS:
285 usb_core_get_status(pdev, req);
286 break;
287
288 case USB_REQ_SET_ADDRESS:
289 usb_core_set_address(pdev, req);
290 break;
291
292 case USB_REQ_GET_CONFIGURATION:
293 case USB_REQ_SET_FEATURE:
294 case USB_REQ_CLEAR_FEATURE:
295 default:
296 ERROR("NOT SUPPORTED %i\n", req->b_request);
297 usb_core_ctl_error(pdev);
298 break;
299 }
300
301 return USBD_OK;
302 }
303
304 /*
305 * usb_core_itf_req
306 * Handle standard usb interface requests
307 * pdev : device instance
308 * req : usb request
309 * return : status
310 */
usb_core_itf_req(struct usb_handle * pdev,struct usb_setup_req * req)311 static enum usb_status usb_core_itf_req(struct usb_handle *pdev,
312 struct usb_setup_req *req)
313 {
314 if (pdev->dev_state != USBD_STATE_CONFIGURED) {
315 usb_core_ctl_error(pdev);
316 return USBD_OK;
317 }
318
319 if (LOBYTE(req->index) <= USBD_MAX_NUM_INTERFACES) {
320 pdev->class->setup(pdev, req);
321
322 if (req->length == 0U) {
323 usb_core_transmit_ep0(pdev, NULL, 0U);
324 }
325 } else {
326 usb_core_ctl_error(pdev);
327 }
328
329 return USBD_OK;
330 }
331
332 /*
333 * usb_core_setup_stage
334 * Handle the setup stage
335 * pdev: device instance
336 * psetup : setup buffer
337 * return : status
338 */
usb_core_setup_stage(struct usb_handle * pdev,uint8_t * psetup)339 static enum usb_status usb_core_setup_stage(struct usb_handle *pdev,
340 uint8_t *psetup)
341 {
342 struct usb_setup_req *req = &pdev->request;
343
344 /* Copy setup buffer into req structure */
345 req->bm_request = psetup[0];
346 req->b_request = psetup[1];
347 req->value = psetup[2] + (psetup[3] << 8);
348 req->index = psetup[4] + (psetup[5] << 8);
349 req->length = psetup[6] + (psetup[7] << 8);
350
351 pdev->ep0_state = USBD_EP0_SETUP;
352 pdev->ep0_data_len = pdev->request.length;
353
354 switch (pdev->request.bm_request & USB_REQ_RECIPIENT_MASK) {
355 case USB_REQ_RECIPIENT_DEVICE:
356 usb_core_dev_req(pdev, &pdev->request);
357 break;
358
359 case USB_REQ_RECIPIENT_INTERFACE:
360 usb_core_itf_req(pdev, &pdev->request);
361 break;
362
363 case USB_REQ_RECIPIENT_ENDPOINT:
364 default:
365 ERROR("receive unsupported request %u",
366 pdev->request.bm_request & USB_REQ_RECIPIENT_MASK);
367 usb_core_set_stall(pdev, pdev->request.bm_request & USB_REQ_DIRECTION);
368 return USBD_FAIL;
369 }
370
371 return USBD_OK;
372 }
373
374 /*
375 * usb_core_data_out
376 * Handle data OUT stage
377 * pdev: device instance
378 * epnum: endpoint index
379 * pdata: buffer to sent
380 * return : status
381 */
usb_core_data_out(struct usb_handle * pdev,uint8_t epnum,uint8_t * pdata)382 static enum usb_status usb_core_data_out(struct usb_handle *pdev, uint8_t epnum,
383 uint8_t *pdata)
384 {
385 struct usb_endpoint *pep;
386
387 if (epnum == 0U) {
388 pep = &pdev->ep_out[0];
389 if (pdev->ep0_state == USBD_EP0_DATA_OUT) {
390 if (pep->rem_length > pep->maxpacket) {
391 pep->rem_length -= pep->maxpacket;
392
393 usb_core_receive(pdev, 0U, pdata,
394 MIN(pep->rem_length,
395 pep->maxpacket));
396 } else {
397 if (pdev->class->ep0_rx_ready &&
398 (pdev->dev_state == USBD_STATE_CONFIGURED)) {
399 pdev->class->ep0_rx_ready(pdev);
400 }
401
402 usb_core_transmit_ep0(pdev, NULL, 0U);
403 }
404 }
405 } else if (pdev->class->data_out != NULL &&
406 (pdev->dev_state == USBD_STATE_CONFIGURED)) {
407 pdev->class->data_out(pdev, epnum);
408 }
409
410 return USBD_OK;
411 }
412
413 /*
414 * usb_core_data_in
415 * Handle data in stage
416 * pdev: device instance
417 * epnum: endpoint index
418 * pdata: buffer to fill
419 * return : status
420 */
usb_core_data_in(struct usb_handle * pdev,uint8_t epnum,uint8_t * pdata)421 static enum usb_status usb_core_data_in(struct usb_handle *pdev, uint8_t epnum,
422 uint8_t *pdata)
423 {
424 if (epnum == 0U) {
425 struct usb_endpoint *pep = &pdev->ep_in[0];
426
427 if (pdev->ep0_state == USBD_EP0_DATA_IN) {
428 if (pep->rem_length > pep->maxpacket) {
429 pep->rem_length -= pep->maxpacket;
430
431 usb_core_transmit(pdev, 0U, pdata,
432 pep->rem_length);
433
434 /* Prepare EP for premature end of transfer */
435 usb_core_receive(pdev, 0U, NULL, 0U);
436 } else {
437 /* Last packet is MPS multiple, send ZLP packet */
438 if ((pep->total_length % pep->maxpacket == 0U) &&
439 (pep->total_length >= pep->maxpacket) &&
440 (pep->total_length < pdev->ep0_data_len)) {
441 usb_core_transmit(pdev, 0U, NULL, 0U);
442
443 pdev->ep0_data_len = 0U;
444
445 /* Prepare endpoint for premature end of transfer */
446 usb_core_receive(pdev, 0U, NULL, 0U);
447 } else {
448 if (pdev->class->ep0_tx_sent != NULL &&
449 (pdev->dev_state ==
450 USBD_STATE_CONFIGURED)) {
451 pdev->class->ep0_tx_sent(pdev);
452 }
453 /* Start the transfer */
454 usb_core_receive_ep0(pdev, NULL, 0U);
455 }
456 }
457 }
458 } else if ((pdev->class->data_in != NULL) &&
459 (pdev->dev_state == USBD_STATE_CONFIGURED)) {
460 pdev->class->data_in(pdev, epnum);
461 }
462
463 return USBD_OK;
464 }
465
466 /*
467 * usb_core_suspend
468 * Handle suspend event
469 * pdev : device instance
470 * return : status
471 */
usb_core_suspend(struct usb_handle * pdev)472 static enum usb_status usb_core_suspend(struct usb_handle *pdev)
473 {
474 INFO("USB Suspend mode\n");
475 pdev->dev_old_state = pdev->dev_state;
476 pdev->dev_state = USBD_STATE_SUSPENDED;
477
478 return USBD_OK;
479 }
480
481 /*
482 * usb_core_resume
483 * Handle resume event
484 * pdev : device instance
485 * return : status
486 */
usb_core_resume(struct usb_handle * pdev)487 static enum usb_status usb_core_resume(struct usb_handle *pdev)
488 {
489 INFO("USB Resume\n");
490 pdev->dev_state = pdev->dev_old_state;
491
492 return USBD_OK;
493 }
494
495 /*
496 * usb_core_sof
497 * Handle SOF event
498 * pdev : device instance
499 * return : status
500 */
usb_core_sof(struct usb_handle * pdev)501 static enum usb_status usb_core_sof(struct usb_handle *pdev)
502 {
503 if (pdev->dev_state == USBD_STATE_CONFIGURED) {
504 if (pdev->class->sof != NULL) {
505 pdev->class->sof(pdev);
506 }
507 }
508
509 return USBD_OK;
510 }
511
512 /*
513 * usb_core_disconnect
514 * Handle device disconnection event
515 * pdev : device instance
516 * return : status
517 */
usb_core_disconnect(struct usb_handle * pdev)518 static enum usb_status usb_core_disconnect(struct usb_handle *pdev)
519 {
520 /* Free class resources */
521 pdev->dev_state = USBD_STATE_DEFAULT;
522 pdev->class->de_init(pdev, pdev->dev_config);
523
524 return USBD_OK;
525 }
526
usb_core_handle_it(struct usb_handle * pdev)527 enum usb_status usb_core_handle_it(struct usb_handle *pdev)
528 {
529 uint32_t param = 0U;
530 uint32_t len = 0U;
531 struct usbd_ep *ep;
532
533 switch (pdev->driver->it_handler(pdev->data->instance, ¶m)) {
534 case USB_DATA_OUT:
535 usb_core_data_out(pdev, param,
536 pdev->data->out_ep[param].xfer_buff);
537 break;
538
539 case USB_DATA_IN:
540 usb_core_data_in(pdev, param,
541 pdev->data->in_ep[param].xfer_buff);
542 break;
543
544 case USB_SETUP:
545 usb_core_setup_stage(pdev, (uint8_t *)pdev->data->setup);
546 break;
547
548 case USB_ENUM_DONE:
549 break;
550
551 case USB_READ_DATA_PACKET:
552 ep = &pdev->data->out_ep[param & USBD_OUT_EPNUM_MASK];
553 len = (param & USBD_OUT_COUNT_MASK) >> USBD_OUT_COUNT_SHIFT;
554 pdev->driver->read_packet(pdev->data->instance,
555 ep->xfer_buff, len);
556 ep->xfer_buff += len;
557 ep->xfer_count += len;
558 break;
559
560 case USB_READ_SETUP_PACKET:
561 ep = &pdev->data->out_ep[param & USBD_OUT_EPNUM_MASK];
562 len = (param & USBD_OUT_COUNT_MASK) >> 0x10;
563 pdev->driver->read_packet(pdev->data->instance,
564 (uint8_t *)pdev->data->setup, 8);
565 ep->xfer_count += len;
566 break;
567
568 case USB_RESET:
569 pdev->dev_state = USBD_STATE_DEFAULT;
570 break;
571
572 case USB_RESUME:
573 if (pdev->data->lpm_state == LPM_L1) {
574 pdev->data->lpm_state = LPM_L0;
575 } else {
576 usb_core_resume(pdev);
577 }
578 break;
579
580 case USB_SUSPEND:
581 usb_core_suspend(pdev);
582 break;
583
584 case USB_LPM:
585 if (pdev->data->lpm_state == LPM_L0) {
586 pdev->data->lpm_state = LPM_L1;
587 } else {
588 usb_core_suspend(pdev);
589 }
590 break;
591
592 case USB_SOF:
593 usb_core_sof(pdev);
594 break;
595
596 case USB_DISCONNECT:
597 usb_core_disconnect(pdev);
598 break;
599
600 case USB_WRITE_EMPTY:
601 pdev->driver->write_empty_tx_fifo(pdev->data->instance, param,
602 pdev->data->in_ep[param].xfer_len,
603 (uint32_t *)&pdev->data->in_ep[param].xfer_count,
604 pdev->data->in_ep[param].maxpacket,
605 &pdev->data->in_ep[param].xfer_buff);
606 break;
607
608 case USB_NOTHING:
609 default:
610 break;
611 }
612
613 return USBD_OK;
614 }
615
usb_core_start_xfer(struct usb_handle * pdev,void * handle,struct usbd_ep * ep)616 static void usb_core_start_xfer(struct usb_handle *pdev,
617 void *handle,
618 struct usbd_ep *ep)
619 {
620 if (ep->num == 0U) {
621 pdev->driver->ep0_start_xfer(handle, ep);
622 } else {
623 pdev->driver->ep_start_xfer(handle, ep);
624 }
625 }
626
627 /*
628 * usb_core_receive
629 * Receive an amount of data
630 * pdev: USB handle
631 * ep_addr: endpoint address
632 * buf: pointer to the reception buffer
633 * len: amount of data to be received
634 * return : status
635 */
usb_core_receive(struct usb_handle * pdev,uint8_t ep_addr,uint8_t * buf,uint32_t len)636 enum usb_status usb_core_receive(struct usb_handle *pdev, uint8_t ep_addr,
637 uint8_t *buf, uint32_t len)
638 {
639 struct usbd_ep *ep;
640 struct pcd_handle *hpcd = (struct pcd_handle *)pdev->data;
641 uint8_t num;
642
643 num = ep_addr & EP_NUM_MASK;
644 if (num >= USBD_EP_NB) {
645 return USBD_FAIL;
646 }
647 ep = &hpcd->out_ep[num];
648
649 /* Setup and start the Xfer */
650 ep->xfer_buff = buf;
651 ep->xfer_len = len;
652 ep->xfer_count = 0U;
653 ep->is_in = false;
654 ep->num = num;
655
656 usb_core_start_xfer(pdev, hpcd->instance, ep);
657
658 return USBD_OK;
659 }
660
661 /*
662 * usb_core_transmit
663 * Send an amount of data
664 * pdev: USB handle
665 * ep_addr: endpoint address
666 * buf: pointer to the transmission buffer
667 * len: amount of data to be sent
668 * return : status
669 */
usb_core_transmit(struct usb_handle * pdev,uint8_t ep_addr,uint8_t * buf,uint32_t len)670 enum usb_status usb_core_transmit(struct usb_handle *pdev, uint8_t ep_addr,
671 uint8_t *buf, uint32_t len)
672 {
673 struct usbd_ep *ep;
674 struct pcd_handle *hpcd = (struct pcd_handle *)pdev->data;
675 uint8_t num;
676
677 num = ep_addr & EP_NUM_MASK;
678 if (num >= USBD_EP_NB) {
679 return USBD_FAIL;
680 }
681 ep = &hpcd->in_ep[num];
682
683 /* Setup and start the Xfer */
684 ep->xfer_buff = buf;
685 ep->xfer_len = len;
686 ep->xfer_count = 0U;
687 ep->is_in = true;
688 ep->num = num;
689
690 usb_core_start_xfer(pdev, hpcd->instance, ep);
691
692 return USBD_OK;
693 }
694
695 /*
696 * usb_core_receive_ep0
697 * Receive an amount of data on ep0
698 * pdev: USB handle
699 * buf: pointer to the reception buffer
700 * len: amount of data to be received
701 * return : status
702 */
usb_core_receive_ep0(struct usb_handle * pdev,uint8_t * buf,uint32_t len)703 enum usb_status usb_core_receive_ep0(struct usb_handle *pdev, uint8_t *buf,
704 uint32_t len)
705 {
706 /* Prepare the reception of the buffer over EP0 */
707 if (len != 0U) {
708 pdev->ep0_state = USBD_EP0_DATA_OUT;
709 } else {
710 pdev->ep0_state = USBD_EP0_STATUS_OUT;
711 }
712
713 pdev->ep_out[0].total_length = len;
714 pdev->ep_out[0].rem_length = len;
715
716 /* Start the transfer */
717 return usb_core_receive(pdev, 0U, buf, len);
718 }
719
720 /*
721 * usb_core_transmit_ep0
722 * Send an amount of data on ep0
723 * pdev: USB handle
724 * buf: pointer to the transmission buffer
725 * len: amount of data to be sent
726 * return : status
727 */
usb_core_transmit_ep0(struct usb_handle * pdev,uint8_t * buf,uint32_t len)728 enum usb_status usb_core_transmit_ep0(struct usb_handle *pdev, uint8_t *buf,
729 uint32_t len)
730 {
731 /* Set EP0 State */
732 if (len != 0U) {
733 pdev->ep0_state = USBD_EP0_DATA_IN;
734 } else {
735 pdev->ep0_state = USBD_EP0_STATUS_IN;
736 }
737
738 pdev->ep_in[0].total_length = len;
739 pdev->ep_in[0].rem_length = len;
740
741 /* Start the transfer */
742 return usb_core_transmit(pdev, 0U, buf, len);
743 }
744
745 /*
746 * usb_core_ctl_error
747 * Handle USB low level error
748 * pdev: device instance
749 * req: usb request
750 * return : None
751 */
752
usb_core_ctl_error(struct usb_handle * pdev)753 void usb_core_ctl_error(struct usb_handle *pdev)
754 {
755 ERROR("%s : Send an ERROR\n", __func__);
756 usb_core_set_stall(pdev, EP0_IN);
757 usb_core_set_stall(pdev, EP0_OUT);
758 }
759
760 /*
761 * usb_core_start
762 * Start the USB device core.
763 * pdev: Device Handle
764 * return : USBD Status
765 */
usb_core_start(struct usb_handle * pdev)766 enum usb_status usb_core_start(struct usb_handle *pdev)
767 {
768 /* Start the low level driver */
769 pdev->driver->start_device(pdev->data->instance);
770
771 return USBD_OK;
772 }
773
774 /*
775 * usb_core_stop
776 * Stop the USB device core.
777 * pdev: Device Handle
778 * return : USBD Status
779 */
usb_core_stop(struct usb_handle * pdev)780 enum usb_status usb_core_stop(struct usb_handle *pdev)
781 {
782 /* Free class resources */
783 pdev->class->de_init(pdev, pdev->dev_config);
784
785 /* Stop the low level driver */
786 pdev->driver->stop_device(pdev->data->instance);
787
788 return USBD_OK;
789 }
790
791 /*
792 * register_usb_driver
793 * Stop the USB device core.
794 * pdev: Device Handle
795 * pcd_handle: PCD handle
796 * driver: USB driver
797 * driver_handle: USB driver handle
798 * return : USBD Status
799 */
register_usb_driver(struct usb_handle * pdev,struct pcd_handle * pcd_handle,const struct usb_driver * driver,void * driver_handle)800 enum usb_status register_usb_driver(struct usb_handle *pdev,
801 struct pcd_handle *pcd_handle,
802 const struct usb_driver *driver,
803 void *driver_handle)
804 {
805 uint8_t i;
806
807 assert(pdev != NULL);
808 assert(pcd_handle != NULL);
809 assert(driver != NULL);
810 assert(driver_handle != NULL);
811
812 /* Free class resources */
813 pdev->driver = driver;
814 pdev->data = pcd_handle;
815 pdev->data->instance = driver_handle;
816 pdev->dev_state = USBD_STATE_DEFAULT;
817 pdev->ep0_state = USBD_EP0_IDLE;
818
819 /* Copy endpoint information */
820 for (i = 0U; i < USBD_EP_NB; i++) {
821 pdev->ep_in[i].maxpacket = pdev->data->in_ep[i].maxpacket;
822 pdev->ep_out[i].maxpacket = pdev->data->out_ep[i].maxpacket;
823 }
824
825 return USBD_OK;
826 }
827
828 /*
829 * register_platform
830 * Register the USB device core.
831 * pdev: Device Handle
832 * plat_call_back: callback
833 * return : USBD Status
834 */
register_platform(struct usb_handle * pdev,const struct usb_desc * plat_call_back)835 enum usb_status register_platform(struct usb_handle *pdev,
836 const struct usb_desc *plat_call_back)
837 {
838 assert(pdev != NULL);
839 assert(plat_call_back != NULL);
840
841 /* Save platform info in class resources */
842 pdev->desc = plat_call_back;
843
844 return USBD_OK;
845 }
846