Forum: Mikrocontroller und Digitale Elektronik STM32 USB Host Library


von Christian (Gast)


Lesenswert?

Hallo alle zusammen!

Seit einigen Tagen beschäftige ich mich mit der USB Host Library für 
mein STM32F4 Discovery. Ziel ist es später meine Kamera steuern zu 
können. Bis dahin is es aber noch ein weiter Weg. Nun habe ich 
allerdings folgendes Problem, bzw. folgende Frage:

Die Abfrage der Gerätekonfiguration liefert mir ein Interface und drei 
Endpunkte zurück. Soweit so gut! Nun wird
1
USBH_ParseCfgDesc()
 aufgerufen um das Interface und die Endpunktdeskriptoren in die 
endsprechenden Datenstrukturen zu schreiben. Dabei kommt mir eines 
seltsam vor. Während des Abarbeitens der Endpunktdeskriptoren merkt sich 
der Parser jeweils die entsprechende wMaxPacketSize mittels
1
prev_ep_size = LE16((uint8_t *)pdesc + 4);
 Zeile ~466 usbh_stdreq.c. Ist nun wMaxPacketSize des aktuellen 
EP-Deskriptors kleiner als die verangegangenen wird abgebrochen. 
wMaxPacketSize des betreffenden Endpointdeskriptors ist bei mir 8, die 
des vorangegangenen 64.
Kann mir dafür einer einen Grund nennen? Ist es Bug oder ein Feature ;-)

LG, Christian

Anbei der Code der entsprechenden Parse-Methode.
1
// usbh_stdreq.c
2
3
static void  USBH_ParseCfgDesc (USBH_CfgDesc_TypeDef* cfg_desc,
4
                                USBH_InterfaceDesc_TypeDef* itf_desc,
5
                                USBH_EpDesc_TypeDef   ep_desc[][USBH_MAX_NUM_ENDPOINTS], 
6
                                uint8_t *buf, 
7
                                uint16_t length)
8
{  
9
  USBH_InterfaceDesc_TypeDef    *pif ;
10
  USBH_InterfaceDesc_TypeDef    temp_pif ;  
11
  USBH_EpDesc_TypeDef           *pep;  
12
  USBH_DescHeader_t             *pdesc = (USBH_DescHeader_t *)buf;
13
  uint16_t                      ptr;
14
  int8_t                        if_ix = 0;
15
  int8_t                        ep_ix = 0;  
16
  static uint16_t               prev_ep_size = 0;
17
  static uint8_t                prev_itf = 0;  
18
  
19
  
20
  pdesc   = (USBH_DescHeader_t *)buf;
21
  
22
  /* Parse configuration descriptor */
23
  cfg_desc->bLength             = *(uint8_t  *) (buf + 0);
24
  cfg_desc->bDescriptorType     = *(uint8_t  *) (buf + 1);
25
  cfg_desc->wTotalLength        = LE16 (buf + 2);
26
  cfg_desc->bNumInterfaces      = *(uint8_t  *) (buf + 4);
27
  cfg_desc->bConfigurationValue = *(uint8_t  *) (buf + 5);
28
  cfg_desc->iConfiguration      = *(uint8_t  *) (buf + 6);
29
  cfg_desc->bmAttributes        = *(uint8_t  *) (buf + 7);
30
  cfg_desc->bMaxPower           = *(uint8_t  *) (buf + 8);    
31
  
32
  
33
  if (length > USB_CONFIGURATION_DESC_SIZE)
34
  {
35
    ptr = USB_LEN_CFG_DESC;
36
    
37
    if ( cfg_desc->bNumInterfaces <= USBH_MAX_NUM_INTERFACES) 
38
    {
39
      pif = (USBH_InterfaceDesc_TypeDef *)0;
40
      
41
      while (ptr < cfg_desc->wTotalLength ) 
42
      {
43
        pdesc = USBH_GetNextDesc((uint8_t *)pdesc, &ptr);
44
        if (pdesc->bDescriptorType   == USB_DESC_TYPE_INTERFACE) 
45
        {
46
          if_ix             = *(((uint8_t *)pdesc ) + 2);
47
          pif               = &itf_desc[if_ix];
48
          
49
          if((*((uint8_t *)pdesc + 3)) < 3)
50
          {
51
          USBH_ParseInterfaceDesc (&temp_pif, (uint8_t *)pdesc);            
52
          ep_ix = 0;
53
          
54
          /* Parse Ep descriptors relative to the current interface */
55
          if(temp_pif.bNumEndpoints <= USBH_MAX_NUM_ENDPOINTS)
56
          {          
57
            while (ep_ix < temp_pif.bNumEndpoints) 
58
            {
59
              pdesc = USBH_GetNextDesc((void* )pdesc, &ptr);
60
              if (pdesc->bDescriptorType   == USB_DESC_TYPE_ENDPOINT) 
61
              {  
62
                pep               = &ep_desc[if_ix][ep_ix];
63
                
64
                if(prev_itf != if_ix)
65
                {
66
                  prev_itf = if_ix;
67
                  USBH_ParseInterfaceDesc (pif, (uint8_t *)&temp_pif); 
68
                }
69
                else
70
                {
71
                  //---------------------------------------------
72
                     HIER WIRD ABGEBROCHEN
73
                  //---------------------------------------------
74
                  if(prev_ep_size > LE16((uint8_t *)pdesc + 4))
75
                  {
76
                    break;
77
                  }
78
                  else
79
                  {
80
                    USBH_ParseInterfaceDesc (pif, (uint8_t *)&temp_pif);    
81
                  }
82
                }
83
                USBH_ParseEPDesc (pep, (uint8_t *)pdesc);
84
                prev_ep_size = LE16((uint8_t *)pdesc + 4);
85
                ep_ix++;
86
              }
87
            }
88
          }
89
         }
90
        }
91
      }
92
    }
93
    prev_ep_size = 0;
94
    prev_itf = 0; 
95
  }  
96
}

von Detlef K. (adenin)


Lesenswert?

Hmm, komischer Code.
Ich sehe, so auf den ersten Blick, keinen Sinn des ELSE-Teiles von 
"if(prev_itf != if_ix)"
Entweder er bricht die while-Schleife ab oder USBH_ParseInterfaceDesc 
(pif, (uint8_t *)&temp_pif) wird ausgeführt, was eigentlich nur den 
Interface-Descriptor aus temp_pif nach pif kopiert. Mir ist unklar, 
wieso dieser wiederholte Kopiervorgang abhängig von wMaxPacketSize 
sein soll und was der Sinn sein soll. Das muss doch nur einmal bei jedem 
neuen Interface gemacht werden (also bei "if(prev_itf != if_ix)").
Ich würde den ELSE-Teil mal auskommentiern und sehen ob's noch geht.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.