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 AND FITNESS FOR A PARTICULAR PURPOSE 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());                // 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       }
00308               
00309       nb_byte=0;
00310       while(data_to_transfer != 0)        
00311       {
00312          if(nb_byte++==EP_CONTROL_LENGTH) 
00313             break;         
00314          
00315 #if (USE_DEVICE_SN_UNIQUE==ENABLE)
00316 
00317          if(f_get_serial_string && (data_to_transfer < (initial_data_to_transfer-1)))    //if we are sending the signature characters (third byte and more...)
00318          {                                                                              //(The first two bytes are the length and the descriptor)
00319             
00320             switch (byte_to_send)
00321             {
00322                case 0:
00323                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
00324                break;
00325               
00326                case 1:
00327                Usb_write_byte(0);                                                   //then, sends a null character (Usb_unicode)                    
00328                break;
00329     
00330                case 2:
00331                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 
00332                break;
00333     
00334                case 3:
00335                Usb_write_byte(0);                                                   //then, sends a null character (Usb_unicode)  
00336                sn_index++;                                                         //increments the signature address pointer.
00337                break;
00338             }
00339             byte_to_send = (byte_to_send+1)%4;     
00340          }
00341          else
00342          {
00343             Usb_write_PGM_byte(pbuffer++);                                                 //Write a flash byte to USB        
00344          }        
00345 #else          
00346          Usb_write_PGM_byte(pbuffer++);          
00347 #endif
00348          data_to_transfer --;                                                             //decrements the number of bytes to transmit.
00349       }
00350       
00351       if (Is_usb_nak_out_sent())
00352          break;
00353       else
00354          Usb_send_control_in();
00355    }
00356    
00357 #if (USE_DEVICE_SN_UNIQUE==ENABLE)      
00358    f_get_serial_string=FALSE;                                                   //end of signature transmission    
00359 #endif   
00360 
00361    if((zlp == TRUE) && (!Is_usb_nak_out_sent()))
00362    {
00363       while(!Is_usb_read_control_enabled());
00364       Usb_send_control_in();
00365    }
00366 
00367    while (!(Is_usb_nak_out_sent()));
00368    Usb_ack_nak_out();
00369    Usb_ack_control_out();
00370    return TRUE;
00371 }
00372 
00373 
00377 void usb_get_configuration(void)
00378 {
00379    Usb_ack_receive_setup();
00380 
00381    Usb_write_byte(usb_configuration_nb);
00382    Usb_ack_in_ready();
00383 
00384    while( !Is_usb_receive_out() );
00385    Usb_ack_receive_out();
00386 }
00387 
00388 
00392 Bool usb_get_status( U8 bmRequestType )
00393 {
00394    U8 wIndex;
00395    U8 dummy;
00396 
00397    dummy    = Usb_read_byte();                 
00398    dummy    = Usb_read_byte();                 
00399    wIndex   = Usb_read_byte();
00400 
00401    switch(bmRequestType)
00402    {
00403       case USB_SETUP_GET_STAND_DEVICE:
00404       Usb_ack_receive_setup();
00405       Usb_write_byte(device_status);
00406       break;
00407 
00408       case USB_SETUP_GET_STAND_INTERFACE:
00409       Usb_ack_receive_setup();
00410       Usb_write_byte(0);      // Reserved - always 0
00411       break;
00412 
00413       case USB_SETUP_GET_STAND_ENDPOINT:
00414       Usb_ack_receive_setup();
00415       wIndex = wIndex & MSK_EP_DIR;
00416       Usb_write_byte( endpoint_status[wIndex] );
00417       break;
00418     
00419       default:
00420       return FALSE;
00421    }
00422    Usb_write_byte(0);
00423 
00424    Usb_send_control_in();
00425    while( !Is_usb_receive_out() );
00426    Usb_ack_receive_out();
00427    return TRUE;
00428 }
00429 
00430 
00434 Bool usb_set_feature( U8 bmRequestType )
00435 {
00436    U8 wValue;
00437    U8 wIndex;
00438    U8 dummy;
00439 
00440    switch (bmRequestType)
00441    {
00442       case USB_SETUP_SET_STAND_DEVICE:
00443       wValue = Usb_read_byte();
00444       switch (wValue)
00445       {
00446          case USB_REMOTE_WAKEUP:
00447          if ((wValue != FEATURE_DEVICE_REMOTE_WAKEUP)
00448          ||  (USB_REMOTE_WAKEUP_FEATURE != ENABLED))
00449             return FALSE;              // Invalid request
00450          device_status |= USB_DEVICE_STATUS_REMOTEWAKEUP;
00451          remote_wakeup_feature = ENABLED;
00452          Usb_ack_receive_setup();
00453          Usb_send_control_in();
00454          break;
00455 
00456 #if (USB_OTG_FEATURE == ENABLED)
00457          case OTG_B_HNP_ENABLE:
00458          if (((OTG_BMATTRIBUTES&HNP_SUPPORT) == 0) || (USB_OTG_FEATURE == DISABLED))   // see usb_descriptors.h
00459             return FALSE;              // Invalid request
00460          otg_features_supported |= OTG_B_HNP_ENABLE;
00461          otg_device_nb_hnp_retry = BDEV_HNP_NB_RETRY;
00462          Usb_ack_receive_setup();
00463          Usb_send_control_in();
00464          break;
00465 
00466          case OTG_A_HNP_SUPPORT:
00467          if (((OTG_BMATTRIBUTES&HNP_SUPPORT) == 0) || (USB_OTG_FEATURE == DISABLED))
00468             return FALSE;              // Invalid request
00469          otg_features_supported |= OTG_A_HNP_SUPPORT;
00470          Usb_ack_receive_setup();
00471          Usb_send_control_in();
00472          break;
00473 
00474          case OTG_A_ALT_HNP_SUPPORT:
00475          if (((OTG_BMATTRIBUTES&HNP_SUPPORT) == 0) || (USB_OTG_FEATURE == DISABLED))
00476             return FALSE;              // Invalid request
00477          otg_features_supported |= OTG_A_ALT_HNP_SUPPORT;
00478          Usb_ack_receive_setup();
00479          Usb_send_control_in();
00480          break;
00481 #endif
00482             
00483          default:
00484          return FALSE;                 // Unknow request
00485          break;
00486       }
00487       break;
00488 
00489       case USB_SETUP_SET_STAND_INTERFACE:
00490       return FALSE;                    // Unknow request
00491       break;
00492 
00493       case USB_SETUP_SET_STAND_ENDPOINT:
00494       wValue   = Usb_read_byte();
00495       dummy    = Usb_read_byte();                
00496       if (wValue != FEATURE_ENDPOINT_HALT)
00497          return FALSE;                 // Unknow request
00498       wIndex = (Usb_read_byte() & MSK_EP_DIR);
00499       if (wIndex == EP_CONTROL)
00500       {
00501          Usb_enable_stall_handshake();
00502          Usb_ack_receive_setup();
00503       }
00504       Usb_select_endpoint(wIndex);
00505       if( !Is_usb_endpoint_enabled())
00506       {
00507          Usb_select_endpoint(EP_CONTROL);
00508          return FALSE;              // Invalid request
00509       }
00510       Usb_enable_stall_handshake();
00511       Usb_select_endpoint(EP_CONTROL);
00512       endpoint_status[wIndex] = 0x01;
00513       Usb_ack_receive_setup();
00514       Usb_send_control_in();
00515       break;
00516 
00517       default:
00518       return FALSE;                    // Unknow request
00519       break;
00520    }
00521    return TRUE;
00522 }
00523 
00524 
00527 Bool usb_clear_feature( U8 bmRequestType )
00528 {
00529    U8 wValue;
00530    U8 wIndex;
00531    U8 dummy;
00532 
00533    switch (bmRequestType)
00534    {
00535       case  USB_SETUP_SET_STAND_DEVICE:
00536       wValue = Usb_read_byte();
00537       if ((wValue != FEATURE_DEVICE_REMOTE_WAKEUP) || (USB_REMOTE_WAKEUP_FEATURE != ENABLED))
00538          return FALSE;              // Invalid request
00539       device_status &= ~USB_DEVICE_STATUS_REMOTEWAKEUP;
00540       remote_wakeup_feature = DISABLED;
00541       Usb_ack_receive_setup();
00542       Usb_send_control_in();
00543       break;
00544    
00545       case USB_SETUP_SET_STAND_INTERFACE:
00546       return FALSE;                    // Unknow request
00547       break;
00548       
00549       case USB_SETUP_SET_STAND_ENDPOINT:
00550       wValue = Usb_read_byte();
00551       dummy  = Usb_read_byte();
00552       if (wValue != FEATURE_ENDPOINT_HALT)
00553          return FALSE;                 // Unknow request
00554       wIndex = (Usb_read_byte() & MSK_EP_DIR);
00555       Usb_select_endpoint(wIndex);
00556       if( !Is_usb_endpoint_enabled())
00557       {
00558          Usb_select_endpoint(EP_CONTROL);
00559          return FALSE;              // Invalid request
00560       } 
00561       if(wIndex != EP_CONTROL)
00562       {
00563          Usb_disable_stall_handshake();
00564          Usb_reset_endpoint(wIndex);
00565          Usb_reset_data_toggle();
00566       }
00567       Usb_select_endpoint(EP_CONTROL);
00568       endpoint_status[wIndex] = 0x00;
00569       Usb_ack_receive_setup();
00570       Usb_send_control_in();
00571       break;
00572    
00573       default:
00574       return FALSE;                    // Unknow request
00575       break;
00576    }
00577    return TRUE;
00578 }
00579 
00580 
00583 Bool usb_get_interface (void)
00584 {
00585    U16   wInterface;
00586    U8    wValue_msb;
00587    U8    wValue_lsb;
00588 
00589    // Read wValue
00590    wValue_lsb = Usb_read_byte();
00591    wValue_msb = Usb_read_byte();
00592    // wValue = Alternate Setting
00593    // wIndex = Interface
00594    LSB(wInterface)=Usb_read_byte();
00595    MSB(wInterface)=Usb_read_byte();
00596    if( (0!=wValue_msb) || (0!=wValue_msb) )
00597       return FALSE;
00598    Usb_ack_receive_setup();
00599    
00600    Usb_write_byte( usb_user_interface_get(wInterface) );
00601    Usb_send_control_in();
00602 
00603    while( !Is_usb_receive_out() );
00604    Usb_ack_receive_out();
00605    return TRUE;
00606 }
00607 
00608 
00611 Bool usb_set_interface (void)
00612 {
00613    U16   wInterface;
00614    U8    wValue_msb;
00615    U8    wValue_lsb;
00616 
00617    // Read wValue
00618    wValue_lsb = Usb_read_byte();
00619    wValue_msb = Usb_read_byte();
00620    // wValue = Alternate Setting
00621    // wIndex = Interface
00622    LSB(wInterface)=Usb_read_byte();
00623    MSB(wInterface)=Usb_read_byte();
00624    if( 0!=wValue_msb )
00625       return FALSE;
00626    Usb_ack_receive_setup();
00627    
00628    usb_user_interface_reset(wInterface, wValue_lsb);
00629    Usb_select_endpoint(EP_CONTROL);
00630             
00631    Usb_send_control_in();
00632    while(!Is_usb_in_ready());
00633    return TRUE;
00634 }
00635 
00636 
00639 void usb_generate_remote_wakeup(void)
00640 {
00641    if(Is_pll_ready()==FALSE)
00642    {
00643       Pll_start_auto();
00644       Wait_pll_ready();
00645    }
00646    Usb_unfreeze_clock();
00647    if (remote_wakeup_feature == ENABLED)
00648    {
00649       Usb_initiate_remote_wake_up();
00650       remote_wakeup_feature = DISABLED;
00651    }
00652 }  
00653 
00654 
00655 #if ((USB_DEVICE_SN_USE==ENABLE) && (USE_DEVICE_SN_UNIQUE==ENABLE))
00663 U8 bin_to_ascii (U8 b)
00664 {
00665 return ( (b <= 0x09) ? (b+'0') : (b+'A'-10) );
00666 }
00667 #endif
00668 

Generated on Mon Nov 3 10:08:24 2008 for ATMEL by  doxygen 1.5.3