usb_device_task.c

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

Generated on Mon Sep 14 13:51:27 2009 for ATMEL by  doxygen 1.5.3