#include "config.h"
#include "conf_usb.h"
#include "usb_task.h"
#include "lib_mcu/usb/usb_drv.h"
#include "usb_descriptors.h"
#include "lib_mcu/power/power_drv.h"
#include "lib_mcu/wdt/wdt_drv.h"
#include "lib_mcu/pll/pll_drv.h"
#include "modules/usb/host_chap9/usb_host_task.h"
#include "modules/usb/host_chap9/usb_host_enum.h"
#include "modules/usb/device_chap9/usb_device_task.h"
Go to the source code of this file.
Defines | |
#define | LOG_STR_CODE(str) |
Functions | |
void | usb_task_init (void) |
void | usb_task (void) |
__interrupt void | usb_general_interrupt () |
Variables | |
U8 | g_sav_int_sof_enable |
volatile U16 | g_usb_event = 0 |
Public : U16 g_usb_event usb_connected is used to store USB events detected upon USB general interrupt subroutine Its value is managed by the following macros (See usb_task.h file) Usb_send_event(x) Usb_ack_event(x) Usb_clear_all_event() Is_usb_event(x) Is_not_usb_event(x). | |
bit | usb_connected |
Public : (bit) usb_connected usb_connected is set to TRUE when VBUS has been detected usb_connected is set to FALSE otherwise Used with USB_DEVICE_FEATURE == ENABLED only /. | |
U8 | usb_configuration_nb |
Public : (U8) usb_configuration_nb Store the number of the USB configuration used by the USB device when its value is different from zero, it means the device mode is enumerated Used with USB_DEVICE_FEATURE == ENABLED only /. | |
U8 | remote_wakeup_feature |
Public : (U8) remote_wakeup_feature Store a host request for remote wake up (set feature received) /. | |
volatile U8 | private_sof_counter = 0 |
Private : (U8) private_sof_counter Incremented by host SOF interrupt subroutime This counter is used to detect timeout in host requests. | |
volatile S_pipe_int | it_pipe_str [MAX_EP_NB] |
volatile U8 | hub_interrupt_sof |
U8 | g_usb_mode = 0x00 |
Public : (U8) g_usb_mode Used in dual role application (both device/host) to store the current mode the usb controller is operating /. | |
U8 | g_old_usb_mode |
The USB task selects the correct USB task (usb_device task or usb_host task to be executed depending on the current mode available. According to USB_DEVICE_FEATURE and USB_HOST_FEATURE value (located in conf_usb.h file) The usb_task can be configured to support USB DEVICE mode or USB Host mode or both for a dual role device application. This module also contains the general USB interrupt subroutine. This subroutine is used to detect asynchronous USB events. Note:
Definition in file usb_task.c.
#define LOG_STR_CODE | ( | str | ) |
__interrupt void usb_general_interrupt | ( | ) |
USB interrupt subroutine This function is called each time a USB interrupt occurs. The following USB DEVICE events are taken in charge:
The following USB HOST events are taken in charge:
For each event, the user can launch an action by completing the associate define (See conf_usb.h file to add action upon events)
Note: Only interrupts events that are enabled are processed
none |
Definition at line 355 of file usb_task.c.
References DISABLE, ENABLE, ENABLED, EVT_HOST_DISCONNECTION, EVT_HOST_HWUP, EVT_HOST_SOF, EVT_USB_DEVICE_FUNCTION, EVT_USB_HOST_FUNCTION, EVT_USB_RESET, EVT_USB_RESUME, EVT_USB_SUSPEND, EVT_USB_WAKE_UP, FALSE, g_old_usb_mode, g_sav_int_sof_enable, g_usb_mode, Host_ack_device_connection, Host_ack_device_disconnection, Host_ack_hwup, Host_ack_sof, Host_device_connection_action, Host_device_disconnection_action, host_disable_all_pipe(), Host_disable_hwup_interrupt, Host_disable_sof_interrupt, Host_get_pipe_type, Host_get_selected_pipe, Host_hwup_action, Host_select_pipe, Host_sof_action, hub_interrupt_sof, Is_device_connection, Is_device_disconnection, Is_host_device_connection_interrupt_enabled, Is_host_device_disconnection_interrupt_enabled, Is_host_hwup, Is_host_hwup_interrupt_enabled, Is_host_sof, Is_host_sof_interrupt_enabled, Is_pll_ready, Is_reset_interrupt_enabled, Is_resume_interrupt_enabled, Is_sof_interrupt_enabled, Is_suspend_interrupt_enabled, Is_usb_id_device, Is_usb_id_interrupt_enabled, Is_usb_id_transition, Is_usb_reset, Is_usb_resume, Is_usb_sof, Is_usb_suspend, Is_usb_wake_up, Is_wake_up_interrupt_enabled, it_pipe_str, LOG_STR_CODE, MAX_EP_NB, private_sof_counter, remote_wakeup_feature, Stop_pll, TRUE, TYPE_INTERRUPT, Usb_ack_id_transition, Usb_ack_reset, Usb_ack_resume, Usb_ack_sof, Usb_ack_suspend, Usb_ack_wake_up, usb_configuration_nb, Usb_disable_resume_interrupt, Usb_disable_suspend_interrupt, Usb_disable_wake_up_interrupt, Usb_enable_reset_interrupt, Usb_enable_resume_interrupt, Usb_enable_suspend_interrupt, Usb_enable_wake_up_interrupt, Usb_freeze_clock, Usb_id_transition_action, usb_init_device(), USB_MODE_DEVICE, USB_MODE_HOST, Usb_reset_action, Usb_resume_action, Usb_send_event, Usb_sof_action, Usb_suspend_action, usb_suspended, Usb_unfreeze_clock, Usb_wake_up_action, Wait_pll_ready, wdtdrv_enable(), and WDTO_16MS.
00357 { 00358 #if (USB_HOST_PIPE_INTERRUPT_TRANSFER == ENABLE) 00359 U8 i; 00360 U8 save_pipe_nb; 00361 #endif 00362 // ---------- DEVICE events management ----------------------------------- 00363 #if (USB_DEVICE_FEATURE == ENABLED) 00364 00365 // - Device start of frame received 00366 if (Is_usb_sof() && Is_sof_interrupt_enabled()) 00367 { 00368 Usb_ack_sof(); 00369 Usb_sof_action(); 00370 } 00371 #ifdef WA_USB_SUSPEND_PERTUBATION 00372 // - Device Suspend event (no more USB activity detected) 00373 if (Is_usb_suspend() && Is_suspend_interrupt_enabled()) 00374 { 00375 usb_suspended=TRUE; 00376 Usb_ack_wake_up(); // clear wake up to detect next event 00377 Usb_send_event(EVT_USB_SUSPEND); 00378 Usb_ack_suspend(); 00379 Usb_enable_wake_up_interrupt(); 00380 Usb_disable_resume_interrupt(); 00381 Usb_freeze_clock(); 00382 Stop_pll(); 00383 Usb_suspend_action(); 00384 } 00385 // - Wake up event (USB activity detected): Used to resume 00386 if (Is_usb_wake_up() && Is_wake_up_interrupt_enabled()) 00387 { 00388 if(Is_pll_ready()==FALSE) 00389 { 00390 Pll_start_auto(); 00391 Wait_pll_ready(); 00392 } 00393 Usb_unfreeze_clock(); 00394 Usb_ack_wake_up(); 00395 if(usb_suspended) 00396 { 00397 Usb_enable_resume_interrupt(); 00398 Usb_enable_reset_interrupt(); 00399 while(Is_usb_wake_up()) 00400 { 00401 Usb_ack_wake_up(); 00402 } 00403 usb_delay_ms(2); 00404 if(Is_usb_sof() || Is_usb_resume() || Is_usb_reset() ) 00405 { 00406 Usb_disable_wake_up_interrupt(); 00407 Usb_wake_up_action(); 00408 Usb_send_event(EVT_USB_WAKE_UP); 00409 Usb_enable_suspend_interrupt(); 00410 Usb_enable_resume_interrupt(); 00411 Usb_enable_reset_interrupt(); 00412 00413 } 00414 else // Workarround to make the USB enter power down mode again (spurious transcient detected on the USB lines) 00415 { 00416 Usb_ack_wake_up(); // clear wake up to detect next event 00417 Usb_send_event(EVT_USB_SUSPEND); 00418 Usb_enable_wake_up_interrupt(); 00419 Usb_disable_resume_interrupt(); 00420 Usb_freeze_clock(); 00421 Stop_pll(); 00422 Usb_suspend_action(); 00423 } 00424 } 00425 } 00426 // - Resume state bus detection 00427 if (Is_usb_resume() && Is_resume_interrupt_enabled()) 00428 { 00429 usb_suspended = FALSE; 00430 Usb_disable_wake_up_interrupt(); 00431 Usb_ack_resume(); 00432 Usb_disable_resume_interrupt(); 00433 Usb_resume_action(); 00434 Usb_send_event(EVT_USB_RESUME); 00435 } 00436 #else 00437 // - Device Suspend event (no more USB activity detected) 00438 if (Is_usb_suspend() && Is_suspend_interrupt_enabled()) 00439 { 00440 // Remote wake-up handler 00441 if ((remote_wakeup_feature == ENABLED) && (usb_configuration_nb != 0)) 00442 { 00443 Usb_disable_suspend_interrupt(); 00444 Usb_ack_wake_up(); 00445 Usb_enable_wake_up_interrupt(); 00446 Stop_pll(); 00447 Usb_freeze_clock(); 00448 Usb_suspend_action(); 00449 00450 // After that user can execute "Usb_initiate_remote_wake_up()" to initiate a remote wake-up 00451 // Note that the suspend interrupt flag SUSPI must still be set to enable upstream resume 00452 // So the SUSPE enable bit must be cleared to avoid redundant interrupt 00453 // **************** 00454 // Please note also that is Vbus is lost during an upstream resume (Host disconnection), 00455 // the RMWKUP bit (used to initiate remote wake up and that is normally cleared by hardware when sent) 00456 // remains set after the event, so that a good way to handle this feature is : 00457 // Usb_unfreeze_clock(); 00458 // Usb_initiate_remote_wake_up(); 00459 // while (Is_usb_pending_remote_wake_up()) 00460 // { 00461 // if (Is_usb_vbus_low()) 00462 // { 00463 // // Emergency action (reset macro, etc.) if Vbus lost during resuming 00464 // break; 00465 // } 00466 // } 00467 // Usb_ack_remote_wake_up_start(); 00468 // **************** 00469 } 00470 else 00471 { 00472 // No remote wake-up supported 00473 Usb_ack_wake_up(); // clear wake up to detect next event 00474 Usb_send_event(EVT_USB_SUSPEND); 00475 Usb_ack_suspend(); // must be executed last (after Usb_suspend_action()) to allow upstream resume 00476 Usb_enable_wake_up_interrupt(); 00477 Usb_freeze_clock(); 00478 Stop_pll(); 00479 Usb_suspend_action(); 00480 } 00481 } 00482 // - Wake up event (USB activity detected): Used to resume 00483 if (Is_usb_wake_up() && Is_wake_up_interrupt_enabled()) 00484 { 00485 if(Is_pll_ready()==FALSE) 00486 { 00487 Pll_start_auto(); 00488 Wait_pll_ready(); 00489 } 00490 Usb_unfreeze_clock(); 00491 Usb_ack_wake_up(); 00492 Usb_disable_wake_up_interrupt(); 00493 Usb_wake_up_action(); 00494 Usb_send_event(EVT_USB_WAKE_UP); 00495 Usb_enable_suspend_interrupt(); 00496 } 00497 // - Resume state bus detection 00498 if (Is_usb_resume() && Is_resume_interrupt_enabled()) 00499 { 00500 Usb_disable_wake_up_interrupt(); 00501 Usb_ack_resume(); 00502 Usb_disable_resume_interrupt(); 00503 Usb_resume_action(); 00504 Usb_send_event(EVT_USB_RESUME); 00505 } 00506 #endif 00507 // - USB bus reset detection 00508 if (Is_usb_reset()&& Is_reset_interrupt_enabled()) 00509 { 00510 Usb_ack_reset(); 00511 usb_init_device(); 00512 Usb_reset_action(); 00513 Usb_send_event(EVT_USB_RESET); 00514 } 00515 #endif// End DEVICE FEATURE MODE 00516 00517 // ---------- HOST events management ----------------------------------- 00518 #if (USB_HOST_FEATURE == ENABLED && USB_DEVICE_FEATURE == ENABLED) 00519 // - ID pin change detection 00520 if(Is_usb_id_transition()&&Is_usb_id_interrupt_enabled()) 00521 { 00522 if(Is_usb_id_device()) 00523 { g_usb_mode=USB_MODE_DEVICE;} 00524 else 00525 { g_usb_mode=USB_MODE_HOST;} 00526 Usb_ack_id_transition(); 00527 if( g_usb_mode != g_old_usb_mode) // Basic Debounce 00528 { 00529 if(Is_usb_id_device()) // Going to device mode 00530 { 00531 Usb_send_event(EVT_USB_DEVICE_FUNCTION); 00532 } 00533 else // Going to host mode 00534 { 00535 Usb_send_event(EVT_USB_HOST_FUNCTION); 00536 } 00537 Usb_id_transition_action(); 00538 LOG_STR_CODE(log_id_change); 00539 #if ( ID_PIN_CHANGE_GENERATE_RESET == ENABLE) 00540 // Hot ID transition generates wdt reset 00541 wdtdrv_enable(WDTO_16MS); 00542 while(1); 00543 #endif 00544 } 00545 } 00546 #endif 00547 #if (USB_HOST_FEATURE == ENABLED) 00548 // - The device has been disconnected 00549 if(Is_device_disconnection() && Is_host_device_disconnection_interrupt_enabled()) 00550 { 00551 host_disable_all_pipe(); 00552 Host_ack_device_disconnection(); 00553 device_state=DEVICE_DISCONNECTED; 00554 Usb_send_event(EVT_HOST_DISCONNECTION); 00555 init_usb_tree(); 00556 LOG_STR_CODE(log_device_disconnect); 00557 Host_device_disconnection_action(); 00558 } 00559 // - Device connection 00560 if(Is_device_connection() && Is_host_device_connection_interrupt_enabled()) 00561 { 00562 Host_ack_device_connection(); 00563 host_disable_all_pipe(); 00564 Host_device_connection_action(); 00565 } 00566 // - Host Start of frame has been sent 00567 if (Is_host_sof() && Is_host_sof_interrupt_enabled()) 00568 { 00569 Host_ack_sof(); 00570 Usb_send_event(EVT_HOST_SOF); 00571 private_sof_counter++; 00572 #if (USB_HUB_SUPPORT==ENABLE) 00573 hub_interrupt_sof++; 00574 #endif 00575 00576 // delay timeout management for interrupt tranfer mode in host mode 00577 #if ((USB_HOST_PIPE_INTERRUPT_TRANSFER==ENABLE) && (TIMEOUT_DELAY_ENABLE==ENABLE)) 00578 if (private_sof_counter>=250) // Count 1/4 sec 00579 { 00580 private_sof_counter=0; 00581 for(i=0;i<MAX_EP_NB;i++) 00582 { 00583 if(it_pipe_str[i].enable==ENABLE) 00584 { 00585 save_pipe_nb=Host_get_selected_pipe(); 00586 Host_select_pipe(i); 00587 if((++it_pipe_str[i].timeout>TIMEOUT_DELAY) && (Host_get_pipe_type()!=TYPE_INTERRUPT)) 00588 { 00589 it_pipe_str[i].enable=DISABLE; 00590 it_pipe_str[i].status=PIPE_DELAY_TIMEOUT; 00591 Host_stop_pipe_interrupt(i); 00592 if (is_any_interrupt_pipe_active()==FALSE) // If no more transfer is armed 00593 { 00594 if (g_sav_int_sof_enable==FALSE) 00595 { 00596 Host_disable_sof_interrupt(); 00597 } 00598 } 00599 it_pipe_str[i].handle(PIPE_DELAY_TIMEOUT,it_pipe_str[i].nb_byte_processed); 00600 } 00601 Host_select_pipe(save_pipe_nb); 00602 } 00603 } 00604 } 00605 #endif // (USB_HOST_PIPE_INTERRUPT_TRANSFER==ENABLE) && (TIMEOUT_DELAY_ENABLE==ENABLE)) 00606 Host_sof_action(); 00607 } 00608 // - Host Wake-up has been received 00609 if (Is_host_hwup() && Is_host_hwup_interrupt_enabled()) 00610 { 00611 Host_disable_hwup_interrupt(); // Wake up interrupt should be disable host is now wake up ! 00612 // CAUTION HWUP can be cleared only when USB clock is active (not frozen)! 00613 Pll_start_auto(); // First Restart the PLL for USB operation 00614 Wait_pll_ready(); // Get sure pll is lock 00615 Usb_unfreeze_clock(); // Enable clock on USB interface 00616 Host_ack_hwup(); // Clear HWUP interrupt flag 00617 Usb_send_event(EVT_HOST_HWUP); // Send software event 00618 Host_hwup_action(); // Map custom action 00619 } 00620 #endif // End HOST FEATURE MODE 00621 }
Referenced by usb_general_interrupt().
bit usb_connected |
Public : (bit) usb_connected usb_connected is set to TRUE when VBUS has been detected usb_connected is set to FALSE otherwise Used with USB_DEVICE_FEATURE == ENABLED only /.
Definition at line 79 of file usb_device_task.c.
volatile S_pipe_int it_pipe_str[MAX_EP_NB] |
Referenced by usb_general_interrupt().
volatile U8 hub_interrupt_sof |
Referenced by usb_general_interrupt().
Definition at line 165 of file usb_task.c.
Referenced by usb_general_interrupt(), usb_task(), and usb_task_init().