Modules | |
Host controller states | |
Defines for device state coding. | |
Data Structures | |
struct | S_pipe_int |
Defines | |
#define | Host_ack_request_resume() (request_resume = FALSE) |
Private ack for resume software event. | |
#define | Host_request_resume() (request_resume = TRUE) |
Should be called to request the host controller to resume the USB bus. | |
#define | Host_request_suspend() (device_state = DEVICE_SUSPENDED) |
Should be called to make the host controller enter USB suspend mode. | |
#define | Is_host_addressed() (device_state >= DEVICE_ADDRESSED) |
Check if there is a device addressed by the host. | |
#define | Is_host_attached() (device_state >= DEVICE_ATTACHED) |
Check if there is a device attached to the host. | |
#define | Is_host_error() (device_state == DEVICE_ERROR) |
Check if there is an error. | |
#define | Is_host_powered() (device_state >= DEVICE_POWERED) |
Check if there is a device powered by the host. | |
#define | Is_host_ready() (device_state == DEVICE_READY) |
Returns TRUE when device connected and correctly enumerated. | |
#define | Is_host_request_resume() (request_resume == TRUE) |
Private check for resume sequence. | |
#define | Is_host_suspended() |
Check if host controller is in suspend mode. | |
#define | PIPE_CRC16 0x10 |
#define | PIPE_DATA_PID 0x02 |
#define | PIPE_DATA_TOGGLE 0x01 |
#define | PIPE_DELAY_TIMEOUT 0x80 |
#define | PIPE_GOOD 0x00 |
#define | PIPE_NAK_TIMEOUT 0x40 |
#define | PIPE_PID 0x04 |
#define | PIPE_STALL 0x20 |
#define | PIPE_TIMEOUT 0x08 |
Typedefs | |
typedef void | Pipe_handler (Status_t status, U16 nb_byte) |
Functions | |
Status_t | host_get_data (U8 pipe, U16 *nb_data, void *ptr_buf) |
This function receives nb_data bytes pointed to by ptr_buf on the specified pipe. | |
Bool | host_get_data_interrupt (U8 pipe, U16 nb_data, void *ptr_buf, Pipe_handler *handler) |
This function receives nb_data bytes pointed to by ptr_buf on the specified pipe. | |
Status_t | host_send_data (U8 pipe, U16 nb_data, const void *ptr_buf) |
This function sends nb_data bytes pointed to by ptr_buf on the specified pipe. | |
Bool | host_send_data_interrupt (U8 pipe, U16 nb_data, const void *ptr_buf, Pipe_handler *handler) |
This function sends nb_data bytes pointed to by ptr_buf on the specified pipe. | |
Bool | is_any_interrupt_pipe_active (void) |
void | reset_it_pipe_str (void) |
void | usb_host_task (void *pvParameters) |
Entry point of the USB host management. | |
void | usb_host_task_init (void) |
This function initializes the USB host controller. | |
void | usb_pipe_interrupt (U8 pipe) |
USB pipe interrupt subroutine. | |
Variables | |
U8 | data_stage [SIZEOF_DATA_STAGE] |
Public: U8 data_stage[SIZEOF_DATA_STAGE] Internal RAM buffer for USB data stage content This buffer is required to setup host enumeration process It contains the device descriptors received. | |
volatile U8 | device_state |
Public: U8 device_state Its value represents the current state of the device connected to the USB host controller Value can be:
| |
volatile U8 | device_status |
volatile Bool | request_resume |
volatile S_usb_setup_data | usb_request |
For control requests management over control pipe. |
#define Host_ack_request_resume | ( | ) | (request_resume = FALSE) |
Private ack for resume software event.
Definition at line 126 of file usb_host_task.h.
Referenced by usb_host_task(), and usb_host_task_init().
#define Host_request_resume | ( | ) | (request_resume = TRUE) |
Should be called to request the host controller to resume the USB bus.
Definition at line 123 of file usb_host_task.h.
Referenced by host_template_task().
#define Host_request_suspend | ( | ) | (device_state = DEVICE_SUSPENDED) |
Should be called to make the host controller enter USB suspend mode.
Definition at line 120 of file usb_host_task.h.
Referenced by host_template_task().
#define Is_host_addressed | ( | ) | (device_state >= DEVICE_ADDRESSED) |
#define Is_host_attached | ( | ) | (device_state >= DEVICE_ATTACHED) |
Check if there is a device attached to the host.
Definition at line 117 of file usb_host_task.h.
Referenced by usb_general_interrupt_non_naked().
#define Is_host_error | ( | ) | (device_state == DEVICE_ERROR) |
#define Is_host_powered | ( | ) | (device_state >= DEVICE_POWERED) |
#define Is_host_ready | ( | ) | (device_state == DEVICE_READY) |
Returns TRUE when device connected and correctly enumerated.
The host high-level application should test this before performing any applicative request.
Definition at line 101 of file usb_host_task.h.
Referenced by host_template_task().
#define Is_host_request_resume | ( | ) | (request_resume == TRUE) |
Private check for resume sequence.
Definition at line 129 of file usb_host_task.h.
Referenced by usb_host_task().
#define Is_host_suspended | ( | ) |
Value:
(device_state == DEVICE_WAIT_RESUME ||\ device_state == DEVICE_SUSPENDED)
Definition at line 104 of file usb_host_task.h.
Referenced by host_template_task().
#define PIPE_CRC16 0x10 |
Definition at line 94 of file usb_host_task.h.
#define PIPE_DATA_PID 0x02 |
Definition at line 91 of file usb_host_task.h.
#define PIPE_DATA_TOGGLE 0x01 |
Definition at line 90 of file usb_host_task.h.
#define PIPE_DELAY_TIMEOUT 0x80 |
Definition at line 97 of file usb_host_task.h.
Referenced by host_get_data(), host_send_data(), and usb_general_interrupt_non_naked().
#define PIPE_GOOD 0x00 |
Definition at line 89 of file usb_host_task.h.
Referenced by host_get_data(), host_get_data_callback(), host_send_data(), host_send_data_callback(), and usb_pipe_interrupt().
#define PIPE_NAK_TIMEOUT 0x40 |
Definition at line 96 of file usb_host_task.h.
Referenced by host_get_data(), host_send_data(), and usb_pipe_interrupt().
#define PIPE_PID 0x04 |
Definition at line 92 of file usb_host_task.h.
#define PIPE_STALL 0x20 |
Definition at line 95 of file usb_host_task.h.
Referenced by host_get_data(), host_send_data(), and usb_pipe_interrupt().
#define PIPE_TIMEOUT 0x08 |
Definition at line 93 of file usb_host_task.h.
typedef void Pipe_handler(Status_t status, U16 nb_byte) |
Definition at line 71 of file usb_host_task.h.
Status_t host_get_data | ( | U8 | pipe, | |
U16 * | nb_data, | |||
void * | ptr_buf | |||
) |
This function receives nb_data bytes pointed to by ptr_buf on the specified pipe.
nb_data is updated with the final number of data bytes received.
pipe | ||
nb_data | ||
ptr_buf |
Definition at line 713 of file usb_host_task.c.
References EVT_HOST_SOF, Host_ack_all_errors, Host_ack_in_received, Host_ack_nak_received, Host_ack_sof, Host_ack_stall, Host_byte_count, Host_configure_pipe_token, Host_disable_sof_interrupt, Host_enable_continuous_in_mode, Host_enable_sof_interrupt, Host_error_status, Host_free_in, Host_freeze_pipe, Host_get_pipe_size, host_read_p_rxpacket(), Host_reset_pipe, Host_reset_pipe_fifo_access, Host_unfreeze_pipe, Is_host_emergency_exit, Is_host_in_received, Is_host_nak_received, Is_host_pipe_error, Is_host_sof_interrupt_enabled, Is_host_stall, Is_usb_event, Is_usb_low_speed_mode, NAK_RECEIVE_TIMEOUT, PIPE_DELAY_TIMEOUT, PIPE_GOOD, PIPE_NAK_TIMEOUT, PIPE_STALL, private_sof_counter, TIMEOUT_DELAY, TOKEN_IN, and Usb_ack_event.
Referenced by host_template_task().
00714 { 00715 Status_t status = PIPE_GOOD; // Frame correctly received by default 00716 Bool sav_int_sof_enable; 00717 Bool sav_glob_int_en; 00718 U8 nak_timeout; 00719 U16 n, i; 00720 #if NAK_TIMEOUT_ENABLE == ENABLE 00721 U16 cpt_nak; 00722 #endif 00723 00724 n = *nb_data; 00725 sav_int_sof_enable = Is_host_sof_interrupt_enabled(); 00726 Host_enable_sof_interrupt(); 00727 Host_enable_continuous_in_mode(pipe); 00728 Host_configure_pipe_token(pipe, TOKEN_IN); 00729 Host_ack_in_received(pipe); 00730 while (n) // While missing data... 00731 { 00732 Host_free_in(pipe); 00733 Host_unfreeze_pipe(pipe); 00734 private_sof_counter = 0; // Reset the counter in SOF detection subroutine 00735 nak_timeout = 0; 00736 #if NAK_TIMEOUT_ENABLE == ENABLE 00737 cpt_nak = 0; 00738 #endif 00739 while (!Is_host_in_received(pipe)) 00740 { 00741 if (Is_host_emergency_exit()) // Asynchronous disconnection or role exchange detected under interrupt 00742 { 00743 status = PIPE_DELAY_TIMEOUT; 00744 Host_reset_pipe(pipe); 00745 goto host_get_data_end; 00746 } 00747 #if TIMEOUT_DELAY_ENABLE == ENABLE 00748 if (private_sof_counter >= 250) // Time-out management 00749 { 00750 private_sof_counter = 0; // Done in host SOF interrupt 00751 if (nak_timeout++ >= TIMEOUT_DELAY) // Check for local time-out 00752 { 00753 status = PIPE_DELAY_TIMEOUT; 00754 Host_reset_pipe(pipe); 00755 goto host_get_data_end; 00756 } 00757 } 00758 #endif 00759 if (Is_host_pipe_error(pipe)) // Error management 00760 { 00761 status = Host_error_status(pipe); 00762 Host_ack_all_errors(pipe); 00763 goto host_get_data_end; 00764 } 00765 if (Is_host_stall(pipe)) // STALL management 00766 { 00767 status = PIPE_STALL; 00768 Host_reset_pipe(pipe); 00769 Host_ack_stall(pipe); 00770 goto host_get_data_end; 00771 } 00772 #if NAK_TIMEOUT_ENABLE == ENABLE 00773 if (Is_host_nak_received(pipe)) // NAK received 00774 { 00775 Host_ack_nak_received(pipe); 00776 if (cpt_nak++ > NAK_RECEIVE_TIMEOUT) 00777 { 00778 status = PIPE_NAK_TIMEOUT; 00779 Host_reset_pipe(pipe); 00780 goto host_get_data_end; 00781 } 00782 } 00783 #endif 00784 } 00785 Host_freeze_pipe(pipe); 00786 Host_reset_pipe_fifo_access(pipe); 00787 i = Host_get_pipe_size(pipe) - Host_byte_count(pipe); 00788 if (!ptr_buf) 00789 { 00790 if (Host_byte_count(pipe) > n) // More bytes received than expected 00791 { 00792 n = 0; 00794 } 00795 else // Nb bytes received <= expected 00796 { 00797 n -= Host_byte_count(pipe); 00798 if (i) // Short packet 00799 { 00800 *nb_data -= n; 00801 n = 0; 00802 } 00803 } 00804 } 00805 else 00806 { 00807 n = host_read_p_rxpacket(pipe, ptr_buf, n, &ptr_buf); 00808 if (Host_byte_count(pipe)) // More bytes received than expected 00809 { 00811 } 00812 else if (i) // Short packet with nb bytes received <= expected 00813 { 00814 *nb_data -= n; 00815 n = 0; 00816 } 00817 } 00818 Host_ack_in_received(pipe); 00819 00820 // In low-speed mode, the USB IP may have not yet sent the ACK at this 00821 // point. The USB IP does not support a new start of transaction request 00822 // from the firmware if the ACK has not been sent. The only means of making 00823 // sure the ACK has been sent is to wait for the next Keep-Alive before 00824 // starting a new transaction. 00825 if (Is_usb_low_speed_mode()) 00826 { 00827 Usb_ack_event(EVT_HOST_SOF); 00828 sav_int_sof_enable = Is_host_sof_interrupt_enabled(); 00829 if ((sav_glob_int_en = Is_global_interrupt_enabled())) Disable_global_interrupt(); 00830 Host_ack_sof(); 00831 (void)Is_host_sof_interrupt_enabled(); 00832 if (sav_glob_int_en) Enable_global_interrupt(); 00833 Host_enable_sof_interrupt(); 00834 while (!Is_usb_event(EVT_HOST_SOF)) // Wait for next Keep-Alive 00835 { 00836 if (Is_host_emergency_exit()) 00837 { 00838 status = PIPE_DELAY_TIMEOUT; 00839 Host_reset_pipe(pipe); 00840 goto host_get_data_end; 00841 } 00842 } 00843 if (!sav_int_sof_enable) // Restore SOF interrupt enable 00844 { 00845 if ((sav_glob_int_en = Is_global_interrupt_enabled())) Disable_global_interrupt(); 00846 Host_disable_sof_interrupt(); 00847 (void)Is_host_sof_interrupt_enabled(); 00848 if (sav_glob_int_en) Enable_global_interrupt(); 00849 } 00850 } 00851 } 00852 host_get_data_end: 00853 Host_freeze_pipe(pipe); 00854 // Restore SOF interrupt enable state 00855 if (!sav_int_sof_enable) 00856 { 00857 if ((sav_glob_int_en = Is_global_interrupt_enabled())) Disable_global_interrupt(); 00858 Host_disable_sof_interrupt(); 00859 (void)Is_host_sof_interrupt_enabled(); 00860 if (sav_glob_int_en) Enable_global_interrupt(); 00861 } 00862 00863 // And return... 00864 return status; 00865 }
Bool host_get_data_interrupt | ( | U8 | pipe, | |
U16 | nb_data, | |||
void * | ptr_buf, | |||
Pipe_handler * | handler | |||
) |
This function receives nb_data bytes pointed to by ptr_buf on the specified pipe.
nb_data is updated with the final number of data bytes received.
pipe | ||
nb_data | ||
ptr_buf | ||
handler | Call-back function pointer |
Definition at line 971 of file usb_host_task.c.
References S_pipe_int::enable, g_sav_int_sof_enable, S_pipe_int::handler, Host_ack_in_received, Host_ack_nak_received, Host_ack_stall, Host_configure_pipe_token, Host_enable_continuous_in_mode, Host_enable_in_received_interrupt, Host_enable_nak_received_interrupt, Host_enable_pipe_error_interrupt, Host_enable_pipe_interrupt, Host_enable_sof_interrupt, Host_enable_stall_interrupt, Host_reset_pipe, Host_unfreeze_pipe, is_any_interrupt_pipe_active(), Is_host_nak_received, Is_host_sof_interrupt_enabled, NAK_RECEIVE_TIMEOUT, S_pipe_int::nak_timeout, S_pipe_int::nb_byte_processed, S_pipe_int::nb_byte_to_process, private_sof_counter, S_pipe_int::ptr_buf, S_pipe_int::timeout, and TOKEN_IN.
Referenced by host_send_data_callback().
00972 { 00973 Bool sav_glob_int_en; 00974 00975 if (it_pipe_str[pipe].enable) return FALSE; 00976 00977 if (!is_any_interrupt_pipe_active()) 00978 { 00979 g_sav_int_sof_enable = Is_host_sof_interrupt_enabled(); 00980 Host_enable_sof_interrupt(); 00981 } 00982 it_pipe_str[pipe].enable = TRUE; 00983 it_pipe_str[pipe].nb_byte_to_process = nb_data; 00984 it_pipe_str[pipe].nb_byte_processed = 0; 00985 it_pipe_str[pipe].ptr_buf = ptr_buf; 00986 it_pipe_str[pipe].handler = handler; 00987 it_pipe_str[pipe].timeout = 0; 00988 it_pipe_str[pipe].nak_timeout = NAK_RECEIVE_TIMEOUT; 00989 00990 private_sof_counter = 0; // Reset the counter in SOF detection subroutine 00991 if ((sav_glob_int_en = Is_global_interrupt_enabled())) Disable_global_interrupt(); 00992 Host_reset_pipe(pipe); 00993 Host_ack_stall(pipe); 00994 Host_ack_nak_received(pipe); 00995 (void)Is_host_nak_received(pipe); 00996 if (sav_glob_int_en) Enable_global_interrupt(); 00997 00998 Host_enable_stall_interrupt(pipe); 00999 #if NAK_TIMEOUT_ENABLE == ENABLE 01000 Host_enable_nak_received_interrupt(pipe); 01001 #endif 01002 Host_enable_pipe_error_interrupt(pipe); 01003 Host_enable_in_received_interrupt(pipe); 01004 Host_enable_pipe_interrupt(pipe); 01005 01006 Host_enable_continuous_in_mode(pipe); 01007 Host_configure_pipe_token(pipe, TOKEN_IN); 01008 Host_ack_in_received(pipe); 01009 Host_unfreeze_pipe(pipe); 01010 01011 return TRUE; 01012 }
Status_t host_send_data | ( | U8 | pipe, | |
U16 | nb_data, | |||
const void * | ptr_buf | |||
) |
This function sends nb_data bytes pointed to by ptr_buf on the specified pipe.
pipe | ||
nb_data | ||
ptr_buf |
Definition at line 608 of file usb_host_task.c.
References Host_ack_all_errors, Host_ack_nak_received, Host_ack_out_ready, Host_ack_out_ready_send, Host_ack_stall, Host_configure_pipe_token, Host_disable_sof_interrupt, Host_enable_sof_interrupt, Host_error_status, Host_freeze_pipe, Host_nb_busy_bank, Host_reset_pipe, Host_reset_pipe_fifo_access, Host_unfreeze_pipe, host_write_p_txpacket(), Is_host_emergency_exit, Is_host_nak_received, Is_host_out_ready, Is_host_pipe_error, Is_host_sof_interrupt_enabled, Is_host_stall, NAK_SEND_TIMEOUT, PIPE_DELAY_TIMEOUT, PIPE_GOOD, PIPE_NAK_TIMEOUT, PIPE_STALL, private_sof_counter, TIMEOUT_DELAY, and TOKEN_OUT.
Referenced by host_template_task().
00609 { 00610 Status_t status = PIPE_GOOD; // Frame correctly sent by default 00611 Bool sav_int_sof_enable; 00612 Bool sav_glob_int_en; 00613 U8 nak_timeout; 00614 #if NAK_TIMEOUT_ENABLE == ENABLE 00615 U16 cpt_nak; 00616 #endif 00617 00618 sav_int_sof_enable = Is_host_sof_interrupt_enabled(); // Save state of enable SOF interrupt 00619 Host_enable_sof_interrupt(); 00620 Host_configure_pipe_token(pipe, TOKEN_OUT); 00621 Host_ack_out_ready(pipe); 00622 Host_unfreeze_pipe(pipe); 00623 while (nb_data) // While there is something to send... 00624 { 00625 // Prepare data to be sent 00626 Host_reset_pipe_fifo_access(pipe); 00627 nb_data = host_write_p_txpacket(pipe, ptr_buf, nb_data, &ptr_buf); 00628 private_sof_counter = 0; // Reset the counter in SOF detection subroutine 00629 #if NAK_TIMEOUT_ENABLE == ENABLE 00630 cpt_nak = 0; 00631 #endif 00632 nak_timeout = 0; 00633 Host_ack_out_ready_send(pipe); 00634 while (!Is_host_out_ready(pipe)) 00635 { 00636 if (Is_host_emergency_exit()) // Async disconnection or role change detected under interrupt 00637 { 00638 status = PIPE_DELAY_TIMEOUT; 00639 Host_reset_pipe(pipe); 00640 goto host_send_data_end; 00641 } 00642 #if TIMEOUT_DELAY_ENABLE == ENABLE 00643 if (private_sof_counter >= 250) // Count 250 ms (250 SOF) 00644 { 00645 private_sof_counter = 0; 00646 if (nak_timeout++ >= TIMEOUT_DELAY) // Increment time-out and check for overflow 00647 { 00648 status = PIPE_DELAY_TIMEOUT; 00649 Host_reset_pipe(pipe); 00650 goto host_send_data_end; 00651 } 00652 } 00653 #endif 00654 if (Is_host_pipe_error(pipe)) // Error management 00655 { 00656 status = Host_error_status(pipe); 00657 Host_ack_all_errors(pipe); 00658 goto host_send_data_end; 00659 } 00660 if (Is_host_stall(pipe)) // STALL management 00661 { 00662 status = PIPE_STALL; 00663 Host_ack_stall(pipe); 00664 goto host_send_data_end; 00665 } 00666 #if NAK_TIMEOUT_ENABLE == ENABLE 00667 if (Is_host_nak_received(pipe)) // NAK received 00668 { 00669 Host_ack_nak_received(pipe); 00670 if (cpt_nak++ > NAK_SEND_TIMEOUT) 00671 { 00672 status = PIPE_NAK_TIMEOUT; 00673 Host_reset_pipe(pipe); 00674 goto host_send_data_end; 00675 } 00676 } 00677 #endif 00678 } 00679 // Here OUT sent 00680 Host_ack_out_ready(pipe); 00681 } 00682 while (Host_nb_busy_bank(pipe)); 00683 host_send_data_end: 00684 Host_freeze_pipe(pipe); 00685 // Restore SOF interrupt enable state 00686 if (!sav_int_sof_enable) 00687 { 00688 if ((sav_glob_int_en = Is_global_interrupt_enabled())) Disable_global_interrupt(); 00689 Host_disable_sof_interrupt(); 00690 (void)Is_host_sof_interrupt_enabled(); 00691 if (sav_glob_int_en) Enable_global_interrupt(); 00692 } 00693 00694 // And return... 00695 return status; 00696 }
Bool host_send_data_interrupt | ( | U8 | pipe, | |
U16 | nb_data, | |||
const void * | ptr_buf, | |||
Pipe_handler * | handler | |||
) |
This function sends nb_data bytes pointed to by ptr_buf on the specified pipe.
pipe | ||
nb_data | ||
ptr_buf | ||
handler | Call-back function pointer |
Definition at line 907 of file usb_host_task.c.
References S_pipe_int::enable, g_sav_int_sof_enable, S_pipe_int::handler, Host_ack_nak_received, Host_ack_out_ready, Host_ack_stall, Host_configure_pipe_token, Host_enable_nak_received_interrupt, Host_enable_out_ready_interrupt, Host_enable_pipe_error_interrupt, Host_enable_pipe_interrupt, Host_enable_sof_interrupt, Host_enable_stall_interrupt, Host_reset_pipe, Host_reset_pipe_fifo_access, Host_send_out, Host_unfreeze_pipe, host_write_p_txpacket(), is_any_interrupt_pipe_active(), Is_host_nak_received, Is_host_resetting_pipe, Is_host_sof_interrupt_enabled, NAK_SEND_TIMEOUT, S_pipe_int::nak_timeout, S_pipe_int::nb_byte_on_going, S_pipe_int::nb_byte_processed, S_pipe_int::nb_byte_to_process, private_sof_counter, S_pipe_int::ptr_buf, S_pipe_int::timeout, and TOKEN_OUT.
Referenced by host_template_task().
00908 { 00909 Bool sav_glob_int_en; 00910 00911 if (it_pipe_str[pipe].enable) return FALSE; 00912 00913 if (!is_any_interrupt_pipe_active()) 00914 { 00915 g_sav_int_sof_enable = Is_host_sof_interrupt_enabled(); 00916 Host_enable_sof_interrupt(); 00917 } 00918 it_pipe_str[pipe].enable = TRUE; 00919 it_pipe_str[pipe].nb_byte_to_process = nb_data; 00920 it_pipe_str[pipe].nb_byte_processed = 0; 00921 it_pipe_str[pipe].ptr_buf = (void *)ptr_buf; 00922 it_pipe_str[pipe].handler = handler; 00923 it_pipe_str[pipe].timeout = 0; 00924 it_pipe_str[pipe].nak_timeout = NAK_SEND_TIMEOUT; 00925 00926 if ((sav_glob_int_en = Is_global_interrupt_enabled())) Disable_global_interrupt(); 00927 Host_reset_pipe(pipe); 00928 (void)Is_host_resetting_pipe(pipe); 00929 if (sav_glob_int_en) Enable_global_interrupt(); 00930 Host_configure_pipe_token(pipe, TOKEN_OUT); 00931 Host_ack_out_ready(pipe); 00932 Host_unfreeze_pipe(pipe); 00933 // Prepare data to be sent 00934 Host_reset_pipe_fifo_access(pipe); 00935 it_pipe_str[pipe].nb_byte_on_going = nb_data - host_write_p_txpacket(pipe, ptr_buf, nb_data, NULL); 00936 private_sof_counter = 0; // Reset the counter in SOF detection subroutine 00937 it_pipe_str[pipe].timeout = 0; // Refresh time-out counter 00938 if ((sav_glob_int_en = Is_global_interrupt_enabled())) Disable_global_interrupt(); 00939 Host_ack_out_ready(pipe); 00940 Host_ack_stall(pipe); 00941 Host_ack_nak_received(pipe); 00942 (void)Is_host_nak_received(pipe); 00943 if (sav_glob_int_en) Enable_global_interrupt(); 00944 00945 Host_enable_stall_interrupt(pipe); 00946 Host_enable_pipe_error_interrupt(pipe); 00947 #if NAK_TIMEOUT_ENABLE == ENABLE 00948 Host_enable_nak_received_interrupt(pipe); 00949 #endif 00950 Host_enable_out_ready_interrupt(pipe); 00951 Host_enable_pipe_interrupt(pipe); 00952 00953 Host_send_out(pipe); // Send the USB frame 00954 00955 return TRUE; 00956 }
Bool is_any_interrupt_pipe_active | ( | void | ) |
Definition at line 884 of file usb_host_task.c.
References MAX_PEP_NB.
Referenced by host_get_data_interrupt(), host_send_data_interrupt(), usb_general_interrupt_non_naked(), and usb_pipe_interrupt().
00885 { 00886 U8 i; 00887 00888 for (i = 0; i < MAX_PEP_NB; i++) 00889 { 00890 if (it_pipe_str[i].enable) return TRUE; 00891 } 00892 00893 return FALSE; 00894 }
void reset_it_pipe_str | ( | void | ) |
Definition at line 872 of file usb_host_task.c.
References S_pipe_int::enable, MAX_PEP_NB, and S_pipe_int::timeout.
Referenced by usb_general_interrupt_non_naked(), and usb_host_task_init().
00873 { 00874 U8 i; 00875 00876 for (i = 0; i < MAX_PEP_NB; i++) 00877 { 00878 it_pipe_str[i].enable = FALSE; 00879 it_pipe_str[i].timeout = 0; 00880 } 00881 }
void usb_host_task | ( | void * | pvParameters | ) |
Entry point of the USB host management.
The aim is to manage the target device connection and enumeration. Depending on device_state, the function performs the required operations to get the device enumerated and configured. Once the device is operational, device_state is DEVICE_READY. This state should be tested by the host task before sending any applicative request to the device. This function is called from the usb_task function depending on the USB operating mode (device or host) currently engaged.
The aim is to manage the target device connection and enumeration. Depending on device_state, the function performs the required operations to get the device enumerated and configured. Once the device is operational, device_state is DEVICE_READY. This state should be tested by the host task before sending any applicative request to the device. This function is called from the usb_task function depending on the USB operating mode (device or host) currently engaged.
USB Host Task Overview
Definition at line 189 of file usb_host_task.c.
References configTSK_USB_HST_PERIOD, CONTROL_GOOD, data_stage, DEVICE_ADDRESS, DEVICE_ADDRESSED, DEVICE_ATTACHED, DEVICE_CONFIGURED, DEVICE_DEFAULT, DEVICE_ERROR, DEVICE_POWERED, DEVICE_READY, device_state, DEVICE_SUSPENDED, DEVICE_UNATTACHED, DEVICE_WAIT_RESUME, EP_CONTROL, EVT_HOST_HWUP, EVT_HOST_SOF, Host_ack_device_connection, Host_ack_device_disconnection, Host_ack_down_stream_resume, Host_ack_hwup, Host_ack_remote_wakeup, Host_ack_request_resume, Host_ack_reset_sent, Host_ack_sof, host_check_class(), host_check_VID_PID(), Host_clear_device_status, Host_configure_address, Host_configure_pipe, Host_device_class_not_supported_action, Host_device_connection_action, Host_device_error_action, Host_device_not_supported_action, Host_device_supported_action, host_disable_all_pipes(), Host_disable_device_disconnection_interrupt, Host_disable_hwup_interrupt, Host_disable_pipe, Host_disable_sof, Host_disable_sof_interrupt, Host_enable_device_disconnection_interrupt, Host_enable_hwup_interrupt, Host_enable_pipe, Host_enable_sof, Host_enable_sof_interrupt, host_get_configuration_descriptor, host_get_device_descriptor, host_get_device_descriptor_incomplete, Host_new_device_connection_action, Host_send_reset, Host_send_resume, host_set_address, host_set_configuration, Host_set_configured, Host_set_device_supported, host_set_feature_remote_wakeup, Host_stop_sending_reset, Host_suspend_action, Host_unallocate_memory, Is_device_supports_remote_wakeup, Is_host_configured, Is_host_device_connection, Is_host_device_disconnection, Is_host_down_stream_resume, Is_host_emergency_exit, Is_host_hwup_interrupt_enabled, Is_host_request_resume, Is_host_sending_reset, Is_host_sof_interrupt_enabled, Is_usb_bconnection_error_interrupt, Is_usb_clock_frozen, Is_usb_event, Is_usb_vbus_error_interrupt, Is_usb_vbus_high, Is_usb_vbus_low, log_device_connected, log_device_enumerated, LOG_STR, log_unsupported_device, log_usb_resumed, log_usb_suspended, MAX_PEP_NB, nb_interface_supported, OFFSET_FIELD_MAXPACKETSIZE, P_CONTROL, SINGLE_BANK, sof_cnt, TOKEN_SETUP, TYPE_CONTROL, Usb_ack_bconnection_error_interrupt, Usb_ack_event, Usb_ack_vbus_error_interrupt, Usb_clear_all_event, Usb_enable_vbus, Usb_freeze_clock, Usb_unfreeze_clock, and User_configure_endpoint.
Referenced by usb_host_task_init().
00193 { 00194 static Bool sav_int_sof_enable; 00195 U8 pipe; 00196 00197 #ifdef FREERTOS_USED 00198 portTickType xLastWakeTime; 00199 00200 xLastWakeTime = xTaskGetTickCount(); 00201 while (TRUE) 00202 { 00203 vTaskDelayUntil(&xLastWakeTime, configTSK_USB_HST_PERIOD); 00204 00205 #endif // FREERTOS_USED 00206 switch (device_state) 00207 { 00208 //------------------------------------------------------ 00209 // DEVICE_UNATTACHED state 00210 // 00211 // - Default init state 00212 // - Try to give device power supply 00213 // 00214 case DEVICE_UNATTACHED: 00215 nb_interface_supported = 0; 00216 Host_clear_device_status(); // Reset device status 00217 Usb_clear_all_event(); // Clear all software events 00218 Host_disable_sof(); 00219 host_disable_all_pipes(); 00220 Usb_enable_vbus(); // Give at least device power supply! 00221 // If VBus OK, wait for device connection 00222 if (Is_usb_vbus_high()) device_state = DEVICE_ATTACHED; 00223 break; 00224 00225 //------------------------------------------------------ 00226 // DEVICE_ATTACHED state 00227 // 00228 // - VBus is on 00229 // - Try to detect device connection 00230 // 00231 case DEVICE_ATTACHED: 00232 if (Is_host_device_connection()) // Device pull-up detected 00233 { 00234 Usb_ack_bconnection_error_interrupt(); 00235 Usb_ack_vbus_error_interrupt(); 00236 Host_ack_device_connection(); 00237 00238 // Now device is connected, enable disconnection interrupt 00239 Host_enable_device_disconnection_interrupt(); 00240 Enable_global_interrupt(); 00241 Host_clear_device_status(); // Reset device status 00242 Host_enable_sof(); // Start SOF generation 00243 Host_enable_sof_interrupt(); // SOF will be detected under interrupt 00244 sof_cnt = 0; 00245 while (sof_cnt < 100) // Wait 100 ms before USB reset 00246 { 00247 if (Is_usb_event(EVT_HOST_SOF)) Usb_ack_event(EVT_HOST_SOF), sof_cnt++; // Count SOFs 00248 if (Is_host_emergency_exit() || Is_usb_bconnection_error_interrupt()) goto device_attached_error; 00249 } 00250 Disable_global_interrupt(); 00251 Host_disable_device_disconnection_interrupt(); 00252 Host_send_reset(); // First USB reset 00253 (void)Is_host_sending_reset(); 00254 Enable_global_interrupt(); 00255 Usb_ack_event(EVT_HOST_SOF); 00256 // Active wait for end of reset send 00257 while (Is_host_sending_reset()) 00258 { 00259 // The USB macro does not signal the end of reset when a disconnection occurs 00260 if (Is_host_device_disconnection()) 00261 { 00262 // Stop sending USB reset 00263 Host_stop_sending_reset(); 00264 } 00265 } 00266 Host_ack_reset_sent(); 00267 if (!Is_host_device_disconnection()) 00268 { 00269 // Workaround for some buggy devices with powerless pull-up 00270 // usually low-speed where data line rises slowly and can be interpreted as disconnection 00271 for (sof_cnt = 0; sof_cnt < 0xFFFF; sof_cnt++) // Basic time-out counter 00272 { 00273 // If we detect SOF, device is still alive and connected, just clear false disconnect flag 00274 if (Is_usb_event(EVT_HOST_SOF) && Is_host_device_disconnection()) 00275 { 00276 Host_ack_device_connection(); 00277 Host_ack_device_disconnection(); 00278 break; 00279 } 00280 } 00281 } 00282 Host_enable_device_disconnection_interrupt(); 00283 sof_cnt = 0; 00284 while (sof_cnt < 100) // Wait 100 ms after USB reset 00285 { 00286 if (Is_usb_event(EVT_HOST_SOF)) Usb_ack_event(EVT_HOST_SOF), sof_cnt++; // Count SOFs 00287 if (Is_host_emergency_exit() || Is_usb_bconnection_error_interrupt()) goto device_attached_error; 00288 } 00289 device_state = DEVICE_POWERED; 00290 LOG_STR(log_device_connected); 00291 Host_device_connection_action(); 00292 sof_cnt = 0; 00293 } 00294 device_attached_error: 00295 // Device connection error, or VBus pb -> Retry the connection process from the beginning 00296 if (Is_usb_bconnection_error_interrupt() || Is_usb_vbus_error_interrupt() || Is_usb_vbus_low()) 00297 { 00298 device_state = DEVICE_UNATTACHED; 00299 Usb_ack_bconnection_error_interrupt(); 00300 Usb_ack_vbus_error_interrupt(); 00301 Host_disable_sof(); 00302 } 00303 break; 00304 00305 //------------------------------------------------------ 00306 // DEVICE_POWERED state 00307 // 00308 // - Device connection (attach) has been detected, 00309 // - Wait 100 ms and configure default control pipe 00310 // 00311 case DEVICE_POWERED: 00312 if (Is_usb_event(EVT_HOST_SOF)) 00313 { 00314 Usb_ack_event(EVT_HOST_SOF); 00315 if (sof_cnt++ >= 100) // Wait 100 ms 00316 { 00317 Host_enable_pipe(P_CONTROL); 00318 (void)Host_configure_pipe(P_CONTROL, 00319 0, 00320 EP_CONTROL, 00321 TYPE_CONTROL, 00322 TOKEN_SETUP, 00323 8, 00324 SINGLE_BANK); 00325 device_state = DEVICE_DEFAULT; 00326 } 00327 } 00328 break; 00329 00330 //------------------------------------------------------ 00331 // DEVICE_DEFAULT state 00332 // 00333 // - Get device descriptor 00334 // - Reconfigure control pipe according to device control endpoint 00335 // - Assign device address 00336 // 00337 case DEVICE_DEFAULT: 00338 // Get first device descriptor 00339 if (host_get_device_descriptor_incomplete() == CONTROL_GOOD) 00340 { 00341 sof_cnt = 0; 00342 while (sof_cnt < 20) // Wait 20 ms before USB reset (special buggy devices...) 00343 { 00344 if (Is_usb_event(EVT_HOST_SOF)) Usb_ack_event(EVT_HOST_SOF), sof_cnt++; 00345 if (Is_host_emergency_exit() || Is_usb_bconnection_error_interrupt()) break; 00346 } 00347 Disable_global_interrupt(); 00348 Host_disable_device_disconnection_interrupt(); 00349 Host_send_reset(); // First USB reset 00350 (void)Is_host_sending_reset(); 00351 Enable_global_interrupt(); 00352 Usb_ack_event(EVT_HOST_SOF); 00353 // Active wait for end of reset send 00354 while (Is_host_sending_reset()) 00355 { 00356 // The USB macro does not signal the end of reset when a disconnection occurs 00357 if (Is_host_device_disconnection()) 00358 { 00359 // Stop sending USB reset 00360 Host_stop_sending_reset(); 00361 } 00362 } 00363 Host_ack_reset_sent(); 00364 if (!Is_host_device_disconnection()) 00365 { 00366 // Workaround for some buggy devices with powerless pull-up 00367 // usually low-speed where data line rises slowly and can be interpreted as disconnection 00368 for (sof_cnt = 0; sof_cnt < 0xFFFF; sof_cnt++) // Basic time-out counter 00369 { 00370 // If we detect SOF, device is still alive and connected, just clear false disconnect flag 00371 if (Is_usb_event(EVT_HOST_SOF) && Is_host_device_disconnection()) 00372 { 00373 Host_ack_device_connection(); 00374 Host_ack_device_disconnection(); 00375 break; 00376 } 00377 } 00378 } 00379 Host_enable_device_disconnection_interrupt(); 00380 sof_cnt = 0; 00381 while (sof_cnt < 200) // Wait 200 ms after USB reset 00382 { 00383 if (Is_usb_event(EVT_HOST_SOF)) Usb_ack_event(EVT_HOST_SOF), sof_cnt++; 00384 if (Is_host_emergency_exit() || Is_usb_bconnection_error_interrupt()) break; 00385 } 00386 Host_disable_pipe(P_CONTROL); 00387 Host_unallocate_memory(P_CONTROL); 00388 Host_enable_pipe(P_CONTROL); 00389 // Reconfigure the control pipe according to the device control endpoint 00390 (void)Host_configure_pipe(P_CONTROL, 00391 0, 00392 EP_CONTROL, 00393 TYPE_CONTROL, 00394 TOKEN_SETUP, 00395 data_stage[OFFSET_FIELD_MAXPACKETSIZE], 00396 SINGLE_BANK); 00397 // Give an absolute device address 00398 if (host_set_address(DEVICE_ADDRESS) == CONTROL_GOOD) 00399 { 00400 for (pipe = 0; pipe < MAX_PEP_NB; pipe++) 00401 Host_configure_address(pipe, DEVICE_ADDRESS); 00402 device_state = DEVICE_ADDRESSED; 00403 } 00404 else device_state = DEVICE_ERROR; 00405 } 00406 else device_state = DEVICE_ERROR; 00407 break; 00408 00409 //------------------------------------------------------ 00410 // DEVICE_ADDRESSED state 00411 // 00412 // - Check if VID PID is in supported list 00413 // 00414 case DEVICE_ADDRESSED: 00415 if (host_get_device_descriptor() == CONTROL_GOOD) 00416 { 00417 // Detect if the device connected belongs to the supported devices table 00418 if (host_check_VID_PID()) 00419 { 00420 Host_set_device_supported(); 00421 Host_device_supported_action(); 00422 device_state = DEVICE_CONFIGURED; 00423 } 00424 else 00425 { 00426 #if HOST_STRICT_VID_PID_TABLE == ENABLE 00427 device_state = DEVICE_ERROR; 00428 LOG_STR(log_unsupported_device); 00429 #else 00430 device_state = DEVICE_CONFIGURED; 00431 #endif 00432 Host_device_not_supported_action(); 00433 } 00434 } 00435 else device_state = DEVICE_ERROR; // Can not get device descriptor 00436 break; 00437 00438 //------------------------------------------------------ 00439 // DEVICE_CONFIGURED state 00440 // 00441 // - Configure pipes for the supported interface 00442 // - Send Set_configuration() request 00443 // - Go to full operating mode (device ready) 00444 // 00445 case DEVICE_CONFIGURED: 00446 if (host_get_configuration_descriptor(0) == CONTROL_GOOD) 00447 { 00448 if (host_check_class()) // Class support OK? 00449 { 00450 #if HOST_AUTO_CFG_ENDPOINT == DISABLE 00451 User_configure_endpoint(); // User call here instead of autoconfig 00452 Host_set_configured(); // Assumes config is OK with user config 00453 #endif 00454 if (Is_host_configured()) 00455 { 00456 if (host_set_configuration(1) == CONTROL_GOOD) // Send Set_configuration 00457 { 00458 // Device and host are now fully configured 00459 // go to DEVICE_READY normal operation 00460 device_state = DEVICE_READY; 00461 // Monitor device disconnection under interrupt 00462 Host_enable_device_disconnection_interrupt(); 00463 // If user host application requires SOF interrupt event 00464 // Keep SOF interrupt enabled, otherwise disable this interrupt 00465 #if HOST_CONTINUOUS_SOF_INTERRUPT == DISABLE 00466 Disable_global_interrupt(); 00467 Host_disable_sof_interrupt(); 00468 (void)Is_host_sof_interrupt_enabled(); 00469 Enable_global_interrupt(); 00470 #endif 00471 Host_new_device_connection_action(); 00472 Enable_global_interrupt(); 00473 LOG_STR(log_device_enumerated); 00474 } 00475 else device_state = DEVICE_ERROR; // Problem during Set_configuration request... 00476 } 00477 } 00478 else // Device class not supported... 00479 { 00480 device_state = DEVICE_ERROR; 00481 LOG_STR(log_unsupported_device); 00482 Host_device_class_not_supported_action(); 00483 } 00484 } 00485 else device_state = DEVICE_ERROR; // Can not get configuration descriptors... 00486 break; 00487 00488 //------------------------------------------------------ 00489 // DEVICE_READY state 00490 // 00491 // - Full standard operating mode 00492 // - Nothing to do... 00493 // 00494 case DEVICE_READY: // Host full standard operating mode! 00495 break; 00496 00497 //------------------------------------------------------ 00498 // DEVICE_ERROR state 00499 // 00500 // - Error state 00501 // - Do custom action call (probably go to default mode...) 00502 // 00503 case DEVICE_ERROR: 00504 #if HOST_ERROR_RESTART == ENABLE 00505 device_state = DEVICE_UNATTACHED; 00506 #endif 00507 Host_device_error_action(); 00508 break; 00509 00510 //------------------------------------------------------ 00511 // DEVICE_SUSPENDED state 00512 // 00513 // - Host application request to suspend the device activity 00514 // - State machine comes here thanks to Host_request_suspend() 00515 // 00516 case DEVICE_SUSPENDED: 00517 if (Is_device_supports_remote_wakeup()) // If the connected device supports remote wake-up 00518 { 00519 host_set_feature_remote_wakeup(); // Enable this feature... 00520 } 00521 LOG_STR(log_usb_suspended); 00522 sav_int_sof_enable = Is_host_sof_interrupt_enabled(); //Save current SOF interrupt enable state 00523 Disable_global_interrupt(); 00524 Host_disable_sof_interrupt(); 00525 (void)Is_host_sof_interrupt_enabled(); 00526 Enable_global_interrupt(); 00527 Host_ack_sof(); 00528 Host_disable_sof(); // Stop SOF generation, this generates the suspend state 00529 Host_ack_hwup(); 00530 Host_enable_hwup_interrupt(); // Enable host wake-up interrupt 00531 // (this is the unique USB interrupt able to wake up the CPU core from power-down mode) 00532 (void)Is_host_hwup_interrupt_enabled(); // Make sure host wake-up interrupt is enabled 00533 Usb_freeze_clock(); 00535 //Stop_pll(); 00536 Host_suspend_action(); // Custom action here! (e.g. go to power-save mode...) 00537 device_state = DEVICE_WAIT_RESUME; // Wait for device resume event 00538 break; 00539 00540 //------------------------------------------------------ 00541 // DEVICE_WAIT_RESUME state 00542 // 00543 // Wait in this state till: 00544 // - the host receives an upstream resume from the device 00545 // - or the host software request the device to resume 00546 // 00547 case DEVICE_WAIT_RESUME: 00548 if (Is_usb_event(EVT_HOST_HWUP) || Is_host_request_resume()) // Remote wake-up has been detected 00549 // or local resume request has been received 00550 { 00551 if (Is_host_request_resume()) // Not a remote wake-up, but a host application request 00552 { 00553 // CAUTION: HWUP can be cleared only when USB clock is active 00555 //Pll_start_auto(); // First Restart the PLL for USB operation 00556 //Wait_pll_ready(); // Make sure PLL is locked 00557 Usb_unfreeze_clock(); // Enable clock on USB interface 00558 (void)Is_usb_clock_frozen(); // Make sure USB interface clock is enabled 00559 Disable_global_interrupt(); 00560 Host_disable_hwup_interrupt(); // Wake-up interrupt should be disabled as host is now awoken! 00561 (void)Is_host_hwup_interrupt_enabled(); 00562 Enable_global_interrupt(); 00563 Host_ack_hwup(); // Clear HWUP interrupt flag 00564 } 00565 Host_enable_sof(); 00566 Host_send_resume(); // Send downstream resume 00567 while (!Is_host_down_stream_resume()); // Wait for downstream resume sent 00568 Host_ack_remote_wakeup(); // Ack remote wake-up reception 00569 Host_ack_request_resume(); // Ack software request 00570 Host_ack_down_stream_resume(); // Ack downstream resume sent 00571 Usb_ack_event(EVT_HOST_HWUP); // Ack software event 00572 if (sav_int_sof_enable) Host_enable_sof_interrupt(); // Restore SOF interrupt enable state before suspend 00573 device_state = DEVICE_READY; // Come back to full operating mode 00574 LOG_STR(log_usb_resumed); 00575 } 00576 break; 00577 00578 //------------------------------------------------------ 00579 // default state 00580 // 00581 // - Default case: ERROR 00582 // - Go to DEVICE_UNATTACHED state 00583 // 00584 default: 00585 device_state = DEVICE_UNATTACHED; 00586 break; 00587 } 00588 #ifdef FREERTOS_USED 00589 } 00590 #endif 00591 }
void usb_host_task_init | ( | void | ) |
This function initializes the USB host controller.
This function enables the USB controller for host-mode operation.
Definition at line 133 of file usb_host_task.c.
References configTSK_USB_HST_NAME, configTSK_USB_HST_PRIORITY, configTSK_USB_HST_STACK_SIZE, device_state, DEVICE_UNATTACHED, Host_ack_request_resume, Host_clear_device_status, Host_enable_device_disconnection_interrupt, Is_usb_clock_frozen, Is_usb_enabled, reset_it_pipe_str(), sof_cnt, Usb_disable, Usb_disable_otg_pad, Usb_disable_vbus_hw_control, Usb_enable, Usb_enable_otg_pad, usb_host_task(), usb_host_tsk, Usb_output_vbof_pin, Usb_set_vbof_active_high, Usb_set_vbof_active_low, and Usb_unfreeze_clock.
Referenced by usb_task().
00134 { 00136 //Pll_start_auto(); 00137 //Wait_pll_ready(); 00138 Disable_global_interrupt(); 00139 Usb_disable(); 00140 (void)Is_usb_enabled(); 00141 Enable_global_interrupt(); 00142 Usb_disable_otg_pad(); 00143 Usb_enable_otg_pad(); 00144 Usb_enable(); 00145 Usb_unfreeze_clock(); 00146 (void)Is_usb_clock_frozen(); 00147 #if USB_VBOF_ACTIVE_LEVEL == HIGH 00148 Usb_set_vbof_active_high(); 00149 #else // USB_VBOF_ACTIVE_LEVEL == LOW 00150 Usb_set_vbof_active_low(); 00151 #endif 00152 Usb_output_vbof_pin(); 00153 Usb_disable_vbus_hw_control(); // Force VBus generation without time-out 00154 Host_enable_device_disconnection_interrupt(); 00155 #if USB_HOST_PIPE_INTERRUPT_TRANSFER == ENABLE 00156 reset_it_pipe_str(); 00157 #endif 00158 device_state = DEVICE_UNATTACHED; 00159 Host_clear_device_status(); 00160 Host_ack_request_resume(); 00161 sof_cnt = 0; 00162 00163 #ifdef FREERTOS_USED 00164 xTaskCreate(usb_host_task, 00165 configTSK_USB_HST_NAME, 00166 configTSK_USB_HST_STACK_SIZE, 00167 NULL, 00168 configTSK_USB_HST_PRIORITY, 00169 &usb_host_tsk); 00170 #endif // FREERTOS_USED 00171 }
void usb_pipe_interrupt | ( | U8 | pipe | ) |
USB pipe interrupt subroutine.
pipe |
Definition at line 1018 of file usb_host_task.c.
References S_pipe_int::enable, g_sav_int_sof_enable, S_pipe_int::handler, Host_ack_all_errors, Host_ack_in_received, Host_ack_nak_received, Host_ack_out_ready, Host_byte_count, Host_disable_sof_interrupt, Host_error_status, Host_free_in, Host_freeze_pipe, Host_get_pipe_size, Host_get_pipe_type, host_read_p_rxpacket(), Host_reset_pipe, Host_reset_pipe_fifo_access, Host_send_out, Host_unfreeze_pipe, host_write_p_txpacket(), is_any_interrupt_pipe_active(), Is_host_in_received, Is_host_nak_received, Is_host_out_ready, Is_host_pipe_error, Is_host_stall, NAK_RECEIVE_TIMEOUT, NAK_SEND_TIMEOUT, S_pipe_int::nak_timeout, S_pipe_int::nb_byte_on_going, S_pipe_int::nb_byte_processed, S_pipe_int::nb_byte_to_process, PIPE_GOOD, PIPE_NAK_TIMEOUT, PIPE_STALL, private_sof_counter, S_pipe_int::status, S_pipe_int::timeout, and TYPE_INTERRUPT.
Referenced by usb_general_interrupt_non_naked().
01019 { 01020 void *ptr_buf; 01021 U16 n, i; 01022 Bool callback = FALSE; 01023 01024 // Detect which events generate an interrupt... 01025 01026 if (Is_host_pipe_error(pipe)) // Error management 01027 { 01028 it_pipe_str[pipe].status = Host_error_status(pipe); 01029 it_pipe_str[pipe].enable = FALSE; 01030 Host_reset_pipe(pipe); 01031 Host_ack_all_errors(pipe); 01032 callback = TRUE; 01033 goto usb_pipe_interrupt_end; 01034 } 01035 01036 if (Is_host_stall(pipe)) // STALL management 01037 { 01038 it_pipe_str[pipe].status = PIPE_STALL; 01039 it_pipe_str[pipe].enable = FALSE; 01040 Host_reset_pipe(pipe); 01041 callback = TRUE; 01042 goto usb_pipe_interrupt_end; 01043 } 01044 01045 #if NAK_TIMEOUT_ENABLE == ENABLE 01046 if (Is_host_nak_received(pipe)) // NAK received 01047 { 01048 Host_ack_nak_received(pipe); 01049 // Check if NAK time-out error occurs (not for interrupt pipes) 01050 if (!--it_pipe_str[pipe].nak_timeout && Host_get_pipe_type(pipe) != TYPE_INTERRUPT) 01051 { 01052 it_pipe_str[pipe].status = PIPE_NAK_TIMEOUT; 01053 it_pipe_str[pipe].enable = FALSE; 01054 Host_reset_pipe(pipe); 01055 callback = TRUE; 01056 goto usb_pipe_interrupt_end; 01057 } 01058 } 01059 #endif 01060 01061 if (Is_host_in_received(pipe)) // Pipe IN reception? 01062 { 01063 ptr_buf = (U8 *)it_pipe_str[pipe].ptr_buf + it_pipe_str[pipe].nb_byte_processed; // Build pointer to data buffer 01064 n = it_pipe_str[pipe].nb_byte_to_process - it_pipe_str[pipe].nb_byte_processed; // Remaining data bytes 01065 Host_freeze_pipe(pipe); 01066 Host_reset_pipe_fifo_access(pipe); 01067 i = Host_get_pipe_size(pipe) - Host_byte_count(pipe); 01068 n = host_read_p_rxpacket(pipe, ptr_buf, n, NULL); 01069 it_pipe_str[pipe].nb_byte_processed = it_pipe_str[pipe].nb_byte_to_process - n; 01070 if (Host_byte_count(pipe)) // More bytes received than expected 01071 { 01073 } 01074 else if (i) // Short packet with nb bytes received <= expected 01075 { 01076 n = 0; 01077 } 01078 Host_ack_in_received(pipe); 01079 if (n) // Still data to process 01080 { 01081 Host_free_in(pipe); 01082 Host_unfreeze_pipe(pipe); // Request another IN transfer 01083 private_sof_counter = 0; // Reset the counter in SOF detection subroutine 01084 it_pipe_str[pipe].timeout = 0; // Reset time-out 01085 it_pipe_str[pipe].nak_timeout = NAK_RECEIVE_TIMEOUT; 01086 } 01087 else // End of transfer 01088 { 01089 it_pipe_str[pipe].enable = FALSE; 01090 it_pipe_str[pipe].status = PIPE_GOOD; 01091 Host_reset_pipe(pipe); 01092 callback = TRUE; 01093 } 01094 } 01095 01096 if (Is_host_out_ready(pipe)) // Pipe OUT sent? 01097 { 01098 Host_ack_out_ready(pipe); 01099 it_pipe_str[pipe].nb_byte_processed += it_pipe_str[pipe].nb_byte_on_going; 01100 it_pipe_str[pipe].nb_byte_on_going = 0; 01101 ptr_buf = (U8 *)it_pipe_str[pipe].ptr_buf + it_pipe_str[pipe].nb_byte_processed; // Build pointer to data buffer 01102 n = it_pipe_str[pipe].nb_byte_to_process - it_pipe_str[pipe].nb_byte_processed; // Remaining data bytes 01103 if (n) // Still data to process 01104 { 01105 Host_unfreeze_pipe(pipe); 01106 // Prepare data to be sent 01107 Host_reset_pipe_fifo_access(pipe); 01108 it_pipe_str[pipe].nb_byte_on_going = n - host_write_p_txpacket(pipe, ptr_buf, n, NULL); 01109 private_sof_counter = 0; // Reset the counter in SOF detection subroutine 01110 it_pipe_str[pipe].timeout = 0; // Refresh time-out counter 01111 it_pipe_str[pipe].nak_timeout = NAK_SEND_TIMEOUT; 01112 Host_send_out(pipe); // Send the USB frame 01113 } 01114 else // End of transfer 01115 { 01116 it_pipe_str[pipe].enable = FALSE; // Tranfer end 01117 it_pipe_str[pipe].status = PIPE_GOOD; // Status OK 01118 Host_reset_pipe(pipe); 01119 callback = TRUE; 01120 } 01121 } 01122 01123 usb_pipe_interrupt_end: 01124 if (!is_any_interrupt_pipe_active() && !g_sav_int_sof_enable) // If no more transfer is armed 01125 { 01126 Host_disable_sof_interrupt(); 01127 } 01128 if (callback) // Any call-back function to perform? 01129 { 01130 it_pipe_str[pipe].handler(it_pipe_str[pipe].status, it_pipe_str[pipe].nb_byte_processed); 01131 } 01132 }
U8 data_stage[SIZEOF_DATA_STAGE] |
Public: U8 data_stage[SIZEOF_DATA_STAGE] Internal RAM buffer for USB data stage content This buffer is required to setup host enumeration process It contains the device descriptors received.
Depending on the device descriptors length, its size can be optimized with the SIZEOF_DATA_STAGE define of conf_usb.h file
Definition at line 111 of file usb_host_task.c.
Referenced by host_check_class(), host_check_VID_PID(), and usb_host_task().
volatile U8 device_state |
Public: U8 device_state Its value represents the current state of the device connected to the USB host controller Value can be:
Definition at line 98 of file usb_host_task.c.
Referenced by usb_general_interrupt_non_naked(), usb_host_task(), and usb_host_task_init().
volatile U8 device_status |
Definition at line 113 of file usb_host_task.c.
volatile Bool request_resume |
Definition at line 115 of file usb_host_task.c.
volatile S_usb_setup_data usb_request |
For control requests management over control pipe.
Definition at line 101 of file usb_host_task.c.
Referenced by host_transfer_control().