#include "config.h"#include "conf_usb.h"#include "usb_host_hub.h"#include "modules/usb/host_chap9/usb_host_task.h"#include "modules/usb/host_chap9/usb_host_enum.h"#include "lib_mcu/usb/usb_drv.h"
Go to the source code of this file.
Defines | |
| #define | HUB_MAX_NB_PORT 4 |
Functions | |
| void | hub_init (U8 hub_number) |
| U32 | get_port_status (U8 port_number) |
| void | hub_manage_port_change_status (U8 port_change_status, U8 hub_number) |
| void | enumerate_hub_port_device (U8 hub_port, U8 port_ev, U8 hub_number) |
Variables | |
| U8 | hub_port_state [USB_MAX_HUB_NUMBER][4] |
| Enumeration state machine for each port of each hub. | |
| U8 | hub_device_address [USB_MAX_HUB_NUMBER] |
| Table to store the device address of the hub connected in the USB tree. | |
| U8 | f_hub_port_disconnect = FALSE |
| Flag to store device connection event. | |
| U8 | nb_hub_present |
| The number of hub connected in the USB tree. | |
Definition in file usb_host_hub.c.
| #define HUB_MAX_NB_PORT 4 |
Definition at line 57 of file usb_host_hub.c.
| void hub_init | ( | U8 | hub_number | ) |
This function initializes the enumeration state machines for each hub port
| U8 | hub_number |
Definition at line 88 of file usb_host_hub.c.
Referenced by enumerate_hub_port_device(), init_usb_tree(), and usb_host_task().
00089 { 00090 U8 i; 00091 00092 for(i=0;i<HUB_MAX_NB_PORT;i++) 00093 { 00094 hub_port_state[hub_number][i]=HUB_DEVICE_POWERED; 00095 } 00096 }
This function returns the status of the specified usb hub port
| U8 | port_number |
Definition at line 108 of file usb_host_hub.c.
Referenced by hub_manage_port_change_status().
00109 { 00110 U32 to_return; 00111 00112 Get_port_status(port_number); 00113 LSB3(to_return)=data_stage[3]; 00114 LSB2(to_return)=data_stage[2]; 00115 LSB1(to_return)=data_stage[1]; 00116 LSB0(to_return)=data_stage[0]; 00117 return to_return; 00118 }
This function decodes the change status repport from the hub interrupt pipe.
The function decodes hub port event and call the "enumerate_hub_port_device" function to manage the enumeration of the device connected to the hub port.
| U8 | port_change_status | |
| U8 | hub_number the number of the hub taht detects the event |
Definition at line 134 of file usb_host_hub.c.
Referenced by usb_host_task().
00135 { 00136 U8 i,c; 00137 U32 port_status; 00138 U8 port_addr_0_in_use=0; 00139 00140 // There should be one and only one device on the bus responding to device address 0 00141 // Look in the hub_port_state state machine if one device is currently using this address 00142 // If another hub is currently using address zero, the function returns imediately 00143 for(i=0;i<USB_MAX_HUB_NUMBER;i++) 00144 { 00145 for(c=1;c<=HUB_MAX_NB_PORT;c++) 00146 { 00147 if((hub_port_state[i][c-1] != HUB_DEVICE_POWERED) && (hub_port_state[i][c-1] != HUB_DEVICE_READY)) 00148 { 00149 //Found one port with one device using the address 0 00150 // memorize this port number 00151 if(i!=(hub_number-1)) 00152 { return; } //Other hub currently using address zero 00153 // ok the hub using the device address zero is the hub that currently generates the event (port_change_status) 00154 port_addr_0_in_use=c; 00155 break; 00156 } 00157 } 00158 } 00159 00160 // For all ports 00161 for(c=1;c<=HUB_MAX_NB_PORT;c++) 00162 { 00163 // One device connected to one port is using device address zero 00164 // Skip all other port activity management 00165 if((port_addr_0_in_use!=0) && (c!=port_addr_0_in_use) ) 00166 { 00167 continue; 00168 } 00169 00170 // Does this port generates port change status ? 00171 if(port_change_status & (1<<c)) 00172 { 00173 // Get port status bytes 00174 port_status=get_port_status(c); 00175 // For each port event, send this event to the function that manage the 00176 // state of the device connected to the hub port 00177 if( port_status & ((U32)1<<C_PORT_CONNECTION)) 00178 { 00179 Clear_port_feature(C_PORT_CONNECTION,c); 00180 if(port_status&((U32)1<<PORT_CONNECTION)) 00181 { 00182 // Port connection low speed -> Unsupported (no PRE token in current OTG interface implementation) 00183 if(port_status&((U32)1<<PORT_LOW_SPEED)) 00184 { 00185 00186 } 00187 else // Port Connection full speed : OK 00188 { 00189 enumerate_hub_port_device(c,HUB_PORT_CONNECTION,hub_number); 00190 } 00191 } 00192 else 00193 { 00194 // Port disconnection 00195 enumerate_hub_port_device(c,HUB_PORT_DISCONNECT,hub_number); 00196 } 00197 } 00198 else if( port_status & ((U32)1<<C_PORT_SUSPEND)) 00199 { 00200 // Port Suspend state 00201 Clear_port_feature(C_PORT_SUSPEND,c); 00202 } 00203 else if( port_status & ((U32)1<<C_PORT_RESET)) 00204 { 00205 // Port Reset sent 00206 Clear_port_feature(C_PORT_RESET,c); 00207 enumerate_hub_port_device(c,HUB_PORT_RESET,hub_number); 00208 } 00209 } 00210 00211 // Previous port using device address zero abort all port device management 00212 // (There should be one and only device with adddress zero on the USB tree) 00213 if((hub_port_state[hub_number-1][c-1] != HUB_DEVICE_POWERED) && (hub_port_state[hub_number-1][c-1] != HUB_DEVICE_READY)) 00214 { 00215 break; // Break port loop and exit from function 00216 } 00217 } 00218 }
Manage the enumeration process of the device connected to the hub port number specified
| U8 | hub_port: the usb hub downstream port number | |
| U8 | port_ev: the hub port event detected |
Definition at line 229 of file usb_host_hub.c.
Referenced by hub_manage_port_change_status().
00230 { 00231 U8 device_index=0; 00232 U8 hub_device_index=0; 00233 U8 nb_port,c; 00234 00235 // Find the device index of the hub_number 00236 for(c=0;c<MAX_DEVICE_IN_USB_TREE;c++) 00237 { 00238 if(usb_tree.device[c].device_address==hub_device_address[hub_number-1]) 00239 { 00240 hub_device_index=c; 00241 } 00242 } 00243 00244 // Find the device index in linked to the specified hub port 00245 // -> look in the usb_tree structure 00246 for(c=0;c<MAX_DEVICE_IN_USB_TREE;c++) 00247 { 00248 if((usb_tree.device[c].hub_port_nb == hub_port) && (usb_tree.device[c].parent_hub_number==hub_number)) 00249 { 00250 device_index=c; 00251 break; 00252 } 00253 } 00254 00255 // Port disconnection detected -> delete device entry and RAZ state machine 00256 // and return ... 00257 if(port_ev==HUB_PORT_DISCONNECT) 00258 { 00259 remove_device_entry(device_index); // Remove device entry in usb tree 00260 usb_tree.nb_device--; 00261 hub_port_state[hub_number-1][hub_port-1]=HUB_DEVICE_POWERED; // RAZ state machine 00262 f_hub_port_disconnect = TRUE; // Flag for device disconnection signaling 00263 return; 00264 } 00265 00266 // Device enumeration state machine for hub port 00267 switch(hub_port_state[hub_number-1][hub_port-1]) 00268 { 00269 // New device connection 00270 // -> Generate first USB reset for the device 00271 case HUB_DEVICE_POWERED: 00272 if(port_ev==HUB_PORT_CONNECTION) 00273 { 00274 device_index=usb_tree.nb_device++; 00275 usb_tree.device[device_index].hub_port_nb=hub_port; 00276 usb_tree.device[device_index].parent_hub_number=hub_number; 00277 Host_select_device(hub_device_index); 00278 Set_port_reset(hub_port); 00279 hub_port_state[hub_number-1][hub_port-1]=HUB_DEVICE_WAIT_RST_1; 00280 } 00281 break; 00282 00283 // Wait First reset successfully generated then: 00284 // -> Get device descriptor to get endpoint zero lenght 00285 // -> Generate second USB reset for the device 00286 case HUB_DEVICE_WAIT_RST_1: 00287 if(port_ev==HUB_PORT_RESET) 00288 { 00289 c = 0; 00290 while (c<250) // wait 250ms after USB reset 00291 { 00292 if (Is_usb_event(EVT_HOST_SOF)) { Usb_ack_event(EVT_HOST_SOF); c++; }// Count Start Of frame 00293 if (Is_host_emergency_exit() || Is_usb_bconnection_error_interrupt()) 00294 {hub_port_state[hub_number-1][hub_port-1]=HUB_DEVICE_POWERED; return;} 00295 } 00296 Host_select_device(device_index); 00297 // By default assumes its ctrl endpoint is 8 bytes only 00298 usb_tree.device[device_index].ep_ctrl_size=8; 00299 // Get its device descriptor to get ctrl endpoint size 00300 if( CONTROL_GOOD == host_get_device_descriptor_uncomplete()) 00301 { 00302 Host_select_device(hub_device_index); 00303 usb_tree.device[device_index].ep_ctrl_size=data_stage[OFFSET_FIELD_MAXPACKETSIZE]; 00304 Set_port_reset(hub_port); // Second USB reset 00305 hub_port_state[hub_number-1][hub_port-1]=HUB_DEVICE_WAIT_RST_2; 00306 } 00307 } 00308 break; 00309 00310 // Wait Second USB reset successfully generated then: 00311 // -> Enumerate the new device 00312 case HUB_DEVICE_WAIT_RST_2: 00313 if(port_ev==HUB_PORT_RESET) 00314 { 00315 c = 0; 00316 while (c<250) // wait 250ms after USB reset 00317 { 00318 if (Is_usb_event(EVT_HOST_SOF)) { Usb_ack_event(EVT_HOST_SOF); c++; }// Count Start Of frame 00319 if (Is_host_emergency_exit() || Is_usb_bconnection_error_interrupt()) 00320 {hub_port_state[hub_number-1][hub_port-1]=HUB_DEVICE_POWERED; return;} 00321 } 00322 // Select this new device 00323 Host_select_device(device_index); 00324 00325 // Give an absolute device address 00326 host_set_address(DEVICE_BASE_ADDRESS+device_index); 00327 usb_tree.device[+device_index].device_address=DEVICE_BASE_ADDRESS+device_index; 00328 00329 // Select this new address 00330 Host_select_device(device_index); 00331 00332 // Get the device descriptor 00333 if (CONTROL_GOOD == host_get_device_descriptor()) 00334 { 00335 // Check if the device connected belongs to the supported devices table 00336 if (HOST_TRUE == host_check_VID_PID()) 00337 { 00338 Host_set_device_supported(); 00339 Host_device_supported_action(); 00340 } 00341 else 00342 { 00343 #if (HOST_STRICT_VID_PID_TABLE==ENABLE) 00344 Host_device_not_supported_action(); 00345 return 00346 #endif 00347 } 00348 // Get Confiuration descriptor 00349 if (CONTROL_GOOD == host_get_configuration_descriptor()) 00350 { 00351 if (HOST_FALSE != host_check_class()) // Class support OK? 00352 { 00353 #if (HOST_AUTO_CFG_ENDPOINT==ENABLE) 00354 if (host_auto_configure_endpoint()) 00355 #else 00356 if(User_configure_endpoint()) // User call here instead of autoconfig 00357 #endif 00358 { 00359 if (CONTROL_GOOD == host_set_configuration(1)) // Send Set_configuration 00360 { 00361 hub_port_state[hub_number-1][hub_port-1] = HUB_DEVICE_READY; 00362 // Check if the connected device is a HUB 00363 if(Get_class(0)==HUB_CLASS ) 00364 { 00365 // Get hub descriptor 00366 if( Get_hub_descriptor()==CONTROL_GOOD) 00367 { 00368 // Power each port of the hub 00369 nb_port=data_stage[NB_PORT_OFFSET]; 00370 for(c=1;c<=nb_port;c++) 00371 { 00372 Set_port_feature(PORT_POWER,c); 00373 } 00374 nb_hub_present++; 00375 hub_init(nb_hub_present-1); 00376 hub_device_address[nb_hub_present-1]=usb_tree.device[device_index].device_address; 00377 } 00378 } 00379 else // New device is not a hub -> Signals device connection 00380 { 00381 new_device_connected=TRUE; 00382 } 00383 } 00384 } 00385 } 00386 } 00387 } 00388 } 00389 break; 00390 00391 case HUB_DEVICE_READY: 00392 break; 00393 default: 00394 break; 00395 } 00396 }
| U8 hub_port_state[USB_MAX_HUB_NUMBER][4] |
Enumeration state machine for each port of each hub.
Definition at line 68 of file usb_host_hub.c.
Referenced by enumerate_hub_port_device(), hub_init(), hub_manage_port_change_status(), and remove_device_entry().
| U8 hub_device_address[USB_MAX_HUB_NUMBER] |
Table to store the device address of the hub connected in the USB tree.
Definition at line 71 of file usb_host_hub.c.
Referenced by enumerate_hub_port_device(), init_usb_tree(), remove_device_entry(), and usb_host_task().
| U8 f_hub_port_disconnect = FALSE |
Flag to store device connection event.
Definition at line 74 of file usb_host_hub.c.
Referenced by enumerate_hub_port_device(), and usb_host_task().
The number of hub connected in the USB tree.
Definition at line 77 of file usb_host_hub.c.
Referenced by enumerate_hub_port_device(), host_auto_configure_endpoint(), remove_device_entry(), and usb_host_task().
1.5.3