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 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()); // 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 } 00311 00312 nb_byte=0; 00313 while(data_to_transfer != 0) 00314 { 00315 if(nb_byte++==EP_CONTROL_LENGTH) 00316 break; 00317 00318 #if (USE_DEVICE_SN_UNIQUE==ENABLE) 00319 00320 if(f_get_serial_string && (data_to_transfer < (initial_data_to_transfer-1))) //if we are sending the signature characters (third byte and more...) 00321 { //(The first two bytes are the length and the descriptor) 00322 00323 switch (byte_to_send) 00324 { 00325 case 0: 00326 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 00327 break; 00328 00329 case 1: 00330 Usb_write_byte(0); //then, sends a null character (Usb_unicode) 00331 break; 00332 00333 case 2: 00334 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 00335 break; 00336 00337 case 3: 00338 Usb_write_byte(0); //then, sends a null character (Usb_unicode) 00339 sn_index++; //increments the signature address pointer. 00340 break; 00341 } 00342 byte_to_send = (byte_to_send+1)%4; 00343 } 00344 else 00345 { 00346 Usb_write_PGM_byte(pbuffer++); //Write a flash byte to USB 00347 } 00348 #else 00349 Usb_write_PGM_byte(pbuffer++); 00350 #endif 00351 data_to_transfer --; //decrements the number of bytes to transmit. 00352 } 00353 00354 if (Is_usb_nak_out_sent()) 00355 break; 00356 else 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()); 00367 Usb_send_control_in(); 00368 } 00369 00370 while (!(Is_usb_nak_out_sent())); 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() ); 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() ); 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 default: 00460 return FALSE; // Unknow request 00461 break; 00462 } 00463 break; 00464 00465 case USB_SETUP_SET_STAND_INTERFACE: 00466 return FALSE; // Unknow request 00467 break; 00468 00469 case USB_SETUP_SET_STAND_ENDPOINT: 00470 wValue = Usb_read_byte(); 00471 dummy = Usb_read_byte(); 00472 if (wValue != FEATURE_ENDPOINT_HALT) 00473 return FALSE; // Unknow request 00474 wIndex = (Usb_read_byte() & MSK_EP_DIR); 00475 if (wIndex == EP_CONTROL) 00476 { 00477 Usb_enable_stall_handshake(); 00478 Usb_ack_receive_setup(); 00479 } 00480 Usb_select_endpoint(wIndex); 00481 if( !Is_usb_endpoint_enabled()) 00482 { 00483 Usb_select_endpoint(EP_CONTROL); 00484 return FALSE; // Invalid request 00485 } 00486 Usb_enable_stall_handshake(); 00487 Usb_select_endpoint(EP_CONTROL); 00488 endpoint_status[wIndex] = 0x01; 00489 Usb_ack_receive_setup(); 00490 Usb_send_control_in(); 00491 break; 00492 00493 default: 00494 return FALSE; // Unknow request 00495 break; 00496 } 00497 return TRUE; 00498 } 00499 00500 00503 Bool usb_clear_feature( U8 bmRequestType ) 00504 { 00505 U8 wValue; 00506 U8 wIndex; 00507 U8 dummy; 00508 00509 switch (bmRequestType) 00510 { 00511 case USB_SETUP_SET_STAND_DEVICE: 00512 wValue = Usb_read_byte(); 00513 if ((wValue != FEATURE_DEVICE_REMOTE_WAKEUP) || (USB_REMOTE_WAKEUP_FEATURE != ENABLED)) 00514 return FALSE; // Invalid request 00515 device_status &= ~USB_DEVICE_STATUS_REMOTEWAKEUP; 00516 remote_wakeup_feature = DISABLED; 00517 Usb_ack_receive_setup(); 00518 Usb_send_control_in(); 00519 break; 00520 00521 case USB_SETUP_SET_STAND_INTERFACE: 00522 return FALSE; // Unknow request 00523 break; 00524 00525 case USB_SETUP_SET_STAND_ENDPOINT: 00526 wValue = Usb_read_byte(); 00527 dummy = Usb_read_byte(); 00528 if (wValue != FEATURE_ENDPOINT_HALT) 00529 return FALSE; // Unknow request 00530 wIndex = (Usb_read_byte() & MSK_EP_DIR); 00531 Usb_select_endpoint(wIndex); 00532 if( !Is_usb_endpoint_enabled()) 00533 { 00534 Usb_select_endpoint(EP_CONTROL); 00535 return FALSE; // Invalid request 00536 } 00537 if(wIndex != EP_CONTROL) 00538 { 00539 Usb_disable_stall_handshake(); 00540 Usb_reset_endpoint(wIndex); 00541 Usb_reset_data_toggle(); 00542 } 00543 Usb_select_endpoint(EP_CONTROL); 00544 endpoint_status[wIndex] = 0x00; 00545 Usb_ack_receive_setup(); 00546 Usb_send_control_in(); 00547 break; 00548 00549 default: 00550 return FALSE; // Unknow request 00551 break; 00552 } 00553 return TRUE; 00554 } 00555 00556 00559 Bool usb_get_interface (void) 00560 { 00561 U16 wInterface; 00562 U8 wValue_msb; 00563 U8 wValue_lsb; 00564 00565 // Read wValue 00566 wValue_lsb = Usb_read_byte(); 00567 wValue_msb = Usb_read_byte(); 00568 // wValue = Alternate Setting 00569 // wIndex = Interface 00570 LSB(wInterface)=Usb_read_byte(); 00571 MSB(wInterface)=Usb_read_byte(); 00572 if( (0!=wValue_msb) || (0!=wValue_msb) ) 00573 return FALSE; 00574 Usb_ack_receive_setup(); 00575 00576 Usb_write_byte( usb_user_interface_get(wInterface) ); 00577 Usb_send_control_in(); 00578 00579 while( !Is_usb_receive_out() ); 00580 Usb_ack_receive_out(); 00581 return TRUE; 00582 } 00583 00584 00587 Bool usb_set_interface (void) 00588 { 00589 U16 wInterface; 00590 U8 wValue_msb; 00591 U8 wValue_lsb; 00592 00593 // Read wValue 00594 wValue_lsb = Usb_read_byte(); 00595 wValue_msb = Usb_read_byte(); 00596 // wValue = Alternate Setting 00597 // wIndex = Interface 00598 LSB(wInterface)=Usb_read_byte(); 00599 MSB(wInterface)=Usb_read_byte(); 00600 if( 0!=wValue_msb ) 00601 return FALSE; 00602 Usb_ack_receive_setup(); 00603 00604 usb_user_interface_reset(wInterface, wValue_lsb); 00605 Usb_select_endpoint(EP_CONTROL); 00606 00607 Usb_send_control_in(); 00608 while(!Is_usb_in_ready()); 00609 return TRUE; 00610 } 00611 00612 00615 void usb_generate_remote_wakeup(void) 00616 { 00617 if(Is_pll_ready()==FALSE) 00618 { 00619 Pll_start_auto(); 00620 Wait_pll_ready(); 00621 } 00622 Usb_unfreeze_clock(); 00623 if (remote_wakeup_feature == ENABLED) 00624 { 00625 Usb_initiate_remote_wake_up(); 00626 remote_wakeup_feature = DISABLED; 00627 } 00628 } 00629 00630 00631 #if ((USB_DEVICE_SN_USE==ENABLE) && (USE_DEVICE_SN_UNIQUE==ENABLE)) 00639 U8 bin_to_ascii (U8 b) 00640 { 00641 return ( (b <= 0x09) ? (b+'0') : (b+'A'-10) ); 00642 } 00643 #endif 00644