Xmega Application Note


usb_standard_request.c

Go to the documentation of this file.
00001 /* This file has been prepared for Doxygen automatic documentation generation.*/
00056 #include "config.h"
00057 #include "conf_usb.h"
00058 #include "usb_drv.h"
00059 #include "usb_descriptors.h"
00060 #include "usb_standard_request.h"
00061 #include "usb_specific_request.h"
00062 
00063 /************************* PROTOTYPES (LOCAL) ********************************/
00064 
00065 static void usb_get_descriptor(void);
00066 static void usb_set_address(void);
00067 static void usb_set_configuration(void);
00068 static void usb_clear_feature(void);
00069 static void usb_set_feature(void);
00070 static void usb_get_status(void);
00071 static void usb_get_configuration(void);
00072 static void usb_get_interface (void);
00073 static void usb_set_interface (void);
00074 
00075 
00076 /* Local parameters. */
00077 
00078 static  uint8_t zlp;
00079 static  uint8_t endpoint_status[NB_ENDPOINTS];
00080 
00081 uint8_t code * pbuffer;
00082 uint8_t data_to_transfer;
00083 uint16_t wInterface;
00084 static uint8_t bmRequestType;
00085 uint8_t usb_configuration_nb;
00086 extern uint8_t usb_connected;
00087 extern code S_usb_device_descriptor usb_user_device_descriptor;
00088 extern code S_usb_user_configuration_descriptor usb_user_configuration_descriptor;
00089 
00090 
00091 
00092 
00097 void usb_enum_var_init (void)
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 }
00107 
00108 
00122 void usb_process_request(void)
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 }
00189 
00190 
00191 
00195 void usb_set_address(void)
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 }
00215 
00216 
00222 void usb_set_configuration( void )
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 }
00245 
00246 
00255 void usb_get_descriptor(void)
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 }
00342 
00343 
00344 
00348 void usb_get_configuration(void)
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 }
00358 
00359 
00363 void usb_get_status(void)
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 }
00403 
00404 
00408 void usb_set_feature(void)
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 }
00449 
00450 
00451 
00454 void usb_clear_feature(void)
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 }
00502 
00503 
00504 
00507 void usb_get_interface (void)
00508 {
00509         Usb_enable_stall_handshake();
00510         Usb_ack_receive_setup();
00511 }
00512 
00513 
00516 void usb_set_interface (void)
00517 {
00518         Usb_ack_receive_setup();
00519         Usb_send_control_in();
00520         while(!Is_usb_in_ready());
00521 }
@DOC_TITLE@
Generated on Mon Jan 18 09:26:08 2010 for AVR1907 Xplain USB Gateway by doxygen 1.5.5