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_template_task().
#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 host_template_task().
#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 host_template_task().
#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 host_template_task().
#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.
#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_template_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_template_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, FALSE, force_enumeration, Get_class, 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_supported, host_set_feature_remote_wakeup, Host_suspend_action, HOST_TRUE, Host_unfreeze_pipe, HUB_CLASS, hub_interrupt_sof, 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, new_device_connected, OFFSET_FIELD_MAXPACKETSIZE, ONE_BANK, PIPE_CONTROL, S_usb_endpoint::pipe_number, saved_device, selected_device, 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=0; 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=0; 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 // monitor device disconnection under interrupt 00496 Host_enable_device_disconnection_interrupt(); 00497 // If user host application requires SOF interrupt event 00498 // Keep SOF interrupt enable otherwize, disable this interrupt 00499 #if (HOST_CONTINUOUS_SOF_INTERRUPT==DISABLE && USB_HUB_SUPPORT==DISABLE) 00500 Host_disable_sof_interrupt(); 00501 #endif 00502 #if (USB_HUB_SUPPORT==ENABLE) 00503 // Check if the connected device is a hub 00504 if(Get_class(0)==HUB_CLASS && Get_subclass(0)==0x00 && Get_protocol(0)==0x00) 00505 { 00506 // Get hub descriptor 00507 if( Get_hub_descriptor()==CONTROL_GOOD) 00508 { 00509 // Power each port of the hub 00510 i=data_stage[NB_PORT_OFFSET]; 00511 for(c=1;c<=i;c++) 00512 { 00513 Set_port_feature(PORT_POWER,c); 00514 } 00515 nb_hub_present = 1; 00516 hub_device_address[0]=DEVICE_BASE_ADDRESS; 00517 hub_init(nb_hub_present-1); 00518 } 00519 } 00520 else 00521 { 00522 nb_hub_present = 0; 00523 new_device_connected=TRUE; 00524 } 00525 #else 00526 new_device_connected=TRUE; 00527 #endif 00528 00529 Enable_interrupt(); 00530 LOG_STR_CODE(log_device_enumerated); 00531 } 00532 else// Problem during Set_configuration request... 00533 { device_state = DEVICE_ERROR; } 00534 } 00535 } 00536 else // device class not supported... 00537 { 00538 device_state = DEVICE_ERROR; 00539 LOG_STR_CODE(log_device_unsupported); 00540 Host_device_class_not_supported_action(); 00541 } 00542 } 00543 else // Can not get configuration descriptors... 00544 { device_state = DEVICE_ERROR; } 00545 break; 00546 00547 //------------------------------------------------------ 00548 // DEVICE_READY state 00549 // 00550 // - Full std operatinf mode 00551 // - Nothing to do... 00552 // 00553 case DEVICE_READY: // Host full std operating mode! 00554 new_device_connected=FALSE; 00555 00556 #if (USB_HUB_SUPPORT==ENABLE) 00557 f_hub_port_disconnect=FALSE; 00558 // If one hub is present in the USB tree and the period interval 00559 // for the interrupt hub endpoint occurs 00560 if(nb_hub_present && hub_interrupt_sof==0) 00561 { 00562 saved_device=selected_device; // Backup user selected device 00563 for(j=1;j<=nb_hub_present;j++) 00564 { 00565 for(i=0;i<MAX_DEVICE_IN_USB_TREE;i++) 00566 { 00567 if(usb_tree.device[i].device_address==hub_device_address[j-1]) break; 00568 } 00569 Host_select_device(i); 00570 Host_select_pipe(usb_tree.device[i].interface[0].ep[0].pipe_number); 00571 Host_ack_nak_received(); 00572 Host_ack_in_received(); 00573 Host_unfreeze_pipe(); 00574 Host_send_in(); 00575 while(1) 00576 { 00577 if(Is_host_nak_received()) break; 00578 if(Is_host_emergency_exit()) break; 00579 if(Is_host_in_received()) break; 00580 } 00581 Host_freeze_pipe(); 00582 if(Is_host_nak_received()) 00583 { 00584 Host_ack_nak_received(); 00585 } 00586 if(Is_host_in_received()) 00587 { 00588 if(Is_host_stall()==FALSE) 00589 { 00590 c=Host_read_byte(); 00591 } 00592 Host_ack_in_received(); 00593 hub_manage_port_change_status(c,j); 00594 } 00595 } // for all hub 00596 Host_select_device(saved_device); // Restore user selected device 00597 #if (USER_PERIODIC_PIPE==ENABLE) 00598 unfreeze_user_periodic_pipe(); 00599 #endif 00600 } 00601 #endif 00602 break; 00603 00604 //------------------------------------------------------ 00605 // DEVICE_ERROR state 00606 // 00607 // - Error state 00608 // - Do custom action call (probably go to default mode...) 00609 // 00610 case DEVICE_ERROR : // TODO !!!! 00611 #if (HOST_ERROR_RESTART==ENABLE) 00612 device_state=DEVICE_UNATTACHED; 00613 #endif 00614 Host_device_error_action(); 00615 break; 00616 00617 //------------------------------------------------------ 00618 // DEVICE_SUSPENDED state 00619 // 00620 // - Host application request to suspend the device activity 00621 // - State machine comes here thanks to Host_request_suspend() 00622 // 00623 case DEVICE_SUSPENDED : 00624 if(Is_device_supports_remote_wakeup()) // If the connected device supports remote wake up 00625 { 00626 host_set_feature_remote_wakeup(); // Enable this feature... 00627 } 00628 LOG_STR_CODE(log_going_to_suspend); 00629 c = Is_host_sof_interrupt_enabled(); //Save current sof interrupt enable state 00630 Host_disable_sof_interrupt(); 00631 Host_ack_sof(); 00632 Host_disable_sof(); // Stop start of frame generation, this generates the suspend state 00633 Host_ack_hwup(); 00634 Host_enable_hwup_interrupt(); // Enable host wake-up interrupt 00635 // (this is the unique USB interrupt able to wake up the CPU core from power-down mode) 00636 Usb_freeze_clock(); 00637 Stop_pll(); 00638 Host_suspend_action(); // Custom action here! (for example go to power-save mode...) 00639 device_state=DEVICE_WAIT_RESUME; // wait for device resume event 00640 break; 00641 00642 //------------------------------------------------------ 00643 // DEVICE_WAIT_RESUME state 00644 // 00645 // - Wait in this state till the host receives an upstream resume from the device 00646 // - or the host software request the device to resume 00647 // 00648 case DEVICE_WAIT_RESUME : 00649 if(Is_usb_event(EVT_HOST_HWUP)|| Is_host_request_resume())// Remote wake up has been detected 00650 // or Local resume request has been received 00651 { 00652 if(Is_host_request_resume()) // Not a remote wakeup, but an host application request 00653 { 00654 Host_disable_hwup_interrupt(); // Wake up interrupt should be disable host is now wake up ! 00655 // CAUTION HWUP can be cleared only when USB clock is active 00656 Pll_start_auto(); // First Restart the PLL for USB operation 00657 Wait_pll_ready(); // Get sure pll is lock 00658 Usb_unfreeze_clock(); // Enable clock on USB interface 00659 Host_ack_hwup(); // Clear HWUP interrupt flag 00660 } 00661 Host_enable_sof(); 00662 Host_send_resume(); // Send down stream resume 00663 while (Is_host_down_stream_resume()==FALSE); // Wait Down stream resume sent 00664 Host_ack_remote_wakeup(); // Ack remote wake-up reception 00665 Host_ack_request_resume(); // Ack software request 00666 Host_ack_down_stream_resume(); // Ack down stream resume sent 00667 Usb_ack_event(EVT_HOST_HWUP); // Ack software event 00668 if(c) { Host_enable_sof_interrupt(); } // Restore SOF interrupt enable state before suspend 00669 device_state=DEVICE_READY; // Come back to full operating mode 00670 LOG_STR_CODE(log_usb_resumed); 00671 } 00672 break; 00673 00674 //------------------------------------------------------ 00675 // DEVICE_DISCONNECTED state 00676 // 00677 // - Device disconnection has been detected 00678 // - Run scheduler in this state at least two times to get sure event is detected by all host application tasks 00679 // - Go to DEVICE_DISCONNECTED_ACK state before DEVICE_UNATTACHED, to get sure scheduler calls all app tasks... 00680 // 00681 case DEVICE_DISCONNECTED : 00682 device_state = DEVICE_DISCONNECTED_ACK; 00683 break; 00684 00685 //------------------------------------------------------ 00686 // DEVICE_DISCONNECTED_ACK state 00687 // 00688 // - Device disconnection has been detected and managed bu applicatives tasks 00689 // - Go to DEVICE_UNATTACHED state 00690 // 00691 case DEVICE_DISCONNECTED_ACK : 00692 device_state = DEVICE_UNATTACHED; 00693 break; 00694 00695 //------------------------------------------------------ 00696 // default state 00697 // 00698 // - Default case: ERROR 00699 // - Goto no device state 00700 // 00701 default : 00702 device_state = DEVICE_UNATTACHED; 00703 break; 00704 } 00705 }
This function send nb_data pointed with *buf with the pipe number specified
pipe | ||
nb_data | ||
buf |
pipe | ||
nb_data | ||
buf |
Definition at line 721 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.
00722 { 00723 U8 c; 00724 U8 status=PIPE_GOOD; 00725 U8 sav_int_sof_enable; 00726 U8 nak_timeout; 00727 U16 cpt_nak; 00728 U8 nb_data_loaded; 00729 U8 cpt_err_timeout=0; 00730 00731 #if (USER_PERIODIC_PIPE==ENABLE) 00732 freeze_user_periodic_pipe(); 00733 #endif 00734 sav_int_sof_enable=Is_host_sof_interrupt_enabled(); // Save state of enable sof interrupt 00735 Host_enable_sof_interrupt(); 00736 Host_select_pipe(pipe); 00737 Host_set_token_out(); 00738 Host_ack_out_sent(); 00739 Host_unfreeze_pipe(); 00740 00741 while (nb_data != 0) // While there is something to send... 00742 { 00743 // Prepare data to be sent 00744 c = Host_get_pipe_length(); 00745 if ( (U16)c > nb_data) 00746 { 00747 nb_data_loaded = (U8)nb_data; 00748 c = nb_data; 00749 } 00750 else 00751 { nb_data_loaded = c; } 00752 while (c!=0) // Load Pipe buffer 00753 { 00754 Host_write_byte(*buf++); 00755 c--; 00756 } 00757 private_sof_counter=0; // Reset the counter in SOF detection sub-routine 00758 cpt_nak=0; 00759 nak_timeout=0; 00760 Host_ack_out_sent(); 00761 Host_send_out(); 00762 while (!Is_host_out_sent()) 00763 { 00764 if (Is_host_emergency_exit())// Async disconnection or role change detected under interrupt 00765 { 00766 status=PIPE_DELAY_TIMEOUT; 00767 Host_reset_pipe(pipe); 00768 goto host_send_data_end; 00769 } 00770 #if (TIMEOUT_DELAY_ENABLE==ENABLE) 00771 if (private_sof_counter>=250) // Count 250ms (250sof) 00772 { 00773 private_sof_counter=0; 00774 if (nak_timeout++>=TIMEOUT_DELAY) // Inc timeout and check for overflow 00775 { 00776 status=PIPE_DELAY_TIMEOUT; 00777 Host_reset_pipe(pipe); 00778 goto host_send_data_end; 00779 } 00780 } 00781 #endif 00782 if (Is_host_pipe_error()) // Any error ? 00783 { 00784 status = Host_error_status(); 00785 Host_ack_all_errors(); 00786 if(status == PIPE_TIMEOUT) 00787 { 00788 if(cpt_err_timeout++>100) 00789 { 00790 goto host_send_data_end; 00791 } 00792 else 00793 { 00794 c=0; 00795 while(c<2) // wait 2 ms 00796 { 00797 if (Is_usb_event(EVT_HOST_SOF)) { Usb_ack_event(EVT_HOST_SOF); c++; } 00798 if (Is_host_emergency_exit() ) {break;} 00799 } 00800 00801 Host_unfreeze_pipe(); 00802 } 00803 } 00804 } 00805 if (Is_host_stall()) // Stall management 00806 { 00807 status =PIPE_STALL; 00808 Host_ack_stall(); 00809 goto host_send_data_end; 00810 } 00811 #if (NAK_TIMEOUT_ENABLE==ENABLE) 00812 if(Is_host_nak_received()) //NAK received 00813 { 00814 Host_ack_nak_received(); 00815 if (cpt_nak++>NAK_SEND_TIMEOUT) 00816 { 00817 status = PIPE_NAK_TIMEOUT; 00818 Host_reset_pipe(pipe); 00819 goto host_send_data_end; 00820 } 00821 } 00822 #endif 00823 } 00824 // Here OUT sent 00825 nb_data -= nb_data_loaded; 00826 status=PIPE_GOOD; // Frame correctly sent 00827 Host_ack_out_sent(); 00828 } 00829 while(0!=Host_number_of_busy_bank()); 00830 00831 host_send_data_end: 00832 Host_freeze_pipe(); 00833 // Restore sof interrupt enable state 00834 if (sav_int_sof_enable==FALSE) {Host_disable_sof_interrupt();} 00835 #if (USER_PERIODIC_PIPE==ENABLE) 00836 unfreeze_user_periodic_pipe(); 00837 #endif 00838 // And return... 00839 return ((U8)status); 00840 }
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 856 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, PIPE_DELAY_TIMEOUT, PIPE_GOOD, PIPE_NAK_TIMEOUT, PIPE_STALL, private_sof_counter, TIMEOUT_DELAY, and unfreeze_user_periodic_pipe().
00857 { 00858 U8 status=PIPE_GOOD; 00859 U8 sav_int_sof_enable; 00860 U8 nak_timeout; 00861 U16 n,i; 00862 U16 cpt_nak; 00863 00864 #if (USER_PERIODIC_PIPE==ENABLE) 00865 freeze_user_periodic_pipe(); 00866 #endif 00867 n=*nb_data; 00868 *nb_data=0; 00869 sav_int_sof_enable=Is_host_sof_interrupt_enabled(); 00870 Host_enable_sof_interrupt(); 00871 Host_select_pipe(pipe); 00872 Host_continuous_in_mode(); 00873 Host_set_token_in(); 00874 Host_ack_in_received(); 00875 while (n) // While missing data... 00876 { 00877 Host_unfreeze_pipe(); 00878 Host_send_in(); 00879 private_sof_counter=0; // Reset the counter in SOF detection sub-routine 00880 nak_timeout=0; 00881 cpt_nak=0; 00882 while (!Is_host_in_received()) 00883 { 00884 if (Is_host_emergency_exit()) // Async disconnection or role change detected under interrupt 00885 { 00886 status=PIPE_DELAY_TIMEOUT; 00887 Host_reset_pipe(pipe); 00888 goto host_get_data_end; 00889 } 00890 #if (TIMEOUT_DELAY_ENABLE==ENABLE) 00891 if (private_sof_counter>=250) // Timeout management 00892 { 00893 private_sof_counter=0; // Done in host SOF interrupt 00894 if (nak_timeout++>=TIMEOUT_DELAY)// Check for local timeout 00895 { 00896 status=PIPE_DELAY_TIMEOUT; 00897 Host_reset_pipe(pipe); 00898 goto host_get_data_end; 00899 } 00900 } 00901 #endif 00902 if(Is_host_pipe_error()) // Error management 00903 { 00904 status = Host_error_status(); 00905 Host_ack_all_errors(); 00906 goto host_get_data_end; 00907 } 00908 if(Is_host_stall()) // STALL management 00909 { 00910 status =PIPE_STALL; 00911 Host_reset_pipe(pipe); 00912 Host_ack_stall(); 00913 goto host_get_data_end; 00914 } 00915 #if (NAK_TIMEOUT_ENABLE==ENABLE) 00916 if(Is_host_nak_received()) //NAK received 00917 { 00918 Host_ack_nak_received(); 00919 if (cpt_nak++>NAK_RECEIVE_TIMEOUT) 00920 { 00921 status = PIPE_NAK_TIMEOUT; 00922 Host_reset_pipe(pipe); 00923 goto host_get_data_end; 00924 } 00925 } 00926 #endif 00927 } 00928 status=PIPE_GOOD; 00929 Host_freeze_pipe(); 00930 if (Host_byte_counter()<=n) 00931 { 00932 if ((Host_byte_counter() < n)&&(Host_byte_counter()<Host_get_pipe_length())) 00933 { n=0;} 00934 else 00935 { n-=Host_byte_counter();} 00936 (*nb_data)+=Host_byte_counter(); // Update nb of byte received 00937 for (i=Host_byte_counter();i;i--) 00938 { *buf=Host_read_byte(); buf++;} 00939 } 00940 else // more bytes received than expected 00941 { // TODO error code management 00942 *nb_data+=n; 00943 for (i=n;i;i--) // Byte number limited to the initial request (limit tab over pb) 00944 { *buf=Host_read_byte(); buf++; } 00945 n=0; 00946 } 00947 Host_ack_in_received(); 00948 } 00949 Host_freeze_pipe(); 00950 host_get_data_end: 00951 if (sav_int_sof_enable==FALSE) 00952 { 00953 Host_disable_sof_interrupt(); 00954 } 00955 #if (USER_PERIODIC_PIPE==ENABLE) 00956 unfreeze_user_periodic_pipe(); 00957 #endif 00958 return ((U8)status); 00959 }
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 999 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_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.
01000 { 01001 Host_select_pipe(pipe); 01002 if(it_pipe_str[pipe].enable==ENABLE) 01003 { 01004 return HOST_FALSE; 01005 } 01006 else 01007 { 01008 if(is_any_interrupt_pipe_active()==FALSE) 01009 { 01010 g_sav_int_sof_enable=Is_host_sof_interrupt_enabled(); 01011 Host_enable_sof_interrupt(); 01012 } 01013 it_pipe_str[pipe].enable=ENABLE; 01014 it_pipe_str[pipe].nb_byte_to_process=nb_data; 01015 it_pipe_str[pipe].nb_byte_processed=0; 01016 it_pipe_str[pipe].ptr_buf=buf; 01017 it_pipe_str[pipe].handle=handle; 01018 it_pipe_str[pipe].timeout=0; 01019 it_pipe_str[pipe].nak_timeout=NAK_RECEIVE_TIMEOUT; 01020 01021 private_sof_counter=0; // Reset the counter in SOF detection sub-routine 01022 Host_reset_pipe(pipe); 01023 Host_enable_stall_interrupt(); 01024 #if (NAK_TIMEOUT_ENABLE==ENABLE) 01025 Host_enable_nak_interrupt(); 01026 #endif 01027 Host_enable_error_interrupt(); 01028 Host_enable_receive_interrupt(); 01029 Host_ack_stall(); 01030 Host_ack_nak_received(); 01031 01032 Host_continuous_in_mode(); 01033 Host_set_token_in(); 01034 Host_unfreeze_pipe(); 01035 return HOST_TRUE; 01036 } 01037 }
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 1050 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.
01051 { 01052 U8 i; 01053 U8 *ptr_buf=buf; 01054 01055 Host_select_pipe(pipe); 01056 if(it_pipe_str[pipe].enable==ENABLE) 01057 { 01058 return HOST_FALSE; 01059 } 01060 else 01061 { 01062 if(is_any_interrupt_pipe_active()==FALSE) 01063 { 01064 g_sav_int_sof_enable=Is_host_sof_interrupt_enabled(); 01065 Host_enable_sof_interrupt(); 01066 } 01067 it_pipe_str[pipe].enable=ENABLE; 01068 it_pipe_str[pipe].nb_byte_to_process=nb_data; 01069 it_pipe_str[pipe].nb_byte_processed=0; 01070 it_pipe_str[pipe].ptr_buf=buf; 01071 it_pipe_str[pipe].handle=handle; 01072 it_pipe_str[pipe].timeout=0; 01073 it_pipe_str[pipe].nak_timeout=NAK_SEND_TIMEOUT; 01074 it_pipe_str[pipe].nb_byte_on_going=0; 01075 01076 Host_reset_pipe(pipe); 01077 Host_unfreeze_pipe(); 01078 // Prepare data to be sent 01079 i = Host_get_pipe_length(); 01080 if ( i > nb_data) // Pipe size> remaining data 01081 { 01082 i = nb_data; 01083 nb_data = 0; 01084 } 01085 else // Pipe size < remaining data 01086 { 01087 nb_data -= i; 01088 } 01089 it_pipe_str[pipe].nb_byte_on_going+=i; // Update nb data processed 01090 while (i!=0) // Load Pipe buffer 01091 { Host_write_byte(*ptr_buf++); i--; 01092 } 01093 private_sof_counter=0; // Reset the counter in SOF detection sub-routine 01094 it_pipe_str[pipe].timeout=0; // Refresh timeout counter 01095 Host_ack_out_sent(); 01096 Host_ack_stall(); 01097 Host_ack_nak_received(); 01098 01099 Host_enable_stall_interrupt(); 01100 Host_enable_error_interrupt(); 01101 #if (NAK_TIMEOUT_ENABLE==ENABLE) 01102 Host_enable_nak_interrupt(); 01103 #endif 01104 Host_enable_transmit_interrupt(); 01105 Host_send_out(); // Send the USB frame 01106 return HOST_TRUE; 01107 } 01108 }
void reset_it_pipe_str | ( | void | ) |
Definition at line 966 of file usb_host_task.c.
References DISABLE, S_pipe_int::enable, i, MAX_EP_NB, and S_pipe_int::timeout.
00967 { 00968 U8 i; 00969 for(i=0;i<MAX_EP_NB;i++) 00970 { 00971 it_pipe_str[i].enable=DISABLE; 00972 it_pipe_str[i].timeout=0; 00973 } 00974 }
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.