示例#1
0
/**
 * @brief This function initializes the USB controller in host mode and
 *        the associated variables.
 *
 * This function enables the USB controller for host mode operation.
 *
 * @param none
 *
 * @return none
 *
 */
void usb_host_task_init(void)
{
   Pll_start_auto();
   Wait_pll_ready();
   Usb_disable();
   Usb_enable();
   Usb_unfreeze_clock();
   Usb_attach();
   Usb_enable_uvcon_pin();
   Usb_select_host();
   Usb_disable_vbus_hw_control();   // Force Vbus generation without timeout
   Host_enable_device_disconnection_interrupt();
   device_state=DEVICE_UNATTACHED;
   init_usb_tree();
}
示例#2
0
__interrupt void usb_general_interrupt()
#endif
{
   #if (USB_HOST_PIPE_INTERRUPT_TRANSFER == ENABLE)
   U8 i;
   U8 save_pipe_nb;
   #endif
// ---------- DEVICE events management -----------------------------------
#if (USB_DEVICE_FEATURE == ENABLED)

   // - Device start of frame received
   if (Is_usb_sof() && Is_sof_interrupt_enabled())
   {
      Usb_ack_sof();
      Usb_sof_action();
   }
#ifdef WA_USB_SUSPEND_PERTUBATION
  // - Device Suspend event (no more USB activity detected)
   if (Is_usb_suspend() && Is_suspend_interrupt_enabled())
   {
      usb_suspended=TRUE;
      Usb_ack_wake_up();                 // clear wake up to detect next event
      Usb_send_event(EVT_USB_SUSPEND);
      Usb_ack_suspend();
      Usb_enable_wake_up_interrupt();
      Usb_disable_resume_interrupt();
      Usb_freeze_clock();
      Stop_pll();
      Usb_suspend_action();
   }
  // - Wake up event (USB activity detected): Used to resume
   if (Is_usb_wake_up() && Is_wake_up_interrupt_enabled())
   {
      if(Is_pll_ready()==FALSE)
      {
         Pll_start_auto();
         Wait_pll_ready();
      }
      Usb_unfreeze_clock();
      Usb_ack_wake_up();
      if(usb_suspended)
      {
         Usb_enable_resume_interrupt();
         Usb_enable_reset_interrupt();
         while(Is_usb_wake_up())
         {
            Usb_ack_wake_up();
         }
         usb_delay_ms(2);
         if(Is_usb_sof() || Is_usb_resume() || Is_usb_reset() )
         {
            Usb_disable_wake_up_interrupt();
            Usb_wake_up_action();
            Usb_send_event(EVT_USB_WAKE_UP);
            Usb_enable_suspend_interrupt();
            Usb_enable_resume_interrupt();
            Usb_enable_reset_interrupt();
            
         }
         else // Workarround to make the USB enter power down mode again (spurious transcient detected on the USB lines)
         {
            Usb_ack_wake_up();                 // clear wake up to detect next event
            Usb_send_event(EVT_USB_SUSPEND);
            Usb_enable_wake_up_interrupt();
            Usb_disable_resume_interrupt();
            Usb_freeze_clock();
            Stop_pll();
            Usb_suspend_action();
         }
      }
   }
  // - Resume state bus detection
   if (Is_usb_resume() && Is_resume_interrupt_enabled())
   {
      usb_suspended = FALSE;
      Usb_disable_wake_up_interrupt();
      Usb_ack_resume();
      Usb_disable_resume_interrupt();
      Usb_resume_action();
      Usb_send_event(EVT_USB_RESUME);
   }
#else
  // - Device Suspend event (no more USB activity detected)
   if (Is_usb_suspend() && Is_suspend_interrupt_enabled())
   {
      // Remote wake-up handler
      if ((remote_wakeup_feature == ENABLED) && (usb_configuration_nb != 0))
      {
        Usb_disable_suspend_interrupt();
        Usb_ack_wake_up();
        Usb_enable_wake_up_interrupt();
        Stop_pll();
        Usb_freeze_clock();
        Usb_suspend_action();
        
        // After that user can execute "Usb_initiate_remote_wake_up()" to initiate a remote wake-up
        // Note that the suspend interrupt flag SUSPI must still be set to enable upstream resume
        // So the SUSPE enable bit must be cleared to avoid redundant interrupt
        // ****************
        // Please note also that is Vbus is lost during an upstream resume (Host disconnection),
        // the RMWKUP bit (used to initiate remote wake up and that is normally cleared by hardware when sent)
        // remains set after the event, so that a good way to handle this feature is :
        //            Usb_unfreeze_clock();
        //            Usb_initiate_remote_wake_up();
        //            while (Is_usb_pending_remote_wake_up())
        //            {
        //              if (Is_usb_vbus_low())
        //              {
        //                // Emergency action (reset macro, etc.) if Vbus lost during resuming
        //                break;
        //              }
        //            }
        //            Usb_ack_remote_wake_up_start();
        // ****************
      }
      else
      {
        // No remote wake-up supported
         Usb_ack_wake_up();                 // clear wake up to detect next event
         Usb_send_event(EVT_USB_SUSPEND);
         Usb_ack_suspend();  // must be executed last (after Usb_suspend_action()) to allow upstream resume
         Usb_enable_wake_up_interrupt();
         Usb_freeze_clock();
         Stop_pll();
         Usb_suspend_action();
      }
   }
  // - Wake up event (USB activity detected): Used to resume
   if (Is_usb_wake_up() && Is_wake_up_interrupt_enabled())
   {
      if(Is_pll_ready()==FALSE)
      {
         Pll_start_auto();
         Wait_pll_ready();
      }
      Usb_unfreeze_clock();
      Usb_ack_wake_up();
      Usb_disable_wake_up_interrupt();
      Usb_wake_up_action();
      Usb_send_event(EVT_USB_WAKE_UP);
      Usb_enable_suspend_interrupt();
   }
  // - Resume state bus detection
   if (Is_usb_resume() && Is_resume_interrupt_enabled())
   {
      Usb_disable_wake_up_interrupt();
      Usb_ack_resume();
      Usb_disable_resume_interrupt();
      Usb_resume_action();
      Usb_send_event(EVT_USB_RESUME);
   }
#endif
  // - USB bus reset detection
   if (Is_usb_reset()&& Is_reset_interrupt_enabled())
   {
      Usb_ack_reset();
      usb_init_device();
      Usb_reset_action();
      Usb_send_event(EVT_USB_RESET);
   }
#endif// End DEVICE FEATURE MODE

// ---------- HOST events management -----------------------------------
#if (USB_HOST_FEATURE == ENABLED && USB_DEVICE_FEATURE == ENABLED)
  // - ID pin change detection
   if(Is_usb_id_transition()&&Is_usb_id_interrupt_enabled())
   {
      if(Is_usb_id_device())
      { g_usb_mode=USB_MODE_DEVICE;}
      else
      { g_usb_mode=USB_MODE_HOST;}
      Usb_ack_id_transition();
      if( g_usb_mode != g_old_usb_mode) // Basic Debounce
      {
         if(Is_usb_id_device()) // Going to device mode
         {
            Usb_send_event(EVT_USB_DEVICE_FUNCTION);
         }
         else                   // Going to host mode
         {
            Usb_send_event(EVT_USB_HOST_FUNCTION);
         }
         Usb_id_transition_action();
         LOG_STR_CODE(log_id_change);
         #if ( ID_PIN_CHANGE_GENERATE_RESET == ENABLE)
         // Hot ID transition generates wdt reset
         wdtdrv_enable(WDTO_16MS);
         while(1);
         #endif
      }
   }
#endif
#if (USB_HOST_FEATURE == ENABLED)
  // - The device has been disconnected
   if(Is_device_disconnection() && Is_host_device_disconnection_interrupt_enabled())
   {
      host_disable_all_pipe();
      Host_ack_device_disconnection();
      device_state=DEVICE_DISCONNECTED;
      Usb_send_event(EVT_HOST_DISCONNECTION);
      init_usb_tree();      
      LOG_STR_CODE(log_device_disconnect);
      Host_device_disconnection_action();
   }
  // - Device connection
   if(Is_device_connection() && Is_host_device_connection_interrupt_enabled())
   {
      Host_ack_device_connection();
      host_disable_all_pipe();
      Host_device_connection_action();
   }
  // - Host Start of frame has been sent
   if (Is_host_sof() && Is_host_sof_interrupt_enabled())
   {
      Host_ack_sof();
      Usb_send_event(EVT_HOST_SOF);
      private_sof_counter++;
#if (USB_HUB_SUPPORT==ENABLE)
      hub_interrupt_sof++;
#endif

      // delay timeout management for interrupt tranfer mode in host mode
      #if ((USB_HOST_PIPE_INTERRUPT_TRANSFER==ENABLE) && (TIMEOUT_DELAY_ENABLE==ENABLE))
      if (private_sof_counter>=250)   // Count 1/4 sec
      {
         private_sof_counter=0;
         for(i=0;i<MAX_EP_NB;i++)
         {
            if(it_pipe_str[i].enable==ENABLE)
            {
               save_pipe_nb=Host_get_selected_pipe();
               Host_select_pipe(i);
               if((++it_pipe_str[i].timeout>TIMEOUT_DELAY) && (Host_get_pipe_type()!=TYPE_INTERRUPT))
               {
                  it_pipe_str[i].enable=DISABLE;
                  it_pipe_str[i].status=PIPE_DELAY_TIMEOUT;
                  Host_stop_pipe_interrupt(i);
                  if (is_any_interrupt_pipe_active()==FALSE)    // If no more transfer is armed
                  {
                     if (g_sav_int_sof_enable==FALSE)
                     {
                        Host_disable_sof_interrupt();
                     }
                  }
                  it_pipe_str[i].handle(PIPE_DELAY_TIMEOUT,it_pipe_str[i].nb_byte_processed);
               }
               Host_select_pipe(save_pipe_nb);
            }
         }
      }
      #endif  // (USB_HOST_PIPE_INTERRUPT_TRANSFER==ENABLE) && (TIMEOUT_DELAY_ENABLE==ENABLE))
      Host_sof_action();
   }
  // - Host Wake-up has been received
   if (Is_host_hwup() && Is_host_hwup_interrupt_enabled())
   {
      Host_disable_hwup_interrupt();  // Wake up interrupt should be disable host is now wake up !
      // CAUTION HWUP can be cleared only when USB clock is active (not frozen)!
      Pll_start_auto();               // First Restart the PLL for USB operation
      Wait_pll_ready();               // Get sure pll is lock
      Usb_unfreeze_clock();           // Enable clock on USB interface
      Host_ack_hwup();                // Clear HWUP interrupt flag
      Usb_send_event(EVT_HOST_HWUP);  // Send software event
      Host_hwup_action();             // Map custom action
   }
#endif // End HOST FEATURE MODE
}