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, &param)) {
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