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 AND FITNESS FOR A PARTICULAR PURPOSE 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 Usb_unfreeze_clock(); 00170 usb_init_device(); // configure the USB controller EP0 00171 Usb_attach(); 00172 Usb_enable_suspend_interrupt(); 00173 Usb_enable_reset_interrupt(); 00174 #if (USB_OTG_FEATURE == ENABLED) 00175 Usb_enable_id_interrupt(); 00176 #endif 00177 } 00178 00189 void usb_device_task(void) 00190 { 00191 00192 #if (USB_OTG_FEATURE == ENABLED) 00193 // Check if a reset has been received 00194 if(Is_usb_event(EVT_USB_RESET)) 00195 { 00196 Usb_ack_event(EVT_USB_RESET); 00197 Usb_reset_endpoint(0); 00198 usb_configuration_nb=0; 00199 otg_b_device_state = B_IDLE; 00200 Clear_otg_features_from_host(); 00201 } 00202 00203 // When OTG mode enabled, B-Device is managed thanks to its state machine 00204 switch (otg_b_device_state) 00205 { 00206 //------------------------------------------------------ 00207 // B_IDLE state 00208 // 00209 // - waits for Vbus to rise 00210 // - initiate SRP if asked by user 00211 // 00212 case B_IDLE: 00213 if (Is_usb_vbus_high()) 00214 { 00215 // Vbus rise 00216 usb_connected = TRUE; 00217 remote_wakeup_feature = DISABLED; 00218 usb_start_device(); 00219 Usb_vbus_on_action(); 00220 Usb_attach(); 00221 otg_b_device_state = B_PERIPHERAL; 00222 Ack_user_request_srp(); 00223 Clear_otg_features_from_host(); 00224 remote_wakeup_feature = DISABLED; 00225 End_session_with_srp(); 00226 if (Is_srp_sent_and_waiting_answer() && (sof_seen_in_session == TRUE)) 00227 { 00228 Ack_srp_sent_and_answer(); 00229 Otg_print_new_failure_message(OTGMSG_A_RESPONDED,OTG_TEMPO_2SEC); 00230 } 00231 Usb_enable_sof_interrupt(); 00232 00233 } 00234 else 00235 { 00236 if (Is_user_requested_srp() && Is_usb_id_device()) 00237 { 00238 // User has requested a SRP 00239 Ack_user_request_srp(); 00240 if (!Is_srp_sent_and_waiting_answer()) 00241 { 00242 Pll_start_auto(); // reinit device mode 00243 Wait_pll_ready(); 00244 Usb_disable(); 00245 Usb_enable_uid_pin(); 00246 Usb_enable(); 00247 Usb_unfreeze_clock(); 00248 Usb_select_device(); 00249 Usb_attach(); 00250 otg_b_device_state = B_SRP_INIT; 00251 Usb_device_initiate_srp(); // hardware waits for initial condition (SE0, Session End level) 00252 sof_seen_in_session = FALSE; 00253 } 00254 } 00255 if ((Is_srp_sent_and_waiting_answer()) && (Is_tb_srp_counter_overflow())) 00256 { 00257 // SRP failed because A-Device did not respond 00258 End_session_with_srp(); 00259 Ack_srp_sent_and_answer(); 00260 Otg_print_new_failure_message(OTGMSG_SRP_A_NO_RESP,OTG_TEMPO_3SEC); 00261 } 00262 } 00263 break; 00264 00265 00266 //------------------------------------------------------ 00267 // B_SRP_INIT 00268 // 00269 // - a SRP has been initiated 00270 // - B-Device waits it is finished to initialize variables 00271 // 00272 case B_SRP_INIT: 00273 if (!Is_usb_device_initiating_srp()) 00274 { 00275 otg_b_device_state = B_IDLE; // SRP initiated, return to Idle state (wait for Vbus to rise) 00276 Srp_sent_and_waiting_answer(); 00277 Init_tb_srp_counter(); 00278 Start_session_with_srp(); 00279 Otg_print_new_event_message(OTGMSG_SRP_STARTED,TB_SRP_FAIL_MIN); 00280 } 00281 break; 00282 00283 00284 //------------------------------------------------------ 00285 // B_PERIPHERAL : the main state of OTG Peripheral 00286 // 00287 // - all events are interrupt-handled 00288 // - but they are saved and this function can execute alternate actions 00289 // - also handle user requests (disconnect) 00290 // 00291 // ====================================================================================== 00292 case B_PERIPHERAL: 00293 if (Is_otg_event(EVT_OTG_DEVICE_CONNECTED)) 00294 { 00295 Otg_ack_event(EVT_OTG_DEVICE_CONNECTED); // set on a SetConfiguration descriptor reception 00296 Otg_print_new_event_message(OTGMSG_CONNECTED_TO_A,OTG_TEMPO_4SEC); 00297 } 00298 if (Is_usb_event(EVT_USB_SUSPEND)) // SUSPEND state 00299 { 00300 // Suspend and HNP operations are handled in the interrupt functions 00301 } 00302 if (Is_srp_sent_and_waiting_answer() && (sof_seen_in_session == TRUE)) 00303 { 00304 Ack_srp_sent_and_answer(); 00305 Otg_print_new_failure_message(OTGMSG_A_RESPONDED,OTG_TEMPO_2SEC); 00306 } 00307 if ((Is_srp_sent_and_waiting_answer()) && (Is_tb_srp_counter_overflow())) 00308 { 00309 // SRP failed because A-Device did not respond 00310 End_session_with_srp(); 00311 Ack_srp_sent_and_answer(); 00312 Otg_print_new_failure_message(OTGMSG_SRP_A_NO_RESP,OTG_TEMPO_3SEC); 00313 } 00314 00315 if (Is_usb_event(EVT_USB_RESUME) && !Is_usb_pending_remote_wake_up()) // RESUME signal detected 00316 { 00317 Usb_ack_event(EVT_USB_RESUME); 00318 Usb_ack_event(EVT_USB_SUSPEND); 00319 Usb_ack_remote_wake_up_start(); 00320 } 00321 if (Is_usb_event(EVT_USB_UNPOWERED)) 00322 { 00323 Usb_ack_event(EVT_USB_UNPOWERED); 00324 Clear_all_user_request(); 00325 otg_b_device_state = B_IDLE; 00326 } 00327 if(Is_usb_event(EVT_USB_RESET)) 00328 { 00329 Usb_ack_event(EVT_USB_RESET); 00330 Usb_reset_endpoint(0); 00331 usb_configuration_nb=0; 00332 Clear_otg_features_from_host(); 00333 } 00334 if (Is_otg_event(EVT_OTG_HNP_ERROR)) 00335 { 00336 Otg_ack_event(EVT_OTG_HNP_ERROR); 00337 Otg_print_new_failure_message(OTGMSG_DEVICE_NO_RESP,OTG_TEMPO_4SEC); 00338 PORTC &= ~0x10; 00339 } 00340 if (Is_user_requested_disc()) 00341 { 00342 Ack_user_request_disc(); 00343 if (Is_usb_id_device()) 00344 { 00345 Usb_detach(); 00346 Usb_freeze_clock(); 00347 while (Is_usb_vbus_high()); // wait for Vbus to be under Va_vbus_valid 00348 otg_b_device_state = B_IDLE; 00349 usb_configuration_nb = 0; 00350 usb_connected = FALSE; 00351 Clear_all_user_request(); 00352 } 00353 } 00354 break; 00355 00356 //------------------------------------------------------ 00357 // B_HOST 00358 // 00359 // - state entered after an HNP success 00360 // - handle user requests (disconnection, suspend, hnp) 00361 // - call the "host_task()" for Host level handlers 00362 // 00363 // ====================================================================================== 00364 case B_HOST: 00365 if (Is_otg_event(EVT_OTG_DEV_UNSUPPORTED)) 00366 { 00367 Otg_ack_event(EVT_OTG_DEV_UNSUPPORTED); 00368 Clear_all_user_request(); 00369 otg_b_device_state = B_IDLE; 00370 device_state = DEVICE_UNATTACHED; 00371 } 00372 if (Is_user_requested_disc() || Is_user_requested_suspend() || Is_user_requested_hnp()) 00373 { 00374 Ack_user_request_disc(); // suspend and hnp requests cleared in B_END_HNP_SUSPEND stage 00375 Host_disable_sof(); // go into suspend mode 00376 Usb_host_reject_hnp(); 00377 otg_b_device_state = B_END_HNP_SUSPEND; 00378 Usb_ack_suspend(); 00379 Usb_enable_suspend_interrupt(); 00380 } 00381 if (Is_usb_event(EVT_USB_UNPOWERED)) 00382 { 00383 Usb_ack_event(EVT_USB_UNPOWERED); 00384 Usb_freeze_clock(); 00385 otg_b_device_state = B_IDLE; 00386 device_state = DEVICE_UNATTACHED; 00387 } 00388 usb_host_task(); // call the host task 00389 break; 00390 00391 //------------------------------------------------------ 00392 // B_END_HNP_SUSPEND 00393 // 00394 // - device enters this state after being B_HOST, on a user request to stop bus activity (suspend, disconnect or hnp request) 00395 // - macro is reset to peripheral mode 00396 // 00397 // ====================================================================================== 00398 case B_END_HNP_SUSPEND: 00399 if (Is_usb_event(EVT_USB_SUSPEND)) 00400 { 00401 Usb_ack_event(EVT_USB_SUSPEND); 00402 Usb_device_stop_hnp(); 00403 Usb_select_device(); 00404 device_state = DEVICE_UNATTACHED; 00405 if (Is_user_requested_hnp() || Is_user_requested_suspend()) 00406 { 00407 otg_b_device_state = B_PERIPHERAL; 00408 Ack_user_request_suspend(); 00409 Ack_user_request_hnp(); 00410 } 00411 else 00412 { 00413 otg_b_device_state = B_IDLE; 00414 Usb_detach(); 00415 Usb_freeze_clock(); 00416 } 00417 } 00418 break; 00419 00420 00421 default: 00422 otg_b_device_state = B_IDLE; 00423 Clear_all_user_request(); 00424 device_state = DEVICE_UNATTACHED; 00425 break; 00426 } 00427 00428 00429 #else 00430 00431 // Non-OTG exclusives Device operations 00432 00433 // VBUS state detection 00434 if (Is_usb_vbus_high()&& (usb_connected==FALSE)) 00435 { 00436 usb_connected = TRUE; 00437 remote_wakeup_feature = DISABLED; 00438 Usb_vbus_on_action(); 00439 Usb_send_event(EVT_USB_POWERED); 00440 usb_start_device(); 00441 } 00442 if (Is_usb_vbus_low()&& (usb_connected==TRUE)) 00443 { 00444 usb_connected = FALSE; 00445 usb_configuration_nb = 0; 00446 Usb_send_event(EVT_USB_UNPOWERED); 00447 Usb_freeze_clock(); 00448 Usb_vbus_off_action(); 00449 } 00450 00451 if(Is_usb_event(EVT_USB_RESET)) 00452 { 00453 Usb_ack_event(EVT_USB_RESET); 00454 Usb_reset_endpoint(0); 00455 usb_configuration_nb=0; 00456 } 00457 00458 #endif 00459 00460 00461 00462 // ======================================= 00463 // Common Standard Device Control Requests 00464 // ======================================= 00465 // - device enumeration process 00466 // - device control commands and features 00467 Usb_select_endpoint(EP_CONTROL); 00468 if (Is_usb_receive_setup()) 00469 { 00470 usb_process_request(); 00471 } 00472 }