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