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