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 AND FITNESS FOR A PARTICULAR PURPOSE 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    Usb_unfreeze_clock();
00170    usb_init_device();         // configure the USB controller EP0
00171    Usb_attach();
00172    Usb_enable_suspend_interrupt();
00173    Usb_enable_reset_interrupt();
00174 #if (USB_OTG_FEATURE == ENABLED)
00175    Usb_enable_id_interrupt();
00176 #endif
00177 }
00178 
00189 void usb_device_task(void)
00190 {
00191   
00192 #if (USB_OTG_FEATURE == ENABLED)
00193    // Check if a reset has been received
00194    if(Is_usb_event(EVT_USB_RESET))
00195    {
00196       Usb_ack_event(EVT_USB_RESET);
00197       Usb_reset_endpoint(0);
00198       usb_configuration_nb=0;
00199       otg_b_device_state = B_IDLE;
00200       Clear_otg_features_from_host();
00201    }
00202 
00203    // When OTG mode enabled, B-Device is managed thanks to its state machine
00204    switch (otg_b_device_state)
00205    {
00206    //------------------------------------------------------
00207    //   B_IDLE state
00208    //
00209    //   - waits for Vbus to rise
00210    //   - initiate SRP if asked by user
00211    //
00212    case B_IDLE:
00213      if (Is_usb_vbus_high())
00214      {
00215        // Vbus rise
00216        usb_connected = TRUE;
00217        remote_wakeup_feature = DISABLED;
00218        usb_start_device();
00219        Usb_vbus_on_action();
00220        Usb_attach();
00221        otg_b_device_state = B_PERIPHERAL;
00222        Ack_user_request_srp();
00223        Clear_otg_features_from_host();
00224        remote_wakeup_feature = DISABLED;
00225        End_session_with_srp();
00226        if (Is_srp_sent_and_waiting_answer() && (sof_seen_in_session == TRUE))
00227        {
00228          Ack_srp_sent_and_answer();
00229          Otg_print_new_failure_message(OTGMSG_A_RESPONDED,OTG_TEMPO_2SEC);
00230        }
00231        Usb_enable_sof_interrupt();
00232        
00233      }
00234      else
00235      {
00236        if (Is_user_requested_srp() && Is_usb_id_device())
00237        {
00238          // User has requested a SRP
00239          Ack_user_request_srp();
00240          if (!Is_srp_sent_and_waiting_answer())
00241          {
00242            Pll_start_auto();  // reinit device mode
00243            Wait_pll_ready();
00244            Usb_disable();
00245            Usb_enable_uid_pin();
00246            Usb_enable();
00247            Usb_unfreeze_clock();
00248            Usb_select_device();
00249            Usb_attach();
00250            otg_b_device_state = B_SRP_INIT;
00251            Usb_device_initiate_srp();       // hardware waits for initial condition (SE0, Session End level)
00252            sof_seen_in_session = FALSE;
00253          }
00254        }
00255        if ((Is_srp_sent_and_waiting_answer()) && (Is_tb_srp_counter_overflow()))
00256        {
00257          // SRP failed because A-Device did not respond
00258          End_session_with_srp();
00259          Ack_srp_sent_and_answer();
00260          Otg_print_new_failure_message(OTGMSG_SRP_A_NO_RESP,OTG_TEMPO_3SEC);
00261        }
00262      }
00263      break;
00264 
00265      
00266    //------------------------------------------------------
00267    //   B_SRP_INIT
00268    //
00269    //   - a SRP has been initiated
00270    //   - B-Device waits it is finished to initialize variables
00271    //
00272    case B_SRP_INIT:
00273      if (!Is_usb_device_initiating_srp())
00274      {
00275        otg_b_device_state = B_IDLE;   // SRP initiated, return to Idle state (wait for Vbus to rise)
00276        Srp_sent_and_waiting_answer();
00277        Init_tb_srp_counter();
00278        Start_session_with_srp();
00279        Otg_print_new_event_message(OTGMSG_SRP_STARTED,TB_SRP_FAIL_MIN);
00280      }
00281      break;
00282 
00283      
00284    //------------------------------------------------------
00285      //   B_PERIPHERAL : the main state of OTG Peripheral
00286    //
00287    //   - all events are interrupt-handled
00288    //   - but they are saved and this function can execute alternate actions
00289    //   - also handle user requests (disconnect)
00290    //
00291    // ======================================================================================
00292    case B_PERIPHERAL:
00293      if (Is_otg_event(EVT_OTG_DEVICE_CONNECTED))
00294      {
00295        Otg_ack_event(EVT_OTG_DEVICE_CONNECTED); // set on a SetConfiguration descriptor reception
00296        Otg_print_new_event_message(OTGMSG_CONNECTED_TO_A,OTG_TEMPO_4SEC);
00297      }
00298      if (Is_usb_event(EVT_USB_SUSPEND)) // SUSPEND state
00299      {
00300         // Suspend and HNP operations are handled in the interrupt functions
00301      }
00302      if (Is_srp_sent_and_waiting_answer() && (sof_seen_in_session == TRUE))
00303      {
00304        Ack_srp_sent_and_answer();
00305        Otg_print_new_failure_message(OTGMSG_A_RESPONDED,OTG_TEMPO_2SEC);
00306      }
00307      if ((Is_srp_sent_and_waiting_answer()) && (Is_tb_srp_counter_overflow())) 
00308      {
00309        // SRP failed because A-Device did not respond
00310        End_session_with_srp();
00311        Ack_srp_sent_and_answer();
00312        Otg_print_new_failure_message(OTGMSG_SRP_A_NO_RESP,OTG_TEMPO_3SEC);
00313      }
00314      
00315      if (Is_usb_event(EVT_USB_RESUME) && !Is_usb_pending_remote_wake_up())  // RESUME signal detected
00316      {
00317        Usb_ack_event(EVT_USB_RESUME);
00318        Usb_ack_event(EVT_USB_SUSPEND);
00319        Usb_ack_remote_wake_up_start();
00320      }
00321      if (Is_usb_event(EVT_USB_UNPOWERED))
00322      {
00323        Usb_ack_event(EVT_USB_UNPOWERED);
00324        Clear_all_user_request();
00325        otg_b_device_state = B_IDLE;
00326      }
00327      if(Is_usb_event(EVT_USB_RESET))
00328      {
00329        Usb_ack_event(EVT_USB_RESET);
00330        Usb_reset_endpoint(0);
00331        usb_configuration_nb=0;
00332        Clear_otg_features_from_host();
00333      }
00334      if (Is_otg_event(EVT_OTG_HNP_ERROR))
00335      {
00336        Otg_ack_event(EVT_OTG_HNP_ERROR);
00337        Otg_print_new_failure_message(OTGMSG_DEVICE_NO_RESP,OTG_TEMPO_4SEC);
00338        PORTC &= ~0x10;
00339      }
00340      if (Is_user_requested_disc())
00341      {
00342        Ack_user_request_disc();
00343        if (Is_usb_id_device())
00344        {
00345          Usb_detach();
00346          Usb_freeze_clock();
00347          while (Is_usb_vbus_high());  // wait for Vbus to be under Va_vbus_valid
00348          otg_b_device_state = B_IDLE;
00349          usb_configuration_nb = 0;
00350          usb_connected = FALSE;
00351          Clear_all_user_request();
00352        }
00353      }
00354      break;
00355 
00356    //------------------------------------------------------
00357    //   B_HOST
00358    //
00359    //   - state entered after an HNP success
00360    //   - handle user requests (disconnection, suspend, hnp)
00361    //   - call the "host_task()" for Host level handlers
00362    //
00363    // ======================================================================================
00364    case B_HOST:
00365      if (Is_otg_event(EVT_OTG_DEV_UNSUPPORTED))
00366      {
00367        Otg_ack_event(EVT_OTG_DEV_UNSUPPORTED);
00368        Clear_all_user_request();
00369        otg_b_device_state = B_IDLE;
00370        device_state = DEVICE_UNATTACHED;
00371      }
00372      if (Is_user_requested_disc() || Is_user_requested_suspend() || Is_user_requested_hnp())
00373      {
00374        Ack_user_request_disc();   // suspend and hnp requests cleared in B_END_HNP_SUSPEND stage
00375        Host_disable_sof();        // go into suspend mode
00376        Usb_host_reject_hnp();
00377        otg_b_device_state = B_END_HNP_SUSPEND;
00378        Usb_ack_suspend();
00379        Usb_enable_suspend_interrupt();
00380      }
00381      if (Is_usb_event(EVT_USB_UNPOWERED))
00382      {
00383        Usb_ack_event(EVT_USB_UNPOWERED);
00384        Usb_freeze_clock();
00385        otg_b_device_state = B_IDLE;
00386        device_state = DEVICE_UNATTACHED;
00387      }
00388      usb_host_task();   // call the host task
00389      break;
00390 
00391    //------------------------------------------------------
00392    //   B_END_HNP_SUSPEND
00393    //
00394    //   - device enters this state after being B_HOST, on a user request to stop bus activity (suspend, disconnect or hnp request)
00395    //   - macro is reset to peripheral mode
00396    //
00397    // ======================================================================================
00398    case B_END_HNP_SUSPEND:
00399      if (Is_usb_event(EVT_USB_SUSPEND))
00400      {
00401        Usb_ack_event(EVT_USB_SUSPEND);
00402        Usb_device_stop_hnp();
00403        Usb_select_device();
00404        device_state = DEVICE_UNATTACHED;
00405        if (Is_user_requested_hnp() || Is_user_requested_suspend())
00406        {
00407          otg_b_device_state = B_PERIPHERAL;
00408          Ack_user_request_suspend();
00409          Ack_user_request_hnp();
00410        }
00411        else
00412        {
00413          otg_b_device_state = B_IDLE;
00414          Usb_detach();
00415          Usb_freeze_clock();
00416        }
00417      }
00418      break;
00419 
00420 
00421    default:
00422      otg_b_device_state = B_IDLE;
00423      Clear_all_user_request();
00424      device_state = DEVICE_UNATTACHED;
00425      break;
00426    }
00427 
00428 
00429 #else
00430    
00431    // Non-OTG exclusives Device operations
00432 
00433    // VBUS state detection
00434    if (Is_usb_vbus_high()&& (usb_connected==FALSE))
00435    {
00436       usb_connected = TRUE;
00437       remote_wakeup_feature = DISABLED;
00438       Usb_vbus_on_action();
00439       Usb_send_event(EVT_USB_POWERED);
00440       usb_start_device();
00441    }
00442    if (Is_usb_vbus_low()&& (usb_connected==TRUE))
00443    {
00444       usb_connected = FALSE;
00445       usb_configuration_nb = 0;
00446       Usb_send_event(EVT_USB_UNPOWERED);
00447       Usb_freeze_clock();
00448       Usb_vbus_off_action();
00449    }
00450 
00451    if(Is_usb_event(EVT_USB_RESET))
00452    {
00453       Usb_ack_event(EVT_USB_RESET);
00454       Usb_reset_endpoint(0);
00455       usb_configuration_nb=0;
00456    }
00457 
00458 #endif
00459 
00460    
00461    
00462    // =======================================
00463    // Common Standard Device Control Requests
00464    // =======================================
00465    //   - device enumeration process
00466    //   - device control commands and features
00467    Usb_select_endpoint(EP_CONTROL);
00468    if (Is_usb_receive_setup())
00469    {
00470       usb_process_request();
00471    }
00472 }

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