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 675 of file usb_task.c.
References private_sof_counter.
Referenced by host_transfer_control().
00676 { 00677 return private_sof_counter; 00678 }
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 194 of file usb_task.c.
References usb_general_interrupt_non_naked().
Referenced by usb_task().
00195 { 00196 portENTER_SWITCHING_ISR(); 00197 usb_general_interrupt_non_naked(); 00198 portEXIT_SWITCHING_ISR(); 00199 }
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 400 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().
00412 { 00413 #ifdef FREERTOS_USED 00414 portBASE_TYPE task_woken = pdFALSE; 00415 #endif 00416 #if USB_HOST_FEATURE == ENABLED && USB_HOST_PIPE_INTERRUPT_TRANSFER == ENABLE 00417 U8 i; 00418 #endif 00419 00420 // ---------- DEVICE/HOST events management ------------------------------------ 00421 #if USB_DEVICE_FEATURE == ENABLED && USB_HOST_FEATURE == ENABLED 00422 // ID pin change detection 00423 if (Is_usb_id_transition() && Is_usb_id_interrupt_enabled()) 00424 { 00425 g_usb_mode = (Is_usb_id_device()) ? USB_MODE_DEVICE : USB_MODE_HOST; 00426 Usb_ack_id_transition(); 00427 if (g_usb_mode != g_old_usb_mode) // Basic debounce 00428 { 00429 // Previously in device mode, check if disconnection was detected 00430 if (g_old_usb_mode == USB_MODE_DEVICE) 00431 { 00432 if (usb_connected) 00433 { 00434 // Device mode diconnection actions 00435 usb_connected = FALSE; 00436 usb_configuration_nb = 0; 00437 Usb_vbus_off_action(); 00438 } 00439 } 00440 // Previously in host mode, check if disconnection was detected 00441 else if (Is_host_attached()) 00442 { 00443 // Host mode diconnection actions 00444 device_state = DEVICE_UNATTACHED; 00445 Host_device_disconnection_action(); 00446 } 00447 LOG_STR(log_pin_id_changed); 00448 Usb_send_event((Is_usb_device()) ? EVT_USB_DEVICE_FUNCTION : 00449 EVT_USB_HOST_FUNCTION); 00450 Usb_id_transition_action(); 00452 // Preliminary management: HARDWARE RESET!!! 00453 #if ID_PIN_CHANGE_GENERATE_RESET == ENABLE 00454 // Hot ID transition generates CPU reset 00455 Usb_disable(); 00456 Usb_disable_otg_pad(); 00457 #ifdef FREERTOS_USED 00458 // Release the semaphore in order to start a new device/host task 00459 taskENTER_CRITICAL(); 00460 xSemaphoreGiveFromISR(usb_tsk_semphr, &task_woken); 00461 taskEXIT_CRITICAL(); 00462 #else 00463 // Reset_CPU(); 00464 #endif 00465 #endif 00466 } 00467 } 00468 #endif // End DEVICE/HOST FEATURE MODE 00469 00470 // ---------- DEVICE events management ----------------------------------------- 00471 #if USB_DEVICE_FEATURE == ENABLED 00472 #if USB_HOST_FEATURE == ENABLED 00473 // If both device and host features are enabled, check if device mode is engaged 00474 // (accessing the USB registers of a non-engaged mode, even with load operations, 00475 // may corrupt USB FIFO data). 00476 if (Is_usb_device()) 00477 #endif 00478 { 00479 // VBus state detection 00480 if (Is_usb_vbus_transition() && Is_usb_vbus_interrupt_enabled()) 00481 { 00482 Usb_ack_vbus_transition(); 00483 if (Is_usb_vbus_high()) 00484 { 00485 usb_start_device(); 00486 Usb_send_event(EVT_USB_POWERED); 00487 Usb_vbus_on_action(); 00488 } 00489 else 00490 { 00491 Usb_unfreeze_clock(); 00492 Usb_detach(); 00493 usb_connected = FALSE; 00494 usb_configuration_nb = 0; 00495 Usb_send_event(EVT_USB_UNPOWERED); 00496 Usb_vbus_off_action(); 00497 #ifdef FREERTOS_USED 00498 // Release the semaphore in order to start a new device/host task 00499 taskENTER_CRITICAL(); 00500 xSemaphoreGiveFromISR(usb_tsk_semphr, &task_woken); 00501 taskEXIT_CRITICAL(); 00502 #endif 00503 } 00504 } 00505 // Device Start-of-Frame received 00506 if (Is_usb_sof() && Is_usb_sof_interrupt_enabled()) 00507 { 00508 Usb_ack_sof(); 00509 Usb_sof_action(); 00510 } 00511 // Device Suspend event (no more USB activity detected) 00512 if (Is_usb_suspend() && Is_usb_suspend_interrupt_enabled()) 00513 { 00514 Usb_ack_suspend(); 00515 Usb_enable_wake_up_interrupt(); 00516 (void)Is_usb_wake_up_interrupt_enabled(); 00517 Usb_freeze_clock(); 00518 Usb_send_event(EVT_USB_SUSPEND); 00519 Usb_suspend_action(); 00520 } 00521 // Wake-up event (USB activity detected): Used to resume 00522 if (Is_usb_wake_up() && Is_usb_wake_up_interrupt_enabled()) 00523 { 00524 Usb_unfreeze_clock(); 00525 (void)Is_usb_clock_frozen(); 00526 Usb_ack_wake_up(); 00527 Usb_disable_wake_up_interrupt(); 00528 Usb_wake_up_action(); 00529 Usb_send_event(EVT_USB_WAKE_UP); 00530 } 00531 // Resume state bus detection 00532 if (Is_usb_resume() && Is_usb_resume_interrupt_enabled()) 00533 { 00534 Usb_disable_wake_up_interrupt(); 00535 Usb_ack_resume(); 00536 Usb_disable_resume_interrupt(); 00537 Usb_resume_action(); 00538 Usb_send_event(EVT_USB_RESUME); 00539 } 00540 // USB bus reset detection 00541 if (Is_usb_reset() && Is_usb_reset_interrupt_enabled()) 00542 { 00543 Usb_ack_reset(); 00544 usb_init_device(); 00545 Usb_reset_action(); 00546 Usb_send_event(EVT_USB_RESET); 00547 } 00548 } 00549 #endif // End DEVICE FEATURE MODE 00550 00551 // ---------- HOST events management ------------------------------------------- 00552 #if USB_HOST_FEATURE == ENABLED 00553 #if USB_DEVICE_FEATURE == ENABLED 00554 // If both device and host features are enabled, check if host mode is engaged 00555 // (accessing the USB registers of a non-engaged mode, even with load operations, 00556 // may corrupt USB FIFO data). 00557 else 00558 #endif 00559 { 00560 // The device has been disconnected 00561 if (Is_host_device_disconnection() && Is_host_device_disconnection_interrupt_enabled()) 00562 { 00563 host_disable_all_pipes(); 00564 Host_ack_device_disconnection(); 00565 #if USB_HOST_PIPE_INTERRUPT_TRANSFER == ENABLE 00566 reset_it_pipe_str(); 00567 #endif 00568 device_state = DEVICE_UNATTACHED; 00569 LOG_STR(log_device_disconnected); 00570 Usb_send_event(EVT_HOST_DISCONNECTION); 00571 Host_device_disconnection_action(); 00572 #ifdef FREERTOS_USED 00573 // Release the semaphore in order to start a new device/host task 00574 taskENTER_CRITICAL(); 00575 xSemaphoreGiveFromISR(usb_tsk_semphr, &task_woken); 00576 taskEXIT_CRITICAL(); 00577 #endif 00578 } 00579 // Device connection 00580 if (Is_host_device_connection() && Is_host_device_connection_interrupt_enabled()) 00581 { 00582 Host_ack_device_connection(); 00583 host_disable_all_pipes(); 00584 Host_device_connection_action(); 00585 } 00586 // Host Start-of-Frame has been sent 00587 if (Is_host_sof() && Is_host_sof_interrupt_enabled()) 00588 { 00589 Host_ack_sof(); 00590 Usb_send_event(EVT_HOST_SOF); 00591 #if (USB_HIGH_SPEED_SUPPORT==ENABLED) 00592 if( Is_usb_full_speed_mode() ) 00593 { 00594 private_sof_counter++; 00595 }else{ 00596 private_sof_counter_HS++; 00597 if( 0 == (private_sof_counter_HS%8) ) 00598 { 00599 private_sof_counter++; 00600 } 00601 } 00602 #else 00603 private_sof_counter++; 00604 #endif 00605 // Delay time-out management for interrupt tranfer mode in host mode 00606 #if USB_HOST_PIPE_INTERRUPT_TRANSFER == ENABLE && TIMEOUT_DELAY_ENABLE == ENABLE 00607 if (private_sof_counter >= 250) // Count 250 ms (SOF @ 1 ms) 00608 { 00609 private_sof_counter = 0; 00610 for (i = 0; i < MAX_PEP_NB; i++) 00611 { 00612 if (it_pipe_str[i].enable && 00613 ++it_pipe_str[i].timeout > TIMEOUT_DELAY && Host_get_pipe_type(i) != TYPE_INTERRUPT) 00614 { 00615 it_pipe_str[i].enable = FALSE; 00616 it_pipe_str[i].status = PIPE_DELAY_TIMEOUT; 00617 Host_reset_pipe(i); 00618 if (!is_any_interrupt_pipe_active() && !g_sav_int_sof_enable) // If no more transfer is armed 00619 { 00620 Host_disable_sof_interrupt(); 00621 } 00622 it_pipe_str[i].handler(PIPE_DELAY_TIMEOUT, it_pipe_str[i].nb_byte_processed); 00623 } 00624 } 00625 } 00626 #endif 00627 Host_sof_action(); 00628 } 00629 // Host Wake-up has been received 00630 if (Is_host_hwup() && Is_host_hwup_interrupt_enabled()) 00631 { 00632 // CAUTION: HWUP can be cleared only when USB clock is active (not frozen)! 00634 //Pll_start_auto(); // First Restart the PLL for USB operation 00635 //Wait_pll_ready(); // Make sure PLL is locked 00636 Usb_unfreeze_clock(); // Enable clock on USB interface 00637 (void)Is_usb_clock_frozen(); // Make sure USB interface clock is enabled 00638 Host_disable_hwup_interrupt(); // Wake-up interrupt should be disabled as host is now awoken! 00639 Host_ack_hwup(); // Clear HWUP interrupt flag 00640 Usb_send_event(EVT_HOST_HWUP); // Send software event 00641 Host_hwup_action(); // Map custom action 00642 } 00643 #if USB_HOST_PIPE_INTERRUPT_TRANSFER == ENABLE 00644 // Host pipe interrupts 00645 while ((i = Host_get_interrupt_pipe_number()) < MAX_PEP_NB) usb_pipe_interrupt(i); 00646 #endif 00647 } 00648 #endif // End HOST FEATURE MODE 00649 00650 #ifdef FREERTOS_USED 00651 return task_woken; 00652 #endif 00653 }
volatile U8 g_old_usb_mode [static] |
Definition at line 162 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 169 of file usb_task.c.
Referenced by usb_general_interrupt_non_naked(), usb_task(), and usb_task_init().