Forum: Mikrocontroller und Digitale Elektronik Stm32 USB virtual com port example


von Max (Gast)


Lesenswert?

Hallo ich versuche gerade das USB-Beispiel von ST VirtualComPort mit 
Hilfe der STM32_USB-FS-Device_Lib_V3.0.1 auf mein Board zu übertragen.

Das Beispiel ist für deren(ST) Evaluationsboards geschrieben.
mein Board hjat einen STM32F103DT6 (LQFG 100 pin).
Ich habe Auch eine 8Mhz quarz und eine Uhrenquarz drauf.

Ich kann das beispiel auf meiner Hardware laufen lassen (nach Anpassung 
des Prozessors) Die Usb Schnittstelle meldet sich auch an und ich kann 
den Treiber installieren - wunderbar. nur bekomme ich den Transfer 
Usart1 -> Usb und zurück nicht hin.

Meine USART ligt an anderen =Pins, deswegen habe ich sie "remapped"

Irgendwelche vorschläge ?

  //      - Word Length = 8 Bits
  //      - 1 Stop Bit
  //      - No parity
  //      - BaudRate = 38400 baud
  //      - Receive and transmit enabled
  //-------------------------------------------------------

  // Remap UART1 to PB6(TX) and PB7(RX)
  GPIO_PinRemapConfig(GPIO_Remap_USART1, ENABLE);

  // Configure the USART1_Tx as Alternate function Push-Pull
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOB, &GPIO_InitStructure);

  // Configure the USART1_Rx as input floating
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 ;
  GPIO_Init(GPIOB, &GPIO_InitStructure);



  USART_InitStructure.USART_BaudRate = 38400;  // 19200;  //57600; 
//115200;
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  USART_InitStructure.USART_StopBits = USART_StopBits_1;
  USART_InitStructure.USART_Parity = USART_Parity_No ;
  USART_InitStructure.USART_HardwareFlowControl = 
USART_HardwareFlowControl_None;
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  USART_Init(USART1, &USART_InitStructure);

  // Enable the USART1
  USART_Cmd(USART1, ENABLE);

danke Max

von Hannes (Gast)


Lesenswert?

Wenn zwischen Deinem und dem Eval Board sonst kein Unterschied ist, dann 
fällt mir eigentlich nur noch ein, dass vielleicht der Clock für PortB 
nicht aktiv ist? Also müsstest Du dann sowas in der Art noch einfügen: 
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

Gruß,
Hannes

von Max (Gast)


Lesenswert?

Hallo Hannes,
danke für die Antwort.
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
ist natürlich (leider) schon drin gewesen.

Vielleicht könnte jemand der das eval board hat mal testen , ob das 
Beispiel funktioniert ?

Achso und wenn mir jemand jagen könnte mit welchen Baudrates die Usb 
Schnittstelle (virt. com port) angesprochen werden möchte.
Wenn ich es richtig sehe, meldet sich die Schnittstelle mit der gleichen 
Geschwindigkeit (und nat. parity, flow usw.) an wie mein Usart 
konfiguriert ist.

vielen Dank im Voraus

Gruß
Max

von Philipp (Gast)


Lesenswert?

allo,
ich habe gestern der virtual com treiber auf einem Olimex Board 
integriert und es hat nach 3 Stunden funktioniert. Das einzige was noch 
ist, wenn ich abstecke und wieder anstecke, dann sagt der PC, daß er 
keine COM gefunden hat. Es sieht so aus, als ob da die Initialisierung 
nach dem Trennen nicht funktioniert.

Wo liegt nun derzeit dein Problem?

ciao,
Philipp

von Erwin R. (er-tronik)


Lesenswert?

Philipp schrieb:
> allo,
> ich habe gestern der virtual com treiber auf einem Olimex Board
> integriert und es hat nach 3 Stunden funktioniert. Das einzige was noch
> ist, wenn ich abstecke und wieder anstecke, dann sagt der PC, daß er
> keine COM gefunden hat. Es sieht so aus, als ob da die Initialisierung
> nach dem Trennen nicht funktioniert.
> Wo liegt nun derzeit dein Problem?

Du solltest auf jeden Fall zuerst das Terminalprogramm beenden (oder 
welches Tool auch immer du für den COM-Port benutzt) bevor du deine 
Schaltung trennst. Nach dem Anstecken sollte dann der Port auch wieder 
vorhanden sein.

Erwin

von Philipp (Gast)


Lesenswert?

Ja, das muß anscheinend so sein. Sonst hilft nur im System Manager 
deaktivieren/aktivieren.

Philipp

von Philipp (Gast)


Lesenswert?

Hallo,
so nun habe ich ein neues Phenomän. Ich bekomme die Zeichen zwar raus, 
aber am Terminal sind die nur als Paket nach einigen Sekunden (ca. 30) 
sichtbar. D.h. es kommen alle 30 Sekunden alle Zeilen die gesendet 
wurden. Also nicht mehr eine nach der anderen Zeile. Es fehlt auch 
keine. Ich gebe jede Sekunde eine Zeile mit ca. 80 Zeichen aus.

Mittlerweile habe ich 3 verschiedene Terminal Programme ausprobiert, 
aber es ist bei allen das gleiche Problem.

Gibt es bei USB eine Art Flush Funktion. Bleiben die Zeichen in einem 
Cache? FIFO habe ich beim Virtuellen Port abgeschaltet - bringt keine 
Besserung.

ciao,
Philipp

von Arne (Gast)


Lesenswert?

Hatte auch Probleme mit der USB-Lib von STM. Die Version vom Februar 
2009 hatte einen deftigen Bug: der Cortex-Interne HW-Puffer konnte 
überlaufen - da fehlte die Flusskontrolle. Weiterhin habe ich dann noch 
einen SW-Ringpuffer zwischen meine Applikation und meine Lib geschaltet 
und nun komme ich auf etwa 800kBit bis 1MBit, wenn die Daten nicht 
weiterverarbeitet werden müssen.
Ich benutze aber weder deren Firmware noch USB Lib - hab ich mir hier 
alles selbst geschrieben.

Wie ist Dein Aufbau? Ich nehme ein Olimex STM32-SK (Vertrieb durch IAR).
Schickst Du Daten vom PC an einen UART des Cortex und schickst die Daten 
dann über die USB des Cortex wieder an den PC zurück?

Falls ja: da hatte ich auch ein Problem. Und zwar hatte ich zwischen PC 
und Cortex UART einen "USB zu 4x RS232" Wandler dran (von exsys) Deren 
treiber hat immer das letzte Paket verschluckt. Wenn dann mal nach einer 
Zeit wieder was eintrudelte hat er das "verschluckte" Paket 
weitergereicht und das neu eingetroffene "verschluckt".
Hab dann das Olimexboard an mein Notebook mit einer PCMCIA RS232 Karte 
gehängt und damit gings dann.

bye, Arne

von Philipp (Gast)


Lesenswert?

Ich habe Queues dazwischen (FreeRTOS). Eigentlich ist der USB derzeit 
nur für Debugausgaben gedacht. Es funktioniert ja eigentlich alles, nur 
irgendwo werden ca. 4kB zwischengespeichert und auf einmal ausgegeben. 
Also beim STM32 (ich verwende das Olimex stm32F103... Board) kanns nicht 
hängen bleiben, denn wo soll er hin damit. Ich sehe auch, daß es raus 
geht und die IRQs werden brav aufgerufen. Kanns am Windows Treiber 
liegen?

von Max (Gast)


Lesenswert?

Hallo entschuldigt, dass ich so lange nichts mehr geschrieben habe.
Meine
Probleme sind so weit gelöst. Ich musste die empfangs und sende routinen 
bei mir dementsprechend anpassen.

Hallo Phillip. Vielleicht hängt das mit einem HUB zusammen ?
ich habe im Augenblick noch das phänomen, dass die Übertragung mit einem 
Hub nicht 100%ig funktioniert.

Vielleicht kommt deine USB nicht mit der Seriellenschnittstelle 
hinterher ?
mir ist aufgefallen, dass man auf gar keinen fall die Zeichen einzeln 
Schreiben darf, sondern die Pakete als Puffer in den USb schreiben muss.

Ich habe einen Ringpuffer in den ich meine Ausgabedaten stelle. dieser 
wird zyklisch aufgerufen und abgearbeitet. (seperat für USB und Usart)

Ausgabe routine
1
 if(USBEnabled&&(GetDADDR() & DADDR_EF)&&(GetDADDR() & DADDR_ADD))
2
    { 
3
      while(!usbtxready) sched();
4
      usbtxready=0;
5
      UserToPMABufferCopy(&usbbuffer[0], ENDP1_TXADDR, count);
6
      SetEPTxCount(ENDP1, count);
7
      SetEPTxValid(ENDP1);
8
    }


usbbuffer ist mein Puffer.

if(USBEnabled&&(GetDADDR() & DADDR_EF)&&(GetDADDR() & DADDR_ADD)) ist 
die Abfrage ,ob USB initialisiert ist , oder nicht.
(USBEnabled, habe ich mir selber gemacht für den Fall, das die USb 
schnittstelle unterbrochen wird.


Eingabe routine :
1
 if ((count_out!=0)&&(USBCount < count_out)&& (bDeviceState == CONFIGURED))
2
  {
3
    c=*(&buffer_out[0] + USBCount);
4
    USBCount++;
5
    if (USBCount==count_out){USBCount=0;count_out=0;}
6
    USBEnabled=1;
7
    return(c);
8
  }

c ist das empfangene Zeichen
count_out ist in den Beispielen Enthalten.
USBcount ist meine eigene Zählvariable, um den puffer auszugeben.

von Arne (Gast)


Lesenswert?

> mir ist aufgefallen, dass man auf gar keinen fall die Zeichen einzeln
> Schreiben darf, sondern die Pakete als Puffer in den USb schreiben muss.

Ich habe das mal hier in der Firma untersucht:
In der USB-ISR habe ich am Anfang eine LED gesetzt und am Ende gelöscht. 
Dann an die LED ein Oszi gehängt und USB mit dem WinXP PC verbunden: bei 
mir pingt der PC im 1kHz Raster den Cortex auf der USB Schnittstelle an. 
Wenn man dann immer nur ein Byte sendet, ist man nicht besser, als mit 
9600bps ;)
Also wirft meine Applikation alles in einen SW-Ringpuffer des BSP. Die 
USB-ISR zieht sich - sobald der PC den Cortex anpingt - soviel als 
möglich aus diesem SW-Ringpuffer in das HW-USB-Packetmemory. Und "jut 
jewesen".

@Philipp:
Keep it simple: Generiere einen Text on the fly auf dem Cortex und haue 
den ans Terminalprg. raus. Schau dann, ob alles ankommt.
Also z.B. 100000x "0123456789" als Text verschicken. Dann am 
Terminalprg. den Empfang in eine Datei mitloggen (TeraTerm kann das 
z.B.) und im Anschluß prüfen, ob die Datei alle Strings enthält.
Und für USB Empfang dan dasselbe in Gegenrichtung. Einfachen Text senden 
und am Cortex prüfen, ob auch immer das Zeichen kam, das er erwartet und 
dann auch die gesamte empfangene Menge prüfen. Easy... finde ich.

bye, Arne

von Philipp (Gast)


Lesenswert?

Hallo,
so jetzt hab ich es mir mal mit einem Hex Editor angesehen. Am Terminal 
kommen immer exakt 8kB (8192 Bytes) auf einmal. Was ich garnicht 
verstehe ist, warum gibt die Routine von ST eigentlich Unicode16 aus und 
nicht 8Bit ASCII. Muß das bei USB so sein???

von Philipp (Gast)


Lesenswert?

Sorry, der Editor zeigt es nur so an. Es sind 4KB, wobei USBlyser 
(Software zum USB debuggen) sagt, der WIndows Treiber hat einen 1000h = 
4KB Buffer. Wo kann ich den ausschalten - der Mode nennt sich 
IRQ/Interrupt Transfer mit niedriger Priorität.

Philipp

von Philipp (Gast)


Lesenswert?

So, das hört sich nun fast wie ein Selbstgespräch an, aber falls jemand 
das gleiche Problem hat ...

Der Fehler war folgender. Ich habe immer gewartet, bis ich 16 Bytes 
zusammen habe. Daturch wurde alles im Treiber gecacht und nicht gleich 
ausgegeben. Nun wir bei einem Zeilenende (weniger als 16 Bytes) der 
Buffer copiert und übertragen. Dadurch erscheint auch die Zeile gleich 
im Terminalprogramm.

So nun kommt das HID dazu.

ciao,
Philipp

von Gast (Gast)


Lesenswert?

Hallo Phillipp,

das gleiche Problem hab ich auch, nur sind's bei mir hexadezimal 4000h 
Byte, die zwischengespeichert werden. Ich hab deinen letzten Post nicht 
ganz verstanden. Wodurch funktioniert es jetzt? Wenn du einen 
Zeilenumbruch sendest??

von Philipp (Gast)


Lesenswert?

Tja, so ganz bin ich mir da noch nicht sicher. Es scheint so, als ob er 
den Buffer nur dann weiterleitet, wenn weniger Zeichen als die 16 
übertragen werden. Es geht auch, wenn zum Schluß 0 Bytes übertragen 
werden (Erkennung für den usbser.sys Treiber). Ich werde das noch weiter 
untersuchen.

ciao,
Philipp

von Potter S. (potter68)


Lesenswert?

Hi,

wie groß sind denn Deine Endpunkte? Laut Spezifikation (2.0, 5.8.3) 
gilt:

A bulk transfer is complete when the endpoint does one of the following:
• Has transferred exactly the amount of data expected
• Transfers a packet with a payload size less than wMaxPacketSize or 
transfers a zero-length packet

Gruß Potter

von Philipp (Gast)


Lesenswert?

Hi,
die Buffer sind 16 Bytes. Nach deiner Erklärung ist mir nun alles klar. 
Ich habe es nun genauso in meiner Applikation integriert.

ciao,
Philipp

von Marcel (Gast)


Lesenswert?

Hallo zusammen!

Bin davor USB Verbindung zum Pc zu programmieren.
Hab dann von dem USB-Beispiel von ST VirtualComPort gelesen, gibt es den 
Quellcode irgendwo?

Danke schonmal!

von Peter K. (mikro1111)


Lesenswert?

kann mir einer von euch das virtual com port example schicken?

habe mir das folgende beispiel geladen.

http://www.mikrocontroller.net/articles/STM32_USB-FS-Device_Lib

kriege es aber nicht zum laufen, da mir die usb_lib.h fehlte. als ich 
die imortiert hatte, fehlte wieder ein ganzer schwung an libs. habt ihr 
vielleicht ein projekt wo alles schon so implementiert ist, dass es so 
läuft???


vielen dank schonmal

von Peter K. (mikro1111)


Lesenswert?

mcdamn@gmx.de

von Peter K. (mikro1111)


Lesenswert?

P. L. schrieb:
> mcdamn@gmx.de

libs sind implementiert. soweit erstmal auch keine fehler mehr, jedoch 
läuft es noch nicht

von Thomas B. (escamoteur)


Lesenswert?

Hast Du auch den entsprechenden Virtual Comport Treiber installiert? Was 
passiert denn wenn Du das USB-Kabel einsteckst?

von Peter K. (mikro1111)


Lesenswert?

es paasiert nichts. das verwundert mich ja gerade.

von Peter K. (mikro1111)


Lesenswert?

ich benutze das olimex board stm32-P103. aber an der verschaltung sollte 
das ja universell sein. also dies dürfte nicht das problem sein.

Habe das beispiel implementiert und die st libraries runtergeladen und 
auch implementiert. kompiliere das ganze jedoch meldet sich, wenn ich 
das ganze starte nichts in windows an.

von Thomas B. (escamoteur)


Lesenswert?

Hast Du mein kleines Beispiel genommen oder das Orginal?

von Thomas B. (escamoteur)


Lesenswert?

Ich hab in den Artikel STM32 USB-FS-Device Lib gerade mal meinen 
Schaltplan eingefügt, mit dem es funktioniert.
Tom

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.