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);
}
예제 #2
0
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);
}