usb_task.c

Go to the documentation of this file.
00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 //_____  I N C L U D E S ___________________________________________________
00033 
00034 #include "config.h"
00035 #include "conf_usb.h"
00036 #include "usb_task.h"
00037 #include "lib_mcu/usb/usb_drv.h"
00038 #if ((USB_DEVICE_FEATURE == ENABLED))
00039 #include "usb_descriptors.h"
00040 #endif
00041 #include "lib_mcu/power/power_drv.h"
00042 #include "lib_mcu/wdt/wdt_drv.h"
00043 #include "lib_mcu/pll/pll_drv.h"
00044 
00045 #if ((USB_HOST_FEATURE == ENABLED))
00046    #include "modules/usb/host_chap9/usb_host_task.h"
00047    #if (USB_HOST_PIPE_INTERRUPT_TRANSFER == ENABLE)
00048       extern U8 g_sav_int_sof_enable;
00049    #endif
00050 #endif
00051 
00052 #if ((USB_DEVICE_FEATURE == ENABLED))
00053    #include "modules/usb/device_chap9/usb_device_task.h"
00054 #endif
00055 
00056 #ifndef  USE_USB_PADS_REGULATOR
00057    #error "USE_USB_PADS_REGULATOR" should be defined as ENABLE or DISABLE in conf_usb.h file
00058 #endif
00059 
00060 //_____ M A C R O S ________________________________________________________
00061 
00062 #ifndef LOG_STR_CODE
00063 #define LOG_STR_CODE(str)
00064 #else
00065 U8 code log_device_disconnect[]="Device Disconnected";
00066 U8 code log_id_change[]="Pin Id Change";
00067 #endif
00068 
00069 //_____ D E F I N I T I O N S ______________________________________________
00070 
00081 volatile U16 g_usb_event=0;
00082 
00083 
00084 #if (USB_DEVICE_FEATURE == ENABLED)
00091 extern bit   usb_connected;
00092 
00099 extern U8    usb_configuration_nb;
00100 #endif
00101 
00102 
00103 #if (USB_HOST_FEATURE == ENABLED)
00110 volatile U8 private_sof_counter=0;
00111 
00112    #if (USB_HOST_PIPE_INTERRUPT_TRANSFER == ENABLE)
00113 extern volatile S_pipe_int   it_pipe_str[MAX_EP_NB];
00114    #endif
00115 
00116 #endif
00117 
00118 #if ((USB_DEVICE_FEATURE == ENABLED)&& (USB_HOST_FEATURE == ENABLED))
00124    U8 g_usb_mode=USB_MODE_UNDEFINED;
00125    U8 g_old_usb_mode;
00126 #endif
00127 
00128 //_____ D E C L A R A T I O N S ____________________________________________
00129 
00140 void usb_task_init(void)
00141 {
00142    #if (USB_HOST_FEATURE == ENABLED && USB_DEVICE_FEATURE == ENABLED)
00143    U8 delay;
00144    #endif
00145 
00146    #if (USE_USB_PADS_REGULATOR==ENABLE)  // Otherwise assume USB PADs regulator is not used
00147    Usb_enable_regulator();
00148    #endif
00149 
00150 // ---- DUAL ROLE DEVICE USB MODE ---------------------------------------------
00151 #if ((USB_DEVICE_FEATURE == ENABLED)&& (USB_HOST_FEATURE == ENABLED))
00152    Usb_enable_uid_pin();
00153    delay=PORTA;
00154    g_usb_mode=USB_MODE_UNDEFINED;
00155    if(Is_usb_id_device())
00156    {
00157      g_usb_mode=USB_MODE_DEVICE;
00158      usb_device_task_init();
00159    }
00160    else
00161    {
00162      g_usb_mode=USB_MODE_HOST;
00163      Usb_ack_id_transition(); // REQUIRED !!! Startup with ID=0, Ack ID pin transistion (default hwd start up is device mode)
00164      Usb_enable_id_interrupt();
00165      Enable_interrupt();
00166      usb_host_task_init();
00167    }
00168    g_old_usb_mode=g_usb_mode;   // Store current usb mode, for mode change detection
00169 // -----------------------------------------------------------------------------
00170 
00171 // ---- DEVICE ONLY USB MODE ---------------------------------------------------
00172 #elif ((USB_DEVICE_FEATURE == ENABLED)&& (USB_HOST_FEATURE == DISABLE))
00173    Usb_force_device_mode();
00174    usb_device_task_init();
00175 // -----------------------------------------------------------------------------
00176 
00177 // ---- REDUCED HOST ONLY USB MODE ---------------------------------------------
00178 #elif ((USB_DEVICE_FEATURE == DISABLE)&& (USB_HOST_FEATURE == ENABLED))
00179    Usb_force_host_mode();
00180    usb_host_task_init();
00181 #elif ((USB_DEVICE_FEATURE == DISABLE)&& (USB_HOST_FEATURE == DISABLE))
00182    #error  at least one of USB_DEVICE_FEATURE or USB_HOST_FEATURE should be enabled
00183 #endif
00184 // -----------------------------------------------------------------------------
00185 
00186 
00187 }
00188 
00199 void usb_task(void)
00200 {
00201 // ---- DUAL ROLE DEVICE USB MODE ---------------------------------------------
00202 #if ((USB_DEVICE_FEATURE == ENABLED)&& (USB_HOST_FEATURE == ENABLED))
00203    if(Is_usb_id_device())
00204    { g_usb_mode=USB_MODE_DEVICE;}
00205    else
00206    { g_usb_mode=USB_MODE_HOST;}
00207   // TODO !!! ID pin hot state change
00208   // Preliminary management: HARDWARE RESET !!!
00209    #if ( ID_PIN_CHANGE_GENERATE_RESET == ENABLE)
00210      // Hot ID transition generates wdt reset
00211       if((g_old_usb_mode!=g_usb_mode))
00212       #ifndef  AVRGCC
00213          {Wdt_change_16ms(); while(1);   LOG_STR_CODE(log_id_change);}
00214       #else
00215          {Wdt_change_enable(); while(1); LOG_STR_CODE(log_id_change);}
00216       #endif
00217 
00218    #endif
00219   g_old_usb_mode=g_usb_mode;   // Store current usb mode, for mode change detection
00220   // Depending on current usb mode, launch the correct usb task (device or host)
00221    switch(g_usb_mode)
00222    {
00223       case USB_MODE_DEVICE:
00224          usb_device_task();
00225          break;
00226       case USB_MODE_HOST:
00227          usb_host_task();
00228          break;
00229       case USB_MODE_UNDEFINED:  // No break !
00230       default:
00231          break;
00232   }
00233 // -----------------------------------------------------------------------------
00234 
00235 // ---- DEVICE ONLY USB MODE ---------------------------------------------------
00236 #elif ((USB_DEVICE_FEATURE == ENABLED)&& (USB_HOST_FEATURE == DISABLE))
00237    usb_device_task();
00238 // -----------------------------------------------------------------------------
00239 
00240 // ---- REDUCED HOST ONLY USB MODE ---------------------------------------------
00241 #elif ((USB_DEVICE_FEATURE == DISABLE)&& (USB_HOST_FEATURE == ENABLED))
00242    usb_host_task();
00243 // -----------------------------------------------------------------------------
00244 
00246 #elif ((USB_DEVICE_FEATURE == DISABLE)&& (USB_HOST_FEATURE == DISABLE))
00247    #error  at least one of USB_DEVICE_FEATURE or USB_HOST_FEATURE should be enabled
00248    #error  otherwise the usb task has nothing to do ...
00249 #endif
00250 // -----------------------------------------------------------------------------
00251 
00252 }
00253 
00282 #ifdef AVRGCC
00283  ISR(USB_GEN_vect)
00284 #else
00285 #pragma vector = USB_GENERAL_vect
00286 __interrupt void usb_general_interrupt()
00287 #endif
00288 {
00289    #if (USB_HOST_PIPE_INTERRUPT_TRANSFER == ENABLE)
00290    U8 i;
00291    U8 save_pipe_nb;
00292    #endif
00293 // ---------- DEVICE events management -----------------------------------
00294 #if (USB_DEVICE_FEATURE == ENABLED)
00295   //- VBUS state detection
00296    if (Is_usb_vbus_transition() && Is_usb_vbus_interrupt_enabled())
00297    {
00298       Usb_ack_vbus_transition();
00299       if (Is_usb_vbus_high())
00300       {
00301          usb_connected = TRUE;
00302          Usb_vbus_on_action();
00303          Usb_send_event(EVT_USB_POWERED);
00304          Usb_enable_reset_interrupt();
00305          usb_start_device();
00306          Usb_attach();
00307       }
00308       else
00309       {
00310          Usb_vbus_off_action();
00311          usb_connected = FALSE;
00312          usb_configuration_nb = 0;
00313          Usb_send_event(EVT_USB_UNPOWERED);
00314       }
00315    }
00316   // - Device start of frame received
00317    if (Is_usb_sof() && Is_sof_interrupt_enabled())
00318    {
00319       Usb_ack_sof();
00320       Usb_sof_action();
00321    }
00322   // - Device Suspend event (no more USB activity detected)
00323    if (Is_usb_suspend() && Is_suspend_interrupt_enabled())
00324    {
00325       Usb_ack_suspend();
00326       Usb_enable_wake_up_interrupt();
00327       Usb_ack_wake_up();                 // clear wake up to detect next event
00328       Usb_freeze_clock();
00329       Usb_send_event(EVT_USB_SUSPEND);
00330       Usb_suspend_action();
00331    }
00332   // - Wake up event (USB activity detected): Used to resume
00333    if (Is_usb_wake_up() && Is_swake_up_interrupt_enabled())
00334    {
00335       Usb_unfreeze_clock();
00336       Usb_ack_wake_up();
00337       Usb_disable_wake_up_interrupt();
00338       Usb_wake_up_action();
00339       Usb_send_event(EVT_USB_WAKE_UP);
00340    }
00341   // - Resume state bus detection
00342    if (Is_usb_resume() && Is_resume_interrupt_enabled())
00343    {
00344       Usb_disable_wake_up_interrupt();
00345       Usb_ack_resume();
00346       Usb_disable_resume_interrupt();
00347       Usb_resume_action();
00348       Usb_send_event(EVT_USB_RESUME);
00349    }
00350   // - USB bus reset detection
00351    if (Is_usb_reset()&& Is_reset_interrupt_enabled())
00352    {
00353       Usb_ack_reset();
00354       usb_init_device();
00355       Usb_reset_action();
00356       Usb_send_event(EVT_USB_RESET);
00357    }
00358 #endif// End DEVICE FEATURE MODE
00359 
00360 // ---------- HOST events management -----------------------------------
00361 #if (USB_HOST_FEATURE == ENABLED && USB_DEVICE_FEATURE == ENABLED)
00362   // - ID pin change detection
00363    if(Is_usb_id_transition()&&Is_usb_id_interrupt_enabled())
00364    {
00365       if(Is_usb_id_device())
00366       { g_usb_mode=USB_MODE_DEVICE;}
00367       else
00368       { g_usb_mode=USB_MODE_HOST;}
00369       Usb_ack_id_transition();
00370       if( g_usb_mode != g_old_usb_mode) // Basic Debounce
00371       {
00372          if(Is_usb_id_device()) // Going to device mode
00373          {
00374             Usb_send_event(EVT_USB_DEVICE_FUNCTION);
00375          }
00376          else                   // Going to host mode
00377          {
00378             Usb_send_event(EVT_USB_HOST_FUNCTION);
00379          }
00380          Usb_id_transition_action();
00381          LOG_STR_CODE(log_id_change);
00382          #if ( ID_PIN_CHANGE_GENERATE_RESET == ENABLE)
00383         // Hot ID transition generates wdt reset
00384             #ifndef  AVRGCC
00385                Wdt_change_16ms(); while(1);
00386             #else
00387                Wdt_change_enable(); while(1);
00388             #endif
00389          #endif
00390       }
00391    }
00392 #endif
00393 #if (USB_HOST_FEATURE == ENABLED)
00394   // - The device has been disconnected
00395    if(Is_device_disconnection() && Is_host_device_disconnection_interrupt_enabled())
00396    {
00397       host_disable_all_pipe();
00398       Host_ack_device_disconnection();
00399       device_state=DEVICE_DISCONNECTED;
00400       Usb_send_event(EVT_HOST_DISCONNECTION);
00401       LOG_STR_CODE(log_device_disconnect);
00402       Host_device_disconnection_action();
00403    }
00404   // - Device connection
00405    if(Is_device_connection() && Is_host_device_connection_interrupt_enabled())
00406    {
00407       Host_ack_device_connection();
00408       host_disable_all_pipe();
00409       Host_device_connection_action();
00410    }
00411   // - Host Start of frame has been sent
00412    if (Is_host_sof() && Is_host_sof_interrupt_enabled())
00413    {
00414       Host_ack_sof();
00415       Usb_send_event(EVT_HOST_SOF);
00416       private_sof_counter++;
00417 
00418       // delay timeout management for interrupt tranfer mode in host mode
00419       #if ((USB_HOST_PIPE_INTERRUPT_TRANSFER==ENABLE) && (TIMEOUT_DELAY_ENABLE==ENABLE))
00420       if (private_sof_counter>=250)   // Count 1/4 sec
00421       {
00422          private_sof_counter=0;
00423          for(i=0;i<MAX_EP_NB;i++)
00424          {
00425             if(it_pipe_str[i].enable==ENABLE)
00426             {
00427                save_pipe_nb=Host_get_selected_pipe();
00428                Host_select_pipe(i);
00429                if((++it_pipe_str[i].timeout>TIMEOUT_DELAY) && (Host_get_pipe_type()!=TYPE_INTERRUPT))
00430                {
00431                   it_pipe_str[i].enable=DISABLE;
00432                   it_pipe_str[i].status=PIPE_DELAY_TIMEOUT;
00433                   Host_stop_pipe_interrupt(i);
00434                   if (is_any_interrupt_pipe_active()==FALSE)    // If no more transfer is armed
00435                   {
00436                      if (g_sav_int_sof_enable==FALSE)
00437                      {
00438                         Host_disable_sof_interrupt();
00439                      }
00440                   }
00441                   it_pipe_str[i].handle(PIPE_DELAY_TIMEOUT,it_pipe_str[i].nb_byte_processed);
00442                }
00443                Host_select_pipe(save_pipe_nb);
00444             }
00445          }
00446       }
00447       #endif  // (USB_HOST_PIPE_INTERRUPT_TRANSFER==ENABLE) && (TIMEOUT_DELAY_ENABLE==ENABLE))
00448       Host_sof_action();
00449    }
00450   // - Host Wake-up has been received
00451    if (Is_host_hwup() && Is_host_hwup_interrupt_enabled())
00452    {
00453       Host_disable_hwup_interrupt();  // Wake up interrupt should be disable host is now wake up !
00454       // CAUTION HWUP can be cleared only when USB clock is active (not frozen)!
00455       Pll_start_auto();               // First Restart the PLL for USB operation
00456       Wait_pll_ready();               // Get sure pll is lock
00457       Usb_unfreeze_clock();           // Enable clock on USB interface
00458       Host_ack_hwup();                // Clear HWUP interrupt flag
00459       Usb_send_event(EVT_HOST_HWUP);  // Send software event
00460       Host_hwup_action();             // Map custom action
00461    }
00462 #endif // End HOST FEATURE MODE
00463 }
00464 
00465 
00466 extern void suspend_action(void)
00467 {
00468    Enable_interrupt();
00469    Enter_power_down_mode();
00470 }
00471 
00472 extern void host_suspend_action(void)
00473 {
00474    //Enter_power_down_mode();  //For example...
00475 }

Generated on Fri Jan 26 17:33:01 2007 for Atmel by  doxygen 1.5.1-p1