Xmega Application Note


usb_standard_request.c File Reference


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.

Application note:
AVR1907: Xplain Evaluation Board
Documentation
For comprehensive code documentation, supported compilers, compiler settings and supported devices see readme.html
Author:
Atmel Corporation: http://www.atmel.com
Support email: avr@atmel.com
Revision
3122
Date
2010-01-13 13:26:22 +0100 (on, 13 jan 2010)

Copyright (c) 2010, Atmel Corporation All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

3. The name of ATMEL may not be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Definition in file usb_standard_request.c.

#include "config.h"
#include "conf_usb.h"
#include "usb_drv.h"
#include "usb_descriptors.h"
#include "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.

Functions

static void usb_clear_feature (void)
 This function manages the SET FEATURE request.
void usb_enum_var_init (void)
 This function initializes the main usb variables:
  • endpoint status
  • connection status.

static void usb_get_configuration (void)
 This function manages the GET CONFIGURATION request. The current configuration number is returned.
static void usb_get_descriptor (void)
 Function to get the USB Descriptor.
static void usb_get_interface (void)
 This function manages the GET_INTERFACE request.
static void usb_get_status (void)
 This function manages the GET STATUS request. The device, interface or endpoint status is returned.
void usb_process_request (void)
 This function reads the SETUP request sent to the default control endpoint and calls the appropriate function. When exiting of the usb_read_request function, the device is ready to manage the next request.
static void usb_set_address (void)
 This function manages the SET ADDRESS request. When complete, the device will filter the requests using the new address.
static void usb_set_configuration (void)
 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.
static void usb_set_feature (void)
 This function manages the SET FEATURE request. The USB test modes are supported by this function.
static void usb_set_interface (void)
 This function manages the SET_INTERFACE request.

Variables

static uint8_t bmRequestType
uint8_t data_to_transfer
static uint8_t endpoint_status [NB_ENDPOINTS]
uint8_t code * pbuffer
uint8_t usb_configuration_nb
 Store the number of the USB configuration used by the USB device.
uint8_t usb_connected
 Global connection status byte.
code
S_usb_user_configuration_descriptor 
usb_user_configuration_descriptor
code S_usb_device_descriptor usb_user_device_descriptor
uint16_t wInterface
static uint8_t zlp


Function Documentation

void usb_clear_feature ( void   )  [static]

This function manages the SET FEATURE request.

Definition at line 454 of file usb_standard_request.c.

References bmRequestType, endpoint_status, ENDPOINT_TYPE, EP_CONTROL, FEATURE_ENDPOINT_HALT, INTERFACE_TYPE, Is_usb_endpoint_enabled, MSK_EP_DIR, Usb_ack_receive_setup, Usb_disable_stall_handshake, Usb_enable_stall_handshake, Usb_read_byte, Usb_reset_data_toggle, Usb_reset_endpoint, Usb_select_endpoint, Usb_send_control_in, and ZERO_TYPE.

Referenced by usb_process_request().

00455 {
00456         uint8_t wValue;
00457         uint8_t wIndex;
00458         uint8_t dummy;
00459         
00460         if (bmRequestType == ZERO_TYPE){
00461                 /* Keep that order (set StallRq/clear RxSetup) or a OUT request
00462                  * following the SETUP may be acknowledged */
00463                 Usb_enable_stall_handshake();
00464                 Usb_ack_receive_setup();
00465                 return;
00466         }else if (bmRequestType == INTERFACE_TYPE){
00467                 /* Keep that order (set StallRq/clear RxSetup) or a OUT request
00468                  * following the SETUP may be acknowledged */
00469                 Usb_enable_stall_handshake();
00470                 Usb_ack_receive_setup();
00471                 return;
00472         }else if (bmRequestType == ENDPOINT_TYPE){
00473                 wValue = Usb_read_byte();
00474                 dummy  = Usb_read_byte();
00475                 
00476                 if (wValue == FEATURE_ENDPOINT_HALT){
00477                         wIndex = (Usb_read_byte() & MSK_EP_DIR);
00478                         
00479                         Usb_select_endpoint(wIndex);
00480                         if(Is_usb_endpoint_enabled()){
00481                                 if(wIndex != EP_CONTROL){
00482                                         Usb_disable_stall_handshake();
00483                                         Usb_reset_endpoint(wIndex);
00484                                         Usb_reset_data_toggle();
00485                                 }
00486                                 Usb_select_endpoint(EP_CONTROL);
00487                                 endpoint_status[wIndex] = 0x00;
00488                                 Usb_ack_receive_setup();
00489                                 Usb_send_control_in();
00490                         }else{
00491                                 Usb_enable_stall_handshake();
00492                                 Usb_ack_receive_setup();
00493                                 return;
00494                         }
00495                 }else{
00496                         Usb_enable_stall_handshake();
00497                         Usb_ack_receive_setup();
00498                         return;
00499                 }
00500         }
00501 }

void usb_enum_var_init ( void   ) 

This function initializes the main usb variables:

  • endpoint status
  • connection status.

Definition at line 97 of file usb_standard_request.c.

References endpoint_status, NB_ENDPOINTS, usb_configuration_nb, and usb_connected.

00098 {
00099         uint8_t ep_num ;
00100         
00101         for( ep_num=0 ; ep_num<NB_ENDPOINTS ; ep_num++ ){
00102                 endpoint_status[ep_num] = 0;
00103         }
00104         usb_connected        = false;    /* USB is not connected */
00105         usb_configuration_nb = 0;        /* Default configuration number is 0 */
00106 }

void usb_get_configuration ( void   )  [static]

This function manages the GET CONFIGURATION request. The current configuration number is returned.

Definition at line 348 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().

00349 {
00350         Usb_ack_receive_setup();
00351         
00352         Usb_write_byte(usb_configuration_nb);
00353         Usb_ack_in_ready();
00354         
00355         while( !Is_usb_receive_out() );
00356         Usb_ack_receive_out();
00357 }

void usb_get_descriptor ( void   )  [static]

Function to get the USB Descriptor.

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.

Definition at line 255 of file usb_standard_request.c.

References CONFIGURATION_DESCRIPTOR, data_to_transfer, DEVICE_DESCRIPTOR, EP_CONTROL_LENGTH, Is_usb_read_control_enabled, Is_usb_receive_out, LSB, MSB, pbuffer, Usb_ack_receive_out, Usb_ack_receive_setup, Usb_enable_stall_handshake, 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 zlp.

Referenced by usb_process_request().

00256 {
00257         uint16_t  wLength         ;
00258         uint8_t  descriptor_type ;
00259         uint8_t  string_type     ;
00260         uint8_t  dummy;
00261         uint8_t  nb_byte;
00262         
00263         zlp             = false;                  /* no zero length packet */
00264         string_type     = Usb_read_byte();        /* read LSB of wValue    */
00265         descriptor_type = Usb_read_byte();        /* read MSB of wValue    */
00266         
00267         switch (descriptor_type)
00268         {
00269             case DEVICE_DESCRIPTOR:
00270                 data_to_transfer = Usb_get_dev_desc_length();
00271                 pbuffer          = Usb_get_dev_desc_pointer();
00272                 break;
00273             case CONFIGURATION_DESCRIPTOR:
00274                 data_to_transfer = Usb_get_conf_desc_length();
00275                 pbuffer          = Usb_get_conf_desc_pointer();
00276                 break;
00277             default:
00278                 if( usb_user_get_descriptor(descriptor_type, string_type)==false )
00279                 {
00280                         Usb_enable_stall_handshake();
00281                         Usb_ack_receive_setup();
00282                         return;
00283                 }
00284                 break;
00285         }
00286         
00287         /* Read out dummy parameters not needed. */
00288         dummy = Usb_read_byte();
00289         dummy = Usb_read_byte();
00290         
00291         /* Read out length of data. */
00292         LSB(wLength) = Usb_read_byte();
00293         MSB(wLength) = Usb_read_byte();
00294         Usb_ack_receive_setup();
00295         
00296         if (wLength > data_to_transfer)
00297         {
00298                 if ((data_to_transfer % EP_CONTROL_LENGTH) == 0){
00299                         zlp = true;
00300                 }else{
00301                         zlp = false;
00302                 }
00303         }else{
00304                 /* Send only requested number of data */
00305                 data_to_transfer = (uint8_t)wLength;
00306         }
00307         
00308         while((data_to_transfer != 0) && (!Is_usb_receive_out())){
00309 
00310                 while(!Is_usb_read_control_enabled());
00311                 
00312                 nb_byte=0;
00313                 
00314                 /* Send data until necessary */
00315                 while(data_to_transfer != 0){
00316                         if(nb_byte++==EP_CONTROL_LENGTH){
00317                                 break;
00318                         }
00319                         Usb_write_byte(*pbuffer++);
00320                         data_to_transfer--;
00321                 }
00322                 Usb_send_control_in();
00323         }
00324         
00325         Usb_send_control_in();
00326         
00327         /* Abort from Host */
00328         if(Is_usb_receive_out()){
00329                 Usb_ack_receive_out();
00330                 return;
00331         }
00332         
00333         if(zlp == true){
00334                 while(!Is_usb_read_control_enabled());
00335                 Usb_send_control_in();
00336         }
00337         
00338         
00339         while(!Is_usb_receive_out());
00340         Usb_ack_receive_out();
00341 }

Here is the call graph for this function:

void usb_get_interface ( void   )  [static]

This function manages the GET_INTERFACE request.

Definition at line 507 of file usb_standard_request.c.

References Usb_ack_receive_setup, and Usb_enable_stall_handshake.

Referenced by usb_process_request().

00508 {
00509         Usb_enable_stall_handshake();
00510         Usb_ack_receive_setup();
00511 }

void usb_get_status ( void   )  [static]

This function manages the GET STATUS request. The device, interface or endpoint status is returned.

Definition at line 363 of file usb_standard_request.c.

References bmRequestType, DEVICE_STATUS, endpoint_status, INTERFACE_STATUS, Is_usb_receive_out, MSK_EP_DIR, REQUEST_DEVICE_STATUS, REQUEST_ENDPOINT_STATUS, REQUEST_INTERFACE_STATUS, Usb_ack_receive_out, Usb_ack_receive_setup, Usb_enable_stall_handshake, Usb_read_byte, Usb_send_control_in, and Usb_write_byte.

Referenced by usb_process_request().

00364 {
00365         uint8_t wIndex;
00366         uint8_t dummy;
00367         
00368         /* Read out dummy parameters not needed. */
00369         dummy    = Usb_read_byte();
00370         dummy    = Usb_read_byte();
00371         
00372         wIndex = Usb_read_byte();
00373         
00374         switch(bmRequestType){
00375             case REQUEST_DEVICE_STATUS:
00376                 Usb_ack_receive_setup();
00377                 Usb_write_byte(DEVICE_STATUS);
00378                 break;
00379                 
00380             case REQUEST_INTERFACE_STATUS:
00381                 Usb_ack_receive_setup();
00382                 Usb_write_byte(INTERFACE_STATUS);
00383                 break;
00384                 
00385             case REQUEST_ENDPOINT_STATUS:
00386                 Usb_ack_receive_setup();
00387                 wIndex = wIndex & MSK_EP_DIR;
00388                 Usb_write_byte(endpoint_status[wIndex]);
00389                 break;
00390                 
00391             default:
00392                 Usb_enable_stall_handshake();
00393                 Usb_ack_receive_setup();
00394                 return;
00395         }
00396         
00397         Usb_write_byte(0x00);
00398         Usb_send_control_in();
00399         
00400         while( !Is_usb_receive_out() );
00401         Usb_ack_receive_out();
00402 }

void usb_process_request ( void   ) 

This function reads the SETUP request sent to the default control endpoint and calls the appropriate function. When exiting of the usb_read_request function, the device is ready to manage the next request.

Note:
list of supported requests: GET_DESCRIPTOR GET_CONFIGURATION SET_ADDRESS SET_CONFIGURATION CLEAR_FEATURE SET_FEATURE GET_STATUS

Definition at line 122 of file usb_standard_request.c.

References bmRequestType, CLEAR_FEATURE, GET_CONFIGURATION, GET_DESCRIPTOR, GET_INTERFACE, GET_STATUS, SET_ADDRESS, SET_CONFIGURATION, SET_DESCRIPTOR, SET_FEATURE, SET_INTERFACE, SYNCH_FRAME, Usb_ack_receive_setup, usb_clear_feature(), Usb_enable_stall_handshake, usb_get_configuration(), usb_get_descriptor(), usb_get_interface(), usb_get_status(), Usb_read_byte, usb_set_address(), usb_set_configuration(), usb_set_feature(), usb_set_interface(), and usb_user_read_request().

Referenced by usb_device_task().

00123 {
00124         uint8_t  bmRequest;
00125         
00126         bmRequestType = Usb_read_byte();
00127         bmRequest     = Usb_read_byte();
00128         
00129         switch (bmRequest)
00130         {
00131             case GET_DESCRIPTOR:
00132                 if (0x80 == bmRequestType) { usb_get_descriptor(); }
00133                 else                       { usb_user_read_request(bmRequestType, bmRequest); }
00134                 break;
00135                 
00136             case GET_CONFIGURATION:
00137                 if (0x80 == bmRequestType) { usb_get_configuration(); }
00138                 else                       { usb_user_read_request(bmRequestType, bmRequest); }
00139                 break;
00140                 
00141             case SET_ADDRESS:
00142                 if (0x00 == bmRequestType) { usb_set_address(); }
00143                 else                       { usb_user_read_request(bmRequestType, bmRequest); }
00144                 break;
00145                 
00146             case SET_CONFIGURATION:
00147                 if (0x00 == bmRequestType) { usb_set_configuration(); }
00148                 else                       { usb_user_read_request(bmRequestType, bmRequest); }
00149                 break;
00150                 
00151             case CLEAR_FEATURE:
00152                 if (0x02 >= bmRequestType) { usb_clear_feature(); }
00153                 else                       { usb_user_read_request(bmRequestType, bmRequest); }
00154                 break;
00155                 
00156             case SET_FEATURE:
00157                 if (0x02 >= bmRequestType) { usb_set_feature(); }
00158                 else                       { usb_user_read_request(bmRequestType, bmRequest); }
00159                 break;
00160                 
00161             case GET_STATUS:
00162                 if ((0x7F < bmRequestType) & (0x82 >= bmRequestType))
00163                 { usb_get_status(); }
00164                 else                       { usb_user_read_request(bmRequestType, bmRequest); }
00165                 break;
00166                 
00167             case GET_INTERFACE:
00168                 if (bmRequestType == 0x81) { usb_get_interface(); }
00169                 else { usb_user_read_request(bmRequestType, bmRequest); }
00170                 break;
00171                 
00172                 
00173             case SET_INTERFACE:
00174                 if (bmRequestType == 0x01) {usb_set_interface();}
00175                 break;
00176         
00177             /* Un-supported request => call to user read request */
00178             case SET_DESCRIPTOR:
00179             case SYNCH_FRAME:
00180             default:
00181                 if(usb_user_read_request(bmRequestType, bmRequest) == false)
00182                 {
00183                         Usb_enable_stall_handshake();
00184                         Usb_ack_receive_setup();
00185                 }
00186                 break;
00187         }
00188 }

Here is the call 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 195 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().

00196 {
00197 #ifdef __ICCAVR__
00198 #pragma diag_suppress=Pa082 /* Suppress warning for undefined order of volatile access. */
00199 #endif
00200         Usb_configure_address(Usb_read_byte());
00201 #ifdef __ICCAVR__
00202 #pragma diag_default=Pa082 /* Back to default. */
00203 #endif
00204 
00205 
00206         
00207         Usb_ack_receive_setup();
00208         
00209         /* Send a ZLP for STATUS phase */
00210         Usb_send_control_in();
00211         while(!Is_usb_in_ready());
00212 
00213         Usb_enable_address();
00214 }

void 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 NB_CONFIGURATION, Usb_ack_receive_setup, usb_configuration_nb, Usb_enable_stall_handshake, Usb_read_byte, Usb_send_control_in, Usb_set_configuration_action, and usb_user_endpoint_init().

Referenced by usb_process_request().

00223 {
00224         uint8_t configuration_number;
00225         
00226         configuration_number = Usb_read_byte();
00227         
00228         if (configuration_number <= NB_CONFIGURATION){
00229                 Usb_ack_receive_setup();
00230                 usb_configuration_nb = configuration_number;
00231         }else{
00232                 /* Keep that order (set StallRq/clear RxSetup) or a OUT request
00233                  * following the SETUP may be acknowledged */
00234                 Usb_enable_stall_handshake();
00235                 Usb_ack_receive_setup();
00236                 return;
00237         }
00238         
00239         /* Send a ZLP for STATUS phase */       
00240         Usb_send_control_in();
00241         
00242         usb_user_endpoint_init(usb_configuration_nb);
00243         Usb_set_configuration_action();
00244 }

Here is the call graph for this function:

void usb_set_feature ( void   )  [static]

This function manages the SET FEATURE request. The USB test modes are supported by this function.

Definition at line 408 of file usb_standard_request.c.

References bmRequestType, endpoint_status, ENDPOINT_TYPE, EP_CONTROL, FEATURE_ENDPOINT_HALT, INTERFACE_TYPE, Is_usb_endpoint_enabled, MSK_EP_DIR, Usb_ack_receive_setup, Usb_enable_stall_handshake, Usb_read_byte, Usb_select_endpoint, and Usb_send_control_in.

Referenced by usb_process_request().

00409 {
00410         uint8_t wValue;
00411         uint8_t wIndex;
00412         uint8_t dummy;
00413         
00414         if (bmRequestType == INTERFACE_TYPE){
00415                 /* Keep that order (set StallRq/clear RxSetup) or a OUT request
00416                  * following the SETUP may be acknowledged */
00417                 Usb_enable_stall_handshake();
00418                 Usb_ack_receive_setup();
00419         }else if (bmRequestType == ENDPOINT_TYPE){
00420                 wValue = Usb_read_byte();
00421                 dummy  = Usb_read_byte();
00422                 
00423                 if (wValue == FEATURE_ENDPOINT_HALT){
00424                         wIndex = (Usb_read_byte() & MSK_EP_DIR);
00425                         
00426                         if (wIndex == EP_CONTROL){
00427                                 Usb_enable_stall_handshake();
00428                                 Usb_ack_receive_setup();
00429                                 return;
00430                         }
00431                         
00432                         Usb_select_endpoint(wIndex);
00433                         if(Is_usb_endpoint_enabled()){
00434                                 Usb_enable_stall_handshake();
00435                                 Usb_select_endpoint(EP_CONTROL);
00436                                 endpoint_status[wIndex] = 0x01;
00437                                 Usb_ack_receive_setup();
00438                                 Usb_send_control_in();
00439                         }else{
00440                                 Usb_enable_stall_handshake();
00441                                 Usb_ack_receive_setup();
00442                         }
00443                 }else{
00444                         Usb_enable_stall_handshake();
00445                         Usb_ack_receive_setup();
00446                 }
00447         }
00448 }

void usb_set_interface ( void   )  [static]

This function manages the SET_INTERFACE request.

Definition at line 516 of file usb_standard_request.c.

References Is_usb_in_ready, Usb_ack_receive_setup, and Usb_send_control_in.

Referenced by usb_process_request().

00517 {
00518         Usb_ack_receive_setup();
00519         Usb_send_control_in();
00520         while(!Is_usb_in_ready());
00521 }


Variable Documentation

uint8_t bmRequestType [static]

Definition at line 82 of file usb_standard_request.c.

Referenced by usb_get_descriptor(), and usb_user_get_descriptor().

uint8_t endpoint_status[NB_ENDPOINTS] [static]

uint8_t code* pbuffer

Definition at line 81 of file usb_standard_request.c.

Referenced by usb_get_descriptor(), and usb_user_get_descriptor().

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

Definition at line 85 of file usb_standard_request.c.

Referenced by usb_device_task(), usb_enum_var_init(), usb_get_configuration(), and usb_set_configuration().

uint8_t usb_connected

Global connection status byte.

usb_connected is set to true when VBUS has been detected usb_connected is set to false otherwise

Definition at line 65 of file usb_device_task.c.

uint16_t wInterface

Definition at line 83 of file usb_standard_request.c.

uint8_t zlp [static]

Definition at line 78 of file usb_standard_request.c.

Referenced by usb_get_descriptor().

@DOC_TITLE@
Generated on Mon Jan 18 09:26:14 2010 for AVR1907 Xplain USB Gateway by doxygen 1.5.5