4 * \brief SAM USB Driver.
6 * Copyright (C) 2014-2016 Atmel Corporation. All rights reserved.
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions are met:
15 * 1. Redistributions of source code must retain the above copyright notice,
16 * this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright notice,
19 * this list of conditions and the following disclaimer in the documentation
20 * and/or other materials provided with the distribution.
22 * 3. The name of Atmel may not be used to endorse or promote products derived
23 * from this software without specific prior written permission.
25 * 4. This software may only be redistributed and used in connection with an
26 * Atmel microcontroller product.
28 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
29 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
30 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
31 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
32 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
36 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
37 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 * POSSIBILITY OF SUCH DAMAGE.
44 * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
47 #define DEVICE_MODE_ONLY true
48 #define SAMD11 DEVICE_MODE_ONLY
55 #undef LITTLE_ENDIAN //redefined in samd51j18a.h
56 #include "samd51j18a.h"
60 #include "status_codes.h"
63 /** Fields definition from a LPM TOKEN */
64 #define USB_LPM_ATTRIBUT_BLINKSTATE_MASK (0xF << 0)
65 #define USB_LPM_ATTRIBUT_HIRD_MASK (0xF << 4)
66 #define USB_LPM_ATTRIBUT_REMOTEWAKE_MASK (1 << 8)
67 #define USB_LPM_ATTRIBUT_BLINKSTATE(value) ((value & 0xF) << 0)
68 #define USB_LPM_ATTRIBUT_HIRD(value) ((value & 0xF) << 4)
69 #define USB_LPM_ATTRIBUT_REMOTEWAKE(value) ((value & 1) << 8)
70 #define USB_LPM_ATTRIBUT_BLINKSTATE_L1 USB_LPM_ATTRIBUT_BLINKSTATE(1)
73 * \brief Mask selecting the index part of an endpoint address
75 #define USB_EP_ADDR_MASK 0x0f
78 * \brief Endpoint transfer direction is IN
80 #define USB_EP_DIR_IN 0x80
83 * \brief Endpoint transfer direction is OUT
85 #define USB_EP_DIR_OUT 0x00
88 * \name USB SRAM data containing pipe descriptor table
89 * The content of the USB SRAM can be :
90 * - modified by USB hardware interface to update pipe status.
91 * Thereby, it is read by software.
92 * - modified by USB software to control pipe.
93 * Thereby, it is read by hardware.
94 * This data section is volatile.
101 UsbDeviceDescriptor usb_endpoint_table[USB_EPT_NUM];
102 } usb_descriptor_table;
103 COMPILER_PACK_RESET()
107 * \brief Local USB module instance
109 static struct usb_module *_usb_instances;
111 /* Device LPM callback variable */
112 static uint32_t device_callback_lpm_wakeup_enable;
115 * \brief Device endpoint callback parameter variable, used to transfer info to UDD wrapper layer
117 static struct usb_endpoint_callback_parameter ep_callback_para;
120 * \internal USB Device IRQ Mask Bits Map
122 static const uint16_t _usb_device_irq_bits[USB_DEVICE_CALLBACK_N] = {
123 USB_DEVICE_INTFLAG_SOF,
124 USB_DEVICE_INTFLAG_EORST,
125 USB_DEVICE_INTFLAG_WAKEUP | USB_DEVICE_INTFLAG_EORSM | USB_DEVICE_INTFLAG_UPRSM,
126 USB_DEVICE_INTFLAG_RAMACER,
127 USB_DEVICE_INTFLAG_SUSPEND,
128 USB_DEVICE_INTFLAG_LPMNYET,
129 USB_DEVICE_INTFLAG_LPMSUSP,
133 * \internal USB Device IRQ Mask Bits Map
135 static const uint8_t _usb_endpoint_irq_bits[USB_DEVICE_EP_CALLBACK_N] = {
136 USB_DEVICE_EPINTFLAG_TRCPT_Msk,
137 USB_DEVICE_EPINTFLAG_TRFAIL_Msk,
138 USB_DEVICE_EPINTFLAG_RXSTP,
139 USB_DEVICE_EPINTFLAG_STALL_Msk
143 * \brief Registers a USB device callback
145 * Registers a callback function which is implemented by the user.
147 * \note The callback must be enabled by \ref usb_device_enable_callback,
148 * in order for the interrupt handler to call it when the conditions for the
149 * callback type is met.
151 * \param[in] module_inst Pointer to USB software instance struct
152 * \param[in] callback_type Callback type given by an enum
153 * \param[in] callback_func Pointer to callback function
155 * \return Status of the registration operation.
156 * \retval STATUS_OK The callback was registered successfully.
158 enum status_code usb_device_register_callback(struct usb_module *module_inst,
159 enum usb_device_callback callback_type,
160 usb_device_callback_t callback_func)
162 /* Sanity check arguments */
164 Assert(callback_func);
166 /* Register callback function */
167 module_inst->device_callback[callback_type] = callback_func;
169 /* Set the bit corresponding to the callback_type */
170 module_inst->device_registered_callback_mask |= _usb_device_irq_bits[callback_type];
176 * \brief Unregisters a USB device callback
178 * Unregisters an asynchronous callback implemented by the user. Removing it
179 * from the internal callback registration table.
181 * \param[in] module_inst Pointer to USB software instance struct
182 * \param[in] callback_type Callback type given by an enum
184 * \return Status of the de-registration operation.
185 * \retval STATUS_OK The callback was unregistered successfully.
187 enum status_code usb_device_unregister_callback(struct usb_module *module_inst,
188 enum usb_device_callback callback_type)
190 /* Sanity check arguments */
193 /* Unregister callback function */
194 module_inst->device_callback[callback_type] = NULL;
196 /* Clear the bit corresponding to the callback_type */
197 module_inst->device_registered_callback_mask &= ~_usb_device_irq_bits[callback_type];
203 * \brief Enables USB device callback generation for a given type.
205 * Enables asynchronous callbacks for a given logical type.
206 * This must be called before USB device generate callback events.
208 * \param[in] module_inst Pointer to USB software instance struct
209 * \param[in] callback_type Callback type given by an enum
211 * \return Status of the callback enable operation.
212 * \retval STATUS_OK The callback was enabled successfully.
214 enum status_code usb_device_enable_callback(struct usb_module *module_inst,
215 enum usb_device_callback callback_type)
217 /* Sanity check arguments */
219 Assert(module_inst->hw);
221 /* clear related flag */
222 module_inst->hw->DEVICE.INTFLAG.reg = _usb_device_irq_bits[callback_type];
224 /* Enable callback */
225 module_inst->device_enabled_callback_mask |= _usb_device_irq_bits[callback_type];
227 module_inst->hw->DEVICE.INTENSET.reg = _usb_device_irq_bits[callback_type];
233 * \brief Disables USB device callback generation for a given type.
235 * Disables asynchronous callbacks for a given logical type.
237 * \param[in] module_inst Pointer to USB software instance struct
238 * \param[in] callback_type Callback type given by an enum
240 * \return Status of the callback disable operation.
241 * \retval STATUS_OK The callback was disabled successfully.
243 enum status_code usb_device_disable_callback(struct usb_module *module_inst,
244 enum usb_device_callback callback_type)
246 /* Sanity check arguments */
248 Assert(module_inst->hw);
250 /* Disable callback */
251 module_inst->device_enabled_callback_mask &= ~_usb_device_irq_bits[callback_type];
253 module_inst->hw->DEVICE.INTENCLR.reg = _usb_device_irq_bits[callback_type];
259 * \brief Registers a USB device endpoint callback
261 * Registers a callback function which is implemented by the user.
263 * \note The callback must be enabled by \ref usb_device_endpoint_enable_callback,
264 * in order for the interrupt handler to call it when the conditions for the
265 * callback type is met.
267 * \param[in] module_inst Pointer to USB software instance struct
268 * \param[in] ep_num Endpoint to configure
269 * \param[in] callback_type Callback type given by an enum
270 * \param[in] callback_func Pointer to callback function
272 * \return Status of the registration operation.
273 * \retval STATUS_OK The callback was registered successfully.
275 enum status_code usb_device_endpoint_register_callback(
276 struct usb_module *module_inst, uint8_t ep_num,
277 enum usb_device_endpoint_callback callback_type,
278 usb_device_endpoint_callback_t callback_func)
280 /* Sanity check arguments */
282 Assert(ep_num < USB_EPT_NUM);
283 Assert(callback_func);
285 /* Register callback function */
286 module_inst->device_endpoint_callback[ep_num][callback_type] = callback_func;
288 /* Set the bit corresponding to the callback_type */
289 module_inst->device_endpoint_registered_callback_mask[ep_num] |= _usb_endpoint_irq_bits[callback_type];
295 * \brief Unregisters a USB device endpoint callback
297 * Unregisters an callback implemented by the user. Removing it
298 * from the internal callback registration table.
300 * \param[in] module_inst Pointer to USB software instance struct
301 * \param[in] ep_num Endpoint to configure
302 * \param[in] callback_type Callback type given by an enum
304 * \return Status of the de-registration operation.
305 * \retval STATUS_OK The callback was unregistered successfully.
307 enum status_code usb_device_endpoint_unregister_callback(
308 struct usb_module *module_inst, uint8_t ep_num,
309 enum usb_device_endpoint_callback callback_type)
311 /* Sanity check arguments */
313 Assert(ep_num < USB_EPT_NUM);
315 /* Unregister callback function */
316 module_inst->device_endpoint_callback[ep_num][callback_type] = NULL;
318 /* Clear the bit corresponding to the callback_type */
319 module_inst->device_endpoint_registered_callback_mask[ep_num] &= ~_usb_endpoint_irq_bits[callback_type];
325 * \brief Enables USB device endpoint callback generation for a given type.
327 * Enables callbacks for a given logical type.
328 * This must be called before USB device pipe generate callback events.
330 * \param[in] module_inst Pointer to USB software instance struct
331 * \param[in] ep Endpoint to configure
332 * \param[in] callback_type Callback type given by an enum
334 * \return Status of the callback enable operation.
335 * \retval STATUS_OK The callback was enabled successfully.
337 enum status_code usb_device_endpoint_enable_callback(
338 struct usb_module *module_inst, uint8_t ep,
339 enum usb_device_endpoint_callback callback_type)
341 /* Sanity check arguments */
343 Assert(module_inst->hw);
345 uint8_t ep_num = ep & USB_EP_ADDR_MASK;
346 Assert(ep_num < USB_EPT_NUM);
348 /* Enable callback */
349 module_inst->device_endpoint_enabled_callback_mask[ep_num] |= _usb_endpoint_irq_bits[callback_type];
351 if (callback_type == USB_DEVICE_ENDPOINT_CALLBACK_TRCPT) {
352 if (ep_num == 0) { // control endpoint
353 module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTENSET.reg = USB_DEVICE_EPINTENSET_TRCPT0 | USB_DEVICE_EPINTENSET_TRCPT1;
354 } else if (ep & USB_EP_DIR_IN) {
355 module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTENSET.reg = USB_DEVICE_EPINTENSET_TRCPT1;
357 module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTENSET.reg = USB_DEVICE_EPINTENSET_TRCPT0;
361 if (callback_type == USB_DEVICE_ENDPOINT_CALLBACK_TRFAIL) {
362 if (ep_num == 0) { // control endpoint
363 module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTENSET.reg = USB_DEVICE_EPINTENSET_TRFAIL0 | USB_DEVICE_EPINTENSET_TRFAIL1;
364 } else if (ep & USB_EP_DIR_IN) {
365 module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTENSET.reg = USB_DEVICE_EPINTENSET_TRFAIL1;
367 module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTENSET.reg = USB_DEVICE_EPINTENSET_TRFAIL0;
371 if (callback_type == USB_DEVICE_ENDPOINT_CALLBACK_RXSTP) {
372 module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTENSET.reg = USB_DEVICE_EPINTENSET_RXSTP;
375 if (callback_type == USB_DEVICE_ENDPOINT_CALLBACK_STALL) {
376 if (ep & USB_EP_DIR_IN) {
377 module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTENSET.reg = USB_DEVICE_EPINTENSET_STALL1;
379 module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTENSET.reg = USB_DEVICE_EPINTENSET_STALL0;
387 * \brief Disables USB device endpoint callback generation for a given type.
389 * Disables callbacks for a given logical type.
391 * \param[in] module_inst Pointer to USB software instance struct
392 * \param[in] ep Endpoint to configure
393 * \param[in] callback_type Callback type given by an enum
395 * \return Status of the callback disable operation.
396 * \retval STATUS_OK The callback was disabled successfully.
398 enum status_code usb_device_endpoint_disable_callback(
399 struct usb_module *module_inst, uint8_t ep,
400 enum usb_device_endpoint_callback callback_type)
402 /* Sanity check arguments */
404 Assert(module_inst->hw);
406 uint8_t ep_num = ep & USB_EP_ADDR_MASK;
407 Assert(ep_num < USB_EPT_NUM);
409 /* Enable callback */
410 module_inst->device_endpoint_enabled_callback_mask[ep_num] &= ~_usb_endpoint_irq_bits[callback_type];
412 if (callback_type == USB_DEVICE_ENDPOINT_CALLBACK_TRCPT) {
413 if (ep_num == 0) { // control endpoint
414 module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTENCLR.reg = USB_DEVICE_EPINTENCLR_TRCPT0 | USB_DEVICE_EPINTENCLR_TRCPT1;
415 } else if (ep & USB_EP_DIR_IN) {
416 module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTENCLR.reg = USB_DEVICE_EPINTENCLR_TRCPT1;
418 module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTENCLR.reg = USB_DEVICE_EPINTENCLR_TRCPT0;
422 if (callback_type == USB_DEVICE_ENDPOINT_CALLBACK_TRFAIL) {
423 if (ep_num == 0) { // control endpoint
424 module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTENCLR.reg = USB_DEVICE_EPINTENCLR_TRFAIL0 | USB_DEVICE_EPINTENCLR_TRFAIL1;
425 } else if (ep & USB_EP_DIR_IN) {
426 module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTENCLR.reg = USB_DEVICE_EPINTENCLR_TRFAIL1;
428 module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTENCLR.reg = USB_DEVICE_EPINTENCLR_TRFAIL0;
432 if (callback_type == USB_DEVICE_ENDPOINT_CALLBACK_RXSTP) {
433 module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTENCLR.reg = USB_DEVICE_EPINTENCLR_RXSTP;
436 if (callback_type == USB_DEVICE_ENDPOINT_CALLBACK_STALL) {
437 if (ep & USB_EP_DIR_IN) {
438 module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTENCLR.reg = USB_DEVICE_EPINTENCLR_STALL1;
440 module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTENCLR.reg = USB_DEVICE_EPINTENCLR_STALL0;
448 * \brief Initializes an USB device endpoint configuration structure to defaults.
450 * Initializes a given USB device endpoint configuration structure to a
451 * set of known default values. This function should be called on all new
452 * instances of these configuration structures before being modified by the
455 * The default configuration is as follows:
456 * \li endpoint address is 0
457 * \li endpoint size is 8 bytes
458 * \li auto_zlp is false
459 * \li endpoint type is control
461 * \param[out] ep_config Configuration structure to initialize to default values
463 void usb_device_endpoint_get_config_defaults(struct usb_device_endpoint_config *ep_config)
465 /* Sanity check arguments */
468 /* Write default config to config struct */
469 ep_config->ep_address = 0;
470 ep_config->ep_size = USB_ENDPOINT_8_BYTE;
471 ep_config->auto_zlp = false;
472 ep_config->ep_type = USB_DEVICE_ENDPOINT_TYPE_CONTROL;
476 * \brief Writes an USB device endpoint configuration to the hardware module.
478 * Writes out a given configuration of an USB device endpoint
479 * configuration to the hardware module. If the pipe is already configured,
480 * the new configuration will replace the existing one.
482 * \param[in] module_inst Pointer to USB software instance struct
483 * \param[in] ep_config Configuration settings for the endpoint
485 * \return Status of the device endpoint configuration operation
486 * \retval STATUS_OK The device endpoint was configured successfully
487 * \retval STATUS_ERR_DENIED The endpoint address is already configured
489 enum status_code usb_device_endpoint_set_config(struct usb_module *module_inst,
490 struct usb_device_endpoint_config *ep_config)
492 /* Sanity check arguments */
496 uint8_t ep_num = ep_config->ep_address & USB_EP_ADDR_MASK;
497 uint8_t ep_bank = (ep_config->ep_address & USB_EP_DIR_IN) ? 1 : 0;
499 switch (ep_config->ep_type) {
500 case USB_DEVICE_ENDPOINT_TYPE_DISABLE:
501 module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPCFG.reg = USB_DEVICE_EPCFG_EPTYPE0(0) | USB_DEVICE_EPCFG_EPTYPE1(0);
504 case USB_DEVICE_ENDPOINT_TYPE_CONTROL:
505 if ((module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPCFG.reg & USB_DEVICE_EPCFG_EPTYPE0_Msk) == 0 && \
506 (module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPCFG.reg & USB_DEVICE_EPCFG_EPTYPE1_Msk) == 0) {
507 module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPCFG.reg = USB_DEVICE_EPCFG_EPTYPE0(1) | USB_DEVICE_EPCFG_EPTYPE1(1);
508 module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_BK0RDY;
509 module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_BK1RDY;
511 return STATUS_ERR_DENIED;
513 if (true == ep_config->auto_zlp) {
514 usb_descriptor_table.usb_endpoint_table[ep_num].DeviceDescBank[0].PCKSIZE.reg |= USB_DEVICE_PCKSIZE_AUTO_ZLP;
515 usb_descriptor_table.usb_endpoint_table[ep_num].DeviceDescBank[1].PCKSIZE.reg |= USB_DEVICE_PCKSIZE_AUTO_ZLP;
517 usb_descriptor_table.usb_endpoint_table[ep_num].DeviceDescBank[0].PCKSIZE.reg &= ~USB_DEVICE_PCKSIZE_AUTO_ZLP;
518 usb_descriptor_table.usb_endpoint_table[ep_num].DeviceDescBank[1].PCKSIZE.reg &= ~USB_DEVICE_PCKSIZE_AUTO_ZLP;
520 usb_descriptor_table.usb_endpoint_table[ep_num].DeviceDescBank[0].PCKSIZE.bit.SIZE = ep_config->ep_size;
521 usb_descriptor_table.usb_endpoint_table[ep_num].DeviceDescBank[1].PCKSIZE.bit.SIZE = ep_config->ep_size;
524 case USB_DEVICE_ENDPOINT_TYPE_ISOCHRONOUS:
526 if ((module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPCFG.reg & USB_DEVICE_EPCFG_EPTYPE1_Msk) == 0){
527 module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPCFG.reg |= USB_DEVICE_EPCFG_EPTYPE1(2);
528 module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_BK1RDY;
530 return STATUS_ERR_DENIED;
533 if ((module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPCFG.reg & USB_DEVICE_EPCFG_EPTYPE0_Msk) == 0){
534 module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPCFG.reg |= USB_DEVICE_EPCFG_EPTYPE0(2);
535 module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_BK0RDY;
537 return STATUS_ERR_DENIED;
542 case USB_DEVICE_ENDPOINT_TYPE_BULK:
544 if ((module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPCFG.reg & USB_DEVICE_EPCFG_EPTYPE1_Msk) == 0){
545 module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPCFG.reg |= USB_DEVICE_EPCFG_EPTYPE1(3);
546 module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_BK1RDY;
548 return STATUS_ERR_DENIED;
551 if ((module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPCFG.reg & USB_DEVICE_EPCFG_EPTYPE0_Msk) == 0){
552 module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPCFG.reg |= USB_DEVICE_EPCFG_EPTYPE0(3);
553 module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_BK0RDY;
555 return STATUS_ERR_DENIED;
560 case USB_DEVICE_ENDPOINT_TYPE_INTERRUPT:
562 if ((module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPCFG.reg & USB_DEVICE_EPCFG_EPTYPE1_Msk) == 0){
563 module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPCFG.reg |= USB_DEVICE_EPCFG_EPTYPE1(4);
564 module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_BK1RDY;
566 return STATUS_ERR_DENIED;
569 if ((module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPCFG.reg & USB_DEVICE_EPCFG_EPTYPE0_Msk) == 0){
570 module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPCFG.reg |= USB_DEVICE_EPCFG_EPTYPE0(4);
571 module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_BK0RDY;
573 return STATUS_ERR_DENIED;
582 usb_descriptor_table.usb_endpoint_table[ep_num].DeviceDescBank[ep_bank].PCKSIZE.bit.SIZE = ep_config->ep_size;
584 if (true == ep_config->auto_zlp) {
585 usb_descriptor_table.usb_endpoint_table[ep_num].DeviceDescBank[ep_bank].PCKSIZE.reg |= USB_DEVICE_PCKSIZE_AUTO_ZLP;
587 usb_descriptor_table.usb_endpoint_table[ep_num].DeviceDescBank[ep_bank].PCKSIZE.reg &= ~USB_DEVICE_PCKSIZE_AUTO_ZLP;
594 * \brief Check if current endpoint is configured
596 * \param module_inst Pointer to USB software instance struct
597 * \param ep Endpoint address (direction & number)
599 * \return \c true if endpoint is configured and ready to use
601 bool usb_device_endpoint_is_configured(struct usb_module *module_inst, uint8_t ep)
603 uint8_t ep_num = ep & USB_EP_ADDR_MASK;
606 if (ep & USB_EP_DIR_IN) {
607 flag = (uint8_t)(module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPCFG.bit.EPTYPE1);
609 flag = (uint8_t)(module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPCFG.bit.EPTYPE0);
611 return ((enum usb_device_endpoint_type)(flag) != USB_DEVICE_ENDPOINT_TYPE_DISABLE);
616 * \brief Abort ongoing job on the endpoint
618 * \param module_inst Pointer to USB software instance struct
619 * \param ep Endpoint address
621 void usb_device_endpoint_abort_job(struct usb_module *module_inst, uint8_t ep)
624 ep_num = ep & USB_EP_ADDR_MASK;
627 if (ep & USB_EP_DIR_IN) {
628 module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_BK1RDY;
629 // Eventually ack a transfer occur during abort
630 module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_TRCPT1;
632 module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_BK0RDY;
633 // Eventually ack a transfer occur during abort
634 module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_TRCPT0;
639 * \brief Check if endpoint is halted
641 * \param module_inst Pointer to USB software instance struct
642 * \param ep Endpoint address
644 * \return \c true if the endpoint is halted
646 bool usb_device_endpoint_is_halted(struct usb_module *module_inst, uint8_t ep)
648 uint8_t ep_num = ep & USB_EP_ADDR_MASK;
650 if (ep & USB_EP_DIR_IN) {
651 return (module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUS.reg & USB_DEVICE_EPSTATUSSET_STALLRQ1);
653 return (module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUS.reg & USB_DEVICE_EPSTATUSSET_STALLRQ0);
658 * \brief Halt the endpoint (send STALL)
660 * \param module_inst Pointer to USB software instance struct
661 * \param ep Endpoint address
663 void usb_device_endpoint_set_halt(struct usb_module *module_inst, uint8_t ep)
665 uint8_t ep_num = ep & USB_EP_ADDR_MASK;
668 if (ep & USB_EP_DIR_IN) {
669 module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_STALLRQ1;
671 module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_STALLRQ0;
676 * \brief Clear endpoint halt state
678 * \param module_inst Pointer to USB software instance struct
679 * \param ep Endpoint address
681 void usb_device_endpoint_clear_halt(struct usb_module *module_inst, uint8_t ep)
683 uint8_t ep_num = ep & USB_EP_ADDR_MASK;
685 if (ep & USB_EP_DIR_IN) {
686 if (module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUS.reg & USB_DEVICE_EPSTATUSSET_STALLRQ1) {
687 // Remove stall request
688 module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_STALLRQ1;
689 if (module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTFLAG.reg & USB_DEVICE_EPINTFLAG_STALL1) {
690 module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_STALL1;
691 // The Stall has occurred, then reset data toggle
692 module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSSET_DTGLIN;
696 if (module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUS.reg & USB_DEVICE_EPSTATUSSET_STALLRQ0) {
697 // Remove stall request
698 module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_STALLRQ0;
699 if (module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTFLAG.reg & USB_DEVICE_EPINTFLAG_STALL0) {
700 module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_STALL0;
701 // The Stall has occurred, then reset data toggle
702 module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSSET_DTGLOUT;
709 * \brief Start write buffer job on a endpoint
711 * \param module_inst Pointer to USB module instance
712 * \param ep_num Endpoint number
713 * \param pbuf Pointer to buffer
714 * \param buf_size Size of buffer
716 * \return Status of procedure
717 * \retval STATUS_OK Job started successfully
718 * \retval STATUS_ERR_DENIED Endpoint is not ready
720 enum status_code usb_device_endpoint_write_buffer_job(struct usb_module *module_inst,uint8_t ep_num,
721 uint8_t* pbuf, uint32_t buf_size)
723 /* Sanity check arguments */
725 Assert(module_inst->hw);
726 Assert(ep_num < USB_EPT_NUM);
729 flag = (uint8_t)(module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPCFG.bit.EPTYPE1);
730 if ((enum usb_device_endpoint_type)(flag) == USB_DEVICE_ENDPOINT_TYPE_DISABLE) {
731 return STATUS_ERR_DENIED;
734 /* get endpoint configuration from setting register */
735 usb_descriptor_table.usb_endpoint_table[ep_num].DeviceDescBank[1].ADDR.reg = (uint32_t)pbuf;
736 usb_descriptor_table.usb_endpoint_table[ep_num].DeviceDescBank[1].PCKSIZE.bit.MULTI_PACKET_SIZE = 0;
737 usb_descriptor_table.usb_endpoint_table[ep_num].DeviceDescBank[1].PCKSIZE.bit.BYTE_COUNT = buf_size;
738 module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_BK1RDY;
744 * \brief Start read buffer job on a endpoint
746 * \param module_inst Pointer to USB module instance
747 * \param ep_num Endpoint number
748 * \param pbuf Pointer to buffer
749 * \param buf_size Size of buffer
751 * \return Status of procedure
752 * \retval STATUS_OK Job started successfully
753 * \retval STATUS_ERR_DENIED Endpoint is not ready
755 enum status_code usb_device_endpoint_read_buffer_job(struct usb_module *module_inst,uint8_t ep_num,
756 uint8_t* pbuf, uint32_t buf_size)
758 /* Sanity check arguments */
760 Assert(module_inst->hw);
761 Assert(ep_num < USB_EPT_NUM);
764 flag = (uint8_t)(module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPCFG.bit.EPTYPE0);
765 if ((enum usb_device_endpoint_type)(flag) == USB_DEVICE_ENDPOINT_TYPE_DISABLE) {
766 return STATUS_ERR_DENIED;
769 /* get endpoint configuration from setting register */
770 usb_descriptor_table.usb_endpoint_table[ep_num].DeviceDescBank[0].ADDR.reg = (uint32_t)pbuf;
771 usb_descriptor_table.usb_endpoint_table[ep_num].DeviceDescBank[0].PCKSIZE.bit.MULTI_PACKET_SIZE = buf_size;
772 usb_descriptor_table.usb_endpoint_table[ep_num].DeviceDescBank[0].PCKSIZE.bit.BYTE_COUNT = 0;
773 module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_BK0RDY;
779 * \brief Start setup packet read job on a endpoint
781 * \param module_inst Pointer to USB device module instance
782 * \param pbuf Pointer to buffer
784 * \return Status of procedure
785 * \retval STATUS_OK Job started successfully
786 * \retval STATUS_ERR_DENIED Endpoint is not ready
788 enum status_code usb_device_endpoint_setup_buffer_job(struct usb_module *module_inst,
791 /* Sanity check arguments */
793 Assert(module_inst->hw);
795 /* get endpoint configuration from setting register */
796 usb_descriptor_table.usb_endpoint_table[0].DeviceDescBank[0].ADDR.reg = (uint32_t)pbuf;
797 usb_descriptor_table.usb_endpoint_table[0].DeviceDescBank[0].PCKSIZE.bit.MULTI_PACKET_SIZE = 8;
798 usb_descriptor_table.usb_endpoint_table[0].DeviceDescBank[0].PCKSIZE.bit.BYTE_COUNT = 0;
799 module_inst->hw->DEVICE.DeviceEndpoint[0].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_BK0RDY;
804 static void _usb_device_interrupt_handler(void)
807 uint16_t flags, flags_run;
808 ep_inst = _usb_instances->hw->DEVICE.EPINTSMRY.reg;
810 /* device interrupt */
814 /* get interrupt flags */
815 flags = _usb_instances->hw->DEVICE.INTFLAG.reg;
817 _usb_instances->device_enabled_callback_mask &
818 _usb_instances->device_registered_callback_mask;
820 for (i = 0; i < USB_DEVICE_CALLBACK_N; i ++) {
821 if (flags & _usb_device_irq_bits[i]) {
822 _usb_instances->hw->DEVICE.INTFLAG.reg =
823 _usb_device_irq_bits[i];
825 if (flags_run & _usb_device_irq_bits[i]) {
826 if (i == USB_DEVICE_CALLBACK_LPMSUSP) {
827 device_callback_lpm_wakeup_enable =
828 usb_descriptor_table.usb_endpoint_table[0].DeviceDescBank[0].EXTREG.bit.VARIABLE
829 & USB_LPM_ATTRIBUT_REMOTEWAKE_MASK;
831 (_usb_instances->device_callback[i])(_usb_instances, &device_callback_lpm_wakeup_enable);
836 /* endpoint interrupt */
838 for (uint8_t i = 0; i < USB_EPT_NUM; i++) {
840 if (ep_inst & (1 << i)) {
841 flags = _usb_instances->hw->DEVICE.DeviceEndpoint[i].EPINTFLAG.reg;
843 _usb_instances->device_endpoint_enabled_callback_mask[i] &
844 _usb_instances->device_endpoint_registered_callback_mask[i];
846 // endpoint transfer stall interrupt
847 if (flags & USB_DEVICE_EPINTFLAG_STALL_Msk) {
848 if (_usb_instances->hw->DEVICE.DeviceEndpoint[i].EPINTFLAG.reg & USB_DEVICE_EPINTFLAG_STALL1) {
849 _usb_instances->hw->DEVICE.DeviceEndpoint[i].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_STALL1;
850 ep_callback_para.endpoint_address = USB_EP_DIR_IN | i;
851 } else if (_usb_instances->hw->DEVICE.DeviceEndpoint[i].EPINTFLAG.reg & USB_DEVICE_EPINTFLAG_STALL0) {
852 _usb_instances->hw->DEVICE.DeviceEndpoint[i].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_STALL0;
853 ep_callback_para.endpoint_address = USB_EP_DIR_OUT | i;
856 if (flags_run & USB_DEVICE_EPINTFLAG_STALL_Msk) {
857 (_usb_instances->device_endpoint_callback[i][USB_DEVICE_ENDPOINT_CALLBACK_STALL])(_usb_instances,&ep_callback_para);
862 // endpoint received setup interrupt
863 if (flags & USB_DEVICE_EPINTFLAG_RXSTP) {
864 _usb_instances->hw->DEVICE.DeviceEndpoint[i].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_RXSTP;
865 if(_usb_instances->device_endpoint_enabled_callback_mask[i] & _usb_endpoint_irq_bits[USB_DEVICE_ENDPOINT_CALLBACK_RXSTP]) {
866 ep_callback_para.received_bytes = (uint16_t)(usb_descriptor_table.usb_endpoint_table[i].DeviceDescBank[0].PCKSIZE.bit.BYTE_COUNT);
867 (_usb_instances->device_endpoint_callback[i][USB_DEVICE_ENDPOINT_CALLBACK_RXSTP])(_usb_instances,&ep_callback_para);
872 // endpoint transfer complete interrupt
873 if (flags & USB_DEVICE_EPINTFLAG_TRCPT_Msk) {
874 if (_usb_instances->hw->DEVICE.DeviceEndpoint[i].EPINTFLAG.reg & USB_DEVICE_EPINTFLAG_TRCPT1) {
875 _usb_instances->hw->DEVICE.DeviceEndpoint[i].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_TRCPT1;
876 ep_callback_para.endpoint_address = USB_EP_DIR_IN | i;
877 ep_callback_para.sent_bytes = (uint16_t)(usb_descriptor_table.usb_endpoint_table[i].DeviceDescBank[1].PCKSIZE.bit.BYTE_COUNT);
879 } else if (_usb_instances->hw->DEVICE.DeviceEndpoint[i].EPINTFLAG.reg & USB_DEVICE_EPINTFLAG_TRCPT0) {
880 _usb_instances->hw->DEVICE.DeviceEndpoint[i].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_TRCPT0;
881 ep_callback_para.endpoint_address = USB_EP_DIR_OUT | i;
882 ep_callback_para.received_bytes = (uint16_t)(usb_descriptor_table.usb_endpoint_table[i].DeviceDescBank[0].PCKSIZE.bit.BYTE_COUNT);
883 ep_callback_para.out_buffer_size = (uint16_t)(usb_descriptor_table.usb_endpoint_table[i].DeviceDescBank[0].PCKSIZE.bit.MULTI_PACKET_SIZE);
885 if(flags_run & USB_DEVICE_EPINTFLAG_TRCPT_Msk) {
886 (_usb_instances->device_endpoint_callback[i][USB_DEVICE_ENDPOINT_CALLBACK_TRCPT])(_usb_instances,&ep_callback_para);
891 // endpoint transfer fail interrupt
892 if (flags & USB_DEVICE_EPINTFLAG_TRFAIL_Msk) {
893 if (_usb_instances->hw->DEVICE.DeviceEndpoint[i].EPINTFLAG.reg & USB_DEVICE_EPINTFLAG_TRFAIL1) {
894 _usb_instances->hw->DEVICE.DeviceEndpoint[i].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_TRFAIL1;
895 if (usb_descriptor_table.usb_endpoint_table[i].DeviceDescBank[1].STATUS_BK.reg & USB_DEVICE_STATUS_BK_ERRORFLOW) {
896 usb_descriptor_table.usb_endpoint_table[i].DeviceDescBank[1].STATUS_BK.reg &= ~USB_DEVICE_STATUS_BK_ERRORFLOW;
898 ep_callback_para.endpoint_address = USB_EP_DIR_IN | i;
899 if (_usb_instances->hw->DEVICE.DeviceEndpoint[i].EPINTFLAG.reg & USB_DEVICE_EPINTFLAG_TRCPT1) {
902 } else if(_usb_instances->hw->DEVICE.DeviceEndpoint[i].EPINTFLAG.reg & USB_DEVICE_EPINTFLAG_TRFAIL0) {
903 _usb_instances->hw->DEVICE.DeviceEndpoint[i].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_TRFAIL0;
904 if (usb_descriptor_table.usb_endpoint_table[i].DeviceDescBank[0].STATUS_BK.reg & USB_DEVICE_STATUS_BK_ERRORFLOW) {
905 usb_descriptor_table.usb_endpoint_table[i].DeviceDescBank[0].STATUS_BK.reg &= ~USB_DEVICE_STATUS_BK_ERRORFLOW;
907 ep_callback_para.endpoint_address = USB_EP_DIR_OUT | i;
908 if (_usb_instances->hw->DEVICE.DeviceEndpoint[i].EPINTFLAG.reg & USB_DEVICE_EPINTFLAG_TRCPT0) {
913 if(flags_run & USB_DEVICE_EPINTFLAG_TRFAIL_Msk) {
914 (_usb_instances->device_endpoint_callback[i][USB_DEVICE_ENDPOINT_CALLBACK_TRFAIL])(_usb_instances,&ep_callback_para);
924 * \brief Enable the USB module peripheral
926 * \param module_inst pointer to USB module instance
928 void usb_enable(struct usb_module *module_inst)
931 Assert(module_inst->hw);
933 module_inst->hw->DEVICE.CTRLA.reg |= USB_CTRLA_ENABLE;
934 while (module_inst->hw->DEVICE.SYNCBUSY.reg == USB_SYNCBUSY_ENABLE);
938 * \brief Disable the USB module peripheral
940 * \param module_inst pointer to USB module instance
942 void usb_disable(struct usb_module *module_inst)
945 Assert(module_inst->hw);
947 module_inst->hw->DEVICE.INTENCLR.reg = USB_DEVICE_INTENCLR_MASK;
948 module_inst->hw->DEVICE.INTFLAG.reg = USB_DEVICE_INTFLAG_MASK;
949 module_inst->hw->DEVICE.CTRLA.reg &= ~USB_CTRLA_ENABLE;
950 while (module_inst->hw->DEVICE.SYNCBUSY.reg == USB_SYNCBUSY_ENABLE);
954 * \brief Interrupt handler for the USB module.
956 void USB_0_Handler(void)
958 if (_usb_instances->hw->DEVICE.CTRLA.bit.MODE) {
962 _usb_device_interrupt_handler();
966 void USB_1_Handler(void)
968 _usb_device_interrupt_handler();
971 void USB_2_Handler(void)
973 _usb_device_interrupt_handler();
976 void USB_3_Handler(void)
978 _usb_device_interrupt_handler();
982 * \brief Get the default USB module settings
984 * \param[out] module_config Configuration structure to initialize to default values
986 void usb_get_config_defaults(struct usb_config *module_config)
988 Assert(module_config);
990 /* Sanity check arguments */
991 Assert(module_config);
992 /* Write default configuration to config struct */
993 module_config->select_host_mode = 0;
994 module_config->run_in_standby = 1;
995 module_config->source_generator = 0;
996 module_config->speed_mode = USB_SPEED_FULL;
999 #define NVM_USB_PAD_TRANSN_POS 45
1000 #define NVM_USB_PAD_TRANSN_SIZE 5
1001 #define NVM_USB_PAD_TRANSP_POS 50
1002 #define NVM_USB_PAD_TRANSP_SIZE 5
1003 #define NVM_USB_PAD_TRIM_POS 55
1004 #define NVM_USB_PAD_TRIM_SIZE 3
1007 * \brief Initializes USB module instance
1009 * Enables the clock and initializes the USB module, based on the given
1010 * configuration values.
1012 * \param[in,out] module_inst Pointer to the software module instance struct
1013 * \param[in] hw Pointer to the USB hardware module
1014 * \param[in] module_config Pointer to the USB configuration options struct
1016 * \return Status of the initialization procedure.
1018 * \retval STATUS_OK The module was initialized successfully
1023 enum status_code usb_init(struct usb_module *module_inst, Usb *const hw,
1024 struct usb_config *module_config)
1026 /* Sanity check arguments */
1028 Assert(module_inst);
1029 Assert(module_config);
1032 uint32_t pad_transn, pad_transp, pad_trim;
1037 Oscctrl *posc = OSCCTRL;
1039 _usb_instances = module_inst;
1041 /* Associate the software module instance with the hardware module */
1042 module_inst->hw = hw;
1044 //setup peripheral and synchronous bus clocks to USB
1045 pmclk->AHBMASK.bit.USB_ = 1;
1046 pmclk->APBBMASK.bit.USB_ = 1;
1048 /* Set up the USB DP/DN pins */
1049 pport->Group[0].PMUX[12].reg = 0x77; //PA24, PA25, function column H for USB D-, D+
1050 pport->Group[0].PINCFG[24].bit.PMUXEN = 1;
1051 pport->Group[0].PINCFG[25].bit.PMUXEN = 1;
1052 pport->Group[1].PMUX[11].bit.PMUXE = 7; //PB22, function column H for USB SOF_1KHz output
1053 pport->Group[1].PINCFG[22].bit.PMUXEN = 1;
1055 //configure and enable DFLL for USB clock recovery mode at 48MHz
1056 posc->DFLLCTRLA.bit.ENABLE = 0;
1057 while (posc->DFLLSYNC.bit.ENABLE);
1058 while (posc->DFLLSYNC.bit.DFLLCTRLB);
1059 posc->DFLLCTRLB.bit.USBCRM = 1;
1060 while (posc->DFLLSYNC.bit.DFLLCTRLB);
1061 posc->DFLLCTRLB.bit.MODE = 1;
1062 while (posc->DFLLSYNC.bit.DFLLCTRLB);
1063 posc->DFLLCTRLB.bit.QLDIS = 0;
1064 while (posc->DFLLSYNC.bit.DFLLCTRLB);
1065 posc->DFLLCTRLB.bit.CCDIS = 1;
1066 posc->DFLLMUL.bit.MUL = 0xbb80; //4800 x 1KHz
1067 while (posc->DFLLSYNC.bit.DFLLMUL);
1068 posc->DFLLCTRLA.bit.ENABLE = 1;
1069 while (posc->DFLLSYNC.bit.ENABLE);
1071 /* Setup clock for module */
1072 pgclk->PCHCTRL[GCLK_USB].bit.GEN = 0;
1073 pgclk->PCHCTRL[GCLK_USB].bit.CHEN = 1;
1076 hw->DEVICE.CTRLA.bit.SWRST = 1;
1077 while (hw->DEVICE.SYNCBUSY.bit.SWRST) {
1081 /* Change QOS values to have the best performance and correct USB behaviour */
1082 USB->DEVICE.QOSCTRL.bit.CQOS = 2;
1083 USB->DEVICE.QOSCTRL.bit.DQOS = 2;
1085 /* Load Pad Calibration */
1087 pad_transn = (USB_FUSES_TRANSN_ADDR >> USB_FUSES_TRANSN_Pos) & USB_FUSES_TRANSN_Msk;
1088 if (pad_transn == 0x1F) {
1092 hw->DEVICE.PADCAL.bit.TRANSN = pad_transn;
1094 pad_transp = (USB_FUSES_TRANSP_ADDR >> USB_FUSES_TRANSP_Pos) & USB_FUSES_TRANSP_Msk;
1095 if (pad_transp == 0x1F) {
1099 hw->DEVICE.PADCAL.bit.TRANSP = pad_transp;
1101 pad_trim = (USB_FUSES_TRIM_ADDR >> USB_FUSES_TRIM_Pos) & USB_FUSES_TRIM_Msk;
1102 if (pad_trim == 0x07) {
1106 hw->DEVICE.PADCAL.bit.TRIM = pad_trim;
1108 /* Set the configuration */
1109 hw->DEVICE.CTRLA.bit.MODE = module_config->select_host_mode;
1110 hw->DEVICE.CTRLA.bit.RUNSTDBY = module_config->run_in_standby;
1111 hw->DEVICE.DESCADD.reg = (uint32_t)(&usb_descriptor_table.usb_endpoint_table[0]);
1112 if (USB_SPEED_FULL == module_config->speed_mode) {
1113 module_inst->hw->DEVICE.CTRLB.bit.SPDCONF = USB_DEVICE_CTRLB_SPDCONF_FS_Val;
1114 } else if(USB_SPEED_LOW == module_config->speed_mode) {
1115 module_inst->hw->DEVICE.CTRLB.bit.SPDCONF = USB_DEVICE_CTRLB_SPDCONF_LS_Val;
1118 memset((uint8_t *)(&usb_descriptor_table.usb_endpoint_table[0]), 0,
1119 sizeof(usb_descriptor_table.usb_endpoint_table));
1121 /* device callback related */
1122 for (i = 0; i < USB_DEVICE_CALLBACK_N; i++) {
1123 module_inst->device_callback[i] = NULL;
1125 for (i = 0; i < USB_EPT_NUM; i++) {
1126 for(j = 0; j < USB_DEVICE_EP_CALLBACK_N; j++) {
1127 module_inst->device_endpoint_callback[i][j] = NULL;
1130 module_inst->device_registered_callback_mask = 0;
1131 module_inst->device_enabled_callback_mask = 0;
1132 for (j = 0; j < USB_EPT_NUM; j++) {
1133 module_inst->device_endpoint_registered_callback_mask[j] = 0;
1134 module_inst->device_endpoint_enabled_callback_mask[j] = 0;
1137 /* Enable interrupts for this USB module */
1138 NVIC_EnableIRQ(USB_0_IRQn);
1139 NVIC_EnableIRQ(USB_2_IRQn);
1140 NVIC_EnableIRQ(USB_3_IRQn);