Xmega Application Note | |||||
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.
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"
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:
| |
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 |
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:
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 }
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.
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 }
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 }
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 }
uint8_t bmRequestType [static] |
Definition at line 84 of file usb_standard_request.c.
Referenced by usb_clear_feature(), usb_get_status(), usb_process_request(), and usb_set_feature().
uint8_t data_to_transfer |
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] |
Definition at line 79 of file usb_standard_request.c.
Referenced by usb_clear_feature(), usb_enum_var_init(), usb_get_status(), and usb_set_feature().
uint8_t code* pbuffer |
Definition at line 81 of file usb_standard_request.c.
Referenced by usb_get_descriptor(), and usb_user_get_descriptor().
uint8_t usb_configuration_nb |
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] |
Generated on Mon Jan 18 09:26:14 2010 for AVR1907 Xplain USB Gateway by ![]() |