blob: eec972851b6b08ec85b638c5e329a04777bd1bc2 [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 */
Kévin Redon4e39b012019-01-30 15:55:58 +0100157#define _IN_RAM(a, s) ((0x20000000 <= (uint32_t)(a)) && (((uint32_t)(a) + (s)) < (0x20000000 + 0x00032000)))
Kévin Redon69b92d92019-01-24 16:39:20 +0100158
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;
Kévin Redond0903f72019-02-23 20:27:17 +01001138 _usbd_ep_set_out_trans(epn, 0, ept->size, 0);
Kévin Redon69b92d92019-01-24 16:39:20 +01001139 } else {
1140 /* Full packets. */
1141 ept->trans_count += trans_size;
1142
1143 /* Wait more data */
1144 if (ept->trans_count < ept->trans_size) {
1145 /* Continue OUT */
1146 trans_next = ept->trans_size - ept->trans_count;
1147 if (ept->flags.bits.use_cache) {
1148 /* Expect single packet each time. */
1149 if (trans_next > ept->size) {
1150 trans_next = ept->size;
1151 }
1152 _usbd_ep_set_buf(epn, 0, (uint32_t)ept->cache);
1153 } else {
1154 /* Multiple packets each time. */
1155 if (trans_next > ept->size) {
1156 if (trans_next > USB_D_DEV_TRANS_MAX) {
1157 trans_next = USB_D_DEV_TRANS_MAX;
Kévin Redon69b92d92019-01-24 16:39:20 +01001158 }
1159 } else if (trans_next < ept->size) {
1160 /* Last un-aligned packet should be cached. */
1161 ept->flags.bits.use_cache = 1;
1162 }
1163 _usbd_ep_set_buf(epn, 0, (uint32_t)&ept->trans_buf[ept->trans_count]);
1164 }
1165 _usbd_ep_set_out_trans(epn, 0, trans_next, 0);
1166 goto _out_rx_exec;
1167 }
1168 }
1169 /* Finish normally. */
1170 if (is_ctrl) {
1171 hri_usbendpoint_clear_EPINTEN_reg(hw, epn, USB_D_BANK0_INT_FLAGS | USB_DEVICE_EPINTFLAG_TRFAIL1);
1172 } else {
1173 hri_usbendpoint_clear_EPINTEN_reg(hw, epn, USB_D_BANK0_INT_FLAGS);
1174 }
1175 /* Use ep0 out cache for next setup packets */
1176 if (0 == epn) {
1177 _usbd_ep_set_buf(epn, 0, (uint32_t)ept->cache);
1178 }
1179 _usb_d_dev_trans_done(ept, USB_TRANS_DONE);
1180 return;
1181
1182_out_rx_exec:
1183 if (!isr) {
1184 if (is_ctrl) {
1185 /* Initialize control OUT transaction. */
1186
1187 /* Control transfer: SETUP or IN request will abort the
1188 * OUT transactions.
1189 * SETUP: terminate OUT without any notification.
1190 * Trigger SETUP notification.
1191 * IN NAK: finish OUT normally. Notify data done.
1192 */
1193 _usbd_ep_clear_bank_status(epn, 1);
1194 /* Detect OUT, SETUP, NAK IN */
1195 inten = USB_D_BANK0_INT_FLAGS | USB_DEVICE_EPINTFLAG_TRFAIL1;
1196 } else {
1197 /* Initialize normal OUT transaction. */
1198 inten = USB_D_BANK0_INT_FLAGS;
1199 }
1200 hri_usbendpoint_set_EPINTEN_reg(hw, epn, inten);
1201 }
1202 _usbd_ep_set_out_rdy(epn, 0, true);
1203}
1204
1205/**
1206 * \brief Handles setup received interrupt
1207 * \param[in] ept Pointer to endpoint information.
1208 */
1209static void _usb_d_dev_handle_setup(struct _usb_d_dev_ep *ept)
1210{
1211 uint8_t epn = USB_EP_GET_N(ept->ep);
1212 bool is_ctrl = _usb_d_dev_ep_is_ctrl(ept);
1213
1214 if (!is_ctrl) {
1215 /* Should never be here! */
1216 _usbd_ep_ack_setup(epn);
1217 _usbd_ep_stop_setup(epn);
1218 return;
1219 }
1220 /* Control transfer:
1221 * SETUP transaction will terminate IN/OUT transaction,
1222 * and start new transaction with received SETUP packet.
1223 */
1224 if (_usb_d_dev_ep_is_busy(ept)) {
1225 ept->flags.bits.is_busy = 0;
1226
1227 /* Stop transfer on either direction. */
1228 _usbd_ep_set_in_rdy(epn, 1, false);
1229 _usbd_ep_set_out_rdy(epn, 0, false);
1230 }
1231 ept->flags.bits.is_stalled = 0;
1232
1233 /* Clear status and notify SETUP */
1234 _usbd_ep_clear_bank_status(epn, 0);
1235 _usbd_ep_clear_bank_status(epn, 1);
1236 _usbd_ep_int_ack(epn, USB_D_BANK0_INT_FLAGS | USB_D_BANK1_INT_FLAGS);
1237 _usbd_ep_int_dis(epn, USB_D_BANK0_INT_FLAGS | USB_D_BANK1_INT_FLAGS);
1238 /* Invoke callback. */
1239 dev_inst.ep_callbacks.setup(ept->ep);
1240}
1241
1242/**
1243 * \brief Handles stall sent interrupt
1244 * \param[in] ept Pointer to endpoint information.
1245 * \param[in] bank_n Bank number.
1246 */
1247static void _usb_d_dev_handle_stall(struct _usb_d_dev_ep *ept, const uint8_t bank_n)
1248{
1249 uint8_t epn = USB_EP_GET_N(ept->ep);
1250 /* Clear interrupt enable. Leave status there for status check. */
1251 _usbd_ep_int_stall_en(epn, bank_n, false);
1252 dev_inst.ep_callbacks.done(ept->ep, USB_TRANS_STALL, ept->trans_count);
1253}
1254
1255/**
1256 * \brief Handles transaction fail interrupt
1257 * \param[in] ept Pointer to endpoint information.
1258 * \param[in] bank_n Bank number.
1259 */
1260static void _usb_d_dev_handle_trfail(struct _usb_d_dev_ep *ept, const uint8_t bank_n)
1261{
1262 Usb * hw = USB;
1263 uint8_t epn = USB_EP_GET_N(ept->ep);
1264 const uint8_t fail[2] = {USB_DEVICE_EPINTFLAG_TRFAIL0, USB_DEVICE_EPINTFLAG_TRFAIL1};
1265 UsbDeviceDescBank *bank = prvt_inst.desc_table[epn].DeviceDescBank;
1266 uint8_t eptype
1267 = bank_n ? hri_usbendpoint_read_EPCFG_EPTYPE1_bf(hw, epn) : hri_usbendpoint_read_EPCFG_EPTYPE0_bf(hw, epn);
1268 bool is_ctrl = _usb_d_dev_ep_is_ctrl(ept);
1269 USB_DEVICE_STATUS_BK_Type st;
1270 st.reg = bank[bank_n].STATUS_BK.reg;
1271
1272 if ((eptype == USB_D_EPTYPE_ISOCH) && st.bit.CRCERR) {
1273 bank[bank_n].STATUS_BK.bit.CRCERR = 0;
1274 hri_usbendpoint_clear_EPINTFLAG_reg(hw, epn, fail[bank_n]);
1275 hri_usbendpoint_clear_EPINTEN_reg(hw, epn, fail[bank_n]);
1276 _usb_d_dev_trans_stop(ept, bank_n, USB_TRANS_ERROR);
1277 } else if (st.bit.ERRORFLOW) {
1278 bank[bank_n].STATUS_BK.bit.ERRORFLOW = 0;
1279 hri_usbendpoint_clear_EPINTFLAG_reg(hw, epn, fail[bank_n]);
1280 hri_usbendpoint_clear_EPINTEN_reg(hw, epn, fail[bank_n]);
1281 /* Abort control transfer. */
1282 if (is_ctrl && _usb_d_dev_ep_is_busy(ept)) {
1283 if (bank_n != _usb_d_dev_ep_is_in(ept)) {
1284 _usb_d_dev_trans_stop(ept, _usb_d_dev_ep_is_in(ept), USB_TRANS_DONE);
1285 }
1286 }
1287 } else {
1288 _usbd_ep_clear_bank_status(epn, bank_n);
1289 hri_usbendpoint_clear_EPINTFLAG_reg(hw, epn, fail[bank_n]);
1290 hri_usbendpoint_clear_EPINTEN_reg(hw, epn, fail[bank_n]);
1291 }
1292}
1293
1294/**
1295 * \brief Analyze flags for setup transaction
1296 * \param[in] ept Pointer to endpoint information.
1297 * \param[in] flags Endpoint interrupt flags.
1298 */
1299static inline void _usb_d_dev_trans_setup_isr(struct _usb_d_dev_ep *ept, const uint8_t flags)
1300{
1301 /*
1302 * SETPU is automatically ACKed by hardware
1303 * OUT & IN should be set to NAK when checking SETUP
1304 * No need to check OUT & IN status.
1305 */
1306 if (flags & USB_DEVICE_EPINTFLAG_RXSTP) {
1307 _usb_d_dev_handle_setup(ept);
1308 } else if (flags & USB_DEVICE_EPINTFLAG_STALL1) {
1309 _usb_d_dev_handle_stall(ept, 1);
1310 } else if (flags & USB_DEVICE_EPINTFLAG_STALL0) {
1311 _usb_d_dev_handle_stall(ept, 0);
1312 }
1313}
1314
1315/**
1316 * \brief Analyze flags for IN transactions
1317 * \param[in] ept Pointer to endpoint information.
1318 * \param[in] flags Endpoint interrupt flags.
1319 */
1320static inline void _usb_d_dev_trans_in_isr(struct _usb_d_dev_ep *ept, const uint8_t flags)
1321{
1322 /*
1323 * Check IN flags
1324 * If control endpoint, SETUP & OUT is checked to see if abort
1325 */
1326 if (flags & USB_DEVICE_EPINTFLAG_STALL1) {
1327 _usb_d_dev_handle_stall(ept, 1);
1328 } else if (flags & USB_DEVICE_EPINTFLAG_TRFAIL1) {
1329 _usb_d_dev_handle_trfail(ept, 1);
1330 } else if (flags & USB_DEVICE_EPINTFLAG_TRCPT1) {
1331 _usb_d_dev_in_next(ept, true);
1332 } else if (_usb_d_dev_ep_is_ctrl(ept)) {
1333 /* Check OUT NAK
1334 * Check SETUP
1335 */
1336 if (flags & USB_DEVICE_EPINTFLAG_TRFAIL0) {
1337 _usb_d_dev_handle_trfail(ept, 0);
1338 } else if (flags & USB_DEVICE_EPINTFLAG_RXSTP) {
1339 _usb_d_dev_handle_setup(ept);
1340 }
1341 }
1342}
1343
1344/**
1345 * \brief Analyze flags for OUT transactions
1346 * \param[in] ept Pointer to endpoint information.
1347 * \param[in] flags Endpoint interrupt flags.
1348 */
1349static inline void _usb_d_dev_trans_out_isr(struct _usb_d_dev_ep *ept, const uint8_t flags)
1350{
1351 /*
1352 * Check OUT flags.
1353 * If control endpoint, SETUP & IN NAK is checked to see if abort
1354 */
1355 if (flags & USB_DEVICE_EPINTFLAG_STALL0) {
1356 _usb_d_dev_handle_stall(ept, 0);
1357 } else if (flags & USB_DEVICE_EPINTFLAG_TRFAIL0) {
1358 _usb_d_dev_handle_trfail(ept, 0);
1359 } else if (flags & USB_DEVICE_EPINTFLAG_TRCPT0) {
1360 _usb_d_dev_out_next(ept, true);
1361 } else if (_usb_d_dev_ep_is_ctrl(ept)) {
1362 /* Check IN NAK
1363 * Check SETUP
1364 */
1365 if (flags & USB_DEVICE_EPINTFLAG_TRFAIL1) {
1366 _usb_d_dev_handle_trfail(ept, 1);
1367 } else if (flags & USB_DEVICE_EPINTFLAG_RXSTP) {
1368 _usb_d_dev_handle_setup(ept);
1369 }
1370 }
1371}
1372
1373/**
1374 * \brief Handles the endpoint interrupts.
1375 * \param[in] epint Endpoint interrupt summary (by bits).
1376 * \param[in] ept Pointer to endpoint information.
1377 */
1378static inline void _usb_d_dev_handle_eps(uint32_t epint, struct _usb_d_dev_ep *ept)
1379{
1380 Usb *hw = USB;
1381
1382 uint8_t flags, mask;
1383 uint8_t epn = USB_EP_GET_N(ept->ep);
1384
1385 if (!(epint & (1u << epn))) {
1386 return;
1387 }
1388 flags = hw->DEVICE.DeviceEndpoint[epn].EPINTFLAG.reg;
1389 mask = hw->DEVICE.DeviceEndpoint[epn].EPINTENSET.reg;
1390 flags &= mask;
1391 if (flags) {
1392 if ((ept->flags.bits.eptype == 0x1) && !_usb_d_dev_ep_is_busy(ept)) {
1393 _usb_d_dev_trans_setup_isr(ept, flags);
1394 } else if (_usb_d_dev_ep_is_in(ept)) {
1395 _usb_d_dev_trans_in_isr(ept, flags);
1396 } else {
1397 _usb_d_dev_trans_out_isr(ept, flags);
1398 }
1399 }
1400}
1401
1402/**
1403 * \brief USB device interrupt handler
1404 * \param[in] unused The parameter is not used
1405 */
1406static void _usb_d_dev_handler(void)
1407{
1408 Usb * hw = USB;
1409 uint8_t i;
1410
1411 uint16_t epint = hw->DEVICE.EPINTSMRY.reg;
1412 if (0 == epint) {
1413 if (_usb_d_dev_handle_nep()) {
1414 return;
1415 }
1416 }
1417 /* Handle endpoints */
1418 for (i = 0; i < USB_D_N_EP; i++) {
1419 struct _usb_d_dev_ep *ept = &dev_inst.ep[i];
1420 if (ept->ep == 0xFF) {
1421 continue;
1422 }
1423 _usb_d_dev_handle_eps(epint, ept);
1424 }
1425}
1426
1427/**
1428 * \brief Reset all endpoint software instances
1429 */
1430static void _usb_d_dev_reset_epts(void)
1431{
1432 uint8_t i;
1433 for (i = 0; i < USB_D_N_EP; i++) {
1434 _usb_d_dev_trans_done(&dev_inst.ep[i], USB_TRANS_RESET);
1435 dev_inst.ep[i].ep = 0xFF;
1436 dev_inst.ep[i].flags.u8 = 0;
1437 }
1438 memset(prvt_inst.desc_table, 0, sizeof(UsbDeviceDescriptor) * (CONF_USB_D_MAX_EP_N + 1));
1439}
1440
1441int32_t _usb_d_dev_init(void)
1442{
1443 Usb * hw = USB;
1444 uint8_t speed = CONF_USB_D_SPEED;
1445 const uint8_t spdconf[4] = {
1446 USB_DEVICE_CTRLB_SPDCONF(1), /* LS */
1447 USB_DEVICE_CTRLB_SPDCONF(0), /* FS */
1448 0,
1449 0 /* Reserved */
1450 };
1451
1452 if (!hri_usbdevice_is_syncing(hw, USB_SYNCBUSY_SWRST)) {
1453 if (hri_usbdevice_get_CTRLA_reg(hw, USB_CTRLA_ENABLE)) {
1454 hri_usbdevice_clear_CTRLA_ENABLE_bit(hw);
1455 hri_usbdevice_wait_for_sync(hw, USB_SYNCBUSY_ENABLE);
1456 }
1457 hri_usbdevice_write_CTRLA_reg(hw, USB_CTRLA_SWRST);
1458 }
1459 hri_usbdevice_wait_for_sync(hw, USB_SYNCBUSY_SWRST);
1460
1461 dev_inst.callbacks.sof = (_usb_d_dev_sof_cb_t)_dummy_func_no_return;
1462 dev_inst.callbacks.event = (_usb_d_dev_event_cb_t)_dummy_func_no_return;
1463
1464 dev_inst.ep_callbacks.setup = (_usb_d_dev_ep_cb_setup_t)_dummy_func_no_return;
1465 dev_inst.ep_callbacks.more = (_usb_d_dev_ep_cb_more_t)_dummy_func_no_return;
1466 dev_inst.ep_callbacks.done = (_usb_d_dev_ep_cb_done_t)_dummy_func_no_return;
1467
1468 _usb_d_dev_reset_epts();
1469
1470 _usb_load_calib();
1471
1472 hri_usbdevice_write_CTRLA_reg(hw, USB_CTRLA_RUNSTDBY);
1473 hri_usbdevice_write_DESCADD_reg(hw, (uint32_t)prvt_inst.desc_table);
1474 hri_usbdevice_write_CTRLB_reg(hw, spdconf[speed] | USB_DEVICE_CTRLB_DETACH);
1475
1476 return ERR_NONE;
1477}
1478
1479void _usb_d_dev_deinit(void)
1480{
1481 Usb *hw = USB;
1482
1483 while (_usb_d_dev_disable() < 0)
1484 ;
1485
1486 hri_usbdevice_write_CTRLA_reg(hw, USB_CTRLA_SWRST);
1487
1488 NVIC_DisableIRQ(USB_0_IRQn);
1489 NVIC_ClearPendingIRQ(USB_0_IRQn);
1490 NVIC_DisableIRQ(USB_1_IRQn);
1491 NVIC_ClearPendingIRQ(USB_1_IRQn);
1492 NVIC_DisableIRQ(USB_2_IRQn);
1493 NVIC_ClearPendingIRQ(USB_2_IRQn);
1494 NVIC_DisableIRQ(USB_3_IRQn);
1495 NVIC_ClearPendingIRQ(USB_3_IRQn);
1496}
1497
1498int32_t _usb_d_dev_enable(void)
1499{
1500 Usb * hw = USB;
1501 uint8_t ctrla;
1502
1503 if (hri_usbdevice_get_SYNCBUSY_reg(hw, (USB_SYNCBUSY_ENABLE | USB_SYNCBUSY_SWRST))) {
1504 return -USB_ERR_DENIED;
1505 }
1506 ctrla = hri_usbdevice_read_CTRLA_reg(hw);
1507 if ((ctrla & USB_CTRLA_ENABLE) == 0) {
1508 hri_usbdevice_write_CTRLA_reg(hw, ctrla | USB_CTRLA_ENABLE);
1509 }
1510
1511 NVIC_EnableIRQ(USB_0_IRQn);
1512 NVIC_EnableIRQ(USB_1_IRQn);
1513 NVIC_EnableIRQ(USB_2_IRQn);
1514 NVIC_EnableIRQ(USB_3_IRQn);
1515
1516 hri_usbdevice_set_INTEN_reg(hw,
1517 USB_DEVICE_INTENSET_SOF | USB_DEVICE_INTENSET_EORST | USB_DEVICE_INTENSET_RAMACER
1518 | USB_D_SUSPEND_INT_FLAGS);
1519
1520 return ERR_NONE;
1521}
1522
1523int32_t _usb_d_dev_disable(void)
1524{
1525 Usb * hw = USB;
1526 uint8_t ctrla;
1527
1528 if (hri_usbdevice_get_SYNCBUSY_reg(hw, (USB_SYNCBUSY_ENABLE | USB_SYNCBUSY_SWRST))) {
1529 return -USB_ERR_DENIED;
1530 }
1531
1532 ctrla = hri_usbdevice_read_CTRLA_reg(hw);
1533 if (ctrla & USB_CTRLA_ENABLE) {
1534 hri_usbdevice_write_CTRLA_reg(hw, ctrla & ~USB_CTRLA_ENABLE);
1535 }
1536
1537 NVIC_DisableIRQ(USB_0_IRQn);
1538 NVIC_DisableIRQ(USB_1_IRQn);
1539 NVIC_DisableIRQ(USB_2_IRQn);
1540 NVIC_DisableIRQ(USB_3_IRQn);
1541
1542 hri_usbdevice_clear_INTEN_reg(hw,
1543 USB_DEVICE_INTENSET_SOF | USB_DEVICE_INTENSET_EORST | USB_DEVICE_INTENSET_RAMACER
1544 | USB_D_SUSPEND_INT_FLAGS | USB_D_WAKEUP_INT_FLAGS);
1545
1546 return ERR_NONE;
1547}
1548
1549void _usb_d_dev_attach(void)
1550{
1551 hri_usbdevice_clear_CTRLB_DETACH_bit(USB);
1552}
1553
1554void _usb_d_dev_detach(void)
1555{
1556 hri_usbdevice_set_CTRLB_DETACH_bit(USB);
1557}
1558
1559#ifndef USB_FSMSTATUS_FSMSTATE_ON
1560#define USB_FSMSTATUS_FSMSTATE_ON USB_FSMSTATUS_FSMSTATE(2ul)
1561#endif
1562void _usb_d_dev_send_remotewakeup(void)
1563{
1564 uint32_t retry = CONF_USB_RMT_WKUP_RETRY;
1565 _usb_d_dev_wait_clk_rdy(CONF_USB_D_CLK_SRC);
1566 while ((USB_FSMSTATUS_FSMSTATE_ON != hri_usbdevice_read_FSMSTATUS_FSMSTATE_bf(USB)) && (retry--)) {
1567 USB->DEVICE.CTRLB.bit.UPRSM = 1;
1568 }
1569}
1570
1571enum usb_speed _usb_d_dev_get_speed(void)
1572{
1573 uint8_t sp = (enum usb_speed)hri_usbdevice_read_STATUS_SPEED_bf(USB);
1574 const enum usb_speed speed[2] = {USB_SPEED_FS, USB_SPEED_LS};
1575
1576 return speed[sp];
1577}
1578
1579void _usb_d_dev_set_address(uint8_t addr)
1580{
1581 hri_usbdevice_write_DADD_reg(USB, USB_DEVICE_DADD_ADDEN | USB_DEVICE_DADD_DADD(addr));
1582}
1583
1584uint8_t _usb_d_dev_get_address(void)
1585{
1586 uint8_t addr = hri_usbdevice_read_DADD_DADD_bf(USB);
1587 return addr;
1588}
1589
1590uint16_t _usb_d_dev_get_frame_n(void)
1591{
1592 uint16_t fn = hri_usbdevice_read_FNUM_FNUM_bf(USB);
1593 return fn;
1594}
1595
1596uint8_t _usb_d_dev_get_uframe_n(void)
1597{
1598 uint8_t ufn = hri_usbdevice_read_FNUM_MFNUM_bf(USB);
1599 return ufn;
1600}
1601
1602/**
1603 * \brief Start a setup transaction
1604 * \param[in] ept Endpoint information.
1605 */
1606static inline void _usb_d_dev_trans_setup(struct _usb_d_dev_ep *ept)
1607{
1608 Usb * hw = USB;
1609 uint8_t epn = USB_EP_GET_N(ept->ep);
1610
1611 _usbd_ep_set_buf(epn, 0, (uint32_t)ept->cache);
1612 _usbd_ep_set_out_trans(epn, 0, ept->size, 0);
1613
1614 hri_usbendpoint_clear_EPSTATUS_reg(hw, epn, USB_DEVICE_EPSTATUS_STALLRQ(0x3) | USB_DEVICE_EPSTATUS_BK1RDY);
1615 _usbd_ep_set_out_rdy(epn, 0, false);
1616
1617 hri_usbendpoint_set_EPINTEN_reg(hw, epn, USB_D_SETUP_INT_FLAGS);
1618}
1619
1620int32_t _usb_d_dev_ep0_init(const uint8_t max_pkt_siz)
1621{
1622 return _usb_d_dev_ep_init(0, USB_EP_XTYPE_CTRL, max_pkt_siz);
1623}
1624
1625int32_t _usb_d_dev_ep_init(const uint8_t ep, const uint8_t attr, const uint16_t max_pkt_siz)
1626{
1627 uint8_t epn = USB_EP_GET_N(ep);
1628 bool dir = USB_EP_GET_DIR(ep);
1629 struct _usb_d_dev_ep *ept = _usb_d_dev_ept(epn, dir);
1630
1631 uint8_t ep_type = attr & USB_EP_XTYPE_MASK;
1632 const struct _usb_ep_cfg_item *pcfg = &_usb_ep_cfgs[epn];
1633
1634 if (epn > CONF_USB_D_MAX_EP_N) {
1635 return -USB_ERR_PARAM;
1636 }
1637 if (ept->ep != 0xFF) {
1638 return -USB_ERR_REDO;
1639 }
1640 if (ep_type == USB_EP_XTYPE_CTRL) {
1641 struct _usb_d_dev_ep *ept_in = _usb_d_dev_ept(epn, !dir);
1642 if (ept_in->ep != 0xFF) {
1643 return -USB_ERR_REDO;
1644 }
1645 if (pcfg->cache == NULL) {
1646 return -USB_ERR_FUNC;
1647 }
1648 }
1649 if ((dir ? pcfg->i_cache : pcfg->cache) && ((dir ? pcfg->i_size : pcfg->size) < max_pkt_siz)) {
1650 return -USB_ERR_FUNC;
1651 }
1652
1653 /* Initialize EP n settings */
1654 ept->cache = (uint8_t *)(dir ? pcfg->i_cache : pcfg->cache);
1655 ept->size = max_pkt_siz;
1656 ept->flags.u8 = (ep_type + 1);
1657 ept->ep = ep;
1658
1659 return USB_OK;
1660}
1661
1662void _usb_d_dev_ep_deinit(uint8_t ep)
1663{
1664 Usb * hw = USB;
1665 uint8_t epn = USB_EP_GET_N(ep);
1666 bool dir = USB_EP_GET_DIR(ep);
1667 struct _usb_d_dev_ep *ept = _usb_d_dev_ept(epn, dir);
1668
1669 if (epn > CONF_USB_D_MAX_EP_N || !_usb_d_dev_ep_is_used(ept)) {
1670 return;
1671 }
1672
1673 /* Finish pending transactions. */
1674 _usb_d_dev_trans_stop(ept, dir, USB_TRANS_RESET);
1675
1676 /* Disable the endpoint. */
1677 if (_usb_d_dev_ep_is_ctrl(ept)) {
1678 hw->DEVICE.DeviceEndpoint[ep].EPCFG.reg = 0;
1679 } else if (USB_EP_GET_DIR(ep)) {
1680 hw->DEVICE.DeviceEndpoint[USB_EP_GET_N(ep)].EPCFG.reg &= ~USB_DEVICE_EPCFG_EPTYPE1_Msk;
1681 } else {
1682 hw->DEVICE.DeviceEndpoint[ep].EPCFG.reg &= ~USB_DEVICE_EPCFG_EPTYPE0_Msk;
1683 }
1684 ept->flags.u8 = 0;
1685 ept->ep = 0xFF;
1686}
1687
1688int32_t _usb_d_dev_ep_enable(const uint8_t ep)
1689{
1690 Usb * hw = USB;
1691 uint8_t epn = USB_EP_GET_N(ep);
1692 bool dir = USB_EP_GET_DIR(ep);
1693 struct _usb_d_dev_ep *ept = _usb_d_dev_ept(epn, dir);
1694 uint8_t epcfg = hri_usbendpoint_read_EPCFG_reg(hw, epn);
1695 UsbDeviceDescBank * bank;
1696
1697 if (epn > CONF_USB_D_MAX_EP_N || !_usb_d_dev_ep_is_used(ept)) {
1698 return -USB_ERR_PARAM;
1699 }
1700
1701 bank = prvt_inst.desc_table[epn].DeviceDescBank;
1702 if (ept->flags.bits.eptype == USB_D_EPTYPE_CTRL) {
1703 if (epcfg & (USB_DEVICE_EPCFG_EPTYPE1_Msk | USB_DEVICE_EPCFG_EPTYPE0_Msk)) {
1704 return -USB_ERR_REDO;
1705 }
1706 hri_usbendpoint_write_EPCFG_reg(hw, epn, USB_D_EPCFG_CTRL);
1707 bank[0].PCKSIZE.reg = USB_DEVICE_PCKSIZE_MULTI_PACKET_SIZE(ept->size)
1708 | USB_DEVICE_PCKSIZE_SIZE(_usbd_ep_pcksize_size(ept->size));
1709 bank[1].PCKSIZE.reg
1710 = USB_DEVICE_PCKSIZE_BYTE_COUNT(ept->size) | USB_DEVICE_PCKSIZE_SIZE(_usbd_ep_pcksize_size(ept->size));
1711 /* By default, control endpoint accept SETUP and NAK all other token. */
1712 _usbd_ep_set_out_rdy(epn, 0, false);
1713 _usbd_ep_set_in_rdy(epn, 1, false);
1714
1715 _usbd_ep_clear_bank_status(epn, 0);
1716 _usbd_ep_clear_bank_status(epn, 1);
1717
1718 /* Enable SETUP reception for control endpoint. */
1719 _usb_d_dev_trans_setup(ept);
1720
1721 } else if (dir) {
1722 if (epcfg & USB_DEVICE_EPCFG_EPTYPE1_Msk) {
1723 return -USB_ERR_REDO;
1724 }
1725 epcfg |= USB_DEVICE_EPCFG_EPTYPE1(ept->flags.bits.eptype);
1726 hri_usbendpoint_write_EPCFG_reg(hw, epn, epcfg);
1727
1728 bank[1].PCKSIZE.reg
1729 = USB_DEVICE_PCKSIZE_BYTE_COUNT(ept->size) | USB_DEVICE_PCKSIZE_SIZE(_usbd_ep_pcksize_size(ept->size));
1730
1731 /* By default, IN endpoint will NAK all token. */
1732 _usbd_ep_set_in_rdy(epn, 1, false);
1733 _usbd_ep_clear_bank_status(epn, 1);
1734
1735 } else {
1736
1737 if (epcfg & USB_DEVICE_EPCFG_EPTYPE0_Msk) {
1738 return -USB_ERR_REDO;
1739 }
1740 epcfg |= USB_DEVICE_EPCFG_EPTYPE0(ept->flags.bits.eptype);
1741 hri_usbendpoint_write_EPCFG_reg(hw, epn, epcfg);
1742
1743 bank[0].PCKSIZE.reg = USB_DEVICE_PCKSIZE_MULTI_PACKET_SIZE(ept->size)
1744 | USB_DEVICE_PCKSIZE_SIZE(_usbd_ep_pcksize_size(ept->size));
1745
1746 /* By default, OUT endpoint will NAK all token. */
1747 _usbd_ep_set_out_rdy(epn, 0, false);
1748 _usbd_ep_clear_bank_status(epn, 0);
1749 }
1750
1751 return USB_OK;
1752}
1753
1754void _usb_d_dev_ep_disable(const uint8_t ep)
1755{
1756 Usb * hw = USB;
1757 uint8_t epn = USB_EP_GET_N(ep);
1758 bool dir = USB_EP_GET_DIR(ep);
1759 struct _usb_d_dev_ep *ept = _usb_d_dev_ept(epn, dir);
1760
1761 _usb_d_dev_trans_stop(ept, dir, USB_TRANS_RESET);
1762 if (_usb_d_dev_ep_is_ctrl(ept)) {
1763 hri_usbendpoint_clear_EPINTEN_reg(hw, epn, USB_D_ALL_INT_FLAGS);
1764 }
1765}
1766
1767/**
1768 * \brief Get endpoint stall status
1769 * \param[in] ept Pointer to endpoint information.
1770 * \param[in] dir Endpoint direction.
1771 * \return Stall status.
1772 * \retval \c true Endpoint is stalled.
1773 * \retval \c false Endpoint is not stalled.
1774 */
1775static inline int32_t _usb_d_dev_ep_stall_get(struct _usb_d_dev_ep *ept, bool dir)
1776{
1777 uint8_t epn = USB_EP_GET_N(ept->ep);
1778 return _usbd_ep_is_stalled(epn, dir);
1779}
1780
1781/**
1782 * \brief Set endpoint stall
1783 * \param[in, out] ept Pointer to endpoint information.
1784 * \param[in] dir Endpoint direction.
1785 * \return Always 0, success.
1786 */
1787static inline int32_t _usb_d_dev_ep_stall_set(struct _usb_d_dev_ep *ept, bool dir)
1788{
1789 uint8_t epn = USB_EP_GET_N(ept->ep);
1790 _usbd_ep_set_stall(epn, dir, true);
1791 _usbd_ep_int_en(epn, USB_DEVICE_EPINTFLAG_STALL0 << dir);
1792 ept->flags.bits.is_stalled = 1;
1793 /* In stall interrupt abort the transfer. */
1794 return ERR_NONE;
1795}
1796
1797/**
1798 * \brief Clear endpoint stall
1799 * \param[in, out] ept Pointer to endpoint information.
1800 * \param[in] dir Endpoint direction.
1801 * \return Always 0, success.
1802 */
1803static inline int32_t _usb_d_dev_ep_stall_clr(struct _usb_d_dev_ep *ept, bool dir)
1804{
1805 uint8_t epn = USB_EP_GET_N(ept->ep);
1806 bool is_stalled = _usbd_ep_is_stalled(epn, dir);
1807 if (!is_stalled) {
1808 return ERR_NONE;
1809 }
1810 _usbd_ep_set_stall(epn, dir, false);
1811 _usbd_ep_int_dis(epn, USB_DEVICE_EPINTFLAG_STALL0 << dir);
1812 if (_usbd_ep_is_stall_sent(epn, dir)) {
1813 _usbd_ep_ack_stall(epn, dir);
1814 _usbd_ep_set_toggle(epn, dir, 0);
1815 }
1816 if (_usb_d_dev_ep_is_ctrl(ept)) {
1817 if ((hri_usbendpoint_read_EPSTATUS_reg(USB, epn) & USB_DEVICE_EPSTATUS_STALLRQ_Msk) == 0) {
1818 ept->flags.bits.is_stalled = 0;
1819 }
1820 } else {
1821 ept->flags.bits.is_stalled = 0;
1822 }
1823 return ERR_NONE;
1824}
1825
1826int32_t _usb_d_dev_ep_stall(const uint8_t ep, const enum usb_ep_stall_ctrl ctrl)
1827{
1828 uint8_t epn = USB_EP_GET_N(ep);
1829 bool dir = USB_EP_GET_DIR(ep);
1830 struct _usb_d_dev_ep *ept = _usb_d_dev_ept(epn, dir);
1831 int32_t rc;
1832
1833 if (epn > CONF_USB_D_MAX_EP_N) {
1834 return -USB_ERR_PARAM;
1835 }
1836
1837 if (USB_EP_STALL_SET == ctrl) {
1838 rc = _usb_d_dev_ep_stall_set(ept, dir);
1839 } else if (USB_EP_STALL_CLR == ctrl) {
1840 rc = _usb_d_dev_ep_stall_clr(ept, dir);
1841 } else {
1842 rc = _usb_d_dev_ep_stall_get(ept, dir);
1843 }
1844 return rc;
1845}
1846
1847/**
1848 * \brief Finish the transaction and invoke callback
1849 * \param[in, out] ept Pointer to endpoint information.
1850 * \param[in] code Information code passed.
1851 */
1852static void _usb_d_dev_trans_done(struct _usb_d_dev_ep *ept, const int32_t code)
1853{
1854 if (!(_usb_d_dev_ep_is_used(ept) && _usb_d_dev_ep_is_busy(ept))) {
1855 return;
1856 }
1857 ept->flags.bits.is_busy = 0;
1858 dev_inst.ep_callbacks.done(ept->ep, code, ept->trans_count);
1859}
1860
1861/**
1862 * \brief Terminate the transaction with specific status code
1863 * \param[in, out] ept Pointer to endpoint information.
1864 * \param[in] dir Endpoint direction.
1865 * \param[in] code Information code passed.
1866 */
1867static void _usb_d_dev_trans_stop(struct _usb_d_dev_ep *ept, bool dir, const int32_t code)
1868{
1869 uint8_t epn = USB_EP_GET_N(ept->ep);
1870 ;
1871 const uint8_t intflags[2] = {USB_D_BANK0_INT_FLAGS, USB_D_BANK1_INT_FLAGS};
1872 if (!(_usb_d_dev_ep_is_used(ept) && _usb_d_dev_ep_is_busy(ept))) {
1873 return;
1874 }
1875 /* Stop transfer */
1876 if (dir) {
1877 /* NAK IN */
1878 _usbd_ep_set_in_rdy(epn, 1, false);
1879 } else {
1880 /* NAK OUT */
1881 _usbd_ep_set_out_rdy(epn, 0, false);
1882 }
1883 _usbd_ep_int_ack(epn, intflags[dir]);
1884 _usbd_ep_int_dis(epn, intflags[dir]);
1885 _usb_d_dev_trans_done(ept, code);
1886}
1887
1888int32_t _usb_d_dev_ep_read_req(const uint8_t ep, uint8_t *req_buf)
1889{
1890 uint8_t epn = USB_EP_GET_N(ep);
1891 UsbDeviceDescBank *bank = prvt_inst.desc_table[epn].DeviceDescBank;
1892 uint32_t addr = bank[0].ADDR.reg;
1893 uint16_t bytes = bank[0].PCKSIZE.bit.BYTE_COUNT;
1894
1895 if (epn > CONF_USB_D_MAX_EP_N || !req_buf) {
1896 return -USB_ERR_PARAM;
1897 }
1898 if (!_usbd_ep_is_ctrl(epn)) {
1899 return -USB_ERR_FUNC;
1900 }
1901 if (!_usbd_ep_is_setup(epn)) {
1902 return ERR_NONE;
1903 }
1904 memcpy(req_buf, (void *)addr, 8);
1905 _usbd_ep_ack_setup(epn);
1906
1907 return bytes;
1908}
1909
1910int32_t _usb_d_dev_ep_trans(const struct usb_d_transfer *trans)
1911{
1912 uint8_t epn = USB_EP_GET_N(trans->ep);
1913 bool dir = USB_EP_GET_DIR(trans->ep);
1914 struct _usb_d_dev_ep *ept = _usb_d_dev_ept(epn, dir);
1915
1916 uint16_t size_mask = (ept->size == 1023) ? 1023 : (ept->size - 1);
1917 bool size_n_aligned = (trans->size & size_mask);
1918
1919 bool use_cache = false;
1920
1921 volatile hal_atomic_t flags;
1922
1923 if (epn > CONF_USB_D_MAX_EP_N) {
1924 return -USB_ERR_PARAM;
1925 }
1926
1927 /* Cases that needs cache:
1928 * 1. Buffer not in RAM (cache all).
1929 * 2. IN/OUT with unaligned buffer (cache all).
1930 * 3. OUT with unaligned packet size (cache last packet).
1931 * 4. OUT size < 8 (sub-case for 3).
1932 */
1933 if (!_usb_is_addr4dma(trans->buf, trans->size) || (!_usb_is_aligned(trans->buf))
1934 || (!dir && (trans->size < ept->size))) {
1935 if (!ept->cache) {
1936 return -USB_ERR_FUNC;
1937 }
1938 /* Use cache all the time. */
1939 use_cache = true;
1940 }
1941 if (!dir && size_n_aligned) {
1942 if (!ept->cache) {
1943 return -USB_ERR_PARAM;
1944 }
1945 /* Set 'use_cache' on last packet. */
1946 }
1947
1948 /* Check halt */
1949 if (ept->flags.bits.is_stalled) {
1950 return USB_HALTED;
1951 }
1952
1953 /* Try to start transactions. */
1954
1955 atomic_enter_critical(&flags);
1956 if (_usb_d_dev_ep_is_busy(ept)) {
1957 atomic_leave_critical(&flags);
1958 return USB_BUSY;
1959 }
1960 ept->flags.bits.is_busy = 1;
1961 atomic_leave_critical(&flags);
1962
1963 /* Copy transaction information. */
1964 ept->trans_buf = trans->buf;
1965 ept->trans_size = trans->size;
1966 ept->trans_count = 0;
1967
1968 ept->flags.bits.dir = dir;
1969 ept->flags.bits.use_cache = use_cache;
1970 ept->flags.bits.need_zlp = (trans->zlp && (!size_n_aligned));
1971
1972 if (dir) {
1973 _usb_d_dev_in_next(ept, false);
1974 } else {
1975 _usb_d_dev_out_next(ept, false);
1976 }
1977
1978 return ERR_NONE;
1979}
1980
1981void _usb_d_dev_ep_abort(const uint8_t ep)
1982{
1983 uint8_t epn = USB_EP_GET_N(ep);
1984 bool dir = USB_EP_GET_DIR(ep);
1985 struct _usb_d_dev_ep *ept = _usb_d_dev_ept(epn, dir);
1986 if (epn > CONF_USB_D_MAX_EP_N) {
1987 return;
1988 }
1989 _usb_d_dev_trans_stop(ept, dir, USB_TRANS_ABORT);
1990}
1991
1992int32_t _usb_d_dev_ep_get_status(const uint8_t ep, struct usb_d_trans_status *stat)
1993{
1994 uint8_t epn = USB_EP_GET_N(ep);
1995 bool dir = USB_EP_GET_DIR(ep);
1996 struct _usb_d_dev_ep *ept = _usb_d_dev_ept(epn, dir);
1997 bool busy, stall;
1998
1999 if (epn > CONF_USB_D_MAX_EP_N) {
2000 return USB_ERR_PARAM;
2001 }
2002 busy = ept->flags.bits.is_busy;
2003 stall = ept->flags.bits.is_stalled;
2004 if (stat) {
2005 stat->stall = stall;
2006 stat->busy = busy;
2007 stat->setup = USB->DEVICE.DeviceEndpoint[epn].EPINTFLAG.bit.RXSTP;
2008 stat->dir = ept->flags.bits.dir;
2009 stat->size = ept->trans_size;
2010 stat->count = ept->trans_count;
2011 stat->ep = ep;
2012 stat->xtype = ept->flags.bits.eptype - 1;
2013 }
2014 if (stall) {
2015 return USB_HALTED;
2016 }
2017 if (busy) {
2018 return USB_BUSY;
2019 }
2020 return USB_OK;
2021}
2022
2023void _usb_d_dev_register_callback(const enum usb_d_cb_type type, const FUNC_PTR func)
2024{
2025 FUNC_PTR f = (func == NULL) ? (FUNC_PTR)_dummy_func_no_return : (FUNC_PTR)func;
2026 if (type == USB_D_CB_EVENT) {
2027 dev_inst.callbacks.event = (_usb_d_dev_event_cb_t)f;
2028 } else if (type == USB_D_CB_SOF) {
2029 dev_inst.callbacks.sof = (_usb_d_dev_sof_cb_t)f;
2030 }
2031}
2032
2033void _usb_d_dev_register_ep_callback(const enum usb_d_dev_ep_cb_type type, const FUNC_PTR func)
2034{
2035 FUNC_PTR f = (func == NULL) ? (FUNC_PTR)_dummy_func_no_return : (FUNC_PTR)func;
2036 if (type == USB_D_DEV_EP_CB_SETUP) {
2037 dev_inst.ep_callbacks.setup = (_usb_d_dev_ep_cb_setup_t)f;
2038 } else if (type == USB_D_DEV_EP_CB_MORE) {
2039 dev_inst.ep_callbacks.more = (_usb_d_dev_ep_cb_more_t)f;
2040 } else if (type == USB_D_DEV_EP_CB_DONE) {
2041 dev_inst.ep_callbacks.done = (_usb_d_dev_ep_cb_done_t)f;
2042 }
2043}
2044
2045/**
2046 * \brief USB interrupt handler
2047 */
2048void USB_0_Handler(void)
2049{
2050
2051 _usb_d_dev_handler();
2052}
2053/**
2054 * \brief USB interrupt handler
2055 */
2056void USB_1_Handler(void)
2057{
2058
2059 _usb_d_dev_handler();
2060}
2061/**
2062 * \brief USB interrupt handler
2063 */
2064void USB_2_Handler(void)
2065{
2066
2067 _usb_d_dev_handler();
2068}
2069/**
2070 * \brief USB interrupt handler
2071 */
2072void USB_3_Handler(void)
2073{
2074
2075 _usb_d_dev_handler();
2076}