- Main Page
- Modules
- Data Structures
- Files
- Related Pages

# usb_host_task.c File Reference

`#include "config.h"`
`#include "conf_usb.h"`
`#include "modules/usb/usb_task.h"`
`#include "usb_host_task.h"`
`#include "lib_mcu/usb/usb_drv.h"`
`#include "lib_mcu/pll/pll_drv.h"`
`#include "modules/usb/host_chap9/usb_host_enum.h"`
`#include "modules/usb/host_chap9/usb_host_hub.h"`

Include dependency graph for usb_host_task.c:

Go to the source code of this file.

## Defines
#define | Usb_id_transition_action()
#define | Host_device_disconnection_action()
#define | Host_device_connection_action()
#define | Host_sof_action()
#define | Host_suspend_action()
#define | Host_hwup_action()
#define | Host_device_not_supported_action()
#define | Host_device_class_not_supported_action()
#define | Host_device_supported_action()
#define | Host_device_error_action()
#define | LOG_STR_CODE(str)
## Functions
void | usb_host_task_init (void)
void | usb_host_task (void)
U8 | host_send_data (U8 pipe, U16 nb_data, U8 *buf)
U8 | host_get_data (U8 pipe, U16 *nb_data, U8 *buf)
void | reset_it_pipe_str (void)
U8 | is_any_interrupt_pipe_active (void)
U8 | host_get_data_interrupt (U8 pipe, U16 nb_data, U8 *buf, void(*handle)(U8 status, U16 nb_byte))
U8 | host_send_data_interrupt (U8 pipe, U16 nb_data, U8 *buf, void(*handle)(U8 status, U16 nb_byte))
__interrupt void | usb_pipe_interrupt ()
## Variables
volatile S_pipe_int | it_pipe_str [MAX_EP_NB]
volatile U8 | pipe_nb_save
U8 | g_sav_int_sof_enable
U8 | device_state
| Public : U8 device_state Its value represent the current state of the device connected to the usb host controller Value can be: DEVICE_ATTACHED DEVICE_POWERED DEVICE_SUSPENDED DEVICE_DEFAULT DEVICE_BASE_ADDRESSED DEVICE_CONFIGURED DEVICE_ERROR DEVICE_UNATTACHED DEVICE_READY DEVICE_WAIT_RESUME DEVICE_DISCONNECTED DEVICE_DISCONNECTED_ACK /.
S_usb_setup_data | usb_request
| For control requests management over pipe 0.
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 Its contains the device descriptors received.
U8 | device_status
U8 | request_resume = FALSE
U8 | force_enumeration = FALSE
U8 | new_device_connected = FALSE
static U16 | c
static U8 | i
static U8 | j
volatile U8 | hub_interrupt_sof = 0
U8 | saved_device

## Detailed Description

This file manages the USB Host controller, the host enumeration process and suspend resume host requests. This task dos not belongs to the scheduler tasks but is called directly from the general usb_task

- Compiler: IAR EWAVR and GNU GCC for AVR
- Supported devices: AT90USB1287, AT90USB1286, AT90USB647, AT90USB646

Author:
  Atmel Corporation: http://www.atmel.com
  Support and FAQ: http://support.atmel.no/

Definition in file usb_host_task.c.

## Define Documentation

#define Usb_id_transition_action | ( |  | ) |

Definition at line 81 of file usb_host_task.c.

#define Host_device_disconnection_action | ( |  | ) |

Definition at line 84 of file usb_host_task.c.

#define Host_device_connection_action | ( |  | ) |

Definition at line 87 of file usb_host_task.c.

#define Host_sof_action | ( |  | ) |

Definition at line 90 of file usb_host_task.c.

#define Host_suspend_action | ( |  | ) |

Definition at line 93 of file usb_host_task.c.

#define Host_hwup_action | ( |  | ) |

Definition at line 96 of file usb_host_task.c.

#define Host_device_not_supported_action | ( |  | ) |

Definition at line 99 of file usb_host_task.c.

#define Host_device_class_not_supported_action | ( |  | ) |

Definition at line 102 of file usb_host_task.c.

#define Host_device_supported_action | ( |  | ) |

Definition at line 105 of file usb_host_task.c.

#define Host_device_error_action | ( |  | ) |

Definition at line 108 of file usb_host_task.c.

#define LOG_STR_CODE | ( | str |  | ) |

Definition at line 115 of file usb_host_task.c.

## Function Documentation

__interrupt void usb_pipe_interrupt | ( |  | ) |

USB pipe interrupt subroutine

Parameters:

  | none |

Returns:
  none

Definition at line 1129 of file usb_host_task.c.

References DISABLE, S_pipe_int::enable, FALSE, g_sav_int_sof_enable, S_pipe_int::handle, Host_ack_all_errors, Host_ack_in_received, Host_ack_nak_received, Host_ack_out_sent, Host_byte_counter, Host_disable_sof_interrupt, Host_error_status, Host_freeze_pipe, Host_get_pipe_length, Host_get_pipe_type, Host_get_selected_pipe, Host_read_byte, Host_select_pipe, Host_send_in, Host_send_out, Host_stop_pipe_interrupt, Host_unfreeze_pipe, Host_write_byte, i, is_any_interrupt_pipe_active(), Is_host_in_received, Is_host_nak_received, Is_host_out_sent, 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_nb_save, PIPE_STALL, private_sof_counter, S_pipe_int::ptr_buf, S_pipe_int::status, S_pipe_int::timeout, TRUE, TYPE_INTERRUPT, and usb_get_nb_pipe_interrupt().

    01131 {
    01132    U8 pipe_nb;
    01133    U8 *ptr_buf;
    01134    void  (*fct_handle)(U8 status,U16 nb_byte);
    01135    U16 n;
    01136    U8 i;
    01137    U8 do_call_back=FALSE;
    01138
    01139    pipe_nb_save = Host_get_selected_pipe();       // Important! Save here working pipe number
    01140    pipe_nb=usb_get_nb_pipe_interrupt();  // work with the correct pipe number that generates the interrupt
    01141    Host_select_pipe(pipe_nb);                        // Select this pipe
    01142    fct_handle=*(it_pipe_str[pipe_nb].handle);
    01143
    01144    // Now try to detect what event generate an interrupt...
    01145
    01146    if (Is_host_pipe_error())             // Any error ?
    01147    {
    01148       it_pipe_str[pipe_nb].status = Host_error_status();
    01149       it_pipe_str[pipe_nb].enable=DISABLE;
    01150       Host_stop_pipe_interrupt(pipe_nb);
    01151       Host_ack_all_errors();
    01152       do_call_back=TRUE;
    01153       goto usb_pipe_interrupt_end;
    01154    }
    01155
    01156    if (Is_host_stall())                  // Stall handshake received ?
    01157    {
    01158       it_pipe_str[pipe_nb].status=PIPE_STALL;
    01159       it_pipe_str[pipe_nb].enable=DISABLE;
    01160       Host_stop_pipe_interrupt(pipe_nb);
    01161       do_call_back=TRUE;
    01162       goto usb_pipe_interrupt_end;
    01163    }
    01164
    01165    #if (NAK_TIMEOUT_ENABLE==ENABLE)
    01166    if (Is_host_nak_received())           // NAK ?
    01167    {
    01168       Host_ack_nak_received();
    01169       // check if number of NAK timeout error occurs (not for interrupt type pipe)
    01170       if((--it_pipe_str[pipe_nb].nak_timeout==0) && (Host_get_pipe_type()!=TYPE_INTERRUPT))
    01171       {
    01172          it_pipe_str[pipe_nb].status=PIPE_NAK_TIMEOUT;
    01173          it_pipe_str[pipe_nb].enable=DISABLE;
    01174          Host_stop_pipe_interrupt(pipe_nb);
    01175          do_call_back=TRUE;
    01176          goto usb_pipe_interrupt_end;
    01177       }
    01178    }
    01179    #endif
    01180
    01181    if (Is_host_in_received())            // Pipe IN reception ?
    01182    {
    01183       ptr_buf=it_pipe_str[pipe_nb].ptr_buf+it_pipe_str[pipe_nb].nb_byte_processed;       // Build pointer to data buffer
    01184       n=it_pipe_str[pipe_nb].nb_byte_to_process-it_pipe_str[pipe_nb].nb_byte_processed;  // Remaining data bytes
    01185       Host_freeze_pipe();
    01186       if (Host_byte_counter()<=n)
    01187       {
    01188          if ((Host_byte_counter() < n)&&(Host_byte_counter()<Host_get_pipe_length())) //Received less than remaining, but less than pipe capacity
    01189                                                                                       //TODO: error code
    01190          {
    01191             n=0;
    01192          }
    01193          else
    01194          {
    01195             n-=Host_byte_counter();
    01196          }
    01197          it_pipe_str[pipe_nb].nb_byte_processed+=Host_byte_counter();  // Update nb of byte received
    01198          for (i=Host_byte_counter();i;i--)
    01199          { *ptr_buf=Host_read_byte(); ptr_buf++;}
    01200       }
    01201       else  // more bytes received than expected
    01202       {     // TODO error code management
    01203          it_pipe_str[pipe_nb].nb_byte_processed+=n;
    01204          for (i=n;i;i--)                  // Byte number limited to the initial request (limit tab over pb)
    01205          { *ptr_buf=Host_read_byte(); ptr_buf++;}
    01206          n=0;
    01207       }
    01208       Host_ack_in_received();
    01209       if(n>0) //still something to process
    01210       {
    01211          Host_unfreeze_pipe();            // Request another IN transfer
    01212          Host_send_in();
    01213          private_sof_counter=0;           // Reset the counter in SOF detection sub-routine
    01214          it_pipe_str[pipe_nb].timeout=0;  // Reset timeout
    01215          it_pipe_str[pipe_nb].nak_timeout=NAK_RECEIVE_TIMEOUT;
    01216
    01217       }
    01218       else //end of transfer
    01219       {
    01220          it_pipe_str[pipe_nb].enable=DISABLE;
    01221          it_pipe_str[pipe_nb].status=PIPE_GOOD;
    01222          Host_stop_pipe_interrupt(pipe_nb);
    01223          do_call_back=TRUE;
    01224       }
    01225    }
    01226
    01227    if(Is_host_out_sent())                  // Pipe OUT sent ?
    01228    {
    01229       Host_ack_out_sent();
    01230       it_pipe_str[pipe_nb].nb_byte_processed+=it_pipe_str[pipe_nb].nb_byte_on_going;
    01231       it_pipe_str[pipe_nb].nb_byte_on_going=0;
    01232       ptr_buf=it_pipe_str[pipe_nb].ptr_buf+it_pipe_str[pipe_nb].nb_byte_processed;       // Build pointer to data buffer
    01233       n=it_pipe_str[pipe_nb].nb_byte_to_process-it_pipe_str[pipe_nb].nb_byte_processed;  // Remaining data bytes
    01234       if(n>0)   // Still data to process...
    01235       {
    01236          Host_unfreeze_pipe();
    01237         // Prepare data to be sent
    01238          i = Host_get_pipe_length();
    01239          if ( i > n)     // Pipe size> remaining data
    01240          {
    01241             i = n;
    01242             n = 0;
    01243          }
    01244          else                // Pipe size < remaining data
    01245          {  n -= i; }
    01246          it_pipe_str[pipe_nb].nb_byte_on_going+=i;   // Update nb data processed
    01247          while (i!=0)                     // Load Pipe buffer
    01248          {
    01249             Host_write_byte(*ptr_buf++); i--;
    01250          }
    01251          private_sof_counter=0;           // Reset the counter in SOF detection sub-routine
    01252          it_pipe_str[pipe_nb].timeout=0;  // Refresh timeout counter
    01253          it_pipe_str[pipe_nb].nak_timeout=NAK_SEND_TIMEOUT;
    01254          Host_send_out();                 // Send the USB frame
    01255       }
    01256       else                                //n==0 Transfer is finished
    01257       {
    01258          it_pipe_str[pipe_nb].enable=DISABLE;    // Tranfer end
    01259          it_pipe_str[pipe_nb].status=PIPE_GOOD;  // Status OK
    01260          Host_stop_pipe_interrupt(pipe_nb);
    01261          do_call_back=TRUE;
    01262       }
    01263    }
    01264
    01265 usb_pipe_interrupt_end:
    01266    Host_select_pipe(pipe_nb_save);   // Restore pipe number !!!!
    01267    if (is_any_interrupt_pipe_active()==FALSE)    // If no more transfer is armed
    01268    {
    01269       if (g_sav_int_sof_enable==FALSE)
    01270       {
    01271          Host_disable_sof_interrupt();
    01272       }
    01273    }
    01274    if(do_call_back)      // Any callback functions to perform ?
    01275    {
    01276       fct_handle(it_pipe_str[pipe_nb].status,it_pipe_str[pipe_nb].nb_byte_processed);
    01277    }
    01278 }

Here is the call graph for this function:

## Variable Documentation

volatile S_pipe_int it_pipe_str[MAX_EP_NB]

Definition at line 129 of file usb_host_task.c.

volatile U8 pipe_nb_save

Definition at line 130 of file usb_host_task.c.

Referenced by usb_pipe_interrupt().

U8 g_sav_int_sof_enable

Definition at line 131 of file usb_host_task.c.

Referenced by host_get_data_interrupt(), host_send_data_interrupt(), usb_general_interrupt(), and usb_pipe_interrupt().

U16 c`[static]`

Definition at line 174 of file usb_host_task.c.

Referenced by enumerate_hub_port_device(), host_check_class(), host_check_VID_PID(), host_send_control(), host_send_data(), hub_manage_port_change_status(), print_msg(), uart_getchar(), usb_host_task(), and usb_mass_storage_cbw().

U8 i`[static]`

Definition at line 178 of file usb_host_task.c.

Referenced by code2data(), df_host_read_sector(), df_host_write_sector(), df_read_sector(), df_read_sector_2_ram(), df_write_sector(), df_write_sector_from_ram(), fat_check_device(), host_auto_configure_endpoint(), host_disable_all_pipe(), host_get_data(), host_get_hwd_pipe_nb(), host_mem_get_lun(), host_mem_init(), host_mem_install(), host_mem_uninstall(), host_send_data_interrupt(), hub_init(), hub_manage_port_change_status(), init_usb_tree(), is_any_interrupt_pipe_active(), memcmp_code(), nav_reset(), remove_device_entry(), reset_it_pipe_str(), sbc_inquiry(), sbc_request_sense(), str_code_to_str_ram(), usb_general_interrupt(), usb_get_nb_pipe_interrupt(), usb_host_task(), usb_pipe_interrupt(), and ushell_cmdusb_ls().

U8 j`[static]`

Definition at line 178 of file usb_host_task.c.

Referenced by df_read_sector(), df_write_sector(), host_get_hwd_pipe_nb(), mystrncmp(), remove_device_entry(), usb_host_task(), and ushell_cmdusb_ls().

volatile U8 hub_interrupt_sof = 0

Definition at line 179 of file usb_host_task.c.

Referenced by usb_general_interrupt(), and usb_host_task().

U8 saved_device

Definition at line 180 of file usb_host_task.c.

Referenced by usb_host_task().