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