logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[STM32] - USB w trybie HID i Virtual COM - możliwe?

mongoł2000 12 Lip 2014 17:07 4347 11
REKLAMA
  • #1 13790521
    mongoł2000
    Poziom 18  
    Posty: 623
    Pomógł: 15
    Ocena: 175
    Witam, wiem ze ST udostępnia przykład klasy composite: HID + pamięć masowa. Czy jest również możliwa praca w trybie HID+Virtual COM ? Zastanawiam się czy wtedy system używa dwóch niezależnych sterowników, czy klasa composite ma jakiś swój driver, a wtedy może nie być możliwe użycie COM+HID. Czy ktoś już przebrnął przez podobny problem?
  • REKLAMA
  • Pomocny post
    #2 13790552
    BlueDraco
    Specjalista - Mikrokontrolery
    Posty: 6479
    Pomógł: 939
    Ocena: 421
    Można zrobić urządzenie złożone z urządzeń dowolnych klas. Każde urządzenie składowe ma własny sterownik niezależny od pozostałych.
  • #3 13793212
    mongoł2000
    Poziom 18  
    Posty: 623
    Pomógł: 15
    Ocena: 175
    A więc stworzyłem deskryptory dla urządzenie kompozytowego CDC+HID. Obserwacje:
    1. Jednak system ma również oddzielny driver dla klasy kompozytowej, instaluje go najpierw.
    2. Potem instalują się sterowniki HID oraz Virtual COM (CDC)
    3. Niestety Virtual COM nie chce mi się zainstalować, mimo że używam drivera, który działał, gdy urządzenie nie pracowało w trybie kompozytowym(może musi być to inny driver??).
    4. Na Win 7 działa tak jak powyżej, natomiast na Win 8.1 otrzymuję kod 10 już przy instalacji drivera dla urządzenia kompozytowego.

    Poniżej deskryptory, może robię coś źle?

    /* USB Standard Device Descriptor */
    const uint8_t Composite_DeviceDescriptor[Composite_SIZ_DEVICE_DESC] =
      {
        0x12,                       /*bLength */
        USB_DEVICE_DESCRIPTOR_TYPE, /*bDescriptorType*/
        0x00,                       /*bcdUSB */
        0x02,
        0xef,                       /*bDeviceClass bylo 00*/
        0x02,                       /*bDeviceSubClass*/
        0x01,                       /*bDeviceProtocol*/
        0x40,                       /*bMaxPacketSize40*/
        0x81,                       /*idVendor (0x0481)*/
        0x04, 
        0x50,                       /*idProduct = 0x5750*/
        0x57,
        0x00,                       /*bcdDevice rel. 2.00*/
        0x02,
        1,                          /*Index of string descriptor describing
                                                  manufacturer */
        2,                          /*Index of string descriptor describing
                                                 product*/
        3,                          /*Index of string descriptor describing the
                                                 device serial number */
        0x01                        /*bNumConfigurations*/
      }
      ; /* Composite_DeviceDescriptor */
    
    
    /* USB Configuration Descriptor */
    /*   All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */
    const uint8_t Composite_ConfigDescriptor[Composite_SIZ_CONFIG_DESC] =
      {
        0x09, /* bLength: Configuration Descriptor size */
        USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */
        Composite_SIZ_CONFIG_DESC,
        /* wTotalLength: Bytes returned */
        0x00,
        0x03,         /* bNumInterfaces: 2 interfaces */
        0x01,         /* bConfigurationValue: Configuration value */
        0x01,         /* iConfiguration: Index of string descriptor describing
                                     the configuration*/
        0xC0,         /* bmAttributes: Self powered */
        0x32,         /* MaxPower 100 mA: this current is used for detecting Vbus */
    
        /************** Descriptor of Custom HID interface ****************/
        /* 09 */
        0x09,         /* bLength: Interface Descriptor size */
        USB_INTERFACE_DESCRIPTOR_TYPE,/* bDescriptorType: Interface descriptor type */
        0x00,         /* bInterfaceNumber: Number of Interface */
        0x00,         /* bAlternateSetting: Alternate setting */
        0x02,         /* bNumEndpoints */
        0x03,         /* bInterfaceClass: HID */
        0x00,         /* bInterfaceSubClass : 1=BOOT, 0=no boot */
        0x00,         /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
        0,            /* iInterface: Index of string descriptor */
        /******************** Descriptor of Custom HID HID ********************/
        /* 18 */
        0x09,         /* bLength: HID Descriptor size */
        HID_DESCRIPTOR_TYPE, /* bDescriptorType: HID */
        0x11,         /* bcdHID: HID Class Spec release number */
        0x01,
        0x00,         /* bCountryCode: Hardware target country */
        0x01,         /* bNumDescriptors: Number of HID class descriptors to follow */
        0x22,         /* bDescriptorType */
        CUSTOMHID_SIZ_REPORT_DESC,/* wItemLength: Total length of Report descriptor */
        0x00,
        /******************** Descriptor of Custom HID endpoints ******************/
        /* 27 */
        0x07,          /* bLength: Endpoint Descriptor size */
        USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: */
    
        0x81,          /* bEndpointAddress: Endpoint Address (IN) */
        0x03,          /* bmAttributes: Interrupt endpoint */
        0x02,          /* wMaxPacketSize: 2 Bytes max */
        0x00,
        0x20,          /* bInterval: Polling Interval (32 ms) */
        /* 34 */
        	
        0x07,	/* bLength: Endpoint Descriptor size */
        USB_ENDPOINT_DESCRIPTOR_TYPE,	/* bDescriptorType: */
    			/*	Endpoint descriptor type */
        0x01,	/* bEndpointAddress: */
    			/*	Endpoint Address (OUT) */
        0x03,	/* bmAttributes: Interrupt endpoint */
        0x02,	/* wMaxPacketSize: 2 Bytes max  */
        0x00,
        0x20,	/* bInterval: Polling Interval (20 ms) */
        /* 41 */
       // IAD ------------------------------------------------------------------------------------------------------------
    
        // Interface Association Descriptor
        0x08,                               // Size of this descriptor in bytes
        0x0B,                               // Interface association descriptor type
        0x01,                               // First associated interface
        0x02,                               // Number of contiguous associated interfaces
        0x02,                          // bInterfaceClass of the first interface
        0x02,             // bInterfaceSubClass of the first interface
        0x01,                             // bInterfaceProtocol of the first interface
        0x00, 
    		/*Interface VCOM Descriptor*/
        0x09,   /* bLength: Interface Descriptor size */
        USB_INTERFACE_DESCRIPTOR_TYPE,  /* bDescriptorType: Interface */
        /* Interface descriptor type */
        0x01,   /* bInterfaceNumber: Number of Interface {?? maybe 0x01}*/
        0x00,   /* bAlternateSetting: Alternate setting */
        0x01,   /* bNumEndpoints: One endpoints used */
        0x02,   /* bInterfaceClass: Communication Interface Class */
        0x02,   /* bInterfaceSubClass: Abstract Control Model */
        0x01,   /* bInterfaceProtocol: Common AT commands */
        0x00,   /* iInterface: */
        /*Header Functional Descriptor*/
        0x05,   /* bLength: Endpoint Descriptor size */
        0x24,   /* bDescriptorType: CS_INTERFACE */
        0x00,   /* bDescriptorSubtype: Header Func Desc */
        0x10,   /* bcdCDC: spec release number */
        0x01,
    
        /*ACM Functional Descriptor*/
        0x04,   /* bFunctionLength */
        0x24,   /* bDescriptorType: CS_INTERFACE */
        0x02,   /* bDescriptorSubtype: Abstract Control Management desc */
        0x02,   /* bmCapabilities */
        /*Union Functional Descriptor*/
        0x05,   /* bFunctionLength */
        0x24,   /* bDescriptorType: CS_INTERFACE */
        0x06,   /* bDescriptorSubtype: Union func desc */
        0x00,   /* bMasterInterface: Communication class interface */
        0x01,   /* bSlaveInterface0: Data Class Interface */
        /*Call Management Functional Descriptor*/
        0x05,   /* bFunctionLength */
        0x24,   /* bDescriptorType: CS_INTERFACE */
        0x01,   /* bDescriptorSubtype: Call Management Func Desc */
        0x00,   /* bmCapabilities: D0+D1 */
        0x02,   /* bDataInterface: 1 */		
        /*Endpoint 2 Descriptor*/
        0x07,   /* bLength: Endpoint Descriptor size */
        USB_ENDPOINT_DESCRIPTOR_TYPE,   /* bDescriptorType: Endpoint */
        0x83,   /* bEndpointAddress: (IN2) */
        0x03,   /* bmAttributes: Interrupt */
        VIRTUAL_COM_PORT_INT_SIZE,      /* wMaxPacketSize: */
        0x00,
        0xFF,   /* bInterval: */
        /*Data class interface descriptor*/
        0x09,   /* bLength: Endpoint Descriptor size */
        USB_INTERFACE_DESCRIPTOR_TYPE,  /* bDescriptorType: */
        0x02,   /* bInterfaceNumber: Number of Interface */
        0x00,   /* bAlternateSetting: Alternate setting */
        0x02,   /* bNumEndpoints: Two endpoints used */
        0x0A,   /* bInterfaceClass: CDC */                                        /////0x02
        0x00,   /* bInterfaceSubClass: */
        0x00,   /* bInterfaceProtocol: */
        0x00,   /* iInterface: */
        /*Endpoint 3 Descriptor*/
        0x07,   /* bLength: Endpoint Descriptor size */
        USB_ENDPOINT_DESCRIPTOR_TYPE,   /* bDescriptorType: Endpoint */
        0x03,   /* bEndpointAddress: (OUT3) */
        0x02,   /* bmAttributes: Bulk */
        VIRTUAL_COM_PORT_DATA_SIZE,             /* wMaxPacketSize: */
        0x00,
        0x00,   /* bInterval: ignore for Bulk transfer */
        /*Endpoint 1 Descriptor*/
        0x07,   /* bLength: Endpoint Descriptor size */
        USB_ENDPOINT_DESCRIPTOR_TYPE,   /* bDescriptorType: Endpoint */
        0x83,   /* bEndpointAddress: (IN3) */
        0x02,   /* bmAttributes: Bulk */
        VIRTUAL_COM_PORT_DATA_SIZE,             /* wMaxPacketSize: */
        0x00,
        0x00    /* bInterval */
        /*32*/
      }; /* Composite_ConfigDescriptor */
  • Pomocny post
    #4 13793494
    BlueDraco
    Specjalista - Mikrokontrolery
    Posty: 6479
    Pomógł: 939
    Ocena: 421
    Zacznij od uruchomienia urządzenia złożonego zawierającego tylko VCOM z deskryptorem IAD.
  • REKLAMA
  • Pomocny post
    #5 13793549
    Konto nie istnieje
    Poziom 1  
  • #6 13794508
    mongoł2000
    Poziom 18  
    Posty: 623
    Pomógł: 15
    Ocena: 175
    Marek_Skalski:
    Może rozwinąć myśl, bo nie za bardzo wiem co jest niespójne i błędne.

    Co do IAD, to z tego co widać tu:

    http://msdn.microsoft.com/en-us/library/windows/hardware/ff540054%28v=vs.85%29.aspx

    Windows 8 nie wspiera IAD i może stąd problem, że na Win7 instalacja sterownika kompozytowego zostaje zakończona pomyślnie, a Win8 pozostawia błąd 10? Więc jeśli się nie mylę to jakie może być inne rozwiązanie użycia HID i Virtual COM w jednym urządzeniu?
    Co ciekawe, w przykładzie od ST, urządzenie HID+Mass Memory nie używa IAD. A więc czy dla moich założeń również da się to zrobić bez IAD?
  • Pomocny post
    #7 13794529
    Konto nie istnieje
    Poziom 1  
  • REKLAMA
  • #8 13795401
    mongoł2000
    Poziom 18  
    Posty: 623
    Pomógł: 15
    Ocena: 175
    Doczytałem na forach Microchip jak zrobić to bez IAD. Opracowałem nowy deskryptor (zrzut z USBlyzer w załączniku), jednak znów HID jest wykrywany, natomiast CDC już nie, tzn. są widoczne dwa urządzenia w menadżerze urządzeń bez sterowników (zapewne interface danych i kontrolny klasy CDC).
    Gdy próbuje zainstalować sterownik do tych urządzeń (sterownik VirtualCOM, który działał gdy urządzenie nie miało HID) to niestety system go nie łyka.
    Poprawiłem Endpointy wg. Twojej rady.
    [STM32] - USB w trybie HID i Virtual COM - możliwe?

    -------------------------------------------
    Udało mi się zainstalować sterownik dla CDC..niestety połowicznie. Dzięki forum ST dotarło do mnie, że mając kilka interfejsów, należy w sterowniku wybrać konkretne, tzn:
    %DESCRIPTION%=DriverInstall,USB\VID_04D8&PID_00DF&MI_01

    I to na końcu to numer interfejsu.

    Niestety po zainstalowaniu tego sterownika, pojawił mi się jeden port COM bez żadnych kodów błędów, natomiast drugi (po instalacji z numerem interfejsu MI_02 w sterowniku) wyskakuje z błędem(Nie można uruchomić tego urządzenia. (Kod 10) Określono nie istniejące urządzenie.).

    Wygląda na to, iż mój Virtual COM posiada 2 interfejsy: danych i kontrolny (stąd menadżer urządzeń pokazywał 3 urządzenia: HID, kontrolny oraz transmisyjny CDC).

    Teraz zagadka: jak zrobić (wydaje mi się, że to wina deskryptora) aby kanał kontrolny i transmisyjny były razem. Wydaje mi się, iż odpowiedzialny za to może być Union Functional Descriptor, jednak jak na razie nie widzę w nim błędu: masterem jest kanał kontrolny natomiast slavem, jest kanał transmisyjny.
    Załączniki:
    • Urz__dzenie_kompozytowe_USB.rar (3.16 KB) Musisz być zalogowany, aby pobrać ten załącznik.
  • Pomocny post
    #9 13796352
    Konto nie istnieje
    Poziom 1  
  • #10 13796553
    mongoł2000
    Poziom 18  
    Posty: 623
    Pomógł: 15
    Ocena: 175
    Tak, masz racje..kontrolny to EP0, chodziło mi o te kontrolne dla CDC.

    Udało mi się (chyba) rozwiązać problem z dwoma urządzeniami dla CDC. Otóż, wykorzystałem IAD (choć nie powinien działać na Win8) i w menadżerze urządzeń wygląda już dobrze.

    Oczywiście przygotowałem sobie obsługę danych kontrolnych(SETUP). Dopisałem obsługę GET_LINE_CODING oraz SET_LINE_CODING. Obsługa jest wplątana w obsługę ustawień dla HID i może z tego względu nie odbieram żadnych danych w endpointach oraz dlatego PC nie wysyła mi poprawnej struktury linecoding zawierającej parametry transmisji.

    [STM32] - USB w trybie HID i Virtual COM - możliwe?

    A tu poprawna struktura, jednak dla urządzanie jedynie z Virtual COM bez HID.

    [STM32] - USB w trybie HID i Virtual COM - możliwe?


    ---------------------------------------
    Zmieniłem układ scalony (tez 103 ale mniejszy) i wszystko działa dobrze! COM i HID równolegle. Pamiętam, że przez przypadek na nóżki USB poszło 5V i być może to spowodowało jakieś lekkie uszkodzenia.
    Czy macie doświadczenia jak klasa IAD wraz z HID i CDC działa na Linux i MAC OS? Czy nie wymaga to tworzenia własnych sterowników?
  • Pomocny post
    #11 13797284
    BlueDraco
    Specjalista - Mikrokontrolery
    Posty: 6479
    Pomógł: 939
    Ocena: 421
    IAD jest potrzebny tylko dla CDC, bo jest to jedyna z klas, o których mowa, która ma dwa interfejsy w jednym urządzeniu. Nie słyszałem o CDC w urządzeniu złożonym bez IAD - ja od dawna używam urządzeń z 2 x CDC + MSC i nie mam z nimi problemów. Drivery w Linuxia instalują się same, w Windows - po podaniu odpowiedniego pliku .INF.
  • REKLAMA
  • #12 13800794
    mongoł2000
    Poziom 18  
    Posty: 623
    Pomógł: 15
    Ocena: 175
    Kurde, biblioteka aplikacji od HID na PC zapewnia wysyłanie danych jedynie po endpoint 0 więc kontrolnym. Co ciekawe terminal HID też wysyła pod kontrolny...czy to jest już taki standard? Wcześniej wykorzystywałem inne endpointy, gdyż nie sądziłem, że poprawne jest używanie zerowego. Niestety teraz czeka mnie zmiana biblioteki USB od ST, ale nie wygląda to trudno.

Podsumowanie tematu

LABEL_AI_GENERATED
W dyskusji poruszono możliwość stworzenia urządzenia USB w trybie composite, łączącego klasy HID i Virtual COM (CDC). Użytkownik zauważył, że system instaluje oddzielne sterowniki dla klasy kompozytowej oraz dla HID i Virtual COM, jednak napotkał problemy z instalacją sterownika Virtual COM na systemie Windows 8.1, co skutkowało błędem 10. Uczestnicy forum sugerowali poprawki w deskryptorach USB, w tym użycie odpowiednich endpointów oraz obsługę żądań kontrolnych. Ostatecznie, po modyfikacjach, udało się zainstalować sterownik dla CDC, co pozwoliło na równoległe działanie obu interfejsów. Wskazano również, że IAD jest wymagany dla CDC, a poprawna obsługa endpointów jest kluczowa dla funkcjonowania urządzenia.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA