コード例 #1
0
ファイル: usb_specific_request.c プロジェクト: kerichsen/asf
//! This function manages the HID Get_Descriptor request.
//!
static void hid_get_descriptor(U8 size_of_report, const U8* p_usb_hid_report)
{
  bool  zlp;
  U16   wIndex;
  U16   wLength;

  zlp = false;                                              /* no zero length packet */

  data_to_transfer = size_of_report;
  pbuffer          = p_usb_hid_report;

  wIndex = Usb_read_endpoint_data(EP_CONTROL, 16);
  wIndex = usb_format_usb_to_mcu_data(16, wIndex);
  wLength = Usb_read_endpoint_data(EP_CONTROL, 16);
  wLength = usb_format_usb_to_mcu_data(16, wLength);
  Usb_ack_setup_received_free();                          //!< clear the setup received flag

  if (wLength > data_to_transfer)
  {
    zlp = !(data_to_transfer % EP_CONTROL_LENGTH);  //!< zero length packet condition
  }
  else
  {
    data_to_transfer = wLength; //!< send only requested number of data bytes
  }

  Usb_ack_nak_out(EP_CONTROL);

  while (data_to_transfer && (!Is_usb_nak_out(EP_CONTROL)))
  {
    while( !Is_usb_control_in_ready() && !Is_usb_nak_out(EP_CONTROL) );

    if( Is_usb_nak_out(EP_CONTROL) )
       break;    // don't clear the flag now, it will be cleared after

    Usb_reset_endpoint_fifo_access(EP_CONTROL);
    data_to_transfer = usb_write_ep_txpacket(EP_CONTROL, pbuffer,
                                             data_to_transfer, &pbuffer);
    if( Is_usb_nak_out(EP_CONTROL) )
       break;
    else
       Usb_ack_control_in_ready_send();  //!< Send data until necessary
  }

  if ( zlp && (!Is_usb_nak_out(EP_CONTROL)) )
  {
    while (!Is_usb_control_in_ready());
    Usb_ack_control_in_ready_send();
  }

  while (!(Is_usb_nak_out(EP_CONTROL)));
  Usb_ack_nak_out(EP_CONTROL);
  while (!Is_usb_control_out_received());
  Usb_ack_control_out_received_free();
}
コード例 #2
0
//******* Speaker control
void audio_speaker_set_mute(void)
{
   while(!Is_usb_control_out_received())
   {
     TASKS_SCHEDULE();
   }
   Usb_reset_endpoint_fifo_access(EP_CONTROL);
   b_speaker_mute=Usb_read_endpoint_data(EP_CONTROL, 8);
   audio_mixer_mute_audio(b_speaker_mute);

   if( b_speaker_mute )
   {
     audio_mixer_dacs_set_volume_direct((uint8_t)SPEAKER_VOL_MIN);
   }
   else
   {
     audio_mixer_dacs_set_volume_direct(s16_speaker_volume);
   }

   Usb_ack_control_out_received_free();
   Usb_ack_control_in_ready_send();  // send a ZLP
   while (!Is_usb_control_in_ready())
   {
     TASKS_SCHEDULE();
   }
}
コード例 #3
0
void audio_speaker_set_volume(void)
{
   while(!Is_usb_control_out_received())
   {
     TASKS_SCHEDULE();
   }
   Usb_reset_endpoint_fifo_access(EP_CONTROL);
   LSB(s16_usb_speaker_volume)=Usb_read_endpoint_data(EP_CONTROL, 8);
   MSB(s16_usb_speaker_volume)=Usb_read_endpoint_data(EP_CONTROL, 8);

   // Convert USB range volume into the volume range of the application.
   s16_speaker_volume = volume_usb_to_appli(s16_usb_speaker_volume) ;

   Usb_ack_control_out_received_free();
   Usb_ack_control_in_ready_send();  // send a ZLP

   // Ensures good limits of the parameter
   s16_speaker_volume = min( s16_speaker_volume, SPEAKER_VOL_MAX);
   s16_speaker_volume = max( s16_speaker_volume, SPEAKER_VOL_MIN);
   audio_mixer_dacs_set_volume_direct(s16_speaker_volume);
   while (!Is_usb_control_in_ready())
   {
     TASKS_SCHEDULE();
   }
}
コード例 #4
0
ファイル: usb_specific_request.c プロジェクト: Mazetti/asf
//! This function is called by the standard USB read request function when
//! the USB request is not supported. This function returns true when the
//! request is processed. This function returns false if the request is not
//! supported. In this case, a STALL handshake will be automatically
//! sent by the standard USB read request function.
//!
bool usb_user_read_request(U8 type, U8 request)
{
  Usb_read_endpoint_data(EP_CONTROL, 8); // string_type
  Usb_read_endpoint_data(EP_CONTROL, 8); // descriptor_type

  switch (request)
  {
#if( EVK1101_CTRL_PANEL_PID==EVK1101_CTRL_PANEL_DEMO_HID_MS_PID )
  case MASS_STORAGE_RESET:
    Usb_ack_setup_received_free();
    Usb_ack_control_in_ready_send();
    return true;

  case GET_MAX_LUN:
    Usb_ack_setup_received_free();
    Usb_reset_endpoint_fifo_access(EP_CONTROL);
    Usb_write_endpoint_data(EP_CONTROL, 8, get_nb_lun() - 1);
    Usb_ack_control_in_ready_send();
    while (!Is_usb_control_in_ready());

    while(!Is_usb_control_out_received());
    Usb_ack_control_out_received_free();
    ms_multiple_drive = true;
    return true;
#endif

  /*
  case HID_SET_REPORT:
    switch (descriptor_type)
    {
    case HID_REPORT_OUTPUT:
      Usb_ack_setup_received_free();
      while (!Is_usb_control_out_received());
      Usb_ack_control_out_received_free();
      Usb_ack_control_in_ready_send();
      while (!Is_usb_control_in_ready());
      return true;

    default:
      break;
    }
    break;

  case HID_SET_IDLE:
    Usb_ack_setup_received_free();
    Usb_ack_control_in_ready_send();
    while (!Is_usb_control_in_ready());
    return true;
*/

  default:
    break;
  }

  return false;
}
コード例 #5
0
//! This function is called by the standard USB read request function when
//! the USB request is not supported. This function returns true when the
//! request is processed. This function returns false if the request is not
//! supported. In this case, a STALL handshake will be automatically
//! sent by the standard USB read request function.
//!
bool usb_user_read_request(uint8_t type, uint8_t request)
{
   uint16_t wInterface;
   uint8_t wValue_msb;
   uint8_t wValue_lsb;

   wValue_lsb = Usb_read_endpoint_data(EP_CONTROL, 8);
   wValue_msb = Usb_read_endpoint_data(EP_CONTROL, 8);

   //** Specific request from Class MassStorage
   if( USB_SETUP_SET_CLASS_INTER == type )
   {
      switch( request )
      {
         case MASS_STORAGE_RESET:
         // wValue must be 0
         // wIndex = Interface
         if( (0!=wValue_lsb) || (0!=wValue_msb) )
            break;
         wInterface=Usb_read_endpoint_data(EP_CONTROL, 16);
         if( INTERFACE_NB != wInterface )
            break;
         Usb_ack_setup_received_free();
         Usb_ack_control_in_ready_send();
         return true;
      }
   }
   if( USB_SETUP_GET_CLASS_INTER == type )
   {
      switch( request )
      {
         case GET_MAX_LUN:
         // wValue must be 0
         // wIndex = Interface
         if( (0!=wValue_lsb) || (0!=wValue_msb) )
            break;
         wInterface=Usb_read_endpoint_data(EP_CONTROL, 16);
         if( INTERFACE_NB != wInterface )
            break;
         Usb_ack_setup_received_free();
         Usb_reset_endpoint_fifo_access(EP_CONTROL);
         Usb_write_endpoint_data(EP_CONTROL, 8, get_nb_lun() - 1);
         Usb_ack_control_in_ready_send();
         while (!Is_usb_control_in_ready());

         while(!Is_usb_control_out_received());
         Usb_ack_control_out_received_free();

         ms_multiple_drive = true;
         return true;
      }
   }

   return false;
}
コード例 #6
0
//! This function manages the SET ADDRESS request. When complete, the device
//! will filter the requests using the new address.
//!
void usb_set_address(void)
{
  U8 addr = Usb_read_endpoint_data(EP_CONTROL, 8);
  Usb_configure_address(addr);

  Usb_ack_setup_received_free();

  Usb_ack_control_in_ready_send();    //!< send a ZLP for STATUS phase
  while (!Is_usb_control_in_ready()); //!< waits for status phase done
                                      //!< before using the new address
  Usb_enable_address();
}
コード例 #7
0
ファイル: usb_specific_request.c プロジェクト: kerichsen/asf
//!
void usb_hid_set_idle (U8 u8_report_id, U8 u8_duration )
{
   U16 wInterface;

   // Get interface number to put in idle mode
   wInterface=Usb_read_endpoint_data(EP_CONTROL, 16);
   Usb_ack_setup_received_free();

   if( wInterface == INTERFACE_NB )
     g_u8_report_rate = u8_duration;

   Usb_ack_control_in_ready_send();
   while (!Is_usb_control_in_ready());
}
コード例 #8
0
static void usb_hid_set_idle (uint8_t u8_report_id, uint8_t u8_duration )
{
   uint16_t wInterface;

   // Get interface number to put in idle mode
   wInterface=usb_format_usb_to_mcu_data(16, Usb_read_endpoint_data(EP_CONTROL, 16));
   Usb_ack_setup_received_free();

   if( wInterface == INTERFACE_NB_KBD )
     g_u8_report_rate = u8_duration;

   Usb_ack_control_in_ready_send();
   while (!Is_usb_control_in_ready());
}
コード例 #9
0
//******* Micro control
void audio_micro_set_mute(void)
{
   while(!Is_usb_control_out_received())
   {
     TASKS_SCHEDULE();
   }
   Usb_reset_endpoint_fifo_access(EP_CONTROL);
   b_micro_mute=Usb_read_endpoint_data(EP_CONTROL, 8);
   Usb_ack_control_out_received_free();
   Usb_ack_control_in_ready_send();  // send a ZLP
   while (!Is_usb_control_in_ready())
   {
     TASKS_SCHEDULE();
   }
}
コード例 #10
0
ファイル: usb_specific_request.c プロジェクト: kerichsen/asf
void cdc_set_line_coding (void)
{
   Usb_ack_setup_received_free();

   while(!Is_usb_control_out_received());
   Usb_reset_endpoint_fifo_access(EP_CONTROL);

   LSB0(line_coding.dwDTERate) = Usb_read_endpoint_data(EP_CONTROL, 8);
   LSB1(line_coding.dwDTERate) = Usb_read_endpoint_data(EP_CONTROL, 8);
   LSB2(line_coding.dwDTERate) = Usb_read_endpoint_data(EP_CONTROL, 8);
   LSB3(line_coding.dwDTERate) = Usb_read_endpoint_data(EP_CONTROL, 8);
   line_coding.bCharFormat = Usb_read_endpoint_data(EP_CONTROL, 8);
   line_coding.bParityType = Usb_read_endpoint_data(EP_CONTROL, 8);
   line_coding.bDataBits = Usb_read_endpoint_data(EP_CONTROL, 8);
   Usb_ack_control_out_received_free();

   Usb_ack_control_in_ready_send();
   while (!Is_usb_control_in_ready());

   // Set the baudrate of the USART
   {
      static usart_options_t dbg_usart_options;
      uint32_t stopbits, parity;

      if     ( line_coding.bCharFormat==0 )   stopbits = USART_1_STOPBIT;
      else if( line_coding.bCharFormat==1 )   stopbits = USART_1_5_STOPBITS;
      else                                    stopbits = USART_2_STOPBITS;

      if     ( line_coding.bParityType==0 )   parity = USART_NO_PARITY;
      else if( line_coding.bParityType==1 )   parity = USART_ODD_PARITY;
      else if( line_coding.bParityType==2 )   parity = USART_EVEN_PARITY;
      else if( line_coding.bParityType==3 )   parity = USART_MARK_PARITY;
      else                                    parity = USART_SPACE_PARITY;

      // Options for debug USART.
      dbg_usart_options.baudrate    = line_coding.dwDTERate;
      dbg_usart_options.charlength  = line_coding.bDataBits;
      dbg_usart_options.paritytype  = parity;
      dbg_usart_options.stopbits    = stopbits;
      dbg_usart_options.channelmode = USART_NORMAL_CHMODE;

      // Initialize it in RS232 mode.
      usart_init_rs232(DBG_USART, &dbg_usart_options, pcl_freq_param.pba_f);

      // Enable Rx interrupts
      DBG_USART->ier = AVR32_USART_IER_RXRDY_MASK;
   }
}
コード例 #11
0
ファイル: usb_specific_request.c プロジェクト: kerichsen/asf
void usb_hid_set_report_feature(void)
{

   Usb_ack_setup_received_free();
   Usb_ack_control_in_ready_send();// send a ZLP

   while(!Is_usb_control_out_received());

   if(Usb_read_endpoint_data(EP_CONTROL, 8)==0x55)
      if(Usb_read_endpoint_data(EP_CONTROL, 8)==0xAA)
         if(Usb_read_endpoint_data(EP_CONTROL, 8)==0x55)
            if(Usb_read_endpoint_data(EP_CONTROL, 8)==0xAA)
            {
               jump_bootloader=1; // Specific Request with 0x55AA55AA code
            }
   Usb_ack_control_out_received_free();
   Usb_ack_control_in_ready_send();    //!< send a ZLP for STATUS phase
   while(!Is_usb_control_in_ready());
}
コード例 #12
0
ファイル: usb_specific_request.c プロジェクト: kerichsen/asf
void cdc_get_line_coding(void)
{
   Usb_ack_setup_received_free();

   Usb_reset_endpoint_fifo_access(EP_CONTROL);
   Usb_write_endpoint_data(EP_CONTROL, 8, LSB0(line_coding.dwDTERate));
   Usb_write_endpoint_data(EP_CONTROL, 8, LSB1(line_coding.dwDTERate));
   Usb_write_endpoint_data(EP_CONTROL, 8, LSB2(line_coding.dwDTERate));
   Usb_write_endpoint_data(EP_CONTROL, 8, LSB3(line_coding.dwDTERate));
   Usb_write_endpoint_data(EP_CONTROL, 8, line_coding.bCharFormat);
   Usb_write_endpoint_data(EP_CONTROL, 8, line_coding.bParityType);
   Usb_write_endpoint_data(EP_CONTROL, 8, line_coding.bDataBits  );

   Usb_ack_control_in_ready_send();
   while (!Is_usb_control_in_ready());

   while(!Is_usb_control_out_received());
   Usb_ack_control_out_received_free();
}
コード例 #13
0
void audio_speaker_set_sample_freq(void)
{
   uint32_t sample_freq=0;
   Usb_ack_setup_received_free();
   while(!Is_usb_control_out_received())
   {
     TASKS_SCHEDULE();
   }
   Usb_reset_endpoint_fifo_access(EP_CONTROL);
   LSB0(sample_freq)=Usb_read_endpoint_data(EP_CONTROL, 8);
   LSB1(sample_freq)=Usb_read_endpoint_data(EP_CONTROL, 8);
   LSB2(sample_freq)=Usb_read_endpoint_data(EP_CONTROL, 8);
   Usb_ack_control_out_received_free();
   Usb_ack_control_in_ready_send();  // send a ZLP
   while (!Is_usb_control_in_ready())
   {
     TASKS_SCHEDULE();
   }

#if (defined BOARD) && (BOARD==EVK1105) && (defined DEFAULT_DACS) && (DEFAULT_DACS==AUDIO_MIXER_DAC_AIC23B)
   // Disable microphone callback interrupt in order for the flush to not be blocked.
   // TODO: audio_mixer_dacs_flush_direct flushes Rx and Tw part of the DAC.
   //       Should we separate them? Here, we want to flash the output only.
   device_audio_disable_microphone();
#endif
   audio_mixer_dacs_flush_direct(false);
   usb_stream_init(
     sample_freq
   , 2
   , 16
   , false
   );
#if (defined BOARD) && (BOARD==EVK1105) && (defined DEFAULT_DACS) && (DEFAULT_DACS==AUDIO_MIXER_DAC_AIC23B)
   // Enable microphone call back interrupts.
   device_audio_enable_microphone();
#endif
}
コード例 #14
0
ファイル: usb_specific_request.c プロジェクト: kerichsen/asf
//! This function is called by the standard USB read request function when
//! the USB request is not supported. This function returns true when the
//! request is processed. This function returns false if the request is not
//! supported. In this case, a STALL handshake will be automatically
//! sent by the standard USB read request function.
//!
bool usb_user_read_request(U8 type, U8 request)
{
   U8    wValue_msb;
   U8    wValue_lsb;

   // Read wValue
   wValue_lsb = Usb_read_endpoint_data(EP_CONTROL, 8);
   wValue_msb = Usb_read_endpoint_data(EP_CONTROL, 8);
/*
   U8 descriptor_type;

  Usb_read_endpoint_data(EP_CONTROL, 8); // string_type
  descriptor_type = Usb_read_endpoint_data(EP_CONTROL, 8);
*/

   //** Specific request from Class HID
   if( 0x81 == type )   // USB_SETUP_GET_STAND_INTERFACE
   {
      switch( request )
      {
         case GET_DESCRIPTOR:
         switch( wValue_msb ) // Descriptor ID
         {
#if (USB_HIGH_SPEED_SUPPORT==false)
            case HID_DESCRIPTOR:
            hid_get_descriptor(
               sizeof(usb_conf_desc_fs.hid)
            ,  (const U8*)&usb_conf_desc_fs.hid);
            return true;
#else
            case HID_DESCRIPTOR:
            if( Is_usb_full_speed_mode() )
            {
               hid_get_descriptor(
                  sizeof(usb_conf_desc_fs.hid)
               ,  (const U8*)&usb_conf_desc_fs.hid);
            }else{
               hid_get_descriptor(
                  sizeof(usb_conf_desc_hs.hid_mouse)
               ,  (const U8*)&usb_conf_desc_hs.hid);
            }
            return true;
#endif

            case HID_REPORT_DESCRIPTOR:
            hid_get_descriptor(
               sizeof(usb_hid_report_descriptor)
            ,  usb_hid_report_descriptor);
            return true;

            case HID_PHYSICAL_DESCRIPTOR:
            // TODO
            break;
         }
         break;
      }
   }
   if( 0x21 == type ) // USB_SETUP_SET_CLASS_INTER
   {
      switch( request )
      {
         case HID_SET_REPORT:
         // The MSB wValue field specifies the Report Type
         // The LSB wValue field specifies the Report ID
         switch (wValue_msb)
         {
            case HID_REPORT_INPUT:
            // TODO
            break;

            case HID_REPORT_OUTPUT:
            Usb_ack_setup_received_free();
            while (!Is_usb_control_out_received());
            Usb_ack_control_out_received_free();
            Usb_ack_control_in_ready_send();
            while (!Is_usb_control_in_ready());
            return true;

            case HID_REPORT_FEATURE:
            usb_hid_set_report_feature();
            return true;
            break;
         }
         break;

         case HID_SET_IDLE:
         usb_hid_set_idle(wValue_lsb, wValue_msb);
         return true;

         case HID_SET_PROTOCOL:
         // TODO
         break;
      }
   }
   if( 0xA1 == type ) // USB_SETUP_GET_CLASS_INTER
   {
      switch( request )
      {
         case HID_GET_REPORT:
         // TODO
         break;
         case HID_GET_IDLE:
         usb_hid_get_idle(wValue_lsb);
         return true;
         case HID_GET_PROTOCOL:
         // TODO
         break;
      }
   }
   return false;  // No supported request
}
コード例 #15
0
//! This function manages the GET DESCRIPTOR request. The device descriptor,
//! the configuration descriptor and the device qualifier are supported. All
//! other descriptors must be supported by the usb_user_get_descriptor
//! function.
//! Only 1 configuration is supported.
//!
void usb_get_descriptor(void)
{
  Bool    zlp;
  U16     wLength;
  U8      descriptor_type;
  U8      string_type;
  Union32 temp;

  zlp             = FALSE;                                  /* no zero length packet */
  string_type     = Usb_read_endpoint_data(EP_CONTROL, 8);  /* read LSB of wValue    */
  descriptor_type = Usb_read_endpoint_data(EP_CONTROL, 8);  /* read MSB of wValue    */

  switch (descriptor_type)
  {
  case DEVICE_DESCRIPTOR:
    data_to_transfer = Usb_get_dev_desc_length();   //!< sizeof(usb_dev_desc);
    pbuffer          = Usb_get_dev_desc_pointer();
    break;

  case CONFIGURATION_DESCRIPTOR:
    data_to_transfer = Usb_get_conf_desc_length();  //!< sizeof(usb_conf_desc);
    pbuffer          = Usb_get_conf_desc_pointer();
    break;

  default:
    if (!usb_user_get_descriptor(descriptor_type, string_type))
    {
      Usb_enable_stall_handshake(EP_CONTROL);
      Usb_ack_setup_received_free();
      return;
    }
    break;
  }

  temp.u32 = Usb_read_endpoint_data(EP_CONTROL, 32);      //!< read wIndex and wLength with a 32-bit access
                                                          //!< since this access is aligned with a 32-bit
                                                          //!< boundary from the beginning of the endpoint
  wLength = usb_format_usb_to_mcu_data(16, temp.u16[1]);  //!< ignore wIndex, keep and format wLength
  Usb_ack_setup_received_free();                          //!< clear the setup received flag

  if (wLength > data_to_transfer)
  {
    zlp = !(data_to_transfer % EP_CONTROL_LENGTH);  //!< zero length packet condition
  }
  else
  {
    // No need to test ZLP sending since we send the exact number of bytes as
    // expected by the host.
    data_to_transfer = (U8)wLength; //!< send only requested number of data bytes
  }

  Usb_ack_nak_out(EP_CONTROL);

  while (data_to_transfer && !Is_usb_nak_out(EP_CONTROL))
  {
    while (!Is_usb_control_in_ready() && !Is_usb_nak_out(EP_CONTROL));

    if (Is_usb_nak_out(EP_CONTROL))
      break;  // don't clear the flag now, it will be cleared after

    Usb_reset_endpoint_fifo_access(EP_CONTROL);
    data_to_transfer = usb_write_ep_txpacket(EP_CONTROL, pbuffer,
                                             data_to_transfer, &pbuffer);
    if (Is_usb_nak_out(EP_CONTROL))
      break;
    else
      Usb_ack_control_in_ready_send();  //!< Send data until necessary
  }

  if (zlp && !Is_usb_nak_out(EP_CONTROL))
  {
    while (!Is_usb_control_in_ready());
    Usb_ack_control_in_ready_send();
  }

  while (!Is_usb_nak_out(EP_CONTROL));
  Usb_ack_nak_out(EP_CONTROL);
  while (!Is_usb_control_out_received());
  Usb_ack_control_out_received_free();
}
コード例 #16
0
//! This function manages the SET INTERFACE request.
//!
void usb_set_interface(void)
{
  Usb_ack_setup_received_free();
  Usb_ack_control_in_ready_send();  //!< send a ZLP for STATUS phase
  while (!Is_usb_control_in_ready());
}
コード例 #17
0
//! This function is called by the standard USB read request function when
//! the USB request is not supported. This function returns TRUE when the
//! request is processed. This function returns FALSE if the request is not
//! supported. In this case, a STALL handshake will be automatically
//! sent by the standard USB read request function.
//!
Bool uac2_user_read_request(U8 type, U8 request)
{   int i;

	// Read wValue
	// why are these file statics?
	wValue_lsb = Usb_read_endpoint_data(EP_CONTROL, 8);
	wValue_msb = Usb_read_endpoint_data(EP_CONTROL, 8);
	wIndex = usb_format_usb_to_mcu_data(16, Usb_read_endpoint_data(EP_CONTROL, 16));
	wLength = usb_format_usb_to_mcu_data(16, Usb_read_endpoint_data(EP_CONTROL, 16));

	if (type == IN_CL_INTERFACE || type == OUT_CL_INTERFACE){    // process Class Specific Interface


		//  request for AUDIO interfaces

		if (wIndex == DSC_INTERFACE_AS){				// Audio Streaming Interface
			if (type == IN_CL_INTERFACE){			// get controls

				if (wValue_msb == AUDIO_AS_VAL_ALT_SETTINGS && wValue_lsb == 0
					&& request == AUDIO_CS_REQUEST_CUR){
					Usb_ack_setup_received_free();

					Usb_reset_endpoint_fifo_access(EP_CONTROL);
					Usb_write_endpoint_data(EP_CONTROL, 8, 0x01);
					Usb_write_endpoint_data(EP_CONTROL, 8, 0b00000011); // alt 0 and 1 valid
					Usb_ack_control_in_ready_send();

					while (!Is_usb_control_out_received());
					Usb_ack_control_out_received_free();
					return TRUE;
				} else if (wValue_msb == AUDIO_AS_ACT_ALT_SETTINGS && wValue_lsb == 0
 						   && request == AUDIO_CS_REQUEST_CUR){
					Usb_ack_setup_received_free();
					Usb_reset_endpoint_fifo_access(EP_CONTROL);
					Usb_write_endpoint_data(EP_CONTROL, 8, usb_alternate_setting);
					Usb_ack_control_in_ready_send();
					while (!Is_usb_control_out_received());
					Usb_ack_control_out_received_free();
					return TRUE;
				} else if (wValue_msb == AUDIO_AS_AUDIO_DATA_FORMAT && wValue_lsb == 0
 						   && request == AUDIO_CS_REQUEST_CUR){
					Usb_ack_setup_received_free();
					Usb_reset_endpoint_fifo_access(EP_CONTROL);
					Usb_write_endpoint_data(EP_CONTROL, 8, 0x01);
					Usb_write_endpoint_data(EP_CONTROL, 8, 0x00);
					Usb_write_endpoint_data(EP_CONTROL, 8, 0x00);
					Usb_write_endpoint_data(EP_CONTROL, 8, 0x00);	// only PCM format
					Usb_ack_control_in_ready_send();
					while (!Is_usb_control_out_received());
					Usb_ack_control_out_received_free();
					return TRUE;
				} else return FALSE;

			} else if (type == OUT_CL_INTERFACE){		// set controls
				if (wValue_msb == AUDIO_AS_ACT_ALT_SETTINGS
					&& request == AUDIO_CS_REQUEST_CUR){
					Usb_ack_setup_received_free();
					while (!Is_usb_control_out_received());
					Usb_reset_endpoint_fifo_access(EP_CONTROL);
					usb_alternate_setting = Usb_read_endpoint_data(EP_CONTROL, 8);
					usb_alternate_setting_changed = TRUE;
					Usb_ack_control_out_received_free();
					Usb_ack_control_in_ready_send();    //!< send a ZLP for STATUS phase
					while (!Is_usb_control_in_ready()); //!< waits for status phase done
					return FALSE;
				}
			} // end OUT_CL_INTERFACE
		} // end DSC_INTERFACE_AS

		if (wIndex == DSC_INTERFACE_AS_OUT){				// Playback Audio Streaming Interface
			if (type == IN_CL_INTERFACE){			// get controls

				if (wValue_msb == AUDIO_AS_VAL_ALT_SETTINGS && wValue_lsb == 0
					&& request == AUDIO_CS_REQUEST_CUR){
					Usb_ack_setup_received_free();

					Usb_reset_endpoint_fifo_access(EP_CONTROL);
					Usb_write_endpoint_data(EP_CONTROL, 8, 0x01);
					Usb_write_endpoint_data(EP_CONTROL, 8, 0b00000011); // alt 0 and 1 valid
					Usb_ack_control_in_ready_send();

					while (!Is_usb_control_out_received());
					Usb_ack_control_out_received_free();
					return TRUE;
				} else if (wValue_msb == AUDIO_AS_ACT_ALT_SETTINGS && wValue_lsb == 0
 						   && request == AUDIO_CS_REQUEST_CUR){
					Usb_ack_setup_received_free();
					Usb_reset_endpoint_fifo_access(EP_CONTROL);
					Usb_write_endpoint_data(EP_CONTROL, 8, usb_alternate_setting_out);
					Usb_ack_control_in_ready_send();
					while (!Is_usb_control_out_received());
					Usb_ack_control_out_received_free();
					return TRUE;
				} else if (wValue_msb == AUDIO_AS_AUDIO_DATA_FORMAT && wValue_lsb == 0
 						   && request == AUDIO_CS_REQUEST_CUR){
					Usb_ack_setup_received_free();
					Usb_reset_endpoint_fifo_access(EP_CONTROL);
					Usb_write_endpoint_data(EP_CONTROL, 8, 0x01);
					Usb_write_endpoint_data(EP_CONTROL, 8, 0x00);
					Usb_write_endpoint_data(EP_CONTROL, 8, 0x00);
					Usb_write_endpoint_data(EP_CONTROL, 8, 0x00);	// only PCM format
					Usb_ack_control_in_ready_send();
					while (!Is_usb_control_out_received());
					Usb_ack_control_out_received_free();
					return TRUE;
				} else return FALSE;

			} else if (type == OUT_CL_INTERFACE){		// set controls
				if (wValue_msb == AUDIO_AS_ACT_ALT_SETTINGS
					&& request == AUDIO_CS_REQUEST_CUR){
					Usb_ack_setup_received_free();
					while (!Is_usb_control_out_received());
					Usb_reset_endpoint_fifo_access(EP_CONTROL);
					usb_alternate_setting_out = Usb_read_endpoint_data(EP_CONTROL, 8);
					usb_alternate_setting_out_changed = TRUE;
					Usb_ack_control_out_received_free();
					Usb_ack_control_in_ready_send();    //!< send a ZLP for STATUS phase
					while (!Is_usb_control_in_ready()); //!< waits for status phase done
					return FALSE;
				}
			} // end OUT_CL_INTERFACE
		} // end DSC_INTERFACE_AS_OUT

		if ( (wIndex % 256) == DSC_INTERFACE_AUDIO){// low byte wIndex is Interface number
													// high byte is for EntityID

			if (type == IN_CL_INTERFACE){			// get controls
				switch (wIndex /256){
				case CSD_ID_1:
					if (wValue_msb == AUDIO_CS_CONTROL_SAM_FREQ && wValue_lsb == 0
						&& request == AUDIO_CS_REQUEST_CUR){
						Usb_ack_setup_received_free();

						Usb_reset_endpoint_fifo_access(EP_CONTROL);
						Usb_write_endpoint_data(EP_CONTROL, 8, current_freq.freq_bytes[3]); // 0x0000bb80 is 48khz
						Usb_write_endpoint_data(EP_CONTROL, 8, current_freq.freq_bytes[2]); // 0x00017700 is 96khz
						Usb_write_endpoint_data(EP_CONTROL, 8, current_freq.freq_bytes[1]); // 0x0002ee00 is 192khz
						Usb_write_endpoint_data(EP_CONTROL, 8, current_freq.freq_bytes[0]);
						Usb_ack_control_in_ready_send();

						while (!Is_usb_control_out_received());
						Usb_ack_control_out_received_free();
						return TRUE;
					}
					else if (wValue_msb == AUDIO_CS_CONTROL_CLOCK_VALID && wValue_lsb == 0
							 && request == AUDIO_CS_REQUEST_CUR){
						Usb_ack_setup_received_free();

						Usb_reset_endpoint_fifo_access(EP_CONTROL);
						Usb_write_endpoint_data(EP_CONTROL, 8, TRUE);	// always valid
						// temp hack to give total # of bytes requested
						for (i = 0; i < (wLength - 1); i++)
							Usb_write_endpoint_data(EP_CONTROL, 8, 0x00);
						Usb_ack_control_in_ready_send();
						while (!Is_usb_control_out_received());
						Usb_ack_control_out_received_free();
						return TRUE;
					}
					else if (wValue_msb == AUDIO_CS_CONTROL_SAM_FREQ && wValue_lsb == 0
							 && request == AUDIO_CS_REQUEST_RANGE){
						Usb_ack_setup_received_free();

						Usb_reset_endpoint_fifo_access(EP_CONTROL);

						// give total # of bytes requested
						for (i = 0; i < (wLength); i++){
							if (FEATURE_DAC_ES9022)
								Usb_write_endpoint_data(EP_CONTROL, 8, Speedx_1[i]);
							else Usb_write_endpoint_data(EP_CONTROL, 8, Speedx_2[i]);
							}
						Usb_ack_control_in_ready_send();

						while (!Is_usb_control_out_received());
						Usb_ack_control_out_received_free();
						return TRUE;

					} else return FALSE;

				case CSD_ID_2:
					if (wValue_msb == AUDIO_CS_CONTROL_SAM_FREQ && wValue_lsb == 0
						&& request == AUDIO_CS_REQUEST_CUR){
						Usb_ack_setup_received_free();
						Usb_reset_endpoint_fifo_access(EP_CONTROL);
						Usb_write_endpoint_data(EP_CONTROL, 8, current_freq.freq_bytes[3]); // 0x0000bb80 is 48khz
						Usb_write_endpoint_data(EP_CONTROL, 8, current_freq.freq_bytes[2]); // 0x00017700 is 96khz
						Usb_write_endpoint_data(EP_CONTROL, 8, current_freq.freq_bytes[1]); // 0x0002ee00 is 192khz
						Usb_write_endpoint_data(EP_CONTROL, 8, current_freq.freq_bytes[0]);
						Usb_ack_control_in_ready_send();
						while (!Is_usb_control_out_received());
						Usb_ack_control_out_received_free();
						return TRUE;
					}
					else if (wValue_msb == AUDIO_CS_CONTROL_CLOCK_VALID && wValue_lsb == 0
							 && request == AUDIO_CS_REQUEST_CUR){
						Usb_ack_setup_received_free();
						Usb_reset_endpoint_fifo_access(EP_CONTROL);
						Usb_write_endpoint_data(EP_CONTROL, 8, TRUE);	// always valid
						// temp hack to give total # of bytes requested
						for (i = 0; i < (wLength - 1); i++)
							Usb_write_endpoint_data(EP_CONTROL, 8, 0x00);

						Usb_ack_control_in_ready_send();
						while (!Is_usb_control_out_received());
						Usb_ack_control_out_received_free();
						return TRUE;
					}
					else if (wValue_msb == AUDIO_CS_CONTROL_SAM_FREQ && wValue_lsb == 0
							 && request == AUDIO_CS_REQUEST_RANGE){
						Usb_ack_setup_received_free();

						Usb_reset_endpoint_fifo_access(EP_CONTROL);

						// give total # of bytes requested
						for (i = 0; i < (wLength); i++)
							Usb_write_endpoint_data(EP_CONTROL, 8, Speedx_2[i]);
						//							  LED_Toggle(LED0);
						Usb_ack_control_in_ready_send();

						while (!Is_usb_control_out_received());
						Usb_ack_control_out_received_free();
						return TRUE;



					} else return FALSE;


				case CSX_ID:
					if (wValue_msb == AUDIO_CX_CLOCK_SELECTOR && wValue_lsb == 0
						&& request == AUDIO_CS_REQUEST_CUR){
						Usb_ack_setup_received_free();
						Usb_reset_endpoint_fifo_access(EP_CONTROL);
						Usb_write_endpoint_data(EP_CONTROL, 8, clock_selected);
						// temp hack to give total # of bytes requested
						for (i = 0; i < (wLength - 1); i++)
							Usb_write_endpoint_data(EP_CONTROL, 8, 0x00);
						Usb_ack_control_in_ready_send();
						while (!Is_usb_control_out_received());
						Usb_ack_control_out_received_free();
						return TRUE;
					} else return FALSE;

				case MIC_FEATURE_UNIT_ID:
					if (wValue_msb == AUDIO_FU_CONTROL_CS_MUTE
						&& request == AUDIO_CS_REQUEST_CUR){
						Usb_ack_setup_received_free();
						Usb_reset_endpoint_fifo_access(EP_CONTROL);

						Usb_write_endpoint_data(EP_CONTROL, 8, mute);
						// temp hack to give total # of bytes requested
						for (i = 0; i < (wLength - 1); i++)
							Usb_write_endpoint_data(EP_CONTROL, 8, 0x00);

						Usb_ack_control_in_ready_send();
						while (!Is_usb_control_out_received());
						Usb_ack_control_out_received_free();
						return TRUE;
					} else return FALSE;

				case SPK_FEATURE_UNIT_ID:
					if (wValue_msb == AUDIO_FU_CONTROL_CS_MUTE
						&& request == AUDIO_CS_REQUEST_CUR){
						Usb_ack_setup_received_free();
						Usb_reset_endpoint_fifo_access(EP_CONTROL);

						Usb_write_endpoint_data(EP_CONTROL, 8, spk_mute);
						// temp hack to give total # of bytes requested
						for (i = 0; i < (wLength - 1); i++)
							Usb_write_endpoint_data(EP_CONTROL, 8, 0x00);

						Usb_ack_control_in_ready_send();
						while (!Is_usb_control_out_received());
						Usb_ack_control_out_received_free();
						return TRUE;
					} else return FALSE;


				case INPUT_TERMINAL_ID:
					if (wValue_msb == AUDIO_TE_CONTROL_CS_CLUSTER && wValue_lsb == 0
						&& request == AUDIO_CS_REQUEST_CUR){
						Usb_ack_setup_received_free();
						Usb_reset_endpoint_fifo_access(EP_CONTROL);
						if (usb_alternate_setting == 1) {
							Usb_write_endpoint_data(EP_CONTROL, 8, INPUT_TERMINAL_NB_CHANNELS);
							Usb_write_endpoint_data(EP_CONTROL, 8, (U8) INPUT_TERMINAL_CHANNEL_CONF);
							Usb_write_endpoint_data(EP_CONTROL, 8, 0x00);
							Usb_write_endpoint_data(EP_CONTROL, 8, 0x00);
							Usb_write_endpoint_data(EP_CONTROL, 8, 0x00);
							Usb_write_endpoint_data(EP_CONTROL, 8, INPUT_TERMINAL_STRING_DESC);
						}
						else {			// zero's at startup alt setting 0
							Usb_write_endpoint_data(EP_CONTROL, 8, 0x00);
							Usb_write_endpoint_data(EP_CONTROL, 8, 0x00);
							Usb_write_endpoint_data(EP_CONTROL, 8, 0x00);
							Usb_write_endpoint_data(EP_CONTROL, 8, 0x00);
							Usb_write_endpoint_data(EP_CONTROL, 8, 0x00);
							Usb_write_endpoint_data(EP_CONTROL, 8, 0x00);
						};
						Usb_ack_control_in_ready_send();
						while (!Is_usb_control_out_received());
						Usb_ack_control_out_received_free();
						return TRUE;
					} else return FALSE;

				case SPK_INPUT_TERMINAL_ID:
					if (wValue_msb == AUDIO_TE_CONTROL_CS_CLUSTER && wValue_lsb == 0
						&& request == AUDIO_CS_REQUEST_CUR){
						Usb_ack_setup_received_free();
						Usb_reset_endpoint_fifo_access(EP_CONTROL);
						if (usb_alternate_setting_out == 1) {
							Usb_write_endpoint_data(EP_CONTROL, 8, SPK_INPUT_TERMINAL_NB_CHANNELS);
							Usb_write_endpoint_data(EP_CONTROL, 8, (U8) SPK_INPUT_TERMINAL_CHANNEL_CONF);
							Usb_write_endpoint_data(EP_CONTROL, 8, 0x00);
							Usb_write_endpoint_data(EP_CONTROL, 8, 0x00);
							Usb_write_endpoint_data(EP_CONTROL, 8, 0x00);
							Usb_write_endpoint_data(EP_CONTROL, 8, INPUT_TERMINAL_STRING_DESC);
						}
						else {			// zero's at startup alt setting 0
							Usb_write_endpoint_data(EP_CONTROL, 8, 0x00);
							Usb_write_endpoint_data(EP_CONTROL, 8, 0x00);
							Usb_write_endpoint_data(EP_CONTROL, 8, 0x00);
							Usb_write_endpoint_data(EP_CONTROL, 8, 0x00);
							Usb_write_endpoint_data(EP_CONTROL, 8, 0x00);
							Usb_write_endpoint_data(EP_CONTROL, 8, 0x00);
						};
						Usb_ack_control_in_ready_send();
						while (!Is_usb_control_out_received());
						Usb_ack_control_out_received_free();
						return TRUE;
					} else return FALSE;
				default:
					return FALSE;
				} // end switch EntityID
			} else if (type == OUT_CL_INTERFACE){		// set controls
				switch (wIndex /256){
				case CSD_ID_1:							// set CUR freq
				case CSD_ID_2:
					if (wValue_msb == AUDIO_CS_CONTROL_SAM_FREQ && wValue_lsb == 0
						&& request == AUDIO_CS_REQUEST_CUR){
						Usb_ack_setup_received_free();
						while (!Is_usb_control_out_received());
						Usb_reset_endpoint_fifo_access(EP_CONTROL);
						current_freq.freq_bytes[3]=Usb_read_endpoint_data(EP_CONTROL, 8);		// read 4 bytes freq to set
						current_freq.freq_bytes[2]=Usb_read_endpoint_data(EP_CONTROL, 8);
						current_freq.freq_bytes[1]=Usb_read_endpoint_data(EP_CONTROL, 8);
						current_freq.freq_bytes[0]=Usb_read_endpoint_data(EP_CONTROL, 8);
						freq_changed = TRUE;
						Usb_ack_control_out_received_free();
						Usb_ack_control_in_ready_send();    //!< send a ZLP for STATUS phase
						while (!Is_usb_control_in_ready()); //!< waits for status phase done
						return TRUE;
					}
					else return FALSE;
				case CSX_ID:
					if (wValue_msb == AUDIO_CX_CLOCK_SELECTOR && wValue_lsb == 0
						&& request == AUDIO_CS_REQUEST_CUR){
						Usb_ack_setup_received_free();
						while (!Is_usb_control_out_received());
						Usb_reset_endpoint_fifo_access(EP_CONTROL);
						clock_selected = Usb_read_endpoint_data(EP_CONTROL, 8);
						clock_changed = TRUE;
						Usb_ack_control_out_received_free();
						Usb_ack_control_in_ready_send();    //!< send a ZLP for STATUS phase
						while (!Is_usb_control_in_ready()); //!< waits for status phase done
						if (clock_selected < 1 || clock_selected > CSX_INPUT_PINS)
							clock_selected = 1;
						return TRUE;
					} else return FALSE;
				case MIC_FEATURE_UNIT_ID:
					if (wValue_msb == AUDIO_FU_CONTROL_CS_MUTE
						&& request == AUDIO_CS_REQUEST_CUR){
						Usb_ack_setup_received_free();
						while (!Is_usb_control_out_received());
						Usb_reset_endpoint_fifo_access(EP_CONTROL);
						mute = Usb_read_endpoint_data(EP_CONTROL, 8);
						Usb_ack_control_out_received_free();
						Usb_ack_control_in_ready_send();    //!< send a ZLP for STATUS phase
						while (!Is_usb_control_in_ready()); //!< waits for status phase done
						return TRUE;
					} else return FALSE;
				case SPK_FEATURE_UNIT_ID:
					if (wValue_msb == AUDIO_FU_CONTROL_CS_MUTE
						&& request == AUDIO_CS_REQUEST_CUR){
						Usb_ack_setup_received_free();
						while (!Is_usb_control_out_received());
						Usb_reset_endpoint_fifo_access(EP_CONTROL);
						spk_mute = Usb_read_endpoint_data(EP_CONTROL, 8);
						Usb_ack_control_out_received_free();
						Usb_ack_control_in_ready_send();    //!< send a ZLP for STATUS phase
						while (!Is_usb_control_in_ready()); //!< waits for status phase done
						return TRUE;
					} else return FALSE;
				default:
					return FALSE;
				}
			} // end OUT_CL_INTERFACE

		} // end Audio Control Interface


	} // end CL_INTERFACE

	return FALSE;  // No supported request
}
コード例 #18
0
ファイル: usb_specific_request.c プロジェクト: kerichsen/asf
void cdc_set_control_line_state (void)
{
   Usb_ack_setup_received_free();
   Usb_ack_control_in_ready_send();
   while (!Is_usb_control_in_ready());
}
コード例 #19
0
//! This function manages the GET DESCRIPTOR request. The device descriptor,
//! the configuration descriptor and the device qualifier are supported. All
//! other descriptors must be supported by the usb_user_get_descriptor
//! function.
//! Only 1 configuration is supported.
//!
void usb_get_descriptor(void)
{
  bool    zlp;
  U16     wLength;
  U8      descriptor_type;
  U8      string_type;
  Union32 temp;
#if (USB_HIGH_SPEED_SUPPORT==true)
  bool    b_first_data = true;
#endif

  zlp             = false;                                  /* no zero length packet */
  string_type     = Usb_read_endpoint_data(EP_CONTROL, 8);  /* read LSB of wValue    */
  descriptor_type = Usb_read_endpoint_data(EP_CONTROL, 8);  /* read MSB of wValue    */

  switch (descriptor_type)
  {
  case DEVICE_DESCRIPTOR:
    data_to_transfer = Usb_get_dev_desc_length();   //!< sizeof(usb_dev_desc);
    pbuffer          = Usb_get_dev_desc_pointer();
    break;

#if (USB_HIGH_SPEED_SUPPORT==false)
  case CONFIGURATION_DESCRIPTOR:
    data_to_transfer = Usb_get_conf_desc_length();  //!< sizeof(usb_conf_desc);
    pbuffer          = Usb_get_conf_desc_pointer();
    break;

#else
  case CONFIGURATION_DESCRIPTOR:
    if( Is_usb_full_speed_mode() )
    {
       data_to_transfer = Usb_get_conf_desc_fs_length();  //!< sizeof(usb_conf_desc_fs);
       pbuffer          = Usb_get_conf_desc_fs_pointer();
    }else{
       data_to_transfer = Usb_get_conf_desc_hs_length();  //!< sizeof(usb_conf_desc_hs);
       pbuffer          = Usb_get_conf_desc_hs_pointer();
    }
    break;

  case OTHER_SPEED_CONFIGURATION_DESCRIPTOR:
    if( !Is_usb_full_speed_mode() )
    {
       data_to_transfer = Usb_get_conf_desc_fs_length();  //!< sizeof(usb_conf_desc_fs);
       pbuffer          = Usb_get_conf_desc_fs_pointer();
    }else{
       data_to_transfer = Usb_get_conf_desc_hs_length();  //!< sizeof(usb_conf_desc_hs);
       pbuffer          = Usb_get_conf_desc_hs_pointer();
    }
    break;

  case DEVICE_QUALIFIER_DESCRIPTOR:
    data_to_transfer = Usb_get_qualifier_desc_length();  //!< sizeof(usb_qualifier_desc);
    pbuffer          = Usb_get_qualifier_desc_pointer();
    break;

#endif

  default:
    if (!usb_user_get_descriptor(descriptor_type, string_type))
    {
      Usb_enable_stall_handshake(EP_CONTROL);
      Usb_ack_setup_received_free();
      return;
    }
    break;
  }

  temp.u32 = Usb_read_endpoint_data(EP_CONTROL, 32);      //!< read wIndex and wLength with a 32-bit access
                                                          //!< since this access is aligned with a 32-bit
                                                          //!< boundary from the beginning of the endpoint
  wLength = usb_format_usb_to_mcu_data(16, temp.u16[1]);  //!< ignore wIndex, keep and format wLength
  Usb_ack_setup_received_free();                          //!< clear the setup received flag

  if (wLength > data_to_transfer)
  {
    zlp = !(data_to_transfer % EP_CONTROL_LENGTH);  //!< zero length packet condition
  }
  else
  {
    // No need to test ZLP sending since we send the exact number of bytes as
    // expected by the host.
    data_to_transfer = wLength; //!< send only requested number of data bytes
  }

  Usb_ack_nak_out(EP_CONTROL);

  while (data_to_transfer && !Is_usb_nak_out(EP_CONTROL))
  {
    while (!Is_usb_control_in_ready() && !Is_usb_nak_out(EP_CONTROL));

    if (Is_usb_nak_out(EP_CONTROL))
      break;  // don't clear the flag now, it will be cleared after

    Usb_reset_endpoint_fifo_access(EP_CONTROL);

#if (USB_HIGH_SPEED_SUPPORT==true) // To support other descriptors like OTHER_SPEED_CONFIGURATION_DESCRIPTOR
    if( b_first_data ) {
      b_first_data = false;
      if( 0!= data_to_transfer ) {
        usb_write_ep_txpacket(EP_CONTROL, pbuffer, 1, &pbuffer);
        data_to_transfer--;
      }
      if( 0!= data_to_transfer ) {
        usb_write_ep_txpacket(EP_CONTROL, &descriptor_type, 1, NULL);
        pbuffer = ((const U8*)pbuffer)+1;
        data_to_transfer--;
      }
    }
#endif
    if( 0!= data_to_transfer ) {
       data_to_transfer = usb_write_ep_txpacket(EP_CONTROL, pbuffer,
                                                data_to_transfer, &pbuffer);
    }
    if (Is_usb_nak_out(EP_CONTROL))
      break;

    Usb_ack_control_in_ready_send();  //!< Send data until necessary
  }

  if (zlp && !Is_usb_nak_out(EP_CONTROL))
  {
    while (!Is_usb_control_in_ready());
    Usb_ack_control_in_ready_send();
  }

  while (!Is_usb_nak_out(EP_CONTROL));
  Usb_ack_nak_out(EP_CONTROL);
  while (!Is_usb_control_out_received());
  Usb_ack_control_out_received_free();
}
コード例 #20
0
//! This function manages the SET INTERFACE request.
//!
void usb_set_interface(void)
{
   U8 u8_i;

   // wValue = Alternate Setting
   // wIndex = Interface
   U16 wValue  = usb_format_usb_to_mcu_data(16, Usb_read_endpoint_data(EP_CONTROL, 16));
   U16 wIndex  = usb_format_usb_to_mcu_data(16, Usb_read_endpoint_data(EP_CONTROL, 16));
   Usb_ack_setup_received_free();

   // Get descriptor
#if (USB_HIGH_SPEED_SUPPORT==true)
   if( Is_usb_full_speed_mode() )
   {
      data_to_transfer = Usb_get_conf_desc_fs_length();  //!< sizeof(usb_conf_desc_fs);
      pbuffer          = Usb_get_conf_desc_fs_pointer();
   }else{
      data_to_transfer = Usb_get_conf_desc_hs_length();  //!< sizeof(usb_conf_desc_hs);
      pbuffer          = Usb_get_conf_desc_hs_pointer();
   }
#else
   data_to_transfer = Usb_get_conf_desc_length();  //!< sizeof(usb_conf_desc);
   pbuffer          = Usb_get_conf_desc_pointer();
#endif

   //** Scan descriptor

   //* Find configuration selected
   if( usb_configuration_nb == 0 )
   {
      // No configuration selected then no interface enable
      Usb_enable_stall_handshake(EP_CONTROL);
      Usb_ack_setup_received_free();
      return;
   }
   u8_i = usb_configuration_nb;
   while( u8_i != 0 )
   {
      if( CONFIGURATION_DESCRIPTOR != ((S_usb_configuration_descriptor*)pbuffer)->bDescriptorType )
      {
         data_to_transfer -=  ((S_usb_configuration_descriptor*)pbuffer)->bLength;
         pbuffer =  (U8*)pbuffer + ((S_usb_configuration_descriptor*)pbuffer)->bLength;
         continue;
      }
      u8_i--;
      if( u8_i != 0 )
      {
         data_to_transfer -=  ((S_usb_configuration_descriptor*)pbuffer)->wTotalLength;
         pbuffer =  (U8*)pbuffer + ((S_usb_configuration_descriptor*)pbuffer)->wTotalLength;
      }
   }

   // Find interface selected
   if( wIndex >= ((S_usb_configuration_descriptor*)pbuffer)->bNumInterfaces )
   {
      // Interface number unknown
      Usb_enable_stall_handshake(EP_CONTROL);
      Usb_ack_setup_received_free();
      return;
   }
   while( 1 )
   {
      if( data_to_transfer <= ((S_usb_interface_descriptor*)pbuffer)->bLength )
      {
         // Interface unknown
         Usb_enable_stall_handshake(EP_CONTROL);
         Usb_ack_setup_received_free();
         return;
      }
      data_to_transfer -=  ((S_usb_interface_descriptor*)pbuffer)->bLength;
      pbuffer =  (U8*)pbuffer + ((S_usb_interface_descriptor*)pbuffer)->bLength;
      if( INTERFACE_DESCRIPTOR != ((S_usb_interface_descriptor*)pbuffer)->bDescriptorType )
         continue;
      if( wIndex != ((S_usb_interface_descriptor*)pbuffer)->bInterfaceNumber )
         continue;
      if( wValue != ((S_usb_interface_descriptor*)pbuffer)->bAlternateSetting )
         continue;
      usb_interface_status[wIndex] = wValue;
      break;
   }

   //* Find endpoints of interface and reset it
   while( 1 )
   {
      if( data_to_transfer <= ((S_usb_endpoint_descriptor*)pbuffer)->bLength )
         break;    // End of interface
      data_to_transfer -=  ((S_usb_endpoint_descriptor*)pbuffer)->bLength;
      pbuffer =  (U8*)pbuffer + ((S_usb_endpoint_descriptor*)pbuffer)->bLength;
      if( INTERFACE_DESCRIPTOR == ((S_usb_endpoint_descriptor*)pbuffer)->bDescriptorType )
         break;    // End of interface
      if( ENDPOINT_DESCRIPTOR == ((S_usb_endpoint_descriptor*)pbuffer)->bDescriptorType )
      {
         // Reset endpoint
         u8_i = ((S_usb_endpoint_descriptor*)pbuffer)->bEndpointAddress & (~MSK_EP_DIR);
         Usb_disable_stall_handshake(u8_i);
         Usb_reset_endpoint(u8_i);
         Usb_reset_data_toggle(u8_i);
      }
   }

   // send a ZLP for STATUS phase
   Usb_ack_control_in_ready_send();
   while (!Is_usb_control_in_ready());
}
コード例 #21
0
//! This function manages the SET FEATURE request. The USB test modes are
//! supported by this function.
//!
void usb_set_feature(void)
{
  U16 wValue  = usb_format_usb_to_mcu_data(16, Usb_read_endpoint_data(EP_CONTROL, 16));
  U16 wIndex  = usb_format_usb_to_mcu_data(16, Usb_read_endpoint_data(EP_CONTROL, 16));
  U16 wLength = usb_format_usb_to_mcu_data(16, Usb_read_endpoint_data(EP_CONTROL, 16));

  if (wLength)
    goto unsupported_request;

   if (bmRequestType==USB_SETUP_SET_STAND_DEVICE) {
#if (USB_REMOTE_WAKEUP_FEATURE == true)
      if (FEATURE_DEVICE_REMOTE_WAKEUP == wValue)
      {
         device_status |= USB_DEV_STATUS_REMOTEWAKEUP;
         remote_wakeup_feature = true;
         Usb_ack_setup_received_free();
         Usb_ack_control_in_ready_send();
         return;
      }
#endif
      goto unsupported_request;
   }

  switch (wValue)
  {
  case FEATURE_ENDPOINT_HALT:
    wIndex = Get_desc_ep_nbr(wIndex);  // clear direction flag
    if (bmRequestType != ENDPOINT_TYPE ||
        wIndex == EP_CONTROL ||
        !Is_usb_endpoint_enabled(wIndex))
      goto unsupported_request;

    Usb_enable_stall_handshake(wIndex);
    Usb_ack_setup_received_free();
    Usb_ack_control_in_ready_send();
    break;

#if (USB_HIGH_SPEED_SUPPORT==true)
  case FEATURE_TEST_MODE:
    if (bmRequestType != DEVICE_TYPE ||
        wIndex & 0x00FF)
      goto unsupported_request;

    switch (wIndex >> 8)
    {
    case TEST_J:
      Usb_ack_setup_received_free();
      Usb_ack_control_in_ready_send();
      while (!Is_usb_control_in_ready());
      Wr_bitfield(AVR32_USBB_udcon, AVR32_USBB_UDCON_SPDCONF_MASK, 2);
      Set_bits(AVR32_USBB_udcon, AVR32_USBB_UDCON_TSTJ_MASK);
      break;

    case TEST_K:
      Usb_ack_setup_received_free();
      Usb_ack_control_in_ready_send();
      while (!Is_usb_control_in_ready());
      Wr_bitfield(AVR32_USBB_udcon, AVR32_USBB_UDCON_SPDCONF_MASK, 2);
      Set_bits(AVR32_USBB_udcon, AVR32_USBB_UDCON_TSTK_MASK);
      break;

    case TEST_SE0_NAK:
      Usb_ack_setup_received_free();
      Usb_ack_control_in_ready_send();
      while (!Is_usb_control_in_ready());
      Wr_bitfield(AVR32_USBB_udcon, AVR32_USBB_UDCON_SPDCONF_MASK, 2);
      break;

    case TEST_PACKET:
      {
        static const U8 test_packet[] =
        {
          // 00000000 * 9
          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
          // 01010101 * 8
          0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
          // 01110111 * 8
          0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE,
          // 0, {111111S * 15}, 111111
          0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
          // S, 111111S, {0111111S * 7}
          0x7F, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD,
          // 00111111, {S0111111 * 9}, S0
          0xFC, 0x7E, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, 0x7E
        };

        Usb_ack_setup_received_free();
        Usb_ack_control_in_ready_send();
        while (!Is_usb_control_in_ready());
        Wr_bitfield(AVR32_USBB_udcon, AVR32_USBB_UDCON_SPDCONF_MASK, 2);
        Usb_disable_endpoint(EP_CONTROL);
        Usb_unallocate_memory(EP_CONTROL);
        (void)Usb_configure_endpoint(EP_CONTROL,
                                     TYPE_BULK,
                                     DIRECTION_IN,
                                     64,
                                     SINGLE_BANK);
        Usb_reset_endpoint(EP_CONTROL);
        Set_bits(AVR32_USBB_udcon, AVR32_USBB_UDCON_TSTPCKT_MASK);
        usb_write_ep_txpacket(EP_CONTROL, &test_packet, sizeof(test_packet), NULL);
        Usb_send_in(EP_CONTROL);
      }
      break;

    case TEST_FORCE_ENABLE: // Only for downstream facing hub ports
    default:
      goto unsupported_request;
    }
    break;
#endif

  case FEATURE_DEVICE_REMOTE_WAKEUP:
  default:
    goto unsupported_request;
  }

  return;

unsupported_request:
  Usb_enable_stall_handshake(EP_CONTROL);
  Usb_ack_setup_received_free();
}