Modules | |
| Host controller states | |
| Defines for device state coding. | |
Defines | |
| #define | Is_host_ready() ((device_state==DEVICE_READY) ? TRUE : FALSE) |
| #define | Is_host_not_ready() ((device_state==DEVICE_READY) ? FALSE :TRUE) |
| Returns true when the high application should not perform request to the device. | |
| #define | Is_host_suspended() (((device_state==DEVICE_WAIT_RESUME) ||(device_state==DEVICE_SUSPENDED)) ? TRUE : FALSE) |
| Check if host controller is in suspend mode. | |
| #define | Is_host_not_suspended() (((device_state==DEVICE_WAIT_RESUME) ||(device_state==DEVICE_SUSPENDED)) ? FALSE : TRUE) |
| Check if host controller is not suspend mode. | |
| #define | Is_host_unattached() ((device_state==DEVICE_UNATTACHED) ? TRUE : FALSE) |
| Check if there is an attached device connected to the host. | |
| #define | Is_host_attached() ((device_state>=DEVICE_UNATTACHED) ? TRUE : FALSE) |
| Check if there is an attached device connected to the host. | |
| #define | Host_request_suspend() (device_state=DEVICE_SUSPENDED) |
| This function should be called to make the host controller enter USB suspend mode. | |
| #define | Host_request_resume() (request_resume=TRUE) |
| This function should be called to request the host controller to resume the USB bus. | |
| #define | Host_ack_request_resume() (request_resume=FALSE) |
| Private ack for software event. | |
| #define | Host_force_enumeration() (force_enumeration=TRUE, device_state=DEVICE_ATTACHED, init_usb_tree()) |
| Force reset and (re)enumeration of the connected device. | |
| #define | Is_host_request_resume() ((request_resume==TRUE) ? TRUE : FALSE) |
| Private check for resume sequence. | |
| #define | Is_new_device_connection_event() (new_device_connected ? TRUE : FALSE) |
| Returns true when a new device is enumerated. | |
| #define | Is_device_disconnection_event() ((device_state==DEVICE_DISCONNECTED_ACK || device_state==DEVICE_DISCONNECTED || f_hub_port_disconnect) ? TRUE : FALSE) |
| Returns true when the device disconnects from the host. | |
| #define | Host_stop_pipe_interrupt(i) |
| Stop all interrupt attached to a pipe. | |
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) |
| 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)) |
| void | reset_it_pipe_str (void) |
| U8 | is_any_interrupt_pipe_active (void) |
Variables | |
| 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:
| |
| U8 | request_resume |
| U8 | new_device_connected |
| U8 | force_enumeration |
| #define Is_host_ready | ( | ) | ((device_state==DEVICE_READY) ? TRUE : FALSE) |
Returns true when device connected and correctly enumerated. The host high level application should tests this before performing any applicative requests to the device connected
Definition at line 85 of file usb_host_task.h.
Referenced by host_ms_task(), ushell_cmdusb_force_enum(), ushell_cmdusb_ls(), and ushell_cmdusb_suspend().
| #define Is_host_not_ready | ( | ) | ((device_state==DEVICE_READY) ? FALSE :TRUE) |
Returns true when the high application should not perform request to the device.
Definition at line 88 of file usb_host_task.h.
| #define Is_host_suspended | ( | ) | (((device_state==DEVICE_WAIT_RESUME) ||(device_state==DEVICE_SUSPENDED)) ? TRUE : FALSE) |
Check if host controller is in suspend mode.
Definition at line 91 of file usb_host_task.h.
Referenced by ushell_cmdusb_ls(), and ushell_cmdusb_resume().
| #define Is_host_not_suspended | ( | ) | (((device_state==DEVICE_WAIT_RESUME) ||(device_state==DEVICE_SUSPENDED)) ? FALSE : TRUE) |
| #define Is_host_unattached | ( | ) | ((device_state==DEVICE_UNATTACHED) ? TRUE : FALSE) |
Check if there is an attached device connected to the host.
Definition at line 97 of file usb_host_task.h.
| #define Is_host_attached | ( | ) | ((device_state>=DEVICE_UNATTACHED) ? TRUE : FALSE) |
Check if there is an attached device connected to the host.
Definition at line 100 of file usb_host_task.h.
| #define Host_request_suspend | ( | ) | (device_state=DEVICE_SUSPENDED) |
This function should be called to make the host controller enter USB suspend mode.
Definition at line 103 of file usb_host_task.h.
Referenced by ushell_cmdusb_suspend().
| #define Host_request_resume | ( | ) | (request_resume=TRUE) |
This function should be called to request the host controller to resume the USB bus.
Definition at line 106 of file usb_host_task.h.
Referenced by ushell_cmdusb_resume().
| #define Host_ack_request_resume | ( | ) | (request_resume=FALSE) |
Private ack for software event.
Definition at line 109 of file usb_host_task.h.
Referenced by usb_host_task().
| #define Host_force_enumeration | ( | ) | (force_enumeration=TRUE, device_state=DEVICE_ATTACHED, init_usb_tree()) |
Force reset and (re)enumeration of the connected device.
Definition at line 112 of file usb_host_task.h.
Referenced by ushell_cmdusb_force_enum().
| #define Is_host_request_resume | ( | ) | ((request_resume==TRUE) ? TRUE : FALSE) |
Private check for resume sequence.
Definition at line 115 of file usb_host_task.h.
Referenced by usb_host_task().
| #define Is_new_device_connection_event | ( | ) | (new_device_connected ? TRUE : FALSE) |
Returns true when a new device is enumerated.
Definition at line 118 of file usb_host_task.h.
Referenced by host_ms_task().
| #define Is_device_disconnection_event | ( | ) | ((device_state==DEVICE_DISCONNECTED_ACK || device_state==DEVICE_DISCONNECTED || f_hub_port_disconnect) ? TRUE : FALSE) |
Returns true when the device disconnects from the host.
Definition at line 122 of file usb_host_task.h.
Referenced by host_ms_task().
| #define Host_stop_pipe_interrupt | ( | i | ) |
Value:
(\
Host_disable_transmit_interrupt(), \
Host_disable_receive_interrupt(), \
Host_disable_stall_interrupt(), \
Host_disable_error_interrupt(), \
Host_disable_nak_interrupt(), \
Host_reset_pipe(i))
Definition at line 128 of file usb_host_task.h.
Referenced by usb_general_interrupt(), and usb_pipe_interrupt().
| void usb_host_task_init | ( | void | ) |
This function initializes the USB controller in host mode, the associated variables and interrupts enables.
This function enables the USB controller for host mode operation.
| none |
This function enables the USB controller for host mode operation.
| none |
Definition at line 194 of file usb_host_task.c.
References device_state, DEVICE_UNATTACHED, Host_enable_device_disconnection_interrupt, init_usb_tree(), Usb_attach, Usb_disable, Usb_disable_vbus_hw_control, Usb_enable, Usb_enable_uvcon_pin, Usb_select_host, Usb_unfreeze_clock, and Wait_pll_ready.
00195 { 00196 Pll_start_auto(); 00197 Wait_pll_ready(); 00198 Usb_disable(); 00199 Usb_enable(); 00200 Usb_unfreeze_clock(); 00201 Usb_attach(); 00202 Usb_enable_uvcon_pin(); 00203 Usb_select_host(); 00204 Usb_disable_vbus_hw_control(); // Force Vbus generation without timeout 00205 Host_enable_device_disconnection_interrupt(); 00206 device_state=DEVICE_UNATTACHED; 00207 init_usb_tree(); 00208 }
| void usb_host_task | ( | void | ) |
Entry point of the host management The aim is to manage the device target connection and enumeration depending on the device_state, the function performs the required operations to get the device enumerated and configured Once the device is operationnal, the device_state value is DEVICE_READY This state should be tested by the host task application before performing any applicative requests to the device. This function is called from usb_task function depending on the usb operating mode (device or host) currently selected.
| none |
| none |
Definition at line 226 of file usb_host_task.c.
References c, CONTROL_GOOD, data_stage, S_usb_tree::device, S_usb_device::device_address, DEVICE_ADDRESSED, DEVICE_ATTACHED, DEVICE_BASE_ADDRESS, DEVICE_CONFIGURED, DEVICE_DEFAULT, DEVICE_DISCONNECTED, DEVICE_DISCONNECTED_ACK, DEVICE_ERROR, DEVICE_POWERED, DEVICE_READY, device_state, DEVICE_SUSPENDED, DEVICE_UNATTACHED, DEVICE_WAIT_RESUME, S_usb_interface::ep, EP_CONTROL, S_usb_device::ep_ctrl_size, EVT_HOST_HWUP, EVT_HOST_SOF, f_hub_port_disconnect, FALSE, force_enumeration, Get_class, Get_hub_descriptor, Get_protocol, Get_subclass, Host_ack_device_connection, Host_ack_device_disconnection, Host_ack_down_stream_resume, Host_ack_hwup, Host_ack_in_received, Host_ack_nak_received, Host_ack_remote_wakeup, Host_ack_request_resume, Host_ack_reset, Host_ack_sof, host_auto_configure_endpoint(), host_check_class(), host_check_VID_PID(), Host_clear_configured, Host_clear_device_ready, Host_clear_device_supported, Host_clear_vbus_request, host_configure_pipe, Host_device_class_not_supported_action, Host_device_connection_action, Host_device_error_action, Host_device_not_supported_action, Host_device_supported_action, Host_disable_device_disconnection_interrupt, Host_disable_hwup_interrupt, Host_disable_sof, Host_disable_sof_interrupt, Host_enable_device_disconnection_interrupt, Host_enable_hwup_interrupt, Host_enable_sof, Host_enable_sof_interrupt, HOST_FALSE, Host_freeze_pipe, host_get_configuration_descriptor, host_get_device_descriptor, host_get_device_descriptor_uncomplete, Host_read_byte, Host_select_device, Host_select_pipe, Host_send_in, Host_send_reset, Host_send_resume, host_set_address, host_set_configuration, Host_set_configured, Host_set_device_ready, Host_set_device_supported, host_set_feature_remote_wakeup, Host_suspend_action, HOST_TRUE, Host_unfreeze_pipe, HUB_CLASS, hub_device_address, hub_init(), hub_interrupt_sof, hub_manage_port_change_status(), i, S_usb_device::interface, Is_device_connection, Is_device_disconnection, Is_device_supports_remote_wakeup, Is_host_down_stream_resume, Is_host_emergency_exit, Is_host_in_received, Is_host_nak_received, Is_host_request_resume, Is_host_reset, Is_host_sof_interrupt_enabled, Is_host_stall, Is_usb_bconnection_error_interrupt, Is_usb_event, Is_usb_srp_interrupt, Is_usb_vbus_error_interrupt, Is_usb_vbus_high, Is_usb_vbus_low, j, LOG_STR_CODE, MAX_DEVICE_IN_USB_TREE, S_usb_tree::nb_device, nb_hub_present, NB_PORT_OFFSET, new_device_connected, OFFSET_FIELD_MAXPACKETSIZE, ONE_BANK, PIPE_CONTROL, S_usb_endpoint::pipe_number, PORT_POWER, saved_device, selected_device, Set_port_feature, SIZE_64, Stop_pll, TOKEN_SETUP, TRUE, TYPE_CONTROL, unfreeze_user_periodic_pipe(), Usb_ack_bconnection_error_interrupt, Usb_ack_event, Usb_ack_srp_interrupt, Usb_ack_vbus_error_interrupt, Usb_clear_all_event, Usb_disable_vbus, Usb_disable_vbus_hw_control, Usb_disable_vbus_pad, Usb_enable_manual_vbus, Usb_enable_vbus, Usb_enable_vbus_hw_control, Usb_enable_vbus_pad, Usb_freeze_clock, usb_tree, Usb_unfreeze_clock, User_configure_endpoint, and Wait_pll_ready.
00227 { 00228 00229 switch (device_state) 00230 { 00231 //------------------------------------------------------ 00232 // DEVICE_UNATTACHED state 00233 // 00234 // - Default init state 00235 // - Try to give device power supply 00236 // 00237 case DEVICE_UNATTACHED: 00238 Host_clear_device_supported(); // Reset Device status 00239 Host_clear_configured(); 00240 Host_clear_device_ready(); 00241 Usb_clear_all_event(); // Clear all software events 00242 new_device_connected=FALSE; 00243 selected_device=0; 00244 00245 #if (USB_HUB_SUPPORT==ENABLE) 00246 nb_hub_present = 0; 00247 #endif 00248 00249 #if (SOFTWARE_VBUS_CTRL==ENABLE) 00250 if( Is_usb_bconnection_error_interrupt()||Is_usb_vbus_error_interrupt()) 00251 { 00252 Usb_ack_bconnection_error_interrupt(); 00253 Usb_ack_vbus_error_interrupt(); 00254 Host_clear_vbus_request(); 00255 } 00256 Usb_disable_vbus_pad(); 00257 Usb_enable_manual_vbus(); 00258 if(Is_usb_srp_interrupt()) 00259 { 00260 Usb_ack_srp_interrupt(); 00261 Usb_enable_vbus_pad(); 00262 Usb_enable_vbus(); 00263 device_state=DEVICE_ATTACHED; 00264 } 00265 #else 00266 Usb_enable_vbus(); // Give at least device power supply!!! 00267 if(Is_usb_vbus_high()) 00268 { device_state=DEVICE_ATTACHED; } // If VBUS ok goto to device connection expectation 00269 #endif 00270 break; 00271 00272 //------------------------------------------------------ 00273 // DEVICE_ATTACHED state 00274 // 00275 // - Vbus is on 00276 // - Try to detected device connection 00277 // 00278 case DEVICE_ATTACHED : 00279 if (Is_device_connection() || (force_enumeration==TRUE)) // Device pull-up detected 00280 { 00281 Host_ack_device_connection(); 00282 Host_clear_device_supported(); // Reset Device status 00283 Host_clear_configured(); 00284 Host_clear_device_ready(); 00285 Usb_clear_all_event(); // Clear all software events 00286 new_device_connected=FALSE; 00287 force_enumeration=FALSE; 00288 00289 // Now device is connected, enable disconnection interrupt 00290 Host_enable_device_disconnection_interrupt(); 00291 Enable_interrupt(); 00292 // Reset device status 00293 Host_clear_device_supported(); 00294 Host_clear_configured(); 00295 Host_clear_device_ready(); 00296 Host_enable_sof(); // Start Start Of Frame generation 00297 Host_enable_sof_interrupt(); // SOF will be detected under interrupt 00298 c = 0; 00299 while (c<100) // wait 100ms before USB reset 00300 { 00301 if (Is_usb_event(EVT_HOST_SOF)) { Usb_ack_event(EVT_HOST_SOF); c++; }// Count Start Of frame 00302 if (Is_host_emergency_exit() || Is_usb_bconnection_error_interrupt()) {goto device_attached_error;} 00303 } 00304 Host_disable_device_disconnection_interrupt(); 00305 Host_send_reset(); // First USB reset 00306 Usb_ack_event(EVT_HOST_SOF); 00307 while (Is_host_reset()); // Active wait of end of reset send 00308 Host_ack_reset(); 00309 //Workaround for some bugly devices with powerless pull up 00310 //usually low speed where data line rise slowly and can be interpretaded as disconnection 00311 for(c=0;c!=0xFFFF;c++) // Basic Timeout counter 00312 { 00313 if(Is_usb_event(EVT_HOST_SOF)) //If we detect SOF, device is still alive and connected, just clear false disconnect flag 00314 { 00315 if(Is_device_disconnection()) 00316 { 00317 Host_ack_device_connection(); 00318 Host_ack_device_disconnection(); 00319 break; 00320 } 00321 } 00322 } 00323 Host_enable_device_disconnection_interrupt(); 00324 // All USB pipes must be reconfigured after a USB reset generation 00325 host_configure_pipe(PIPE_CONTROL, \ 00326 TYPE_CONTROL, \ 00327 TOKEN_SETUP, \ 00328 EP_CONTROL, \ 00329 SIZE_64, \ 00330 ONE_BANK, \ 00331 0 ); 00332 c = 0; 00333 while (c<100) // wait 100ms after USB reset 00334 { 00335 if (Is_usb_event(EVT_HOST_SOF)) { Usb_ack_event(EVT_HOST_SOF); c++; }// Count Start Of frame 00336 if (Is_host_emergency_exit() || Is_usb_bconnection_error_interrupt()) {goto device_attached_error;} 00337 } 00338 device_state = DEVICE_POWERED; 00339 c=0; 00340 } 00341 device_attached_error: 00342 // Device connection error, or vbus pb -> Retry the connection process from the begining 00343 if( Is_usb_bconnection_error_interrupt()||Is_usb_vbus_error_interrupt()||Is_usb_vbus_low()) 00344 { 00345 Usb_ack_bconnection_error_interrupt(); 00346 Usb_enable_vbus_hw_control(); 00347 device_state=DEVICE_UNATTACHED; 00348 Usb_disable_vbus(); 00349 Usb_disable_vbus_pad(); 00350 Usb_enable_vbus_pad(); 00351 Usb_ack_vbus_error_interrupt(); 00352 Usb_enable_vbus(); 00353 Usb_disable_vbus_hw_control(); 00354 Host_disable_sof(); 00355 } 00356 break; 00357 00358 //------------------------------------------------------ 00359 // DEVICE_POWERED state 00360 // 00361 // - Device connection (attach) as been detected, 00362 // - Wait 100ms and configure default control pipe 00363 // 00364 case DEVICE_POWERED : 00365 LOG_STR_CODE(log_device_connected); 00366 Host_device_connection_action(); 00367 if (Is_usb_event(EVT_HOST_SOF)) 00368 { 00369 Usb_ack_event(EVT_HOST_SOF); 00370 if (c++ >= 100) // Wait 100ms 00371 { 00372 device_state = DEVICE_DEFAULT; 00373 } 00374 } 00375 break; 00376 00377 //------------------------------------------------------ 00378 // DEVICE_DEFAULT state 00379 // 00380 // - Get device descriptor 00381 // - Reconfigure Pipe 0 according to Device EP0 00382 // - Attribute device address 00383 // 00384 case DEVICE_DEFAULT : 00385 // Get first device descriptor 00386 Host_select_device(0); 00387 usb_tree.device[0].ep_ctrl_size=8; 00388 if( CONTROL_GOOD == host_get_device_descriptor_uncomplete()) 00389 { 00390 c = 0; 00391 while(c<20) // wait 20ms before USB reset (special buggly devices...) 00392 { 00393 if (Is_usb_event(EVT_HOST_SOF)) { Usb_ack_event(EVT_HOST_SOF); c++; } 00394 if (Is_host_emergency_exit() || Is_usb_bconnection_error_interrupt()) {break;} 00395 } 00396 Host_disable_device_disconnection_interrupt(); 00397 Host_send_reset(); // First USB reset 00398 Usb_ack_event(EVT_HOST_SOF); 00399 while (Is_host_reset()); // Active wait of end of reset send 00400 Host_ack_reset(); 00401 //Workaround for some bugly devices with powerless pull up 00402 //usually low speed where data line rise slowly and can be interpretaded as disconnection 00403 for(c=0;c!=0xFFFF;c++) // Basic Timeout counter 00404 { 00405 if(Is_usb_event(EVT_HOST_SOF)) //If we detect SOF, device is still alive and connected, just clear false disconnect flag 00406 { 00407 if(Is_device_disconnection()) 00408 { 00409 Host_ack_device_connection(); 00410 Host_ack_device_disconnection(); 00411 break; 00412 } 00413 } 00414 } 00415 Host_enable_device_disconnection_interrupt(); 00416 c = 0; 00417 host_configure_pipe(PIPE_CONTROL, \ 00418 TYPE_CONTROL, \ 00419 TOKEN_SETUP, \ 00420 EP_CONTROL, \ 00421 SIZE_64, \ 00422 ONE_BANK, \ 00423 0 ); 00424 while(c<200) // wait 200ms after USB reset 00425 { 00426 if (Is_usb_event(EVT_HOST_SOF)) { Usb_ack_event(EVT_HOST_SOF); c++; } 00427 if (Is_host_emergency_exit() || Is_usb_bconnection_error_interrupt()) {break;} 00428 } 00429 usb_tree.device[0].ep_ctrl_size=data_stage[OFFSET_FIELD_MAXPACKETSIZE]; 00430 00431 // Give an absolute device address 00432 host_set_address(DEVICE_BASE_ADDRESS); 00433 usb_tree.device[0].device_address=DEVICE_BASE_ADDRESS; 00434 device_state = DEVICE_ADDRESSED; 00435 } 00436 else 00437 { device_state = DEVICE_ERROR; } 00438 break; 00439 00440 //------------------------------------------------------ 00441 // DEVICE_BASE_ADDRESSED state 00442 // 00443 // - Check if VID PID is in supported list 00444 // 00445 case DEVICE_ADDRESSED : 00446 if (CONTROL_GOOD == host_get_device_descriptor()) 00447 { 00448 // Detect if the device connected belongs to the supported devices table 00449 if (HOST_TRUE == host_check_VID_PID()) 00450 { 00451 Host_set_device_supported(); 00452 Host_device_supported_action(); 00453 device_state = DEVICE_CONFIGURED; 00454 } 00455 else 00456 { 00457 #if (HOST_STRICT_VID_PID_TABLE==ENABLE) 00458 Host_device_not_supported_action(); 00459 device_state = DEVICE_ERROR; 00460 #else 00461 device_state = DEVICE_CONFIGURED; 00462 #endif 00463 } 00464 } 00465 else // Can not get device descriptor 00466 { device_state = DEVICE_ERROR; } 00467 break; 00468 00469 //------------------------------------------------------ 00470 // DEVICE_CONFIGURED state 00471 // 00472 // - Configure pipes for the supported interface 00473 // - Send Set_configuration() request 00474 // - Goto full operating mode (device ready) 00475 // 00476 case DEVICE_CONFIGURED : 00477 if (CONTROL_GOOD == host_get_configuration_descriptor()) 00478 { 00479 if (HOST_FALSE != host_check_class()) // Class support OK? 00480 { 00481 usb_tree.nb_device++; 00482 #if (HOST_AUTO_CFG_ENDPOINT==ENABLE) 00483 if(host_auto_configure_endpoint()) 00484 #else 00485 Host_set_configured(); // Assumes config is OK with user config 00486 if(User_configure_endpoint()) // User call here instead of autoconfig 00487 #endif 00488 { 00489 if (CONTROL_GOOD== host_set_configuration(1)) // Send Set_configuration 00490 { 00491 //host_set_interface(interface_bound,interface_bound_alt_set); 00492 // device and host are now fully configured 00493 // goto DEVICE READY normal operation 00494 device_state = DEVICE_READY; 00495 Host_set_device_ready(); 00496 // monitor device disconnection under interrupt 00497 Host_enable_device_disconnection_interrupt(); 00498 // If user host application requires SOF interrupt event 00499 // Keep SOF interrupt enable otherwize, disable this interrupt 00500 #if (HOST_CONTINUOUS_SOF_INTERRUPT==DISABLE && USB_HUB_SUPPORT==DISABLE) 00501 Host_disable_sof_interrupt(); 00502 #endif 00503 #if (USB_HUB_SUPPORT==ENABLE) 00504 // Check if the connected device is a hub 00505 if(Get_class(0)==HUB_CLASS && Get_subclass(0)==0x00 && Get_protocol(0)==0x00) 00506 { 00507 // Get hub descriptor 00508 if( Get_hub_descriptor()==CONTROL_GOOD) 00509 { 00510 // Power each port of the hub 00511 i=data_stage[NB_PORT_OFFSET]; 00512 for(c=1;c<=i;c++) 00513 { 00514 Set_port_feature(PORT_POWER,c); 00515 } 00516 nb_hub_present = 1; 00517 hub_device_address[0]=DEVICE_BASE_ADDRESS; 00518 hub_init(nb_hub_present-1); 00519 } 00520 } 00521 else 00522 { 00523 nb_hub_present = 0; 00524 new_device_connected=TRUE; 00525 } 00526 #else 00527 new_device_connected=TRUE; 00528 #endif 00529 00530 Enable_interrupt(); 00531 LOG_STR_CODE(log_device_enumerated); 00532 } 00533 else// Problem during Set_configuration request... 00534 { device_state = DEVICE_ERROR; } 00535 } 00536 } 00537 else // device class not supported... 00538 { 00539 device_state = DEVICE_ERROR; 00540 LOG_STR_CODE(log_device_unsupported); 00541 Host_device_class_not_supported_action(); 00542 } 00543 } 00544 else // Can not get configuration descriptors... 00545 { device_state = DEVICE_ERROR; } 00546 break; 00547 00548 //------------------------------------------------------ 00549 // DEVICE_READY state 00550 // 00551 // - Full std operatinf mode 00552 // - Nothing to do... 00553 // 00554 case DEVICE_READY: // Host full std operating mode! 00555 new_device_connected=FALSE; 00556 00557 #if (USB_HUB_SUPPORT==ENABLE) 00558 f_hub_port_disconnect=FALSE; 00559 // If one hub is present in the USB tree and the period interval 00560 // for the interrupt hub endpoint occurs 00561 if(nb_hub_present && hub_interrupt_sof==0) 00562 { 00563 saved_device=selected_device; // Backup user selected device 00564 for(j=1;j<=nb_hub_present;j++) 00565 { 00566 for(i=0;i<MAX_DEVICE_IN_USB_TREE;i++) 00567 { 00568 if(usb_tree.device[i].device_address==hub_device_address[j-1]) break; 00569 } 00570 Host_select_device(i); 00571 Host_select_pipe(usb_tree.device[i].interface[0].ep[0].pipe_number); 00572 Host_ack_nak_received(); 00573 Host_ack_in_received(); 00574 Host_unfreeze_pipe(); 00575 Host_send_in(); 00576 while(1) 00577 { 00578 if(Is_host_nak_received()) break; 00579 if(Is_host_emergency_exit()) break; 00580 if(Is_host_in_received()) break; 00581 } 00582 Host_freeze_pipe(); 00583 if(Is_host_nak_received()) 00584 { 00585 Host_ack_nak_received(); 00586 } 00587 if(Is_host_in_received()) 00588 { 00589 if(Is_host_stall()==FALSE) 00590 { 00591 c=Host_read_byte(); 00592 } 00593 Host_ack_in_received(); 00594 hub_manage_port_change_status(c,j); 00595 } 00596 } // for all hub 00597 Host_select_device(saved_device); // Restore user selected device 00598 #if (USER_PERIODIC_PIPE==ENABLE) 00599 unfreeze_user_periodic_pipe(); 00600 #endif 00601 } 00602 #endif 00603 break; 00604 00605 //------------------------------------------------------ 00606 // DEVICE_ERROR state 00607 // 00608 // - Error state 00609 // - Do custom action call (probably go to default mode...) 00610 // 00611 case DEVICE_ERROR : // TODO !!!! 00612 #if (HOST_ERROR_RESTART==ENABLE) 00613 device_state=DEVICE_UNATTACHED; 00614 #endif 00615 Host_device_error_action(); 00616 break; 00617 00618 //------------------------------------------------------ 00619 // DEVICE_SUSPENDED state 00620 // 00621 // - Host application request to suspend the device activity 00622 // - State machine comes here thanks to Host_request_suspend() 00623 // 00624 case DEVICE_SUSPENDED : 00625 if(Is_device_supports_remote_wakeup()) // If the connected device supports remote wake up 00626 { 00627 host_set_feature_remote_wakeup(); // Enable this feature... 00628 } 00629 LOG_STR_CODE(log_going_to_suspend); 00630 c = Is_host_sof_interrupt_enabled(); //Save current sof interrupt enable state 00631 Host_disable_sof_interrupt(); 00632 Host_ack_sof(); 00633 Host_disable_sof(); // Stop start of frame generation, this generates the suspend state 00634 Host_ack_hwup(); 00635 Host_enable_hwup_interrupt(); // Enable host wake-up interrupt 00636 // (this is the unique USB interrupt able to wake up the CPU core from power-down mode) 00637 Usb_freeze_clock(); 00638 Stop_pll(); 00639 Host_suspend_action(); // Custom action here! (for example go to power-save mode...) 00640 device_state=DEVICE_WAIT_RESUME; // wait for device resume event 00641 break; 00642 00643 //------------------------------------------------------ 00644 // DEVICE_WAIT_RESUME state 00645 // 00646 // - Wait in this state till the host receives an upstream resume from the device 00647 // - or the host software request the device to resume 00648 // 00649 case DEVICE_WAIT_RESUME : 00650 if(Is_usb_event(EVT_HOST_HWUP)|| Is_host_request_resume())// Remote wake up has been detected 00651 // or Local resume request has been received 00652 { 00653 if(Is_host_request_resume()) // Not a remote wakeup, but an host application request 00654 { 00655 Host_disable_hwup_interrupt(); // Wake up interrupt should be disable host is now wake up ! 00656 // CAUTION HWUP can be cleared only when USB clock is active 00657 Pll_start_auto(); // First Restart the PLL for USB operation 00658 Wait_pll_ready(); // Get sure pll is lock 00659 Usb_unfreeze_clock(); // Enable clock on USB interface 00660 Host_ack_hwup(); // Clear HWUP interrupt flag 00661 } 00662 Host_enable_sof(); 00663 Host_send_resume(); // Send down stream resume 00664 while (Is_host_down_stream_resume()==FALSE); // Wait Down stream resume sent 00665 Host_ack_remote_wakeup(); // Ack remote wake-up reception 00666 Host_ack_request_resume(); // Ack software request 00667 Host_ack_down_stream_resume(); // Ack down stream resume sent 00668 Usb_ack_event(EVT_HOST_HWUP); // Ack software event 00669 if(c) { Host_enable_sof_interrupt(); } // Restore SOF interrupt enable state before suspend 00670 device_state=DEVICE_READY; // Come back to full operating mode 00671 LOG_STR_CODE(log_usb_resumed); 00672 } 00673 break; 00674 00675 //------------------------------------------------------ 00676 // DEVICE_DISCONNECTED state 00677 // 00678 // - Device disconnection has been detected 00679 // - Run scheduler in this state at least two times to get sure event is detected by all host application tasks 00680 // - Go to DEVICE_DISCONNECTED_ACK state before DEVICE_UNATTACHED, to get sure scheduler calls all app tasks... 00681 // 00682 case DEVICE_DISCONNECTED : 00683 device_state = DEVICE_DISCONNECTED_ACK; 00684 break; 00685 00686 //------------------------------------------------------ 00687 // DEVICE_DISCONNECTED_ACK state 00688 // 00689 // - Device disconnection has been detected and managed bu applicatives tasks 00690 // - Go to DEVICE_UNATTACHED state 00691 // 00692 case DEVICE_DISCONNECTED_ACK : 00693 device_state = DEVICE_UNATTACHED; 00694 break; 00695 00696 //------------------------------------------------------ 00697 // default state 00698 // 00699 // - Default case: ERROR 00700 // - Goto no device state 00701 // 00702 default : 00703 device_state = DEVICE_UNATTACHED; 00704 break; 00705 } 00706 }
This function send nb_data pointed with *buf with the pipe number specified
| pipe | ||
| nb_data | ||
| buf |
| pipe | ||
| nb_data | ||
| buf |
Definition at line 722 of file usb_host_task.c.
References c, EVT_HOST_SOF, FALSE, freeze_user_periodic_pipe(), Host_ack_all_errors, Host_ack_nak_received, Host_ack_out_sent, Host_ack_stall, Host_disable_sof_interrupt, Host_enable_sof_interrupt, Host_error_status, Host_freeze_pipe, Host_get_pipe_length, Host_number_of_busy_bank, Host_reset_pipe, Host_select_pipe, Host_send_out, Host_set_token_out, Host_unfreeze_pipe, Host_write_byte, Is_host_emergency_exit, Is_host_nak_received, Is_host_out_sent, Is_host_pipe_error, Is_host_sof_interrupt_enabled, Is_host_stall, Is_usb_event, NAK_SEND_TIMEOUT, PIPE_DELAY_TIMEOUT, PIPE_GOOD, PIPE_NAK_TIMEOUT, PIPE_STALL, PIPE_TIMEOUT, private_sof_counter, TIMEOUT_DELAY, unfreeze_user_periodic_pipe(), and Usb_ack_event.
00723 { 00724 U8 c; 00725 U8 status=PIPE_GOOD; 00726 U8 sav_int_sof_enable; 00727 U8 nak_timeout; 00728 U16 cpt_nak; 00729 U8 nb_data_loaded; 00730 U8 cpt_err_timeout=0; 00731 00732 #if (USER_PERIODIC_PIPE==ENABLE) 00733 freeze_user_periodic_pipe(); 00734 #endif 00735 sav_int_sof_enable=Is_host_sof_interrupt_enabled(); // Save state of enable sof interrupt 00736 Host_enable_sof_interrupt(); 00737 Host_select_pipe(pipe); 00738 Host_set_token_out(); 00739 Host_ack_out_sent(); 00740 Host_unfreeze_pipe(); 00741 00742 while (nb_data != 0) // While there is something to send... 00743 { 00744 // Prepare data to be sent 00745 c = Host_get_pipe_length(); 00746 if ( (U16)c > nb_data) 00747 { 00748 nb_data_loaded = (U8)nb_data; 00749 c = nb_data; 00750 } 00751 else 00752 { nb_data_loaded = c; } 00753 while (c!=0) // Load Pipe buffer 00754 { 00755 Host_write_byte(*buf++); 00756 c--; 00757 } 00758 private_sof_counter=0; // Reset the counter in SOF detection sub-routine 00759 cpt_nak=0; 00760 nak_timeout=0; 00761 Host_ack_out_sent(); 00762 Host_send_out(); 00763 while (!Is_host_out_sent()) 00764 { 00765 if (Is_host_emergency_exit())// Async disconnection or role change detected under interrupt 00766 { 00767 status=PIPE_DELAY_TIMEOUT; 00768 Host_reset_pipe(pipe); 00769 goto host_send_data_end; 00770 } 00771 #if (TIMEOUT_DELAY_ENABLE==ENABLE) 00772 if (private_sof_counter>=250) // Count 250ms (250sof) 00773 { 00774 private_sof_counter=0; 00775 if (nak_timeout++>=TIMEOUT_DELAY) // Inc timeout and check for overflow 00776 { 00777 status=PIPE_DELAY_TIMEOUT; 00778 Host_reset_pipe(pipe); 00779 goto host_send_data_end; 00780 } 00781 } 00782 #endif 00783 if (Is_host_pipe_error()) // Any error ? 00784 { 00785 status = Host_error_status(); 00786 Host_ack_all_errors(); 00787 if(status == PIPE_TIMEOUT) 00788 { 00789 if(cpt_err_timeout++>100) 00790 { 00791 goto host_send_data_end; 00792 } 00793 else 00794 { 00795 c=0; 00796 while(c<2) // wait 2 ms 00797 { 00798 if (Is_usb_event(EVT_HOST_SOF)) { Usb_ack_event(EVT_HOST_SOF); c++; } 00799 if (Is_host_emergency_exit() ) {break;} 00800 } 00801 00802 Host_unfreeze_pipe(); 00803 } 00804 } 00805 } 00806 if (Is_host_stall()) // Stall management 00807 { 00808 status =PIPE_STALL; 00809 Host_ack_stall(); 00810 goto host_send_data_end; 00811 } 00812 #if (NAK_TIMEOUT_ENABLE==ENABLE) 00813 if(Is_host_nak_received()) //NAK received 00814 { 00815 Host_ack_nak_received(); 00816 if (cpt_nak++>NAK_SEND_TIMEOUT) 00817 { 00818 status = PIPE_NAK_TIMEOUT; 00819 Host_reset_pipe(pipe); 00820 goto host_send_data_end; 00821 } 00822 } 00823 #endif 00824 } 00825 // Here OUT sent 00826 nb_data -= nb_data_loaded; 00827 status=PIPE_GOOD; // Frame correctly sent 00828 Host_ack_out_sent(); 00829 } 00830 while(0!=Host_number_of_busy_bank()); 00831 00832 host_send_data_end: 00833 Host_freeze_pipe(); 00834 // Restore sof interrupt enable state 00835 if (sav_int_sof_enable==FALSE) {Host_disable_sof_interrupt();} 00836 #if (USER_PERIODIC_PIPE==ENABLE) 00837 unfreeze_user_periodic_pipe(); 00838 #endif 00839 // And return... 00840 return ((U8)status); 00841 }
This function receives nb_data pointed with *buf with the pipe number specified The nb_data parameter is passed as a U16 pointer, thus the data pointed by this pointer is updated with the final number of data byte received.
| pipe | ||
| nb_data | ||
| buf |
| pipe | ||
| nb_data | ||
| buf |
Definition at line 857 of file usb_host_task.c.
References FALSE, freeze_user_periodic_pipe(), Host_ack_all_errors, Host_ack_in_received, Host_ack_nak_received, Host_ack_stall, Host_byte_counter, Host_continuous_in_mode, Host_disable_sof_interrupt, Host_enable_sof_interrupt, Host_error_status, Host_freeze_pipe, Host_get_pipe_length, Host_read_byte, Host_reset_pipe, Host_select_pipe, Host_send_in, Host_set_token_in, Host_unfreeze_pipe, i, Is_host_emergency_exit, Is_host_in_received, Is_host_nak_received, Is_host_pipe_error, Is_host_sof_interrupt_enabled, Is_host_stall, NAK_RECEIVE_TIMEOUT, NULL, PIPE_DELAY_TIMEOUT, PIPE_GOOD, PIPE_NAK_TIMEOUT, PIPE_STALL, private_sof_counter, TIMEOUT_DELAY, and unfreeze_user_periodic_pipe().
00858 { 00859 U8 status=PIPE_GOOD; 00860 U8 sav_int_sof_enable; 00861 U8 nak_timeout; 00862 U16 n,i; 00863 U16 cpt_nak; 00864 00865 #if (USER_PERIODIC_PIPE==ENABLE) 00866 freeze_user_periodic_pipe(); 00867 #endif 00868 n=*nb_data; 00869 *nb_data=0; 00870 sav_int_sof_enable=Is_host_sof_interrupt_enabled(); 00871 Host_enable_sof_interrupt(); 00872 Host_select_pipe(pipe); 00873 Host_continuous_in_mode(); 00874 Host_set_token_in(); 00875 Host_ack_in_received(); 00876 while (n) // While missing data... 00877 { 00878 Host_unfreeze_pipe(); 00879 Host_send_in(); 00880 private_sof_counter=0; // Reset the counter in SOF detection sub-routine 00881 nak_timeout=0; 00882 cpt_nak=0; 00883 while (!Is_host_in_received()) 00884 { 00885 if (Is_host_emergency_exit()) // Async disconnection or role change detected under interrupt 00886 { 00887 status=PIPE_DELAY_TIMEOUT; 00888 Host_reset_pipe(pipe); 00889 goto host_get_data_end; 00890 } 00891 #if (TIMEOUT_DELAY_ENABLE==ENABLE) 00892 if (private_sof_counter>=250) // Timeout management 00893 { 00894 private_sof_counter=0; // Done in host SOF interrupt 00895 if (nak_timeout++>=TIMEOUT_DELAY)// Check for local timeout 00896 { 00897 status=PIPE_DELAY_TIMEOUT; 00898 Host_reset_pipe(pipe); 00899 goto host_get_data_end; 00900 } 00901 } 00902 #endif 00903 if(Is_host_pipe_error()) // Error management 00904 { 00905 status = Host_error_status(); 00906 Host_ack_all_errors(); 00907 goto host_get_data_end; 00908 } 00909 if(Is_host_stall()) // STALL management 00910 { 00911 if( Is_host_in_received() ) 00912 break; 00913 status =PIPE_STALL; 00914 Host_reset_pipe(pipe); 00915 Host_ack_stall(); 00916 goto host_get_data_end; 00917 } 00918 #if (NAK_TIMEOUT_ENABLE==ENABLE) 00919 if(Is_host_nak_received()) //NAK received 00920 { 00921 Host_ack_nak_received(); 00922 if (cpt_nak++>NAK_RECEIVE_TIMEOUT) 00923 { 00924 status = PIPE_NAK_TIMEOUT; 00925 Host_reset_pipe(pipe); 00926 goto host_get_data_end; 00927 } 00928 } 00929 #endif 00930 } 00931 status=PIPE_GOOD; 00932 Host_freeze_pipe(); 00933 if (Host_byte_counter()<=n) 00934 { 00935 if ((Host_byte_counter() < n)&&(Host_byte_counter()<Host_get_pipe_length())) 00936 { n=0;} 00937 else 00938 { n-=Host_byte_counter();} 00939 (*nb_data)+=Host_byte_counter(); // Update nb of byte received 00940 if( NULL != buf ) 00941 { 00942 for (i=Host_byte_counter();i;i--) 00943 { *buf=Host_read_byte(); buf++;} 00944 } 00945 } 00946 else // more bytes received than expected 00947 { // TODO error code management 00948 *nb_data+=n; 00949 if( NULL != buf ) 00950 { 00951 for (i=n;i;i--) // Byte number limited to the initial request (limit tab over pb) 00952 { *buf=Host_read_byte(); buf++; } 00953 } 00954 n=0; 00955 } 00956 Host_ack_in_received(); 00957 } 00958 Host_freeze_pipe(); 00959 host_get_data_end: 00960 if (sav_int_sof_enable==FALSE) 00961 { 00962 Host_disable_sof_interrupt(); 00963 } 00964 #if (USER_PERIODIC_PIPE==ENABLE) 00965 unfreeze_user_periodic_pipe(); 00966 #endif 00967 return ((U8)status); 00968 }
| U8 host_get_data_interrupt | ( | U8 | pipe, | |
| U16 | nb_data, | |||
| U8 * | buf, | |||
| void(*)(U8 status, U16 nb_byte) | handle | |||
| ) |
This function receives nb_data pointed with *buf with the pipe number specified The nb_data parameter is passed as a U16 pointer, thus the data pointed by this pointer is updated with the final number of data byte received.
| pipe | ||
| nb_data | ||
| buf | ||
| handle | call back function pointer |
Definition at line 1008 of file usb_host_task.c.
References S_pipe_int::enable, ENABLE, FALSE, g_sav_int_sof_enable, S_pipe_int::handle, Host_ack_in_received, Host_ack_nak_received, Host_ack_stall, Host_continuous_in_mode, Host_enable_error_interrupt, Host_enable_nak_interrupt, Host_enable_receive_interrupt, Host_enable_sof_interrupt, Host_enable_stall_interrupt, HOST_FALSE, Host_reset_pipe, Host_select_pipe, Host_set_token_in, HOST_TRUE, Host_unfreeze_pipe, is_any_interrupt_pipe_active(), Is_host_sof_interrupt_enabled, NAK_RECEIVE_TIMEOUT, S_pipe_int::nak_timeout, S_pipe_int::nb_byte_processed, S_pipe_int::nb_byte_to_process, private_sof_counter, S_pipe_int::ptr_buf, and S_pipe_int::timeout.
01009 { 01010 Host_select_pipe(pipe); 01011 if(it_pipe_str[pipe].enable==ENABLE) 01012 { 01013 return HOST_FALSE; 01014 } 01015 else 01016 { 01017 if(is_any_interrupt_pipe_active()==FALSE) 01018 { 01019 g_sav_int_sof_enable=Is_host_sof_interrupt_enabled(); 01020 Host_enable_sof_interrupt(); 01021 } 01022 it_pipe_str[pipe].enable=ENABLE; 01023 it_pipe_str[pipe].nb_byte_to_process=nb_data; 01024 it_pipe_str[pipe].nb_byte_processed=0; 01025 it_pipe_str[pipe].ptr_buf=buf; 01026 it_pipe_str[pipe].handle=handle; 01027 it_pipe_str[pipe].timeout=0; 01028 it_pipe_str[pipe].nak_timeout=NAK_RECEIVE_TIMEOUT; 01029 01030 private_sof_counter=0; // Reset the counter in SOF detection sub-routine 01031 Host_reset_pipe(pipe); 01032 Host_enable_stall_interrupt(); 01033 #if (NAK_TIMEOUT_ENABLE==ENABLE) 01034 Host_enable_nak_interrupt(); 01035 #endif 01036 Host_enable_error_interrupt(); 01037 Host_enable_receive_interrupt(); 01038 Host_ack_stall(); 01039 Host_ack_nak_received(); 01040 01041 Host_continuous_in_mode(); 01042 Host_set_token_in(); 01043 Host_ack_in_received(); 01044 Host_unfreeze_pipe(); 01045 return HOST_TRUE; 01046 } 01047 }
| U8 host_send_data_interrupt | ( | U8 | pipe, | |
| U16 | nb_data, | |||
| U8 * | buf, | |||
| void(*)(U8 status, U16 nb_byte) | handle | |||
| ) |
This function send nb_data pointed with *buf with the pipe number specified
| pipe | ||
| nb_data | ||
| buf | ||
| handle | call back function pointer |
Definition at line 1060 of file usb_host_task.c.
References S_pipe_int::enable, ENABLE, FALSE, g_sav_int_sof_enable, S_pipe_int::handle, Host_ack_nak_received, Host_ack_out_sent, Host_ack_stall, Host_enable_error_interrupt, Host_enable_nak_interrupt, Host_enable_sof_interrupt, Host_enable_stall_interrupt, Host_enable_transmit_interrupt, HOST_FALSE, Host_get_pipe_length, Host_reset_pipe, Host_select_pipe, Host_send_out, HOST_TRUE, Host_unfreeze_pipe, Host_write_byte, i, is_any_interrupt_pipe_active(), Is_host_sof_interrupt_enabled, NAK_SEND_TIMEOUT, S_pipe_int::nak_timeout, S_pipe_int::nb_byte_on_going, S_pipe_int::nb_byte_processed, S_pipe_int::nb_byte_to_process, private_sof_counter, S_pipe_int::ptr_buf, and S_pipe_int::timeout.
01061 { 01062 U8 i; 01063 U8 *ptr_buf=buf; 01064 01065 Host_select_pipe(pipe); 01066 if(it_pipe_str[pipe].enable==ENABLE) 01067 { 01068 return HOST_FALSE; 01069 } 01070 else 01071 { 01072 if(is_any_interrupt_pipe_active()==FALSE) 01073 { 01074 g_sav_int_sof_enable=Is_host_sof_interrupt_enabled(); 01075 Host_enable_sof_interrupt(); 01076 } 01077 it_pipe_str[pipe].enable=ENABLE; 01078 it_pipe_str[pipe].nb_byte_to_process=nb_data; 01079 it_pipe_str[pipe].nb_byte_processed=0; 01080 it_pipe_str[pipe].ptr_buf=buf; 01081 it_pipe_str[pipe].handle=handle; 01082 it_pipe_str[pipe].timeout=0; 01083 it_pipe_str[pipe].nak_timeout=NAK_SEND_TIMEOUT; 01084 it_pipe_str[pipe].nb_byte_on_going=0; 01085 01086 Host_reset_pipe(pipe); 01087 Host_unfreeze_pipe(); 01088 // Prepare data to be sent 01089 i = Host_get_pipe_length(); 01090 if ( i > nb_data) // Pipe size> remaining data 01091 { 01092 i = nb_data; 01093 nb_data = 0; 01094 } 01095 else // Pipe size < remaining data 01096 { 01097 nb_data -= i; 01098 } 01099 it_pipe_str[pipe].nb_byte_on_going+=i; // Update nb data processed 01100 while (i!=0) // Load Pipe buffer 01101 { Host_write_byte(*ptr_buf++); i--; 01102 } 01103 private_sof_counter=0; // Reset the counter in SOF detection sub-routine 01104 it_pipe_str[pipe].timeout=0; // Refresh timeout counter 01105 Host_ack_out_sent(); 01106 Host_ack_stall(); 01107 Host_ack_nak_received(); 01108 01109 Host_enable_stall_interrupt(); 01110 Host_enable_error_interrupt(); 01111 #if (NAK_TIMEOUT_ENABLE==ENABLE) 01112 Host_enable_nak_interrupt(); 01113 #endif 01114 Host_enable_transmit_interrupt(); 01115 Host_send_out(); // Send the USB frame 01116 return HOST_TRUE; 01117 } 01118 }
| void reset_it_pipe_str | ( | void | ) |
Definition at line 975 of file usb_host_task.c.
References DISABLE, S_pipe_int::enable, i, MAX_EP_NB, and S_pipe_int::timeout.
00976 { 00977 U8 i; 00978 for(i=0;i<MAX_EP_NB;i++) 00979 { 00980 it_pipe_str[i].enable=DISABLE; 00981 it_pipe_str[i].timeout=0; 00982 } 00983 }
| U8 is_any_interrupt_pipe_active | ( | void | ) |
Public : U8 device_state Its value represent the current state of the device connected to the usb host controller Value can be:
Definition at line 152 of file usb_host_task.c.
Definition at line 169 of file usb_host_task.c.
Definition at line 171 of file usb_host_task.c.
Definition at line 170 of file usb_host_task.c.
1.5.3