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

# usb_standard_request.c

Go to the documentation of this file.

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