Exemplo n.º 1
0
//------------------------------------------------------------------------------
/// Entry point of the USB mamnagement
/// Depending on the USB mode supported (HOST/DEVICE/DUAL_ROLE) the function
/// calls the coresponding USB management function
//------------------------------------------------------------------------------
void usb_task(void)
{
    // DUAL ROLE DEVICE USB MODE
    if(Is_usb_id_device()) {
        g_usb_mode = USB_MODE_DEVICE;
    }
    else {
        g_usb_mode = USB_MODE_HOST;
    }
    g_old_usb_mode = g_usb_mode;   // Store current usb mode, for mode change detection
    // Depending on current usb mode, launch the correct usb task (device or host)

    // Configure OTG timers
    Set_otg_custom_timer(VBUSRISE_70MS);
    Set_otg_custom_timer(VBUSPULSE_40MS);
    Set_otg_custom_timer(VFALLTMOUT_131MS);
    Set_otg_custom_timer(SRPMINDET_100US);
   
    switch(g_usb_mode) {
        case USB_MODE_DEVICE:
            //usb_device_task();
            //MSDDriver_StateMachine();
            Scheduler_task_3();
            break;

        case USB_MODE_HOST:
          if( pOTGDescriptor->bOTGADevSRPReaction == VBUS_PULSE) {
            Usb_select_vbus_srp_method();
          }
          else {
            Usb_select_data_srp_method();
          }
            usb_host_task();
            // Handle Vbus overcurrent error (auto-disabled if not supported or not defined in board driver file)
            if (Is_vbus_overcurrent()) {
                Otg_print_new_event_message(OTGMSG_VBUS_SURCHARGE,OTG_TEMPO_3SEC);
            }
            break;

        case USB_MODE_UNDEFINED:  // No break !
            default:
            break;
    }
    Otg_message_task();
}
Exemplo n.º 2
0
//! @brief Entry point of the USB device mamagement
//!
//! This function is the entry point of the USB management. Each USB
//! event is checked here in order to launch the appropriate action.
//! If a Setup request occurs on the Default Control Endpoint,
//! the usb_process_request() function is call in the usb_standard_request.c file
//!
//! @param none
//!
//! @return none
void usb_device_task(void)
{
  
#if (USB_OTG_FEATURE == ENABLED)
   // Check if a reset has been received
   if(Is_usb_event(EVT_USB_RESET))
   {
      Usb_ack_event(EVT_USB_RESET);
      Usb_reset_endpoint(0);
      usb_configuration_nb=0;
      otg_b_device_state = B_IDLE;
      Clear_otg_features_from_host();
   }

   // When OTG mode enabled, B-Device is managed thanks to its state machine
   switch (otg_b_device_state)
   {
   //------------------------------------------------------
   //   B_IDLE state
   //
   //   - waits for Vbus to rise
   //   - initiate SRP if asked by user
   //
   case B_IDLE:
     if (Is_usb_vbus_high())
     {
       // Vbus rise
       usb_connected = TRUE;
       remote_wakeup_feature = DISABLED;
       usb_start_device();
       Usb_vbus_on_action();
       Usb_attach();
       otg_b_device_state = B_PERIPHERAL;
       Ack_user_request_srp();
       Clear_otg_features_from_host();
       remote_wakeup_feature = DISABLED;
       End_session_with_srp();
       if (Is_srp_sent_and_waiting_answer() && (sof_seen_in_session == TRUE))
       {
         Ack_srp_sent_and_answer();
         Otg_print_new_failure_message(OTGMSG_A_RESPONDED,OTG_TEMPO_2SEC);
       }
       Usb_enable_sof_interrupt();
       
     }
     else
     {
       if (Is_user_requested_srp() && Is_usb_id_device())
       {
         // User has requested a SRP
         Ack_user_request_srp();
         if (!Is_srp_sent_and_waiting_answer())
         {
           Pll_start_auto();  // reinit device mode
           Wait_pll_ready();
           Usb_disable();
           Usb_enable_uid_pin();
           Usb_enable();
           Usb_unfreeze_clock();
           Usb_select_device();
           Usb_attach();
           otg_b_device_state = B_SRP_INIT;
           Usb_device_initiate_srp();       // hardware waits for initial condition (SE0, Session End level)
           sof_seen_in_session = FALSE;
         }
       }
       if ((Is_srp_sent_and_waiting_answer()) && (Is_tb_srp_counter_overflow()))
       {
         // SRP failed because A-Device did not respond
         End_session_with_srp();
         Ack_srp_sent_and_answer();
         Otg_print_new_failure_message(OTGMSG_SRP_A_NO_RESP,OTG_TEMPO_3SEC);
       }
     }
     break;

     
   //------------------------------------------------------
   //   B_SRP_INIT
   //
   //   - a SRP has been initiated
   //   - B-Device waits it is finished to initialize variables
   //
   case B_SRP_INIT:
     if (!Is_usb_device_initiating_srp())
     {
       otg_b_device_state = B_IDLE;   // SRP initiated, return to Idle state (wait for Vbus to rise)
       Srp_sent_and_waiting_answer();
       Init_tb_srp_counter();
       Start_session_with_srp();
       Otg_print_new_event_message(OTGMSG_SRP_STARTED,TB_SRP_FAIL_MIN);
     }
     break;

     
   //------------------------------------------------------
     //   B_PERIPHERAL : the main state of OTG Peripheral
   //
   //   - all events are interrupt-handled
   //   - but they are saved and this function can execute alternate actions
   //   - also handle user requests (disconnect)
   //
   // ======================================================================================
   case B_PERIPHERAL:
     if (Is_otg_event(EVT_OTG_DEVICE_CONNECTED))
     {
       Otg_ack_event(EVT_OTG_DEVICE_CONNECTED); // set on a SetConfiguration descriptor reception
       Otg_print_new_event_message(OTGMSG_CONNECTED_TO_A,OTG_TEMPO_4SEC);
     }
     if (Is_usb_event(EVT_USB_SUSPEND)) // SUSPEND state
     {
        // Suspend and HNP operations are handled in the interrupt functions
     }
     if (Is_srp_sent_and_waiting_answer() && (sof_seen_in_session == TRUE))
     {
       Ack_srp_sent_and_answer();
       Otg_print_new_failure_message(OTGMSG_A_RESPONDED,OTG_TEMPO_2SEC);
     }
     if ((Is_srp_sent_and_waiting_answer()) && (Is_tb_srp_counter_overflow())) 
     {
       // SRP failed because A-Device did not respond
       End_session_with_srp();
       Ack_srp_sent_and_answer();
       Otg_print_new_failure_message(OTGMSG_SRP_A_NO_RESP,OTG_TEMPO_3SEC);
     }
     
     if (Is_usb_event(EVT_USB_RESUME) && !Is_usb_pending_remote_wake_up())  // RESUME signal detected
     {
       Usb_ack_event(EVT_USB_RESUME);
       Usb_ack_event(EVT_USB_SUSPEND);
       Usb_ack_remote_wake_up_start();
     }
     if (Is_usb_event(EVT_USB_UNPOWERED))
     {
       Usb_ack_event(EVT_USB_UNPOWERED);
       Clear_all_user_request();
       otg_b_device_state = B_IDLE;
     }
     if(Is_usb_event(EVT_USB_RESET))
     {
       Usb_ack_event(EVT_USB_RESET);
       Usb_reset_endpoint(0);
       usb_configuration_nb=0;
       Clear_otg_features_from_host();
     }
     if (Is_otg_event(EVT_OTG_HNP_ERROR))
     {
       Otg_ack_event(EVT_OTG_HNP_ERROR);
       Otg_print_new_failure_message(OTGMSG_DEVICE_NO_RESP,OTG_TEMPO_4SEC);
       PORTC &= ~0x10;
     }
     if (Is_user_requested_disc())
     {
       Ack_user_request_disc();
       if (Is_usb_id_device())
       {
         Usb_detach();
         Usb_freeze_clock();
         while (Is_usb_vbus_high());  // wait for Vbus to be under Va_vbus_valid
         otg_b_device_state = B_IDLE;
         usb_configuration_nb = 0;
         usb_connected = FALSE;
         Clear_all_user_request();
       }
     }
     break;

   //------------------------------------------------------
   //   B_HOST
   //
   //   - state entered after an HNP success
   //   - handle user requests (disconnection, suspend, hnp)
   //   - call the "host_task()" for Host level handlers
   //
   // ======================================================================================
   case B_HOST:
     if (Is_otg_event(EVT_OTG_DEV_UNSUPPORTED))
     {
       Otg_ack_event(EVT_OTG_DEV_UNSUPPORTED);
       Clear_all_user_request();
       otg_b_device_state = B_IDLE;
       device_state = DEVICE_UNATTACHED;
     }
     if (Is_user_requested_disc() || Is_user_requested_suspend() || Is_user_requested_hnp())
     {
       Ack_user_request_disc();   // suspend and hnp requests cleared in B_END_HNP_SUSPEND stage
       Host_disable_sof();        // go into suspend mode
       Usb_host_reject_hnp();
       otg_b_device_state = B_END_HNP_SUSPEND;
       Usb_ack_suspend();
       Usb_enable_suspend_interrupt();
     }
     if (Is_usb_event(EVT_USB_UNPOWERED))
     {
       Usb_ack_event(EVT_USB_UNPOWERED);
       Usb_freeze_clock();
       otg_b_device_state = B_IDLE;
       device_state = DEVICE_UNATTACHED;
     }
     usb_host_task();   // call the host task
     break;

   //------------------------------------------------------
   //   B_END_HNP_SUSPEND
   //
   //   - device enters this state after being B_HOST, on a user request to stop bus activity (suspend, disconnect or hnp request)
   //   - macro is reset to peripheral mode
   //
   // ======================================================================================
   case B_END_HNP_SUSPEND:
     if (Is_usb_event(EVT_USB_SUSPEND))
     {
       Usb_ack_event(EVT_USB_SUSPEND);
       Usb_device_stop_hnp();
       Usb_select_device();
       device_state = DEVICE_UNATTACHED;
       if (Is_user_requested_hnp() || Is_user_requested_suspend())
       {
         otg_b_device_state = B_PERIPHERAL;
         Ack_user_request_suspend();
         Ack_user_request_hnp();
       }
       else
       {
         otg_b_device_state = B_IDLE;
         Usb_detach();
         Usb_freeze_clock();
       }
     }
     break;


   default:
     otg_b_device_state = B_IDLE;
     Clear_all_user_request();
     device_state = DEVICE_UNATTACHED;
     break;
   }


#else
   
   // Non-OTG exclusives Device operations

   // VBUS state detection
   if (Is_usb_vbus_high()&& (usb_connected==FALSE))
   {
      usb_connected = TRUE;
      remote_wakeup_feature = DISABLED;
      Usb_vbus_on_action();
      Usb_send_event(EVT_USB_POWERED);
      usb_start_device();
   }
   if (Is_usb_vbus_low()&& (usb_connected==TRUE))
   {
      usb_connected = FALSE;
      usb_configuration_nb = 0;
      Usb_send_event(EVT_USB_UNPOWERED);
      Usb_detach();
      Usb_freeze_clock();
      Usb_vbus_off_action();
   }

   if(Is_usb_event(EVT_USB_RESET))
   {
      Usb_ack_event(EVT_USB_RESET);
      Usb_reset_endpoint(0);
      usb_configuration_nb=0;
   }

#endif

   
   
   // =======================================
   // Common Standard Device Control Requests
   // =======================================
   //   - device enumeration process
   //   - device control commands and features
   Usb_select_endpoint(EP_CONTROL);
   if (Is_usb_receive_setup())
   {
      usb_process_request();
   }
}