ATMEL: usb_host_task.c File Reference

- 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 84 of file usb_host_task.c.

#define Host_device_disconnection_action | ( |  | ) |

Definition at line 87 of file usb_host_task.c.

#define Host_device_connection_action | ( |  | ) |

Definition at line 90 of file usb_host_task.c.

#define Host_sof_action | ( |  | ) |

Definition at line 93 of file usb_host_task.c.

#define Host_suspend_action | ( |  | ) |

Definition at line 96 of file usb_host_task.c.

#define Host_hwup_action | ( |  | ) |

Definition at line 99 of file usb_host_task.c.

#define Host_device_not_supported_action | ( |  | ) |

Definition at line 102 of file usb_host_task.c.

#define Host_device_class_not_supported_action | ( |  | ) |

Definition at line 105 of file usb_host_task.c.

#define Host_device_supported_action | ( |  | ) |

Definition at line 108 of file usb_host_task.c.

#define Host_device_error_action | ( |  | ) |

Definition at line 111 of file usb_host_task.c.

#define LOG_STR_CODE | ( | str |  | ) |

Definition at line 118 of file usb_host_task.c.

## Function Documentation

__interrupt void usb_pipe_interrupt | ( |  | ) |

USB pipe interrupt subroutine

Parameters:

  | none |

Returns:
  none

Definition at line 1132 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().

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

Here is the call graph for this function:

## Variable Documentation

volatile S_pipe_int it_pipe_str[MAX_EP_NB]

Definition at line 132 of file usb_host_task.c.

volatile U8 pipe_nb_save

Definition at line 133 of file usb_host_task.c.

Referenced by usb_pipe_interrupt().

U8 g_sav_int_sof_enable

Definition at line 134 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 177 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 181 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(), dfu_flush_prog(), dfu_load_hex(), dfu_prog(), dfu_read(), fat_check_device(), host_auto_configure_endpoint(), host_disable_all_pipe(), host_get_data(), host_get_hwd_pipe_nb(), host_hid_task(), host_mem_get_lun(), host_mem_init(), host_mem_install(), host_mem_uninstall(), host_mouse_task(), 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 181 of file usb_host_task.c.

Referenced by df_read_sector(), df_write_sector(), dfu_prog(), dfu_read(), 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 182 of file usb_host_task.c.

Referenced by usb_general_interrupt(), and usb_host_task().

U8 saved_device

Definition at line 183 of file usb_host_task.c.

Referenced by usb_host_task().