usb_host_enum.c

Go to the documentation of this file.
00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 //_____ I N C L U D E S ____________________________________________________
00017 
00018 #include "config.h"
00019 #include "conf_usb.h"
00020 #include "lib_mcu/usb/usb_drv.h"
00021 #include "usb_host_enum.h"
00022 #include "modules/usb/usb_task.h"
00023 #include "usb_host_task.h"
00024 
00025 
00026 #if ((USB_OTG_FEATURE == ENABLED) && (TARGET_BOARD==SPIDER))
00027    #include "lib_board/lcd/lcd_drv.h"
00028 #endif
00029 
00030 //_____ M A C R O S ________________________________________________________
00031 
00032 
00033 //_____ D E F I N I T I O N ________________________________________________
00034 
00035 //_____ P R I V A T E   D E C L A R A T I O N ______________________________
00036 
00037 #if (USB_HOST_FEATURE == DISABLED)
00038    #warning trying to compile a file used with the USB HOST without USB_HOST_FEATURE enabled
00039 #endif
00040 
00041 #if (MAX_INTERFACE_SUPPORTED<1)
00042 #error MAX_INTERFACE_SUPPORTED<1 : The host controller should support at least one interface...
00043 #endif
00044 
00045 #if (USB_HOST_FEATURE == ENABLED)
00046 extern S_usb_setup_data usb_request;
00047 
00048 
00049 #ifndef VID_PID_TABLE
00050    #error VID_PID_TABLE should be defined somewhere (conf_usb.h)
00051   //   VID_PID_TABLE format definition:
00052   //   #define VID_PID_TABLE      {VID1, number_of_pid_for_this_VID1, PID11_value,..., PID1X_Value \
00053   //                              ...\
00054   //                              ,VIDz, number_of_pid_for_this_VIDz, PIDz1_value,..., PIDzX_Value}
00055 #endif
00056 
00057 #ifndef CLASS_SUBCLASS_PROTOCOL
00058    #error CLASS_SUBCLASS_PROTOCOL shoud be defined somewhere (conf_usb.h)
00059   //   CLASS_SUBCLASS_PROTOCOL format definition:
00060   //   #define CLASS_SUBCLASS_PROTOCOL  {CLASS1, SUB_CLASS1,PROTOCOL1, \
00061   //                                     ...\
00062   //                                     CLASSz, SUB_CLASSz,PROTOCOLz}
00063 #endif
00064 
00065 
00067 U16 registered_VID_PID[]   = VID_PID_TABLE;
00068 
00070 U8  registered_class[]     = CLASS_SUBCLASS_PROTOCOL;
00071 
00073 //  This table is dynamically built with the "host_configure_endpoint_class" function
00074 U8 ep_table[MAX_EP_NB]={0,0,0,0,0,0,0};
00075 
00077 U8 nb_interface_supported=0;
00078 
00079 S_interface interface_supported[MAX_INTERFACE_SUPPORTED];
00080 
00082 U16 device_PID;
00084 U16 device_VID;
00086 U8 bmattributes;
00088 U8 maxpower;
00089 
00090 //_____ D E C L A R A T I O N ______________________________________________
00091 
00102 U8 host_check_VID_PID(void)
00103 {
00104 U8  c,d;
00105 
00106    // Rebuild VID PID from data stage
00107    LSB(device_VID) = data_stage[OFFSET_FIELD_LSB_VID];
00108    MSB(device_VID) = data_stage[OFFSET_FIELD_MSB_VID];
00109    LSB(device_PID) = data_stage[OFFSET_FIELD_LSB_PID];
00110    MSB(device_PID) = data_stage[OFFSET_FIELD_MSB_PID];
00111 
00112    // Compare detected VID PID with supported table
00113    c=0;
00114 
00115    while (c< sizeof(registered_VID_PID)/2)   // /2 because registered_VID_PID table is U16...
00116    {
00117       if (registered_VID_PID[c] == device_VID)   // VID is correct
00118       {
00119          d = (U8)registered_VID_PID[c+1];    // store nb of PID for this VID
00120          while (d != 0)
00121          {
00122             if (registered_VID_PID[c+d+1] == device_PID)
00123             {
00124                return HOST_TRUE;
00125             }
00126             d--;
00127          }
00128       }
00129       c+=registered_VID_PID[c+1]+2;
00130    }
00131    return HOST_FALSE;
00132 }
00133 
00134 #if (USB_OTG_FEATURE == ENABLED)
00135 
00144 U8 host_check_OTG_features(void)
00145 {
00146   U8 index;     // variable offset used to search the OTG descriptor
00147   U8 nb_bytes;  // number of bytes of the config descriptor
00148 
00149   Peripheral_is_not_otg_device();  // init
00150   otg_features_supported = 0;
00151 
00152   nb_bytes = data_stage[OFFSET_FIELD_TOTAL_LENGHT];
00153   index = 0;
00154   if (nb_bytes > 0x09)   // check this is not a reduced/uncomplete config descriptor
00155   {
00156     while (index < nb_bytes)  // search in the descriptors
00157     {
00158       if (data_stage[index+OFFSET_FIELD_DESCRIPTOR_TYPE] != OTG_DESCRIPTOR)   // IS the pointed descriptor THE OTG DESCRIPTOR ?
00159       {
00160         index += data_stage[index+OFFSET_DESCRIPTOR_LENGHT];    // NO, skip to next descriptor
00161       }
00162       else
00163       {
00164         if (data_stage[index+OFFSET_DESCRIPTOR_LENGHT] == OTG_DESCRIPTOR_bLength)   // YES, check descriptor length
00165         {
00166           Peripheral_is_otg_device();   // an OTG descriptor has been found
00167           otg_features_supported = data_stage[index+OFFSET_FIELD_OTG_FEATURES];    // load otg features supported
00168           return HOST_TRUE;
00169         }
00170         else
00171         {
00172           return HOST_FALSE;    // bad descriptor length
00173         }
00174       }
00175     }
00176   }
00177   else
00178   {
00179     return HOST_FALSE;    // this was only a reduced/uncomplete configuration descriptor
00180   }
00181   return HOST_TRUE;
00182 }
00183 #endif
00184 
00185 
00197 U8 host_check_class(void)
00198 {
00199 U8  c;
00200 T_DESC_OFFSET  descriptor_offset;
00201 T_DESC_OFFSET  conf_offset_end;
00202 U16  config_size;
00203 U8  device_class;
00204 U8  device_subclass;
00205 U8  device_protocol;
00206 
00207    nb_interface_supported=0;   //First asumes ,no interface is supported!
00208    if (data_stage[OFFSET_FIELD_DESCRIPTOR_TYPE] != CONFIGURATION_DESCRIPTOR)           // check if configuration descriptor
00209    { return HOST_FALSE;}
00210    LSB(config_size) = data_stage[OFFSET_FIELD_TOTAL_LENGHT];
00211    MSB(config_size) = data_stage[OFFSET_FIELD_TOTAL_LENGHT+1];
00212    bmattributes = data_stage[OFFSET_FIELD_BMATTRIBUTES];
00213    maxpower = data_stage[OFFSET_FIELD_MAXPOWER];
00214    descriptor_offset = 0;
00215    conf_offset_end = descriptor_offset + config_size;
00216 
00217    // Look in all interfaces declared in the configuration
00218    while(descriptor_offset < conf_offset_end)
00219    {
00220       // Find next interface descriptor
00221       while (data_stage[descriptor_offset+OFFSET_FIELD_DESCRIPTOR_TYPE] != INTERFACE_DESCRIPTOR)
00222       {
00223          descriptor_offset += data_stage[descriptor_offset];
00224          if(descriptor_offset >= conf_offset_end)
00225          {
00226             if(nb_interface_supported)
00227             {return HOST_TRUE;}
00228             else return HOST_FALSE;
00229          }
00230       }
00231       // Found an interface descriptor
00232       // Get charateristics of this interface
00233       device_class    = data_stage[descriptor_offset + OFFSET_FIELD_CLASS];
00234       device_subclass = data_stage[descriptor_offset + OFFSET_FIELD_SUB_CLASS];
00235       device_protocol = data_stage[descriptor_offset + OFFSET_FIELD_PROTOCOL];
00236       // Look in registered class table for match
00237       c=0;
00238       while (c< sizeof(registered_class))
00239       {
00240          if (registered_class[c] == device_class)                 // class is correct!
00241          {
00242             if (registered_class[c+1] == device_subclass)         // sub class is correct!
00243             {
00244                if (registered_class[c+2] == device_protocol)      // protocol is correct!
00245                {
00246                   // Prepare for another item CLASS/SUB_CLASS/PROTOCOL in table
00247                   c+=3;
00248                   // Store this interface as supported interface
00249                   // Memorize its interface nb
00250                   interface_supported[nb_interface_supported].interface_nb=data_stage[descriptor_offset+OFFSET_FIELD_INTERFACE_NB];
00251                   //          its alternate setting
00252                   interface_supported[nb_interface_supported].altset_nb=data_stage[descriptor_offset+OFFSET_FIELD_ALT];
00253                   //          its USB class
00254                   interface_supported[nb_interface_supported].class=device_class;
00255                   //          its USB subclass
00256                   interface_supported[nb_interface_supported].subclass=device_subclass;
00257                   //          its USB protocol
00258                   interface_supported[nb_interface_supported].protocol=device_protocol;
00259                   //          the number of endpoints associated to this interface
00260                   //          Note: The associated endpoints addresses are stored during pipe attribution...
00261                   interface_supported[nb_interface_supported].nb_ep=data_stage[descriptor_offset+OFFSET_FIELS_NB_OF_EP];
00262                   // Update the number of interface supported
00263                   nb_interface_supported++;
00264                   // Check the maximum number of interfaces we can support
00265                   if(nb_interface_supported>=MAX_INTERFACE_SUPPORTED)
00266                   {
00267                      return HOST_TRUE;
00268                   }
00269                }
00270             }
00271          }
00272          c+=3; // Check other item CLASS/SUB_CLASS/PROTOCOL in table
00273       }
00274       descriptor_offset += data_stage[descriptor_offset]; // Next descriptor
00275       if(descriptor_offset > SIZEOF_DATA_STAGE)           // Check overflow
00276       {
00277          if(nb_interface_supported)
00278          {return HOST_TRUE;}
00279          else return HOST_FALSE;
00280       }
00281    }
00282    if(nb_interface_supported)
00283    { return HOST_TRUE; }
00284    else return HOST_FALSE;
00285 }
00286 
00293 U8 host_auto_configure_endpoint()
00294 {
00295 U8  nb_endpoint_to_configure;
00296 T_DESC_OFFSET  descriptor_offset;
00297 U8  physical_pipe=1;   // =1 cause lookup table assumes that physiacl pipe 0 is reserved for control
00298 U8 i;
00299 U8 ep_index;
00300 
00301    // For all interfaces to configure...
00302    for(i=0;i<nb_interface_supported;i++)
00303    {
00304       ep_index=0;
00305       // First look for the target interface descriptor offset
00306       descriptor_offset = get_interface_descriptor_offset(interface_supported[i].interface_nb,interface_supported[i].altset_nb);
00307       // Get the number of endpoint to configure for this interface
00308       nb_endpoint_to_configure = data_stage[descriptor_offset+OFFSET_FIELS_NB_OF_EP];
00309       // Get the first Endpoint descriptor offset to configure
00310       descriptor_offset += data_stage[descriptor_offset+OFFSET_DESCRIPTOR_LENGHT];  // pointing on endpoint descriptor
00311 
00312       // While there is at least one pipe to configure
00313       while (nb_endpoint_to_configure)
00314       {
00315          // Check and look for an Endpoint descriptor
00316          while (data_stage[descriptor_offset+OFFSET_FIELD_DESCRIPTOR_TYPE] != ENDPOINT_DESCRIPTOR)
00317          {
00318             descriptor_offset += data_stage[descriptor_offset];
00319             if(descriptor_offset > SIZEOF_DATA_STAGE)   // No more endpoint descriptor found -> Errror !
00320             {  return HOST_FALSE; }
00321          }
00322 
00323         // Select the new physical pipe to configure and get ride of any previous configuration for this physical pipe
00324          Host_select_pipe(physical_pipe);
00325          Host_disable_pipe();
00326          Usb_unallocate_memory();
00327          Host_enable_pipe();
00328 
00329          // Build the pipe configuration according to the endpoint descriptors fields received
00330          //
00331          // host_configure_pipe(
00332          //    physical_pipe,                                                                    // pipe nb in USB interface
00333          //    data_stage[descriptor_offset+OFFSET_FIELD_EP_TYPE],                               // pipe type (interrupt/BULK/ISO)
00334          //    Get_pipe_token(data_stage[descriptor_offset+OFFSET_FIELD_EP_ADDR]),               // pipe addr
00335          //    (data_stage[descriptor_offset+2] & MSK_EP_DIR),                                   // pipe dir (IN/OUT)
00336          //    host_determine_pipe_size((U16)data_stage[descriptor_offset+OFFSET_FIELD_EP_SIZE]),// pipe size
00337          //    ONE_BANK,                                                                         // bumber of bank to allocate for pipe
00338          //    data_stage[descriptor_offset+OFFSET_FIELD_EP_INTERVAL]                            // interrupt period (for interrupt pipe)
00339          //  );
00340          host_configure_pipe(                                                          \
00341             physical_pipe,                                                             \
00342             data_stage[descriptor_offset+OFFSET_FIELD_EP_TYPE],                        \
00343             Get_pipe_token(data_stage[descriptor_offset+OFFSET_FIELD_EP_ADDR]),        \
00344             (data_stage[descriptor_offset+OFFSET_FIELD_EP_ADDR] & MSK_EP_DIR),                            \
00345             host_determine_pipe_size((U16)data_stage[descriptor_offset+OFFSET_FIELD_EP_SIZE]),\
00346             ONE_BANK,                                                                  \
00347             data_stage[descriptor_offset+OFFSET_FIELD_EP_INTERVAL]                     \
00348          );
00349 
00350          // Update Physical Pipe lookup table with device enpoint address
00351          ep_table[physical_pipe]=data_stage[descriptor_offset+OFFSET_FIELD_EP_ADDR];
00352          physical_pipe++;
00353          // Update endpoint addr table in supported interface structure
00354          interface_supported[i].ep_addr[ep_index++]=data_stage[descriptor_offset+OFFSET_FIELD_EP_ADDR];
00355          descriptor_offset += data_stage[descriptor_offset];             // pointing on next descriptor
00356 
00357          // All target endpoints configured ?
00358          nb_endpoint_to_configure--;
00359       } //for(i=0;i<nb_interface_supported;i++)
00360    }
00361    Host_set_configured();
00362    return HOST_TRUE;
00363 }
00364 
00376 T_DESC_OFFSET get_interface_descriptor_offset(U8 interface, U8 alt)
00377 {
00378    U8 nb_interface;
00379    T_DESC_OFFSET descriptor_offset;
00380 
00381    nb_interface = data_stage[OFFSET_FIELD_NB_INTERFACE];      // Detects the number of interfaces in this configuration
00382    descriptor_offset = data_stage[OFFSET_DESCRIPTOR_LENGHT];  // now pointing on next descriptor
00383 
00384    while(descriptor_offset < SIZEOF_DATA_STAGE)            // Look in all interfaces declared in the configuration
00385    {
00386       while (data_stage[descriptor_offset+OFFSET_FIELD_DESCRIPTOR_TYPE] != INTERFACE_DESCRIPTOR)
00387       {
00388          descriptor_offset += data_stage[descriptor_offset];
00389          if(descriptor_offset > SIZEOF_DATA_STAGE)
00390          {  return HOST_FALSE;  }
00391       }
00392       if (data_stage[descriptor_offset+OFFSET_FIELD_INTERFACE_NB]==interface
00393           && data_stage[descriptor_offset+OFFSET_FIELD_ALT]==alt)
00394       {
00395         return  descriptor_offset;
00396       }
00397       descriptor_offset += data_stage[descriptor_offset];
00398    }
00399    return descriptor_offset;
00400 }
00401 
00412 U8 host_get_hwd_pipe_nb(U8 ep_addr)
00413 {
00414    U8 i;
00415    for(i=0;i<MAX_EP_NB;i++)
00416    {
00417       if(ep_table[i]==ep_addr)
00418       { return i; }
00419    }
00420    return 0;
00421 }
00422 
00439 U8 host_send_control(U8* data_pointer)
00440 {
00441 U16 data_length;
00442 U8 sav_int_sof_enable;
00443 U8 c;
00444 
00445    Usb_ack_event(EVT_HOST_SOF);
00446    sav_int_sof_enable=Is_host_sof_interrupt_enabled();
00447    Host_enable_sof_interrupt();                   // SOF software detection is in interrupt sub-routine
00448    while(Is_not_usb_event(EVT_HOST_SOF))          // Wait 1 sof
00449    {
00450       if (Is_host_emergency_exit())
00451       {
00452          c=CONTROL_TIMEOUT;
00453          Host_freeze_pipe();
00454          Host_reset_pipe(0);
00455          goto host_send_control_end;
00456       }
00457    }
00458    if (sav_int_sof_enable==FALSE)
00459    {
00460       Host_disable_sof_interrupt();
00461    }
00462 
00463    Host_select_pipe(0);
00464    Host_set_token_setup();
00465    Host_ack_setup();
00466    Host_unfreeze_pipe();
00467   // Build the setup request fields
00468    Host_write_byte(usb_request.bmRequestType);
00469    Host_write_byte(usb_request.bRequest);
00470    Host_write_byte(LSB(usb_request.wValue));
00471    Host_write_byte(MSB(usb_request.wValue));
00472    Host_write_byte(LSB(usb_request.wIndex));
00473    Host_write_byte(MSB(usb_request.wIndex));
00474    Host_write_byte(LSB(usb_request.wLength));
00475    Host_write_byte(MSB(usb_request.wLength));
00476 
00477    Host_send_setup();
00478    while(Is_host_setup_sent() == FALSE)  // wait for SETUP ack
00479    {
00480 #if (USB_OTG_FEATURE == ENABLED)
00481       if (Is_timeout_bdev_response_overflow())
00482       {
00483          Otg_print_new_failure_message(OTGMSG_DEVICE_NO_RESP,OTG_TEMPO_4SEC);
00484          c=CONTROL_TIMEOUT;
00485          Host_freeze_pipe();
00486          Host_reset_pipe(0);
00487          goto host_send_control_end;
00488       }
00489 #endif
00490       if (Is_host_emergency_exit())
00491       {
00492          c=CONTROL_TIMEOUT;
00493          Host_freeze_pipe();
00494          Host_reset_pipe(0);
00495          goto host_send_control_end;
00496       }
00497       if(Is_host_pipe_error())           // Any error ?
00498       {
00499          c = Host_error_status();
00500          Host_ack_all_errors();
00501          goto host_send_control_end;     // Send error status
00502       }
00503    }
00504   // Setup token sent now send In or OUT token
00505   // Before just wait one SOF
00506    Usb_ack_event(EVT_HOST_SOF);
00507    sav_int_sof_enable=Is_host_sof_interrupt_enabled();
00508    Host_enable_sof_interrupt();
00509    Host_freeze_pipe();
00510    data_length = usb_request.wLength;
00511    while(Is_not_usb_event(EVT_HOST_SOF))         // Wait 1 sof
00512    {
00513       if (Is_host_emergency_exit())
00514       {
00515          c=CONTROL_TIMEOUT;
00516          Host_freeze_pipe();
00517          Host_reset_pipe(0);
00518          goto host_send_control_end;
00519       }
00520    }
00521    if (sav_int_sof_enable==FALSE)
00522    {  Host_disable_sof_interrupt();  }   // Restore SOF interrupt enable
00523 
00524   // IN request management ---------------------------------------------
00525    if(usb_request.bmRequestType & 0x80)           // bmRequestType : Data stage IN (bmRequestType==1)
00526    {
00527       Host_standard_in_mode();
00528       Host_set_token_in();
00529       while(data_length != 0)
00530       {
00531          Host_unfreeze_pipe();
00532          while(!Is_host_control_in_received())
00533          {
00534             if (Is_host_emergency_exit())
00535             {
00536                c=CONTROL_TIMEOUT;
00537                Host_freeze_pipe();
00538                Host_reset_pipe(0);
00539                goto host_send_control_end;
00540             }
00541       #if (USB_OTG_FEATURE == ENABLED)
00542             if (Is_timeout_bdev_response_overflow())
00543             {
00544                Otg_print_new_failure_message(OTGMSG_DEVICE_NO_RESP,OTG_TEMPO_4SEC);
00545                c=CONTROL_TIMEOUT;
00546                Host_freeze_pipe();
00547                Host_reset_pipe(0);
00548                goto host_send_control_end;
00549             }
00550       #endif
00551             if(Is_host_pipe_error())
00552             {
00553                c = Host_error_status();
00554                Host_ack_all_errors();
00555                goto host_send_control_end;
00556             }
00557             if(Is_host_stall())
00558             {
00559                c=CONTROL_STALL;
00560                Host_ack_stall();
00561                goto host_send_control_end;
00562             }
00563          }
00564          c = Host_data_length_U8();
00565          if (c == Host_get_pipe_length())
00566          {
00567             data_length -= c;
00568             if (usb_request.uncomplete_read == TRUE)           // uncomplete_read
00569             {
00570                data_length = 0;
00571             }
00572          }
00573          else
00574          {
00575             data_length = 0;
00576          }
00577          while (c!=0)
00578          {
00579             *data_pointer = Host_read_byte();
00580             data_pointer++;
00581             c--;
00582          }
00583          Host_freeze_pipe();
00584          Host_ack_control_in();
00585          Host_send_control_in();
00586       }                                // end of IN data stage
00587 
00588       Host_set_token_out();
00589       Host_unfreeze_pipe();
00590       Host_ack_control_out();
00591       Host_send_control_out();
00592       while(!Is_host_control_out_sent())
00593       {
00594     #if (USB_OTG_FEATURE == ENABLED)
00595           if (Is_timeout_bdev_response_overflow())
00596           {
00597              Otg_print_new_failure_message(OTGMSG_DEVICE_NO_RESP,OTG_TEMPO_4SEC);
00598              c=CONTROL_TIMEOUT;
00599              Host_freeze_pipe();
00600              Host_reset_pipe(0);
00601              goto host_send_control_end;
00602           }
00603     #endif
00604          if (Is_host_emergency_exit())
00605          {
00606             c=CONTROL_TIMEOUT;
00607             Host_freeze_pipe();
00608             Host_reset_pipe(0);
00609             goto host_send_control_end;
00610          }
00611          if(Is_host_pipe_error())
00612          {
00613             c = Host_error_status();
00614             Host_ack_all_errors();
00615             goto host_send_control_end;
00616          }
00617          if(Is_host_stall())
00618          {
00619             c=CONTROL_STALL;
00620             Host_ack_stall();
00621             goto host_send_control_end;
00622          }
00623       }
00624       Host_ack_control_out();
00625       c=(CONTROL_GOOD);
00626       goto host_send_control_end;
00627    }
00628 
00629   // OUT request management ---------------------------------------------
00630    else                                 // Data stage OUT (bmRequestType==0)
00631    {
00632       Host_set_token_out();
00633       Host_ack_control_out();
00634       while(data_length != 0)
00635       {
00636          Host_unfreeze_pipe();
00637          c = Host_get_pipe_length();
00638          if ( (U16)c > data_length)
00639          {
00640             c = (U8)data_length;
00641             data_length = 0;
00642          }
00643          else
00644          {
00645             data_length -= c;
00646          }
00647          while (c!=0)
00648          {
00649             Host_write_byte(*data_pointer);
00650             data_pointer++;
00651             c--;
00652          }
00653          Host_send_control_out();
00654          while (!Is_host_control_out_sent())
00655          {
00656             if (Is_host_emergency_exit())
00657             {
00658                c=CONTROL_TIMEOUT;
00659                Host_freeze_pipe();
00660                Host_reset_pipe(0);
00661                goto host_send_control_end;
00662             }
00663       #if (USB_OTG_FEATURE == ENABLED)
00664             if (Is_timeout_bdev_response_overflow())
00665             {
00666                Otg_print_new_failure_message(OTGMSG_DEVICE_NO_RESP,OTG_TEMPO_4SEC);
00667                c=CONTROL_TIMEOUT;
00668                Host_freeze_pipe();
00669                Host_reset_pipe(0);
00670                goto host_send_control_end;
00671             }
00672       #endif
00673             if(Is_host_pipe_error())
00674             {
00675                c = Host_error_status();
00676                Host_ack_all_errors();
00677                goto host_send_control_end;
00678             }
00679             if(Is_host_stall())
00680             {
00681                c=CONTROL_STALL;
00682                Host_ack_stall();
00683                goto host_send_control_end;
00684             }
00685          }
00686          Host_ack_control_out();
00687       }                                // end of OUT data stage
00688       Host_freeze_pipe();
00689       Host_set_token_in();
00690       Host_unfreeze_pipe();
00691       while(!Is_host_control_in_received())
00692       {
00693          if (Is_host_emergency_exit())
00694          {
00695             c=CONTROL_TIMEOUT;
00696             Host_freeze_pipe();
00697             Host_reset_pipe(0);
00698             goto host_send_control_end;
00699          }
00700   #if (USB_OTG_FEATURE == ENABLED)
00701         if (Is_timeout_bdev_response_overflow())
00702         {
00703            Otg_print_new_failure_message(OTGMSG_DEVICE_NO_RESP,OTG_TEMPO_4SEC);
00704            c=CONTROL_TIMEOUT;
00705            Host_freeze_pipe();
00706            Host_reset_pipe(0);
00707            goto host_send_control_end;
00708         }
00709   #endif
00710          if(Is_host_pipe_error())
00711          {
00712             c = Host_error_status();
00713             Host_ack_all_errors();
00714             goto host_send_control_end;
00715          }
00716          if(Is_host_stall())
00717          {
00718             c=CONTROL_STALL;
00719             Host_ack_stall();
00720             goto host_send_control_end;
00721          }
00722       }
00723       Host_ack_control_in();
00724       Host_freeze_pipe();
00725       Host_send_control_in();
00726       c=(CONTROL_GOOD);
00727       goto host_send_control_end;
00728    }
00729 host_send_control_end:
00730    return ((U8)c);
00731 }
00732 
00733 #endif   //(USB_HOST_FEATURE == ENABLED)
00734 

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