usb_host_task.c

Go to the documentation of this file.
00001 
00020 //_____  I N C L U D E S ___________________________________________________
00021 
00022 #include "config.h"
00023 #include "conf_usb.h"
00024 #include "modules/usb/usb_task.h"
00025 #include "usb_host_task.h"
00026 #include "lib_mcu/usb/usb_drv.h"
00027 #include "lib_mcu/pll/pll_drv.h"
00028 #include "modules/usb/host_chap9/usb_host_enum.h"
00029 
00030 #if (USB_OTG_FEATURE == ENABLED)
00031   #include "modules/usb/device_chap9/usb_device_task.h"
00032   #if (TARGET_BOARD==SPIDER)
00033     #include "lib_board/lcd/lcd_drv.h"
00034   #endif
00035 
00036   #ifndef OTG_ENABLE_HNP_AFTER_SRP
00037     #warning  OTG_ENABLE_HNP_AFTER_SRP should be defined somewhere in config files (conf_usb.h)
00038   #endif
00039 
00040   #ifndef OTG_B_DEVICE_AUTORUN_HNP_IF_REQUIRED
00041     #warning  OTG_B_DEVICE_AUTORUN_HNP_IF_REQUIRED should be defined somewhere in config files (conf_usb.h)
00042   #endif
00043 
00044   #ifndef OTG_VBUS_AUTO_WHEN_A_PLUG
00045     #warning  OTG_VBUS_AUTO_WHEN_A_PLUG should be defined somewhere in config files (conf_usb.h)
00046   #endif
00047 
00048   #ifndef OTG_ADEV_SRP_REACTION
00049     #warning  OTG_ADEV_SRP_REACTION should be defined somewhere in config files (conf_usb.h)
00050   #endif
00051 
00052   #if (HOST_STRICT_VID_PID_TABLE != ENABLE)
00053     #warning  HOST_STRICT_VID_PID_TABLE must be defined to ENABLED to comply with Targeted Peripheral List requirements
00054   #endif
00055 #endif
00056 
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_ADDRESS
00065    #error DEVICE_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 
00134    
00135 #if (USB_OTG_FEATURE == ENABLED)
00138   U16 otg_ta_srp_wait_connect;
00139   
00142   U16 otg_ta_aidl_bdis_tmr;
00143   
00146   U8  otg_ta_vbus_rise;
00147   
00150   U16 otg_timeout_bdev_respond;
00151   
00154   U8  otg_device_connected;
00155   
00158   U8  otg_a_device_srp;
00159 
00162   U16 otg_end_hnp_vbus_delay;
00163 #endif
00164 
00165 
00190 U8 device_state;
00191 
00193 S_usb_setup_data    usb_request;
00194 
00204 U8 data_stage[SIZEOF_DATA_STAGE];
00205 
00206 U8 device_status;
00207 U8 request_resume;
00208 
00209 static U16  c;                // As internal host start of frame counter
00210 
00211 U8 new_device_connected=0;
00212 
00213 
00225 void usb_host_task_init(void)
00226 {
00227    Pll_start_auto();
00228    Wait_pll_ready();
00229    Usb_disable();
00230    Usb_enable();
00231    Usb_unfreeze_clock();
00232    Usb_attach();
00233    Usb_enable_uvcon_pin();
00234    Usb_select_host();
00235    Usb_disable_vbus_hw_control();   // Force Vbus generation without timeout
00236    Host_enable_device_disconnection_interrupt();
00237    #if (USB_OTG_FEATURE == ENABLED)
00238    Usb_enable_id_interrupt();
00239      #if (OTG_ADEV_SRP_REACTION == VBUS_PULSE)
00240        Usb_select_vbus_srp_method();
00241      #else
00242        Usb_select_data_srp_method();
00243      #endif
00244    #endif
00245    device_state=DEVICE_UNATTACHED;
00246 }
00247 
00264 void usb_host_task(void)
00265 {
00266   U32 dec;
00267   U8  desc_temp;
00268    switch (device_state)
00269    {
00270      //------------------------------------------------------
00271      //   DEVICE_UNATTACHED state
00272      //
00273      //   - Default init state
00274      //   - Try to give device power supply
00275      //
00276       case DEVICE_UNATTACHED:
00277          for (c=0;c<MAX_EP_NB;c++) {ep_table[c]=0;}// Reset PIPE lookup table with device EP addr
00278          nb_interface_supported=0;
00279          Host_clear_device_supported();        // Reset Device status
00280          Host_clear_configured();
00281          Host_clear_device_ready();
00282          Usb_clear_all_event();                // Clear all software events
00283          new_device_connected=0;
00284 #if (USB_OTG_FEATURE == ENABLED)
00285          Host_end_session_started_srp();
00286          Peripheral_is_not_otg_device();
00287          Usb_host_reject_hnp();
00288          Usb_disable_role_exchange_interrupt();
00289          Usb_disable_hnp_error_interrupt();
00290 #endif
00291          if (Is_usb_id_host())
00292          {
00293 #if (SOFTWARE_VBUS_CTRL==ENABLE)
00294            if( Is_usb_bconnection_error_interrupt()||Is_usb_vbus_error_interrupt())
00295            {
00296               Usb_ack_bconnection_error_interrupt();
00297               Usb_ack_vbus_error_interrupt();
00298               Host_clear_vbus_request();
00299            }
00300            #if ((USB_OTG_FEATURE == DISABLED) || (OTG_VBUS_AUTO_WHEN_A_PLUG == ENABLED))
00301            if (Is_usb_id_host())
00302            {
00303              Host_ack_device_connection();
00304              Usb_enable_manual_vbus();
00305              Host_vbus_action();
00306              #if (USB_OTG_FEATURE == ENABLED)
00307              Init_ta_vbus_rise_counter();
00308              #endif
00309            }
00310            #endif
00311            #if ((USB_OTG_FEATURE == ENABLED) && (OTG_VBUS_AUTO_WHEN_A_PLUG == DISABLED))
00312            // Handle user requests to turn Vbus ON or OFF
00313            if (Is_usb_id_host() && Is_user_requested_vbus())
00314            {
00315              Ack_user_request_vbus();
00316              if (Is_usb_vbus_manual_on())
00317              {
00318                Usb_disable_vbus();
00319                Usb_disable_manual_vbus();
00320                Host_vbus_action();
00321              }
00322              else
00323              {
00324                Usb_enable_manual_vbus();
00325                Host_vbus_action();
00326                Init_ta_vbus_rise_counter();
00327              }
00328            }
00329 
00330              #if (OTG_VBUS_AUTO_AFTER_A_PLUG_INSERTION == ENABLED)
00331              if (id_changed_to_host_event == ENABLED)
00332              {
00333                id_changed_to_host_event = DISABLED;
00334                Usb_enable_manual_vbus();
00335                Init_ta_vbus_rise_counter();
00336                Host_vbus_action();
00337              }
00338              #endif
00339            #endif
00340 
00341            #if (USB_OTG_FEATURE == ENABLED)
00342            if (Is_ta_vbus_rise_counter_overflow() && Is_usb_vbus_low() && Is_usb_vbus_manual_on())
00343            {
00344              // In the case of an user manual request to turn on Vbus, generate an error message if
00345              // Vbus not reach Va_vbus_valid before Ta_vbus_rise (rise time verification)
00346              Usb_disable_vbus();
00347              Usb_disable_manual_vbus();
00348              Host_vbus_action();
00349              Otg_print_new_event_message(OTGMSG_VBUS_SURCHARGE,OTG_TEMPO_3SEC);
00350              Otg_print_new_failure_message(OTGMSG_UNSUPPORTED,OTG_TEMPO_4SEC);
00351            }
00352            #else
00353            Usb_disable_vbus_pad();
00354            Usb_enable_manual_vbus();
00355            #endif
00356 
00357            if(Is_usb_srp_interrupt())
00358            {
00359               Usb_ack_srp_interrupt();
00360 
00361               if (!Is_usb_vbus_manual_on())  // if Vbus was not already delivered, it is really an SRP (OTG B-Device)
00362               {
00363                 #if (USB_OTG_FEATURE == ENABLED)
00364                 Otg_print_new_event_message(OTGMSG_SRP_RECEIVED,OTG_TEMPO_2SEC);
00365                 Host_session_started_srp();
00366                 Init_ta_srp_counter();
00367                 Srp_received_and_waiting_connect();
00368                 Init_ta_vbus_rise_counter();
00369                 #endif
00370               }
00371               device_state=DEVICE_ATTACHED;
00372               Usb_ack_bconnection_error_interrupt();
00373               Usb_enable_vbus_pad();
00374               Usb_enable_vbus();
00375               Host_vbus_action();
00376            }
00377 #else
00378            Usb_enable_vbus();                    // Give at least device power supply!!!
00379            Host_vbus_action();
00380            if(Is_usb_vbus_high())
00381            { device_state=DEVICE_ATTACHED; }     // If VBUS ok goto to device connection expectation
00382 #endif
00383          }
00384          #if (USB_OTG_FEATURE == ENABLED)
00385          else
00386            if (otg_b_device_state == B_HOST)
00387            {
00388              device_state = DEVICE_ATTACHED;
00389            }
00390          #endif
00391       break;
00392 
00393      //------------------------------------------------------
00394      //   DEVICE_ATTACHED state
00395      //
00396      //   - Vbus is on
00397      //   - Try to detect device connection
00398      //
00399       case DEVICE_ATTACHED :
00400 #if (USB_OTG_FEATURE == ENABLED)
00401          if (Is_device_connection() || (Is_usb_id_device() && (otg_b_device_state == B_HOST)))
00402 #else
00403          if (Is_device_connection())     // Device pull-up detected
00404 #endif
00405          {
00406             Host_ack_device_connection();
00407             #if (USB_OTG_FEATURE == ENABLED)
00408             Ack_srp_received_and_connect();   // connection might have been requested by SRP
00409             #endif
00410            // Now device is connected, enable disconnection interrupt
00411             Host_enable_device_disconnection_interrupt();
00412             Enable_interrupt();
00413            // Reset device status
00414             Host_clear_device_supported();
00415             Host_clear_configured();
00416             Host_clear_device_ready();
00417             Host_ack_sof();
00418             Host_enable_sof();            // Start Start Of Frame generation
00419             Host_enable_sof_interrupt();  // SOF will be detected under interrupt
00420             c = 0;
00421             while (c<100)                 // wait 100ms before USB reset
00422             {
00423                if (Is_usb_event(EVT_HOST_SOF)) { Usb_ack_event(EVT_HOST_SOF); c++; }  // Count Start Of frame
00424                if (Is_host_emergency_exit() || Is_usb_bconnection_error_interrupt()) {goto device_attached_error;}
00425                #if (USB_OTG_FEATURE == ENABLED)
00426                if (Is_usb_device_enabled()) { break; }
00427                #endif
00428             }
00429             Host_disable_device_disconnection_interrupt();
00430 
00431             Host_send_reset();          // First USB reset
00432             Usb_ack_event(EVT_HOST_SOF);
00433             while (Is_host_reset())
00434             {
00435               #if (USB_OTG_FEATURE == ENABLED)
00436               if (Is_usb_device_enabled()) { break; }
00437               #endif
00438             } // Active wait of end of reset send
00439             Host_ack_reset();
00440 
00441             #if (USB_OTG_FEATURE == ENABLED)
00442             // User can choose the number of consecutive resets sent
00443             c = 1;
00444             while (c != OTG_RESET_LENGTH)
00445             {
00446               Host_send_reset();
00447               Usb_ack_event(EVT_HOST_SOF);
00448               while (Is_host_reset())
00449               {
00450                 #if (USB_OTG_FEATURE == ENABLED)
00451                 if (Is_usb_device_enabled()) { break; }
00452                 #endif
00453               }// Active wait of end of reset send
00454               Host_ack_reset();
00455               c++;
00456             }
00457             #endif
00458 
00459 
00460             //Workaround for some bugly devices with powerless pull up
00461             //usually low speed where data line rise slowly and can be interpretaded as disconnection
00462             for(c=0;c!=0xFFFF;c++)    // Basic Timeout counter
00463             {
00464                if(Is_usb_event(EVT_HOST_SOF))   //If we detect SOF, device is still alive and connected, just clear false disconnect flag
00465                {
00466                   if(Is_device_disconnection())
00467                   {
00468                       Host_ack_device_connection();
00469                       Host_ack_device_disconnection();
00470                       break;
00471                   }
00472                }
00473             }
00474             Host_enable_device_disconnection_interrupt();
00475             c = 0;
00476             while (c<100)               // wait 100ms after USB reset
00477             {
00478                if (Is_usb_event(EVT_HOST_SOF)) { Usb_ack_event(EVT_HOST_SOF); c++; }// Count Start Of frame
00479                if (Is_host_emergency_exit() || Is_usb_bconnection_error_interrupt()) {goto device_attached_error;}
00480                #if (USB_OTG_FEATURE == ENABLED)
00481                if (Is_usb_device_enabled()) { break; }
00482                #endif
00483             }
00484             device_state = DEVICE_POWERED;
00485             c=0;
00486          }
00487          #if ((USB_OTG_FEATURE == ENABLED) && (OTG_VBUS_AUTO_WHEN_A_PLUG == DISABLED))
00488          else
00489          {
00490              // Handle SRP connection
00491              if (Is_srp_received_and_waiting_connect())
00492              {
00493                // Check if time-out elapsed between SRP and device connection
00494                if (Is_ta_srp_counter_overflow())
00495                {
00496                  Ack_srp_received_and_connect();
00497                  Clear_all_user_request();
00498                  device_state = DEVICE_DISCONNECTED;
00499                  Otg_print_new_failure_message(OTGMSG_DEVICE_NO_RESP,OTG_TEMPO_4SEC);
00500                }
00501 
00502                if (Is_usb_bconnection_error_interrupt())
00503                {    // used when a B-Device has sent SRP and connects after the max connection delay accepted by hardware module
00504                     // vbus is initialized (no drop on output thanks to capacitor)
00505                   Usb_ack_bconnection_error_interrupt();
00506                   Usb_disable_vbus();
00507                   Usb_disable_vbus_pad();
00508                   Usb_enable_vbus_pad();
00509                   Usb_enable_vbus_hw_control();
00510                   Usb_enable_vbus();
00511                }
00512              }
00513              if (Is_ta_vbus_rise_counter_overflow() && Is_usb_vbus_low())
00514              {
00515                // In the case of an SRP request to turn on Vbus, generate an error message if
00516                // Vbus not reach Va_vbus_valid before Ta_vbus_rise (rise time verification)
00517                Usb_disable_vbus();
00518                Usb_disable_manual_vbus();
00519                Host_vbus_action();
00520 
00521                device_state = DEVICE_DISCONNECTED;
00522 
00523                Otg_print_new_event_message(OTGMSG_VBUS_SURCHARGE,OTG_TEMPO_3SEC);
00524                Otg_print_new_failure_message(OTGMSG_UNSUPPORTED,OTG_TEMPO_4SEC);
00525              }
00526          }
00527          #endif
00528 
00529          #if ((USB_OTG_FEATURE == ENABLED) && (OTG_VBUS_AUTO_WHEN_A_PLUG == DISABLED))
00530          // Handle user request to turn Vbus off
00531          if (Is_usb_id_host() && Is_user_requested_vbus())
00532          {
00533            Ack_user_request_vbus();
00534            Usb_disable_vbus();
00535            Usb_disable_manual_vbus();
00536            Host_vbus_action();
00537            device_state = DEVICE_UNATTACHED;
00538          }
00539          #endif
00540 
00541          device_attached_error:
00542          #if ((USB_OTG_FEATURE == DISABLED) || (OTG_VBUS_AUTO_WHEN_A_PLUG == ENABLED))
00543         // Device connection error, or vbus pb -> Retry the connection process from the begining
00544          if( Is_usb_bconnection_error_interrupt()||Is_usb_vbus_error_interrupt()||Is_usb_vbus_low())
00545          {
00546            if (Is_usb_id_host())
00547            {
00548               Usb_ack_bconnection_error_interrupt();
00549               Usb_enable_vbus_hw_control();
00550               device_state=DEVICE_UNATTACHED;
00551               Usb_disable_vbus();
00552               Usb_disable_vbus_pad();
00553               Usb_enable_vbus_pad();
00554               Usb_ack_vbus_error_interrupt();
00555               Usb_enable_vbus();
00556               Usb_disable_vbus_hw_control();
00557               Host_disable_sof();
00558               Host_vbus_action();
00559            }
00560            else   { device_state = DEVICE_UNATTACHED; }
00561          }
00562          #endif
00563 
00564          break;
00565 
00566      //------------------------------------------------------
00567      //   DEVICE_POWERED state
00568      //
00569      //   - Device connection (attach) as been detected,
00570      //   - Wait 100ms and configure default control pipe
00571      //
00572       case DEVICE_POWERED :
00573          LOG_STR_CODE(log_device_connected);
00574          Host_device_connection_action();
00575          if (Is_usb_event(EVT_HOST_SOF))
00576          {
00577             Usb_ack_event(EVT_HOST_SOF);
00578             if (c++ >= 100)                          // Wait 100ms
00579             {
00580                device_state = DEVICE_DEFAULT;
00581                Host_select_pipe(PIPE_CONTROL);
00582                Host_enable_pipe();
00583                host_configure_pipe(PIPE_CONTROL, \
00584                                    TYPE_CONTROL, \
00585                                    TOKEN_SETUP,  \
00586                                    EP_CONTROL,   \
00587                                    SIZE_8,       \
00588                                    ONE_BANK,     \
00589                                    0             );
00590                device_state = DEVICE_DEFAULT;
00591             }
00592          }
00593          break;
00594 
00595      //------------------------------------------------------
00596      //   DEVICE_DEFAULT state
00597      //
00598      //   - Get device descriptor
00599      //   - Reconfigure Pipe 0 according to Device EP0
00600      //   - Attribute device address
00601      //
00602       case DEVICE_DEFAULT :
00603         // Get first device descriptor
00604          #if (USB_OTG_FEATURE == ENABLED)
00605          Peripheral_is_not_otg_device();    // init status variable
00606          Init_timeout_bdev_response();      // init B-Device "waiting response" delay (handled by timer interrupt in usb_task.c)
00607          #endif
00608          if( CONTROL_GOOD == host_get_device_descriptor_uncomplete())
00609          {
00610             c = 0;
00611             while(c<20)           // wait 20ms before USB reset (special buggly devices...)
00612             {
00613                if (Is_usb_event(EVT_HOST_SOF)) { Usb_ack_event(EVT_HOST_SOF); c++; }
00614                if (Is_host_emergency_exit() || Is_usb_bconnection_error_interrupt())  {break;}
00615             }
00616             Host_disable_device_disconnection_interrupt();
00617 
00618             Host_send_reset();          // First USB reset
00619             Usb_ack_event(EVT_HOST_SOF);
00620             while (Is_host_reset());    // Active wait of end of reset send
00621             Host_ack_reset();
00622             #if (USB_OTG_FEATURE == ENABLED)    // for OTG compliance, reset duration must be > 50ms (delay between reset < 3ms)
00623             c = 1;
00624             while (c != OTG_RESET_LENGTH)
00625             {
00626               Host_send_reset();
00627               Usb_ack_event(EVT_HOST_SOF);
00628               while (Is_host_reset());    // Active wait of end of reset send
00629               Host_ack_reset();
00630               c++;
00631             }
00632             #endif
00633 
00634 
00635             //Workaround for some bugly devices with powerless pull up
00636             //usually low speed where data line rise slowly and can be interpretaded as disconnection
00637             for(c=0;c!=0xFFFF;c++)    // Basic Timeout counter
00638             {
00639                if(Is_usb_event(EVT_HOST_SOF))   //If we detect SOF, device is still alive and connected, just clear false disconnect flag
00640                {
00641                   if(Is_device_disconnection())
00642                   {
00643                       Host_ack_device_connection();
00644                       Host_ack_device_disconnection();
00645                       break;
00646                   }
00647                }
00648             }
00649             Host_enable_device_disconnection_interrupt();
00650             c = 0;
00651             while(c<200)           // wait 200ms after USB reset
00652             {
00653                if (Is_usb_event(EVT_HOST_SOF)) { Usb_ack_event(EVT_HOST_SOF); c++; }
00654                if (Is_host_emergency_exit() || Is_usb_bconnection_error_interrupt())  {break;}
00655             }
00656             Host_select_pipe(PIPE_CONTROL);
00657             Host_disable_pipe();
00658             Host_unallocate_memory();
00659             Host_enable_pipe();
00660            // Re-Configure the Ctrl Pipe according to the device ctrl EP
00661             host_configure_pipe(PIPE_CONTROL,                                \
00662                                 TYPE_CONTROL,                                \
00663                                 TOKEN_SETUP,                                 \
00664                                 EP_CONTROL,                                  \
00665                                 host_determine_pipe_size((U16)data_stage[OFFSET_FIELD_MAXPACKETSIZE]),\
00666                                 ONE_BANK,                                    \
00667                                 0                                            );
00668            // Give an absolute device address
00669             host_set_address(DEVICE_ADDRESS);
00670             Host_configure_address(DEVICE_ADDRESS);
00671             device_state = DEVICE_ADDRESSED;
00672          }
00673          else
00674          {
00675            device_state = DEVICE_ERROR;
00676          }
00677          break;
00678 
00679      //------------------------------------------------------
00680      //   DEVICE_ADDRESSED state
00681      //
00682      //   - Check if VID PID is in supported list
00683      //
00684       case DEVICE_ADDRESSED :
00685          if (CONTROL_GOOD == host_get_device_descriptor())
00686          {
00687            // Detect if the device connected belongs to the supported devices table
00688             if (HOST_TRUE == host_check_VID_PID())
00689             {
00690                Host_set_device_supported();
00691                Host_device_supported_action();
00692                device_state = DEVICE_CONFIGURED;
00693                #if (USB_OTG_FEATURE == ENABLED)
00694                  // In OTG A-HOST state, initiate a HNP if the OTG B-DEVICE has requested this session with a SRP
00695                  if ((OTG_ENABLE_HNP_AFTER_SRP == ENABLED) && Is_host_session_started_srp() && Is_usb_id_host())
00696                  {
00697                     device_state = A_INIT_HNP;
00698                  }
00699                  else
00700                  {
00701                    if (Is_device_supports_hnp())
00702                    {
00703                      if (CONTROL_GOOD != host_set_feature_a_hnp_support())
00704                      {
00705                        device_state = A_END_HNP_WAIT_VFALL;   // end session if Device STALLs the request
00706                      }
00707                    }
00708                  }
00709                #endif
00710             }
00711             else
00712             {
00713                #if (USB_OTG_FEATURE == ENABLED)
00714                // In OTG, if the B-DEVICE VID/PID does not match the Target Peripheral List, it is seen as "Unsupported"
00715                //  - a HNP must be initiated if the device supports it
00716                //  - an error message must be displayed (and difference must be made between "Std device" and "Hub")
00717                desc_temp = data_stage[OFFSET_DEV_DESC_CLASS]; // store the device class (for future hub check)
00718                if (otg_b_device_state != B_HOST)
00719                {
00720                  if (Is_host_session_started_srp())
00721                  {
00722                    if (CONTROL_GOOD == host_get_configuration_descriptor())
00723                    {
00724                      host_check_OTG_features();
00725                      if (Is_device_supports_hnp())
00726                      {
00727                        device_state = A_INIT_HNP;         // unsupported (or test) device will cause a HNP request
00728                      }
00729                      else
00730                      {
00731                        device_state = A_END_HNP_WAIT_VFALL;
00732                        if (desc_temp == HUB_CLASS_CODE)
00733                        {
00734                          // Display "Hub unsupported" message
00735                          Otg_print_new_failure_message(OTGMSG_UNSUPPORTED_HUB,OTG_TEMPO_4SEC);
00736                        }
00737                        else
00738                        {
00739                          // Display "Class unsupported" message
00740                          Otg_print_new_failure_message(OTGMSG_UNSUPPORTED,OTG_TEMPO_4SEC);
00741                        }
00742                      }
00743                    }
00744                    else
00745                    {
00746                      device_state = A_END_HNP_WAIT_VFALL;
00747                    }
00748                  }
00749                  else
00750                  {
00751                    device_state = A_INIT_HNP;
00752                  }
00753                }
00754                else
00755                {
00756                  Otg_print_new_failure_message(OTGMSG_UNSUPPORTED,OTG_TEMPO_4SEC);
00757                  Set_user_request_disc();   // ask end of session now
00758                  Set_user_request_suspend();
00759                }
00760                #else
00761                  #if (HOST_STRICT_VID_PID_TABLE==ENABLE)
00762                     device_state = DEVICE_ERROR;
00763                     Host_device_not_supported_action();
00764                  #else
00765                     device_state = DEVICE_CONFIGURED;
00766                  #endif
00767                #endif
00768             }
00769 
00770          }
00771          else // Can not get device descriptor
00772          {  device_state = DEVICE_ERROR; }
00773          break;
00774 
00775      //------------------------------------------------------
00776      //   DEVICE_CONFIGURED state
00777      //
00778      //   - Configure pipes for the supported interface
00779      //   - Send Set_configuration() request
00780      //   - Goto full operating mode (device ready)
00781      //
00782       case DEVICE_CONFIGURED :
00783          if (CONTROL_GOOD == host_get_configuration_descriptor())
00784          {
00785             if (HOST_FALSE != host_check_class()) // Class support OK?
00786             {
00787             #if (USB_OTG_FEATURE == ENABLED)
00788               // Collect information about peripheral OTG descriptor if present
00789               host_check_OTG_features();
00790             #endif
00791             #if (HOST_AUTO_CFG_ENDPOINT==ENABLE)
00792               host_auto_configure_endpoint();
00793             #else
00794                User_configure_endpoint(); // User call here instead of autoconfig
00795                Host_set_configured();     // Assumes config is OK with user config
00796             #endif
00797                if (Is_host_configured())
00798                {
00799                   if (CONTROL_GOOD== host_set_configuration(1))  // Send Set_configuration
00800                   {
00801                      // host_set_interface(interface_bound,interface_bound_alt_set);
00802                      // device and host are now fully configured
00803                      // goto DEVICE READY normal operation
00804                       device_state = DEVICE_READY;
00805                      // monitor device disconnection under interrupt
00806                       Host_enable_device_disconnection_interrupt();
00807                      // If user host application requires SOF interrupt event
00808                      // Keep SOF interrupt enable otherwize, disable this interrupt
00809                   #if (HOST_CONTINUOUS_SOF_INTERRUPT==DISABLE)
00810                       Host_disable_sof_interrupt();
00811                   #endif
00812                       new_device_connected=TRUE;
00813                       Enable_interrupt();
00814                       LOG_STR_CODE(log_device_enumerated);
00815                   }
00816                   else// Problem during Set_configuration request...
00817                   {   device_state = DEVICE_ERROR;  }
00818                }
00819             }
00820             else // device class not supported...
00821             {
00822                 device_state = DEVICE_ERROR;
00823                 LOG_STR_CODE(log_device_unsupported);
00824                 Host_device_class_not_supported_action();
00825             }
00826          }
00827          else // Can not get configuration descriptors...
00828          {  device_state = DEVICE_ERROR; }
00829          break;
00830 
00831      //------------------------------------------------------
00832      //   DEVICE_READY state
00833      //
00834      //   - Full standard operating mode
00835      //   - Nothing to do...
00836      //
00837       case DEVICE_READY:     // Host full std operating mode!
00838          new_device_connected=FALSE;
00839 
00840          // Handles user requests : "stop Vbus" and "suspend"
00841          #if (USB_OTG_FEATURE == ENABLED)
00842          if (Is_usb_id_host())
00843          {
00844            #if (OTG_VBUS_AUTO_WHEN_A_PLUG == DISABLED)
00845            if (Is_user_requested_vbus())
00846            {
00847              Ack_user_request_vbus();
00848              Usb_disable_vbus();
00849              Usb_disable_manual_vbus();
00850              Host_vbus_action();
00851              Clear_all_user_request();
00852              device_state = A_END_HNP_WAIT_VFALL;
00853            }
00854            #endif
00855 
00856            if (Is_user_requested_suspend() || Is_user_requested_hnp())
00857            {
00858              // Before entering suspend mode, A-Host must send a SetFeature(b_hnp_enable) if supported by the B-Periph
00859              Ack_user_request_hnp();
00860              Ack_user_request_suspend();
00861              device_state = A_INIT_HNP;
00862            }
00863          }
00864          #endif
00865          break;
00866 
00867      //------------------------------------------------------
00868      //   DEVICE_ERROR state
00869      //
00870      //   - Error state
00871      //   - Do custom action call (probably go to default mode...)
00872      //
00873       case DEVICE_ERROR :
00874       #if (USB_OTG_FEATURE == ENABLED)  // TBD
00875          device_state=DEVICE_UNATTACHED;
00876       #elif (HOST_ERROR_RESTART==ENABLE)
00877          device_state=DEVICE_UNATTACHED;
00878       #endif
00879          Host_device_error_action();
00880          break;
00881 
00882      //------------------------------------------------------
00883      //   DEVICE_SUSPENDED state
00884      //
00885      //   - Host application request to suspend the device activity
00886      //   - State machine comes here thanks to Host_request_suspend()
00887      //
00888       case DEVICE_SUSPENDED :
00889          // If OTG device, initiate a HNP process (go to specific state)
00890          if ((USB_OTG_FEATURE == ENABLED) && Is_peripheral_otg_device())
00891          {
00892            device_state = A_INIT_HNP;
00893          }
00894          else
00895          {
00896            device_state=DEVICE_WAIT_RESUME;    // wait for device resume event
00897            if(Is_device_supports_remote_wakeup()) // If the connected device supports remote wake up
00898            {
00899               if (CONTROL_GOOD != host_set_feature_remote_wakeup())
00900               {
00901                 device_state = DEVICE_DISCONNECTED;   // stop connexion because device has not accepted the feature
00902               }
00903            }
00904 
00905            LOG_STR_CODE(log_going_to_suspend);
00906            c = Is_host_sof_interrupt_enabled(); //Save current sof interrupt enable state
00907            Host_disable_sof_interrupt();
00908            Host_ack_sof();
00909            Host_disable_sof();           // Stop start of frame generation, this generates the suspend state
00910 
00911            Host_ack_remote_wakeup();
00912            Host_enable_remote_wakeup_interrupt();
00913            Host_ack_hwup();
00914            Host_enable_hwup_interrupt(); // Enable host wake-up interrupt
00915                                          // (this is the unique USB interrupt able to wake up the CPU core from power-down mode)
00916            Usb_freeze_clock();
00917            Stop_pll();
00918            Host_suspend_action();              // Custom action here! (for example go to power-save mode...)
00919          }
00920          break;
00921 
00922      //------------------------------------------------------
00923      //   DEVICE_WAIT_RESUME state
00924      //
00925      //   - Wait in this state till the host receives an upstream resume from the device
00926      //   - or the host software request the device to resume
00927      //
00928       case DEVICE_WAIT_RESUME :
00929          if(Is_usb_event(EVT_HOST_REMOTE_WAKEUP)|| Is_host_request_resume())// Remote wake up has been detected
00930                                                                             // or Local resume request has been received
00931          {
00932             if(Is_host_request_resume())       // Not a remote wakeup, but an host application request
00933             {
00934                Host_disable_hwup_interrupt();  // Wake up interrupt should be disable host is now wake up !
00935                   // CAUTION HWUP can be cleared only when USB clock is active
00936                Pll_start_auto();               // First Restart the PLL for USB operation
00937                Wait_pll_ready();               // Get sure pll is lock
00938                Usb_unfreeze_clock();           // Enable clock on USB interface
00939             }
00940             Host_ack_hwup();                // Clear HWUP interrupt flag
00941             Host_enable_sof();
00942 
00943             if (Is_usb_event(EVT_HOST_REMOTE_WAKEUP))
00944             {
00945               Usb_ack_event(EVT_HOST_REMOTE_WAKEUP);    // Ack software event
00946               Host_disable_sof_interrupt();
00947               Host_ack_device_disconnection();
00948               Host_disable_device_disconnection_interrupt();
00949 
00950               Host_send_resume();     // this other downstream resume is done to ensure min. 20ms of HOST DRIVING RESUME (not Device)
00951               while (!Is_device_disconnection() && Host_is_resume());
00952               c = 0;
00953               Host_ack_sof();
00954               while (!Is_device_disconnection() && (c != 12))   // wait for min. 10ms of device recovery time
00955               {
00956                 if (Is_host_sof())
00957                 {
00958                   Host_ack_sof();
00959                   c++;
00960                 }
00961               }
00962               if (Is_device_disconnection())
00963               {
00964                 usb_host_task_init();
00965                 device_state = DEVICE_DISCONNECTED;
00966                 Host_ack_remote_wakeup();        // Ack remote wake-up reception
00967                 Host_ack_request_resume();       // Ack software request
00968                 Host_ack_down_stream_resume();   // Ack down stream resume sent
00969                 #if ((USB_OTG_FEATURE == ENABLED) && (OTG_VBUS_AUTO_WHEN_A_PLUG == DISABLED))
00970                 Usb_disable_vbus();
00971                 Usb_disable_manual_vbus();
00972                 Host_vbus_action();
00973                 Clear_all_user_request();
00974                 while (Is_usb_vbus_high());
00975                 #endif
00976               }
00977               else
00978               {
00979                 device_state = DEVICE_READY;
00980                 Host_ack_remote_wakeup();        // Ack remote wake-up reception
00981                 Host_ack_request_resume();       // Ack software request
00982                 Host_ack_down_stream_resume();   // Ack down stream resume sent
00983               }
00984               Host_enable_device_disconnection_interrupt();
00985               Host_ack_sof();
00986             }
00987             else
00988             {
00989               Host_send_resume();                            // Send down stream resume
00990               //-----------------------
00991               // Work-around for case of Device disconnection during Suspend
00992               // The disconnection is never detected and the Resume bit remains high (and RSMEDI flag never set)
00993               // If the timeout elapses, it implies that the device has disconnected => macro is reset (to reset the Resume bit)
00994               dec = 0;
00995               while (dec < 0x4FFFF)   // several hundreds of ms
00996               {
00997                 if (Is_host_down_stream_resume())   // Wait Down stream resume sent
00998                 {
00999                   Host_ack_remote_wakeup();        // Ack remote wake-up reception
01000                   Host_ack_request_resume();       // Ack software request
01001                   Host_ack_down_stream_resume();   // Ack down stream resume sent
01002                   if(c) { Host_enable_sof_interrupt(); } // Restore SOF interrupt enable state before suspend
01003                   device_state=DEVICE_READY;       // Come back to full operating mode
01004                   LOG_STR_CODE(log_usb_resumed);
01005                   dec = 0x3FFFFE; // will cause a loop end
01006                 }
01007                 dec++;
01008               }
01009 
01010               if (dec != 0x3FFFFF)    // if resume failed
01011               {
01012                 usb_host_task_init();
01013                 device_state = DEVICE_DISCONNECTED;
01014                 #if ((USB_OTG_FEATURE == ENABLED) && (OTG_VBUS_AUTO_WHEN_A_PLUG == DISABLED))
01015                 Usb_disable_vbus();
01016                 Usb_disable_manual_vbus();
01017                 Host_vbus_action();
01018                 Clear_all_user_request();
01019                 while (Is_usb_vbus_high());
01020                 #endif
01021               }
01022               else
01023               {
01024                 c = 0;
01025                 Host_ack_sof();
01026                 while (!Is_device_disconnection() && (c != 12))   // wait for min. 10ms of device recovery time
01027                 {
01028                   if (Is_host_sof())
01029                   {
01030                     Host_ack_sof();
01031                     c++;
01032                   }
01033                 }
01034               }
01035               //-----------------------End of Work Around
01036             }
01037          }
01038          #if ((USB_OTG_FEATURE == ENABLED) && (OTG_VBUS_AUTO_WHEN_A_PLUG == DISABLED))
01039          // Handle "stop Vbus" user request
01040          if (Is_user_requested_vbus() && Is_usb_id_host())
01041          {
01042            Ack_user_request_vbus();
01043            Usb_disable_vbus();
01044            Usb_disable_manual_vbus();
01045            Host_vbus_action();
01046            Clear_all_user_request();
01047            device_state = A_END_HNP_WAIT_VFALL;
01048          }
01049          #endif
01050          break;
01051 
01052      //------------------------------------------------------
01053      //   DEVICE_DISCONNECTED state
01054      //
01055      //   - Device disconnection has been detected
01056      //   - Run scheduler in this state at least two times to get sure event is detected by all host application tasks
01057      //   - Go to DEVICE_DISCONNECTED_ACK state before DEVICE_UNATTACHED, to get sure scheduler calls all app tasks...
01058      //
01059       case DEVICE_DISCONNECTED :
01060          device_state = DEVICE_DISCONNECTED_ACK;
01061          break;
01062 
01063      //------------------------------------------------------
01064      //   DEVICE_DISCONNECTED_ACK state
01065      //
01066      //   - Device disconnection has been detected and managed bu applicatives tasks
01067      //   - Go to DEVICE_UNATTACHED state
01068      //
01069       case DEVICE_DISCONNECTED_ACK :
01070          host_disable_all_pipe();
01071          device_state = DEVICE_UNATTACHED;
01072          #if (USB_OTG_FEATURE == ENABLED)
01073          if (OTG_VBUS_AUTO_WHEN_A_PLUG == DISABLED)
01074          {
01075            Usb_disable_manual_vbus();
01076            Usb_disable_vbus();
01077            Host_vbus_action();
01078            Clear_all_user_request();
01079          }
01080          End_session_with_srp();
01081          Usb_ack_srp_interrupt();
01082          #endif
01083          break;
01084 
01085          
01086 #if (USB_OTG_FEATURE == ENABLED)
01087      //------------------------------------------------------
01088      //   OTG Specific states : A_PERIPHERAL (A-Host has been turned into a Device after a HNP)
01089      //
01090      //   - End session (and stop driving Vbus) when detecting suspend condition
01091      //   - Disconnect on user request
01092      //   - Call standard (non-OTG) device task to handle the Endpoint 0 requests
01093      //
01094       case A_PERIPHERAL:
01095         // End of role exchange : A_PERIPH go into DEVICE_DISCONNECTED mode : stop supplying VBUS
01096         if (Is_usb_event(EVT_USB_SUSPEND))
01097         {
01098           Clear_all_user_request();
01099           Usb_ack_event(EVT_USB_SUSPEND);
01100           Usb_disable_wake_up_interrupt();
01101           Usb_ack_role_exchange_interrupt();
01102           Usb_select_host();
01103           Usb_attach();
01104           Usb_unfreeze_clock();
01105           otg_b_device_state = B_IDLE;
01106           device_state = A_END_HNP_WAIT_VFALL;
01107           Usb_ack_srp_interrupt();
01108         }
01109         if (Is_user_requested_disc() || Is_user_requested_vbus())
01110         {
01111           Clear_all_user_request();
01112           Usb_disable_suspend_interrupt();
01113           Usb_ack_role_exchange_interrupt();
01114           Usb_select_host();
01115           Usb_unfreeze_clock();
01116           otg_b_device_state = B_IDLE;
01117           device_state = A_END_HNP_WAIT_VFALL;
01118         }
01119         if (!Is_device_disconnection_event() && (device_state != A_END_HNP_WAIT_VFALL))
01120         {
01121           usb_device_task();
01122         }
01123         break;
01124 
01125      //------------------------------------------------------
01126      //   OTG Specific states : A_INIT_HNP
01127      //
01128      //   - Software enters this state when it has been requested to initiate a HNP
01129      //   - Handle "set feature" commands such as B_HNP_ENABLE or REMOTE_WAKE_UP
01130      //   - Handle failures
01131      //
01132       case A_INIT_HNP:
01133         Ack_user_request_hnp();
01134         Ack_user_request_suspend();
01135         if (Is_peripheral_otg_device() || !Is_host_configured())
01136         {
01137           device_state = A_SUSPEND;
01138           if(Is_device_supports_remote_wakeup() && Is_host_configured()) // If the connected device supports remote wake up
01139           {
01140             if (CONTROL_GOOD == host_set_feature_remote_wakeup())
01141             {
01142               Host_ack_remote_wakeup();
01143               Host_enable_remote_wakeup_interrupt();
01144               Host_ack_hwup();
01145               Host_enable_hwup_interrupt(); // Enable host wake-up interrupt
01146             }
01147             else
01148             {
01149               device_state = A_END_HNP_WAIT_VFALL;   // stop connection because device has STALLed the feature
01150             }
01151           }
01152 
01153           if (Is_device_supports_hnp() || !Is_host_configured())
01154           {
01155             if (CONTROL_GOOD == host_set_feature_b_hnp_enable())
01156             {
01157               // B-Device has not STALLed the SetFeature
01158               Usb_host_accept_hnp();
01159               Usb_ack_role_exchange_interrupt();
01160               Usb_ack_hnp_error_interrupt();
01161               Usb_enable_role_exchange_interrupt();
01162               Usb_enable_hnp_error_interrupt();
01163               Host_disable_device_disconnection_interrupt();
01164               Host_disable_device_connection_interrupt();
01165             }
01166             else
01167             {
01168               Otg_print_new_failure_message(OTGMSG_DEVICE_NO_RESP,OTG_TEMPO_4SEC);
01169               device_state = A_END_HNP_WAIT_VFALL;
01170             }
01171           }
01172           Host_ack_remote_wakeup();
01173           Host_enable_remote_wakeup_interrupt();
01174           Init_ta_aidl_bdis_counter();
01175           Host_disable_sof_interrupt();
01176           Host_ack_sof();
01177           Host_disable_sof();           // Stop start of frame generation, this generates the suspend state
01178           Usb_disable_suspend_interrupt();
01179         }
01180         else
01181         {
01182           device_state = DEVICE_SUSPENDED;
01183         }
01184         break;
01185 
01186      //------------------------------------------------------
01187      //   OTG Specific states : A_SUSPEND
01188      //
01189      //   - A-Host enters this state when it has requested the B-DEVICE to start HNP, and have entered Suspend mode
01190      //   - Detects device silences (with HNP time-out management) and Resume condition
01191      //
01192       case A_SUSPEND:
01193         Usb_ack_suspend();
01194         // HNP is managed by interrupt (HNPERRI/ROLEEXI)
01195         if (Is_ta_aidl_bdis_counter_overflow())
01196         {
01197           device_state = A_END_HNP_WAIT_VFALL;   // stop Vbus = end of current session
01198         }
01199         if (Is_usb_event(EVT_HOST_HWUP)|| Is_host_request_resume())
01200         {
01201           device_state = DEVICE_WAIT_RESUME;
01202         }
01203         break;
01204 
01205      //------------------------------------------------------
01206      //   OTG Specific states : A_END_HNP_WAIT_VFALL
01207      //
01208      //   - A-PERIPH enters this state when it has detected a Suspend from the B-Host
01209      //   - It stop Vbus delivery and waits line discharge (to avoid spurious SRP detection)
01210      //
01211       case A_END_HNP_WAIT_VFALL:
01212         Usb_disable_manual_vbus();
01213         Usb_disable_vbus();
01214         usb_configuration_nb = 0;
01215         Host_vbus_action();
01216         Clear_all_user_request();
01217     #if   (OTG_COMPLIANCE_TRICKS == ENABLED)
01218         device_state = DEVICE_DISCONNECTED;
01219         usb_host_task_init();
01220     #else
01221         if (Is_usb_vbus_low())
01222         {
01223           usb_host_task_init();
01224           Init_ta_vbus_fall_counter();
01225           device_state = A_TEMPO_VBUS_DISCHARGE;
01226         }
01227     #endif
01228         break;
01229 
01230      //------------------------------------------------------
01231      //   OTG Specific states : A_TEMPO_VBUS_DISCHARGE
01232      //
01233      //   - State entered from A_END_HNP_WAIT_VFALL, when Vbus has just reached the vbus_valid threshold
01234      //   - In this state we wait long enough (50ms) to be sure that Vbus is not valid on the other device (if still connected)
01235      //   - When delay is elapsed, go to reset state
01236       case A_TEMPO_VBUS_DISCHARGE:
01237         if (otg_end_hnp_vbus_delay == 0)
01238         {
01239           Host_ack_device_connection();
01240           Host_ack_device_disconnection();
01241           Usb_ack_role_exchange_interrupt();
01242           Usb_ack_srp_interrupt();
01243           device_state = DEVICE_DISCONNECTED;
01244         }
01245         break;
01246 #endif
01247 
01248      //------------------------------------------------------
01249      //   default state
01250      //
01251      //   - Default case: ERROR
01252      //   - Goto no device state
01253      //
01254       default :
01255          device_state = DEVICE_UNATTACHED;
01256          break;
01257       }
01258 }
01259 
01260 //___ 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  _________________________
01261 
01274 U8 host_send_data(U8 pipe, U16 nb_data, U8 *buf)
01275 {
01276    U8 c;
01277    U8 status=PIPE_GOOD;
01278    U8 sav_int_sof_enable;
01279    U8 nak_timeout;
01280    U16 cpt_nak;
01281    U8 nb_data_loaded;
01282 
01283    sav_int_sof_enable=Is_host_sof_interrupt_enabled();  // Save state of enable sof interrupt
01284    Host_enable_sof_interrupt();
01285    Host_select_pipe(pipe);
01286    Host_set_token_out();
01287    Host_ack_out_sent();
01288    while (nb_data != 0)         // While there is something to send...
01289    {
01290       Host_unfreeze_pipe();
01291      // Prepare data to be sent
01292       c = Host_get_pipe_length();
01293       if ( (U16)c > nb_data)
01294       {
01295          nb_data_loaded = (U8)nb_data;
01296          c = nb_data;
01297       }
01298       else
01299       {  nb_data_loaded = c; }
01300       while (c!=0)              // Load Pipe buffer
01301       {
01302          Host_write_byte(*buf++);
01303          c--;
01304       }
01305       private_sof_counter=0;    // Reset the counter in SOF detection sub-routine
01306       cpt_nak=0;
01307       nak_timeout=0;
01308       Host_ack_out_sent();
01309       Host_send_out();
01310       while (!Is_host_out_sent())
01311       {
01312          if (Is_host_emergency_exit())// Async disconnection or role change detected under interrupt
01313          {
01314             status=PIPE_DELAY_TIMEOUT;
01315             Host_reset_pipe(pipe);
01316             goto host_send_data_end;
01317          }
01318          #if (TIMEOUT_DELAY_ENABLE==ENABLE)
01319          if (private_sof_counter>=250)            // Count 250ms (250sof)
01320          {
01321             private_sof_counter=0;
01322             if (nak_timeout++>=TIMEOUT_DELAY) // Inc timeout and check for overflow
01323             {
01324                status=PIPE_DELAY_TIMEOUT;
01325                Host_reset_pipe(pipe);
01326                goto host_send_data_end;
01327             }
01328          }
01329          #endif
01330          if (Is_host_pipe_error()) // Any error ?
01331          {
01332             status = Host_error_status();
01333             Host_ack_all_errors();
01334             goto host_send_data_end;
01335          }
01336          if (Is_host_stall())      // Stall management
01337          {
01338             status =PIPE_STALL;
01339             Host_ack_stall();
01340             goto host_send_data_end;
01341          }
01342          #if (NAK_TIMEOUT_ENABLE==ENABLE)
01343          if(Is_host_nak_received())  //NAK received
01344          {
01345             Host_ack_nak_received();
01346             if (cpt_nak++>NAK_SEND_TIMEOUT)
01347             {
01348                status = PIPE_NAK_TIMEOUT;
01349                Host_reset_pipe(pipe);
01350                goto host_send_data_end;
01351             }
01352          }
01353          #endif
01354       }
01355       // Here OUT sent
01356       nb_data -= nb_data_loaded;
01357       status=PIPE_GOOD;         // Frame correctly sent
01358       Host_ack_out_sent();
01359    }
01360    Host_freeze_pipe();
01361 host_send_data_end:
01362   // Restore sof interrupt enable state
01363    if (sav_int_sof_enable==FALSE)   {Host_disable_sof_interrupt();}
01364   // And return...
01365    return ((U8)status);
01366 }
01367 
01368 
01369 
01382 U8 host_get_data(U8 pipe, U16 *nb_data, U8 *buf)
01383 {
01384    U8 status=PIPE_GOOD;
01385    U8 sav_int_sof_enable;
01386    U8 nak_timeout;
01387    U16 n,i;
01388    U16 cpt_nak;
01389 
01390    n=*nb_data;
01391    *nb_data=0;
01392    sav_int_sof_enable=Is_host_sof_interrupt_enabled();
01393    Host_enable_sof_interrupt();
01394    Host_select_pipe(pipe);
01395    Host_continuous_in_mode();
01396    Host_set_token_in();
01397    Host_ack_in_received();
01398    while (n)              // While missing data...
01399    {
01400       Host_unfreeze_pipe();
01401       Host_send_in();
01402       private_sof_counter=0; // Reset the counter in SOF detection sub-routine
01403       nak_timeout=0;
01404       cpt_nak=0;
01405       while (!Is_host_in_received())
01406       {
01407          if (Is_host_emergency_exit())   // Async disconnection or role change detected under interrupt
01408          {
01409             status=PIPE_DELAY_TIMEOUT;
01410             Host_reset_pipe(pipe);
01411             goto host_get_data_end;
01412          }
01413          #if (TIMEOUT_DELAY_ENABLE==ENABLE)
01414          if (private_sof_counter>=250)   // Timeout management
01415          {
01416             private_sof_counter=0;       // Done in host SOF interrupt
01417             if (nak_timeout++>=TIMEOUT_DELAY)// Check for local timeout
01418             {
01419                status=PIPE_DELAY_TIMEOUT;
01420                Host_reset_pipe(pipe);
01421                goto host_get_data_end;
01422             }
01423          }
01424          #endif
01425          if(Is_host_pipe_error())        // Error management
01426          {
01427             status = Host_error_status();
01428             Host_ack_all_errors();
01429             goto host_get_data_end;
01430          }
01431          if(Is_host_stall())             // STALL management
01432          {
01433             status =PIPE_STALL;
01434             Host_reset_pipe(pipe);
01435             Host_ack_stall();
01436             goto host_get_data_end;
01437          }
01438          #if (NAK_TIMEOUT_ENABLE==ENABLE)
01439          if(Is_host_nak_received())  //NAK received
01440          {
01441             Host_ack_nak_received();
01442             if (cpt_nak++>NAK_RECEIVE_TIMEOUT)
01443             {
01444                status = PIPE_NAK_TIMEOUT;
01445                Host_reset_pipe(pipe);
01446                goto host_get_data_end;
01447             }
01448          }
01449          #endif
01450       }
01451       status=PIPE_GOOD;
01452       Host_freeze_pipe();
01453       if (Host_byte_counter()<=n)
01454       {
01455          if ((Host_byte_counter() < n)&&(Host_byte_counter()<Host_get_pipe_length()))
01456          { n=0;}
01457          else
01458          { n-=Host_byte_counter();}
01459          (*nb_data)+=Host_byte_counter();  // Update nb of byte received
01460          for (i=Host_byte_counter();i;i--)
01461          { *buf=Host_read_byte(); buf++;}
01462       }
01463       else  // more bytes received than expected
01464       {     // TODO error code management
01465          *nb_data+=n;
01466          for (i=n;i;i--)                  // Byte number limited to the initial request (limit tab over pb)
01467          {  *buf=Host_read_byte(); buf++; }
01468          n=0;
01469       }
01470       Host_ack_in_received();
01471    }
01472    Host_freeze_pipe();
01473 host_get_data_end:
01474    if (sav_int_sof_enable==FALSE)
01475    {
01476       Host_disable_sof_interrupt();
01477    }
01478    return ((U8)status);
01479 }
01480 
01481 
01482 //___ 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  _________________________
01483 
01484 #if (USB_HOST_PIPE_INTERRUPT_TRANSFER == ENABLE)
01485 
01486 void reset_it_pipe_str(void)
01487 {
01488    U8 i;
01489    for(i=0;i<MAX_EP_NB;i++)
01490    {
01491       it_pipe_str[i].enable=DISABLE;
01492       it_pipe_str[i].timeout=0;
01493    }
01494 }
01495 
01496 U8 is_any_interrupt_pipe_active(void)
01497 {
01498    U8 i;
01499    for(i=0;i<MAX_EP_NB;i++)
01500    {
01501       if(it_pipe_str[i].enable==ENABLE) return TRUE;
01502    }
01503    return FALSE;
01504 }
01505 
01519 U8 host_get_data_interrupt(U8 pipe, U16 nb_data, U8 *buf,void(*handle)(U8 status, U16 nb_byte))
01520 {
01521    Host_select_pipe(pipe);
01522    if(it_pipe_str[pipe].enable==ENABLE)
01523    {
01524       return HOST_FALSE;
01525    }
01526    else
01527    {
01528       if(is_any_interrupt_pipe_active()==FALSE)
01529       {
01530          g_sav_int_sof_enable=Is_host_sof_interrupt_enabled();
01531          Host_enable_sof_interrupt();
01532       }
01533       it_pipe_str[pipe].enable=ENABLE;
01534       it_pipe_str[pipe].nb_byte_to_process=nb_data;
01535       it_pipe_str[pipe].nb_byte_processed=0;
01536       it_pipe_str[pipe].ptr_buf=buf;
01537       it_pipe_str[pipe].handle=handle;
01538       it_pipe_str[pipe].timeout=0;
01539       it_pipe_str[pipe].nak_timeout=NAK_RECEIVE_TIMEOUT;
01540 
01541       private_sof_counter=0;           // Reset the counter in SOF detection sub-routine
01542       Host_reset_pipe(pipe);
01543       Host_enable_stall_interrupt();
01544       #if (NAK_TIMEOUT_ENABLE==ENABLE)
01545       Host_enable_nak_interrupt();
01546       #endif
01547       Host_enable_error_interrupt();
01548       Host_enable_receive_interrupt();
01549       Host_ack_stall();
01550       Host_ack_nak_received();
01551 
01552       Host_continuous_in_mode();
01553       Host_set_token_in();
01554       Host_unfreeze_pipe();
01555       return HOST_TRUE;
01556    }
01557 }
01558 
01570 U8 host_send_data_interrupt(U8 pipe, U16 nb_data, U8 *buf, void(*handle)(U8 status, U16 nb_byte))
01571 {
01572    U8 i;
01573    U8 *ptr_buf=buf;
01574 
01575    Host_select_pipe(pipe);
01576    if(it_pipe_str[pipe].enable==ENABLE)
01577    {
01578       return HOST_FALSE;
01579    }
01580    else
01581    {
01582       if(is_any_interrupt_pipe_active()==FALSE)
01583       {
01584          g_sav_int_sof_enable=Is_host_sof_interrupt_enabled();
01585          Host_enable_sof_interrupt();
01586       }
01587       it_pipe_str[pipe].enable=ENABLE;
01588       it_pipe_str[pipe].nb_byte_to_process=nb_data;
01589       it_pipe_str[pipe].nb_byte_processed=0;
01590       it_pipe_str[pipe].ptr_buf=buf;
01591       it_pipe_str[pipe].handle=handle;
01592       it_pipe_str[pipe].timeout=0;
01593       it_pipe_str[pipe].nak_timeout=NAK_SEND_TIMEOUT;
01594       it_pipe_str[pipe].nb_byte_on_going=0;
01595 
01596       Host_reset_pipe(pipe);
01597       Host_unfreeze_pipe();
01598       // Prepare data to be sent
01599       i = Host_get_pipe_length();
01600       if ( i > nb_data)                // Pipe size> remaining data
01601       {
01602          i = nb_data;
01603          nb_data = 0;
01604       }
01605       else                             // Pipe size < remaining data
01606       {
01607          nb_data -= i;
01608       }
01609       it_pipe_str[pipe].nb_byte_on_going+=i;   // Update nb data processed
01610       while (i!=0)                    // Load Pipe buffer
01611       {  Host_write_byte(*ptr_buf++); i--;
01612       }
01613       private_sof_counter=0;          // Reset the counter in SOF detection sub-routine
01614       it_pipe_str[pipe].timeout=0;    // Refresh timeout counter
01615       Host_ack_out_sent();
01616       Host_ack_stall();
01617       Host_ack_nak_received();
01618 
01619       Host_enable_stall_interrupt();
01620       Host_enable_error_interrupt();
01621       #if (NAK_TIMEOUT_ENABLE==ENABLE)
01622       Host_enable_nak_interrupt();
01623       #endif
01624       Host_enable_transmit_interrupt();
01625       Host_send_out();                // Send the USB frame
01626       return HOST_TRUE;
01627    }
01628 }
01629 
01635 #ifdef AVRGCC
01636  ISR(USB_COM_vect)
01637 #else
01638 #pragma vector = USB_ENDPOINT_PIPE_vect
01639 __interrupt void usb_pipe_interrupt()
01640 #endif
01641 {
01642    U8 pipe_nb;
01643    U8 *ptr_buf;
01644    void  (*fct_handle)(U8 status,U16 nb_byte);
01645    U16 n;
01646    U8 i;
01647    U8 do_call_back=FALSE;
01648 
01649    pipe_nb_save = Host_get_selected_pipe();       // Important! Save here working pipe number
01650    pipe_nb=usb_get_nb_pipe_interrupt();  // work with the correct pipe number that generates the interrupt
01651    Host_select_pipe(pipe_nb);                        // Select this pipe
01652    fct_handle=*(it_pipe_str[pipe_nb].handle);
01653 
01654    // Now try to detect what event generate an interrupt...
01655 
01656    if (Is_host_pipe_error())             // Any error ?
01657    {
01658       it_pipe_str[pipe_nb].status = Host_error_status();
01659       it_pipe_str[pipe_nb].enable=DISABLE;
01660       Host_stop_pipe_interrupt(pipe_nb);
01661       Host_ack_all_errors();
01662       do_call_back=TRUE;
01663       goto usb_pipe_interrupt_end;
01664    }
01665 
01666    if (Is_host_stall())                  // Stall handshake received ?
01667    {
01668       it_pipe_str[pipe_nb].status=PIPE_STALL;
01669       it_pipe_str[pipe_nb].enable=DISABLE;
01670       Host_stop_pipe_interrupt(pipe_nb);
01671       do_call_back=TRUE;
01672       goto usb_pipe_interrupt_end;
01673    }
01674 
01675    #if (NAK_TIMEOUT_ENABLE==ENABLE)
01676    if (Is_host_nak_received())           // NAK ?
01677    {
01678       Host_ack_nak_received();
01679       // check if number of NAK timeout error occurs (not for interrupt type pipe)
01680       if((--it_pipe_str[pipe_nb].nak_timeout==0) && (Host_get_pipe_type()!=TYPE_INTERRUPT))
01681       {
01682          it_pipe_str[pipe_nb].status=PIPE_NAK_TIMEOUT;
01683          it_pipe_str[pipe_nb].enable=DISABLE;
01684          Host_stop_pipe_interrupt(pipe_nb);
01685          do_call_back=TRUE;
01686          goto usb_pipe_interrupt_end;
01687       }
01688    }
01689    #endif
01690 
01691    if (Is_host_in_received())            // Pipe IN reception ?
01692    {
01693       ptr_buf=it_pipe_str[pipe_nb].ptr_buf+it_pipe_str[pipe_nb].nb_byte_processed;       // Build pointer to data buffer
01694       n=it_pipe_str[pipe_nb].nb_byte_to_process-it_pipe_str[pipe_nb].nb_byte_processed;  // Remaining data bytes
01695       Host_freeze_pipe();
01696       if (Host_byte_counter()<=n)
01697       {
01698          if ((Host_byte_counter() < n)&&(Host_byte_counter()<Host_get_pipe_length())) //Received less than remaining, but less than pipe capacity
01699                                                                                       //TODO: error code
01700          {
01701             n=0;
01702          }
01703          else
01704          {
01705             n-=Host_byte_counter();
01706          }
01707          it_pipe_str[pipe_nb].nb_byte_processed+=Host_byte_counter();  // Update nb of byte received
01708          for (i=Host_byte_counter();i;i--)
01709          { *ptr_buf=Host_read_byte(); ptr_buf++;}
01710       }
01711       else  // more bytes received than expected
01712       {     // TODO error code management
01713          it_pipe_str[pipe_nb].nb_byte_processed+=n;
01714          for (i=n;i;i--)                  // Byte number limited to the initial request (limit tab over pb)
01715          { *ptr_buf=Host_read_byte(); ptr_buf++;}
01716          n=0;
01717       }
01718       Host_ack_in_received();
01719       if(n>0) //still something to process
01720       {
01721          Host_unfreeze_pipe();            // Request another IN transfer
01722          Host_send_in();
01723          private_sof_counter=0;           // Reset the counter in SOF detection sub-routine
01724          it_pipe_str[pipe_nb].timeout=0;  // Reset timeout
01725          it_pipe_str[pipe_nb].nak_timeout=NAK_RECEIVE_TIMEOUT;
01726 
01727       }
01728       else //end of transfer
01729       {
01730          it_pipe_str[pipe_nb].enable=DISABLE;
01731          it_pipe_str[pipe_nb].status=PIPE_GOOD;
01732          Host_stop_pipe_interrupt(pipe_nb);
01733          do_call_back=TRUE;
01734       }
01735    }
01736 
01737    if(Is_host_out_sent())                  // Pipe OUT sent ?
01738    {
01739       Host_ack_out_sent();
01740       it_pipe_str[pipe_nb].nb_byte_processed+=it_pipe_str[pipe_nb].nb_byte_on_going;
01741       it_pipe_str[pipe_nb].nb_byte_on_going=0;
01742       ptr_buf=it_pipe_str[pipe_nb].ptr_buf+it_pipe_str[pipe_nb].nb_byte_processed;       // Build pointer to data buffer
01743       n=it_pipe_str[pipe_nb].nb_byte_to_process-it_pipe_str[pipe_nb].nb_byte_processed;  // Remaining data bytes
01744       if(n>0)   // Still data to process...
01745       {
01746          Host_unfreeze_pipe();
01747         // Prepare data to be sent
01748          i = Host_get_pipe_length();
01749          if ( i > n)     // Pipe size> remaining data
01750          {
01751             i = n;
01752             n = 0;
01753          }
01754          else                // Pipe size < remaining data
01755          {  n -= i; }
01756          it_pipe_str[pipe_nb].nb_byte_on_going+=i;   // Update nb data processed
01757          while (i!=0)                     // Load Pipe buffer
01758          {
01759             Host_write_byte(*ptr_buf++); i--;
01760          }
01761          private_sof_counter=0;           // Reset the counter in SOF detection sub-routine
01762          it_pipe_str[pipe_nb].timeout=0;  // Refresh timeout counter
01763          it_pipe_str[pipe_nb].nak_timeout=NAK_SEND_TIMEOUT;
01764          Host_send_out();                 // Send the USB frame
01765       }
01766       else                                //n==0 Transfer is finished
01767       {
01768          it_pipe_str[pipe_nb].enable=DISABLE;    // Tranfer end
01769          it_pipe_str[pipe_nb].status=PIPE_GOOD;  // Status OK
01770          Host_stop_pipe_interrupt(pipe_nb);
01771          do_call_back=TRUE;
01772       }
01773    }
01774 
01775 usb_pipe_interrupt_end:
01776    Host_select_pipe(pipe_nb_save);   // Restore pipe number !!!!
01777    if (is_any_interrupt_pipe_active()==FALSE)    // If no more transfer is armed
01778    {
01779       if (g_sav_int_sof_enable==FALSE)
01780       {
01781          Host_disable_sof_interrupt();
01782       }
01783    }
01784    if(do_call_back)      // Any callback functions to perform ?
01785    {
01786       fct_handle(it_pipe_str[pipe_nb].status,it_pipe_str[pipe_nb].nb_byte_processed);
01787    }
01788 }
01789 #endif
01790 
01791 
01792 #endif // USB_HOST_FEATURE ENABLE
01793 

Generated on Mon Feb 19 09:31:47 2007 for Atmel by  doxygen 1.5.1-p1