void udd_attach(void)
{
	irqflags_t flags;
	flags = cpu_irq_save();

	// At startup the USB bus state is unknown,
	// therefore the state is considered IDLE to not miss any USB event
	udd_sleep_mode(true);

	// Enable peripheral clock and USB clock
	udd_enable_periph_ck();

	// Authorize attach if VBus is present
	udd_enable_transceiver();
	udd_attach_device();

	// Enable USB line events
	udd_enable_suspend_interrupt();
	udd_enable_wake_up_interrupt();
	udd_enable_resume_interrupt();
	udd_enable_ext_resume_interrupt();
	udd_enable_sof_interrupt();

	cpu_irq_restore(flags);
}
Beispiel #2
0
void udd_detach(void)
{
	otg_unfreeze_clock();
	// Detach device from the bus
	udd_detach_device();
	udd_sleep_mode(false);
}
Beispiel #3
0
void udd_attach(void)
{
	irqflags_t flags;
	flags = cpu_irq_save();

	// At startup the USB bus state is unknown,
	// therefore the state is considered IDLE to not miss any USB event
	udd_sleep_mode(true);
	otg_unfreeze_clock();
	while (!Is_otg_clock_usable());

	// Authorize attach if Vbus is present
	udd_attach_device();

	// Enable USB line events
	udd_enable_reset_interrupt();
	udd_enable_suspend_interrupt();
	udd_enable_wake_up_interrupt();
	udd_enable_sof_interrupt();

	// Reset following interrupts flag
	udd_ack_reset();
	udd_ack_sof();

	// The first suspend interrupt must be forced
	udd_raise_suspend();
	udd_ack_wake_up();
	otg_freeze_clock();
	cpu_irq_restore(flags);
}
void udd_detach(void)
{
	// Disable transceiver
	udd_disable_transceiver();
	// Detach device from the bus
	udd_detach_device();
	udd_sleep_mode(false);
}
Beispiel #5
0
void udd_send_remotewakeup(void)
{
#ifndef UDD_NO_SLEEP_MGR
	if (!udd_b_idle)
#endif
	{
		udd_sleep_mode(true); // Enter in IDLE mode
		udd_send_remote_wake_up();
	}
}
Beispiel #6
0
void udd_attach(void)
{
	irqflags_t flags;
	flags = cpu_irq_save();

	// At startup the USB bus state is unknown, 
	// therefore the state is considered IDLE to not miss any USB event
	udd_sleep_mode(true);
	otg_unfreeze_clock();
	
	// This section of clock check can be improved with a chek of 
	// USB clock source via sysclk()
#if UC3A3
	// For parts with high speed feature, the "USABLE" clock is the UTMI clock,
	// and the UTMI clock is disabled in suspend mode. Thereby, the utmi clock
	// can't be checked when USB line is not attached or in suspend mode 
	// But it is not a issue, because the clock source is the OSC
#else
	// Check USB clock because the source can be a PLL
	while( !Is_clock_usable() );
#endif
	// Authorize attach if VBus is present
	udd_attach_device();

	// (RESET_AND_WAKEUP)
	// After the attach and the first USB suspend, the following USB Reset time can be inferior to CPU restart clock time.
	// Thus, the USB Reset state is not detected and endpoint control is not allocated
	// In this case, a Reset is do automatically after attach.
	udc_reset();	// Reset USB Device Stack Core
	udd_reset_ep_ctrl();	// Reset endpoint control
	udd_ctrl_init();	// Reset endpoint control management

	// Enable USB line events
	udd_enable_reset_interrupt();
	udd_enable_suspend_interrupt();
	udd_enable_wake_up_interrupt();
#ifdef UDC_SOF_EVENT
	udd_enable_sof_interrupt();
#endif
	// Reset following interupts flag
	udd_ack_reset();
	udd_ack_sof();
   
   // The first suspend interrupt must be forced
#if UC3A3
   // With UTMI, the first suspend is detected but must be cleared to reoccur interrupt
   udd_ack_suspend();
#else
   // The first suspend interrupt is not detected else raise it
   udd_raise_suspend();
#endif
	udd_ack_wake_up();
	otg_freeze_clock();
	cpu_irq_restore(flags);
}
Beispiel #7
0
void udd_send_remotewakeup(void)
{
#ifndef UDD_NO_SLEEP_MGR
	if (!udd_b_idle)
#endif
	{
		udd_sleep_mode(true); // Enter in IDLE mode
		otg_unfreeze_clock();
		udd_initiate_remote_wake_up();
	}
}
Beispiel #8
0
void udd_disable(void)
{
	irqflags_t flags;
	flags = cpu_irq_save();
	// Disable USB pad
	otg_disable();
	otg_disable_pad();
	sysclk_disable_usb();
	udd_sleep_mode(false);
#ifndef UDD_NO_SLEEP_MGR
	sleepmgr_unlock_mode(USBB_SLEEP_MODE_USB_SUSPEND);
#endif
	cpu_irq_restore(flags);
}
Beispiel #9
0
void udd_disable(void)
{
	irqflags_t flags;
	flags = cpu_irq_save();
	udd_detach_device();
	// Disable interface
	USB_CTRLA = 0;
	USB_CTRLB = 0;
	sysclk_disable_usb();
	udd_sleep_mode(false);
#ifndef UDD_NO_SLEEP_MGR
	sleepmgr_unlock_mode(USBC_SLEEP_MODE_USB_SUSPEND);
#endif
	cpu_irq_restore(flags);
}
Beispiel #10
0
void udd_attach(void)
{
	irqflags_t flags;
	flags = cpu_irq_save();

	// At startup the USB bus state is unknown,
	// therefore the state is considered IDLE to not miss any USB event
	udd_sleep_mode(true);

	udd_ack_suspend_event();
	udd_ack_resume_event();
	udd_attach_device();
	// Enable main USB interrupts
	udd_enable_tc_interrupt();
	udd_enable_busevt_interrupt();
	udd_enable_setup_interrupt();
	udd_enable_start_of_frame_interrupt();

	cpu_irq_restore(flags);
}
Beispiel #11
0
void udd_attach(void)
{
	irqflags_t flags;
	flags = cpu_irq_save();

	// At startup the USB bus state is unknown,
	// therefore the state is considered IDLE to not miss any USB event
	udd_sleep_mode(true);
	otg_unfreeze_clock();
	while( !Is_otg_clock_usable() );

	// Authorize attach if Vbus is present
	udd_attach_device();

	// Enable USB line events
	udd_enable_reset_interrupt();
	udd_enable_suspend_interrupt();
	udd_enable_wake_up_interrupt();
	udd_enable_sof_interrupt();
#ifdef USB_DEVICE_HS_SUPPORT
	udd_enable_msof_interrupt();
#endif
	// Reset following interrupts flag
	udd_ack_reset();
	udd_ack_sof();
	udd_ack_msof();

	// The first suspend interrupt must be forced
#if UC3A3
	// With UTMI, the first suspend is detected but must be cleared to reoccur interrupt
	udd_ack_suspend();
#else
	// The first suspend interrupt is not detected else raise it
	udd_raise_suspend();
#endif
	udd_ack_wake_up();
	otg_freeze_clock();
	cpu_irq_restore(flags);
}
Beispiel #12
0
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
}
Beispiel #13
0
ISR(udd_interrupt, AVR32_USBB_IRQ_GROUP, UDD_USB_INT_LEVEL)
#endif
{
#ifdef UDC_SOF_EVENT
	if (Is_udd_sof()) {
		udd_ack_sof();
		UDC_SOF_EVENT();
		goto udd_interrupt_end;
	}
#endif

	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 (0!=USB_DEVICE_MAX_EP)
		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_clock_usable() ) {
			if(Is_udd_suspend()) break;   // In case of USB state change in HS
		};
		// 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_udd_vbus_transition()) {
		// Ack VBus transition and send status to high level
		otg_unfreeze_clock();
		udd_ack_vbus_transition();
		otg_freeze_clock();
#ifdef UDC_VBUS_EVENT
		UDC_VBUS_EVENT(Is_udd_vbus_high());
#endif
		goto udd_interrupt_end;
	}
udd_interrupt_end:
	otg_data_memory_barrier();
	return;
}
Beispiel #14
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);
}