Ejemplo n.º 1
0
/*!
 *  \brief Leave the USB Mass Storage mode while the USB host is plugged in.
 *
 */
bool b_supervisor_leave_UsbMassStorage_mode( void )
{
  Usb_detach();
  bIsInMaintenance = false;  // We're not in maintenance mode anymore.
  prv_v_leave_maintenance_mode();
  return (pdTRUE);
}
Ejemplo n.º 2
0
void
Jump_To_Bootloader(void)
{
  /* Disable all interrupts */
  cli();

#ifdef UDCON
  /* If USB is used, detach from the bus */
  Usb_detach();

  uint8_t i;

  /* Wait two seconds for the USB detachment to register on the host */
  for(i = 0; i < 200; i++) {
    _delay_ms(10);
    watchdog_periodic();
  }
#endif

  /* Set the bootloader key to the magic value and force a reset */
  Boot_Key = MAGIC_BOOT_KEY;

  eeprom_write_byte(EEPROM_MAGIC_BYTE_ADDR, 0xFF);

  /* Enable interrupts */
  sei();

  watchdog_reboot();
}
//! @brief Get data report from Host
//!
void hid_report_out(void)
{
  int led_number;
  int led_state;

   if(Is_usb_out_received(EP_HID_GENERIC_OUT))
   {
      Usb_reset_endpoint_fifo_access(EP_HID_GENERIC_OUT);
      memset(rxbuf, 0, RXBUF_SIZE);
      usb_read_ep_rxpacket(EP_HID_GENERIC_OUT, &rxbuf, RXBUF_SIZE, NULL);
      Usb_ack_out_received_free(EP_HID_GENERIC_OUT);
      // The Data has been read and stored in rxbuf

      led_state      = rxbuf[0]&0x0F; // RepportOUT[0] is LEDS value
      led_number     = rxbuf[1]&0x0F;
      switch (led_number)
      {
         case 1:
            if(led_state)
            {   gpio_clr_gpio_pin(LED0_GPIO);   }
            else { gpio_set_gpio_pin(LED0_GPIO);}
            break;
         case 2:
            if(led_state)
            {   gpio_clr_gpio_pin(LED1_GPIO);   }
            else { gpio_set_gpio_pin(LED1_GPIO);}
            break;
         case 3:
            if(led_state)
            {   gpio_clr_gpio_pin(LED2_GPIO);   }
            else { gpio_set_gpio_pin(LED2_GPIO);}
            break;
         case 4:
            if(led_state)
            {   gpio_clr_gpio_pin(LED3_GPIO);   }
            else { gpio_set_gpio_pin(LED3_GPIO);}
            break;
      }

   }

   //** Check if we received DFU mode command from host
   if(jump_bootloader)
   {
      uint32_t volatile tempo;
      gpio_set_gpio_pin(LED0_GPIO);
      gpio_set_gpio_pin(LED1_GPIO);
      gpio_set_gpio_pin(LED2_GPIO);
      gpio_set_gpio_pin(LED3_GPIO);
      Usb_detach();                          // Detach actual generic HID application
      for(tempo=0;tempo<70000;tempo++);      // Wait some time before
      //start_boot();                          // Jumping to bootloader
      while(1);
   }
}
Ejemplo n.º 4
0
/*! \brief Release a system mutex.
 *
 *  \param xSemaphore   A handle to the semaphore being released.
 *
 *  \return pdTRUE if the semaphore was released. pdFALSE if an error occurred.
 */
portBASE_TYPE x_supervisor_SemaphoreGive( xSemaphoreHandle xSemaphore )
{
#ifdef USB_ENABLE
#if USB_DEVICE_FEATURE == true
   if( ( 0 != u8IsMaintenanceRequired ) && ( false == bOutOfMaintenance ) )
   {
      // If we have to enter in the maintenance mode, do not release the mutex.
      // => this mutex is now the property of the supervisor.
      u8IsMaintenanceRequired++;

      // If all mutexes have been acquired, switch to maintenance mode.
      if( ( SUPERVISOR_MAINTENANCE_NBMUTEX_TOTAKE +1 ) == u8IsMaintenanceRequired )
      {
         fat_cache_flush(); // Flush the FAT cache.
         nav_reset();       // Reset all file system navigators. We will mount
                            // the com1shell default drive when we'll leave the
                            // maintenance mode.
         // Switch to maintenance mode.
         xSemaphoreGive( xUSBMutex );

         // If the USB clock is frozen, unfreeze it so that we can write in the
         // USB registers. The USB clock is frozen if a "Device Suspend" event
         // occurred (no more USB activity detected) (cf. usb_general_interrupt()).
         if(true == Is_usb_clock_frozen())
         {
           Usb_unfreeze_clock();
         }
         // If it is not already detached, physically detach the USB device.
         if(false == Is_usb_detached())
         {
           Usb_detach();
         }
         vTaskDelay(500); // Wait 500ms
         Usb_attach();     // Reconnect the device.

         bIsInMaintenance = true;
         u8IsMaintenanceRequired = 0;
         TRACE_COM2( "Entering maintenance mode");
#ifdef MMILCD_ENABLE
         vMMI_SetUserMenuMode( eUserMenuWaitHost, pdTRUE );
#endif
      }
      return( pdTRUE );
   }
   else
#endif
#endif
      return( xSemaphoreGive( xSemaphore ) );
}
Ejemplo n.º 5
0
/*!
 *  \brief Called upon remote host connect (upon VBUS ON event when we are device)
 */
void v_supervisor_Host_Connects( void )
{
#ifdef USB_ENABLE
#if configCTRLPANEL_TRACE == 1
   TempoVbusOn++;
#endif
   if(( 0 == u8IsMaintenanceRequired )&&( false == bIsInMaintenance ))
   {
      // If we connect to the host and the Control Panel is not "set as USB key",
      // properly detach from the USB host (instead of behaving out of the USB spec
      // by not completely enumerating as a Mass Storage device).
      Usb_unfreeze_clock();
      Usb_detach();
   }
   if( SUPERVISOR_USB_ROLE_NONE == u8CurrentUsbRole )
   {   // Consider only one of these events in case we get several.
      u8CurrentUsbRole = SUPERVISOR_USB_ROLE_DEVICE;
   }
#endif
}
Ejemplo n.º 6
0
__interrupt
#endif
static void usb_general_interrupt(void)

#endif
{
#ifdef FREERTOS_USED
  portBASE_TYPE task_woken = pdFALSE;
#endif
#if USB_HOST_FEATURE == true && USB_HOST_PIPE_INTERRUPT_TRANSFER == ENABLE
  U8 i;
#endif

// ---------- DEVICE/HOST events management ------------------------------------
#if USB_DEVICE_FEATURE == true && USB_HOST_FEATURE == true
  // ID pin change detection
  if (Is_usb_id_transition() && Is_usb_id_interrupt_enabled())
  {
    g_usb_mode = (Is_usb_id_device()) ? USB_MODE_DEVICE : USB_MODE_HOST;
    Usb_ack_id_transition();
    if (g_usb_mode != g_old_usb_mode) // Basic debounce
    {
      // Previously in device mode, check if disconnection was detected
      if (g_old_usb_mode == USB_MODE_DEVICE)
      {
        if (usb_connected)
        {
          // Device mode disconnection actions
          usb_connected = false;
          usb_configuration_nb = 0;
          Usb_vbus_off_action();
        }
      }
      // Previously in host mode, check if disconnection was detected
      else if (Is_host_attached())
      {
        // Host mode disconnection actions
        device_state = DEVICE_UNATTACHED;
        Host_device_disconnection_action();
      }

      //LOG_STR(log_pin_id_changed);
      if (Is_usb_id_device() == USB_MODE_DEVICE) { LOG_STR(log_pin_id_changed_to_device); }
		else { LOG_STR(log_pin_id_changed_to_host); }
	  
	  Usb_send_event((Is_usb_device()) ? EVT_USB_DEVICE_FUNCTION :
                                         EVT_USB_HOST_FUNCTION);
      Usb_id_transition_action();

	  // Easier to recover from ID signal de-bounce and ID pin transitions by shutting down the USB and resetting state machine to re-init
#if ID_PIN_CHANGE_SHUTDOWN_USB == ENABLE
      Usb_disable();
      Usb_disable_otg_pad();

extern void UsbResetStateMachine(void);
	  UsbResetStateMachine();

    #ifdef FREERTOS_USED
      // Release the semaphore in order to start a new device/host task
      taskENTER_CRITICAL();
      xSemaphoreGiveFromISR(usb_tsk_semphr, &task_woken);
      taskEXIT_CRITICAL();
	#endif
#endif

#if ID_PIN_CHANGE_GENERATE_RESET == ENABLE
      Reset_CPU();
#endif
    }
  }
#endif  // End DEVICE/HOST FEATURE MODE

// ---------- DEVICE events management -----------------------------------------
#if USB_DEVICE_FEATURE == true
  #if USB_HOST_FEATURE == true
  // If both device and host features are enabled, check if device mode is engaged
  // (accessing the USB registers of a non-engaged mode, even with load operations,
  // may corrupt USB FIFO data).
  if (Is_usb_device())
  #endif
  {
    // VBus state detection
    if (Is_usb_vbus_transition() && Is_usb_vbus_interrupt_enabled())
    {
      Usb_ack_vbus_transition();
      if (Is_usb_vbus_high())
      {
        usb_start_device();
        Usb_send_event(EVT_USB_POWERED);
        Usb_vbus_on_action();
      }
      else
      {
        Usb_unfreeze_clock();
        Usb_detach();
        usb_connected = false;
        usb_configuration_nb = 0;
        Usb_send_event(EVT_USB_UNPOWERED);
        Usb_vbus_off_action();
  #ifdef FREERTOS_USED
        // Release the semaphore in order to start a new device/host task
        taskENTER_CRITICAL();
        xSemaphoreGiveFromISR(usb_tsk_semphr, &task_woken);
        taskEXIT_CRITICAL();
  #endif
      }
    }
    // Device Start-of-Frame received
    if (Is_usb_sof() && Is_usb_sof_interrupt_enabled())
    {
      Usb_ack_sof();
      Usb_sof_action();
    }
    // Device Suspend event (no more USB activity detected)
    if (Is_usb_suspend() && Is_usb_suspend_interrupt_enabled())
    {
      Usb_ack_suspend();
      Usb_enable_wake_up_interrupt();
      (void)Is_usb_wake_up_interrupt_enabled();
      Usb_freeze_clock();
      Usb_send_event(EVT_USB_SUSPEND);
      Usb_suspend_action();
    }
    // Wake-up event (USB activity detected): Used to resume
    if (Is_usb_wake_up() && Is_usb_wake_up_interrupt_enabled())
    {
      Usb_unfreeze_clock();
      (void)Is_usb_clock_frozen();
      Usb_ack_wake_up();
      Usb_disable_wake_up_interrupt();
      Usb_wake_up_action();
      Usb_send_event(EVT_USB_WAKE_UP);
    }
    // Resume state bus detection
    if (Is_usb_resume() && Is_usb_resume_interrupt_enabled())
    {
      Usb_disable_wake_up_interrupt();
      Usb_ack_resume();
      Usb_disable_resume_interrupt();
      Usb_resume_action();
      Usb_send_event(EVT_USB_RESUME);
    }
    // USB bus reset detection
    if (Is_usb_reset() && Is_usb_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 == true
  #if USB_DEVICE_FEATURE == true
  // If both device and host features are enabled, check if host mode is engaged
  // (accessing the USB registers of a non-engaged mode, even with load operations,
  // may corrupt USB FIFO data).
  else
  #endif
  {
    // The device has been disconnected
    if (Is_host_device_disconnection() && Is_host_device_disconnection_interrupt_enabled())
    {
      host_disable_all_pipes();
      Host_ack_device_disconnection();
  #if USB_HOST_PIPE_INTERRUPT_TRANSFER == ENABLE
      reset_it_pipe_str();
  #endif
      device_state = DEVICE_UNATTACHED;
      LOG_STR(log_device_disconnected);
      Usb_send_event(EVT_HOST_DISCONNECTION);
      Host_device_disconnection_action();
  #ifdef FREERTOS_USED
      // Release the semaphore in order to start a new device/host task
      taskENTER_CRITICAL();
      xSemaphoreGiveFromISR(usb_tsk_semphr, &task_woken);
      taskEXIT_CRITICAL();
  #endif
    }
    // Device connection
    if (Is_host_device_connection() && Is_host_device_connection_interrupt_enabled())
    {
      Host_ack_device_connection();
      host_disable_all_pipes();
      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);
#if (USB_HIGH_SPEED_SUPPORT==true)
      if( Is_usb_full_speed_mode() )
      {
         private_sof_counter++;
      }else{
         private_sof_counter_HS++;
         if( 0 == (private_sof_counter_HS%8) )
         {
            private_sof_counter++;
         }
      }
#else
      private_sof_counter++;
#endif
      // Delay time-out management for interrupt transfer mode in host mode
  #if USB_HOST_PIPE_INTERRUPT_TRANSFER == ENABLE && TIMEOUT_DELAY_ENABLE == ENABLE
      if (private_sof_counter >= 250) // Count 250 ms (SOF @ 1 ms)
      {
        private_sof_counter = 0;
        for (i = 0; i < MAX_PEP_NB; i++)
        {
          if (it_pipe_str[i].enable &&
              ++it_pipe_str[i].timeout > TIMEOUT_DELAY && Host_get_pipe_type(i) != TYPE_INTERRUPT)
          {
            it_pipe_str[i].enable = false;
            it_pipe_str[i].status = PIPE_DELAY_TIMEOUT;
            Host_reset_pipe(i);
            if (!is_any_interrupt_pipe_active() && !g_sav_int_sof_enable) // If no more transfer is armed
            {
              Host_disable_sof_interrupt();
            }
            it_pipe_str[i].handler(PIPE_DELAY_TIMEOUT, it_pipe_str[i].nb_byte_processed);
          }
        }
      }
  #endif
      Host_sof_action();
    }
    // Host Wake-up has been received
    if (Is_host_hwup() && Is_host_hwup_interrupt_enabled())
    {
      // CAUTION: HWUP can be cleared only when USB clock is active (not frozen)!
      //! @todo Implement this on the silicon version
      //Pll_start_auto();               // First Restart the PLL for USB operation
      //Wait_pll_ready();               // Make sure PLL is locked
      Usb_unfreeze_clock();           // Enable clock on USB interface
      (void)Is_usb_clock_frozen();    // Make sure USB interface clock is enabled
      Host_disable_hwup_interrupt();  // Wake-up interrupt should be disabled as host is now awoken!
      Host_ack_hwup();                // Clear HWUP interrupt flag
      Usb_send_event(EVT_HOST_HWUP);  // Send software event
      Host_hwup_action();             // Map custom action
    }
  #if USB_HOST_PIPE_INTERRUPT_TRANSFER == ENABLE
    // Host pipe interrupts
    while ((i = Host_get_interrupt_pipe_number()) < MAX_PEP_NB) usb_pipe_interrupt(i);
  #endif
  }
#endif  // End HOST FEATURE MODE

#ifdef FREERTOS_USED
  return task_woken;
#endif
}
Ejemplo n.º 7
0
ISR(usb_general_interrupt, AVR32_USBB_IRQ_GROUP, USB_INT_LEVEL)

#endif
{
#ifdef FREERTOS_USED
  portBASE_TYPE task_woken = pdFALSE;
#endif
  uint8_t i;
  /* avoid Cppcheck Warning */
  UNUSED(i);

// ---------- DEVICE/HOST events management ------------------------------------
#if USB_DEVICE_FEATURE == true && USB_HOST_FEATURE == true
  // ID pin change detection
  if (Is_usb_id_transition() && Is_usb_id_interrupt_enabled())
  {
    g_usb_mode = (Is_usb_id_device()) ? USB_MODE_DEVICE : USB_MODE_HOST;
    Usb_ack_id_transition();
    if (g_usb_mode != g_old_usb_mode) // Basic debounce
    {
      // Previously in device mode, check if disconnection was detected
      if (g_old_usb_mode == USB_MODE_DEVICE)
      {
        if (usb_connected)
        {
          // Device mode diconnection actions
          usb_connected = false;
          usb_configuration_nb = 0;
          Usb_vbus_off_action();
        }
      }
      // Previously in host mode, check if disconnection was detected
      else if (Is_host_attached())
      {
        // Host mode diconnection actions
        device_state = DEVICE_UNATTACHED;
        Host_device_disconnection_action();
      }
      LOG_STR(log_pin_id_changed);
      Usb_send_event((Is_usb_device()) ? EVT_USB_DEVICE_FUNCTION :
                                         EVT_USB_HOST_FUNCTION);
      Usb_id_transition_action();
      //! @todo ID pin hot state change!!!
      // Preliminary management: HARDWARE RESET!!!
  #if ID_PIN_CHANGE_GENERATE_RESET == ENABLE
      // Hot ID transition generates CPU reset
      Usb_disable();
      Usb_disable_otg_pad();
    #ifdef FREERTOS_USED
      // Release the semaphore in order to start a new device/host task
      taskENTER_CRITICAL();
      xSemaphoreGiveFromISR(usb_tsk_semphr, &task_woken);
      taskEXIT_CRITICAL();
    #else
#if defined(CPU_RESET_CALLBACK)
      CPU_RESET_CALLBACK();
#endif
      Reset_CPU();
    #endif
  #endif
      g_old_usb_mode = g_usb_mode;  // Store current USB mode, for mode change detection
    }
  }
#endif  // End DEVICE/HOST FEATURE MODE

// ---------- DEVICE events management -----------------------------------------
#if USB_DEVICE_FEATURE == true
  #if USB_HOST_FEATURE == true
  // If both device and host features are enabled, check if device mode is engaged
  // (accessing the USB registers of a non-engaged mode, even with load operations,
  // may corrupt USB FIFO data).
  if (Is_usb_device())
  #endif
  {
    // VBus state detection
    if (Is_usb_vbus_transition() && Is_usb_vbus_interrupt_enabled())
    {
      Usb_ack_vbus_transition();
      if (Is_usb_vbus_high())
      {
        usb_start_device();
        Usb_send_event(EVT_USB_POWERED);
        Usb_vbus_on_action();
      }
      else
      {
        Usb_unfreeze_clock();
        Usb_detach();
        usb_connected = false;
        usb_configuration_nb = 0;
        Usb_send_event(EVT_USB_UNPOWERED);
        Usb_vbus_off_action();
  #ifdef FREERTOS_USED
        // Release the semaphore in order to start a new device/host task
        taskENTER_CRITICAL();
        xSemaphoreGiveFromISR(usb_tsk_semphr, &task_woken);
        taskEXIT_CRITICAL();
  #endif
      }
    }
    // Device Start-of-Frame received
    if (Is_usb_sof() && Is_usb_sof_interrupt_enabled())
    {
      Usb_ack_sof();
      Usb_sof_action();
    }
    // Device Suspend event (no more USB activity detected)
    if (Is_usb_suspend() && Is_usb_suspend_interrupt_enabled())
    {
      Usb_ack_suspend();
      Usb_enable_wake_up_interrupt();
      (void)Is_usb_wake_up_interrupt_enabled();
      Usb_freeze_clock();
      Usb_send_event(EVT_USB_SUSPEND);
      Usb_suspend_action();
    }
    // Wake-up event (USB activity detected): Used to resume
    if (Is_usb_wake_up() && Is_usb_wake_up_interrupt_enabled())
    {
      Usb_unfreeze_clock();
      (void)Is_usb_clock_frozen();
      Usb_ack_wake_up();
      Usb_disable_wake_up_interrupt();
      Usb_wake_up_action();
      Usb_send_event(EVT_USB_WAKE_UP);
    }
    // Resume state bus detection
    if (Is_usb_resume() && Is_usb_resume_interrupt_enabled())
    {
      Usb_disable_wake_up_interrupt();
      Usb_ack_resume();
      Usb_disable_resume_interrupt();
      Usb_resume_action();
      Usb_send_event(EVT_USB_RESUME);
    }
    // USB bus reset detection
    if (Is_usb_reset() && Is_usb_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 == true
  #if USB_DEVICE_FEATURE == true
  // If both device and host features are enabled, check if host mode is engaged
  // (accessing the USB registers of a non-engaged mode, even with load operations,
  // may corrupt USB FIFO data).
  else
  #endif
  {
    // The device has been disconnected
    if (Is_host_device_disconnection() && Is_host_device_disconnection_interrupt_enabled())
    {
      host_disable_all_pipes();
      Host_ack_device_disconnection();
  #if USB_HOST_PIPE_INTERRUPT_TRANSFER == ENABLE
      reset_it_pipe_str();
  #endif
  #ifdef HOST_VBUS_LOW_TIMEOUT
      cpu_set_timeout(HOST_VBUS_LOW_TIMEOUT, &timer_vbus_low);
      device_state = DEVICE_VBUS_LOW;
  #else
      device_state = DEVICE_UNATTACHED;
  #endif
      LOG_STR(log_device_disconnected);
      Usb_send_event(EVT_HOST_DISCONNECTION);
      Host_device_disconnection_action();
  #ifdef FREERTOS_USED
      // Release the semaphore in order to start a new device/host task
      taskENTER_CRITICAL();
      xSemaphoreGiveFromISR(usb_tsk_semphr, &task_woken);
      taskEXIT_CRITICAL();
  #endif
    }
    // Device connection
    if (Is_host_device_connection() && Is_host_device_connection_interrupt_enabled())
    {
      Host_ack_device_connection();
      host_disable_all_pipes();
      Usb_send_event(EVT_HOST_CONNECTION);
      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++;
      // Delay time-out 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 250 ms (SOF @ 1 ms)
      {
        private_sof_counter = 0;
        for (i = 0; i < MAX_PEP_NB; i++)
        {
          if (it_pipe_str[i].enable &&
              ++it_pipe_str[i].timeout > TIMEOUT_DELAY && Host_get_pipe_type(i) != TYPE_INTERRUPT)
          {
            it_pipe_str[i].enable = false;
            it_pipe_str[i].status = PIPE_DELAY_TIMEOUT;
            Host_reset_pipe(i);
            if (!is_any_interrupt_pipe_active() && !g_sav_int_sof_enable) // If no more transfer is armed
            {
              Host_disable_sof_interrupt();
            }
            it_pipe_str[i].handler(PIPE_DELAY_TIMEOUT, it_pipe_str[i].nb_byte_processed);
          }
        }
      }
  #endif
      Host_sof_action();
    }
    // Host Wake-up has been received
    if (Is_host_hwup() && Is_host_hwup_interrupt_enabled())
    {
      // CAUTION: HWUP can be cleared only when USB clock is active (not frozen)!
      //! @todo Implement this on the silicon version
      //Pll_start_auto();               // First Restart the PLL for USB operation
      //Wait_pll_ready();               // Make sure PLL is locked
      Usb_unfreeze_clock();           // Enable clock on USB interface
      (void)Is_usb_clock_frozen();    // Make sure USB interface clock is enabled
      Host_disable_hwup_interrupt();  // Wake-up interrupt should be disabled as host is now awoken!
      Host_ack_hwup();                // Clear HWUP interrupt flag
      Usb_send_event(EVT_HOST_HWUP);  // Send software event
      Host_hwup_action();             // Map custom action
    }

    Host_int_action();

    while ((i = Host_get_interrupt_pipe_number()) < MAX_PEP_NB)
    {
      if (Is_host_in_received(i) && Is_host_in_received_interrupt_enabled(i))
      {
        Host_freeze_pipe(i);
        Host_disable_in_received_interrupt(i);
      }
    }

  #if defined(USB_HIGH_SPEED_SUPPORT) && USB_HIGH_SPEED_SUPPORT == true && \
    defined(PIPE_AUDIO_IN)
    // Workaround - freeze the IN audio pipe
    if (Is_host_in_received(PIPE_AUDIO_IN))
    {
      extern void workaround_freeze_iso_in(void);
      workaround_freeze_iso_in();
    }
  #endif // USB_HIGH_SPEED_SUPPORT == true

  #if USB_HOST_PIPE_INTERRUPT_TRANSFER == ENABLE
    // Host pipe interrupts
    while ((i = Host_get_interrupt_pipe_number()) < MAX_PEP_NB) usb_pipe_interrupt(i);
  #endif
  }
#endif  // End HOST FEATURE MODE

#ifdef FREERTOS_USED
  return task_woken;
#endif
}
Ejemplo n.º 8
0
/**
 *  @brief Entry point of the USB mamnagement
 *
 *  Depending on the USB mode supported (HOST/DEVICE/DUAL_ROLE) the function
 *  calls the coresponding usb management function.
 *
 *  @param none
 *
 *  @return none
*/
void usb_task(void)
{
// ---- DUAL ROLE DEVICE USB MODE ---------------------------------------------
#if ((USB_DEVICE_FEATURE == ENABLED)&& (USB_HOST_FEATURE == ENABLED))
   if(Is_usb_id_device())
   { g_usb_mode=USB_MODE_DEVICE;}
   else
   { g_usb_mode=USB_MODE_HOST;}

   if( g_old_usb_mode != g_usb_mode )
   {
      // ID pin hot state change
#if ( ID_PIN_CHANGE_GENERATE_RESET == ENABLE)
      // Hot ID transition generates wdt reset
      wdtdrv_enable(WDTO_16MS);
      while(1);
#else
      // Hot ID transition reset USB mode      
      Usb_ack_id_transition(); // REQUIRED
      if (Is_usb_id_host())
      {
         Usb_disable_resume_interrupt();
         Usb_disable_wake_up_interrupt();
         Usb_disable_suspend_interrupt();
         Usb_disable_reset_interrupt();
         Usb_detach();
         Usb_disable();
         usb_host_task_init();
      }
      else
      { 
         Host_disable_device_disconnection_interrupt();
         Host_disable_sof_interrupt();
         Host_disable_sof();
         Usb_disable_vbus();
         Usb_disable_manual_vbus();
         Usb_freeze_clock();
         Usb_disable();
         usb_device_task_init();
      }
#endif
   }
   
   // Store current usb mode, for mode change detection
   g_old_usb_mode=g_usb_mode;

   // Depending on current usb mode, launch the correct usb task (device or host)
   switch(g_usb_mode)
   {
      case USB_MODE_DEVICE:
      usb_device_task();
      break;
      
      case USB_MODE_HOST:
      usb_host_task();
      break;
      
      case USB_MODE_UNDEFINED:  // No break !
      default:
      break;
  }
// -----------------------------------------------------------------------------

// ---- DEVICE ONLY USB MODE ---------------------------------------------------
#elif ((USB_DEVICE_FEATURE == ENABLED)&& (USB_HOST_FEATURE == DISABLE))
   usb_device_task();
// -----------------------------------------------------------------------------

// ---- REDUCED HOST ONLY USB MODE ---------------------------------------------
#elif ((USB_DEVICE_FEATURE == DISABLE)&& (USB_HOST_FEATURE == ENABLED))
   usb_host_task();
// -----------------------------------------------------------------------------

//! ---- ERROR, NO MODE ENABLED -------------------------------------------------
#elif ((USB_DEVICE_FEATURE == DISABLE)&& (USB_HOST_FEATURE == DISABLE))
   #error  at least one of USB_DEVICE_FEATURE or USB_HOST_FEATURE should be enabled
   #error  otherwise the usb task has nothing to do ...
#endif
// -----------------------------------------------------------------------------

}
Ejemplo n.º 9
0
/*!
 *  \brief The switch-to-maintenance-mode command: initiate the process to \n
 *         switch to maintenance mode.
 *         Format: maintain
 *
 *  \note  This function must be of the type pfShellCmd defined by the shell module.
 *
 *  \param xModId         Input. The module that is calling this function.
 *  \param FsNavId        Ignored.
 *  \param ac             Ignored.
 *  \param av             Ignored.
 *  \param ppcStringReply Input/Output. The response string.
 *                        If Input is NULL, no response string will be output.
 *                        Else a malloc for the response string is performed here;
 *                        the caller must free this string.
 *
 *  \return the status of the command execution.
 */
eExecStatus e_supervisor_switch_to_maintenance_mode( eModId xModId,
                              signed short FsNavId,
                              int ac, signed portCHAR *av[],
                              signed portCHAR **ppcStringReply )
{
   if( NULL != ppcStringReply )
      *ppcStringReply = NULL;

#ifdef USB_ENABLE
#if USB_DEVICE_FEATURE == true
   if( ( false == bIsInMaintenance )
       && ( 0 == u8IsMaintenanceRequired ) )
   {   // We're not in maintenance mode.
      // Initiate the process of switching to maintenance mode.
      if( 0 == u8IsMaintenanceRequired )   u8IsMaintenanceRequired++;

      // Take all maintenance mutex except the USB mutex.
      if( true == x_supervisor_SemaphoreTake( xLOGMutex, 0 ) )       u8IsMaintenanceRequired++;
#if NW_INTEGRATED_IN_CONTROL_PANEL
      if( true == x_supervisor_SemaphoreTake( xWEBMutex, 0 ) )       u8IsMaintenanceRequired++;
#endif
      if( true == x_supervisor_SemaphoreTake( xSHELLFSMutex, 0 ) )   u8IsMaintenanceRequired++;
      if( true == x_supervisor_SemaphoreTake( xCFGMutex, 0 ) )       u8IsMaintenanceRequired++;

      // If all mutexes have been acquired, switch to maintenance mode.
      if( ( SUPERVISOR_MAINTENANCE_NBMUTEX_TOTAKE +1 ) == u8IsMaintenanceRequired )
      {
         fat_cache_flush(); // flush the FAT cache.
         nav_reset();       // Reset all file system navigators. We will mount
                            // the com1shell default drive when we'll leave the
                            // maintenance mode.
         // Switch to maintenance mode.
         xSemaphoreGive( xUSBMutex );

         // If the USB clock is frozen, unfreeze it so that we can write in the
         // USB registers.
         if(true == Is_usb_clock_frozen())
         {
           Usb_unfreeze_clock();
         }
         // If it is not akready detached, physically detach the USB device.
         if(false == Is_usb_detached())
         {
           Usb_detach();
         }
         vTaskDelay(500); // Wait 500ms
         Usb_attach();     // Reconnect the device.

         bIsInMaintenance = true;
         u8IsMaintenanceRequired = 0;
         TRACE_COM2( "Entering maintenance mode");
#ifdef MMILCD_ENABLE
         vMMI_SetUserMenuMode( eUserMenuWaitHost, pdTRUE );
#endif
      }
      // ELSE: we'll switch to maintenance mode in x_supervisor_SemaphoreGive()
      // (when the mutex(es) that we couldn't get will be released).
   }
   else
   {
      NAKED_TRACE_COM2( "Won't go to maintenance mode:"CRLF"bIsInMaintenance=%d u8CurrentUsbRole=%d u8IsMaintenanceRequired=%d", bIsInMaintenance, u8CurrentUsbRole, u8IsMaintenanceRequired );
   }
#endif
#endif

   return( SHELL_EXECSTATUS_OK );
}
Ejemplo n.º 10
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();
   }
}
Ejemplo n.º 11
0
/**
 \brief Process incomming char on debug port
 */
void menu_process(char c)
{

	static enum menustate_enum            /* Defines an enumeration type    */
	{
		normal,
		channel
	} menustate = normal;
	
	static char channel_string[3];
	static uint8_t channel_string_i = 0;
	
	int tempchannel;
	

	if (menustate == channel) {

		switch(c) {
			case '\r':
			case '\n':		
				channel_string[channel_string_i] = 0;
								
				//Will return zero in event of error...
				tempchannel = atoi(channel_string);
				
				//Bounds check only if user had real input
				if ( ((channel_string_i) && (tempchannel < 11)) || (tempchannel > 26))  {
					PRINTF_P(PSTR("\n\rInvalid input\n\r"));				
				}
				
				//If valid input, change it
				if (tempchannel) {
					radio_set_operating_channel(tempchannel);
					eeprom_write_byte(9, tempchannel);   //Write channel
					eeprom_write_byte(10, ~tempchannel); //Bit inverse as check
				}

				menustate = normal;
				break;
		
			case '\b':
			
				if (channel_string_i)
					channel_string_i--;
				break;
					
			default:
			
				if (channel_string_i > 1) {
					menustate = normal;
					PRINTF_P(PSTR("\n\rInput too long!\n\r"));
					break;
				}
				
				channel_string[channel_string_i] = c;
				channel_string_i++;
		}


	} else {

		uint8_t i;
		switch(c) {
			case '\r':
			case '\n':
				break;

			case 'h':
			case '?':
				menu_print();
				break;

			case 's':
				PRINTF_P(PSTR("Jackdaw now in sniffer mode\n\r"));
				usbstick_mode.sendToRf = 0;
				usbstick_mode.translate = 0;
				break;

			case 'n':
				PRINTF_P(PSTR("Jackdaw now in network mode\n\r"));
				usbstick_mode.sendToRf = 1;
				usbstick_mode.translate = 1;
				break;

			case '6':
				if (usbstick_mode.sicslowpan) {
					PRINTF_P(PSTR("Jackdaw does not perform 6lowpan translation\n\r"));
					usbstick_mode.sicslowpan = 0;
				} else {
					PRINTF_P(PSTR("Jackdaw now performs 6lowpan translations\n\r"));
					usbstick_mode.sicslowpan = 1;
				}	
				
				break;

			case 'r':
				if (usbstick_mode.raw) {
					PRINTF_P(PSTR("Jackdaw does not capture raw frames\n\r"));
					usbstick_mode.raw = 0;
				} else {
					PRINTF_P(PSTR("Jackdaw now captures raw frames\n\r"));
					usbstick_mode.raw = 1;
				}	
				break;

			case 'c':
				PRINTF_P(PSTR("Select 802.15.4 Channel in range 11-26 [%d]: "), radio_get_operating_channel());
				menustate = channel;
				channel_string_i = 0;
				break;
				
				
			
			case 'm':
				PRINTF_P(PSTR("Currently Jackdaw:\n\r  * Will "));
				if (usbstick_mode.sendToRf == 0) { PRINTF_P(PSTR("not "));}
				PRINTF_P(PSTR("send data over RF\n\r  * Will "));
				if (usbstick_mode.translate == 0) { PRINTF_P(PSTR("not "));}
				PRINTF_P(PSTR("change link-local addresses inside IP messages\n\r  * Will "));
				if (usbstick_mode.sicslowpan == 0) { PRINTF_P(PSTR("not "));}
				PRINTF_P(PSTR("decompress 6lowpan headers\n\r  * Will "));
				if (usbstick_mode.raw == 0) { PRINTF_P(PSTR("not "));}
				PRINTF_P(PSTR("Output raw 802.15.4 frames\n\r "));
				PRINTF_P(PSTR("  * Operates on channel %d\n\r"), radio_get_operating_channel());
				break;

			case 'u':

				//Mass storage mode
				usb_mode = mass_storage;

				//No more serial port
				stdout = NULL;

				//RNDIS is over
				rndis_state = 	rndis_uninitialized;
				Leds_off();

				//Deatch USB
				Usb_detach();

				//Wait a few seconds
				for(i = 0; i < 50; i++)
					_delay_ms(100);

				//Attach USB
				Usb_attach();


				break;

			default:
				PRINTF_P(PSTR("%c is not a valid option! h for menu\n\r"), c);
				break;
		}


	}

	return;

}
Ejemplo n.º 12
0
static void
usb_eth_setup_timeout_fallback_check() {
	extern uint8_t fingerPresent;
		/* Device is Enumerated but RNDIS not loading. We might
		   have a system that does not support IAD (winXP). If so
		   count the timeout then switch to just network interface. */
	static uint16_t iad_fail_timeout, rndis_fail_timeout;	
	if (usb_mode == rndis_debug) {
		//If we have timed out, detach
		if (iad_fail_timeout == IAD_TIMEOUT_DETACH) {
		
			//Failed - BUT we are using "reverse logic", hence we force device
			//into this mode. This is used to allow Windows Vista have time to
			//install the drivers
			if (fingerPresent && (rndis_state != rndis_data_initialized) && Is_device_enumerated() ) {
				iad_fail_timeout = 0;
			} else {
					stdout = NULL;
					Usb_detach();
					doInit = 1; //Also mark system as needing intilizing
			}
			
		//Then wait a few before re-attaching
		} else if (iad_fail_timeout == IAD_TIMEOUT_ATTACH) {
		
			if (fingerPresent) {
				usb_mode = mass_storage;
			} else {
				usb_mode = rndis_only;
			}
			Usb_attach();
		}

		//Increment timeout when device is not initializing, OR we have already detached,
		//OR the user had their finger on the device, indicating a reverse of logic
		if ( ( (rndis_state != rndis_data_initialized) && Is_device_enumerated() ) ||
		  (iad_fail_timeout > IAD_TIMEOUT_DETACH) || 
		   (fingerPresent) ) {
			iad_fail_timeout++;
		} else {	
		iad_fail_timeout = 0;
		}
	} //usb_mode == rndis_debug


	 /* Device is Enumerated but RNDIS STIL not loading. We just
		have RNDIS interface, so obviously no drivers on target.
		Just go ahead and mount ourselves as mass storage... */
	if (usb_mode == rndis_only) {
		//If we have timed out, detach
		if (rndis_fail_timeout == RNDIS_TIMEOUT_DETACH) {
			Usb_detach();
		//Then wait a few before re-attaching
		} else if (rndis_fail_timeout == RNDIS_TIMEOUT_ATTACH) {
			usb_mode = mass_storage;
			Usb_attach();
		}

		//Increment timeout when device is not initializing, OR we are already
		//counting to detach
		if ( ( (rndis_state != rndis_data_initialized)) ||
		  (rndis_fail_timeout > RNDIS_TIMEOUT_DETACH) ) {
			rndis_fail_timeout++;
		} else {	
		rndis_fail_timeout = 0;
		}
	}//usb_mode == rnids_only
}