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
1.5.3