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 the values of USB_DEVICE_FEATURE and USB_HOST_FEATURE (located in the 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.
#include "compiler.h"
#include "intc.h"
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#include "conf_usb.h"
#include "usb_drv.h"
#include "usb_task.h"
#include "usb_descriptors.h"
#include "usb_device_task.h"
#include "usb_host_task.h"
#include "pm.h"
Go to the source code of this file.
Functions | |
U32 | host_get_timeout (void) |
void | host_suspend_action (void) |
static void | usb_general_interrupt (void) |
USB interrupt routine. | |
static portBASE_TYPE | usb_general_interrupt_non_naked (void) |
Entry point of the USB mamnagement. | |
void | usb_suspend_action (void) |
void | usb_task (void *pvParameters) |
Entry point of the USB mamnagement. | |
void | usb_task_init (void) |
This function initializes the USB process. | |
Variables | |
static volatile U8 | g_old_usb_mode |
volatile Bool | 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) Is_usb_event(x) Usb_clear_all_event(). | |
volatile U8 | g_usb_mode = USB_MODE_UNDEFINED |
Public: U8 g_usb_mode Used in dual-role application (both device/host) to store the current mode the USB controller is operating. | |
volatile S_pipe_int | it_pipe_str [MAX_PEP_NB] |
static const char | log_device_disconnected [] = "Device disconnected\n" |
static const char | log_pin_id_changed [] = "Pin Id changed\n" |
volatile U32 | private_sof_counter |
Private: U8 private_sof_counter Incremented by host SOF interrupt subroutime This counter is used to detect time-out in host requests. | |
static U8 | private_sof_counter_HS = 0 |
volatile Bool | usb_connected |
Public: Bool 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. | |
xTaskHandle | usb_device_tsk |
Handle to the USB Device task. | |
xTaskHandle | usb_host_tsk |
Handle to the USB Host task. | |
static xSemaphoreHandle | usb_tsk_semphr = NULL |
Handle to the USB task semaphore. |
U32 host_get_timeout | ( | void | ) |
Definition at line 676 of file usb_task.c.
References private_sof_counter.
Referenced by host_transfer_control().
00677 { 00678 return private_sof_counter; 00679 }
static void usb_general_interrupt | ( | void | ) | [static] |
USB interrupt routine.
When FreeRTOS is used, the USB interrupt routine may trigger task switches, so it must use special OS prologue and epilogue. This function must be naked in order to have no stack frame. usb_general_interrupt_non_naked is therefore used for the required stack frame of the interrupt routine.
Definition at line 195 of file usb_task.c.
References usb_general_interrupt_non_naked().
Referenced by usb_task().
00196 { 00197 portENTER_SWITCHING_ISR(); 00198 usb_general_interrupt_non_naked(); 00199 portEXIT_SWITCHING_ISR(); 00200 }
static portBASE_TYPE usb_general_interrupt_non_naked | ( | void | ) | [static] |
Entry point of the USB mamnagement.
Depending on the USB mode supported (HOST/DEVICE/DUAL_ROLE) the function calls the coresponding USB management function. USB interrupt routine 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 associated #define (see the conf_usb.h file to add actions on events).
Note: Only interrupt events that are enabled are processed.
Warning: If device and host tasks are not tasks in an RTOS, rough events like ID transition, VBus transition, device disconnection, etc. that need to kill then restart these tasks may lead to an undefined state if they occur just before something is activated in the USB macro (e.g. pipe/endpoint transfer...).
Definition at line 401 of file usb_task.c.
References device_state, DEVICE_UNATTACHED, S_pipe_int::enable, EVT_HOST_DISCONNECTION, EVT_HOST_HWUP, EVT_HOST_SOF, EVT_USB_DEVICE_FUNCTION, EVT_USB_HOST_FUNCTION, EVT_USB_POWERED, EVT_USB_RESET, EVT_USB_RESUME, EVT_USB_SUSPEND, EVT_USB_UNPOWERED, EVT_USB_WAKE_UP, g_old_usb_mode, g_sav_int_sof_enable, g_usb_mode, S_pipe_int::handler, 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_pipes(), Host_disable_hwup_interrupt, Host_disable_sof_interrupt, Host_get_interrupt_pipe_number, Host_get_pipe_type, Host_hwup_action, Host_reset_pipe, Host_sof_action, is_any_interrupt_pipe_active(), Is_host_attached, Is_host_device_connection, Is_host_device_connection_interrupt_enabled, Is_host_device_disconnection, Is_host_device_disconnection_interrupt_enabled, Is_host_hwup, Is_host_hwup_interrupt_enabled, Is_host_sof, Is_host_sof_interrupt_enabled, Is_usb_clock_frozen, Is_usb_device, Is_usb_full_speed_mode, Is_usb_id_device, Is_usb_id_interrupt_enabled, Is_usb_id_transition, Is_usb_reset, Is_usb_reset_interrupt_enabled, Is_usb_resume, Is_usb_resume_interrupt_enabled, Is_usb_sof, Is_usb_sof_interrupt_enabled, Is_usb_suspend, Is_usb_suspend_interrupt_enabled, Is_usb_vbus_high, Is_usb_vbus_interrupt_enabled, Is_usb_vbus_transition, Is_usb_wake_up, Is_usb_wake_up_interrupt_enabled, log_device_disconnected, log_pin_id_changed, LOG_STR, MAX_PEP_NB, PIPE_DELAY_TIMEOUT, private_sof_counter, private_sof_counter_HS, reset_it_pipe_str(), S_pipe_int::status, TIMEOUT_DELAY, TYPE_INTERRUPT, Usb_ack_id_transition, Usb_ack_reset, Usb_ack_resume, Usb_ack_sof, Usb_ack_suspend, Usb_ack_vbus_transition, Usb_ack_wake_up, usb_configuration_nb, usb_connected, Usb_detach, Usb_disable, Usb_disable_otg_pad, Usb_disable_resume_interrupt, Usb_disable_wake_up_interrupt, Usb_enable_wake_up_interrupt, Usb_freeze_clock, Usb_id_transition_action, usb_init_device(), USB_MODE_DEVICE, USB_MODE_HOST, usb_pipe_interrupt(), Usb_reset_action, Usb_resume_action, Usb_send_event, Usb_sof_action, usb_start_device(), Usb_suspend_action, usb_tsk_semphr, Usb_unfreeze_clock, Usb_vbus_off_action, Usb_vbus_on_action, and Usb_wake_up_action.
Referenced by usb_general_interrupt().
00413 { 00414 #ifdef FREERTOS_USED 00415 portBASE_TYPE task_woken = pdFALSE; 00416 #endif 00417 #if USB_HOST_FEATURE == ENABLED && USB_HOST_PIPE_INTERRUPT_TRANSFER == ENABLE 00418 U8 i; 00419 #endif 00420 00421 // ---------- DEVICE/HOST events management ------------------------------------ 00422 #if USB_DEVICE_FEATURE == ENABLED && USB_HOST_FEATURE == ENABLED 00423 // ID pin change detection 00424 if (Is_usb_id_transition() && Is_usb_id_interrupt_enabled()) 00425 { 00426 g_usb_mode = (Is_usb_id_device()) ? USB_MODE_DEVICE : USB_MODE_HOST; 00427 Usb_ack_id_transition(); 00428 if (g_usb_mode != g_old_usb_mode) // Basic debounce 00429 { 00430 // Previously in device mode, check if disconnection was detected 00431 if (g_old_usb_mode == USB_MODE_DEVICE) 00432 { 00433 if (usb_connected) 00434 { 00435 // Device mode diconnection actions 00436 usb_connected = FALSE; 00437 usb_configuration_nb = 0; 00438 Usb_vbus_off_action(); 00439 } 00440 } 00441 // Previously in host mode, check if disconnection was detected 00442 else if (Is_host_attached()) 00443 { 00444 // Host mode diconnection actions 00445 device_state = DEVICE_UNATTACHED; 00446 Host_device_disconnection_action(); 00447 } 00448 LOG_STR(log_pin_id_changed); 00449 Usb_send_event((Is_usb_device()) ? EVT_USB_DEVICE_FUNCTION : 00450 EVT_USB_HOST_FUNCTION); 00451 Usb_id_transition_action(); 00453 // Preliminary management: HARDWARE RESET!!! 00454 #if ID_PIN_CHANGE_GENERATE_RESET == ENABLE 00455 // Hot ID transition generates CPU reset 00456 Usb_disable(); 00457 Usb_disable_otg_pad(); 00458 #ifdef FREERTOS_USED 00459 // Release the semaphore in order to start a new device/host task 00460 taskENTER_CRITICAL(); 00461 xSemaphoreGiveFromISR(usb_tsk_semphr, &task_woken); 00462 taskEXIT_CRITICAL(); 00463 #else 00464 // Reset_CPU(); 00465 #endif 00466 #endif 00467 } 00468 } 00469 #endif // End DEVICE/HOST FEATURE MODE 00470 00471 // ---------- DEVICE events management ----------------------------------------- 00472 #if USB_DEVICE_FEATURE == ENABLED 00473 #if USB_HOST_FEATURE == ENABLED 00474 // If both device and host features are enabled, check if device mode is engaged 00475 // (accessing the USB registers of a non-engaged mode, even with load operations, 00476 // may corrupt USB FIFO data). 00477 if (Is_usb_device()) 00478 #endif 00479 { 00480 // VBus state detection 00481 if (Is_usb_vbus_transition() && Is_usb_vbus_interrupt_enabled()) 00482 { 00483 Usb_ack_vbus_transition(); 00484 if (Is_usb_vbus_high()) 00485 { 00486 usb_start_device(); 00487 Usb_send_event(EVT_USB_POWERED); 00488 Usb_vbus_on_action(); 00489 } 00490 else 00491 { 00492 Usb_unfreeze_clock(); 00493 Usb_detach(); 00494 usb_connected = FALSE; 00495 usb_configuration_nb = 0; 00496 Usb_send_event(EVT_USB_UNPOWERED); 00497 Usb_vbus_off_action(); 00498 #ifdef FREERTOS_USED 00499 // Release the semaphore in order to start a new device/host task 00500 taskENTER_CRITICAL(); 00501 xSemaphoreGiveFromISR(usb_tsk_semphr, &task_woken); 00502 taskEXIT_CRITICAL(); 00503 #endif 00504 } 00505 } 00506 // Device Start-of-Frame received 00507 if (Is_usb_sof() && Is_usb_sof_interrupt_enabled()) 00508 { 00509 Usb_ack_sof(); 00510 Usb_sof_action(); 00511 } 00512 // Device Suspend event (no more USB activity detected) 00513 if (Is_usb_suspend() && Is_usb_suspend_interrupt_enabled()) 00514 { 00515 Usb_ack_suspend(); 00516 Usb_enable_wake_up_interrupt(); 00517 (void)Is_usb_wake_up_interrupt_enabled(); 00518 Usb_freeze_clock(); 00519 Usb_send_event(EVT_USB_SUSPEND); 00520 Usb_suspend_action(); 00521 } 00522 // Wake-up event (USB activity detected): Used to resume 00523 if (Is_usb_wake_up() && Is_usb_wake_up_interrupt_enabled()) 00524 { 00525 Usb_unfreeze_clock(); 00526 (void)Is_usb_clock_frozen(); 00527 Usb_ack_wake_up(); 00528 Usb_disable_wake_up_interrupt(); 00529 Usb_wake_up_action(); 00530 Usb_send_event(EVT_USB_WAKE_UP); 00531 } 00532 // Resume state bus detection 00533 if (Is_usb_resume() && Is_usb_resume_interrupt_enabled()) 00534 { 00535 Usb_disable_wake_up_interrupt(); 00536 Usb_ack_resume(); 00537 Usb_disable_resume_interrupt(); 00538 Usb_resume_action(); 00539 Usb_send_event(EVT_USB_RESUME); 00540 } 00541 // USB bus reset detection 00542 if (Is_usb_reset() && Is_usb_reset_interrupt_enabled()) 00543 { 00544 Usb_ack_reset(); 00545 usb_init_device(); 00546 Usb_reset_action(); 00547 Usb_send_event(EVT_USB_RESET); 00548 } 00549 } 00550 #endif // End DEVICE FEATURE MODE 00551 00552 // ---------- HOST events management ------------------------------------------- 00553 #if USB_HOST_FEATURE == ENABLED 00554 #if USB_DEVICE_FEATURE == ENABLED 00555 // If both device and host features are enabled, check if host mode is engaged 00556 // (accessing the USB registers of a non-engaged mode, even with load operations, 00557 // may corrupt USB FIFO data). 00558 else 00559 #endif 00560 { 00561 // The device has been disconnected 00562 if (Is_host_device_disconnection() && Is_host_device_disconnection_interrupt_enabled()) 00563 { 00564 host_disable_all_pipes(); 00565 Host_ack_device_disconnection(); 00566 #if USB_HOST_PIPE_INTERRUPT_TRANSFER == ENABLE 00567 reset_it_pipe_str(); 00568 #endif 00569 device_state = DEVICE_UNATTACHED; 00570 LOG_STR(log_device_disconnected); 00571 Usb_send_event(EVT_HOST_DISCONNECTION); 00572 Host_device_disconnection_action(); 00573 #ifdef FREERTOS_USED 00574 // Release the semaphore in order to start a new device/host task 00575 taskENTER_CRITICAL(); 00576 xSemaphoreGiveFromISR(usb_tsk_semphr, &task_woken); 00577 taskEXIT_CRITICAL(); 00578 #endif 00579 } 00580 // Device connection 00581 if (Is_host_device_connection() && Is_host_device_connection_interrupt_enabled()) 00582 { 00583 Host_ack_device_connection(); 00584 host_disable_all_pipes(); 00585 Host_device_connection_action(); 00586 } 00587 // Host Start-of-Frame has been sent 00588 if (Is_host_sof() && Is_host_sof_interrupt_enabled()) 00589 { 00590 Host_ack_sof(); 00591 Usb_send_event(EVT_HOST_SOF); 00592 #if (USB_HIGH_SPEED_SUPPORT==ENABLED) 00593 if( Is_usb_full_speed_mode() ) 00594 { 00595 private_sof_counter++; 00596 }else{ 00597 private_sof_counter_HS++; 00598 if( 0 == (private_sof_counter_HS%8) ) 00599 { 00600 private_sof_counter++; 00601 } 00602 } 00603 #else 00604 private_sof_counter++; 00605 #endif 00606 // Delay time-out management for interrupt tranfer mode in host mode 00607 #if USB_HOST_PIPE_INTERRUPT_TRANSFER == ENABLE && TIMEOUT_DELAY_ENABLE == ENABLE 00608 if (private_sof_counter >= 250) // Count 250 ms (SOF @ 1 ms) 00609 { 00610 private_sof_counter = 0; 00611 for (i = 0; i < MAX_PEP_NB; i++) 00612 { 00613 if (it_pipe_str[i].enable && 00614 ++it_pipe_str[i].timeout > TIMEOUT_DELAY && Host_get_pipe_type(i) != TYPE_INTERRUPT) 00615 { 00616 it_pipe_str[i].enable = FALSE; 00617 it_pipe_str[i].status = PIPE_DELAY_TIMEOUT; 00618 Host_reset_pipe(i); 00619 if (!is_any_interrupt_pipe_active() && !g_sav_int_sof_enable) // If no more transfer is armed 00620 { 00621 Host_disable_sof_interrupt(); 00622 } 00623 it_pipe_str[i].handler(PIPE_DELAY_TIMEOUT, it_pipe_str[i].nb_byte_processed); 00624 } 00625 } 00626 } 00627 #endif 00628 Host_sof_action(); 00629 } 00630 // Host Wake-up has been received 00631 if (Is_host_hwup() && Is_host_hwup_interrupt_enabled()) 00632 { 00633 // CAUTION: HWUP can be cleared only when USB clock is active (not frozen)! 00635 //Pll_start_auto(); // First Restart the PLL for USB operation 00636 //Wait_pll_ready(); // Make sure PLL is locked 00637 Usb_unfreeze_clock(); // Enable clock on USB interface 00638 (void)Is_usb_clock_frozen(); // Make sure USB interface clock is enabled 00639 Host_disable_hwup_interrupt(); // Wake-up interrupt should be disabled as host is now awoken! 00640 Host_ack_hwup(); // Clear HWUP interrupt flag 00641 Usb_send_event(EVT_HOST_HWUP); // Send software event 00642 Host_hwup_action(); // Map custom action 00643 } 00644 #if USB_HOST_PIPE_INTERRUPT_TRANSFER == ENABLE 00645 // Host pipe interrupts 00646 while ((i = Host_get_interrupt_pipe_number()) < MAX_PEP_NB) usb_pipe_interrupt(i); 00647 #endif 00648 } 00649 #endif // End HOST FEATURE MODE 00650 00651 #ifdef FREERTOS_USED 00652 return task_woken; 00653 #endif 00654 }
volatile U8 g_old_usb_mode [static] |
Definition at line 163 of file usb_task.c.
Referenced by usb_general_interrupt_non_naked(), and usb_task().
volatile Bool g_sav_int_sof_enable |
Definition at line 78 of file usb_host_task.c.
Referenced by host_get_data_interrupt(), host_send_data_interrupt(), usb_general_interrupt_non_naked(), and usb_pipe_interrupt().
volatile S_pipe_int it_pipe_str[MAX_PEP_NB] |
Definition at line 79 of file usb_host_task.c.
const char log_device_disconnected[] = "Device disconnected\n" [static] |
const char log_pin_id_changed[] = "Pin Id changed\n" [static] |
U8 private_sof_counter_HS = 0 [static] |
volatile Bool usb_connected |
Public: Bool 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 80 of file usb_device_task.c.
Referenced by usb_device_task(), usb_device_task_init(), usb_general_interrupt_non_naked(), and usb_start_device().
xTaskHandle usb_device_tsk |
Handle to the USB Device task.
Definition at line 84 of file usb_device_task.c.
Referenced by usb_device_task_init(), and usb_task().
xTaskHandle usb_host_tsk |
Handle to the USB Host task.
Definition at line 122 of file usb_host_task.c.
Referenced by usb_host_task_init(), and usb_task().
xSemaphoreHandle usb_tsk_semphr = NULL [static] |
Handle to the USB task semaphore.
Definition at line 170 of file usb_task.c.
Referenced by usb_general_interrupt_non_naked(), usb_task(), and usb_task_init().