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 :
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 :
Hier der komplette CooCox-Projektordner zum Download :
Hier der Link zu dem PC-Programm :
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.
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
kein Problem, ich kann das PC-Programm ändern. USB und DMA hab ich noch nicht gesehen (hab aber auch nicht danach gesucht)
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.
habe gerade die Version 1.1 hochgeladen, probier die mal aus und sag bescheid ob das so ok ist.
Vielen Dank für die Änderung am Programm!
Es funktioniert einwandfrei!!
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
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)
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
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.
ok, danke. Ich werds mal ausprobieren.
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
Wenn du mein PC-Programm “HID-Terminal-UB” meinst, davon gibt es keinen Quellcode hier. Werde ich auch nicht hochladen.
warum?
darum
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
falls du einen VCP-Treiber für Linux findest müsste das funktionieren.
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!
i dont use KEIL, so i cant help.