USB host task module


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:
  • DEVICE_ATTACHED
  • DEVICE_POWERED
  • DEVICE_SUSPENDED
  • DEVICE_DEFAULT
  • DEVICE_ADDRESSED
  • DEVICE_CONFIGURED
  • DEVICE_ERROR
  • DEVICE_UNATTACHED
  • DEVICE_READY
  • DEVICE_WAIT_RESUME.

volatile U8 device_status
volatile Bool request_resume
volatile S_usb_setup_data usb_request
 For control requests management over control pipe.


Define Documentation

 
#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)

Check if there is a device addressed by the host.

Definition at line 111 of file usb_host_task.h.

 
#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)

Check if there is an error.

Definition at line 108 of file usb_host_task.h.

 
#define Is_host_powered (  )     (device_state >= DEVICE_POWERED)

Check if there is a device powered by the host.

Definition at line 114 of file usb_host_task.h.

 
#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:

Check if host controller is in suspend mode.

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

#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 Documentation

typedef void Pipe_handler(Status_t status, U16 nb_byte)

Definition at line 71 of file usb_host_task.h.


Function Documentation

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.

Note:
This function activates the host SOF interrupt to detect time-outs. The initial enable state of this interrupt will be restored.
Parameters:
pipe 
nb_data 
ptr_buf 
Returns:
Status_t: Pipe status

Todo:
Error code management

Todo:
Error code management

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.

Parameters:
pipe 
nb_data 
ptr_buf 
handler Call-back function pointer
Returns:
Bool: Status

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.

Note:
This function activates the host SOF interrupt to detect time-outs. The initial enable state of this interrupt will be restored.
Parameters:
pipe 
nb_data 
ptr_buf 
Returns:
Status_t: Pipe status

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.

Parameters:
pipe 
nb_data 
ptr_buf 
handler Call-back function pointer
Returns:
Bool: Status

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.jpg

USB Host Task Overview

Todo:

Todo:
Implement this on the silicon version

Todo:
Implement this on the silicon version

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.

Todo:
Implement this on the silicon version

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.

Parameters:
pipe 

Todo:
Error code management

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 }


Variable Documentation

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:

  • DEVICE_ATTACHED
  • DEVICE_POWERED
  • DEVICE_SUSPENDED
  • DEVICE_DEFAULT
  • DEVICE_ADDRESSED
  • DEVICE_CONFIGURED
  • DEVICE_ERROR
  • DEVICE_UNATTACHED
  • DEVICE_READY
  • DEVICE_WAIT_RESUME.

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.

For control requests management over control pipe.

Definition at line 101 of file usb_host_task.c.

Referenced by host_transfer_control().


Generated on Fri Feb 19 02:27:53 2010 for AVR32 - USB Enumeration Example by  doxygen 1.5.5