48-USB_HID-Library (STM32F4)

Mit dieser Library meldet sich die CPU (per USB) am PC als HID-Device an.

Zum Datenaustausch zwischen dem PC und der CPU ist kein spezieller Treiber notwendig (der ist bei Windows schon dabei)

Es wird der Interrupt-Mode benutzt, der PC fragt also zyklisch die CPU nach Daten ab. Die Geschwindigkeit (von 1ms bis 255ms) kann im H-File eingestellt werden.

Die Größe vom sende und empfangs Puffer (der pro Zeiteinheit übertragen wird) kann auch im H-File eingestellt werden. Hier sind Werte von 1Byte bis 64Bytes möglich.

Die Einstellung 64Bytes pro Block und eine Abfragerate von 1ms ergibt 64kByte/sec . Das entspricht dem Maximum Wert für USB-FullSpeed.

Die VID und PID steht auch in einem H-File genauso die Beschreibung Strings für das Device (“STM32 HID-Device”) mit der Ser.Nr. 0×0100

Auf der PC-Seite gibt es fertige Programme (z.B. von STM den USB HID-Demonstrator) oder, was ich auch benutzt habe das “Simple HID-Write” von dieser Seite :
http://www.lvr.com/hidpage.htm

Ich habe für die PC-Seite ein mini HID-Terminal geschrieben der auf der USB-DLL von Silicon-Labs aufbaut. Um die Library zu testen reicht es, man kann Daten senden und empfangen.

Die Funktionen der Library sind identisch mit der von USB-CDC. Es gibt eine Funktion zum initialisieren, eine zum abfragen vom USB-Status und je eine Funktion zum senden und empfangen von Daten. Es werden hier aber keine Strings übertragen sondern ein Array von Bytes.

Im Demo wird nach dem empfang von Daten der Block als Echo wieder zurückgesendet.
Der PC muss auf der Report-ID Nr. 0×00 senden und empfangen wird auch über 0×00.

Es wird ein USB-Kabel mit Micro-USB-Stecker benötigt. (gibts bei EBay oder Amazon)

Hinweis : im File “usbd_hid_core.c” wird beim compilieren in der Funktion “USBD_HID_DataOut” eine Warning angezeigt. Ich habe leider keinen Workaround dafür gefunden…vlt. kennt sich jemand besser damit aus und kann sich hier melden.

Beispielbild :

usb_hid

Benutzte Pins :

1
2
3
4
5
PA8   -> USB_OTG_SOF (wird nicht benutzt)
PA9   -> USB_OTG_VBUS
PA10  -> USB_OTG_ID
PA11  -> USB_OTG_DM
PA12  -> USB_OTG_DP

Voraussetzungen :

1
2
Benutzte Module der CooCox-IDE : GPIO, MISC
Benutzte Librarys : keine

Enumerationen :

1
2
3
4
5
typedef enum {
  USB_HID_NO_INIT =0, // USB-Schnittstelle noch nicht initialisiert
  USB_HID_DETACHED,   // USB-Verbindung getrennt
  USB_HID_CONNECTED   // USB-Verbindung hergestellt
}USB_HID_STATUS_t;

:

1
2
3
4
5
typedef enum {
  RX_USB_ERR =0, // keine USB Verbindung
  RX_EMPTY,      // nichts empfangen
  RX_READY       // es steht was im Empfangspuffer
}USB_HID_RXSTATUS_t;

Funktionen :

1
2
3
4
void UB_USB_HID_Init(void);                                 // zum init der USB-Schnittstelle
USB_HID_STATUS_t UB_USB_HID_GetStatus(void);                // USB Status abprüfen
ErrorStatus UB_USB_HID_SendData(uint8_t *ptr, uint8_t len); // zum senden von Daten per USB
USB_HID_RXSTATUS_t UB_USB_HID_ReceiveData(uint8_t *ptr);    // zum empfangen von Daten per USB

Beispiel :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
//--------------------------------------------------------------
// File     : main.c
// Datum    : 23.06.2013
// Version  : 1.0
// Autor    : UB
// EMail    : mc-4u(@)t-online.de
// Web      : www.mikrocontroller-4u.de
// CPU      : STM32F4
// IDE      : CooCox CoIDE 1.7.0
// Module   : CMSIS_BOOT, M4_CMSIS_CORE
// Funktion : Demo der USB-HID-Library
// Hinweis  : Diese zwei Files muessen auf 8MHz stehen
//              "cmsis_boot/stm32f4xx.h"
//              "cmsis_boot/system_stm32f4xx.c"
//--------------------------------------------------------------
 
#include "main.h"
#include "stm32_ub_usb_hid.h"
 
int main(void)
{
  uint8_t buf[HID_OUT_BUFFER_SIZE]; // puffer für Datenempfang
  USB_HID_RXSTATUS_t check=RX_EMPTY;
 
  SystemInit(); // Quarz Einstellungen aktivieren
 
  // Init vom USB-OTG-Port als HID-Device
  UB_USB_HID_Init();
 
  while(1)
  {
    // Test ob USB-Verbindung zum PC besteht
    if(UB_USB_HID_GetStatus()==USB_HID_CONNECTED) {
      // Ceck ob Daten per USB empfangen wurden
      check=UB_USB_HID_ReceiveData(buf);
      if(check==RX_READY) {
        // wenn Daten empfangen wurden
        // als Echo wieder zurücksenden
        UB_USB_HID_SendData(buf,HID_OUT_BUFFER_SIZE);
      }
    }
  }
}

Hier die Library zum Download :

ub_stm32f4_usb_hid_v100

Hier der komplette CooCox-Projektordner zum Download :

Demo_48_USB_HID

Hier der Link zu dem PC-Programm :

PC-Programme

19 Antworten auf 48-USB_HID-Library (STM32F4)

  1. Peter sagt:

    Hallo,
    danke für ein weiteres Demo!

    Zur Warning in USBD_HID_DataOut ein paar Infos:
    der * bei *USB_HID_OUT_BUF in Zeile 345 macht keinen Sinn. Mit dem * übergibst du das erste Zeichen des USB_HID_OUT_BUF als dessen Adresse. So kopiert USB_OTG_ReadPacket die Daten in’s Nirvana. Wenn man den * weg lässt, gibt es keine Warning, dafür funktioniert das Demo nicht mehr. Kommentiert man die Zeile 345 aus, funktionert es wieder.
    Tiefer bin ich nicht eingestiegen.

    Das erfreulich ist, dass der Treiber hier nicht so ‘zickt’ wie beim CDC. Hier kann man einen Reset beim Discovery ausführen, auch wenn das PC Programm noch Verbindung hat. Eine neue Verbindung kann dann ohne Neustart des PC Programms erfolgen.

  2. Hannes sagt:

    Hallo,
    ich habe vermutlich zeitgleich mit dir an einer USB HID Lösung gebastelt und bin leider erst jetzt auf deine tolle Seite und USB Lib gestoßen! Wirklich eine gute Arbeit.
    Dein Terminalprogramm ist auch spitze, hatte noch keine Probleme damit!!
    (früher habe ich auch den SimpleHidWrite verwendet).

    Nun noch meine Fragen an dich:
    – Ist es möglich eine zusätzliche Funktion bei dem Terminalprog einzubauen, dass die Bufferanzeige wahlweise als HEX oder ASCII dargestellt wird??
    – Hast du bei deiner Suche zum USB HID eine Lösung oder Beispielprog gefunden wo der USB mit DMA arbeitet oder weißt du wie man die USB Lib von ST auf DMA umstellen kann?

    Vielen Dank!
    SG Hannes

    • admin_ub sagt:

      kein Problem, ich kann das PC-Programm ändern. USB und DMA hab ich noch nicht gesehen (hab aber auch nicht danach gesucht)

      • Hannes sagt:

        Super, das wäre klasse! Vielen Dank im Voraus!

        Du hast Recht, habe bei der USB Lib teilweise DMA gelesen und bin davon ausgegangen das es funktionieren müsste.
        Leider gibt es diese Funktion aber nur für USB HS.

        • admin_ub sagt:

          habe gerade die Version 1.1 hochgeladen, probier die mal aus und sag bescheid ob das so ok ist.

          • Hannes sagt:

            Vielen Dank für die Änderung am Programm!
            Es funktioniert einwandfrei!! :-)

  3. karl sagt:

    hi,
    ich beziehe mich auf deine Aussage
    “Die Einstellung 64Bytes pro Block und eine Abfragerate von 1ms ergibt 64kByte/sec. Das entspricht dem Maximum Wert für USB-FullSpeed.”

    USB-Fullspeed hat doch eine Rate von 1500kByte/sec.

    Gruß
    Karl

    • admin_ub sagt:

      Bei USB-HID wird der Interrupt-Transfer benutzt …da ist bei 64kByte/sec schluss. Im Bulk-Transfer (z.B. USB-CDC) geht es theoretisch bis 1,5MByte/sec. (siehe WIKI)

  4. Karl^ sagt:

    hi Uwe,
    kannst du mir erklären wieso du den Report Deskriptor so geschrieben hast!?
    // USB HID Device Report Descriptor
    //————————————————————–
    __ALIGN_BEGIN static uint8_t CustomHID_ReportDescriptor[CUSTOMHID_SIZ_REPORT_DESC] __ALIGN_END =
    {
    0×06, 0xFF, 0xFF,
    0×09, 0×01,
    0xA1, 0×01,

    // IN (CPU –> PC)
    0×09, 0×02,
    0×09, 0×03,
    0×15, 0×00,
    0×26, 0xff, 0×00,
    0×75, 0×08,
    0×95, HID_IN_BUFFER_SIZE,
    0×81, 0×02,

    diese zwei Zeilen verstehe ich nicht so ganz
    0×09, 0×02,
    0×09, 0×03,

    und weiter bei der Übertragung vom PC zur CPU verwendest du
    0×09, 0×04,
    0×09, 0×05,
    und Feature
    0×09, 0×06,
    0×09, 0×07,

    damit wird doch jedesmal ein Usage erzeugt und dann auch jedesmal ein anderes und diese hier ist eigentlich auch reserviert: 0×09, 0×03,
    wieso? wozu?

    Ich will eigentlich nur eine HID-Verbindung zum Rechner haben und hänge an diesen Report Deskriptor, da ich keine Standard-Verbindung, sprich Maus, Tastatur, etc. machen möchte, sondern nur Daten als Interrupt-Transfer an den PC senden und diese dort mit eigener Software weiter verarbeiten. Wie müsste dann der Report Deskriptor aussehen??

    Grüße
    Karl

    • admin_ub sagt:

      ich habe den Report-Descriptor von einem Atmel Beispiel übernommen. Um ehrlich zu sein kenne ich mit USB zu wenig aus um da etwas “falsches” zu erkennen.

      • Karl sagt:

        ok, danke. Ich werds mal ausprobieren.

  5. OASH sagt:

    Hallo,

    Danke für diese Seiten und Informationen.

    Wo kann ich den Code des HIDßTerminal Programme finden? Ich hab viel gesucht aber kein Code…

    Danke

    • admin_ub sagt:

      Wenn du mein PC-Programm “HID-Terminal-UB” meinst, davon gibt es keinen Quellcode hier. Werde ich auch nicht hochladen.

  6. OASH sagt:

    warum?

    • admin_ub sagt:

      darum

  7. Helge sagt:

    Moin,
    bin wirklich beeindruckt von deiner lib-Samlung!
    Könntest du mir sagen, ob der virtuelle COM-Port mit dem STM auch auf einem Linux system wie zB. ubuntu funktioniert ?

    Beste Grüße
    Helge

    • admin_ub sagt:

      falls du einen VCP-Treiber für Linux findest müsste das funktionieren.

  8. Alirio Oliveira sagt:

    Hello!

    You can send this lib in keil? I tried compile this on COIDE and got a lot erros, but i’m not understand this IDE. new on STM32.
    Please help-me.

    Thankfull!

    • admin_ub sagt:

      i dont use KEIL, so i cant help.


Wie hat Dir dieser Artikel gefallen?

1 Stern2 Sterne3 Sterne4 Sterne5 Sterne (Noch keine Bewertungen)
Loading...

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert