Esempio n. 1
0
//!
//! @brief This function receives nb_data bytes pointed to by ptr_buf on the specified pipe.
//!
//! *nb_data is updated with the final number of data bytes received.
//!
//! @param pipe
//! @param nb_data
//! @param ptr_buf
//! @param handler Call-back function pointer
//!
//! @return bool: Status
//!
bool host_get_data_interrupt(uint8_t pipe, uint16_t nb_data, void *ptr_buf, Pipe_handler *handler)
{
  bool sav_glob_int_en;

  if (it_pipe_str[pipe].enable) return false;

  if (!is_any_interrupt_pipe_active())
  {
    g_sav_int_sof_enable = Is_host_sof_interrupt_enabled();
    Host_enable_sof_interrupt();
  }
  it_pipe_str[pipe].enable = true;
  it_pipe_str[pipe].nb_byte_to_process = nb_data;
  it_pipe_str[pipe].nb_byte_processed = 0;
  it_pipe_str[pipe].ptr_buf = ptr_buf;
  it_pipe_str[pipe].handler = handler;
  it_pipe_str[pipe].timeout = 0;
  it_pipe_str[pipe].nak_timeout = NAK_RECEIVE_TIMEOUT;

  private_sof_counter = 0;          // Reset the counter in SOF detection subroutine
  if ((sav_glob_int_en = cpu_irq_is_enabled())) cpu_irq_disable();
  Host_reset_pipe(pipe);
  Host_ack_stall(pipe);
  Host_ack_nak_received(pipe);
  (void)Is_host_nak_received(pipe);
  if (sav_glob_int_en) cpu_irq_enable();

  Host_enable_stall_interrupt(pipe);
  #if NAK_TIMEOUT_ENABLE == ENABLE
  Host_enable_nak_received_interrupt(pipe);
  #endif
  Host_enable_pipe_error_interrupt(pipe);
  Host_enable_in_received_interrupt(pipe);
  Host_enable_pipe_interrupt(pipe);

  Host_enable_continuous_in_mode(pipe);
  Host_configure_pipe_token(pipe, TOKEN_IN);
  Host_ack_in_received(pipe);
  Host_unfreeze_pipe(pipe);

  return true;
}
Esempio n. 2
0
void host_mouse_hid_task(void)
#endif
{
  uint8_t i;

#ifdef FREERTOS_USED
  portTickType xLastWakeTime;

  xLastWakeTime = xTaskGetTickCount();
  while (true)
  {
    vTaskDelayUntil(&xLastWakeTime, configTSK_USB_HHID_MOUSE_PERIOD);

#endif  // FREERTOS_USED
    // First, check the host controller is in full operating mode with the
    // B-device attached and enumerated
    if (Is_host_ready())
    {
      // New device connection (executed only once after device connection)
      if (mouse_hid_new_device_connected)
      {
        mouse_hid_new_device_connected = false;

        // For all supported interfaces
        for (i = 0; i < Get_nb_supported_interface(); i++)
        {
          if(Get_class(i)==HID_CLASS && Get_protocol(i)==MOUSE_PROTOCOL)
          {
            host_hid_set_idle(HID_IDLE_DURATION_INDEFINITE, HID_REPORT_ID_ALL, i);
            host_hid_get_report(HID_REPORT_DESCRIPTOR, 0, i);
            pipe_mouse_in = Get_ep_pipe(i, 0);
            Host_enable_continuous_in_mode(pipe_mouse_in);
            Host_unfreeze_pipe(pipe_mouse_in);
            mouse_hid_connected=true;
            break;
          }
        }
      }

      if( Is_host_mouse_hid_configured() )
      {
        if((Is_host_in_received(pipe_mouse_in)) && (Is_host_stall(pipe_mouse_in)==false) )
        {
           Host_reset_pipe_fifo_access(pipe_mouse_in);
           usb_report[0]=
           usb_report[1]=
           usb_report[2]=
           usb_report[3]=0;
           host_read_p_rxpacket(pipe_mouse_in, (void*)usb_report, 4, NULL);
           Host_ack_in_received(pipe_mouse_in);
           Host_free_in(pipe_mouse_in);
           new_x = usb_report[1];
           new_y = usb_report[2];
           mouse_x += new_x;
           mouse_y += new_y;
           if(      mouse_x<MOUSE_X_MIN ) mouse_x=MOUSE_X_MIN;
           else if( mouse_x>MOUSE_X_MAX ) mouse_x=MOUSE_X_MAX;
           if(      mouse_y<MOUSE_Y_MIN ) mouse_y=MOUSE_Y_MIN;
           else if( mouse_y>MOUSE_Y_MAX ) mouse_y=MOUSE_Y_MAX;
           mouse_b0=usb_report[0] & 1;
           mouse_b1=usb_report[0] & 2;
           mouse_b2=usb_report[0] & 4;
           disp_led_mouse();
           disp_ascii_mouse();
        }
        if(Is_host_nak_received(pipe_mouse_in))
        {
           Host_ack_nak_received(pipe_mouse_in);
           LED_Off(LED_HOST_MOUSE_B0 );
           LED_Off(LED_HOST_MOUSE_B1 );
           LED_Off(LED_HOST_MOUSE_B2 );
           LED_Off(LED_HOST_MOUSE_B3 );
        }
      }
    }


#ifdef FREERTOS_USED
  }
#endif
}
Esempio n. 3
0
//!
//! @brief This function receives nb_data bytes pointed to by ptr_buf on the specified pipe.
//!
//! *nb_data is updated with the final number of data bytes received.
//!
//! @note This function activates the host SOF interrupt to detect time-outs.
//! The initial enable state of this interrupt will be restored.
//!
//! @param pipe
//! @param nb_data
//! @param ptr_buf
//!
//! @return Status_t: Pipe status
//!
Status_t host_get_data(uint8_t pipe, uint16_t *nb_data, void *ptr_buf)
{
  Status_t status = PIPE_GOOD;      // Frame correctly received by default
  bool sav_int_sof_enable;
  bool sav_glob_int_en;
  uint8_t nak_timeout;
  uint16_t n, i;
#if NAK_TIMEOUT_ENABLE == ENABLE
  uint16_t cpt_nak;
#endif

  n = *nb_data;
  sav_int_sof_enable = Is_host_sof_interrupt_enabled();
  Host_enable_sof_interrupt();
  Host_enable_continuous_in_mode(pipe);
  Host_configure_pipe_token(pipe, TOKEN_IN);
  Host_ack_in_received(pipe);
  while (n)                         // While missing data...
  {
    Host_free_in(pipe);
    Host_unfreeze_pipe(pipe);
    private_sof_counter = 0;        // Reset the counter in SOF detection subroutine
    nak_timeout = 0;
#if NAK_TIMEOUT_ENABLE == ENABLE
    cpt_nak = 0;
#endif
    while (!Is_host_in_received(pipe))
    {
      if (Is_host_emergency_exit()) // Asynchronous disconnection or role exchange detected under interrupt
      {
        status = PIPE_DELAY_TIMEOUT;
        Host_reset_pipe(pipe);
        goto host_get_data_end;
      }
#if TIMEOUT_DELAY_ENABLE == ENABLE
      if (private_sof_counter >= 250) // Time-out management
      {
        private_sof_counter = 0;    // Done in host SOF interrupt
        if (nak_timeout++ >= TIMEOUT_DELAY) // Check for local time-out
        {
          status = PIPE_DELAY_TIMEOUT;
          Host_reset_pipe(pipe);
          goto host_get_data_end;
        }
      }
#endif
      if (Is_host_pipe_error(pipe)) // Error management
      {
        status = Host_error_status(pipe);
        Host_ack_all_errors(pipe);
        goto host_get_data_end;
      }
      if (Is_host_stall(pipe))      // STALL management
      {
        status = PIPE_STALL;
        Host_reset_pipe(pipe);
        Host_ack_stall(pipe);
        goto host_get_data_end;
      }
#if NAK_TIMEOUT_ENABLE == ENABLE
      if (Is_host_nak_received(pipe)) // NAK received
      {
        Host_ack_nak_received(pipe);
        if (cpt_nak++ > NAK_RECEIVE_TIMEOUT)
        {
          status = PIPE_NAK_TIMEOUT;
          Host_reset_pipe(pipe);
          goto host_get_data_end;
        }
      }
#endif
    }
    Host_freeze_pipe(pipe);
    Host_reset_pipe_fifo_access(pipe);
    i = Host_get_pipe_size(pipe) - Host_byte_count(pipe);
    if (!ptr_buf)
    {
      if (Host_byte_count(pipe) > n)  // More bytes received than expected
      {
        n = 0;
        //! @todo Error code management
      }
      else                            // Nb bytes received <= expected
      {
        n -= Host_byte_count(pipe);
        if (i)                          // Short packet
        {
          *nb_data -= n;
          n = 0;
        }
      }
    }
    else
    {
      n = host_read_p_rxpacket(pipe, ptr_buf, n, &ptr_buf);
      if (Host_byte_count(pipe))      // More bytes received than expected
      {
        //! @todo Error code management
      }
      else if (i)                     // Short packet with nb bytes received <= expected
      {
        *nb_data -= n;
        n = 0;
      }
    }
    Host_ack_in_received(pipe);

    // In low-speed mode, the USB IP may have not yet sent the ACK at this
    // point. The USB IP does not support a new start of transaction request
    // from the firmware if the ACK has not been sent. The only means of making
    // sure the ACK has been sent is to wait for the next Keep-Alive before
    // starting a new transaction.
    if (Is_usb_low_speed_mode())
    {
      Usb_ack_event(EVT_HOST_SOF);
      sav_int_sof_enable = Is_host_sof_interrupt_enabled();
      if ((sav_glob_int_en = cpu_irq_is_enabled())) cpu_irq_disable();
      Host_ack_sof();
      (void)Is_host_sof_interrupt_enabled();
      if (sav_glob_int_en) cpu_irq_enable();
      Host_enable_sof_interrupt();
      while (!Is_usb_event(EVT_HOST_SOF))         // Wait for next Keep-Alive
      {
        if (Is_host_emergency_exit())
        {
          status = PIPE_DELAY_TIMEOUT;
          Host_reset_pipe(pipe);
          goto host_get_data_end;
        }
      }
      if (!sav_int_sof_enable)                    // Restore SOF interrupt enable
      {
        if ((sav_glob_int_en = cpu_irq_is_enabled())) cpu_irq_disable();
        Host_disable_sof_interrupt();
        (void)Is_host_sof_interrupt_enabled();
        if (sav_glob_int_en) cpu_irq_enable();
      }
    }
  }
host_get_data_end:
  Host_freeze_pipe(pipe);
  // Restore SOF interrupt enable state
  if (!sav_int_sof_enable)
  {
    if ((sav_glob_int_en = cpu_irq_is_enabled())) cpu_irq_disable();
    Host_disable_sof_interrupt();
    (void)Is_host_sof_interrupt_enabled();
    if (sav_glob_int_en) cpu_irq_enable();
  }

  // And return...
  return status;
}