USB host enumeration functions


Data Structures

struct  S_usb_setup_data
 Usb Setup Data. More...
struct  S_usb_endpoint
struct  S_usb_interface
struct  S_usb_device
struct  S_usb_tree

Defines

#define REQUEST_TYPE_POS   0
#define REQUEST_POS   1
#define VALUE_HIGH_POS   2
#define VALUE_LOW_POS   3
#define INDEX_HIGH_POS   4
#define INDEX_LOW_POS   5
#define LENGTH_HIGH_POS   6
#define LENGTH_LOW_POS   7
#define UNCOMPLETE_READ_POS   8
#define DATA_ADDR_HIGH_POS   9
#define DATA_ADDR_LOW_POS   10
#define CONTROL_GOOD   0
#define CONTROL_DATA_TOGGLE   0x01
#define CONTROL_DATA_PID   0x02
#define CONTROL_PID   0x04
#define CONTROL_TIMEOUT   0x08
#define CONTROL_CRC16   0x10
#define CONTROL_STALL   0x20
#define CONTROL_NO_DEVICE   0x40
 Set of defines for offset in data stage.
#define OFFSET_FIELD_MAXPACKETSIZE   7
#define OFFSET_FIELD_MSB_VID   9
#define OFFSET_FIELD_LSB_VID   8
#define OFFSET_FIELD_MSB_PID   11
#define OFFSET_FIELD_LSB_PID   10
#define OFFSET_DESCRIPTOR_LENGHT   0
#define OFFSET_FIELD_DESCRIPTOR_TYPE   1
#define OFFSET_FIELD_TOTAL_LENGHT   2
#define OFFSET_FIELD_BMATTRIBUTES   7
#define OFFSET_FIELD_MAXPOWER   8
#define OFFSET_FIELD_NB_INTERFACE   4
 OFFSET for INTERFACE DESCRIPTORS.
#define OFFSET_FIELD_CLASS   5
#define OFFSET_FIELD_SUB_CLASS   6
#define OFFSET_FIELD_PROTOCOL   7
#define OFFSET_FIELD_INTERFACE_NB   2
#define OFFSET_FIELD_ALT   3
#define OFFSET_FIELS_NB_OF_EP   4
#define OFFSET_FIELD_EP_ADDR   2
#define OFFSET_FIELD_EP_TYPE   3
#define OFFSET_FIELD_EP_SIZE   4
#define OFFSET_FIELD_EP_INTERVAL   6
#define HOST_FALSE   0
#define HOST_TRUE   1
#define host_clear_endpoint_feature(ep)
 host_clear_endpoint_feature
#define host_get_configuration()
 host_get_configuration
#define host_set_configuration(cfg_nb)
 host_set_configuration
#define host_set_interface(interface_nb, alt_setting)
 host_set_interface
#define host_get_device_descriptor_uncomplete()
 host_get_device_descriptor_uncomplete
#define host_get_device_descriptor()
 host_get_device_descriptor
#define host_get_configuration_descriptor()
 host_get_configuration_descriptor
#define host_get_descriptor_uncomplete()
#define host_set_address(addr)
 host_set_address
#define host_set_feature_remote_wakeup()
 host_set_feature_remote_wakeup
#define host_ms_get_max_lun()
 host_ms_get_max_lun
#define Get_VID()   (usb_tree.device[selected_device].vid)
 Get_VID.
#define Get_PID()   (usb_tree.device[selected_device].pid)
 Get_PID.
#define Get_ep0_size()   (usb_tree.device[selected_device].ep_ctrl_size)
 Get_ep0_size.
#define Get_maxpower()   (usb_tree.device[selected_device].maxpower)
 Get_maxpower.
#define Get_class(s_interface)   (usb_tree.device[selected_device].interface[s_interface].class)
#define Get_subclass(s_interface)   (usb_tree.device[selected_device].interface[s_interface].subclass)
#define Get_protocol(s_interface)   (usb_tree.device[selected_device].interface[s_interface].protocol)
#define Get_ep_addr(s_interface, n_ep)   (usb_tree.device[selected_device].interface[s_interface].ep[n_ep].ep_addr)
#define Get_nb_ep(s_interface)   (usb_tree.device[selected_device].interface[s_interface].nb_ep)
#define Get_alts_s(s_interface)   (usb_tree.device[selected_device].interface[s_interface].altset_nb)
#define Get_interface_number(s_interface)   (usb_tree.device[selected_device].interface[s_interface].interface_nb)
#define Get_nb_supported_interface()   (usb_tree.device[selected_device].nb_interface)
#define Is_device_self_powered()   ((usb_tree.device[selected_device].bmattributes & USB_CONFIG_ATTRIBUTES_SELFPOWERED) ? TRUE : FALSE)
#define Get_nb_device()   (usb_tree.nb_device)
#define Is_device_supports_remote_wakeup()   ((usb_tree.device[selected_device].bmattributes & USB_CONFIG_ATTRIBUTES_REMOTEWAKEUP) ? TRUE : FALSE)
#define Host_select_device(i)   (host_select_device(i))
#define Host_get_nb_device()   ((U16)(usb_tree.nb_device))

Functions

U8 host_send_control (U8 *)
 host_send_control.
U8 host_check_VID_PID (void)
 host_check_VID_PID
U8 host_check_class (void)
 host_check_class
U8 host_auto_configure_endpoint ()
U8 get_interface_descriptor_offset (U8 interface, U8 alt)
 get_interface_descriptor_offset
U8 host_get_hwd_pipe_nb (U8 ep_addr)
void init_usb_tree (void)
 init_usb_tree
void remove_device_entry (U8 device_index)
 remove_device_entry
void host_select_device (U8 i)
void freeze_user_periodic_pipe (void)
void unfreeze_user_periodic_pipe (void)

Variables

U8 user_periodic_pipe
S_usb_tree usb_tree
 The main structure that represents the usb tree connected to the host controller.
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 selected_device
U8 ctrl_pipe_size

Define Documentation

#define REQUEST_TYPE_POS   0

Definition at line 134 of file usb_host_enum.h.

#define REQUEST_POS   1

Definition at line 135 of file usb_host_enum.h.

#define VALUE_HIGH_POS   2

Definition at line 136 of file usb_host_enum.h.

#define VALUE_LOW_POS   3

Definition at line 137 of file usb_host_enum.h.

#define INDEX_HIGH_POS   4

Definition at line 138 of file usb_host_enum.h.

#define INDEX_LOW_POS   5

Definition at line 139 of file usb_host_enum.h.

#define LENGTH_HIGH_POS   6

Definition at line 140 of file usb_host_enum.h.

#define LENGTH_LOW_POS   7

Definition at line 141 of file usb_host_enum.h.

#define UNCOMPLETE_READ_POS   8

Definition at line 142 of file usb_host_enum.h.

#define DATA_ADDR_HIGH_POS   9

Definition at line 143 of file usb_host_enum.h.

#define DATA_ADDR_LOW_POS   10

Definition at line 144 of file usb_host_enum.h.

#define CONTROL_GOOD   0

Definition at line 146 of file usb_host_enum.h.

Referenced by host_send_control(), and usb_host_task().

#define CONTROL_DATA_TOGGLE   0x01

Definition at line 147 of file usb_host_enum.h.

#define CONTROL_DATA_PID   0x02

Definition at line 148 of file usb_host_enum.h.

#define CONTROL_PID   0x04

Definition at line 149 of file usb_host_enum.h.

#define CONTROL_TIMEOUT   0x08

Definition at line 150 of file usb_host_enum.h.

Referenced by host_send_control().

#define CONTROL_CRC16   0x10

Definition at line 151 of file usb_host_enum.h.

#define CONTROL_STALL   0x20

Definition at line 152 of file usb_host_enum.h.

Referenced by host_send_control().

#define CONTROL_NO_DEVICE   0x40

Set of defines for offset in data stage.

Definition at line 153 of file usb_host_enum.h.

#define OFFSET_FIELD_MAXPACKETSIZE   7

Definition at line 157 of file usb_host_enum.h.

Referenced by usb_host_task().

#define OFFSET_FIELD_MSB_VID   9

Definition at line 158 of file usb_host_enum.h.

Referenced by host_check_VID_PID().

#define OFFSET_FIELD_LSB_VID   8

Definition at line 159 of file usb_host_enum.h.

Referenced by host_check_VID_PID().

#define OFFSET_FIELD_MSB_PID   11

Definition at line 160 of file usb_host_enum.h.

Referenced by host_check_VID_PID().

#define OFFSET_FIELD_LSB_PID   10

Definition at line 161 of file usb_host_enum.h.

Referenced by host_check_VID_PID().

#define OFFSET_DESCRIPTOR_LENGHT   0

Definition at line 163 of file usb_host_enum.h.

Referenced by get_interface_descriptor_offset(), and host_auto_configure_endpoint().

#define OFFSET_FIELD_DESCRIPTOR_TYPE   1

Definition at line 164 of file usb_host_enum.h.

Referenced by get_interface_descriptor_offset(), host_auto_configure_endpoint(), and host_check_class().

#define OFFSET_FIELD_TOTAL_LENGHT   2

Definition at line 165 of file usb_host_enum.h.

Referenced by host_check_class().

#define OFFSET_FIELD_BMATTRIBUTES   7

Definition at line 166 of file usb_host_enum.h.

Referenced by host_check_class().

#define OFFSET_FIELD_MAXPOWER   8

Definition at line 167 of file usb_host_enum.h.

Referenced by host_check_class().

#define OFFSET_FIELD_NB_INTERFACE   4

OFFSET for INTERFACE DESCRIPTORS.

Definition at line 172 of file usb_host_enum.h.

Referenced by get_interface_descriptor_offset().

#define OFFSET_FIELD_CLASS   5

Definition at line 173 of file usb_host_enum.h.

Referenced by host_check_class().

#define OFFSET_FIELD_SUB_CLASS   6

Definition at line 174 of file usb_host_enum.h.

Referenced by host_check_class().

#define OFFSET_FIELD_PROTOCOL   7

Definition at line 175 of file usb_host_enum.h.

Referenced by host_check_class().

#define OFFSET_FIELD_INTERFACE_NB   2

Definition at line 177 of file usb_host_enum.h.

Referenced by get_interface_descriptor_offset(), and host_check_class().

#define OFFSET_FIELD_ALT   3

Definition at line 178 of file usb_host_enum.h.

Referenced by get_interface_descriptor_offset(), and host_check_class().

#define OFFSET_FIELS_NB_OF_EP   4

Definition at line 179 of file usb_host_enum.h.

Referenced by host_check_class().

#define OFFSET_FIELD_EP_ADDR   2

Definition at line 181 of file usb_host_enum.h.

Referenced by host_auto_configure_endpoint().

#define OFFSET_FIELD_EP_TYPE   3

Definition at line 182 of file usb_host_enum.h.

Referenced by host_auto_configure_endpoint().

#define OFFSET_FIELD_EP_SIZE   4

Definition at line 183 of file usb_host_enum.h.

Referenced by host_auto_configure_endpoint().

#define OFFSET_FIELD_EP_INTERVAL   6

Definition at line 184 of file usb_host_enum.h.

Referenced by host_auto_configure_endpoint().

#define HOST_FALSE   0

Definition at line 186 of file usb_host_enum.h.

Referenced by get_interface_descriptor_offset(), host_auto_configure_endpoint(), host_check_class(), host_check_VID_PID(), host_get_data_interrupt(), host_send_data_interrupt(), and usb_host_task().

#define HOST_TRUE   1

Definition at line 187 of file usb_host_enum.h.

Referenced by host_auto_configure_endpoint(), host_check_class(), host_check_VID_PID(), host_get_data_interrupt(), host_send_data_interrupt(), and usb_host_task().

#define host_clear_endpoint_feature ( ep   ) 

Value:

host_clear_endpoint_feature

this function send a clear endpoint request

Parameters:
U8 ep (the target endpoint nb)
Returns:
status

Definition at line 200 of file usb_host_enum.h.

 
#define host_get_configuration (  ) 

Value:

host_get_configuration

this function send a get configuration request

Parameters:
none 
Returns:
status

Definition at line 216 of file usb_host_enum.h.

#define host_set_configuration ( cfg_nb   ) 

Value:

host_set_configuration

this function send a set configuration request

Parameters:
U8 configuration numer to activate
Returns:
status

Definition at line 232 of file usb_host_enum.h.

Referenced by usb_host_task().

#define host_set_interface ( interface_nb,
alt_setting   ) 

Value:

host_set_interface

this function send a set interface request to specify a specific alt setting for an interface

Parameters:
U8 interface_nb (the interface) U8 alt_setting (the alternate setting to activate)
Returns:
status

Definition at line 250 of file usb_host_enum.h.

 
#define host_get_device_descriptor_uncomplete (  ) 

Value:

host_get_device_descriptor_uncomplete

this function send a get device desriptor request. The descriptor table received is stored in data_stage array. The received descriptors is limited to the control pipe lenght

Parameters:
none 
Returns:
status

Definition at line 271 of file usb_host_enum.h.

Referenced by usb_host_task().

 
#define host_get_device_descriptor (  ) 

Value:

host_get_device_descriptor

this function send a get device desriptor request. The descriptor table received is stored in data_stage array.

Parameters:
none 
Returns:
status

Definition at line 291 of file usb_host_enum.h.

Referenced by usb_host_task().

 
#define host_get_configuration_descriptor (  ) 

Value:

host_get_configuration_descriptor

this function send a get device configuration request. The configuration descriptor table received is stored in data_stage array.

Parameters:
none 
Returns:
status

Definition at line 310 of file usb_host_enum.h.

Referenced by usb_host_task().

 
#define host_get_descriptor_uncomplete (  ) 

Value:

Definition at line 318 of file usb_host_enum.h.

#define host_set_address ( addr   ) 

Value:

host_set_address

this function send a set address request.

Parameters:
U8 address (the addr attributed to the device)
Returns:
status

Definition at line 336 of file usb_host_enum.h.

Referenced by usb_host_task().

 
#define host_set_feature_remote_wakeup (  ) 

Value:

host_set_feature_remote_wakeup

this function send a set feature device remote wakeup

Parameters:
none 
Returns:
status

Definition at line 353 of file usb_host_enum.h.

Referenced by usb_host_task().

 
#define host_ms_get_max_lun (  ) 

Value:

host_ms_get_max_lun

this function send the mass storage specific request "get max lun"

Parameters:
none 
Returns:
status

Definition at line 372 of file usb_host_enum.h.

 
#define Get_VID (  )     (usb_tree.device[selected_device].vid)

Get_VID.

this function returns the VID of the device connected

Parameters:
none 
Returns:
U16 (VID value)

Definition at line 390 of file usb_host_enum.h.

Referenced by host_check_VID_PID().

 
#define Get_PID (  )     (usb_tree.device[selected_device].pid)

Get_PID.

this function returns the PID of the device connected

Parameters:
none 
Returns:
U16 (PID value)

Definition at line 402 of file usb_host_enum.h.

Referenced by host_check_VID_PID().

 
#define Get_ep0_size (  )     (usb_tree.device[selected_device].ep_ctrl_size)

Get_ep0_size.

this function returns the size of the control endpoint for the selected device

Parameters:
none 
Returns:
U8 (EP0 size)

Definition at line 414 of file usb_host_enum.h.

 
#define Get_maxpower (  )     (usb_tree.device[selected_device].maxpower)

Get_maxpower.

this function returns the maximum power consumption ot the connected device (unit is 2mA)

Parameters:
none 
Returns:
U8 (maxpower value)

Definition at line 426 of file usb_host_enum.h.

#define Get_class ( s_interface   )     (usb_tree.device[selected_device].interface[s_interface].class)

this function returns the USB class associated to the specified interface

Parameters:
U8 s_interface: the supported interface number
Returns:
U16 (CLASS code)

Definition at line 435 of file usb_host_enum.h.

Referenced by host_template_task(), and usb_host_task().

#define Get_subclass ( s_interface   )     (usb_tree.device[selected_device].interface[s_interface].subclass)

this function returns the USB subclass associated to the specified interface

Parameters:
U8 s_interface: the supported interface number
Returns:
U16 (SUBCLASS code)

Definition at line 444 of file usb_host_enum.h.

Referenced by host_template_task(), and usb_host_task().

#define Get_protocol ( s_interface   )     (usb_tree.device[selected_device].interface[s_interface].protocol)

this function returns the USB protocol associated to the specified interface

Parameters:
U8 s_interface: the supported interface number
Returns:
U16 (protocol code)

Definition at line 453 of file usb_host_enum.h.

Referenced by host_template_task(), and usb_host_task().

#define Get_ep_addr ( s_interface,
n_ep   )     (usb_tree.device[selected_device].interface[s_interface].ep[n_ep].ep_addr)

this function returns endpoint address associated to the specified interface and endpoint number in this interface.

Parameters:
U8 s_interface: the supported interface number
U8 n_ep: the endpoint number in this interface
Returns:
U8 (endpoint address)

Definition at line 464 of file usb_host_enum.h.

Referenced by host_template_task().

#define Get_nb_ep ( s_interface   )     (usb_tree.device[selected_device].interface[s_interface].nb_ep)

this function returns number of endpoints associated to a supported interface.

Parameters:
U8 s_interface: the supported interface number
Returns:
U8 (number of enpoints)

Definition at line 474 of file usb_host_enum.h.

#define Get_alts_s ( s_interface   )     (usb_tree.device[selected_device].interface[s_interface].altset_nb)

this function returns number of the alternate setting field associated to a supported interface.

Parameters:
U8 s_interface: the supported interface number
Returns:
U8 (number of alt setting value)

Definition at line 484 of file usb_host_enum.h.

#define Get_interface_number ( s_interface   )     (usb_tree.device[selected_device].interface[s_interface].interface_nb)

this function returns number of the interface number associated to a supported interface.

Parameters:
U8 s_interface: the supported interface number
Returns:
U8 (number of the interface)

Definition at line 494 of file usb_host_enum.h.

 
#define Get_nb_supported_interface (  )     (usb_tree.device[selected_device].nb_interface)

this function returns the number of interface supported in the device connected

Parameters:
none 
Returns:
U8 : The number of interface

Definition at line 503 of file usb_host_enum.h.

Referenced by host_template_task().

 
#define Is_device_self_powered (  )     ((usb_tree.device[selected_device].bmattributes & USB_CONFIG_ATTRIBUTES_SELFPOWERED) ? TRUE : FALSE)

this function returns true if the device connected is self powered

Parameters:
none 
Returns:
U8 : The number of interface

Definition at line 512 of file usb_host_enum.h.

 
#define Get_nb_device (  )     (usb_tree.nb_device)

this function returns the number of devices connected in the USB tree

Parameters:
none 
Returns:
U8 : The number of device

Definition at line 521 of file usb_host_enum.h.

 
#define Is_device_supports_remote_wakeup (  )     ((usb_tree.device[selected_device].bmattributes & USB_CONFIG_ATTRIBUTES_REMOTEWAKEUP) ? TRUE : FALSE)

this function returns true if the device supports remote wake_up

Parameters:
none 
Returns:
U8 : The number of interface

Definition at line 530 of file usb_host_enum.h.

Referenced by usb_host_task().

#define Host_select_device ( i   )     (host_select_device(i))

Definition at line 533 of file usb_host_enum.h.

Referenced by init_usb_tree(), unfreeze_user_periodic_pipe(), and usb_host_task().

 
#define Host_get_nb_device (  )     ((U16)(usb_tree.nb_device))

Definition at line 538 of file usb_host_enum.h.


Function Documentation

U8 host_send_control ( U8 data_pointer  ) 

host_send_control.

This function is the generic Pipe 0 management function This function is used to send and receive control request over pipe 0

Todo:
Fix all timeout errors and disconnection in active wait loop
Parameters:
data_pointer 
Returns:
status
Note:
This function uses the usb_request global structure as parameter. Thus this structure should be filled before calling this function.

Definition at line 528 of file usb_host_enum.c.

References S_usb_setup_data::bmRequestType, S_usb_setup_data::bRequest, c, CONTROL_GOOD, CONTROL_STALL, CONTROL_TIMEOUT, S_usb_tree::device, S_usb_device::device_address, S_usb_device::ep_ctrl_size, EVT_HOST_SOF, FALSE, freeze_user_periodic_pipe(), Host_ack_all_errors, Host_ack_control_in, Host_ack_control_out, Host_ack_setup, Host_ack_stall, Host_configure_address, Host_data_length_U8, Host_disable_sof_interrupt, Host_enable_sof_interrupt, Host_error_status, Host_freeze_pipe, Host_read_byte, Host_reset_pipe, Host_select_pipe, Host_send_control_in, Host_send_control_out, Host_send_setup, Host_set_token_in, Host_set_token_out, Host_set_token_setup, Host_standard_in_mode, Host_unfreeze_pipe, Host_write_byte, Is_host_control_in_received, Is_host_control_out_sent, Is_host_emergency_exit, Is_host_pipe_error, Is_host_setup_sent, Is_host_sof_interrupt_enabled, Is_host_stall, Is_not_usb_event, LSB, MSB, selected_device, TRUE, S_usb_setup_data::uncomplete_read, unfreeze_user_periodic_pipe(), Usb_ack_event, USB_SETUP_DIR_DEVICE_TO_HOST, S_usb_setup_data::wIndex, S_usb_setup_data::wLength, and S_usb_setup_data::wValue.

00529 {
00530 U16 data_length;
00531 U8 sav_int_sof_enable;
00532 U8 c;
00533 U8 ep_size_max;
00534 
00535 #if (USB_HUB_SUPPORT==ENABLE && USER_PERIODIC_PIPE==ENABLE)
00536    freeze_user_periodic_pipe();
00537 #endif 
00538 
00539    ep_size_max = usb_tree.device[selected_device].ep_ctrl_size;
00540    Host_configure_address(usb_tree.device[selected_device].device_address);
00541 
00542    Usb_ack_event(EVT_HOST_SOF);
00543    sav_int_sof_enable=Is_host_sof_interrupt_enabled();
00544    Host_enable_sof_interrupt();                   // SOF software detection is in interrupt sub-routine
00545    while(Is_not_usb_event(EVT_HOST_SOF))          // Wait 1 sof
00546    {
00547       if (Is_host_emergency_exit())
00548       {
00549          c=CONTROL_TIMEOUT;
00550          Host_freeze_pipe();
00551          Host_reset_pipe(0);
00552          goto host_send_control_end;
00553       }
00554    }
00555    if (sav_int_sof_enable==FALSE)
00556    {
00557       Host_disable_sof_interrupt();
00558    }
00559 
00560    Host_select_pipe(0);
00561    Host_set_token_setup();
00562    Host_ack_setup();
00563    Host_unfreeze_pipe();
00564   // Build the setup request fields
00565    Host_write_byte(usb_request.bmRequestType);
00566    Host_write_byte(usb_request.bRequest);
00567    Host_write_byte(LSB(usb_request.wValue));
00568    Host_write_byte(MSB(usb_request.wValue));
00569    Host_write_byte(LSB(usb_request.wIndex));
00570    Host_write_byte(MSB(usb_request.wIndex));
00571    Host_write_byte(LSB(usb_request.wLength));
00572    Host_write_byte(MSB(usb_request.wLength));
00573 
00574    Host_send_setup();
00575    while(Is_host_setup_sent() == FALSE)  // wait for SETUP ack
00576    {
00577       if (Is_host_emergency_exit())
00578       {
00579          c=CONTROL_TIMEOUT;
00580          Host_freeze_pipe();
00581          Host_reset_pipe(0);
00582          goto host_send_control_end;
00583       }
00584       if(Is_host_pipe_error())           // Any error ?
00585       {
00586          c = Host_error_status();
00587          Host_ack_all_errors();
00588          goto host_send_control_end;     // Send error status
00589       }
00590    }
00591   // Setup token sent now send In or OUT token
00592   // Before just wait one SOF
00593    Usb_ack_event(EVT_HOST_SOF);
00594    sav_int_sof_enable=Is_host_sof_interrupt_enabled();
00595    Host_enable_sof_interrupt();
00596    Host_freeze_pipe();
00597    data_length = usb_request.wLength;
00598    while(Is_not_usb_event(EVT_HOST_SOF))         // Wait 1 sof
00599    {
00600       if (Is_host_emergency_exit())
00601       {
00602          c=CONTROL_TIMEOUT;
00603          Host_freeze_pipe();
00604          Host_reset_pipe(0);
00605          goto host_send_control_end;
00606       }
00607    }
00608    if (sav_int_sof_enable==FALSE)
00609    {  Host_disable_sof_interrupt();  }   // Restore SOF interrupt enable
00610 
00611   // IN request management ---------------------------------------------
00612    if(usb_request.bmRequestType & USB_SETUP_DIR_DEVICE_TO_HOST)
00613    {
00614       Host_standard_in_mode();
00615       Host_set_token_in();
00616       while(data_length != 0)
00617       {
00618          Host_unfreeze_pipe();
00619          while(!Is_host_control_in_received())
00620          {
00621             if (Is_host_emergency_exit())
00622             {
00623                c=CONTROL_TIMEOUT;
00624                Host_freeze_pipe();
00625                Host_reset_pipe(0);
00626                goto host_send_control_end;
00627             }
00628             if(Is_host_pipe_error())
00629             {
00630                c = Host_error_status();
00631                Host_ack_all_errors();
00632                goto host_send_control_end;
00633             }
00634             if(Is_host_stall())
00635             {
00636                c=CONTROL_STALL;
00637                Host_ack_stall();
00638                goto host_send_control_end;
00639             }
00640          }
00641          c = Host_data_length_U8();
00642          if (c == ep_size_max)
00643          {
00644             data_length -= c;
00645             if (usb_request.uncomplete_read == TRUE)           // uncomplete_read
00646             {
00647                data_length = 0;
00648             }
00649          }
00650          else
00651          {
00652             data_length = 0;
00653          }
00654          while (c!=0)
00655          {
00656             *data_pointer = Host_read_byte();
00657             data_pointer++;
00658             c--;
00659          }
00660          Host_freeze_pipe();
00661          Host_ack_control_in();
00662          Host_send_control_in();
00663       }                                // end of IN data stage
00664 
00665       Host_set_token_out();
00666       Host_unfreeze_pipe();
00667       Host_ack_control_out();
00668       Host_send_control_out();
00669       while(!Is_host_control_out_sent())
00670       {
00671          if (Is_host_emergency_exit())
00672          {
00673             c=CONTROL_TIMEOUT;
00674             Host_freeze_pipe();
00675             Host_reset_pipe(0);
00676             goto host_send_control_end;
00677          }
00678          if(Is_host_pipe_error())
00679          {
00680             c = Host_error_status();
00681             Host_ack_all_errors();
00682             goto host_send_control_end;
00683          }
00684          if(Is_host_stall())
00685          {
00686             c=CONTROL_STALL;
00687             Host_ack_stall();
00688             goto host_send_control_end;
00689          }
00690       }
00691       Host_ack_control_out();
00692       c=(CONTROL_GOOD);
00693       goto host_send_control_end;
00694    }
00695 
00696   // OUT request management ---------------------------------------------
00697    else                                 // Data stage OUT (bmRequestType==0)
00698    {
00699       Host_set_token_out();
00700       Host_ack_control_out();
00701       while(data_length != 0)
00702       {
00703          Host_unfreeze_pipe();
00704          c = ep_size_max;
00705          if ( ep_size_max > data_length)
00706          {
00707             c = (U8)data_length;
00708             data_length = 0;
00709          }
00710          else
00711          {
00712             data_length -= c;
00713          }
00714          while (c!=0)
00715          {
00716             Host_write_byte(*data_pointer);
00717             data_pointer++;
00718             c--;
00719          }
00720          Host_send_control_out();
00721          while (!Is_host_control_out_sent())
00722          {
00723             if (Is_host_emergency_exit())
00724             {
00725                c=CONTROL_TIMEOUT;
00726                Host_freeze_pipe();
00727                Host_reset_pipe(0);
00728                goto host_send_control_end;
00729             }
00730             if(Is_host_pipe_error())
00731             {
00732                c = Host_error_status();
00733                Host_ack_all_errors();
00734                goto host_send_control_end;
00735             }
00736             if(Is_host_stall())
00737             {
00738                c=CONTROL_STALL;
00739                Host_ack_stall();
00740                goto host_send_control_end;
00741             }
00742          }
00743          Host_ack_control_out();
00744       }                                // end of OUT data stage
00745       Host_freeze_pipe();
00746       Host_set_token_in();
00747       Host_unfreeze_pipe();
00748       while(!Is_host_control_in_received())
00749       {
00750          if (Is_host_emergency_exit())
00751          {
00752             c=CONTROL_TIMEOUT;
00753             Host_freeze_pipe();
00754             Host_reset_pipe(0);
00755             goto host_send_control_end;
00756          }
00757          if(Is_host_pipe_error())
00758          {
00759             c = Host_error_status();
00760             Host_ack_all_errors();
00761             goto host_send_control_end;
00762          }
00763          if(Is_host_stall())
00764          {
00765             c=CONTROL_STALL;
00766             Host_ack_stall();
00767             goto host_send_control_end;
00768          }
00769       }
00770       Host_ack_control_in();
00771       Host_freeze_pipe();
00772       Host_send_control_in();
00773       c=(CONTROL_GOOD);
00774       goto host_send_control_end;
00775    }
00776 host_send_control_end:
00777 #if(USB_HUB_SUPPORT==ENABLE && USER_PERIODIC_PIPE==ENABLE)
00778    unfreeze_user_periodic_pipe();
00779 #endif  
00780    return ((U8)c);
00781 }

Here is the call graph for this function:

U8 host_check_VID_PID ( void   ) 

host_check_VID_PID

This function checks if the VID and the PID are supported (if the VID/PID belongs to the VID_PID table)

Parameters:
none 
Returns:
status

Definition at line 123 of file usb_host_enum.c.

References c, data_stage, S_usb_tree::device, Get_PID, Get_VID, HOST_FALSE, HOST_TRUE, LSB, MSB, OFFSET_FIELD_LSB_PID, OFFSET_FIELD_LSB_VID, OFFSET_FIELD_MSB_PID, OFFSET_FIELD_MSB_VID, S_usb_device::pid, registered_VID_PID, selected_device, and S_usb_device::vid.

00124 {
00125 U8  c,d;
00126 
00127    // Rebuild VID PID from data stage
00128    LSB(usb_tree.device[selected_device].vid) = data_stage[OFFSET_FIELD_LSB_VID];
00129    MSB(usb_tree.device[selected_device].vid) = data_stage[OFFSET_FIELD_MSB_VID];
00130    LSB(usb_tree.device[selected_device].pid) = data_stage[OFFSET_FIELD_LSB_PID];
00131    MSB(usb_tree.device[selected_device].pid) = data_stage[OFFSET_FIELD_MSB_PID];
00132 
00133    // Compare detected VID PID with supported table
00134    c=0;
00135    while (c< sizeof(registered_VID_PID)/2)   // /2 because registered_VID_PID table is U16...
00136    {
00137       if (registered_VID_PID[c] == Get_VID())   // VID is correct
00138       {
00139          d = (U8)registered_VID_PID[c+1];    // store nb of PID for this VID
00140          while (d != 0)
00141          {
00142             if (registered_VID_PID[c+d+1] == Get_PID())
00143             {
00144                return HOST_TRUE;
00145             }
00146             d--;
00147          }
00148       }
00149       c+=registered_VID_PID[c+1]+2;
00150    }
00151    return HOST_FALSE;
00152 }

U8 host_check_class ( void   ) 

host_check_class

This function checks if the device class is supported. The function looks in all interface declared in the received dewcriptors, if one of them match with the CLASS/SUB_CLASS/PROTOCOL table

Parameters:
none 
Returns:
status

Definition at line 165 of file usb_host_enum.c.

References S_usb_interface::altset_nb, S_usb_device::bmattributes, c, S_usb_interface::class, data_stage, DESCRIPTOR_CONFIGURATION, DESCRIPTOR_INTERFACE, S_usb_tree::device, HOST_FALSE, HOST_TRUE, S_usb_device::interface, S_usb_interface::interface_nb, LSB, MAX_INTERFACE_FOR_DEVICE, S_usb_device::maxpower, MSB, S_usb_interface::nb_ep, S_usb_device::nb_interface, OFFSET_FIELD_ALT, OFFSET_FIELD_BMATTRIBUTES, OFFSET_FIELD_CLASS, OFFSET_FIELD_DESCRIPTOR_TYPE, OFFSET_FIELD_INTERFACE_NB, OFFSET_FIELD_MAXPOWER, OFFSET_FIELD_PROTOCOL, OFFSET_FIELD_SUB_CLASS, OFFSET_FIELD_TOTAL_LENGHT, OFFSET_FIELS_NB_OF_EP, S_usb_interface::protocol, registered_class, selected_device, SIZEOF_DATA_STAGE, S_usb_interface::subclass, and T_DESC_OFFSET.

00166 {
00167 U8  c;
00168 T_DESC_OFFSET  descriptor_offset;
00169 T_DESC_OFFSET  conf_offset_end;
00170 U16  config_size;
00171 U8  device_class;
00172 U8  device_subclass;
00173 U8  device_protocol;
00174 U8  nb_interface_supported;
00175 
00176 
00177    nb_interface_supported=0;   //First asumes ,no interface is supported!
00178    if (data_stage[OFFSET_FIELD_DESCRIPTOR_TYPE] != DESCRIPTOR_CONFIGURATION)           // check if configuration descriptor
00179    { return HOST_FALSE;}
00180    LSB(config_size) = data_stage[OFFSET_FIELD_TOTAL_LENGHT];
00181    MSB(config_size) = data_stage[OFFSET_FIELD_TOTAL_LENGHT+1];
00182    usb_tree.device[selected_device].bmattributes = data_stage[OFFSET_FIELD_BMATTRIBUTES];
00183    usb_tree.device[selected_device].maxpower = data_stage[OFFSET_FIELD_MAXPOWER];
00184    descriptor_offset = 0;
00185    conf_offset_end = descriptor_offset + config_size;
00186 
00187    // Look in all interfaces declared in the configuration
00188    while(descriptor_offset < conf_offset_end)
00189    {
00190       // Find next interface descriptor
00191       while (data_stage[descriptor_offset+OFFSET_FIELD_DESCRIPTOR_TYPE] != DESCRIPTOR_INTERFACE)
00192       {
00193          descriptor_offset += data_stage[descriptor_offset];
00194          if(descriptor_offset >= conf_offset_end)
00195          {
00196             if(nb_interface_supported)
00197             {
00198                return HOST_TRUE;
00199             }
00200             else return HOST_FALSE;
00201          }
00202       }
00203       // Found an interface descriptor
00204       // Get charateristics of this interface
00205       device_class    = data_stage[descriptor_offset + OFFSET_FIELD_CLASS];
00206       device_subclass = data_stage[descriptor_offset + OFFSET_FIELD_SUB_CLASS];
00207       device_protocol = data_stage[descriptor_offset + OFFSET_FIELD_PROTOCOL];
00208       // Look in registered class table for match
00209       c=0;
00210       while (c< sizeof(registered_class))
00211       {
00212          if (registered_class[c] == device_class)                 // class is correct!
00213          {
00214             if (registered_class[c+1] == device_subclass)         // sub class is correct!
00215             {
00216                if (registered_class[c+2] == device_protocol)      // protocol is correct!
00217                {
00218                   // Prepare for another item CLASS/SUB_CLASS/PROTOCOL in table
00219                   c+=3;
00220                   // Store this interface as supported interface
00221                   // Memorize its interface nb
00222                   usb_tree.device[selected_device].interface[nb_interface_supported].interface_nb=data_stage[descriptor_offset+OFFSET_FIELD_INTERFACE_NB];
00223                   //          its alternate setting
00224                   usb_tree.device[selected_device].interface[nb_interface_supported].altset_nb=data_stage[descriptor_offset+OFFSET_FIELD_ALT];
00225                   //          its USB class
00226                   usb_tree.device[selected_device].interface[nb_interface_supported].class=device_class;
00227                   //          its USB subclass
00228                   usb_tree.device[selected_device].interface[nb_interface_supported].subclass=device_subclass;
00229                   //          its USB protocol
00230                   usb_tree.device[selected_device].interface[nb_interface_supported].protocol=device_protocol;
00231                   //          the number of endpoints associated to this interface
00232                   //          Note: The associated endpoints addresses are stored during pipe attribution...
00233                   usb_tree.device[selected_device].interface[nb_interface_supported].nb_ep=data_stage[descriptor_offset+OFFSET_FIELS_NB_OF_EP];
00234                   // Update the number of interface supported
00235                   nb_interface_supported++;
00236                   // Update the number of interface supported for the device
00237                   usb_tree.device[selected_device].nb_interface++;
00238                   // Check the maximum number of interfaces we can support
00239                   if(nb_interface_supported>=MAX_INTERFACE_FOR_DEVICE)
00240                   {
00241                      return HOST_TRUE;
00242                   }
00243                }
00244             }
00245          }
00246          c+=3; // Check other item CLASS/SUB_CLASS/PROTOCOL in table
00247       }
00248       descriptor_offset += data_stage[descriptor_offset]; // Next descriptor
00249       if(descriptor_offset > SIZEOF_DATA_STAGE)           // Check overflow
00250       {
00251          if(nb_interface_supported)
00252          {
00253             return HOST_TRUE;
00254          }
00255          else return HOST_FALSE;
00256       }
00257    }
00258    if(nb_interface_supported)
00259    { 
00260       return HOST_TRUE; 
00261    }
00262    else return HOST_FALSE;
00263 }

U8 host_auto_configure_endpoint (  ) 

This function configures the pipe according to the device class of the interface selected. THe function will configure the pipe corresponding to the last device selected

Returns:
status

Definition at line 272 of file usb_host_enum.c.

References S_usb_interface::altset_nb, S_usb_interface::class, data_stage, DESCRIPTOR_ENDPOINT, S_usb_tree::device, S_usb_interface::ep, S_usb_endpoint::ep_addr, S_usb_endpoint::ep_size, S_usb_endpoint::ep_type, FALSE, get_interface_descriptor_offset(), Get_pipe_token, host_configure_pipe, host_determine_pipe_size(), Host_disable_pipe, Host_enable_pipe, HOST_FALSE, Host_get_selected_pipe, Host_select_pipe, Host_set_configured, HOST_TRUE, Host_unallocate_memory, i, S_usb_device::interface, S_usb_interface::interface_nb, Is_host_pipe_memory_allocated, MAX_EP_NB, MSK_EP_DIR, S_usb_tree::nb_device, S_usb_interface::nb_ep, S_usb_device::nb_interface, OFFSET_DESCRIPTOR_LENGHT, OFFSET_FIELD_DESCRIPTOR_TYPE, OFFSET_FIELD_EP_ADDR, OFFSET_FIELD_EP_INTERVAL, OFFSET_FIELD_EP_SIZE, OFFSET_FIELD_EP_TYPE, ONE_BANK, S_usb_endpoint::pipe_number, SIZE_8, SIZEOF_DATA_STAGE, T_DESC_OFFSET, TOKEN_IN, TWO_BANKS, TYPE_BULK, TYPE_INTERRUPT, user_periodic_pipe, and user_periodic_pipe_device_index.

00273 {
00274 U8  nb_endpoint_to_configure;
00275 T_DESC_OFFSET  descriptor_offset;
00276 U8  physical_pipe=1;   // =1 cause lookup table assumes that physical pipe 0 is reserved for control
00277 U8 i;
00278 U8 ep_index;
00279 U8 device,interface,alt_interface;
00280 U8 nb_interface;
00281 
00282    // Get the last device number to configure
00283    device = usb_tree.nb_device-1;
00284    
00285    // Get the nulber of interface to configure for the last device connected
00286    nb_interface = usb_tree.device[device].nb_interface;
00287    
00288    // Look for first physical pipe free
00289    // TODO improve allocation mechanism...
00290    i = Host_get_selected_pipe();    // Save current selected pipe
00291    for(physical_pipe=1;physical_pipe<MAX_EP_NB-1;physical_pipe++)
00292    {
00293       Host_select_pipe(physical_pipe);
00294       if(Is_host_pipe_memory_allocated()==FALSE) break; // Pipe already allocated try next one
00295    }
00296    Host_select_pipe(i); //Restore previous selected pipe
00297 
00298    // For all interfaces to configure...
00299    for(i=0;i<nb_interface;i++)
00300    {
00301       ep_index=0;
00302       // Look for the target interface descriptor offset
00303       interface = usb_tree.device[device].interface[i].interface_nb;
00304       alt_interface = usb_tree.device[device].interface[i].altset_nb;
00305       descriptor_offset = get_interface_descriptor_offset(interface,alt_interface);
00306       // Get the number of endpoint to configure for this interface
00307       nb_endpoint_to_configure = usb_tree.device[device].interface[i].nb_ep;
00308       // Get the first Endpoint descriptor offset to configure
00309       descriptor_offset += data_stage[descriptor_offset+OFFSET_DESCRIPTOR_LENGHT];  // pointing on endpoint descriptor
00310 
00311       // While there is at least one pipe to configure
00312       while (nb_endpoint_to_configure)
00313       {
00314          // Check and look for an Endpoint descriptor
00315          while (data_stage[descriptor_offset+OFFSET_FIELD_DESCRIPTOR_TYPE] != DESCRIPTOR_ENDPOINT)
00316          {
00317             descriptor_offset += data_stage[descriptor_offset];
00318             if(descriptor_offset > SIZEOF_DATA_STAGE)   // No more endpoint descriptor found -> Errror !
00319             {  return HOST_FALSE; }
00320          }
00321 #if (SAVE_INTERRUPT_PIPE_FOR_DMS_INTERFACE==ENABLE)
00322          // @TODO HUB support & INTERRUPT PIPE No validated
00323          if(data_stage[descriptor_offset+OFFSET_FIELD_EP_TYPE]==TYPE_INTERRUPT && usb_tree.device[device].interface[i].class==0x08)
00324          {
00325             nb_endpoint_to_configure--;
00326             usb_tree.device[device].interface[i].nb_ep--;
00327             continue;
00328          }
00329 #endif         
00330 
00331          // Select the new physical pipe to configure and get ride of any previous configuration for this physical pipe
00332          Host_select_pipe(physical_pipe);
00333          Host_disable_pipe();
00334          Host_unallocate_memory();
00335          Host_enable_pipe();
00336 
00337          // Build the pipe configuration according to the endpoint descriptors fields received
00338          //
00339          // host_configure_pipe(
00340          //    physical_pipe,                                                                    // pipe nb in USB interface
00341          //    data_stage[descriptor_offset+OFFSET_FIELD_EP_TYPE],                               // pipe type (interrupt/BULK/ISO)
00342          //    Get_pipe_token(data_stage[descriptor_offset+OFFSET_FIELD_EP_ADDR]),               // pipe addr
00343          //    (data_stage[descriptor_offset+2] & MSK_EP_DIR),                                   // pipe dir (IN/OUT)
00344          //    host_determine_pipe_size((U16)data_stage[descriptor_offset+OFFSET_FIELD_EP_SIZE]),// pipe size
00345          //    ONE_BANK,                                                                         // bumber of bank to allocate for pipe
00346          //    data_stage[descriptor_offset+OFFSET_FIELD_EP_INTERVAL]                            // interrupt period (for interrupt pipe)
00347          //  );
00348 
00349 #if (USB_HUB_SUPPORT==ENABLE)
00350          // For USB hub move from interupt type to bulk type
00351          if(data_stage[descriptor_offset+OFFSET_FIELD_EP_TYPE]==TYPE_INTERRUPT && usb_tree.device[device].interface[i].class==0x09)
00352          {
00353                host_configure_pipe(physical_pipe, \
00354                              TYPE_BULK, \
00355                              TOKEN_IN,  \
00356                              1,   \
00357                              SIZE_8,      \
00358                              ONE_BANK,     \
00359                              0             );  
00360          }
00361          else // The device connected is not a hub
00362          {
00363             if( nb_hub_present==0) // No hub already exist in the USB tree
00364             {
00365                host_configure_pipe(                                                          \
00366                   physical_pipe,                                                             \
00367                   data_stage[descriptor_offset+OFFSET_FIELD_EP_TYPE],                        \
00368                   Get_pipe_token(data_stage[descriptor_offset+OFFSET_FIELD_EP_ADDR]),        \
00369                   (data_stage[descriptor_offset+OFFSET_FIELD_EP_ADDR] & MSK_EP_DIR),                            \
00370                   host_determine_pipe_size((U16)data_stage[descriptor_offset+OFFSET_FIELD_EP_SIZE]),\
00371                   TWO_BANKS,                                                                  \
00372                   data_stage[descriptor_offset+OFFSET_FIELD_EP_INTERVAL]                     \
00373                );
00374             }
00375             else // At least one hub is present in the usb tree
00376             {
00377                if(data_stage[descriptor_offset+OFFSET_FIELD_EP_TYPE]==TYPE_BULK ) // If BULK type : OK
00378                {
00379                      host_configure_pipe(                                                          \
00380                      physical_pipe,                                                             \
00381                      data_stage[descriptor_offset+OFFSET_FIELD_EP_TYPE],                        \
00382                      Get_pipe_token(data_stage[descriptor_offset+OFFSET_FIELD_EP_ADDR]),        \
00383                      (data_stage[descriptor_offset+OFFSET_FIELD_EP_ADDR] & MSK_EP_DIR),                            \
00384                      host_determine_pipe_size((U16)data_stage[descriptor_offset+OFFSET_FIELD_EP_SIZE]),\
00385                      TWO_BANKS,                                                                  \
00386                      data_stage[descriptor_offset+OFFSET_FIELD_EP_INTERVAL]                     \
00387                   ); 
00388                }
00389                #if (USER_PERIODIC_PIPE==ENABLE)
00390                else
00391                if(user_periodic_pipe==0 )                  
00392                {
00393                   user_periodic_pipe=physical_pipe;
00394                   user_periodic_pipe_device_index=device;
00395                   host_configure_pipe(                                                          \
00396                      physical_pipe,                                                             \
00397                      data_stage[descriptor_offset+OFFSET_FIELD_EP_TYPE],                        \
00398                      Get_pipe_token(data_stage[descriptor_offset+OFFSET_FIELD_EP_ADDR]),        \
00399                      (data_stage[descriptor_offset+OFFSET_FIELD_EP_ADDR] & MSK_EP_DIR),                            \
00400                      host_determine_pipe_size((U16)data_stage[descriptor_offset+OFFSET_FIELD_EP_SIZE]),\
00401                      ONE_BANK,                                                                  \
00402                      data_stage[descriptor_offset+OFFSET_FIELD_EP_INTERVAL]                     \
00403                   );                  
00404                }
00405                else
00406                {
00407                   nb_endpoint_to_configure--;
00408                   usb_tree.device[device].interface[i].nb_ep--;
00409                   continue;                  
00410                }
00411                #endif
00412             }
00413          }
00414 #else // NO HUB SUPPORT
00415          host_configure_pipe(                                                          \
00416             physical_pipe,                                                             \
00417             data_stage[descriptor_offset+OFFSET_FIELD_EP_TYPE],                        \
00418             Get_pipe_token(data_stage[descriptor_offset+OFFSET_FIELD_EP_ADDR]),        \
00419             (data_stage[descriptor_offset+OFFSET_FIELD_EP_ADDR] & MSK_EP_DIR),                            \
00420             host_determine_pipe_size((U16)data_stage[descriptor_offset+OFFSET_FIELD_EP_SIZE]),\
00421             TWO_BANKS,                                                                 \
00422             data_stage[descriptor_offset+OFFSET_FIELD_EP_INTERVAL]                     \
00423          );
00424 #endif          
00425          
00426          // Update endpoint addr table in supported interface structure
00427          usb_tree.device[device].interface[i].ep[ep_index].ep_addr = data_stage[descriptor_offset+OFFSET_FIELD_EP_ADDR];
00428          // Update physical pipe number used for this endpoint
00429          usb_tree.device[device].interface[i].ep[ep_index].pipe_number = physical_pipe;
00430          // Update endpoint size in supported interface structure
00431          usb_tree.device[device].interface[i].ep[ep_index].ep_size = data_stage[descriptor_offset+OFFSET_FIELD_EP_SIZE];
00432          // Update endpoint type in supported interface structure
00433          usb_tree.device[device].interface[i].ep[ep_index].ep_type = data_stage[descriptor_offset+OFFSET_FIELD_EP_TYPE];
00434          // point on next descriptor
00435          descriptor_offset += data_stage[descriptor_offset];        
00436          // Use next physical pipe
00437          if (physical_pipe++>=MAX_EP_NB)
00438          {
00439              return HOST_FALSE;
00440          }
00441          // To configure next endpoint 
00442          ep_index++;
00443          // All target endpoints configured ?
00444          nb_endpoint_to_configure--;
00445       } //for(i=0;i<nb_interface;i++)
00446    }
00447    Host_set_configured();
00448    return HOST_TRUE;
00449 }

Here is the call graph for this function:

U8 get_interface_descriptor_offset ( U8  interface,
U8  alt 
)

get_interface_descriptor_offset

This function returns the offset in data_stage where to find the interface descriptor whose number and alternate setting values are passed as parameters

Parameters:
interface the interface nb to look for offset descriptor
alt the interface alt setting number
Returns:
T_DESC_OFFSET offset in data_stage[]

Definition at line 462 of file usb_host_enum.c.

References data_stage, DESCRIPTOR_INTERFACE, HOST_FALSE, OFFSET_DESCRIPTOR_LENGHT, OFFSET_FIELD_ALT, OFFSET_FIELD_DESCRIPTOR_TYPE, OFFSET_FIELD_INTERFACE_NB, OFFSET_FIELD_NB_INTERFACE, SIZEOF_DATA_STAGE, and T_DESC_OFFSET.

00463 {
00464    U8 nb_interface;
00465    T_DESC_OFFSET descriptor_offset;
00466 
00467    nb_interface = data_stage[OFFSET_FIELD_NB_INTERFACE];      // Detects the number of interfaces in this configuration
00468    descriptor_offset = data_stage[OFFSET_DESCRIPTOR_LENGHT];  // now pointing on next descriptor
00469 
00470    while(descriptor_offset < SIZEOF_DATA_STAGE)            // Look in all interfaces declared in the configuration
00471    {
00472       while (data_stage[descriptor_offset+OFFSET_FIELD_DESCRIPTOR_TYPE] != DESCRIPTOR_INTERFACE)
00473       {
00474          descriptor_offset += data_stage[descriptor_offset];
00475          if(descriptor_offset > SIZEOF_DATA_STAGE)
00476          {  return HOST_FALSE;  }
00477       }
00478       if (data_stage[descriptor_offset+OFFSET_FIELD_INTERFACE_NB]==interface
00479           && data_stage[descriptor_offset+OFFSET_FIELD_ALT]==alt)
00480       {
00481         return  descriptor_offset;
00482       }
00483       descriptor_offset += data_stage[descriptor_offset];
00484    }
00485    return descriptor_offset;
00486 }

U8 host_get_hwd_pipe_nb ( U8  ep_addr  ) 

This function returns the physical pipe number linked to a logical endpoint address.

Parameters:
ep_addr 
Returns:
physical_pipe_number
Note:
the function returns 0 if no ep_addr is found in the look up table.

Definition at line 498 of file usb_host_enum.c.

References S_usb_tree::device, S_usb_interface::ep, S_usb_endpoint::ep_addr, i, S_usb_device::interface, j, MAX_EP_PER_INTERFACE, MAX_INTERFACE_FOR_DEVICE, S_usb_endpoint::pipe_number, and selected_device.

00499 {
00500    U8 i,j;
00501    for(j=0;j<MAX_INTERFACE_FOR_DEVICE;j++)
00502    {
00503       for(i=0;i<MAX_EP_PER_INTERFACE;i++)
00504       {
00505          if(usb_tree.device[selected_device].interface[j].ep[i].ep_addr==ep_addr)
00506          { return usb_tree.device[selected_device].interface[j].ep[i].pipe_number; }
00507       }
00508    }
00509    return 0;
00510 }

void init_usb_tree ( void   ) 

init_usb_tree

This function initializes the usb_tree structure when no device is connected to the root downstream port

Returns:
none

Definition at line 790 of file usb_host_enum.c.

References Host_select_device, i, MAX_DEVICE_IN_USB_TREE, S_usb_tree::nb_device, remove_device_entry(), user_periodic_pipe, and user_periodic_pipe_device_index.

00791 {
00792    U8 i;
00793   
00794    // Clear all device entry
00795    for(i=0;i<MAX_DEVICE_IN_USB_TREE;i++)
00796    {
00797       remove_device_entry(i);
00798    }
00799    // By default select device 0 (connected to root port)
00800    Host_select_device(0);
00801 
00802 #if (USB_HUB_SUPPORT==ENABLE)
00803    #if (USER_PERIODIC_PIPE==ENABLE)
00804    user_periodic_pipe=0;
00805    user_periodic_pipe_device_index=0;
00806    #endif
00807    for(i=0;i<HUB_MAX_NB_PORT;i++)
00808    hub_init(i);
00809    for(i=0;i<USB_MAX_HUB_NUMBER;i++)   
00810    hub_device_address[i]=0;
00811 #endif
00812 
00813    // Clear the number of device in the tree
00814    usb_tree.nb_device=0;
00815 
00816 }

Here is the call graph for this function:

void remove_device_entry ( U8  device_index  ) 

remove_device_entry

This function reset the device entry required when a device disconnect from the usb tree

If the removed device is a hub, the function also removes the devices connected to this hub. The function is also in charge of the USB DPRAM desallocation mechanism. DPRAM is deallocated only if the removed device is the last device that allocate pipes.

Parameters:
device_index the device numer index in the usb_tree that disconnects
Returns:
none

Definition at line 831 of file usb_host_enum.c.

References S_usb_interface::altset_nb, S_usb_device::bmattributes, S_usb_interface::class, S_usb_tree::device, S_usb_device::device_address, S_usb_interface::ep, S_usb_endpoint::ep_addr, S_usb_device::ep_ctrl_size, S_usb_endpoint::ep_size, S_usb_endpoint::ep_type, Host_get_selected_pipe, Host_select_pipe, Host_unallocate_memory, HUB_CLASS, S_usb_device::hub_port_nb, i, S_usb_device::interface, S_usb_interface::interface_nb, j, MAX_DEVICE_IN_USB_TREE, MAX_EP_PER_INTERFACE, MAX_INTERFACE_FOR_DEVICE, S_usb_device::maxpower, S_usb_tree::nb_device, S_usb_interface::nb_ep, S_usb_device::nb_interface, S_usb_device::parent_hub_number, S_usb_device::pid, S_usb_endpoint::pipe_number, S_usb_interface::protocol, remove_device_entry(), S_usb_interface::subclass, and S_usb_device::vid.

00832 {
00833    U8 i,j,k,m;
00834    
00835 #if (USB_HUB_SUPPORT==ENABLE)   
00836    // Check if the disconnected device is a hub
00837    if(usb_tree.device[device_index].interface[0].class==HUB_CLASS)
00838    {
00839       nb_hub_present--; 
00840       for(i=0;i<USB_MAX_HUB_NUMBER;i++)      // For entire hub table
00841       {  // Find the hub number that deconnects
00842          if(hub_device_address[i]==usb_tree.device[device_index].device_address)
00843          {  // Reset its port state machine
00844             for(j=0;j<HUB_MAX_NB_PORT;j++)  // For all ports 
00845             {         
00846                hub_port_state[i][j]=HUB_DEVICE_POWERED; 
00847             }
00848             // Look devices previously connected to this hub and remove ther entries
00849             for(j=0;j<MAX_DEVICE_IN_USB_TREE;j++)
00850             {
00851                if(usb_tree.device[j].parent_hub_number==(i+1))
00852                {
00853                   usb_tree.nb_device--;
00854                   // Caution recursive function !!!!
00855                   remove_device_entry(j);                  
00856                }
00857             }
00858             hub_device_address[i]=0;
00859             break;
00860          }
00861       }
00862    }
00863 #endif   
00864 
00865    // Unallocate USB pipe memory only if the device disconnection is the last device 
00866    // enumerated
00867    // TODO: Improve it for devices removing from hub.
00868    // But cannot unallocate USB DPRAM if there is an active pipe number > current pipe for the removed device....
00869    if(usb_tree.nb_device==device_index+1)
00870    {
00871       for(j=0;j<MAX_INTERFACE_FOR_DEVICE;j++)
00872       {
00873          for(k=0;k<MAX_EP_PER_INTERFACE;k++)
00874          {
00875             m=usb_tree.device[device_index].interface[j].ep[k].pipe_number;
00876             if(m!=0)
00877             {
00878                i = Host_get_selected_pipe();
00879                Host_select_pipe(m);
00880                Host_unallocate_memory();
00881                Host_select_pipe(i);
00882             }
00883          }
00884       }
00885    }
00886    // Reset device entry fields ...
00887    usb_tree.device[device_index].device_address = 0;
00888    usb_tree.device[device_index].ep_ctrl_size = 0;
00889    usb_tree.device[device_index].hub_port_nb = 0;
00890    usb_tree.device[device_index].parent_hub_number = 0;
00891    usb_tree.device[device_index].nb_interface = 0;
00892    usb_tree.device[device_index].pid = 0;
00893    usb_tree.device[device_index].vid = 0;
00894    usb_tree.device[device_index].bmattributes = 0;   
00895    usb_tree.device[device_index].maxpower = 0;   
00896    
00897    for(j=0;j<MAX_INTERFACE_FOR_DEVICE;j++)
00898    {
00899       usb_tree.device[device_index].interface[j].interface_nb = 0;
00900       usb_tree.device[device_index].interface[j].altset_nb = 0;
00901       usb_tree.device[device_index].interface[j].class = 0;
00902       usb_tree.device[device_index].interface[j].subclass = 0;
00903       usb_tree.device[device_index].interface[j].protocol = 0;
00904       usb_tree.device[device_index].interface[j].nb_ep = 0;
00905       for(k=0;k<MAX_EP_PER_INTERFACE;k++)
00906       {
00907          usb_tree.device[device_index].interface[j].ep[k].ep_addr = 0;
00908          usb_tree.device[device_index].interface[j].ep[k].pipe_number = 0;
00909          usb_tree.device[device_index].interface[j].ep[k].ep_size = 0;
00910          usb_tree.device[device_index].interface[j].ep[k].ep_type = 0;
00911       }
00912    }   
00913 }

Here is the call graph for this function:

void host_select_device ( U8  i  ) 

Definition at line 952 of file usb_host_enum.c.

References S_usb_tree::device, S_usb_device::device_address, freeze_user_periodic_pipe(), Host_configure_address, and selected_device.

Here is the call graph for this function:

void freeze_user_periodic_pipe ( void   ) 

Definition at line 918 of file usb_host_enum.c.

References Host_freeze_pipe, Host_select_pipe, Is_host_pipe_freeze, user_periodic_pipe, and user_periodic_pipe_freeze_state.

00919 {
00920    if(user_periodic_pipe)
00921    {
00922       Host_select_pipe(user_periodic_pipe);
00923       if(Is_host_pipe_freeze()) 
00924       {
00925          user_periodic_pipe_freeze_state=0;
00926       }
00927       else
00928       {
00929          user_periodic_pipe_freeze_state=1;
00930          Host_freeze_pipe();
00931       }
00932    } 
00933 }

void unfreeze_user_periodic_pipe ( void   ) 

Definition at line 937 of file usb_host_enum.c.

References Host_select_device, Host_select_pipe, Host_unfreeze_pipe, user_periodic_pipe, user_periodic_pipe_device_index, and user_periodic_pipe_freeze_state.

00938 {
00939    if(user_periodic_pipe)
00940    {
00941       if(user_periodic_pipe_freeze_state)
00942       {   
00943          Host_select_pipe(user_periodic_pipe);
00944          Host_unfreeze_pipe();
00945       }
00946       Host_select_device(user_periodic_pipe_device_index);
00947    }   
00948 }


Variable Documentation

U8 user_periodic_pipe

Definition at line 100 of file usb_host_enum.c.

S_usb_tree usb_tree

The main structure that represents the usb tree connected to the host controller.

Definition at line 97 of file usb_host_enum.c.

S_usb_setup_data usb_request

For control requests management over pipe 0.

Definition at line 155 of file usb_host_task.c.

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.

Depending on the device descriptors lenght, its size can be optimized with the SIZEOF_DATA_STAGE define of conf_usb.h file

/

Definition at line 166 of file usb_host_task.c.

Referenced by get_interface_descriptor_offset(), host_auto_configure_endpoint(), host_check_class(), host_check_VID_PID(), and usb_host_task().

U8 device_status

Definition at line 168 of file usb_host_task.c.

U8 selected_device

Definition at line 107 of file usb_host_enum.c.

U8 ctrl_pipe_size


Generated on Mon Nov 3 10:08:27 2008 for ATMEL by  doxygen 1.5.3