1 /* usb_dc_kinetis.c - Kinetis USBFSOTG usb device driver */
2 
3 /*
4  * Copyright (c) 2017 PHYTEC Messtechnik GmbH
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 
9 #define DT_DRV_COMPAT nxp_kinetis_usbd
10 
11 #include <soc.h>
12 #include <string.h>
13 #include <stdio.h>
14 #include <zephyr/kernel.h>
15 #include <zephyr/sys/byteorder.h>
16 #include <zephyr/usb/usb_device.h>
17 #include <zephyr/init.h>
18 
19 #define LOG_LEVEL CONFIG_USB_DRIVER_LOG_LEVEL
20 #include <zephyr/logging/log.h>
21 #include <zephyr/irq.h>
22 LOG_MODULE_REGISTER(usb_dc_kinetis);
23 
24 #define NUM_OF_EP_MAX		DT_INST_PROP(0, num_bidir_endpoints)
25 
26 #define BD_OWN_MASK		(1 << 5)
27 #define BD_DATA01_MASK		(1 << 4)
28 #define BD_KEEP_MASK		(1 << 3)
29 #define BD_NINC_MASK		(1 << 2)
30 #define BD_DTS_MASK		(1 << 1)
31 #define BD_STALL_MASK		(1 << 0)
32 
33 #define KINETIS_SETUP_TOKEN	0x0d
34 #define KINETIS_IN_TOKEN	0x09
35 #define KINETIS_OUT_TOKEN	0x01
36 
37 #define USBFSOTG_PERID		0x04
38 #define USBFSOTG_REV		0x33
39 
40 #define KINETIS_EP_NUMOF_MASK	0xf
41 #define KINETIS_ADDR2IDX(addr)	((addr) & (KINETIS_EP_NUMOF_MASK))
42 
43 /*
44  * In some SoC USB0 base register is defined as USBFS0
45  */
46 #if !defined(USB0) && defined(USBFS0)
47 #define USB0				USBFS0
48 #endif
49 
50 /*
51  * Buffer Descriptor (BD) entry provides endpoint buffer control
52  * information for USBFS controller. Every endpoint direction requires
53  * two BD entries.
54  */
55 struct buf_descriptor {
56 	union {
57 		uint32_t bd_fields;
58 
59 		struct {
60 			uint32_t reserved_1_0 : 2;
61 			uint32_t tok_pid : 4;
62 			uint32_t data01 : 1;
63 			uint32_t own : 1;
64 			uint32_t reserved_15_8 : 8;
65 			uint32_t bc : 16;
66 		} get __packed;
67 
68 		struct {
69 			uint32_t reserved_1_0 : 2;
70 			uint32_t bd_ctrl : 6;
71 			uint32_t reserved_15_8 : 8;
72 			uint32_t bc : 16;
73 		} set __packed;
74 
75 	} __packed;
76 	uint32_t   buf_addr;
77 } __packed;
78 
79 /*
80  * Buffer Descriptor Table for the endpoints buffer management.
81  * The driver configuration with 16 fully bidirectional endpoints would require
82  * four BD entries per endpoint and 512 bytes of memory.
83  */
84 static struct buf_descriptor __aligned(512) bdt[(NUM_OF_EP_MAX) * 2 * 2];
85 
86 #define BD_IDX_EP0TX_EVEN		2
87 #define BD_IDX_EP0TX_ODD		3
88 
89 #define EP_BUF_NUMOF_BLOCKS		(NUM_OF_EP_MAX / 2)
90 
91 K_HEAP_DEFINE(ep_buf_pool, 512 * EP_BUF_NUMOF_BLOCKS + 128);
92 
93 struct ep_mem_block {
94 	void *data;
95 };
96 
97 struct usb_ep_ctrl_data {
98 	struct ep_status {
99 		uint16_t in_enabled : 1;
100 		uint16_t out_enabled : 1;
101 		uint16_t in_data1 : 1;
102 		uint16_t out_data1 : 1;
103 		uint16_t in_odd : 1;
104 		uint16_t out_odd : 1;
105 		uint16_t in_stalled : 1;
106 		uint16_t out_stalled : 1;
107 	} status;
108 	uint16_t mps_in;
109 	uint16_t mps_out;
110 	struct ep_mem_block mblock_in;
111 	struct ep_mem_block mblock_out;
112 	usb_dc_ep_callback cb_in;
113 	usb_dc_ep_callback cb_out;
114 };
115 
116 #define USBD_THREAD_STACK_SIZE		1024
117 
118 struct usb_device_data {
119 	usb_dc_status_callback status_cb;
120 	uint8_t address;
121 	uint32_t bd_active;
122 	struct usb_ep_ctrl_data ep_ctrl[NUM_OF_EP_MAX];
123 	bool attached;
124 
125 	K_KERNEL_STACK_MEMBER(thread_stack, USBD_THREAD_STACK_SIZE);
126 	struct k_thread thread;
127 };
128 
129 static struct usb_device_data dev_data;
130 
131 #define USB_DC_CB_TYPE_MGMT		0
132 #define USB_DC_CB_TYPE_EP		1
133 
134 struct cb_msg {
135 	uint8_t ep;
136 	uint8_t type;
137 	uint32_t cb;
138 };
139 
140 K_MSGQ_DEFINE(usb_dc_msgq, sizeof(struct cb_msg), 10, 4);
141 static void usb_kinetis_isr_handler(void);
142 
143 /*
144  * This function returns the BD element index based on
145  * endpoint address and the odd bit.
146  */
get_bdt_idx(uint8_t ep,uint8_t odd)147 static inline uint8_t get_bdt_idx(uint8_t ep, uint8_t odd)
148 {
149 	if (ep & USB_EP_DIR_IN) {
150 		return ((((KINETIS_ADDR2IDX(ep)) * 4) + 2  + (odd & 1)));
151 	}
152 	return ((((KINETIS_ADDR2IDX(ep)) * 4) + (odd & 1)));
153 }
154 
kinetis_usb_init(void)155 static int kinetis_usb_init(void)
156 {
157 #if !DT_INST_PROP(0, no_voltage_regulator)
158 	/* enable USB voltage regulator */
159 	SIM->SOPT1 |= SIM_SOPT1_USBREGEN_MASK;
160 #endif
161 
162 	USB0->USBTRC0 |= USB_USBTRC0_USBRESET_MASK;
163 	k_busy_wait(2000);
164 
165 	USB0->CTL = 0;
166 	/* enable USB module, AKA USBEN bit in CTL1 register */
167 	USB0->CTL |= USB_CTL_USBENSOFEN_MASK;
168 
169 	if ((USB0->PERID != USBFSOTG_PERID) ||
170 	    (USB0->REV != USBFSOTG_REV)) {
171 		return -1;
172 	}
173 
174 	USB0->BDTPAGE1 = (uint8_t)(((uint32_t)bdt) >> 8);
175 	USB0->BDTPAGE2 = (uint8_t)(((uint32_t)bdt) >> 16);
176 	USB0->BDTPAGE3 = (uint8_t)(((uint32_t)bdt) >> 24);
177 
178 	/* clear interrupt flags */
179 	USB0->ISTAT = 0xFF;
180 
181 	/* enable reset interrupt */
182 	USB0->INTEN = USB_INTEN_USBRSTEN_MASK;
183 
184 	USB0->USBCTRL = USB_USBCTRL_PDE_MASK;
185 
186 
187 
188 	LOG_DBG("");
189 
190 	return 0;
191 }
192 
usb_dc_reset(void)193 int usb_dc_reset(void)
194 {
195 	for (uint8_t i = 0; i < 16; i++) {
196 		USB0->ENDPOINT[i].ENDPT = 0;
197 	}
198 	dev_data.bd_active = 0U;
199 	dev_data.address = 0U;
200 
201 	USB0->CTL |= USB_CTL_ODDRST_MASK;
202 	USB0->CTL &= ~USB_CTL_ODDRST_MASK;
203 
204 	/* Clear interrupt status flags */
205 	USB0->ISTAT = 0xFF;
206 	/* Clear error flags */
207 	USB0->ERRSTAT = 0xFF;
208 	/* Enable all error interrupt sources */
209 	USB0->ERREN = 0xFF;
210 	/* Reset default address */
211 	USB0->ADDR = 0x00;
212 
213 	USB0->INTEN = (USB_INTEN_USBRSTEN_MASK |
214 		       USB_INTEN_TOKDNEEN_MASK |
215 		       USB_INTEN_SLEEPEN_MASK  |
216 		       USB_INTEN_SOFTOKEN_MASK |
217 		       USB_INTEN_STALLEN_MASK |
218 		       USB_INTEN_ERROREN_MASK);
219 
220 	LOG_DBG("");
221 
222 	return 0;
223 }
224 
usb_dc_attach(void)225 int usb_dc_attach(void)
226 {
227 	if (dev_data.attached) {
228 		LOG_WRN("already attached");
229 	}
230 
231 	kinetis_usb_init();
232 
233 	/*
234 	 * Call usb_dc_reset here because the device stack does not make it
235 	 * after USB_DC_RESET status event.
236 	 */
237 	usb_dc_reset();
238 
239 	dev_data.attached = 1;
240 	LOG_DBG("attached");
241 
242 	/* non-OTG device mode, enable DP Pullup */
243 	USB0->CONTROL = USB_CONTROL_DPPULLUPNONOTG_MASK;
244 
245 	return 0;
246 }
247 
usb_dc_detach(void)248 int usb_dc_detach(void)
249 {
250 	LOG_DBG("");
251 	/* disable USB and DP Pullup */
252 	USB0->CTL  &= ~USB_CTL_USBENSOFEN_MASK;
253 	USB0->CONTROL &= ~USB_CONTROL_DPPULLUPNONOTG_MASK;
254 
255 	return 0;
256 }
257 
usb_dc_set_address(const uint8_t addr)258 int usb_dc_set_address(const uint8_t addr)
259 {
260 	LOG_DBG("");
261 
262 	if (!dev_data.attached) {
263 		return -EINVAL;
264 	}
265 
266 	/*
267 	 * The device stack tries to set the address before
268 	 * sending the ACK with ZLP, which is totally stupid,
269 	 * as workaround the address will be buffered and
270 	 * placed later inside isr handler (see KINETIS_IN_TOKEN).
271 	 */
272 	dev_data.address = 0x80 | (addr & 0x7f);
273 
274 	return 0;
275 }
276 
usb_dc_ep_check_cap(const struct usb_dc_ep_cfg_data * const cfg)277 int usb_dc_ep_check_cap(const struct usb_dc_ep_cfg_data * const cfg)
278 {
279 	uint8_t ep_idx = USB_EP_GET_IDX(cfg->ep_addr);
280 
281 	if (ep_idx > (NUM_OF_EP_MAX - 1)) {
282 		LOG_ERR("endpoint index/address out of range");
283 		return -EINVAL;
284 	}
285 
286 	switch (cfg->ep_type) {
287 	case USB_DC_EP_CONTROL:
288 		if (cfg->ep_mps > USB_MAX_CTRL_MPS) {
289 			return -EINVAL;
290 		}
291 		return 0;
292 	case USB_DC_EP_BULK:
293 		if (cfg->ep_mps > USB_MAX_FS_BULK_MPS) {
294 			return -EINVAL;
295 		}
296 		break;
297 	case USB_DC_EP_INTERRUPT:
298 		if (cfg->ep_mps > USB_MAX_FS_INT_MPS) {
299 			return -EINVAL;
300 		}
301 		break;
302 	case USB_DC_EP_ISOCHRONOUS:
303 		if (cfg->ep_mps > USB_MAX_FS_ISO_MPS) {
304 			return -EINVAL;
305 		}
306 		break;
307 	default:
308 		LOG_ERR("Unknown endpoint type!");
309 		return -EINVAL;
310 	}
311 
312 	if (ep_idx & BIT(0)) {
313 		if (USB_EP_GET_DIR(cfg->ep_addr) != USB_EP_DIR_IN) {
314 			LOG_INF("pre-selected as IN endpoint");
315 			return -1;
316 		}
317 	} else {
318 		if (USB_EP_GET_DIR(cfg->ep_addr) != USB_EP_DIR_OUT) {
319 			LOG_INF("pre-selected as OUT endpoint");
320 			return -1;
321 		}
322 	}
323 
324 	return 0;
325 }
326 
usb_dc_ep_configure(const struct usb_dc_ep_cfg_data * const cfg)327 int usb_dc_ep_configure(const struct usb_dc_ep_cfg_data * const cfg)
328 {
329 	uint8_t ep_idx = USB_EP_GET_IDX(cfg->ep_addr);
330 	struct usb_ep_ctrl_data *ep_ctrl;
331 	struct ep_mem_block *block;
332 	uint8_t idx_even;
333 	uint8_t idx_odd;
334 
335 	if (usb_dc_ep_check_cap(cfg)) {
336 		return -EINVAL;
337 	}
338 
339 	idx_even = get_bdt_idx(cfg->ep_addr, 0);
340 	idx_odd = get_bdt_idx(cfg->ep_addr, 1);
341 	ep_ctrl = &dev_data.ep_ctrl[ep_idx];
342 
343 	if (ep_idx && (dev_data.ep_ctrl[ep_idx].status.in_enabled ||
344 	    dev_data.ep_ctrl[ep_idx].status.out_enabled)) {
345 		LOG_WRN("endpoint already configured");
346 		return -EALREADY;
347 	}
348 
349 	LOG_DBG("ep %x, mps %d, type %d", cfg->ep_addr, cfg->ep_mps,
350 		cfg->ep_type);
351 
352 	if (USB_EP_DIR_IS_OUT(cfg->ep_addr)) {
353 		block = &(ep_ctrl->mblock_out);
354 	} else {
355 		block = &(ep_ctrl->mblock_in);
356 	}
357 
358 	if (bdt[idx_even].buf_addr) {
359 		k_heap_free(&ep_buf_pool, block->data);
360 	}
361 
362 	USB0->ENDPOINT[ep_idx].ENDPT = 0;
363 	(void)memset(&bdt[idx_even], 0, sizeof(struct buf_descriptor));
364 	(void)memset(&bdt[idx_odd], 0, sizeof(struct buf_descriptor));
365 
366 	block->data = k_heap_alloc(&ep_buf_pool, cfg->ep_mps * 2U, K_NO_WAIT);
367 	if (block->data != NULL) {
368 		(void)memset(block->data, 0, cfg->ep_mps * 2U);
369 	} else {
370 		LOG_ERR("Memory allocation time-out");
371 		return -ENOMEM;
372 	}
373 
374 	bdt[idx_even].buf_addr = (uint32_t)block->data;
375 	LOG_INF("idx_even %x", (uint32_t)block->data);
376 	bdt[idx_odd].buf_addr = (uint32_t)((uint8_t *)block->data + cfg->ep_mps);
377 	LOG_INF("idx_odd %x", (uint32_t)((uint8_t *)block->data + cfg->ep_mps));
378 
379 	if (cfg->ep_addr & USB_EP_DIR_IN) {
380 		dev_data.ep_ctrl[ep_idx].mps_in = cfg->ep_mps;
381 	} else {
382 		dev_data.ep_ctrl[ep_idx].mps_out = cfg->ep_mps;
383 	}
384 
385 	bdt[idx_even].set.bc = cfg->ep_mps;
386 	bdt[idx_odd].set.bc = cfg->ep_mps;
387 
388 	dev_data.ep_ctrl[ep_idx].status.out_data1 = false;
389 	dev_data.ep_ctrl[ep_idx].status.in_data1 = false;
390 
391 	switch (cfg->ep_type) {
392 	case USB_DC_EP_CONTROL:
393 		LOG_DBG("configure control endpoint");
394 		USB0->ENDPOINT[ep_idx].ENDPT |= (USB_ENDPT_EPHSHK_MASK |
395 						 USB_ENDPT_EPRXEN_MASK |
396 						 USB_ENDPT_EPTXEN_MASK);
397 		break;
398 	case USB_DC_EP_BULK:
399 	case USB_DC_EP_INTERRUPT:
400 		USB0->ENDPOINT[ep_idx].ENDPT |= USB_ENDPT_EPHSHK_MASK;
401 		if (USB_EP_DIR_IS_OUT(cfg->ep_addr)) {
402 			USB0->ENDPOINT[ep_idx].ENDPT |= USB_ENDPT_EPRXEN_MASK;
403 		} else {
404 			USB0->ENDPOINT[ep_idx].ENDPT |= USB_ENDPT_EPTXEN_MASK;
405 		}
406 		break;
407 	case USB_DC_EP_ISOCHRONOUS:
408 		if (USB_EP_DIR_IS_OUT(cfg->ep_addr)) {
409 			USB0->ENDPOINT[ep_idx].ENDPT |= USB_ENDPT_EPRXEN_MASK;
410 		} else {
411 			USB0->ENDPOINT[ep_idx].ENDPT |= USB_ENDPT_EPTXEN_MASK;
412 		}
413 		break;
414 	default:
415 		return -EINVAL;
416 	}
417 
418 	return 0;
419 }
420 
usb_dc_ep_set_stall(const uint8_t ep)421 int usb_dc_ep_set_stall(const uint8_t ep)
422 {
423 	uint8_t ep_idx = USB_EP_GET_IDX(ep);
424 	uint8_t bd_idx;
425 
426 	if (ep_idx > (NUM_OF_EP_MAX - 1)) {
427 		LOG_ERR("Wrong endpoint index/address");
428 		return -EINVAL;
429 	}
430 
431 	LOG_DBG("ep %x, idx %d", ep, ep_idx);
432 
433 	if (USB_EP_DIR_IS_OUT(ep)) {
434 		dev_data.ep_ctrl[ep_idx].status.out_stalled = 1U;
435 		bd_idx = get_bdt_idx(ep,
436 				     ~dev_data.ep_ctrl[ep_idx].status.out_odd);
437 	} else {
438 		dev_data.ep_ctrl[ep_idx].status.in_stalled = 1U;
439 		bd_idx = get_bdt_idx(ep,
440 				     dev_data.ep_ctrl[ep_idx].status.in_odd);
441 	}
442 
443 	bdt[bd_idx].set.bd_ctrl = BD_STALL_MASK | BD_DTS_MASK | BD_OWN_MASK;
444 
445 	return 0;
446 }
447 
usb_dc_ep_clear_stall(const uint8_t ep)448 int usb_dc_ep_clear_stall(const uint8_t ep)
449 {
450 	uint8_t ep_idx = USB_EP_GET_IDX(ep);
451 	uint8_t bd_idx;
452 
453 	if (ep_idx > (NUM_OF_EP_MAX - 1)) {
454 		LOG_ERR("Wrong endpoint index/address");
455 		return -EINVAL;
456 	}
457 
458 	LOG_DBG("ep %x, idx %d", ep, ep_idx);
459 	USB0->ENDPOINT[ep_idx].ENDPT &= ~USB_ENDPT_EPSTALL_MASK;
460 
461 	if (USB_EP_DIR_IS_OUT(ep)) {
462 		dev_data.ep_ctrl[ep_idx].status.out_stalled = 0U;
463 		dev_data.ep_ctrl[ep_idx].status.out_data1 = false;
464 		bd_idx = get_bdt_idx(ep,
465 				     ~dev_data.ep_ctrl[ep_idx].status.out_odd);
466 		bdt[bd_idx].set.bd_ctrl = 0U;
467 		bdt[bd_idx].set.bd_ctrl = BD_DTS_MASK | BD_OWN_MASK;
468 	} else {
469 		dev_data.ep_ctrl[ep_idx].status.in_stalled = 0U;
470 		dev_data.ep_ctrl[ep_idx].status.in_data1 = false;
471 		bd_idx = get_bdt_idx(ep,
472 				     dev_data.ep_ctrl[ep_idx].status.in_odd);
473 		bdt[bd_idx].set.bd_ctrl = 0U;
474 	}
475 
476 	/* Resume TX token processing, see USBx_CTL field descriptions */
477 	if (ep == 0U) {
478 		USB0->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK;
479 	}
480 
481 	return 0;
482 }
483 
usb_dc_ep_is_stalled(const uint8_t ep,uint8_t * const stalled)484 int usb_dc_ep_is_stalled(const uint8_t ep, uint8_t *const stalled)
485 {
486 	uint8_t ep_idx = USB_EP_GET_IDX(ep);
487 
488 	if (ep_idx > (NUM_OF_EP_MAX - 1)) {
489 		LOG_ERR("Wrong endpoint index/address");
490 		return -EINVAL;
491 	}
492 
493 	LOG_DBG("ep %x, idx %d", ep_idx, ep);
494 	if (!stalled) {
495 		return -EINVAL;
496 	}
497 
498 	*stalled = 0U;
499 	if (USB_EP_DIR_IS_OUT(ep)) {
500 		*stalled = dev_data.ep_ctrl[ep_idx].status.out_stalled;
501 	} else {
502 		*stalled = dev_data.ep_ctrl[ep_idx].status.in_stalled;
503 	}
504 
505 	uint8_t bd_idx = get_bdt_idx(ep,
506 			dev_data.ep_ctrl[ep_idx].status.in_odd);
507 	LOG_WRN("active bd ctrl: %x", bdt[bd_idx].set.bd_ctrl);
508 	bd_idx = get_bdt_idx(ep,
509 			~dev_data.ep_ctrl[ep_idx].status.in_odd);
510 	LOG_WRN("next bd ctrl: %x", bdt[bd_idx].set.bd_ctrl);
511 
512 	return 0;
513 }
514 
usb_dc_ep_halt(const uint8_t ep)515 int usb_dc_ep_halt(const uint8_t ep)
516 {
517 	return usb_dc_ep_set_stall(ep);
518 }
519 
usb_dc_ep_enable(const uint8_t ep)520 int usb_dc_ep_enable(const uint8_t ep)
521 {
522 	uint8_t ep_idx = USB_EP_GET_IDX(ep);
523 	uint8_t idx_even;
524 	uint8_t idx_odd;
525 
526 	if (ep_idx > (NUM_OF_EP_MAX - 1)) {
527 		LOG_ERR("Wrong endpoint index/address");
528 		return -EINVAL;
529 	}
530 
531 	idx_even = get_bdt_idx(ep, 0);
532 	idx_odd = get_bdt_idx(ep, 1);
533 
534 	if (ep_idx && (dev_data.ep_ctrl[ep_idx].status.in_enabled ||
535 	    dev_data.ep_ctrl[ep_idx].status.out_enabled)) {
536 		LOG_WRN("endpoint 0x%x already enabled", ep);
537 		return -EALREADY;
538 	}
539 
540 	if (USB_EP_DIR_IS_OUT(ep)) {
541 		bdt[idx_even].set.bd_ctrl = BD_DTS_MASK | BD_OWN_MASK;
542 		bdt[idx_odd].set.bd_ctrl = 0U;
543 		dev_data.ep_ctrl[ep_idx].status.out_odd = 0U;
544 		dev_data.ep_ctrl[ep_idx].status.out_stalled = 0U;
545 		dev_data.ep_ctrl[ep_idx].status.out_data1 = false;
546 		dev_data.ep_ctrl[ep_idx].status.out_enabled = true;
547 	} else {
548 		bdt[idx_even].bd_fields = 0U;
549 		bdt[idx_odd].bd_fields = 0U;
550 		dev_data.ep_ctrl[ep_idx].status.in_odd = 0U;
551 		dev_data.ep_ctrl[ep_idx].status.in_stalled = 0U;
552 		dev_data.ep_ctrl[ep_idx].status.in_data1 = false;
553 		dev_data.ep_ctrl[ep_idx].status.in_enabled = true;
554 	}
555 
556 	LOG_INF("ep 0x%x, ep_idx %d", ep, ep_idx);
557 
558 	return 0;
559 }
560 
usb_dc_ep_disable(const uint8_t ep)561 int usb_dc_ep_disable(const uint8_t ep)
562 {
563 	uint8_t ep_idx = USB_EP_GET_IDX(ep);
564 	uint8_t idx_even;
565 	uint8_t idx_odd;
566 
567 	if (ep_idx > (NUM_OF_EP_MAX - 1)) {
568 		LOG_ERR("Wrong endpoint index/address");
569 		return -EINVAL;
570 	}
571 
572 	idx_even = get_bdt_idx(ep, 0);
573 	idx_odd = get_bdt_idx(ep, 1);
574 
575 	LOG_INF("ep %x, idx %d", ep_idx, ep);
576 
577 	bdt[idx_even].bd_fields = 0U;
578 	bdt[idx_odd].bd_fields = 0U;
579 	if (USB_EP_DIR_IS_OUT(ep)) {
580 		dev_data.ep_ctrl[ep_idx].status.out_enabled = false;
581 	} else {
582 		dev_data.ep_ctrl[ep_idx].status.in_enabled = false;
583 	}
584 
585 	return 0;
586 }
587 
usb_dc_ep_flush(const uint8_t ep)588 int usb_dc_ep_flush(const uint8_t ep)
589 {
590 	uint8_t ep_idx = USB_EP_GET_IDX(ep);
591 
592 	if (ep_idx > (NUM_OF_EP_MAX - 1)) {
593 		LOG_ERR("Wrong endpoint index/address");
594 		return -EINVAL;
595 	}
596 
597 	LOG_DBG("ep %x, idx %d", ep_idx, ep);
598 
599 	return 0;
600 }
601 
usb_dc_ep_write(const uint8_t ep,const uint8_t * const data,const uint32_t data_len,uint32_t * const ret_bytes)602 int usb_dc_ep_write(const uint8_t ep, const uint8_t *const data,
603 		    const uint32_t data_len, uint32_t * const ret_bytes)
604 {
605 	uint8_t ep_idx = USB_EP_GET_IDX(ep);
606 	uint32_t len_to_send = data_len;
607 	uint8_t odd;
608 	uint8_t bd_idx;
609 	uint8_t *bufp;
610 
611 	if (ep_idx > (NUM_OF_EP_MAX - 1)) {
612 		LOG_ERR("Wrong endpoint index/address");
613 		return -EINVAL;
614 	}
615 
616 	odd = dev_data.ep_ctrl[ep_idx].status.in_odd;
617 	bd_idx = get_bdt_idx(ep, odd);
618 	bufp = (uint8_t *)bdt[bd_idx].buf_addr;
619 
620 	if (USB_EP_GET_DIR(ep) != USB_EP_DIR_IN) {
621 		LOG_ERR("Wrong endpoint direction");
622 		return -EINVAL;
623 	}
624 
625 	if (dev_data.ep_ctrl[ep_idx].status.in_stalled) {
626 		LOG_WRN("endpoint is stalled");
627 		return -EBUSY;
628 	}
629 
630 	while (bdt[bd_idx].get.own) {
631 		LOG_DBG("ep 0x%x is busy", ep);
632 		k_yield();
633 	}
634 
635 	LOG_DBG("bd idx %x bufp %p odd %d", bd_idx, bufp, odd);
636 
637 	if (data_len > dev_data.ep_ctrl[ep_idx].mps_in) {
638 		len_to_send = dev_data.ep_ctrl[ep_idx].mps_in;
639 	}
640 
641 	bdt[bd_idx].set.bc = len_to_send;
642 
643 	for (uint32_t n = 0; n < len_to_send; n++) {
644 		bufp[n] = data[n];
645 	}
646 
647 	dev_data.ep_ctrl[ep_idx].status.in_odd = ~odd;
648 	if (dev_data.ep_ctrl[ep_idx].status.in_data1) {
649 		bdt[bd_idx].set.bd_ctrl = BD_DTS_MASK |
650 					  BD_DATA01_MASK |
651 					  BD_OWN_MASK;
652 	} else {
653 		bdt[bd_idx].set.bd_ctrl = BD_DTS_MASK | BD_OWN_MASK;
654 	}
655 
656 	/* Toggle next Data1 */
657 	dev_data.ep_ctrl[ep_idx].status.in_data1 ^= 1;
658 
659 	LOG_DBG("ep 0x%x write %d bytes from %d", ep, len_to_send, data_len);
660 
661 	if (ret_bytes) {
662 		*ret_bytes = len_to_send;
663 	}
664 
665 	return 0;
666 }
667 
usb_dc_ep_read_wait(uint8_t ep,uint8_t * data,uint32_t max_data_len,uint32_t * read_bytes)668 int usb_dc_ep_read_wait(uint8_t ep, uint8_t *data, uint32_t max_data_len,
669 			uint32_t *read_bytes)
670 {
671 	uint8_t ep_idx = USB_EP_GET_IDX(ep);
672 	uint32_t data_len;
673 	uint8_t bd_idx;
674 	uint8_t *bufp;
675 
676 	if (ep_idx > (NUM_OF_EP_MAX - 1)) {
677 		LOG_ERR("Wrong endpoint index/address");
678 		return -EINVAL;
679 	}
680 
681 	/* select the index of active endpoint buffer */
682 	bd_idx = get_bdt_idx(ep, dev_data.ep_ctrl[ep_idx].status.out_odd);
683 	bufp = (uint8_t *)bdt[bd_idx].buf_addr;
684 
685 	if (USB_EP_GET_DIR(ep) != USB_EP_DIR_OUT) {
686 		LOG_ERR("Wrong endpoint direction");
687 		return -EINVAL;
688 	}
689 
690 	if (dev_data.ep_ctrl[ep_idx].status.out_stalled) {
691 		LOG_WRN("endpoint is stalled");
692 		return -EBUSY;
693 	}
694 
695 	/* Allow to read 0 bytes */
696 	if (!data && max_data_len) {
697 		LOG_ERR("Wrong arguments");
698 		return -EINVAL;
699 	}
700 
701 	while (bdt[bd_idx].get.own) {
702 		LOG_ERR("Endpoint is occupied by the controller");
703 		return -EBUSY;
704 	}
705 
706 	data_len  = bdt[bd_idx].get.bc;
707 
708 	if (!data && !max_data_len) {
709 		/*
710 		 * When both buffer and max data to read are zero return
711 		 * the available data in buffer.
712 		 */
713 		if (read_bytes) {
714 			*read_bytes = data_len;
715 		}
716 		return 0;
717 	}
718 
719 	if (data_len > max_data_len) {
720 		LOG_WRN("Not enough room to copy all the data!");
721 		data_len = max_data_len;
722 	}
723 
724 	if (data != NULL) {
725 		for (uint32_t i = 0; i < data_len; i++) {
726 			data[i] = bufp[i];
727 		}
728 	}
729 
730 	LOG_DBG("Read idx %d, req %d, read %d bytes", bd_idx, max_data_len,
731 		data_len);
732 
733 	if (read_bytes) {
734 		*read_bytes = data_len;
735 	}
736 
737 	return 0;
738 }
739 
740 
usb_dc_ep_read_continue(uint8_t ep)741 int usb_dc_ep_read_continue(uint8_t ep)
742 {
743 	uint8_t ep_idx = USB_EP_GET_IDX(ep);
744 	uint8_t bd_idx;
745 
746 	if (ep_idx > (NUM_OF_EP_MAX - 1)) {
747 		LOG_ERR("Wrong endpoint index/address");
748 		return -EINVAL;
749 	}
750 
751 	bd_idx = get_bdt_idx(ep, dev_data.ep_ctrl[ep_idx].status.out_odd);
752 
753 	if (USB_EP_GET_DIR(ep) != USB_EP_DIR_OUT) {
754 		LOG_ERR("Wrong endpoint direction");
755 		return -EINVAL;
756 	}
757 
758 	if (bdt[bd_idx].get.own) {
759 		/* May occur when usb_transfer initializes the OUT transfer */
760 		LOG_WRN("Current buffer is claimed by the controller");
761 		return 0;
762 	}
763 
764 	/* select the index of the next endpoint buffer */
765 	bd_idx = get_bdt_idx(ep, ~dev_data.ep_ctrl[ep_idx].status.out_odd);
766 	/* Update next toggle bit */
767 	dev_data.ep_ctrl[ep_idx].status.out_data1 ^= 1;
768 	bdt[bd_idx].set.bc = dev_data.ep_ctrl[ep_idx].mps_out;
769 
770 	/* Reset next buffer descriptor and set next toggle bit  */
771 	if (dev_data.ep_ctrl[ep_idx].status.out_data1) {
772 		bdt[bd_idx].set.bd_ctrl = BD_DTS_MASK |
773 					  BD_DATA01_MASK |
774 					  BD_OWN_MASK;
775 	} else {
776 		bdt[bd_idx].set.bd_ctrl = BD_DTS_MASK | BD_OWN_MASK;
777 	}
778 
779 	/* Resume TX token processing, see USBx_CTL field descriptions */
780 	if (ep_idx == 0U) {
781 		USB0->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK;
782 	}
783 
784 	LOG_DBG("idx next %x", bd_idx);
785 
786 	return 0;
787 }
788 
usb_dc_ep_read(const uint8_t ep,uint8_t * const data,const uint32_t max_data_len,uint32_t * const read_bytes)789 int usb_dc_ep_read(const uint8_t ep, uint8_t *const data,
790 		   const uint32_t max_data_len, uint32_t *const read_bytes)
791 {
792 	int retval = usb_dc_ep_read_wait(ep, data, max_data_len, read_bytes);
793 
794 	if (retval) {
795 		return retval;
796 	}
797 
798 	if (!data && !max_data_len) {
799 		/* When both buffer and max data to read are zero the above
800 		 * call would fetch the data len and we simply return.
801 		 */
802 		return 0;
803 	}
804 
805 	if (usb_dc_ep_read_continue(ep) != 0) {
806 		return -EINVAL;
807 	}
808 
809 	LOG_DBG("");
810 
811 	return 0;
812 }
813 
usb_dc_ep_set_callback(const uint8_t ep,const usb_dc_ep_callback cb)814 int usb_dc_ep_set_callback(const uint8_t ep, const usb_dc_ep_callback cb)
815 {
816 	uint8_t ep_idx = USB_EP_GET_IDX(ep);
817 
818 	if (ep_idx > (NUM_OF_EP_MAX - 1)) {
819 		LOG_ERR("Wrong endpoint index/address");
820 		return -EINVAL;
821 	}
822 
823 	if (!dev_data.attached) {
824 		return -EINVAL;
825 	}
826 
827 	if (ep & USB_EP_DIR_IN) {
828 		dev_data.ep_ctrl[ep_idx].cb_in = cb;
829 	} else {
830 		dev_data.ep_ctrl[ep_idx].cb_out = cb;
831 	}
832 	LOG_DBG("ep_idx %x", ep_idx);
833 
834 	return 0;
835 }
836 
usb_dc_set_status_callback(const usb_dc_status_callback cb)837 void usb_dc_set_status_callback(const usb_dc_status_callback cb)
838 {
839 	LOG_DBG("");
840 
841 	dev_data.status_cb = cb;
842 }
843 
usb_dc_ep_mps(const uint8_t ep)844 int usb_dc_ep_mps(const uint8_t ep)
845 {
846 	uint8_t ep_idx = USB_EP_GET_IDX(ep);
847 
848 	if (ep_idx > (NUM_OF_EP_MAX - 1)) {
849 		LOG_ERR("Wrong endpoint index/address");
850 		return -EINVAL;
851 	}
852 
853 	if (ep & USB_EP_DIR_IN) {
854 		return dev_data.ep_ctrl[ep_idx].mps_in;
855 	} else {
856 		return dev_data.ep_ctrl[ep_idx].mps_out;
857 	}
858 }
859 
reenable_control_endpoints(void)860 static inline void reenable_control_endpoints(void)
861 {
862 	struct usb_dc_ep_cfg_data ep_cfg;
863 
864 	/* Reconfigure control endpoint 0 after a reset */
865 	ep_cfg.ep_addr = USB_CONTROL_EP_OUT;
866 	ep_cfg.ep_mps = USB_CONTROL_EP_MPS;
867 	ep_cfg.ep_type = USB_DC_EP_CONTROL;
868 	usb_dc_ep_configure(&ep_cfg);
869 	ep_cfg.ep_addr = USB_CONTROL_EP_IN;
870 	usb_dc_ep_configure(&ep_cfg);
871 
872 	/* Enable both endpoint directions */
873 	usb_dc_ep_enable(USB_CONTROL_EP_OUT);
874 	usb_dc_ep_enable(USB_CONTROL_EP_IN);
875 }
876 
usb_kinetis_isr_handler(void)877 static void usb_kinetis_isr_handler(void)
878 {
879 	uint8_t istatus  = USB0->ISTAT;
880 	uint8_t status  = USB0->STAT;
881 	struct cb_msg msg;
882 
883 
884 	if (istatus & USB_ISTAT_USBRST_MASK) {
885 		dev_data.address = 0U;
886 		USB0->ADDR = (uint8_t)0;
887 		/*
888 		 * Device reset is not possible because the stack does not
889 		 * configure the endpoints after the USB_DC_RESET event,
890 		 * therefore, we must re-enable the default control 0 endpoint
891 		 * after a reset event
892 		 */
893 		USB0->CTL |= USB_CTL_ODDRST_MASK;
894 		USB0->CTL &= ~USB_CTL_ODDRST_MASK;
895 		reenable_control_endpoints();
896 		msg.ep = 0U;
897 		msg.type = USB_DC_CB_TYPE_MGMT;
898 		msg.cb = USB_DC_RESET;
899 		k_msgq_put(&usb_dc_msgq, &msg, K_NO_WAIT);
900 	}
901 
902 	if (istatus == USB_ISTAT_ERROR_MASK) {
903 		USB0->ERRSTAT = 0xFF;
904 		msg.ep = 0U;
905 		msg.type = USB_DC_CB_TYPE_MGMT;
906 		msg.cb = USB_DC_ERROR;
907 		k_msgq_put(&usb_dc_msgq, &msg, K_NO_WAIT);
908 	}
909 
910 	if (istatus & USB_ISTAT_STALL_MASK) {
911 		if (dev_data.ep_ctrl[0].status.out_stalled) {
912 			usb_dc_ep_clear_stall(0);
913 		}
914 		if (dev_data.ep_ctrl[0].status.in_stalled) {
915 			usb_dc_ep_clear_stall(0x80);
916 		}
917 	}
918 
919 	if (istatus & USB_ISTAT_TOKDNE_MASK) {
920 
921 		uint8_t ep_idx = status >> USB_STAT_ENDP_SHIFT;
922 		uint8_t ep = ((status << 4) & USB_EP_DIR_IN) | ep_idx;
923 		uint8_t odd = (status & USB_STAT_ODD_MASK) >> USB_STAT_ODD_SHIFT;
924 		uint8_t idx = get_bdt_idx(ep, odd);
925 		uint8_t token_pid = bdt[idx].get.tok_pid;
926 
927 		msg.ep = ep;
928 		msg.type = USB_DC_CB_TYPE_EP;
929 
930 		switch (token_pid) {
931 		case KINETIS_SETUP_TOKEN:
932 			dev_data.ep_ctrl[ep_idx].status.out_odd = odd;
933 			/* clear tx entries */
934 			bdt[BD_IDX_EP0TX_EVEN].bd_fields = 0U;
935 			bdt[BD_IDX_EP0TX_ODD].bd_fields = 0U;
936 			/*
937 			 * Set/Reset here the toggle bits for control endpoint
938 			 * because the device stack does not care about it.
939 			 */
940 			dev_data.ep_ctrl[ep_idx].status.in_data1 = true;
941 			dev_data.ep_ctrl[ep_idx].status.out_data1 = false;
942 			dev_data.ep_ctrl[ep_idx].status.out_odd = odd;
943 
944 			msg.cb = USB_DC_EP_SETUP;
945 			k_msgq_put(&usb_dc_msgq, &msg, K_NO_WAIT);
946 			break;
947 		case KINETIS_OUT_TOKEN:
948 			dev_data.ep_ctrl[ep_idx].status.out_odd = odd;
949 
950 			msg.cb = USB_DC_EP_DATA_OUT;
951 			k_msgq_put(&usb_dc_msgq, &msg, K_NO_WAIT);
952 			break;
953 		case KINETIS_IN_TOKEN:
954 			/* SET ADDRESS workaround */
955 			if (dev_data.address & 0x80) {
956 				USB0->ADDR = dev_data.address & 0x7f;
957 				dev_data.address = 0U;
958 			}
959 
960 			msg.cb = USB_DC_EP_DATA_IN;
961 			k_msgq_put(&usb_dc_msgq, &msg, K_NO_WAIT);
962 			break;
963 		default:
964 			break;
965 		}
966 	}
967 
968 	if (istatus & USB_ISTAT_SLEEP_MASK) {
969 		/* Enable resume interrupt */
970 		USB0->INTEN |= USB_INTEN_RESUMEEN_MASK;
971 		msg.ep = 0U;
972 		msg.type = USB_DC_CB_TYPE_MGMT;
973 		msg.cb = USB_DC_SUSPEND;
974 		k_msgq_put(&usb_dc_msgq, &msg, K_NO_WAIT);
975 	}
976 
977 	if (istatus & USB_ISTAT_RESUME_MASK) {
978 		/* Disable resume interrupt */
979 		USB0->INTEN &= ~USB_INTEN_RESUMEEN_MASK;
980 		msg.ep = 0U;
981 		msg.type = USB_DC_CB_TYPE_MGMT;
982 		msg.cb = USB_DC_RESUME;
983 		k_msgq_put(&usb_dc_msgq, &msg, K_NO_WAIT);
984 	}
985 
986 	/* Clear interrupt status bits */
987 	USB0->ISTAT = istatus;
988 }
989 
990 /*
991  * This thread is only used to not run the USB device stack and endpoint
992  * callbacks in the ISR context, which happens when an callback function
993  * is called. TODO: something similar should be implemented in the USB
994  * device stack so that it can be used by all drivers.
995  */
usb_kinetis_thread_main(void * arg1,void * unused1,void * unused2)996 static void usb_kinetis_thread_main(void *arg1, void *unused1, void *unused2)
997 {
998 	ARG_UNUSED(arg1);
999 	ARG_UNUSED(unused1);
1000 	ARG_UNUSED(unused2);
1001 	struct cb_msg msg;
1002 	uint8_t ep_idx;
1003 
1004 	while (true) {
1005 		k_msgq_get(&usb_dc_msgq, &msg, K_FOREVER);
1006 		ep_idx = USB_EP_GET_IDX(msg.ep);
1007 
1008 		if (msg.type == USB_DC_CB_TYPE_EP) {
1009 			switch (msg.cb) {
1010 			case USB_DC_EP_SETUP:
1011 				if (dev_data.ep_ctrl[ep_idx].cb_out) {
1012 					dev_data.ep_ctrl[ep_idx].cb_out(msg.ep,
1013 						USB_DC_EP_SETUP);
1014 				}
1015 				break;
1016 			case USB_DC_EP_DATA_OUT:
1017 				if (dev_data.ep_ctrl[ep_idx].cb_out) {
1018 					dev_data.ep_ctrl[ep_idx].cb_out(msg.ep,
1019 						USB_DC_EP_DATA_OUT);
1020 				}
1021 				break;
1022 			case USB_DC_EP_DATA_IN:
1023 				if (dev_data.ep_ctrl[ep_idx].cb_in) {
1024 					dev_data.ep_ctrl[ep_idx].cb_in(msg.ep,
1025 						USB_DC_EP_DATA_IN);
1026 				}
1027 				break;
1028 			default:
1029 				LOG_ERR("unknown msg");
1030 				break;
1031 			}
1032 		} else if (dev_data.status_cb) {
1033 			switch (msg.cb) {
1034 			case USB_DC_RESET:
1035 				dev_data.status_cb(USB_DC_RESET, NULL);
1036 				break;
1037 			case USB_DC_ERROR:
1038 				dev_data.status_cb(USB_DC_ERROR, NULL);
1039 				break;
1040 			case USB_DC_SUSPEND:
1041 				dev_data.status_cb(USB_DC_SUSPEND, NULL);
1042 				break;
1043 			case USB_DC_RESUME:
1044 				dev_data.status_cb(USB_DC_RESUME, NULL);
1045 				break;
1046 			default:
1047 				LOG_ERR("unknown msg");
1048 				break;
1049 			}
1050 		}
1051 	}
1052 }
1053 
usb_kinetis_init(void)1054 static int usb_kinetis_init(void)
1055 {
1056 
1057 	(void)memset(bdt, 0, sizeof(bdt));
1058 	k_thread_create(&dev_data.thread, dev_data.thread_stack,
1059 			USBD_THREAD_STACK_SIZE,
1060 			usb_kinetis_thread_main, NULL, NULL, NULL,
1061 			K_PRIO_COOP(2), 0, K_NO_WAIT);
1062 	k_thread_name_set(&dev_data.thread, "usb_kinetis");
1063 
1064 	IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority),
1065 		    usb_kinetis_isr_handler, 0, 0);
1066 	irq_enable(DT_INST_IRQN(0));
1067 
1068 	return 0;
1069 }
1070 
1071 SYS_INIT(usb_kinetis_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE);
1072