usb_task.c File Reference

#include "config.h"
#include "conf_usb.h"
#include "usb_task.h"
#include "lib_mcu/usb/usb_drv.h"
#include "usb_descriptors.h"
#include "lib_mcu/power/power_drv.h"
#include "lib_mcu/wdt/wdt_drv.h"
#include "lib_mcu/pll/pll_drv.h"
#include "modules/usb/host_chap9/usb_host_task.h"
#include "modules/usb/host_chap9/usb_host_enum.h"
#include "modules/usb/device_chap9/usb_device_task.h"

Include dependency graph for usb_task.c:

Go to the source code of this file.

Defines

#define LOG_STR_CODE(str)

Functions

void usb_task_init (void)
void usb_task (void)
__interrupt void usb_general_interrupt ()

Variables

U8 g_sav_int_sof_enable
volatile U16 g_usb_event = 0
 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 usb_task.h file) Usb_send_event(x) Usb_ack_event(x) Usb_clear_all_event() Is_usb_event(x) Is_not_usb_event(x).
bit usb_connected
 Public : (bit) 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 /.
U8 usb_configuration_nb
 Public : (U8) usb_configuration_nb Store the number of the USB configuration used by the USB device when its value is different from zero, it means the device mode is enumerated Used with USB_DEVICE_FEATURE == ENABLED only /.
U8 remote_wakeup_feature
 Public : (U8) remote_wakeup_feature Store a host request for remote wake up (set feature received) /.
volatile U8 private_sof_counter = 0
 Private : (U8) private_sof_counter Incremented by host SOF interrupt subroutime This counter is used to detect timeout in host requests.
volatile S_pipe_int it_pipe_str [MAX_EP_NB]
volatile U8 hub_interrupt_sof
U8 g_usb_mode = 0x00
 Public : (U8) g_usb_mode Used in dual role application (both device/host) to store the current mode the usb controller is operating /.
U8 g_old_usb_mode


Detailed Description

This file manages 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 USB_DEVICE_FEATURE and USB_HOST_FEATURE value (located in 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:

Author:
Atmel Corporation: http://www.atmel.com
Support and FAQ: http://support.atmel.no/

Definition in file usb_task.c.


Define Documentation

#define LOG_STR_CODE ( str   ) 

Definition at line 85 of file usb_task.c.


Function Documentation

__interrupt void usb_general_interrupt (  ) 

USB interrupt subroutine This function is called each time a USB interrupt occurs. The following USB DEVICE events are taken in charge:

The following USB HOST events are taken in charge:

For each event, the user can launch an action by completing the associate define (See conf_usb.h file to add action upon events)

Note: Only interrupts events that are enabled are processed

Parameters:
none 
Returns:
none

Definition at line 352 of file usb_task.c.

References DEVICE_DISCONNECTED, device_state, DISABLE, S_pipe_int::enable, ENABLE, ENABLED, EVT_HOST_DISCONNECTION, EVT_HOST_HWUP, EVT_HOST_SOF, EVT_USB_DEVICE_FUNCTION, EVT_USB_HOST_FUNCTION, EVT_USB_RESET, EVT_USB_RESUME, EVT_USB_SUSPEND, EVT_USB_WAKE_UP, FALSE, g_old_usb_mode, g_sav_int_sof_enable, g_usb_mode, S_pipe_int::handle, Host_ack_device_connection, Host_ack_device_disconnection, Host_ack_hwup, Host_ack_sof, Host_device_connection_action, Host_device_disconnection_action, host_disable_all_pipe(), Host_disable_hwup_interrupt, Host_disable_sof_interrupt, Host_get_pipe_type, Host_get_selected_pipe, Host_hwup_action, Host_select_pipe, Host_sof_action, Host_stop_pipe_interrupt, hub_interrupt_sof, i, init_usb_tree(), is_any_interrupt_pipe_active(), Is_device_connection, Is_device_disconnection, Is_host_device_connection_interrupt_enabled, Is_host_device_disconnection_interrupt_enabled, Is_host_hwup, Is_host_hwup_interrupt_enabled, Is_host_sof, Is_host_sof_interrupt_enabled, Is_pll_ready, Is_reset_interrupt_enabled, Is_resume_interrupt_enabled, Is_sof_interrupt_enabled, Is_suspend_interrupt_enabled, Is_usb_id_device, Is_usb_id_interrupt_enabled, Is_usb_id_transition, Is_usb_reset, Is_usb_resume, Is_usb_sof, Is_usb_suspend, Is_usb_wake_up, Is_wake_up_interrupt_enabled, LOG_STR_CODE, MAX_EP_NB, PIPE_DELAY_TIMEOUT, private_sof_counter, remote_wakeup_feature, S_pipe_int::status, Stop_pll, TIMEOUT_DELAY, TRUE, TYPE_INTERRUPT, Usb_ack_id_transition, Usb_ack_reset, Usb_ack_resume, Usb_ack_sof, Usb_ack_suspend, Usb_ack_wake_up, usb_configuration_nb, Usb_disable_resume_interrupt, Usb_disable_suspend_interrupt, Usb_disable_wake_up_interrupt, Usb_enable_reset_interrupt, Usb_enable_resume_interrupt, Usb_enable_suspend_interrupt, Usb_enable_wake_up_interrupt, Usb_freeze_clock, Usb_id_transition_action, usb_init_device(), USB_MODE_DEVICE, USB_MODE_HOST, Usb_reset_action, Usb_resume_action, Usb_send_event, Usb_sof_action, Usb_suspend_action, usb_suspended, Usb_unfreeze_clock, Usb_wake_up_action, Wait_pll_ready, wdtdrv_enable(), and WDTO_16MS.

00354 {
00355    #if (USB_HOST_PIPE_INTERRUPT_TRANSFER == ENABLE)
00356    U8 i;
00357    U8 save_pipe_nb;
00358    #endif
00359 // ---------- DEVICE events management -----------------------------------
00360 #if (USB_DEVICE_FEATURE == ENABLED)
00361 
00362   // - Device start of frame received
00363    if (Is_usb_sof() && Is_sof_interrupt_enabled())
00364    {
00365       Usb_ack_sof();
00366       Usb_sof_action();
00367    }
00368 #ifdef WA_USB_SUSPEND_PERTUBATION
00369   // - Device Suspend event (no more USB activity detected)
00370    if (Is_usb_suspend() && Is_suspend_interrupt_enabled())
00371    {
00372       usb_suspended=TRUE;
00373       Usb_ack_wake_up();                 // clear wake up to detect next event
00374       Usb_send_event(EVT_USB_SUSPEND);
00375       Usb_ack_suspend();
00376       Usb_enable_wake_up_interrupt();
00377       Usb_disable_resume_interrupt();
00378       Usb_freeze_clock();
00379       Stop_pll();
00380       Usb_suspend_action();
00381    }
00382   // - Wake up event (USB activity detected): Used to resume
00383    if (Is_usb_wake_up() && Is_wake_up_interrupt_enabled())
00384    {
00385       if(Is_pll_ready()==FALSE)
00386       {
00387          Pll_start_auto();
00388          Wait_pll_ready();
00389       }
00390       Usb_unfreeze_clock();
00391       Usb_ack_wake_up();
00392       if(usb_suspended)
00393       {
00394          Usb_enable_resume_interrupt();
00395          Usb_enable_reset_interrupt();
00396          while(Is_usb_wake_up())
00397          {
00398             Usb_ack_wake_up();
00399          }
00400          usb_delay_ms(2);
00401          if(Is_usb_sof() || Is_usb_resume() || Is_usb_reset() )
00402          {
00403             Usb_disable_wake_up_interrupt();
00404             Usb_wake_up_action();
00405             Usb_send_event(EVT_USB_WAKE_UP);
00406             Usb_enable_suspend_interrupt();
00407             Usb_enable_resume_interrupt();
00408             Usb_enable_reset_interrupt();
00409             
00410          }
00411          else // Workarround to make the USB enter power down mode again (spurious transcient detected on the USB lines)
00412          {
00413             Usb_ack_wake_up();                 // clear wake up to detect next event
00414             Usb_send_event(EVT_USB_SUSPEND);
00415             Usb_enable_wake_up_interrupt();
00416             Usb_disable_resume_interrupt();
00417             Usb_freeze_clock();
00418             Stop_pll();
00419             Usb_suspend_action();
00420          }
00421       }
00422    }
00423   // - Resume state bus detection
00424    if (Is_usb_resume() && Is_resume_interrupt_enabled())
00425    {
00426       usb_suspended = FALSE;
00427       Usb_disable_wake_up_interrupt();
00428       Usb_ack_resume();
00429       Usb_disable_resume_interrupt();
00430       Usb_resume_action();
00431       Usb_send_event(EVT_USB_RESUME);
00432    }
00433 #else
00434   // - Device Suspend event (no more USB activity detected)
00435    if (Is_usb_suspend() && Is_suspend_interrupt_enabled())
00436    {
00437       // Remote wake-up handler
00438       if ((remote_wakeup_feature == ENABLED) && (usb_configuration_nb != 0))
00439       {
00440         Usb_disable_suspend_interrupt();
00441         Usb_ack_wake_up();
00442         Usb_enable_wake_up_interrupt();
00443         Stop_pll();
00444         Usb_freeze_clock();
00445         Usb_suspend_action();
00446         
00447         // After that user can execute "Usb_initiate_remote_wake_up()" to initiate a remote wake-up
00448         // Note that the suspend interrupt flag SUSPI must still be set to enable upstream resume
00449         // So the SUSPE enable bit must be cleared to avoid redundant interrupt
00450         // ****************
00451         // Please note also that is Vbus is lost during an upstream resume (Host disconnection),
00452         // the RMWKUP bit (used to initiate remote wake up and that is normally cleared by hardware when sent)
00453         // remains set after the event, so that a good way to handle this feature is :
00454         //            Usb_unfreeze_clock();
00455         //            Usb_initiate_remote_wake_up();
00456         //            while (Is_usb_pending_remote_wake_up())
00457         //            {
00458         //              if (Is_usb_vbus_low())
00459         //              {
00460         //                // Emergency action (reset macro, etc.) if Vbus lost during resuming
00461         //                break;
00462         //              }
00463         //            }
00464         //            Usb_ack_remote_wake_up_start();
00465         // ****************
00466       }
00467       else
00468       {
00469         // No remote wake-up supported
00470          Usb_ack_wake_up();                 // clear wake up to detect next event
00471          Usb_send_event(EVT_USB_SUSPEND);
00472          Usb_ack_suspend();  // must be executed last (after Usb_suspend_action()) to allow upstream resume
00473          Usb_enable_wake_up_interrupt();
00474          Usb_freeze_clock();
00475          Stop_pll();
00476          Usb_suspend_action();
00477       }
00478    }
00479   // - Wake up event (USB activity detected): Used to resume
00480    if (Is_usb_wake_up() && Is_wake_up_interrupt_enabled())
00481    {
00482       if(Is_pll_ready()==FALSE)
00483       {
00484          Pll_start_auto();
00485          Wait_pll_ready();
00486       }
00487       Usb_unfreeze_clock();
00488       Usb_ack_wake_up();
00489       Usb_disable_wake_up_interrupt();
00490       Usb_wake_up_action();
00491       Usb_send_event(EVT_USB_WAKE_UP);
00492       Usb_enable_suspend_interrupt();
00493    }
00494   // - Resume state bus detection
00495    if (Is_usb_resume() && Is_resume_interrupt_enabled())
00496    {
00497       Usb_disable_wake_up_interrupt();
00498       Usb_ack_resume();
00499       Usb_disable_resume_interrupt();
00500       Usb_resume_action();
00501       Usb_send_event(EVT_USB_RESUME);
00502    }
00503 #endif
00504   // - USB bus reset detection
00505    if (Is_usb_reset()&& Is_reset_interrupt_enabled())
00506    {
00507       Usb_ack_reset();
00508       usb_init_device();
00509       Usb_reset_action();
00510       Usb_send_event(EVT_USB_RESET);
00511    }
00512 #endif// End DEVICE FEATURE MODE
00513 
00514 // ---------- HOST events management -----------------------------------
00515 #if (USB_HOST_FEATURE == ENABLED && USB_DEVICE_FEATURE == ENABLED)
00516   // - ID pin change detection
00517    if(Is_usb_id_transition()&&Is_usb_id_interrupt_enabled())
00518    {
00519       if(Is_usb_id_device())
00520       { g_usb_mode=USB_MODE_DEVICE;}
00521       else
00522       { g_usb_mode=USB_MODE_HOST;}
00523       Usb_ack_id_transition();
00524       if( g_usb_mode != g_old_usb_mode) // Basic Debounce
00525       {
00526          if(Is_usb_id_device()) // Going to device mode
00527          {
00528             Usb_send_event(EVT_USB_DEVICE_FUNCTION);
00529          }
00530          else                   // Going to host mode
00531          {
00532             Usb_send_event(EVT_USB_HOST_FUNCTION);
00533          }
00534          Usb_id_transition_action();
00535          LOG_STR_CODE(log_id_change);
00536          #if ( ID_PIN_CHANGE_GENERATE_RESET == ENABLE)
00537          // Hot ID transition generates wdt reset
00538          wdtdrv_enable(WDTO_16MS);
00539          while(1);
00540          #endif
00541       }
00542    }
00543 #endif
00544 #if (USB_HOST_FEATURE == ENABLED)
00545   // - The device has been disconnected
00546    if(Is_device_disconnection() && Is_host_device_disconnection_interrupt_enabled())
00547    {
00548       host_disable_all_pipe();
00549       Host_ack_device_disconnection();
00550       device_state=DEVICE_DISCONNECTED;
00551       Usb_send_event(EVT_HOST_DISCONNECTION);
00552       init_usb_tree();      
00553       LOG_STR_CODE(log_device_disconnect);
00554       Host_device_disconnection_action();
00555    }
00556   // - Device connection
00557    if(Is_device_connection() && Is_host_device_connection_interrupt_enabled())
00558    {
00559       Host_ack_device_connection();
00560       host_disable_all_pipe();
00561       Host_device_connection_action();
00562    }
00563   // - Host Start of frame has been sent
00564    if (Is_host_sof() && Is_host_sof_interrupt_enabled())
00565    {
00566       Host_ack_sof();
00567       Usb_send_event(EVT_HOST_SOF);
00568       private_sof_counter++;
00569 #if (USB_HUB_SUPPORT==ENABLE)
00570       hub_interrupt_sof++;
00571 #endif
00572 
00573       // delay timeout management for interrupt tranfer mode in host mode
00574       #if ((USB_HOST_PIPE_INTERRUPT_TRANSFER==ENABLE) && (TIMEOUT_DELAY_ENABLE==ENABLE))
00575       if (private_sof_counter>=250)   // Count 1/4 sec
00576       {
00577          private_sof_counter=0;
00578          for(i=0;i<MAX_EP_NB;i++)
00579          {
00580             if(it_pipe_str[i].enable==ENABLE)
00581             {
00582                save_pipe_nb=Host_get_selected_pipe();
00583                Host_select_pipe(i);
00584                if((++it_pipe_str[i].timeout>TIMEOUT_DELAY) && (Host_get_pipe_type()!=TYPE_INTERRUPT))
00585                {
00586                   it_pipe_str[i].enable=DISABLE;
00587                   it_pipe_str[i].status=PIPE_DELAY_TIMEOUT;
00588                   Host_stop_pipe_interrupt(i);
00589                   if (is_any_interrupt_pipe_active()==FALSE)    // If no more transfer is armed
00590                   {
00591                      if (g_sav_int_sof_enable==FALSE)
00592                      {
00593                         Host_disable_sof_interrupt();
00594                      }
00595                   }
00596                   it_pipe_str[i].handle(PIPE_DELAY_TIMEOUT,it_pipe_str[i].nb_byte_processed);
00597                }
00598                Host_select_pipe(save_pipe_nb);
00599             }
00600          }
00601       }
00602       #endif  // (USB_HOST_PIPE_INTERRUPT_TRANSFER==ENABLE) && (TIMEOUT_DELAY_ENABLE==ENABLE))
00603       Host_sof_action();
00604    }
00605   // - Host Wake-up has been received
00606    if (Is_host_hwup() && Is_host_hwup_interrupt_enabled())
00607    {
00608       Host_disable_hwup_interrupt();  // Wake up interrupt should be disable host is now wake up !
00609       // CAUTION HWUP can be cleared only when USB clock is active (not frozen)!
00610       Pll_start_auto();               // First Restart the PLL for USB operation
00611       Wait_pll_ready();               // Get sure pll is lock
00612       Usb_unfreeze_clock();           // Enable clock on USB interface
00613       Host_ack_hwup();                // Clear HWUP interrupt flag
00614       Usb_send_event(EVT_HOST_HWUP);  // Send software event
00615       Host_hwup_action();             // Map custom action
00616    }
00617 #endif // End HOST FEATURE MODE
00618 }

Here is the call graph for this function:


Variable Documentation

U8 g_sav_int_sof_enable

Definition at line 131 of file usb_host_task.c.

bit usb_connected

Public : (bit) 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 /.

Definition at line 76 of file usb_device_task.c.

volatile S_pipe_int it_pipe_str[MAX_EP_NB]

Definition at line 129 of file usb_host_task.c.

volatile U8 hub_interrupt_sof

Definition at line 179 of file usb_host_task.c.

U8 g_old_usb_mode

Definition at line 162 of file usb_task.c.

Referenced by usb_general_interrupt(), usb_task(), and usb_task_init().


Generated on Mon Nov 3 10:08:26 2008 for ATMEL by  doxygen 1.5.3