blob: 6bf09abbbdd54939231086a9a17dd25dfe9ea2d6 [file] [log] [blame]
Kévin Redon69b92d92019-01-24 16:39:20 +01001/**
2 * \file
3 *
4 * \brief SAM USB HPL
5 *
6 * Copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries.
7 *
8 * \asf_license_start
9 *
10 * \page License
11 *
12 * Subject to your compliance with these terms, you may use Microchip
13 * software and any derivatives exclusively with Microchip products.
14 * It is your responsibility to comply with third party license terms applicable
15 * to your use of third party software (including open source software) that
16 * may accompany Microchip software.
17 *
18 * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
19 * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
20 * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
21 * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
22 * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
23 * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
24 * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
25 * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
26 * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
27 * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
28 * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
29 *
30 * \asf_license_stop
31 *
32 */
33
34#include <compiler.h>
35#include <hal_atomic.h>
36#include <hpl_usb.h>
37#include <hpl_usb_device.h>
38
39#include <hpl_usb_config.h>
40#include <string.h>
41#include <utils_assert.h>
42
43/**
44 * \brief Dummy callback function
45 * \return Always false.
46 */
47static bool _dummy_func_no_return(uint32_t unused0, uint32_t unused1)
48{
49 (void)unused0;
50 (void)unused1;
51 return false;
52}
53
54/**
55 * \brief Load USB calibration value from NVM
56 */
57static void _usb_load_calib(void)
58{
59#define NVM_USB_PAD_TRANSN_POS 32
60#define NVM_USB_PAD_TRANSN_SIZE 5
61#define NVM_USB_PAD_TRANSP_POS 37
62#define NVM_USB_PAD_TRANSP_SIZE 5
63#define NVM_USB_PAD_TRIM_POS 42
64#define NVM_USB_PAD_TRIM_SIZE 3
65 Usb * hw = USB;
66 uint32_t pad_transn
67 = (*((uint32_t *)(NVMCTRL_SW0) + (NVM_USB_PAD_TRANSN_POS / 32)) >> (NVM_USB_PAD_TRANSN_POS % 32))
68 & ((1 << NVM_USB_PAD_TRANSN_SIZE) - 1);
69 uint32_t pad_transp
70 = (*((uint32_t *)(NVMCTRL_SW0) + (NVM_USB_PAD_TRANSP_POS / 32)) >> (NVM_USB_PAD_TRANSP_POS % 32))
71 & ((1 << NVM_USB_PAD_TRANSP_SIZE) - 1);
72 uint32_t pad_trim = (*((uint32_t *)(NVMCTRL_SW0) + (NVM_USB_PAD_TRIM_POS / 32)) >> (NVM_USB_PAD_TRIM_POS % 32))
73 & ((1 << NVM_USB_PAD_TRIM_SIZE) - 1);
74 if (pad_transn == 0 || pad_transn == 0x1F) {
75 pad_transn = 9;
76 }
77 if (pad_transp == 0 || pad_transp == 0x1F) {
78 pad_transp = 25;
79 }
80 if (pad_trim == 0 || pad_trim == 0x7) {
81 pad_trim = 6;
82 }
83
84 hw->DEVICE.PADCAL.reg = USB_PADCAL_TRANSN(pad_transn) | USB_PADCAL_TRANSP(pad_transp) | USB_PADCAL_TRIM(pad_trim);
85
86 hw->DEVICE.QOSCTRL.bit.CQOS = 3;
87 hw->DEVICE.QOSCTRL.bit.DQOS = 3;
88}
89
90/** \name USB clock source management */
91/*@{*/
92
93/** USB clock is generated by DFLL. */
94#define USB_CLK_SRC_DFLL 0
95
96/** USB clock is generated by DPLL. */
97#define USB_CLK_SRC_DPLL 1
98
99/** Uses DFLL as USB clock source. */
100#define CONF_USB_D_CLK_SRC USB_CLK_SRC_DFLL
101
102/** Retry for USB remote wakeup sending. */
103#define CONF_USB_RMT_WKUP_RETRY 5
104
105/**
106 * \brief Wait DPLL clock to be ready
107 */
108static inline void _usb_d_dev_wait_dpll_rdy(void)
109{
110#define DPLL_READY_FLAG (OSCCTRL_DPLLSTATUS_CLKRDY | OSCCTRL_DPLLSTATUS_LOCK)
111 while (hri_oscctrl_get_DPLLSTATUS_reg(OSCCTRL, 0, DPLL_READY_FLAG) != DPLL_READY_FLAG)
112 ;
113}
114
115/**
116 * \brief Wait DFLL clock to be ready
117 */
118static inline void _usb_d_dev_wait_dfll_rdy(void)
119{
120 if (hri_oscctrl_get_DFLLCTRLB_MODE_bit(OSCCTRL)) {
121 while (hri_oscctrl_get_STATUS_reg(OSCCTRL, (OSCCTRL_STATUS_DFLLRDY | OSCCTRL_STATUS_DFLLLCKC))
122 != (OSCCTRL_STATUS_DFLLRDY | OSCCTRL_STATUS_DFLLLCKC))
123 ;
124 } else {
125 while (hri_oscctrl_get_STATUS_reg(OSCCTRL, OSCCTRL_STATUS_DFLLRDY) != OSCCTRL_STATUS_DFLLRDY)
126 ;
127 }
128}
129
130/**
131 * \brief Wait USB source clock to be ready
132 * \param[in] clk_src Clock source, could be \ref USB_CLK_SRC_DFLL or
133 * \ref USB_CLK_SRC_DPLL.
134 */
135static inline void _usb_d_dev_wait_clk_rdy(const uint8_t clk_src)
136{
137 if (clk_src == USB_CLK_SRC_DFLL) {
138 _usb_d_dev_wait_dfll_rdy();
139 } else if (clk_src == USB_CLK_SRC_DPLL) {
140 _usb_d_dev_wait_dpll_rdy();
141 }
142}
143
144/*@}*/
145
146/** \name USB general settings */
147/*@{*/
148
149/** Increase the value to be aligned. */
150#define _usb_align_up(val) (((val)&0x3) ? (((val) + 4 - ((val)&0x3))) : (val))
151
152/** Check if the buffer is in RAM (can DMA), or cache needed
153 * \param[in] a Buffer start address.
154 * \param[in] s Buffer size, in number of bytes.
155 * \return \c true If the buffer is in RAM.
156 */
157#define _IN_RAM(a, s) ((0x20000000 <= (uint32_t)(a)) && (((uint32_t)(a) + (s)) < (0x20000000 + 0x00042000)))
158
159/** Check if the address should be placed in RAM. */
160#define _usb_is_addr4dma(addr, size) _IN_RAM((addr), (size))
161
162/** Check if the address is 32-bit aligned. */
163#define _usb_is_aligned(val) (((uint32_t)(val)&0x3) == 0)
164/*@}*/
165
166/* Cache static configurations.
167 * By default, all OUT endpoint have 64 bytes cache. */
168#ifndef CONF_USB_EP0_CACHE
169/** Endpoint cache buffer for OUT transactions (none-control) or SETUP/IN/OUT
170 * transactions (control). */
171#define CONF_USB_EP0_CACHE 64
172#endif
173
174#ifndef CONF_USB_EP0_I_CACHE
175/** Endpoint cache buffer for IN transactions (none-control). */
176#define CONF_USB_EP0_I_CACHE 0
177#endif
178
179#ifndef CONF_USB_EP1_CACHE
180/** Endpoint cache buffer for OUT transactions (none-control) or SETUP/IN/OUT
181 * transactions (control). */
182#define CONF_USB_EP1_CACHE 64
183#endif
184
185#ifndef CONF_USB_EP1_I_CACHE
186/** Endpoint cache buffer for IN transactions (none-control). */
187#define CONF_USB_EP1_I_CACHE 0
188#endif
189
190#ifndef CONF_USB_EP2_CACHE
191/** Endpoint cache buffer for OUT transactions (none-control) or SETUP/IN/OUT
192 * transactions (control). */
193#define CONF_USB_EP2_CACHE 64
194#endif
195
196#ifndef CONF_USB_EP2_I_CACHE
197/** Endpoint cache buffer for IN transactions (none-control). */
198#define CONF_USB_EP2_I_CACHE 0
199#endif
200
201#ifndef CONF_USB_EP3_CACHE
202/** Endpoint cache buffer for OUT transactions (none-control) or SETUP/IN/OUT
203 * transactions (control). */
204#define CONF_USB_EP3_CACHE 64
205#endif
206
207#ifndef CONF_USB_EP3_I_CACHE
208/** Endpoint cache buffer for IN transactions (none-control). */
209#define CONF_USB_EP3_I_CACHE 0
210#endif
211
212#ifndef CONF_USB_EP4_CACHE
213/** Endpoint cache buffer for OUT transactions (none-control) or SETUP/IN/OUT
214 * transactions (control). */
215#define CONF_USB_EP4_CACHE 64
216#endif
217
218#ifndef CONF_USB_EP4_I_CACHE
219/** Endpoint cache buffer for IN transactions (none-control). */
220#define CONF_USB_EP4_I_CACHE 0
221#endif
222
223#ifndef CONF_USB_EP5_CACHE
224/** Endpoint cache buffer for OUT transactions (none-control) or SETUP/IN/OUT
225 * transactions (control). */
226#define CONF_USB_EP5_CACHE 64
227#endif
228
229#ifndef CONF_USB_EP5_I_CACHE
230/** Endpoint cache buffer for IN transactions (none-control). */
231#define CONF_USB_EP5_I_CACHE 0
232#endif
233
234#ifndef CONF_USB_EP6_CACHE
235/** Endpoint cache buffer for OUT transactions (none-control) or SETUP/IN/OUT
236 * transactions (control). */
237#define CONF_USB_EP6_CACHE 64
238#endif
239
240#ifndef CONF_USB_EP6_I_CACHE
241/** Endpoint cache buffer for IN transactions (none-control). */
242#define CONF_USB_EP6_I_CACHE 0
243#endif
244
245#ifndef CONF_USB_EP7_CACHE
246/** Endpoint cache buffer for OUT transactions (none-control) or SETUP/IN/OUT
247 * transactions (control). */
248#define CONF_USB_EP7_CACHE 64
249#endif
250
251#ifndef CONF_USB_EP7_I_CACHE
252/** Endpoint cache buffer for IN transactions (none-control). */
253#define CONF_USB_EP7_I_CACHE 0
254#endif
255
256#ifndef CONF_USB_EP8_CACHE
257/** Endpoint cache buffer for OUT transactions (none-control) or SETUP/IN/OUT
258 * transactions (control). */
259#define CONF_USB_EP8_CACHE 64
260#endif
261
262#ifndef CONF_USB_EP8_I_CACHE
263/** Endpoint cache buffer for IN transactions (none-control). */
264#define CONF_USB_EP8_I_CACHE 0
265#endif
266
267#ifndef CONF_USB_EP9_CACHE
268/** Endpoint cache buffer for OUT transactions (none-control) or SETUP/IN/OUT
269 * transactions (control). */
270#define CONF_USB_EP9_CACHE 64
271#endif
272
273#ifndef CONF_USB_EP9_I_CACHE
274/** Endpoint cache buffer for IN transactions (none-control). */
275#define CONF_USB_EP9_I_CACHE 0
276#endif
277
278/** Endpoint cache buffer for OUT transactions (none-control) or SETUP/IN/OUT
279 * transactions (control). */
280#if CONF_USB_EP0_CACHE
281static uint32_t _usb_ep0_cache[_usb_align_up(CONF_USB_EP0_CACHE) / 4];
282#else
283#define _usb_ep0_cache NULL
284#endif
285
286/** Endpoint cache buffer for IN transactions (none-control). */
287#define _usb_ep0_i_cache NULL
288
289/** Endpoint cache buffer for OUT transactions (none-control) or SETUP/IN/OUT
290 * transactions (control). */
291#if CONF_USB_EP1_CACHE && CONF_USB_D_MAX_EP_N >= 1
292static uint32_t _usb_ep1_cache[_usb_align_up(CONF_USB_EP1_CACHE) / 4];
293#else
294#define _usb_ep1_cache NULL
295#endif
296
297/** Endpoint cache buffer for IN transactions (none-control). */
298#if CONF_USB_EP1_I_CACHE && CONF_USB_D_MAX_EP_N >= 1
299static uint32_t _usb_ep1_i_cache[_usb_align_up(CONF_USB_EP1_I_CACHE) / 4];
300#else
301#define _usb_ep1_i_cache NULL
302#endif
303
304/** Endpoint cache buffer for OUT transactions (none-control) or SETUP/IN/OUT
305 * transactions (control). */
306#if CONF_USB_EP2_CACHE && CONF_USB_D_MAX_EP_N >= 2
307static uint32_t _usb_ep2_cache[_usb_align_up(CONF_USB_EP2_CACHE) / 4];
308#else
309#define _usb_ep2_cache NULL
310#endif
311
312/** Endpoint cache buffer for IN transactions (none-control). */
313#if CONF_USB_EP2_I_CACHE && CONF_USB_D_MAX_EP_N >= 2
314static uint32_t _usb_ep2_i_cache[_usb_align_up(CONF_USB_EP2_I_CACHE) / 4];
315#else
316#define _usb_ep2_i_cache NULL
317#endif
318
319/** Endpoint cache buffer for OUT transactions (none-control) or SETUP/IN/OUT
320 * transactions (control). */
321#if CONF_USB_EP3_CACHE && CONF_USB_D_MAX_EP_N >= 3
322static uint32_t _usb_ep3_cache[_usb_align_up(CONF_USB_EP3_CACHE) / 4];
323#else
324#define _usb_ep3_cache NULL
325#endif
326
327/** Endpoint cache buffer for IN transactions (none-control). */
328#if CONF_USB_EP3_I_CACHE && CONF_USB_D_MAX_EP_N >= 3
329static uint32_t _usb_ep3_i_cache[_usb_align_up(CONF_USB_EP3_I_CACHE) / 4];
330#else
331#define _usb_ep3_i_cache NULL
332#endif
333
334/** Endpoint cache buffer for OUT transactions (none-control) or SETUP/IN/OUT
335 * transactions (control). */
336#if CONF_USB_EP4_CACHE && CONF_USB_D_MAX_EP_N >= 4
337static uint32_t _usb_ep4_cache[_usb_align_up(CONF_USB_EP4_CACHE) / 4];
338#else
339#define _usb_ep4_cache NULL
340#endif
341
342/** Endpoint cache buffer for IN transactions (none-control). */
343#if CONF_USB_EP4_I_CACHE && CONF_USB_D_MAX_EP_N >= 4
344static uint32_t _usb_ep4_i_cache[_usb_align_up(CONF_USB_EP4_I_CACHE) / 4];
345#else
346#define _usb_ep4_i_cache NULL
347#endif
348
349/** Endpoint cache buffer for OUT transactions (none-control) or SETUP/IN/OUT
350 * transactions (control). */
351#if CONF_USB_EP5_CACHE && CONF_USB_D_MAX_EP_N >= 5
352static uint32_t _usb_ep5_cache[_usb_align_up(CONF_USB_EP5_CACHE) / 4];
353#else
354#define _usb_ep5_cache NULL
355#endif
356
357/** Endpoint cache buffer for IN transactions (none-control). */
358#if CONF_USB_EP5_I_CACHE && CONF_USB_D_MAX_EP_N >= 5
359static uint32_t _usb_ep5_i_cache[_usb_align_up(CONF_USB_EP5_I_CACHE) / 4];
360#else
361#define _usb_ep5_i_cache NULL
362#endif
363
364/** Endpoint cache buffer for OUT transactions (none-control) or SETUP/IN/OUT
365 * transactions (control). */
366#if CONF_USB_EP6_CACHE && CONF_USB_D_MAX_EP_N >= 6
367static uint32_t _usb_ep6_cache[_usb_align_up(CONF_USB_EP6_CACHE) / 4];
368#else
369#define _usb_ep6_cache NULL
370#endif
371
372/** Endpoint cache buffer for IN transactions (none-control). */
373#if CONF_USB_EP6_I_CACHE && CONF_USB_D_MAX_EP_N >= 6
374static uint32_t _usb_ep6_i_cache[_usb_align_up(CONF_USB_EP6_I_CACHE) / 4];
375#else
376#define _usb_ep6_i_cache NULL
377#endif
378
379/** Endpoint cache buffer for OUT transactions (none-control) or SETUP/IN/OUT
380 * transactions (control). */
381#if CONF_USB_EP7_CACHE && CONF_USB_D_MAX_EP_N >= 7
382static uint32_t _usb_ep7_cache[_usb_align_up(CONF_USB_EP7_CACHE) / 4];
383#else
384#define _usb_ep7_cache NULL
385#endif
386
387/** Endpoint cache buffer for IN transactions (none-control). */
388#if CONF_USB_EP7_I_CACHE && CONF_USB_D_MAX_EP_N >= 7
389static uint32_t _usb_ep7_i_cache[_usb_align_up(CONF_USB_EP7_I_CACHE) / 4];
390#else
391#define _usb_ep7_i_cache NULL
392#endif
393
394/** Endpoint cache buffer for OUT transactions (none-control) or SETUP/IN/OUT
395 * transactions (control). */
396#if CONF_USB_EP8_CACHE && CONF_USB_D_MAX_EP_N >= 8
397static uint32_t _usb_ep8_cache[_usb_align_up(CONF_USB_EP8_CACHE) / 4];
398#else
399#define _usb_ep8_cache NULL
400#endif
401
402/** Endpoint cache buffer for IN transactions (none-control). */
403#if CONF_USB_EP8_I_CACHE && CONF_USB_D_MAX_EP_N >= 8
404static uint32_t _usb_ep8_i_cache[_usb_align_up(CONF_USB_EP8_I_CACHE) / 4];
405#else
406#define _usb_ep8_i_cache NULL
407#endif
408
409/** Endpoint cache buffer for OUT transactions (none-control) or SETUP/IN/OUT
410 * transactions (control). */
411#if CONF_USB_EP9_CACHE && CONF_USB_D_MAX_EP_N >= 9
412static uint32_t _usb_ep9_cache[_usb_align_up(CONF_USB_EP9_CACHE) / 4];
413#else
414#define _usb_ep9_cache NULL
415#endif
416
417/** Endpoint cache buffer for IN transactions (none-control). */
418#if CONF_USB_EP9_I_CACHE && CONF_USB_D_MAX_EP_N >= 9
419static uint32_t _usb_ep9_i_cache[_usb_align_up(CONF_USB_EP9_I_CACHE) / 4];
420#else
421#define _usb_ep9_i_cache NULL
422#endif
423
424/** Access endpoint cache buffer for OUT transactions (none-control) or
425 * SETUP/IN/OUT transactions (control). */
426#define _USB_EP_CACHE(n) ((void *)_usb_ep##n##_cache)
427
428/** Access endpoint cache buffer for IN transactions (none-control). */
429#define _USB_EP_I_CACHE(n) ((void *)_usb_ep##n##_i_cache)
430
431/** The configuration settings for one of the endpoint hardware. */
432struct _usb_ep_cfg_item {
433 /* Endpoint cache buffer for OUT transactions (none-control) or
434 * SETUP/IN/OUT transactions (control). */
435 void *cache;
436 /* endpoint cache buffer for IN transactions (none-control). */
437 void *i_cache;
438 /* Cache buffer size for OUT transactions (none-control) or
439 * SETUP/IN/OUT transactions (control). */
440 uint16_t size;
441 /* Cache buffer size for IN transactions (none-control). */
442 uint16_t i_size;
443};
444
445/** Build the endpoint configuration settings for one endpoint. */
446#define _USB_EP_CFG_ITEM(n) \
447 { \
448 _USB_EP_CACHE(n), _USB_EP_I_CACHE(n), CONF_USB_EP##n##_CACHE, CONF_USB_EP##n##_I_CACHE, \
449 }
450
451/** The configuration settings for all endpoint. */
452static const struct _usb_ep_cfg_item _usb_ep_cfgs[] = {_USB_EP_CFG_ITEM(0)
453#if CONF_USB_D_MAX_EP_N >= 1
454 ,
455 _USB_EP_CFG_ITEM(1)
456#endif
457#if CONF_USB_D_MAX_EP_N >= 2
458 ,
459 _USB_EP_CFG_ITEM(2)
460#endif
461#if CONF_USB_D_MAX_EP_N >= 3
462 ,
463 _USB_EP_CFG_ITEM(3)
464#endif
465#if CONF_USB_D_MAX_EP_N >= 4
466 ,
467 _USB_EP_CFG_ITEM(4)
468#endif
469#if CONF_USB_D_MAX_EP_N >= 5
470 ,
471 _USB_EP_CFG_ITEM(5)
472#endif
473#if CONF_USB_D_MAX_EP_N >= 6
474 ,
475 _USB_EP_CFG_ITEM(6)
476#endif
477#if CONF_USB_D_MAX_EP_N >= 7
478 ,
479 _USB_EP_CFG_ITEM(7)
480#endif
481#if CONF_USB_D_MAX_EP_N >= 8
482 ,
483 _USB_EP_CFG_ITEM(8)
484#endif
485#if CONF_USB_D_MAX_EP_N >= 9
486 ,
487 _USB_EP_CFG_ITEM(9)
488#endif
489};
490
491/** \name HW specific settings and implements */
492/*@{*/
493
494/** Number of endpoints supported. */
495#define USB_D_N_EP (1 + CONF_USB_D_NUM_EP_SP * 2)
496
497/** HPL USB device endpoint struct. */
498struct _usb_d_dev_ep {
499 /** Pointer to transaction buffer. */
500 uint8_t *trans_buf;
501 /** Transaction size. */
502 uint32_t trans_size;
503 /** Transaction transferred count. */
504 uint32_t trans_count;
505
506 /** Pointer to cache buffer, must be aligned. */
507 uint8_t *cache;
508
509 /** Endpoint size. */
510 uint16_t size;
511 /** Endpoint address. */
512 uint8_t ep;
513 /** Feature flags. */
514 union {
515 /** Interpreted by bit fields. */
516 struct {
517 /** EPCFG.ETYPE. */
518 uint8_t eptype : 3;
519 /** Stall status. */
520 uint8_t is_stalled : 1;
521 /** Transaction auto ZLP. */
522 uint8_t need_zlp : 1;
523 /** Transaction with cache */
524 uint8_t use_cache : 1;
525 /** Endpoint is busy. */
526 uint8_t is_busy : 1;
527 /** Transaction direction. */
528 uint8_t dir : 1;
529 } bits;
530 uint8_t u8;
531 } flags;
532};
533
534/** Check if the endpoint is used. */
535#define _usb_d_dev_ep_is_used(ept) ((ept)->ep != 0xFF)
536
537/** Check if the endpoint is busy doing transactions. */
538#define _usb_d_dev_ep_is_busy(ept) ((ept)->flags.bits.is_busy)
539
540/** Check if the endpoint is control endpoint. */
541#define _usb_d_dev_ep_is_ctrl(ept) ((ept)->flags.bits.eptype == USB_D_EPTYPE_CTRL)
542
543/** Check if the endpoint transactions are IN. */
544#define _usb_d_dev_ep_is_in(ept) ((ept)->flags.bits.dir)
545
546/** Interrupt flags for SETUP transaction. */
547#define USB_D_SETUP_INT_FLAGS (USB_DEVICE_EPINTFLAG_RXSTP)
548
549/** Interrupt flags for BANK1 transactions. */
550#define USB_D_BANK1_INT_FLAGS (USB_DEVICE_EPINTFLAG_TRCPT1 | USB_DEVICE_EPINTFLAG_TRFAIL1 | USB_DEVICE_EPINTFLAG_STALL1)
551
552/** Interrupt flags for BANK0 transactions. */
553#define USB_D_BANK0_INT_FLAGS (USB_DEVICE_EPINTFLAG_TRCPT0 | USB_DEVICE_EPINTFLAG_TRFAIL0 | USB_DEVICE_EPINTFLAG_STALL0)
554
555/** Interrupt flags for SETUP/IN/OUT transactions. */
556#define USB_D_ALL_INT_FLAGS (0x7F)
557
558/** Interrupt flags for WAKEUP event. */
559#define USB_D_WAKEUP_INT_FLAGS (USB_DEVICE_INTFLAG_UPRSM | USB_DEVICE_INTFLAG_EORSM | USB_DEVICE_INTFLAG_WAKEUP)
560
561/** Interrupt flags for SUSPEND event. */
562#define USB_D_SUSPEND_INT_FLAGS (USB_DEVICE_INTFLAG_LPMSUSP | USB_DEVICE_INTFLAG_SUSPEND)
563
564/** Max data bytes for a single DMA transfer. */
565#define USB_D_DEV_TRANS_MAX 8192 /* 14-bits, uses 13-bits. */
566
567/** Endpoint type setting to disable. */
568#define USB_D_EPTYPE_DISABLE 0
569
570/** Endpoint type setting to work as control endpoint. */
571#define USB_D_EPTYPE_CTRL 1
572
573/** Endpoint type setting to work as isochronous endpoint. */
574#define USB_D_EPTYPE_ISOCH 2
575
576/** Endpoint type setting to work as interrupt endpoint. */
577#define USB_D_EPTYPE_INT 3
578
579/** Endpoint type setting to work as bulk endpoint. */
580#define USB_D_EPTYPE_BULK 4
581
582/** Endpoint type setting for dual bank endpoint. */
583#define USB_D_EPTYPE_DUAL 5
584
585/** EPCFG register value for control endpoints. */
586#define USB_D_EPCFG_CTRL 0x11
587
588/** HPL USB device struct. */
589struct _usb_d_dev {
590 /** Callbacks of USB device. */
591 struct _usb_d_dev_callbacks callbacks;
592 /** Endpoint transaction callbacks. */
593 struct _usb_d_dev_ep_callbacks ep_callbacks;
594 /** Endpoints (ep0 + others). */
595 struct _usb_d_dev_ep ep[USB_D_N_EP];
596};
597
598/** Private data for SAM0 USB peripheral.
599 */
600typedef struct _usb_d_dev_prvt {
601 /** USB device descriptor table for peripheral to work. */
602 UsbDeviceDescriptor desc_table[CONF_USB_D_MAX_EP_N + 1];
603} usb_d_dev_prvt_t;
604
605/*@}*/
606
607/** USB device driver instance. */
608static struct _usb_d_dev dev_inst;
609
610/** USB device driver private data instance. */
611static struct _usb_d_dev_prvt prvt_inst;
612
613static void _usb_d_dev_reset_epts(void);
614
615static void _usb_d_dev_trans_done(struct _usb_d_dev_ep *ept, const int32_t status);
616static void _usb_d_dev_trans_stop(struct _usb_d_dev_ep *ept, bool dir, const int32_t code);
617
618static void _usb_d_dev_in_next(struct _usb_d_dev_ep *ept, bool isr);
619static void _usb_d_dev_out_next(struct _usb_d_dev_ep *ept, bool isr);
620
621static inline void _usb_d_dev_trans_setup(struct _usb_d_dev_ep *ept);
622
623/** \brief ACK the endpoint interrupt
624 * \param[in] epn Endpoint number.
625 * \param[in] flags Interrupt flags.
626 */
627static inline void _usbd_ep_int_ack(uint8_t epn, uint32_t flags)
628{
629 hri_usbendpoint_clear_EPINTFLAG_reg(USB, epn, flags);
630}
631
632/** \brief Enable the endpoint interrupt
633 * \param[in] epn Endpoint number.
634 * \param[in] flags Interrupt flags.
635 */
636static inline void _usbd_ep_int_en(uint8_t epn, uint32_t flags)
637{
638 hri_usbendpoint_set_EPINTEN_reg(USB, epn, flags);
639}
640
641/** \brief Disable the endpoint interrupt
642 * \param[in] epn Endpoint number.
643 * \param[in] flags Interrupt flags.
644 */
645static inline void _usbd_ep_int_dis(uint8_t epn, uint32_t flags)
646{
647 hri_usbendpoint_clear_EPINTEN_reg(USB, epn, flags);
648}
649
650/** \brief Check if endpoint is control endpoint
651 * \param[in] epn Endpoint number.
652 */
653static inline bool _usbd_ep_is_ctrl(uint8_t epn)
654{
655 return (hri_usbendpoint_read_EPCFG_reg(USB, epn) == USB_D_EPCFG_CTRL);
656}
657
658/** \brief Set endpoint stall
659 * \param[in] epn Endpoint number.
660 * \param[in] bank_n Endpoint bank number.
661 * \param[in] st Stall status.
662 */
663static inline void _usbd_ep_set_stall(uint8_t epn, uint8_t bank_n, bool st)
664{
665 if (st) {
666 hri_usbendpoint_set_EPSTATUS_reg(USB, epn, (USB_DEVICE_EPSTATUS_STALLRQ0 << bank_n));
667 } else {
668 hri_usbendpoint_clear_EPSTATUS_reg(USB, epn, (USB_DEVICE_EPSTATUS_STALLRQ0 << bank_n));
669 }
670}
671
672/** \brief Check if the endpoint is stalled
673 * \param[in] epn Endpoint number.
674 * \param[in] bank_n Endpoint bank number.
675 * \return \c true if it's stalled.
676 */
677static inline bool _usbd_ep_is_stalled(uint8_t epn, uint8_t bank_n)
678{
679 Usb *hw = USB;
680 return (hri_usbendpoint_read_EPSTATUS_reg(hw, epn) & (USB_DEVICE_EPSTATUS_STALLRQ0 << bank_n));
681}
682
683/** \brief Check if stall has been sent from the endpoint
684 * \param[in] epn Endpoint number.
685 * \param[in] bank_n Endpoint bank number.
686 * \return \c true if it's sent.
687 */
688static inline bool _usbd_ep_is_stall_sent(uint8_t epn, uint8_t bank_n)
689{
690 Usb *hw = USB;
691 return (hri_usbendpoint_read_EPINTFLAG_reg(hw, epn) & (USB_DEVICE_EPINTFLAG_STALL0 << bank_n));
692}
693
694/** \brief ACK endpoint STALL interrupt
695 * \param[in] epn Endpoint number.
696 * \param[in] bank_n Endpoint bank number.
697 */
698static inline void _usbd_ep_ack_stall(uint8_t epn, uint8_t bank_n)
699{
700 _usbd_ep_int_ack(epn, (USB_DEVICE_EPINTFLAG_STALL0 << bank_n));
701}
702
703/** \brief Enable/disable endpoint STALL interrupt
704 * \param[in] epn Endpoint number.
705 * \param[in] bank_n Endpoint bank number.
706 * \param[in] en \c true to enable, \c false to disable.
707 */
708static inline void _usbd_ep_int_stall_en(uint8_t epn, uint8_t bank_n, const bool en)
709{
710 if (en) {
711 _usbd_ep_int_en(epn, USB_DEVICE_EPINTFLAG_STALL0 << bank_n);
712 } else {
713 _usbd_ep_int_dis(epn, USB_DEVICE_EPINTFLAG_STALL0 << bank_n);
714 }
715}
716
717/** \brief Stop SETUP transactions
718 * \param[in] epn Endpoint number.
719 */
720static inline void _usbd_ep_stop_setup(uint8_t epn)
721{
722 hri_usbendpoint_clear_EPINTEN_RXSTP_bit(USB, epn);
723}
724
725/** \brief Check if SETUP packet is ready in cache
726 * \param[in] epn Endpoint number.
727 */
728static inline bool _usbd_ep_is_setup(uint8_t epn)
729{
730 return hri_usbendpoint_get_EPINTFLAG_reg(USB, epn, USB_DEVICE_EPINTFLAG_RXSTP);
731}
732
733/** \brief ACK endpoint SETUP interrupt
734 * \param[in] epn Endpoint number.
735 */
736static inline void _usbd_ep_ack_setup(uint8_t epn)
737{
738 _usbd_ep_int_ack(epn, USB_DEVICE_EPINTFLAG_RXSTP);
739}
740
741/** \brief Set endpoint toggle value
742 * \param[in] epn Endpoint number.
743 * \param[in] bank_n Endpoint bank number.
744 * \param[in] tgl Toggle value.
745 */
746static inline void _usbd_ep_set_toggle(uint8_t epn, uint8_t bank_n, uint8_t tgl)
747{
748 if (tgl) {
749 hri_usbendpoint_set_EPSTATUS_reg(USB, epn, (USB_DEVICE_EPSTATUS_DTGLOUT << bank_n));
750 } else {
751 hri_usbendpoint_clear_EPSTATUS_reg(USB, epn, (USB_DEVICE_EPSTATUS_DTGLOUT << bank_n));
752 }
753}
754
755/** \brief ACK IN/OUT complete interrupt
756 * \param[in] epn Endpoint number.
757 * \param[in] bank_n Endpoint bank number.
758 */
759static inline void _usbd_ep_ack_io_cpt(uint8_t epn, uint8_t bank_n)
760{
761 _usbd_ep_int_ack(epn, USB_DEVICE_EPINTFLAG_TRCPT0 << bank_n);
762}
763
764/** \brief Set DMA buffer used for bank data
765 * \param[in] epn Endpoint number.
766 * \param[in] bank_n Endpoint bank number.
767 * \param[in] addr DMA buffer address to set.
768 */
769static inline void _usbd_ep_set_buf(uint8_t epn, uint8_t bank_n, uint32_t addr)
770{
771 UsbDeviceDescBank *bank = &prvt_inst.desc_table[epn].DeviceDescBank[bank_n];
772 bank->ADDR.reg = addr;
773}
774
775/** \brief Set bank count for IN transactions
776 * \param[in] epn Endpoint number.
777 * \param[in] bank_n Endpoint bank number.
778 * \param[in] count Data count for IN.
779 */
780static inline void _usbd_ep_set_in_count(uint8_t epn, uint8_t bank_n, uint16_t count)
781{
782 UsbDeviceDescBank *bank = &prvt_inst.desc_table[epn].DeviceDescBank[bank_n];
783 bank->PCKSIZE.bit.MULTI_PACKET_SIZE = count;
784}
785
786/** \brief Set bank size for IN transactions
787 * \param[in] epn Endpoint number.
788 * \param[in] bank_n Endpoint bank number.
789 * \param[in] size Data size for IN.
790 */
791static inline void _usbd_ep_set_in_size(uint8_t epn, uint8_t bank_n, uint16_t size)
792{
793 UsbDeviceDescBank *bank = &prvt_inst.desc_table[epn].DeviceDescBank[bank_n];
794 bank->PCKSIZE.bit.BYTE_COUNT = size;
795}
796
797/** \brief Set bank count for OUT transaction
798 * \param[in] epn Endpoint number.
799 * \param[in] bank_n Endpoint bank number.
800 * \param[in] count Data count for OUT.
801 */
802static inline void _usbd_ep_set_out_count(uint8_t epn, uint8_t bank_n, uint16_t count)
803{
804 UsbDeviceDescBank *bank = &prvt_inst.desc_table[epn].DeviceDescBank[bank_n];
805 bank->PCKSIZE.bit.BYTE_COUNT = count;
806}
807
808/** \brief Set bank size for OUT transactions
809 * \param[in] epn Endpoint number.
810 * \param[in] bank_n Endpoint bank number.
811 * \param[in] size Data size for OUT.
812 */
813static inline void _usbd_ep_set_out_size(uint8_t epn, uint8_t bank_n, uint16_t size)
814{
815 UsbDeviceDescBank *bank = &prvt_inst.desc_table[epn].DeviceDescBank[bank_n];
816 bank->PCKSIZE.bit.MULTI_PACKET_SIZE = size;
817}
818
819/** Set bank size and count for IN transactions
820 * \param[in] epn Endpoint number.
821 * \param[in] bank_n Endpoint bank number.
822 * \param[in] size Data size.
823 * \param[in] count Initial data count.
824 */
825static inline void _usbd_ep_set_in_trans(uint8_t epn, uint8_t bank_n, uint32_t size, uint32_t count)
826{
827 _usbd_ep_set_in_size(epn, bank_n, size);
828 _usbd_ep_set_in_count(epn, bank_n, count);
829}
830
831/** \brief Set bank size and count for OUT transaction
832 * \param[in] epn Endpoint number.
833 * \param[in] bank_n Endpoint bank number.
834 * \param[in] size Data size.
835 * \param[in] count Initial data count.
836 */
837static inline void _usbd_ep_set_out_trans(uint8_t epn, uint8_t bank_n, uint32_t size, uint32_t count)
838{
839 _usbd_ep_set_out_size(epn, bank_n, size);
840 _usbd_ep_set_out_count(epn, bank_n, count);
841}
842
843/** \brief Clear bank status
844 * \param[in] epn Endpoint number.
845 * \param[in] bank_n Endpoint bank number.
846 */
847static inline void _usbd_ep_clear_bank_status(uint8_t epn, uint8_t bank_n)
848{
849 UsbDeviceDescBank *bank = &prvt_inst.desc_table[epn].DeviceDescBank[bank_n];
850 bank->STATUS_BK.reg = 0;
851}
852
853/** Set IN ready for IN transactions
854 * \param[in] epn Endpoint number.
855 * \param[in] bank_n Endpoint bank number.
856 * \param[in] rdy Set to \c true to indicate IN packet ready to TX.
857 */
858static inline void _usbd_ep_set_in_rdy(uint8_t epn, uint8_t bank_n, const bool rdy)
859{
860 if (rdy) {
861 hri_usbendpoint_set_EPSTATUS_reg(USB, epn, USB_DEVICE_EPSTATUS_BK0RDY << bank_n);
862 } else {
863 hri_usbendpoint_clear_EPSTATUS_reg(USB, epn, USB_DEVICE_EPSTATUS_BK0RDY << bank_n);
864 }
865}
866
867/** \brief Set bank ready for OUT transactions
868 * \param[in] epn Endpoint number.
869 * \param[in] bank_n Endpoint bank number.
870 * \param[in] rdy Set to \c true to indicate OUT bank ready to RX.
871 */
872static inline void _usbd_ep_set_out_rdy(uint8_t epn, uint8_t bank_n, const bool rdy)
873{
874 if (rdy) {
875 hri_usbendpoint_clear_EPSTATUS_reg(USB, epn, USB_DEVICE_EPSTATUS_BK0RDY << bank_n);
876 } else {
877 hri_usbendpoint_set_EPSTATUS_reg(USB, epn, USB_DEVICE_EPSTATUS_BK0RDY << bank_n);
878 }
879}
880
881/**
882 * \brief Convert USB endpoint size to HW PCKSIZE.SIZE
883 * \param[in] n Number of bytes of endpoint size.
884 */
885static inline uint8_t _usbd_ep_pcksize_size(uint16_t n)
886{
887 return (
888 (n > 512)
889 ? 7
890 : ((n > 256) ? 6 : ((n > 128) ? 5 : ((n > 64) ? 4 : ((n > 32) ? 3 : ((n > 16) ? 2 : ((n > 8) ? 1 : 0)))))));
891}
892
893/**
894 * \brief Obtain endpoint descriptor pointer
895 * \param[in] epn Endpoint number.
896 * \param[in] dir Endpoint direction.
897 */
898static inline struct _usb_d_dev_ep *_usb_d_dev_ept(uint8_t epn, bool dir)
899{
900 uint8_t ep_index = (epn == 0) ? 0 : (dir ? (epn + CONF_USB_D_MAX_EP_N) : epn);
901 return &dev_inst.ep[ep_index];
902}
903
904/**
905 * \brief Handles USB SOF interrupt
906 */
907static inline void _usb_d_dev_sof(void)
908{
909 /* ACK SOF interrupt. */
910 hri_usbdevice_clear_INTFLAG_reg(USB, USB_DEVICE_INTFLAG_SOF);
911 dev_inst.callbacks.sof();
912}
913
914/**
915 * \brief Handles USB LPM Suspend interrupt
916 */
917static inline void _usb_d_dev_lpmsusp(void)
918{
919 uint8_t i;
920 uint32_t lpm_variable = 0;
921
922 /* ACK LPMSUSP interrupt. */
923 hri_usbdevice_clear_INTFLAG_reg(USB, USB_D_SUSPEND_INT_FLAGS);
924 /* Change interrupt masks */
925 hri_usbdevice_clear_INTEN_reg(USB, USB_D_SUSPEND_INT_FLAGS);
926 hri_usbdevice_set_INTEN_reg(USB, USB_D_WAKEUP_INT_FLAGS);
927
928 /* Find LPM data */
929 for (i = 0; i < CONF_USB_D_MAX_EP_N; i++) {
930 UsbDeviceDescBank *bank = &prvt_inst.desc_table[i].DeviceDescBank[0];
931 if (bank->EXTREG.bit.SUBPID == 0x3) {
932 /* Save LPM variable */
933 lpm_variable = bank->EXTREG.bit.VARIABLE;
934 /* Clear */
935 bank->EXTREG.reg = 0;
936 break;
937 }
938 }
939 dev_inst.callbacks.event(USB_EV_LPM_SUSPEND, lpm_variable);
940}
941
942/**
943 * \brief Handles USB RAM Error interrupt
944 */
945static inline void _usb_d_dev_ramerr(void)
946{
947 hri_usbdevice_clear_INTFLAG_reg(USB, USB_DEVICE_INTFLAG_RAMACER);
948 dev_inst.callbacks.event(USB_EV_ERROR, 0);
949}
950
951/**
952 * \brief Handles USB resume/wakeup interrupts
953 */
954static inline void _usb_d_dev_wakeup(void)
955{
956 hri_usbdevice_clear_INTFLAG_reg(USB, USB_D_WAKEUP_INT_FLAGS);
957 hri_usbdevice_clear_INTEN_reg(USB, USB_D_WAKEUP_INT_FLAGS);
958 hri_usbdevice_set_INTEN_reg(USB, USB_D_SUSPEND_INT_FLAGS);
959
960 _usb_d_dev_wait_clk_rdy(CONF_USB_D_CLK_SRC);
961 dev_inst.callbacks.event(USB_EV_WAKEUP, 0);
962}
963
964/**
965 * \brief Handles USB signal reset interrupt
966 */
967static inline void _usb_d_dev_reset(void)
968{
969 /* EP0 will not be reseted by USB RESET, disable manually. */
970 hri_usbendpoint_write_EPCFG_reg(USB, 0, 0);
971
972 hri_usbdevice_clear_INTFLAG_reg(USB, USB_DEVICE_INTFLAG_EORST);
973 hri_usbdevice_clear_INTEN_reg(USB, USB_D_WAKEUP_INT_FLAGS);
974 hri_usbdevice_set_INTEN_reg(USB, USB_D_SUSPEND_INT_FLAGS);
975
976 _usb_d_dev_reset_epts();
977 dev_inst.callbacks.event(USB_EV_RESET, 0);
978}
979
980static inline void _usb_d_dev_suspend(void)
981{
982 hri_usbdevice_clear_INTFLAG_reg(USB, USB_D_SUSPEND_INT_FLAGS);
983 hri_usbdevice_clear_INTEN_reg(USB, USB_D_SUSPEND_INT_FLAGS);
984 hri_usbdevice_set_INTEN_reg(USB, USB_D_WAKEUP_INT_FLAGS);
985
986 dev_inst.callbacks.event(USB_EV_SUSPEND, 0);
987}
988
989/**
990 * \brief Handles USB non-endpoint interrupt
991 */
992static inline bool _usb_d_dev_handle_nep(void)
993{
994 bool rc = true;
995 uint16_t flags = hri_usbdevice_read_INTFLAG_reg(USB);
996 flags &= hri_usbdevice_read_INTEN_reg(USB);
997
998 if (flags & USB_DEVICE_INTFLAG_SOF) {
999 _usb_d_dev_sof();
1000 return true;
1001 }
1002 if (flags & USB_DEVICE_INTFLAG_LPMSUSP) {
1003 _usb_d_dev_lpmsusp();
1004 } else if (flags & USB_DEVICE_INTFLAG_RAMACER) {
1005 _usb_d_dev_ramerr();
1006 } else if (flags & USB_D_WAKEUP_INT_FLAGS) {
1007 _usb_d_dev_wakeup();
1008 } else if (flags & USB_DEVICE_INTFLAG_EORST) {
1009 _usb_d_dev_reset();
1010 } else if (flags & USB_DEVICE_INTFLAG_SUSPEND) {
1011 _usb_d_dev_suspend();
1012 } else {
1013 rc = false;
1014 }
1015 return rc;
1016}
1017
1018/**
1019 * \brief Prepare next IN transactions
1020 * \param[in] ept Pointer to endpoint information.
1021 * \param[in] isr Invoked from ISR.
1022 */
1023static void _usb_d_dev_in_next(struct _usb_d_dev_ep *ept, bool isr)
1024{
1025 Usb * hw = USB;
1026 uint8_t epn = USB_EP_GET_N(ept->ep);
1027 UsbDeviceDescBank *bank = &prvt_inst.desc_table[epn].DeviceDescBank[0];
1028 uint16_t trans_count = isr ? bank[1].PCKSIZE.bit.BYTE_COUNT : 0;
1029 uint16_t trans_next;
1030 uint16_t last_pkt = trans_count & ((ept->size == 1023) ? ept->size : (ept->size - 1));
1031 uint8_t inten = 0;
1032 bool is_ctrl = _usb_d_dev_ep_is_ctrl(ept);
1033
1034 if (isr) {
1035 _usbd_ep_ack_io_cpt(epn, 1);
1036 }
1037
1038 ept->trans_count += trans_count;
1039 /* Send more data. */
1040 if (ept->trans_count < ept->trans_size) {
1041 trans_next = ept->trans_size - ept->trans_count;
1042 if (ept->flags.bits.use_cache) {
1043 if (trans_next > ept->size) {
1044 trans_next = ept->size;
1045 }
1046 memcpy(ept->cache, &ept->trans_buf[ept->trans_count], trans_next);
1047 _usbd_ep_set_buf(epn, 1, (uint32_t)ept->cache);
1048 } else {
1049 if (trans_next > USB_D_DEV_TRANS_MAX) {
1050 trans_next = USB_D_DEV_TRANS_MAX;
1051 }
1052 _usbd_ep_set_buf(epn, 1, (uint32_t)&ept->trans_buf[ept->trans_count]);
1053 }
1054 _usbd_ep_set_in_trans(epn, 1, trans_next, 0);
1055 goto _in_tx_exec;
1056 } else if (ept->flags.bits.need_zlp) {
1057 ept->flags.bits.need_zlp = 0;
1058 _usbd_ep_set_in_trans(epn, 1, 0, 0);
1059 goto _in_tx_exec;
1060 }
1061 /* Complete. */
1062 if (is_ctrl) {
1063 hri_usbendpoint_clear_EPINTEN_reg(hw, epn, USB_D_BANK1_INT_FLAGS | USB_DEVICE_EPINTFLAG_TRCPT0);
1064 } else {
1065 hri_usbendpoint_clear_EPINTEN_reg(hw, epn, USB_D_BANK1_INT_FLAGS);
1066 }
1067
1068 /* No ping-pong, so ask more data without background transfer. */
1069 if (last_pkt == ept->size) {
1070 ept->flags.bits.is_busy = 0;
1071 if (dev_inst.ep_callbacks.more(ept->ep, ept->trans_count)) {
1072 /* More data added. */
1073 return;
1074 }
1075 ept->flags.bits.is_busy = 1;
1076 }
1077 /* Finish normally. */
1078 _usb_d_dev_trans_done(ept, USB_TRANS_DONE);
1079 return;
1080
1081_in_tx_exec:
1082 if (!isr) {
1083 if (is_ctrl) {
1084 /* Control endpoint: SETUP or OUT will abort IN transaction.
1085 * SETUP: terminate the IN without any notification. Trigger
1086 * SETUP callback.
1087 * OUT NAK: terminate IN.
1088 */
1089 inten = USB_D_BANK1_INT_FLAGS | USB_DEVICE_EPINTFLAG_TRFAIL0;
1090 } else {
1091 /* Initialize normal IN transaction. */
1092 inten = USB_D_BANK1_INT_FLAGS;
1093 }
1094 hri_usbendpoint_set_EPINTEN_reg(hw, epn, inten);
1095 }
1096 _usbd_ep_set_in_rdy(epn, 1, true);
1097}
1098
1099/**
1100 * \brief Prepare next OUT transactions
1101 * \param[in] ept Pointer to endpoint information.
1102 * \param[in] isr Invoked from ISR.
1103 */
1104static void _usb_d_dev_out_next(struct _usb_d_dev_ep *ept, bool isr)
1105{
1106 Usb * hw = USB;
1107 uint8_t epn = USB_EP_GET_N(ept->ep);
1108 UsbDeviceDescBank *bank = &prvt_inst.desc_table[epn].DeviceDescBank[0];
1109 uint16_t trans_size = isr ? bank->PCKSIZE.bit.MULTI_PACKET_SIZE : 0;
1110 uint16_t last_trans = isr ? bank->PCKSIZE.bit.BYTE_COUNT : 0;
1111 uint16_t size_mask = (ept->size == 1023) ? 1023 : (ept->size - 1);
1112 uint16_t last_pkt = last_trans & size_mask;
1113 uint16_t trans_next;
1114 uint8_t inten;
1115 bool is_ctrl = _usb_d_dev_ep_is_ctrl(ept);
1116
1117 if (isr) {
1118 _usbd_ep_ack_io_cpt(epn, 0);
1119 }
1120
1121 /* If cache is used, copy data to buffer. */
1122 if (ept->flags.bits.use_cache && ept->trans_size) {
1123 uint16_t buf_remain = ept->trans_size - ept->trans_count;
1124 memcpy(&ept->trans_buf[ept->trans_count], ept->cache, (buf_remain > last_pkt) ? last_pkt : buf_remain);
1125 }
1126
1127 /* Force wait ZLP */
1128 if (ept->trans_size == 0 && ept->flags.bits.need_zlp) {
1129 ept->flags.bits.need_zlp = 0;
1130 ept->flags.bits.use_cache = 1;
1131 _usbd_ep_set_buf(epn, 0, (uint32_t)ept->cache);
1132 _usbd_ep_set_out_trans(epn, 0, ept->size, 0);
1133 goto _out_rx_exec;
1134 } else if (isr && last_pkt < ept->size) {
1135 /* Short packet. */
1136 ept->flags.bits.need_zlp = 0;
1137 ept->trans_count += last_trans;
1138 } else {
1139 /* Full packets. */
1140 ept->trans_count += trans_size;
1141
1142 /* Wait more data */
1143 if (ept->trans_count < ept->trans_size) {
1144 /* Continue OUT */
1145 trans_next = ept->trans_size - ept->trans_count;
1146 if (ept->flags.bits.use_cache) {
1147 /* Expect single packet each time. */
1148 if (trans_next > ept->size) {
1149 trans_next = ept->size;
1150 }
1151 _usbd_ep_set_buf(epn, 0, (uint32_t)ept->cache);
1152 } else {
1153 /* Multiple packets each time. */
1154 if (trans_next > ept->size) {
1155 if (trans_next > USB_D_DEV_TRANS_MAX) {
1156 trans_next = USB_D_DEV_TRANS_MAX;
1157 } else {
1158 /* Must expect multiple of ep size. */
1159 trans_next -= trans_next & size_mask;
1160 }
1161 } else if (trans_next < ept->size) {
1162 /* Last un-aligned packet should be cached. */
1163 ept->flags.bits.use_cache = 1;
1164 }
1165 _usbd_ep_set_buf(epn, 0, (uint32_t)&ept->trans_buf[ept->trans_count]);
1166 }
1167 _usbd_ep_set_out_trans(epn, 0, trans_next, 0);
1168 goto _out_rx_exec;
1169 }
1170 }
1171 /* Finish normally. */
1172 if (is_ctrl) {
1173 hri_usbendpoint_clear_EPINTEN_reg(hw, epn, USB_D_BANK0_INT_FLAGS | USB_DEVICE_EPINTFLAG_TRFAIL1);
1174 } else {
1175 hri_usbendpoint_clear_EPINTEN_reg(hw, epn, USB_D_BANK0_INT_FLAGS);
1176 }
1177 /* Use ep0 out cache for next setup packets */
1178 if (0 == epn) {
1179 _usbd_ep_set_buf(epn, 0, (uint32_t)ept->cache);
1180 }
1181 _usb_d_dev_trans_done(ept, USB_TRANS_DONE);
1182 return;
1183
1184_out_rx_exec:
1185 if (!isr) {
1186 if (is_ctrl) {
1187 /* Initialize control OUT transaction. */
1188
1189 /* Control transfer: SETUP or IN request will abort the
1190 * OUT transactions.
1191 * SETUP: terminate OUT without any notification.
1192 * Trigger SETUP notification.
1193 * IN NAK: finish OUT normally. Notify data done.
1194 */
1195 _usbd_ep_clear_bank_status(epn, 1);
1196 /* Detect OUT, SETUP, NAK IN */
1197 inten = USB_D_BANK0_INT_FLAGS | USB_DEVICE_EPINTFLAG_TRFAIL1;
1198 } else {
1199 /* Initialize normal OUT transaction. */
1200 inten = USB_D_BANK0_INT_FLAGS;
1201 }
1202 hri_usbendpoint_set_EPINTEN_reg(hw, epn, inten);
1203 }
1204 _usbd_ep_set_out_rdy(epn, 0, true);
1205}
1206
1207/**
1208 * \brief Handles setup received interrupt
1209 * \param[in] ept Pointer to endpoint information.
1210 */
1211static void _usb_d_dev_handle_setup(struct _usb_d_dev_ep *ept)
1212{
1213 uint8_t epn = USB_EP_GET_N(ept->ep);
1214 bool is_ctrl = _usb_d_dev_ep_is_ctrl(ept);
1215
1216 if (!is_ctrl) {
1217 /* Should never be here! */
1218 _usbd_ep_ack_setup(epn);
1219 _usbd_ep_stop_setup(epn);
1220 return;
1221 }
1222 /* Control transfer:
1223 * SETUP transaction will terminate IN/OUT transaction,
1224 * and start new transaction with received SETUP packet.
1225 */
1226 if (_usb_d_dev_ep_is_busy(ept)) {
1227 ept->flags.bits.is_busy = 0;
1228
1229 /* Stop transfer on either direction. */
1230 _usbd_ep_set_in_rdy(epn, 1, false);
1231 _usbd_ep_set_out_rdy(epn, 0, false);
1232 }
1233 ept->flags.bits.is_stalled = 0;
1234
1235 /* Clear status and notify SETUP */
1236 _usbd_ep_clear_bank_status(epn, 0);
1237 _usbd_ep_clear_bank_status(epn, 1);
1238 _usbd_ep_int_ack(epn, USB_D_BANK0_INT_FLAGS | USB_D_BANK1_INT_FLAGS);
1239 _usbd_ep_int_dis(epn, USB_D_BANK0_INT_FLAGS | USB_D_BANK1_INT_FLAGS);
1240 /* Invoke callback. */
1241 dev_inst.ep_callbacks.setup(ept->ep);
1242}
1243
1244/**
1245 * \brief Handles stall sent interrupt
1246 * \param[in] ept Pointer to endpoint information.
1247 * \param[in] bank_n Bank number.
1248 */
1249static void _usb_d_dev_handle_stall(struct _usb_d_dev_ep *ept, const uint8_t bank_n)
1250{
1251 uint8_t epn = USB_EP_GET_N(ept->ep);
1252 /* Clear interrupt enable. Leave status there for status check. */
1253 _usbd_ep_int_stall_en(epn, bank_n, false);
1254 dev_inst.ep_callbacks.done(ept->ep, USB_TRANS_STALL, ept->trans_count);
1255}
1256
1257/**
1258 * \brief Handles transaction fail interrupt
1259 * \param[in] ept Pointer to endpoint information.
1260 * \param[in] bank_n Bank number.
1261 */
1262static void _usb_d_dev_handle_trfail(struct _usb_d_dev_ep *ept, const uint8_t bank_n)
1263{
1264 Usb * hw = USB;
1265 uint8_t epn = USB_EP_GET_N(ept->ep);
1266 const uint8_t fail[2] = {USB_DEVICE_EPINTFLAG_TRFAIL0, USB_DEVICE_EPINTFLAG_TRFAIL1};
1267 UsbDeviceDescBank *bank = prvt_inst.desc_table[epn].DeviceDescBank;
1268 uint8_t eptype
1269 = bank_n ? hri_usbendpoint_read_EPCFG_EPTYPE1_bf(hw, epn) : hri_usbendpoint_read_EPCFG_EPTYPE0_bf(hw, epn);
1270 bool is_ctrl = _usb_d_dev_ep_is_ctrl(ept);
1271 USB_DEVICE_STATUS_BK_Type st;
1272 st.reg = bank[bank_n].STATUS_BK.reg;
1273
1274 if ((eptype == USB_D_EPTYPE_ISOCH) && st.bit.CRCERR) {
1275 bank[bank_n].STATUS_BK.bit.CRCERR = 0;
1276 hri_usbendpoint_clear_EPINTFLAG_reg(hw, epn, fail[bank_n]);
1277 hri_usbendpoint_clear_EPINTEN_reg(hw, epn, fail[bank_n]);
1278 _usb_d_dev_trans_stop(ept, bank_n, USB_TRANS_ERROR);
1279 } else if (st.bit.ERRORFLOW) {
1280 bank[bank_n].STATUS_BK.bit.ERRORFLOW = 0;
1281 hri_usbendpoint_clear_EPINTFLAG_reg(hw, epn, fail[bank_n]);
1282 hri_usbendpoint_clear_EPINTEN_reg(hw, epn, fail[bank_n]);
1283 /* Abort control transfer. */
1284 if (is_ctrl && _usb_d_dev_ep_is_busy(ept)) {
1285 if (bank_n != _usb_d_dev_ep_is_in(ept)) {
1286 _usb_d_dev_trans_stop(ept, _usb_d_dev_ep_is_in(ept), USB_TRANS_DONE);
1287 }
1288 }
1289 } else {
1290 _usbd_ep_clear_bank_status(epn, bank_n);
1291 hri_usbendpoint_clear_EPINTFLAG_reg(hw, epn, fail[bank_n]);
1292 hri_usbendpoint_clear_EPINTEN_reg(hw, epn, fail[bank_n]);
1293 }
1294}
1295
1296/**
1297 * \brief Analyze flags for setup transaction
1298 * \param[in] ept Pointer to endpoint information.
1299 * \param[in] flags Endpoint interrupt flags.
1300 */
1301static inline void _usb_d_dev_trans_setup_isr(struct _usb_d_dev_ep *ept, const uint8_t flags)
1302{
1303 /*
1304 * SETPU is automatically ACKed by hardware
1305 * OUT & IN should be set to NAK when checking SETUP
1306 * No need to check OUT & IN status.
1307 */
1308 if (flags & USB_DEVICE_EPINTFLAG_RXSTP) {
1309 _usb_d_dev_handle_setup(ept);
1310 } else if (flags & USB_DEVICE_EPINTFLAG_STALL1) {
1311 _usb_d_dev_handle_stall(ept, 1);
1312 } else if (flags & USB_DEVICE_EPINTFLAG_STALL0) {
1313 _usb_d_dev_handle_stall(ept, 0);
1314 }
1315}
1316
1317/**
1318 * \brief Analyze flags for IN transactions
1319 * \param[in] ept Pointer to endpoint information.
1320 * \param[in] flags Endpoint interrupt flags.
1321 */
1322static inline void _usb_d_dev_trans_in_isr(struct _usb_d_dev_ep *ept, const uint8_t flags)
1323{
1324 /*
1325 * Check IN flags
1326 * If control endpoint, SETUP & OUT is checked to see if abort
1327 */
1328 if (flags & USB_DEVICE_EPINTFLAG_STALL1) {
1329 _usb_d_dev_handle_stall(ept, 1);
1330 } else if (flags & USB_DEVICE_EPINTFLAG_TRFAIL1) {
1331 _usb_d_dev_handle_trfail(ept, 1);
1332 } else if (flags & USB_DEVICE_EPINTFLAG_TRCPT1) {
1333 _usb_d_dev_in_next(ept, true);
1334 } else if (_usb_d_dev_ep_is_ctrl(ept)) {
1335 /* Check OUT NAK
1336 * Check SETUP
1337 */
1338 if (flags & USB_DEVICE_EPINTFLAG_TRFAIL0) {
1339 _usb_d_dev_handle_trfail(ept, 0);
1340 } else if (flags & USB_DEVICE_EPINTFLAG_RXSTP) {
1341 _usb_d_dev_handle_setup(ept);
1342 }
1343 }
1344}
1345
1346/**
1347 * \brief Analyze flags for OUT transactions
1348 * \param[in] ept Pointer to endpoint information.
1349 * \param[in] flags Endpoint interrupt flags.
1350 */
1351static inline void _usb_d_dev_trans_out_isr(struct _usb_d_dev_ep *ept, const uint8_t flags)
1352{
1353 /*
1354 * Check OUT flags.
1355 * If control endpoint, SETUP & IN NAK is checked to see if abort
1356 */
1357 if (flags & USB_DEVICE_EPINTFLAG_STALL0) {
1358 _usb_d_dev_handle_stall(ept, 0);
1359 } else if (flags & USB_DEVICE_EPINTFLAG_TRFAIL0) {
1360 _usb_d_dev_handle_trfail(ept, 0);
1361 } else if (flags & USB_DEVICE_EPINTFLAG_TRCPT0) {
1362 _usb_d_dev_out_next(ept, true);
1363 } else if (_usb_d_dev_ep_is_ctrl(ept)) {
1364 /* Check IN NAK
1365 * Check SETUP
1366 */
1367 if (flags & USB_DEVICE_EPINTFLAG_TRFAIL1) {
1368 _usb_d_dev_handle_trfail(ept, 1);
1369 } else if (flags & USB_DEVICE_EPINTFLAG_RXSTP) {
1370 _usb_d_dev_handle_setup(ept);
1371 }
1372 }
1373}
1374
1375/**
1376 * \brief Handles the endpoint interrupts.
1377 * \param[in] epint Endpoint interrupt summary (by bits).
1378 * \param[in] ept Pointer to endpoint information.
1379 */
1380static inline void _usb_d_dev_handle_eps(uint32_t epint, struct _usb_d_dev_ep *ept)
1381{
1382 Usb *hw = USB;
1383
1384 uint8_t flags, mask;
1385 uint8_t epn = USB_EP_GET_N(ept->ep);
1386
1387 if (!(epint & (1u << epn))) {
1388 return;
1389 }
1390 flags = hw->DEVICE.DeviceEndpoint[epn].EPINTFLAG.reg;
1391 mask = hw->DEVICE.DeviceEndpoint[epn].EPINTENSET.reg;
1392 flags &= mask;
1393 if (flags) {
1394 if ((ept->flags.bits.eptype == 0x1) && !_usb_d_dev_ep_is_busy(ept)) {
1395 _usb_d_dev_trans_setup_isr(ept, flags);
1396 } else if (_usb_d_dev_ep_is_in(ept)) {
1397 _usb_d_dev_trans_in_isr(ept, flags);
1398 } else {
1399 _usb_d_dev_trans_out_isr(ept, flags);
1400 }
1401 }
1402}
1403
1404/**
1405 * \brief USB device interrupt handler
1406 * \param[in] unused The parameter is not used
1407 */
1408static void _usb_d_dev_handler(void)
1409{
1410 Usb * hw = USB;
1411 uint8_t i;
1412
1413 uint16_t epint = hw->DEVICE.EPINTSMRY.reg;
1414 if (0 == epint) {
1415 if (_usb_d_dev_handle_nep()) {
1416 return;
1417 }
1418 }
1419 /* Handle endpoints */
1420 for (i = 0; i < USB_D_N_EP; i++) {
1421 struct _usb_d_dev_ep *ept = &dev_inst.ep[i];
1422 if (ept->ep == 0xFF) {
1423 continue;
1424 }
1425 _usb_d_dev_handle_eps(epint, ept);
1426 }
1427}
1428
1429/**
1430 * \brief Reset all endpoint software instances
1431 */
1432static void _usb_d_dev_reset_epts(void)
1433{
1434 uint8_t i;
1435 for (i = 0; i < USB_D_N_EP; i++) {
1436 _usb_d_dev_trans_done(&dev_inst.ep[i], USB_TRANS_RESET);
1437 dev_inst.ep[i].ep = 0xFF;
1438 dev_inst.ep[i].flags.u8 = 0;
1439 }
1440 memset(prvt_inst.desc_table, 0, sizeof(UsbDeviceDescriptor) * (CONF_USB_D_MAX_EP_N + 1));
1441}
1442
1443int32_t _usb_d_dev_init(void)
1444{
1445 Usb * hw = USB;
1446 uint8_t speed = CONF_USB_D_SPEED;
1447 const uint8_t spdconf[4] = {
1448 USB_DEVICE_CTRLB_SPDCONF(1), /* LS */
1449 USB_DEVICE_CTRLB_SPDCONF(0), /* FS */
1450 0,
1451 0 /* Reserved */
1452 };
1453
1454 if (!hri_usbdevice_is_syncing(hw, USB_SYNCBUSY_SWRST)) {
1455 if (hri_usbdevice_get_CTRLA_reg(hw, USB_CTRLA_ENABLE)) {
1456 hri_usbdevice_clear_CTRLA_ENABLE_bit(hw);
1457 hri_usbdevice_wait_for_sync(hw, USB_SYNCBUSY_ENABLE);
1458 }
1459 hri_usbdevice_write_CTRLA_reg(hw, USB_CTRLA_SWRST);
1460 }
1461 hri_usbdevice_wait_for_sync(hw, USB_SYNCBUSY_SWRST);
1462
1463 dev_inst.callbacks.sof = (_usb_d_dev_sof_cb_t)_dummy_func_no_return;
1464 dev_inst.callbacks.event = (_usb_d_dev_event_cb_t)_dummy_func_no_return;
1465
1466 dev_inst.ep_callbacks.setup = (_usb_d_dev_ep_cb_setup_t)_dummy_func_no_return;
1467 dev_inst.ep_callbacks.more = (_usb_d_dev_ep_cb_more_t)_dummy_func_no_return;
1468 dev_inst.ep_callbacks.done = (_usb_d_dev_ep_cb_done_t)_dummy_func_no_return;
1469
1470 _usb_d_dev_reset_epts();
1471
1472 _usb_load_calib();
1473
1474 hri_usbdevice_write_CTRLA_reg(hw, USB_CTRLA_RUNSTDBY);
1475 hri_usbdevice_write_DESCADD_reg(hw, (uint32_t)prvt_inst.desc_table);
1476 hri_usbdevice_write_CTRLB_reg(hw, spdconf[speed] | USB_DEVICE_CTRLB_DETACH);
1477
1478 return ERR_NONE;
1479}
1480
1481void _usb_d_dev_deinit(void)
1482{
1483 Usb *hw = USB;
1484
1485 while (_usb_d_dev_disable() < 0)
1486 ;
1487
1488 hri_usbdevice_write_CTRLA_reg(hw, USB_CTRLA_SWRST);
1489
1490 NVIC_DisableIRQ(USB_0_IRQn);
1491 NVIC_ClearPendingIRQ(USB_0_IRQn);
1492 NVIC_DisableIRQ(USB_1_IRQn);
1493 NVIC_ClearPendingIRQ(USB_1_IRQn);
1494 NVIC_DisableIRQ(USB_2_IRQn);
1495 NVIC_ClearPendingIRQ(USB_2_IRQn);
1496 NVIC_DisableIRQ(USB_3_IRQn);
1497 NVIC_ClearPendingIRQ(USB_3_IRQn);
1498}
1499
1500int32_t _usb_d_dev_enable(void)
1501{
1502 Usb * hw = USB;
1503 uint8_t ctrla;
1504
1505 if (hri_usbdevice_get_SYNCBUSY_reg(hw, (USB_SYNCBUSY_ENABLE | USB_SYNCBUSY_SWRST))) {
1506 return -USB_ERR_DENIED;
1507 }
1508 ctrla = hri_usbdevice_read_CTRLA_reg(hw);
1509 if ((ctrla & USB_CTRLA_ENABLE) == 0) {
1510 hri_usbdevice_write_CTRLA_reg(hw, ctrla | USB_CTRLA_ENABLE);
1511 }
1512
1513 NVIC_EnableIRQ(USB_0_IRQn);
1514 NVIC_EnableIRQ(USB_1_IRQn);
1515 NVIC_EnableIRQ(USB_2_IRQn);
1516 NVIC_EnableIRQ(USB_3_IRQn);
1517
1518 hri_usbdevice_set_INTEN_reg(hw,
1519 USB_DEVICE_INTENSET_SOF | USB_DEVICE_INTENSET_EORST | USB_DEVICE_INTENSET_RAMACER
1520 | USB_D_SUSPEND_INT_FLAGS);
1521
1522 return ERR_NONE;
1523}
1524
1525int32_t _usb_d_dev_disable(void)
1526{
1527 Usb * hw = USB;
1528 uint8_t ctrla;
1529
1530 if (hri_usbdevice_get_SYNCBUSY_reg(hw, (USB_SYNCBUSY_ENABLE | USB_SYNCBUSY_SWRST))) {
1531 return -USB_ERR_DENIED;
1532 }
1533
1534 ctrla = hri_usbdevice_read_CTRLA_reg(hw);
1535 if (ctrla & USB_CTRLA_ENABLE) {
1536 hri_usbdevice_write_CTRLA_reg(hw, ctrla & ~USB_CTRLA_ENABLE);
1537 }
1538
1539 NVIC_DisableIRQ(USB_0_IRQn);
1540 NVIC_DisableIRQ(USB_1_IRQn);
1541 NVIC_DisableIRQ(USB_2_IRQn);
1542 NVIC_DisableIRQ(USB_3_IRQn);
1543
1544 hri_usbdevice_clear_INTEN_reg(hw,
1545 USB_DEVICE_INTENSET_SOF | USB_DEVICE_INTENSET_EORST | USB_DEVICE_INTENSET_RAMACER
1546 | USB_D_SUSPEND_INT_FLAGS | USB_D_WAKEUP_INT_FLAGS);
1547
1548 return ERR_NONE;
1549}
1550
1551void _usb_d_dev_attach(void)
1552{
1553 hri_usbdevice_clear_CTRLB_DETACH_bit(USB);
1554}
1555
1556void _usb_d_dev_detach(void)
1557{
1558 hri_usbdevice_set_CTRLB_DETACH_bit(USB);
1559}
1560
1561#ifndef USB_FSMSTATUS_FSMSTATE_ON
1562#define USB_FSMSTATUS_FSMSTATE_ON USB_FSMSTATUS_FSMSTATE(2ul)
1563#endif
1564void _usb_d_dev_send_remotewakeup(void)
1565{
1566 uint32_t retry = CONF_USB_RMT_WKUP_RETRY;
1567 _usb_d_dev_wait_clk_rdy(CONF_USB_D_CLK_SRC);
1568 while ((USB_FSMSTATUS_FSMSTATE_ON != hri_usbdevice_read_FSMSTATUS_FSMSTATE_bf(USB)) && (retry--)) {
1569 USB->DEVICE.CTRLB.bit.UPRSM = 1;
1570 }
1571}
1572
1573enum usb_speed _usb_d_dev_get_speed(void)
1574{
1575 uint8_t sp = (enum usb_speed)hri_usbdevice_read_STATUS_SPEED_bf(USB);
1576 const enum usb_speed speed[2] = {USB_SPEED_FS, USB_SPEED_LS};
1577
1578 return speed[sp];
1579}
1580
1581void _usb_d_dev_set_address(uint8_t addr)
1582{
1583 hri_usbdevice_write_DADD_reg(USB, USB_DEVICE_DADD_ADDEN | USB_DEVICE_DADD_DADD(addr));
1584}
1585
1586uint8_t _usb_d_dev_get_address(void)
1587{
1588 uint8_t addr = hri_usbdevice_read_DADD_DADD_bf(USB);
1589 return addr;
1590}
1591
1592uint16_t _usb_d_dev_get_frame_n(void)
1593{
1594 uint16_t fn = hri_usbdevice_read_FNUM_FNUM_bf(USB);
1595 return fn;
1596}
1597
1598uint8_t _usb_d_dev_get_uframe_n(void)
1599{
1600 uint8_t ufn = hri_usbdevice_read_FNUM_MFNUM_bf(USB);
1601 return ufn;
1602}
1603
1604/**
1605 * \brief Start a setup transaction
1606 * \param[in] ept Endpoint information.
1607 */
1608static inline void _usb_d_dev_trans_setup(struct _usb_d_dev_ep *ept)
1609{
1610 Usb * hw = USB;
1611 uint8_t epn = USB_EP_GET_N(ept->ep);
1612
1613 _usbd_ep_set_buf(epn, 0, (uint32_t)ept->cache);
1614 _usbd_ep_set_out_trans(epn, 0, ept->size, 0);
1615
1616 hri_usbendpoint_clear_EPSTATUS_reg(hw, epn, USB_DEVICE_EPSTATUS_STALLRQ(0x3) | USB_DEVICE_EPSTATUS_BK1RDY);
1617 _usbd_ep_set_out_rdy(epn, 0, false);
1618
1619 hri_usbendpoint_set_EPINTEN_reg(hw, epn, USB_D_SETUP_INT_FLAGS);
1620}
1621
1622int32_t _usb_d_dev_ep0_init(const uint8_t max_pkt_siz)
1623{
1624 return _usb_d_dev_ep_init(0, USB_EP_XTYPE_CTRL, max_pkt_siz);
1625}
1626
1627int32_t _usb_d_dev_ep_init(const uint8_t ep, const uint8_t attr, const uint16_t max_pkt_siz)
1628{
1629 uint8_t epn = USB_EP_GET_N(ep);
1630 bool dir = USB_EP_GET_DIR(ep);
1631 struct _usb_d_dev_ep *ept = _usb_d_dev_ept(epn, dir);
1632
1633 uint8_t ep_type = attr & USB_EP_XTYPE_MASK;
1634 const struct _usb_ep_cfg_item *pcfg = &_usb_ep_cfgs[epn];
1635
1636 if (epn > CONF_USB_D_MAX_EP_N) {
1637 return -USB_ERR_PARAM;
1638 }
1639 if (ept->ep != 0xFF) {
1640 return -USB_ERR_REDO;
1641 }
1642 if (ep_type == USB_EP_XTYPE_CTRL) {
1643 struct _usb_d_dev_ep *ept_in = _usb_d_dev_ept(epn, !dir);
1644 if (ept_in->ep != 0xFF) {
1645 return -USB_ERR_REDO;
1646 }
1647 if (pcfg->cache == NULL) {
1648 return -USB_ERR_FUNC;
1649 }
1650 }
1651 if ((dir ? pcfg->i_cache : pcfg->cache) && ((dir ? pcfg->i_size : pcfg->size) < max_pkt_siz)) {
1652 return -USB_ERR_FUNC;
1653 }
1654
1655 /* Initialize EP n settings */
1656 ept->cache = (uint8_t *)(dir ? pcfg->i_cache : pcfg->cache);
1657 ept->size = max_pkt_siz;
1658 ept->flags.u8 = (ep_type + 1);
1659 ept->ep = ep;
1660
1661 return USB_OK;
1662}
1663
1664void _usb_d_dev_ep_deinit(uint8_t ep)
1665{
1666 Usb * hw = USB;
1667 uint8_t epn = USB_EP_GET_N(ep);
1668 bool dir = USB_EP_GET_DIR(ep);
1669 struct _usb_d_dev_ep *ept = _usb_d_dev_ept(epn, dir);
1670
1671 if (epn > CONF_USB_D_MAX_EP_N || !_usb_d_dev_ep_is_used(ept)) {
1672 return;
1673 }
1674
1675 /* Finish pending transactions. */
1676 _usb_d_dev_trans_stop(ept, dir, USB_TRANS_RESET);
1677
1678 /* Disable the endpoint. */
1679 if (_usb_d_dev_ep_is_ctrl(ept)) {
1680 hw->DEVICE.DeviceEndpoint[ep].EPCFG.reg = 0;
1681 } else if (USB_EP_GET_DIR(ep)) {
1682 hw->DEVICE.DeviceEndpoint[USB_EP_GET_N(ep)].EPCFG.reg &= ~USB_DEVICE_EPCFG_EPTYPE1_Msk;
1683 } else {
1684 hw->DEVICE.DeviceEndpoint[ep].EPCFG.reg &= ~USB_DEVICE_EPCFG_EPTYPE0_Msk;
1685 }
1686 ept->flags.u8 = 0;
1687 ept->ep = 0xFF;
1688}
1689
1690int32_t _usb_d_dev_ep_enable(const uint8_t ep)
1691{
1692 Usb * hw = USB;
1693 uint8_t epn = USB_EP_GET_N(ep);
1694 bool dir = USB_EP_GET_DIR(ep);
1695 struct _usb_d_dev_ep *ept = _usb_d_dev_ept(epn, dir);
1696 uint8_t epcfg = hri_usbendpoint_read_EPCFG_reg(hw, epn);
1697 UsbDeviceDescBank * bank;
1698
1699 if (epn > CONF_USB_D_MAX_EP_N || !_usb_d_dev_ep_is_used(ept)) {
1700 return -USB_ERR_PARAM;
1701 }
1702
1703 bank = prvt_inst.desc_table[epn].DeviceDescBank;
1704 if (ept->flags.bits.eptype == USB_D_EPTYPE_CTRL) {
1705 if (epcfg & (USB_DEVICE_EPCFG_EPTYPE1_Msk | USB_DEVICE_EPCFG_EPTYPE0_Msk)) {
1706 return -USB_ERR_REDO;
1707 }
1708 hri_usbendpoint_write_EPCFG_reg(hw, epn, USB_D_EPCFG_CTRL);
1709 bank[0].PCKSIZE.reg = USB_DEVICE_PCKSIZE_MULTI_PACKET_SIZE(ept->size)
1710 | USB_DEVICE_PCKSIZE_SIZE(_usbd_ep_pcksize_size(ept->size));
1711 bank[1].PCKSIZE.reg
1712 = USB_DEVICE_PCKSIZE_BYTE_COUNT(ept->size) | USB_DEVICE_PCKSIZE_SIZE(_usbd_ep_pcksize_size(ept->size));
1713 /* By default, control endpoint accept SETUP and NAK all other token. */
1714 _usbd_ep_set_out_rdy(epn, 0, false);
1715 _usbd_ep_set_in_rdy(epn, 1, false);
1716
1717 _usbd_ep_clear_bank_status(epn, 0);
1718 _usbd_ep_clear_bank_status(epn, 1);
1719
1720 /* Enable SETUP reception for control endpoint. */
1721 _usb_d_dev_trans_setup(ept);
1722
1723 } else if (dir) {
1724 if (epcfg & USB_DEVICE_EPCFG_EPTYPE1_Msk) {
1725 return -USB_ERR_REDO;
1726 }
1727 epcfg |= USB_DEVICE_EPCFG_EPTYPE1(ept->flags.bits.eptype);
1728 hri_usbendpoint_write_EPCFG_reg(hw, epn, epcfg);
1729
1730 bank[1].PCKSIZE.reg
1731 = USB_DEVICE_PCKSIZE_BYTE_COUNT(ept->size) | USB_DEVICE_PCKSIZE_SIZE(_usbd_ep_pcksize_size(ept->size));
1732
1733 /* By default, IN endpoint will NAK all token. */
1734 _usbd_ep_set_in_rdy(epn, 1, false);
1735 _usbd_ep_clear_bank_status(epn, 1);
1736
1737 } else {
1738
1739 if (epcfg & USB_DEVICE_EPCFG_EPTYPE0_Msk) {
1740 return -USB_ERR_REDO;
1741 }
1742 epcfg |= USB_DEVICE_EPCFG_EPTYPE0(ept->flags.bits.eptype);
1743 hri_usbendpoint_write_EPCFG_reg(hw, epn, epcfg);
1744
1745 bank[0].PCKSIZE.reg = USB_DEVICE_PCKSIZE_MULTI_PACKET_SIZE(ept->size)
1746 | USB_DEVICE_PCKSIZE_SIZE(_usbd_ep_pcksize_size(ept->size));
1747
1748 /* By default, OUT endpoint will NAK all token. */
1749 _usbd_ep_set_out_rdy(epn, 0, false);
1750 _usbd_ep_clear_bank_status(epn, 0);
1751 }
1752
1753 return USB_OK;
1754}
1755
1756void _usb_d_dev_ep_disable(const uint8_t ep)
1757{
1758 Usb * hw = USB;
1759 uint8_t epn = USB_EP_GET_N(ep);
1760 bool dir = USB_EP_GET_DIR(ep);
1761 struct _usb_d_dev_ep *ept = _usb_d_dev_ept(epn, dir);
1762
1763 _usb_d_dev_trans_stop(ept, dir, USB_TRANS_RESET);
1764 if (_usb_d_dev_ep_is_ctrl(ept)) {
1765 hri_usbendpoint_clear_EPINTEN_reg(hw, epn, USB_D_ALL_INT_FLAGS);
1766 }
1767}
1768
1769/**
1770 * \brief Get endpoint stall status
1771 * \param[in] ept Pointer to endpoint information.
1772 * \param[in] dir Endpoint direction.
1773 * \return Stall status.
1774 * \retval \c true Endpoint is stalled.
1775 * \retval \c false Endpoint is not stalled.
1776 */
1777static inline int32_t _usb_d_dev_ep_stall_get(struct _usb_d_dev_ep *ept, bool dir)
1778{
1779 uint8_t epn = USB_EP_GET_N(ept->ep);
1780 return _usbd_ep_is_stalled(epn, dir);
1781}
1782
1783/**
1784 * \brief Set endpoint stall
1785 * \param[in, out] ept Pointer to endpoint information.
1786 * \param[in] dir Endpoint direction.
1787 * \return Always 0, success.
1788 */
1789static inline int32_t _usb_d_dev_ep_stall_set(struct _usb_d_dev_ep *ept, bool dir)
1790{
1791 uint8_t epn = USB_EP_GET_N(ept->ep);
1792 _usbd_ep_set_stall(epn, dir, true);
1793 _usbd_ep_int_en(epn, USB_DEVICE_EPINTFLAG_STALL0 << dir);
1794 ept->flags.bits.is_stalled = 1;
1795 /* In stall interrupt abort the transfer. */
1796 return ERR_NONE;
1797}
1798
1799/**
1800 * \brief Clear endpoint stall
1801 * \param[in, out] ept Pointer to endpoint information.
1802 * \param[in] dir Endpoint direction.
1803 * \return Always 0, success.
1804 */
1805static inline int32_t _usb_d_dev_ep_stall_clr(struct _usb_d_dev_ep *ept, bool dir)
1806{
1807 uint8_t epn = USB_EP_GET_N(ept->ep);
1808 bool is_stalled = _usbd_ep_is_stalled(epn, dir);
1809 if (!is_stalled) {
1810 return ERR_NONE;
1811 }
1812 _usbd_ep_set_stall(epn, dir, false);
1813 _usbd_ep_int_dis(epn, USB_DEVICE_EPINTFLAG_STALL0 << dir);
1814 if (_usbd_ep_is_stall_sent(epn, dir)) {
1815 _usbd_ep_ack_stall(epn, dir);
1816 _usbd_ep_set_toggle(epn, dir, 0);
1817 }
1818 if (_usb_d_dev_ep_is_ctrl(ept)) {
1819 if ((hri_usbendpoint_read_EPSTATUS_reg(USB, epn) & USB_DEVICE_EPSTATUS_STALLRQ_Msk) == 0) {
1820 ept->flags.bits.is_stalled = 0;
1821 }
1822 } else {
1823 ept->flags.bits.is_stalled = 0;
1824 }
1825 return ERR_NONE;
1826}
1827
1828int32_t _usb_d_dev_ep_stall(const uint8_t ep, const enum usb_ep_stall_ctrl ctrl)
1829{
1830 uint8_t epn = USB_EP_GET_N(ep);
1831 bool dir = USB_EP_GET_DIR(ep);
1832 struct _usb_d_dev_ep *ept = _usb_d_dev_ept(epn, dir);
1833 int32_t rc;
1834
1835 if (epn > CONF_USB_D_MAX_EP_N) {
1836 return -USB_ERR_PARAM;
1837 }
1838
1839 if (USB_EP_STALL_SET == ctrl) {
1840 rc = _usb_d_dev_ep_stall_set(ept, dir);
1841 } else if (USB_EP_STALL_CLR == ctrl) {
1842 rc = _usb_d_dev_ep_stall_clr(ept, dir);
1843 } else {
1844 rc = _usb_d_dev_ep_stall_get(ept, dir);
1845 }
1846 return rc;
1847}
1848
1849/**
1850 * \brief Finish the transaction and invoke callback
1851 * \param[in, out] ept Pointer to endpoint information.
1852 * \param[in] code Information code passed.
1853 */
1854static void _usb_d_dev_trans_done(struct _usb_d_dev_ep *ept, const int32_t code)
1855{
1856 if (!(_usb_d_dev_ep_is_used(ept) && _usb_d_dev_ep_is_busy(ept))) {
1857 return;
1858 }
1859 ept->flags.bits.is_busy = 0;
1860 dev_inst.ep_callbacks.done(ept->ep, code, ept->trans_count);
1861}
1862
1863/**
1864 * \brief Terminate the transaction with specific status code
1865 * \param[in, out] ept Pointer to endpoint information.
1866 * \param[in] dir Endpoint direction.
1867 * \param[in] code Information code passed.
1868 */
1869static void _usb_d_dev_trans_stop(struct _usb_d_dev_ep *ept, bool dir, const int32_t code)
1870{
1871 uint8_t epn = USB_EP_GET_N(ept->ep);
1872 ;
1873 const uint8_t intflags[2] = {USB_D_BANK0_INT_FLAGS, USB_D_BANK1_INT_FLAGS};
1874 if (!(_usb_d_dev_ep_is_used(ept) && _usb_d_dev_ep_is_busy(ept))) {
1875 return;
1876 }
1877 /* Stop transfer */
1878 if (dir) {
1879 /* NAK IN */
1880 _usbd_ep_set_in_rdy(epn, 1, false);
1881 } else {
1882 /* NAK OUT */
1883 _usbd_ep_set_out_rdy(epn, 0, false);
1884 }
1885 _usbd_ep_int_ack(epn, intflags[dir]);
1886 _usbd_ep_int_dis(epn, intflags[dir]);
1887 _usb_d_dev_trans_done(ept, code);
1888}
1889
1890int32_t _usb_d_dev_ep_read_req(const uint8_t ep, uint8_t *req_buf)
1891{
1892 uint8_t epn = USB_EP_GET_N(ep);
1893 UsbDeviceDescBank *bank = prvt_inst.desc_table[epn].DeviceDescBank;
1894 uint32_t addr = bank[0].ADDR.reg;
1895 uint16_t bytes = bank[0].PCKSIZE.bit.BYTE_COUNT;
1896
1897 if (epn > CONF_USB_D_MAX_EP_N || !req_buf) {
1898 return -USB_ERR_PARAM;
1899 }
1900 if (!_usbd_ep_is_ctrl(epn)) {
1901 return -USB_ERR_FUNC;
1902 }
1903 if (!_usbd_ep_is_setup(epn)) {
1904 return ERR_NONE;
1905 }
1906 memcpy(req_buf, (void *)addr, 8);
1907 _usbd_ep_ack_setup(epn);
1908
1909 return bytes;
1910}
1911
1912int32_t _usb_d_dev_ep_trans(const struct usb_d_transfer *trans)
1913{
1914 uint8_t epn = USB_EP_GET_N(trans->ep);
1915 bool dir = USB_EP_GET_DIR(trans->ep);
1916 struct _usb_d_dev_ep *ept = _usb_d_dev_ept(epn, dir);
1917
1918 uint16_t size_mask = (ept->size == 1023) ? 1023 : (ept->size - 1);
1919 bool size_n_aligned = (trans->size & size_mask);
1920
1921 bool use_cache = false;
1922
1923 volatile hal_atomic_t flags;
1924
1925 if (epn > CONF_USB_D_MAX_EP_N) {
1926 return -USB_ERR_PARAM;
1927 }
1928
1929 /* Cases that needs cache:
1930 * 1. Buffer not in RAM (cache all).
1931 * 2. IN/OUT with unaligned buffer (cache all).
1932 * 3. OUT with unaligned packet size (cache last packet).
1933 * 4. OUT size < 8 (sub-case for 3).
1934 */
1935 if (!_usb_is_addr4dma(trans->buf, trans->size) || (!_usb_is_aligned(trans->buf))
1936 || (!dir && (trans->size < ept->size))) {
1937 if (!ept->cache) {
1938 return -USB_ERR_FUNC;
1939 }
1940 /* Use cache all the time. */
1941 use_cache = true;
1942 }
1943 if (!dir && size_n_aligned) {
1944 if (!ept->cache) {
1945 return -USB_ERR_PARAM;
1946 }
1947 /* Set 'use_cache' on last packet. */
1948 }
1949
1950 /* Check halt */
1951 if (ept->flags.bits.is_stalled) {
1952 return USB_HALTED;
1953 }
1954
1955 /* Try to start transactions. */
1956
1957 atomic_enter_critical(&flags);
1958 if (_usb_d_dev_ep_is_busy(ept)) {
1959 atomic_leave_critical(&flags);
1960 return USB_BUSY;
1961 }
1962 ept->flags.bits.is_busy = 1;
1963 atomic_leave_critical(&flags);
1964
1965 /* Copy transaction information. */
1966 ept->trans_buf = trans->buf;
1967 ept->trans_size = trans->size;
1968 ept->trans_count = 0;
1969
1970 ept->flags.bits.dir = dir;
1971 ept->flags.bits.use_cache = use_cache;
1972 ept->flags.bits.need_zlp = (trans->zlp && (!size_n_aligned));
1973
1974 if (dir) {
1975 _usb_d_dev_in_next(ept, false);
1976 } else {
1977 _usb_d_dev_out_next(ept, false);
1978 }
1979
1980 return ERR_NONE;
1981}
1982
1983void _usb_d_dev_ep_abort(const uint8_t ep)
1984{
1985 uint8_t epn = USB_EP_GET_N(ep);
1986 bool dir = USB_EP_GET_DIR(ep);
1987 struct _usb_d_dev_ep *ept = _usb_d_dev_ept(epn, dir);
1988 if (epn > CONF_USB_D_MAX_EP_N) {
1989 return;
1990 }
1991 _usb_d_dev_trans_stop(ept, dir, USB_TRANS_ABORT);
1992}
1993
1994int32_t _usb_d_dev_ep_get_status(const uint8_t ep, struct usb_d_trans_status *stat)
1995{
1996 uint8_t epn = USB_EP_GET_N(ep);
1997 bool dir = USB_EP_GET_DIR(ep);
1998 struct _usb_d_dev_ep *ept = _usb_d_dev_ept(epn, dir);
1999 bool busy, stall;
2000
2001 if (epn > CONF_USB_D_MAX_EP_N) {
2002 return USB_ERR_PARAM;
2003 }
2004 busy = ept->flags.bits.is_busy;
2005 stall = ept->flags.bits.is_stalled;
2006 if (stat) {
2007 stat->stall = stall;
2008 stat->busy = busy;
2009 stat->setup = USB->DEVICE.DeviceEndpoint[epn].EPINTFLAG.bit.RXSTP;
2010 stat->dir = ept->flags.bits.dir;
2011 stat->size = ept->trans_size;
2012 stat->count = ept->trans_count;
2013 stat->ep = ep;
2014 stat->xtype = ept->flags.bits.eptype - 1;
2015 }
2016 if (stall) {
2017 return USB_HALTED;
2018 }
2019 if (busy) {
2020 return USB_BUSY;
2021 }
2022 return USB_OK;
2023}
2024
2025void _usb_d_dev_register_callback(const enum usb_d_cb_type type, const FUNC_PTR func)
2026{
2027 FUNC_PTR f = (func == NULL) ? (FUNC_PTR)_dummy_func_no_return : (FUNC_PTR)func;
2028 if (type == USB_D_CB_EVENT) {
2029 dev_inst.callbacks.event = (_usb_d_dev_event_cb_t)f;
2030 } else if (type == USB_D_CB_SOF) {
2031 dev_inst.callbacks.sof = (_usb_d_dev_sof_cb_t)f;
2032 }
2033}
2034
2035void _usb_d_dev_register_ep_callback(const enum usb_d_dev_ep_cb_type type, const FUNC_PTR func)
2036{
2037 FUNC_PTR f = (func == NULL) ? (FUNC_PTR)_dummy_func_no_return : (FUNC_PTR)func;
2038 if (type == USB_D_DEV_EP_CB_SETUP) {
2039 dev_inst.ep_callbacks.setup = (_usb_d_dev_ep_cb_setup_t)f;
2040 } else if (type == USB_D_DEV_EP_CB_MORE) {
2041 dev_inst.ep_callbacks.more = (_usb_d_dev_ep_cb_more_t)f;
2042 } else if (type == USB_D_DEV_EP_CB_DONE) {
2043 dev_inst.ep_callbacks.done = (_usb_d_dev_ep_cb_done_t)f;
2044 }
2045}
2046
2047/**
2048 * \brief USB interrupt handler
2049 */
2050void USB_0_Handler(void)
2051{
2052
2053 _usb_d_dev_handler();
2054}
2055/**
2056 * \brief USB interrupt handler
2057 */
2058void USB_1_Handler(void)
2059{
2060
2061 _usb_d_dev_handler();
2062}
2063/**
2064 * \brief USB interrupt handler
2065 */
2066void USB_2_Handler(void)
2067{
2068
2069 _usb_d_dev_handler();
2070}
2071/**
2072 * \brief USB interrupt handler
2073 */
2074void USB_3_Handler(void)
2075{
2076
2077 _usb_d_dev_handler();
2078}