00001 00002 00003 00004 00005 00006 00007 00008 00009 00010 00011 00012 00013 00014 00015 00016 00017 00018 00019 00020 00021 00022 00023 00024 00025 00026 00027 00028 00029 00030 00031 00032 //_____ I N C L U D E S ___________________________________________________ 00033 00034 #include "config.h" 00035 #include "conf_usb.h" 00036 #include "usb_task.h" 00037 #include "lib_mcu/usb/usb_drv.h" 00038 #if ((USB_DEVICE_FEATURE == ENABLED)) 00039 #include "usb_descriptors.h" 00040 #endif 00041 #include "lib_mcu/power/power_drv.h" 00042 #include "lib_mcu/wdt/wdt_drv.h" 00043 #include "lib_mcu/pll/pll_drv.h" 00044 00045 #if ((USB_HOST_FEATURE == ENABLED)) 00046 #include "modules/usb/host_chap9/usb_host_task.h" 00047 #if (USB_HOST_PIPE_INTERRUPT_TRANSFER == ENABLE) 00048 extern U8 g_sav_int_sof_enable; 00049 #endif 00050 #endif 00051 00052 #if ((USB_DEVICE_FEATURE == ENABLED)) 00053 #include "modules/usb/device_chap9/usb_device_task.h" 00054 #endif 00055 00056 #ifndef USE_USB_PADS_REGULATOR 00057 #error "USE_USB_PADS_REGULATOR" should be defined as ENABLE or DISABLE in conf_usb.h file 00058 #endif 00059 00060 //_____ M A C R O S ________________________________________________________ 00061 00062 #ifndef LOG_STR_CODE 00063 #define LOG_STR_CODE(str) 00064 #else 00065 U8 code log_device_disconnect[]="Device Disconnected"; 00066 U8 code log_id_change[]="Pin Id Change"; 00067 #endif 00068 00069 //_____ D E F I N I T I O N S ______________________________________________ 00070 00081 volatile U16 g_usb_event=0; 00082 00083 00084 #if (USB_DEVICE_FEATURE == ENABLED) 00091 extern bit usb_connected; 00092 00099 extern U8 usb_configuration_nb; 00100 #endif 00101 00102 00103 #if (USB_HOST_FEATURE == ENABLED) 00110 volatile U8 private_sof_counter=0; 00111 00112 #if (USB_HOST_PIPE_INTERRUPT_TRANSFER == ENABLE) 00113 extern volatile S_pipe_int it_pipe_str[MAX_EP_NB]; 00114 #endif 00115 00116 #endif 00117 00118 #if ((USB_DEVICE_FEATURE == ENABLED)&& (USB_HOST_FEATURE == ENABLED)) 00124 U8 g_usb_mode=USB_MODE_UNDEFINED; 00125 U8 g_old_usb_mode; 00126 #endif 00127 00128 //_____ D E C L A R A T I O N S ____________________________________________ 00129 00140 void usb_task_init(void) 00141 { 00142 #if (USB_HOST_FEATURE == ENABLED && USB_DEVICE_FEATURE == ENABLED) 00143 U8 delay; 00144 #endif 00145 00146 #if (USE_USB_PADS_REGULATOR==ENABLE) // Otherwise assume USB PADs regulator is not used 00147 Usb_enable_regulator(); 00148 #endif 00149 00150 // ---- DUAL ROLE DEVICE USB MODE --------------------------------------------- 00151 #if ((USB_DEVICE_FEATURE == ENABLED)&& (USB_HOST_FEATURE == ENABLED)) 00152 Usb_enable_uid_pin(); 00153 delay=PORTA; 00154 g_usb_mode=USB_MODE_UNDEFINED; 00155 if(Is_usb_id_device()) 00156 { 00157 g_usb_mode=USB_MODE_DEVICE; 00158 usb_device_task_init(); 00159 } 00160 else 00161 { 00162 g_usb_mode=USB_MODE_HOST; 00163 Usb_ack_id_transition(); // REQUIRED !!! Startup with ID=0, Ack ID pin transistion (default hwd start up is device mode) 00164 Usb_enable_id_interrupt(); 00165 Enable_interrupt(); 00166 usb_host_task_init(); 00167 } 00168 g_old_usb_mode=g_usb_mode; // Store current usb mode, for mode change detection 00169 // ----------------------------------------------------------------------------- 00170 00171 // ---- DEVICE ONLY USB MODE --------------------------------------------------- 00172 #elif ((USB_DEVICE_FEATURE == ENABLED)&& (USB_HOST_FEATURE == DISABLE)) 00173 Usb_force_device_mode(); 00174 usb_device_task_init(); 00175 // ----------------------------------------------------------------------------- 00176 00177 // ---- REDUCED HOST ONLY USB MODE --------------------------------------------- 00178 #elif ((USB_DEVICE_FEATURE == DISABLE)&& (USB_HOST_FEATURE == ENABLED)) 00179 Usb_force_host_mode(); 00180 usb_host_task_init(); 00181 #elif ((USB_DEVICE_FEATURE == DISABLE)&& (USB_HOST_FEATURE == DISABLE)) 00182 #error at least one of USB_DEVICE_FEATURE or USB_HOST_FEATURE should be enabled 00183 #endif 00184 // ----------------------------------------------------------------------------- 00185 00186 00187 } 00188 00199 void usb_task(void) 00200 { 00201 // ---- DUAL ROLE DEVICE USB MODE --------------------------------------------- 00202 #if ((USB_DEVICE_FEATURE == ENABLED)&& (USB_HOST_FEATURE == ENABLED)) 00203 if(Is_usb_id_device()) 00204 { g_usb_mode=USB_MODE_DEVICE;} 00205 else 00206 { g_usb_mode=USB_MODE_HOST;} 00207 // TODO !!! ID pin hot state change 00208 // Preliminary management: HARDWARE RESET !!! 00209 #if ( ID_PIN_CHANGE_GENERATE_RESET == ENABLE) 00210 // Hot ID transition generates wdt reset 00211 if((g_old_usb_mode!=g_usb_mode)) 00212 #ifndef AVRGCC 00213 {Wdt_change_16ms(); while(1); LOG_STR_CODE(log_id_change);} 00214 #else 00215 {Wdt_change_enable(); while(1); LOG_STR_CODE(log_id_change);} 00216 #endif 00217 00218 #endif 00219 g_old_usb_mode=g_usb_mode; // Store current usb mode, for mode change detection 00220 // Depending on current usb mode, launch the correct usb task (device or host) 00221 switch(g_usb_mode) 00222 { 00223 case USB_MODE_DEVICE: 00224 usb_device_task(); 00225 break; 00226 case USB_MODE_HOST: 00227 usb_host_task(); 00228 break; 00229 case USB_MODE_UNDEFINED: // No break ! 00230 default: 00231 break; 00232 } 00233 // ----------------------------------------------------------------------------- 00234 00235 // ---- DEVICE ONLY USB MODE --------------------------------------------------- 00236 #elif ((USB_DEVICE_FEATURE == ENABLED)&& (USB_HOST_FEATURE == DISABLE)) 00237 usb_device_task(); 00238 // ----------------------------------------------------------------------------- 00239 00240 // ---- REDUCED HOST ONLY USB MODE --------------------------------------------- 00241 #elif ((USB_DEVICE_FEATURE == DISABLE)&& (USB_HOST_FEATURE == ENABLED)) 00242 usb_host_task(); 00243 // ----------------------------------------------------------------------------- 00244 00246 #elif ((USB_DEVICE_FEATURE == DISABLE)&& (USB_HOST_FEATURE == DISABLE)) 00247 #error at least one of USB_DEVICE_FEATURE or USB_HOST_FEATURE should be enabled 00248 #error otherwise the usb task has nothing to do ... 00249 #endif 00250 // ----------------------------------------------------------------------------- 00251 00252 } 00253 00282 #ifdef AVRGCC 00283 ISR(USB_GEN_vect) 00284 #else 00285 #pragma vector = USB_GENERAL_vect 00286 __interrupt void usb_general_interrupt() 00287 #endif 00288 { 00289 #if (USB_HOST_PIPE_INTERRUPT_TRANSFER == ENABLE) 00290 U8 i; 00291 U8 save_pipe_nb; 00292 #endif 00293 // ---------- DEVICE events management ----------------------------------- 00294 #if (USB_DEVICE_FEATURE == ENABLED) 00295 //- VBUS state detection 00296 if (Is_usb_vbus_transition() && Is_usb_vbus_interrupt_enabled()) 00297 { 00298 Usb_ack_vbus_transition(); 00299 if (Is_usb_vbus_high()) 00300 { 00301 usb_connected = TRUE; 00302 Usb_vbus_on_action(); 00303 Usb_send_event(EVT_USB_POWERED); 00304 Usb_enable_reset_interrupt(); 00305 usb_start_device(); 00306 Usb_attach(); 00307 } 00308 else 00309 { 00310 Usb_vbus_off_action(); 00311 usb_connected = FALSE; 00312 usb_configuration_nb = 0; 00313 Usb_send_event(EVT_USB_UNPOWERED); 00314 } 00315 } 00316 // - Device start of frame received 00317 if (Is_usb_sof() && Is_sof_interrupt_enabled()) 00318 { 00319 Usb_ack_sof(); 00320 Usb_sof_action(); 00321 } 00322 // - Device Suspend event (no more USB activity detected) 00323 if (Is_usb_suspend() && Is_suspend_interrupt_enabled()) 00324 { 00325 Usb_ack_suspend(); 00326 Usb_enable_wake_up_interrupt(); 00327 Usb_ack_wake_up(); // clear wake up to detect next event 00328 Usb_freeze_clock(); 00329 Usb_send_event(EVT_USB_SUSPEND); 00330 Usb_suspend_action(); 00331 } 00332 // - Wake up event (USB activity detected): Used to resume 00333 if (Is_usb_wake_up() && Is_swake_up_interrupt_enabled()) 00334 { 00335 Usb_unfreeze_clock(); 00336 Usb_ack_wake_up(); 00337 Usb_disable_wake_up_interrupt(); 00338 Usb_wake_up_action(); 00339 Usb_send_event(EVT_USB_WAKE_UP); 00340 } 00341 // - Resume state bus detection 00342 if (Is_usb_resume() && Is_resume_interrupt_enabled()) 00343 { 00344 Usb_disable_wake_up_interrupt(); 00345 Usb_ack_resume(); 00346 Usb_disable_resume_interrupt(); 00347 Usb_resume_action(); 00348 Usb_send_event(EVT_USB_RESUME); 00349 } 00350 // - USB bus reset detection 00351 if (Is_usb_reset()&& Is_reset_interrupt_enabled()) 00352 { 00353 Usb_ack_reset(); 00354 usb_init_device(); 00355 Usb_reset_action(); 00356 Usb_send_event(EVT_USB_RESET); 00357 } 00358 #endif// End DEVICE FEATURE MODE 00359 00360 // ---------- HOST events management ----------------------------------- 00361 #if (USB_HOST_FEATURE == ENABLED && USB_DEVICE_FEATURE == ENABLED) 00362 // - ID pin change detection 00363 if(Is_usb_id_transition()&&Is_usb_id_interrupt_enabled()) 00364 { 00365 if(Is_usb_id_device()) 00366 { g_usb_mode=USB_MODE_DEVICE;} 00367 else 00368 { g_usb_mode=USB_MODE_HOST;} 00369 Usb_ack_id_transition(); 00370 if( g_usb_mode != g_old_usb_mode) // Basic Debounce 00371 { 00372 if(Is_usb_id_device()) // Going to device mode 00373 { 00374 Usb_send_event(EVT_USB_DEVICE_FUNCTION); 00375 } 00376 else // Going to host mode 00377 { 00378 Usb_send_event(EVT_USB_HOST_FUNCTION); 00379 } 00380 Usb_id_transition_action(); 00381 LOG_STR_CODE(log_id_change); 00382 #if ( ID_PIN_CHANGE_GENERATE_RESET == ENABLE) 00383 // Hot ID transition generates wdt reset 00384 #ifndef AVRGCC 00385 Wdt_change_16ms(); while(1); 00386 #else 00387 Wdt_change_enable(); while(1); 00388 #endif 00389 #endif 00390 } 00391 } 00392 #endif 00393 #if (USB_HOST_FEATURE == ENABLED) 00394 // - The device has been disconnected 00395 if(Is_device_disconnection() && Is_host_device_disconnection_interrupt_enabled()) 00396 { 00397 host_disable_all_pipe(); 00398 Host_ack_device_disconnection(); 00399 device_state=DEVICE_DISCONNECTED; 00400 Usb_send_event(EVT_HOST_DISCONNECTION); 00401 LOG_STR_CODE(log_device_disconnect); 00402 Host_device_disconnection_action(); 00403 } 00404 // - Device connection 00405 if(Is_device_connection() && Is_host_device_connection_interrupt_enabled()) 00406 { 00407 Host_ack_device_connection(); 00408 host_disable_all_pipe(); 00409 Host_device_connection_action(); 00410 } 00411 // - Host Start of frame has been sent 00412 if (Is_host_sof() && Is_host_sof_interrupt_enabled()) 00413 { 00414 Host_ack_sof(); 00415 Usb_send_event(EVT_HOST_SOF); 00416 private_sof_counter++; 00417 00418 // delay timeout management for interrupt tranfer mode in host mode 00419 #if ((USB_HOST_PIPE_INTERRUPT_TRANSFER==ENABLE) && (TIMEOUT_DELAY_ENABLE==ENABLE)) 00420 if (private_sof_counter>=250) // Count 1/4 sec 00421 { 00422 private_sof_counter=0; 00423 for(i=0;i<MAX_EP_NB;i++) 00424 { 00425 if(it_pipe_str[i].enable==ENABLE) 00426 { 00427 save_pipe_nb=Host_get_selected_pipe(); 00428 Host_select_pipe(i); 00429 if((++it_pipe_str[i].timeout>TIMEOUT_DELAY) && (Host_get_pipe_type()!=TYPE_INTERRUPT)) 00430 { 00431 it_pipe_str[i].enable=DISABLE; 00432 it_pipe_str[i].status=PIPE_DELAY_TIMEOUT; 00433 Host_stop_pipe_interrupt(i); 00434 if (is_any_interrupt_pipe_active()==FALSE) // If no more transfer is armed 00435 { 00436 if (g_sav_int_sof_enable==FALSE) 00437 { 00438 Host_disable_sof_interrupt(); 00439 } 00440 } 00441 it_pipe_str[i].handle(PIPE_DELAY_TIMEOUT,it_pipe_str[i].nb_byte_processed); 00442 } 00443 Host_select_pipe(save_pipe_nb); 00444 } 00445 } 00446 } 00447 #endif // (USB_HOST_PIPE_INTERRUPT_TRANSFER==ENABLE) && (TIMEOUT_DELAY_ENABLE==ENABLE)) 00448 Host_sof_action(); 00449 } 00450 // - Host Wake-up has been received 00451 if (Is_host_hwup() && Is_host_hwup_interrupt_enabled()) 00452 { 00453 Host_disable_hwup_interrupt(); // Wake up interrupt should be disable host is now wake up ! 00454 // CAUTION HWUP can be cleared only when USB clock is active (not frozen)! 00455 Pll_start_auto(); // First Restart the PLL for USB operation 00456 Wait_pll_ready(); // Get sure pll is lock 00457 Usb_unfreeze_clock(); // Enable clock on USB interface 00458 Host_ack_hwup(); // Clear HWUP interrupt flag 00459 Usb_send_event(EVT_HOST_HWUP); // Send software event 00460 Host_hwup_action(); // Map custom action 00461 } 00462 #endif // End HOST FEATURE MODE 00463 } 00464 00465 00466 extern void suspend_action(void) 00467 { 00468 Enable_interrupt(); 00469 Enter_power_down_mode(); 00470 } 00471 00472 extern void host_suspend_action(void) 00473 { 00474 //Enter_power_down_mode(); //For example... 00475 }