ATMEL: usb_standard_request.c Source File

- Main Page
- Modules
- Data Structures
- Files
- Related Pages

# usb_standard_request.c

Go to the documentation of this file.

    00001 /*This file is prepared for Doxygen automatic documentation generation.*/
    00021
    00022 /* Copyright (c) 2009 Atmel Corporation. All rights reserved.
    00023  *
    00024  * Redistribution and use in source and binary forms, with or without
    00025  * modification, are permitted provided that the following conditions are met:
    00026  *
    00027  * 1. Redistributions of source code must retain the above copyright notice,
    00028  * this list of conditions and the following disclaimer.
    00029  *
    00030  * 2. Redistributions in binary form must reproduce the above copyright notice,
    00031  * this list of conditions and the following disclaimer in the documentation
    00032  * and/or other materials provided with the distribution.
    00033  *
    00034  * 3. The name of Atmel may not be used to endorse or promote products derived
    00035  * from this software without specific prior written permission.
    00036  *
    00037  * 4. This software may only be redistributed and used in connection with an Atmel
    00038  * AVR product.
    00039  *
    00040  * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
    00041  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
    00042  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE EXPRESSLY AND
    00043  * SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
    00044  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
    00045  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
    00046  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
    00047  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    00048  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
    00049  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    00050  */
    00051
    00052 //_____ I N C L U D E S ____________________________________________________
    00053
    00054 #include "config.h"
    00055 #include "conf_usb.h"
    00056 #include "lib_mcu/usb/usb_drv.h"
    00057 #include "lib_mcu/pll/pll_drv.h"
    00058 #include "usb_descriptors.h"
    00059 #include "modules/usb/device_chap9/usb_standard_request.h"
    00060 #include "usb_specific_request.h"
    00061
    00062 #if ((USB_DEVICE_SN_USE==ENABLE) && (USE_DEVICE_SN_UNIQUE==ENABLE))
    00063 #include "lib_mcu/flash/flash_drv.h"
    00064 static  U8   bin_to_ascii (U8 b);
    00065 #endif
    00066
    00067 //_____ D E F I N I T I O N ________________________________________________
    00068
    00069 static   Bool  usb_get_descriptor   ( void );
    00070 static   void  usb_set_address      ( void );
    00071 static   Bool  usb_set_configuration( void );
    00072 static   void  usb_get_configuration( void );
    00073 static   Bool  usb_get_status       ( U8 bmRequestType );
    00074 static   Bool  usb_set_feature      ( U8 bmRequestType );
    00075 static   Bool  usb_clear_feature    ( U8 bmRequestType );
    00076 static   Bool  usb_get_interface    ( void );
    00077 static   Bool  usb_set_interface    ( void );
    00078
    00079 #ifndef USB_REMOTE_WAKEUP_FEATURE
    00080    #error USB_REMOTE_WAKEUP_FEATURE should be defined as ENABLE or DISABLE in conf_usb.h
    00081 #endif
    00082
    00083 #if (USE_DEVICE_SN_UNIQUE==ENABLE)
    00084     U8   f_get_serial_string=FALSE;
    00085 #endif
    00086
    00087
    00088 //_____ D E C L A R A T I O N ______________________________________________
    00089
    00090 #ifdef __GNUC__                          // AVRGCC does not support point to PGM space
    00091    PGM_VOID_P pbuffer;
    00092    #define Usb_write_PGM_byte(byte) (Usb_write_byte(pgm_read_byte_near((unsigned int)byte)))
    00093 #else
    00094    U8   code *pbuffer;
    00095    #define Usb_write_PGM_byte(byte) (Usb_write_byte(*byte))
    00096 #endif
    00097
    00098 U8    endpoint_status[MAX_EP_NB];
    00099 U8    data_to_transfer;
    00100 U8    usb_configuration_nb;
    00101 U8    remote_wakeup_feature = DISABLE;
    00102 static U8    device_status = DEVICE_STATUS;
    00103
    00104
    00109 void usb_process_request(void)
    00110 {
    00111    U8 bmRequestType;
    00112    U8 bmRequest;
    00113
    00114    Usb_ack_control_out();
    00115    bmRequestType = Usb_read_byte();
    00116    bmRequest     = Usb_read_byte();
    00117
    00118    switch (bmRequest)
    00119    {
    00120       case SETUP_GET_DESCRIPTOR:
    00121       if (USB_SETUP_GET_STAND_DEVICE == bmRequestType)
    00122       {
    00123          if( usb_get_descriptor() )
    00124             return;
    00125       }
    00126       break;
    00127
    00128       case SETUP_GET_CONFIGURATION:
    00129       if (USB_SETUP_GET_STAND_DEVICE == bmRequestType)
    00130       {
    00131          usb_get_configuration();
    00132          return;
    00133       }
    00134       break;
    00135
    00136       case SETUP_SET_ADDRESS:
    00137       if (USB_SETUP_SET_STAND_DEVICE == bmRequestType)
    00138       {
    00139          usb_set_address();
    00140          return;
    00141       }
    00142       break;
    00143
    00144       case SETUP_SET_CONFIGURATION:
    00145       if (USB_SETUP_SET_STAND_DEVICE == bmRequestType)
    00146       {
    00147          if( usb_set_configuration() )
    00148             return;
    00149       }
    00150       break;
    00151
    00152       case SETUP_CLEAR_FEATURE:
    00153       if (usb_clear_feature(bmRequestType))
    00154          return;
    00155       break;
    00156
    00157       case SETUP_SET_FEATURE:
    00158       if (usb_set_feature(bmRequestType))
    00159          return;
    00160       break;
    00161
    00162       case SETUP_GET_STATUS:
    00163       if (usb_get_status(bmRequestType))
    00164          return;
    00165       break;
    00166
    00167       case SETUP_GET_INTERFACE:
    00168       if (USB_SETUP_GET_STAND_INTERFACE == bmRequestType)
    00169       {
    00170          if( usb_get_interface() )
    00171             return;
    00172       }
    00173       break;
    00174
    00175       case SETUP_SET_INTERFACE:
    00176       if (bmRequestType == USB_SETUP_SET_STAND_INTERFACE)
    00177       {
    00178          if( usb_set_interface() )
    00179             return;
    00180       }
    00181       break;
    00182
    00183       default:
    00184       break;
    00185    }
    00186
    00187    // un-supported like standard request => call to user read request
    00188    if( !usb_user_read_request(bmRequestType, bmRequest) )
    00189    {
    00190       // Request unknow in the specific request list from interface
    00191       // keep that order (set StallRq/clear RxSetup) or a
    00192       // OUT request following the SETUP may be acknowledged
    00193       Usb_enable_stall_handshake();
    00194       Usb_ack_receive_setup();
    00195       endpoint_status[(EP_CONTROL & MSK_EP_DIR)] = 0x01;
    00196    }
    00197 }
    00198
    00199
    00203 void usb_set_address(void)
    00204 {
    00205    U8 addr = Usb_read_byte();
    00206    Usb_configure_address(addr);
    00207
    00208    Usb_ack_receive_setup();
    00209
    00210    Usb_send_control_in();                    // send a ZLP for STATUS phase
    00211    while(!Is_usb_in_ready()) {if(Is_usb_vbus_low())break;} // waits for status phase done
    00212                                              // before using the new address
    00213    Usb_enable_address();
    00214 }
    00215
    00216
    00222 Bool usb_set_configuration( void )
    00223 {
    00224    U8 configuration_number;
    00225
    00226    // Get/Check new configuration
    00227    configuration_number = Usb_read_byte();
    00228    if (configuration_number > NB_CONFIGURATION)
    00229       return FALSE;  //  Bad configuration number then stall request
    00230    Usb_ack_receive_setup();
    00231    usb_configuration_nb = configuration_number;
    00232
    00233    Usb_send_control_in();                          // send a ZLP for STATUS phase
    00234    usb_user_endpoint_init(usb_configuration_nb);   // endpoint configuration
    00235    Usb_set_configuration_action();
    00236    return TRUE;
    00237 }
    00238
    00239
    00246 Bool usb_get_descriptor(void)
    00247 {
    00248    Bool zlp;
    00249    U16  wLength;
    00250    U8   descriptor_type ;
    00251    U8   string_type;
    00252    U8   dummy;
    00253    U8   nb_byte;
    00254    U8   byte_to_send;
    00255 #if (USE_DEVICE_SN_UNIQUE==ENABLE)
    00256    U16  sn_index=0;
    00257    U8   initial_data_to_transfer;
    00258 #endif
    00259
    00260    zlp             = FALSE;                  /* no zero length packet */
    00261    string_type     = Usb_read_byte();        /* read LSB of wValue    */
    00262    descriptor_type = Usb_read_byte();        /* read MSB of wValue    */
    00263
    00264    switch (descriptor_type)
    00265    {
    00266       case DESCRIPTOR_DEVICE:
    00267       data_to_transfer = Usb_get_dev_desc_length();
    00268       pbuffer          = Usb_get_dev_desc_pointer();
    00269       break;
    00270
    00271       case DESCRIPTOR_CONFIGURATION:
    00272       data_to_transfer = Usb_get_conf_desc_length();
    00273       pbuffer          = Usb_get_conf_desc_pointer();
    00274       break;
    00275
    00276       default:
    00277       if( !usb_user_get_descriptor(descriptor_type, string_type))
    00278          return FALSE;  // Unknow descriptor then stall request
    00279       break;
    00280    }
    00281
    00282    dummy = Usb_read_byte();
    00283    dummy = Usb_read_byte();
    00284    LSB(wLength) = Usb_read_byte();
    00285    MSB(wLength) = Usb_read_byte();
    00286    Usb_ack_receive_setup() ;
    00287
    00288    if (wLength > data_to_transfer)
    00289    {
    00290       if ((data_to_transfer % EP_CONTROL_LENGTH) == 0) { zlp = TRUE; }
    00291       else { zlp = FALSE; }
    00292    }
    00293    else
    00294    {
    00295       data_to_transfer = (U8)wLength;
    00296    }
    00297
    00298    Usb_ack_nak_out();
    00299
    00300    byte_to_send=0;
    00301 #if (USE_DEVICE_SN_UNIQUE==ENABLE)
    00302    initial_data_to_transfer = data_to_transfer;
    00303 #endif
    00304    while((data_to_transfer != 0) && (!Is_usb_nak_out_sent()))
    00305    {
    00306       while(!Is_usb_read_control_enabled())
    00307       {
    00308          if (Is_usb_nak_out_sent())
    00309             break;    // don't clear the flag now, it will be cleared after
    00310          if (Is_usb_vbus_low())
    00311             break;
    00312       }
    00313
    00314       nb_byte=0;
    00315       while(data_to_transfer != 0)
    00316       {
    00317          if(nb_byte++==EP_CONTROL_LENGTH)
    00318             break;
    00319
    00320 #if (USE_DEVICE_SN_UNIQUE==ENABLE)
    00321
    00322          if(f_get_serial_string && (data_to_transfer < (initial_data_to_transfer-1)))    //if we are sending the signature characters (third byte and more...)
    00323          {                                                                              //(The first two bytes are the length and the descriptor)
    00324
    00325             switch (byte_to_send)
    00326             {
    00327                case 0:
    00328                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
    00329                break;
    00330
    00331                case 1:
    00332                Usb_write_byte(0);                                                   //then, sends a null character (Usb_unicode)
    00333                break;
    00334
    00335                case 2:
    00336                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
    00337                break;
    00338
    00339                case 3:
    00340                Usb_write_byte(0);                                                   //then, sends a null character (Usb_unicode)
    00341                sn_index++;                                                         //increments the signature address pointer.
    00342                break;
    00343             }
    00344             byte_to_send = (byte_to_send+1)%4;
    00345          }
    00346          else
    00347          {
    00348             Usb_write_PGM_byte(pbuffer++);                                                 //Write a flash byte to USB
    00349          }
    00350 #else
    00351          Usb_write_PGM_byte(pbuffer++);
    00352 #endif
    00353          data_to_transfer --;                                                             //decrements the number of bytes to transmit.
    00354       }
    00355
    00356       if (Is_usb_nak_out_sent())
    00357          break;
    00358       if (Is_usb_vbus_low())
    00359          break;
    00360       Usb_send_control_in();
    00361    }
    00362
    00363 #if (USE_DEVICE_SN_UNIQUE==ENABLE)
    00364    f_get_serial_string=FALSE;                                                   //end of signature transmission
    00365 #endif
    00366
    00367    if((zlp == TRUE) && (!Is_usb_nak_out_sent()))
    00368    {
    00369       while(!Is_usb_read_control_enabled()) {if(Is_usb_vbus_low())break;}
    00370       Usb_send_control_in();
    00371    }
    00372
    00373    while (!(Is_usb_nak_out_sent())) {if(Is_usb_vbus_low())break;}
    00374    Usb_ack_nak_out();
    00375    Usb_ack_control_out();
    00376    return TRUE;
    00377 }
    00378
    00379
    00383 void usb_get_configuration(void)
    00384 {
    00385    Usb_ack_receive_setup();
    00386
    00387    Usb_write_byte(usb_configuration_nb);
    00388    Usb_ack_in_ready();
    00389
    00390    while( !Is_usb_receive_out() ){if(Is_usb_vbus_low())break;}
    00391    Usb_ack_receive_out();
    00392 }
    00393
    00394
    00398 Bool usb_get_status( U8 bmRequestType )
    00399 {
    00400    U8 wIndex;
    00401    U8 dummy;
    00402
    00403    dummy    = Usb_read_byte();
    00404    dummy    = Usb_read_byte();
    00405    wIndex   = Usb_read_byte();
    00406
    00407    switch(bmRequestType)
    00408    {
    00409       case USB_SETUP_GET_STAND_DEVICE:
    00410       Usb_ack_receive_setup();
    00411       Usb_write_byte(device_status);
    00412       break;
    00413
    00414       case USB_SETUP_GET_STAND_INTERFACE:
    00415       Usb_ack_receive_setup();
    00416       Usb_write_byte(0);      // Reserved - always 0
    00417       break;
    00418
    00419       case USB_SETUP_GET_STAND_ENDPOINT:
    00420       Usb_ack_receive_setup();
    00421       wIndex = wIndex & MSK_EP_DIR;
    00422       Usb_write_byte( endpoint_status[wIndex] );
    00423       break;
    00424
    00425       default:
    00426       return FALSE;
    00427    }
    00428    Usb_write_byte(0);
    00429
    00430    Usb_send_control_in();
    00431    while( !Is_usb_receive_out() ){if(Is_usb_vbus_low())break;}
    00432    Usb_ack_receive_out();
    00433    return TRUE;
    00434 }
    00435
    00436
    00440 Bool usb_set_feature( U8 bmRequestType )
    00441 {
    00442    U8 wValue;
    00443    U8 wIndex;
    00444    U8 dummy;
    00445
    00446    switch (bmRequestType)
    00447    {
    00448       case USB_SETUP_SET_STAND_DEVICE:
    00449       wValue = Usb_read_byte();
    00450       switch (wValue)
    00451       {
    00452          case USB_REMOTE_WAKEUP:
    00453          if ((wValue != FEATURE_DEVICE_REMOTE_WAKEUP)
    00454          ||  (USB_REMOTE_WAKEUP_FEATURE != ENABLED))
    00455             return FALSE;              // Invalid request
    00456          device_status |= USB_DEVICE_STATUS_REMOTEWAKEUP;
    00457          remote_wakeup_feature = ENABLED;
    00458          Usb_ack_receive_setup();
    00459          Usb_send_control_in();
    00460          break;
    00461
    00462 #if (USB_OTG_FEATURE == ENABLED)
    00463          case OTG_B_HNP_ENABLE:
    00464          if (((OTG_BMATTRIBUTES&HNP_SUPPORT) == 0) || (USB_OTG_FEATURE == DISABLED))   // see usb_descriptors.h
    00465             return FALSE;              // Invalid request
    00466          otg_features_supported |= OTG_B_HNP_ENABLE;
    00467          otg_device_nb_hnp_retry = BDEV_HNP_NB_RETRY;
    00468          Usb_ack_receive_setup();
    00469          Usb_send_control_in();
    00470          break;
    00471
    00472          case OTG_A_HNP_SUPPORT:
    00473          if (((OTG_BMATTRIBUTES&HNP_SUPPORT) == 0) || (USB_OTG_FEATURE == DISABLED))
    00474             return FALSE;              // Invalid request
    00475          otg_features_supported |= OTG_A_HNP_SUPPORT;
    00476          Usb_ack_receive_setup();
    00477          Usb_send_control_in();
    00478          break;
    00479
    00480          case OTG_A_ALT_HNP_SUPPORT:
    00481          if (((OTG_BMATTRIBUTES&HNP_SUPPORT) == 0) || (USB_OTG_FEATURE == DISABLED))
    00482             return FALSE;              // Invalid request
    00483          otg_features_supported |= OTG_A_ALT_HNP_SUPPORT;
    00484          Usb_ack_receive_setup();
    00485          Usb_send_control_in();
    00486          break;
    00487 #endif
    00488
    00489          default:
    00490          return FALSE;                 // Unknow request
    00491          break;
    00492       }
    00493       break;
    00494
    00495       case USB_SETUP_SET_STAND_INTERFACE:
    00496       return FALSE;                    // Unknow request
    00497       break;
    00498
    00499       case USB_SETUP_SET_STAND_ENDPOINT:
    00500       wValue   = Usb_read_byte();
    00501       dummy    = Usb_read_byte();
    00502       if (wValue != FEATURE_ENDPOINT_HALT)
    00503          return FALSE;                 // Unknow request
    00504       wIndex = (Usb_read_byte() & MSK_EP_DIR);
    00505       if (wIndex == EP_CONTROL)
    00506       {
    00507          Usb_enable_stall_handshake();
    00508          Usb_ack_receive_setup();
    00509       }
    00510       Usb_select_endpoint(wIndex);
    00511       if( !Is_usb_endpoint_enabled())
    00512       {
    00513          Usb_select_endpoint(EP_CONTROL);
    00514          return FALSE;              // Invalid request
    00515       }
    00516       Usb_enable_stall_handshake();
    00517       Usb_select_endpoint(EP_CONTROL);
    00518       endpoint_status[wIndex] = 0x01;
    00519       Usb_ack_receive_setup();
    00520       Usb_send_control_in();
    00521       break;
    00522
    00523       default:
    00524       return FALSE;                    // Unknow request
    00525       break;
    00526    }
    00527    return TRUE;
    00528 }
    00529
    00530
    00533 Bool usb_clear_feature( U8 bmRequestType )
    00534 {
    00535    U8 wValue;
    00536    U8 wIndex;
    00537    U8 dummy;
    00538
    00539    switch (bmRequestType)
    00540    {
    00541       case  USB_SETUP_SET_STAND_DEVICE:
    00542       wValue = Usb_read_byte();
    00543       if ((wValue != FEATURE_DEVICE_REMOTE_WAKEUP) || (USB_REMOTE_WAKEUP_FEATURE != ENABLED))
    00544          return FALSE;              // Invalid request
    00545       device_status &= ~USB_DEVICE_STATUS_REMOTEWAKEUP;
    00546       remote_wakeup_feature = DISABLED;
    00547       Usb_ack_receive_setup();
    00548       Usb_send_control_in();
    00549       break;
    00550
    00551       case USB_SETUP_SET_STAND_INTERFACE:
    00552       return FALSE;                    // Unknow request
    00553       break;
    00554
    00555       case USB_SETUP_SET_STAND_ENDPOINT:
    00556       wValue = Usb_read_byte();
    00557       dummy  = Usb_read_byte();
    00558       if (wValue != FEATURE_ENDPOINT_HALT)
    00559          return FALSE;                 // Unknow request
    00560       wIndex = (Usb_read_byte() & MSK_EP_DIR);
    00561       Usb_select_endpoint(wIndex);
    00562       if( !Is_usb_endpoint_enabled())
    00563       {
    00564          Usb_select_endpoint(EP_CONTROL);
    00565          return FALSE;              // Invalid request
    00566       }
    00567       if(wIndex != EP_CONTROL)
    00568       {
    00569          Usb_disable_stall_handshake();
    00570          Usb_reset_endpoint(wIndex);
    00571          Usb_reset_data_toggle();
    00572       }
    00573       Usb_select_endpoint(EP_CONTROL);
    00574       endpoint_status[wIndex] = 0x00;
    00575       Usb_ack_receive_setup();
    00576       Usb_send_control_in();
    00577       break;
    00578
    00579       default:
    00580       return FALSE;                    // Unknow request
    00581       break;
    00582    }
    00583    return TRUE;
    00584 }
    00585
    00586
    00589 Bool usb_get_interface (void)
    00590 {
    00591    U16   wInterface;
    00592    U8    wValue_msb;
    00593    U8    wValue_lsb;
    00594
    00595    // Read wValue
    00596    wValue_lsb = Usb_read_byte();
    00597    wValue_msb = Usb_read_byte();
    00598    // wValue = Alternate Setting
    00599    // wIndex = Interface
    00600    LSB(wInterface)=Usb_read_byte();
    00601    MSB(wInterface)=Usb_read_byte();
    00602    if( (0!=wValue_msb) || (0!=wValue_msb) )
    00603       return FALSE;
    00604    Usb_ack_receive_setup();
    00605
    00606    Usb_write_byte( usb_user_interface_get(wInterface) );
    00607    Usb_send_control_in();
    00608
    00609    while( !Is_usb_receive_out() ){if(Is_usb_vbus_low())break;}
    00610    Usb_ack_receive_out();
    00611    return TRUE;
    00612 }
    00613
    00614
    00617 Bool usb_set_interface (void)
    00618 {
    00619    U16   wInterface;
    00620    U8    wValue_msb;
    00621    U8    wValue_lsb;
    00622
    00623    // Read wValue
    00624    wValue_lsb = Usb_read_byte();
    00625    wValue_msb = Usb_read_byte();
    00626    // wValue = Alternate Setting
    00627    // wIndex = Interface
    00628    LSB(wInterface)=Usb_read_byte();
    00629    MSB(wInterface)=Usb_read_byte();
    00630    if( 0!=wValue_msb )
    00631       return FALSE;
    00632    Usb_ack_receive_setup();
    00633
    00634    usb_user_interface_reset(wInterface, wValue_lsb);
    00635    Usb_select_endpoint(EP_CONTROL);
    00636
    00637    Usb_send_control_in();
    00638    while(!Is_usb_in_ready()) {if(Is_usb_vbus_low())break;}
    00639    return TRUE;
    00640 }
    00641
    00642
    00645 void usb_generate_remote_wakeup(void)
    00646 {
    00647    if(Is_pll_ready()==FALSE)
    00648    {
    00649       Pll_start_auto();
    00650       Wait_pll_ready();
    00651    }
    00652    Usb_unfreeze_clock();
    00653    if (remote_wakeup_feature == ENABLED)
    00654    {
    00655       Usb_initiate_remote_wake_up();
    00656       remote_wakeup_feature = DISABLED;
    00657    }
    00658 }
    00659
    00660
    00661 #if ((USB_DEVICE_SN_USE==ENABLE) && (USE_DEVICE_SN_UNIQUE==ENABLE))
    00669 U8 bin_to_ascii (U8 b)
    00670 {
    00671 return ( (b <= 0x09) ? (b+'0') : (b+'A'-10) );
    00672 }
    00673 #endif
    00674