Defines | Functions | Variables

# usb_standard_request.c File Reference

Process USB device enumeration requests. More...

`#include "config.h"`
`#include "conf_usb.h"`
`#include "lib_mcu/usb/usb_drv.h"`
`#include "lib_mcu/pll/pll_drv.h"`
`#include "usb_descriptors.h"`
`#include "modules/usb/device_chap9/usb_standard_request.h"`
`#include "usb_specific_request.h"`
Include dependency graph for usb_standard_request.c:

Go to the source code of this file.

## Defines
#define | Usb_write_PGM_byte(byte) (Usb_write_byte(*byte))
## Functions
static Bool | usb_get_descriptor (void)
| This function manages the GET DESCRIPTOR request.
static void | usb_set_address (void)
| This function manages the SET ADDRESS request.
static Bool | usb_set_configuration (void)
| This function manages the SET CONFIGURATION request.
static void | usb_get_configuration (void)
| This function manages the GET CONFIGURATION request.
static Bool | usb_get_status (U8 bmRequestType)
| This function manages the GET STATUS request.
static Bool | usb_set_feature (U8 bmRequestType)
| This function manages the SET FEATURE request.
static Bool | usb_clear_feature (U8 bmRequestType)
| This function manages the SET FEATURE request.
static Bool | usb_get_interface (void)
| This function manages the SETUP_GET_INTERFACE request.
static Bool | usb_set_interface (void)
| This function manages the SETUP_SET_INTERFACE request.
void | usb_process_request (void)
| This function reads the SETUP request sent to the default control endpoint and calls the appropriate function.
void | usb_generate_remote_wakeup (void)
| This function manages the remote wake up generation.
## Variables
U8 code * | pbuffer
U8 | endpoint_status [7]
U8 | data_to_transfer
U8 | usb_configuration_nb
| Public : (U8) usb_configuration_nb Store the number of the USB configuration used by the USB device when its value is different from zero, it means the device mode is enumerated Used with USB_DEVICE_FEATURE == ENABLED only /.
U8 | remote_wakeup_feature = 0
| Public : (U8) remote_wakeup_feature Store a host request for remote wake up (set feature received) /.
U8 | device_status = USB_DEVICE_STATUS_BUS_POWERED

## Detailed Description

Process USB device enumeration requests.

This file contains the USB endpoint 0 management routines corresponding to the standard enumeration process (refer to chapter 9 of the USB specification. This file calls routines of the usb_specific_request.c file for non-standard request management. The enumeration parameters (descriptor tables) are contained in the usb_descriptors.c file.

- Compiler: IAR EWAVR and GNU GCC for AVR
- Supported devices: ATmega32U4

Author:
  Atmel Corporation: http://www.atmel.com
  Support and FAQ: http://support.atmel.no/

Definition in file usb_standard_request.c.

## Define Documentation

#define Usb_write_PGM_byte | ( |  | byte ) | (Usb_write_byte(*byte))

Definition at line 95 of file usb_standard_request.c.

Referenced by usb_get_descriptor().

## Function Documentation

Bool usb_get_descriptor | ( | void | ) | `[static]`

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.

< sizeof (usb_user_device_descriptor);

< sizeof (usb_user_configuration_descriptor);

< don't care of wIndex field

< read wLength

< clear the receive setup flag

< send only requested number of data

< Send data until necessary

< Check endpoint 0 size

Definition at line 246 of file usb_standard_request.c.

References data_to_transfer, DESCRIPTOR_CONFIGURATION, DESCRIPTOR_DEVICE, EP_CONTROL_LENGTH, FALSE, Flash_read_sn, Is_usb_nak_out_sent, Is_usb_read_control_enabled, LSB, MSB, pbuffer, TRUE, Usb_ack_control_out, Usb_ack_nak_out, Usb_ack_receive_setup, Usb_get_conf_desc_length, Usb_get_conf_desc_pointer, Usb_get_dev_desc_length, Usb_get_dev_desc_pointer, Usb_read_byte, Usb_send_control_in, usb_user_get_descriptor(), Usb_write_byte, and Usb_write_PGM_byte.

Referenced by usb_process_request().

    {
       Bool zlp;
       U16  wLength;
       U8   descriptor_type ;
       U8   string_type;
       U8   dummy;
       U8   nb_byte;
       U8   byte_to_send;
    #if (USE_DEVICE_SN_UNIQUE==ENABLE)
       U16  sn_index=0;
       U8   initial_data_to_transfer;
    #endif

       zlp             = FALSE;                  /* no zero length packet */
       string_type     = Usb_read_byte();        /* read LSB of wValue    */
       descriptor_type = Usb_read_byte();        /* read MSB of wValue    */

       switch (descriptor_type)
       {
          case DESCRIPTOR_DEVICE:
          data_to_transfer = Usb_get_dev_desc_length();
          pbuffer          = Usb_get_dev_desc_pointer();
          break;

          case DESCRIPTOR_CONFIGURATION:
          data_to_transfer = Usb_get_conf_desc_length();
          pbuffer          = Usb_get_conf_desc_pointer();
          break;

          default:
          if( !usb_user_get_descriptor(descriptor_type, string_type))
             return FALSE;  // Unknow descriptor then stall request
          break;
       }

       dummy = Usb_read_byte();
       dummy = Usb_read_byte();
       LSB(wLength) = Usb_read_byte();
       MSB(wLength) = Usb_read_byte();
       Usb_ack_receive_setup() ;

       if (wLength > data_to_transfer)
       {
          if ((data_to_transfer % EP_CONTROL_LENGTH) == 0) { zlp = TRUE; }
          else { zlp = FALSE; }
       }
       else
       {
          data_to_transfer = (U8)wLength;
       }

       Usb_ack_nak_out();

       byte_to_send=0;
    #if (USE_DEVICE_SN_UNIQUE==ENABLE)
       initial_data_to_transfer = data_to_transfer;
    #endif
       while((data_to_transfer != 0) && (!Is_usb_nak_out_sent()))
       {
          while(!Is_usb_read_control_enabled())
          {
             if (Is_usb_nak_out_sent())
                break;    // don't clear the flag now, it will be cleared after
          }

          nb_byte=0;
          while(data_to_transfer != 0)
          {
             if(nb_byte++==EP_CONTROL_LENGTH)
                break;

    #if (USE_DEVICE_SN_UNIQUE==ENABLE)

             if(f_get_serial_string && (data_to_transfer < (initial_data_to_transfer-1)))    //if we are sending the signature characters (third byte and more...)
             {                                                                              //(The first two bytes are the length and the descriptor)

                switch (byte_to_send)
                {
                   case 0:
                   Usb_write_byte(bin_to_ascii((Flash_read_sn(sn_index)>>4) & 0x0F)); //sends the fist part (MSB) of the signature hex number, converted in ascii
                   break;

                   case 1:
                   Usb_write_byte(0);                                                   //then, sends a null character (Usb_unicode)
                   break;

                   case 2:
                   Usb_write_byte(bin_to_ascii(Flash_read_sn(sn_index) & 0x0F));      //sends the second part (LSB) of the signature hex number, converted in ascii
                   break;

                   case 3:
                   Usb_write_byte(0);                                                   //then, sends a null character (Usb_unicode)
                   sn_index++;                                                         //increments the signature address pointer.
                   break;
                }
                byte_to_send = (byte_to_send+1)%4;
             }
             else
             {
                Usb_write_PGM_byte(pbuffer++);                                                 //Write a flash byte to USB
             }
    #else
             Usb_write_PGM_byte(pbuffer++);
    #endif
             data_to_transfer --;                                                             //decrements the number of bytes to transmit.
          }

          if (Is_usb_nak_out_sent())
             break;
          else
             Usb_send_control_in();
       }

    #if (USE_DEVICE_SN_UNIQUE==ENABLE)
       f_get_serial_string=FALSE;                                                   //end of signature transmission
    #endif

       if((zlp == TRUE) && (!Is_usb_nak_out_sent()))
       {
          while(!Is_usb_read_control_enabled());
          Usb_send_control_in();
       }

       while (!(Is_usb_nak_out_sent()));
       Usb_ack_nak_out();
       Usb_ack_control_out();
       return TRUE;
    }

Here is the call graph for this function:

Here is the caller graph for this function:

void usb_set_address | ( | void | ) | `[static]`

This function manages the SET ADDRESS request.

When complete, the device will filter the requests using the new address.

Definition at line 203 of file usb_standard_request.c.

References Is_usb_in_ready, Usb_ack_receive_setup, Usb_configure_address, Usb_enable_address, Usb_read_byte, and Usb_send_control_in.

Referenced by usb_process_request().

    {
       U8 addr = Usb_read_byte();
       Usb_configure_address(addr);

       Usb_ack_receive_setup();

       Usb_send_control_in();                    // send a ZLP for STATUS phase
       while(!Is_usb_in_ready());                // waits for status phase done
                                                 // before using the new address
       Usb_enable_address();
    }

Here is the caller graph for this function:

Bool usb_set_configuration | ( | void | ) | `[static]`

This function manages the SET CONFIGURATION request.

If the selected configuration is valid, this function call the usb_user_endpoint_init() function that will configure the endpoints following the configuration number.

Definition at line 222 of file usb_standard_request.c.

References FALSE, NB_CONFIGURATION, TRUE, Usb_ack_receive_setup, usb_configuration_nb, Usb_read_byte, Usb_send_control_in, Usb_set_configuration_action, and usb_user_endpoint_init().

Referenced by usb_process_request().

    {
       U8 configuration_number;

       // Get/Check new configuration
       configuration_number = Usb_read_byte();
       if (configuration_number > NB_CONFIGURATION)
          return FALSE;  //  Bad configuration number then stall request
       Usb_ack_receive_setup();
       usb_configuration_nb = configuration_number;

       Usb_send_control_in();                          // send a ZLP for STATUS phase
       usb_user_endpoint_init(usb_configuration_nb);   // endpoint configuration
       Usb_set_configuration_action();
       return TRUE;
    }

Here is the call graph for this function:

Here is the caller graph for this function:

void usb_get_configuration | ( | void | ) | `[static]`

This function manages the GET CONFIGURATION request.

The current configuration number is returned.

Definition at line 380 of file usb_standard_request.c.

References Is_usb_receive_out, Usb_ack_in_ready, Usb_ack_receive_out, Usb_ack_receive_setup, usb_configuration_nb, and Usb_write_byte.

Referenced by usb_process_request().

    {
       Usb_ack_receive_setup();

       Usb_write_byte(usb_configuration_nb);
       Usb_ack_in_ready();

       while( !Is_usb_receive_out() );
       Usb_ack_receive_out();
    }

Here is the caller graph for this function:

Bool usb_get_status | ( | U8 | bmRequestType ) | `[static]`

This function manages the GET STATUS request.

The device, interface or endpoint status is returned.

< dummy read

< dummy read

Definition at line 395 of file usb_standard_request.c.

References device_status, endpoint_status, FALSE, Is_usb_receive_out, MSK_EP_DIR, TRUE, Usb_ack_receive_out, Usb_ack_receive_setup, Usb_read_byte, Usb_send_control_in, USB_SETUP_GET_STAND_DEVICE, USB_SETUP_GET_STAND_ENDPOINT, USB_SETUP_GET_STAND_INTERFACE, and Usb_write_byte.

Referenced by usb_process_request().

    {
       U8 wIndex;
       U8 dummy;

       dummy    = Usb_read_byte();
       dummy    = Usb_read_byte();
       wIndex   = Usb_read_byte();

       switch(bmRequestType)
       {
          case USB_SETUP_GET_STAND_DEVICE:
          Usb_ack_receive_setup();
          Usb_write_byte(device_status);
          break;

          case USB_SETUP_GET_STAND_INTERFACE:
          Usb_ack_receive_setup();
          Usb_write_byte(0);      // Reserved - always 0
          break;

          case USB_SETUP_GET_STAND_ENDPOINT:
          Usb_ack_receive_setup();
          wIndex = wIndex & MSK_EP_DIR;
          Usb_write_byte( endpoint_status[wIndex] );
          break;

          default:
          return FALSE;
       }
       Usb_write_byte(0);

       Usb_send_control_in();
       while( !Is_usb_receive_out() );
       Usb_ack_receive_out();
       return TRUE;
    }

Here is the caller graph for this function:

Bool usb_set_feature | ( | U8 | bmRequestType ) | `[static]`

This function manages the SET FEATURE request.

The USB test modes are supported by this function.

< dummy read

Definition at line 437 of file usb_standard_request.c.

References device_status, ENABLED, endpoint_status, EP_CONTROL, FALSE, FEATURE_DEVICE_REMOTE_WAKEUP, FEATURE_ENDPOINT_HALT, Is_usb_endpoint_enabled, MSK_EP_DIR, remote_wakeup_feature, TRUE, Usb_ack_receive_setup, USB_DEVICE_STATUS_REMOTEWAKEUP, Usb_enable_stall_handshake, Usb_read_byte, USB_REMOTE_WAKEUP, USB_REMOTE_WAKEUP_FEATURE, Usb_select_endpoint, Usb_send_control_in, USB_SETUP_SET_STAND_DEVICE, USB_SETUP_SET_STAND_ENDPOINT, and USB_SETUP_SET_STAND_INTERFACE.

Referenced by usb_process_request().

    {
       U8 wValue;
       U8 wIndex;
       U8 dummy;

       switch (bmRequestType)
       {
          case USB_SETUP_SET_STAND_DEVICE:
          wValue = Usb_read_byte();
          switch (wValue)
          {
             case USB_REMOTE_WAKEUP:
             if ((wValue != FEATURE_DEVICE_REMOTE_WAKEUP)
             ||  (USB_REMOTE_WAKEUP_FEATURE != ENABLED))
                return FALSE;              // Invalid request
             device_status |= USB_DEVICE_STATUS_REMOTEWAKEUP;
             remote_wakeup_feature = ENABLED;
             Usb_ack_receive_setup();
             Usb_send_control_in();
             break;

             default:
             return FALSE;                 // Unknow request
             break;
          }
          break;

          case USB_SETUP_SET_STAND_INTERFACE:
          return FALSE;                    // Unknow request
          break;

          case USB_SETUP_SET_STAND_ENDPOINT:
          wValue   = Usb_read_byte();
          dummy    = Usb_read_byte();
          if (wValue != FEATURE_ENDPOINT_HALT)
             return FALSE;                 // Unknow request
          wIndex = (Usb_read_byte() & MSK_EP_DIR);
          if (wIndex == EP_CONTROL)
          {
             Usb_enable_stall_handshake();
             Usb_ack_receive_setup();
          }
          Usb_select_endpoint(wIndex);
          if( !Is_usb_endpoint_enabled())
          {
             Usb_select_endpoint(EP_CONTROL);
             return FALSE;              // Invalid request
          }
          Usb_enable_stall_handshake();
          Usb_select_endpoint(EP_CONTROL);
          endpoint_status[wIndex] = 0x01;
          Usb_ack_receive_setup();
          Usb_send_control_in();
          break;

          default:
          return FALSE;                    // Unknow request
          break;
       }
       return TRUE;
    }

Here is the caller graph for this function:

Bool usb_clear_feature | ( | U8 | bmRequestType ) | `[static]`

This function manages the SET FEATURE request.

Definition at line 503 of file usb_standard_request.c.

References device_status, DISABLED, ENABLED, endpoint_status, EP_CONTROL, FALSE, FEATURE_DEVICE_REMOTE_WAKEUP, FEATURE_ENDPOINT_HALT, Is_usb_endpoint_enabled, MSK_EP_DIR, remote_wakeup_feature, TRUE, Usb_ack_receive_setup, USB_DEVICE_STATUS_REMOTEWAKEUP, Usb_disable_stall_handshake, Usb_read_byte, USB_REMOTE_WAKEUP_FEATURE, Usb_reset_data_toggle, Usb_reset_endpoint, Usb_select_endpoint, Usb_send_control_in, USB_SETUP_SET_STAND_DEVICE, USB_SETUP_SET_STAND_ENDPOINT, and USB_SETUP_SET_STAND_INTERFACE.

Referenced by usb_process_request().

    {
       U8 wValue;
       U8 wIndex;
       U8 dummy;

       switch (bmRequestType)
       {
          case  USB_SETUP_SET_STAND_DEVICE:
          wValue = Usb_read_byte();
          if ((wValue != FEATURE_DEVICE_REMOTE_WAKEUP) || (USB_REMOTE_WAKEUP_FEATURE != ENABLED))
             return FALSE;              // Invalid request
          device_status &= ~USB_DEVICE_STATUS_REMOTEWAKEUP;
          remote_wakeup_feature = DISABLED;
          Usb_ack_receive_setup();
          Usb_send_control_in();
          break;

          case USB_SETUP_SET_STAND_INTERFACE:
          return FALSE;                    // Unknow request
          break;

          case USB_SETUP_SET_STAND_ENDPOINT:
          wValue = Usb_read_byte();
          dummy  = Usb_read_byte();
          if (wValue != FEATURE_ENDPOINT_HALT)
             return FALSE;                 // Unknow request
          wIndex = (Usb_read_byte() & MSK_EP_DIR);
          Usb_select_endpoint(wIndex);
          if( !Is_usb_endpoint_enabled())
          {
             Usb_select_endpoint(EP_CONTROL);
             return FALSE;              // Invalid request
          }
          if(wIndex != EP_CONTROL)
          {
             Usb_disable_stall_handshake();
             Usb_reset_endpoint(wIndex);
             Usb_reset_data_toggle();
          }
          Usb_select_endpoint(EP_CONTROL);
          endpoint_status[wIndex] = 0x00;
          Usb_ack_receive_setup();
          Usb_send_control_in();
          break;

          default:
          return FALSE;                    // Unknow request
          break;
       }
       return TRUE;
    }

Here is the caller graph for this function:

Bool usb_get_interface | ( | void | ) | `[static]`

This function manages the SETUP_GET_INTERFACE request.

Definition at line 559 of file usb_standard_request.c.

References FALSE, Is_usb_receive_out, LSB, MSB, TRUE, Usb_ack_receive_out, Usb_ack_receive_setup, Usb_read_byte, Usb_send_control_in, usb_user_interface_get(), and Usb_write_byte.

Referenced by usb_process_request().

    {
       U16   wInterface;
       U8    wValue_msb;
       U8    wValue_lsb;

       // Read wValue
       wValue_lsb = Usb_read_byte();
       wValue_msb = Usb_read_byte();
       // wValue = Alternate Setting
       // wIndex = Interface
       LSB(wInterface)=Usb_read_byte();
       MSB(wInterface)=Usb_read_byte();
       if( (0!=wValue_msb) || (0!=wValue_msb) )
          return FALSE;
       Usb_ack_receive_setup();

       Usb_write_byte( usb_user_interface_get(wInterface) );
       Usb_send_control_in();

       while( !Is_usb_receive_out() );
       Usb_ack_receive_out();
       return TRUE;
    }

Here is the call graph for this function:

Here is the caller graph for this function:

Bool usb_set_interface | ( | void | ) | `[static]`

This function manages the SETUP_SET_INTERFACE request.

Definition at line 587 of file usb_standard_request.c.

References EP_CONTROL, FALSE, Is_usb_in_ready, LSB, MSB, TRUE, Usb_ack_receive_setup, Usb_read_byte, Usb_select_endpoint, Usb_send_control_in, and usb_user_interface_reset().

Referenced by usb_process_request().

    {
       U16   wInterface;
       U8    wValue_msb;
       U8    wValue_lsb;

       // Read wValue
       wValue_lsb = Usb_read_byte();
       wValue_msb = Usb_read_byte();
       // wValue = Alternate Setting
       // wIndex = Interface
       LSB(wInterface)=Usb_read_byte();
       MSB(wInterface)=Usb_read_byte();
       if( 0!=wValue_msb )
          return FALSE;
       Usb_ack_receive_setup();

       usb_user_interface_reset(wInterface, wValue_lsb);
       Usb_select_endpoint(EP_CONTROL);

       Usb_send_control_in();
       while(!Is_usb_in_ready());
       return TRUE;
    }

Here is the call graph for this function:

Here is the caller graph for this function:

## Variable Documentation

U8 code* pbuffer

Definition at line 94 of file usb_standard_request.c.

Referenced by hid_get_hid_descriptor(), hid_get_report_descriptor(), usb_get_descriptor(), and usb_user_get_descriptor().

U8 endpoint_status[7]

Definition at line 98 of file usb_standard_request.c.

Referenced by usb_clear_feature(), usb_get_status(), usb_process_request(), and usb_set_feature().

U8 data_to_transfer

Definition at line 99 of file usb_standard_request.c.

Referenced by hid_get_hid_descriptor(), hid_get_report_descriptor(), usb_get_descriptor(), and usb_user_get_descriptor().

U8 device_status = USB_DEVICE_STATUS_BUS_POWERED

Definition at line 102 of file usb_standard_request.c.

Referenced by usb_clear_feature(), usb_get_status(), and usb_set_feature().