void udd_enable(void) { irqflags_t flags; flags = cpu_irq_save(); #if SAMG55 matrix_set_usb_device(); #endif // Enable USB hardware udd_enable_periph_ck(); sysclk_enable_usb(); // Cortex, uses NVIC, no need to register IRQ handler NVIC_SetPriority((IRQn_Type) ID_UDP, UDD_USB_INT_LEVEL); NVIC_EnableIRQ((IRQn_Type) ID_UDP); // Reset internal variables #if (0!=USB_DEVICE_MAX_EP) udd_ep_job_table_reset(); #endif // Always authorize asynchronous USB interrupts to exit of sleep mode pmc_set_fast_startup_input(PMC_FSMR_USBAL); #ifndef UDD_NO_SLEEP_MGR // Initialize the sleep mode authorized for the USB suspend mode udd_b_idle = false; sleepmgr_lock_mode(UDP_SLEEP_MODE_USB_SUSPEND); #endif #if UDD_VBUS_IO /* Initialize VBus monitor */ udd_vbus_init(udd_vbus_handler); udd_vbus_monitor_sleep_mode(true); /* Force Vbus interrupt when Vbus is always high * This is possible due to a short timing between a Host mode stop/start. */ if (Is_udd_vbus_high()) { udd_vbus_handler(USB_VBUS_PIO_ID, USB_VBUS_PIO_MASK); } #else # ifndef USB_DEVICE_ATTACH_AUTO_DISABLE udd_attach(); # endif #endif cpu_irq_restore(flags); }
/** * USB VBus pin change handler */ static void udd_vbus_handler(uint32_t id, uint32_t mask) { if (USB_VBUS_PIO_ID != id || USB_VBUS_PIO_MASK != mask) { return; } /* PIO interrupt status has been cleared, just detect level */ bool b_vbus_high = Is_otg_vbus_high(); if (b_vbus_high) { udd_vbus_monitor_sleep_mode(false); udd_attach(); } else { udd_vbus_monitor_sleep_mode(true); udd_detach(); } UDC_VBUS_EVENT(b_vbus_high); }
ISR(udd_interrupt, AVR32_USBB_IRQ_GROUP, UDD_USB_INT_LEVEL) # endif #endif { if (Is_udd_sof()) { udd_ack_sof(); if (Is_udd_full_speed_mode()) { udc_sof_notify(); } #ifdef UDC_SOF_EVENT UDC_SOF_EVENT(); #endif goto udd_interrupt_end; } if (Is_udd_msof()) { udd_ack_msof(); udc_sof_notify(); goto udd_interrupt_end; } if (udd_ctrl_interrupt()) goto udd_interrupt_end; // Interrupt acked by control endpoint managed #if (0 != USB_DEVICE_MAX_EP) if (udd_ep_interrupt()) goto udd_interrupt_end; // Interrupt acked by bulk/interrupt/isochronous endpoint managed #endif // USB bus reset detection if (Is_udd_reset()) { udd_ack_reset(); // Abort all jobs on-going #if (USB_DEVICE_MAX_EP != 0) udd_ep_job_table_kill(); #endif // Reset USB Device Stack Core udc_reset(); // Reset endpoint control udd_reset_ep_ctrl(); // Reset endpoint control management udd_ctrl_init(); goto udd_interrupt_end; } if (Is_udd_suspend_interrupt_enabled() && Is_udd_suspend()) { otg_unfreeze_clock(); // The suspend interrupt is automatic acked when a wakeup occur udd_disable_suspend_interrupt(); udd_enable_wake_up_interrupt(); otg_freeze_clock(); // Mandatory to exit of sleep mode after a wakeup event udd_sleep_mode(false); // Enter in SUSPEND mode #ifdef UDC_SUSPEND_EVENT UDC_SUSPEND_EVENT(); #endif goto udd_interrupt_end; } if (Is_udd_wake_up_interrupt_enabled() && Is_udd_wake_up()) { // Ack wakeup interrupt and enable suspend interrupt otg_unfreeze_clock(); // Check USB clock ready after suspend and eventually sleep USB clock while( !Is_otg_clock_usable() ); // The wakeup interrupt is automatic acked when a suspend occur udd_disable_wake_up_interrupt(); udd_enable_suspend_interrupt(); udd_sleep_mode(true); // Enter in IDLE mode #ifdef UDC_RESUME_EVENT UDC_RESUME_EVENT(); #endif goto udd_interrupt_end; } if (Is_otg_vbus_transition()) { // Ack Vbus transition and send status to high level otg_unfreeze_clock(); otg_ack_vbus_transition(); otg_freeze_clock(); #ifndef USB_DEVICE_ATTACH_AUTO_DISABLE if (Is_otg_vbus_high()) { udd_attach(); } else { udd_detach(); } #endif #ifdef UDC_VBUS_EVENT UDC_VBUS_EVENT(Is_otg_vbus_high()); #endif goto udd_interrupt_end; } udd_interrupt_end: otg_data_memory_barrier(); #if (defined FREERTOS_USED) // Since we do not know if the user callbacks have used or not FreeRTOS APIs, let's // consider that exiting from the USB interrupt will require a context switch. return pdTRUE; #else return; #endif }
void udd_enable(void) { uint8_t i; irqflags_t flags; // Sanity check Silicon revision #if AVR8_PART_IS_DEFINED(ATxmega128A1U) // The part ATxmega128A1U Rev. J is not supported, please use new silicon revision. Assert(!(MCU_REVID < 0x0A)); #endif #ifdef CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC # if CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC == OSC_ID_USBSOF // RC oscillator calibration via USB Start Of Frame is not available // in low speed mode. // Thus, the calibration is disabled // when USB interface start in low speed mode DFLLRC32M.CTRL = 0; # endif #endif #ifdef USB_DEVICE_LOW_SPEED // The USB hardware need of 6MHz in low speed mode sysclk_enable_usb(6); udd_set_low_speed(); #else // The USB hardware need of 48MHz in full speed mode sysclk_enable_usb(48); udd_set_full_speed(); #endif // The XMEGA_A1U does not support the RC calibration through Keepalive (Low speed). #if (!defined USB_DEVICE_LOW_SPEED) || (!XMEGA_A1U) # ifdef CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC # if CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC == OSC_ID_USBSOF // The SOF calibration can be enabled DFLLRC32M.CTRL = DFLL_ENABLE_bm; # endif # endif #endif flags = cpu_irq_save(); // Reset endpoints table for (i = 0; i < ((USB_DEVICE_MAX_EP + 1) * 2); i++) { udd_sram.ep_ctrl[i].CTRL = 0; } #if (0!=USB_DEVICE_MAX_EP) // Reset internal variables for (i = 0; i < (USB_DEVICE_MAX_EP * 2); i++) { udd_ep_job[i].busy = false; } #endif //** Enable USB hardware usb_pad_init(); udd_set_nb_max_ep(USB_DEVICE_MAX_EP); udd_enable_interface(); udd_enable_store_frame_number(); #if XMEGA_A1U Assert(((uint16_t)(&udd_sram) & 0x0F) == 0); /* check align on 16bit */ #else Assert(((uint16_t)(&udd_sram) & 0x01) == 0); /* check align on WORD */ #endif udd_set_ep_table_addr(udd_sram.ep_ctrl); // Enable TC fifo management udd_enable_fifo(); udd_reset_fifo(); // Enable Interrupt USB Device udd_enable_interrupt(UDD_USB_INT_LEVEL); #ifndef UDD_NO_SLEEP_MGR // Initialize the sleep mode authorized for the USB suspend mode udd_b_idle = false; sleepmgr_lock_mode(USBC_SLEEP_MODE_USB_SUSPEND); #endif #ifndef USB_DEVICE_ATTACH_AUTO_DISABLE udd_attach(); #endif cpu_irq_restore(flags); }
void udd_enable(void) { irqflags_t flags; flags = cpu_irq_save(); #ifdef UHD_ENABLE //* DUAL ROLE INITIALIZATION if (otg_dual_enable()) { // The current mode has been started by otg_dual_enable() cpu_irq_restore(flags); return; } #else //* SINGLE DEVICE MODE INITIALIZATION sysclk_enable_usb(); // Here, only the device mode is possible, // USBC interrupt is linked to UDD interrupt irq_register_handler( # ifdef FREERTOS_USED (__int_handler) # endif udd_interrupt, AVR32_USBC_IRQ, UDD_USB_INT_LEVEL); // Always authorize asynchronous USB interrupts to exit of sleep mode pm_asyn_wake_up_enable(AVR32_PM_AWEN_USBCWEN_MASK); #endif #if (defined USB_ID) && (defined UHD_ENABLE) // Check that the device mode is selected by ID pin if (!Is_otg_id_device()) { cpu_irq_restore(flags); return; // Device is not the current mode } #else // ID pin not used then force device mode otg_disable_id_pin(); otg_force_device_mode(); #endif // Enable USB hardware otg_enable_pad(); otg_enable(); otg_unfreeze_clock(); (void)Is_otg_clock_frozen(); memset((uint8_t *) udd_g_ep_table, 0, sizeof(udd_g_ep_table)); otg_register_desc_tab(udd_g_ep_table); // Reset internal variables #if (0!=USB_DEVICE_MAX_EP) { uint8_t i; for (i = 0; i < USB_DEVICE_MAX_EP; i++) { udd_ep_job[i].busy = false; } } #endif // Set the USB speed requested by configuration file #ifdef USB_DEVICE_LOW_SPEED udd_low_speed_enable(); #else udd_low_speed_disable(); # ifdef USB_DEVICE_HS_SUPPORT udd_high_speed_enable(); # else udd_high_speed_disable(); # endif #endif otg_ack_vbus_transition(); // Force Vbus interrupt in case of Vbus always with a high level // This is possible with a short timing between a Host mode stop/start. if (Is_otg_vbus_high()) { otg_raise_vbus_transition(); } otg_enable_vbus_interrupt(); otg_freeze_clock(); #ifndef UDD_NO_SLEEP_MGR // Initialize the sleep mode authorized for the USB suspend mode udd_b_idle = false; sleepmgr_lock_mode(USBC_SLEEP_MODE_USB_SUSPEND); #endif #if UC3L3_L4 # ifndef USB_DEVICE_ATTACH_AUTO_DISABLE udd_attach(); # endif #endif cpu_irq_restore(flags); }
void udd_enable(void) { irqflags_t flags; flags = cpu_irq_save(); #ifdef UHD_ENABLE // DUAL ROLE INITIALIZATION if (otg_dual_enable()) { // The current mode has been started by otg_dual_enable() cpu_irq_restore(flags); return; } #else // SINGLE DEVICE MODE INITIALIZATION sysclk_enable_usb(); pmc_enable_periph_clk(ID_UOTGHS); // Here, only the device mode is possible, then link UHDP interrupt to UDD interrupt NVIC_SetPriority((IRQn_Type) ID_UOTGHS, USB_INT_LEVEL); NVIC_EnableIRQ((IRQn_Type) ID_UOTGHS); // Always authorize asynchrony USB interrupts to exit of sleep mode // For SAM USB wake up device except BACKUP mode pmc_set_fast_startup_input(PMC_FSMR_USBAL); #endif #if (OTG_ID_IO) && (defined UHD_ENABLE) // Check that the device mode is selected by ID pin if (!Is_otg_id_device()) { cpu_irq_restore(flags); return; // Device is not the current mode } #else // ID pin not used and force device mode otg_force_device_mode(); #endif // Enable USB hardware otg_enable(); // Reset internal variables #if (0!=USB_DEVICE_MAX_EP) udd_ep_job_table_reset(); #endif #ifndef UDD_NO_SLEEP_MGR if (!udd_b_sleep_initialized) { udd_b_sleep_initialized = true; // Initialize the sleep mode authorized for the USB suspend mode udd_b_idle = false; sleepmgr_lock_mode(UHDP_SLEEP_MODE_USB_SUSPEND); } else { udd_sleep_mode(false); // Enter idle mode } #endif #if OTG_VBUS_IO /* Initialize VBus monitor */ otg_vbus_init(udd_vbus_handler); udd_vbus_monitor_sleep_mode(true); /* Force VBus interrupt when VBus is always high * This is possible due to a short timing between a Host mode stop/start. */ if (Is_otg_vbus_high()) { udd_vbus_handler(USB_VBUS_PIO_ID, USB_VBUS_PIO_MASK); } #else # ifndef USB_DEVICE_ATTACH_AUTO_DISABLE udd_attach(); # endif #endif cpu_irq_restore(flags); }
void udd_enable(void) { uint8_t i; irqflags_t flags; // Sanity check Silicon revision #if AVR8_PART_IS_DEFINED(ATxmega128A1U) // The part ATxmega128A1U Rev. J is not supported, please use new silicon revision. Assert(!(MCU_REVID < 0x0A)); #endif uint8_t dfll_save = DFLLRC32M.CTRL; DFLLRC32M.CTRL = 0; #ifdef USB_DEVICE_LOW_SPEED // The USB hardware need of 6MHz in low speed mode //sysclk_enable_usb(6); udd_set_low_speed(); #else // The USB hardware need of 48MHz in full speed mode //sysclk_enable_usb(48); udd_set_full_speed(); #endif DFLLRC32M.CTRL = dfll_save; flags = cpu_irq_save(); // Reset endpoints table for (i = 0; i < ((USB_DEVICE_MAX_EP + 1) * 2); i++) { udd_sram.ep_ctrl[i].CTRL = 0; } #if (0!=USB_DEVICE_MAX_EP) // Reset internal variables for (i = 0; i < (USB_DEVICE_MAX_EP * 2); i++) { udd_ep_job[i].busy = false; } #endif //** Enable USB hardware usb_pad_init(); udd_set_nb_max_ep(USB_DEVICE_MAX_EP); udd_enable_interface(); udd_enable_store_frame_number(); #if XMEGA_A1U Assert(((uint16_t)(&udd_sram) & 0x0F) == 0); /* check align on 16bit */ #else Assert(((uint16_t)(&udd_sram) & 0x01) == 0); /* check align on WORD */ #endif udd_set_ep_table_addr(udd_sram.ep_ctrl); // Enable TC fifo management udd_enable_fifo(); udd_reset_fifo(); // Enable Interrupt USB Device udd_enable_interrupt(UDD_USB_INT_LEVEL); #ifndef UDD_NO_SLEEP_MGR // Initialize the sleep mode authorized for the USB suspend mode udd_b_idle = false; sleepmgr_lock_mode(USBC_SLEEP_MODE_USB_SUSPEND); #endif #ifndef USB_DEVICE_ATTACH_AUTO_DISABLE udd_attach(); #endif cpu_irq_restore(flags); }