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