00001 /*This file has been prepared for Doxygen automatic documentation generation.*/ 00018 00019 /* Copyright (c) 2007, Atmel Corporation All rights reserved. 00020 * 00021 * Redistribution and use in source and binary forms, with or without 00022 * modification, are permitted provided that the following conditions are met: 00023 * 00024 * 1. Redistributions of source code must retain the above copyright notice, 00025 * this list of conditions and the following disclaimer. 00026 * 00027 * 2. Redistributions in binary form must reproduce the above copyright notice, 00028 * this list of conditions and the following disclaimer in the documentation 00029 * and/or other materials provided with the distribution. 00030 * 00031 * 3. The name of ATMEL may not be used to endorse or promote products derived 00032 * from this software without specific prior written permission. 00033 * 00034 * THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED 00035 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 00036 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE EXPRESSLY AND 00037 * SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, 00038 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00039 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00040 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 00041 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00042 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 00043 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00044 */ 00045 00046 //_____ I N C L U D E S ___________________________________________________ 00047 00048 #include "config.h" 00049 #include "conf_usb.h" 00050 #include "usb_device_task.h" 00051 #include "modules/usb/usb_task.h" 00052 #if (USB_OTG_FEATURE == ENABLED) 00053 #include "modules/usb/host_chap9/usb_host_task.h" 00054 #endif 00055 #include "lib_mcu/usb/usb_drv.h" 00056 #include "usb_descriptors.h" 00057 #include "modules/usb/device_chap9/usb_standard_request.h" 00058 #include "lib_mcu/pll/pll_drv.h" 00059 00060 #if ((TARGET_BOARD==SPIDER) && (USB_OTG_FEATURE==ENABLED)) 00061 #include "lib_board/lcd/lcd_drv.h" 00062 #endif 00063 00064 //_____ M A C R O S ________________________________________________________ 00065 00066 00067 00068 00069 //_____ D E F I N I T I O N S ______________________________________________ 00070 00076 bit usb_connected=FALSE; 00077 00083 bit usb_suspended=FALSE; 00084 00085 00086 00087 00094 extern U8 usb_configuration_nb; 00095 00096 00097 #if (USB_OTG_FEATURE == ENABLED) 00100 U8 otg_b_device_state; 00101 00104 U8 otg_device_sessions; 00105 00108 U8 otg_b_device_hnp; 00109 00112 U16 otg_tb_srp_cpt; 00113 00117 U8 sof_seen_in_session; 00118 #endif 00119 00120 00121 //_____ D E C L A R A T I O N S ____________________________________________ 00122 00135 void usb_device_task_init(void) 00136 { 00137 Enable_interrupt(); 00138 Usb_disable(); 00139 Usb_enable(); 00140 Usb_select_device(); 00141 #if (USB_LOW_SPEED_DEVICE==ENABLE) 00142 Usb_low_speed_mode(); 00143 #endif 00144 Enable_interrupt(); 00145 #if (USB_OTG_FEATURE == ENABLED) 00146 Usb_enable_id_interrupt(); 00147 Clear_otg_features_from_host(); 00148 otg_device_sessions = 0; 00149 #endif 00150 } 00151 00165 void usb_start_device (void) 00166 { 00167 Pll_start_auto(); 00168 Wait_pll_ready(); 00169 00170 Disable_interrupt(); 00171 Usb_unfreeze_clock(); 00172 usb_init_device(); // configure the USB controller EP0 00173 Usb_attach(); 00174 Enable_interrupt(); 00175 00176 Usb_enable_suspend_interrupt(); 00177 Usb_enable_reset_interrupt(); 00178 #if (USB_OTG_FEATURE == ENABLED) 00179 Usb_enable_id_interrupt(); 00180 #endif 00181 } 00182 00193 void usb_device_task(void) 00194 { 00195 00196 #if (USB_OTG_FEATURE == ENABLED) 00197 // Check if a reset has been received 00198 if(Is_usb_event(EVT_USB_RESET)) 00199 { 00200 Usb_ack_event(EVT_USB_RESET); 00201 Usb_reset_endpoint(0); 00202 usb_configuration_nb=0; 00203 otg_b_device_state = B_IDLE; 00204 Clear_otg_features_from_host(); 00205 } 00206 00207 // When OTG mode enabled, B-Device is managed thanks to its state machine 00208 switch (otg_b_device_state) 00209 { 00210 //------------------------------------------------------ 00211 // B_IDLE state 00212 // 00213 // - waits for Vbus to rise 00214 // - initiate SRP if asked by user 00215 // 00216 case B_IDLE: 00217 if (Is_usb_vbus_high()) 00218 { 00219 // Vbus rise 00220 usb_connected = TRUE; 00221 remote_wakeup_feature = DISABLED; 00222 usb_start_device(); 00223 Usb_vbus_on_action(); 00224 Usb_attach(); 00225 otg_b_device_state = B_PERIPHERAL; 00226 Ack_user_request_srp(); 00227 Clear_otg_features_from_host(); 00228 remote_wakeup_feature = DISABLED; 00229 End_session_with_srp(); 00230 if (Is_srp_sent_and_waiting_answer() && (sof_seen_in_session == TRUE)) 00231 { 00232 Ack_srp_sent_and_answer(); 00233 Otg_print_new_failure_message(OTGMSG_A_RESPONDED,OTG_TEMPO_2SEC); 00234 } 00235 Usb_enable_sof_interrupt(); 00236 00237 } 00238 else 00239 { 00240 if (Is_user_requested_srp() && Is_usb_id_device()) 00241 { 00242 // User has requested a SRP 00243 Ack_user_request_srp(); 00244 if (!Is_srp_sent_and_waiting_answer()) 00245 { 00246 Pll_start_auto(); // reinit device mode 00247 Wait_pll_ready(); 00248 Usb_disable(); 00249 Usb_enable_uid_pin(); 00250 Usb_enable(); 00251 Usb_unfreeze_clock(); 00252 Usb_select_device(); 00253 Usb_attach(); 00254 otg_b_device_state = B_SRP_INIT; 00255 Usb_device_initiate_srp(); // hardware waits for initial condition (SE0, Session End level) 00256 sof_seen_in_session = FALSE; 00257 } 00258 } 00259 if ((Is_srp_sent_and_waiting_answer()) && (Is_tb_srp_counter_overflow())) 00260 { 00261 // SRP failed because A-Device did not respond 00262 End_session_with_srp(); 00263 Ack_srp_sent_and_answer(); 00264 Otg_print_new_failure_message(OTGMSG_SRP_A_NO_RESP,OTG_TEMPO_3SEC); 00265 } 00266 } 00267 break; 00268 00269 00270 //------------------------------------------------------ 00271 // B_SRP_INIT 00272 // 00273 // - a SRP has been initiated 00274 // - B-Device waits it is finished to initialize variables 00275 // 00276 case B_SRP_INIT: 00277 if (!Is_usb_device_initiating_srp()) 00278 { 00279 otg_b_device_state = B_IDLE; // SRP initiated, return to Idle state (wait for Vbus to rise) 00280 Srp_sent_and_waiting_answer(); 00281 Init_tb_srp_counter(); 00282 Start_session_with_srp(); 00283 Otg_print_new_event_message(OTGMSG_SRP_STARTED,TB_SRP_FAIL_MIN); 00284 } 00285 break; 00286 00287 00288 //------------------------------------------------------ 00289 // B_PERIPHERAL : the main state of OTG Peripheral 00290 // 00291 // - all events are interrupt-handled 00292 // - but they are saved and this function can execute alternate actions 00293 // - also handle user requests (disconnect) 00294 // 00295 // ====================================================================================== 00296 case B_PERIPHERAL: 00297 if (Is_otg_event(EVT_OTG_DEVICE_CONNECTED)) 00298 { 00299 Otg_ack_event(EVT_OTG_DEVICE_CONNECTED); // set on a SetConfiguration descriptor reception 00300 Otg_print_new_event_message(OTGMSG_CONNECTED_TO_A,OTG_TEMPO_4SEC); 00301 } 00302 if (Is_usb_event(EVT_USB_SUSPEND)) // SUSPEND state 00303 { 00304 // Suspend and HNP operations are handled in the interrupt functions 00305 } 00306 if (Is_srp_sent_and_waiting_answer() && (sof_seen_in_session == TRUE)) 00307 { 00308 Ack_srp_sent_and_answer(); 00309 Otg_print_new_failure_message(OTGMSG_A_RESPONDED,OTG_TEMPO_2SEC); 00310 } 00311 if ((Is_srp_sent_and_waiting_answer()) && (Is_tb_srp_counter_overflow())) 00312 { 00313 // SRP failed because A-Device did not respond 00314 End_session_with_srp(); 00315 Ack_srp_sent_and_answer(); 00316 Otg_print_new_failure_message(OTGMSG_SRP_A_NO_RESP,OTG_TEMPO_3SEC); 00317 } 00318 00319 if (Is_usb_event(EVT_USB_RESUME) && !Is_usb_pending_remote_wake_up()) // RESUME signal detected 00320 { 00321 Usb_ack_event(EVT_USB_RESUME); 00322 Usb_ack_event(EVT_USB_SUSPEND); 00323 Usb_ack_remote_wake_up_start(); 00324 } 00325 if (Is_usb_event(EVT_USB_UNPOWERED)) 00326 { 00327 Usb_ack_event(EVT_USB_UNPOWERED); 00328 Clear_all_user_request(); 00329 otg_b_device_state = B_IDLE; 00330 } 00331 if(Is_usb_event(EVT_USB_RESET)) 00332 { 00333 Usb_ack_event(EVT_USB_RESET); 00334 Usb_reset_endpoint(0); 00335 usb_configuration_nb=0; 00336 Clear_otg_features_from_host(); 00337 } 00338 if (Is_otg_event(EVT_OTG_HNP_ERROR)) 00339 { 00340 Otg_ack_event(EVT_OTG_HNP_ERROR); 00341 Otg_print_new_failure_message(OTGMSG_DEVICE_NO_RESP,OTG_TEMPO_4SEC); 00342 PORTC &= ~0x10; 00343 } 00344 if (Is_user_requested_disc()) 00345 { 00346 Ack_user_request_disc(); 00347 if (Is_usb_id_device()) 00348 { 00349 Usb_detach(); 00350 Usb_freeze_clock(); 00351 while (Is_usb_vbus_high()); // wait for Vbus to be under Va_vbus_valid 00352 otg_b_device_state = B_IDLE; 00353 usb_configuration_nb = 0; 00354 usb_connected = FALSE; 00355 Clear_all_user_request(); 00356 } 00357 } 00358 break; 00359 00360 //------------------------------------------------------ 00361 // B_HOST 00362 // 00363 // - state entered after an HNP success 00364 // - handle user requests (disconnection, suspend, hnp) 00365 // - call the "host_task()" for Host level handlers 00366 // 00367 // ====================================================================================== 00368 case B_HOST: 00369 if (Is_otg_event(EVT_OTG_DEV_UNSUPPORTED)) 00370 { 00371 Otg_ack_event(EVT_OTG_DEV_UNSUPPORTED); 00372 Clear_all_user_request(); 00373 otg_b_device_state = B_IDLE; 00374 device_state = DEVICE_UNATTACHED; 00375 } 00376 if (Is_user_requested_disc() || Is_user_requested_suspend() || Is_user_requested_hnp()) 00377 { 00378 Ack_user_request_disc(); // suspend and hnp requests cleared in B_END_HNP_SUSPEND stage 00379 Host_disable_sof(); // go into suspend mode 00380 Usb_host_reject_hnp(); 00381 otg_b_device_state = B_END_HNP_SUSPEND; 00382 Usb_ack_suspend(); 00383 Usb_enable_suspend_interrupt(); 00384 } 00385 if (Is_usb_event(EVT_USB_UNPOWERED)) 00386 { 00387 Usb_ack_event(EVT_USB_UNPOWERED); 00388 Usb_freeze_clock(); 00389 otg_b_device_state = B_IDLE; 00390 device_state = DEVICE_UNATTACHED; 00391 } 00392 usb_host_task(); // call the host task 00393 break; 00394 00395 //------------------------------------------------------ 00396 // B_END_HNP_SUSPEND 00397 // 00398 // - device enters this state after being B_HOST, on a user request to stop bus activity (suspend, disconnect or hnp request) 00399 // - macro is reset to peripheral mode 00400 // 00401 // ====================================================================================== 00402 case B_END_HNP_SUSPEND: 00403 if (Is_usb_event(EVT_USB_SUSPEND)) 00404 { 00405 Usb_ack_event(EVT_USB_SUSPEND); 00406 Usb_device_stop_hnp(); 00407 Usb_select_device(); 00408 device_state = DEVICE_UNATTACHED; 00409 if (Is_user_requested_hnp() || Is_user_requested_suspend()) 00410 { 00411 otg_b_device_state = B_PERIPHERAL; 00412 Ack_user_request_suspend(); 00413 Ack_user_request_hnp(); 00414 } 00415 else 00416 { 00417 otg_b_device_state = B_IDLE; 00418 Usb_detach(); 00419 Usb_freeze_clock(); 00420 } 00421 } 00422 break; 00423 00424 00425 default: 00426 otg_b_device_state = B_IDLE; 00427 Clear_all_user_request(); 00428 device_state = DEVICE_UNATTACHED; 00429 break; 00430 } 00431 00432 00433 #else 00434 00435 // Non-OTG exclusives Device operations 00436 00437 // VBUS state detection 00438 if (Is_usb_vbus_high()&& (usb_connected==FALSE)) 00439 { 00440 usb_connected = TRUE; 00441 remote_wakeup_feature = DISABLED; 00442 Usb_vbus_on_action(); 00443 Usb_send_event(EVT_USB_POWERED); 00444 usb_start_device(); 00445 } 00446 if (Is_usb_vbus_low()&& (usb_connected==TRUE)) 00447 { 00448 usb_connected = FALSE; 00449 usb_configuration_nb = 0; 00450 Usb_send_event(EVT_USB_UNPOWERED); 00451 Usb_detach(); 00452 Usb_freeze_clock(); 00453 Usb_vbus_off_action(); 00454 } 00455 00456 if(Is_usb_event(EVT_USB_RESET)) 00457 { 00458 Usb_ack_event(EVT_USB_RESET); 00459 Usb_reset_endpoint(0); 00460 usb_configuration_nb=0; 00461 } 00462 00463 #endif 00464 00465 00466 00467 // ======================================= 00468 // Common Standard Device Control Requests 00469 // ======================================= 00470 // - device enumeration process 00471 // - device control commands and features 00472 Usb_select_endpoint(EP_CONTROL); 00473 if (Is_usb_receive_setup()) 00474 { 00475 usb_process_request(); 00476 } 00477 }
1.5.3