usb_device_task.c

Go to the documentation of this file.
00001 /*This file has been prepared for Doxygen automatic documentation generation.*/
00018 
00019 /* Copyright (c) 2007, Atmel Corporation All rights reserved.
00020  *
00021  * Redistribution and use in source and binary forms, with or without
00022  * modification, are permitted provided that the following conditions are met:
00023  *
00024  * 1. Redistributions of source code must retain the above copyright notice,
00025  * this list of conditions and the following disclaimer.
00026  *
00027  * 2. Redistributions in binary form must reproduce the above copyright notice,
00028  * this list of conditions and the following disclaimer in the documentation
00029  * and/or other materials provided with the distribution.
00030  *
00031  * 3. The name of ATMEL may not be used to endorse or promote products derived
00032  * from this software without specific prior written permission.
00033  *
00034  * THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
00035  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00036  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE EXPRESSLY AND
00037  * SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
00038  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00039  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00040  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00041  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00042  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00043  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00044  */
00045 
00046 //_____  I N C L U D E S ___________________________________________________
00047 
00048 #include "config.h"
00049 #include "conf_usb.h"
00050 #include "usb_device_task.h"
00051 #include "modules/usb/usb_task.h"
00052 #if (USB_OTG_FEATURE == ENABLED)
00053   #include "modules/usb/host_chap9/usb_host_task.h"
00054 #endif
00055 #include "lib_mcu/usb/usb_drv.h"
00056 #include "usb_descriptors.h"
00057 #include "modules/usb/device_chap9/usb_standard_request.h"
00058 #include "lib_mcu/pll/pll_drv.h"
00059 
00060 #if ((TARGET_BOARD==SPIDER) && (USB_OTG_FEATURE==ENABLED))
00061     #include "lib_board/lcd/lcd_drv.h"
00062 #endif
00063 
00064 //_____ M A C R O S ________________________________________________________
00065 
00066 
00067 
00068 
00069 //_____ D E F I N I T I O N S ______________________________________________
00070 
00076 bit   usb_connected=FALSE;
00077 
00083 bit   usb_suspended=FALSE;
00084 
00085 
00086 
00087 
00094 extern U8  usb_configuration_nb;
00095 
00096 
00097 #if (USB_OTG_FEATURE == ENABLED)
00100 U8  otg_b_device_state;
00101 
00104 U8  otg_device_sessions;
00105 
00108 U8  otg_b_device_hnp;
00109 
00112 U16 otg_tb_srp_cpt;
00113 
00117 U8  sof_seen_in_session;
00118 #endif
00119 
00120 
00121 //_____ D E C L A R A T I O N S ____________________________________________
00122 
00135 void usb_device_task_init(void)
00136 {
00137    Enable_interrupt();
00138    Usb_disable();
00139    Usb_enable();
00140    Usb_select_device();
00141 #if (USB_LOW_SPEED_DEVICE==ENABLE)
00142    Usb_low_speed_mode();
00143 #endif
00144    Enable_interrupt();
00145 #if (USB_OTG_FEATURE == ENABLED)
00146    Usb_enable_id_interrupt();
00147    Clear_otg_features_from_host();
00148    otg_device_sessions = 0;
00149 #endif
00150 }
00151 
00165 void usb_start_device (void)
00166 {
00167    Pll_start_auto();
00168    Wait_pll_ready();
00169 
00170    Disable_interrupt();
00171    Usb_unfreeze_clock();
00172    usb_init_device();         // configure the USB controller EP0
00173    Usb_attach();
00174    Enable_interrupt();
00175    
00176    Usb_enable_suspend_interrupt();
00177    Usb_enable_reset_interrupt();
00178 #if (USB_OTG_FEATURE == ENABLED)
00179    Usb_enable_id_interrupt();
00180 #endif
00181 }
00182 
00193 void usb_device_task(void)
00194 {
00195   
00196 #if (USB_OTG_FEATURE == ENABLED)
00197    // Check if a reset has been received
00198    if(Is_usb_event(EVT_USB_RESET))
00199    {
00200       Usb_ack_event(EVT_USB_RESET);
00201       Usb_reset_endpoint(0);
00202       usb_configuration_nb=0;
00203       otg_b_device_state = B_IDLE;
00204       Clear_otg_features_from_host();
00205    }
00206 
00207    // When OTG mode enabled, B-Device is managed thanks to its state machine
00208    switch (otg_b_device_state)
00209    {
00210    //------------------------------------------------------
00211    //   B_IDLE state
00212    //
00213    //   - waits for Vbus to rise
00214    //   - initiate SRP if asked by user
00215    //
00216    case B_IDLE:
00217      if (Is_usb_vbus_high())
00218      {
00219        // Vbus rise
00220        usb_connected = TRUE;
00221        remote_wakeup_feature = DISABLED;
00222        usb_start_device();
00223        Usb_vbus_on_action();
00224        Usb_attach();
00225        otg_b_device_state = B_PERIPHERAL;
00226        Ack_user_request_srp();
00227        Clear_otg_features_from_host();
00228        remote_wakeup_feature = DISABLED;
00229        End_session_with_srp();
00230        if (Is_srp_sent_and_waiting_answer() && (sof_seen_in_session == TRUE))
00231        {
00232          Ack_srp_sent_and_answer();
00233          Otg_print_new_failure_message(OTGMSG_A_RESPONDED,OTG_TEMPO_2SEC);
00234        }
00235        Usb_enable_sof_interrupt();
00236        
00237      }
00238      else
00239      {
00240        if (Is_user_requested_srp() && Is_usb_id_device())
00241        {
00242          // User has requested a SRP
00243          Ack_user_request_srp();
00244          if (!Is_srp_sent_and_waiting_answer())
00245          {
00246            Pll_start_auto();  // reinit device mode
00247            Wait_pll_ready();
00248            Usb_disable();
00249            Usb_enable_uid_pin();
00250            Usb_enable();
00251            Usb_unfreeze_clock();
00252            Usb_select_device();
00253            Usb_attach();
00254            otg_b_device_state = B_SRP_INIT;
00255            Usb_device_initiate_srp();       // hardware waits for initial condition (SE0, Session End level)
00256            sof_seen_in_session = FALSE;
00257          }
00258        }
00259        if ((Is_srp_sent_and_waiting_answer()) && (Is_tb_srp_counter_overflow()))
00260        {
00261          // SRP failed because A-Device did not respond
00262          End_session_with_srp();
00263          Ack_srp_sent_and_answer();
00264          Otg_print_new_failure_message(OTGMSG_SRP_A_NO_RESP,OTG_TEMPO_3SEC);
00265        }
00266      }
00267      break;
00268 
00269      
00270    //------------------------------------------------------
00271    //   B_SRP_INIT
00272    //
00273    //   - a SRP has been initiated
00274    //   - B-Device waits it is finished to initialize variables
00275    //
00276    case B_SRP_INIT:
00277      if (!Is_usb_device_initiating_srp())
00278      {
00279        otg_b_device_state = B_IDLE;   // SRP initiated, return to Idle state (wait for Vbus to rise)
00280        Srp_sent_and_waiting_answer();
00281        Init_tb_srp_counter();
00282        Start_session_with_srp();
00283        Otg_print_new_event_message(OTGMSG_SRP_STARTED,TB_SRP_FAIL_MIN);
00284      }
00285      break;
00286 
00287      
00288    //------------------------------------------------------
00289      //   B_PERIPHERAL : the main state of OTG Peripheral
00290    //
00291    //   - all events are interrupt-handled
00292    //   - but they are saved and this function can execute alternate actions
00293    //   - also handle user requests (disconnect)
00294    //
00295    // ======================================================================================
00296    case B_PERIPHERAL:
00297      if (Is_otg_event(EVT_OTG_DEVICE_CONNECTED))
00298      {
00299        Otg_ack_event(EVT_OTG_DEVICE_CONNECTED); // set on a SetConfiguration descriptor reception
00300        Otg_print_new_event_message(OTGMSG_CONNECTED_TO_A,OTG_TEMPO_4SEC);
00301      }
00302      if (Is_usb_event(EVT_USB_SUSPEND)) // SUSPEND state
00303      {
00304         // Suspend and HNP operations are handled in the interrupt functions
00305      }
00306      if (Is_srp_sent_and_waiting_answer() && (sof_seen_in_session == TRUE))
00307      {
00308        Ack_srp_sent_and_answer();
00309        Otg_print_new_failure_message(OTGMSG_A_RESPONDED,OTG_TEMPO_2SEC);
00310      }
00311      if ((Is_srp_sent_and_waiting_answer()) && (Is_tb_srp_counter_overflow())) 
00312      {
00313        // SRP failed because A-Device did not respond
00314        End_session_with_srp();
00315        Ack_srp_sent_and_answer();
00316        Otg_print_new_failure_message(OTGMSG_SRP_A_NO_RESP,OTG_TEMPO_3SEC);
00317      }
00318      
00319      if (Is_usb_event(EVT_USB_RESUME) && !Is_usb_pending_remote_wake_up())  // RESUME signal detected
00320      {
00321        Usb_ack_event(EVT_USB_RESUME);
00322        Usb_ack_event(EVT_USB_SUSPEND);
00323        Usb_ack_remote_wake_up_start();
00324      }
00325      if (Is_usb_event(EVT_USB_UNPOWERED))
00326      {
00327        Usb_ack_event(EVT_USB_UNPOWERED);
00328        Clear_all_user_request();
00329        otg_b_device_state = B_IDLE;
00330      }
00331      if(Is_usb_event(EVT_USB_RESET))
00332      {
00333        Usb_ack_event(EVT_USB_RESET);
00334        Usb_reset_endpoint(0);
00335        usb_configuration_nb=0;
00336        Clear_otg_features_from_host();
00337      }
00338      if (Is_otg_event(EVT_OTG_HNP_ERROR))
00339      {
00340        Otg_ack_event(EVT_OTG_HNP_ERROR);
00341        Otg_print_new_failure_message(OTGMSG_DEVICE_NO_RESP,OTG_TEMPO_4SEC);
00342        PORTC &= ~0x10;
00343      }
00344      if (Is_user_requested_disc())
00345      {
00346        Ack_user_request_disc();
00347        if (Is_usb_id_device())
00348        {
00349          Usb_detach();
00350          Usb_freeze_clock();
00351          while (Is_usb_vbus_high());  // wait for Vbus to be under Va_vbus_valid
00352          otg_b_device_state = B_IDLE;
00353          usb_configuration_nb = 0;
00354          usb_connected = FALSE;
00355          Clear_all_user_request();
00356        }
00357      }
00358      break;
00359 
00360    //------------------------------------------------------
00361    //   B_HOST
00362    //
00363    //   - state entered after an HNP success
00364    //   - handle user requests (disconnection, suspend, hnp)
00365    //   - call the "host_task()" for Host level handlers
00366    //
00367    // ======================================================================================
00368    case B_HOST:
00369      if (Is_otg_event(EVT_OTG_DEV_UNSUPPORTED))
00370      {
00371        Otg_ack_event(EVT_OTG_DEV_UNSUPPORTED);
00372        Clear_all_user_request();
00373        otg_b_device_state = B_IDLE;
00374        device_state = DEVICE_UNATTACHED;
00375      }
00376      if (Is_user_requested_disc() || Is_user_requested_suspend() || Is_user_requested_hnp())
00377      {
00378        Ack_user_request_disc();   // suspend and hnp requests cleared in B_END_HNP_SUSPEND stage
00379        Host_disable_sof();        // go into suspend mode
00380        Usb_host_reject_hnp();
00381        otg_b_device_state = B_END_HNP_SUSPEND;
00382        Usb_ack_suspend();
00383        Usb_enable_suspend_interrupt();
00384      }
00385      if (Is_usb_event(EVT_USB_UNPOWERED))
00386      {
00387        Usb_ack_event(EVT_USB_UNPOWERED);
00388        Usb_freeze_clock();
00389        otg_b_device_state = B_IDLE;
00390        device_state = DEVICE_UNATTACHED;
00391      }
00392      usb_host_task();   // call the host task
00393      break;
00394 
00395    //------------------------------------------------------
00396    //   B_END_HNP_SUSPEND
00397    //
00398    //   - device enters this state after being B_HOST, on a user request to stop bus activity (suspend, disconnect or hnp request)
00399    //   - macro is reset to peripheral mode
00400    //
00401    // ======================================================================================
00402    case B_END_HNP_SUSPEND:
00403      if (Is_usb_event(EVT_USB_SUSPEND))
00404      {
00405        Usb_ack_event(EVT_USB_SUSPEND);
00406        Usb_device_stop_hnp();
00407        Usb_select_device();
00408        device_state = DEVICE_UNATTACHED;
00409        if (Is_user_requested_hnp() || Is_user_requested_suspend())
00410        {
00411          otg_b_device_state = B_PERIPHERAL;
00412          Ack_user_request_suspend();
00413          Ack_user_request_hnp();
00414        }
00415        else
00416        {
00417          otg_b_device_state = B_IDLE;
00418          Usb_detach();
00419          Usb_freeze_clock();
00420        }
00421      }
00422      break;
00423 
00424 
00425    default:
00426      otg_b_device_state = B_IDLE;
00427      Clear_all_user_request();
00428      device_state = DEVICE_UNATTACHED;
00429      break;
00430    }
00431 
00432 
00433 #else
00434    
00435    // Non-OTG exclusives Device operations
00436 
00437    // VBUS state detection
00438    if (Is_usb_vbus_high()&& (usb_connected==FALSE))
00439    {
00440       usb_connected = TRUE;
00441       remote_wakeup_feature = DISABLED;
00442       Usb_vbus_on_action();
00443       Usb_send_event(EVT_USB_POWERED);
00444       usb_start_device();
00445    }
00446    if (Is_usb_vbus_low()&& (usb_connected==TRUE))
00447    {
00448       usb_connected = FALSE;
00449       usb_configuration_nb = 0;
00450       Usb_send_event(EVT_USB_UNPOWERED);
00451       Usb_detach();
00452       Usb_freeze_clock();
00453       Usb_vbus_off_action();
00454    }
00455 
00456    if(Is_usb_event(EVT_USB_RESET))
00457    {
00458       Usb_ack_event(EVT_USB_RESET);
00459       Usb_reset_endpoint(0);
00460       usb_configuration_nb=0;
00461    }
00462 
00463 #endif
00464 
00465    
00466    
00467    // =======================================
00468    // Common Standard Device Control Requests
00469    // =======================================
00470    //   - device enumeration process
00471    //   - device control commands and features
00472    Usb_select_endpoint(EP_CONTROL);
00473    if (Is_usb_receive_setup())
00474    {
00475       usb_process_request();
00476    }
00477 }

Generated on Fri May 15 15:41:36 2009 for ATMEL by  doxygen 1.5.3