13-USB_CDC-Library (STM32F429)

Hier eine Library um den USB-OTG-Port am Discovery-Board im CDC-Mode zu betreiben. Damit wird beim Verbinden mit einem PC ein virtueller Comport eingerichtet über den man (wie per UART) Daten austauschen kann.

Auf der PC Seite muss der “VirtualComPort-Driver von ST” installiert sein. Den gibts auf der ST-Seite zum download (ich hab mit Version 1.3.1 getestet).
Auf der ST-Seite nach “STSW-STM32102″ suchen.

Die LIB erwartet beim empfang als Endekennung das Zeichen “0x0D” = CarriageReturn
(das muss der PC also am Stringende anhängen)

Beim Protokoll (Baudrate, Stopbits usw) muss nichts eingestellt werden, das wird vom USB-Treiber erledigt.

In der Library gibt es eine Sende und eine Empfangsfunktion für Strings und eine Funktion zum testen ob die USB-Verbindung steht.

Ich hab auch ein “mini” PC-Terminal-Programm geschrieben um die Funktion zu testen.

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

Hinweis : weil für USB eine Clock-Frq von 48MHz zwingend notwendig ist und diese Frq mit einer Sysclock von 180MHz nicht einstellbar ist, wurde für diese Library der Sysclock auf 168MHz runtergesetzt !!

Benutzte Pins

  PB13  -> USB_OTG_VBUS
  PB12  -> USB_OTG_ID
  PB14  -> USB_OTG_DM
  PB15  -> USB_OTG_DP

Enumerationen :

1
2
3
4
5
typedef enum {
  USB_CDC_NO_INIT =0, // USB-Schnittstelle noch nicht initialisiert
  USB_CDC_DETACHED,   // USB-Verbindung getrennt
  USB_CDC_CONNECTED   // USB-Verbindung hergestellt
}USB_CDC_STATUS_t;

:

1
2
3
4
5
6
7
typedef enum {
  NONE = 0,  // keine Endekennung
  LFCR,      // LineFeed + CarriageReturn (0x0A,0x0D)
  CRLF,      // CarriageReturn + LineFeed (0x0D,0x0A)
  LF,        // nur LineFeed (0x0A)
  CR         // nur CarriageReturn (0x0D)
}USB_CDC_LASTBYTE_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_CDC_RXSTATUS_t;

Funktionen :

1
2
3
4
void UB_USB_CDC_Init(void);                                                // zum init der USB-Schnittstelle
USB_CDC_STATUS_t UB_USB_CDC_GetStatus(void);                               // USB Status abprüfen
ErrorStatus UB_USB_CDC_SendString(char *ptr, USB_CDC_LASTBYTE_t end_cmd);  // zum senden eines Strings per USB
USB_CDC_RXSTATUS_t UB_USB_CDC_ReceiveString(char *ptr);                    // zum empfangen eines Strings 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
44
45
46
47
48
49
50
51
52
53
54
//--------------------------------------------------------------
// File     : main.c
// Datum    : 02.11.2013
// Version  : 1.0
// Autor    : UB
// EMail    : mc-4u(@)t-online.de
// Web      : www.mikrocontroller-4u.de
// CPU      : STM32F429
// IDE      : CooCox CoIDE 1.7.4
// GCC      : 4.7 2012q4
// Module   : CMSIS_BOOT, M4_CMSIS_CORE
// Funktion : Demo der USB-CDC-Library
// Hinweis  : Diese zwei Files muessen auf 8MHz stehen
//              "cmsis_boot/stm32f4xx.h"
//              "cmsis_boot/system_stm32f4xx.c"
// In Configuration diese Define hinzufügen :
// "STM32F429_439xx" , "__ASSEMBLY__" , "USE_STDPERIPH_DRIVER"
//--------------------------------------------------------------
 
#include "main.h"
#include "stm32_ub_led.h"
#include "stm32_ub_usb_cdc.h"
 
int main(void)
{
  char rx_buf[APP_TX_BUF_SIZE]; // puffer fuer Datenempfang
  USB_CDC_RXSTATUS_t check=RX_EMPTY;
 
  SystemInit(); // Quarz Einstellungen aktivieren
 
  // init der LEDs
  UB_Led_Init();
 
  // Init vom USB-OTG-Port als CDC-Device
  // (Virtueller-ComPort)
  UB_USB_CDC_Init();
 
  while(1)
  {
    // Test ob USB-Verbindung zum PC besteht
    if(UB_USB_CDC_GetStatus()==USB_CDC_CONNECTED) {
      UB_Led_On(LED_GREEN);
   	  // test ob etwas per USB empfangen wurde
      check=UB_USB_CDC_ReceiveString(rx_buf);
      if(check==RX_READY) {
        // wenn ja, dann als Echo zurücksenden
        UB_USB_CDC_SendString(rx_buf,LFCR);
      }
    }
    else {
      UB_Led_Off(LED_GREEN);
    }
  }
}

Hier die Library zum Download :

usb_cdc_device_f429_v100

Hier der komplette CooCox-Projektordner zum Download :

Demo_F429_13

Hier der Link zu dem PC-Programm :

PC-Programme


19 Antworten auf 13-USB_CDC-Library (STM32F429)

  1. joe14 sagt:

    I have problem with implementing this. Can be problem with using this lib inside c++ program. I use C++ in CooCox with this instructions http://www.coocox.org/forum/images/ckeditorfiles/20131023205634_How_to_use_CPlusPlus_in_CoIDE.pdf

    • admin_ub sagt:

      uhh sorry, i can’t say anything about “c++” i use “c” only. But try to add this statement in all the “H-Files”

      1
      2
      3
      4
      5
      6
      7
      8
      9
      
      #ifdef __cplusplus
      extern “C” {
      #endif
       
      // H-File code
       
      #ifdef __cplusplus
      }
      #endif

      it’s a lot of work and i can’t promise thats the solution :-(
      By the way…C++ is not really necessary :-)

      • joe14 sagt:

        Thank you, I can confirm it compiles. I don’t have board right here now, so I cant test it, but after adding lines you suggested it compiles.

        I am using C++, because i am porting code from arduino mega, where i wrote some source in c++

  2. Joerg sagt:

    Wo dran liegt es eigenlich, dass nur USB-FullSpeed und nicht HighSpeed geht?

    • admin_ub sagt:

      An der Hardware…für HighSpeed wird ein externer PHY am ULPI-Bus der CPU benötigt. Da dieser auf dem Board nicht vorhanden ist, geht nur FullSpeed.

  3. Tobi sagt:

    Hi,
    super Arbeit Danke dafür.
    Ich habe eine Frage:
    in Zeile 535 der system_stm32f4xx.c steht noch folgendes:

    535
    536
    
    /* Enable the Over-drive to extend the clock frequency to 180 Mhz */
    PWR->CR |= PWR_CR_ODEN;

    auf S.91 von “DocID024030 Rev 2″ RM0090 Reference manual
    ist angegeben, dass damit APB1 Max 45 MHz ist.
    Mit dem Prescaler 4 ist APB1 aber 42 MHz oder verändert der Over-drive mode daran etwas?

    • admin_ub sagt:

      Die max FRQ von 45MHz hat man nur, wenn Sysclk=180MHz beträgt. (180/4=45). Aber für die USB-Librarys habe ich den Sysclock auf 168MHz runtergesetzt und damit ist APB1 nur 42MHz.

  4. Tobi sagt:

    Hi,
    ich habe ein Problem, welches bei der Lib für das STM32F4DISCO anscheinend schonmal aufgetreten ist. Der PC erkennt nicht, dass eine Hardware angeschlossen wurde. Der ST Virt. Com Driver ist installiert.
    Muss ich noch etwas beachten?

    Danke
    Tobias

    • admin_ub sagt:

      bist du 100% sicher das deine USB-Clock 48MHz sind ? … wenn der eine andere Frq hat, wird das Device nicht erkannt.

  5. NeoExacun sagt:

    Ich habe ein schwerwiegendes Problem mit der Lib.

    Sobald ich sie im Projekt hinzufüge wird das Kompilat leider unbrauchbar. Wenn ich es aufspiele passiert garnichts mehr. Sobald ich die Dateien wieder aus dem Projekt lösche geht alles wieder.

    Die Ausgabe vom Debugger sieht folgendermaßen aus:
    file “****/stm32f429/Debug/bin/stm32f429.elf”
    Reading symbols from ****\stm32f429\Debug\bin\stm32f429.elf…done.
    set tdesc filename E:/CooCox/CoIDE/bin/target_desc/arm-with-m.xml
    target remote 127.0.0.1:2009
    Remote debugging using 127.0.0.1:2009
    0x0800cac4 in UB_I2C3_Init () at ****\ub_lib\stm32_ub_i2c3.c:84
    84 GPIO_InitStructure.GPIO_Pin = I2C3DEV.SDA.PIN;
    tbreak main
    Temporary breakpoint 1 at 0x800d848: file ****\main.c, line 335.
    continue
    Continuing.

    • admin_ub sagt:

      funktioniert den das Beispiel-Projekt wie es soll, oder geht das auch nicht ?. Ansonsten wirst du mit dem Debugger schauen müssen wo genau er hängen bleibt.

  6. Christoph sagt:

    Guten Morgen,
    erstmal vielen Dank für so klare Libraries. Die werde ich mir noch weiter anschauen.

    unterscheided sich der STM32F429 als USB CDC device zu dem STM32F4 Discovery?

    Das STM32F4 Discovery habe ich erfolgreich als Serial Device auf meinem Mac eingebunden. (Ich verwende nicht deine Lib sonder ein Murks aus ALTER(USB) (!) und neuer StdPeriphLib(Rest)). Die funktionierende Version konnte ich leider nicht auf den F429 umbiegen.
    Deine Libraryversion kompiliert. Das Gerät wird aber auf meinem Mac nicht als serial device eingebunden. Und zu allem überfluss “blockiert” der Mac das gerät sodass ich es nicht in einer Virtuellen Maschine verwenden kann. Bisher habe ich keinen Plan was da passiert. Das USB Gerät wird erkannt, aber nicht als device eingebunden.
    Ich habe es allerdings geschafft den F420 mit libusb ein paar bytes zuzuschubsen, aber das funktioniert bisher nur einseitig und nicht zuverlässig.

    Deswegen nochmal die anfangsfrage: besteht da ein prinzipieller Unterschied zwischen den evaluatiosnboards bzw. libraryversionen ?

    Was ich bisher erkennen konnte ist in der Funktion
    USB_OTG_BSP_Init()
    steht bei dir:
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_OTG_HS, ENABLE);
    und in meiner funktionierenden Version
    RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_OTG_FS, ENABLE);

    Unter Windows wird das serielle Gerät erkannt. Nur will ich jetzt nicht alles umschmeißen, deswegen habe ich ja als backup eine Virtuelle Maschine.

    P.S: meine Frau liest gerade mit und sagt wir hätten sie nicht mehr alle und brauchen ein gutes Psychopharmaka

    Schönen Gruß
    Christoph

    • admin_ub sagt:

      der Unterschied zwischen den zwei Disco Boards ist :
      bei F407 ist der User-USB an den FullSpeed-Port angeschlossen (PA11,PA12) beim F429 hängt er am HighSpeed-Port (PB14, PB15) der allerdings nur im FullSpeed-Mode läuft. (für HighSpeed wäre ein externer PHY notwendig)

  7. Mathias sagt:

    Guten Tag,
    gibt es den für die USB CDC Funktion auch irgendwo einen Block zum einbinden in Simulink ?

    Gruß Mathias

    • admin_ub sagt:

      von mir nicht.

  8. Mathias sagt:

    Ok,
    ich werde versuchen den Code in einem “Custom Block” in Simulink einzubinden. Das scheint irgendwie zu klappen.
    Trotzdem erst einmal Danke !

  9. Florian sagt:

    Hallo,
    vielen Dank für diese Startup Hilfe.

    Leider bin ich noch nicht in das ST Spezifische eingearbeitet, aber wenn man das Programm mit einem 25MHz Clock betreiben möchte, muss man (im Vergleich zu Deinem Demo Programm) in stm32f4xx.h:

    #define HSE_VALUE ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */

    und in system_stm32f4xx.c:

    #define PLL_M 25

    setzen, oder ??? Noch irgendwas anderes ??? Leider erkennt mein Geräte Manager den USB/COM noch nicht, obwohl ich den ST VirtualComPortDriver installiert habe.

    Würde mich riesig über eine Antwort freuen.

    Cheers, Florian

    • admin_ub sagt:

      für USB Anwendungen muss der Sysclock auf 168MHz eingestellt sein
      (nicht auf 180 MHz)
      du brauchst also HSE=25000000, PLL_M = 25, PLL_N = 336
      wahrscheinlich steht bei dir das PLL_N noch auf 360

  10. Marcel sagt:

    Hallo,
    erstmal vielen Dank für deine zahlreichen Bibliotheken. Bisher hatte ich VCP nur auf einem STM32f407-Discovery mit einer Libary von Tim Majerle laufen.

    Ich versuche gerade deine “13-USB_CDC-Library (STM32F429)” Libary auf meinem STM32F429-DISC1 zum laufen zu bekommen, leider ohne Erfolg. Selbst mit dem CoIDE Projekt von dir habe ich im Geräte Manager nur 2 Geräte (STM32 VirtualComPort in FS Mode) deren Treiber nicht installiert werden konnte.

    ist die Libary überhaupt mit dem Stm32F429i-DISC1 kompatibel?


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.