/* This source file is part of the AVR Software Framework 2.0.0 release */ | |
/*This file is prepared for Doxygen automatic documentation generation.*/ | |
/*! \file ****************************************************************** | |
* | |
* \brief Management of the USB task either device/host or both. | |
* | |
* The USB task selects the correct USB task (USB device task or USB host | |
* task) to be executed depending on the current mode available. | |
* | |
* According to the values of USB_DEVICE_FEATURE and USB_HOST_FEATURE | |
* (located in the conf_usb.h file), the USB task can be configured to | |
* support USB device mode or USB host mode or both for a dual-role device | |
* application. | |
* | |
* This module also contains the general USB interrupt subroutine. This | |
* subroutine is used to detect asynchronous USB events. | |
* | |
* Note: | |
* - The USB task belongs to main; the USB device and host tasks do not. | |
* They are called from the general USB task. | |
* - See the conf_usb.h file for more details about the configuration of | |
* this module. | |
* | |
* - Compiler: IAR EWAVR32 and GNU GCC for AVR32 | |
* - Supported devices: All AVR32 devices with a USB module can be used. | |
* - AppNote: | |
* | |
* \author Atmel Corporation: http://www.atmel.com \n | |
* Support and FAQ: http://support.atmel.no/ | |
* | |
***************************************************************************/ | |
/* Copyright (c) 2009 Atmel Corporation. All rights reserved. | |
* | |
* Redistribution and use in source and binary forms, with or without | |
* modification, are permitted provided that the following conditions are met: | |
* | |
* 1. Redistributions of source code must retain the above copyright notice, this | |
* list of conditions and the following disclaimer. | |
* | |
* 2. Redistributions in binary form must reproduce the above copyright notice, | |
* this list of conditions and the following disclaimer in the documentation | |
* and/or other materials provided with the distribution. | |
* | |
* 3. The name of Atmel may not be used to endorse or promote products derived | |
* from this software without specific prior written permission. | |
* | |
* 4. This software may only be redistributed and used in connection with an Atmel | |
* AVR product. | |
* | |
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED | |
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE | |
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR | |
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE | |
* | |
*/ | |
//_____ I N C L U D E S ___________________________________________________ | |
#include "conf_usb.h" | |
#include "compiler.h" | |
//#include "intc.h" | |
#ifdef FREERTOS_USED | |
#include "libfreertos.h" | |
#include "FreeRTOSConfig.h" | |
#include "FreeRTOSTask.h" | |
//#include "semphr.h" | |
#endif | |
#include "usb_drv.h" | |
#include "usb_task.h" | |
#if USB_DEVICE_FEATURE == ENABLED | |
#include "usb_descriptors.h" | |
#include "usb_device_task.h" | |
#endif | |
#if USB_HOST_FEATURE == ENABLED | |
#include "usb_host_task.h" | |
#endif | |
//#if UC3C | |
//#include "pm_uc3c.h" | |
//#else | |
//#include "pm.h" | |
//#endif | |
//_____ M A C R O S ________________________________________________________ | |
//_____ D E F I N I T I O N S ______________________________________________ | |
#if USB_HOST_FEATURE == DISABLED | |
volatile Bool usb_device_connected; | |
#else | |
extern volatile Bool usb_device_connected; | |
#endif | |
//! | |
//! Public: U16 g_usb_event | |
//! usb_connected is used to store USB events detected upon | |
//! USB general interrupt subroutine | |
//! Its value is managed by the following macros (See \ref usb_task.h file) | |
//! Usb_send_event(x) | |
//! Usb_ack_event(x) | |
//! Is_usb_event(x) | |
//! Usb_clear_all_event() | |
volatile U16 g_usb_event = 0; | |
#if (USB_HOST_FEATURE == ENABLED) /*&& (USB_DEVICE_FEATURE == ENABLED)*/ && (USB_HIGH_SPEED_SUPPORT==ENABLED) | |
static U8 private_sof_counter_HS = 0; // Full speed SOF = 1ms , High speed µSOF = 125µs | |
#endif | |
#if USB_DEVICE_FEATURE == ENABLED | |
//! | |
//! Public: Bool usb_connected | |
//! usb_connected is set to TRUE when VBus has been detected | |
//! usb_connected is set to FALSE otherwise | |
//! Used with USB_DEVICE_FEATURE == ENABLED only | |
extern volatile Bool usb_connected; | |
#ifdef FREERTOS_USED | |
//! Handle to the USB Device task | |
extern xTaskHandle usb_device_tsk; | |
#endif | |
#endif | |
#if USB_HOST_FEATURE == ENABLED | |
static const char log_device_disconnected[] = "Device disconnected\n"; | |
//! | |
//! Private: U8 private_sof_counter | |
//! Incremented by host SOF interrupt subroutime | |
//! This counter is used to detect time-out in host requests. | |
//! It must not be modified by the user applicative tasks. | |
volatile U32 private_sof_counter; | |
#if USB_HOST_PIPE_INTERRUPT_TRANSFER == ENABLE | |
extern volatile Bool g_sav_int_sof_enable; | |
extern volatile S_pipe_int it_pipe_str[MAX_PEP_NB]; | |
#endif | |
#ifdef FREERTOS_USED | |
//! Handle to the USB Host task | |
extern xTaskHandle usb_host_tsk; | |
#endif | |
#endif | |
#if USB_DEVICE_FEATURE == ENABLED && USB_HOST_FEATURE == ENABLED | |
static const char log_pin_id_changed[] = "Pin Id changed\n"; | |
//! | |
//! Public: U8 g_usb_mode | |
//! Used in dual-role application (both device/host) to store | |
//! the current mode the USB controller is operating | |
volatile U8 g_usb_mode = USB_MODE_UNDEFINED; | |
static volatile U8 g_old_usb_mode; | |
#endif | |
#ifdef FREERTOS_USED | |
//! Handle to the USB task semaphore | |
static xSemaphoreHandle usb_tsk_semphr = NULL; | |
#endif | |
//_____ D E C L A R A T I O N S ____________________________________________ | |
#ifdef FREERTOS_USED | |
#if (defined __GNUC__) | |
__attribute__((__noinline__)) | |
#endif | |
static portBASE_TYPE usb_general_interrupt_non_naked(void); | |
//! @brief USB interrupt routine | |
//! | |
//! When FreeRTOS is used, the USB interrupt routine may trigger task switches, | |
//! so it must use special OS prologue and epilogue. This function must be naked | |
//! in order to have no stack frame. usb_general_interrupt_non_naked is | |
//! therefore used for the required stack frame of the interrupt routine. | |
#if (defined __GNUC__) | |
__attribute__((__naked__)) | |
#elif (defined __ICCAVR32__) | |
#pragma shadow_registers = full | |
#endif | |
static void usb_general_interrupt(void) | |
{ | |
portENTER_SWITCHING_ISR(); | |
usb_general_interrupt_non_naked(); | |
portEXIT_SWITCHING_ISR(); | |
} | |
#else | |
#if (defined __GNUC__) | |
__attribute__((__interrupt__)) | |
static void usb_general_interrupt(void); | |
#elif (defined __ICCAVR32__) | |
__interrupt | |
static void usb_general_interrupt(void); | |
#endif | |
#endif // FREERTOS_USED | |
//! @brief This function initializes the USB process. | |
//! | |
//! Depending on the mode supported (HOST/DEVICE/DUAL_ROLE) the function | |
//! calls the coresponding USB mode initialization function | |
void usb_task_init(void) | |
{ | |
usb_device_connected=0; | |
/* Disable unwanted interrupt */ | |
// Host | |
Host_disable_device_connection_interrupt(); | |
Host_disable_device_disconnection_interrupt(); | |
Host_disable_reset_sent_interrupt(); | |
Host_disable_down_stream_resume_interrupt(); | |
Host_disable_remote_wakeup_interrupt(); | |
Host_disable_sof_interrupt(); | |
Host_disable_hwup_interrupt(); | |
// Device | |
Usb_disable_suspend_interrupt(); | |
Usb_disable_msof_interrupt(); | |
Usb_disable_sof_interrupt(); | |
Usb_disable_reset_interrupt(); | |
Usb_disable_wake_up_interrupt(); | |
Usb_disable_resume_interrupt(); | |
Usb_disable_remote_wake_up_interrupt(); | |
// Arbitrer | |
#ifdef FREERTOS_USED | |
// Create the semaphore | |
vSemaphoreCreateBinary(usb_tsk_semphr); | |
if ( xTaskCreate( usb_task, configTSK_USB_NAME, configTSK_USB_STACK_SIZE, NULL, configTSK_USB_PRIORITY, NULL ) != pdPASS ) | |
{ | |
printf( "Failed to create usb_task\r\n" ) ; | |
} | |
} | |
void usb_task(void *pvParameters) | |
{ | |
#endif // FREERTOS_USED | |
// Register the USB interrupt handler to the interrupt controller and enable | |
// the USB interrupt. | |
// Disable_global_interrupt(); | |
// INTC_register_interrupt((__int_handler)&usb_general_interrupt, AVR32_USBB_IRQ, USB_INT_LEVEL); | |
// Enable_global_interrupt(); | |
// | |
#ifdef FREERTOS_USED | |
while (TRUE) | |
{ | |
// Wait for the semaphore | |
while (!xSemaphoreTake(usb_tsk_semphr, portMAX_DELAY)); | |
#endif // FREERTOS_USED | |
// ---- DUAL-ROLE DEVICE/HOST USB MODE ----------------------------------------- | |
#if USB_DEVICE_FEATURE == ENABLED && USB_HOST_FEATURE == ENABLED | |
#ifdef FREERTOS_USED | |
if (usb_device_tsk) vTaskDelete(usb_device_tsk), usb_device_tsk = NULL; | |
if (usb_host_tsk) vTaskDelete(usb_host_tsk), usb_host_tsk = NULL; | |
#endif | |
Usb_input_id_pin(); | |
Usb_enable_id_pin(); | |
if (Is_usb_id_device()) | |
{ | |
g_usb_mode = USB_MODE_DEVICE; | |
usb_device_task_init(); | |
} | |
else | |
{ | |
private_sof_counter = 0; | |
g_usb_mode = USB_MODE_HOST; | |
usb_host_task_init(); | |
} | |
g_old_usb_mode = g_usb_mode; // Store current USB mode, for mode change detection | |
Usb_raise_id_transition(); // Check no ID transition has been missed during initialization | |
Usb_enable_id_interrupt(); | |
Enable_global_interrupt(); | |
// ----------------------------------------------------------------------------- | |
// ---- DEVICE-ONLY USB MODE --------------------------------------------------- | |
#elif USB_DEVICE_FEATURE == ENABLED | |
#ifdef FREERTOS_USED | |
if (usb_device_tsk) vTaskDelete(usb_device_tsk), usb_device_tsk = NULL; | |
#endif | |
Usb_force_device_mode(); | |
usb_device_task_init(); | |
// ----------------------------------------------------------------------------- | |
// ---- REDUCED-HOST-ONLY USB MODE --------------------------------------------- | |
#elif USB_HOST_FEATURE == ENABLED | |
#ifdef FREERTOS_USED | |
if (usb_host_tsk) vTaskDelete(usb_host_tsk), usb_host_tsk = NULL; | |
#endif | |
private_sof_counter = 0; | |
Usb_force_host_mode(); | |
usb_host_task_init(); | |
// ----------------------------------------------------------------------------- | |
// ---- ERROR, NO MODE ENABLED ------------------------------------------------- | |
#else | |
#error At least one of USB_DEVICE_FEATURE and USB_HOST_FEATURE must be enabled | |
#endif | |
// ----------------------------------------------------------------------------- | |
#ifdef FREERTOS_USED | |
} | |
#endif | |
} | |
//! @brief Entry point of the USB mamnagement | |
//! | |
//! Depending on the USB mode supported (HOST/DEVICE/DUAL_ROLE) the function | |
//! calls the coresponding USB management function. | |
#ifndef FREERTOS_USED | |
void usb_task(void) | |
{ | |
// ---- DUAL-ROLE DEVICE/HOST USB MODE ----------------------------------------- | |
#if USB_DEVICE_FEATURE == ENABLED && USB_HOST_FEATURE == ENABLED | |
if (g_old_usb_mode != g_usb_mode) | |
{ | |
if (Is_usb_id_device()) | |
{ | |
usb_device_task_init(); | |
}else{ | |
private_sof_counter = 0; | |
usb_host_task_init(); | |
} | |
g_old_usb_mode = g_usb_mode; // Store current USB mode, for mode change detection | |
Usb_enable_id_interrupt(); | |
Enable_global_interrupt(); | |
} | |
// Depending on current USB mode, launch the correct USB task (device or host) | |
switch (g_old_usb_mode) | |
{ | |
case USB_MODE_DEVICE: | |
usb_device_task(); | |
break; | |
case USB_MODE_HOST: | |
usb_host_task(); | |
break; | |
case USB_MODE_UNDEFINED: | |
default: | |
break; | |
} | |
// ----------------------------------------------------------------------------- | |
// ---- DEVICE-ONLY USB MODE --------------------------------------------------- | |
#elif USB_DEVICE_FEATURE == ENABLED | |
usb_device_task(); | |
// ----------------------------------------------------------------------------- | |
// ---- REDUCED-HOST-ONLY USB MODE --------------------------------------------- | |
#elif USB_HOST_FEATURE == ENABLED | |
usb_host_task(); | |
// ----------------------------------------------------------------------------- | |
// ---- ERROR, NO MODE ENABLED ------------------------------------------------- | |
#else | |
#error At least one of USB_DEVICE_FEATURE and USB_HOST_FEATURE must be enabled | |
#endif | |
// ----------------------------------------------------------------------------- | |
} | |
#endif | |
//! @brief USB interrupt routine | |
//! | |
//! This function is called each time a USB interrupt occurs. | |
//! The following USB DEVICE events are taken in charge: | |
//! - VBus On / Off | |
//! - Start-of-Frame | |
//! - Suspend | |
//! - Wake-Up | |
//! - Resume | |
//! - Reset | |
//! | |
//! The following USB HOST events are taken in charge: | |
//! - Device connection | |
//! - Device Disconnection | |
//! - Start-of-Frame | |
//! - ID pin change | |
//! - SOF (or Keep alive in low-speed) sent | |
//! - Wake-up on USB line detected | |
//! - Pipe events | |
//! | |
//! For each event, the user can launch an action by completing the associated | |
//! \#define (see the conf_usb.h file to add actions on events). | |
//! | |
//! Note: Only interrupt events that are enabled are processed. | |
//! | |
//! Warning: If device and host tasks are not tasks in an RTOS, rough events | |
//! like ID transition, VBus transition, device disconnection, etc. that need to | |
//! kill then restart these tasks may lead to an undefined state if they occur | |
//! just before something is activated in the USB macro (e.g. pipe/endpoint | |
//! transfer...). | |
//! | |
//! @return Nothing in the standalone configuration; a boolean indicating | |
//! whether a task switch is required in the FreeRTOS configuration | |
#ifdef FREERTOS_USED | |
#if (defined __GNUC__) | |
__attribute__((__noinline__)) | |
#elif (defined __ICCAVR32__) | |
#pragma optimize = no_inline | |
#endif | |
static portBASE_TYPE usb_general_interrupt_non_naked(void) | |
#else | |
#if (defined __GNUC__) | |
__attribute__((__interrupt__)) | |
#elif (defined __ICCAVR32__) | |
__interrupt | |
#endif | |
//static void usb_general_interrupt(void) | |
void UOTGHS_IrqHandler(void) | |
#endif | |
{ | |
#ifdef FREERTOS_USED | |
portBASE_TYPE task_woken = pdFALSE; | |
#endif | |
#if USB_HOST_FEATURE == ENABLED && USB_HOST_PIPE_INTERRUPT_TRANSFER == ENABLE | |
U8 i; | |
#endif | |
//TRACE_OTG("UOTGHS_SR: 0x%X\n\r", UOTGHS->UOTGHS_SR); | |
//TRACE_OTG("HOST: 0x%X\n\r", (UOTGHS->UOTGHS_HSTISR & UOTGHS->UOTGHS_HSTIMR)); | |
//TRACE_OTG("DEV : 0x%X\n\r", (UOTGHS->UOTGHS_DEVISR & UOTGHS->UOTGHS_DEVIMR)); | |
// ---------- DEVICE/HOST events management ------------------------------------ | |
#if USB_DEVICE_FEATURE == ENABLED && USB_HOST_FEATURE == ENABLED | |
// ID pin change detection | |
if (Is_usb_id_transition() && Is_usb_id_interrupt_enabled()) | |
{ | |
g_usb_mode = (Is_usb_id_device()) ? USB_MODE_DEVICE : USB_MODE_HOST; | |
Usb_ack_id_transition(); | |
if (g_usb_mode != g_old_usb_mode) // Basic debounce | |
{ | |
// Previously in device mode, check if disconnection was detected | |
if (g_old_usb_mode == USB_MODE_DEVICE) | |
{ | |
if (usb_connected) | |
{ | |
// Device mode diconnection actions | |
usb_connected = FALSE; | |
usb_configuration_nb = 0; | |
Usb_vbus_off_action(); | |
} | |
} | |
// Previously in host mode, check if disconnection was detected | |
else if (Is_host_attached()) | |
{ | |
// Host mode diconnection actions | |
device_state = DEVICE_UNATTACHED; | |
Host_device_disconnection_action(); | |
} | |
LOG_STR(log_pin_id_changed); | |
Usb_send_event((Is_usb_device()) ? EVT_USB_DEVICE_FUNCTION : | |
EVT_USB_HOST_FUNCTION); | |
Usb_id_transition_action(); | |
//! @todo ID pin hot state change!!! | |
// Preliminary management: HARDWARE RESET!!! | |
#if ID_PIN_CHANGE_GENERATE_RESET == ENABLE | |
// Hot ID transition generates CPU reset | |
Usb_disable(); | |
Usb_disable_otg_pad(); | |
#ifdef FREERTOS_USED | |
// Release the semaphore in order to start a new device/host task | |
taskENTER_CRITICAL(); | |
xSemaphoreGiveFromISR(usb_tsk_semphr, &task_woken); | |
taskEXIT_CRITICAL(); | |
#else | |
// Reset_CPU(); | |
#endif | |
#endif | |
} | |
} | |
#endif // End DEVICE/HOST FEATURE MODE | |
// ---------- DEVICE events management ----------------------------------------- | |
#if USB_DEVICE_FEATURE == ENABLED | |
#if USB_HOST_FEATURE == ENABLED | |
// If both device and host features are enabled, check if device mode is engaged | |
// (accessing the USB registers of a non-engaged mode, even with load operations, | |
// may corrupt USB FIFO data). | |
if (Is_usb_device()) | |
#endif | |
{ | |
// VBus state detection | |
if (Is_usb_vbus_transition() && Is_usb_vbus_interrupt_enabled()) | |
{ | |
Usb_ack_vbus_transition(); | |
if (Is_usb_vbus_high()) | |
{ | |
usb_start_device(); | |
Usb_send_event(EVT_USB_POWERED); | |
Usb_vbus_on_action(); | |
} | |
else | |
{ | |
Usb_unfreeze_clock(); | |
Usb_detach(); | |
usb_connected = FALSE; | |
usb_configuration_nb = 0; | |
Usb_send_event(EVT_USB_UNPOWERED); | |
Usb_vbus_off_action(); | |
#ifdef FREERTOS_USED | |
// Release the semaphore in order to start a new device/host task | |
taskENTER_CRITICAL(); | |
xSemaphoreGiveFromISR(usb_tsk_semphr, &task_woken); | |
taskEXIT_CRITICAL(); | |
#endif | |
} | |
} | |
// Device Start-of-Frame received | |
if (Is_usb_sof() && Is_usb_sof_interrupt_enabled()) | |
{ | |
Usb_ack_sof(); | |
Usb_sof_action(); | |
} | |
// Device Suspend event (no more USB activity detected) | |
if (Is_usb_suspend() && Is_usb_suspend_interrupt_enabled()) | |
{ | |
Usb_ack_suspend(); | |
Usb_enable_wake_up_interrupt(); | |
(void)Is_usb_wake_up_interrupt_enabled(); | |
Usb_freeze_clock(); | |
Usb_send_event(EVT_USB_SUSPEND); | |
Usb_suspend_action(); | |
} | |
// Wake-up event (USB activity detected): Used to resume | |
if (Is_usb_wake_up() && Is_usb_wake_up_interrupt_enabled()) | |
{ | |
Usb_unfreeze_clock(); | |
(void)Is_usb_clock_frozen(); | |
Usb_ack_wake_up(); | |
Usb_disable_wake_up_interrupt(); | |
Usb_wake_up_action(); | |
Usb_send_event(EVT_USB_WAKE_UP); | |
} | |
// Resume state bus detection | |
if (Is_usb_resume() && Is_usb_resume_interrupt_enabled()) | |
{ | |
Usb_disable_wake_up_interrupt(); | |
Usb_ack_resume(); | |
Usb_disable_resume_interrupt(); | |
Usb_resume_action(); | |
Usb_send_event(EVT_USB_RESUME); | |
} | |
// USB bus reset detection | |
if (Is_usb_reset() && Is_usb_reset_interrupt_enabled()) | |
{ | |
Usb_ack_reset(); | |
usb_init_device(); | |
Usb_reset_action(); | |
Usb_send_event(EVT_USB_RESET); | |
} | |
} | |
#endif // End DEVICE FEATURE MODE | |
// ---------- HOST events management ------------------------------------------- | |
#if USB_HOST_FEATURE == ENABLED | |
#if USB_DEVICE_FEATURE == ENABLED | |
// If both device and host features are enabled, check if host mode is engaged | |
// (accessing the USB registers of a non-engaged mode, even with load operations, | |
// may corrupt USB FIFO data). | |
else | |
#endif | |
{ | |
// The device has been disconnected | |
if (Is_host_device_disconnection() && Is_host_device_disconnection_interrupt_enabled()) | |
{ | |
usb_device_connected = 0; | |
host_disable_all_pipes(); | |
Host_ack_device_disconnection(); | |
#if USB_HOST_PIPE_INTERRUPT_TRANSFER == ENABLE | |
reset_it_pipe_str(); | |
#endif | |
device_state = DEVICE_UNATTACHED; | |
LOG_STR(log_device_disconnected); | |
Usb_send_event(EVT_HOST_DISCONNECTION); | |
Host_device_disconnection_action(); | |
#ifdef FREERTOS_USED | |
// Release the semaphore in order to start a new device/host task | |
taskENTER_CRITICAL(); | |
xSemaphoreGiveFromISR(usb_tsk_semphr, &task_woken); | |
taskEXIT_CRITICAL(); | |
#endif | |
} | |
// Device connection | |
if (Is_host_device_connection() && Is_host_device_connection_interrupt_enabled()) | |
{ | |
usb_device_connected = 1; | |
Host_ack_device_connection(); | |
host_disable_all_pipes(); | |
Host_device_connection_action(); | |
} | |
// Host Start-of-Frame has been sent | |
if (Is_host_sof() && Is_host_sof_interrupt_enabled()) | |
{ | |
Host_ack_sof(); | |
Usb_send_event(EVT_HOST_SOF); | |
#if (USB_HIGH_SPEED_SUPPORT==ENABLED) | |
if( Is_usb_full_speed_mode() ) | |
{ | |
private_sof_counter++; | |
}else{ | |
private_sof_counter_HS++; | |
if( 0 == (private_sof_counter_HS%8) ) | |
{ | |
private_sof_counter++; | |
} | |
} | |
#else | |
private_sof_counter++; | |
#endif | |
// Delay time-out management for interrupt tranfer mode in host mode | |
#if USB_HOST_PIPE_INTERRUPT_TRANSFER == ENABLE && TIMEOUT_DELAY_ENABLE == ENABLE | |
if (private_sof_counter >= 250) // Count 250 ms (SOF @ 1 ms) | |
{ | |
private_sof_counter = 0; | |
for (i = 0; i < MAX_PEP_NB; i++) | |
{ | |
if (it_pipe_str[i].enable && | |
++it_pipe_str[i].timeout > TIMEOUT_DELAY && Host_get_pipe_type(i) != TYPE_INTERRUPT) | |
{ | |
it_pipe_str[i].enable = FALSE; | |
it_pipe_str[i].status = PIPE_DELAY_TIMEOUT; | |
Host_reset_pipe(i); | |
if (!is_any_interrupt_pipe_active() && !g_sav_int_sof_enable) // If no more transfer is armed | |
{ | |
Host_disable_sof_interrupt(); | |
} | |
it_pipe_str[i].handler(PIPE_DELAY_TIMEOUT, it_pipe_str[i].nb_byte_processed); | |
} | |
} | |
} | |
#endif | |
Host_sof_action(); | |
} | |
// Host Wake-up has been received | |
if (Is_host_hwup() && Is_host_hwup_interrupt_enabled()) | |
{ | |
// CAUTION: HWUP can be cleared only when USB clock is active (not frozen)! | |
//! @todo Implement this on the silicon version | |
//Pll_start_auto(); // First Restart the PLL for USB operation | |
//Wait_pll_ready(); // Make sure PLL is locked | |
Usb_unfreeze_clock(); // Enable clock on USB interface | |
(void)Is_usb_clock_frozen(); // Make sure USB interface clock is enabled | |
Host_disable_hwup_interrupt(); // Wake-up interrupt should be disabled as host is now awoken! | |
Host_ack_hwup(); // Clear HWUP interrupt flag | |
Usb_send_event(EVT_HOST_HWUP); // Send software event | |
Host_hwup_action(); // Map custom action | |
} | |
#if USB_HOST_PIPE_INTERRUPT_TRANSFER == ENABLE | |
// Host pipe interrupts | |
for(i=0; i<MAX_PEP_NB; i++) | |
{ | |
if( Host_get_interrupt_pipe_number(i) != 0 ) | |
{ | |
usb_pipe_interrupt(i); | |
} | |
} | |
#endif | |
} | |
#endif // End HOST FEATURE MODE | |
#ifdef FREERTOS_USED | |
return task_woken; | |
#endif | |
} | |
#if USB_DEVICE_FEATURE == ENABLED | |
void usb_suspend_action(void) | |
{ | |
// volatile avr32_pm_t *pm = &AVR32_PM; | |
// pm->AWEN.usb_waken = 1; | |
// SLEEP(AVR32_PM_SMODE_STOP); | |
// pm->AWEN.usb_waken = 0; | |
} | |
#endif | |
#if USB_HOST_FEATURE == ENABLED | |
void host_suspend_action(void) | |
{ | |
Enable_global_interrupt(); | |
//! @todo Implement this on the silicon version | |
//Enter_power_down_mode(); // For example... | |
} | |
U32 host_get_timeout( void ) | |
{ | |
return private_sof_counter; | |
} | |
#endif |