- Main Page
- Modules
- Data Structures
- Files
- Related Pages

# usb_host_task.c

Go to the documentation of this file.

    00001 /*This file has been prepared for Doxygen automatic documentation generation.*/
    00016
    00017 /* Copyright (c) 2007, Atmel Corporation All rights reserved.
    00018  *
    00019  * Redistribution and use in source and binary forms, with or without
    00020  * modification, are permitted provided that the following conditions are met:
    00021  *
    00022  * 1. Redistributions of source code must retain the above copyright notice,
    00023  * this list of conditions and the following disclaimer.
    00024  *
    00025  * 2. Redistributions in binary form must reproduce the above copyright notice,
    00026  * this list of conditions and the following disclaimer in the documentation
    00027  * and/or other materials provided with the distribution.
    00028  *
    00029  * 3. The name of ATMEL may not be used to endorse or promote products derived
    00030  * from this software without specific prior written permission.
    00031  *
    00032  * THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
    00033  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
    00034  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE EXPRESSLY AND
    00035  * SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
    00036  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
    00037  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
    00038  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
    00039  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    00040  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
    00041  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    00042  */
    00043
    00044 //_____  I N C L U D E S ___________________________________________________
    00045
    00046 #include "config.h"
    00047 #include "conf_usb.h"
    00048 #include "modules/usb/usb_task.h"
    00049 #include "usb_host_task.h"
    00050 #include "lib_mcu/usb/usb_drv.h"
    00051 #include "lib_mcu/pll/pll_drv.h"
    00052 #include "modules/usb/host_chap9/usb_host_enum.h"
    00053
    00054 #if (USB_HUB_SUPPORT == ENABLE)
    00055 #include "modules/usb/host_chap9/usb_host_hub.h"
    00056 #endif
    00057
    00058 #if (USB_HOST_FEATURE == DISABLED)
    00059    #warning trying to compile a file used with the USB HOST without USB_HOST_FEATURE enabled
    00060 #endif
    00061
    00062 #if (USB_HOST_FEATURE == ENABLED)
    00063
    00064 #ifndef DEVICE_BASE_ADDRESS
    00065    #error DEVICE_BASE_ADDRESS should be defined somewhere in config files (conf_usb.h)
    00066 #endif
    00067
    00068 #ifndef SIZEOF_DATA_STAGE
    00069    #error SIZEOF_DATA_STAGE should be defined in conf_usb.h
    00070 #endif
    00071
    00072 #ifndef HOST_CONTINUOUS_SOF_INTERRUPT
    00073    #error HOST_CONTINUOUS_SOF_INTERRUPT should be defined as ENABLE or DISABLE in conf_usb.h
    00074 #endif
    00075
    00076 #ifndef USB_HOST_PIPE_INTERRUPT_TRANSFER
    00077    #error USB_HOST_PIPE_INTERRUPT_TRANSFER should be defined as ENABLE or DISABLE in conf_usb.h
    00078 #endif
    00079
    00080 #ifndef Usb_id_transition_action
    00081    #define Usb_id_transition_action()
    00082 #endif
    00083 #ifndef  Host_device_disconnection_action
    00084    #define Host_device_disconnection_action()
    00085 #endif
    00086 #ifndef  Host_device_connection_action
    00087    #define Host_device_connection_action()
    00088 #endif
    00089 #ifndef  Host_sof_action
    00090    #define Host_sof_action()
    00091 #endif
    00092 #ifndef  Host_suspend_action
    00093    #define Host_suspend_action()
    00094 #endif
    00095 #ifndef  Host_hwup_action
    00096    #define Host_hwup_action()
    00097 #endif
    00098 #ifndef  Host_device_not_supported_action
    00099    #define Host_device_not_supported_action()
    00100 #endif
    00101 #ifndef  Host_device_class_not_supported_action
    00102    #define Host_device_class_not_supported_action()
    00103 #endif
    00104 #ifndef  Host_device_supported_action
    00105    #define Host_device_supported_action()
    00106 #endif
    00107 #ifndef  Host_device_error_action
    00108    #define Host_device_error_action()
    00109 #endif
    00110
    00111
    00112 //_____ M A C R O S ________________________________________________________
    00113
    00114 #ifndef LOG_STR_CODE
    00115 #define LOG_STR_CODE(str)
    00116 #else
    00117 U8 code log_device_connected[]="Device Connection";
    00118 U8 code log_device_enumerated[]="Device Enumerated";
    00119 U8 code log_device_unsupported[]="Unsupported Device";
    00120 U8 code log_going_to_suspend[]="Usb suspend";
    00121 U8 code log_usb_resumed[]="Usb resumed";
    00122 #endif
    00123
    00124 //_____ D E F I N I T I O N S ______________________________________________
    00125
    00126 //_____ D E C L A R A T I O N S ____________________________________________
    00127
    00128 #if (USB_HOST_PIPE_INTERRUPT_TRANSFER == ENABLE)
    00129    volatile S_pipe_int   it_pipe_str[MAX_EP_NB];
    00130    volatile U8 pipe_nb_save;
    00131    U8 g_sav_int_sof_enable;
    00132 #endif
    00133
    00152 U8 device_state;
    00153
    00155 S_usb_setup_data usb_request;
    00156
    00166 U8 data_stage[SIZEOF_DATA_STAGE];
    00167
    00168 U8 device_status;
    00169 U8 request_resume = FALSE;
    00170 U8 force_enumeration = FALSE;
    00171 U8 new_device_connected = FALSE;
    00172
    00173
    00174 static U16  c;                // As internal host start of frame counter
    00175
    00176
    00177 #if (USB_HUB_SUPPORT == ENABLE)
    00178    static U8 i,j;
    00179    volatile U8 hub_interrupt_sof=0;
    00180    U8 saved_device;
    00181 #endif
    00182
    00194 void usb_host_task_init(void)
    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 }
    00209
    00226 void usb_host_task(void)
    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 }
    00707
    00708 //___ F U N C T I O N S   F O R   P O L L I N G   M A N A G E D   D A T A  F L O W S  _________________________
    00709
    00722 U8 host_send_data(U8 pipe, U16 nb_data, U8 *buf)
    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 }
    00842
    00843
    00844
    00857 U8 host_get_data(U8 pipe, U16 *nb_data, U8 *buf)
    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 }
    00969
    00970
    00971 //___ F U N C T I O N S   F O R   I N T E R R U P T   M A N A G E D   D A T A   F L O W S  _________________________
    00972
    00973 #if (USB_HOST_PIPE_INTERRUPT_TRANSFER == ENABLE)
    00974
    00975 void reset_it_pipe_str(void)
    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 }
    00984
    00985 U8 is_any_interrupt_pipe_active(void)
    00986 {
    00987    U8 i;
    00988    for(i=0;i<MAX_EP_NB;i++)
    00989    {
    00990       if(it_pipe_str[i].enable==ENABLE) return TRUE;
    00991    }
    00992    return FALSE;
    00993 }
    00994
    01008 U8 host_get_data_interrupt(U8 pipe, U16 nb_data, U8 *buf,void(*handle)(U8 status, U16 nb_byte))
    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 }
    01048
    01060 U8 host_send_data_interrupt(U8 pipe, U16 nb_data, U8 *buf, void(*handle)(U8 status, U16 nb_byte))
    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 }
    01119
    01125 #ifdef __GNUC__
    01126  ISR(USB_COM_vect)
    01127 #else
    01128 #pragma vector = USB_Endpoint_Pipe_vect
    01129 __interrupt void usb_pipe_interrupt()
    01130 #endif
    01131 {
    01132    U8 pipe_nb;
    01133    U8 *ptr_buf;
    01134    void  (*fct_handle)(U8 status,U16 nb_byte);
    01135    U16 n;
    01136    U8 i;
    01137    U8 do_call_back=FALSE;
    01138
    01139    pipe_nb_save = Host_get_selected_pipe();       // Important! Save here working pipe number
    01140    pipe_nb=usb_get_nb_pipe_interrupt();  // work with the correct pipe number that generates the interrupt
    01141    Host_select_pipe(pipe_nb);                        // Select this pipe
    01142    fct_handle=*(it_pipe_str[pipe_nb].handle);
    01143
    01144    // Now try to detect what event generate an interrupt...
    01145
    01146    if (Is_host_pipe_error())             // Any error ?
    01147    {
    01148       it_pipe_str[pipe_nb].status = Host_error_status();
    01149       it_pipe_str[pipe_nb].enable=DISABLE;
    01150       Host_stop_pipe_interrupt(pipe_nb);
    01151       Host_ack_all_errors();
    01152       do_call_back=TRUE;
    01153       goto usb_pipe_interrupt_end;
    01154    }
    01155
    01156    if (Is_host_stall())                  // Stall handshake received ?
    01157    {
    01158       it_pipe_str[pipe_nb].status=PIPE_STALL;
    01159       it_pipe_str[pipe_nb].enable=DISABLE;
    01160       Host_stop_pipe_interrupt(pipe_nb);
    01161       do_call_back=TRUE;
    01162       goto usb_pipe_interrupt_end;
    01163    }
    01164
    01165    #if (NAK_TIMEOUT_ENABLE==ENABLE)
    01166    if (Is_host_nak_received())           // NAK ?
    01167    {
    01168       Host_ack_nak_received();
    01169       // check if number of NAK timeout error occurs (not for interrupt type pipe)
    01170       if((--it_pipe_str[pipe_nb].nak_timeout==0) && (Host_get_pipe_type()!=TYPE_INTERRUPT))
    01171       {
    01172          it_pipe_str[pipe_nb].status=PIPE_NAK_TIMEOUT;
    01173          it_pipe_str[pipe_nb].enable=DISABLE;
    01174          Host_stop_pipe_interrupt(pipe_nb);
    01175          do_call_back=TRUE;
    01176          goto usb_pipe_interrupt_end;
    01177       }
    01178    }
    01179    #endif
    01180
    01181    if (Is_host_in_received())            // Pipe IN reception ?
    01182    {
    01183       ptr_buf=it_pipe_str[pipe_nb].ptr_buf+it_pipe_str[pipe_nb].nb_byte_processed;       // Build pointer to data buffer
    01184       n=it_pipe_str[pipe_nb].nb_byte_to_process-it_pipe_str[pipe_nb].nb_byte_processed;  // Remaining data bytes
    01185       Host_freeze_pipe();
    01186       if (Host_byte_counter()<=n)
    01187       {
    01188          if ((Host_byte_counter() < n)&&(Host_byte_counter()<Host_get_pipe_length())) //Received less than remaining, but less than pipe capacity
    01189                                                                                       //TODO: error code
    01190          {
    01191             n=0;
    01192          }
    01193          else
    01194          {
    01195             n-=Host_byte_counter();
    01196          }
    01197          it_pipe_str[pipe_nb].nb_byte_processed+=Host_byte_counter();  // Update nb of byte received
    01198          for (i=Host_byte_counter();i;i--)
    01199          { *ptr_buf=Host_read_byte(); ptr_buf++;}
    01200       }
    01201       else  // more bytes received than expected
    01202       {     // TODO error code management
    01203          it_pipe_str[pipe_nb].nb_byte_processed+=n;
    01204          for (i=n;i;i--)                  // Byte number limited to the initial request (limit tab over pb)
    01205          { *ptr_buf=Host_read_byte(); ptr_buf++;}
    01206          n=0;
    01207       }
    01208       Host_ack_in_received();
    01209       if(n>0) //still something to process
    01210       {
    01211          Host_unfreeze_pipe();            // Request another IN transfer
    01212          Host_send_in();
    01213          private_sof_counter=0;           // Reset the counter in SOF detection sub-routine
    01214          it_pipe_str[pipe_nb].timeout=0;  // Reset timeout
    01215          it_pipe_str[pipe_nb].nak_timeout=NAK_RECEIVE_TIMEOUT;
    01216
    01217       }
    01218       else //end of transfer
    01219       {
    01220          it_pipe_str[pipe_nb].enable=DISABLE;
    01221          it_pipe_str[pipe_nb].status=PIPE_GOOD;
    01222          Host_stop_pipe_interrupt(pipe_nb);
    01223          do_call_back=TRUE;
    01224       }
    01225    }
    01226
    01227    if(Is_host_out_sent())                  // Pipe OUT sent ?
    01228    {
    01229       Host_ack_out_sent();
    01230       it_pipe_str[pipe_nb].nb_byte_processed+=it_pipe_str[pipe_nb].nb_byte_on_going;
    01231       it_pipe_str[pipe_nb].nb_byte_on_going=0;
    01232       ptr_buf=it_pipe_str[pipe_nb].ptr_buf+it_pipe_str[pipe_nb].nb_byte_processed;       // Build pointer to data buffer
    01233       n=it_pipe_str[pipe_nb].nb_byte_to_process-it_pipe_str[pipe_nb].nb_byte_processed;  // Remaining data bytes
    01234       if(n>0)   // Still data to process...
    01235       {
    01236          Host_unfreeze_pipe();
    01237         // Prepare data to be sent
    01238          i = Host_get_pipe_length();
    01239          if ( i > n)     // Pipe size> remaining data
    01240          {
    01241             i = n;
    01242             n = 0;
    01243          }
    01244          else                // Pipe size < remaining data
    01245          {  n -= i; }
    01246          it_pipe_str[pipe_nb].nb_byte_on_going+=i;   // Update nb data processed
    01247          while (i!=0)                     // Load Pipe buffer
    01248          {
    01249             Host_write_byte(*ptr_buf++); i--;
    01250          }
    01251          private_sof_counter=0;           // Reset the counter in SOF detection sub-routine
    01252          it_pipe_str[pipe_nb].timeout=0;  // Refresh timeout counter
    01253          it_pipe_str[pipe_nb].nak_timeout=NAK_SEND_TIMEOUT;
    01254          Host_send_out();                 // Send the USB frame
    01255       }
    01256       else                                //n==0 Transfer is finished
    01257       {
    01258          it_pipe_str[pipe_nb].enable=DISABLE;    // Tranfer end
    01259          it_pipe_str[pipe_nb].status=PIPE_GOOD;  // Status OK
    01260          Host_stop_pipe_interrupt(pipe_nb);
    01261          do_call_back=TRUE;
    01262       }
    01263    }
    01264
    01265 usb_pipe_interrupt_end:
    01266    Host_select_pipe(pipe_nb_save);   // Restore pipe number !!!!
    01267    if (is_any_interrupt_pipe_active()==FALSE)    // If no more transfer is armed
    01268    {
    01269       if (g_sav_int_sof_enable==FALSE)
    01270       {
    01271          Host_disable_sof_interrupt();
    01272       }
    01273    }
    01274    if(do_call_back)      // Any callback functions to perform ?
    01275    {
    01276       fct_handle(it_pipe_str[pipe_nb].status,it_pipe_str[pipe_nb].nb_byte_processed);
    01277    }
    01278 }
    01279 #endif
    01280
    01281
    01282 #endif // USB_HOST_FEATURE ENABLE
    01283